| /******************************************************************************* |
| * Copyright (c) 2007, 2015 Intel Corporation, QNX Software Systems, and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Intel Corporation - initial API and implementation |
| * Markus Schorn (Wind River Systems) |
| * Andrew Gvozdev |
| * QNX Software Systems - [271628] NPE in configs for project that failed to convert |
| * James Blackburn (Broadcom Corp.) |
| * Serge Beauchamp (Freescale Semiconductor) - Bug 406545 |
| * cartu38 opendev (STMicroelectronics) - Bug 531915 |
| *******************************************************************************/ |
| package org.eclipse.cdt.ui.newui; |
| |
| import java.io.File; |
| import java.lang.reflect.InvocationTargetException; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.cdt.core.CCorePlugin; |
| import org.eclipse.cdt.core.model.CoreModel; |
| import org.eclipse.cdt.core.model.ICElement; |
| import org.eclipse.cdt.core.model.ICProject; |
| import org.eclipse.cdt.core.model.util.CDTListComparator; |
| import org.eclipse.cdt.core.settings.model.CConfigurationStatus; |
| import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; |
| import org.eclipse.cdt.core.settings.model.ICFolderDescription; |
| import org.eclipse.cdt.core.settings.model.ICMultiItemsHolder; |
| import org.eclipse.cdt.core.settings.model.ICProjectDescription; |
| import org.eclipse.cdt.core.settings.model.ICResourceDescription; |
| import org.eclipse.cdt.core.settings.model.MultiItemsHolder; |
| import org.eclipse.cdt.internal.ui.dialogs.OptionalMessageDialog; |
| import org.eclipse.cdt.internal.ui.newui.Messages; |
| import org.eclipse.cdt.ui.CDTSharedImages; |
| import org.eclipse.cdt.ui.CUIPlugin; |
| import org.eclipse.cdt.ui.PreferenceConstants; |
| import org.eclipse.cdt.utils.ui.controls.ControlFactory; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExtension; |
| import org.eclipse.core.runtime.IExtensionPoint; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.QualifiedName; |
| import org.eclipse.help.HelpSystem; |
| import org.eclipse.help.IContext; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.dialogs.ProgressMonitorDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.preference.IPreferencePageContainer; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.resource.ResourceLocator; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.layout.FillLayout; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Combo; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Group; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.MessageBox; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.TabFolder; |
| import org.eclipse.swt.widgets.TabItem; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPartReference; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation; |
| import org.eclipse.ui.dialogs.PropertyPage; |
| |
| /** |
| * It is a parent for all standard CDT property pages |
| * in new CDT model. |
| * |
| * Although it is enough for new page to implement |
| * "IWorkbenchPropertyPage" interface, it would be |
| * better to extend it from "AbstractPage". |
| * |
| * In this case, we'll able to use: |
| * - dynamic tabs support via cPropertyTab extension point |
| * - a lot of utility methods: see ICPropertyProvider interface |
| * - mechanism of messages sent to all pages and all tabs in them |
| * |
| * In fact, descendants of AbstractPage have to implement |
| * the only method: |
| * protected boolean isSingle(); |
| * It it returns false, current page can contain multiple tabs |
| * (obtained through "cPropertyTab" extension point). |
| * If it returns true, only one content tab is possible. If |
| * more than 1 tabs refer to this pas as a parent, only 1st |
| * one would be taken into account, others will be ignored. |
| */ |
| public abstract class AbstractPage extends PropertyPage implements IPreferencePageContainer, // dynamic pages |
| ICPropertyProvider2 // utility methods for tabs |
| { |
| private static ICResourceDescription resd = null; |
| private static ICConfigurationDescription[] cfgDescs = null; |
| private static ICConfigurationDescription lastSelectedCfg = null; |
| private static ICConfigurationDescription[] multiCfgs = null; // selected multi cfg |
| // tabs |
| private static final String EXTENSION_POINT_ID = "org.eclipse.cdt.ui.cPropertyTab"; //$NON-NLS-1$ |
| private static final String ELEMENT_NAME = "tab"; //$NON-NLS-1$ |
| private static final String CLASS_NAME = "class"; //$NON-NLS-1$ |
| private static final String PARENT_NAME = "parent"; //$NON-NLS-1$ |
| private static final String IMAGE_NAME = "icon"; //$NON-NLS-1$ |
| private static final String TIP_NAME = "tooltip"; //$NON-NLS-1$ |
| private static final String TEXT_NAME = "name"; //$NON-NLS-1$ |
| private static final String WEIGHT_NAME = "weight"; //$NON-NLS-1$ |
| private static final String HELPID_NAME = "helpId"; //$NON-NLS-1$ |
| |
| private static final Object NOT_NULL = new Object(); |
| public static final String EMPTY_STR = ""; //$NON-NLS-1$ |
| |
| private static final int SAVE_MODE_OK = 1; |
| private static final int SAVE_MODE_APPLY = 2; |
| private static final int SAVE_MODE_APPLYOK = 3; |
| |
| private static final String PREF_ASK_REINDEX = "askReindex"; //$NON-NLS-1$ |
| |
| private Map<URL, Image> loadedIcons = new HashMap<>(); |
| private static Map<Class<? extends AbstractPage>, Class<? extends ICPropertyTab>> recentTabs = new HashMap<>(); |
| |
| private final Image IMG_WARN = CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_REFACTORING_WARNING); |
| /* |
| * Dialog widgets |
| */ |
| private Combo configSelector; |
| private Button manageButton; |
| private Button excludeFromBuildCheck; |
| private Label errIcon; |
| private Text errMessage; |
| private Composite errPane; |
| private Composite parentComposite; |
| /* |
| * Bookeeping variables |
| */ |
| protected boolean noContentOnPage = false; |
| protected boolean displayedConfig = false; |
| protected IResource internalElement = null; |
| protected boolean isProject = false; |
| protected boolean isFolder = false; |
| protected boolean isFile = false; |
| |
| // tabs |
| protected TabFolder folder; |
| protected ArrayList<InternalTab> itabs = new ArrayList<>(); |
| protected ICPropertyTab currentTab; |
| |
| private static boolean isNewOpening = true; |
| |
| protected class InternalTab { |
| Composite comp; |
| String text; |
| String tip; |
| Image image; |
| ICPropertyTab tab; |
| |
| InternalTab(Composite _comp, String _text, Image _image, ICPropertyTab _tab, String _tip) { |
| comp = _comp; |
| text = _text; |
| image = _image; |
| tab = _tab; |
| tip = _tip; |
| } |
| |
| public TabItem createOn(TabFolder f) { |
| if (tab.canBeVisible()) { |
| TabItem ti = new TabItem(f, SWT.NONE); |
| ti.setText(text); |
| if (tip != null) |
| ti.setToolTipText(tip); |
| if (image != null) |
| ti.setImage(image); |
| ti.setControl(comp); |
| ti.setData(tab); |
| return ti; |
| } |
| return null; |
| } |
| } |
| |
| /** |
| * Default constructor |
| */ |
| public AbstractPage() { |
| if (CDTPropertyManager.getPagesCount() == 0) { |
| cfgDescs = null; |
| lastSelectedCfg = null; |
| multiCfgs = null; |
| } |
| } |
| |
| @Override |
| protected Control createContents(Composite parent) { |
| // Create the container we return to the property page editor |
| Composite composite = new Composite(parent, SWT.NULL); |
| composite.setFont(parent.getFont()); |
| GridLayout compositeLayout = new GridLayout(); |
| compositeLayout.numColumns = 1; |
| compositeLayout.marginHeight = 0; |
| compositeLayout.marginWidth = 0; |
| composite.setLayout(compositeLayout); |
| |
| String s = null; |
| if (!checkElement()) { |
| s = Messages.AbstractPage_0; |
| } else if (!isApplicable()) { |
| return null; |
| } else if (!isCDTProject(getProject())) { |
| s = Messages.AbstractPage_2; |
| } |
| |
| if (s == null) { |
| contentForCDT(composite); |
| return composite; |
| } |
| |
| // no contents |
| Label label = new Label(composite, SWT.LEFT); |
| label.setText(s); |
| label.setFont(composite.getFont()); |
| noContentOnPage = true; |
| noDefaultAndApplyButton(); |
| return composite; |
| } |
| |
| protected void contentForCDT(Composite composite) { |
| GridData gd; |
| |
| if (showsConfig()) { |
| // Add a config selection area |
| Group configGroup = ControlFactory.createGroup(composite, EMPTY_STR, 1); |
| gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL); |
| gd.grabExcessHorizontalSpace = true; |
| gd.widthHint = 150; |
| configGroup.setLayoutData(gd); |
| configGroup.setLayout(new GridLayout(3, false)); |
| |
| Label configLabel = new Label(configGroup, SWT.NONE); |
| configLabel.setText(Messages.AbstractPage_6); |
| configLabel.setLayoutData(new GridData(GridData.BEGINNING)); |
| |
| configSelector = new Combo(configGroup, SWT.READ_ONLY | SWT.DROP_DOWN); |
| configSelector.addListener(SWT.Selection, new Listener() { |
| @Override |
| public void handleEvent(Event e) { |
| handleConfigSelection(); |
| } |
| }); |
| gd = new GridData(GridData.FILL_BOTH); |
| configSelector.setLayoutData(gd); |
| |
| if (!CDTPrefUtil.getBool(CDTPrefUtil.KEY_NOMNG)) { |
| manageButton = new Button(configGroup, SWT.PUSH); |
| manageButton.setText(Messages.AbstractPage_12); |
| gd = new GridData(GridData.END); |
| gd.minimumWidth = 150; |
| manageButton.setLayoutData(gd); |
| manageButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| IProject[] obs = new IProject[] { getProject() }; |
| IConfigManager cm = ManageConfigSelector.getManager(obs); |
| if (cm != null && cm.manage(obs, false)) { |
| cfgDescs = null; |
| populateConfigurations(); |
| } |
| } |
| }); |
| } else { // dummy object to avoid breaking layout |
| new Label(configGroup, SWT.NONE).setLayoutData(new GridData(GridData.END)); |
| } |
| |
| errPane = new Composite(configGroup, SWT.NONE); |
| gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.horizontalSpan = 3; |
| errPane.setLayoutData(gd); |
| GridLayout gl = new GridLayout(2, false); |
| gl.marginHeight = 0; |
| gl.marginWidth = 0; |
| gl.verticalSpacing = 0; |
| gl.horizontalSpacing = 0; |
| errPane.setLayout(gl); |
| |
| errIcon = new Label(errPane, SWT.LEFT); |
| errIcon.setLayoutData(new GridData(GridData.BEGINNING)); |
| errIcon.setImage(IMG_WARN); |
| |
| errMessage = new Text(errPane, SWT.LEFT | SWT.READ_ONLY); |
| errMessage.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| |
| if (isForFolder() || isForFile()) { |
| excludeFromBuildCheck = new Button(configGroup, SWT.CHECK); |
| excludeFromBuildCheck.setText(Messages.AbstractPage_7); |
| gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.horizontalSpan = 3; |
| excludeFromBuildCheck.setLayoutData(gd); |
| excludeFromBuildCheck.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| ICResourceDescription rcDescription = getResDesc(); |
| rcDescription.setExcluded(excludeFromBuildCheck.getSelection()); |
| if (currentTab instanceof AbstractCPropertyTab) { |
| ((AbstractCPropertyTab) currentTab).updateData(rcDescription); |
| } |
| } |
| }); |
| } |
| } |
| |
| // Update the contents of the configuration widget |
| populateConfigurations(); |
| if (excludeFromBuildCheck != null) { |
| excludeFromBuildCheck.setSelection(getResDesc().isExcluded()); |
| } |
| // Create the Specific objects for each page |
| createWidgets(composite); |
| } |
| |
| public void createWidgets(Composite c) { |
| GridData gd; |
| parentComposite = new Composite(c, SWT.NONE); |
| parentComposite.setLayoutData(gd = new GridData(GridData.FILL_BOTH)); |
| gd.widthHint = 600; |
| itabs.clear(); |
| if (!isSingle()) { |
| parentComposite.setLayout(new FillLayout()); |
| folder = new TabFolder(parentComposite, SWT.NONE); |
| // folder.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY)); |
| } |
| loadExtensionsSynchronized(parentComposite); |
| |
| // Set listener after data load, to avoid firing |
| // selection event on not-initialized tab items |
| if (folder != null) { |
| folder.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(org.eclipse.swt.events.SelectionEvent event) { |
| if (folder.getSelection().length > 0) { |
| updateSelectedTab(); |
| } |
| } |
| }); |
| if (folder.getItemCount() > 0) { |
| int selectedTab = 0; |
| Class<? extends ICPropertyTab> recentTab = recentTabs.get(getClass()); |
| if (recentTab != null) { |
| TabItem[] tabs = folder.getItems(); |
| for (int i = 0; i < tabs.length; i++) { |
| TabItem control = tabs[i]; |
| if (recentTab.isInstance(control.getData())) { |
| selectedTab = i; |
| break; |
| } |
| } |
| } |
| folder.setSelection(selectedTab); |
| updateSelectedTab(); |
| } |
| } |
| } |
| |
| private void updateSelectedTab() { |
| ICPropertyTab newTab = (ICPropertyTab) folder.getSelection()[0].getData(); |
| if (newTab != null && currentTab != newTab) { |
| recentTabs.put(getClass(), newTab.getClass()); |
| if (currentTab != null) |
| currentTab.handleTabEvent(ICPropertyTab.VISIBLE, null); |
| currentTab = newTab; |
| currentTab.handleTabEvent(ICPropertyTab.VISIBLE, NOT_NULL); |
| } |
| } |
| |
| /** |
| * |
| */ |
| @Override |
| public IProject getProject() { |
| Object element = getElement(); |
| if (element != null) { |
| if (element instanceof IFile || element instanceof IProject || element instanceof IFolder) { |
| IResource f = (IResource) element; |
| return f.getProject(); |
| } else if (element instanceof ICProject) |
| return ((ICProject) element).getProject(); |
| } |
| return null; |
| } |
| |
| /* |
| * Event Handlers |
| */ |
| private void handleConfigSelection() { |
| // If there is nothing in config selection widget just bail |
| if (configSelector.getItemCount() == 0) |
| return; |
| int selectionIndex = configSelector.getSelectionIndex(); |
| if (selectionIndex == -1) |
| return; |
| if (cfgDescs == null || cfgDescs.length == 0) |
| return; |
| |
| // Check if the user has selected the "all / multiple" configuration |
| if (selectionIndex >= cfgDescs.length) { |
| if (selectionIndex == cfgDescs.length) { // all |
| multiCfgs = cfgDescs; |
| } else { // multiple |
| // Check previous state of variables figuring out if need to pop up selection dialog |
| // areCfgsStillThere() covers deletions by a user in Manage Configurations dialog |
| boolean enterMultiCfgsDialog = (multiCfgs == null) || (multiCfgs == cfgDescs) |
| || !areCfgsStillThere(multiCfgs); |
| if (enterMultiCfgsDialog) { |
| ICConfigurationDescription[] mcfgs = ConfigMultiSelectionDialog.select(cfgDescs, |
| parentComposite.getShell()); |
| if (mcfgs == null || mcfgs.length == 0) { |
| // return back to previous selection |
| int cfgIndex = -1; |
| if (multiCfgs == cfgDescs) { // return to choice "All" |
| cfgIndex = cfgDescs.length; |
| } else { |
| cfgIndex = getCfgIndex(lastSelectedCfg); |
| } |
| configSelector.select(cfgIndex); |
| return; |
| } |
| multiCfgs = mcfgs; |
| } |
| |
| } |
| lastSelectedCfg = null; |
| |
| cfgChanged(MultiItemsHolder.createCDescription(multiCfgs)); |
| return; |
| } |
| multiCfgs = null; |
| |
| String id1 = getResDesc() == null ? null : getResDesc().getId(); |
| lastSelectedCfg = cfgDescs[selectionIndex]; |
| String id2 = lastSelectedCfg.getId(); |
| if (id2 != null && !id2.equals(id1)) { |
| cfgChanged(lastSelectedCfg); |
| } |
| } |
| |
| /** |
| * Find index of configuration description in the internal array of |
| * configuration descriptions. |
| * |
| * @param cfgd |
| * @return index of found configuration description or index of active |
| * configuration. |
| */ |
| private static int getCfgIndex(ICConfigurationDescription cfgd) { |
| int index = 0; |
| for (int i = 0; i < cfgDescs.length; ++i) { |
| if (cfgd != null) { |
| if (cfgd.getId().equals(cfgDescs[i].getId())) { |
| return i; |
| } |
| } else if (cfgDescs[i].isActive()) { |
| index = i; |
| } |
| } |
| return index; |
| } |
| |
| /** |
| * Find index of active configuration description in the internal array of |
| * configuration descriptions. |
| * |
| * @return index of active configuration description. |
| */ |
| private static int getActiveCfgIndex() { |
| return getCfgIndex(null); |
| } |
| |
| /** |
| * Check if all configuration descriptions are present in the internal array of |
| * configuration descriptions. |
| * @param cfgs |
| * @return true if all present, false otherwise |
| */ |
| private static boolean areCfgsStillThere(ICConfigurationDescription[] cfgs) { |
| if (cfgs == null || cfgDescs == null) |
| return false; |
| |
| for (ICConfigurationDescription multiCfg : cfgs) { |
| boolean foundOne = false; |
| for (ICConfigurationDescription cfgDesc : cfgDescs) { |
| if (multiCfg.getId().equals(cfgDesc.getId())) { |
| foundOne = true; |
| break; |
| } |
| } |
| if (!foundOne) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| @Override |
| public boolean performCancel() { |
| if (!noContentOnPage && displayedConfig) |
| forEach(ICPropertyTab.CANCEL); |
| |
| CDTPropertyManager.performCancel(this); |
| |
| return true; |
| } |
| |
| @Override |
| public void performDefaults() { |
| if (!noContentOnPage && displayedConfig) |
| forEach(ICPropertyTab.DEFAULTS); |
| } |
| |
| @Override |
| public void performApply() { |
| performSave(SAVE_MODE_APPLY); |
| } |
| |
| /** |
| * There are 2 ways to perform OK for CDT property pages. |
| * 1st (default): |
| * All pages use the same editable copy of ICProjectDescription. |
| * When OK occurs, this object is simply set. |
| * |
| * 2nd: |
| * When OK occurs, each page must copy its data to new instance |
| * of ICProjectDescription, like it occurs during Apply event. |
| * It allows to avoid collisions with other property pages, |
| * which do not share ICProjectDescription instance. |
| * But some changes may be saved wrong if they are affected |
| * by data from another property pages (Discovery options etc). |
| |
| * To enable 2nd mode, just create the following file: |
| * <workspace>/.metadata/.plugins/org.eclipse.cdt.ui/apply_mode |
| */ |
| |
| @Override |
| public boolean performOk() { |
| File f = CUIPlugin.getDefault().getStateLocation().append("apply_mode").toFile(); //$NON-NLS-1$ |
| if (f.exists()) |
| return performSave(SAVE_MODE_APPLYOK); |
| return performSave(SAVE_MODE_OK); |
| |
| } |
| |
| /** |
| * Searches in the prj for the config description with the same ID as for given cfg. |
| * If there's no such cfgd, it will be created. |
| * |
| * @param prj - project description where we'll search (or create) config description |
| * @param cfg - config description belonging to another project description, |
| * it is a sample for search and base for possile creation |
| * of resulting configuration description. |
| * |
| * @return the configuration description (found or created) or null in case of error |
| */ |
| private ICConfigurationDescription findCfg(ICProjectDescription prj, ICConfigurationDescription cfg) { |
| String id = cfg.getId(); |
| // find config with the same ID as original one |
| ICConfigurationDescription c = prj.getConfigurationById(id); |
| // if there's no cfg found, try to create it |
| if (c == null) { |
| try { |
| c = prj.createConfiguration(id, cfg.getName(), cfg); |
| c.setDescription(cfg.getDescription()); |
| } catch (CoreException e) { |
| /* do nothing: c is already null */ |
| } |
| } |
| // if creation failed, report an error and return null |
| if (c == null) { |
| MessageBox mb = new MessageBox(getShell()); |
| mb.setMessage(Messages.AbstractPage_3); |
| mb.open(); |
| } |
| return c; |
| } |
| |
| /** |
| * The same code used to perform OK and Apply |
| */ |
| private boolean performSave(int mode) { |
| final int finalMode = mode; |
| if (noContentOnPage || !displayedConfig) |
| return true; |
| if ((mode == SAVE_MODE_OK || mode == SAVE_MODE_APPLYOK) && CDTPropertyManager.isSaveDone()) |
| return true; // do not duplicate |
| |
| final boolean needs = (mode != SAVE_MODE_OK); |
| final ICProjectDescription local_prjd = needs ? CoreModel.getDefault().getProjectDescription(getProject()) |
| : null; |
| |
| ICResourceDescription lc = null; |
| |
| if (needs) { |
| if (isMultiCfg()) { |
| ICResourceDescription[] rds = (ICResourceDescription[]) ((ICMultiItemsHolder) resd).getItems(); |
| for (int i = 0; i < rds.length; i++) { |
| ICConfigurationDescription c = local_prjd.getConfigurationById(rds[i].getConfiguration().getId()); |
| rds[i] = getResDesc(c); |
| } |
| lc = MultiItemsHolder.createRDescription(rds); |
| } else { |
| ICConfigurationDescription c = findCfg(local_prjd, resd.getConfiguration()); |
| if (c == null) |
| return false; // cannot save: no cfg found |
| lc = getResDesc(c); |
| } |
| } |
| final ICResourceDescription local_cfgd = lc; |
| |
| IRunnableWithProgress runnable = new IRunnableWithProgress() { |
| |
| private void sendOK() { |
| for (int j = 0; j < CDTPropertyManager.getPagesCount(); j++) { |
| Object p = CDTPropertyManager.getPage(j); |
| if (p != null && p instanceof AbstractPage) { |
| AbstractPage ap = (AbstractPage) p; |
| if (ap.displayedConfig) |
| ap.forEach(ICPropertyTab.OK, null); |
| } |
| } |
| } |
| |
| @Override |
| public void run(IProgressMonitor monitor) { |
| // ask all tabs to store changes in cfg |
| switch (finalMode) { |
| case SAVE_MODE_APPLYOK: |
| sendOK(); |
| ICConfigurationDescription[] olds = CDTPropertyManager |
| .getProjectDescription(AbstractPage.this, getProject()).getConfigurations(); |
| for (ICConfigurationDescription old : olds) { |
| resd = getResDesc(old); |
| ICResourceDescription r = getResDesc(local_prjd.getConfigurationById(old.getId())); |
| for (int j = 0; j < CDTPropertyManager.getPagesCount(); j++) { |
| Object p = CDTPropertyManager.getPage(j); |
| if (p != null && p instanceof AbstractPage) { |
| AbstractPage ap = (AbstractPage) p; |
| if (ap.displayedConfig) { |
| ap.forEach(ICPropertyTab.UPDATE, resd); |
| ap.forEach(ICPropertyTab.APPLY, r); |
| } |
| } |
| } |
| } |
| break; |
| case SAVE_MODE_APPLY: |
| forEach(ICPropertyTab.APPLY, local_cfgd); |
| break; |
| case SAVE_MODE_OK: |
| sendOK(); |
| break; |
| } // end switch |
| try { |
| if (needs) // |
| CoreModel.getDefault().setProjectDescription(getProject(), local_prjd); |
| else |
| CDTPropertyManager.performOk(AbstractPage.this); |
| } catch (CoreException e) { |
| CUIPlugin.logError(Messages.AbstractPage_11 + e.getLocalizedMessage()); |
| } |
| updateViews(internalElement); |
| } |
| }; |
| IRunnableWithProgress op = new WorkspaceModifyDelegatingOperation(runnable); |
| try { |
| PlatformUI.getWorkbench().getProgressService().runInUI(new ProgressMonitorDialog(getShell()), op, |
| ResourcesPlugin.getWorkspace().getRoot()); |
| } catch (InvocationTargetException e) { |
| Throwable e1 = e.getTargetException(); |
| CUIPlugin.errorDialog(getShell(), Messages.AbstractPage_8, Messages.AbstractPage_9, e1, true); |
| return false; |
| } catch (InterruptedException e) { |
| // IProgressService.runInUI(...) misuses this exception to signal that the operation was canceled. |
| return false; |
| } |
| |
| final boolean rebuildIndex = isIndexerAffected(); |
| if (rebuildIndex) |
| rebuildIndex(); |
| return true; |
| } |
| |
| private boolean isIndexerAffected() { |
| ICProjectDescription desc = CoreModel.getDefault().getProjectDescription(getProject(), false); |
| if (desc == null || desc.isCdtProjectCreating()) |
| return false; |
| |
| Iterator<InternalTab> it = itabs.iterator(); |
| while (it.hasNext()) { |
| InternalTab tab = it.next(); |
| if (tab != null) { |
| ICPropertyTab tabtab = tab.tab; |
| if (tabtab instanceof AbstractCPropertyTab && ((AbstractCPropertyTab) tabtab).isIndexerAffected()) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| private void rebuildIndex() { |
| final Shell shell = getShell(); |
| final String title = getTitle(); |
| final String msg = Messages.AbstractPage_rebuildIndex_question; |
| int result = OptionalMessageDialog.open(PREF_ASK_REINDEX, shell, title, null /* default image */, msg, |
| MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 0); |
| if (result == OptionalMessageDialog.NOT_SHOWN) { |
| result = OptionalMessageDialog.getDialogDetail(PREF_ASK_REINDEX); |
| } else if (result != SWT.DEFAULT) { |
| OptionalMessageDialog.setDialogDetail(PREF_ASK_REINDEX, result); |
| } |
| if (result == 0) { // first button |
| final IProject project = getProject(); |
| CCorePlugin.getIndexManager().reindex(CoreModel.getDefault().create(project)); |
| } |
| } |
| |
| private void populateConfigurations() { |
| IProject prj = getProject(); |
| // Do nothing in case of Preferences page. |
| if (prj == null) |
| return; |
| |
| // Do not re-read if list already created by another page |
| if (cfgDescs == null) { |
| ICProjectDescription pDesc = CDTPropertyManager.getProjectDescription(this, prj); |
| cfgDescs = (pDesc == null) ? null : pDesc.getConfigurations(); |
| if (cfgDescs == null || cfgDescs.length == 0) |
| return; |
| Arrays.sort(cfgDescs, CDTListComparator.getInstance()); |
| |
| } else { |
| if (cfgDescs.length == 0) |
| return; |
| // just register in CDTPropertyManager; |
| CDTPropertyManager.getProjectDescription(this, prj); |
| } |
| |
| // Do nothing if widget not created yet. |
| if (configSelector == null) { |
| lastSelectedCfg = cfgDescs[getActiveCfgIndex()]; |
| cfgChanged(lastSelectedCfg); |
| return; |
| } |
| |
| // Clear and replace the contents of the selector widget |
| configSelector.removeAll(); |
| for (int i = 0; i < cfgDescs.length; ++i) { |
| String name = cfgDescs[i].getName(); |
| if (cfgDescs[i].isActive()) { |
| name = name + " " + Messages.AbstractPage_16; //$NON-NLS-1$ |
| } |
| configSelector.add(name); |
| } |
| |
| // Ensure that the last selected config is selected by default |
| int cfgIndex = getCfgIndex(lastSelectedCfg); |
| |
| // "All cfgs" - shown if at least 2 cfgs available |
| if (cfgDescs.length > 1) { |
| configSelector.add(Messages.AbstractPage_4); |
| if (multiCfgs == cfgDescs) { |
| cfgIndex = cfgDescs.length; |
| } |
| } |
| // "Multi cfgs" - shown if at least 3 cfgs available |
| if (cfgDescs.length > 2) { |
| configSelector.add(Messages.AbstractPage_5); |
| if (multiCfgs != null && multiCfgs != cfgDescs) { |
| cfgIndex = cfgDescs.length + 1; |
| } |
| } |
| |
| if (cfgIndex < 0) { |
| cfgIndex = getActiveCfgIndex(); |
| } |
| |
| configSelector.select(cfgIndex); |
| handleConfigSelection(); |
| } |
| |
| @Override |
| public void updateButtons() { |
| } |
| |
| @Override |
| public void updateMessage() { |
| } |
| |
| @Override |
| public void updateTitle() { |
| } |
| |
| @Override |
| public void updateContainer() { |
| } |
| |
| @Override |
| public boolean isValid() { |
| updateContainer(); |
| return super.isValid(); |
| } |
| |
| @Override |
| public void setVisible(boolean visible) { |
| super.setVisible(visible); |
| if (visible) { |
| handleResize(true); |
| displayedConfig = true; |
| if (excludeFromBuildCheck != null && resd != null) |
| excludeFromBuildCheck.setSelection(resd.isExcluded()); |
| populateConfigurations(); |
| } |
| |
| if (itabs.size() < 1) |
| return; |
| |
| if (currentTab == null && folder.getItemCount() > 0) { |
| Object ob = folder.getItem(0).getData(); |
| currentTab = (ICPropertyTab) ob; |
| } |
| if (currentTab != null) |
| currentTab.handleTabEvent(ICPropertyTab.VISIBLE, visible ? NOT_NULL : null); |
| } |
| |
| protected void handleResize(boolean visible) { |
| if (!getShell().isVisible()) { |
| return; // do not resize shell before its open, it will screw up shell positioning |
| } |
| if (visible && !isNewOpening) |
| return; // do not duplicate |
| if (visible) |
| isNewOpening = false; |
| |
| int saveMode = CDTPrefUtil.getInt(CDTPrefUtil.KEY_POSSAVE); |
| if (saveMode == CDTPrefUtil.POSITION_SAVE_NONE) |
| return; |
| |
| if (internalElement == null && !checkElement()) |
| return; // not initialized. Do not process |
| IProject prj = getProject(); |
| if (prj == null) |
| return; // preferences. Do not process. |
| QualifiedName WIDTH = new QualifiedName(prj.getName(), ".property.page.width"); //$NON-NLS-1$ |
| QualifiedName HEIGHT = new QualifiedName(prj.getName(), ".property.page.height"); //$NON-NLS-1$ |
| QualifiedName XKEY = new QualifiedName(prj.getName(), ".property.page.x"); //$NON-NLS-1$ |
| QualifiedName YKEY = new QualifiedName(prj.getName(), ".property.page.y"); //$NON-NLS-1$ |
| Rectangle r = getShell().getBounds(); |
| try { |
| if (visible) { |
| String w = prj.getPersistentProperty(WIDTH); |
| String h = prj.getPersistentProperty(HEIGHT); |
| if (w != null) |
| r.width = Integer.parseInt(w); |
| if (h != null) |
| r.height = Integer.parseInt(h); |
| if (saveMode == CDTPrefUtil.POSITION_SAVE_BOTH) { |
| String x = prj.getPersistentProperty(XKEY); |
| String y = prj.getPersistentProperty(YKEY); |
| if (x != null) |
| r.x = Integer.parseInt(x); |
| if (y != null) |
| r.y = Integer.parseInt(y); |
| } |
| getShell().setBounds(r); |
| } else { |
| prj.setPersistentProperty(WIDTH, String.valueOf(r.width)); |
| prj.setPersistentProperty(HEIGHT, String.valueOf(r.height)); |
| prj.setPersistentProperty(XKEY, String.valueOf(r.x)); |
| prj.setPersistentProperty(YKEY, String.valueOf(r.y)); |
| } |
| } catch (CoreException e) { |
| } |
| } |
| |
| @Override |
| public IPreferenceStore getPreferenceStore() { |
| return CUIPlugin.getDefault().getPreferenceStore(); |
| } |
| |
| /** |
| * @deprecated, use {@link #getPreferenceStore()}, instead. |
| */ |
| @Override |
| @Deprecated |
| public org.eclipse.core.runtime.Preferences getPreferences() { |
| return CUIPlugin.getDefault().getPluginPreferences(); |
| } |
| |
| @Override |
| public void enableConfigSelection(boolean enable) { |
| if (configSelector != null) |
| configSelector.setEnabled(enable); |
| if (manageButton != null) |
| manageButton.setEnabled(enable); |
| } |
| |
| /** |
| * Returns configuration descriptions for given project |
| */ |
| @Override |
| public ICConfigurationDescription[] getCfgsReadOnly(IProject p) { |
| ICProjectDescription prjd = CoreModel.getDefault().getProjectDescription(p, false); |
| if (prjd != null) |
| return prjd.getConfigurations(); |
| return null; |
| } |
| |
| /** |
| * Returns loaded configuration descriptions for current project |
| */ |
| @Override |
| public ICConfigurationDescription[] getCfgsEditable() { |
| return cfgDescs; |
| } |
| |
| /** Checks whether project is new CDT project |
| * |
| * @param p - project to check |
| * @returns true if it's new-style project. |
| */ |
| public static boolean isCDTPrj(IProject p) { |
| ICProjectDescription prjd = CoreModel.getDefault().getProjectDescription(p, false); |
| if (prjd == null) |
| return false; |
| ICConfigurationDescription[] cfgs = prjd.getConfigurations(); |
| return (cfgs != null && cfgs.length > 0); |
| } |
| |
| @Override |
| public boolean isCDTProject(IProject p) { |
| return isCDTPrj(p); |
| } |
| |
| @Override |
| public ICResourceDescription getResDesc() { |
| if (resd == null) { |
| if (cfgDescs == null) { |
| populateConfigurations(); |
| } |
| if (lastSelectedCfg != null) { |
| resd = getResDesc(lastSelectedCfg); |
| } |
| } |
| return resd; |
| } |
| |
| @Override |
| public ICResourceDescription getResDesc(ICConfigurationDescription cf) { |
| IAdaptable ad = getElement(); |
| |
| if (isForProject()) |
| return cf.getRootFolderDescription(); |
| ICResourceDescription out = null; |
| IResource res = (IResource) ad; |
| IPath p = res.getProjectRelativePath(); |
| if (isForFolder() || isForFile()) { |
| if (cf instanceof ICMultiItemsHolder) { |
| out = cf.getResourceDescription(p, isForFolder()); // sic ! |
| } else { |
| out = cf.getResourceDescription(p, false); |
| if (!p.equals(out.getPath())) { |
| try { |
| if (isForFolder()) |
| out = cf.createFolderDescription(p, (ICFolderDescription) out); |
| else |
| out = cf.createFileDescription(p, out); |
| } catch (CoreException e) { |
| System.out.println(Messages.AbstractPage_10 + p.toOSString() + "\n" + e.getLocalizedMessage()); //$NON-NLS-1$ |
| } |
| } |
| } |
| } |
| return out; |
| } |
| |
| protected void cfgChanged(ICConfigurationDescription _cfgd) { |
| CConfigurationStatus st = _cfgd.getConfigurationStatus(); |
| if (st.getCode() == CConfigurationStatus.TOOLCHAIN_NOT_SUPPORTED) { |
| // Re-check, maybe user got the problem fixed |
| st = _cfgd.getConfigurationData().getStatus(); |
| } |
| if (errPane != null && errMessage != null) { |
| if (st.isOK()) { |
| errPane.setVisible(false); |
| } else { |
| errMessage.setText(st.getMessage()); |
| errPane.setVisible(true); |
| } |
| } |
| |
| resd = getResDesc(_cfgd); |
| |
| if (excludeFromBuildCheck != null) { |
| excludeFromBuildCheck.setEnabled(resd.canExclude(!resd.isExcluded())); |
| excludeFromBuildCheck.setSelection(resd.isExcluded()); |
| } |
| int x = CDTPropertyManager.getPagesCount(); |
| for (int i = 0; i < x; i++) { |
| Object p = CDTPropertyManager.getPage(i); |
| if (p == null || !(p instanceof AbstractPage)) |
| continue; |
| AbstractPage ap = (AbstractPage) p; |
| if (ap.displayedConfig) |
| ap.forEach(ICPropertyTab.UPDATE, getResDesc()); |
| } |
| } |
| |
| @Override |
| public void dispose() { |
| // Dispose the tabs |
| if (displayedConfig) |
| forEach(ICPropertyTab.DISPOSE); |
| // Dispose any loaded images |
| for (Image img : loadedIcons.values()) |
| img.dispose(); |
| loadedIcons.clear(); |
| |
| if (!isNewOpening) |
| handleResize(false); // save page size |
| isNewOpening = true; |
| // Remove this page from the property manager |
| CDTPropertyManager.remove(this); |
| // clear static variables |
| if (CDTPropertyManager.getPagesCount() == 0) { |
| resd = null; |
| cfgDescs = null; |
| } |
| } |
| |
| /** |
| * The only method to be redefined in descendants |
| * @return |
| * true if single page is required |
| * false if multiple pages are possible |
| */ |
| abstract protected boolean isSingle(); |
| |
| /** |
| * Defines whether the configurations control is shown or not. |
| * Subclasses may override this. |
| * @return true, if the configurations control should be shown (default); false otherwise |
| */ |
| protected boolean showsConfig() { |
| return true; |
| } |
| |
| /** |
| * Apply specified method to all tabs |
| */ |
| protected void forEach(int m) { |
| forEach(m, null); |
| } |
| |
| protected void forEach(int m, Object pars) { |
| Iterator<InternalTab> it = itabs.iterator(); |
| while (it.hasNext()) { |
| InternalTab tab = it.next(); |
| if (tab != null) |
| tab.tab.handleTabEvent(m, pars); |
| } |
| } |
| |
| // redefine page width |
| /* |
| public Point computeSize() { |
| Point p = super.computeSize(); |
| if (p.x > MAX_WIDTH) p.x = MAX_WIDTH; |
| return p; |
| } |
| */ |
| |
| public static String getWeight(IConfigurationElement e) { |
| String s = e.getAttribute(WEIGHT_NAME); |
| return (s == null) ? EMPTY_STR : s; |
| } |
| |
| private synchronized void loadExtensionsSynchronized(Composite parent) { |
| // Get the extensions |
| IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(EXTENSION_POINT_ID); |
| if (extensionPoint == null) |
| return; |
| IExtension[] extensions = extensionPoint.getExtensions(); |
| if (extensions == null) |
| return; |
| |
| List<IConfigurationElement> elements = new ArrayList<>(); |
| for (IExtension ext : extensions) |
| elements.addAll(Arrays.asList(ext.getConfigurationElements())); |
| Collections.sort(elements, CDTUIListComparator.getInstance()); |
| |
| for (IConfigurationElement element : elements) { |
| if (element.getName().equals(ELEMENT_NAME)) { |
| if (loadTab(element, parent)) |
| return; |
| } else { |
| System.out.println(Messages.AbstractPage_13 + element.getName()); |
| } |
| } |
| } |
| |
| /** |
| * |
| * @param element |
| * @param parent |
| * @return true if we should exit (no more loadings) |
| * false if we should continue extensions scan. |
| * @throws BuildException |
| */ |
| private boolean loadTab(IConfigurationElement element, Composite parent) { |
| // MBSCustomPageData currentPageData; |
| // Check whether it's our tab |
| if (!this.getClass().getName().equals(element.getAttribute(PARENT_NAME))) |
| return false; |
| |
| ICPropertyTab page = null; |
| try { |
| page = (ICPropertyTab) element.createExecutableExtension(CLASS_NAME); |
| } catch (CoreException e) { |
| System.out.println(Messages.AbstractPage_14 + e.getLocalizedMessage()); |
| return false; |
| } |
| if (page == null) |
| return false; |
| |
| String helpId = element.getAttribute(HELPID_NAME); |
| if (helpId != null && helpId.length() > 0 |
| // TODO: in next version: refer to ICPropertyTab instead of AbstractCPropertyTab |
| && page instanceof AbstractCPropertyTab) { |
| ((AbstractCPropertyTab) page).setHelpContextId(helpId); |
| } |
| |
| Image _img = getIcon(element); |
| if (_img != null) |
| page.handleTabEvent(ICPropertyTab.SET_ICON, _img); |
| |
| if (isSingle()) { |
| // note that name, image and tooltip |
| // are ignored for single page. |
| page.createControls(parent, this); |
| InternalTab itab = new InternalTab(parent, EMPTY_STR, null, page, null); |
| itabs.add(itab); |
| currentTab = page; |
| return true; // don't load other tabs |
| } |
| String _name = element.getAttribute(TEXT_NAME); |
| String _tip = element.getAttribute(TIP_NAME); |
| |
| Composite _comp = new Composite(folder, SWT.NONE); |
| page.createControls(_comp, this); |
| InternalTab itab = new InternalTab(_comp, _name, _img, page, _tip); |
| itab.createOn(folder); |
| itabs.add(itab); |
| return false; |
| } |
| |
| private Image getIcon(IConfigurationElement config) { |
| ImageDescriptor idesc = null; |
| URL url = null; |
| String iconName = config.getAttribute(IMAGE_NAME); |
| if (iconName != null) { |
| idesc = ResourceLocator.imageDescriptorFromBundle( |
| Platform.getBundle(config.getDeclaringExtension().getContributor().getName()).getSymbolicName(), |
| iconName).get(); |
| } |
| if (idesc == null) |
| return null; |
| Image img = idesc.createImage(); |
| loadedIcons.put(url, img); |
| return img; |
| } |
| |
| @Override |
| public void informAll(int code, Object data) { |
| for (int i = 0; i < CDTPropertyManager.getPagesCount(); i++) { |
| Object p = CDTPropertyManager.getPage(i); |
| if (p == null || !(p instanceof AbstractPage)) |
| continue; |
| AbstractPage ap = (AbstractPage) p; |
| ap.forEach(code, data); |
| } |
| } |
| |
| @Override |
| public void informPages(int code, Object data) { |
| for (int i = 0; i < CDTPropertyManager.getPagesCount(); i++) { |
| Object p = CDTPropertyManager.getPage(i); |
| if (p == null || !(p instanceof AbstractPage)) |
| continue; |
| AbstractPage ap = (AbstractPage) p; |
| ap.handleMessage(code, data); |
| } |
| } |
| |
| @Override |
| public void handleMessage(int code, Object data) { |
| switch (code) { |
| // First re-check visibility of all tabs. |
| // While tab deletion can be made on the fly, |
| // tabs adding will be made by re-creation |
| // of all elements, to preserve their order |
| case ICPropertyTab.MANAGEDBUILDSTATE: |
| if (folder == null) { |
| if (itabs == null || itabs.size() == 0) |
| return; |
| ICPropertyTab t = itabs.get(0).tab; |
| if (!t.canBeVisible()) |
| t.handleTabEvent(ICPropertyTab.VISIBLE, null); |
| return; |
| } |
| boolean willAdd = false; |
| TabItem[] ts = folder.getItems(); |
| int x = folder.getSelectionIndex(); |
| String currHeader = (x == -1) ? null : ts[x].getText(); |
| for (int i = 0; i < itabs.size(); i++) { |
| InternalTab itab = itabs.get(i); |
| TabItem ti = null; |
| for (TabItem element2 : ts) { |
| if (element2.isDisposed()) |
| continue; |
| if (element2.getData() == itab.tab) { |
| ti = element2; |
| break; |
| } |
| } |
| if (itab.tab.canBeVisible()) { |
| if (ti == null) { |
| willAdd = true; |
| break; |
| } |
| } else { |
| if (ti != null) |
| ti.dispose(); |
| } |
| } |
| // in case of new tab added, |
| // we have to dispose and re-create all tabs |
| if (willAdd) { |
| for (int j = 0; j < ts.length; j++) |
| if (ts[j] != null && !ts[j].isDisposed()) |
| ts[j].dispose(); |
| TabItem ti = null; |
| for (int i = 0; i < itabs.size(); i++) { |
| InternalTab itab = itabs.get(i); |
| if (itab.tab.canBeVisible()) { |
| TabItem currTI = itab.createOn(folder); |
| if (currHeader != null && currHeader.equals(itab.text)) |
| ti = currTI; |
| } |
| } |
| if (ti != null) |
| folder.setSelection(ti); |
| } |
| break; |
| } |
| } |
| |
| /** |
| * Performs conversion of incoming element to internal representation. |
| */ |
| protected boolean checkElement() { |
| IAdaptable el = super.getElement(); |
| if (el instanceof ICElement) |
| internalElement = ((ICElement) el).getResource(); |
| else if (el instanceof IResource) |
| internalElement = (IResource) el; |
| else |
| internalElement = el.getAdapter(IResource.class); |
| if (internalElement == null) |
| return false; |
| isProject = internalElement instanceof IProject; |
| isFolder = internalElement instanceof IFolder; |
| isFile = internalElement instanceof IFile; |
| return true; |
| } |
| |
| // override parent's method to use proper class |
| @Override |
| public IAdaptable getElement() { |
| if (internalElement == null && !checkElement()) |
| throw (new NullPointerException(Messages.AbstractPage_15)); |
| return internalElement; |
| } |
| |
| @Override |
| public boolean isForProject() { |
| return isProject; |
| } |
| |
| @Override |
| public boolean isForFolder() { |
| return isFolder; |
| } |
| |
| @Override |
| public boolean isForFile() { |
| return isFile; |
| } |
| |
| @Override |
| public boolean isForPrefs() { |
| return false; |
| } |
| |
| @Override |
| public boolean isMultiCfg() { |
| return resd instanceof ICMultiItemsHolder; |
| } |
| |
| /** |
| * Checks whether CDT property pages can be open for given object. |
| * In particular, header files and text files are not allowed. |
| * |
| * Note, that org.eclipse.cdt.ui.plugin.xml contains appropriate |
| * filters to avoid displaying CDT pages for unwanted objects. |
| * So this check is only backup, it would prevent from NullPointer |
| * exceptions in case when xml filters were modified somehow. |
| * |
| * @return - true if element is applicable to CDT pages. |
| */ |
| public boolean isApplicable() { |
| if (internalElement == null && !checkElement()) |
| return false; // unknown element |
| if (isForFile()) // only source files are applicable |
| return true; //CoreModel.isValidSourceUnitName(getProject(), internalElement.getName()); |
| return true; // Projects and folders are always applicable |
| } |
| |
| /** |
| * update views (in particular, display resource configurations) |
| */ |
| public static void updateViews(IResource res) { |
| if (res == null) |
| return; |
| IWorkbenchPartReference refs[] = CUIPlugin.getActiveWorkbenchWindow().getActivePage().getViewReferences(); |
| for (IWorkbenchPartReference ref : refs) { |
| IWorkbenchPart part = ref.getPart(false); |
| if (part != null && part instanceof IPropertyChangeListener) |
| ((IPropertyChangeListener) part).propertyChange( |
| new PropertyChangeEvent(res, PreferenceConstants.PREF_SHOW_CU_CHILDREN, null, null)); |
| } |
| } |
| |
| /** |
| * Adjusts form size according to contents dimensions |
| */ |
| public void resize() { |
| Shell sh = parentComposite.getShell(); |
| Point p0 = sh.getLocation(); |
| Point p1 = sh.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); |
| Rectangle r = sh.getDisplay().getClientArea(); |
| p1.x = Math.min(p1.x, (r.width - p0.x)); |
| p1.y = Math.min(p1.y, (r.height - p0.y)); |
| sh.setSize(p1); |
| } |
| |
| /** |
| * Returns Apply button widget |
| * Allows public access to it. |
| */ |
| @Override |
| public Button getAButton() { |
| return getApplyButton(); |
| } |
| |
| /** |
| * Returns Default button widget. |
| * Allows public access to it. |
| */ |
| @Override |
| public Button getDButton() { |
| return getDefaultsButton(); |
| } |
| |
| @Override |
| public void performHelp() { |
| // TODO: in next version: refer to ICPropertyTab instead of AbstractCPropertyTab |
| if (currentTab != null && currentTab instanceof AbstractCPropertyTab) { |
| String s = ((AbstractCPropertyTab) currentTab).getHelpContextId(); |
| if (s != null && s.length() > 0) { |
| IContext context = HelpSystem.getContext(s); |
| if (context != null) |
| PlatformUI.getWorkbench().getHelpSystem().displayHelp(context); |
| else |
| PlatformUI.getWorkbench().getHelpSystem().displayDynamicHelp(); |
| } |
| } |
| } |
| |
| /** |
| * @since 5.7 |
| */ |
| @Override |
| public ICPropertyTab getSelectedTab() { |
| return currentTab; |
| } |
| |
| } |