blob: 47fb72c7b4f0f4071f64d33f410846737d7f76f9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2016 Intel Corporation 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)
* James Blackburn (Broadcom Corp.)
* Serge Beauchamp (Freescale Semiconductor) - Bug 406545
*******************************************************************************/
package org.eclipse.cdt.ui.newui;
import java.lang.reflect.Method;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.cdtvariables.ICdtVariable;
import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.newui.Messages;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
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.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.views.navigator.ResourceComparator;
/**
* It is a parent for all standard property tabs
* in new CDT model.
*
* Although it's enough for new tabs to implement
* ICPropertyTab interface only, it would be better
* to extend them from this class.
*
* In this case, we'll able to use:
* - a lot of utility methods via "provider" link.
* In particular, it allows to get current project,
* configuration etc. See ICPropertyProvider interface.
* - a standard way to create buttons (ins/edit/del etc)
* and to handle their events (see buttonPressed(int))
* - several utility methods to create widgets in the
* uniform manner (setupLabel(), setupText() etc).
* - means to handle control messages which are the main
* communication way for new CDT model pages and tabs.
*/
public abstract class AbstractCPropertyTab implements ICPropertyTab {
public static final Method GRAY_METHOD = getGrayEnabled();
public static final int BUTTON_WIDTH = 120; // used as hint for all push buttons
// commonly used button names
public static final String EMPTY_STR = ""; //$NON-NLS-1$
public static final String ADD_STR = Messages.FileListControl_add;
public static final String DEL_STR = Messages.FileListControl_delete;
public static final String EDIT_STR = Messages.FileListControl_edit;
public static final String MOVEUP_STR = Messages.FileListControl_moveup;
public static final String MOVEDOWN_STR = Messages.FileListControl_movedown;
/** @since 5.4 */
public static final String PROJECTBUTTON_NAME = "Project...";
public static final String WORKSPACEBUTTON_NAME = Messages.FileListControl_button_workspace;
public static final String FILESYSTEMBUTTON_NAME = Messages.FileListControl_button_fs;
public static final String VARIABLESBUTTON_NAME = Messages.AbstractCPropertyTab_1;
public static final String FILESYSTEM_DIR_DIALOG_MSG = Messages.BrowseEntryDialog_fs_dir_dlg_msg;
public static final String FILESYSTEM_FILE_DIALOG_TITLE = EMPTY_STR;
public static final String WORKSPACE_DIR_DIALOG_TITLE = Messages.BrowseEntryDialog_wsp_dir_dlg_title;
public static final String WORKSPACE_FILE_DIALOG_TITLE = Messages.BrowseEntryDialog_wsp_file_dlg_title;
public static final String WORKSPACE_DIR_DIALOG_MSG = Messages.BrowseEntryDialog_wsp_dir_dlg_msg;
public static final String WORKSPACE_FILE_DIALOG_MSG = Messages.BrowseEntryDialog_wsp_file_dlg_msg;
public static final String WORKSPACE_FILE_DIALOG_ERR = Messages.BrowseEntryDialog_wsp_file_dlg_err;
public static final String WORKSPACE_DIR_DIALOG_ERR = Messages.BrowseEntryDialog_wsp_dir_dlg_err;
public static final String BACKGROUND_TEXT_DEFAULT = Messages.AbstractCPropertyTab_2;
public static final Color BACKGROUND_FOR_USER_VAR = new Color(Display.getDefault(), 255, 255, 200); // light yellow
private static final String PREFIX = "org.eclipse.cdt.ui."; //$NON-NLS-1$
public static final int TRI_UNKNOWN = 2;
public static final int TRI_YES = 1;
public static final int TRI_NO = 0;
protected static final String ENUM = "enum"; //$NON-NLS-1$
protected static final String SSET = "set"; //$NON-NLS-1$
private PageBook pageBook; // to select between background and usercomp.
private CLabel background;
private Composite userdata;
protected Composite usercomp; // space where user can create widgets
protected Composite buttoncomp; // space for buttons on the right
private Button[] buttons; // buttons in buttoncomp
public ICPropertyProvider page;
protected Image icon = null;
private String helpId = EMPTY_STR;
protected boolean visible;
@Override
public void createControls(Composite _parent, ICPropertyProvider _provider) {
page = _provider;
createControls(_parent);
}
/**
* Creates basic widgets for property tab.
* Descendants should, normally, override
* this method but call super.createControls().
*
* @param parent
*/
protected void createControls(Composite parent) {
parent.setLayout(new FillLayout());
pageBook = new PageBook(parent, SWT.NULL);
background = new CLabel(pageBook, SWT.CENTER | SWT.SHADOW_NONE);
background.setText(EMPTY_STR);
GridData gd;
userdata = new Composite(pageBook, SWT.NONE);
userdata.setLayout(new GridLayout(2, false));
usercomp = new Composite(userdata, SWT.NONE);
usercomp.setLayoutData(gd = new GridData(GridData.FILL_BOTH));
gd.widthHint = 150;
buttoncomp = new Composite(userdata, SWT.NONE);
buttoncomp.setLayoutData(gd = new GridData(GridData.END));
// width hint must be set to one, otherwise subclasses that do not have buttons
// don't look pretty, bug 242408
gd.widthHint = 1;
pageBook.showPage(userdata);
PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, helpId);
}
/**
* The common way to create buttons cluster
* on the right of tab workspace.
* @param names : array of button names
* null instead of name means "skip place"
*/
protected void initButtons(String[] names) {
initButtons(buttoncomp, names, 80);
}
protected void initButtons(String[] names, int width) {
initButtons(buttoncomp, names, width);
}
/**
* Ability to create standard button on any composite.
* @param c
* @param names
*/
protected void initButtons(Composite c, String[] names) {
initButtons(c, names, 80);
}
protected void initButtons(Composite c, String[] names, int width) {
if (names == null || names.length == 0)
return;
c.setLayoutData(new GridData(GridData.FILL_VERTICAL));
c.setLayout(new GridLayout(1, false));
buttons = new Button[names.length];
for (int i = 0; i < names.length; i++) {
buttons[i] = new Button(c, SWT.PUSH);
GridData gdb = new GridData(GridData.VERTICAL_ALIGN_CENTER);
gdb.grabExcessHorizontalSpace = false;
gdb.horizontalAlignment = SWT.FILL;
gdb.minimumWidth = width;
if (names[i] != null)
buttons[i].setText(names[i]);
else { // no button, but placeholder !
buttons[i].setVisible(false);
buttons[i].setEnabled(false);
gdb.heightHint = 10;
}
buttons[i].setLayoutData(gdb);
buttons[i].addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
buttonPressed(event);
}
});
}
}
/**
* Called when user changes
* @param cfg - selected configuration
*/
private void configChanged(ICResourceDescription cfg) {
if (visible)
updateData(cfg);
}
/**
* Disposes the SWT resources allocated by this dialog page.
*/
public void dispose() {
}
/**
* Sets the visibility of this property tab.
*
* @param _visible <code>true</code> to make this tab visible,
* and <code>false</code> to hide it
*/
public void setVisible(boolean _visible) {
visible = _visible;
if (visible)
updateData(page.getResDesc());
}
/**
* Descendant tabs should implement this method so
* that it copies it's data from one description
* to another. Only data affected by given tab
* should be copied.
*
* @param src
* @param dst
*/
protected abstract void performApply(ICResourceDescription src, ICResourceDescription dst);
protected abstract void performDefaults();
protected abstract void updateData(ICResourceDescription cfg);
protected abstract void updateButtons();
protected void performCancel() {
}
protected void performOK() {
}
/**
* @param e - event to be handled
*/
private void buttonPressed(SelectionEvent e) {
for (int i = 0; i < buttons.length; i++) {
if (buttons[i].equals(e.widget)) {
buttonPressed(i);
return;
}
}
}
/**
* Method should be rewritten to handle button presses
* @param i : number of button pressed
*
* Does nothing by default.
* May (but not must) be overridden.
*/
protected void buttonPressed(int i) {
}
/**
* Checks state of existing button.
*
* @param i - button index
* @return - true if button exists and enabled
*/
protected boolean buttonIsEnabled(int i) {
if (buttons == null || buttons.length <= i)
return false;
return buttons[i].isEnabled();
}
/**
* Changes state of existing button.
* Does nothing if index is invalid
*
* @param i - button index
* @param state - required state
*/
protected void buttonSetEnabled(int i, boolean state) {
if (buttons == null || buttons.length <= i)
return;
buttons[i].setEnabled(state);
}
/**
* Changes text of existing button
* Does nothing if index is invalid
*
* @param i - button index
* @param text - text to display
*/
protected void buttonSetText(int i, String text) {
if (buttons == null || buttons.length <= i)
return;
buttons[i].setText(text);
Composite c = buttons[i].getParent();
if (c != null) {
c.pack();
c = c.getParent();
if (c != null)
c.layout(true);
}
}
/**********************************************
* Utility methods for unified widget creation
**********************************************/
protected Label setupLabel(Composite c, String name, int span, int mode) {
Label l = new Label(c, SWT.NONE);
l.setText(name);
setupControl(l, span, mode);
return l;
}
protected Button setupButton(Composite c, String name, int span, int mode) {
Button b = new Button(c, SWT.PUSH);
b.setText(name);
setupControl(b, span, mode);
GridData g = (GridData) b.getLayoutData();
g.minimumWidth = BUTTON_WIDTH;
g.horizontalAlignment = SWT.RIGHT;
b.setLayoutData(g);
return b;
}
protected Text setupText(Composite c, int span, int mode) {
Text t = new Text(c, SWT.SINGLE | SWT.BORDER);
setupControl(t, span, mode);
return t;
}
protected Group setupGroup(Composite c, String name, int cols, int mode) {
Group g = new Group(c, SWT.NONE);
g.setText(name);
g.setLayout(new GridLayout(cols, false));
setupControl(g, 1, mode);
return g;
}
/**
* @since 7.2
*/
protected Composite setupComposite(Composite c, int cols, int mode) {
Composite c1 = new Composite(c, SWT.NONE);
c1.setLayout(new GridLayout(cols, false));
setupControl(c1, 1, mode);
return c1;
}
protected Button setupCheck(Composite c, String name, int span, int mode) {
Button b = new Button(c, SWT.CHECK);
b.setText(name);
setupControl(b, span, mode);
b.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
((Button) event.widget).setGrayed(false);
checkPressed(event);
}
});
return b;
}
/**
* @since 7.2
*/
protected Button setupRadio(Composite c, String name, int span, int mode) {
Button b = new Button(c, SWT.RADIO);
b.setText(name);
setupControl(b, span, mode);
b.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
((Button) event.widget).setGrayed(false);
checkPressed(event);
}
});
return b;
}
/**
* Selection handler for checkbox created
* by methods "setupCheck()" or "setupTri()"
* Descendants should override this method
* if they use "setupCheck".
* Usually the method body will look like:
* {
* Control b = (Control)e.widget;
* if (b.equals(myFirstCheckbox) { ... }
* else if (b.equals(mySecondCheckbox) { ... }
* ... }
*/
protected void checkPressed(SelectionEvent e) {
}
protected void setupControl(Control c, int span, int mode) {
// although we use GridLayout usually,
// exceptions can occur: do nothing.
if (c != null) {
if (span != 0) {
GridData gd = new GridData(mode);
gd.horizontalSpan = span;
c.setLayoutData(gd);
}
Composite p = c.getParent();
c.setFont(p.getFont());
}
}
/*
* A set of methods providing selection dialogs for files or dirs.
*/
public static String getFileSystemDirDialog(Shell shell, String text) {
DirectoryDialog dialog = new DirectoryDialog(shell, SWT.OPEN | SWT.APPLICATION_MODAL);
if (text != null && text.trim().length() != 0)
dialog.setFilterPath(text);
dialog.setMessage(FILESYSTEM_DIR_DIALOG_MSG);
return dialog.open();
}
public static String getFileSystemFileDialog(Shell shell, String text) {
FileDialog dialog = new FileDialog(shell);
if (text != null && text.trim().length() != 0)
dialog.setFilterPath(text);
dialog.setText(FILESYSTEM_FILE_DIALOG_TITLE);
return dialog.open();
}
/**
* @since 5.3
*/
public static String getFileSystemFileDialog(Shell shell, String text, String[] filter) {
FileDialog dialog = new FileDialog(shell);
if (text != null && text.trim().length() != 0)
dialog.setFilterPath(text);
dialog.setFilterExtensions(filter);
dialog.setText(FILESYSTEM_FILE_DIALOG_TITLE);
return dialog.open();
}
public static String getVariableDialog(Shell shell, ICConfigurationDescription cfgd) {
ICdtVariableManager vm = CCorePlugin.getDefault().getCdtVariableManager();
BuildVarListDialog dialog = new BuildVarListDialog(shell, vm.getVariables(cfgd));
dialog.setTitle(Messages.AbstractCPropertyTab_0);
if (dialog.open() == Window.OK) {
Object[] selected = dialog.getResult();
if (selected.length > 0) {
String s = ((ICdtVariable) selected[0]).getName();
return "${" + s.trim() + "}"; //$NON-NLS-1$//$NON-NLS-2$
}
}
return null;
}
public static String getWorkspaceDirDialog(Shell shell, String text) {
return getWorkspaceDialog(shell, text, true, null);
}
public static String getWorkspaceFileDialog(Shell shell, String text) {
return getWorkspaceDialog(shell, text, false, null);
}
/**
* @since 5.4
*/
public static String getProjectDirDialog(Shell shell, String text, IProject prj) {
return getWorkspaceDialog(shell, text, true, prj);
}
/**
* @since 5.4
*/
public static String getProjectFileDialog(Shell shell, String text, IProject prj) {
return getWorkspaceDialog(shell, text, false, prj);
}
private static String getWorkspaceDialog(Shell shell, String text, boolean dir, IProject prj) {
String currentPathText;
IPath path;
currentPathText = text;
/* Remove double quotes */
currentPathText = currentPathText.replaceAll("\"", ""); //$NON-NLS-1$ //$NON-NLS-2$
path = new Path(currentPathText);
ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(shell, new WorkbenchLabelProvider(),
new WorkbenchContentProvider());
if (prj == null)
dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
else
dialog.setInput(prj);
dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
if (dir) {
IResource container = null;
if (path.isAbsolute()) {
IContainer cs[] = ResourcesPlugin.getWorkspace().getRoot().findContainersForLocation(path);
if (cs != null && cs.length > 0)
container = cs[0];
}
dialog.setInitialSelection(container);
dialog.setValidator(new ISelectionStatusValidator() {
@Override
public IStatus validate(Object[] selection) {
if (selection != null)
if (selection.length > 0)
if ((selection[0] instanceof IFile))
return new StatusInfo(IStatus.ERROR, WORKSPACE_DIR_DIALOG_ERR);
return new StatusInfo();
}
});
dialog.setTitle(WORKSPACE_DIR_DIALOG_TITLE);
dialog.setMessage(WORKSPACE_DIR_DIALOG_MSG);
} else {
IResource resource = null;
if (path.isAbsolute()) {
resource = ResourceLookup.selectFileForLocation(path, prj);
}
dialog.setInitialSelection(resource);
dialog.setValidator(new ISelectionStatusValidator() {
@Override
public IStatus validate(Object[] selection) {
if (selection != null)
if (selection.length > 0)
if (!(selection[0] instanceof IFile))
return new StatusInfo(IStatus.ERROR, WORKSPACE_FILE_DIALOG_ERR);
return new StatusInfo();
}
});
dialog.setTitle(WORKSPACE_FILE_DIALOG_TITLE);
dialog.setMessage(WORKSPACE_FILE_DIALOG_MSG);
}
if (dialog.open() == Window.OK) {
IResource resource = (IResource) dialog.getFirstResult();
if (resource != null) {
StringBuilder buf = new StringBuilder();
return buf.append("${").append("workspace_loc:").append(resource.getFullPath()).append("}").toString(); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
}
}
return null;
}
// shortcut to frequently-used method
public ICResourceDescription getResDesc() {
return page.getResDesc();
}
/**
* Common event handler: called by parent for each tab
*/
@Override
public void handleTabEvent(int kind, Object data) {
switch (kind) {
case ICPropertyTab.OK:
if (canBeVisible())
performOK();
break;
case ICPropertyTab.APPLY:
if (canBeVisible())
performApply(getResDesc(), (ICResourceDescription) data);
break;
case ICPropertyTab.CANCEL:
if (canBeVisible())
performCancel();
break;
case ICPropertyTab.DEFAULTS:
if (canBeVisible() /*&& getResDesc() != null*/) {
updateData(getResDesc());
performDefaults();
}
break;
case ICPropertyTab.UPDATE:
if (canSupportMultiCfg() || !page.isMultiCfg()) {
if (canBeVisible()) {
setButtonVisible(true);
configChanged((ICResourceDescription) data);
}
} else
setAllVisible(false, null);
break;
case ICPropertyTab.DISPOSE:
dispose();
break;
case ICPropertyTab.VISIBLE:
if (canSupportMultiCfg() || !page.isMultiCfg()) {
if (canBeVisible()) {
setVisible(data != null);
setButtonVisible(data != null);
} else
setVisible(false);
} else
setAllVisible(false, null);
break;
case ICPropertyTab.SET_ICON:
icon = (Image) data;
break;
default:
break;
}
}
// By default, returns true (no visibility restriction)
// But several pages should rewrite this functionality.
@Override
public boolean canBeVisible() {
return true;
}
/**
* Method to be implemented by inherited classes to indicate whether or not the tab supports displaying
* and editing settings for multiple configuration selection.
*
* Default implementation returns true.
*
* @return true if the tab supports multiple configurations, false otherwise
* @since 5.7
*/
public boolean canSupportMultiCfg() {
return true;
}
/**
* Returns true if this tab is the one currently selected in the UI.
*
* @return true if this tab is the one selected in the UI, false otherwise.
* @since 5.7
*/
public boolean isTabSelected() {
if (page instanceof ICPropertyProvider2)
return ((ICPropertyProvider2) page).getSelectedTab() == this;
return false;
}
/**
* Added to avoid usage PixelConverter class.
* @param control
* @return FontMetrics
*/
public static FontMetrics getFontMetrics(Control control) {
GC gc = new GC(control);
gc.setFont(control.getFont());
FontMetrics fFontMetrics = gc.getFontMetrics();
gc.dispose();
return fFontMetrics;
}
/**
* Sets checkbox to appropriate state:
* unchecked or checked
* @param b - checkbox to set
* @param state
*/
public static void setTriSelection(Button b, boolean state) {
setTriSelection(b, state ? TRI_YES : TRI_NO);
}
/**
* Sets checkbox to appropriate state:
* unchecked, checked or unknown (grayed)
* @param b - checkbox to set
* @param state
*/
public static void setTriSelection(Button b, int state) {
switch (state) {
case TRI_NO:
b.setGrayed(false);
b.setSelection(false);
break;
case TRI_YES:
b.setGrayed(false);
b.setSelection(true);
break;
case TRI_UNKNOWN:
b.setGrayed(true);
b.setSelection(true);
break;
}
}
/**
* This method will be simplified after M5 release,
* when Button.setGrayed() method will be accessible.
* In this case, reflection will not be required.
*
* @param b
* @param value
* @deprecated call {@link Button#setGrayed(boolean)} instead
*/
@Deprecated
public static void setGrayed(Button b, boolean value) {
b.setGrayed(value);
}
/**
* This method will be removed after M5 release,
* when Button.setGrayed() will be officially accessible.
*
* @return reference to Button.setGrayed() method
*/
private static Method getGrayEnabled() {
try {
Class<?> cl = Class.forName("org.eclipse.swt.widgets.Button"); //$NON-NLS-1$
return cl.getMethod("setGrayed", new Class[] { boolean.class }); //$NON-NLS-1$
} catch (ClassNotFoundException e) {
return null;
} catch (NoSuchMethodException e) {
return null;
}
}
/**
* Utility method to show/hide working panes
* When panes are hidden, message becomes visible
*
* @param visible - true or false
* @param msg - text to be shown instead of panes
*/
protected void setAllVisible(boolean visible, String msg) {
if (!visible) {
setBackgroundText(msg);
pageBook.showPage(background);
} else {
pageBook.showPage(userdata);
}
setButtonVisible(visible);
}
/**
* Utility method to show/hide the 'Apply' and 'Restore Defaults' buttons
* @param visible - true or false
* @since 5.7
*/
protected void setButtonVisible(boolean visible) {
if (page != null && isTabSelected()) {
Button b = page.getAButton();
if (b != null)
b.setVisible(visible);
b = page.getDButton();
if (b != null)
b.setVisible(visible);
}
}
/**
* Allows changing message on background pane,
* which becomes visible after usercomp hidden
*
* @param s - text to display or null for default
*/
protected void setBackgroundText(String s) {
background.setText(s == null ? BACKGROUND_TEXT_DEFAULT : s);
}
/**
* Used to display double-clickable buttons for multiple configurations
* string list mode (see Multiple Configurations Edit Preference page).
*
* @deprecated as of CDT 8.0. This functionality is presented as links
* to the preference page, see {@link AbstractLangsListTab#updateStringListModeControl()}
*/
@Deprecated
protected void updateLbs(Label lb1, Label lb2) {
if (page.isMultiCfg()) {
if (lb1 != null) {
lb1.setText(CDTPrefUtil.getDMode());
lb1.setVisible(true);
}
if (lb2 != null) {
lb2.setText(CDTPrefUtil.getWMode());
lb2.setVisible(true);
}
} else {
if (lb1 != null)
lb1.setVisible(false);
if (lb2 != null)
lb2.setVisible(false);
}
}
/**
* The writing mode for multiple configurations edits (configuration drop-down list
* in project properties). This mode applies to lists of entries.
* See preference Multiple Configurations Edit, String List Write Mode.
*
* @return
* {@code true} if each list should be replaced as a whole with the
* list user is currently working with in UI<br/>
* {@code false} if changes apply only to individual entries and unaffected
* entries are preserved.
*/
protected boolean isWModifyMode() {
int wmode = CDTPrefUtil.getMultiCfgStringListWriteMode();
return (wmode == CDTPrefUtil.WMODE_MODIFY);
}
public String getHelpContextId() {
return helpId;
}
public void setHelpContextId(String id) {
helpId = PREFIX + id;
}
/**
* Allows subclasses to inform the container about changes relevant to the indexer.
* The tab will be asked before the apply is performed. As a consequence of returning
* <code>true</code> the user will be asked whether she wants to rebuild the index.
* @since 5.2
*/
protected boolean isIndexerAffected() {
return false;
}
}