/******************************************************************************* * Copyright (c) 2013, 2015 Red Hat, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat initial API and implementation *******************************************************************************/ package org.eclipse.linuxtools.internal.profiling.launch; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; import org.eclipse.debug.ui.ILaunchConfigurationTab; import org.eclipse.linuxtools.internal.profiling.launch.provider.ProviderProfileConstants; import org.eclipse.linuxtools.internal.profiling.launch.provider.launch.ProviderFramework; import org.eclipse.linuxtools.internal.profiling.launch.provider.launch.ProviderLaunchShortcut; import org.eclipse.linuxtools.profiling.launch.ProfileLaunchConfigurationTabGroup; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; /** * Shared class for displaying profiling options in a single tab. * * @since 2.0 */ public abstract class AbstractProfilingOptionsTab extends AbstractLaunchConfigurationTab { private String type; private String name; private String id; private Composite top; private Combo providerCombo; private AbstractLaunchConfigurationTab[] tabs; private ILaunchConfiguration initial; private Map<String, String> comboItems; private CTabFolder tabgroup; protected Image img; // if tabs are being initialized do not call performApply() private Map<String, Boolean> initialized = new HashMap<> (); /** * Get list of profiling providers for the user to choose from. * * @return Map of provider ids and provider tool names */ protected abstract Map<String, String> getProviders(); @Override public void createControl(Composite parent) { top = new Composite(parent, SWT.NONE); setControl(top); top.setLayout(new GridLayout(1, true)); comboItems = getProviders(); Set<String> providerNames = comboItems.keySet(); providerCombo = new Combo(top, SWT.READ_ONLY); providerCombo.setItems(providerNames.toArray(new String[0])); if (providerNames.size() == 0) { providerCombo.setVisible(false); providerCombo.setEnabled(false); Label label = new Label(top, SWT.NULL); label.setText(Messages.ProfilingTab_no_category_profilers_installed); } tabgroup = new CTabFolder(top, SWT.NONE); tabgroup.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); providerCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String curProviderId = comboItems.get(providerCombo.getText()); loadTabGroupItems(tabgroup, curProviderId); initializeFrom(initial); // Since we are calling initializeFrom manually, we have to // update the launch configuration dialog manually to ensure // initial validation on the configuration. updateLaunchConfigurationDialog(); top.layout(); } }); } /** * Get the default provider id to use if one is not set for the configuration. * * @return default provider id */ protected abstract String getDefaultProviderId(); private void loadTabGroupItems(CTabFolder tabgroup, String curProviderId) { // dispose of old tabs and their state for (CTabItem item : tabgroup.getItems()) { item.dispose(); } setErrorMessage(null); initialized.clear(); ProfileLaunchConfigurationTabGroup tabGroupConfig; if (curProviderId == null || curProviderId.isEmpty()) { curProviderId = getDefaultProviderId(); } // starting initialization of this tab's controls initialized.put(curProviderId, false); tabGroupConfig = ProviderFramework.getTabGroupProviderFromId(curProviderId); if (tabGroupConfig == null) { String profilingToolName = null; try { profilingToolName = initial.getAttribute(ProviderProfileConstants.PROVIDER_CONFIG_TOOLNAME_ATT, (String)null); } catch (CoreException e) { // do nothing } if (profilingToolName == null) { setErrorMessage(NLS.bind(Messages.ProfilingTab_specified_providerid_not_installed, curProviderId)); } else { setErrorMessage(NLS.bind(Messages.ProfilingTab_specified_profiler_not_installed, profilingToolName)); } return; } tabs = tabGroupConfig.getProfileTabs(); setProvider(curProviderId); // Show provider name in combo. int itemIndex = getComboItemIndexFromId(curProviderId); providerCombo.select(itemIndex); // Set name of configuration. setConfigurationName(providerCombo.getText()); // create the tab item, and load the specified tab inside for (ILaunchConfigurationTab tab : tabs) { tab.setLaunchConfigurationDialog(getLaunchConfigurationDialog()); CTabItem item = new CTabItem(tabgroup, SWT.NONE); item.setText(tab.getName()); item.setImage(tab.getImage()); tab.createControl(tabgroup); item.setControl(tab.getControl()); tabgroup.setSelection(0); } } @Override public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { if (providerCombo != null && !providerCombo.getText().isEmpty()) { for (AbstractLaunchConfigurationTab tab : tabs) { tab.setDefaults(configuration); } } } @Override public void initializeFrom(ILaunchConfiguration configuration) { /** * First time the configuration is selected. * * This is a cheap way to get access to the launch configuration. Our * tabs are loaded dynamically, so the tab group doesn't "know" about * them. We get access to this launch configuration to ensure that we * can properly load the widgets the first time. */ // update current configuration (initial) with configuration being // passed in initial = configuration; // check if there exists a launch provider id in the configuration if (initial != null) { try { String providerId = initial.getAttribute( ProviderProfileConstants.PROVIDER_CONFIG_ATT, (String)null); // load provider corresponding to specified ids loadTabGroupItems(tabgroup, providerId); } catch (CoreException e) { // continue, initialize tabs } } if (tabs != null) { for (AbstractLaunchConfigurationTab tab : tabs) { tab.initializeFrom(configuration); } } // finished initialization initialized.put(getProviderId(), true); } @Override public void performApply(ILaunchConfigurationWorkingCopy configuration) { // make sure tabs are not null, and the tab's controls have been // initialized. Boolean isInitialized = initialized.get(getProviderId()); isInitialized = (isInitialized != null) ? isInitialized : false; if (tabs != null && isInitialized) { for (AbstractLaunchConfigurationTab tab : tabs) { tab.performApply(configuration); } } } /** * Set the provider attribute in the specified configuration. * @param providerId The new provider id. */ private void setProvider(String providerId) { try { ILaunchConfigurationWorkingCopy wc = initial.getWorkingCopy(); wc.setAttribute(ProviderProfileConstants.PROVIDER_CONFIG_ATT, providerId); initial = wc.doSave(); } catch (CoreException e1) { e1.printStackTrace(); } } /** * Set name of the launch configuration. * * @param newToolName String tool name to be appended to configuration name, */ protected void setConfigurationName(String newToolName) { try { String currentToolName = initial.getAttribute( ProviderProfileConstants.PROVIDER_CONFIG_TOOLNAME_ATT, ""); //$NON-NLS-1$ // Append the new tool name as long as the current and new tool // names are different. if (newToolName != null && !newToolName.isEmpty() && !currentToolName.equals(newToolName)) { String projectName = initial.getAttribute( ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$ // String of the form <project name> [<tool name>]. String newConfigurationName = ProviderLaunchShortcut .generateProviderConfigurationName(projectName, newToolName); // Unique name of the form <project name> [<tool name>]{(<number>)}. String newUniqueToolName = getLaunchManager() .generateLaunchConfigurationName(newConfigurationName); // Save changes in current configuration. ILaunchConfigurationWorkingCopy wc = initial.getWorkingCopy(); wc.rename(newUniqueToolName); wc.setAttribute( ProviderProfileConstants.PROVIDER_CONFIG_TOOLNAME_ATT, newToolName); initial = wc.doSave(); // Set name field in launch configuration dialog to avoid the // new configuration name from being overwritten. getLaunchConfigurationDialog().setName(newUniqueToolName); } } catch (CoreException e) { // If unable to set the name, leave the original name as is. } } /** * Get the provider ID for the provider of the currently loaded * configuration. * * @return the provider ID or an empty string if the configuration * has no provider ID defined. */ private String getProviderId() { try { return initial.getAttribute( ProviderProfileConstants.PROVIDER_CONFIG_ATT, ""); //$NON-NLS-1$ } catch (CoreException e) { return ""; //$NON-NLS-1$ } } /** * Get Combo item name from specified id * * @param id provider id * @return name of item, <code>null</code> if no entry found with given id. */ private String getComboItemNameFromId(String id) { for (Entry<String, String> entry : comboItems.entrySet()) { if (id.equals(entry.getValue())) { return entry.getKey(); } } return null; } /** * Get index of specific name in the combo items list. * * @param name Name of item * @return Index of given name, -1 if it not found. */ private int getItemIndex(String name) { int itemCount = providerCombo.getItemCount(); for (int i = 0; i < itemCount; i++) { if (providerCombo.getItem(i).equals(name)) { return i; } } return -1; } /** * Get index of specific id in the provider combo items list * * @param id Combo item id. * @return index of given id in provider combo items list, -1 if it not found. */ private int getComboItemIndexFromId(String id) { String providerName = getComboItemNameFromId(id); return getItemIndex(providerName); } @Override public boolean isValid(ILaunchConfiguration config) { String provider; try { provider = config.getAttribute( ProviderProfileConstants.PROVIDER_CONFIG_ATT, ""); //$NON-NLS-1$ } catch (CoreException e) { setErrorMessage(e.getMessage()); return false; } if (provider.isEmpty()) { setErrorMessage(Messages.ProfilingTab_providerid_not_found); return false; } Boolean isInitialized = initialized.get(getProviderId()); if (isInitialized) { // Tabs should not be null after initialization. if (tabs == null) { return false; } // Validate tab configurations of underlying tool. for (AbstractLaunchConfigurationTab tab : tabs) { if (!tab.isValid(config)) { setErrorMessage(tab.getErrorMessage()); return false; } } } return true; } /** * Get name of profiling type that used for this tab. * * @return String profiling name. */ @Override public String getName() { return name; } /** * Set the name for this tab. * * @param name New tab name. */ protected void setName(String name) { this.name = name; } @Override public String getId() { return id; } /** * Set the id for this tab. * * @param id New id of the tab. */ protected void setId(String id) { this.id = id; } /** * Get profiling type of the configuration. * * @return String profiling type this plug-in supports. */ protected String getProfilingType() { return type; } /** * Set profiling type of configuration. * * @param type New profiling type. */ protected void setProfilingType(String type) { this.type = type; } @Override public Image getImage() { return img; } /** * Set the image for this tab. * * @param img New image. */ public void setImage(Image img) { this.img = img; } @Override public void dispose() { if (img != null) { img.dispose(); } super.dispose(); } }