diff --git a/build/org.eclipse.cdt.make.ui/plugin.xml b/build/org.eclipse.cdt.make.ui/plugin.xml index 002d57859e9..511eb8174e3 100644 --- a/build/org.eclipse.cdt.make.ui/plugin.xml +++ b/build/org.eclipse.cdt.make.ui/plugin.xml @@ -494,11 +494,11 @@ ` - + - + diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/AllLanguageSettingsProvidersMBSTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/AllLanguageSettingsProvidersMBSTests.java index 4ab865896ad..6937c34379a 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/AllLanguageSettingsProvidersMBSTests.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/AllLanguageSettingsProvidersMBSTests.java @@ -25,6 +25,7 @@ public class AllLanguageSettingsProvidersMBSTests extends TestSuite { public AllLanguageSettingsProvidersMBSTests() { super(AllLanguageSettingsProvidersMBSTests.class.getName()); + addTestSuite(LanguageSettingsProvidersMBSTest.class); addTestSuite(GCCBuildCommandParserTest.class); addTestSuite(BuiltinSpecsDetectorTest.class); addTestSuite(GCCBuiltinSpecsDetectorTest.class); diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java index b9dfedc77d3..45fc75c5d72 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java @@ -14,16 +14,23 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage; +import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.settings.model.CIncludePathEntry; import org.eclipse.cdt.core.settings.model.CMacroEntry; +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.ICProjectDescriptionManager; import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.core.testplugin.ResourceHelper; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; +import org.eclipse.cdt.internal.core.Cygwin; +import org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorCygwin; import org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; /** * Test cases to test GCC built-in specs detector. @@ -45,6 +52,20 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { } } + /** + * Mock GCCBuiltinSpecsDetectorCygwin to gain access to protected methods. + */ + class MockGCCBuiltinSpecsDetectorCygwin extends GCCBuiltinSpecsDetectorCygwin { + @Override + public void startupForLanguage(String languageId) throws CoreException { + super.startupForLanguage(languageId); + } + @Override + public void shutdownForLanguage() { + super.shutdownForLanguage(); + } + } + @Override protected void setUp() throws Exception { super.setUp(); @@ -55,6 +76,21 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { super.tearDown(); } + /** + * Helper method to fetch configuration descriptions. + */ + private ICConfigurationDescription[] getConfigurationDescriptions(IProject project) { + CoreModel coreModel = CoreModel.getDefault(); + ICProjectDescriptionManager mngr = coreModel.getProjectDescriptionManager(); + // project description + ICProjectDescription projectDescription = mngr.getProjectDescription(project); + assertNotNull(projectDescription); + assertEquals(1, projectDescription.getConfigurations().length); + // configuration description + ICConfigurationDescription[] cfgDescriptions = projectDescription.getConfigurations(); + return cfgDescriptions; + } + /** * Test expansion of variables in build command. */ @@ -363,4 +399,68 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { assertEquals(1, entries.size()); } + /** + * Test parsing of include directives for Cygwin for global provider. + */ + public void testGCCBuiltinSpecsDetector_Cygwin_NoProject() throws Exception { + if (!Cygwin.isAvailable()) { + // Skip the test if Cygwin is not available. + return; + } + + String cygwinLocation = "/usr/include"; + String windowsLocation = ResourceHelper.cygwinToWindowsPath(cygwinLocation); + assertTrue("windowsLocation=["+windowsLocation+"]", new Path(windowsLocation).getDevice()!=null); + + MockGCCBuiltinSpecsDetectorCygwin detector = new MockGCCBuiltinSpecsDetectorCygwin(); + + detector.startup(null, null); + detector.startupForLanguage(null); + detector.processLine("#include <...> search starts here:"); + detector.processLine(" /usr/include"); + detector.processLine("End of search list."); + detector.shutdownForLanguage(); + detector.shutdown(); + + // check populated entries + List entries = detector.getSettingEntries(null, null, null); + assertEquals(new CIncludePathEntry(new Path(windowsLocation), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0)); + assertEquals(1, entries.size()); + } + + /** + * Test parsing of include directives for Cygwin for provider running for a configuration. + */ + public void testGCCBuiltinSpecsDetector_Cygwin_Configuration() throws Exception { + if (!Cygwin.isAvailable()) { + // Skip the test if Cygwin is not available. + return; + } + + String cygwinLocation = "/usr/include"; + String windowsLocation = ResourceHelper.cygwinToWindowsPath(cygwinLocation); + assertTrue("windowsLocation=["+windowsLocation+"]", new Path(windowsLocation).getDevice()!=null); + + // Create model project and folders to test + String projectName = getName(); + IProject project = ResourceHelper.createCDTProjectWithConfig(projectName); + ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + + MockGCCBuiltinSpecsDetectorCygwin detector = new MockGCCBuiltinSpecsDetectorCygwin(); + + detector.startup(cfgDescription, null); + detector.startupForLanguage(null); + detector.processLine("#include <...> search starts here:"); + detector.processLine(" /usr/include"); + detector.processLine("End of search list."); + detector.shutdownForLanguage(); + detector.shutdown(); + + // check populated entries + List entries = detector.getSettingEntries(null, null, null); + assertEquals(new CIncludePathEntry(new Path(windowsLocation), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0)); + assertEquals(1, entries.size()); + } + } diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/LanguageSettingsProvidersMBSTest.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/LanguageSettingsProvidersMBSTest.java new file mode 100644 index 00000000000..2f63c1c041c --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/LanguageSettingsProvidersMBSTest.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * 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.language.settings.providers.tests; + +import java.util.ArrayList; +import java.util.List; + +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.LanguageSettingsPersistenceProjectTests; +import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.core.testplugin.util.BaseTestCase; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.dataprovider.ConfigurationDataProvider; +import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; + +/** + * Test creation of a new project in respect with language settings providers. + */ +public class LanguageSettingsProvidersMBSTest extends BaseTestCase { + private static final String MBS_LANGUAGE_SETTINGS_PROVIDER_ID = ScannerDiscoveryLegacySupport.MBS_LANGUAGE_SETTINGS_PROVIDER_ID; + private static final String USER_LANGUAGE_SETTINGS_PROVIDER_ID = ScannerDiscoveryLegacySupport.USER_LANGUAGE_SETTINGS_PROVIDER_ID; + private static final String GCC_SPECS_DETECTOR_ID = "org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector"; + private static final String PROJECT_TYPE_EXECUTABLE_GNU = "cdt.managedbuild.target.gnu.exe"; + private static final String LANGUAGE_SETTINGS_PROJECT_XML = LanguageSettingsPersistenceProjectTests.LANGUAGE_SETTINGS_PROJECT_XML; + private static final String LANGUAGE_SETTINGS_WORKSPACE_XML = LanguageSettingsPersistenceProjectTests.LANGUAGE_SETTINGS_WORKSPACE_XML; + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + ManagedBuildTestHelper.removeProject(this.getName()); + super.tearDown(); + } + + /** + * Imitate a new Project Wizard. New Project Wizards really do these things in CDT. + */ + private static IProject imitateNewProjectWizard(String name, String projectTypeId) throws CoreException { + IProject project = ManagedBuildTestHelper.createProject(name, projectTypeId); + ManagedBuildTestHelper.addManagedBuildNature(project); + + ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project, true); + assertNotNull(prjDescription); + ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations(); + for (ICConfigurationDescription cfgDescription : cfgDescriptions) { + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(project, true); + IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(cfgDescription); + ConfigurationDataProvider.setDefaultLanguageSettingsProviders(cfg, cfgDescription); + + assertTrue(((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders().size() > 0); + } + + CoreModel.getDefault().setProjectDescription(project, prjDescription); + + return project; + } + + /** + * Test new GNU Executable project. + */ + public void testGnuToolchainProviders() throws Exception { + // create a new project imitating wizard + IProject project = imitateNewProjectWizard(this.getName(), PROJECT_TYPE_EXECUTABLE_GNU); + + // check that the language settings providers are in place. + ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project, false); + assertNotNull(prjDescription); + ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations(); + for (ICConfigurationDescription cfgDescription : cfgDescriptions) { + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + List providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + { + ILanguageSettingsProvider provider = providers.get(0); + String id = provider.getId(); + assertEquals(USER_LANGUAGE_SETTINGS_PROVIDER_ID, id); + assertEquals(false, LanguageSettingsManager.isPreferShared(id)); + assertEquals(false, LanguageSettingsManager.isWorkspaceProvider(provider)); + } + { + ILanguageSettingsProvider provider = providers.get(1); + String id = provider.getId(); + assertEquals(MBS_LANGUAGE_SETTINGS_PROVIDER_ID, id); + assertEquals(true, LanguageSettingsManager.isPreferShared(id)); + assertEquals(true, LanguageSettingsManager.isWorkspaceProvider(provider)); + } + { + ILanguageSettingsProvider provider = providers.get(2); + String id = provider.getId(); + assertEquals(GCC_SPECS_DETECTOR_ID, id); + assertEquals(true, LanguageSettingsManager.isPreferShared(id)); + assertEquals(true, LanguageSettingsManager.isWorkspaceProvider(provider)); + } + assertEquals(3, providers.size()); + } + } + + /** + * Test that no unnecessary storage file is created for language settings for default set + * of language settings providers. + */ + public void testProjectPersistence_Defaults() throws Exception { + // create a new project imitating wizard + IProject project = imitateNewProjectWizard(this.getName(), PROJECT_TYPE_EXECUTABLE_GNU); + + // double-check that the project contains language settings providers + ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project, false); + assertNotNull(prjDescription); + ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations(); + for (ICConfigurationDescription cfgDescription : cfgDescriptions) { + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + String[] defaultIds = ((ILanguageSettingsProvidersKeeper) cfgDescription).getDefaultLanguageSettingsProvidersIds(); + List providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + assertEquals(defaultIds.length, providers.size()); + for (int i = 0; i < defaultIds.length; i++) { + assertEquals(providers.get(i).getId(), defaultIds[i]); + } + assertTrue(defaultIds.length > 0); + } + + // no settings file in project area + IFile xmlStorageFile = project.getFile(LANGUAGE_SETTINGS_PROJECT_XML); + assertEquals(false, xmlStorageFile.exists()); + assertEquals(false, xmlStorageFile.getParent().exists()); // .settings folder + + // no settings file in workspace area + String xmlPrjWspStorageFileLocation = LanguageSettingsPersistenceProjectTests.getStoreLocationInWorkspaceArea(project.getName()+'.'+LANGUAGE_SETTINGS_WORKSPACE_XML); + java.io.File xmlStorageFilePrjWsp = new java.io.File(xmlPrjWspStorageFileLocation); + assertEquals(false, xmlStorageFilePrjWsp.exists()); + } + + /** + * Test that storage file is created for language settings for empty set of language settings providers. + */ + public void testProjectPersistence_NoProviders() throws Exception { + // create a new project imitating wizard + IProject project = imitateNewProjectWizard(this.getName(), PROJECT_TYPE_EXECUTABLE_GNU); + + // remove language settings providers from the project + ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project, true); + assertNotNull(prjDescription); + ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations(); + for (ICConfigurationDescription cfgDescription : cfgDescriptions) { + assertNotNull(cfgDescription); + assertTrue(cfgDescription instanceof ILanguageSettingsProvidersKeeper); + + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(new ArrayList()); + assertTrue(((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders().size() == 0); + } + + CoreModel.getDefault().setProjectDescription(project, prjDescription); + + // settings file appears in project area + IFile xmlStorageFile = project.getFile(LANGUAGE_SETTINGS_PROJECT_XML); + assertEquals(true, xmlStorageFile.exists()); + + // no settings file in workspace area + String xmlPrjWspStorageFileLocation = LanguageSettingsPersistenceProjectTests.getStoreLocationInWorkspaceArea(project.getName()+'.'+LANGUAGE_SETTINGS_WORKSPACE_XML); + java.io.File xmlStorageFilePrjWsp = new java.io.File(xmlPrjWspStorageFileLocation); + assertEquals(false, xmlStorageFilePrjWsp.exists()); + + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml index ae8c2baf886..c8c2e7e40ad 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml @@ -308,13 +308,14 @@ + id="org.eclipse.cdt.build.core.prefbase.cfg" + languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;${Toolchain}" + name="%cfg1_base"> + + + + - The semi-colon separated list of the default error parsers to be used with this configuration. The list is ordered with the first error parser on the list invoked first, the second error parser second, and so on. The list may contain the error parsers defined by CDT and/or other installed error parser extensions. The list of error parsers to be used may be changed by the user on a per-configuration basis. When specified, this overrides the tool-chain errorParsers attribute. + The semi-colon separated list of the default error parsers to be used with this configuration. The list is ordered with the first error parser on the list invoked first, the second error parser second, and so on. The list may contain the error parsers defined by CDT and/or other installed error parser extensions. The list of error parsers to be used may be changed by the user on a per-configuration basis. When specified, this overrides the tool-chain errorParsers attribute. + + + + + + + Semicolon-separated list of providers ID implementing ILanguageSettingProvider interface. +This field could be amended with toolchain-level providers list by using ${Toolchain} keyword. Provider ID can be prefixed with "*", in this case shared instance of the provider defined on workspace level is used. Also provider ID can be prefixed with "-" which will cause id to be removed from the preceeding list including providers defined with ${Toolchain} keyword. +If this field is not specified, "*org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" (MBS Language Settings Provider) is used by default. @@ -405,7 +414,15 @@ Specifying this attribute is fully equivalent to specifying the "org.eclips - The semi-colon separated list of the default error parsers to be used with this tool-chain. The list is ordered with the first error parser on the list invoked first, the second error parser second, and so on. The list may contain the error parsers defined by CDT and/or other installed error parser extensions. When specified, this overrides the tool errorParsers attributes of the tool children of the tool-chain and the builder child of the tool-chain. + The semi-colon separated list of the default error parsers to be used with this tool-chain. The list is ordered with the first error parser on the list invoked first, the second error parser second, and so on. The list may contain the error parsers defined by CDT and/or other installed error parser extensions. When specified, this overrides the tool errorParsers attributes of the tool children of the tool-chain and the builder child of the tool-chain. + + + + + + + Semicolon-separated list of providers ID implementing ILanguageSettingProvider interface. Provider ID can be prefixed with "*", in this case shared instance of the provider defined on workspace level is used. +This list could be adjusted on configuration level in the corresponding attribute. @@ -732,14 +749,14 @@ The pathConverter of a toolchain applies for all tools of the toolchain except i - Specifies whether this Tool represents a user-define custom build step. The default is false. When True, the default value of the commandLinePattern attribute changes to “$(command)”. + Specifies whether this Tool represents a user-define custom build step. The default is false. When True, the default value of the commandLinePattern attribute changes to “$(command)�. - Specifies a string that is written to the build output prior to each invocation of the tool. The default value is “Invoking tool-name (tool-id)…” + Specifies a string that is written to the build output prior to each invocation of the tool. The default value is “Invoking tool-name (tool-id)…� @@ -1066,7 +1083,7 @@ Overrides language id specified with the languageId attribute. - The id of the input type that is used in determining the build “rules” for the output type and for the default name of the output file. The default is the input type with primaryInput == true. + The id of the input type that is used in determining the build “rules� for the output type and for the default name of the output file. The default is the input type with primaryInput == true. @@ -1080,7 +1097,7 @@ Overrides language id specified with the languageId attribute. - Some tools produce files with a special prefix that must be specified. For example, a librarian on POSIX systems expects the output to be libtarget.a, so 'lib' would be the prefix. The default is to use the Tool “outputPrefix” attribute if primaryOutput is True, otherwise the default is an empty string. This attribute supports MBS configuration context macros. + Some tools produce files with a special prefix that must be specified. For example, a librarian on POSIX systems expects the output to be libtarget.a, so 'lib' would be the prefix. The default is to use the Tool “outputPrefix� attribute if primaryOutput is True, otherwise the default is an empty string. This attribute supports MBS configuration context macros. @@ -2035,11 +2052,11 @@ If the "buildPathResolver" attribute is specified, the "pathDelim Represents the applicability type for this enablement. Can contain the following values: -UI_VISIBILITY – the given enablement expression specifies whether the option is to be visible in UI, -UI_ENABLEMENT – the given enablement expression specifies the enable state of the controls that represent the option in UI, -CMD_USAGE – the given enablement expression specifies whether the option is to be used in command line +UI_VISIBILITY – the given enablement expression specifies whether the option is to be visible in UI, +UI_ENABLEMENT – the given enablement expression specifies the enable state of the controls that represent the option in UI, +CMD_USAGE – the given enablement expression specifies whether the option is to be used in command line CONTAINER_ATTRIBUTE - the given enablement expressions specifies thecontainer attribute value -ALL – this value means the combination of all the above values. +ALL – this value means the combination of all the above values. Several types could be specified simultaneously using the "|" as a delimiter, e.g.: type="UI_VISIBILITY|CMD_USAGE" @@ -2173,7 +2190,7 @@ Default value is true. - Specifies the expected value. If the current option value matches the value specified in this attribute, the checkOption element is treated as true, otherwise – as false. + Specifies the expected value. If the current option value matches the value specified in this attribute, the checkOption element is treated as true, otherwise – as false. The expected value could be specified either as a string that may contain build macros or as a regular expression. During the comparison, the build macros are resolved and the option value is checked to match the resulting string or regular expression. The way the expected value is specified and treated depends on the value of the isRegex attribute @@ -2188,14 +2205,14 @@ The expected value could be specified either as a string that may contain build - The id of the option which is to be compared with the option specified with the “optionId” attribute. The default is the id of the option that holds this expression. If the “value” attribute is specified, both the “otherOptionId” and the “otherHolderId” attributes are ignored. When searching for the option to be checked, MBS will examine all the options the holder contains along with all superclasses of each option to find the option with the specified id. + The id of the option which is to be compared with the option specified with the “optionId� attribute. The default is the id of the option that holds this expression. If the “value� attribute is specified, both the “otherOptionId� and the “otherHolderId� attributes are ignored. When searching for the option to be checked, MBS will examine all the options the holder contains along with all superclasses of each option to find the option with the specified id. - The option holder id that holds the option specified with the “otherOptionId” attribute. The default is the id of the holder that holds the container of this expression. If the “value” attribute is specified, both the “otherOptionId” and the “otherHolderId” attributes are ingnored. When searching for the needed holder, MBS will examine all the holders the current configuration contains along with all superclasses of each holder in order to find the holder with the specified id. + The option holder id that holds the option specified with the “otherOptionId� attribute. The default is the id of the holder that holds the container of this expression. If the “value� attribute is specified, both the “otherOptionId� and the “otherHolderId� attributes are ingnored. When searching for the needed holder, MBS will examine all the holders the current configuration contains along with all superclasses of each holder in order to find the holder with the specified id. @@ -2219,7 +2236,7 @@ The expected value could be specified either as a string that may contain build - Specifies the expected value. If the current string specified in the “string” attribute matches the value specified in this attribute, the checkString element is treated as true, otherwise – as false. + Specifies the expected value. If the current string specified in the “string� attribute matches the value specified in this attribute, the checkString element is treated as true, otherwise – as false. The expected value could be specified either as a string that might contain the build macros or as a regular expression. The way the value is specified and treated depends on the value of the isRegex attribute. diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig/CfgScannerConfigUtil.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig/CfgScannerConfigUtil.java index 6c27670a7b6..bc1bf490785 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig/CfgScannerConfigUtil.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig/CfgScannerConfigUtil.java @@ -159,7 +159,12 @@ public class CfgScannerConfigUtil { Set profiles = new TreeSet(); if (toolchain!=null) { - String toolchainProfileId = toolchain.getScannerConfigDiscoveryProfileId(); + String toolchainProfileId = null; + if (toolchain instanceof ToolChain) { + toolchainProfileId = ((ToolChain) toolchain).getLegacyScannerConfigDiscoveryProfileId(); + } else { + toolchainProfileId = toolchain.getScannerConfigDiscoveryProfileId(); + } if (toolchainProfileId!=null && toolchainProfileId.length()>0) { profiles.add(toolchainProfileId); } @@ -227,7 +232,7 @@ public class CfgScannerConfigUtil { Set profiles = new TreeSet(); - String attribute = ((InputType) inputType).getDiscoveryProfileIdAttribute(); + String attribute = ((InputType) inputType).getLegacyDiscoveryProfileIdAttribute(); if (attribute!=null) { // FIXME: temporary; we should add new method to IInputType instead of that for (String profileId : attribute.split("\\|")) { //$NON-NLS-1$ diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java index 8b7f0499dce..8aba30dbfe9 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java @@ -24,14 +24,14 @@ import org.eclipse.core.runtime.IPath; /** * A tool-integrator defines default configurations as children of the project type. - * These provide a template for the configurations added to the user's project, - * which are stored in the project's .cproject file. + * These provide a template for the configurations added to the user's project, + * which are stored in the project's .cproject file. *

- * The configuration contains one child of type tool-chain. This describes how the + * The configuration contains one child of type tool-chain. This describes how the * project's resources are transformed into the build artifact. The configuration can * contain one or more children of type resourceConfiguration. These describe build * settings of individual resources that are different from the configuration as a whole. - * + * * @since 2.1 * @noextend This class is not intended to be subclassed by clients. * @noimplement This interface is not intended to be implemented by clients. @@ -39,33 +39,35 @@ import org.eclipse.core.runtime.IPath; public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesContainer { public static final String ARTIFACT_NAME = "artifactName"; //$NON-NLS-1$ public static final String CLEAN_COMMAND = "cleanCommand"; //$NON-NLS-1$ - public static final String PREBUILD_STEP = "prebuildStep"; //$NON-NLS-1$ - public static final String POSTBUILD_STEP = "postbuildStep"; //$NON-NLS-1$ - public static final String PREANNOUNCEBUILD_STEP = "preannouncebuildStep"; //$NON-NLS-1$ - public static final String POSTANNOUNCEBUILD_STEP = "postannouncebuildStep"; //$NON-NLS-1$ + public static final String PREBUILD_STEP = "prebuildStep"; //$NON-NLS-1$ + public static final String POSTBUILD_STEP = "postbuildStep"; //$NON-NLS-1$ + public static final String PREANNOUNCEBUILD_STEP = "preannouncebuildStep"; //$NON-NLS-1$ + public static final String POSTANNOUNCEBUILD_STEP = "postannouncebuildStep"; //$NON-NLS-1$ // Schema element names public static final String CONFIGURATION_ELEMENT_NAME = "configuration"; //$NON-NLS-1$ public static final String ERROR_PARSERS = "errorParsers"; //$NON-NLS-1$ + /** @since 8.1 */ + public static final String LANGUAGE_SETTINGS_PROVIDERS = "languageSettingsProviders"; public static final String EXTENSION = "artifactExtension"; //$NON-NLS-1$ public static final String PARENT = "parent"; //$NON-NLS-1$ - + public static final String DESCRIPTION = "description"; //$NON-NLS-1$ - + public static final String BUILD_PROPERTIES = "buildProperties"; //$NON-NLS-1$ public static final String BUILD_ARTEFACT_TYPE = "buildArtefactType"; //$NON-NLS-1$ public static final String IS_SYSTEM = "isSystem"; //$NON-NLS-1$ public static final String SOURCE_ENTRIES = "sourceEntries"; //$NON-NLS-1$ - - + + /** * Returns the description of the configuration. - * + * * @return String */ public String getDescription(); - + /** * Sets the description of the receiver to the value specified in the argument */ @@ -84,204 +86,212 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont * @param name - The name for the new tool chain * @param isExtensionElement - set {@code true} if the toolchain being created * represents extension point toolchain - * + * * @return IToolChain */ public IToolChain createToolChain(IToolChain superClass, String Id, String name, boolean isExtensionElement); - + /** - * Returns the extension that should be applied to build artifacts created by + * Returns the extension that should be applied to build artifacts created by * this configuration. - * + * * @return String */ - public String getArtifactExtension(); + public String getArtifactExtension(); /** * Returns the name of the final build artifact. - * + * * @return String */ public String getArtifactName(); /** - * Returns the build arguments from this configuration's builder - * + * Returns the build arguments from this configuration's builder + * * @return String */ public String getBuildArguments(); /** - * Returns the build command from this configuration's builder - * + * Returns the build command from this configuration's builder + * * @return String */ public String getBuildCommand(); - + /** * Returns the prebuild step command - * - * @return String - */ - public String getPrebuildStep(); - - /** - * Returns the postbuild step command - * - * @return String - */ - public String getPostbuildStep(); - - /** - * Returns the display string associated with the prebuild step - * - * @return String - */ - public String getPreannouncebuildStep(); - - /** - * Returns the display string associated with the postbuild step - * - * @return String - */ - public String getPostannouncebuildStep(); - - /** + * + * @return String + */ + public String getPrebuildStep(); + + /** + * Returns the postbuild step command + * + * @return String + */ + public String getPostbuildStep(); + + /** + * Returns the display string associated with the prebuild step + * + * @return String + */ + public String getPreannouncebuildStep(); + + /** + * Returns the display string associated with the postbuild step + * + * @return String + */ + public String getPostannouncebuildStep(); + + /** * Answers the OS-specific command to remove files created by the build * of this configuration. - * + * * @return String */ public String getCleanCommand(); /** - * Answers the semicolon separated list of unique IDs of the error parsers associated + * Answers the semicolon separated list of unique IDs of the error parsers associated * with this configuration. - * + * * @return String */ public String getErrorParserIds(); /** - * Answers the ordered list of unique IDs of the error parsers associated + * Answers the ordered list of unique IDs of the error parsers associated * with this configuration. - * + * * @return String[] */ public String[] getErrorParserList(); - + /** - * Projects have C or CC natures. Tools can specify a filter so they are not - * misapplied to a project. This method allows the caller to retrieve a list - * of tools from a project that are correct for a project's nature. - * - * @return an array of ITools that have compatible filters + * Returns default language settings providers IDs specified for the configuration. + * @return default language settings providers IDs. + * + * @since 8.1 + */ + public String[] getDefaultLanguageSettingsProvidersIds(); + + /** + * Projects have C or CC natures. Tools can specify a filter so they are not + * misapplied to a project. This method allows the caller to retrieve a list + * of tools from a project that are correct for a project's nature. + * + * @return an array of ITools that have compatible filters * for this configuration. */ ITool[] getFilteredTools(); - + /** * Returns the managed-project parent of this configuration, if this is a * project configuration. Otherwise, returns null. - * + * * @return IManagedProject */ public IManagedProject getManagedProject(); - + /** * Returns the Eclipse project that owns the configuration. - * + * * @return IResource */ public IResource getOwner(); - + /** - * Returns the configuration that this configuration is based on. - * + * Returns the configuration that this configuration is based on. + * * @return IConfiguration */ public IConfiguration getParent(); - + /** * Returns the project-type parent of this configuration, if this is an * extension configuration. Otherwise, returns null. - * + * * @return IProjectType */ public IProjectType getProjectType(); - + /** * @param path - path of the resource - * + * * @return the resource configuration child of this configuration * that is associated with the project resource, or null if none. */ public IResourceConfiguration getResourceConfiguration(String path); - + /** * Returns the resource configuration children of this configuration. - * + * * @return IResourceConfigurations[] */ public IResourceConfiguration[] getResourceConfigurations(); - + /** * Returns the ITool in this configuration's tool-chain with - * the same id as the argument, or null. - * + * the same id as the argument, or null. + * * @param id unique identifier to search for * @return ITool */ public ITool getTool(String id); /** - * Returns the ITool in this configuration's tool-chain with - * the specified ID, or the tool(s) with a superclass with this id. - * - *

If the tool-chain does not have a tool with that ID, the method - * returns an empty array. It is the responsibility of the caller to - * verify the return value. - * + * Returns the ITool in this configuration's tool-chain with + * the specified ID, or the tool(s) with a superclass with this id. + * + *

If the tool-chain does not have a tool with that ID, the method + * returns an empty array. It is the responsibility of the caller to + * verify the return value. + * * @param id unique identifier of the tool to search for * @return ITool[] * @since 3.0.2 */ public ITool[] getToolsBySuperClassId(String id); - + /** * Returns the IToolChain child of this configuration. - * + * * @return IToolChain */ public IToolChain getToolChain(); - + /** * Returns the command-line invocation command for the specified tool. - * + * * @param tool The tool that will have its command retrieved. * @return String The command */ public String getToolCommand(ITool tool); - + /** * Returns the tools that are used in this configuration's tool-chain. - * + * * @return ITool[] */ public ITool[] getTools(); /** - * Returns the tool in this configuration specified with + * Returns the tool in this configuration specified with * the toolChain#targetTool attribute that creates the build artifact - * - * NOTE: This method returns null in case the toolChain definition + * + * NOTE: This method returns null in case the toolChain definition * does not have the targetTool attribute or if the attribute does not * refer to the appropriate tool. * For the target tool calculation the IConfiguration#calculateTargetTool() * method should be used - * + * * @see IConfiguration#calculateTargetTool() - * + * * @return ITool */ public ITool getTargetTool(); @@ -289,42 +299,42 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont /** * Returns true if this configuration has overridden the default build * build command in this configuration, otherwise false. - * - * @return boolean + * + * @return boolean */ public boolean hasOverriddenBuildCommand(); - + /** - * Returns true if the extension matches one of the special - * file extensions the tools for the configuration consider to be a header file. - * + * Returns true if the extension matches one of the special + * file extensions the tools for the configuration consider to be a header file. + * * @param ext the file extension of the resource * @return boolean */ public boolean isHeaderFile(String ext); - + /** - * Returns true if this configuration has changes that need to - * be saved in the project file, else false. + * Returns true if this configuration has changes that need to + * be saved in the project file, else false. * Should not be called for an extension configuration. - * - * @return boolean + * + * @return boolean */ public boolean isDirty(); - + /** * Returns true if this configuration was loaded from a manifest file, * and false if it was loaded from a project (.cdtbuild) file. - * - * @return boolean + * + * @return boolean */ public boolean isExtensionElement(); /** - * Returns whether this configuration has been changed and requires the + * Returns whether this configuration has been changed and requires the * project to be rebuilt. - * - * @return true if the configuration contains a change + * + * @return true if the configuration contains a change * that needs the project to be rebuilt. * Should not be called for an extension configuration. */ @@ -332,13 +342,13 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont /** * Removes a resource configuration from the configuration's list. - * + * * @param resConfig - resource configuration to remove */ public void removeResourceConfiguration(IResourceInfo resConfig); - + public void removeResourceInfo(IPath path); - + /** * Set (override) the extension that should be appended to the build artifact * for the receiver. @@ -352,7 +362,7 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont public void setArtifactName(String name); /** - * Sets the arguments to be passed to the build utility used by the + * Sets the arguments to be passed to the build utility used by the * receiver to produce a build goal. */ public void setBuildArguments(String makeArgs); @@ -363,26 +373,26 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont public void setBuildCommand(String command); /** - * Sets the prebuild step for the receiver to the value in the argument. - */ - public void setPrebuildStep(String step); - - /** - * Sets the postbuild step for the receiver to the value in the argument. - */ - public void setPostbuildStep(String step); - - /** - * Sets the prebuild step display string for the receiver to the value in the argument. - */ - public void setPreannouncebuildStep(String announceStep); - - /** - * Sets the postbuild step display string for the receiver to the value in the argument. - */ - public void setPostannouncebuildStep(String announceStep); - - /** + * Sets the prebuild step for the receiver to the value in the argument. + */ + public void setPrebuildStep(String step); + + /** + * Sets the postbuild step for the receiver to the value in the argument. + */ + public void setPostbuildStep(String step); + + /** + * Sets the prebuild step display string for the receiver to the value in the argument. + */ + public void setPreannouncebuildStep(String announceStep); + + /** + * Sets the postbuild step display string for the receiver to the value in the argument. + */ + public void setPostannouncebuildStep(String announceStep); + + /** * Sets the command used to clean the outputs of this configuration. * @param command - the command to clean outputs */ @@ -404,46 +414,46 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont * Sets the name of the receiver to the value specified in the argument */ public void setName(String name); - + /** * Sets the value of a boolean option for this configuration. - * + * * @param parent The holder/parent of the option. * @param option The option to change. * @param value The value to apply to the option. - * + * * @return IOption The modified option. This can be the same option or a newly created option. - * + * * @since 3.0 - The type of parent has changed from ITool to IHoldsOptions. * Code assuming ITool as type, will continue to work unchanged. */ - public IOption setOption(IHoldsOptions parent, IOption option, boolean value) - throws BuildException; + public IOption setOption(IHoldsOptions parent, IOption option, boolean value) + throws BuildException; /** * Sets the value of a string option for this configuration. - * + * * @param parent The holder/parent of the option. * @param option The option that will be effected by change. * @param value The value to apply to the option. - * + * * @return IOption The modified option. This can be the same option or a newly created option. - * + * * @since 3.0 - The type of parent has changed from ITool to IHoldsOptions. * Code assuming ITool as type, will continue to work unchanged. */ public IOption setOption(IHoldsOptions parent, IOption option, String value) throws BuildException; - + /** * Sets the value of a list option for this configuration. - * + * * @param parent The holder/parent of the option. * @param option The option to change. * @param value The values to apply to the option. - * + * * @return IOption The modified option. This can be the same option or a newly created option. - * + * * @since 3.0 - The type of parent has changed from ITool to IHoldsOptions. * Code assuming ITool as type, will continue to work unchanged. */ @@ -452,7 +462,7 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont /** * Sets the rebuild state in this configuration. - * + * * @param rebuild true will force a rebuild the next time the project builds * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#setRebuildState(boolean) */ @@ -460,93 +470,93 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont /** * Overrides the tool command for a tool defined in this configuration's tool-chain. - * + * * @param tool The tool that will have its command modified. * @param command The command */ public void setToolCommand(ITool tool, String command); - + /** * Returns true if the configuration's tool-chain is supported on the system * otherwise returns false - * - * @return boolean - */ + * + * @return boolean + */ public boolean isSupported(); - + /** * Returns the implementation of the IConfigurationEnvironmentVariableSupplier provided * by the tool-integrator or null if none. - * - * @return IConfigurationEnvironmentVariableSupplier - */ + * + * @return IConfigurationEnvironmentVariableSupplier + */ public IConfigurationEnvironmentVariableSupplier getEnvironmentVariableSupplier(); - + /** * Returns the tool-integrator provided implementation of the configuration build macro supplier - * or null if none. - * + * or null if none. + * * @return IConfigurationBuildMacroSupplier */ public IConfigurationBuildMacroSupplier getBuildMacroSupplier(); - + /** * answers true if the configuration is temporary, otherwise - false * @return boolean */ public boolean isTemporary(); - + /** * Returns whether this configuration requires a full rebuild - * + * * @return boolean */ public boolean needsFullRebuild(); /** * Calculates the configuration target tool. - * + * * @return ITool or null if not found - * + * * @since 3.1 */ public ITool calculateTargetTool(); - + /** - * Returns a ITool for the tool associated with the + * Returns a ITool for the tool associated with the * output extension. - * + * * @param extension the file extension of the output file * @return ITool - * + * * @since 3.1 */ public ITool getToolFromOutputExtension(String extension); - + /** - * Returns a ITool for the tool associated with the + * Returns a ITool for the tool associated with the * input extension. - * + * * @param sourceExtension the file extension of the input file * @return ITool - * + * * @since 3.1 */ public ITool getToolFromInputExtension(String sourceExtension); - + IResourceInfo getResourceInfo(IPath path, boolean exactPath); - + IResourceInfo[] getResourceInfos(); - + IResourceInfo getResourceInfoById(String id); - - IFolderInfo getRootFolderInfo(); - + + IFolderInfo getRootFolderInfo(); + IFileInfo createFileInfo(IPath path); IFileInfo createFileInfo(IPath path, String id, String name); - + IFileInfo createFileInfo(IPath path, IFolderInfo base, ITool baseTool, String id, String name); IFileInfo createFileInfo(IPath path, IFileInfo base, String id, String name); @@ -554,49 +564,49 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont IFolderInfo createFolderInfo(IPath path); IFolderInfo createFolderInfo(IPath path, String id, String name); - + IFolderInfo createFolderInfo(IPath path, IFolderInfo base, String id, String name); - + CConfigurationData getConfigurationData(); - + ICSourceEntry[] getSourceEntries(); void setSourceEntries(ICSourceEntry[] entries); - + CBuildData getBuildData(); - + IBuilder getBuilder(); - + IBuilder getEditableBuilder(); - + String getOutputPrefix(String outputExtension); - + boolean isSystemObject(); - + String getOutputExtension(String resourceExtension); - + String getOutputFlag(String outputExt); - - IManagedCommandLineInfo generateToolCommandLineInfo( String sourceExtension, String[] flags, + + IManagedCommandLineInfo generateToolCommandLineInfo( String sourceExtension, String[] flags, String outputFlag, String outputPrefix, String outputName, String[] inputResources, IPath inputLocation, IPath outputLocation ); - + String[] getUserObjects(String extension); - + String[] getLibs(String extension); - + boolean buildsFileType(String srcExt); - + boolean supportsBuild(boolean managed); - + boolean isManagedBuildOn(); void setManagedBuildOn(boolean on) throws BuildException; - + boolean isBuilderCompatible(IBuilder builder); - + void changeBuilder(IBuilder newBuilder, String id, String name); - + IBuildPropertyValue getBuildArtefactType(); - + void setBuildArtefactType(String id) throws BuildException; } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java index 57cba447fca..2757a06b134 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java @@ -16,19 +16,19 @@ import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; /** - * This interface represents a tool-integrator-defined, ordered set of tools - * that transform the project's input into the project's outputs. A - * tool-chain can be defined as part of a configuration, or as an + * This interface represents a tool-integrator-defined, ordered set of tools + * that transform the project's input into the project's outputs. A + * tool-chain can be defined as part of a configuration, or as an * independent specification that is referenced in a separate configuration * via the toolChain superclass attribute. *

* The toolChain contains one or more children of type tool. These define - * the tools used in the tool-chain. The toolChain contains one child of + * the tools used in the tool-chain. The toolChain contains one child of * type targetPlatform. This defines the architecture/os combination where - * the outputs of the project can be deployed. The toolChain contains one + * the outputs of the project can be deployed. The toolChain contains one * child of type builder. This defines the "build" or "make" utility that * is used to drive the transformation of the inputs into outputs. - * + * * @since 2.1 * @noextend This class is not intended to be subclassed by clients. * @noimplement This interface is not intended to be implemented by clients. @@ -49,13 +49,16 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { public static final String IS_SYSTEM= "isSystem"; //$NON-NLS-1$ public static final String NON_INTERNAL_BUILDER_ID = "nonInternalBuilderId"; //$NON-NLS-1$ public static final String RESOURCE_TYPE_BASED_DISCOVERY = "resourceTypeBasedDiscovery"; //$NON-NLS-1$ - + // The attribute name for the scanner info collector public static final String SCANNER_CONFIG_PROFILE_ID = "scannerConfigDiscoveryProfileId"; //$NON-NLS-1$ + /** @since 8.1 */ + public static final String LANGUAGE_SETTINGS_PROVIDERS = "languageSettingsProviders"; + /** * Returns the configuration that is the parent of this tool-chain. - * + * * @return IConfiguration */ public IConfiguration getParent(); @@ -67,14 +70,14 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { * @param Id The id for the new tool chain * @param name The name for the new tool chain * @param isExtensionElement Indicates whether this is an extension element or a managed project element - * + * * @return ITargetPlatform */ public ITargetPlatform createTargetPlatform(ITargetPlatform superClass, String Id, String name, boolean isExtensionElement); /** * Returns the target-platform child of this tool-chain - * + * * @return ITargetPlatform */ public ITargetPlatform getTargetPlatform(); @@ -87,30 +90,30 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { /** * Returns the 'versionsSupported' of this tool-chain - * + * * @return String */ public String getVersionsSupported(); /** * Returns the 'convertToId' of this tool-chain - * + * * @return String */ public String getConvertToId(); - + /** - * Sets the 'versionsSupported' attribute of the tool-chain. + * Sets the 'versionsSupported' attribute of the tool-chain. */ - + public void setVersionsSupported(String versionsSupported); - + /** - * Sets the 'convertToId' attribute of the tool-chain. + * Sets the 'convertToId' attribute of the tool-chain. */ public void setConvertToId(String convertToId); - + /** * Creates the Builder child of this tool-chain. * @@ -118,7 +121,7 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { * @param Id The id for the new tool chain * @param name The name for the new tool chain * @param isExtensionElement Indicates whether this is an extension element or a managed project element - * + * * @return IBuilder */ public IBuilder createBuilder(IBuilder superClass, String Id, String name, boolean isExtensionElement); @@ -131,7 +134,7 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { /** * Returns the builder child of this tool-chain. - * + * * @return IBuilder */ public IBuilder getBuilder(); @@ -143,35 +146,35 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { * @param Id The id for the new tool chain * @param name The name for the new tool chain * @param isExtensionElement Indicates whether this is an extension element or a managed project element - * + * * @return ITool */ public ITool createTool(ITool superClass, String Id, String name, boolean isExtensionElement); /** * Returns an array of tool children of this tool-chain - * + * * @return ITool[] */ public ITool[] getTools(); /** - * Returns the tool in this tool-chain with the ID specified in the argument, - * or null - * + * Returns the tool in this tool-chain with the ID specified in the argument, + * or null + * * @param id The ID of the requested tool * @return ITool */ public ITool getTool(String id); /** - * Returns the ITool in the tool-chain with the specified - * ID, or the tool(s) with a superclass with this id. - * - *

If the tool-chain does not have a tool with that ID, the method - * returns an empty array. It is the responsibility of the caller to - * verify the return value. - * + * Returns the ITool in the tool-chain with the specified + * ID, or the tool(s) with a superclass with this id. + * + *

If the tool-chain does not have a tool with that ID, the method + * returns an empty array. It is the responsibility of the caller to + * verify the return value. + * * @param id unique identifier of the tool to search for * @return ITool[] * @since 3.0.2 @@ -181,55 +184,55 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { /** * Returns the IToolChain that is the superclass of this * tool-chain, or null if the attribute was not specified. - * + * * @return IToolChain */ public IToolChain getSuperClass(); - + /** * Returns whether this element is abstract. Returns false * if the attribute was not specified. - * @return boolean + * @return boolean */ public boolean isAbstract(); /** - * Sets the isAbstract attribute of the tool-chain. + * Sets the isAbstract attribute of the tool-chain. */ public void setIsAbstract(boolean b); - + /** * Returns a semi-colon delimited list of child Ids of the superclass' * children that should not be automatically inherited by this element. - * Returns an empty string if the attribute was not specified. - * @return String + * Returns an empty string if the attribute was not specified. + * @return String */ public String getUnusedChildren(); - + /** * Returns an array of operating systems the tool-chain outputs can run on. - * + * * @return String[] */ public String[] getOSList(); /** * Sets the OS list. - * + * * @param OSs The list of OS names */ public void setOSList(String[] OSs); - + /** * Returns an array of architectures the tool-chain outputs can run on. - * + * * @return String[] */ public String[] getArchList(); - + /** * Sets the architecture list. - * + * * @param archs The list of architecture names */ public void setArchList(String[] archs); @@ -237,7 +240,7 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { /** * Returns the semicolon separated list of unique IDs of the error parsers associated * with the tool-chain. - * + * * @return String */ public String getErrorParserIds(); @@ -249,9 +252,9 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { public String getErrorParserIds(IConfiguration config); /** - * Returns the ordered list of unique IDs of the error parsers associated with the + * Returns the ordered list of unique IDs of the error parsers associated with the * tool-chain. - * + * * @return String[] */ public String[] getErrorParserList(); @@ -262,8 +265,17 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { public void setErrorParserIds(String ids); /** - * Returns the scanner config discovery profile id or null if none. - * + * Returns the default language settings providers IDs. + * + * @return the default language settings providers IDs separated by semicolon or {@code null} if none. + * + * @since 8.1 + */ + public String getDefaultLanguageSettingsProvidersIds(); + + /** + * Returns the scanner config discovery profile id or null if none. + * * @return String */ public String getScannerConfigDiscoveryProfileId(); @@ -274,93 +286,93 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { public void setScannerConfigDiscoveryProfileId(String profileId); /** - * Returns the sem-colon separated list of Tool ids containing each - * tool that can create the final build artifact (the end target of - * the build). MBS will use the first ID in the list that matches - * a Tool in the ToolChain. One reason for specifying a list, is - * that different versions of a tool can be selected based upon the + * Returns the sem-colon separated list of Tool ids containing each + * tool that can create the final build artifact (the end target of + * the build). MBS will use the first ID in the list that matches + * a Tool in the ToolChain. One reason for specifying a list, is + * that different versions of a tool can be selected based upon the * project nature (e.g. different tool definitions for a linker for C vs. C++). - * + * * @return String */ public String getTargetToolIds(); /** - * Sets the sem-colon separated list of Tool ids containing each - * tool that can create the final build artifact (the end target of - * the build). + * Sets the sem-colon separated list of Tool ids containing each + * tool that can create the final build artifact (the end target of + * the build). */ public void setTargetToolIds(String targetToolIds); /** - * Returns the list of Tool ids containing each - * tool that can create the final build artifact (the end target of - * the build). MBS will use the first ID in the list that matches - * a Tool in the ToolChain. One reason for specifying a list, is - * that different versions of a tool can be selected based upon the + * Returns the list of Tool ids containing each + * tool that can create the final build artifact (the end target of + * the build). MBS will use the first ID in the list that matches + * a Tool in the ToolChain. One reason for specifying a list, is + * that different versions of a tool can be selected based upon the * project nature (e.g. different tool definitions for a linker for C vs. C++). - * + * * @return String[] */ public String[] getTargetToolList(); - + /** - * Returns the OutputTypes in this tool-chain, besides the primary - * output of the targetTool, that are also considered to be build - * artifacts. - * + * Returns the OutputTypes in this tool-chain, besides the primary + * output of the targetTool, that are also considered to be build + * artifacts. + * * @return IOutputType[] */ public IOutputType[] getSecondaryOutputs(); - + /** - * Sets the semicolon separated list of OutputType identifiers in + * Sets the semicolon separated list of OutputType identifiers in * this tool-chain, besides the primary output of the targetTool, - * that are also considered to be build artifacts. + * that are also considered to be build artifacts. */ public void setSecondaryOutputs(String ids); /** - * Returns true if this tool-chain has changes that need to + * Returns true if this tool-chain has changes that need to * be saved in the project file, else false. - * - * @return boolean + * + * @return boolean */ public boolean isDirty(); - + /** * Sets the element's "dirty" (have I been modified?) flag. */ public void setDirty(boolean isDirty); - + /** * Returns true if this tool-chain was loaded from a manifest file, * and false if it was loaded from a project (.cdtbuild) file. - * - * @return boolean + * + * @return boolean */ public boolean isExtensionElement(); - + /** * Returns true if the tool-chain support is installed on the system * otherwise returns false - * - * @return boolean - */ + * + * @return boolean + */ public boolean isSupported(); - + /** * Returns the tool-integrator provided implementation of the configuration environment variable supplier - * or null if none. - * + * or null if none. + * * @return IConfigurationEnvironmentVariableSupplier */ public IConfigurationEnvironmentVariableSupplier getEnvironmentVariableSupplier(); - + /** * Returns the tool-integrator provided implementation of the configuration build macro supplier - * or null if none. - * + * or null if none. + * * @return IConfigurationBuildMacroSupplier */ public IConfigurationBuildMacroSupplier getBuildMacroSupplier(); @@ -370,16 +382,16 @@ public interface IToolChain extends IBuildObject, IHoldsOptions { * or null, if no conversion is required */ public IOptionPathConverter getOptionPathConverter() ; - + IFolderInfo getParentFolderInfo(); - + CTargetPlatformData getTargetPlatformData(); - + boolean supportsBuild(boolean managed); - + boolean isSystemObject(); - + boolean matches(IToolChain tc); - + String getUniqueRealName(); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java index 8a55afcaead..d63ea654413 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2011 IBM Corporation and others. + * Copyright (c) 2003, 2012 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 @@ -26,6 +26,7 @@ import java.util.Vector; import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set; import org.eclipse.cdt.build.internal.core.scannerconfig.CfgDiscoveredPathManager.PathInfoCache; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.ErrorParserManager; import org.eclipse.cdt.core.settings.model.CSourceEntry; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; @@ -83,8 +84,10 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; import org.eclipse.osgi.util.NLS; import org.osgi.framework.Version; @@ -92,6 +95,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild private static final String EMPTY_STRING = ""; //$NON-NLS-1$ private static final String EMPTY_CFG_ID = "org.eclipse.cdt.build.core.emptycfg"; //$NON-NLS-1$ + private static final String LANGUAGE_SETTINGS_PROVIDER_DELIMITER = ";"; //$NON-NLS-1$ // Parent and children private String parentId; @@ -102,6 +106,8 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild private String cleanCommand; private String artifactExtension; private String errorParserIds; + private String defaultLanguageSettingsProvidersAttribute; + private String[] defaultLanguageSettingsProvidersIds; private String prebuildStep; private String postbuildStep; private String preannouncebuildStep; @@ -781,6 +787,9 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild // Get the semicolon separated list of IDs of the error parsers errorParserIds = SafeStringInterner.safeIntern(element.getAttribute(ERROR_PARSERS)); + // Get the initial/default language setttings providers IDs + defaultLanguageSettingsProvidersAttribute = SafeStringInterner.safeIntern(element.getAttribute(LANGUAGE_SETTINGS_PROVIDERS)); + // Get the artifact extension artifactExtension = SafeStringInterner.safeIntern(element.getAttribute(EXTENSION)); @@ -1453,6 +1462,55 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild return set; } + private String getDefaultLanguageSettingsProvidersAttribute() { + if (defaultLanguageSettingsProvidersAttribute == null && parent instanceof Configuration) { + defaultLanguageSettingsProvidersAttribute = ((Configuration) parent).getDefaultLanguageSettingsProvidersAttribute(); + } + + return defaultLanguageSettingsProvidersAttribute; + } + + @Override + public String[] getDefaultLanguageSettingsProvidersIds() { + defaultLanguageSettingsProvidersIds = null; + if (defaultLanguageSettingsProvidersIds == null) { + getDefaultLanguageSettingsProvidersAttribute(); + if (defaultLanguageSettingsProvidersAttribute != null) { + List ids = new ArrayList(); + String[] defaultIds = defaultLanguageSettingsProvidersAttribute.split(LANGUAGE_SETTINGS_PROVIDER_DELIMITER); + for (String id : defaultIds) { + if (id != null && !id.isEmpty()) { + if (id.startsWith("-")) { + id = id.substring(1); + ids.remove(id); + } else if (!ids.contains(id)){ + if (id.contains("${Toolchain}")) { + IToolChain toolchain = getToolChain(); + if (toolchain != null) { + String toolchainProvidersIds = toolchain.getDefaultLanguageSettingsProvidersIds(); + if (toolchainProvidersIds != null) { + ids.addAll(Arrays.asList(toolchainProvidersIds.split(LANGUAGE_SETTINGS_PROVIDER_DELIMITER))); + } else { + String message = "Invalid use of ${Toolchain} tag, toolchain does not specify language settings providers. cfg=" + getId(); + ManagedBuilderCorePlugin.log(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, IStatus.ERROR, message, new Exception())); + } + } + } else { + ids.add(id); + } + } + } + + } + defaultLanguageSettingsProvidersIds = ids.toArray(new String[ids.size()]); + } else if (parent != null) { + defaultLanguageSettingsProvidersIds = parent.getDefaultLanguageSettingsProvidersIds(); + } + } + + return defaultLanguageSettingsProvidersIds; + } + /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.core.IConfiguration#setArtifactExtension(java.lang.String) */ diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java index 7932e7b2f39..a706a2d0b00 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.StringTokenizer; import java.util.Vector; +import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.core.settings.model.ICStorageElement; @@ -24,6 +25,7 @@ import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.internal.core.SafeStringInterner; import org.eclipse.cdt.managedbuilder.core.IAdditionalInput; import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IFileInfo; import org.eclipse.cdt.managedbuilder.core.IInputOrder; import org.eclipse.cdt.managedbuilder.core.IInputType; @@ -37,6 +39,7 @@ import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.enablement.OptionEnablementExpression; import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGeneratorType; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IPath; @@ -1838,9 +1841,56 @@ public class InputType extends BuildObject implements IInputType { return id; } + /** + * Temporary method to support compatibility during SD transition. + */ + private boolean isLanguageSettingsProvidersFunctionalityEnabled() { + boolean isLanguageSettingsProvidersEnabled = false; + ITool tool = getParent(); + if (tool!=null) { + IBuildObject bo = tool.getParent(); + if (bo instanceof IToolChain) { + IConfiguration cfg = ((IToolChain) bo).getParent(); + if (cfg!=null) { + IResource rc = cfg.getOwner(); + if (rc!=null) { + IProject project = rc.getProject(); + isLanguageSettingsProvidersEnabled = ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityEnabled(project); + } + } + } + } + return isLanguageSettingsProvidersEnabled; + } + + /** + * Temporary method to support compatibility during SD transition. + * @noreference This method is not intended to be referenced by clients. + */ + public String getLegacyDiscoveryProfileIdAttribute(){ + String profileId = buildInfoDicsoveryProfileId; + if (profileId == null) { + profileId = ScannerDiscoveryLegacySupport.getDeprecatedLegacyProfiles(id); + if (profileId == null && superClass instanceof InputType) { + profileId = ((InputType)superClass).getLegacyDiscoveryProfileIdAttribute(); + } + } + return profileId; + } + public String getDiscoveryProfileIdAttribute(){ - if(buildInfoDicsoveryProfileId == null && superClass != null) - return ((InputType)superClass).getDiscoveryProfileIdAttribute(); + if (!isLanguageSettingsProvidersFunctionalityEnabled()) + return getLegacyDiscoveryProfileIdAttribute(); + + return getDiscoveryProfileIdAttributeInternal(); + } + + /** + * Method extracted temporarily to support compatibility during SD transition. + */ + private String getDiscoveryProfileIdAttributeInternal(){ + if(buildInfoDicsoveryProfileId == null && superClass instanceof InputType) + return ((InputType)superClass).getDiscoveryProfileIdAttributeInternal(); return buildInfoDicsoveryProfileId; } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java index 0b1f6c233e5..3ce6f992212 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java @@ -50,16 +50,16 @@ import org.eclipse.core.runtime.IPath; import org.osgi.framework.Version; /** - * This class represents a set of configurations + * This class represents a set of configurations * to be edited simultaneously on property pages. */ public class MultiConfiguration extends MultiItemsHolder implements IMultiConfiguration { private static final String[] EMPTY_STR_ARRAY = new String[0]; - + protected IConfiguration[] fCfgs = null; private int curr = 0; - + public MultiConfiguration(IConfiguration[] cfs) { fCfgs = cfs; for (int i=0; i getDefaultLanguageSettingsProviders(IConfiguration cfg) { + List providers = new ArrayList(); + String[] ids = cfg.getDefaultLanguageSettingsProvidersIds(); + if (ids != null) { + for (String id : ids) { + ILanguageSettingsProvider provider = null; + if (!LanguageSettingsManager.isPreferShared(id)) { + provider = LanguageSettingsManager.getExtensionProviderCopy(id, false); + } + if (provider == null) { + provider = LanguageSettingsManager.getWorkspaceProvider(id); + } + providers.add(provider); + } + } + + // AG TODO - should it be when empty or when ids==null? + if (providers.isEmpty()) { + providers = ScannerDiscoveryLegacySupport.getDefaultProvidersLegacy(); + } + + return providers; + } + + private static void setDefaultLanguageSettingsProvidersIds(IConfiguration cfg, ICConfigurationDescription cfgDescription) { + if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) { + List providers = getDefaultLanguageSettingsProviders(cfg); + String[] ids = new String[providers.size()]; + for (int i = 0; i < ids.length; i++) { + ILanguageSettingsProvider provider = providers.get(i); + ids[i] = provider.getId(); + } + ((ILanguageSettingsProvidersKeeper) cfgDescription).setDefaultLanguageSettingsProvidersIds(ids); + } + + } + + public static void setDefaultLanguageSettingsProviders(IConfiguration cfg, ICConfigurationDescription cfgDescription) { + setDefaultLanguageSettingsProvidersIds(cfg, cfgDescription); + List providers = getDefaultLanguageSettingsProviders(cfg); + ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); + } + + private boolean isPersistedCfg(ICConfigurationDescription cfgDescription){ return cfgDescription.getSessionProperty(CFG_PERSISTED_PROPERTY) != null; } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/GCCBuiltinSpecsDetectorCygwin.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/GCCBuiltinSpecsDetectorCygwin.java new file mode 100644 index 00000000000..00e8b291613 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/GCCBuiltinSpecsDetectorCygwin.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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.language.settings.providers; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector; +import org.eclipse.core.resources.IResource; + +/** + * Class to detect built-in compiler settings. + * The paths are converted to cygwin "file-system" representation. + * + */ +public class GCCBuiltinSpecsDetectorCygwin extends GCCBuiltinSpecsDetector { + private static final URI CYGWIN_ROOT; + static { + try { + CYGWIN_ROOT = new URI("cygwin:/"); //$NON-NLS-1$ + } catch (URISyntaxException e) { + // hey we know this works + throw new IllegalStateException(e); + } + } + + @Override + protected URI getMappedRootURI(IResource sourceFile, String parsedResourceName) { + if (mappedRootURI == null) { + mappedRootURI = super.getMappedRootURI(sourceFile, parsedResourceName); + if (mappedRootURI == null) { + mappedRootURI = CYGWIN_ROOT; + } + } + return mappedRootURI; + } + + @Override + protected URI getBuildDirURI(URI mappedRootURI) { + if (buildDirURI == null) { + buildDirURI = super.getBuildDirURI(mappedRootURI); + if (buildDirURI == null) { + buildDirURI = CYGWIN_ROOT; + } + } + return buildDirURI; + } + + @Override + public GCCBuiltinSpecsDetectorCygwin cloneShallow() throws CloneNotSupportedException { + return (GCCBuiltinSpecsDetectorCygwin) super.cloneShallow(); + } + + @Override + public GCCBuiltinSpecsDetectorCygwin clone() throws CloneNotSupportedException { + return (GCCBuiltinSpecsDetectorCygwin) super.clone(); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java index e927462383b..f10253685ff 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.errorparsers.RegexErrorPattern; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsLogger; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; @@ -167,6 +168,11 @@ public abstract class AbstractBuildCommandParser extends AbstractLanguageSetting } setSettingEntries(currentCfgDescription, rc, currentLanguageId, entries); + + // AG FIXME - temporary log to remove before CDT Juno release + LanguageSettingsLogger.logInfo(getPrefixForLog() + + getClass().getSimpleName() + " collected " + (entries!=null ? ("" + entries.size()) : "null") + " entries for " + rc); + } /** 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 b31af8cae35..b988e1bbb30 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 @@ -37,6 +37,7 @@ import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.internal.core.BuildRunnerHelper; import org.eclipse.cdt.internal.core.XmlUtil; +import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsLogger; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; import org.eclipse.cdt.utils.CommandLineUtil; @@ -317,12 +318,17 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti @Override public void registerListener(ICConfigurationDescription cfgDescription) { + // AG FIXME - temporary log to remove before CDT Juno release + LanguageSettingsLogger.logInfo(getPrefixForLog() + "registerListener [" + System.identityHashCode(this) + "] " + this); + currentCfgDescription = cfgDescription; execute(); } @Override public void unregisterListener() { + // AG FIXME - temporary log to remove before CDT Juno release + LanguageSettingsLogger.logInfo(getPrefixForLog() + "unregisterListener [" + System.identityHashCode(this) + "] " + this); } @Override @@ -347,6 +353,8 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti */ protected void execute() { if (isExecuted) { + // AG FIXME - temporary log to remove before CDT Juno release +// LanguageSettingsLogger.logInfo(getPrefixForLog() + "Already executed [" + System.identityHashCode(this) + "] " + this); return; } isExecuted = true; @@ -385,6 +393,9 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti } job.setRule(rule); job.schedule(); + + // AG FIXME - temporary log to remove before CDT Juno release + LanguageSettingsLogger.logInfo(getPrefixForLog() + "Execution scheduled [" + System.identityHashCode(this) + "] " + this); } /** @@ -481,6 +492,11 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti protected void shutdownForLanguage() { if (detectedSettingEntries != null && detectedSettingEntries.size() > 0) { collected = detectedSettingEntries.size(); + + // AG FIXME - temporary log to remove before CDT Juno release + LanguageSettingsLogger.logInfo(getPrefixForLog() + + getClass().getSimpleName() + " collected " + detectedSettingEntries.size() + " entries" + " for language " + currentLanguageId); + setSettingEntries(currentCfgDescription, currentResource, currentLanguageId, detectedSettingEntries); } detectedSettingEntries = null; diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java index c3e480fdff3..bded3f9e06f 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java @@ -38,6 +38,7 @@ 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.internal.core.XmlUtil; +import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsLogger; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.cdt.utils.EFSExtensionManager; import org.eclipse.core.filesystem.EFS; @@ -556,6 +557,19 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett return buildDirURI; } + // AG FIXME - temporary, remove me + @Deprecated + protected String getPrefixForLog() { + String str; + if (currentCfgDescription!= null) { + IProject ownerProject = currentCfgDescription.getProjectDescription().getProject(); + str = ownerProject + ":" + currentCfgDescription.getName(); + } else { + str = "[global]"; + } + return str + ": "; + } + /** * Sets language settings entries for current configuration description, current resource * and current language ID. @@ -564,6 +578,10 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett */ protected void setSettingEntries(List entries) { setSettingEntries(currentCfgDescription, currentResource, currentLanguageId, entries); + + // AG FIXME - temporary log to remove before CDT Juno release + LanguageSettingsLogger.logInfo(getPrefixForLog() + + getClass().getSimpleName() + " collected " + (entries!=null ? ("" + entries.size()) : "null") + " entries for " + currentResource); } /** diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml b/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml index 146c331769c..af177faa5b7 100644 --- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml @@ -1269,7 +1269,6 @@ dependencyExtensions="h" dependencyCalculator="org.eclipse.cdt.managedbuilder.makegen.gnu.DefaultGCCDependencyCalculator2" id="cdt.managedbuild.tool.gnu.c.compiler.input" - scannerConfigDiscoveryProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC|org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile" languageId="org.eclipse.cdt.core.gcc"> + /> + /> + osList="linux,hpux,aix,qnx" + targetTool="cdt.managedbuild.tool.gnu.c.linker;cdt.managedbuild.tool.gnu.cpp.linker;cdt.managedbuild.tool.gnu.archiver"> @@ -1842,6 +1842,7 @@ configurationEnvironmentSupplier="org.eclipse.cdt.managedbuilder.gnu.mingw.MingwEnvironmentVariableSupplier" id="cdt.managedbuild.toolchain.gnu.mingw.base" isToolChainSupported="org.eclipse.cdt.managedbuilder.gnu.mingw.MingwIsToolChainSupported" + languageSettingsProviders="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser;org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" name="%ToolChainName.MinGW" osList="win32" targetTool="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base;cdt.managedbuild.tool.gnu.c.linker.mingw.base;cdt.managedbuild.tool.gnu.archiver"> @@ -2083,9 +2084,9 @@ + id="cdt.managedbuild.config.gnu.base" + languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"> + cleanCommand="rm -rf" + id="cdt.managedbuild.config.gnu.cygwin.base" + languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"> + cleanCommand="rm -rf" + id="cdt.managedbuild.config.gnu.mingw.base" + languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"> + + + - + @@ -564,7 +573,7 @@ - + @@ -625,6 +634,7 @@ name="%MBSPerProjectProfile.name" profileId="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP"/> + + + + + + + + + + + + + + + + + + + 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 00000000000..9f999d8d7a6 --- /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 00000000000..b12bf1c19c3 --- /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 00000000000..0eed304893e --- /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 458f7e517a1..9c6bb0af7ee 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/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/WizardDefaultsTab.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/WizardDefaultsTab.java index 636382cc660..c52396b28d2 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/WizardDefaultsTab.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/WizardDefaultsTab.java @@ -11,6 +11,7 @@ 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; @@ -22,7 +23,7 @@ import org.eclipse.swt.widgets.Composite; /** * @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. */ @@ -30,6 +31,7 @@ public class WizardDefaultsTab extends AbstractCPropertyTab { private Button show_sup; private Button show_oth; + private Button checkBoxTryNewSD; @Override public void createControls(Composite parent) { @@ -37,27 +39,34 @@ public class WizardDefaultsTab extends AbstractCPropertyTab { usercomp.setLayout(new GridLayout(1, false)); show_sup = new Button(usercomp, SWT.CHECK); - show_sup.setText(Messages.WizardDefaultsTab_0); + show_sup.setText(Messages.WizardDefaultsTab_0); show_sup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); show_oth = new Button(usercomp, SWT.CHECK); - show_oth.setText(Messages.WizardDefaultsTab_1); + show_oth.setText(Messages.WizardDefaultsTab_1); show_oth.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + checkBoxTryNewSD = new Button(usercomp, SWT.CHECK); + checkBoxTryNewSD.setText(org.eclipse.cdt.internal.ui.newui.Messages.CDTMainWizardPage_TrySD90); + checkBoxTryNewSD.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + show_sup.setSelection(!CDTPrefUtil.getBool(CDTPrefUtil.KEY_NOSUPP)); show_oth.setSelection(CDTPrefUtil.getBool(CDTPrefUtil.KEY_OTHERS)); + checkBoxTryNewSD.setSelection(CDTPrefUtil.getBool(LanguageSettingsProvidersPage.KEY_NEWSD)); } @Override protected void performOK() { CDTPrefUtil.setBool(CDTPrefUtil.KEY_NOSUPP, !show_sup.getSelection()); CDTPrefUtil.setBool(CDTPrefUtil.KEY_OTHERS, show_oth.getSelection()); + CDTPrefUtil.setBool(LanguageSettingsProvidersPage.KEY_NEWSD, checkBoxTryNewSD.getSelection()); } - + @Override protected void performDefaults() { show_sup.setSelection(true); show_oth.setSelection(false); + checkBoxTryNewSD.setSelection(true); } @Override diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java index 1cb3196cbea..27a75b7433a 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/DiscoveryTab.java @@ -24,10 +24,13 @@ import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set import org.eclipse.cdt.build.internal.core.scannerconfig.CfgDiscoveredPathManager; import org.eclipse.cdt.build.internal.core.scannerconfig.CfgScannerConfigUtil; import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager; +import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; import org.eclipse.cdt.core.model.util.CDTListComparator; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICResourceDescription; import org.eclipse.cdt.core.settings.model.util.CDataUtil; +import org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProvidersPage; +import org.eclipse.cdt.internal.ui.newui.StatusMessageLine; import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2; import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2Set; @@ -46,7 +49,9 @@ import org.eclipse.cdt.managedbuilder.core.IInputType; import org.eclipse.cdt.managedbuilder.core.IResourceInfo; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.ui.Messages; +import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.newui.CDTPrefUtil; import org.eclipse.cdt.utils.ui.controls.ControlFactory; import org.eclipse.cdt.utils.ui.controls.TabFolderLayout; @@ -103,6 +108,7 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf private Button reportProblemsCheckBox; private Combo profileComboBox; private Composite profileOptionsComposite; + private Button clearButton; private ICfgScannerConfigBuilderInfo2Set cbi; private Map baseInfoMap; @@ -116,6 +122,8 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf private DiscoveryPageWrapper wrapper = null; + private StatusMessageLine fStatusLine; + /* * (non-Javadoc) * @@ -184,6 +192,9 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf profileOptionsComposite.setLayoutData(gd); profileOptionsComposite.setLayout(new TabFolderLayout()); + fStatusLine = new StatusMessageLine(usercomp, SWT.LEFT, 2); + setEnablement(); + sashForm.setWeights(DEFAULT_SASH_WEIGHTS); } @@ -236,7 +247,7 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf Label clearLabel = ControlFactory.createLabel(autoDiscoveryGroup, Messages.DiscoveryTab_ClearDisoveredEntries); // "Clear" button - Button clearButton = ControlFactory.createPushButton(autoDiscoveryGroup, Messages.DiscoveryTab_Clear); + clearButton = ControlFactory.createPushButton(autoDiscoveryGroup, Messages.DiscoveryTab_Clear); GridData gd = (GridData) clearButton.getLayoutData(); gd.grabExcessHorizontalSpace = true; //Bug 331783 - NLS: "Clear" button label in Makefile Project preferences truncated @@ -334,6 +345,27 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf } else { setVisibility(Messages.DiscoveryTab_6); } + + setEnablement(); + } + + private void setEnablement() { + IStatus status = null; + ICConfigurationDescription cfgDescription = page.getResDesc().getConfiguration(); + boolean isEnabled = !LanguageSettingsProvidersPage.isLanguageSettingsProvidersEnabled(getProject()) || ScannerDiscoveryLegacySupport.isMbsLanguageSettingsProviderOn(cfgDescription); + if (!isEnabled) { + status = new Status(IStatus.INFO, CUIPlugin.PLUGIN_ID, "Managed Build language settings provider is not enabled."); + } + + scopeComboBox.setEnabled(isEnabled); + resTable.setEnabled(isEnabled); + boolean isSCDEnabled = autoDiscoveryCheckBox.getSelection(); + reportProblemsCheckBox.setEnabled(isEnabled && isSCDEnabled); + autoDiscoveryCheckBox.setEnabled(isEnabled); + autoDiscoveryGroup.setEnabled(isEnabled); + clearButton.setEnabled(isEnabled); + + fStatusLine.setErrorStatus(status); } private void setVisibility(String errMsg) { @@ -372,7 +404,13 @@ public class DiscoveryTab extends AbstractCBuildPropertyTab implements IBuildInf buildInfo = (IScannerConfigBuilderInfo2) ti.getData("info"); //$NON-NLS-1$ String selectedProfileId = buildInfo.getSelectedProfileId(); iContext = (CfgInfoContext) ti.getData("cont"); //$NON-NLS-1$ - autoDiscoveryCheckBox.setSelection(buildInfo.isAutoDiscoveryEnabled() + boolean autodiscoveryEnabled2 = buildInfo.isAutoDiscoveryEnabled(); + if (autodiscoveryEnabled2) { + IConfiguration cfg = iContext.getConfiguration(); + ICConfigurationDescription cfgDescription = ManagedBuildManager.getDescriptionForConfiguration(cfg); + autodiscoveryEnabled2 = ScannerDiscoveryLegacySupport.isLegacyScannerDiscoveryOn(cfgDescription); + } + autoDiscoveryCheckBox.setSelection(autodiscoveryEnabled2 && !selectedProfileId.equals(ScannerConfigProfileManager.NULL_PROFILE_ID)); reportProblemsCheckBox.setSelection(buildInfo.isProblemReportingEnabled()); diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/MBSWizardHandler.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/MBSWizardHandler.java index 73be50d9ad8..34a56e4e29a 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/MBSWizardHandler.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/MBSWizardHandler.java @@ -23,6 +23,9 @@ import java.util.SortedMap; import java.util.TreeMap; import java.util.TreeSet; +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.ScannerDiscoveryLegacySupport; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription; @@ -41,8 +44,9 @@ import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.core.Configuration; import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo; import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject; -import org.eclipse.cdt.managedbuilder.ui.properties.ManagedBuilderUIPlugin; +import org.eclipse.cdt.managedbuilder.internal.dataprovider.ConfigurationDataProvider; import org.eclipse.cdt.managedbuilder.internal.ui.Messages; +import org.eclipse.cdt.managedbuilder.ui.properties.ManagedBuilderUIPlugin; import org.eclipse.cdt.ui.newui.CDTPrefUtil; import org.eclipse.cdt.ui.templateengine.IWizardDataPage; import org.eclipse.cdt.ui.templateengine.Template; @@ -73,10 +77,10 @@ import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; /** * This object is created per each Project type - * + * * It is responsible for: * - corresponding line in left pane of 1st wizard page - * - whole view of right pane, including + * - whole view of right pane, including * * @noextend This class is not intended to be subclassed by clients. * @noinstantiate This class is not intended to be instantiated by clients. @@ -84,16 +88,17 @@ import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; public class MBSWizardHandler extends CWizardHandler { public static final String ARTIFACT = "org.eclipse.cdt.build.core.buildArtefactType"; //$NON-NLS-1$ public static final String EMPTY_STR = ""; //$NON-NLS-1$ - + private static final String PROPERTY = "org.eclipse.cdt.build.core.buildType"; //$NON-NLS-1$ private static final String PROP_VAL = PROPERTY + ".debug"; //$NON-NLS-1$ - private static final String tooltip = - Messages.CWizardHandler_1 + - Messages.CWizardHandler_2 + - Messages.CWizardHandler_3 + - Messages.CWizardHandler_4 + - Messages.CWizardHandler_5; - + + private static final String tooltip = + Messages.CWizardHandler_1 + + Messages.CWizardHandler_2 + + Messages.CWizardHandler_3 + + Messages.CWizardHandler_4 + + Messages.CWizardHandler_5; + protected SortedMap full_tcs = new TreeMap(); private String propertyId = null; private IProjectType pt = null; @@ -106,12 +111,12 @@ public class MBSWizardHandler extends CWizardHandler { private EntryInfo entryInfo; protected CfgHolder[] cfgs = null; protected IWizardPage[] customPages; - + /** * Current list of preferred toolchains */ private List preferredTCs = new ArrayList(); - + protected static final class EntryInfo { private SortedMap tcs; private EntryDescriptor entryDescriptor; @@ -124,12 +129,12 @@ public class MBSWizardHandler extends CWizardHandler { private IWizardPage predatingPage; private IWizardPage followingPage; private IWizard wizard; - + public EntryInfo(EntryDescriptor dr, SortedMap _tcs){ entryDescriptor = dr; tcs = _tcs; } - + /** * @since 5.1 */ @@ -137,7 +142,7 @@ public class MBSWizardHandler extends CWizardHandler { this(dr, _tcs); wizard = w; } - + public boolean isValid(){ initialize(); return isValid; @@ -147,7 +152,7 @@ public class MBSWizardHandler extends CWizardHandler { initialize(); return template; } - + public EntryDescriptor getDescriptor(){ return entryDescriptor; } @@ -155,19 +160,19 @@ public class MBSWizardHandler extends CWizardHandler { private void initialize(){ if(initialized) return; - + do { if(entryDescriptor == null) break; String path[] = entryDescriptor.getPathArray(); if(path == null || path.length == 0) break; - + projectTypeId = path[0]; - if(!entryDescriptor.isDefaultForCategory() && + if(!entryDescriptor.isDefaultForCategory() && path.length > 1 && (!path[0].equals(ManagedBuildWizard.OTHERS_LABEL))){ - templateId = path[path.length - 1]; - Template templates[] = null; + templateId = path[path.length - 1]; + Template templates[] = null; if(wizard instanceof ICDTCommonProjectWizard) { ICDTCommonProjectWizard wz = (ICDTCommonProjectWizard)wizard; String[] langIDs = wz.getLanguageIDs(); @@ -176,38 +181,38 @@ public class MBSWizardHandler extends CWizardHandler { for (String id : langIDs) { lstTemplates.addAll(Arrays.asList(TemplateEngineUI.getDefault(). getTemplates(projectTypeId, null, id))); - } + } templates = lstTemplates.toArray(new Template[lstTemplates.size()]); } - } + } if(null == templates) { templates = TemplateEngineUI.getDefault().getTemplates(projectTypeId); } if((null == templates) || (templates.length == 0)) break; - + for (Template t : templates) { if(t.getTemplateId().equals(templateId)){ template = t; break; } } - + if(template == null) break; } - + isValid = true; } while(false); initialized = true; } - + public Template getInitializedTemplate(IWizardPage predatingPage, IWizardPage followingPage, Map map){ getNextPage(predatingPage, followingPage); - + Template template = getTemplate(); - + if(template != null){ Map valueStore = template.getValueStore(); // valueStore.clear(); @@ -223,11 +228,11 @@ public class MBSWizardHandler extends CWizardHandler { } return template; } - + public IWizardPage getNextPage(IWizardPage predatingPage, IWizardPage followingPage) { initialize(); - if(this.templatePages == null - || this.predatingPage != predatingPage + if(this.templatePages == null + || this.predatingPage != predatingPage || this.followingPage != followingPage){ this.predatingPage = predatingPage; this.followingPage = followingPage; @@ -238,12 +243,12 @@ public class MBSWizardHandler extends CWizardHandler { followingPage.setPreviousPage(predatingPage); } } - + if(templatePages.length != 0) return templatePages[0]; return followingPage; } - + private boolean canFinish(IWizardPage predatingPage, IWizardPage followingPage){ getNextPage(predatingPage, followingPage); for(int i = 0; i < templatePages.length; i++){ @@ -252,47 +257,47 @@ public class MBSWizardHandler extends CWizardHandler { } return true; } - + /** - * Filters toolchains - * + * Filters toolchains + * * @return - set of compatible toolchain's IDs */ protected Set tc_filter() { Set full = tcs.keySet(); - if (entryDescriptor == null) + if (entryDescriptor == null) return full; Set out = new LinkedHashSet(full.size()); for (String s : full) - if (isToolChainAcceptable(s)) + if (isToolChainAcceptable(s)) out.add(s); return out; } /** * Checks whether given toolchain can be displayed - * + * * @param tcId - toolchain _NAME_ to check * @return - true if toolchain can be displayed */ public boolean isToolChainAcceptable(String tcId) { - if (template == null || template.getTemplateInfo() == null) + if (template == null || template.getTemplateInfo() == null) return true; - + String[] toolChainIds = template.getTemplateInfo().getToolChainIds(); - if (toolChainIds == null || toolChainIds.length == 0) + if (toolChainIds == null || toolChainIds.length == 0) return true; - + Object ob = tcs.get(tcId); if (ob == null) return true; // sic ! This can occur with Other Toolchain only if (!(ob instanceof IToolChain)) return false; - + String id1 = ((IToolChain)ob).getId(); IToolChain sup = ((IToolChain)ob).getSuperClass(); String id2 = sup == null ? null : sup.getId(); - + for (String id : toolChainIds) { if ((id != null && id.equals(id1)) || (id != null && id.equals(id2))) @@ -305,20 +310,20 @@ public class MBSWizardHandler extends CWizardHandler { return tc_filter().size(); } } - + public MBSWizardHandler(IProjectType _pt, Composite p, IWizard w) { - super(p, Messages.CWizardHandler_0, _pt.getName()); + super(p, Messages.CWizardHandler_0, _pt.getName()); pt = _pt; setWizard(w); } public MBSWizardHandler(String name, Composite p, IWizard w) { - super(p, Messages.CWizardHandler_0, name); + super(p, Messages.CWizardHandler_0, name); setWizard(w); } public MBSWizardHandler(IBuildPropertyValue val, Composite p, IWizard w) { - super(p, Messages.CWizardHandler_0, val.getName()); + super(p, Messages.CWizardHandler_0, val.getName()); propertyId = val.getId(); setWizard(w); } @@ -330,16 +335,16 @@ public class MBSWizardHandler extends CWizardHandler { startingPage = w.getStartingPage(); } } - + protected IWizardPage getStartingPage(){ return startingPage; } - + public Map getMainPageData() { WizardNewProjectCreationPage page = (WizardNewProjectCreationPage)getStartingPage(); Map data = new HashMap(); String projName = page.getProjectName(); - projName = projName != null ? projName.trim() : EMPTY_STR; + projName = projName != null ? projName.trim() : EMPTY_STR; data.put("projectName", projName); //$NON-NLS-1$ data.put("baseName", getBaseName(projName)); //$NON-NLS-1$ data.put("baseNameUpper", getBaseName(projName).toUpperCase() ); //$NON-NLS-1$ @@ -350,7 +355,7 @@ public class MBSWizardHandler extends CWizardHandler { data.put("location", location); //getProjectLocation().toPortableString()); //$NON-NLS-1$ return data; } - + private String getBaseName(String name) { String baseName = name; int dot = baseName.lastIndexOf('.'); @@ -363,11 +368,11 @@ public class MBSWizardHandler extends CWizardHandler { } return baseName; } - + @Override public void handleSelection() { List preferred = CDTPrefUtil.getPreferredTCs(); - + if (table == null) { table = new Table(parent, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER); table.getAccessible().addAccessibleListener( @@ -400,7 +405,7 @@ public class MBSWizardHandler extends CWizardHandler { counter++; } if (counter > 0) table.select(position); - } + } table.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { @@ -421,11 +426,11 @@ public class MBSWizardHandler extends CWizardHandler { if (listener != null) listener.toolChainListChanged(table.getSelectionCount()); } - + private void loadCustomPages() { - if (! (getWizard() instanceof ICDTCommonProjectWizard)) - return; // not probable - + if (! (getWizard() instanceof ICDTCommonProjectWizard)) + return; // not probable + ICDTCommonProjectWizard wz = (ICDTCommonProjectWizard)getWizard(); MBSCustomPageManager.init(); MBSCustomPageManager.addStockPage(getStartingPage(), CDTMainWizardPage.PAGE_ID); @@ -438,9 +443,9 @@ public class MBSWizardHandler extends CWizardHandler { customPages = MBSCustomPageManager.getCustomPages(); - if (customPages == null) + if (customPages == null) customPages = new IWizardPage[0]; - + for (IWizardPage customPage : customPages) customPage.setWizard(wz); setCustomPagesFilter(wz); @@ -463,13 +468,13 @@ public class MBSWizardHandler extends CWizardHandler { boolean ptIsNull = (getProjectType() == null); if (!ptIsNull) MBSCustomPageManager.addPageProperty( - MBSCustomPageManager.PAGE_ID, - MBSCustomPageManager.PROJECT_TYPE, + MBSCustomPageManager.PAGE_ID, + MBSCustomPageManager.PROJECT_TYPE, getProjectType().getId() ); IToolChain[] tcs = getSelectedToolChains(); - ArrayList x = new ArrayList(); + ArrayList x = new ArrayList(); TreeSet y = new TreeSet(); if (tcs!=null) { int n = tcs.length; @@ -477,7 +482,7 @@ public class MBSWizardHandler extends CWizardHandler { if (tcs[i] == null) // --- NO TOOLCHAIN --- continue; // has no custom pages. x.add(tcs[i]); - + IConfiguration cfg = tcs[i].getParent(); if (cfg == null) continue; @@ -487,24 +492,24 @@ public class MBSWizardHandler extends CWizardHandler { } } MBSCustomPageManager.addPageProperty( - MBSCustomPageManager.PAGE_ID, - MBSCustomPageManager.TOOLCHAIN, + MBSCustomPageManager.PAGE_ID, + MBSCustomPageManager.TOOLCHAIN, x); - + if (ptIsNull) { if (y.size() > 0) MBSCustomPageManager.addPageProperty( - MBSCustomPageManager.PAGE_ID, - MBSCustomPageManager.PROJECT_TYPE, + MBSCustomPageManager.PAGE_ID, + MBSCustomPageManager.PROJECT_TYPE, y); else MBSCustomPageManager.addPageProperty( - MBSCustomPageManager.PAGE_ID, - MBSCustomPageManager.PROJECT_TYPE, + MBSCustomPageManager.PAGE_ID, + MBSCustomPageManager.PROJECT_TYPE, null); } } - + @Override public void handleUnSelection() { if (table != null) { @@ -517,16 +522,16 @@ public class MBSWizardHandler extends CWizardHandler { if (tc.isAbstract() || tc.isSystemObject()) return; IConfiguration[] cfgs = null; // New style managed project type. Configurations are referenced via propertyId. - if (propertyId != null) { + if (propertyId != null) { cfgs = ManagedBuildManager.getExtensionConfigurations(tc, ARTIFACT, propertyId); // Old style managewd project type. Configs are obtained via projectType } else if (pt != null) { cfgs = ManagedBuildManager.getExtensionConfigurations(tc, pt); - } + } if (cfgs == null || cfgs.length == 0) return; full_tcs.put(tc.getUniqueRealName(), tc); } - + @Override public void createProject(IProject project, boolean defaults, boolean onFinish, IProgressMonitor monitor) throws CoreException { try { @@ -544,20 +549,20 @@ public class MBSWizardHandler extends CWizardHandler { public void convertProject(IProject proj, IProgressMonitor monitor) throws CoreException { setProjectDescription(proj, true, true, monitor); } - + private void setProjectDescription(IProject project, boolean defaults, boolean onFinish, IProgressMonitor monitor) throws CoreException { ICProjectDescriptionManager mngr = CoreModel.getDefault().getProjectDescriptionManager(); ICProjectDescription des = mngr.createProjectDescription(project, false, !onFinish); ManagedBuildInfo info = ManagedBuildManager.createBuildInfo(project); monitor.worked(10); cfgs = getCfgItems(false); - if (cfgs == null || cfgs.length == 0) + if (cfgs == null || cfgs.length == 0) cfgs = CDTConfigWizardPage.getDefaultCfgs(this); - + if (cfgs == null || cfgs.length == 0 || cfgs[0].getConfiguration() == null) { - throw new CoreException(new Status(IStatus.ERROR, + throw new CoreException(new Status(IStatus.ERROR, ManagedBuilderUIPlugin.getUniqueIdentifier(), - Messages.CWizardHandler_6)); + Messages.CWizardHandler_6)); } Configuration cf = (Configuration)cfgs[0].getConfiguration(); ManagedProject mProj = new ManagedProject(project, cf.getProjectType()); @@ -565,12 +570,12 @@ public class MBSWizardHandler extends CWizardHandler { monitor.worked(10); cfgs = CfgHolder.unique(cfgs); cfgs = CfgHolder.reorder(cfgs); - + ICConfigurationDescription cfgDebug = null; ICConfigurationDescription cfgFirst = null; - + int work = 50/cfgs.length; - + for (CfgHolder cfg : cfgs) { cf = (Configuration)cfg.getConfiguration(); String id = ManagedBuildManager.calculateChildId(cf.getId(), null); @@ -582,32 +587,53 @@ public class MBSWizardHandler extends CWizardHandler { IBuilder bld = config.getEditableBuilder(); if (bld != null) { bld.setManagedBuildOn(true); } - + config.setName(cfg.getName()); config.setArtifactName(mProj.getDefaultArtifactName()); - + IBuildProperty b = config.getBuildProperties().getProperty(PROPERTY); if (cfgDebug == null && b != null && b.getValue() != null && PROP_VAL.equals(b.getValue().getId())) cfgDebug = cfgDes; - if (cfgFirst == null) // select at least first configuration - cfgFirst = cfgDes; + if (cfgFirst == null) // select at least first configuration + cfgFirst = cfgDes; + + if (cfgDes instanceof ILanguageSettingsProvidersKeeper) { + boolean isTryingNewSD = false; + IWizardPage page = getStartingPage(); + if (page instanceof CDTMainWizardPage) { + isTryingNewSD = ((CDTMainWizardPage)page).isTryingNewSD(); + } + + ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(project, isTryingNewSD); + List providers; + if (isTryingNewSD) { + ConfigurationDataProvider.setDefaultLanguageSettingsProviders(config, cfgDes); + } else { + if (cfgDes instanceof ILanguageSettingsProvidersKeeper) { + ((ILanguageSettingsProvidersKeeper) cfgDes).setLanguageSettingProviders(ScannerDiscoveryLegacySupport.getDefaultProvidersLegacy()); + } + } + } else { + ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(project, false); + } + monitor.worked(work); } mngr.setProjectDescription(project, des); } - + @Override protected void doTemplatesPostProcess(IProject prj) { if(entryInfo == null) return; - + Template template = entryInfo.getInitializedTemplate(getStartingPage(), getConfigPage(), getMainPageData()); if(template == null) return; List configs = new ArrayList(); for (CfgHolder cfg : cfgs) { - configs.add((IConfiguration)cfg.getConfiguration()); + configs.add(cfg.getConfiguration()); } template.getTemplateInfo().setConfigurations(configs); @@ -616,19 +642,19 @@ public class MBSWizardHandler extends CWizardHandler { TemplateEngineUIUtil.showError(statuses[0].getMessage(), statuses[0].getException()); } } - + protected CDTConfigWizardPage getConfigPage() { if (fConfigPage == null) { fConfigPage = new CDTConfigWizardPage(this); } return fConfigPage; } - + @Override public IWizardPage getSpecificPage() { return entryInfo.getNextPage(getStartingPage(), getConfigPage()); } - + /** * Mark preferred toolchains with specific images */ @@ -647,11 +673,11 @@ public class MBSWizardHandler extends CWizardHandler { } } } - + public List getPreferredTCNames() { return preferredTCs; } - + @Override public String getHeader() { return head; } public boolean isDummy() { return false; } @@ -659,11 +685,11 @@ public class MBSWizardHandler extends CWizardHandler { public boolean supportsPreferred() { return true; } @Override - public boolean isChanged() { + public boolean isChanged() { if (savedToolChains == null) return true; IToolChain[] tcs = getSelectedToolChains(); - if (savedToolChains.length != tcs.length) + if (savedToolChains.length != tcs.length) return true; for (IToolChain savedToolChain : savedToolChains) { boolean found = false; @@ -678,12 +704,12 @@ public class MBSWizardHandler extends CWizardHandler { } return false; } - + @Override public void saveState() { savedToolChains = getSelectedToolChains(); } - + // Methods specific for MBSWizardHandler public IToolChain[] getSelectedToolChains() { @@ -699,7 +725,7 @@ public class MBSWizardHandler extends CWizardHandler { public int getToolChainsCount() { if (entryInfo == null) return full_tcs.size(); - else + else return entryInfo.tc_filter().size(); } public String getPropertyId() { @@ -716,13 +742,13 @@ public class MBSWizardHandler extends CWizardHandler { return fConfigPage.getCfgItems(defaults); } @Override - public String getErrorMessage() { + public String getErrorMessage() { TableItem[] tis = table.getSelection(); if (tis == null || tis.length == 0) - return Messages.MBSWizardHandler_0; + return Messages.MBSWizardHandler_0; return null; } - + @Override protected void doCustom(IProject newProject) { IRunnableWithProgress[] operations = MBSCustomPageManager.getOperations(); @@ -736,7 +762,7 @@ public class MBSWizardHandler extends CWizardHandler { ManagedBuilderUIPlugin.log(e); } } - + @Override public void postProcess(IProject newProject, boolean created) { deleteExtraConfigs(newProject); @@ -747,17 +773,17 @@ public class MBSWizardHandler extends CWizardHandler { doCustom(newProject); } } - + /** - * Deletes configurations - * + * Deletes configurations + * * @param newProject - affected project */ private void deleteExtraConfigs(IProject newProject) { - if (isChanged()) return; // no need to delete + if (isChanged()) return; // no need to delete if (listener != null && listener.isCurrent()) return; // nothing to delete if (fConfigPage == null || !fConfigPage.pagesLoaded) return; - + ICProjectDescription prjd = CoreModel.getDefault().getProjectDescription(newProject, true); if (prjd == null) return; ICConfigurationDescription[] all = prjd.getConfigurations(); @@ -781,19 +807,19 @@ public class MBSWizardHandler extends CWizardHandler { CoreModel.getDefault().setProjectDescription(newProject, prjd); } catch (CoreException e) {} } - + @Override - public boolean isApplicable(EntryDescriptor data) { + public boolean isApplicable(EntryDescriptor data) { EntryInfo info = new EntryInfo(data, full_tcs, wizard); return info.isValid() && (info.getToolChainsCount() > 0); } - + @Override public void initialize(EntryDescriptor data) throws CoreException { EntryInfo info = new EntryInfo(data, full_tcs, wizard); if(!info.isValid()) throw new CoreException(new Status(IStatus.ERROR, ManagedBuilderUIPlugin.getUniqueIdentifier(), "inappropriate descriptor")); //$NON-NLS-1$ - + entryInfo = info; } @@ -819,20 +845,19 @@ public class MBSWizardHandler extends CWizardHandler { public boolean canFinish() { if(entryInfo == null) return false; - + if (!getConfigPage().isCustomPageComplete()) return false; - + if(!entryInfo.canFinish(startingPage, getConfigPage())) return false; - + if (customPages != null) for (int i=0; i tcMap = new HashMap(); - - + + /** * True if the user entered a non-empty string in the project name field. In that state, we avoid * automatically filling the project name field with the directory name (last segment of the location) he @@ -68,6 +71,9 @@ public class NewMakeProjFromExistingPage extends WizardPage { */ boolean projectNameSetByUser; + private Button checkBoxTryNewSD; + + protected NewMakeProjFromExistingPage() { super(Messages.NewMakeProjFromExistingPage_0); setTitle(Messages.NewMakeProjFromExistingPage_1); @@ -87,6 +93,22 @@ public class NewMakeProjFromExistingPage extends WizardPage { addSourceSelector(comp); addLanguageSelector(comp); addToolchainSelector(comp); + + checkBoxTryNewSD = new Button(comp, SWT.CHECK); + checkBoxTryNewSD.setText(org.eclipse.cdt.internal.ui.newui.Messages.CDTMainWizardPage_TrySD90); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 2; + checkBoxTryNewSD.setLayoutData(gd); + + + // restore settings from preferences + boolean isTryNewSD = true; + boolean contains = CUIPlugin.getDefault().getPreferenceStore().contains(LanguageSettingsProvidersPage.KEY_NEWSD); + if (contains) { + isTryNewSD = CDTPrefUtil.getBool(LanguageSettingsProvidersPage.KEY_NEWSD); + } + checkBoxTryNewSD.setSelection(isTryNewSD); + setControl(comp); } @@ -109,7 +131,7 @@ public class NewMakeProjFromExistingPage extends WizardPage { } } }); - + // Note that the modify listener gets called not only when the user enters text but also when we // programatically set the field. This listener only gets called when the user modifies the field projectName.addKeyListener(new KeyAdapter() { @@ -119,17 +141,17 @@ public class NewMakeProjFromExistingPage extends WizardPage { } }); } - + /** * Validates the contents of the page, setting the page error message and Finish button state accordingly - * + * * @since 8.1 */ protected void validatePage() { - // Don't generate an error if project name or location is empty, but do disable Finish button. + // Don't generate an error if project name or location is empty, but do disable Finish button. String msg = null; boolean complete = true; // ultimately treated as false if msg != null - + String name = getProjectName(); if (name.isEmpty()) { complete = false; @@ -257,11 +279,11 @@ public class NewMakeProjFromExistingPage extends WizardPage { tcList = new List(group, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); - + // Base the List control size on the number of total toolchains, up to 15 entries, but allocate for no // less than five (small list boxes look strange). A vertical scrollbar will appear as needed updateTcMap(false); - gd.heightHint = tcList.getItemHeight() * (1 + Math.max(Math.min(tcMap.size(), 15), 5)); // +1 for + gd.heightHint = tcList.getItemHeight() * (1 + Math.max(Math.min(tcMap.size(), 15), 5)); // +1 for tcList.setLayoutData(gd); tcList.add(Messages.NewMakeProjFromExistingPage_11); @@ -279,11 +301,11 @@ public class NewMakeProjFromExistingPage extends WizardPage { supportedOnly.setSelection(true); updateTcWidget(true); - } + } /** * Load our map and with the suitable toolchains and then populate the List control - * + * * @param supportedOnly * if true, consider only supported toolchains */ @@ -302,7 +324,7 @@ public class NewMakeProjFromExistingPage extends WizardPage { /** * Load our map with the suitable toolchains. - * + * * @param supportedOnly * if true, add only toolchains that are available and which support the host platform */ @@ -342,4 +364,11 @@ public class NewMakeProjFromExistingPage extends WizardPage { return selection.length != 0 ? tcMap.get(selection[0]) : null; } + /** + * AG FIXME temporary method to be removed before CDT Juno release. + * @since 8.1 + */ + public boolean isTryingNewSD() { + return checkBoxTryNewSD.getSelection(); + } } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/STDWizardHandler.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/STDWizardHandler.java index b5128f0ef2e..dead8c0e84c 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/STDWizardHandler.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/STDWizardHandler.java @@ -11,7 +11,10 @@ *******************************************************************************/ package org.eclipse.cdt.managedbuilder.ui.wizards; +import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper; +import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager; import org.eclipse.cdt.core.settings.model.extension.CConfigurationData; @@ -23,11 +26,14 @@ import org.eclipse.cdt.managedbuilder.internal.core.Configuration; import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo; import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject; import org.eclipse.cdt.managedbuilder.internal.core.ToolChain; +import org.eclipse.cdt.managedbuilder.internal.dataprovider.ConfigurationDataProvider; import org.eclipse.cdt.managedbuilder.internal.ui.Messages; +import org.eclipse.cdt.ui.wizards.CDTMainWizardPage; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.wizard.IWizard; +import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.swt.widgets.Composite; /** @@ -37,13 +43,13 @@ import org.eclipse.swt.widgets.Composite; public class STDWizardHandler extends MBSWizardHandler { public STDWizardHandler(Composite p, IWizard w) { - super(Messages.StdBuildWizard_0, p, w); + super(Messages.StdBuildWizard_0, p, w); } @Override public void addTc(IToolChain tc) { if (tc == null) { - full_tcs.put(Messages.StdProjectTypeHandler_0, null); + full_tcs.put(Messages.StdProjectTypeHandler_0, null); } else { if (tc.isAbstract() || tc.isSystemObject()) return; // unlike CWizardHandler, we don't check for configs @@ -58,9 +64,9 @@ public class STDWizardHandler extends MBSWizardHandler { public void createProject(IProject project, boolean defaults, boolean onFinish, IProgressMonitor monitor) throws CoreException { try { monitor.beginTask("", 100);//$NON-NLS-1$ - + setProjectDescription(project, defaults, onFinish, monitor); - + doTemplatesPostProcess(project); doCustom(project); monitor.worked(30); @@ -71,6 +77,7 @@ public class STDWizardHandler extends MBSWizardHandler { private void setProjectDescription(IProject project, boolean defaults, boolean onFinish, IProgressMonitor monitor) throws CoreException { + ICProjectDescriptionManager mngr = CoreModel.getDefault().getProjectDescriptionManager(); ICProjectDescription des = mngr.createProjectDescription(project, false, !onFinish); ManagedBuildInfo info = ManagedBuildManager.createBuildInfo(project); @@ -95,28 +102,51 @@ public class STDWizardHandler extends MBSWizardHandler { } bld.setManagedBuildOn(false); } else { - System.out.println(Messages.StdProjectTypeHandler_3); + System.out.println(Messages.StdProjectTypeHandler_3); } cfg.setArtifactName(mProj.getDefaultArtifactName()); CConfigurationData data = cfg.getConfigurationData(); - des.createConfiguration(ManagedBuildManager.CFG_DATA_PROVIDER_ID, data); + ICConfigurationDescription cfgDes = des.createConfiguration(ManagedBuildManager.CFG_DATA_PROVIDER_ID, data); + + if (cfgDes instanceof ILanguageSettingsProvidersKeeper) { + boolean isTryingNewSD = false; + IWizardPage page = getStartingPage(); + if (page instanceof CDTMainWizardPage) { + isTryingNewSD = ((CDTMainWizardPage)page).isTryingNewSD(); + } + + ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(project, isTryingNewSD); + if (isTryingNewSD) { + ConfigurationDataProvider.setDefaultLanguageSettingsProviders(cfg, cfgDes); + } else { + if (cfgDes instanceof ILanguageSettingsProvidersKeeper) { + ((ILanguageSettingsProvidersKeeper) cfgDes).setLanguageSettingProviders(ScannerDiscoveryLegacySupport.getDefaultProvidersLegacy()); + } + } + } else { + ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(project, false); + } + monitor.worked(work); } mngr.setProjectDescription(project, des); } - public boolean canCreateWithoutToolchain() { return true; } - + + public boolean canCreateWithoutToolchain() { + return true; + } + @Override public void convertProject(IProject proj, IProgressMonitor monitor) throws CoreException { setProjectDescription(proj, true, true, monitor); } - + /** * If no toolchains selected by user, use default toolchain */ @Override public IToolChain[] getSelectedToolChains() { - if (full_tcs.size() == 0 || table.getSelection().length == 0) + if (full_tcs.size() == 0 || table.getSelection().length == 0) return new IToolChain[] { null }; else return super.getSelectedToolChains(); diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java index 66ab7ac5fe4..4ec0625febc 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java @@ -17,6 +17,7 @@ import java.util.List; import junit.framework.TestSuite; import org.eclipse.cdt.core.AbstractExecutableExtensionBase; +import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; import org.eclipse.cdt.core.settings.model.CIncludePathEntry; import org.eclipse.cdt.core.settings.model.CMacroEntry; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; @@ -55,6 +56,7 @@ public class LanguageSettingsManagerTests extends BaseTestCase { private static final String PROVIDER_NAME_2 = "test.provider.2.name"; private static final String CFG_ID = "test.configuration.id"; private static final String LANG_ID = "test.lang.id"; + private static final String LANG_CPP = GPPLanguage.ID; private static final IFile FILE_0 = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("/project/path0")); /** @@ -805,4 +807,156 @@ public class LanguageSettingsManagerTests extends BaseTestCase { assertSame(provider, providers.get(0)); } + /** + * TODO - YAGNI? + */ + public void testBuildResourceTree_FileInFolder() throws Exception { + // sample entries + CMacroEntry entry = new CMacroEntry("MACRO", null, 0); + List entries = new ArrayList(); + entries.add(entry); + + // create resources + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + IFile file = ResourceHelper.createFile(project, "file.cpp"); + assertNotNull(file); + + // create a provider and set the entries + LanguageSettingsSerializableProvider provider = new LanguageSettingsSerializableProvider(PROVIDER_1, PROVIDER_NAME_1); + provider.setSettingEntries(null, file, null, entries); + // build the hierarchy + LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, null, project); + + // check that entries go to highest possible level + assertEquals(entries, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file, null)); + assertEquals(entries, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, project, null)); + } + + /** + * TODO - YAGNI? + */ + public void testBuildResourceTree_FileInSubFolder() throws Exception { + // sample entries + CMacroEntry entry = new CMacroEntry("MACRO", null, 0); + List entries = new ArrayList(); + entries.add(entry); + + // create resources + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + IFolder folder = ResourceHelper.createFolder(project, "Folder"); + IFile file = ResourceHelper.createFile(project, "Folder/file.cpp"); + + // create a provider and set the entries + LanguageSettingsSerializableProvider provider = new LanguageSettingsSerializableProvider(PROVIDER_1, PROVIDER_NAME_1); + provider.setSettingEntries(null, file, null, entries); + // build the hierarchy + LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, null, project); + + // check that entries go to highest possible level + assertEquals(entries, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file, null)); + assertEquals(entries, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, folder, null)); + assertEquals(entries, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, project, null)); + } + + /** + * TODO - YAGNI? + */ + public void testBuildResourceTree_TwoSubFolders() throws Exception { + // sample entries + List entries1 = new ArrayList(); + entries1.add(new CMacroEntry("MACRO_1", null, 0)); + List entries2 = new ArrayList(); + entries2.add(new CMacroEntry("MACRO_2", null, 0)); + + // create resources + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + IFolder folder1 = ResourceHelper.createFolder(project, "Folder1"); + IFolder folder2 = ResourceHelper.createFolder(project, "Folder2"); + IFile file1 = ResourceHelper.createFile(project, "Folder1/file1.cpp"); + IFile file2 = ResourceHelper.createFile(project, "Folder2/file2.cpp"); + + // create a provider and set the entries + LanguageSettingsSerializableProvider provider = new LanguageSettingsSerializableProvider(PROVIDER_1, PROVIDER_NAME_1); + provider.setSettingEntries(null, file1, null, entries1); + provider.setSettingEntries(null, file2, null, entries2); + // build the hierarchy + LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, null, project); + + // check that entries go to highest possible level + assertEquals(entries1, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file1, null)); + assertEquals(entries1, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, folder1, null)); + + assertEquals(entries2, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file2, null)); + assertEquals(entries2, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, folder2, null)); + + assertEquals(0, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, project, null).size()); + } + + /** + * TODO - YAGNI? + */ + public void testBuildResourceTree_FlippingSettings() throws Exception { + // sample entries + List entries1 = new ArrayList(); + entries1.add(new CMacroEntry("MACRO_1", null, 0)); + List entries2 = new ArrayList(); + entries2.add(new CMacroEntry("MACRO_2", null, 0)); + + // create resources + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + IFile file1 = ResourceHelper.createFile(project, "file1.cpp"); + IFile file2 = ResourceHelper.createFile(project, "file2.cpp"); + IFile file3 = ResourceHelper.createFile(project, "file3.cpp"); + + // create a provider + LanguageSettingsSerializableProvider provider = new LanguageSettingsSerializableProvider(PROVIDER_1, PROVIDER_NAME_1); + + // set the entries for the first 2 files + provider.setSettingEntries(null, file1, null, entries1); + provider.setSettingEntries(null, file2, null, entries1); + // build the hierarchy + LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, null, project); + // double-check where the entries go + assertEquals(entries1, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file1, null)); + assertEquals(entries1, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file2, null)); + assertEquals(entries1, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, project, null)); + + // set the entries for the second+third files (second file flips the settings) + provider.setSettingEntries(null, file2, null, entries2); + provider.setSettingEntries(null, file3, null, entries2); + // build the hierarchy + LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, null, project); + // check where the entries go, it should not lose entries for the first file + assertEquals(entries1, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file1, null)); + assertEquals(entries2, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file2, null)); + assertEquals(entries2, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file3, null)); + assertEquals(entries2, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, project, null)); + } + + /** + * TODO - YAGNI? + */ + public void testBuildResourceTree_WithLanguage() throws Exception { + // sample entries + CMacroEntry entry = new CMacroEntry("MACRO", null, 0); + List entries = new ArrayList(); + entries.add(entry); + + // create resources + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + IFolder folder = ResourceHelper.createFolder(project, "Folder"); + IFile file = ResourceHelper.createFile(project, "Folder/file.cpp"); + + // create a provider and set the entries + LanguageSettingsSerializableProvider provider = new LanguageSettingsSerializableProvider(PROVIDER_1, PROVIDER_NAME_1); + provider.setSettingEntries(null, file, LANG_CPP, entries); + // build the hierarchy + LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, LANG_CPP, project); + + // check that entries go to highest possible level + assertEquals(entries, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file, LANG_CPP)); + assertEquals(entries, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, folder, LANG_CPP)); + assertEquals(entries, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, project, LANG_CPP)); + } + } 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 53f77ee6fc3..b8b1bc9cd5a 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 @@ -12,7 +12,9 @@ package org.eclipse.cdt.core.language.settings.providers; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.CoreModel; @@ -47,11 +49,18 @@ public class ScannerDiscoveryLegacySupport { private static final String PREFERENCES_QUALIFIER = CCorePlugin.PLUGIN_ID; private static final String LANGUAGE_SETTINGS_PROVIDERS_NODE = "languageSettingsProviders"; //$NON-NLS-1$ + private static Map legacyProfiles = null; + + + /** + * 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); + } } /** @@ -87,8 +96,10 @@ public class ScannerDiscoveryLegacySupport { /** * Check if legacy Scanner Discovery in MBS should be active. + * @noreference This is internal helper method to support compatibility with previous versions + * which is not intended to be referenced by clients. */ - private static boolean isMbsLanguageSettingsProviderOn(ICConfigurationDescription cfgDescription) { + public static boolean isMbsLanguageSettingsProviderOn(ICConfigurationDescription cfgDescription) { if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) { List lsProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); for (ILanguageSettingsProvider lsp : lsProviders) { @@ -141,4 +152,37 @@ public class ScannerDiscoveryLegacySupport { return providers; } + /** + * Returns the values of scanner discovery profiles (scannerConfigDiscoveryProfileId) which were deprecated + * and replaced with language settings providers in plugin.xml. + * This (temporary) function serves as fail-safe switch during the transition. + * + * @param id - can be id of either org.eclipse.cdt.managedbuilder.internal.core.InputType + * or org.eclipse.cdt.managedbuilder.internal.core.ToolChain. + * @return legacy scannerConfigDiscoveryProfileId. + */ + @SuppressWarnings("nls") + public static String getDeprecatedLegacyProfiles(String id) { + if (legacyProfiles == null) { + legacyProfiles = new HashMap(); + + // InputTypes + // TODO -doublecheck +// legacyProfiles.put(inputTypeId, scannerConfigDiscoveryProfileId); + legacyProfiles.put("cdt.managedbuild.tool.gnu.c.compiler.input", "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC|org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"); + legacyProfiles.put("cdt.managedbuild.tool.gnu.cpp.compiler.input", "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP|org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"); + legacyProfiles.put("cdt.managedbuild.tool.gnu.c.compiler.input.cygwin", "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC"); + legacyProfiles.put("cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin", "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP"); + legacyProfiles.put("cdt.managedbuild.tool.xlc.c.compiler.input", "org.eclipse.cdt.managedbuilder.xlc.core.XLCManagedMakePerProjectProfile"); + legacyProfiles.put("cdt.managedbuild.tool.xlc.cpp.c.compiler.input", "org.eclipse.cdt.managedbuilder.xlc.core.XLCManagedMakePerProjectProfile"); + legacyProfiles.put("cdt.managedbuild.tool.xlc.cpp.compiler.input", "org.eclipse.cdt.managedbuilder.xlc.core.XLCManagedMakePerProjectProfileCPP"); + + // Toolchains + // TODO -doublecheck +// legacyProfiles.put(toolchainId, scannerConfigDiscoveryProfileId); + } + + return legacyProfiles.get(id); + } + } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java index 4758393d90d..16b9a000c95 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java @@ -64,6 +64,7 @@ import org.eclipse.cdt.internal.core.CharOperation; import org.eclipse.cdt.internal.core.cdtvariables.CoreVariableSubstitutor; import org.eclipse.cdt.internal.core.cdtvariables.DefaultVariableContextInfo; import org.eclipse.cdt.internal.core.cdtvariables.ICoreVariableContextInfo; +import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsLogger; import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer; import org.eclipse.cdt.internal.core.model.APathEntry; import org.eclipse.cdt.internal.core.model.CModelStatus; @@ -2016,6 +2017,9 @@ public class PathEntryTranslator { public boolean visit(PathSettingsContainer container) { CResourceData rcData = (CResourceData)container.getValue(); if (rcData != null) { + // AG FIXME - temporary log to remove before CDT Juno release + temporaryLog(cfgDescription, kinds, rcData); + PathEntryCollector child = collector.createChild(container.getPath()); for (int kind : kinds) { List list = new ArrayList(); @@ -2027,6 +2031,24 @@ public class PathEntryTranslator { } return true; } + + // AG FIXME - temporary log to remove before CDT Juno release + @Deprecated + private void temporaryLog(final ICConfigurationDescription cfgDescription, final int[] kinds, CResourceData rcData) { + String kindsStr=""; + for (int kind : kinds) { + String kstr = LanguageSettingEntriesSerializer.kindToString(kind); + if (kindsStr.length()==0) { + kindsStr = kstr; + } else { + kindsStr += "|" + kstr; + } + } + final IProject prj = cfgDescription.getProjectDescription().getProject(); + String log_msg = "path="+prj+"/"+rcData.getPath()+", kind=["+kindsStr+"]"+" (PathEntryTranslator.collectEntries())"; + LanguageSettingsLogger.logInfo(log_msg); + } + }); return collector; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsLogger.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsLogger.java new file mode 100644 index 00000000000..d5b0d6aebd6 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsLogger.java @@ -0,0 +1,79 @@ +package org.eclipse.cdt.internal.core.language.settings.providers; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * AG FIXME -Temporary class for logging language settings providers development. + * To remove before CDT Juno release + * + */ +@Deprecated +public class LanguageSettingsLogger { + private static boolean isEnabled() { + return false; +// return true; + } + + /** + * @param msg + * @noreference This method is not intended to be referenced by clients. + */ + @Deprecated + public static void logInfo(String msg) { + if (isEnabled()) { + Exception e = new Exception(msg); + IStatus status = new Status(IStatus.INFO, CCorePlugin.PLUGIN_ID, msg, e); + CCorePlugin.log(status); + } + } + + /** + * @param msg + * @noreference This method is not intended to be referenced by clients. + */ + @Deprecated + public static void logWarning(String msg) { + if (isEnabled()) { + Exception e = new Exception(msg); + IStatus status = new Status(IStatus.WARNING, CCorePlugin.PLUGIN_ID, msg, e); + CCorePlugin.log(status); + } + } + + /** + * @param msg + * @noreference This method is not intended to be referenced by clients. + */ + @Deprecated + public static void logError(String msg) { + if (isEnabled()) { + Exception e = new Exception(msg); + IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, msg, e); + CCorePlugin.log(status); + } + } + + /** + * @param rc + * @param who - pass "this" (calling class instance) here + * @noreference This method is not intended to be referenced by clients. + */ + @Deprecated + public static void logScannerInfoProvider(IResource rc, Object who) { + if (isEnabled()) { + String msg = "rc="+rc+" <-- "+who.getClass().getSimpleName(); //$NON-NLS-1$ //$NON-NLS-2$ + if (rc instanceof IFile) { + LanguageSettingsLogger.logInfo(msg); + } else if (rc instanceof IProject) { + LanguageSettingsLogger.logWarning(msg); + } else { + LanguageSettingsLogger.logError(msg); + } + } + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java index 593e4c3ba8c..2695db42248 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java @@ -28,6 +28,8 @@ import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsSerializableProvider; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsStorage; import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; +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.ICProjectDescription; @@ -498,6 +500,9 @@ public class LanguageSettingsProvidersSerializer { * @throws CoreException */ public static void serializeLanguageSettingsWorkspace() throws CoreException { + // AG FIXME - temporary log to remove before CDT Juno release + LanguageSettingsLogger.logWarning("LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace()"); + URI uriStoreWsp = getStoreInWorkspaceArea(STORAGE_WORKSPACE_LANGUAGE_SETTINGS); List serializableWorkspaceProviders = new ArrayList(); for (ILanguageSettingsProvider provider : rawGlobalWorkspaceProviders.values()) { @@ -804,6 +809,9 @@ public class LanguageSettingsProvidersSerializer { */ public static void serializeLanguageSettings(ICProjectDescription prjDescription) throws CoreException { IProject project = prjDescription.getProject(); + // AG FIXME - temporary log to remove before CDT Juno release + LanguageSettingsLogger.logWarning("LanguageSettingsProvidersSerializer.serializeLanguageSettings() for " + project); + try { // Using side effect of adding the module to the storage prjDescription.getStorage(CPROJECT_STORAGE_MODULE, true); @@ -1229,6 +1237,35 @@ public class LanguageSettingsProvidersSerializer { return provider instanceof LanguageSettingsWorkspaceProvider; } + /** + * Reports inconsistency in log. + * AG FIXME - temporary method to remove before CDT Juno release + */ + @SuppressWarnings("nls") + @Deprecated + public static void assertConsistency(ICProjectDescription prjDescription) { + if (prjDescription != null) { + List prjProviders = new ArrayList(); + for (ICConfigurationDescription cfgDescription : prjDescription.getConfigurations()) { + if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) { + List providers = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + for (ILanguageSettingsProvider provider : providers) { + if (!LanguageSettingsManager.isWorkspaceProvider(provider)) { + if (isInList(prjProviders, provider)) { + IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, "Inconsistent state, duplicate LSP in project description " + + "[" + System.identityHashCode(provider) + "] " + + provider); + CoreException e = new CoreException(status); + CCorePlugin.log(e); + } + prjProviders.add(provider); + } + } + } + } + } + } + /** * Check that this particular element is in the list. */ @@ -1320,9 +1357,13 @@ public class LanguageSettingsProvidersSerializer { */ public static void reRegisterListeners(ICProjectDescription oldPrjDescription, ICProjectDescription newPrjDescription) { if (oldPrjDescription == newPrjDescription) { + assertConsistency(oldPrjDescription); return; } + assertConsistency(oldPrjDescription); + assertConsistency(newPrjDescription); + List oldListeners = getListeners(oldPrjDescription); List newAssociations = getListenersAssociations(newPrjDescription); @@ -1389,6 +1430,9 @@ public class LanguageSettingsProvidersSerializer { * @param event - the {@link ILanguageSettingsChangeEvent} event to be broadcast. */ private static void notifyLanguageSettingsChangeListeners(ILanguageSettingsChangeEvent event) { + // AG FIXME - temporary log to remove before CDT Juno release + LanguageSettingsLogger.logWarning("Firing " + event); + for (Object listener : fLanguageSettingsChangeListeners.getListeners()) { ((ILanguageSettingsChangeListener) listener).handleEvent(event); } @@ -1592,4 +1636,109 @@ public class LanguageSettingsProvidersSerializer { return new ArrayList(newProviders); } + /** + * Check if the language is applicable for the file. + */ + private static boolean isLanguageInScope(IResource rc, ICConfigurationDescription cfgDescription, String languageId) { + if (rc instanceof IFile) { + ILanguage lang = null; + try { + lang = LanguageManager.getInstance().getLanguageForFile((IFile) rc, cfgDescription); + } catch (CoreException e) { + CCorePlugin.log("Error while determining language for a file", e); //$NON-NLS-1$ + } + if (lang == null || (languageId != null && !languageId.equals(lang.getId()))) { + return false; + } + } + return true; + } + + /** + * Builds for the provider a nicer-looking resource tree to present hierarchical view to the user. + * + * Note that it is not advisable to "compact" the tree because of potential loss of information + * which is especially important during partial or incremental builds. + * + * Note also that after using this method for a while for BOP parsers it appears that disadvantages + * outweigh benefits. In particular, it doesn't result in saving memory as the language settings + * (and the lists itself) are not duplicated in memory anyway but optimized with using WeakHashSet + * and SafeStringInterner. + * + * This method is a candidate for removal. + * + * @param provider - language settings provider to build the tree for. + * @param cfgDescription - configuration description. + * @param languageId - language ID. + * @param folder - container where the tree roots. + */ + public static void buildResourceTree(LanguageSettingsSerializableProvider provider, + ICConfigurationDescription cfgDescription, String languageId, IContainer folder) { + IResource[] members = null; + try { + members = folder.members(); + } catch (Exception e) { + CCorePlugin.log(e); + } + if (members==null) + return; + + for (IResource rc : members) { + if (rc instanceof IContainer) { + buildResourceTree(provider, cfgDescription, languageId, (IContainer) rc); + } + } + + int rcNumber = members.length; + + Map, Integer> listMap = new HashMap, Integer>(); + + // on the first pass find majority entry list, i.e. list present most often + List majorityEntries = null; + List candidate = null; + int candidateCount = 0; + for (IResource rc : members) { + if (!isLanguageInScope(rc, cfgDescription, languageId)) { + rcNumber--; + } else { + List entries = provider.getSettingEntries(null, rc, languageId); + if (entries==null && rc instanceof IContainer) { + rcNumber--; + } else { + Integer count = listMap.get(entries); + if (count==null) { + count = 0; + } + count++; + + if (count>candidateCount) { + candidateCount = count; + candidate = entries; + } + + listMap.put(entries, count); + } + } + + if (candidateCount > rcNumber/2) { + majorityEntries = candidate; + break; + } + } + + if (majorityEntries!=null) { + provider.setSettingEntries(cfgDescription, folder, languageId, majorityEntries); + } + + // second pass - assign the entries to the folders + for (IResource rc : members) { + List entries = provider.getSettingEntries(null, rc, languageId); + if (entries!=null && entries==majorityEntries) { + if (!(rc instanceof IFile)) { // preserve information which files were collected + provider.setSettingEntries(cfgDescription, rc, languageId, null); + } + } + } + } + } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java index b9d2201791b..304265ca32c 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java @@ -64,6 +64,9 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider @Override public ExtendedScannerInfo getScannerInformation(IResource rc) { + // AG FIXME - temporary log to remove before CDT Juno release + LanguageSettingsLogger.logScannerInfoProvider(rc, this); + IProject project = rc.getProject(); if (project==null) return DUMMY_SCANNER_INFO; diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/DescriptionScannerInfoProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/DescriptionScannerInfoProvider.java index f6317eb69e9..b662f38c14e 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/DescriptionScannerInfoProvider.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/DescriptionScannerInfoProvider.java @@ -35,6 +35,7 @@ import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener; import org.eclipse.cdt.core.settings.model.ICResourceDescription; import org.eclipse.cdt.core.settings.model.ICSettingBase; import org.eclipse.cdt.core.settings.model.ICSettingEntry; +import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsLogger; import org.eclipse.cdt.utils.EFSExtensionManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -77,6 +78,9 @@ public class DescriptionScannerInfoProvider implements IScannerInfoProvider, ICP @Override public IScannerInfo getScannerInformation(IResource resource) { + // AG FIXME - temporary log to remove before CDT Juno release + LanguageSettingsLogger.logScannerInfoProvider(resource, this); + if(!fInited) updateProjCfgInfo(CProjectDescriptionManager.getInstance().getProjectDescription(fProject, false)); diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml index f58003a9329..b843c0af349 100644 --- a/core/org.eclipse.cdt.core/plugin.xml +++ b/core/org.eclipse.cdt.core/plugin.xml @@ -782,5 +782,12 @@ factoryClass="org.eclipse.cdt.internal.core.resources.ResourceExclusionFactory"> + + + + diff --git a/core/org.eclipse.cdt.core/schema/LanguageSettingsProvider.exsd b/core/org.eclipse.cdt.core/schema/LanguageSettingsProvider.exsd index 9cfae19859f..8c5e164a99d 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 "true" of this attribute is meaningful only for providers ca - CDT 9.0 + CDT 8.1 diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java index 9295514553e..3ab88b851cc 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java @@ -29,8 +29,10 @@ import org.eclipse.cdt.core.model.IMacroFileEntry; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; import org.eclipse.cdt.core.parser.IScannerInfoProvider; +import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsLogger; import org.eclipse.cdt.internal.core.model.PathEntryManager; import org.eclipse.cdt.internal.core.settings.model.ScannerInfoProviderProxy; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; @@ -96,6 +98,13 @@ public class ScannerProvider extends AbstractCExtension implements IScannerInfoP */ @Override public IScannerInfo getScannerInformation(IResource resource) { + // AG FIXME - temporary log to remove before CDT Juno release + if (resource instanceof IFile) { + LanguageSettingsLogger.logInfo("rc="+resource+" (ScannerProvider.getScannerInformation())"); + } else { + LanguageSettingsLogger.logWarning("rc="+resource+" (ScannerProvider.getScannerInformation())"); + } + IPath resPath = resource.getFullPath(); try { diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/CygwinEFSExtensionProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/CygwinEFSExtensionProvider.java new file mode 100644 index 00000000000..d643c9784d7 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/CygwinEFSExtensionProvider.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2011, 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.core.resources; + +import java.net.URI; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.EFSExtensionProvider; +import org.eclipse.cdt.internal.core.Cygwin; + +public class CygwinEFSExtensionProvider extends EFSExtensionProvider { + @Override + public String getMappedPath(URI locationURI) { + String cygwinPath = getPathFromURI(locationURI); + String windowsPath = null; + try { + windowsPath = Cygwin.cygwinToWindowsPath(cygwinPath); + } catch (Exception e) { + CCorePlugin.log(e); + } + return windowsPath; + } +} diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF index ed8dab488a6..b90b6aa0a12 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 13ce11b1490..4b98a62c6ee 100644 Binary files a/core/org.eclipse.cdt.ui/icons/obj16/filesyst.gif and b/core/org.eclipse.cdt.ui/icons/obj16/filesyst.gif 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 00000000000..93368302e91 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/obj16/ls_entries.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/obj16/ls_entries_provider.gif b/core/org.eclipse.cdt.ui/icons/obj16/ls_entries_provider.gif new file mode 100644 index 00000000000..4832572f211 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/obj16/ls_entries_provider.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/obj16/provider_ls_obj.gif b/core/org.eclipse.cdt.ui/icons/obj16/provider_ls_obj.gif new file mode 100644 index 00000000000..7f3f595bc5e Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/obj16/provider_ls_obj.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/obj16/search.gif b/core/org.eclipse.cdt.ui/icons/obj16/search.gif new file mode 100644 index 00000000000..d540a01f4d9 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/obj16/search.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/cfg_ovr.gif b/core/org.eclipse.cdt.ui/icons/ovr16/cfg_ovr.gif new file mode 100644 index 00000000000..f82aa5fbb49 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/ovr16/cfg_ovr.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/edited_ov.gif b/core/org.eclipse.cdt.ui/icons/ovr16/edited_ov.gif new file mode 100644 index 00000000000..48526ac8b38 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/ovr16/edited_ov.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/empty_ovr.png b/core/org.eclipse.cdt.ui/icons/ovr16/empty_ovr.png new file mode 100644 index 00000000000..337395a0812 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/ovr16/empty_ovr.png differ diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/global_ovr.gif b/core/org.eclipse.cdt.ui/icons/ovr16/global_ovr.gif new file mode 100644 index 00000000000..2888b2eefa9 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/ovr16/global_ovr.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/import_co.gif b/core/org.eclipse.cdt.ui/icons/ovr16/import_co.gif new file mode 100644 index 00000000000..b0a24b27844 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/ovr16/import_co.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/link_ovr.gif b/core/org.eclipse.cdt.ui/icons/ovr16/link_ovr.gif new file mode 100644 index 00000000000..4f1440ebe0e Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/ovr16/link_ovr.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/lock_ovr.gif b/core/org.eclipse.cdt.ui/icons/ovr16/lock_ovr.gif new file mode 100644 index 00000000000..4499ad076d3 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/ovr16/lock_ovr.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/overlay-has-context.gif b/core/org.eclipse.cdt.ui/icons/ovr16/overlay-has-context.gif new file mode 100644 index 00000000000..c53adcf7f30 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/ovr16/overlay-has-context.gif 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 00000000000..339a6fadc92 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/ovr16/person_ovr.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/ovr16/project_co.gif b/core/org.eclipse.cdt.ui/icons/ovr16/project_co.gif new file mode 100644 index 00000000000..388f31514c4 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/ovr16/project_co.gif differ diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index f50ea9bbbe8..cf101407a8f 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -607,9 +607,11 @@ 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 +excludeCommand.name = Exclude from BuildActionDefinition.selectEnclosing.description = Expand the selection to enclosing C/C++ element ActionDefinition.selectEnclosing.name = Select Enclosing C/C++ Element ActionDefinition.selectNext.description = Expand the selection to next C/C++ element ActionDefinition.selectNext.name = Select Next C/C++ Element @@ -617,6 +619,8 @@ 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 +LanguageSettingsProviderUIExtensionPoint=Language Settings Provider UI +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 2923254b523..307d6916148 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -26,6 +26,7 @@ + @@ -3368,6 +3369,20 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This extension point defines appearance and behavior of UI controls for Language Settings Providers defined with extension point <samp>org.eclipse.cdt.core.LanguageSettingsProvider</samp>. + + + + + + + + + + This extension point is used to define appearance and behavior of Language Settings Providers in user interface. + + + + + + + + + + + + + + + + + + ID of the extension point, not used + + + + + + + Name of the extension point, not used + + + + + + + + + + + + + The definition of UI elements associated with ID of language settings provider. + + + + + + + ID of language settings provider for which appearance is being defined. + + + + + + + The path to the provider icon in the defining plugin, for example icons/obj16/picture.gif. + + + + + + + + + + Options page for the provider to appear in preferences in Providers tab. + + + + + + + + + + Defines if user is allowed to edit provider's entries in UI. + + + + + + + Defines if user is allowed to clear provider's entries in UI. For some providers like compiler specs detectors that may trigger automatic rerun. + + + + + + + + + + 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). + + + + + + + Class of language settings provider for which appearance is being defined. + + + + + + + + + + The path to the provider icon in the defining plugin, for example icons/obj16/picture.gif. + + + + + + + + + + Options page for the provider to appear in preferences in Providers tab. + + + + + + + + + + Defines if user is allowed to edit provider's entries in UI. + + + + + + + Defines if user is allowed to clear provider's entries in UI. For some providers like compiler specs detectors that may trigger automatic rerun. + + + + + + + + + + + + CDT 8.1 + + + + + + + + + For an example see definition for org.eclipse.cdt.ui.UserLanguageSettingsProvider. + + + + + + + + + [Enter API information here.] + + + + + + + + + + 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 + + + + 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 00000000000..8b71742590a --- /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. + *

+ * Note that although this class is a subclass of Composite, + * it does not make sense to add children to it, or set a layout on it. + *

+ *
+ *
Styles: + *
BORDER, READ_ONLY, FLAT
+ *
Events: + *
Selection
+ *
+ */ +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. + *

+ * The style value is either one of the style constants defined in + * class SWT which is applicable to instances of this + * class, or must be built by bitwise OR'ing together + * (that is, using the int "|" operator) two or more + * of those SWT style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + *

+ * + * @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
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • + *
+ * + * @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 + *
  • ERROR_NULL_ARGUMENT - if the string is null
  • + * + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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. + *

    + * Note: To add an item at the end of the list, use the + * result of calling getItemCount() as the + * index or use add(String). + *

    + * + * @param string the new item + * @param index the index for the item + * + * @exception IllegalArgumentException
      + *
    • ERROR_NULL_ARGUMENT - if the string is null
    • + *
    • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list (inclusive)
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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 ModifyListener + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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 SelectionListener + * interface. + *

    + * widgetSelected is called when the combo's list selection changes. + * widgetDefaultSelected is typically called when ENTER is pressed the combo's text area. + *

    + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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. + *

    + * Note: To clear the selected items in the receiver's list, + * use deselectAll(). + *

    + * + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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 + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + * + */ +public void deselect (int index) { + checkWidget (); + table.deselect (index); +} +/** + * Deselects all selected items in the receiver's list. + *

    + * Note: To clear the selection in the receiver's text field, + * use clearSelection(). + *

    + * + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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
      + *
    • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +public int getItemCount () { + checkWidget (); + return table.getItemCount (); +} +/** + * Returns the height of the area which would be used to + * display one of the items in the receiver's list. + * + * @return the height of one item + * + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +public int getItemHeight () { + checkWidget (); + return table.getItemHeight (); +} +/** + * Returns an array of Strings which are the items + * in the receiver's list. + *

    + * 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. + *

    + * + * @return the items in the receiver's list + * + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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 Point 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
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +public String getText () { + checkWidget (); + return text.getText (); +} +/** + * Returns the height of the receivers's text field. + * + * @return the text height + * + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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 setTextLimit(), it will be the constant + * Combo.LIMIT. + * + * @return the text limit + * + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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
      + *
    • ERROR_NULL_ARGUMENT - if the string is null
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_INVALID_RANGE - if either the start or end are not between 0 and the number of elements in the list minus 1 (inclusive)
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_NULL_ARGUMENT - if the string is null
    • + *
    • ERROR_INVALID_ARGUMENT - if the string is not found in the list
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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. + *

    + * @exception SWTException

      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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 remove'ing the old item at the index, and then + * add'ing the new item at that index. + * + * @param index the index for the item + * @param string the new text for the item + * + * @exception IllegalArgumentException
      + *
    • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
    • + *
    • ERROR_NULL_ARGUMENT - if the string is null
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_NULL_ARGUMENT - if the items array is null
    • + *
    • ERROR_INVALID_ARGUMENT - if an item in the items array is null
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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. + *

    + * Note : No Layout can be set on this Control because it already + * manages the size and position of its children. + *

    + * + * @param layout the receiver's new layout or null + * + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_NULL_ARGUMENT - if the point is null
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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. + *

    + * Note: The text field in a Combo 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. + *

    + * + * @param string the new text + * + * @exception IllegalArgumentException
      + *
    • ERROR_NULL_ARGUMENT - if the string is null
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_CANNOT_BE_ZERO - if the limit is zero
    • + *
    + * @exception SWTException
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ +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
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @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 00000000000..c60196a13eb --- /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_ProjectRelative, + 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 00000000000..fa4b78ce773 --- /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> initialProvidersMap = new HashMap>(); + + /** + * 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 entries = getSettingEntries(provider); + if (entries == null && !(rc instanceof IProject)) { + List 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 entriesParent = provider.getSettingEntries(null, null, currentLanguageId); + if (entries != null && !entries.equals(entriesParent)) { + overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_SETTING; + } + } + } + + ICConfigurationDescription cfgDescription = getConfigurationDescription(); + List 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 entriesList = getSettingEntriesUpResourceTree(lsProvider); + if (entriesList == null) { + return null; + } + + // convert to modifiable list + entriesList = new ArrayList(entriesList); + + if (builtInCheckBox.getSelection() == false) { + for (Iterator 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 getSettingEntriesUpResourceTree(ILanguageSettingsProvider provider) { + if (currentLanguageId == null) + return null; + + ICConfigurationDescription cfgDescription = getConfigurationDescription(); + IResource rc = getResource(); + List 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 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 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.CDTMainWizardPage_TrySD90, 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 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 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 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 entries) { + if (provider instanceof ILanguageSettingsEditableProvider) { + ICConfigurationDescription cfgDescription = getConfigurationDescription(); + IResource rc = getResource(); + if (entries != null && rc != null) { + List parentEntries = null; + if (rc instanceof IProject) { + parentEntries = new ArrayList(); + } 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 getEntriesShownToUser(ILanguageSettingsProvider provider) { + ICConfigurationDescription cfgDescription = getConfigurationDescription(); + IResource rc = getResource(); + List entries = provider.getSettingEntries(cfgDescription, rc, currentLanguageId); + if (entries == null) { + entries = getSettingEntriesUpResourceTree(provider); + } + entries = new ArrayList(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 initialProviders = initialProvidersMap.get(cfgDescription.getId()); + if (initialProviders.contains(provider)) { + List providers = new ArrayList(((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 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 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 empty = new ArrayList(); + 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 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 getProviders(String languageSettingId) { + List itemsList = new LinkedList(); + if (currentLanguageId != null) { + IResource rc = getResource(); + ICConfigurationDescription cfgDescription = getConfigurationDescription(); + if (rc != null && cfgDescription instanceof ILanguageSettingsProvidersKeeper) { + List 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 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 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 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 oldProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders(); + List newProviders = new ArrayList(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 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 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 00000000000..7cb5c087873 --- /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 loadedIcons = new ArrayList(); + private static Map fImagesUrlById = new HashMap(); + private static Map fImagesUrlByClass = new HashMap(); + private static List fRegirestedIds = new ArrayList(); + private static List fRegisteredClasses = new ArrayList(); + + private static Map> fAssociationsById = new HashMap>(); + private static Map> fAssociationsByClass = new HashMap>(); + + /** + * 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 properties = new HashMap(); + 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 properties = new HashMap(); + 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 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 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 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 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 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 00000000000..1c2a0101b13 --- /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 presentedProviders = null; + private final Map optionsPageMap = new HashMap(); + private Map> initialProvidersByCfg = new HashMap>(); + + /** + * 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 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 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 initialProviders = initialProvidersByCfg.get(cfgDescription.getId()); + List 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 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 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 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 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("{0}", 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.CDTMainWizardPage_TrySD90, 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 providers) { + // ensure sorting by name all unchecked providers + Collections.sort(providers, new Comparator() { + @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 idsList = new ArrayList(); + + List providers; + ICConfigurationDescription cfgDescription = getConfigurationDescription(); + if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) { + providers = new ArrayList(((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders()); + for (ILanguageSettingsProvider provider : providers) { + idsList.add(provider.getId()); + } + } else { + providers = new ArrayList(); + } + + List 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 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 cfgProviders = new ArrayList(((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders()); + String[] defaultIds = ((ILanguageSettingsProvidersKeeper) cfgDescription).getDefaultLanguageSettingsProvidersIds(); + + List newProviders = new ArrayList(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(); + 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 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 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 00000000000..e93bae0f8d3 --- /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 00000000000..84f5d735386 --- /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 2f96922703a..7e26e3a295c 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 c6f86743b89..1f5e16eddd7 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 @@ -84,6 +84,7 @@ public class Messages extends NLS { public static String CDTCommonProjectWizard_creatingProject; public static String CDTMainWizardPage_0; public static String CDTMainWizardPage_1; + public static String CDTMainWizardPage_TrySD90; public static String CLocationOutputTab_0; public static String CLocationSourceTab_0; public static String CLocationTab_0; @@ -138,7 +139,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 +174,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 +188,42 @@ 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_ProjectRelative; + 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 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 8da3b3582fc..284f752f134 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,42 @@ 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 (Ignore during build) +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_ProjectRelative=Project-Relative +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. +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 +240,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 @@ -272,8 +304,11 @@ StringVariableSelectionDialog_message=&Choose a variable (? = any character, * = StringVariableSelectionDialog_columnDescription=&Variable Description: CDTMainWizardPage_0=Project name cannot contain '\#' symbol CDTMainWizardPage_1=Project category is selected. Expand the category and select a concrete project type. +CDTMainWizardPage_TrySD90=I want to try new upcoming version of Scanner Discovery in CDT 9.0 (sd90 v.0.9.0) 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 4176c89f54e..f6c933f455d 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 } } + public 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 list = provider.getSettingEntries(cfgDescription, rc, languageId); + if (list!=null) { + List 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 adf97abc88d..ab44e87cc30 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 @@ -210,6 +210,39 @@ public class CDTSharedImages { public static final String IMG_VIEW_PIN_ACTION_B = "icons/obj16/toolbar_pinned_b.gif"; //$NON-NLS-1$ public static final String IMG_VIEW_PIN_ACTION_MULTI = "icons/obj16/toolbar_pinned_multi.gif"; //$NON-NLS-1$ + // Language Settings Images + /** @since 5.4 */ + public static final String IMG_OBJS_LANG_SETTINGS_PROVIDER = "icons/obj16/ls_entries_provider.gif"; //$NON-NLS-1$ + /** @since 5.4 */ + public static final String IMG_ETOOL_PROJECT = "icons/etool16/prj_obj.gif"; //$NON-NLS-1$ + + /** @since 5.4 */ + public static final String IMG_OVR_GLOBAL = "icons/ovr16/global_ovr.gif"; //$NON-NLS-1$ + /** @since 5.4 */ + public static final String IMG_OVR_IMPORT = "icons/ovr16/import_co.gif"; //$NON-NLS-1$ + /** @since 5.4 */ + public static final String IMG_OVR_LINK = "icons/ovr16/link_ovr.gif"; //$NON-NLS-1$ + /** @since 5.4 */ + public static final String IMG_OVR_CONFIGURATION = "icons/ovr16/cfg_ovr.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_INDEXED = "icons/ovr16/indexedFile.gif"; //$NON-NLS-1$ + /** @since 5.4 */ + public static final String IMG_OVR_REFERENCE = "icons/ovr16/referencedby_co.gif"; //$NON-NLS-1$ + /** @since 5.4 */ + public static final String IMG_OVR_PROJECT = "icons/ovr16/project_co.gif"; //$NON-NLS-1$ + /** @since 5.4 */ + public static final String IMG_OVR_CONTEXT = "icons/ovr16/overlay-has-context.gif"; //$NON-NLS-1$ + /** @since 5.4 */ + public static final String IMG_OVR_LOCK = "icons/ovr16/lock_ovr.gif"; //$NON-NLS-1$ + /** @since 5.4 */ + public static final String IMG_OVR_EDITED = "icons/ovr16/edited_ov.gif"; //$NON-NLS-1$ + /** @since 5.4 */ + public static final String IMG_OVR_EMPTY = "icons/ovr16/empty_ovr.png"; //$NON-NLS-1$ + /** @since 5.4 */ + public static final String IMG_OVR_USER = "icons/ovr16/person_ovr.gif"; //$NON-NLS-1$ + /** * The method finds URL of the image corresponding to the key which could be project-relative path * of the image in org.eclipse.cdt.ui plugin or a (previously registered) string representation of URL 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 00000000000..13871ccfa8c --- /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 00000000000..7317e6e8c4c --- /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 aaa8b02edf1..ddd9791406d 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
    @@ -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 * true 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 63e0fe4ec34..637b944fa27 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 fe692d14e27..c8e9e891a81 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; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/PropertyTester.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/PropertyTester.java index 120caaebc72..cd2775223d5 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/PropertyTester.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/PropertyTester.java @@ -10,39 +10,63 @@ *******************************************************************************/ package org.eclipse.cdt.ui.newui; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.osgi.service.prefs.BackingStoreException; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.ui.CUIPlugin; /** - * Checks whether given object is a source file. + * Property tester to test expressions in plugin.xml. Tests following expressions: + * 1. Checks whether given object is a source file. Usage: + * + * 2. Checks value of a preference. Usage: + * + * * @noextend This class is not intended to be subclassed by clients. */ public class PropertyTester extends org.eclipse.core.expressions.PropertyTester { - private static final String KEY_SRC = "isSource"; //$NON-NLS-1$ - private static final String KEY_PAGE = "pageEnabled"; //$NON-NLS-1$ - private static final String VAL_EXP = "export"; //$NON-NLS-1$ - private static final String VAL_TOOL = "toolEdit"; //$NON-NLS-1$ + private static final String KEY_SRC = "isSource"; //$NON-NLS-1$ + private static final String KEY_PREF = "checkPreference"; //$NON-NLS-1$ @Override - public boolean test(Object receiver, String property, Object[] args, - Object expectedValue) { + public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { if (KEY_SRC.equals(property)) { if (receiver instanceof ITranslationUnit) { - return ((ITranslationUnit)receiver).isSourceUnit(); - } - else if (receiver instanceof IFile) { - IFile file = (IFile)receiver; + return ((ITranslationUnit) receiver).isSourceUnit(); + } else if (receiver instanceof IFile) { + IFile file = (IFile) receiver; return CoreModel.isValidSourceUnitName(file.getProject(), file.getName()); } - } else if (KEY_PAGE.equals(property) - && expectedValue instanceof String) { - String s = (String) expectedValue; - if (VAL_EXP.equalsIgnoreCase(s)) - return CDTPrefUtil.getBool(CDTPrefUtil.KEY_EXPORT); - if (VAL_TOOL.equalsIgnoreCase(s)) - return !CDTPrefUtil.getBool(CDTPrefUtil.KEY_NOTOOLM); + } else if (KEY_PREF.equals(property) && expectedValue instanceof String) { + boolean result = false; + final Pattern pat = Pattern.compile("(.*):(.*)=(.*)"); //$NON-NLS-1$ + Matcher matcher = pat.matcher((String) expectedValue); + if (matcher.matches()) { + String pluginId = matcher.group(1); + String preference = matcher.group(2); + String wantedValue = matcher.group(3); + + IEclipsePreferences node = InstanceScope.INSTANCE.getNode(pluginId); + if (wantedValue != null) { + String actualValue = node.get(preference, ""); //$NON-NLS-1$ + result = wantedValue.equals(actualValue) || (wantedValue.equals("false") && actualValue.isEmpty()); //$NON-NLS-1$ + } else { + try { + result = Arrays.asList(node.keys()).contains(preference); + } catch (BackingStoreException e) { + CUIPlugin.log(e); + } + } + } + return result; } return false; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/CDTMainWizardPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/CDTMainWizardPage.java index bcdd3864dbf..f69606cbaf9 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/CDTMainWizardPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/CDTMainWizardPage.java @@ -50,6 +50,7 @@ import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.newui.CDTPrefUtil; import org.eclipse.cdt.ui.newui.PageLayout; +import org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProvidersPage; import org.eclipse.cdt.internal.ui.newui.Messages; public class CDTMainWizardPage extends WizardNewProjectCreationPage implements IWizardItemsListListener { @@ -67,6 +68,7 @@ import org.eclipse.cdt.internal.ui.newui.Messages; private Tree tree; private Composite right; private Button show_sup; + private Button checkBoxTryNewSD; private Label right_label; public CWizardHandler h_selected = null; @@ -154,6 +156,20 @@ import org.eclipse.cdt.internal.ui.newui.Messages; // restore settings from preferences show_sup.setSelection(!CDTPrefUtil.getBool(CDTPrefUtil.KEY_NOSUPP)); + + checkBoxTryNewSD = new Button(c, SWT.CHECK); + checkBoxTryNewSD.setText(Messages.CDTMainWizardPage_TrySD90); + /* GridData */gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 2; + checkBoxTryNewSD.setLayoutData(gd); + + // restore settings from preferences + boolean isTryNewSD = true; + boolean contains = CUIPlugin.getDefault().getPreferenceStore().contains(LanguageSettingsProvidersPage.KEY_NEWSD); + if (contains) { + isTryNewSD = CDTPrefUtil.getBool(LanguageSettingsProvidersPage.KEY_NEWSD); + } + checkBoxTryNewSD.setSelection(isTryNewSD); } @Override @@ -481,5 +497,13 @@ import org.eclipse.cdt.internal.ui.newui.Messages; public List filterItems(List items) { return items; } + + /** + * AG FIXME - remove before CDT Juno release. + * @since 5.4 + */ + public boolean isTryingNewSD() { + return checkBoxTryNewSD.getSelection(); + } } diff --git a/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/plugin.xml b/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/plugin.xml index f6c2ea28a99..4a98554cb60 100644 --- a/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/plugin.xml +++ b/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/plugin.xml @@ -522,18 +522,19 @@ name="%TargetName.xlc.exe" projectMacroSupplier="org.eclipse.cdt.managedbuilder.xlc.ui.XLCProjectMacroSupplier"> + artifactExtension="exe" + cleanCommand="rm -rf" + errorParsers="org.eclipse.cdt.errorparsers.xlc.XlcErrorParser" + id="cdt.managedbuild.config.xlc.exe.debug" + languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.managedbuilder.xlc.core.XlcBuildCommandParser" + name="%ConfigName.Dbg"> + name="%ConfigName.Rel" + artifactExtension="exe" + cleanCommand="rm -rf" + errorParsers="org.eclipse.cdt.errorparsers.xlc.XlcErrorParser" + languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.managedbuilder.xlc.core.XlcBuildCommandParser" + id="cdt.managedbuild.config.xlc.exe.release"> + name="%ConfigName.Dbg" + cleanCommand="rm -rf" + artifactExtension="so" + errorParsers="org.eclipse.cdt.errorparsers.xlc.XlcErrorParser" + languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.managedbuilder.xlc.core.XlcBuildCommandParser" + id="cdt.managedbuild.config.xlc.so.debug"> + id="cdt.managedbuild.toolchain.xlc.so.debug" + languageSettingsProviders="org.eclipse.cdt.managedbuilder.xlc.core.XlcBuildCommandParser;org.eclipse.cdt.managedbuilder.xlc.core.XlcBuiltinSpecsDetector" + name="%ToolChainName.Dbg" + targetTool="cdt.managedbuild.tool.xlc.c.linker.so.debug;cdt.managedbuild.tool.xlc.cpp.linker.so.debug"> + name="%ConfigName.Rel" + cleanCommand="rm -rf" + artifactExtension="so" + errorParsers="org.eclipse.cdt.errorparsers.xlc.XlcErrorParser" + languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.managedbuilder.xlc.core.XlcBuildCommandParser" + id="cdt.managedbuild.config.xlc.so.release"> + id="cdt.managedbuild.toolchain.xlc.so.release" + languageSettingsProviders="org.eclipse.cdt.managedbuilder.xlc.core.XlcBuildCommandParser;org.eclipse.cdt.managedbuilder.xlc.core.XlcBuiltinSpecsDetector" + name="%ToolChainName.Rel" + targetTool="cdt.managedbuild.tool.xlc.c.linker.so.release;cdt.managedbuild.tool.xlc.cpp.linker.so.release"> + name="%ConfigName.Dbg" + cleanCommand="rm -rf" + artifactExtension="lib" + errorParsers="org.eclipse.cdt.errorparsers.xlc.XlcErrorParser" + languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.managedbuilder.xlc.core.XlcBuildCommandParser" + id="cdt.managedbuild.config.xlc.lib.debug"> + id="cdt.managedbuild.toolchain.xlc.lib.debug" + languageSettingsProviders="org.eclipse.cdt.managedbuilder.xlc.core.XlcBuildCommandParser;org.eclipse.cdt.managedbuilder.xlc.core.XlcBuiltinSpecsDetector" + name="%ToolChainName.Dbg" + targetTool="cdt.managedbuild.tool.xlc.archiver.lib.debug"> + name="%ConfigName.Rel" + cleanCommand="rm -rf" + artifactExtension="lib" + errorParsers="org.eclipse.cdt.errorparsers.xlc.XlcErrorParser" + languageSettingsProviders="org.eclipse.cdt.ui.UserLanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.managedbuilder.xlc.core.XlcBuildCommandParser" + id="cdt.managedbuild.config.xlc.lib.release"> + id="cdt.managedbuild.toolchain.xlc.lib.release" + languageSettingsProviders="org.eclipse.cdt.managedbuilder.xlc.core.XlcBuildCommandParser;org.eclipse.cdt.managedbuilder.xlc.core.XlcBuiltinSpecsDetector" + name="%ToolChainName.Rel" + targetTool="cdt.managedbuild.tool.xlc.archiver.lib.release"> @@ -3753,7 +3762,6 @@ id="cdt.managedbuild.tool.xlc.cpp.c.compiler.input" name="%inputType.c.name.2" primaryInput="true" - scannerConfigDiscoveryProfileId="org.eclipse.cdt.managedbuilder.xlc.core.XLCManagedMakePerProjectProfile" sourceContentType="org.eclipse.cdt.core.cSource" sources="c"> @@ -3763,7 +3771,6 @@ id="cdt.managedbuild.tool.xlc.cpp.compiler.input" name="%inputType.cpp.name" primaryInput="true" - scannerConfigDiscoveryProfileId="org.eclipse.cdt.managedbuilder.xlc.core.XLCManagedMakePerProjectProfileCPP" sourceContentType="org.eclipse.cdt.core.cxxSource" sources="c,C,cc,cxx,cpp">