Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Gvozdev2012-05-01 22:36:29 -0400
committerAndrew Gvozdev2012-05-01 23:05:37 -0400
commit2b5e3e6a20a411b4f000c0d9a4eb7a33813a628c (patch)
tree745f350fba172de078332a534b44a3e6bd98e93a
parentaae4b1de8eb0544940484487772a85ae4b34c3c9 (diff)
downloadorg.eclipse.cdt-2b5e3e6a20a411b4f000c0d9a4eb7a33813a628c.tar.gz
org.eclipse.cdt-2b5e3e6a20a411b4f000c0d9a4eb7a33813a628c.tar.xz
org.eclipse.cdt-2b5e3e6a20a411b4f000c0d9a4eb7a33813a628c.zip
bug 328007: [sd90] Design user interface for new scanner discovery
-rw-r--r--build/org.eclipse.cdt.make.ui/icons/obj16/search.gifbin0 -> 347 bytes
-rw-r--r--build/org.eclipse.cdt.make.ui/plugin.properties2
-rw-r--r--build/org.eclipse.cdt.make.ui/plugin.xml8
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java2
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF1
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/inspect_sys.gifbin0 -> 553 bytes
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/log_obj.gifbin0 -> 335 bytes
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/mbs.gifbin0 -> 380 bytes
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/plugin.xml39
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.java11
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.properties13
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/BuiltinSpecsDetectorOptionPage.java155
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/GCCBuildCommandParserOptionPage.java231
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/ScannerDiscoveryConsole.java39
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/ScannerDiscoveryGlobalConsole.java117
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/PropertyPageDefsTab.java61
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java8
-rw-r--r--core/org.eclipse.cdt.core/schema/LanguageSettingsProvider.exsd2
-rw-r--r--core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF2
-rw-r--r--core/org.eclipse.cdt.ui/icons/obj16/filesyst.gifbin310 -> 144 bytes
-rw-r--r--core/org.eclipse.cdt.ui/icons/obj16/ls_entries.gifbin0 -> 386 bytes
-rw-r--r--core/org.eclipse.cdt.ui/icons/ovr16/edited_ovr.gifbin0 -> 167 bytes
-rw-r--r--core/org.eclipse.cdt.ui/icons/ovr16/person_ovr.gifbin0 -> 165 bytes
-rw-r--r--core/org.eclipse.cdt.ui/plugin.properties6
-rw-r--r--core/org.eclipse.cdt.ui/plugin.xml44
-rw-r--r--core/org.eclipse.cdt.ui/schema/LanguageSettingsProviderAssociation.exsd200
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ImageCombo.java1471
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingEntryDialog.java615
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java1134
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderAssociationManager.java361
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java1171
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersLabelProvider.java96
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersPage.java104
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/LanguageSettingsImages.java40
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java39
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties39
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/ProblemsLabelDecorator.java37
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CDTSharedImages.java8
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/language/settings/providers/AbstractLanguageSettingProviderOptionPage.java79
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/language/settings/providers/LanguageSettingsProvidersImages.java33
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractCPropertyTab.java224
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractLangsListTab.java8
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ErrorParsTab.java2
43 files changed, 6249 insertions, 153 deletions
diff --git a/build/org.eclipse.cdt.make.ui/icons/obj16/search.gif b/build/org.eclipse.cdt.make.ui/icons/obj16/search.gif
new file mode 100644
index 0000000000..d540a01f4d
--- /dev/null
+++ b/build/org.eclipse.cdt.make.ui/icons/obj16/search.gif
Binary files differ
diff --git a/build/org.eclipse.cdt.make.ui/plugin.properties b/build/org.eclipse.cdt.make.ui/plugin.properties
index 21b341f00e..a931132ab9 100644
--- a/build/org.eclipse.cdt.make.ui/plugin.properties
+++ b/build/org.eclipse.cdt.make.ui/plugin.properties
@@ -43,6 +43,8 @@ LastTargetBuild.description=Rebuild the last make target for the selected contai
PreferenceBuildSettings.name=Settings
ErrorParsersTab.name=Error Parsers
ErrorParsersTab.tooltip=Error Parsers scan build output and report errors in Problems view
+LanguageSettingsProvidersTab.name=Discovery
+LanguageSettingsProvidersTab.tooltip=Language settings providers
PreferenceMakeProject.name=New Make Projects
PreferenceMake.name=Make Targets
diff --git a/build/org.eclipse.cdt.make.ui/plugin.xml b/build/org.eclipse.cdt.make.ui/plugin.xml
index 002d57859e..b93d372f94 100644
--- a/build/org.eclipse.cdt.make.ui/plugin.xml
+++ b/build/org.eclipse.cdt.make.ui/plugin.xml
@@ -470,6 +470,14 @@
tooltip="%ErrorParsersTab.tooltip"
weight="020">
</tab>
+ <tab
+ class="org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProviderTab"
+ icon="icons/obj16/search.gif"
+ name="%LanguageSettingsProvidersTab.name"
+ parent="org.eclipse.cdt.make.internal.ui.preferences.BuildSettingsPreferencePage"
+ tooltip="%LanguageSettingsProvidersTab.tooltip"
+ weight="040">
+ </tab>
</extension>
<extension
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java
index b31af8cae3..4d2014f425 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java
@@ -78,7 +78,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
private static final String CDT_MANAGEDBUILDER_UI_PLUGIN_ID = "org.eclipse.cdt.managedbuilder.ui"; //$NON-NLS-1$
private static final String SCANNER_DISCOVERY_CONSOLE = "org.eclipse.cdt.managedbuilder.ScannerDiscoveryConsole"; //$NON-NLS-1$
private static final String SCANNER_DISCOVERY_GLOBAL_CONSOLE = "org.eclipse.cdt.managedbuilder.ScannerDiscoveryGlobalConsole"; //$NON-NLS-1$
- private static final String DEFAULT_CONSOLE_ICON = "icons/obj16/inspect_system.gif"; //$NON-NLS-1$
+ private static final String DEFAULT_CONSOLE_ICON = "icons/obj16/inspect_sys.gif"; //$NON-NLS-1$
private static final String GMAKE_ERROR_PARSER_ID = "org.eclipse.cdt.core.GmakeErrorParser"; //$NON-NLS-1$
private static final String ATTR_PARAMETER = "parameter"; //$NON-NLS-1$
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF
index beaff8e8eb..1e00b74378 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF
+++ b/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF
@@ -14,6 +14,7 @@ Export-Package: org.eclipse.cdt.managedbuilder.ui.preferences,
Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.2.0,4.0.0)",
org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)",
org.eclipse.ui;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.ui.console;bundle-version="[3.5.100,4.0.0)",
org.eclipse.cdt.core;bundle-version="[5.0.0,6.0.0)",
org.eclipse.cdt.ui;bundle-version="[5.0.0,6.0.0)",
org.eclipse.cdt.managedbuilder.core;bundle-version="[8.1.0,9.0.0)",
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/inspect_sys.gif b/build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/inspect_sys.gif
new file mode 100644
index 0000000000..d68100a748
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/inspect_sys.gif
Binary files differ
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/log_obj.gif b/build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/log_obj.gif
new file mode 100644
index 0000000000..aebeab820d
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/log_obj.gif
Binary files differ
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/mbs.gif b/build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/mbs.gif
new file mode 100644
index 0000000000..3406bb1865
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.ui/icons/obj16/mbs.gif
Binary files differ
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml
index 9dd588b939..f5c72d2b4a 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml
+++ b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml
@@ -671,5 +671,42 @@
projectType="org.eclipse.cdt.build.makefile.projectType">
</projectTypePage>
</extension>
-
+ <extension
+ point="org.eclipse.cdt.ui.LanguageSettingsProviderAssociation">
+ <id-association
+ id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider"
+ icon="icons/obj16/mbs.gif"
+ ui-clear-entries="false"
+ ui-edit-entries="false">
+ </id-association>
+ <class-association
+ class="org.eclipse.cdt.managedbuilder.language.settings.providers.AbstractBuildCommandParser"
+ icon="icons/obj16/log_obj.gif"
+ page="org.eclipse.cdt.managedbuilder.internal.ui.language.settings.providers.GCCBuildCommandParserOptionPage"
+ ui-clear-entries="true"
+ ui-edit-entries="false">
+ </class-association>
+ <class-association
+ class="org.eclipse.cdt.managedbuilder.language.settings.providers.AbstractBuiltinSpecsDetector"
+ icon="icons/obj16/inspect_sys.gif"
+ page="org.eclipse.cdt.managedbuilder.internal.ui.language.settings.providers.BuiltinSpecsDetectorOptionPage"
+ ui-clear-entries="true"
+ ui-edit-entries="false">
+ </class-association>
+ </extension>
+ <extension
+ point="org.eclipse.cdt.core.CBuildConsole">
+ <CBuildConsole
+ id="org.eclipse.cdt.managedbuilder.ScannerDiscoveryConsole"
+ class="org.eclipse.cdt.managedbuilder.internal.ui.language.settings.providers.ScannerDiscoveryConsole">
+ </CBuildConsole>
+ </extension>
+ <extension
+ point="org.eclipse.cdt.core.CBuildConsole">
+ <CBuildConsole
+ id="org.eclipse.cdt.managedbuilder.ScannerDiscoveryGlobalConsole"
+ class="org.eclipse.cdt.managedbuilder.internal.ui.language.settings.providers.ScannerDiscoveryGlobalConsole">
+ </CBuildConsole>
+ </extension>
+
</plugin>
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.java
index 82299423e1..5986337af0 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.java
@@ -61,6 +61,10 @@ public class Messages extends NLS {
public static String BuildToolSettingsPage_tool_advancedSettings;
public static String BuildToolSettingsPage_tool_command;
public static String BuildToolSettingsPage_tool_commandLinePattern;
+ public static String BuiltinSpecsDetectorOptionPage_AllocateConsole;
+ public static String BuiltinSpecsDetectorOptionPage_Browse;
+ public static String BuiltinSpecsDetectorOptionPage_ChooseFile;
+ public static String BuiltinSpecsDetectorOptionPage_CompilerSpecsCommand;
public static String CConfigWizardPage_0;
public static String CConfigWizardPage_1;
public static String CConfigWizardPage_10;
@@ -105,6 +109,12 @@ public class Messages extends NLS {
public static String DiscoveryTab_ErrorClearingEntries;
public static String EnvironmentTab_15;
public static String EnvironmentTab_23;
+ public static String GCCBuildCommandParserOptionPage_CompilerPattern;
+ public static String GCCBuildCommandParserOptionPage_ContainerForDiscoveredEntries;
+ public static String GCCBuildCommandParserOptionPage_File;
+ public static String GCCBuildCommandParserOptionPage_Folder;
+ public static String GCCBuildCommandParserOptionPage_Project;
+ public static String GCCBuildCommandParserOptionPage_ResolvePaths;
public static String MacrosBlock_label_delete_all_confirm_message;
public static String MacrosBlock_label_delete_all_confirm_title;
public static String MacrosBlock_label_delete_confirm_message;
@@ -212,6 +222,7 @@ public class Messages extends NLS {
public static String PropertyPageDefsTab_8;
public static String PropertyPageDefsTab_9;
public static String PropertyPageDefsTab_showIncludeFileTab;
+ public static String PropertyPageDefsTab_showProvidersTab;
public static String RefreshPolicyExceptionDialog_addDialogLabel;
public static String RefreshPolicyExceptionDialog_AddExceptionInfoDialog_message;
public static String RefreshPolicyExceptionDialog_AddExceptionInfoDialog_title;
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.properties b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.properties
index 652c667936..a39e524536 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.properties
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.properties
@@ -274,6 +274,7 @@ PropertyPageDefsTab_7=Show disc. page names if they are unique. Else show profil
PropertyPageDefsTab_8=Always show names + profile IDs
PropertyPageDefsTab_9=Always show profile IDs only
PropertyPageDefsTab_showIncludeFileTab=Display "Include Files" tab
+PropertyPageDefsTab_showProvidersTab=Display "Preprocessor Include Paths" tabs
ProjectConvert_convertersList=Converters List
AbstractPrefPage_0=\ Preference settings will be applied to new projects \n only when there were no toolchains selected.
@@ -303,3 +304,15 @@ NewCfgDialog_5=Import predefined
ToolChainSelectionPage_Description=Select the initial toolchain for this project.
ToolChainSelectionPage_Title=Select Tool Chain
+
+# Language Settings Providers
+BuiltinSpecsDetectorOptionPage_AllocateConsole=Allocate console in the Console View
+BuiltinSpecsDetectorOptionPage_Browse=Browse...
+BuiltinSpecsDetectorOptionPage_ChooseFile=Choose file
+BuiltinSpecsDetectorOptionPage_CompilerSpecsCommand=Command to get compiler specs:
+GCCBuildCommandParserOptionPage_CompilerPattern=Compiler command pattern:
+GCCBuildCommandParserOptionPage_ContainerForDiscoveredEntries=Container to keep discovered entries
+GCCBuildCommandParserOptionPage_File=File (use when settings vary for different files)
+GCCBuildCommandParserOptionPage_Folder=Folder (use when settings are the same for all files in each folder)
+GCCBuildCommandParserOptionPage_Project=Project (use when settings are the same for all files in the project)
+GCCBuildCommandParserOptionPage_ResolvePaths=Use heuristics to resolve paths
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/BuiltinSpecsDetectorOptionPage.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/BuiltinSpecsDetectorOptionPage.java
new file mode 100644
index 0000000000..9888493ed5
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/BuiltinSpecsDetectorOptionPage.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2012 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.managedbuilder.internal.ui.language.settings.providers;
+
+import org.eclipse.cdt.managedbuilder.internal.ui.Messages;
+import org.eclipse.cdt.managedbuilder.language.settings.providers.AbstractBuiltinSpecsDetector;
+import org.eclipse.cdt.ui.language.settings.providers.AbstractLanguageSettingProviderOptionPage;
+import org.eclipse.cdt.utils.ui.controls.ControlFactory;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Options page for {@link AbstractBuiltinSpecsDetector}.
+ */
+public final class BuiltinSpecsDetectorOptionPage extends AbstractLanguageSettingProviderOptionPage {
+ private boolean fEditable;
+ private Text inputCommand;
+ private Button allocateConsoleCheckBox;
+
+ @Override
+ public void createControl(Composite parent) {
+ fEditable = parent.isEnabled();
+ AbstractBuiltinSpecsDetector provider = (AbstractBuiltinSpecsDetector) getProvider();
+
+ Composite composite = createCompositeForPageArea(parent);
+ createCompilerCommandInputControl(composite, provider);
+ createBrowseButton(composite);
+ createConsoleCheckbox(composite, provider);
+
+ setControl(composite);
+ }
+
+ /**
+ * Create composite for the page.
+ */
+ private Composite createCompositeForPageArea(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.marginWidth = 1;
+ layout.marginHeight = 1;
+ layout.marginRight = 1;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+ Dialog.applyDialogFont(composite);
+
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ composite.setLayoutData(gd);
+ return composite;
+ }
+
+ /**
+ * Create input control for compiler command.
+ */
+ private void createCompilerCommandInputControl(Composite composite, AbstractBuiltinSpecsDetector provider) {
+ Label label = ControlFactory.createLabel(composite, Messages.BuiltinSpecsDetectorOptionPage_CompilerSpecsCommand);
+ GridData gd = new GridData();
+ gd.horizontalSpan = 2;
+ label.setLayoutData(gd);
+ label.setEnabled(fEditable);
+
+ inputCommand = ControlFactory.createTextField(composite, SWT.SINGLE | SWT.BORDER);
+ String command = provider.getCommand();
+ inputCommand.setText(command!=null ? command : ""); //$NON-NLS-1$
+ inputCommand.setEnabled(fEditable);
+ inputCommand.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ String text = inputCommand.getText();
+ AbstractBuiltinSpecsDetector provider = (AbstractBuiltinSpecsDetector) getProvider();
+ if (!text.equals(provider.getCommand())) {
+ AbstractBuiltinSpecsDetector selectedProvider = (AbstractBuiltinSpecsDetector) getProviderWorkingCopy();
+ selectedProvider.setCommand(text);
+ refreshItem(selectedProvider);
+ }
+ }
+ });
+ }
+
+ /**
+ * Create "Browse" button.
+ */
+ private void createBrowseButton(Composite composite) {
+ Button button = ControlFactory.createPushButton(composite, Messages.BuiltinSpecsDetectorOptionPage_Browse);
+ button.setEnabled(fEditable);
+ button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ FileDialog dialog = new FileDialog(getShell(), SWT.NONE);
+ dialog.setText(Messages.BuiltinSpecsDetectorOptionPage_ChooseFile);
+ String fileName = inputCommand.getText();
+ // taking chance that the first word is a compiler path
+ int space = fileName.indexOf(' ');
+ if (space > 0) {
+ fileName = fileName.substring(0, space);
+ }
+ IPath folder = new Path(fileName).removeLastSegments(1);
+ dialog.setFilterPath(folder.toOSString());
+ String chosenFile = dialog.open();
+ if (chosenFile != null) {
+ inputCommand.insert(chosenFile);
+ }
+ }
+ });
+ }
+
+ /**
+ * Create check-box for console.
+ */
+ private void createConsoleCheckbox(Composite composite, AbstractBuiltinSpecsDetector provider) {
+ allocateConsoleCheckBox = new Button(composite, SWT.CHECK);
+ allocateConsoleCheckBox.setText(Messages.BuiltinSpecsDetectorOptionPage_AllocateConsole);
+ allocateConsoleCheckBox.setSelection(provider.isConsoleEnabled());
+ allocateConsoleCheckBox.setEnabled(fEditable);
+ allocateConsoleCheckBox.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean enabled = allocateConsoleCheckBox.getSelection();
+ AbstractBuiltinSpecsDetector provider = (AbstractBuiltinSpecsDetector) getProvider();
+ if (enabled != provider.isConsoleEnabled()) {
+ AbstractBuiltinSpecsDetector selectedProvider = (AbstractBuiltinSpecsDetector) getProviderWorkingCopy();
+ selectedProvider.setConsoleEnabled(enabled);
+ refreshItem(selectedProvider);
+ }
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+ }
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/GCCBuildCommandParserOptionPage.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/GCCBuildCommandParserOptionPage.java
new file mode 100644
index 0000000000..9f999d8d7a
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/GCCBuildCommandParserOptionPage.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2012 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.managedbuilder.internal.ui.language.settings.providers;
+
+import org.eclipse.cdt.managedbuilder.internal.ui.Messages;
+import org.eclipse.cdt.managedbuilder.language.settings.providers.AbstractBuildCommandParser;
+import org.eclipse.cdt.ui.language.settings.providers.AbstractLanguageSettingProviderOptionPage;
+import org.eclipse.cdt.utils.ui.controls.ControlFactory;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Options page for {@link AbstractBuildCommandParser}.
+ *
+ */
+public final class GCCBuildCommandParserOptionPage extends AbstractLanguageSettingProviderOptionPage {
+ private boolean fEditable;
+
+ private Text inputCommand;
+ private Button expandRelativePathCheckBox;
+
+ private Button scopeProjectRadioButton;
+ private Button scopeFolderRadioButton;
+ private Button scopeFileRadioButton;
+
+ @Override
+ public void createControl(Composite parent) {
+ fEditable = parent.isEnabled();
+ AbstractBuildCommandParser provider = (AbstractBuildCommandParser) getProvider();
+
+ Composite composite = new Composite(parent, SWT.NONE);
+ createCompositeForPageArea(composite);
+ createCompilerPatternInputControl(provider, composite);
+ createResourceScopeGroup(provider, composite);
+ createResolvePathsCheckbox(composite, provider);
+
+ setControl(composite);
+ }
+
+ /**
+ * Create composite for the page.
+ */
+ private void createCompositeForPageArea(final Composite composite) {
+ {
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.marginWidth = 1;
+ layout.marginHeight = 1;
+ layout.marginRight = 1;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+ Dialog.applyDialogFont(composite);
+
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ composite.setLayoutData(gd);
+ }
+ }
+
+ /**
+ * Create input control for compiler pattern.
+ */
+ private void createCompilerPatternInputControl(AbstractBuildCommandParser provider, Composite composite) {
+ Label label = ControlFactory.createLabel(composite, Messages.GCCBuildCommandParserOptionPage_CompilerPattern);
+ GridData gd = new GridData();
+ gd.horizontalSpan = 1;
+ label.setLayoutData(gd);
+ label.setEnabled(fEditable);
+
+ inputCommand = ControlFactory.createTextField(composite, SWT.SINGLE | SWT.BORDER);
+ String compilerPattern = provider.getCompilerPattern();
+ inputCommand.setText(compilerPattern!=null ? compilerPattern : ""); //$NON-NLS-1$
+
+ gd = new GridData();
+ gd.horizontalSpan = 1;
+ gd.grabExcessHorizontalSpace = true;
+ gd.horizontalAlignment = SWT.FILL;
+ inputCommand.setLayoutData(gd);
+ inputCommand.setEnabled(fEditable);
+
+ inputCommand.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ String text = inputCommand.getText();
+ AbstractBuildCommandParser provider = (AbstractBuildCommandParser) getProvider();
+ if (!text.equals(provider.getCompilerPattern())) {
+ AbstractBuildCommandParser selectedProvider = (AbstractBuildCommandParser) getProviderWorkingCopy();
+ selectedProvider.setCompilerPattern(text);
+ refreshItem(selectedProvider);
+ }
+ }
+ });
+ }
+
+ /**
+ * Create check-box for resolving paths.
+ */
+ private void createResolvePathsCheckbox(Composite composite, AbstractBuildCommandParser provider) {
+ expandRelativePathCheckBox = new Button(composite, SWT.CHECK);
+ expandRelativePathCheckBox.setText(Messages.GCCBuildCommandParserOptionPage_ResolvePaths);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ expandRelativePathCheckBox.setLayoutData(gd);
+
+ expandRelativePathCheckBox.setSelection(provider.isResolvingPaths());
+ expandRelativePathCheckBox.setEnabled(fEditable);
+ expandRelativePathCheckBox.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean enabled = expandRelativePathCheckBox.getSelection();
+ AbstractBuildCommandParser provider = (AbstractBuildCommandParser) getProvider();
+ if (enabled != provider.isResolvingPaths()) {
+ AbstractBuildCommandParser selectedProvider = (AbstractBuildCommandParser) getProviderWorkingCopy();
+ selectedProvider.setResolvingPaths(enabled);
+ refreshItem(selectedProvider);
+ }
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+ }
+
+ /**
+ * Create group and radio buttons for container to keep discovered entries.
+ */
+ private void createResourceScopeGroup(AbstractBuildCommandParser provider, Composite composite) {
+ Group resourceScopeGroup = new Group(composite, SWT.NONE);
+ resourceScopeGroup.setText(Messages.GCCBuildCommandParserOptionPage_ContainerForDiscoveredEntries);
+ resourceScopeGroup.setLayout(new GridLayout(2, false));
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ resourceScopeGroup.setLayoutData(gd);
+
+ scopeFileRadioButton = new Button(resourceScopeGroup, SWT.RADIO);
+ scopeFileRadioButton.setText(Messages.GCCBuildCommandParserOptionPage_File);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ scopeFileRadioButton.setLayoutData(gd);
+
+ scopeFileRadioButton.setSelection(provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.FILE);
+ scopeFileRadioButton.setEnabled(fEditable);
+ scopeFileRadioButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean enabled = scopeFileRadioButton.getSelection();
+ AbstractBuildCommandParser provider = (AbstractBuildCommandParser) getProvider();
+ if (enabled != (provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.FILE)) {
+ AbstractBuildCommandParser selectedProvider = (AbstractBuildCommandParser) getProviderWorkingCopy();
+ selectedProvider.setResourceScope(AbstractBuildCommandParser.ResourceScope.FILE);
+ refreshItem(selectedProvider);
+ }
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+
+ scopeFolderRadioButton = new Button(resourceScopeGroup, SWT.RADIO);
+ scopeFolderRadioButton.setText(Messages.GCCBuildCommandParserOptionPage_Folder);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ scopeFolderRadioButton.setLayoutData(gd);
+
+ scopeFolderRadioButton.setSelection(provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.FOLDER);
+ scopeFolderRadioButton.setEnabled(fEditable);
+ scopeFolderRadioButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean enabled = scopeFolderRadioButton.getSelection();
+ AbstractBuildCommandParser provider = (AbstractBuildCommandParser) getProvider();
+ if (enabled != (provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.FOLDER)) {
+ AbstractBuildCommandParser selectedProvider = (AbstractBuildCommandParser) getProviderWorkingCopy();
+ selectedProvider.setResourceScope(AbstractBuildCommandParser.ResourceScope.FOLDER);
+ refreshItem(selectedProvider);
+ }
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+
+ scopeProjectRadioButton = new Button(resourceScopeGroup, SWT.RADIO);
+ scopeProjectRadioButton.setText(Messages.GCCBuildCommandParserOptionPage_Project);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ scopeProjectRadioButton.setLayoutData(gd);
+
+ scopeProjectRadioButton.setSelection(provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.PROJECT);
+ scopeProjectRadioButton.setEnabled(fEditable);
+ scopeProjectRadioButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean enabled = scopeProjectRadioButton.getSelection();
+ AbstractBuildCommandParser provider = (AbstractBuildCommandParser) getProvider();
+ if (enabled != (provider.getResourceScope() == AbstractBuildCommandParser.ResourceScope.PROJECT)) {
+ AbstractBuildCommandParser selectedProvider = (AbstractBuildCommandParser) getProviderWorkingCopy();
+ selectedProvider.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT);
+ refreshItem(selectedProvider);
+ }
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+ }
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/ScannerDiscoveryConsole.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/ScannerDiscoveryConsole.java
new file mode 100644
index 0000000000..b12bf1c19c
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/ScannerDiscoveryConsole.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.managedbuilder.internal.ui.language.settings.providers;
+
+import java.net.URL;
+
+import org.eclipse.cdt.internal.ui.buildconsole.CBuildConsole;
+import org.eclipse.cdt.managedbuilder.language.settings.providers.AbstractBuiltinSpecsDetector;
+import org.eclipse.cdt.ui.language.settings.providers.LanguageSettingsProvidersImages;
+
+/**
+ * Console adapter for {@link AbstractBuiltinSpecsDetector}.
+ */
+public class ScannerDiscoveryConsole extends CBuildConsole {
+ /**
+ * {@inheritDoc}
+ * @param consoleId - a console ID is expected here which then is used as menu context ID.
+ * @param defaultIconUrl - if {@code LanguageSettingsProviderAssociation} extension point
+ * defines URL by provider id, {@code defaultIconUrl} will be ignored and the URL from the extension
+ * point will be used. If not, supplied {@code defaultIconUrl} will be used.
+ */
+ @Override
+ public void init(String consoleId, String name, URL defaultIconUrl) {
+ URL iconUrl = LanguageSettingsProvidersImages.getImageUrl(consoleId);
+ if (iconUrl == null) {
+ iconUrl = defaultIconUrl;
+ }
+
+ super.init(consoleId, name, iconUrl);
+ }
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/ScannerDiscoveryGlobalConsole.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/ScannerDiscoveryGlobalConsole.java
new file mode 100644
index 0000000000..0eed304893
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/language/settings/providers/ScannerDiscoveryGlobalConsole.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.managedbuilder.internal.ui.language.settings.providers;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.cdt.core.ConsoleOutputStream;
+import org.eclipse.cdt.internal.core.ICConsole;
+import org.eclipse.cdt.managedbuilder.language.settings.providers.AbstractBuiltinSpecsDetector;
+import org.eclipse.cdt.ui.CDTSharedImages;
+import org.eclipse.cdt.ui.language.settings.providers.LanguageSettingsProvidersImages;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+
+/**
+ * Console adapter for global {@link AbstractBuiltinSpecsDetector}.
+ *
+ * Note that this console is not colored.
+ */
+public class ScannerDiscoveryGlobalConsole implements ICConsole {
+ private MessageConsole console;
+
+ private class ConsoleOutputStreamAdapter extends ConsoleOutputStream {
+ private MessageConsoleStream fConsoleStream;
+ public ConsoleOutputStreamAdapter(MessageConsoleStream stream) {
+ fConsoleStream = stream;
+ }
+ @Override
+ public void write(int arg0) throws IOException {
+ fConsoleStream.write(arg0);
+ }
+ @Override
+ public synchronized void write(byte[] b, int off, int len) throws IOException {
+ fConsoleStream.write(b, off, len);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ fConsoleStream.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ fConsoleStream.close();
+ }
+ }
+
+ @Override
+ public void start(IProject project) {
+ Assert.isTrue(project == null);
+ }
+
+ @Override
+ public ConsoleOutputStream getOutputStream() throws CoreException {
+ return new ConsoleOutputStreamAdapter(console.newMessageStream());
+ }
+
+ @Override
+ public ConsoleOutputStream getInfoStream() throws CoreException {
+ return new ConsoleOutputStreamAdapter(console.newMessageStream());
+ }
+
+ @Override
+ public ConsoleOutputStream getErrorStream() throws CoreException {
+ return new ConsoleOutputStreamAdapter(console.newMessageStream());
+ }
+
+ @Override
+ public void init(String consoleId, String name, URL defaultIconUrl) {
+ console = null;
+
+ IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
+ IConsole[] allConsoles = consoleManager.getConsoles();
+ for (IConsole con : allConsoles) {
+ if (name.equals(con.getName()) && con instanceof MessageConsole) {
+ console = (MessageConsole) con;
+ console.clearConsole();
+ break;
+ }
+ }
+
+ if (console==null) {
+ URL iconUrl = LanguageSettingsProvidersImages.getImageUrl(consoleId);
+ if (iconUrl == null) {
+ iconUrl = defaultIconUrl;
+ }
+
+ ImageDescriptor imageDescriptor;
+ if (iconUrl != null) {
+ imageDescriptor = CDTSharedImages.getImageDescriptor(iconUrl.toString());
+ } else {
+ imageDescriptor = ImageDescriptor.getMissingImageDescriptor();
+ }
+
+ console = new MessageConsole(name, imageDescriptor);
+ console.activate();
+ consoleManager.addConsoles(new IConsole[]{ console });
+ }
+ }
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/PropertyPageDefsTab.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/PropertyPageDefsTab.java
index 458f7e517a..9c6bb0af7e 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/PropertyPageDefsTab.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/PropertyPageDefsTab.java
@@ -12,9 +12,10 @@
package org.eclipse.cdt.managedbuilder.ui.preferences;
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
+import org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProvidersPage;
+import org.eclipse.cdt.managedbuilder.internal.ui.Messages;
import org.eclipse.cdt.ui.newui.AbstractCPropertyTab;
import org.eclipse.cdt.ui.newui.CDTPrefUtil;
-import org.eclipse.cdt.managedbuilder.internal.ui.Messages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
@@ -25,19 +26,20 @@ import org.eclipse.swt.widgets.Group;
/**
* @since 5.1
- *
+ *
* @noextend This class is not intended to be subclassed by clients.
* @noinstantiate This class is not intended to be instantiated by clients.
*/
public class PropertyPageDefsTab extends AbstractCPropertyTab {
private static final int SPACING = 5; // for radio buttons layout
-
+
private Button show_tree;
private Button show_inc_files;
private Button show_mng;
private Button show_tool;
private Button show_exp;
+ private Button show_providers_tab; // temporary checkbox for scanner discovery Providers tab
private Button show_tipbox;
private Button b_0;
@@ -48,77 +50,82 @@ public class PropertyPageDefsTab extends AbstractCPropertyTab {
private Button s_0;
private Button s_1;
private Button s_2;
-
+
@Override
public void createControls(Composite parent) {
super.createControls(parent);
usercomp.setLayout(new GridLayout(1, false));
show_mng = new Button(usercomp, SWT.CHECK);
- show_mng.setText(Messages.PropertyPageDefsTab_0);
+ show_mng.setText(Messages.PropertyPageDefsTab_0);
show_mng.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
show_inc_files = new Button(usercomp, SWT.CHECK);
- show_inc_files.setText(Messages.PropertyPageDefsTab_showIncludeFileTab);
+ show_inc_files.setText(Messages.PropertyPageDefsTab_showIncludeFileTab);
show_inc_files.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
show_tree = new Button(usercomp, SWT.CHECK);
- show_tree.setText(Messages.PropertyPageDefsTab_1);
+ show_tree.setText(Messages.PropertyPageDefsTab_1);
show_tree.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
show_tool = new Button(usercomp, SWT.CHECK);
- show_tool.setText(Messages.PropertyPageDefsTab_4);
+ show_tool.setText(Messages.PropertyPageDefsTab_4);
show_tool.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
show_exp = new Button(usercomp, SWT.CHECK);
- show_exp.setText(Messages.PropertyPageDefsTab_10);
+ show_exp.setText(Messages.PropertyPageDefsTab_10);
show_exp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
+
+ show_providers_tab = new Button(usercomp, SWT.CHECK);
+ show_providers_tab.setText(Messages.PropertyPageDefsTab_showProvidersTab);
+ show_providers_tab.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
show_tipbox = new Button(usercomp, SWT.CHECK);
- show_tipbox.setText(Messages.PropertyPageDefsTab_16);
+ show_tipbox.setText(Messages.PropertyPageDefsTab_16);
show_tipbox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Group saveGrp = new Group(usercomp, SWT.NONE);
- saveGrp.setText(Messages.PropertyPageDefsTab_11);
+ saveGrp.setText(Messages.PropertyPageDefsTab_11);
saveGrp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
FillLayout fl = new FillLayout(SWT.VERTICAL);
fl.spacing = SPACING;
fl.marginHeight = SPACING;
fl.marginWidth = SPACING;
saveGrp.setLayout(fl);
-
+
s_0 = new Button(saveGrp, SWT.RADIO);
- s_0.setText(Messages.PropertyPageDefsTab_13);
+ s_0.setText(Messages.PropertyPageDefsTab_13);
s_1 = new Button(saveGrp, SWT.RADIO);
- s_1.setText(Messages.PropertyPageDefsTab_12);
+ s_1.setText(Messages.PropertyPageDefsTab_12);
s_2 = new Button(saveGrp, SWT.RADIO);
- s_2.setText(Messages.PropertyPageDefsTab_14);
-
+ s_2.setText(Messages.PropertyPageDefsTab_14);
+
Group discGrp = new Group(usercomp, SWT.NONE);
- discGrp.setText(Messages.PropertyPageDefsTab_5);
+ discGrp.setText(Messages.PropertyPageDefsTab_5);
discGrp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
fl = new FillLayout(SWT.VERTICAL);
fl.spacing = SPACING;
fl.marginHeight = SPACING;
fl.marginWidth = SPACING;
discGrp.setLayout(fl);
-
+
b_0 = new Button(discGrp, SWT.RADIO);
- b_0.setText(Messages.PropertyPageDefsTab_6);
+ b_0.setText(Messages.PropertyPageDefsTab_6);
b_1 = new Button(discGrp, SWT.RADIO);
- b_1.setText(Messages.PropertyPageDefsTab_7);
+ b_1.setText(Messages.PropertyPageDefsTab_7);
b_2 = new Button(discGrp, SWT.RADIO);
- b_2.setText(Messages.PropertyPageDefsTab_8);
+ b_2.setText(Messages.PropertyPageDefsTab_8);
b_3 = new Button(discGrp, SWT.RADIO);
- b_3.setText(Messages.PropertyPageDefsTab_9);
-
+ b_3.setText(Messages.PropertyPageDefsTab_9);
+
show_inc_files.setSelection(CDTPrefUtil.getBool(CDTPrefUtil.KEY_SHOW_INC_FILES));
show_tree.setSelection(CDTPrefUtil.getBool(CDTPrefUtil.KEY_DTREE));
show_mng.setSelection(!CDTPrefUtil.getBool(CDTPrefUtil.KEY_NOMNG));
show_tool.setSelection(!CDTPrefUtil.getBool(CDTPrefUtil.KEY_NOTOOLM));
show_exp.setSelection(CDTPrefUtil.getBool(CDTPrefUtil.KEY_EXPORT));
+ show_providers_tab.setSelection(!CDTPrefUtil.getBool(LanguageSettingsProvidersPage.KEY_NO_SHOW_PROVIDERS));
show_tipbox.setSelection(CDTPrefUtil.getBool(CDTPrefUtil.KEY_TIPBOX));
-
+
switch (CDTPrefUtil.getInt(CDTPrefUtil.KEY_DISC_NAMES)) {
case CDTPrefUtil.DISC_NAMING_UNIQUE_OR_BOTH: b_0.setSelection(true); break;
case CDTPrefUtil.DISC_NAMING_UNIQUE_OR_IDS: b_1.setSelection(true); break;
@@ -140,6 +147,7 @@ public class PropertyPageDefsTab extends AbstractCPropertyTab {
CDTPrefUtil.setBool(CDTPrefUtil.KEY_NOMNG, !show_mng.getSelection());
CDTPrefUtil.setBool(CDTPrefUtil.KEY_NOTOOLM, !show_tool.getSelection());
CDTPrefUtil.setBool(CDTPrefUtil.KEY_EXPORT, show_exp.getSelection());
+ CDTPrefUtil.setBool(LanguageSettingsProvidersPage.KEY_NO_SHOW_PROVIDERS, !show_providers_tab.getSelection());
CDTPrefUtil.setBool(CDTPrefUtil.KEY_TIPBOX, show_tipbox.getSelection());
int x = 0;
if (b_1.getSelection()) x = 1;
@@ -152,7 +160,7 @@ public class PropertyPageDefsTab extends AbstractCPropertyTab {
else if (s_2.getSelection()) x = CDTPrefUtil.POSITION_SAVE_NONE;
CDTPrefUtil.setInt(CDTPrefUtil.KEY_POSSAVE, x);
}
-
+
@Override
protected void performDefaults() {
show_tree.setSelection(false);
@@ -160,6 +168,7 @@ public class PropertyPageDefsTab extends AbstractCPropertyTab {
show_mng.setSelection(true);
show_tool.setSelection(true);
show_exp.setSelection(false);
+ show_providers_tab.setSelection(false);
show_tipbox.setSelection(false);
b_0.setSelection(true);
b_1.setSelection(false);
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java
index 53f77ee6fc..212d31465a 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java
@@ -47,11 +47,15 @@ public class ScannerDiscoveryLegacySupport {
private static final String PREFERENCES_QUALIFIER = CCorePlugin.PLUGIN_ID;
private static final String LANGUAGE_SETTINGS_PROVIDERS_NODE = "languageSettingsProviders"; //$NON-NLS-1$
+ /**
+ * Get preferences node for org.eclipse.cdt.core.
+ */
private static Preferences getPreferences(IProject project) {
- if (project == null)
+ if (project == null) {
return InstanceScope.INSTANCE.getNode(PREFERENCES_QUALIFIER).node(LANGUAGE_SETTINGS_PROVIDERS_NODE);
- else
+ } else {
return new LocalProjectScope(project).getNode(PREFERENCES_QUALIFIER).node(LANGUAGE_SETTINGS_PROVIDERS_NODE);
+ }
}
/**
diff --git a/core/org.eclipse.cdt.core/schema/LanguageSettingsProvider.exsd b/core/org.eclipse.cdt.core/schema/LanguageSettingsProvider.exsd
index 9cfae19859..8c5e164a99 100644
--- a/core/org.eclipse.cdt.core/schema/LanguageSettingsProvider.exsd
+++ b/core/org.eclipse.cdt.core/schema/LanguageSettingsProvider.exsd
@@ -226,7 +226,7 @@ The value &quot;true&quot; of this attribute is meaningful only for providers ca
<meta.section type="since"/>
</appInfo>
<documentation>
- CDT 9.0
+ CDT 8.1
</documentation>
</annotation>
diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
index ed8dab488a..b90b6aa0a1 100644
--- a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
@@ -29,6 +29,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
org.eclipse.cdt.internal.ui.includebrowser;x-internal:=true,
org.eclipse.cdt.internal.ui.indexview;x-internal:=true,
org.eclipse.cdt.internal.ui.language;x-internal:=true,
+ org.eclipse.cdt.internal.ui.language.settings.providers;x-internal:=true,
org.eclipse.cdt.internal.ui.navigator;x-internal:=true,
org.eclipse.cdt.internal.ui.newui;x-internal:=true,
org.eclipse.cdt.internal.ui.preferences;x-internal:=true,
@@ -75,6 +76,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
org.eclipse.cdt.ui.browser.typeinfo,
org.eclipse.cdt.ui.dialogs,
org.eclipse.cdt.ui.internal.templateengine.wizard;x-internal:=true,
+ org.eclipse.cdt.ui.language.settings.providers,
org.eclipse.cdt.ui.newui,
org.eclipse.cdt.ui.refactoring,
org.eclipse.cdt.ui.refactoring.actions,
diff --git a/core/org.eclipse.cdt.ui/icons/obj16/filesyst.gif b/core/org.eclipse.cdt.ui/icons/obj16/filesyst.gif
index 13ce11b149..4b98a62c6e 100644
--- a/core/org.eclipse.cdt.ui/icons/obj16/filesyst.gif
+++ b/core/org.eclipse.cdt.ui/icons/obj16/filesyst.gif
Binary files differ
diff --git a/core/org.eclipse.cdt.ui/icons/obj16/ls_entries.gif b/core/org.eclipse.cdt.ui/icons/obj16/ls_entries.gif
new file mode 100644
index 0000000000..93368302e9
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/icons/obj16/ls_entries.gif
Binary files differ
diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/edited_ovr.gif b/core/org.eclipse.cdt.ui/icons/ovr16/edited_ovr.gif
new file mode 100644
index 0000000000..48526ac8b3
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/icons/ovr16/edited_ovr.gif
Binary files differ
diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/person_ovr.gif b/core/org.eclipse.cdt.ui/icons/ovr16/person_ovr.gif
new file mode 100644
index 0000000000..339a6fadc9
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/icons/ovr16/person_ovr.gif
Binary files differ
diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties
index f50ea9bbbe..c840921cb7 100644
--- a/core/org.eclipse.cdt.ui/plugin.properties
+++ b/core/org.eclipse.cdt.ui/plugin.properties
@@ -607,6 +607,9 @@ includeFolderDecorator.description = Decorates missing include folders with erro
templatesViewName= Templates
+AllLanguageSettingEntries.name=Providers
+AllLanguageSettingEntries.tooltip=Language Setting Entries Providers
+
deleteConfigsCommand.name = Reset to Default
excludeCommand.name = Exclude from Build
ActionDefinition.selectEnclosing.description = Expand the selection to enclosing C/C++ element
@@ -617,6 +620,7 @@ ActionDefinition.selectPrevious.description = Expand the selection to enclosing
ActionDefinition.selectPrevious.name = Select Previous C/C++ Element
ActionDefinition.selectLast.description = Restore last selection in C/C++ editor
ActionDefinition.selectLast.name = Restore Last C/C++ Selection
+LanguageSettingsProviderAssociationExtensionPoint=Language Settings Provider UI
overrideAnnotation.label = C/C++ Override indicators
transfer.EditorAppearance.name = C/C++ Editor Appearance
@@ -631,4 +635,4 @@ extension-point.name = Refresh Exclusion Contributor
# New New Project Wizard
newProjectWizard.name = C/C++ Project (prototype)
-projectTypePages = Project Type Pages \ No newline at end of file
+projectTypePages = Project Type Pages
diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml
index 2923254b52..9d7e8e2cb4 100644
--- a/core/org.eclipse.cdt.ui/plugin.xml
+++ b/core/org.eclipse.cdt.ui/plugin.xml
@@ -26,6 +26,7 @@
<extension-point id="quickAssistProcessors" name="%quickAssistProcessorExtensionPoint" schema="schema/quickAssistProcessors.exsd"/>
<extension-point id="DocCommentOwner" name="%DocCommentOwner.name" schema="schema/DocCommentOwner.exsd"/>
<extension-point id="workingSetConfigurations" name="%workingSetConfigurationsExtensionPoint" schema="schema/workingSetConfigurations.exsd"/>
+ <extension-point id="LanguageSettingsProviderAssociation" name="%LanguageSettingsProviderAssociationExtensionPoint" schema="schema/LanguageSettingsProviderAssociation.exsd"/>
<extension-point id="RefreshExclusionContributor" name="%extension-point.name" schema="schema/RefreshExclusionContributor.exsd"/>
<extension-point id="projectTypePages" name="%ProjectTypePages" schema="schema/projectTypePages.exsd"/>
@@ -3368,6 +3369,17 @@
</adapt>
</enabledWhen>
</page>
+ <page
+ name="Preprocessor Include Paths, Macros etc."
+ id="org.eclipse.cdt.ui.language.settings"
+ class="org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProvidersPage"
+ category="org.eclipse.cdt.ui.newui.Page_head_general">
+ <enabledWhen>
+ <adapt type="org.eclipse.core.resources.IResource">
+ <test property="org.eclipse.core.resources.projectNature" value="org.eclipse.cdt.core.cnature"/>
+ </adapt>
+ </enabledWhen>
+ </page>
</extension>
<extension
@@ -4302,6 +4314,38 @@
</complexArray>
</processType>
</extension>
+ <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+ <provider
+ class="org.eclipse.cdt.core.language.settings.providers.LanguageSettingsGenericProvider"
+ id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"
+ name="CDT User Setting Entries"
+ prefer-non-shared="true">
+ </provider>
+ </extension>
+ <extension point="org.eclipse.cdt.ui.LanguageSettingsProviderAssociation">
+ <id-association
+ id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"
+ icon="icons/obj16/person-me.gif"
+ ui-clear-entries="true"
+ ui-edit-entries="true">
+ </id-association>
+ </extension>
+ <extension point="org.eclipse.cdt.ui.cPropertyTab">
+ <tab
+ class="org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsEntriesTab"
+ icon="icons/obj16/ls_entries.gif"
+ name="Entries"
+ weight="010"
+ parent="org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProvidersPage"
+ tooltip="%AllLanguageSettingEntries.tooltip"/>
+ <tab
+ class="org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProviderTab"
+ icon="icons/obj16/extension_obj.gif"
+ name="Providers"
+ weight="020"
+ parent="org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProvidersPage"
+ tooltip="%AllLanguageSettingEntries.tooltip"/>
+ </extension>
<extension
point="org.eclipse.ui.commands">
<command
diff --git a/core/org.eclipse.cdt.ui/schema/LanguageSettingsProviderAssociation.exsd b/core/org.eclipse.cdt.ui/schema/LanguageSettingsProviderAssociation.exsd
new file mode 100644
index 0000000000..f4b54ca3a3
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/schema/LanguageSettingsProviderAssociation.exsd
@@ -0,0 +1,200 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.cdt.ui" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.cdt.ui" id="LanguageSettingsProviderAssociation" name="Language Settings Provider UI Associations"/>
+ </appInfo>
+ <documentation>
+ This extension point defines appearance and behavior of UI controls for Language Settings Providers defined with extension point &lt;samp&gt;org.eclipse.cdt.core.LanguageSettingsProvider&lt;/samp&gt;.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ <documentation>
+ This extension point is used to define appearance and behavior of Language Settings Providers in user interface.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="id-association" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="class-association" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ ID of the extension point, not used
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ Name of the extension point, not used
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="id-association">
+ <annotation>
+ <documentation>
+ The definition of UI elements associated with ID of language settings provider.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ ID of language settings provider for which appearance is being defined.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ The path to the provider icon in the defining plugin, for example icons/obj16/picture.gif.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="page" type="string">
+ <annotation>
+ <documentation>
+ Options page for the provider to appear in preferences in Providers tab.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.cdt.ui.dialogs.ICOptionPage"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="ui-edit-entries" type="boolean">
+ <annotation>
+ <documentation>
+ Defines if user is allowed to edit provider&apos;s entries in UI.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="ui-clear-entries" type="boolean">
+ <annotation>
+ <documentation>
+ Defines if user is allowed to clear provider&apos;s entries in UI. For some providers like compiler specs detectors that may trigger automatic rerun.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="class-association">
+ <annotation>
+ <documentation>
+ The definition of UI elements associated with type of language settings provider. Providers subclassed from this type will inherit characteristics from closest super-type (unless exact ID association is defined).
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ Class of language settings provider for which appearance is being defined.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ The path to the provider icon in the defining plugin, for example icons/obj16/picture.gif.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="page" type="string">
+ <annotation>
+ <documentation>
+ Options page for the provider to appear in preferences in Providers tab.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.cdt.ui.dialogs.ICOptionPage"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="ui-edit-entries" type="boolean">
+ <annotation>
+ <documentation>
+ Defines if user is allowed to edit provider&apos;s entries in UI.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="ui-clear-entries" type="boolean">
+ <annotation>
+ <documentation>
+ Defines if user is allowed to clear provider&apos;s entries in UI. For some providers like compiler specs detectors that may trigger automatic rerun.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ CDT 8.1
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ For an example see definition for org.eclipse.cdt.ui.UserLanguageSettingsProvider.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2010, 2012 Andrew Gvozdev and others.
+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
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ImageCombo.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ImageCombo.java
new file mode 100644
index 0000000000..8b71742590
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ImageCombo.java
@@ -0,0 +1,1471 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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:
+ * IBM Corporation - initial API and implementation
+ * Tom Seidel - enhancements for image-handling
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui;
+
+import java.util.Arrays;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.accessibility.ACC;
+import org.eclipse.swt.accessibility.AccessibleAdapter;
+import org.eclipse.swt.accessibility.AccessibleControlAdapter;
+import org.eclipse.swt.accessibility.AccessibleControlEvent;
+import org.eclipse.swt.accessibility.AccessibleEvent;
+import org.eclipse.swt.accessibility.AccessibleTextAdapter;
+import org.eclipse.swt.accessibility.AccessibleTextEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.TypedListener;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * The ImageCombo class represents a selectable user interface object
+ * that combines a text field and a table and issues notification
+ * when an item is selected from the table.
+ * <p>
+ * Note that although this class is a subclass of <code>Composite</code>,
+ * it does not make sense to add children to it, or set a layout on it.
+ * </p>
+ * <dl>
+ * <dt><b>Styles:</b>
+ * <dd>BORDER, READ_ONLY, FLAT</dd>
+ * <dt><b>Events:</b>
+ * <dd>Selection</dd>
+ * </dl>
+ */
+public final class ImageCombo extends Composite {
+
+ Text text;
+ Table table;
+ int visibleItemCount = 5;
+ Shell popup;
+ Button arrow;
+ boolean hasFocus;
+ Listener listener, filter;
+ Color foreground, background;
+ Font font;
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a widget which will be the parent of the new instance (cannot be null)
+ * @param style the style of widget to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * </ul>
+ *
+ * @see SWT#BORDER
+ * @see SWT#READ_ONLY
+ * @see SWT#FLAT
+ * @see Widget#getStyle()
+ */
+public ImageCombo (Composite parent, int style) {
+ super (parent, style = checkStyle (style));
+
+ int textStyle = SWT.SINGLE;
+ if ((style & SWT.READ_ONLY) != 0) textStyle |= SWT.READ_ONLY;
+ if ((style & SWT.FLAT) != 0) textStyle |= SWT.FLAT;
+ text = new Text (this, SWT.NONE);
+ int arrowStyle = SWT.ARROW | SWT.DOWN;
+ if ((style & SWT.FLAT) != 0) arrowStyle |= SWT.FLAT;
+ arrow = new Button (this, arrowStyle);
+
+ listener = new Listener () {
+ public void handleEvent (Event event) {
+ if (popup == event.widget) {
+ popupEvent (event);
+ return;
+ }
+ if (text == event.widget) {
+ textEvent (event);
+ return;
+ }
+ if (table == event.widget) {
+ listEvent (event);
+ return;
+ }
+ if (arrow == event.widget) {
+ arrowEvent (event);
+ return;
+ }
+ if (ImageCombo.this == event.widget) {
+ comboEvent (event);
+ return;
+ }
+ if (getShell () == event.widget) {
+ handleFocus (SWT.FocusOut);
+ }
+ }
+ };
+ filter = new Listener() {
+ public void handleEvent(Event event) {
+ Shell shell = ((Control)event.widget).getShell ();
+ if (shell == ImageCombo.this.getShell ()) {
+ handleFocus (SWT.FocusOut);
+ }
+ }
+ };
+
+ int [] comboEvents = {SWT.Dispose, SWT.Move, SWT.Resize};
+ for (int i=0; i<comboEvents.length; i++) this.addListener (comboEvents [i], listener);
+
+ int [] textEvents = {SWT.KeyDown, SWT.KeyUp, SWT.Modify, SWT.MouseDown, SWT.MouseUp, SWT.Traverse, SWT.FocusIn};
+ for (int i=0; i<textEvents.length; i++) text.addListener (textEvents [i], listener);
+
+ int [] arrowEvents = {SWT.Selection, SWT.FocusIn};
+ for (int i=0; i<arrowEvents.length; i++) arrow.addListener (arrowEvents [i], listener);
+
+ createPopup( -1);
+ initAccessible();
+}
+static int checkStyle (int style) {
+ int mask = SWT.BORDER | SWT.READ_ONLY | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+ return style & mask;
+}
+/**
+ * Adds the argument to the end of the receiver's list.
+ *
+ * @param string the new item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #add(String,int)
+ */
+public void add (String string, Image image) {
+ checkWidget();
+ if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ TableItem newItem = new TableItem(this.table,SWT.NONE);
+ newItem.setText(string);
+ if (image != null) newItem.setImage(image);
+}
+/**
+ * Adds the argument to the receiver's list at the given
+ * zero-relative index.
+ * <p>
+ * Note: To add an item at the end of the list, use the
+ * result of calling <code>getItemCount()</code> as the
+ * index or use <code>add(String)</code>.
+ * </p>
+ *
+ * @param string the new item
+ * @param index the index for the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #add(String)
+ */
+public void add (String string,Image image, int index) {
+ checkWidget();
+ if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ TableItem newItem = new TableItem(this.table,SWT.NONE,index);
+ if (image != null) newItem.setImage(image);
+}
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's text is modified, by sending
+ * it one of the messages defined in the <code>ModifyListener</code>
+ * interface.
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ModifyListener
+ * @see #removeModifyListener
+ */
+public void addModifyListener (ModifyListener listener) {
+ checkWidget();
+ if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Modify, typedListener);
+}
+/**
+ * Adds the listener to the collection of listeners who will
+ * be notified when the receiver's selection changes, by sending
+ * it one of the messages defined in the <code>SelectionListener</code>
+ * interface.
+ * <p>
+ * <code>widgetSelected</code> is called when the combo's list selection changes.
+ * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed the combo's text area.
+ * </p>
+ *
+ * @param listener the listener which should be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #removeSelectionListener
+ * @see SelectionEvent
+ */
+public void addSelectionListener(SelectionListener listener) {
+ checkWidget();
+ if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ addListener (SWT.DefaultSelection,typedListener);
+}
+void arrowEvent (Event event) {
+ switch (event.type) {
+ case SWT.FocusIn: {
+ handleFocus (SWT.FocusIn);
+ break;
+ }
+ case SWT.Selection: {
+ dropDown (!isDropped ());
+ break;
+ }
+ }
+}
+/**
+ * Sets the selection in the receiver's text field to an empty
+ * selection starting just before the first character. If the
+ * text field is editable, this has the effect of placing the
+ * i-beam at the start of the text.
+ * <p>
+ * Note: To clear the selected items in the receiver's list,
+ * use <code>deselectAll()</code>.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #deselectAll
+ */
+public void clearSelection () {
+ checkWidget ();
+ text.clearSelection ();
+ table.deselectAll ();
+}
+void comboEvent (Event event) {
+ switch (event.type) {
+ case SWT.Dispose:
+ if (popup != null && !popup.isDisposed ()) {
+ table.removeListener (SWT.Dispose, listener);
+ popup.dispose ();
+ }
+ Shell shell = getShell ();
+ shell.removeListener (SWT.Deactivate, listener);
+ Display display = getDisplay ();
+ display.removeFilter (SWT.FocusIn, filter);
+ popup = null;
+ text = null;
+ table = null;
+ arrow = null;
+ break;
+ case SWT.Move:
+ dropDown (false);
+ break;
+ case SWT.Resize:
+ internalLayout (false);
+ break;
+ }
+}
+
+public Point computeSize (int wHint, int hHint, boolean changed) {
+ checkWidget ();
+ int width = 0, height = 0;
+ String[] items = getStringsFromTable();
+ int textWidth = 0;
+ GC gc = new GC (text);
+ int spacer = gc.stringExtent (" ").x; //$NON-NLS-1$
+ for (int i = 0; i < items.length; i++) {
+ textWidth = Math.max (gc.stringExtent (items[i]).x, textWidth);
+ }
+ gc.dispose();
+ Point textSize = text.computeSize (SWT.DEFAULT, SWT.DEFAULT, changed);
+ Point arrowSize = arrow.computeSize (SWT.DEFAULT, SWT.DEFAULT, changed);
+ Point listSize = table.computeSize (wHint, SWT.DEFAULT, changed);
+ int borderWidth = getBorderWidth ();
+
+ height = Math.max (hHint, Math.max (textSize.y, arrowSize.y) + 2*borderWidth);
+ width = Math.max (wHint, Math.max (textWidth + 2*spacer + arrowSize.x + 2*borderWidth, listSize.x));
+ return new Point (width, height);
+}
+void createPopup(int selectionIndex) {
+ // create shell and list
+ popup = new Shell (getShell (), SWT.NO_TRIM | SWT.ON_TOP);
+ int style = getStyle ();
+ int listStyle = SWT.SINGLE | SWT.V_SCROLL;
+ if ((style & SWT.FLAT) != 0) listStyle |= SWT.FLAT;
+ if ((style & SWT.RIGHT_TO_LEFT) != 0) listStyle |= SWT.RIGHT_TO_LEFT;
+ if ((style & SWT.LEFT_TO_RIGHT) != 0) listStyle |= SWT.LEFT_TO_RIGHT;
+ // create a table instead of a list.
+ table = new Table (popup, listStyle);
+ if (font != null) table.setFont (font);
+ if (foreground != null) table.setForeground (foreground);
+ if (background != null) table.setBackground (background);
+
+ int [] popupEvents = {SWT.Close, SWT.Paint, SWT.Deactivate};
+ for (int i=0; i<popupEvents.length; i++) popup.addListener (popupEvents [i], listener);
+ int [] listEvents = {SWT.MouseUp, SWT.Selection, SWT.Traverse, SWT.KeyDown, SWT.KeyUp, SWT.FocusIn, SWT.Dispose};
+ for (int i=0; i<listEvents.length; i++) table.addListener (listEvents [i], listener);
+
+ if (selectionIndex != -1) table.setSelection (selectionIndex);
+}
+/**
+ * Deselects the item at the given zero-relative index in the receiver's
+ * list. If the item at the index was already deselected, it remains
+ * deselected. Indices that are out of range are ignored.
+ *
+ * @param index the index of the item to deselect
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void deselect (int index) {
+ checkWidget ();
+ table.deselect (index);
+}
+/**
+ * Deselects all selected items in the receiver's list.
+ * <p>
+ * Note: To clear the selection in the receiver's text field,
+ * use <code>clearSelection()</code>.
+ * </p>
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see #clearSelection
+ */
+public void deselectAll () {
+ checkWidget ();
+ table.deselectAll ();
+}
+void dropDown (boolean drop) {
+ if (drop == isDropped ()) return;
+ if (!drop) {
+ popup.setVisible (false);
+ if (!isDisposed ()&& arrow.isFocusControl()) {
+ text.setFocus();
+ }
+ return;
+ }
+
+ if (getShell() != popup.getParent ()) {
+ TableItem[] items = table.getItems ();
+ int selectionIndex = table.getSelectionIndex ();
+ table.removeListener (SWT.Dispose, listener);
+ popup.dispose();
+ popup = null;
+ table = null;
+ createPopup (selectionIndex);
+ }
+
+ Point size = getSize ();
+ int itemCount = table.getItemCount ();
+ itemCount = (itemCount == 0) ? visibleItemCount : Math.min(visibleItemCount, itemCount);
+ int itemHeight = table.getItemHeight () * itemCount;
+ Point listSize = table.computeSize (SWT.DEFAULT, itemHeight, false);
+ table.setBounds (1, 1, Math.max (size.x - 2, listSize.x), listSize.y);
+
+ int index = table.getSelectionIndex ();
+ if (index != -1) table.setTopIndex (index);
+ Display display = getDisplay ();
+ Rectangle listRect = table.getBounds ();
+ Rectangle parentRect = display.map (getParent (), null, getBounds ());
+ Point comboSize = getSize ();
+ Rectangle displayRect = getMonitor ().getClientArea ();
+ int width = Math.max (comboSize.x, listRect.width + 2);
+ int height = listRect.height + 2;
+ int x = parentRect.x;
+ int y = parentRect.y + comboSize.y;
+ if (y + height > displayRect.y + displayRect.height) y = parentRect.y - height;
+ popup.setBounds (x, y, width, height);
+ popup.setVisible (true);
+ table.setFocus ();
+}
+/*
+ * Return the Label immediately preceding the receiver in the z-order,
+ * or null if none.
+ */
+Label getAssociatedLabel () {
+ Control[] siblings = getParent ().getChildren ();
+ for (int i = 0; i < siblings.length; i++) {
+ if (siblings [i] == ImageCombo.this) {
+ if (i > 0 && siblings [i-1] instanceof Label) {
+ return (Label) siblings [i-1];
+ }
+ }
+ }
+ return null;
+}
+public Control [] getChildren () {
+ checkWidget();
+ return new Control [0];
+}
+/**
+ * Gets the editable state.
+ *
+ * @return whether or not the reciever is editable
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public boolean getEditable () {
+ checkWidget ();
+ return text.getEditable();
+}
+/**
+ * Returns the item at the given, zero-relative index in the
+ * receiver's list. Throws an exception if the index is out
+ * of range.
+ *
+ * @param index the index of the item to return
+ * @return the item at the given index
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TableItem getItem (int index) {
+ checkWidget();
+ return this.table.getItem (index);
+}
+/**
+ * Returns the number of items contained in the receiver's list.
+ *
+ * @return the number of items
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemCount () {
+ checkWidget ();
+ return table.getItemCount ();
+}
+/**
+ * Returns the height of the area which would be used to
+ * display <em>one</em> of the items in the receiver's list.
+ *
+ * @return the height of one item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getItemHeight () {
+ checkWidget ();
+ return table.getItemHeight ();
+}
+/**
+ * Returns an array of <code>String</code>s which are the items
+ * in the receiver's list.
+ * <p>
+ * Note: This is not the actual structure used by the receiver
+ * to maintain its list of items, so modifying the array will
+ * not affect the receiver.
+ * </p>
+ *
+ * @return the items in the receiver's list
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public TableItem [] getItems () {
+ checkWidget ();
+ return table.getItems ();
+}
+char getMnemonic (String string) {
+ int index = 0;
+ int length = string.length ();
+ do {
+ while ((index < length) && (string.charAt (index) != '&')) index++;
+ if (++index >= length) return '\0';
+ if (string.charAt (index) != '&') return string.charAt (index);
+ index++;
+ } while (index < length);
+ return '\0';
+}
+
+String [] getStringsFromTable()
+{
+ String[] items = new String[this.table.getItems().length];
+ for (int i = 0, n = items.length; i < n; i++) {
+ items[i]=this.table.getItem(i).getText();
+ }
+ return items;
+}
+/**
+ * Returns a <code>Point</code> whose x coordinate is the start
+ * of the selection in the receiver's text field, and whose y
+ * coordinate is the end of the selection. The returned values
+ * are zero-relative. An "empty" selection as indicated by
+ * the the x and y coordinates having the same value.
+ *
+ * @return a point representing the selection start and end
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public Point getSelection () {
+ checkWidget ();
+ return text.getSelection ();
+}
+/**
+ * Returns the zero-relative index of the item which is currently
+ * selected in the receiver's list, or -1 if no item is selected.
+ *
+ * @return the index of the selected item
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getSelectionIndex () {
+ checkWidget ();
+ return table.getSelectionIndex ();
+}
+public int getStyle () {
+ int style = super.getStyle ();
+ style &= ~SWT.READ_ONLY;
+ if (!text.getEditable()) style |= SWT.READ_ONLY;
+ return style;
+}
+/**
+ * Returns a string containing a copy of the contents of the
+ * receiver's text field.
+ *
+ * @return the receiver's text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText () {
+ checkWidget ();
+ return text.getText ();
+}
+/**
+ * Returns the height of the receivers's text field.
+ *
+ * @return the text height
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getTextHeight () {
+ checkWidget ();
+ return text.getLineHeight ();
+}
+/**
+ * Returns the maximum number of characters that the receiver's
+ * text field is capable of holding. If this has not been changed
+ * by <code>setTextLimit()</code>, it will be the constant
+ * <code>Combo.LIMIT</code>.
+ *
+ * @return the text limit
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getTextLimit () {
+ checkWidget ();
+ return text.getTextLimit ();
+}
+/**
+ * Gets the number of items that are visible in the drop
+ * down portion of the receiver's list.
+ *
+ * @return the number of items that are visible
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public int getVisibleItemCount () {
+ checkWidget ();
+ return visibleItemCount;
+}
+void handleFocus (int type) {
+ if (isDisposed ()) return;
+ switch (type) {
+ case SWT.FocusIn: {
+ if (hasFocus) return;
+ if (getEditable ()) text.selectAll ();
+ hasFocus = true;
+ Shell shell = getShell ();
+ shell.removeListener (SWT.Deactivate, listener);
+ shell.addListener (SWT.Deactivate, listener);
+ Display display = getDisplay ();
+ display.removeFilter (SWT.FocusIn, filter);
+ display.addFilter (SWT.FocusIn, filter);
+ Event e = new Event ();
+ notifyListeners (SWT.FocusIn, e);
+ break;
+ }
+ case SWT.FocusOut: {
+ if (!hasFocus) return;
+ Control focusControl = getDisplay ().getFocusControl ();
+ if (focusControl == arrow || focusControl == table || focusControl == text) return;
+ hasFocus = false;
+ Shell shell = getShell ();
+ shell.removeListener(SWT.Deactivate, listener);
+ Display display = getDisplay ();
+ display.removeFilter (SWT.FocusIn, filter);
+ Event e = new Event ();
+ notifyListeners (SWT.FocusOut, e);
+ break;
+ }
+ }
+}
+/**
+ * Searches the receiver's list starting at the first item
+ * (index 0) until an item is found that is equal to the
+ * argument, and returns the index of that item. If no item
+ * is found, returns -1.
+ *
+ * @param string the search item
+ * @return the index of the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int indexOf (String string) {
+ checkWidget ();
+ if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ return Arrays.asList(getStringsFromTable()).indexOf (string);
+}
+
+
+void initAccessible() {
+ AccessibleAdapter accessibleAdapter = new AccessibleAdapter () {
+ public void getName (AccessibleEvent e) {
+ String name = null;
+ Label label = getAssociatedLabel ();
+ if (label != null) {
+ name = stripMnemonic (label.getText());
+ }
+ e.result = name;
+ }
+ public void getKeyboardShortcut(AccessibleEvent e) {
+ String shortcut = null;
+ Label label = getAssociatedLabel ();
+ if (label != null) {
+ String text = label.getText ();
+ if (text != null) {
+ char mnemonic = getMnemonic (text);
+ if (mnemonic != '\0') {
+ shortcut = "Alt+"+mnemonic; //$NON-NLS-1$
+ }
+ }
+ }
+ e.result = shortcut;
+ }
+ public void getHelp (AccessibleEvent e) {
+ e.result = getToolTipText ();
+ }
+ };
+ getAccessible ().addAccessibleListener (accessibleAdapter);
+ text.getAccessible ().addAccessibleListener (accessibleAdapter);
+ table.getAccessible ().addAccessibleListener (accessibleAdapter);
+
+ arrow.getAccessible ().addAccessibleListener (new AccessibleAdapter() {
+ public void getName (AccessibleEvent e) {
+ e.result = isDropped () ? SWT.getMessage ("SWT_Close") : SWT.getMessage ("SWT_Open"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ public void getKeyboardShortcut (AccessibleEvent e) {
+ e.result = "Alt+Down Arrow"; //$NON-NLS-1$
+ }
+ public void getHelp (AccessibleEvent e) {
+ e.result = getToolTipText ();
+ }
+ });
+
+ getAccessible().addAccessibleTextListener (new AccessibleTextAdapter() {
+ public void getCaretOffset (AccessibleTextEvent e) {
+ e.offset = text.getCaretPosition ();
+ }
+ });
+
+ getAccessible().addAccessibleControlListener (new AccessibleControlAdapter() {
+ public void getChildAtPoint (AccessibleControlEvent e) {
+ Point testPoint = toControl (e.x, e.y);
+ if (getBounds ().contains (testPoint)) {
+ e.childID = ACC.CHILDID_SELF;
+ }
+ }
+
+ public void getLocation (AccessibleControlEvent e) {
+ Rectangle location = getBounds ();
+ Point pt = toDisplay (location.x, location.y);
+ e.x = pt.x;
+ e.y = pt.y;
+ e.width = location.width;
+ e.height = location.height;
+ }
+
+ public void getChildCount (AccessibleControlEvent e) {
+ e.detail = 0;
+ }
+
+ public void getRole (AccessibleControlEvent e) {
+ e.detail = ACC.ROLE_COMBOBOX;
+ }
+
+ public void getState (AccessibleControlEvent e) {
+ e.detail = ACC.STATE_NORMAL;
+ }
+
+ public void getValue (AccessibleControlEvent e) {
+ e.result = getText ();
+ }
+ });
+
+ text.getAccessible ().addAccessibleControlListener (new AccessibleControlAdapter () {
+ public void getRole (AccessibleControlEvent e) {
+ e.detail = text.getEditable () ? ACC.ROLE_TEXT : ACC.ROLE_LABEL;
+ }
+ });
+
+ arrow.getAccessible ().addAccessibleControlListener (new AccessibleControlAdapter() {
+ public void getDefaultAction (AccessibleControlEvent e) {
+ e.result = isDropped () ? SWT.getMessage ("SWT_Close") : SWT.getMessage ("SWT_Open"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ });
+}
+boolean isDropped () {
+ return popup.getVisible ();
+}
+public boolean isFocusControl () {
+ checkWidget();
+ if (text.isFocusControl () || arrow.isFocusControl () || table.isFocusControl () || popup.isFocusControl ()) {
+ return true;
+ }
+ return super.isFocusControl ();
+}
+void internalLayout (boolean changed) {
+ if (isDropped ()) dropDown (false);
+ Rectangle rect = getClientArea ();
+ int width = rect.width;
+ int height = rect.height;
+ Point arrowSize = arrow.computeSize (SWT.DEFAULT, height, changed);
+ text.setBounds (0, 0, width - arrowSize.x, height);
+ arrow.setBounds (width - arrowSize.x, 0, arrowSize.x, arrowSize.y);
+}
+void listEvent (Event event) {
+ switch (event.type) {
+ case SWT.Dispose:
+ if (getShell () != popup.getParent ()) {
+ TableItem[] items = table.getItems ();
+ int selectionIndex = table.getSelectionIndex ();
+ popup = null;
+ table = null;
+ createPopup (selectionIndex);
+ }
+ break;
+ case SWT.FocusIn: {
+ handleFocus (SWT.FocusIn);
+ break;
+ }
+ case SWT.MouseUp: {
+ if (event.button != 1) return;
+ dropDown (false);
+ break;
+ }
+ case SWT.Selection: {
+ int index = table.getSelectionIndex ();
+ if (index == -1) return;
+ text.setText (table.getItem (index).getText());
+ text.selectAll ();
+ table.setSelection (index);
+ Event e = new Event ();
+ e.time = event.time;
+ e.stateMask = event.stateMask;
+ e.doit = event.doit;
+ notifyListeners (SWT.Selection, e);
+ event.doit = e.doit;
+ break;
+ }
+ case SWT.Traverse: {
+ switch (event.detail) {
+ case SWT.TRAVERSE_RETURN:
+ case SWT.TRAVERSE_ESCAPE:
+ case SWT.TRAVERSE_ARROW_PREVIOUS:
+ case SWT.TRAVERSE_ARROW_NEXT:
+ event.doit = false;
+ break;
+ }
+ Event e = new Event ();
+ e.time = event.time;
+ e.detail = event.detail;
+ e.doit = event.doit;
+ e.character = event.character;
+ e.keyCode = event.keyCode;
+ notifyListeners (SWT.Traverse, e);
+ event.doit = e.doit;
+ event.detail = e.detail;
+ break;
+ }
+ case SWT.KeyUp: {
+ Event e = new Event ();
+ e.time = event.time;
+ e.character = event.character;
+ e.keyCode = event.keyCode;
+ e.stateMask = event.stateMask;
+ notifyListeners (SWT.KeyUp, e);
+ break;
+ }
+ case SWT.KeyDown: {
+ if (event.character == SWT.ESC) {
+ // Escape key cancels popup list
+ dropDown (false);
+ }
+ if ((event.stateMask & SWT.ALT) != 0 && (event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_DOWN)) {
+ dropDown (false);
+ }
+ if (event.character == SWT.CR) {
+ // Enter causes default selection
+ dropDown (false);
+ Event e = new Event ();
+ e.time = event.time;
+ e.stateMask = event.stateMask;
+ notifyListeners (SWT.DefaultSelection, e);
+ }
+ // At this point the widget may have been disposed.
+ // If so, do not continue.
+ if (isDisposed ()) break;
+ Event e = new Event();
+ e.time = event.time;
+ e.character = event.character;
+ e.keyCode = event.keyCode;
+ e.stateMask = event.stateMask;
+ notifyListeners(SWT.KeyDown, e);
+ break;
+
+ }
+ }
+}
+
+void popupEvent(Event event) {
+ switch (event.type) {
+ case SWT.Paint:
+ // draw black rectangle around list
+ Rectangle listRect = table.getBounds();
+ Color black = getDisplay().getSystemColor(SWT.COLOR_BLACK);
+ event.gc.setForeground(black);
+ event.gc.drawRectangle(0, 0, listRect.width + 1, listRect.height + 1);
+ break;
+ case SWT.Close:
+ event.doit = false;
+ dropDown (false);
+ break;
+ case SWT.Deactivate:
+ dropDown (false);
+ break;
+ }
+}
+public void redraw () {
+ super.redraw();
+ text.redraw();
+ arrow.redraw();
+ if (popup.isVisible()) table.redraw();
+}
+public void redraw (int x, int y, int width, int height, boolean all) {
+ super.redraw(x, y, width, height, true);
+}
+
+/**
+ * Removes the item from the receiver's list at the given
+ * zero-relative index.
+ *
+ * @param index the index for the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (int index) {
+ checkWidget();
+ table.remove (index);
+}
+/**
+ * Removes the items from the receiver's list which are
+ * between the given zero-relative start and end
+ * indices (inclusive).
+ *
+ * @param start the start of the range
+ * @param end the end of the range
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if either the start or end are not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (int start, int end) {
+ checkWidget();
+ table.remove (start, end);
+}
+/**
+ * Searches the receiver's list starting at the first item
+ * until an item is found that is equal to the argument,
+ * and removes that item from the list.
+ *
+ * @param string the item to remove
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the string is not found in the list</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void remove (String string) {
+ checkWidget();
+ if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ int index = -1;
+ for (int i = 0, n = table.getItemCount(); i < n; i++) {
+ if (table.getItem(i).getText().equals(string)) {
+ index = i;
+ break;
+ }
+ }
+ remove(index);
+}
+/**
+ * Removes all of the items from the receiver's list and clear the
+ * contents of receiver's text field.
+ * <p>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void removeAll () {
+ checkWidget();
+ text.setText (""); //$NON-NLS-1$
+ table.removeAll ();
+}
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's text is modified.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see ModifyListener
+ * @see #addModifyListener
+ */
+public void removeModifyListener (ModifyListener listener) {
+ checkWidget();
+ if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ removeListener(SWT.Modify, listener);
+}
+/**
+ * Removes the listener from the collection of listeners who will
+ * be notified when the receiver's selection changes.
+ *
+ * @param listener the listener which should no longer be notified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see SelectionListener
+ * @see #addSelectionListener
+ */
+public void removeSelectionListener (SelectionListener listener) {
+ checkWidget();
+ if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ removeListener(SWT.Selection, listener);
+ removeListener(SWT.DefaultSelection,listener);
+}
+/**
+ * Selects the item at the given zero-relative index in the receiver's
+ * list. If the item at the index was already selected, it remains
+ * selected. Indices that are out of range are ignored.
+ *
+ * @param index the index of the item to select
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void select (int index) {
+ checkWidget();
+ if (index == -1) {
+ table.deselectAll ();
+ text.setText (""); //$NON-NLS-1$
+ return;
+ }
+ if (0 <= index && index < table.getItemCount()) {
+ if (index != getSelectionIndex()) {
+ text.setText (table.getItem (index).getText());
+ text.selectAll ();
+ table.select (index);
+ table.showSelection ();
+ }
+ }
+}
+public void setBackground (Color color) {
+ super.setBackground(color);
+ background = color;
+ if (text != null) text.setBackground(color);
+ if (table != null) table.setBackground(color);
+ if (arrow != null) arrow.setBackground(color);
+}
+/**
+ * Sets the editable state.
+ *
+ * @param editable the new editable state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void setEditable (boolean editable) {
+ checkWidget ();
+ text.setEditable(editable);
+}
+public void setEnabled (boolean enabled) {
+ super.setEnabled(enabled);
+ if (popup != null) popup.setVisible (false);
+ if (text != null) text.setEnabled(enabled);
+ if (arrow != null) arrow.setEnabled(enabled);
+}
+public boolean setFocus () {
+ checkWidget();
+ return text.setFocus ();
+}
+public void setFont (Font font) {
+ super.setFont (font);
+ this.font = font;
+ text.setFont (font);
+ table.setFont (font);
+ internalLayout (true);
+}
+public void setForeground (Color color) {
+ super.setForeground(color);
+ foreground = color;
+ if (text != null) text.setForeground(color);
+ if (table != null) table.setForeground(color);
+ if (arrow != null) arrow.setForeground(color);
+}
+/**
+ * Sets the text of the item in the receiver's list at the given
+ * zero-relative index to the string argument. This is equivalent
+ * to <code>remove</code>'ing the old item at the index, and then
+ * <code>add</code>'ing the new item at that index.
+ *
+ * @param index the index for the item
+ * @param string the new text for the item
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setItem (int index, String string, Image image) {
+ checkWidget();
+ remove(index);
+ add(string,image,index);
+}
+/**
+ * Sets the receiver's list to be the given array of items.
+ *
+ * @param items the array of items
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the items array is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if an item in the items array is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setItems (String [] items) {
+ checkWidget ();
+ this.table.removeAll();
+ for (int i = 0, n = items.length; i < n; i++) {
+ add(items[i],null);
+ }
+ if (!text.getEditable ()) text.setText (""); //$NON-NLS-1$
+}
+
+/**
+ * Sets the layout which is associated with the receiver to be
+ * the argument which may be null.
+ * <p>
+ * Note : No Layout can be set on this Control because it already
+ * manages the size and position of its children.
+ * </p>
+ *
+ * @param layout the receiver's new layout or null
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setLayout (Layout layout) {
+ checkWidget ();
+ return;
+}
+/**
+ * Sets the selection in the receiver's text field to the
+ * range specified by the argument whose x coordinate is the
+ * start of the selection and whose y coordinate is the end
+ * of the selection.
+ *
+ * @param selection a point representing the new selection start and end
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setSelection (Point selection) {
+ checkWidget();
+ if (selection == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ text.setSelection (selection.x, selection.y);
+}
+
+/**
+ * Sets the contents of the receiver's text field to the
+ * given string.
+ * <p>
+ * Note: The text field in a <code>Combo</code> is typically
+ * only capable of displaying a single line of text. Thus,
+ * setting the text to a string containing line breaks or
+ * other special characters will probably cause it to
+ * display incorrectly.
+ * </p>
+ *
+ * @param string the new text
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText (String string) {
+ checkWidget();
+ if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ int index = -1;
+ for (int i = 0, n = table.getItemCount(); i < n; i++) {
+ if (table.getItem(i).getText().equals(string)) {
+ index = i;
+ break;
+ }
+ }
+ if (index == -1) {
+ table.deselectAll ();
+ text.setText (string);
+ return;
+ }
+ text.setText (string);
+ text.selectAll ();
+ table.setSelection (index);
+ table.showSelection ();
+}
+/**
+ * Sets the maximum number of characters that the receiver's
+ * text field is capable of holding to be the argument.
+ *
+ * @param limit new text limit
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_CANNOT_BE_ZERO - if the limit is zero</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setTextLimit (int limit) {
+ checkWidget();
+ text.setTextLimit (limit);
+}
+
+public void setToolTipText (String string) {
+ checkWidget();
+ super.setToolTipText(string);
+ arrow.setToolTipText (string);
+ text.setToolTipText (string);
+}
+
+public void setVisible (boolean visible) {
+ super.setVisible(visible);
+ if (!visible) popup.setVisible(false);
+}
+/**
+ * Sets the number of items that are visible in the drop
+ * down portion of the receiver's list.
+ *
+ * @param count the new number of items to be visible
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void setVisibleItemCount (int count) {
+ checkWidget ();
+ if (count < 0) return;
+ visibleItemCount = count;
+}
+String stripMnemonic (String string) {
+ int index = 0;
+ int length = string.length ();
+ do {
+ while ((index < length) && (string.charAt (index) != '&')) index++;
+ if (++index >= length) return string;
+ if (string.charAt (index) != '&') {
+ return string.substring(0, index-1) + string.substring(index, length);
+ }
+ index++;
+ } while (index < length);
+ return string;
+}
+void textEvent (Event event) {
+ switch (event.type) {
+ case SWT.FocusIn: {
+ handleFocus (SWT.FocusIn);
+ break;
+ }
+ case SWT.KeyDown: {
+ if (event.character == SWT.CR) {
+ dropDown (false);
+ Event e = new Event ();
+ e.time = event.time;
+ e.stateMask = event.stateMask;
+ notifyListeners (SWT.DefaultSelection, e);
+ }
+ //At this point the widget may have been disposed.
+ // If so, do not continue.
+ if (isDisposed ()) break;
+
+ if (event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_DOWN) {
+ event.doit = false;
+ if ((event.stateMask & SWT.ALT) != 0) {
+ boolean dropped = isDropped ();
+ text.selectAll ();
+ if (!dropped) setFocus ();
+ dropDown (!dropped);
+ break;
+ }
+
+ int oldIndex = getSelectionIndex ();
+ if (event.keyCode == SWT.ARROW_UP) {
+ select (Math.max (oldIndex - 1, 0));
+ } else {
+ select (Math.min (oldIndex + 1, getItemCount () - 1));
+ }
+ if (oldIndex != getSelectionIndex ()) {
+ Event e = new Event();
+ e.time = event.time;
+ e.stateMask = event.stateMask;
+ notifyListeners (SWT.Selection, e);
+ }
+ //At this point the widget may have been disposed.
+ // If so, do not continue.
+ if (isDisposed ()) break;
+ }
+
+ // Further work : Need to add support for incremental search in
+ // pop up list as characters typed in text widget
+
+ Event e = new Event ();
+ e.time = event.time;
+ e.character = event.character;
+ e.keyCode = event.keyCode;
+ e.stateMask = event.stateMask;
+ notifyListeners (SWT.KeyDown, e);
+ break;
+ }
+ case SWT.KeyUp: {
+ Event e = new Event ();
+ e.time = event.time;
+ e.character = event.character;
+ e.keyCode = event.keyCode;
+ e.stateMask = event.stateMask;
+ notifyListeners (SWT.KeyUp, e);
+ break;
+ }
+ case SWT.Modify: {
+ table.deselectAll ();
+ Event e = new Event ();
+ e.time = event.time;
+ notifyListeners (SWT.Modify, e);
+ break;
+ }
+ case SWT.MouseDown: {
+ if (event.button != 1) return;
+ if (text.getEditable ()) return;
+ boolean dropped = isDropped ();
+ text.selectAll ();
+ if (!dropped) setFocus ();
+ dropDown (!dropped);
+ break;
+ }
+ case SWT.MouseUp: {
+ if (event.button != 1) return;
+ if (text.getEditable ()) return;
+ text.selectAll ();
+ break;
+ }
+ case SWT.Traverse: {
+ switch (event.detail) {
+ case SWT.TRAVERSE_RETURN:
+ case SWT.TRAVERSE_ARROW_PREVIOUS:
+ case SWT.TRAVERSE_ARROW_NEXT:
+ // The enter causes default selection and
+ // the arrow keys are used to manipulate the list contents so
+ // do not use them for traversal.
+ event.doit = false;
+ break;
+ }
+
+ Event e = new Event ();
+ e.time = event.time;
+ e.detail = event.detail;
+ e.doit = event.doit;
+ e.character = event.character;
+ e.keyCode = event.keyCode;
+ notifyListeners (SWT.Traverse, e);
+ event.doit = e.doit;
+ event.detail = e.detail;
+ break;
+ }
+ }
+}
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingEntryDialog.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingEntryDialog.java
new file mode 100644
index 0000000000..277cd15bd4
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingEntryDialog.java
@@ -0,0 +1,615 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.language.settings.providers;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+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.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
+import org.eclipse.cdt.core.settings.model.ICSettingEntry;
+import org.eclipse.cdt.core.settings.model.util.CDataUtil;
+import org.eclipse.cdt.ui.CDTSharedImages;
+import org.eclipse.cdt.ui.newui.AbstractCPropertyTab;
+import org.eclipse.cdt.ui.newui.AbstractPropertyDialog;
+
+import org.eclipse.cdt.internal.ui.ImageCombo;
+import org.eclipse.cdt.internal.ui.newui.LanguageSettingsImages;
+import org.eclipse.cdt.internal.ui.newui.Messages;
+
+/**
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class LanguageSettingEntryDialog extends AbstractPropertyDialog {
+ private static final String SLASH = "/"; //$NON-NLS-1$
+
+ private ICConfigurationDescription cfgDescription;
+ private IProject project;
+ private ICLanguageSettingEntry entry;
+ private boolean clearValue;
+ private int kind;
+
+ private Composite compositeArea;
+ private Label iconComboKind;
+ private ImageCombo comboKind;
+ private ImageCombo comboPathCategory;
+ private Label labelInput;
+ public Text inputName;
+ private Label checkBoxValue;
+ public Text inputValue;
+ private Button buttonBrowse;
+ private Button buttonVars;
+ private Button checkBoxBuiltIn;
+ private Button checkBoxFramework;
+
+ private Button buttonOk;
+ private Button buttonCancel;
+
+ private static final int COMBO_INDEX_INCLUDE_PATH = 0;
+ private static final int COMBO_INDEX_MACRO = 1;
+ private static final int COMBO_INDEX_INCLUDE_FILE = 2;
+ private static final int COMBO_INDEX_MACRO_FILE = 3;
+ private static final int COMBO_INDEX_LIBRARY_PATH = 4;
+ private static final int COMBO_INDEX_LIBRARY_FILE = 5;
+
+ final private String [] comboKindItems = {
+ Messages.LanguageSettingEntryDialog_IncludeDirectory,
+ Messages.LanguageSettingEntryDialog_PreporocessorMacro,
+ Messages.LanguageSettingEntryDialog_IncludeFile,
+ Messages.LanguageSettingEntryDialog_PreprocessorMacroFile,
+ Messages.LanguageSettingEntryDialog_LibraryPath,
+ Messages.LanguageSettingEntryDialog_Library,
+ };
+ final private Image[] comboKindImages = {
+ CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_INCLUDES_FOLDER),
+ CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_MACRO),
+ CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_TUNIT_HEADER),
+ CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_MACROS_FILE),
+ CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_LIBRARY_FOLDER),
+ CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_LIBRARY),
+ };
+
+ private static final int COMBO_PATH_INDEX_PROJECT = 0;
+ private static final int COMBO_PATH_INDEX_WORKSPACE = 1;
+ private static final int COMBO_PATH_INDEX_FILESYSTEM = 2;
+
+ final private String [] pathCategories = {
+ Messages.LanguageSettingEntryDialog_ProjectPath,
+ Messages.LanguageSettingEntryDialog_WorkspacePath,
+ Messages.LanguageSettingEntryDialog_Filesystem,
+ };
+ final private Image[] pathCategoryImages = {
+ CDTSharedImages.getImage(CDTSharedImages.IMG_ETOOL_PROJECT),
+ CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_WORKSPACE),
+ CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_FILESYSTEM),
+ };
+
+ private ICLanguageSettingEntry[] entries;
+
+
+ public LanguageSettingEntryDialog(Shell parent, ICConfigurationDescription cfgDescription, int kind) {
+ super(parent, ""); //$NON-NLS-1$
+ this.cfgDescription = cfgDescription;
+ this.project = cfgDescription.getProjectDescription().getProject();
+ this.entry = null;
+ this.clearValue = true;
+ this.kind = kind;
+ }
+
+ /**
+ * This constructor is intended to be used with {@code clearValue=true} for "Add" dialogs
+ * where provided entry is used as a template.
+ */
+ public LanguageSettingEntryDialog(Shell parent, ICConfigurationDescription cfgDescription, ICLanguageSettingEntry entry, boolean clearValue) {
+ super(parent, ""); //$NON-NLS-1$
+ this.cfgDescription = cfgDescription;
+ this.project = cfgDescription.getProjectDescription().getProject();
+ this.entry = entry;
+ this.kind = entry!=null ? entry.getKind() : ICSettingEntry.INCLUDE_PATH;
+ this.clearValue = clearValue;
+ }
+
+ /**
+ * This constructor is used for "Edit" dialogs to edit provided entry
+ */
+ public LanguageSettingEntryDialog(Shell parent, ICConfigurationDescription cfgDescription, ICLanguageSettingEntry entry) {
+ this(parent, cfgDescription, entry, false);
+ }
+
+ private int comboIndexToKind(int index) {
+ int kind=0;
+ switch (index) {
+ case COMBO_INDEX_INCLUDE_PATH:
+ kind = ICSettingEntry.INCLUDE_PATH;
+ break;
+ case COMBO_INDEX_MACRO:
+ kind = ICSettingEntry.MACRO;
+ break;
+ case COMBO_INDEX_INCLUDE_FILE:
+ kind = ICSettingEntry.INCLUDE_FILE;
+ break;
+ case COMBO_INDEX_MACRO_FILE:
+ kind = ICSettingEntry.MACRO_FILE;
+ break;
+ case COMBO_INDEX_LIBRARY_PATH:
+ kind = ICSettingEntry.LIBRARY_PATH;
+ break;
+ case COMBO_INDEX_LIBRARY_FILE:
+ kind = ICSettingEntry.LIBRARY_FILE;
+ break;
+ }
+ return kind;
+ }
+
+ private int kindToComboIndex(int kind) {
+ int index=0;
+ switch (kind) {
+ case ICSettingEntry.INCLUDE_PATH:
+ index = COMBO_INDEX_INCLUDE_PATH;
+ break;
+ case ICSettingEntry.MACRO:
+ index = COMBO_INDEX_MACRO;
+ break;
+ case ICSettingEntry.INCLUDE_FILE:
+ index = COMBO_INDEX_INCLUDE_FILE;
+ break;
+ case ICSettingEntry.MACRO_FILE:
+ index = COMBO_INDEX_MACRO_FILE;
+ break;
+ case ICSettingEntry.LIBRARY_PATH:
+ index = COMBO_INDEX_LIBRARY_PATH;
+ break;
+ case ICSettingEntry.LIBRARY_FILE:
+ index = COMBO_INDEX_LIBRARY_FILE;
+ break;
+ }
+ return index;
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ parent.setLayout(new GridLayout(4, false));
+ GridData gd;
+
+ // Composite for the dialog area
+ compositeArea = new Composite (parent, SWT.NONE);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.verticalAlignment = SWT.TOP;
+ gd.horizontalSpan = 7;
+ compositeArea.setLayoutData(gd);
+ compositeArea.setLayout(new GridLayout(7, false));
+
+ // Icon for kind
+ iconComboKind = new Label (compositeArea, SWT.NONE);
+ gd = new GridData();
+ gd.verticalAlignment = SWT.TOP;
+ gd.horizontalAlignment = SWT.RIGHT;
+ iconComboKind.setLayoutData(gd);
+ iconComboKind.setText(Messages.LanguageSettingEntryDialog_SelectKind);
+ int kindToComboIndex = kindToComboIndex(kind);
+ iconComboKind.setImage(comboKindImages[kindToComboIndex]);
+
+ // Combo for the setting entry kind
+ comboKind = new ImageCombo(compositeArea, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER);
+ for (int i = 0; i < comboKindItems.length; i++) {
+ comboKind.add(comboKindItems[i], comboKindImages[i]);
+ }
+ comboKind.setText(comboKindItems[kindToComboIndex]);
+
+ comboKind.addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateImages();
+ setButtons();
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+
+ }
+ });
+ comboKind.setEnabled(clearValue);
+
+ // Icon for path category
+ final Label comboPathCategoryIcon = new Label (compositeArea, SWT.NONE);
+ gd = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_END);
+ gd.verticalAlignment = SWT.TOP;
+ gd.widthHint = 15;
+ comboPathCategoryIcon.setLayoutData(gd);
+ comboPathCategoryIcon.setText(""); //$NON-NLS-1$
+
+ // Combo for path category
+ comboPathCategory = new ImageCombo(compositeArea, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER);
+ for (int i = 0; i < pathCategories.length; i++) {
+ comboPathCategory.add(pathCategories[i], pathCategoryImages[i]);
+ }
+ int pcindex = COMBO_PATH_INDEX_PROJECT;
+ if (entry != null) {
+ if ((entry.getFlags() & ICSettingEntry.VALUE_WORKSPACE_PATH) == 0) {
+ pcindex = COMBO_PATH_INDEX_FILESYSTEM;
+ } else {
+ if (entry.getName().startsWith(SLASH)) {
+ pcindex = COMBO_PATH_INDEX_WORKSPACE;
+ } else {
+ pcindex = COMBO_PATH_INDEX_PROJECT;
+ }
+ }
+
+ }
+ comboPathCategory.setText(pathCategories[pcindex]);
+ gd = new GridData(SWT.FILL, SWT.NONE, false, false);
+ gd.verticalAlignment = SWT.TOP;
+ gd.horizontalSpan = 4;
+ comboPathCategory.setLayoutData(gd);
+
+ comboPathCategory.addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateImages();
+ setButtons();
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+
+ }
+ });
+
+ // Dir/File/Name label
+ labelInput = new Label(compositeArea, SWT.NONE);
+ labelInput.setText(Messages.LanguageSettingEntryDialog_Directory);
+ gd = new GridData();
+ labelInput.setLayoutData(gd);
+
+ // Dir/File/Name input
+ inputName = new Text(compositeArea, SWT.SINGLE | SWT.BORDER);
+ if (entry!=null && !clearValue) {
+ inputName.setText(entry.getName());
+ }
+ gd = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ gd.widthHint = 200;
+ inputName.setLayoutData(gd);
+ inputName.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ setButtons();
+ }});
+
+ inputName.setFocus();
+ inputName.setSelection(0, inputName.getText().length());
+
+ // Value label
+ checkBoxValue = new Label(compositeArea, SWT.NONE);
+ checkBoxValue.setText(Messages.LanguageSettingEntryDialog_Value);
+ gd = new GridData();
+ checkBoxValue.setLayoutData(gd);
+
+ // Path button
+ buttonBrowse = new Button(compositeArea, SWT.PUSH);
+ buttonBrowse.setText("..."); //$NON-NLS-1$
+ buttonBrowse.setImage(pathCategoryImages[0]);
+ buttonBrowse.setLayoutData(new GridData());
+ buttonBrowse.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ buttonPressed(event);
+ }
+ });
+
+ // Variables button
+ buttonVars = new Button(compositeArea, SWT.PUSH);
+ buttonVars.setText(AbstractCPropertyTab.VARIABLESBUTTON_NAME);
+ buttonVars.setLayoutData(new GridData());
+ buttonVars.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ buttonPressed(event);
+ }
+ });
+
+ // Value input. Located after the other controls to get sufficient width
+ int comboPathWidth = comboPathCategory.computeSize(SWT.DEFAULT, SWT.NONE).x;
+ inputValue = new Text(compositeArea, SWT.SINGLE | SWT.BORDER);
+ if (entry != null && !clearValue) {
+ inputValue.setText(entry.getValue());
+ }
+ gd = new GridData(SWT.FILL, SWT.NONE, false, false);
+ gd.widthHint = comboPathWidth;
+ inputValue.setLayoutData(gd);
+
+ if (entry != null && kind == ICSettingEntry.MACRO && !clearValue) {
+ inputValue.setFocus();
+ inputValue.setSelection(0, inputValue.getText().length());
+ }
+
+ // Checkboxes
+ Composite compCheckboxes = new Composite (parent, SWT.NONE);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.verticalAlignment = SWT.TOP;
+ gd.horizontalSpan = 4;
+ compCheckboxes.setLayoutData(gd);
+ compCheckboxes.setLayout(new GridLayout(1, false));
+
+ // Checkbox "Built-In"
+ checkBoxBuiltIn = new Button(compCheckboxes, SWT.CHECK);
+ checkBoxBuiltIn.setText(Messages.LanguageSettingEntryDialog_BuiltInFlag);
+ checkBoxBuiltIn.setSelection(entry!=null && (entry.getFlags()&ICSettingEntry.BUILTIN)!=0);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ checkBoxBuiltIn.setLayoutData(gd);
+ checkBoxBuiltIn.addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateImages();
+ setButtons();
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+
+ // Checkbox "Framework"
+ checkBoxFramework = new Button(compCheckboxes, SWT.CHECK);
+ checkBoxFramework.setText(Messages.LanguageSettingEntryDialog_FrameworkFolder);
+ checkBoxFramework.setSelection(entry!=null && (entry.getFlags()&ICSettingEntry.FRAMEWORKS_MAC)!=0);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ checkBoxFramework.setLayoutData(gd);
+ checkBoxFramework.addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateImages();
+ setButtons();
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+
+ // Buttons
+ Composite compButtons = new Composite (parent, SWT.FILL);
+ gd = new GridData(SWT.RIGHT, SWT.BOTTOM, false, false);
+ gd.horizontalSpan = 4;
+ gd.grabExcessVerticalSpace = true;
+ compButtons.setLayoutData(gd);
+ compButtons.setLayout(new GridLayout(4, false));
+
+ // placeholder
+ Label placeholder = new Label(compButtons, 0);
+ placeholder.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL));
+
+ // Button OK
+ buttonOk = new Button(compButtons, SWT.PUSH);
+ buttonOk.setText(IDialogConstants.OK_LABEL);
+ gd = new GridData();
+ gd.widthHint = buttonVars.computeSize(SWT.DEFAULT,SWT.NONE).x;
+ buttonOk.setLayoutData(gd);
+ buttonOk.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ buttonPressed(event);
+ }
+ });
+
+ // Button Cancel
+ buttonCancel = new Button(compButtons, SWT.PUSH);
+ buttonCancel.setText(IDialogConstants.CANCEL_LABEL);
+ gd = new GridData();
+ gd.widthHint = buttonVars.computeSize(SWT.DEFAULT, SWT.NONE).x;
+ buttonCancel.setLayoutData(gd);
+ buttonCancel.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ buttonPressed(event);
+ }
+ });
+
+ parent.getShell().setDefaultButton(buttonOk);
+ parent.pack();
+
+ updateImages();
+ setButtons();
+ return parent;
+ }
+
+ private void setButtons() {
+ int kindSelectionIndex = comboKind.getSelectionIndex();
+ boolean isMacroSelected = (kindSelectionIndex == COMBO_INDEX_MACRO);
+ comboPathCategory.setVisible(!isMacroSelected);
+ buttonBrowse.setVisible(!isMacroSelected);
+ buttonVars.setVisible(!isMacroSelected);
+ checkBoxValue.setVisible(isMacroSelected);
+ inputValue.setVisible(isMacroSelected);
+
+ ((GridData)checkBoxValue.getLayoutData()).exclude = !isMacroSelected;
+ ((GridData)inputValue.getLayoutData()).exclude = !isMacroSelected;
+
+ ((GridData)buttonBrowse.getLayoutData()).exclude = isMacroSelected;
+ ((GridData)buttonVars.getLayoutData()).exclude = isMacroSelected;
+
+ switch (kindSelectionIndex) {
+ case COMBO_INDEX_INCLUDE_PATH:
+ case COMBO_INDEX_LIBRARY_PATH:
+ labelInput.setText(Messages.LanguageSettingEntryDialog_Path);
+ break;
+ case COMBO_INDEX_INCLUDE_FILE:
+ case COMBO_INDEX_MACRO_FILE:
+ case COMBO_INDEX_LIBRARY_FILE:
+ labelInput.setText(Messages.LanguageSettingEntryDialog_File);
+ break;
+ case COMBO_INDEX_MACRO:
+ default:
+ labelInput.setText(Messages.LanguageSettingEntryDialog_Name);
+ }
+
+ inputValue.setEnabled(isMacroSelected);
+
+ int indexPathKind = comboPathCategory.getSelectionIndex();
+ boolean isProjectSelected = (indexPathKind == COMBO_PATH_INDEX_PROJECT);
+ boolean isWorkspaceSelected = (indexPathKind == COMBO_PATH_INDEX_WORKSPACE);
+ boolean isFilesystemSelected = (indexPathKind == COMBO_PATH_INDEX_FILESYSTEM);
+
+ String path = inputName.getText();
+ if (path.trim().length() == 0) {
+ buttonOk.setEnabled(false);
+ } else {
+ buttonOk.setEnabled((isProjectSelected && !path.startsWith(SLASH)) ||
+ (isWorkspaceSelected && path.startsWith(SLASH)) || isFilesystemSelected);
+ }
+
+ buttonVars.setEnabled(isFilesystemSelected);
+
+ compositeArea.layout(true);
+ }
+
+ @Override
+ public void buttonPressed(SelectionEvent e) {
+ String str = null;
+ if (e.widget.equals(buttonOk)) {
+ String name = inputName.getText();
+ text1 = name;
+ String value = inputValue.getText();
+ result = true;
+
+ int flagBuiltIn = checkBoxBuiltIn.getSelection() ? ICSettingEntry.BUILTIN : 0;
+ int flagFramework = checkBoxFramework.getSelection() ? ICSettingEntry.FRAMEWORKS_MAC : 0;
+ int indexPathKind = comboPathCategory.getSelectionIndex();
+ int kind = comboKind.getSelectionIndex();
+ boolean isProjectPath = indexPathKind==COMBO_PATH_INDEX_PROJECT;
+ boolean isWorkspacePath = (kind!=COMBO_INDEX_MACRO) && (isProjectPath || indexPathKind==COMBO_PATH_INDEX_WORKSPACE);
+ int flagWorkspace = isWorkspacePath ? ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED : 0;
+ int flags = flagBuiltIn | flagWorkspace | flagFramework;
+
+ ICLanguageSettingEntry entry=null;
+ switch (comboKind.getSelectionIndex()) {
+ case COMBO_INDEX_INCLUDE_PATH:
+ entry = CDataUtil.createCIncludePathEntry(name, flags);
+ break;
+ case COMBO_INDEX_MACRO:
+ // note that value=null is not supported by CMacroEntry
+ entry = CDataUtil.createCMacroEntry(name, value, flags);
+ break;
+ case COMBO_INDEX_INCLUDE_FILE:
+ entry = CDataUtil.createCIncludeFileEntry(name, flags);
+ break;
+ case COMBO_INDEX_MACRO_FILE:
+ entry = CDataUtil.createCMacroFileEntry(name, flags);
+ break;
+ case COMBO_INDEX_LIBRARY_PATH:
+ entry = CDataUtil.createCLibraryPathEntry(name, flags);
+ break;
+ case COMBO_INDEX_LIBRARY_FILE:
+ entry = CDataUtil.createCLibraryFileEntry(name, flags);
+ break;
+ default:
+ result = false;
+ }
+
+ entries = new ICLanguageSettingEntry[] {entry};
+ shell.dispose();
+ } else if (e.widget.equals(buttonCancel)) {
+ shell.dispose();
+ } else if (e.widget.equals(buttonBrowse)) {
+ boolean isDirectory = false;
+ boolean isFile = false;
+ switch (comboKind.getSelectionIndex()) {
+ case COMBO_INDEX_INCLUDE_PATH:
+ case COMBO_INDEX_LIBRARY_PATH:
+ isDirectory = true;
+ break;
+ case COMBO_INDEX_INCLUDE_FILE:
+ case COMBO_INDEX_MACRO_FILE:
+ case COMBO_INDEX_LIBRARY_FILE:
+ isFile = true;
+ break;
+ case COMBO_INDEX_MACRO:
+ break;
+ }
+
+ if (isDirectory) {
+ switch (comboPathCategory.getSelectionIndex()) {
+ case COMBO_PATH_INDEX_WORKSPACE:
+ str = AbstractCPropertyTab.getWorkspaceDirDialog(shell, inputName.getText());
+ break;
+ case COMBO_PATH_INDEX_PROJECT:
+ str = AbstractCPropertyTab.getProjectDirDialog(shell, inputName.getText(), project);
+ break;
+ case COMBO_PATH_INDEX_FILESYSTEM:
+ str = AbstractCPropertyTab.getFileSystemDirDialog(shell, inputName.getText());
+ break;
+ }
+ } else if (isFile) {
+ switch (comboPathCategory.getSelectionIndex()) {
+ case COMBO_PATH_INDEX_WORKSPACE:
+ str = AbstractCPropertyTab.getWorkspaceFileDialog(shell, inputName.getText());
+ break;
+ case COMBO_PATH_INDEX_PROJECT:
+ str = AbstractCPropertyTab.getProjectFileDialog(shell, inputName.getText(), project);
+ break;
+ case COMBO_PATH_INDEX_FILESYSTEM:
+ str = AbstractCPropertyTab.getFileSystemFileDialog(shell, inputName.getText());
+ break;
+ }
+ }
+
+ if (str != null) {
+ str = strip_wsp(str);
+ if (comboPathCategory.getSelectionIndex()==COMBO_PATH_INDEX_PROJECT && str.startsWith(SLASH+project.getName()+SLASH)) {
+ str=str.substring(project.getName().length()+2);
+ }
+ inputName.setText(str);
+ }
+ } else if (e.widget.equals(buttonVars)) {
+ str = AbstractCPropertyTab.getVariableDialog(shell, cfgDescription);
+ if (str != null) inputName.insert(str);
+ }
+ }
+
+ public ICLanguageSettingEntry[] getEntries() {
+ return entries;
+ }
+
+ private void updateImages() {
+ int indexEntryKind = comboKind.getSelectionIndex();
+ int indexPathKind = comboPathCategory.getSelectionIndex();
+ shell.setText(Messages.LanguageSettingEntryDialog_Add + comboKindItems[indexEntryKind]);
+
+ int kind = comboIndexToKind(indexEntryKind);
+ int flagBuiltin = checkBoxBuiltIn.getSelection() ? ICSettingEntry.BUILTIN : 0;
+ int flagFramework = checkBoxFramework.getSelection() ? ICSettingEntry.FRAMEWORKS_MAC : 0;
+ boolean isWorkspacePath = indexPathKind==COMBO_PATH_INDEX_PROJECT || indexPathKind==COMBO_PATH_INDEX_WORKSPACE;
+ int flagWorkspace = isWorkspacePath ? ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED : 0;
+ int flags = flagBuiltin | flagWorkspace | flagFramework;
+ Image image = LanguageSettingsImages.getImage(kind, flags, indexPathKind==COMBO_PATH_INDEX_PROJECT);
+
+ iconComboKind.setImage(image);
+ shell.setImage(image);
+
+ buttonBrowse.setImage(pathCategoryImages[indexPathKind]);
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java
new file mode 100644
index 0000000000..f708569a2b
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java
@@ -0,0 +1,1134 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.language.settings.providers;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+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.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsBroadcastingProvider;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsEditableProvider;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsBaseProvider;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
+import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.model.LanguageManager;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
+import org.eclipse.cdt.core.settings.model.ICResourceDescription;
+import org.eclipse.cdt.core.settings.model.ICSettingEntry;
+import org.eclipse.cdt.ui.CDTSharedImages;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.newui.AbstractCPropertyTab;
+import org.eclipse.cdt.ui.newui.CDTPrefUtil;
+
+import org.eclipse.cdt.internal.ui.newui.LanguageSettingsImages;
+import org.eclipse.cdt.internal.ui.newui.Messages;
+import org.eclipse.cdt.internal.ui.newui.StatusMessageLine;
+
+/**
+ * This tab presents language settings entries categorized by language
+ * settings providers.
+ *
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class LanguageSettingsEntriesTab extends AbstractCPropertyTab {
+ private static final int[] DEFAULT_ENTRIES_SASH_WEIGHTS = new int[] { 10, 30 };
+
+ private SashForm sashFormEntries;
+ private Tree treeLanguages;
+ private Tree treeEntries;
+ private TreeViewer treeEntriesViewer;
+ private String currentLanguageId = null;
+ private static String currentLanguageIdGlobal = null;
+
+ private Button builtInCheckBox;
+ private Button enableProvidersCheckBox;
+ private StatusMessageLine fStatusLine;
+
+ private LanguageSettingsProvidersPage masterPropertyPage = null;
+
+ private static final int BUTTON_ADD = 0;
+ private static final int BUTTON_EDIT = 1;
+ private static final int BUTTON_DELETE = 2;
+ // there is a separator instead of button #3
+ private static final int BUTTON_MOVE_UP = 4;
+ private static final int BUTTON_MOVE_DOWN = 5;
+
+ private static final String[] BUTTON_LABELS = new String[6];
+ {
+ BUTTON_LABELS[BUTTON_ADD] = ADD_STR;
+ BUTTON_LABELS[BUTTON_EDIT] = EDIT_STR;
+ BUTTON_LABELS[BUTTON_DELETE] = DEL_STR;
+ BUTTON_LABELS[BUTTON_MOVE_UP] = MOVEUP_STR;
+ BUTTON_LABELS[BUTTON_MOVE_DOWN] = MOVEDOWN_STR;
+ }
+
+ private static final String CLEAR_STR = Messages.LanguageSettingsProviderTab_Clear;
+
+ private Map<String, List<ILanguageSettingsProvider>> initialProvidersMap = new HashMap<String, List<ILanguageSettingsProvider>>();
+
+ /**
+ * Label provider for language settings providers displayed by this tab.
+ */
+ private class EntriesTreeLabelProvider extends LanguageSettingsProvidersLabelProvider {
+ @Override
+ protected String[] getOverlayKeys(ILanguageSettingsProvider provider) {
+ String[] overlayKeys = super.getOverlayKeys(provider);
+
+ if (currentLanguageId != null) {
+ IResource rc = getResource();
+ List<ICLanguageSettingEntry> entries = getSettingEntries(provider);
+ if (entries == null && !(rc instanceof IProject)) {
+ List<ICLanguageSettingEntry> entriesParent = getSettingEntriesUpResourceTree(provider);
+ if (entriesParent != null) {
+ overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_PARENT;
+ }
+ } else if (provider instanceof ILanguageSettingsBroadcastingProvider && (page.isForFile() || page.isForFolder())) {
+ // Assuming that the default entries for a resource are always null.
+ // Using that for performance reasons. See note in performDefaults().
+ List<ICLanguageSettingEntry> entriesParent = provider.getSettingEntries(null, null, currentLanguageId);
+ if (entries != null && !entries.equals(entriesParent)) {
+ overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_SETTING;
+ }
+ }
+ }
+
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ List<ILanguageSettingsProvider> initialProviders = initialProvidersMap.get(cfgDescription.getId());
+ if (initialProviders != null && !initialProviders.contains(provider)) {
+ overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_EDITED;
+ }
+ return overlayKeys;
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof ICLanguageSettingEntry) {
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ return LanguageSettingsImages.getImage((ICLanguageSettingEntry) element, cfgDescription);
+ }
+
+ return super.getImage(element);
+ }
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof ICLanguageSettingEntry) {
+ ICLanguageSettingEntry entry = (ICLanguageSettingEntry) element;
+ String s = entry.getName();
+ if ((entry.getKind() == ICSettingEntry.MACRO) && (entry.getFlags()&ICSettingEntry.UNDEFINED) == 0) {
+ s = s + '=' + entry.getValue();
+ }
+ return s;
+ }
+
+ return super.getText(element);
+ }
+ }
+
+ /**
+ * Content provider for setting entries tree.
+ */
+ private class EntriesTreeContentProvider implements ITreeContentProvider {
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof Object[])
+ return (Object[]) parentElement;
+
+ if (parentElement instanceof ILanguageSettingsProvider) {
+ ILanguageSettingsProvider lsProvider = (ILanguageSettingsProvider)parentElement;
+ List<ICLanguageSettingEntry> entriesList = getSettingEntriesUpResourceTree(lsProvider);
+ if (entriesList == null) {
+ return null;
+ }
+
+ // convert to modifiable list
+ entriesList = new ArrayList<ICLanguageSettingEntry>(entriesList);
+
+ if (builtInCheckBox.getSelection() == false) {
+ for (Iterator<ICLanguageSettingEntry> iter = entriesList.iterator(); iter.hasNext();) {
+ ICLanguageSettingEntry entry = iter.next();
+ if (entry.isBuiltIn()) {
+ iter.remove();
+ }
+ }
+ }
+ return entriesList.toArray();
+ }
+
+ return null;
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ return null;
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ Object[] children = getChildren(element);
+ return children!=null && children.length>0;
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ }
+
+ /**
+ * Shortcut for getting the current resource for the property page.
+ */
+ private IResource getResource() {
+ return (IResource)page.getElement();
+ }
+
+ /**
+ * Shortcut for getting the current configuration description.
+ */
+ private ICConfigurationDescription getConfigurationDescription() {
+ return getResDesc().getConfiguration();
+ }
+
+ /**
+ * Shortcut for getting the currently selected provider.
+ */
+ private ILanguageSettingsProvider getSelectedProvider() {
+ ILanguageSettingsProvider provider = null;
+
+ TreeItem[] items = treeEntries.getSelection();
+ if (items.length == 1) {
+ TreeItem item = items[0];
+ Object itemData = item.getData();
+ if (itemData instanceof ICLanguageSettingEntry) {
+ item = item.getParentItem();
+ if (item != null) {
+ itemData = item.getData();
+ }
+ }
+ if (itemData instanceof ILanguageSettingsProvider) {
+ provider = (ILanguageSettingsProvider)itemData;
+ }
+ }
+
+ return provider;
+ }
+
+ /**
+ * Shortcut for getting the currently selected setting entry.
+ */
+ private ICLanguageSettingEntry getSelectedEntry() {
+ ICLanguageSettingEntry entry = null;
+
+ TreeItem[] items = treeEntries.getSelection();
+ if (items.length == 1) {
+ TreeItem item = items[0];
+ Object itemData = item.getData();
+ if (itemData instanceof ICLanguageSettingEntry) {
+ entry = (ICLanguageSettingEntry)itemData;
+ }
+ }
+
+ return entry;
+ }
+
+ /**
+ * Shortcut for getting setting entries for current context. {@link LanguageSettingsManager}
+ * will be checking parent resources if no settings defined for current resource.
+ *
+ * @return list of setting entries for the current context.
+ */
+ private List<ICLanguageSettingEntry> getSettingEntriesUpResourceTree(ILanguageSettingsProvider provider) {
+ if (currentLanguageId == null)
+ return null;
+
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ IResource rc = getResource();
+ List<ICLanguageSettingEntry> entries = LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, cfgDescription, rc, currentLanguageId);
+ return entries;
+ }
+
+ /**
+ * Shortcut for getting setting entries for current context without checking the parent resource.
+ * @return list of setting entries for the current context.
+ */
+ private List<ICLanguageSettingEntry> getSettingEntries(ILanguageSettingsProvider provider) {
+ if (currentLanguageId==null)
+ return null;
+
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ IResource rc = getResource();
+ return provider.getSettingEntries(cfgDescription, rc, currentLanguageId);
+ }
+
+ /**
+ * Store original providers to be able to tell whether they were changed by user.
+ */
+ private void trackInitialSettings() {
+ if (!page.isForPrefs()) {
+ ICConfigurationDescription[] cfgDescriptions = page.getCfgsEditable();
+ for (ICConfigurationDescription cfgDescription : cfgDescriptions) {
+ if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
+ String cfgId = cfgDescription.getId();
+ List<ILanguageSettingsProvider> initialProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
+ initialProvidersMap.put(cfgId, initialProviders);
+ }
+ }
+ }
+ }
+
+ /**
+ * Create UI control for languages.
+ */
+ private void createTreeForLanguages(Composite parent) {
+ treeLanguages = new Tree(parent, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL);
+ treeLanguages.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+ treeLanguages.setHeaderVisible(true);
+
+ treeLanguages.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ TreeItem[] items = treeLanguages.getSelection();
+ if (items.length > 0) {
+ currentLanguageId = (String) items[0].getData();
+ currentLanguageIdGlobal = currentLanguageId;
+ updateTreeForEntries();
+ }
+ }
+ });
+
+ final TreeColumn columnLanguages = new TreeColumn(treeLanguages, SWT.NONE);
+ columnLanguages.setText(Messages.AbstractLangsListTab_Languages);
+ columnLanguages.setWidth(200);
+ columnLanguages.setResizable(false);
+ columnLanguages.setToolTipText(Messages.AbstractLangsListTab_Languages);
+
+ treeLanguages.addPaintListener(new PaintListener() {
+ @Override
+ public void paintControl(PaintEvent e) {
+ int x = treeLanguages.getBounds().width - 5;
+ if (columnLanguages.getWidth() != x) {
+ columnLanguages.setWidth(x);
+ }
+ }
+ });
+ }
+
+ /**
+ * Create tree for providers and their entries.
+ */
+ private void createTreeForEntries(Composite parent) {
+ treeEntries = new Tree(parent, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
+ treeEntries.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+ treeEntries.setHeaderVisible(true);
+ treeEntries.setLinesVisible(true);
+
+ final TreeColumn treeCol = new TreeColumn(treeEntries, SWT.NONE);
+ treeEntries.addPaintListener(new PaintListener() {
+ @Override
+ public void paintControl(PaintEvent e) {
+ int x = treeEntries.getClientArea().width;
+ if (treeCol.getWidth() != x)
+ treeCol.setWidth(x);
+ }
+ });
+
+ treeCol.setText(Messages.LanguageSettingsProviderTab_SettingEntries);
+ treeCol.setWidth(200);
+ treeCol.setResizable(false);
+ treeCol.setToolTipText(Messages.LanguageSettingsProviderTab_SettingEntriesTooltip);
+
+ treeEntriesViewer = new TreeViewer(treeEntries);
+ treeEntriesViewer.setContentProvider(new EntriesTreeContentProvider());
+ treeEntriesViewer.setLabelProvider(new EntriesTreeLabelProvider());
+
+ treeEntriesViewer.setUseHashlookup(true);
+
+ treeEntries.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (treeLanguages.getSelectionCount() == 0) {
+ selectLanguage(currentLanguageId);
+ }
+ updateStatusLine();
+ updateButtons();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ if (buttonIsEnabled(BUTTON_EDIT) && treeEntries.getSelection().length>0)
+ buttonPressed(BUTTON_EDIT);
+ }
+ });
+
+ }
+
+ /**
+ * Create sash form.
+ */
+ private void createSashForm() {
+ sashFormEntries = new SashForm(usercomp,SWT.HORIZONTAL);
+
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ gd.horizontalSpan = 2;
+ gd.grabExcessVerticalSpace = true;
+ sashFormEntries.setLayoutData(gd);
+
+ GridLayout layout = new GridLayout();
+ sashFormEntries.setLayout(layout);
+
+ createTreeForLanguages(sashFormEntries);
+ createTreeForEntries(sashFormEntries);
+
+ sashFormEntries.setWeights(DEFAULT_ENTRIES_SASH_WEIGHTS);
+ }
+
+ /**
+ * Create check-box to control whether to show built-in entries or not.
+ */
+ private void createBuiltInsCheckBox() {
+ builtInCheckBox = setupCheck(usercomp, Messages.AbstractLangsListTab_ShowBuiltin, 1, GridData.FILL_HORIZONTAL);
+ builtInCheckBox.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateTreeForEntries();
+ }
+ });
+ builtInCheckBox.setSelection(true);
+ builtInCheckBox.setEnabled(true);
+ }
+
+ /**
+ * Create check-box to allow disable/enable language settings providers functionality.
+ */
+ private void createEnableProvidersCheckBox() {
+ // take the flag from master page if available (normally for resource properties)
+ if (masterPropertyPage != null) {
+ enableProvidersCheckBox = setupCheck(usercomp, Messages.LanguageSettingsProviders_EnableForProject, 2, GridData.FILL_HORIZONTAL);
+ enableProvidersCheckBox.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean enabled = enableProvidersCheckBox.getSelection();
+ masterPropertyPage.setLanguageSettingsProvidersEnabled(enabled);
+ enableTabControls(enabled);
+ updateStatusLine();
+ }
+ });
+
+ enableProvidersCheckBox.setSelection(masterPropertyPage.isLanguageSettingsProvidersEnabled());
+
+ // display but disable the checkbox for file/folder resource
+ enableProvidersCheckBox.setEnabled(page.isForProject());
+ enableTabControls(enableProvidersCheckBox.getSelection());
+ }
+ }
+
+ @Override
+ public void createControls(Composite parent) {
+ super.createControls(parent);
+ currentLanguageId = null;
+
+ usercomp.setLayout(new GridLayout());
+ GridData gd = (GridData) usercomp.getLayoutData();
+ // Discourage settings entry table from trying to show all its items at once, see bug 264330
+ gd.heightHint =1;
+
+ if (page instanceof LanguageSettingsProvidersPage) {
+ masterPropertyPage = (LanguageSettingsProvidersPage) page;
+ }
+
+ trackInitialSettings();
+
+ createSashForm();
+ fStatusLine = new StatusMessageLine(usercomp, SWT.LEFT, 2);
+ createBuiltInsCheckBox();
+ // "I want to try new scanner discovery" temporary checkbox
+ createEnableProvidersCheckBox();
+
+ initButtons(BUTTON_LABELS);
+ updateData(getResDesc());
+ }
+
+ /**
+ * Gray out or restore all controls except enabling check-box.
+ */
+ private void enableTabControls(boolean enable) {
+ sashFormEntries.setEnabled(enable);
+ treeLanguages.setEnabled(enable);
+ treeEntries.setEnabled(enable);
+ builtInCheckBox.setEnabled(enable);
+
+ buttoncomp.setEnabled(enable);
+
+ if (enable) {
+ updateTreeForEntries();
+ } else {
+ buttonSetEnabled(BUTTON_ADD, false);
+ buttonSetEnabled(BUTTON_EDIT, false);
+ buttonSetEnabled(BUTTON_DELETE, false);
+ buttonSetEnabled(BUTTON_MOVE_UP, false);
+ buttonSetEnabled(BUTTON_MOVE_DOWN, false);
+ }
+ }
+
+ /**
+ * Updates state for all buttons. Called when table selection changes.
+ */
+ @Override
+ protected void updateButtons() {
+ ILanguageSettingsProvider provider = getSelectedProvider();
+ ICLanguageSettingEntry entry = getSelectedEntry();
+ List<ICLanguageSettingEntry> entries = getSettingEntriesUpResourceTree(provider);
+
+ boolean isEntrySelected = (entry != null);
+ boolean isProviderSelected = !isEntrySelected && (provider != null);
+
+ boolean isAllowedToEdit = provider instanceof ILanguageSettingsEditableProvider
+ && LanguageSettingsProviderAssociationManager.isAllowedToEditEntries(provider);
+
+ boolean isAllowedToClear = provider instanceof ILanguageSettingsEditableProvider
+ && LanguageSettingsProviderAssociationManager.isAllowedToClear(provider);
+
+ boolean canAdd = isAllowedToEdit;
+ boolean canEdit = isAllowedToEdit && isEntrySelected;
+ boolean canDelete = isAllowedToEdit && isEntrySelected;
+ boolean canClear = isAllowedToClear && isProviderSelected && entries != null && entries.size() > 0;
+
+ boolean canMoveUp = false;
+ boolean canMoveDown = false;
+ if (isAllowedToEdit && isEntrySelected && entries != null) {
+ int last = entries.size() - 1;
+ int pos = getExactIndex(entries, entry);
+
+ if (pos >= 0 && pos <= last) {
+ canMoveUp = (pos != 0);
+ canMoveDown = (pos != last);
+ }
+ }
+
+ buttonSetText(BUTTON_DELETE, isProviderSelected ? CLEAR_STR : DEL_STR);
+
+ buttonSetEnabled(BUTTON_ADD, canAdd);
+ buttonSetEnabled(BUTTON_EDIT, canEdit);
+ buttonSetEnabled(BUTTON_DELETE, canDelete || canClear);
+
+ buttonSetEnabled(BUTTON_MOVE_UP, canMoveUp);
+ buttonSetEnabled(BUTTON_MOVE_DOWN, canMoveDown);
+ }
+
+ /**
+ * Displays warning message - if any - for selected language settings entry.
+ */
+ private void updateStatusLine() {
+ IStatus status=null;
+ if (enableProvidersCheckBox.getSelection() == true) {
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ status = LanguageSettingsImages.getStatus(getSelectedEntry(), cfgDescription);
+ }
+ if (status == null || status == Status.OK_STATUS) {
+ ILanguageSettingsProvider provider = getSelectedProvider();
+ boolean isAllowedEditing = provider instanceof ILanguageSettingsEditableProvider
+ && LanguageSettingsProviderAssociationManager.isAllowedToEditEntries(provider);
+ if (provider != null && !isAllowedEditing) {
+ status = new Status(IStatus.INFO, CUIPlugin.PLUGIN_ID, Messages.LanguageSettingsEntriesTab_Entries_Not_Editable);
+ }
+ }
+ if (status == null || status == Status.OK_STATUS) {
+ if (treeLanguages.getItemCount() <= 0) {
+ status = new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, Messages.LanguageSettingsEntriesTab_Cannot_Determine_Languages);
+ }
+ }
+ fStatusLine.setErrorStatus(status);
+ }
+
+ /**
+ * Handle buttons
+ */
+ @Override
+ public void buttonPressed(int buttonIndex) {
+ ILanguageSettingsProvider selectedProvider = getSelectedProvider();
+ ICLanguageSettingEntry selectedEntry = getSelectedEntry();
+
+ switch (buttonIndex) {
+ case BUTTON_ADD:
+ performAdd(selectedProvider);
+ break;
+ case BUTTON_EDIT:
+ performEdit(selectedProvider, selectedEntry);
+ break;
+ case BUTTON_DELETE:
+ performDelete(selectedProvider, selectedEntry);
+ break;
+ case BUTTON_MOVE_UP:
+ performMoveUp(selectedProvider, selectedEntry);
+ break;
+ case BUTTON_MOVE_DOWN:
+ performMoveDown(selectedProvider, selectedEntry);
+ break;
+ default:
+ }
+ treeEntries.setFocus();
+ }
+
+ /**
+ * That method returns exact position of an element in the list.
+ * Note that {@link List#indexOf(Object)} returns position of the first element
+ * equals to the given one, not exact element.
+ *
+ * @param entries
+ * @param entry
+ * @return exact position of the element or -1 of not found.
+ */
+ private int getExactIndex(List<ICLanguageSettingEntry> entries, ICLanguageSettingEntry entry) {
+ if (entries != null) {
+ for (int i = 0; i < entries.size(); i++) {
+ if (entries.get(i) == entry)
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Find TreeItem associated with a provider.
+ */
+ private TreeItem findProviderItem(String id) {
+ TreeItem[] providerItems = treeEntries.getItems();
+ for (TreeItem providerItem : providerItems) {
+ Object providerItemData = providerItem.getData();
+ if (providerItemData instanceof ILanguageSettingsProvider) {
+ ILanguageSettingsProvider provider = (ILanguageSettingsProvider)providerItemData;
+ if (provider.getId().equals(id)) {
+ return providerItem;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Find TreeItem associated with a provider's entry.
+ */
+ private TreeItem findEntryItem(String providerId, ICLanguageSettingEntry entry) {
+ TreeItem[] providerItems = treeEntries.getItems();
+ for (TreeItem providerItem : providerItems) {
+ Object providerItemData = providerItem.getData();
+ if (providerItemData instanceof ILanguageSettingsProvider) {
+ ILanguageSettingsProvider provider = (ILanguageSettingsProvider)providerItemData;
+ if (provider.getId().equals(providerId)) {
+ TreeItem[] entryItems = providerItem.getItems();
+ for (TreeItem entryItem : entryItems) {
+ Object entryItemData = entryItem.getData();
+ if (entryItemData==entry)
+ return entryItem;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Select language settings entry item in the tree.
+ */
+ private void selectItem(String providerId, ICLanguageSettingEntry entry) {
+ TreeItem providerItem = findProviderItem(providerId);
+ if (providerItem != null) {
+ treeEntries.select(providerItem);
+ if (providerItem.getItems().length > 0) {
+ treeEntries.showItem(providerItem.getItems()[0]);
+ }
+ TreeItem entryItem = findEntryItem(providerId, entry);
+ if (entryItem != null) {
+ treeEntries.showItem(entryItem);
+ treeEntries.select(entryItem);
+ }
+ updateStatusLine();
+ }
+ }
+
+ /**
+ * Add language settings entry.
+ */
+ private void addEntry(ILanguageSettingsProvider provider, ICLanguageSettingEntry entry) {
+ if (provider != null && entry != null) {
+ String providerId = provider.getId();
+
+ List<ICLanguageSettingEntry> entries = getEntriesShownToUser(provider);
+ ICLanguageSettingEntry selectedEntry = getSelectedEntry();
+ int pos = getExactIndex(entries, selectedEntry);
+ entries.add(pos+1, entry);
+ saveEntries(provider, entries);
+
+ updateTreeForEntries();
+ selectItem(providerId, entry);
+ updateButtons();
+ }
+ }
+
+ /**
+ * Save entries into provider considering resource parent.
+ */
+ private void saveEntries(ILanguageSettingsProvider provider, List<ICLanguageSettingEntry> entries) {
+ if (provider instanceof ILanguageSettingsEditableProvider) {
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ IResource rc = getResource();
+ if (entries != null && rc != null) {
+ List<ICLanguageSettingEntry> parentEntries = null;
+ if (rc instanceof IProject) {
+ parentEntries = new ArrayList<ICLanguageSettingEntry>();
+ } else {
+ parentEntries = LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, cfgDescription, rc.getParent(), currentLanguageId);
+ }
+ if (entries.equals(parentEntries)) {
+ // to use parent entries instead
+ entries = null;
+ }
+ }
+ ((ILanguageSettingsEditableProvider)provider).setSettingEntries(cfgDescription, rc, currentLanguageId, entries);
+ }
+ }
+
+ /**
+ * Get list of setting entries shown to user. If current resource has no entries assigned the parent
+ * resource is inspected.
+ */
+ private List<ICLanguageSettingEntry> getEntriesShownToUser(ILanguageSettingsProvider provider) {
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ IResource rc = getResource();
+ List<ICLanguageSettingEntry> entries = provider.getSettingEntries(cfgDescription, rc, currentLanguageId);
+ if (entries == null) {
+ entries = getSettingEntriesUpResourceTree(provider);
+ }
+ entries = new ArrayList<ICLanguageSettingEntry>(entries);
+ return entries;
+ }
+
+ /**
+ * Call dialog to add settings entry.
+ */
+ private void performAdd(ILanguageSettingsProvider selectedProvider) {
+ if (selectedProvider instanceof ILanguageSettingsEditableProvider) {
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ ICLanguageSettingEntry selectedEntry = getSelectedEntry();
+ LanguageSettingEntryDialog addDialog = new LanguageSettingEntryDialog(usercomp.getShell(), cfgDescription, selectedEntry, true);
+ if (addDialog.open()) {
+ ICLanguageSettingEntry settingEntry = addDialog.getEntries()[0];
+ if (settingEntry != null) {
+ selectedProvider = getWorkingCopy((ILanguageSettingsEditableProvider)selectedProvider);
+ addEntry(selectedProvider, settingEntry);
+ }
+ }
+ }
+ }
+
+ /**
+ * Return working copy of the provider to edit in current session. If the supplied provider is already
+ * the working copy return it. If not, create a copy to be edited.
+ */
+ private ILanguageSettingsEditableProvider getWorkingCopy(ILanguageSettingsEditableProvider provider) {
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ List<ILanguageSettingsProvider> initialProviders = initialProvidersMap.get(cfgDescription.getId());
+ if (initialProviders.contains(provider)) {
+ List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>(((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders());
+ int pos = providers.indexOf(provider);
+ if (pos >= 0) {
+ try {
+ provider = provider.clone();
+ providers.set(pos, provider);
+ ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers);
+ } catch (CloneNotSupportedException e) {
+ CUIPlugin.log("Internal Error: cannot clone provider "+provider.getId(), e); //$NON-NLS-1$
+ }
+ } else {
+ CUIPlugin.log("Internal Error: cannot find provider "+provider.getId(), new Exception()); //$NON-NLS-1$
+ }
+ }
+ return provider;
+ }
+
+ /**
+ * Call dialog to edit settings entry.
+ */
+ private void performEdit(ILanguageSettingsProvider selectedProvider, ICLanguageSettingEntry selectedEntry) {
+ if (selectedProvider instanceof ILanguageSettingsEditableProvider && selectedEntry != null) {
+ ICConfigurationDescription cfgDecsription = getConfigurationDescription();
+ LanguageSettingEntryDialog editDialog = new LanguageSettingEntryDialog(usercomp.getShell(), cfgDecsription, selectedEntry);
+ if (editDialog.open()) {
+ ICLanguageSettingEntry newEntry = editDialog.getEntries()[0];
+ if (newEntry != null) {
+ selectedProvider = getWorkingCopy((ILanguageSettingsEditableProvider)selectedProvider);
+ replaceEntry(selectedProvider, selectedEntry, newEntry);
+ }
+ }
+
+ }
+ }
+
+ /**
+ * Delete provider's entry and update UI.
+ */
+ private void deleteEntry(ILanguageSettingsProvider provider, ICLanguageSettingEntry entry) {
+ if (provider != null && entry != null) {
+ String providerId = provider.getId();
+
+ List<ICLanguageSettingEntry> entries = getEntriesShownToUser(provider);
+ int pos = getExactIndex(entries, entry);
+ entries.remove(entry);
+ saveEntries(provider, entries);
+
+ if (pos >= entries.size()) {
+ pos = entries.size() - 1;
+ }
+ ICLanguageSettingEntry entryToSelect = (pos >= 0) ? entries.get(pos) : null;
+
+ updateTreeForEntries();
+ selectItem(providerId, entryToSelect);
+ updateButtons();
+ }
+ }
+
+ /**
+ * Replace provider's entry and update UI.
+ */
+ private void replaceEntry(ILanguageSettingsProvider provider, ICLanguageSettingEntry oldEntry, ICLanguageSettingEntry newEntry) {
+ if (provider != null && oldEntry != null && newEntry != null) {
+ String providerId = provider.getId();
+
+ List<ICLanguageSettingEntry> entries = getEntriesShownToUser(provider);
+ int pos = getExactIndex(entries, oldEntry);
+ entries.set(pos, newEntry);
+ saveEntries(provider, entries);
+
+ updateTreeForEntries();
+ selectItem(providerId, newEntry);
+ updateButtons();
+ }
+ }
+
+ /**
+ * Clear all provider's entries for the given resource and update UI.
+ */
+ private void clearProvider(ILanguageSettingsProvider provider) {
+ if (provider != null) {
+ String providerId = provider.getId();
+ List<ICLanguageSettingEntry> empty = new ArrayList<ICLanguageSettingEntry>();
+ saveEntries(provider, empty);
+
+ updateTreeForEntries();
+ selectItem(providerId, null);
+ updateButtons();
+ }
+ }
+
+ /**
+ * Clear provider's entries for the given resource or remove one entry depending on selection.
+ */
+ private void performDelete(ILanguageSettingsProvider selectedProvider, ICLanguageSettingEntry selectedEntry) {
+ if (selectedProvider instanceof ILanguageSettingsEditableProvider) {
+ selectedProvider = getWorkingCopy((ILanguageSettingsEditableProvider)selectedProvider);
+ if (selectedEntry != null) {
+ deleteEntry(selectedProvider, selectedEntry);
+ } else {
+ clearProvider(selectedProvider);
+ }
+ }
+ }
+
+ /**
+ * Move provider's entry up or down.
+ */
+ private void moveEntry(ILanguageSettingsProvider provider, ICLanguageSettingEntry entry, boolean up) {
+ if (provider != null && entry != null) {
+ String providerId = provider.getId();
+
+ List<ICLanguageSettingEntry> entries = getEntriesShownToUser(provider);
+ int pos = getExactIndex(entries, entry);
+ int newPos = up ? pos-1 : pos+1;
+ Collections.swap(entries, pos, newPos);
+ saveEntries(provider, entries);
+
+ updateTreeForEntries();
+ selectItem(providerId, entry);
+ updateButtons();
+ }
+ }
+
+ /**
+ * Move provider's entry up.
+ */
+ private void performMoveUp(ILanguageSettingsProvider selectedProvider, ICLanguageSettingEntry selectedEntry) {
+ if (selectedEntry != null && (selectedProvider instanceof ILanguageSettingsEditableProvider)) {
+ selectedProvider = getWorkingCopy((ILanguageSettingsEditableProvider)selectedProvider);
+ moveEntry(selectedProvider, selectedEntry, true);
+ }
+ }
+
+ /**
+ * Move provider's entry down.
+ */
+ private void performMoveDown(ILanguageSettingsProvider selectedProvider, ICLanguageSettingEntry selectedEntry) {
+ if (selectedEntry != null && (selectedProvider instanceof ILanguageSettingsEditableProvider)) {
+ selectedProvider = getWorkingCopy((ILanguageSettingsEditableProvider)selectedProvider);
+ moveEntry(selectedProvider, selectedEntry, false);
+ }
+ }
+
+ /**
+ * Get list of providers to display in the settings entry tree.
+ */
+ private List<ILanguageSettingsProvider> getProviders(String languageSettingId) {
+ List<ILanguageSettingsProvider> itemsList = new LinkedList<ILanguageSettingsProvider>();
+ if (currentLanguageId != null) {
+ IResource rc = getResource();
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ if (rc != null && cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
+ List<ILanguageSettingsProvider> cfgProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
+ for (ILanguageSettingsProvider cfgProvider : cfgProviders) {
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(cfgProvider);
+ if (rawProvider instanceof LanguageSettingsBaseProvider) {
+ // filter out providers incapable of providing entries for this language
+ List<String> languageIds = ((LanguageSettingsBaseProvider)rawProvider).getLanguageScope();
+ if (languageIds != null && !languageIds.contains(currentLanguageId)) {
+ continue;
+ }
+ }
+ itemsList.add(cfgProvider);
+ }
+ }
+ }
+ return itemsList;
+ }
+
+ /**
+ * Re-reads and refreshes the entries tree.
+ */
+ private void updateTreeForEntries() {
+ List<ILanguageSettingsProvider> tableItems = getProviders(currentLanguageId);
+ treeEntriesViewer.setInput(tableItems.toArray(new Object[tableItems.size()]));
+ updateStatusLine();
+ updateButtons();
+ }
+
+ /**
+ * Re-reads and refreshes the languages tree.
+ */
+ private void updateTreeForLanguages(ICResourceDescription rcDes) {
+ treeLanguages.removeAll();
+ currentLanguageId = null;
+
+ List<String> languageIds = LanguageSettingsManager.getLanguages(rcDes);
+ Collections.sort(languageIds);
+ for (String langId : languageIds) {
+ ILanguage language = LanguageManager.getInstance().getLanguage(langId);
+ if (language == null)
+ continue;
+
+ String langName = language.getName();
+ if (langName == null || langName.length() == 0)
+ continue;
+
+ TreeItem t = new TreeItem(treeLanguages, SWT.NONE);
+ t.setText(0, langName);
+ t.setData(langId);
+ if (currentLanguageIdGlobal != null && currentLanguageIdGlobal.equals(langId)) {
+ currentLanguageId = currentLanguageIdGlobal;
+ treeLanguages.setSelection(t);
+ } else if (currentLanguageId == null) {
+ // this selects first language on first round
+ // do not select the tree item and global language selection here, only on actual click
+ currentLanguageId = langId;
+ }
+ }
+
+ }
+
+ /**
+ * Change selection of language.
+ */
+ private void selectLanguage(String langId) {
+ currentLanguageId = langId;
+ currentLanguageIdGlobal = currentLanguageId;
+
+ for (TreeItem t : treeLanguages.getItems()) {
+ if (t.getData().equals(langId)) {
+ treeLanguages.setSelection(t);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Update the tab. Called when configuration changes.
+ */
+ @Override
+ public void updateData(ICResourceDescription rcDes) {
+ if (!canBeVisible())
+ return;
+
+ if (rcDes != null) {
+ if (page.isMultiCfg()) {
+ setAllVisible(false, null);
+ return;
+ } else {
+ setAllVisible(true, null);
+ }
+
+ updateTreeForLanguages(rcDes);
+ updateTreeForEntries();
+
+ if (masterPropertyPage != null) {
+ boolean enabled = masterPropertyPage.isLanguageSettingsProvidersEnabled();
+ enableProvidersCheckBox.setSelection(enabled);
+ enableTabControls(enabled);
+ }
+ }
+ updateButtons();
+ }
+
+ @Override
+ protected void performDefaults() {
+ // This page restores defaults for file/folder only.
+ // Project and Preferences page are restored by LanguageSettingsProviderTab.
+ if (page.isForFile() || page.isForFolder()) {
+ // The logic below is not exactly correct as the default for a resource could be different than null.
+ // It is supposed to match the one taken from extension for the same resource which in theory can be non-null.
+ // However for the performance reasons for resource decorators where the same logic is used
+ // we use null for resetting file/folder resource which should be correct in most cases.
+ // Count that as a feature.
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ if (!(cfgDescription instanceof ILanguageSettingsProvidersKeeper)) {
+ return;
+ }
+
+ boolean changed = false;
+ IResource rc = getResource();
+ List<ILanguageSettingsProvider> oldProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
+ List<ILanguageSettingsProvider> newProviders = new ArrayList<ILanguageSettingsProvider>(oldProviders.size());
+
+ // clear entries for a given resource for all languages where applicable
+providers: for (ILanguageSettingsProvider provider : oldProviders) {
+ ILanguageSettingsEditableProvider providerCopy = null;
+ if (provider instanceof ILanguageSettingsEditableProvider) {
+ for (TreeItem langItems : treeLanguages.getItems()) {
+ String langId = (String)langItems.getData();
+ if (langId != null) {
+ if (provider.getSettingEntries(cfgDescription, rc, langId) != null) {
+ if (providerCopy == null) {
+ // copy providers to be able to "Cancel" in UI
+ providerCopy = LanguageSettingsManager.getProviderCopy((ILanguageSettingsEditableProvider) provider, true);
+ if (providerCopy == null) {
+ continue providers;
+ }
+ }
+ providerCopy.setSettingEntries(cfgDescription, rc, langId, null);
+ changed = true;
+ }
+ }
+ }
+ }
+ if (providerCopy != null) {
+ newProviders.add(providerCopy);
+ } else {
+ newProviders.add(provider);
+ }
+ }
+ if (changed) {
+ ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(newProviders);
+ updateTreeForEntries();
+ }
+ }
+ }
+
+ @Override
+ protected void performApply(ICResourceDescription srcRcDescription, ICResourceDescription destRcDescription) {
+ if (!page.isForPrefs()) {
+ ICConfigurationDescription sd = srcRcDescription.getConfiguration();
+ ICConfigurationDescription dd = destRcDescription.getConfiguration();
+ if (sd instanceof ILanguageSettingsProvidersKeeper && dd instanceof ILanguageSettingsProvidersKeeper) {
+ List<ILanguageSettingsProvider> newProviders = ((ILanguageSettingsProvidersKeeper) sd).getLanguageSettingProviders();
+ ((ILanguageSettingsProvidersKeeper) dd).setLanguageSettingProviders(newProviders);
+ }
+ }
+
+ performOK();
+
+ trackInitialSettings();
+ updateData(getResDesc());
+ }
+
+ @Override
+ protected void performOK() {
+ if (masterPropertyPage != null && enableProvidersCheckBox.getEnabled()) {
+ masterPropertyPage.applyLanguageSettingsProvidersEnabled();
+ }
+ }
+
+ @Override
+ public boolean canBeVisible() {
+ if (CDTPrefUtil.getBool(LanguageSettingsProvidersPage.KEY_NO_SHOW_PROVIDERS)) {
+ return false;
+ }
+
+ // filter out files not associated with any languages such as *.o
+ if (page.isForFile()) {
+ List<String> languageIds = LanguageSettingsManager.getLanguages(getResDesc());
+ for (String langId : languageIds) {
+ ILanguage language = LanguageManager.getInstance().getLanguage(langId);
+ if (language != null)
+ return true;
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderAssociationManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderAssociationManager.java
new file mode 100644
index 0000000000..7cb5c08787
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderAssociationManager.java
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.language.settings.providers;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.ui.CDTSharedImages;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.dialogs.ICOptionPage;
+
+/**
+ * This class manages extensions of extension point org.eclipse.cdt.core.LanguageSettingsProvider
+ * which defines appearance and behavior of UI controls for Language Settings Providers.
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class LanguageSettingsProviderAssociationManager {
+ /** Name of the extension point for contributing language settings provider associations */
+ private static final String PROVIDER_ASSOCIATION_EXTENSION_POINT_SIMPLE_ID = "LanguageSettingsProviderAssociation"; //$NON-NLS-1$
+
+ private static final String ELEM_ID_ASSOCIATION = "id-association"; //$NON-NLS-1$
+ private static final String ELEM_CLASS_ASSOCIATION = "class-association"; //$NON-NLS-1$
+ private static final String ATTR_ID = "id"; //$NON-NLS-1$
+ private static final String ATTR_CLASS = "class"; //$NON-NLS-1$
+ private static final String ATTR_ICON = "icon"; //$NON-NLS-1$
+ private static final String ATTR_PAGE = "page"; //$NON-NLS-1$
+ private static final String ATTR_UI_CLEAR_ENTRIES = "ui-clear-entries"; //$NON-NLS-1$
+ private static final String ATTR_UI_EDIT_ENTRIES = "ui-edit-entries"; //$NON-NLS-1$
+
+ private static boolean isLoaded = false;
+ private static List<URL> loadedIcons = new ArrayList<URL>();
+ private static Map<String, URL> fImagesUrlById = new HashMap<String, URL>();
+ private static Map<String, URL> fImagesUrlByClass = new HashMap<String, URL>();
+ private static List<String> fRegirestedIds = new ArrayList<String>();
+ private static List<String> fRegisteredClasses = new ArrayList<String>();
+
+ private static Map<String, Map<String, String>> fAssociationsById = new HashMap<String, Map<String, String>>();
+ private static Map<String, Map<String, String>> fAssociationsByClass = new HashMap<String, Map<String, String>>();
+
+ /**
+ * Load extensions into memory maps.
+ */
+ private static void loadExtensions() {
+ if (isLoaded) {
+ return;
+ }
+ isLoaded = true;
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint extension = registry.getExtensionPoint(CUIPlugin.PLUGIN_ID, PROVIDER_ASSOCIATION_EXTENSION_POINT_SIMPLE_ID);
+ if (extension != null) {
+ IExtension[] extensions = extension.getExtensions();
+ for (IExtension ext : extensions) {
+ @SuppressWarnings("unused")
+ String extensionID = ext.getUniqueIdentifier();
+ for (IConfigurationElement cfgEl : ext.getConfigurationElements()) {
+ if (cfgEl.getName().equals(ELEM_ID_ASSOCIATION)) {
+ String id = cfgEl.getAttribute(ATTR_ID);
+ URL url = getIconUrl(cfgEl);
+ fImagesUrlById.put(id, url);
+ fRegirestedIds.add(id);
+
+ Map<String, String> properties = new HashMap<String, String>();
+ putNotEmpty(properties, ATTR_PAGE, cfgEl.getAttribute(ATTR_PAGE));
+ putNotEmpty(properties, ATTR_UI_CLEAR_ENTRIES, cfgEl.getAttribute(ATTR_UI_CLEAR_ENTRIES));
+ putNotEmpty(properties, ATTR_UI_EDIT_ENTRIES, cfgEl.getAttribute(ATTR_UI_EDIT_ENTRIES));
+ fAssociationsById.put(id, properties);
+ } else if (cfgEl.getName().equals(ELEM_CLASS_ASSOCIATION)) {
+ String className = cfgEl.getAttribute(ATTR_CLASS);
+ URL url = getIconUrl(cfgEl);
+ fImagesUrlByClass.put(className, url);
+ String pageClass = cfgEl.getAttribute(ATTR_PAGE);
+ if (pageClass != null && pageClass.length() > 0) {
+ fRegisteredClasses.add(className);
+ }
+
+ Map<String, String> properties = new HashMap<String, String>();
+ putNotEmpty(properties, ATTR_PAGE, cfgEl.getAttribute(ATTR_PAGE));
+ putNotEmpty(properties, ATTR_UI_CLEAR_ENTRIES, cfgEl.getAttribute(ATTR_UI_CLEAR_ENTRIES));
+ putNotEmpty(properties, ATTR_UI_EDIT_ENTRIES, cfgEl.getAttribute(ATTR_UI_EDIT_ENTRIES));
+ fAssociationsByClass.put(className, properties);
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Put value into properties ignoring nulls.
+ */
+ private static void putNotEmpty(Map<String, String> properties, String key, String value) {
+ if (value != null)
+ properties.put(key, value);
+ }
+
+ /**
+ * Find icon URL in its bundle.
+ */
+ private static URL getIconUrl(IConfigurationElement config) {
+ URL url = null;
+ try {
+ String iconName = config.getAttribute(ATTR_ICON);
+ if (iconName != null) {
+ URL pluginInstallUrl = Platform.getBundle(config.getDeclaringExtension().getContributor().getName()).getEntry("/"); //$NON-NLS-1$
+ url = new URL(pluginInstallUrl, iconName);
+ if (loadedIcons.contains(url)) {
+ return url;
+ }
+ }
+ } catch (MalformedURLException e) {
+ CUIPlugin.log(e);
+ }
+
+ loadedIcons.add(url);
+ if (url != null) {
+ CDTSharedImages.register(url);
+ }
+
+ return url;
+ }
+
+ /**
+ * Get image URL for language settings provider with the given ID.
+ *
+ * @param providerId - ID of language settings provider.
+ * @return image URL or {@code null}.
+ */
+ public static URL getImageUrl(String providerId) {
+ loadExtensions();
+ return fImagesUrlById.get(providerId);
+ }
+
+ /**
+ * Create an Options page for language settings provider with given ID.
+ */
+ private static ICOptionPage createOptionsPageById(String providerId) {
+ loadExtensions();
+
+ if (fRegirestedIds.contains(providerId)) {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint extension = registry.getExtensionPoint(CUIPlugin.PLUGIN_ID, PROVIDER_ASSOCIATION_EXTENSION_POINT_SIMPLE_ID);
+ if (extension != null) {
+ IExtension[] extensions = extension.getExtensions();
+ for (IExtension ext : extensions) {
+ try {
+ @SuppressWarnings("unused")
+ String extensionID = ext.getUniqueIdentifier();
+ for (IConfigurationElement cfgEl : ext.getConfigurationElements()) {
+ if (cfgEl.getName().equals(ELEM_ID_ASSOCIATION)) {
+ String id = cfgEl.getAttribute(ATTR_ID);
+ if (providerId.equals(id)) {
+ String pageClass = cfgEl.getAttribute(ATTR_PAGE);
+ if (pageClass != null && pageClass.trim().length() > 0) {
+ ICOptionPage page = (ICOptionPage) cfgEl.createExecutableExtension(ATTR_PAGE);
+ return page;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ CUIPlugin.log("Cannot load LanguageSettingsProviderAssociation extension " + ext.getUniqueIdentifier(), e); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Create an Options page for language settings provider class by its name.
+ */
+ private static ICOptionPage createOptionsPageByClass(String providerClassName) {
+ loadExtensions();
+
+ if (fRegisteredClasses.contains(providerClassName)) {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint extension = registry.getExtensionPoint(CUIPlugin.PLUGIN_ID, PROVIDER_ASSOCIATION_EXTENSION_POINT_SIMPLE_ID);
+ if (extension != null) {
+ IExtension[] extensions = extension.getExtensions();
+ for (IExtension ext : extensions) {
+ try {
+ @SuppressWarnings("unused")
+ String extensionID = ext.getUniqueIdentifier();
+ for (IConfigurationElement cfgEl : ext.getConfigurationElements()) {
+ if (cfgEl.getName().equals(ELEM_CLASS_ASSOCIATION)) {
+ String className = cfgEl.getAttribute(ATTR_CLASS);
+ if (providerClassName.equals(className)) {
+ String pageClass = cfgEl.getAttribute(ATTR_PAGE);
+ if (pageClass!=null && pageClass.trim().length()>0) {
+ ICOptionPage page = (ICOptionPage) cfgEl.createExecutableExtension(ATTR_PAGE);
+ return page;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ CUIPlugin.log("Cannot load LanguageSettingsProviderAssociation extension " + ext.getUniqueIdentifier(), e); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns Language Settings Provider image registered for closest superclass
+ * or interface.
+ *
+ * @param providerClass - class to find Language Settings Provider image.
+ * @return image or {@code null}
+ */
+ public static URL getImage(Class<? extends ILanguageSettingsProvider> providerClass) {
+ URL url = null;
+
+ outer: for (Class<?> c = providerClass; c != null; c = c.getSuperclass()) {
+ url = getImageURL(c);
+ if (url != null) {
+ break;
+ }
+
+ // this does not check for super-interfaces, feel free to implement as needed
+ for (Class<?> i : c.getInterfaces()) {
+ url = getImageURL(i);
+ if (url != null) {
+ break outer;
+ }
+ }
+ }
+ return url;
+ }
+
+ /**
+ * Return image URL registered for the given class.
+ */
+ private static URL getImageURL(Class<?> clazz) {
+ String className = clazz.getCanonicalName();
+ for (Entry<String, URL> entry : fImagesUrlByClass.entrySet()) {
+ if (entry.getKey().equals(className)) {
+ return entry.getValue();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns language settings provider Options page registered for closest superclass.
+ *
+ * @param provider - instance of provider to create Options page for.
+ * @return image or {@code null}.
+ */
+ public static ICOptionPage createOptionsPage(ILanguageSettingsProvider provider) {
+ String id = provider.getId();
+ ICOptionPage optionsPage = createOptionsPageById(id);
+ if (optionsPage != null) {
+ return optionsPage;
+ }
+
+ Class<? extends ILanguageSettingsProvider> clazz = provider.getClass();
+ outer: for (Class<?> c = clazz ;c != null; c = c.getSuperclass()) {
+ optionsPage = createOptionsPageByClass(c);
+ if (optionsPage != null) {
+ break;
+ }
+
+ // this does not check for super-interfaces, feel free to implement as needed
+ for (Class<?> i : c.getInterfaces()) {
+ optionsPage = createOptionsPageByClass(i);
+ if (optionsPage != null) {
+ break outer;
+ }
+ }
+ }
+ return optionsPage;
+ }
+
+ /**
+ * Create an Options page for language settings provider class.
+ */
+ private static ICOptionPage createOptionsPageByClass(Class<?> clazz) {
+ ICOptionPage optionsPage = null;
+ String className = clazz.getCanonicalName();
+ if (fRegisteredClasses.contains(className)) {
+ optionsPage = createOptionsPageByClass(className);
+ }
+ return optionsPage;
+ }
+
+ /**
+ * Returns value of the attribute of the provider by id or closest superclass.
+ */
+ private static boolean getBooleanAttribute(ILanguageSettingsProvider provider, String attr) {
+ loadExtensions();
+
+ String id = provider.getId();
+
+ Map<String, String> properties = fAssociationsById.get(id);
+ if (properties != null) {
+ return Boolean.parseBoolean(properties.get(attr));
+ }
+
+ for (Class<?> c = provider.getClass();c != null; c = c.getSuperclass()) {
+ String className = c.getCanonicalName();
+ properties = fAssociationsByClass.get(className);
+ if (properties != null) {
+ return Boolean.parseBoolean(properties.get(attr));
+ }
+
+ // this does not check for superinterfaces, feel free to implement as needed
+ for (Class<?> i : c.getInterfaces()) {
+ String interfaceName = i.getCanonicalName();
+ properties = fAssociationsByClass.get(interfaceName);
+ if (properties != null) {
+ return Boolean.parseBoolean(properties.get(attr));
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if the user is allowed to edit language settings provider entries in UI.
+ * @param provider - language settings provider.
+ * @return {@code true} if editing is allowed or {@code false} if not.
+ */
+ public static boolean isAllowedToEditEntries(ILanguageSettingsProvider provider) {
+ return getBooleanAttribute(provider, ATTR_UI_EDIT_ENTRIES);
+ }
+
+ /**
+ * Check if the user is allowed to clear language settings provider entries in UI.
+ * @param provider - language settings provider.
+ * @return {@code true} if clearing is allowed or {@code false} if not.
+ */
+ public static boolean isAllowedToClear(ILanguageSettingsProvider provider) {
+ return getBooleanAttribute(provider, ATTR_UI_CLEAR_ENTRIES);
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java
new file mode 100644
index 0000000000..0e81a9b766
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java
@@ -0,0 +1,1171 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.language.settings.providers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsEditableProvider;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsSerializableProvider;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICResourceDescription;
+import org.eclipse.cdt.ui.CDTSharedImages;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.dialogs.ICOptionPage;
+import org.eclipse.cdt.ui.language.settings.providers.AbstractLanguageSettingProviderOptionPage;
+import org.eclipse.cdt.ui.newui.AbstractCPropertyTab;
+import org.eclipse.cdt.ui.newui.CDTPrefUtil;
+import org.eclipse.cdt.utils.ui.controls.TabFolderLayout;
+
+import org.eclipse.cdt.internal.ui.newui.Messages;
+import org.eclipse.cdt.internal.ui.newui.StatusMessageLine;
+
+/**
+ * This tab presents language settings entries categorized by language
+ * settings providers.
+ *
+ *@noinstantiate This class is not intended to be instantiated by clients.
+ *@noextend This class is not intended to be subclassed by clients.
+ */
+public class LanguageSettingsProviderTab extends AbstractCPropertyTab {
+ private static final String WORKSPACE_PREFERENCE_PAGE = "org.eclipse.cdt.ui.preferences.BuildSettingProperties"; //$NON-NLS-1$
+ private static final String TEST_PLUGIN_ID_PATTERN = "org.eclipse.cdt.*.tests.*"; //$NON-NLS-1$
+
+ private static final String CLEAR_STR = Messages.LanguageSettingsProviderTab_Clear;
+ private static final String RESET_STR = Messages.LanguageSettingsProviderTab_Reset;
+
+ private static final int BUTTON_CLEAR = 0;
+ private static final int BUTTON_RESET = 1;
+ // there is a separator instead of button #2
+ private static final int BUTTON_MOVE_UP = 3;
+ private static final int BUTTON_MOVE_DOWN = 4;
+
+ private static final int[] DEFAULT_CONFIGURE_SASH_WEIGHTS = new int[] { 50, 50 };
+ private SashForm sashFormProviders;
+
+ private Table tableProviders;
+ private CheckboxTableViewer tableProvidersViewer;
+ private Group groupOptionsPage;
+ private ICOptionPage currentOptionsPage = null;
+ private Composite compositeOptionsPage;
+
+ private Button enableProvidersCheckBox;
+ private StatusMessageLine fStatusLine;
+
+ private Button sharedProviderCheckBox = null;
+ private Link linkToWorkspacePreferences = null;
+ private Button projectStorageCheckBox = null;
+
+ private LanguageSettingsProvidersPage masterPropertyPage = null;
+
+ /**
+ * List of providers presented to the user.
+ * For global providers included in a configuration this contains references
+ * not raw providers.
+ */
+ private List<ILanguageSettingsProvider> presentedProviders = null;
+ private final Map<String, ICOptionPage> optionsPageMap = new HashMap<String, ICOptionPage>();
+ private Map<String, List<ILanguageSettingsProvider>> initialProvidersByCfg = new HashMap<String, List<ILanguageSettingsProvider>>();
+
+ /**
+ * Label provider for language settings providers displayed by this tab.
+ */
+ private class ProvidersTableLabelProvider extends LanguageSettingsProvidersLabelProvider {
+ @Override
+ protected String[] getOverlayKeys(ILanguageSettingsProvider provider) {
+ if (provider.getName() == null) {
+ String[] overlayKeys = new String[5];
+ overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_ERROR;
+ return overlayKeys;
+ }
+
+ String[] overlayKeys = super.getOverlayKeys(provider);
+
+ if (page.isForProject()) {
+ if (isEditedForProject(provider)) {
+ overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_EDITED;
+ } else if (!LanguageSettingsManager.getExtensionProviderIds().contains(provider.getId())) {
+ overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_USER;
+ } else if (isReconfiguredForProject(provider)) {
+ overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_SETTING;
+ }
+ } else if (page.isForPrefs()) {
+ if (isWorkingCopy(provider) && !provider.equals(LanguageSettingsManager.getRawProvider(LanguageSettingsManager.getWorkspaceProvider(provider.getId())))) {
+ overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_EDITED;
+ } else if (!LanguageSettingsManager.getExtensionProviderIds().contains(provider.getId())) {
+ overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_USER;
+ } else {
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider);
+ if (rawProvider instanceof ILanguageSettingsEditableProvider && !LanguageSettingsManager.isEqualExtensionProvider(rawProvider, false)) {
+ overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_SETTING;
+ }
+ }
+ }
+
+ return overlayKeys;
+ }
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof ILanguageSettingsProvider) {
+ ILanguageSettingsProvider provider = (ILanguageSettingsProvider) element;
+ String name = provider.getName();
+ if (name != null && (page.isForPrefs() || isPresentedAsShared(provider))) {
+ return name + Messages.LanguageSettingsProvidersLabelProvider_TextDecorator_Shared;
+ }
+ }
+ return super.getText(element);
+ }
+ }
+
+ /**
+ * Returns the provider which is being presented to the user in UI.
+ * Used by option pages when there is a need.
+ * Warning: Do not cache the result as the provider can be replaced at any time.
+ * @param id - id of the provider.
+ *
+ * @return the provider.
+ */
+ public ILanguageSettingsProvider getProvider(String id) {
+ return findProvider(id, presentedProviders);
+ }
+
+ /**
+ * Check if the provider is a working copy and can be modified.
+ */
+ private boolean isWorkingCopy(ILanguageSettingsProvider provider) {
+ boolean isWorkingCopy = false;
+ if (page.isForPrefs()) {
+ isWorkingCopy = ! LanguageSettingsManager.isWorkspaceProvider(provider);
+ } else {
+ if (!LanguageSettingsManager.isWorkspaceProvider(provider)) {
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ List<ILanguageSettingsProvider> initialProviders = initialProvidersByCfg.get(cfgDescription.getId());
+ isWorkingCopy = ! initialProviders.contains(provider);
+ }
+
+ }
+ return isWorkingCopy;
+ }
+
+ /**
+ * Returns current working copy of the provider. Creates one if it has not been created yet.
+ * A working copy will be discarded if user pushes [Cancel] or it will replace original
+ * provider on [Apply] or [OK].
+ *
+ * This method is used also by option pages when there is a need to modify the provider.
+ * Warning: Do not cache the result as the provider can be replaced at any time.
+ *
+ * @param id - id of the provider.
+ * @return working copy of the provider.
+ */
+ public ILanguageSettingsProvider getWorkingCopy(String id) {
+ ILanguageSettingsProvider provider = findProvider(id, presentedProviders);
+ if (isWorkingCopy(provider)) {
+ return provider;
+ }
+
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider);
+ ILanguageSettingsEditableProvider newProvider = LanguageSettingsManager.getProviderCopy((ILanguageSettingsEditableProvider)rawProvider, true);
+ if (newProvider != null) {
+ replaceSelectedProvider(newProvider);
+ // Warning: Do not initializeOptionsPage() here as the method can be called from an existing page
+ }
+
+ return newProvider;
+ }
+
+ /**
+ * Refresh provider item in the table and update buttons.
+ * This method is intended for use by an Options Page of the provider.
+ *
+ * @param provider - provider item in the table to refresh.
+ */
+ public void refreshItem(ILanguageSettingsProvider provider) {
+ tableProvidersViewer.refresh(provider);
+ updateButtons();
+ }
+
+ /**
+ * Check if provider should get "reconfigured" overlay in UI.
+ */
+ private boolean isReconfiguredForProject(ILanguageSettingsProvider provider) {
+ String id = provider.getId();
+
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ String[] defaultIds = ((ILanguageSettingsProvidersKeeper) cfgDescription).getDefaultLanguageSettingsProvidersIds();
+ List<ILanguageSettingsProvider> providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
+
+ // check for the provider mismatch in configuration list vs. default list from the tool-chain
+ if (defaultIds != null && (Arrays.asList(defaultIds).contains(id) != providers.contains(provider))) {
+ return true;
+ }
+
+ // check if provider belongs to configuration (i.e. checked in the table)
+ if (!providers.contains(provider)) {
+ return false;
+ }
+
+ // check if "shared" flag matches default shared preference from extension point definition
+ if (LanguageSettingsManager.isPreferShared(id) != LanguageSettingsManager.isWorkspaceProvider(provider)) {
+ return true;
+ }
+
+ // check if configuration provider equals to the default one from extension point
+ if (!LanguageSettingsManager.isWorkspaceProvider(provider) && !LanguageSettingsManager.isEqualExtensionProvider(provider, false)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if provider should get "edited" overlay in UI.
+ */
+ private boolean isEditedForProject(ILanguageSettingsProvider provider) {
+ String id = provider.getId();
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ List<ILanguageSettingsProvider> initialProviders = initialProvidersByCfg.get(cfgDescription.getId());
+ List<ILanguageSettingsProvider> providers = getCheckedProviders();
+
+ // check for the provider mismatch in configuration list vs. initial list
+ ILanguageSettingsProvider initialProvider = findProvider(id, initialProviders);
+ if ((initialProvider != null) != providers.contains(provider)) {
+ return true;
+ }
+
+ // check if "shared" flag matches that of initial provider
+ if (providers.contains(provider) && LanguageSettingsManager.isWorkspaceProvider(initialProvider) != LanguageSettingsManager.isWorkspaceProvider(provider)) {
+ return true;
+ }
+
+ // check if configuration provider equals to the initial one
+ if (!LanguageSettingsManager.isWorkspaceProvider(provider) && !provider.equals(initialProvider)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks if the provider should be presented as shared. Unchecked providers are shown as non-shared
+ * if they are defined as non-shared in extension point even if in fact shared instance is used to display
+ * the options page.
+ */
+ private boolean isPresentedAsShared(ILanguageSettingsProvider provider) {
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ List<ILanguageSettingsProvider> providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
+ return LanguageSettingsManager.isWorkspaceProvider(provider) &&
+ ( providers.contains(provider) || LanguageSettingsManager.isPreferShared(provider.getId()) );
+ }
+
+ /**
+ * Find provider with a given ID in the list or {@code null}.
+ */
+ private ILanguageSettingsProvider findProvider(String id, List<ILanguageSettingsProvider> providers) {
+ for (ILanguageSettingsProvider provider : providers) {
+ if (provider.getId().equals(id)) {
+ return provider;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Shortcut for getting the currently selected provider.
+ * Do not use if you need to change provider's settings or entries, use {@link #getWorkingCopy(String)}.
+ */
+ private ILanguageSettingsProvider getSelectedProvider() {
+ ILanguageSettingsProvider provider = null;
+
+ int pos = tableProviders.getSelectionIndex();
+ if (pos >= 0 && pos < tableProviders.getItemCount()) {
+ provider = (ILanguageSettingsProvider)tableProvidersViewer.getElementAt(pos);
+ }
+ return provider;
+ }
+
+ /**
+ * Shortcut for getting the current configuration description.
+ */
+ private ICConfigurationDescription getConfigurationDescription() {
+ if (page.isForPrefs()) {
+ return null;
+ }
+
+ return getResDesc().getConfiguration();
+ }
+
+ /**
+ * Get the list of providers checked in the table in UI.
+ * @return
+ */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private List<ILanguageSettingsProvider> getCheckedProviders() {
+ return (List)Arrays.asList(tableProvidersViewer.getCheckedElements());
+ }
+
+ /**
+ * Replace the selected provider in UI and in configuration.
+ */
+ private void replaceSelectedProvider(ILanguageSettingsProvider newProvider) {
+ int pos = tableProviders.getSelectionIndex();
+ boolean isChecked = tableProvidersViewer.getChecked(tableProvidersViewer.getElementAt(pos));
+
+ presentedProviders.set(pos, newProvider);
+ tableProvidersViewer.refresh();
+ tableProvidersViewer.setChecked(newProvider, isChecked);
+ tableProviders.setSelection(pos);
+ tableProvidersViewer.refresh(newProvider);
+
+ saveCheckedProviders();
+ }
+
+ /**
+ * Save checked providers from UI table into configuration.
+ */
+ private void saveCheckedProviders() {
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
+ ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(getCheckedProviders());
+ }
+ }
+
+ /**
+ * Store original providers to be able to tell whether they were changed by user.
+ */
+ private void trackInitialSettings() {
+ if (!page.isForPrefs()) {
+ ICConfigurationDescription[] cfgDescriptions = page.getCfgsEditable();
+ for (ICConfigurationDescription cfgDescription : cfgDescriptions) {
+ if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
+ String cfgId = cfgDescription.getId();
+ List<ILanguageSettingsProvider> initialProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
+ initialProvidersByCfg.put(cfgId, initialProviders);
+ }
+ }
+ }
+ }
+
+ /**
+ * Create table to display providers.
+ */
+ private void createProvidersPane(Composite parent) {
+ Composite composite = new Composite(parent, SWT.BORDER | SWT.SINGLE);
+ composite.setLayout(new GridLayout());
+
+ // items checkboxes only for project properties page
+ tableProviders = new Table(composite, page.isForPrefs() ? SWT.NONE : SWT.CHECK);
+ tableProviders.setLayoutData(new GridData(GridData.FILL_BOTH));
+ tableProviders.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ displaySelectedOptionPage();
+ updateButtons();
+ }
+ });
+ tableProvidersViewer = new CheckboxTableViewer(tableProviders);
+ tableProvidersViewer.setContentProvider(new ArrayContentProvider());
+ tableProvidersViewer.setLabelProvider(new ProvidersTableLabelProvider());
+
+ tableProvidersViewer.addCheckStateListener(new ICheckStateListener() {
+ @Override
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ ILanguageSettingsProvider checkedProvider = (ILanguageSettingsProvider) event.getElement();
+ String id = checkedProvider.getId();
+ ILanguageSettingsProvider newProvider = null;
+
+ if (event.getChecked()) {
+ if (LanguageSettingsManager.isWorkspaceProvider(checkedProvider) && !LanguageSettingsManager.isPreferShared(id)) {
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(checkedProvider);
+ if (rawProvider instanceof ILanguageSettingsEditableProvider) {
+ newProvider = LanguageSettingsManager.getProviderCopy((ILanguageSettingsEditableProvider) rawProvider, false);
+ }
+ }
+ } else {
+ if (!LanguageSettingsManager.isWorkspaceProvider(checkedProvider)) {
+ newProvider = LanguageSettingsManager.getWorkspaceProvider(id);
+ }
+ }
+
+ int pos = presentedProviders.indexOf(checkedProvider);
+ tableProviders.setSelection(pos);
+
+ if (newProvider != null) {
+ replaceSelectedProvider(newProvider); // will refresh and save checked providers
+ createOptionsPage(newProvider);
+ } else {
+ tableProvidersViewer.refresh(checkedProvider);
+ saveCheckedProviders();
+ // option page is reused
+ }
+
+ displaySelectedOptionPage();
+ updateButtons();
+ }
+ });
+ }
+
+ /**
+ * Change "globality" of a provider.
+ */
+ private ILanguageSettingsProvider toggleGlobalProvider(ILanguageSettingsProvider provider, boolean toGlobal) {
+ ILanguageSettingsProvider newProvider = null;
+
+ String id = provider.getId();
+ if (toGlobal) {
+ newProvider = LanguageSettingsManager.getWorkspaceProvider(id);
+ } else {
+ // Toggle to configuration-owned provider
+ try {
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider);
+ if (rawProvider instanceof ILanguageSettingsEditableProvider) {
+ newProvider = ((ILanguageSettingsEditableProvider) rawProvider).cloneShallow();
+ }
+ } catch (CloneNotSupportedException e) {
+ CUIPlugin.log("Error cloning provider " + id, e); //$NON-NLS-1$
+ }
+ }
+ if (newProvider != null) {
+ replaceSelectedProvider(newProvider);
+ createOptionsPage(newProvider);
+ displaySelectedOptionPage();
+ updateButtons();
+ } else {
+ newProvider = provider;
+ }
+
+ return newProvider;
+ }
+
+ /**
+ * Create a check-box for "shared" or "global" property of a provider.
+ */
+ private void createSharedProviderCheckBox(Composite parent) {
+ sharedProviderCheckBox = new Button(parent, SWT.CHECK);
+ sharedProviderCheckBox.setText(Messages.LanguageSettingsProviderTab_ShareProviders);
+ sharedProviderCheckBox.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean isGlobal = sharedProviderCheckBox.getSelection();
+ ILanguageSettingsProvider provider = getSelectedProvider();
+ if (isGlobal != LanguageSettingsManager.isWorkspaceProvider(provider)) {
+ // globality changed
+ provider = toggleGlobalProvider(provider, isGlobal);
+ }
+ projectStorageCheckBox.setSelection(provider instanceof LanguageSettingsSerializableProvider
+ && LanguageSettingsManager.isStoringEntriesInProjectArea((LanguageSettingsSerializableProvider) provider));
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+ }
+
+ /**
+ * Create a check-box defining where to store entries of a provider.
+ */
+ private void createProjectStorageCheckBox(Composite parent) {
+ projectStorageCheckBox = new Button(parent, SWT.CHECK);
+ projectStorageCheckBox.setText(Messages.LanguageSettingsProviderTab_StoreEntriesInsideProject);
+ projectStorageCheckBox.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean inProjectArea = projectStorageCheckBox.getSelection();
+ ILanguageSettingsProvider newProvider = getWorkingCopy(getSelectedProvider().getId());
+ LanguageSettingsManager.setStoringEntriesInProjectArea((LanguageSettingsSerializableProvider) newProvider, inProjectArea);
+ replaceSelectedProvider(newProvider);
+ createOptionsPage(newProvider);
+ displaySelectedOptionPage();
+ updateButtons();
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+ }
+
+ /**
+ * Create a link to Preferences page.
+ */
+ private void createLinkToPreferences(final Composite parent, int span) {
+ linkToWorkspacePreferences = new Link(parent, SWT.NONE);
+ String href = NLS.bind("<a href=\"workspace\">{0}</a>", Messages.LanguageSettingsProviderTab_WorkspaceSettings); //$NON-NLS-1$
+ linkToWorkspacePreferences.setText(NLS.bind(Messages.LanguageSettingsProviderTab_OptionsCanBeChangedInPreferencesDiscoveryTab, href));
+ GridData gd = new GridData();
+ gd.horizontalSpan = span;
+ linkToWorkspacePreferences.setLayoutData(gd);
+
+ linkToWorkspacePreferences.addListener(SWT.Selection, new Listener() {
+ @Override
+ public void handleEvent(Event event) {
+ // Use event.text to tell which link was used
+ PreferencesUtil.createPreferenceDialogOn(parent.getShell(), WORKSPACE_PREFERENCE_PAGE, null, null).open();
+ }
+ });
+ }
+
+ /**
+ * Create Options pane.
+ */
+ private void createOptionsPane(Composite parent) {
+ groupOptionsPage = new Group(parent, SWT.SHADOW_ETCHED_IN);
+ groupOptionsPage.setText(Messages.LanguageSettingsProviderTab_LanguageSettingsProvidersOptions);
+ groupOptionsPage.setLayout(new GridLayout(2, false));
+
+ if (!page.isForPrefs()) {
+ createSharedProviderCheckBox(groupOptionsPage);
+ createProjectStorageCheckBox(groupOptionsPage);
+ createLinkToPreferences(groupOptionsPage, 2);
+ }
+
+ compositeOptionsPage = new Composite(groupOptionsPage, SWT.NONE);
+ compositeOptionsPage.setLayout(new TabFolderLayout());
+ }
+
+ /**
+ * Create sash form.
+ */
+ private void createSashForm() {
+ sashFormProviders = new SashForm(usercomp, SWT.VERTICAL);
+ GridLayout layout = new GridLayout();
+ sashFormProviders.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ gd.horizontalSpan = 2;
+ sashFormProviders.setLayoutData(gd);
+
+ createProvidersPane(sashFormProviders);
+ createOptionsPane(sashFormProviders);
+
+ sashFormProviders.setWeights(DEFAULT_CONFIGURE_SASH_WEIGHTS);
+ }
+
+ /**
+ * Gray out or restore all controls except enabling check-box.
+ */
+ private void enableTabControls(boolean enable) {
+ sashFormProviders.setEnabled(enable);
+ tableProviders.setEnabled(enable);
+ compositeOptionsPage.setEnabled(enable);
+
+ buttoncomp.setEnabled(enable);
+
+ if (enable) {
+ displaySelectedOptionPage();
+ } else {
+ if (currentOptionsPage != null) {
+ currentOptionsPage.setVisible(false);
+ }
+
+ buttonSetEnabled(BUTTON_CLEAR, false);
+ buttonSetEnabled(BUTTON_RESET, false);
+ buttonSetEnabled(BUTTON_MOVE_UP, false);
+ buttonSetEnabled(BUTTON_MOVE_DOWN, false);
+ }
+ }
+
+ /**
+ * Create check-box to allow disable/enable language settings providers functionality.
+ */
+ private void createEnableProvidersCheckBox() {
+ // take the flag from master page if available (normally for resource properties)
+ if (masterPropertyPage != null) {
+ enableProvidersCheckBox = setupCheck(usercomp, Messages.LanguageSettingsProviders_EnableForProject, 2, GridData.FILL_HORIZONTAL);
+ enableProvidersCheckBox.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean enabled = enableProvidersCheckBox.getSelection();
+ masterPropertyPage.setLanguageSettingsProvidersEnabled(enabled);
+ enableTabControls(enabled);
+ }
+ });
+
+ enableProvidersCheckBox.setSelection(masterPropertyPage.isLanguageSettingsProvidersEnabled());
+
+ // display but disable the checkbox for file/folder resource
+ enableProvidersCheckBox.setEnabled(page.isForProject());
+ enableTabControls(enableProvidersCheckBox.getSelection());
+ }
+ }
+
+ @Override
+ public void createControls(Composite parent) {
+ super.createControls(parent);
+
+ usercomp.setLayout(new GridLayout());
+ GridData gd = (GridData) usercomp.getLayoutData();
+ // Discourage settings entry table from trying to show all its items at once, see bug 264330
+ gd.heightHint = 1;
+
+ if (page instanceof LanguageSettingsProvidersPage) {
+ masterPropertyPage = (LanguageSettingsProvidersPage) page;
+ }
+
+ trackInitialSettings();
+
+ createSashForm();
+
+ fStatusLine = new StatusMessageLine(usercomp, SWT.LEFT, 2);
+ if (!page.isForPrefs()) {
+ createEnableProvidersCheckBox();
+ }
+
+ String[] buttonLabels;
+ if (page.isForPrefs()) {
+ buttonLabels = new String[2];
+ buttonLabels[BUTTON_CLEAR] = CLEAR_STR;
+ buttonLabels[BUTTON_RESET] = RESET_STR;
+ } else {
+ buttonLabels = new String[5];
+ buttonLabels[BUTTON_CLEAR] = CLEAR_STR;
+ buttonLabels[BUTTON_RESET] = RESET_STR;
+ buttonLabels[BUTTON_MOVE_UP] = MOVEUP_STR;
+ buttonLabels[BUTTON_MOVE_DOWN] = MOVEDOWN_STR;
+ }
+ initButtons(buttonLabels);
+
+ updateData(getResDesc());
+ }
+
+ /**
+ * Clear entries of the selected provider.
+ */
+ private void performClear(ILanguageSettingsProvider selectedProvider) {
+ if (isWorkingCopy(selectedProvider)) {
+ if (selectedProvider instanceof LanguageSettingsSerializableProvider) {
+ LanguageSettingsSerializableProvider editableProvider = (LanguageSettingsSerializableProvider) selectedProvider;
+ editableProvider.clear();
+ tableProvidersViewer.update(selectedProvider, null);
+ }
+ } else {
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(selectedProvider);
+ if (rawProvider instanceof ILanguageSettingsEditableProvider) {
+ ILanguageSettingsEditableProvider newProvider = LanguageSettingsManager.getProviderCopy((ILanguageSettingsEditableProvider) rawProvider, false);
+ if (newProvider != null) {
+ replaceSelectedProvider(newProvider);
+ createOptionsPage(newProvider);
+ displaySelectedOptionPage();
+ }
+ }
+ }
+ updateButtons();
+ }
+
+ /**
+ * Reset settings of the selected provider.
+ */
+ private void performReset(ILanguageSettingsProvider selectedProvider) {
+ String id = selectedProvider.getId();
+
+ ILanguageSettingsProvider newProvider = null;
+ if (page.isForPrefs()) {
+ newProvider = LanguageSettingsManager.getExtensionProviderCopy(id, true);
+ if (newProvider == null) {
+ Status status = new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.ERROR, Messages.GeneralMessages_InternalError_ReportLogToCdtTeam,
+ new Exception("Internal Error getting copy of provider id="+id)); //$NON-NLS-1$
+ fStatusLine.setErrorStatus(status);
+ CUIPlugin.log(status);
+ }
+ } else {
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ String[] defaultIds = ((ILanguageSettingsProvidersKeeper) cfgDescription).getDefaultLanguageSettingsProvidersIds();
+ boolean isDefault = Arrays.asList(defaultIds).contains(id);
+ if (isDefault && !LanguageSettingsManager.isPreferShared(id)) {
+ newProvider = LanguageSettingsManager.getExtensionProviderCopy(id, true);
+ if (newProvider == null) {
+ Status status = new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.ERROR, Messages.GeneralMessages_InternalError_ReportLogToCdtTeam,
+ new Exception("Internal Error getting copy of provider id="+id)); //$NON-NLS-1$
+ fStatusLine.setErrorStatus(status);
+ CUIPlugin.log(status);
+ }
+ } else {
+ newProvider = LanguageSettingsManager.getWorkspaceProvider(id);
+ }
+ tableProvidersViewer.setChecked(selectedProvider, isDefault);
+ }
+
+ if (newProvider != null) {
+ replaceSelectedProvider(newProvider);
+ createOptionsPage(newProvider);
+ displaySelectedOptionPage();
+ updateButtons();
+ }
+ }
+
+ /**
+ * Move selected provider in the table.
+ */
+ private void moveProvider(int oldPos, int newPos) {
+ Collections.swap(presentedProviders, oldPos, newPos);
+ tableProvidersViewer.refresh();
+ tableProviders.showSelection();
+
+ saveCheckedProviders();
+ updateButtons();
+ }
+
+ /**
+ * Move selected provider up.
+ */
+ private void performMoveUp(ILanguageSettingsProvider selectedProvider) {
+ int pos = presentedProviders.indexOf(selectedProvider);
+ if (pos > 0) {
+ moveProvider(pos, pos-1);
+ }
+ }
+
+ /**
+ * Move selected provider down.
+ */
+ private void performMoveDown(ILanguageSettingsProvider selectedProvider) {
+ int pos = presentedProviders.indexOf(selectedProvider);
+ int last = presentedProviders.size() - 1;
+ if (pos >= 0 && pos < last) {
+ moveProvider(pos, pos+1);
+ }
+ }
+
+ /**
+ * Handle pressed buttons.
+ */
+ @Override
+ public void buttonPressed(int buttonIndex) {
+ ILanguageSettingsProvider selectedProvider = getSelectedProvider();
+
+ switch (buttonIndex) {
+ case BUTTON_CLEAR:
+ performClear(selectedProvider);
+ break;
+ case BUTTON_RESET:
+ performReset(selectedProvider);
+ break;
+ case BUTTON_MOVE_UP:
+ performMoveUp(selectedProvider);
+ break;
+ case BUTTON_MOVE_DOWN:
+ performMoveDown(selectedProvider);
+ break;
+ default:
+ }
+ }
+
+ /**
+ * Updates state for all buttons.
+ */
+ @Override
+ protected void updateButtons() {
+ ILanguageSettingsProvider provider = getSelectedProvider();
+ boolean isProviderSelected = provider != null;
+ boolean canForWorkspace = isProviderSelected && page.isForPrefs();
+ boolean canForProject = isProviderSelected && page.isForProject();
+
+ int pos = tableProviders.getSelectionIndex();
+ int count = tableProviders.getItemCount();
+ int last = count - 1;
+ boolean isRangeOk = (pos >= 0 && pos <= last);
+
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider);
+ boolean isAllowedClearing = rawProvider instanceof ILanguageSettingsEditableProvider && rawProvider instanceof LanguageSettingsSerializableProvider
+ && LanguageSettingsProviderAssociationManager.isAllowedToClear(rawProvider);
+
+ boolean canClear = isAllowedClearing && (canForWorkspace || (canForProject && !LanguageSettingsManager.isWorkspaceProvider(provider)));
+ if (rawProvider instanceof LanguageSettingsSerializableProvider) {
+ canClear = canClear && !((LanguageSettingsSerializableProvider)rawProvider).isEmpty();
+ }
+
+ boolean canResetForProject = canForProject && isReconfiguredForProject(provider);
+ boolean canResetForWorkspace = canForWorkspace &&
+ (rawProvider instanceof ILanguageSettingsEditableProvider
+ && !LanguageSettingsManager.isEqualExtensionProvider(rawProvider, false))
+ && ( LanguageSettingsManager.getExtensionProviderIds().contains(rawProvider.getId()) );
+ boolean canReset = canResetForProject || canResetForWorkspace;
+
+ boolean canMoveUp = canForProject && isRangeOk && pos != 0;
+ boolean canMoveDown = canForProject && isRangeOk && pos != last;
+
+ buttonSetEnabled(BUTTON_CLEAR, canClear);
+ buttonSetEnabled(BUTTON_RESET, canReset);
+ buttonSetEnabled(BUTTON_MOVE_UP, canMoveUp);
+ buttonSetEnabled(BUTTON_MOVE_DOWN, canMoveDown);
+ }
+
+ /**
+ * Sort providers displayed in UI. Sorting is by name except test providers are shown
+ * on bottom.
+ */
+ private void sortByName(List<ILanguageSettingsProvider> providers) {
+ // ensure sorting by name all unchecked providers
+ Collections.sort(providers, new Comparator<ILanguageSettingsProvider>() {
+ @Override
+ public int compare(ILanguageSettingsProvider prov1, ILanguageSettingsProvider prov2) {
+ Boolean isTest1 = prov1.getId().matches(TEST_PLUGIN_ID_PATTERN);
+ Boolean isTest2 = prov2.getId().matches(TEST_PLUGIN_ID_PATTERN);
+ int result = isTest1.compareTo(isTest2);
+ if (result == 0) {
+ String name1 = prov1.getName();
+ String name2 = prov2.getName();
+ if (name1 != null && name2 != null) {
+ result = name1.compareTo(name2);
+ }
+ }
+ return result;
+ }
+ });
+ }
+
+ /**
+ * Initialize providers list.
+ */
+ private void initializeProviders() {
+ // The providers list is formed to consist of configuration providers (checked elements on top of the table)
+ // and after that other providers which could be possible added (unchecked) sorted by name.
+
+ List<String> idsList = new ArrayList<String>();
+
+ List<ILanguageSettingsProvider> providers;
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
+ providers = new ArrayList<ILanguageSettingsProvider>(((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders());
+ for (ILanguageSettingsProvider provider : providers) {
+ idsList.add(provider.getId());
+ }
+ } else {
+ providers = new ArrayList<ILanguageSettingsProvider>();
+ }
+
+ List<ILanguageSettingsProvider> allAvailableProvidersSet = LanguageSettingsManager.getWorkspaceProviders();
+ sortByName(allAvailableProvidersSet);
+
+ for (ILanguageSettingsProvider provider : allAvailableProvidersSet) {
+ String id = provider.getId();
+ if (!idsList.contains(id)) {
+ providers.add(provider);
+ idsList.add(id);
+ }
+ }
+
+ // renders better when using temporary
+ presentedProviders = providers;
+
+ ILanguageSettingsProvider selectedProvider = getSelectedProvider();
+ String selectedId = selectedProvider!=null ? selectedProvider.getId() : null;
+
+ tableProvidersViewer.setInput(presentedProviders);
+ if (selectedId!=null) {
+ for (int i=0; i<presentedProviders.size(); i++) {
+ if (selectedId.equals(presentedProviders.get(i).getId())) {
+ tableProviders.setSelection(i);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Get option page from {@link LanguageSettingsProviderAssociationManager}.
+ */
+ private ICOptionPage getOptionsPage(ILanguageSettingsProvider provider) {
+ ICOptionPage optionsPage = null;
+ if (provider != null) {
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider);
+ if (rawProvider != null) {
+ optionsPage = LanguageSettingsProviderAssociationManager.createOptionsPage(rawProvider);
+ }
+
+ if (optionsPage instanceof AbstractLanguageSettingProviderOptionPage) {
+ ((AbstractLanguageSettingProviderOptionPage)optionsPage).init(this, provider.getId());
+ }
+ }
+
+ return optionsPage;
+ }
+
+ /**
+ * Create Options page for a provider.
+ */
+ private void createOptionsPage(ILanguageSettingsProvider provider) {
+ ICOptionPage optionsPage = getOptionsPage(provider);
+
+ if (optionsPage != null) {
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider);
+ boolean isEditableForProject = page.isForProject() && provider instanceof ILanguageSettingsEditableProvider;
+ boolean isEditableForPrefs = page.isForPrefs() && rawProvider instanceof ILanguageSettingsEditableProvider;
+ boolean isEditable = isEditableForProject || isEditableForPrefs;
+ compositeOptionsPage.setEnabled(isEditable);
+
+ String id = (provider != null) ? provider.getId() : null;
+ optionsPageMap.put(id, optionsPage);
+ optionsPage.setContainer(page);
+ optionsPage.createControl(compositeOptionsPage);
+ optionsPage.setVisible(false);
+ compositeOptionsPage.layout(true);
+ }
+ }
+
+ /**
+ * Display selected option page.
+ */
+ private void displaySelectedOptionPage() {
+ if (currentOptionsPage != null) {
+ currentOptionsPage.setVisible(false);
+ }
+
+ ILanguageSettingsProvider provider = getSelectedProvider();
+ String id = (provider != null) ? provider.getId() : null;
+
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider);
+
+ currentOptionsPage = optionsPageMap.get(id);
+
+ if (!page.isForPrefs() ) {
+ boolean isChecked = tableProvidersViewer.getChecked(provider);
+ boolean isShared = isPresentedAsShared(provider);
+ boolean isRawProviderEditable = rawProvider instanceof ILanguageSettingsEditableProvider;
+
+ sharedProviderCheckBox.setVisible(provider != null);
+ sharedProviderCheckBox.setEnabled(isChecked && isRawProviderEditable);
+ sharedProviderCheckBox.setSelection(isShared);
+
+ projectStorageCheckBox.setVisible(rawProvider instanceof LanguageSettingsSerializableProvider);
+ projectStorageCheckBox.setEnabled(isChecked && !isShared);
+ projectStorageCheckBox.setSelection(provider instanceof LanguageSettingsSerializableProvider
+ && LanguageSettingsManager.isStoringEntriesInProjectArea((LanguageSettingsSerializableProvider) provider));
+
+ linkToWorkspacePreferences.setVisible(isShared && currentOptionsPage != null);
+ linkToWorkspacePreferences.setEnabled(isChecked);
+ }
+
+ if (currentOptionsPage != null) {
+ currentOptionsPage.setVisible(true);
+
+ boolean isEditableForProject = page.isForProject() && provider instanceof ILanguageSettingsEditableProvider;
+ boolean isEditableForPrefs = page.isForPrefs() && rawProvider instanceof ILanguageSettingsEditableProvider;
+ boolean isEditable = isEditableForProject || isEditableForPrefs;
+ currentOptionsPage.getControl().setEnabled(isEditable);
+ compositeOptionsPage.setEnabled(isEditable);
+ }
+ }
+
+ /**
+ * Populate provider tables and their option pages
+ */
+ private void updateProvidersTable() {
+ ILanguageSettingsProvider selectedProvider = getSelectedProvider();
+ String selectedId = selectedProvider != null ? selectedProvider.getId() : null;
+
+ // update viewer if the list of providers changed
+ int pos = tableProviders.getSelectionIndex();
+ tableProvidersViewer.setInput(presentedProviders);
+ tableProviders.setSelection(pos);
+
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
+ List<ILanguageSettingsProvider> cfgProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
+ tableProvidersViewer.setCheckedElements(cfgProviders.toArray(new ILanguageSettingsProvider[0]));
+ }
+
+ if (selectedId != null) {
+ for (int i = 0; i < presentedProviders.size(); i++) {
+ if (selectedId.equals(presentedProviders.get(i).getId())) {
+ tableProviders.setSelection(i);
+ break;
+ }
+ }
+ }
+ tableProvidersViewer.refresh();
+
+ optionsPageMap.clear();
+ for (ILanguageSettingsProvider provider : presentedProviders) {
+ createOptionsPage(provider);
+ }
+
+ displaySelectedOptionPage();
+ }
+
+ /**
+ * Update the tab. Called when configuration changes.
+ */
+ @Override
+ public void updateData(ICResourceDescription rcDes) {
+ if (!canBeVisible())
+ return;
+
+ if (rcDes!=null) {
+ if (page.isMultiCfg()) {
+ setAllVisible(false, null);
+ return;
+ } else {
+ setAllVisible(true, null);
+ }
+
+ if (masterPropertyPage != null) {
+ boolean enabled = masterPropertyPage.isLanguageSettingsProvidersEnabled();
+ enableProvidersCheckBox.setSelection(enabled);
+ enableTabControls(enabled);
+ }
+ }
+
+ // for Preference page initialize providers list just once as no configuration here to change
+ // and re-initializing could overwrite modified providers in case of switching tabs or pages
+ if (!page.isForPrefs() || presentedProviders == null) {
+ initializeProviders();
+ }
+ updateProvidersTable();
+ updateButtons();
+ }
+
+ @Override
+ protected void performDefaults() {
+ if (page.isForProject() && (enableProvidersCheckBox==null || enableProvidersCheckBox.getSelection() == false))
+ return;
+
+ if (page.isForPrefs() || page.isForProject()) {
+ if (MessageDialog.openQuestion(usercomp.getShell(),
+ Messages.LanguageSettingsProviderTab_TitleResetProviders,
+ Messages.LanguageSettingsProviderTab_AreYouSureToResetProviders)) {
+
+ if (page.isForProject()) {
+ ICConfigurationDescription cfgDescription = getConfigurationDescription();
+ if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
+ List<ILanguageSettingsProvider> cfgProviders = new ArrayList<ILanguageSettingsProvider>(((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders());
+ String[] defaultIds = ((ILanguageSettingsProvidersKeeper) cfgDescription).getDefaultLanguageSettingsProvidersIds();
+
+ List<ILanguageSettingsProvider> newProviders = new ArrayList<ILanguageSettingsProvider>(defaultIds.length);
+ for (String id : defaultIds) {
+ boolean preferShared = LanguageSettingsManager.isPreferShared(id);
+ ILanguageSettingsProvider newProvider = null;
+ if (!preferShared) {
+ newProvider = LanguageSettingsManager.getExtensionProviderCopy(id, true);
+ }
+ if (newProvider == null) {
+ newProvider = LanguageSettingsManager.getWorkspaceProvider(id);
+ }
+ newProviders.add(newProvider);
+ }
+
+ if (!cfgProviders.equals(newProviders)) {
+ ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(newProviders);
+ }
+ }
+
+ } else if (page.isForPrefs()) {
+ presentedProviders = new ArrayList<ILanguageSettingsProvider>();
+ for (ILanguageSettingsProvider provider : LanguageSettingsManager.getWorkspaceProviders()) {
+ if (!LanguageSettingsManager.isEqualExtensionProvider(provider, true)) {
+ ILanguageSettingsProvider extProvider = LanguageSettingsManager.getExtensionProviderCopy(provider.getId(), true);
+ if (extProvider != null) {
+ provider = extProvider;
+ }
+ }
+ presentedProviders.add(provider);
+ }
+ sortByName(presentedProviders);
+ }
+ }
+
+ ICResourceDescription rcDescription = getResDesc();
+
+ updateData(rcDescription);
+ // update other tabs
+ masterPropertyPage.informAll(UPDATE, rcDescription);
+ }
+ }
+
+ @Override
+ protected void performApply(ICResourceDescription srcRcDescription, ICResourceDescription destRcDescription) {
+ if (!page.isForPrefs()) {
+ ICConfigurationDescription sd = srcRcDescription.getConfiguration();
+ ICConfigurationDescription dd = destRcDescription.getConfiguration();
+ if (sd instanceof ILanguageSettingsProvidersKeeper && dd instanceof ILanguageSettingsProvidersKeeper) {
+ List<ILanguageSettingsProvider> newProviders = ((ILanguageSettingsProvidersKeeper) sd).getLanguageSettingProviders();
+ ((ILanguageSettingsProvidersKeeper) dd).setLanguageSettingProviders(newProviders);
+ }
+ }
+
+ performOK();
+
+ trackInitialSettings();
+ updateData(getResDesc());
+ }
+
+ @Override
+ protected void performOK() {
+ // Build Settings page
+ if (page.isForPrefs()) {
+ try {
+ LanguageSettingsManager.setWorkspaceProviders(presentedProviders);
+ } catch (CoreException e) {
+ CUIPlugin.log("Error setting user defined providers", e); //$NON-NLS-1$
+ }
+ initializeProviders();
+ }
+
+ if (masterPropertyPage != null && enableProvidersCheckBox.getEnabled()) {
+ masterPropertyPage.applyLanguageSettingsProvidersEnabled();
+ }
+
+ Collection<ICOptionPage> optionPages = optionsPageMap.values();
+ for (ICOptionPage op : optionPages) {
+ try {
+ op.performApply(null);
+ } catch (CoreException e) {
+ CUIPlugin.log("Error applying options page", e); //$NON-NLS-1$
+ }
+ }
+ }
+
+ @Override
+ public boolean canBeVisible() {
+ if (CDTPrefUtil.getBool(LanguageSettingsProvidersPage.KEY_NO_SHOW_PROVIDERS)) {
+ return false;
+ }
+
+ return page.isForPrefs() || page.isForProject();
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersLabelProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersLabelProvider.java
new file mode 100644
index 0000000000..e93bae0f8d
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersLabelProvider.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.language.settings.providers;
+
+import java.net.URL;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
+import org.eclipse.cdt.ui.CDTSharedImages;
+
+import org.eclipse.cdt.internal.ui.newui.Messages;
+
+/**
+ * Label provider for language settings providers.
+ *
+ */
+public class LanguageSettingsProvidersLabelProvider extends LabelProvider {
+ private static final String TEST_PLUGIN_ID_PATTERN = "org.eclipse.cdt.*.tests.*"; //$NON-NLS-1$
+ private static final String OOPS = "OOPS"; //$NON-NLS-1$
+
+ /**
+ * Returns base image key (for image without overlay).
+ */
+ protected String getBaseKey(ILanguageSettingsProvider provider) {
+ String imageKey = null;
+ // try id-association
+ String id = provider.getId();
+ URL url = LanguageSettingsProviderAssociationManager.getImageUrl(id);
+ // try class-association
+ if (url == null) {
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider);
+ if (rawProvider != null) {
+ url = LanguageSettingsProviderAssociationManager.getImage(rawProvider.getClass());
+ }
+ }
+ if (url != null) {
+ imageKey = url.toString();
+ }
+
+ if (imageKey == null) {
+ if (id.matches(TEST_PLUGIN_ID_PATTERN)) {
+ imageKey = CDTSharedImages.IMG_OBJS_CDT_TESTING;
+ } else {
+ imageKey = CDTSharedImages.IMG_OBJS_EXTENSION;
+ }
+ }
+ return imageKey;
+ }
+
+ /**
+ * Returns keys for image overlays. Returning {@code null} is not allowed.
+ */
+ protected String[] getOverlayKeys(ILanguageSettingsProvider provider) {
+ return new String[5];
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof ILanguageSettingsProvider) {
+ ILanguageSettingsProvider provider = (ILanguageSettingsProvider)element;
+ String imageKey = getBaseKey(provider);
+ String[] overlayKeys = getOverlayKeys(provider);
+ return CDTSharedImages.getImageOverlaid(imageKey, overlayKeys);
+ }
+ return null;
+ }
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof ILanguageSettingsProvider) {
+ ILanguageSettingsProvider provider = (ILanguageSettingsProvider) element;
+ String name = provider.getName();
+ if (name != null) {
+ if (LanguageSettingsManager.isWorkspaceProvider(provider)) {
+ name = name + Messages.LanguageSettingsProvidersLabelProvider_TextDecorator_Shared;
+ }
+ return name;
+ }
+ return NLS.bind(Messages.GeneralMessages_NonAccessibleID, provider.getId());
+ }
+ return OOPS;
+ }
+
+} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersPage.java
new file mode 100644
index 0000000000..84f5d73538
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProvidersPage.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.language.settings.providers;
+
+import org.eclipse.core.resources.IProject;
+
+import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
+import org.eclipse.cdt.ui.newui.AbstractPage;
+import org.eclipse.cdt.ui.newui.ICPropertyTab;
+
+/**
+ * Property page for language settings providers tabs.
+ * The handling of isLanguageSettingsProvidersEnabled is temporary, this control is to be removed.
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class LanguageSettingsProvidersPage extends AbstractPage {
+ /** @since 5.4 */ // temporary key, subject to removal
+ public static final String KEY_NO_SHOW_PROVIDERS = "properties.providers.tab.disable"; //$NON-NLS-1$
+ /** @since 5.4 */ // temporary key, subject to removal
+ public static final String KEY_NEWSD = "wizard.try.new.sd.enable"; //$NON-NLS-1$
+
+ private static boolean isLanguageSettingsProvidersEnabled = false;
+ private static IProject project = null;
+
+ @Override
+ protected boolean isSingle() {
+ return false;
+ }
+
+ /**
+ * Check if language settings providers functionality is enabled for the project.
+ * Need this method as another page could be inquiring before this page gets initialized.
+ *
+ * @noreference This method is temporary and not intended to be referenced by clients.
+ */
+ public static boolean isLanguageSettingsProvidersEnabled(IProject prj) {
+ if (prj != null) {
+ if (prj.equals(project)) {
+ return isLanguageSettingsProvidersEnabled;
+ } else {
+ return ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityEnabled(project);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if language settings providers functionality is enabled for the current project.
+ *
+ * @noreference This method is temporary and not intended to be referenced by clients.
+ */
+ public boolean isLanguageSettingsProvidersEnabled() {
+ IProject prj = getProject();
+ if (prj != null) {
+ if (!prj.equals(project)) {
+ project = prj;
+ isLanguageSettingsProvidersEnabled = ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityEnabled(project);
+ }
+ return isLanguageSettingsProvidersEnabled;
+ }
+ return false;
+ }
+
+ /**
+ * Enable or disable language settings providers functionality for the current project.
+ * Triggers update of all the property pages.
+ *
+ * Note that this method only sets property for the current editing session.
+ * Use {@link #applyLanguageSettingsProvidersEnabled()} to apply to the project.
+ *
+ * @noreference This method is temporary and not intended to be referenced by clients.
+ */
+ public void setLanguageSettingsProvidersEnabled(boolean enable) {
+ isLanguageSettingsProvidersEnabled = enable;
+ project = getProject();
+ forEach(ICPropertyTab.UPDATE,getResDesc());
+ }
+
+ /**
+ * Apply enablement of language settings providers functionality to the current project.
+ *
+ * @noreference This method is temporary and not intended to be referenced by clients.
+ */
+ public void applyLanguageSettingsProvidersEnabled() {
+ ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(getProject(), isLanguageSettingsProvidersEnabled);
+ }
+
+ @Override
+ public void dispose() {
+ isLanguageSettingsProvidersEnabled = false;
+ project = null;
+ super.dispose();
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/LanguageSettingsImages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/LanguageSettingsImages.java
index 2f96922703..7e26e3a295 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/LanguageSettingsImages.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/LanguageSettingsImages.java
@@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.ui.newui;
+import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
@@ -23,6 +24,7 @@ import org.eclipse.swt.graphics.Image;
import org.eclipse.cdt.core.settings.model.ACPathEntry;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
+import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICSettingEntry;
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.ui.CDTSharedImages;
@@ -32,16 +34,48 @@ import org.eclipse.cdt.ui.CUIPlugin;
* Helper class to provide unified images for {@link ICLanguageSettingEntry}.
*/
public class LanguageSettingsImages {
+ public static Image getImage(int kind, int flags, boolean isProjectRelative) {
+ String imageKey = getImageKey(kind, flags, isProjectRelative);
+ if (imageKey != null) {
+ return CDTSharedImages.getImage(imageKey);
+ }
+ return null;
+ }
+
+ /**
+ * Returns image for the given entry from internally managed repository including
+ * necessary overlays for given configuration description.
+ *
+ * @param entry - language settings entry to get an image for.
+ * @param cfgDescription - configuration description of the entry.
+ * @return the image for the entry with appropriate overlays.
+ */
+ public static Image getImage(ICLanguageSettingEntry entry, ICConfigurationDescription cfgDescription) {
+ String projectName = null;
+
+ if (cfgDescription != null) {
+ ICProjectDescription prjDescription = cfgDescription.getProjectDescription();
+ if (prjDescription != null) {
+ IProject project = prjDescription.getProject();
+ if (project != null) {
+ projectName = project.getName();
+ }
+ }
+ }
+
+ return getImage(entry, projectName, cfgDescription);
+ }
+
/**
* @return the base key for the image.
*/
public static String getImageKey(int kind, int flag, boolean isProjectRelative) {
String imageKey = null;
-
+
boolean isWorkspacePath = (flag & ICSettingEntry.VALUE_WORKSPACE_PATH) != 0;
boolean isBuiltin = (flag & ICSettingEntry.BUILTIN) != 0;
boolean isFramework = (flag & ICSettingEntry.FRAMEWORKS_MAC) != 0;
-
+
switch (kind) {
case ICSettingEntry.INCLUDE_PATH:
if (isWorkspacePath) {
@@ -89,7 +123,7 @@ public class LanguageSettingsImages {
* @param cfgDescription - configuration description of the entry.
* @return the image for the entry with appropriate overlays.
*/
- public static Image getImage(ICLanguageSettingEntry entry, String projectName, ICConfigurationDescription cfgDescription) {
+ private static Image getImage(ICLanguageSettingEntry entry, String projectName, ICConfigurationDescription cfgDescription) {
int kind = entry.getKind();
int flags = entry.getFlags();
boolean isWorkspacePath = (flags & ICSettingEntry.VALUE_WORKSPACE_PATH) != 0;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java
index c6f86743b8..d0ad9a79ce 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java
@@ -4,7 +4,7 @@
* 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:
* Andrew Gvozdev - Initial API and implementation
* IBM Corporation
@@ -138,7 +138,6 @@ public class Messages extends NLS {
public static String EnvironmentTab_8;
public static String EnvironmentTab_9;
public static String ErrorParsTab_error_IllegalCharacter;
- public static String ErrorParsTab_error_NonAccessibleID;
public static String ErrorParsTab_error_NonEmptyName;
public static String ErrorParsTab_error_NonUniqueID;
public static String ErrorParsTab_error_OnApplyingSettings;
@@ -174,6 +173,8 @@ public class Messages extends NLS {
public static String FileListControl_editdialog_title;
public static String FileListControl_movedown;
public static String FileListControl_moveup;
+ public static String GeneralMessages_InternalError_ReportLogToCdtTeam;
+ public static String GeneralMessages_NonAccessibleID;
public static String IncludeDialog_0;
public static String IncludeDialog_1;
public static String IncludeDialog_2;
@@ -186,9 +187,43 @@ public class Messages extends NLS {
public static String IncludeTab_2;
public static String IncludeTab_export;
public static String IncludeTab_import;
+ public static String LanguageSettingEntryDialog_Add;
+ public static String LanguageSettingEntryDialog_BuiltInFlag;
+ public static String LanguageSettingEntryDialog_Directory;
+ public static String LanguageSettingEntryDialog_File;
+ public static String LanguageSettingEntryDialog_Filesystem;
+ public static String LanguageSettingEntryDialog_FrameworkFolder;
+ public static String LanguageSettingEntryDialog_IncludeDirectory;
+ public static String LanguageSettingEntryDialog_IncludeFile;
+ public static String LanguageSettingEntryDialog_Library;
+ public static String LanguageSettingEntryDialog_LibraryPath;
+ public static String LanguageSettingEntryDialog_Name;
+ public static String LanguageSettingEntryDialog_Path;
+ public static String LanguageSettingEntryDialog_PreporocessorMacro;
+ public static String LanguageSettingEntryDialog_PreprocessorMacroFile;
+ public static String LanguageSettingEntryDialog_ProjectPath;
+ public static String LanguageSettingEntryDialog_SelectKind;
+ public static String LanguageSettingEntryDialog_Value;
+ public static String LanguageSettingEntryDialog_WorkspacePath;
+ public static String LanguageSettingsEntriesTab_Cannot_Determine_Languages;
+ public static String LanguageSettingsEntriesTab_Entries_Not_Editable;
public static String LanguageSettingsImages_FileDoesNotExist;
public static String LanguageSettingsImages_FolderDoesNotExist;
public static String LanguageSettingsImages_UsingRelativePathsNotRecommended;
+ public static String LanguageSettingsProviders_EnableForProject;
+ public static String LanguageSettingsProvidersLabelProvider_TextDecorator_Shared;
+ public static String LanguageSettingsProviderTab_AreYouSureToResetProviders;
+ public static String LanguageSettingsProviderTab_Clear;
+ public static String LanguageSettingsProviderTab_LanguageSettingsProvidersOptions;
+ public static String LanguageSettingsProviderTab_OptionsCanBeChangedInPreferencesDiscoveryTab;
+ public static String LanguageSettingsProviderTab_ProviderOptions;
+ public static String LanguageSettingsProviderTab_Reset;
+ public static String LanguageSettingsProviderTab_SettingEntries;
+ public static String LanguageSettingsProviderTab_SettingEntriesTooltip;
+ public static String LanguageSettingsProviderTab_ShareProviders;
+ public static String LanguageSettingsProviderTab_StoreEntriesInsideProject;
+ public static String LanguageSettingsProviderTab_TitleResetProviders;
+ public static String LanguageSettingsProviderTab_WorkspaceSettings;
public static String LanguagesTab_0;
public static String LanguagesTab_1;
public static String LibraryPathTab_1;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties
index 8da3b3582f..06cc6138bd 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties
@@ -166,9 +166,45 @@ IncludeDialog_0=Directory:
IncludeDialog_1=File:
IncludeDialog_2=Add to all configurations
IncludeDialog_3=Add to all languages
+LanguageSettingEntryDialog_Add=Add
+LanguageSettingEntryDialog_BuiltInFlag=Treat as built-in
+LanguageSettingEntryDialog_Directory=Dir:
+LanguageSettingEntryDialog_File=File:
+LanguageSettingEntryDialog_Filesystem=Filesystem
+LanguageSettingEntryDialog_FrameworkFolder=Framework folder (Mac only)
+LanguageSettingEntryDialog_IncludeDirectory=Include Directory
+LanguageSettingEntryDialog_IncludeFile=Include File
+LanguageSettingEntryDialog_Library=Library
+LanguageSettingEntryDialog_LibraryPath=Library Path
+LanguageSettingEntryDialog_Name=Name:
+LanguageSettingEntryDialog_Path=Path:
+LanguageSettingEntryDialog_PreporocessorMacro=Preprocessor Macro
+LanguageSettingEntryDialog_PreprocessorMacroFile=Preprocessor Macros File
+LanguageSettingEntryDialog_ProjectPath=Project Path
+LanguageSettingEntryDialog_SelectKind=Select Kind:
+LanguageSettingEntryDialog_Value=Value:
+LanguageSettingEntryDialog_WorkspacePath=Workspace Path
+LanguageSettingsEntriesTab_Cannot_Determine_Languages=Cannot determine toolchain languages.
+LanguageSettingsEntriesTab_Entries_Not_Editable=Setting entries for this provider are supplied by the system and are not editable.
LanguageSettingsImages_FileDoesNotExist=The selected file does not exist or not accessible.
LanguageSettingsImages_FolderDoesNotExist=The selected folder does not exist or not accessible.
LanguageSettingsImages_UsingRelativePathsNotRecommended=Using relative paths is ambiguous and not recommended. It can cause unexpected effects.
+
+LanguageSettingsProviders_EnableForProject=Enable language settings providers for this project
+LanguageSettingsProvidersLabelProvider_TextDecorator_Shared=\ \ \ [ Shared ]
+LanguageSettingsProviderTab_AreYouSureToResetProviders=Are you sure you want to reset all customized language settings providers?\nPlease note that providers may regain entries on their own schedule.
+LanguageSettingsProviderTab_Clear=Clear Entries
+LanguageSettingsProviderTab_LanguageSettingsProvidersOptions=Language Settings Provider Options
+LanguageSettingsProviderTab_OptionsCanBeChangedInPreferencesDiscoveryTab=Options of global providers below can be changed in {0}, Discovery Tab.
+LanguageSettingsProviderTab_Reset=Reset
+LanguageSettingsProviderTab_ProviderOptions=Language Settings Provider Options
+LanguageSettingsProviderTab_SettingEntries=Setting Entries
+LanguageSettingsProviderTab_SettingEntriesTooltip=Setting Entries
+LanguageSettingsProviderTab_ShareProviders=Share setting entries between projects (global provider)
+LanguageSettingsProviderTab_StoreEntriesInsideProject=Store entries in project settings folder (easing project miration)
+LanguageSettingsProviderTab_TitleResetProviders=Reset Language Settings Providers
+LanguageSettingsProviderTab_WorkspaceSettings=Workspace Settings
+
LanguagesTab_0=Content type
LanguagesTab_1=Language
LibraryPathTab_1=Add...
@@ -207,7 +243,6 @@ ErrorParsTab_error_NonEmptyName=Specify non empty name
ErrorParsTab_error_NonUniqueID=Error parser ID is not unique, specify different name
ErrorParsTab_error_OnApplyingSettings=Error applying Error Parser Tab settings
ErrorParsTab_error_OnRestoring=Error restoring default Error Parser Tab settings
-ErrorParsTab_error_NonAccessibleID=[ Not accessible id={0} ]
ErrorParsTab_error_IllegalCharacter=Special character ''{0}'' is not allowed
ErrorParsTab_label_EnterName=Enter name of new error parser:
ErrorParsTab_label_DefaultRegexErrorParserName=Regex Error Parser
@@ -274,6 +309,8 @@ CDTMainWizardPage_0=Project name cannot contain '\#' symbol
CDTMainWizardPage_1=Project category is selected. Expand the category and select a concrete project type.
CProjectWizard_0=Add C Project Nature
CCProjectWizard_0=Add CC Project Nature
+GeneralMessages_InternalError_ReportLogToCdtTeam=Internal error happened, report application log to CDT team.
+GeneralMessages_NonAccessibleID=[ Not accessible id={0} ]
WorkingSetConfigAction_21=Building project
WorkingSetConfigAction_22=Build error
IncludeTab_export=Export Settings...
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/ProblemsLabelDecorator.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/ProblemsLabelDecorator.java
index 4176c89f54..21ec525f43 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/ProblemsLabelDecorator.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/ProblemsLabelDecorator.java
@@ -10,12 +10,13 @@
*******************************************************************************/
package org.eclipse.cdt.internal.ui.viewsupport;
+import java.util.List;
+
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IBaseLabelProvider;
@@ -29,6 +30,10 @@ import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.ui.texteditor.MarkerUtilities;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
+import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
@@ -36,6 +41,7 @@ import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
import org.eclipse.cdt.ui.CElementImageDescriptor;
@@ -379,6 +385,31 @@ public class ProblemsLabelDecorator implements ILabelDecorator, ILightweightLabe
}
}
+ private static boolean isCustomizedResource(ICConfigurationDescription cfgDescription, IResource rc) {
+ if (rc instanceof IProject)
+ return false;
+
+ if (!ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityEnabled(rc.getProject())) {
+ ICResourceDescription rcDescription = cfgDescription.getResourceDescription(rc.getProjectRelativePath(), true);
+ return rcDescription != null;
+ }
+
+ if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
+ for (ILanguageSettingsProvider provider: ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders()) {
+ for (String languageId : LanguageSettingsManager.getLanguages(rc, cfgDescription)) {
+ List<ICLanguageSettingEntry> list = provider.getSettingEntries(cfgDescription, rc, languageId);
+ if (list != null) {
+ List<ICLanguageSettingEntry> listDefault = provider.getSettingEntries(cfgDescription, rc.getParent(), languageId);
+ // != is OK here due as the equal lists will have the same reference in WeakHashSet
+ if (list != listDefault)
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
/**
* @param rc - resource to check
* @return flags {@link TICK_CONFIGURATION} if the resource has custom settings and possibly needs
@@ -393,9 +424,7 @@ public class ProblemsLabelDecorator implements ILabelDecorator, ILightweightLabe
if (prjDescription != null) {
ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration();
if (cfgDescription != null) {
- IPath path = rc.getProjectRelativePath();
- ICResourceDescription rcDescription = cfgDescription.getResourceDescription(path, true);
- if (rcDescription != null)
+ if (isCustomizedResource(cfgDescription, rc))
result |= TICK_CONFIGURATION;
}
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CDTSharedImages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CDTSharedImages.java
index adf97abc88..e812341ba4 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CDTSharedImages.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CDTSharedImages.java
@@ -172,6 +172,8 @@ public class CDTSharedImages {
public static final String IMG_OBJS_CORRECTION_RENAME = "icons/obj16/correction_rename.gif"; //$NON-NLS-1$
public static final String IMG_OBJS_CORRECTION_LINKED_RENAME = "icons/obj16/correction_linked_rename.gif"; //$NON-NLS-1$
+ /** @since 5.4 */
+ public static final String IMG_ETOOL_PROJECT = "icons/etool16/prj_obj.gif"; //$NON-NLS-1$
public static final String IMG_VIEW_BUILD_CONSOLE = "icons/view16/buildconsole.gif"; //$NON-NLS-1$
// Images for file list control
@@ -186,6 +188,12 @@ public class CDTSharedImages {
public static final String IMG_OVR_ERROR = "icons/ovr16/error_co.gif"; //$NON-NLS-1$
public static final String IMG_OVR_SETTING = "icons/ovr16/setting_nav.gif"; //$NON-NLS-1$
public static final String IMG_OVR_INACTIVE = "icons/ovr16/inactive_co.gif"; //$NON-NLS-1$
+ /** @since 5.4 */
+ public static final String IMG_OVR_PARENT = "icons/ovr16/path_inherit_co.gif"; //$NON-NLS-1$
+ /** @since 5.4 */
+ public static final String IMG_OVR_EDITED = "icons/ovr16/edited_ovr.gif"; //$NON-NLS-1$
+ /** @since 5.4 */
+ public static final String IMG_OVR_USER = "icons/ovr16/person_ovr.gif"; //$NON-NLS-1$
// Pin & Clone
public static final String IMG_THREAD_SUSPENDED_R_PINNED = "icons/obj16/threads_obj_r.gif"; //$NON-NLS-1$
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/language/settings/providers/AbstractLanguageSettingProviderOptionPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/language/settings/providers/AbstractLanguageSettingProviderOptionPage.java
new file mode 100644
index 0000000000..13871ccfa8
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/language/settings/providers/AbstractLanguageSettingProviderOptionPage.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.ui.language.settings.providers;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
+import org.eclipse.cdt.ui.dialogs.AbstractCOptionPage;
+import org.eclipse.cdt.ui.newui.AbstractCPropertyTab;
+
+import org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProviderTab;
+
+/**
+ * Abstract class to implement language settings providers Options page.
+ *
+ * @since 5.4
+ */
+public abstract class AbstractLanguageSettingProviderOptionPage extends AbstractCOptionPage {
+ private LanguageSettingsProviderTab providerTab;
+ private String providerId;
+
+ /**
+ * Initialize the options page with the owning tab and provider ID.
+ *
+ * @param providerTab - provider tab which owns the options page.
+ * @param providerId - ID of the provider the options page is for.
+ */
+ public void init(AbstractCPropertyTab providerTab, String providerId) {
+ this.providerTab = (LanguageSettingsProviderTab) providerTab;
+ this.providerId = providerId;
+ }
+
+ /**
+ * Get provider being displayed on this Options Page.
+ * @return provider.
+ */
+ public ILanguageSettingsProvider getProvider() {
+ return LanguageSettingsManager.getRawProvider(providerTab.getProvider(providerId));
+ }
+
+ /**
+ * Get working copy of the provider to allow its options to be modified.
+ * @return working copy of the provider.
+ */
+ public ILanguageSettingsProvider getProviderWorkingCopy() {
+ return providerTab.getWorkingCopy(providerId);
+ }
+
+ /**
+ * Refresh provider item in the table and update buttons.
+ * This method is intended for use by an Options Page of the provider.
+ *
+ * @param provider - provider item in the table to refresh.
+ */
+ public void refreshItem(ILanguageSettingsProvider provider) {
+ providerTab.refreshItem(provider);
+ }
+
+ @Override
+ public void performApply(IProgressMonitor monitor) throws CoreException {
+ // normally should be handled by LanguageSettingsProviderTab
+ }
+
+ @Override
+ public void performDefaults() {
+ // normally should be handled by LanguageSettingsProviderTab
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/language/settings/providers/LanguageSettingsProvidersImages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/language/settings/providers/LanguageSettingsProvidersImages.java
new file mode 100644
index 0000000000..7317e6e8c4
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/language/settings/providers/LanguageSettingsProvidersImages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2012 Andrew Gvozdev and others.
+ * 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:
+ * Andrew Gvozdev - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.ui.language.settings.providers;
+
+import java.net.URL;
+
+import org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProviderAssociationManager;
+
+/**
+ * Utility class to provide API for language settings providers images.
+ *
+ * @since 5.4
+ */
+public class LanguageSettingsProvidersImages {
+ /**
+ * Get image URL for language settings provider with the given ID.
+ *
+ * @param providerId - ID of language settings provider.
+ * @return image URL or {@code null}.
+ */
+ public static URL getImageUrl(String providerId) {
+ return LanguageSettingsProviderAssociationManager.getImageUrl(providerId);
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractCPropertyTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractCPropertyTab.java
index aaa8b02edf..ddd9791406 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractCPropertyTab.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractCPropertyTab.java
@@ -64,70 +64,72 @@ import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.newui.Messages;
/**
- * It is a parent for all standard property tabs
+ * 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
+ * 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.
+ * 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).
+ * uniform manner (setupLabel(), setupText() etc).
* - means to handle control messages which are the main
- * communication way for new CDT model pages and tabs.
+ * 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;
- 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 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 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 Image icon = null;
+ private String helpId = EMPTY_STR;
+
protected boolean visible;
@Override
@@ -139,8 +141,8 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
/**
* Creates basic widgets for property tab.
* Descendants should, normally, override
- * this method but call super.createControls().
- *
+ * this method but call super.createControls().
+ *
* @param parent
*/
protected void createControls(Composite parent) {
@@ -153,27 +155,27 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
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"
+ * null instead of name means "skip place"
*/
protected void initButtons(String[] names) {
initButtons(buttoncomp, names, 80);
@@ -181,7 +183,7 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
protected void initButtons(String[] names, int width) {
initButtons(buttoncomp, names, width);
}
-
+
/**
* Ability to create standard button on any composite.
* @param c
@@ -201,15 +203,15 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
gdb.grabExcessHorizontalSpace = false;
gdb.horizontalAlignment = SWT.FILL;
gdb.minimumWidth = width;
-
+
if (names[i] != null)
buttons[i].setText(names[i]);
- else { // no button, but placeholder !
+ 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
@@ -219,15 +221,15 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
});
}
}
-
+
/**
- * Called when user changes
+ * 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.
*/
@@ -244,13 +246,13 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
visible = _visible;
if (visible) updateData(page.getResDesc());
}
-
+
/**
- * Descendant tabs should implement this method so
- * that it copies it's data from one description
+ * 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
*/
@@ -272,32 +274,32 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
}
}
}
-
+
/**
- * Method should be rewritten to handle button presses
+ * Method should be rewritten to handle button presses
* @param i : number of button pressed
- *
- * Does nothing by default.
+ *
+ * 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
+ * @return - true if button exists and enabled
*/
protected boolean buttonIsEnabled(int i) {
- if (buttons == null || buttons.length <= 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
*/
@@ -305,11 +307,11 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
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
*/
@@ -345,13 +347,13 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
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);
@@ -359,7 +361,7 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
setupControl(g, 1, mode);
return g;
}
-
+
protected Button setupCheck(Composite c, String name, int span, int mode) {
Button b = new Button(c, SWT.CHECK);
b.setText(name);
@@ -375,23 +377,23 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
}
/**
- * Selection handler for checkbox created
- * by methods "setupCheck()" or "setupTri()"
- * Descendants should override this method
- * if they use "setupCheck".
+ * 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) { ... }
+ * 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.
+ // exceptions can occur: do nothing.
if (c != null) {
if (span != 0) {
GridData gd = new GridData(mode);
@@ -402,11 +404,11 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
c.setFont(p.getFont());
}
}
-
+
/*
- * A set of methods providing selection dialogs for files or dirs.
+ * 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);
@@ -431,12 +433,12 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
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);
+ dialog.setTitle(Messages.AbstractCPropertyTab_0);
if (dialog.open() == Window.OK) {
Object[] selected = dialog.getResult();
if (selected.length > 0) {
@@ -453,7 +455,19 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
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;
@@ -461,7 +475,7 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
/* 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());
@@ -470,7 +484,7 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
else
dialog.setInput(prj);
dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
-
+
if (dir) {
IResource container = null;
if(path.isAbsolute()){
@@ -512,14 +526,14 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
}
if (dialog.open() == Window.OK) {
IResource resource = (IResource) dialog.getFirstResult();
- if (resource != null) {
+ if (resource != null) {
StringBuffer buf = new StringBuffer();
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();
@@ -553,19 +567,19 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
dispose();
break;
case ICPropertyTab.VISIBLE:
- if (canBeVisible())
+ if (canBeVisible())
setVisible(data != null);
- else
+ else
setVisible(false);
break;
case ICPropertyTab.SET_ICON:
- icon = (Image)data;
+ icon = (Image)data;
break;
default:
break;
}
}
-
+
// By default, returns true (no visibility restriction)
// But several pages should rewrite this functionality.
@Override
@@ -587,20 +601,20 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
}
/**
- * Sets checkbox to appropriate state:
+ * Sets checkbox to appropriate state:
* unchecked or checked
* @param b - checkbox to set
- * @param state
+ * @param state
*/
public static void setTriSelection(Button b, boolean state) {
setTriSelection(b, state ? TRI_YES : TRI_NO);
}
-
+
/**
- * Sets checkbox to appropriate state:
+ * Sets checkbox to appropriate state:
* unchecked, checked or unknown (grayed)
* @param b - checkbox to set
- * @param state
+ * @param state
*/
public static void setTriSelection(Button b, int state) {
switch (state) {
@@ -623,7 +637,7 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
* 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
@@ -636,7 +650,7 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
/**
* 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() {
@@ -652,8 +666,8 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
/**
* Utility method to show/hide working panes
- * When panes are hidden, message becomes visible
- *
+ * When panes are hidden, message becomes visible
+ *
* @param visible - true or false
* @param msg - text to be shown instead of panes
*/
@@ -673,21 +687,21 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
b.setVisible(visible);
}
}
-
+
/**
* Allows changing message on background pane,
* which becomes visible after usercomp hidden
- *
- * @param s - text to display or null for default
+ *
+ * @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()}
*/
@@ -714,7 +728,7 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
* 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/>
@@ -729,12 +743,12 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab {
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.
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractLangsListTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractLangsListTab.java
index 63e0fe4ec3..637b944fa2 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractLangsListTab.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractLangsListTab.java
@@ -19,7 +19,6 @@ import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
-import org.eclipse.core.resources.IProject;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
@@ -242,7 +241,7 @@ public abstract class AbstractLangsListTab extends AbstractCPropertyTab {
int index = table.getSelectionIndex();
if (index<0 || table.getSelectionIndices().length!=1)
return null;
-
+
return (ICLanguageSettingEntry)(table.getItem(index).getData());
}
@@ -730,8 +729,7 @@ public abstract class AbstractLangsListTab extends AbstractCPropertyTab {
public Image getColumnImage(Object element, int columnIndex) {
if (columnIndex==0 && (element instanceof ICLanguageSettingEntry)) {
ICConfigurationDescription cfg = getResDesc().getConfiguration();
- IProject project = cfg.getProjectDescription().getProject();
- return LanguageSettingsImages.getImage((ICLanguageSettingEntry) element, project.getName(), cfg);
+ return LanguageSettingsImages.getImage((ICLanguageSettingEntry) element, cfg);
}
return null;
}
@@ -760,7 +758,7 @@ public abstract class AbstractLangsListTab extends AbstractCPropertyTab {
} else if (columnIndex == 0) {
return element.toString();
}
-
+
return null;
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ErrorParsTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ErrorParsTab.java
index fe692d14e2..c8e9e891a8 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ErrorParsTab.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ErrorParsTab.java
@@ -166,7 +166,7 @@ public class ErrorParsTab extends AbstractCPropertyTab {
return name;
}
}
- return NLS.bind(Messages.ErrorParsTab_error_NonAccessibleID, id);
+ return NLS.bind(Messages.GeneralMessages_NonAccessibleID, id);
}
return OOPS;
}

Back to the top