From 433174325efeedeb93014425aa7144c67fcb9348 Mon Sep 17 00:00:00 2001 From: Mike Kucera Date: Tue, 12 Aug 2008 18:29:20 +0000 Subject: [PATCH] project settings import/export wizards, bug 242010 --- .../eclipse/cdt/ui/tests/AutomatedSuite.java | 4 + .../ProjectSettingsWizardPageMock.java | 71 +++ .../SettingsImportExportTest.java | 285 ++++++++++++ .../SettingsWizardTestSuite.java | 25 ++ core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF | 1 + core/org.eclipse.cdt.ui/plugin.properties | 3 + core/org.eclipse.cdt.ui/plugin.xml | 35 +- .../IProjectSettingsWizardPage.java | 61 +++ .../IProjectSettingsWizardPageStrategy.java | 54 +++ .../settingswizards/ISettingsProcessor.java | 76 ++++ .../IncludePathsSettingsProcessor.java | 94 ++++ .../MacroSettingsProcessor.java | 143 ++++++ .../ui/wizards/settingswizards/Messages.java | 75 ++++ .../ProjectSettingsExportStrategy.java | 177 ++++++++ .../ProjectSettingsExportWizard.java | 32 ++ .../ProjectSettingsImportStrategy.java | 239 ++++++++++ .../ProjectSettingsImportWizard.java | 31 ++ .../ProjectSettingsWizard.java | 51 +++ .../ProjectSettingsWizardPage.java | 422 ++++++++++++++++++ .../SettingsImportExportException.java | 30 ++ .../settingswizards/SettingsProcessor.java | 112 +++++ .../ui/wizards/settingswizards/XMLUtils.java | 67 +++ .../settingswizards/messages.properties | 44 ++ .../plugin.properties | 1 - debug/org.eclipse.cdt.debug.ui/plugin.xml | 5 +- 25 files changed, 2129 insertions(+), 9 deletions(-) create mode 100644 core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/ProjectSettingsWizardPageMock.java create mode 100644 core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsImportExportTest.java create mode 100644 core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsWizardTestSuite.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IProjectSettingsWizardPage.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IProjectSettingsWizardPageStrategy.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ISettingsProcessor.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IncludePathsSettingsProcessor.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/MacroSettingsProcessor.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/Messages.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsExportStrategy.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsExportWizard.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsImportStrategy.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsImportWizard.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsWizard.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsWizardPage.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/SettingsImportExportException.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/SettingsProcessor.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/XMLUtils.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/messages.properties diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java index b52bf682b44..26869e31473 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java @@ -28,6 +28,7 @@ import org.eclipse.cdt.ui.tests.text.contentassist2.ContentAssist2TestSuite; import org.eclipse.cdt.ui.tests.text.selection.SelectionTestSuite; import org.eclipse.cdt.ui.tests.typehierarchy.TypeHierarchyTestSuite; import org.eclipse.cdt.ui.tests.viewsupport.ViewSupportTestSuite; +import org.eclipse.cdt.ui.tests.wizards.settingswizards.SettingsWizardTestSuite; /** * Test all areas of the UI. @@ -85,6 +86,9 @@ public class AutomatedSuite extends TestSuite { // tests from package org.eclipse.cdt.ui.tests.chelp addTest(CHelpTest.suite()); + + // tests from package org.eclipse.cdt.ui.tests.wizards.settingswizards + addTest(SettingsWizardTestSuite.suite()); } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/ProjectSettingsWizardPageMock.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/ProjectSettingsWizardPageMock.java new file mode 100644 index 00000000000..ee8d70a1828 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/ProjectSettingsWizardPageMock.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.wizards.settingswizards; + +import java.util.List; + +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; + +import org.eclipse.cdt.internal.ui.wizards.settingswizards.IProjectSettingsWizardPage; +import org.eclipse.cdt.internal.ui.wizards.settingswizards.ISettingsProcessor; + +public class ProjectSettingsWizardPageMock implements IProjectSettingsWizardPage { + + private String path; + private List selectedSettingsProcessors; + private ICConfigurationDescription selectedConfiguration; + private List settingsProcessors; + + public void setDestinationFilePath(String path) { + this.path = path; + } + + public String getDestinationFilePath() { + return path; + } + + public void setSelectedConfiguration(ICConfigurationDescription config) { + this.selectedConfiguration = config; + } + + public ICConfigurationDescription getSelectedConfiguration() { + return selectedConfiguration; + } + + public void setSelectedSettingsProcessors(List processors) { + this.selectedSettingsProcessors = processors; + } + + public List getSelectedSettingsProcessors() { + return selectedSettingsProcessors; + } + + public void setSettingsProcessors(List processors) { + this.settingsProcessors = processors; + } + + public List getSettingsProcessors() { + return settingsProcessors; + } + + public void setDisplayedSettingsProcessors( List processors) { + // do nothing + } + + public void setMessage(String message, int flag) { + // do nothing + } + + public void showErrorDialog(String dialogTitle, String message) { + // do nothing + } + +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsImportExportTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsImportExportTest.java new file mode 100644 index 00000000000..f7487c68015 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsImportExportTest.java @@ -0,0 +1,285 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.wizards.settingswizards; + +import java.io.FileWriter; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.dialogs.IMessageProvider; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +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.ICFolderDescription; +import org.eclipse.cdt.core.settings.model.ICLanguageSetting; +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.testplugin.CProjectHelper; +import org.eclipse.cdt.ui.tests.BaseUITestCase; + +import org.eclipse.cdt.internal.ui.wizards.settingswizards.ISettingsProcessor; +import org.eclipse.cdt.internal.ui.wizards.settingswizards.IncludePathsSettingsProcessor; +import org.eclipse.cdt.internal.ui.wizards.settingswizards.MacroSettingsProcessor; +import org.eclipse.cdt.internal.ui.wizards.settingswizards.ProjectSettingsExportStrategy; +import org.eclipse.cdt.internal.ui.wizards.settingswizards.ProjectSettingsImportStrategy; + +public class SettingsImportExportTest extends BaseUITestCase { + + private static ICLanguageSettingEntry[] EXPORTED_MACROS = new ICLanguageSettingEntry[] { + new CMacroEntry("MAC1", "value1", 0), + new CMacroEntry("anothermacro", "", 0), + new CMacroEntry("smac", "blah", 0) + }; + + private static ICLanguageSettingEntry[] EXPORTED_INCLUDES = new ICLanguageSettingEntry[] { + new CIncludePathEntry("/path/to/somewhere", 0), + new CIncludePathEntry("/blah/blah/blah", 0), + new CIncludePathEntry("pantera/is/awesome", 0) + }; + + + + public SettingsImportExportTest() {} + + public SettingsImportExportTest(String name) { + super(name); + } + + + + // This could be replaced with an extension point + private static final List processors = Arrays.asList( + new IncludePathsSettingsProcessor(), + new MacroSettingsProcessor() + ); + + + private static void createFile(String contents, String filePath) throws Exception { + IPath path = new Path(filePath); + FileWriter writer = new FileWriter(path.toFile()); + writer.write(contents); + writer.close(); + } + + private static void deleteFile(String filePath) { + new Path(filePath).toFile().delete(); + } + + private static String getFilePath(String fileName) { + IPath workspaceLocation = ResourcesPlugin.getWorkspace().getRoot().getLocation(); + return workspaceLocation.toOSString() + Path.SEPARATOR + fileName; + } + + + private void setUpProjectSettings(ICProject cProject) throws Exception { + IProject project = cProject.getProject(); + ICProjectDescription desc = CoreModel.getDefault().getProjectDescription(project, true); + ICConfigurationDescription config = desc.getActiveConfiguration(); + ICFolderDescription folder = config.getRootFolderDescription(); + ICLanguageSetting[] languageSettings = folder.getLanguageSettings(); + ICLanguageSetting languageSetting = languageSettings[0]; + languageSetting.setSettingEntries(ICSettingEntry.MACRO, Arrays.asList(EXPORTED_MACROS)); + languageSetting.setSettingEntries(ICSettingEntry.INCLUDE_PATH, EXPORTED_INCLUDES); + CoreModel.getDefault().setProjectDescription(project, desc); + } + + + public void testNormalExportImport() throws Exception { + ICProject exportProject = CProjectHelper.createCCProject("TempProject1", "unused"); + ICProject importProject = CProjectHelper.createCCProject("TempProject2", "unused"); + setUpProjectSettings(exportProject); + + ProjectSettingsWizardPageMock page = new ProjectSettingsWizardPageMock() { + @Override public void setMessage(String message, int flag) { + if(flag == IMessageProvider.ERROR) + fail("there should be no error message displayed"); + } + @Override public void showErrorDialog(String dialogTitle, String message) { + fail("the error dialog should not be displayed"); + } + }; + + page.setDestinationFilePath(getFilePath("settings.xml")); + page.setSettingsProcessors(processors); + page.setSelectedSettingsProcessors(processors); + ICProjectDescription desc = CoreModel.getDefault().getProjectDescription(exportProject.getProject(), false); + ICConfigurationDescription config = desc.getActiveConfiguration(); + page.setSelectedConfiguration(config); + + ProjectSettingsExportStrategy exporter = new ProjectSettingsExportStrategy(); + exporter.finish(page); + + + // now import into another project + + desc = CoreModel.getDefault().getProjectDescription(importProject.getProject(), true); + config = desc.getActiveConfiguration(); + page.setSelectedConfiguration(config); + + ProjectSettingsImportStrategy importer = new ProjectSettingsImportStrategy(); + importer.finish(page); + + desc = CoreModel.getDefault().getProjectDescription(importProject.getProject(), true); + config = desc.getActiveConfiguration(); + ICFolderDescription folder = config.getRootFolderDescription(); + ICLanguageSetting languageSetting = folder.getLanguageSettings()[0]; + + ICLanguageSettingEntry[] importedMacros = languageSetting.getSettingEntries(ICSettingEntry.MACRO); + + assertEquals(EXPORTED_MACROS.length, importedMacros.length); + for(int i = 0; i < importedMacros.length; i++) { + assertEquals(EXPORTED_MACROS[i].getName(), importedMacros[i].getName()); + assertEquals(EXPORTED_MACROS[i].getValue(), importedMacros[i].getValue()); + } + + ICLanguageSettingEntry[] importedIncludes = languageSetting.getSettingEntries(ICSettingEntry.INCLUDE_PATH); + + assertEquals(EXPORTED_INCLUDES.length, importedIncludes.length); + for(int i = 0; i < importedIncludes.length; i++) { + assertTrue(importedIncludes[i].getName().endsWith(EXPORTED_INCLUDES[i].getName())); + } + + CProjectHelper.delete(importProject); + CProjectHelper.delete(exportProject); + } + + + public static void vaidateCorrectErrorHandling(String xmlContent) throws Exception { + String filePath = getFilePath("test.txt"); + createFile(xmlContent, filePath); + + ICProject project = CProjectHelper.createCCProject("VaidateProject", "unused"); + + ICProjectDescription desc = CoreModel.getDefault().getProjectDescription(project.getProject(), false); + ICConfigurationDescription config = desc.getActiveConfiguration(); + + final boolean[] errorDialogShown = new boolean[] {false}; + ProjectSettingsWizardPageMock page = new ProjectSettingsWizardPageMock() { + @Override public void setMessage(String message, int flag) { + fail(); + } + @Override public void showErrorDialog(String dialogTitle, String message) { + errorDialogShown[0] = true; + } + }; + page.setDestinationFilePath(filePath); + page.setSettingsProcessors(processors); + page.setSelectedSettingsProcessors(processors); + page.setSelectedConfiguration(config); + + + ProjectSettingsImportStrategy importer = new ProjectSettingsImportStrategy(); + importer.finish(page); + + assertTrue(xmlContent, errorDialogShown[0]); + + assertNoSettingsImported(project.getProject()); + + // TODO test that no macros or includes were imported + CProjectHelper.delete(project); + deleteFile(filePath); + } + + private static void assertNoSettingsImported(IProject project) { + ICProjectDescription desc = CoreModel.getDefault().getProjectDescription(project, true); + ICConfigurationDescription config = desc.getActiveConfiguration(); + ICFolderDescription folder = config.getRootFolderDescription(); + ICLanguageSetting[] languageSettings = folder.getLanguageSettings(); + for(ICLanguageSetting languageSetting : languageSettings) { + ICLanguageSettingEntry[] entries = languageSetting.getSettingEntries(ICSettingEntry.MACRO); + for(ICLanguageSettingEntry entry : entries) { + assertTrue(entry.isBuiltIn()); + } + entries = languageSetting.getSettingEntries(ICSettingEntry.INCLUDE_PATH); + for(ICLanguageSettingEntry entry : entries) { + assertTrue(entry.isBuiltIn()); + } + } + } + + // {badXML1} + // blah blah blah + // + // {badXML2} + // + // + // {badXML3} + // + //
+ //
+ //
+ // + // {badXML4} + // + //
+ // + // + //
+ //
+ // + // {badXML5} + // + //
+ // + // aaaa + // + //
+ //
+ // + // {badXML6} + // + //
+ // + // + // aaaa + // + // + //
+ //
+ // + // {badXML7} + // + //
+ // + // + // aaaa + // + // + //
+ //
+ // + // {badXML8} + // + //
+ // + // C:\WINDOWS + // + //
+ //
+ public void testNotValid() throws Exception { + vaidateCorrectErrorHandling(readTaggedComment("badXML1")); + vaidateCorrectErrorHandling(readTaggedComment("badXML2")); + vaidateCorrectErrorHandling(readTaggedComment("badXML3")); + vaidateCorrectErrorHandling(readTaggedComment("badXML4")); + vaidateCorrectErrorHandling(readTaggedComment("badXML5")); // missing tag + vaidateCorrectErrorHandling(readTaggedComment("badXML6")); // missing tag + vaidateCorrectErrorHandling(readTaggedComment("badXML7")); // extra tag + vaidateCorrectErrorHandling(readTaggedComment("badXML8")); + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsWizardTestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsWizardTestSuite.java new file mode 100644 index 00000000000..29d30a359df --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/wizards/settingswizards/SettingsWizardTestSuite.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.wizards.settingswizards; + +import junit.framework.TestSuite; + +public class SettingsWizardTestSuite extends TestSuite { + + public static TestSuite suite() { + return new SettingsWizardTestSuite(); + } + + public SettingsWizardTestSuite() { + super(SettingsWizardTestSuite.class.getName()); + addTestSuite(SettingsImportExportTest.class); + } +} diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF index 853e3b077f3..b65e1fcf0f9 100644 --- a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF @@ -57,6 +57,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true, org.eclipse.cdt.internal.ui.wizards.dialogfields;x-internal:=true, org.eclipse.cdt.internal.ui.wizards.filewizard;x-internal:=true, org.eclipse.cdt.internal.ui.wizards.folderwizard;x-internal:=true, + org.eclipse.cdt.internal.ui.wizards.settingswizards, org.eclipse.cdt.internal.ui.workingsets;x-internal:=true, org.eclipse.cdt.ui, org.eclipse.cdt.ui.actions, diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index 1c2e70abdae..6cee9a42112 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -462,6 +462,9 @@ teamProjectIndexExportWizard.name = Team Shared Index teamProjectIndexExportWizard.description = Exports C/C++ index for use in other workspaces. exportWizard.CDTCategory.name = C/C++ +projectSettingsIndexExportWizard.name = C/C++ Project Settings +importWizard.CDTCategory.name = C/C++ + page.c.general=C/C++ General # menu labels Configurations.menu=Build Configurations diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index d13db6815f9..d94ecf6ca71 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -2841,6 +2841,10 @@ + + - - + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IProjectSettingsWizardPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IProjectSettingsWizardPage.java new file mode 100644 index 00000000000..798daa818c1 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IProjectSettingsWizardPage.java @@ -0,0 +1,61 @@ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +import java.util.List; + +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; + +/** + * Defines the methods that the strategies can call on the + * wizard page. + * + * This interface exists mainly so that it can be implemented by a + * mock object, which makes testing the strategies easy. + * + * @author Mike Kucera + */ +public interface IProjectSettingsWizardPage { + + static final String FILENAME_EXTENSION = "xml"; //$NON-NLS-1$ + + + /** + * Sets the input list for the displayed list of settings processors. + */ + void setDisplayedSettingsProcessors(List processors); + + /** + * Returns a list of all the available settings processors. + */ + List getSettingsProcessors(); + + /** + * Returns a list of the settings processors that were selected by the user. + */ + List getSelectedSettingsProcessors(); + + /** + * Returns the contents of the file path text box. + */ + String getDestinationFilePath(); + + /** + * Returns the configuration that was selected by the user. + * + * The selected project can be determined by calling + * ICCOnfigurationDescription.getProjectDescription().getProject(); + */ + ICConfigurationDescription getSelectedConfiguration(); + + /** + * Causes an error dialog to be shown to the user. + */ + void showErrorDialog(String dialogTitle, String message); + + /** + * Displays a message at the top of the wizard page. + * @param flag a constant from the IMessageProvider interface + */ + void setMessage(String message, int flag); + + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IProjectSettingsWizardPageStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IProjectSettingsWizardPageStrategy.java new file mode 100644 index 00000000000..c4ac71bd6f7 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IProjectSettingsWizardPageStrategy.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +/** + * The wizard page is very similar for importing and exporting, + * the wizard page delegates to a strategy object which defines + * the behavior that is specific to import and export. + * + * @author Mike Kucera + * + */ +public interface IProjectSettingsWizardPageStrategy { + + enum MessageType { TITLE, MESSAGE, SETTINGS, CHECKBOX, FILE } + + + /** + * Some of the strings displayed on the wizard page are + * different, this method returns the correct string + * to display depending on the strategy. + */ + String getMessage(MessageType messageType); + + + /** + * Event sent to strategy object when the + * page has been created (at the end of createControl()) + */ + void pageCreated(IProjectSettingsWizardPage page); + + + /** + * Event sent to strategy object when the user selects + * a file name. + */ + void fileSelected(IProjectSettingsWizardPage page); + + + /** + * Event sent to strategy object when the user clicks + * finish on the wizard page. + */ + boolean finish(IProjectSettingsWizardPage page); + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ISettingsProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ISettingsProcessor.java new file mode 100644 index 00000000000..77c1c689d6d --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ISettingsProcessor.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + + +import org.eclipse.swt.graphics.Image; +import org.w3c.dom.Element; +import org.xml.sax.ContentHandler; + +import org.eclipse.cdt.core.settings.model.ICFolderDescription; + + +/** + * The exported XML file is divided into 'section' elements, each + * ISettingsProcessor is responsible for reading and writing + * a particular section. + * + * A section can contain anything, for example include paths or macros. + * No schema is defined for the XML file, that way additional settings + * processors can be easily added. In the future there may be an extension + * point for adding settings processors. + * + * + * @author Mike Kucera + */ +public interface ISettingsProcessor { + + /** + * Return the string that will appear in the selection list + * on the wizard page. + */ + String getDisplayName(); + + + /** + * Return the image that will appear in the selection list + * on the wizard page. + */ + Image getIcon(); + + + /** + * The name of the section in the XML file. + * + * This String should be unique, so prefix it with the package + * name or something. + */ + String getSectionName(); + + + /** + * Outputs a section of the XML file using the given SAX ContentHandler. + * + * @param projectRoot The folder description for the selected project and configuration + * @throws SettingsImportExportException if the section could not be written + */ + void writeSectionXML(ICFolderDescription projectRoot, ContentHandler content) throws SettingsImportExportException; + + + /** + * Passed part of the DOM tree that represents the section + * that is processed by this importer. + * + * @param projectRoot The folder description for the selected project and configuration + * @throws SettingsImportExportException if the section could not be read and imported + */ + void readSectionXML(ICFolderDescription projectRoot, Element section) throws SettingsImportExportException; +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IncludePathsSettingsProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IncludePathsSettingsProcessor.java new file mode 100644 index 00000000000..6428aa7d747 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/IncludePathsSettingsProcessor.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.graphics.Image; +import org.w3c.dom.Element; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +import org.eclipse.cdt.core.settings.model.CIncludePathEntry; +import org.eclipse.cdt.core.settings.model.ICLanguageSetting; +import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.core.settings.model.ICSettingEntry; +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.ui.CPluginImages; + + +/** + * A settings processor that imports and exports include paths. + * + * @author Mike Kucera + * + */ +public class IncludePathsSettingsProcessor extends SettingsProcessor { + + private static final String SECTION_NAME = "org.eclipse.cdt.internal.ui.wizards.settingswizards.IncludePaths"; //$NON-NLS-1$ + + private static final String INCLUDE_PATH_ELEMENT = "includepath"; //$NON-NLS-1$ + + + public Image getIcon() { + return CUIPlugin.getImageDescriptorRegistry().get(CPluginImages.DESC_OBJS_INCLUDES_FOLDER); + } + + public String getDisplayName() { + return Messages.ProjectSettingsWizardPage_Processor_Includes; + } + + public String getSectionName() { + return SECTION_NAME; + } + + @Override + protected int getSettingsType() { + return ICSettingEntry.INCLUDE_PATH; + } + + @Override + protected void writeSettings(ContentHandler content, ICLanguageSettingEntry setting) throws SettingsImportExportException { + char[] value = setting.getValue().toCharArray(); + + try { + content.startElement(NONE, NONE, INCLUDE_PATH_ELEMENT, null); + content.characters(value, 0, value.length); + content.endElement(NONE, NONE, INCLUDE_PATH_ELEMENT); + newline(content); + + } catch (SAXException e) { + throw new SettingsImportExportException(e); + } + } + + + @Override + protected void readSettings(ICLanguageSetting setting, Element language) throws SettingsImportExportException { + List includes = new ArrayList(); + + List includeNodes = XMLUtils.extractChildElements(language, INCLUDE_PATH_ELEMENT); + for(Element includeElement : includeNodes) { + String include = includeElement.getTextContent(); + if(include != null && include.length() > 0) + includes.add(new CIncludePathEntry(include, 0)); + } + + if(includes.isEmpty()) + return; + + // need to do this or existing settings will disappear + includes.addAll(setting.getSettingEntriesList(ICLanguageSettingEntry.INCLUDE_PATH)); + setting.setSettingEntries(ICSettingEntry.INCLUDE_PATH, includes); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/MacroSettingsProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/MacroSettingsProcessor.java new file mode 100644 index 00000000000..ff8a3dca163 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/MacroSettingsProcessor.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.graphics.Image; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +import org.eclipse.cdt.core.settings.model.CMacroEntry; +import org.eclipse.cdt.core.settings.model.ICLanguageSetting; +import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; + +import org.eclipse.cdt.core.settings.model.ICSettingEntry; +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.ui.CPluginImages; + +/** + * A settings processor that imports and exports symbols. + * + * @author Mike Kucera + * + */ +public class MacroSettingsProcessor extends SettingsProcessor { + + public static final String SECTION_NAME = "org.eclipse.cdt.internal.ui.wizards.settingswizards.Macros"; //$NON-NLS-1$ + + private static final String MACRO_ELEMENT = "macro"; //$NON-NLS-1$ + private static final String NAME_ELEMENT = "name"; //$NON-NLS-1$ + private static final String VALUE_ELEMENT = "value"; //$NON-NLS-1$ + + + public Image getIcon() { + return CUIPlugin.getImageDescriptorRegistry().get(CPluginImages.DESC_OBJS_MACRO); + } + + public String getDisplayName() { + return Messages.ProjectSettingsWizardPage_Processor_Macros; + } + + public String getSectionName() { + return SECTION_NAME; + } + + @Override + protected int getSettingsType() { + return ICSettingEntry.MACRO; + } + + @Override + protected void writeSettings(ContentHandler content, ICLanguageSettingEntry setting) throws SettingsImportExportException { + char[] name = setting.getName().toCharArray(); + char[] value = setting.getValue().toCharArray(); + + try { + content.startElement(NONE, NONE, MACRO_ELEMENT, null); + newline(content); + + content.startElement(NONE, NONE, NAME_ELEMENT, null); + content.characters(name, 0, name.length); + content.endElement(NONE, NONE, NAME_ELEMENT); + + content.startElement(NONE, NONE, VALUE_ELEMENT, null); + content.characters(value, 0, value.length); + content.endElement(NONE, NONE, VALUE_ELEMENT); + newline(content); + + content.endElement(NONE, NONE, MACRO_ELEMENT); + newline(content); + + } catch(SAXException e) { + throw new SettingsImportExportException(e); + } + } + + + @Override + protected void readSettings(ICLanguageSetting setting, Element language) throws SettingsImportExportException { + List macros = new ArrayList(); + + List macrosNodes = XMLUtils.extractChildElements(language, MACRO_ELEMENT); + + for(Element macroElement : macrosNodes) { + String name = null; + String value = null; + + NodeList nodeList = macroElement.getChildNodes(); + for(int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + switch(node.getNodeType()) { + case Node.TEXT_NODE: + Text text = (Text)node; + if(XMLUtils.isWhitespace(text.getData())) + break; + throw new SettingsImportExportException("Unknown text: '" + text.getData() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + case Node.ELEMENT_NODE: + Element element = (Element)node; + String tagName = element.getTagName(); + if(name == null && tagName.equals(NAME_ELEMENT)) + name = element.getTextContent(); + else if(value == null && tagName.equals(VALUE_ELEMENT)) + value = element.getTextContent(); + else + throw new SettingsImportExportException("Unknown or extra tag: " + tagName); //$NON-NLS-1$ + break; + default: + throw new SettingsImportExportException("Unknown node: " + node.getNodeName()); //$NON-NLS-1$ + } + } + + if(name == null) + throw new SettingsImportExportException("There must be one element"); //$NON-NLS-1$ + if(value == null) + throw new SettingsImportExportException("There must be one element"); //$NON-NLS-1$ + + macros.add(new CMacroEntry(name, value, 0)); + } + + if(macros.isEmpty()) + return; + + // need to do this or existing settings will disappear + macros.addAll(setting.getSettingEntriesList(ICLanguageSettingEntry.MACRO)); + setting.setSettingEntries(ICSettingEntry.MACRO, macros); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/Messages.java new file mode 100644 index 00000000000..dccead10c92 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/Messages.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +import org.eclipse.osgi.util.NLS; + + +class Messages extends NLS { + + private static final String BUNDLE_NAME = + "org.eclipse.cdt.internal.ui.wizards.settingswizards.messages"; //$NON-NLS-1$ + + static { + initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { } + + + // messages specific to the import page + public static String + ProjectSettingsWizardPage_Import_title, + ProjectSettingsWizardPage_Import_message, + ProjectSettingsWizardPage_Import_selectSettings, + ProjectSettingsWizardPage_Import_checkBox, + ProjectSettingsWizardPage_Import_file, + ProjectSettingsWizardPage_Import_parseError, + ProjectSettingsWizardPage_Import_openError; + + // messages specific to the export page + public static String + ProjectSettingsWizardPage_Export_title, + ProjectSettingsWizardPage_Export_message, + ProjectSettingsWizardPage_Export_selectSettings, + ProjectSettingsWizardPage_Export_checkBox, + ProjectSettingsWizardPage_Export_file; + + // messages common to both + public static String + ProjectSettingsWizardPage_selectAll, + ProjectSettingsWizardPage_deselectAll, + ProjectSettingsWizardPage_selectProject, + ProjectSettingsWizardPage_browse, + ProjectSettingsWizardPage_selectConfiguration; + + // messages for settings processors + public static String + ProjectSettingsWizardPage_Processor_Includes, + ProjectSettingsWizardPage_Processor_Macros; + + // error messages during export + public static String + ProjectSettingsExportStrategy_couldNotOpen, + ProjectSettingsExportStrategy_exportError, + ProjectSettingsExportStrategy_exportFailed, + ProjectSettingsExportStrategy_fileOpenError, + ProjectSettingsExportStrategy_xmlError; + + // error messages during import + public static String + ProjectSettingsImportStrategy_couldNotImport, + ProjectSettingsImportStrategy_couldNotOpen, + ProjectSettingsImportStrategy_fileOpenError, + ProjectSettingsImportStrategy_importError, + ProjectSettingsImportStrategy_saveError; + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsExportStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsExportStrategy.java new file mode 100644 index 00000000000..62b8a60f009 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsExportStrategy.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + + +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.List; + +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICFolderDescription; +import org.eclipse.cdt.ui.CUIPlugin; + +/** + * Custom behavior for the Export wizard. + * + * @author Mike Kucera + * + */ +public class ProjectSettingsExportStrategy implements IProjectSettingsWizardPageStrategy { + + public static final String ROOT_ELEMENT = "cdtprojectproperties"; //$NON-NLS-1$ + public static final String SECTION_ELEMENT = "section"; //$NON-NLS-1$ + public static final String SECTION_NAME_ATTRIBUTE = "name"; //$NON-NLS-1$ + + + + private static final String NONE = ""; //$NON-NLS-1$ + private static final String CDATA = "CDATA"; //$NON-NLS-1$ + + + + public String getMessage(MessageType type) { + switch(type) { + case TITLE: return Messages.ProjectSettingsWizardPage_Export_title; + case MESSAGE: return Messages.ProjectSettingsWizardPage_Export_message; + case CHECKBOX: return Messages.ProjectSettingsWizardPage_Export_checkBox; + case FILE: return Messages.ProjectSettingsWizardPage_Export_file; + case SETTINGS: return Messages.ProjectSettingsWizardPage_Export_selectSettings; + default: return null; + } + } + + + public void pageCreated(IProjectSettingsWizardPage page) { + // do nothing + } + + + public void fileSelected(IProjectSettingsWizardPage page) { + // do nothing + } + + + private Writer getWriter(IProjectSettingsWizardPage page) throws IOException { + IPath path = new Path(page.getDestinationFilePath()); + if(!IProjectSettingsWizardPage.FILENAME_EXTENSION.equals(path.getFileExtension())) + path.addFileExtension(IProjectSettingsWizardPage.FILENAME_EXTENSION); + + return new FileWriter(path.toFile()); + } + + + /** + * Exports the selected project settings to an XML file. + */ + public boolean finish(IProjectSettingsWizardPage page) { + SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); + TransformerHandler handler = null; + try { + handler = factory.newTransformerHandler(); + } catch (TransformerConfigurationException e) { + CUIPlugin.log(e); + page.showErrorDialog(Messages.ProjectSettingsExportStrategy_exportError, + Messages.ProjectSettingsExportStrategy_exportFailed); + return false; + } + + // gets a writer for the file that was selected by the user + Writer writer; + try { + writer = getWriter(page); + } catch(IOException e) { + page.showErrorDialog(Messages.ProjectSettingsExportStrategy_fileOpenError, + Messages.ProjectSettingsExportStrategy_couldNotOpen); + return false; + } + + // stream the results to the writer as text + handler.setResult(new StreamResult(writer)); + + // write out the XML header + Transformer transformer = handler.getTransformer(); + transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1"); //$NON-NLS-1$ + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + + List exporters = page.getSelectedSettingsProcessors(); + + ICConfigurationDescription config = page.getSelectedConfiguration(); + ICFolderDescription projectRoot = config.getRootFolderDescription(); + + try { + AttributesImpl attributes = new AttributesImpl(); + + handler.startDocument(); + newline(handler); + handler.startElement(NONE, NONE, ROOT_ELEMENT, null); + newline(handler); + + for(ISettingsProcessor exporter : exporters) { + attributes.clear(); + attributes.addAttribute(NONE, NONE, SECTION_NAME_ATTRIBUTE, CDATA, exporter.getSectionName()); + handler.startElement(NONE, NONE, SECTION_ELEMENT, attributes); + newline(handler); + + // each exporter is responsible for writing out its own section of the file + exporter.writeSectionXML(projectRoot, handler); + + handler.endElement(NONE, NONE, SECTION_ELEMENT); + newline(handler); + } + + handler.endElement(NONE, NONE, ROOT_ELEMENT); + newline(handler); + handler.endDocument(); + newline(handler); + + } catch (SAXException e) { + CUIPlugin.log(e); + page.showErrorDialog(Messages.ProjectSettingsExportStrategy_exportError, + Messages.ProjectSettingsExportStrategy_xmlError); + return false; + } catch(SettingsImportExportException e) { + CUIPlugin.log(e); + page.showErrorDialog(Messages.ProjectSettingsExportStrategy_fileOpenError, + Messages.ProjectSettingsExportStrategy_couldNotOpen); + return false; + } + + return true; + } + + + + + + + /** + * Outputs a newline (\n) to the given ContentHandler. + */ + private static void newline(ContentHandler handler) throws SAXException { + handler.ignorableWhitespace("\n".toCharArray(), 0, 1); //$NON-NLS-1$ + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsExportWizard.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsExportWizard.java new file mode 100644 index 00000000000..9fd894e722f --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsExportWizard.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IExportWizard; +import org.eclipse.ui.IWorkbench; + +public class ProjectSettingsExportWizard extends ProjectSettingsWizard implements IExportWizard { + + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + super.init(workbench, selection); + setWindowTitle(Messages.ProjectSettingsWizardPage_Export_title); + } + + @Override + public ProjectSettingsWizardPage getPage() { + return ProjectSettingsWizardPage.createExportWizardPage(); + } + + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsImportStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsImportStrategy.java new file mode 100644 index 00000000000..a51dae49fd5 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsImportStrategy.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICFolderDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.ui.CUIPlugin; + +/** + * Custom behavior for the Import wizard. + * + * @author Mike Kucera + * + */ +public class ProjectSettingsImportStrategy implements IProjectSettingsWizardPageStrategy { + + + public String getMessage(MessageType type) { + switch(type) { + case TITLE: return Messages.ProjectSettingsWizardPage_Import_title; + case MESSAGE: return Messages.ProjectSettingsWizardPage_Import_message; + case CHECKBOX: return Messages.ProjectSettingsWizardPage_Import_checkBox; + case FILE: return Messages.ProjectSettingsWizardPage_Import_file; + case SETTINGS: return Messages.ProjectSettingsWizardPage_Import_selectSettings; + default: return null; + } + } + + + /* + * Start with an empty list of processors. + */ + public void pageCreated(IProjectSettingsWizardPage page) { + page.setDisplayedSettingsProcessors(Collections.emptyList()); + } + + + /* + * Collects the importers that can be applied to the file and displays + * them to the user. + */ + public void fileSelected(IProjectSettingsWizardPage page) { + List pairs = Collections.emptyList(); + try { + pairs = extractSectionsFromFile(page); + page.setMessage(getMessage(MessageType.MESSAGE), IMessageProvider.NONE); // its all good + } catch (FileNotFoundException e) { + page.setMessage(Messages.ProjectSettingsWizardPage_Import_openError, IMessageProvider.ERROR); + } catch (SettingsImportExportException e) { + page.setMessage(Messages.ProjectSettingsWizardPage_Import_parseError, IMessageProvider.ERROR); + } + + List importersToDisplay = new ArrayList(); + for(ImporterSectionPair pair : pairs) { + importersToDisplay.add(pair.importer); + } + + // if there was an error then importersToDisplay will be empty and this will clear the list + page.setDisplayedSettingsProcessors(importersToDisplay); + } + + + /* + * Parse the file again and this time actually do the import. + */ + public boolean finish(IProjectSettingsWizardPage page) { + // get the selected project and configuration + ICConfigurationDescription config = page.getSelectedConfiguration(); + IProject project = config.getProjectDescription().getProject(); + + // get a writable copy of the project description so that we can make changes to it + ICProjectDescription writableDescription = CoreModel.getDefault().getProjectDescription(project, true); + ICConfigurationDescription writableConfig = writableDescription.getConfigurationById(config.getId()); + ICFolderDescription writableProjectRoot = writableConfig.getRootFolderDescription(); + + List selectedImporters = page.getSelectedSettingsProcessors(); + + try { + List pairs = extractSectionsFromFile(page); + + for(ImporterSectionPair pair : pairs) { + if(selectedImporters.contains(pair.importer)) + pair.importer.readSectionXML(writableProjectRoot, pair.section); + } + + } catch (FileNotFoundException e) { + CUIPlugin.log(e); + page.showErrorDialog(Messages.ProjectSettingsImportStrategy_fileOpenError, + Messages.ProjectSettingsImportStrategy_couldNotOpen); + return false; + } catch (SettingsImportExportException e) { // error during parsing or importing + CUIPlugin.log(e); + page.showErrorDialog(Messages.ProjectSettingsImportStrategy_importError, + Messages.ProjectSettingsImportStrategy_couldNotImport); + return false; + } + + // only if all the importing was successful do we actually write out to the .cproject file + try { + CoreModel.getDefault().setProjectDescription(project, writableDescription); + } catch (CoreException e) { + CUIPlugin.log(e); + page.showErrorDialog(Messages.ProjectSettingsImportStrategy_importError, + Messages.ProjectSettingsImportStrategy_saveError); + return false; + } + + return true; + } + + + private static class ImporterSectionPair { + Element section; + ISettingsProcessor importer; + ImporterSectionPair(ISettingsProcessor importer, Element section) { + this.importer = importer; + this.section = section; + } + } + + /* + * Attempts to parse the file the user selected. + */ + private List extractSectionsFromFile(IProjectSettingsWizardPage page) throws FileNotFoundException, SettingsImportExportException { + // get the file path that the user input + String filePath = page.getDestinationFilePath(); + + // get all the importers + Map importers = new HashMap(); + for(ISettingsProcessor processor : page.getSettingsProcessors()) { + importers.put(processor.getSectionName(), processor); + } + + FileInputStream in = new FileInputStream(filePath); // throws FileNotFoundException + + // try to parse the file as generic XML with no schema + Document document = parse(in); + + // now try to get a list of
elements + Element root = document.getDocumentElement(); + List sections = XMLUtils.extractChildElements(root, ProjectSettingsExportStrategy.SECTION_ELEMENT); + + List pairs = new ArrayList(); + + // associate an importer with each section + for(Element section : sections) { + String sectionName = section.getAttribute(ProjectSettingsExportStrategy.SECTION_NAME_ATTRIBUTE); + if(sectionName != null) { + ISettingsProcessor importer = importers.get(sectionName); + + // if there is an importer available for the section then delegate to it + if(importer != null) + pairs.add(new ImporterSectionPair(importer, section)); + } + } + + return pairs; + } + + + /** + * An error handler that aborts the XML parse at the first sign + * of any kind of problem. + */ + private static ErrorHandler ABORTING_ERROR_HANDER = new ErrorHandler() { + public void error(SAXParseException e) throws SAXException { + throw e; + } + public void fatalError(SAXParseException e) throws SAXException { + throw e; + } + public void warning(SAXParseException e) throws SAXException { + throw e; + } + }; + + + /* + * Uses JAXP to parse the file. Returns null if the file could + * not be parsed as XML. + * + * Not validating because I want to make it easy to add new settings processors. + * Eventually there could be an extension point for adding settings processors + * so I'm coding everything with the assumption that each settings processor + * will do its own validation programatically. + */ + private static Document parse(InputStream in) throws SettingsImportExportException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); + factory.setNamespaceAware(false); + factory.setIgnoringComments(true); + + try { + DocumentBuilder parser = factory.newDocumentBuilder(); + parser.setErrorHandler(ABORTING_ERROR_HANDER); // causes SAXException to be thrown on any parse error + InputSource input = new InputSource(in); // TODO should I be using an InputSource? + Document doc = parser.parse(input); + return doc; + + } catch (Exception e) { + throw new SettingsImportExportException(e); + } + } + + + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsImportWizard.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsImportWizard.java new file mode 100644 index 00000000000..ce80d7a1bc9 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsImportWizard.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; + +public class ProjectSettingsImportWizard extends ProjectSettingsWizard implements IImportWizard { + + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + super.init(workbench, selection); + setWindowTitle(Messages.ProjectSettingsWizardPage_Import_title); + } + + @Override + public ProjectSettingsWizardPage getPage() { + return ProjectSettingsWizardPage.createImportWizardPage(); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsWizard.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsWizard.java new file mode 100644 index 00000000000..80a1519819a --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsWizard.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +import org.eclipse.core.resources.IProject; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.IWorkbench; + +public abstract class ProjectSettingsWizard extends Wizard { + + private ProjectSettingsWizardPage mainPage; + private IStructuredSelection selection; + + public abstract ProjectSettingsWizardPage getPage(); + + @Override + public void addPages() { + super.addPages(); + mainPage = getPage(); + + // happens if the user invoked the wizard by right clicking on a project element + if(selection != null) { + IProject project = (IProject)selection.getFirstElement(); + mainPage.setInitialProject(project); + } + + addPage(mainPage); + } + + @Override + public boolean performFinish() { + return mainPage.finish(); + } + + + public void init(IWorkbench workbench, IStructuredSelection selection) { + this.selection = selection; + setNeedsProgressMonitor(true); + } + + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsWizardPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsWizardPage.java new file mode 100644 index 00000000000..0eb31c9a9d8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/ProjectSettingsWizardPage.java @@ -0,0 +1,422 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.wizard.WizardPage; +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.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.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +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.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.ui.CElementLabelProvider; +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.ui.viewsupport.ListContentProvider; +import org.eclipse.cdt.internal.ui.wizards.settingswizards.IProjectSettingsWizardPageStrategy.MessageType; + +/** + * + */ +abstract public class ProjectSettingsWizardPage extends WizardPage implements IProjectSettingsWizardPage { + + public static final String FILENAME_EXTENSION = "xml"; //$NON-NLS-1$ + + + private final IProjectSettingsWizardPageStrategy strategy; + private final List processors; + + private ICProject selectedProject; + private ICConfigurationDescription selectedConfiguration; + + private Text filePathText; + private CheckboxTableViewer settingsViewer; + + private IProject initialProject; + + /** + * + * @param strategy + * @param initialProject the initial project to be selected, may be null + */ + private ProjectSettingsWizardPage(IProjectSettingsWizardPageStrategy strategy) { + super(""); //$NON-NLS-1$ + this.strategy = strategy; + + // This could be replaced with an extension point + this.processors = Arrays.asList( + new IncludePathsSettingsProcessor(), + new MacroSettingsProcessor() + ); + + } + + + + + protected abstract void layoutPage(Composite parent); + + + public static ProjectSettingsWizardPage createExportWizardPage() { + return new ProjectSettingsWizardPage(new ProjectSettingsExportStrategy()) { + @Override + public void layoutPage(Composite parent) { + createProjectSelectionGroup(parent); + createSettingsSelectionGroup(parent); + //createCheckboxSelectionGroup(parent); + createFileSelectionGroup(parent); + } + }; + } + + + public static ProjectSettingsWizardPage createImportWizardPage() { + return new ProjectSettingsWizardPage(new ProjectSettingsImportStrategy()) { + @Override + public void layoutPage(Composite parent) { + createFileSelectionGroup(parent); + createProjectSelectionGroup(parent); + createSettingsSelectionGroup(parent); + //createCheckboxSelectionGroup(parent); + } + }; + } + + + public boolean finish() { + return strategy.finish(this); + } + + + public void setInitialProject(IProject project) { + this.initialProject = project; + } + + + public List getSettingsProcessors() { + return Collections.unmodifiableList(processors); + } + + + public List getSelectedSettingsProcessors() { + List selected = new ArrayList(); + for(Object element : settingsViewer.getCheckedElements()) { + selected.add((ISettingsProcessor)element); + } + return selected; + } + + public String getDestinationFilePath() { + return filePathText.getText(); + } + + + public ICProject getSelectedProject() { + return selectedProject; + } + + + public ICConfigurationDescription getSelectedConfiguration() { + return selectedConfiguration; + } + + public void setDisplayedSettingsProcessors(List processors) { + settingsViewer.setInput(processors); + settingsViewer.refresh(); + } + + + public void showErrorDialog(String dialogTitle, String message) { + Shell shell = Display.getCurrent().getActiveShell(); + Status status = new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, 0, message, null); + ErrorDialog.openError(shell, dialogTitle, null, status); + } + + + public void createControl(Composite parent) { + setTitle(strategy.getMessage(MessageType.TITLE)); + setMessage(strategy.getMessage(MessageType.MESSAGE)); + + Composite composite = new Composite(parent, SWT.NULL); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL)); + composite.setFont(parent.getFont()); + + layoutPage(composite); + + setControl(composite); + + strategy.pageCreated(this); + + updateWidgetEnablements(); + } + + + private void updateWidgetEnablements() { + boolean enableFinishButton = selectedProject != null + && selectedConfiguration != null + && settingsViewer.getCheckedElements().length > 0 + && filePathText.getText().length() > 0; + + // since this wizard has only one page we can toggle the finish button using the setPageComplete() method + setPageComplete(enableFinishButton); + } + + + + protected void createProjectSelectionGroup(Composite parent) { + Composite projectSelectionGroup = new Composite(parent, SWT.NONE); + projectSelectionGroup.setLayout(new GridLayout(2, true)); + projectSelectionGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + projectSelectionGroup.setFont(parent.getFont()); + + Label projectLabel = new Label(projectSelectionGroup, SWT.NONE); + projectLabel.setText(Messages.ProjectSettingsWizardPage_selectProject); + projectLabel.setLayoutData(new GridData()); + + Label configLabel = new Label(projectSelectionGroup, SWT.NONE); + configLabel.setText(Messages.ProjectSettingsWizardPage_selectConfiguration); + configLabel.setLayoutData(new GridData()); + + final Table projectTable = new Table(projectSelectionGroup, SWT.SINGLE | SWT.BORDER); + projectTable.setLayoutData(new GridData(GridData.FILL_BOTH)); + + TableViewer projectViewer = new TableViewer(projectTable); + projectViewer.setContentProvider(new ListContentProvider()); + projectViewer.setLabelProvider(new CElementLabelProvider()); + List openProjects = getAllOpenCProjects(); + projectViewer.setInput(openProjects); + + final Table configTable = new Table(projectSelectionGroup, SWT.SINGLE | SWT.BORDER); + configTable.setLayoutData(new GridData(GridData.FILL_BOTH)); + + final TableViewer configViewer = new TableViewer(configTable); + configViewer.setContentProvider(new ListContentProvider()); + configViewer.setLabelProvider(new LabelProvider() { + @Override public String getText(Object element) { + return ((ICConfigurationDescription)element).getName(); + } + }); + + // TODO what if nothing is selected? + projectTable.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { + TableItem[] items = projectTable.getSelection(); + selectedProject = (ICProject)items[0].getData(); // its a single select so this is ok + selectedConfiguration = null; + configViewer.setInput(getConfigurations(selectedProject)); + configViewer.refresh(); + updateWidgetEnablements(); + } + }); + + + configTable.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { + TableItem[] items = configTable.getSelection(); + selectedConfiguration = (ICConfigurationDescription)items[0].getData(); + updateWidgetEnablements(); + } + }); + + if(initialProject != null) { + String initialProjectName = initialProject.getName(); + for(int i = 0; i < openProjects.size(); i++) { + ICProject tableProject = openProjects.get(i); + if(tableProject.getElementName().equals(initialProjectName)) { + projectTable.select(i); + configViewer.setInput(getConfigurations(tableProject)); + configViewer.refresh(); + selectedProject = tableProject; + break; + } + } + } + } + + + private static List getConfigurations(ICProject project) { + // get a read-only project description, no need to waste memory + ICProjectDescription description = CCorePlugin.getDefault().getProjectDescription(project.getProject(), false); + return Arrays.asList(description.getConfigurations()); + } + + + private static List getAllOpenCProjects() { + List projects = new ArrayList(); + try { + for(ICProject project : CoreModel.getDefault().getCModel().getCProjects()) { + if(project.getProject().isOpen()) { + projects.add(project); + } + } + } catch(CModelException e) { + CUIPlugin.log(e); + } + return projects; + } + + + protected void createSettingsSelectionGroup(Composite parent) { + Composite settingsSelectionGroup = new Composite(parent, SWT.NONE); + settingsSelectionGroup.setLayout(new GridLayout()); + settingsSelectionGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + settingsSelectionGroup.setFont(parent.getFont()); + + Label label = new Label(settingsSelectionGroup, SWT.NONE); + label.setText(strategy.getMessage(MessageType.SETTINGS)); + + Table table = new Table(settingsSelectionGroup, SWT.CHECK | SWT.BORDER); + table.setLayoutData(new GridData(GridData.FILL_BOTH)); + + + settingsViewer = new CheckboxTableViewer(table); + settingsViewer.setContentProvider(new ListContentProvider()); + + settingsViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + updateWidgetEnablements(); + } + }); + + LabelProvider settingsProcessorLabelProvider = new LabelProvider() { + @Override public Image getImage(Object element) { + return ((ISettingsProcessor)element).getIcon(); + } + @Override public String getText(Object element) { + return ((ISettingsProcessor)element).getDisplayName(); + } + }; + + settingsViewer.setLabelProvider(settingsProcessorLabelProvider); + settingsViewer.setInput(processors); + + + Composite buttonComposite = new Composite(settingsSelectionGroup, SWT.NONE); + GridLayout layout = new GridLayout(2, true); + layout.marginHeight= layout.marginWidth= 0; + buttonComposite.setLayout(layout); + buttonComposite.setLayoutData(new GridData()); + + Button selectButton = new Button(buttonComposite, SWT.PUSH); + selectButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + selectButton.setText(Messages.ProjectSettingsWizardPage_selectAll); + + selectButton.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { + settingsViewer.setAllChecked(true); + updateWidgetEnablements(); + } + }); + + Button deselectButton = new Button(buttonComposite, SWT.PUSH); + deselectButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + deselectButton.setText(Messages.ProjectSettingsWizardPage_deselectAll); + + deselectButton.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { + settingsViewer.setAllChecked(false); + updateWidgetEnablements(); + } + }); + } + + + protected void createFileSelectionGroup(Composite parent) { + Composite fileSelectionGroup = new Composite(parent, SWT.NONE); + fileSelectionGroup.setLayout(new GridLayout(2, false)); + fileSelectionGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fileSelectionGroup.setFont(parent.getFont()); + + Label label = new Label(fileSelectionGroup, SWT.NONE); + label.setText(strategy.getMessage(MessageType.FILE)); + GridData gridData = new GridData(); + gridData.horizontalSpan = 2; + label.setLayoutData(gridData); + + filePathText = new Text(fileSelectionGroup, SWT.SINGLE | SWT.BORDER); + filePathText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + filePathText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + updateWidgetEnablements(); + strategy.fileSelected(ProjectSettingsWizardPage.this); + } + }); + + Button browseButton = new Button(fileSelectionGroup, SWT.PUSH); + browseButton.setText(Messages.ProjectSettingsWizardPage_browse); + browseButton.setLayoutData(new GridData()); + browseButton.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { + FileDialog fileDialog = new FileDialog(getShell(), SWT.SAVE); + fileDialog.setFilterExtensions(new String[] {"*." + FILENAME_EXTENSION}); //$NON-NLS-1$ + String filePath = fileDialog.open(); + if(filePath != null) + filePathText.setText(filePath); + } + }); + } + + + + +// protected void createCheckboxSelectionGroup(Composite parent) { +// Composite checkboxSelectGroup = new Composite(parent, SWT.NONE); +// checkboxSelectGroup.setLayout(new GridLayout()); +// checkboxSelectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); +// checkboxSelectGroup.setFont(parent.getFont()); +// +// final Button checkBox = new Button(checkboxSelectGroup, SWT.CHECK); +// checkBox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); +// checkBox.setText(strategy.getMessage(CHECKBOX)); +// +// checkBox.addSelectionListener(new SelectionAdapter() { +// @Override public void widgetSelected(SelectionEvent e) { +// strategy.handleCheckboxClick(ProjectSettingsWizardPage.this, checkBox.getSelection()); +// } +// }); +// } + + +} + diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/SettingsImportExportException.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/SettingsImportExportException.java new file mode 100644 index 00000000000..6de12451587 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/SettingsImportExportException.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +public class SettingsImportExportException extends Exception { + + public SettingsImportExportException() { + } + + public SettingsImportExportException(String message) { + super(message); + } + + public SettingsImportExportException(Throwable t) { + super(t); + } + + public SettingsImportExportException(String message, Throwable t) { + super(message, t); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/SettingsProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/SettingsProcessor.java new file mode 100644 index 00000000000..4b97e6e784e --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/SettingsProcessor.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.w3c.dom.Element; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import org.eclipse.cdt.core.settings.model.ICFolderDescription; +import org.eclipse.cdt.core.settings.model.ICLanguageSetting; +import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; + +/** + * Base class implementing standard import and export functionality + * for a section of the file. + * + * @author Mike Kucera + */ +public abstract class SettingsProcessor implements ISettingsProcessor { + + protected static final String NONE = ""; //$NON-NLS-1$ + protected static final String CDATA = "CDATA"; //$NON-NLS-1$ + + protected static final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$ + protected static final String LANGUAGE_ELEMENT = "language"; //$NON-NLS-1$ + + + /** + */ + protected abstract int getSettingsType(); + + protected abstract void writeSettings(ContentHandler content, ICLanguageSettingEntry setting) + throws SettingsImportExportException; + + protected abstract void readSettings(ICLanguageSetting setting, Element language) + throws SettingsImportExportException; + + + /** + * Outputs a newline (\n) to the given ContentHandler. + */ + protected static void newline(ContentHandler handler) throws SAXException { + handler.ignorableWhitespace("\n".toCharArray(), 0, 1); //$NON-NLS-1$ + } + + + + public void writeSectionXML(ICFolderDescription projectRoot, ContentHandler content) throws SettingsImportExportException { + ICLanguageSetting[] languages = projectRoot.getLanguageSettings(); + AttributesImpl attributes = new AttributesImpl(); + + try { + for(ICLanguageSetting language : languages) { + //TODO for some reason language.getLanguageId() is returning null + String languageName = language.getName(); + attributes.clear(); + attributes.addAttribute(NONE, NONE, NAME_ATTRIBUTE, CDATA, languageName); + content.startElement(NONE, NONE, LANGUAGE_ELEMENT, attributes); + newline(content); + + ICLanguageSettingEntry[] settings = language.getSettingEntries(getSettingsType()); + + for(ICLanguageSettingEntry setting : settings) { + if(!setting.isBuiltIn()) { + writeSettings(content, setting); + } + } + + newline(content); + content.endElement(NONE, NONE, LANGUAGE_ELEMENT); + newline(content); + } + + } catch(SAXException e) { + throw new SettingsImportExportException(e); + } + } + + + + public void readSectionXML(ICFolderDescription projectRoot, Element section) throws SettingsImportExportException { + ICLanguageSetting[] languageSettings = projectRoot.getLanguageSettings(); + + Map languageMap = new HashMap(); + for(ICLanguageSetting language : languageSettings) { + languageMap.put(language.getName(), language); + } + + List elements = XMLUtils.extractChildElements(section, LANGUAGE_ELEMENT); // throws SettingsImportExportException + for(Element languageElement : elements) { + String languageName = languageElement.getAttribute(NAME_ATTRIBUTE); + ICLanguageSetting setting = languageMap.get(languageName); + if(setting != null) + readSettings(setting, languageElement); + } + } + + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/XMLUtils.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/XMLUtils.java new file mode 100644 index 00000000000..d924408eaf7 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/XMLUtils.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.wizards.settingswizards; + +import java.util.ArrayList; +import java.util.List; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +class XMLUtils { + + private XMLUtils() {} + + + public static List extractChildElements(Element node, String childElementName) throws SettingsImportExportException { + List extracted = new ArrayList(); + + NodeList children = node.getChildNodes(); + for(int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + switch(child.getNodeType()) { + case Node.ELEMENT_NODE: + Element element = (Element)child; + if(element.getTagName().equals(childElementName)) { + extracted.add(element); + } + else + throw new SettingsImportExportException("Unknown tag: " + element.getTagName()); //$NON-NLS-1$ + break; + case Node.TEXT_NODE: + Text text = (Text)child; + if(isWhitespace(text.getData())) + break; + throw new SettingsImportExportException("Unknown text: '" + text.getData() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + default: + throw new SettingsImportExportException("Unknown node: " + child.getNodeName()); //$NON-NLS-1$ + } + } + + return extracted; + } + + + public static boolean isWhitespace(String s) { + if(s == null) + return false; + + for(char c : s.toCharArray()) { + if(!Character.isWhitespace(c)) { + return false; + } + } + + return true; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/messages.properties new file mode 100644 index 00000000000..227d511a8e1 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/settingswizards/messages.properties @@ -0,0 +1,44 @@ +################################################################################## +# Copyright (c) 2008 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 +################################################################################## +ProjectSettingsExportStrategy_couldNotOpen=Could not open specified file +ProjectSettingsExportStrategy_exportError=Export Error +ProjectSettingsExportStrategy_exportFailed=Export failed +ProjectSettingsExportStrategy_fileOpenError=File Open Error +ProjectSettingsExportStrategy_xmlError=Export failure, error writing XML file + +ProjectSettingsImportStrategy_couldNotImport=File could not be imported +ProjectSettingsImportStrategy_couldNotOpen=Could not open the specified file +ProjectSettingsImportStrategy_fileOpenError=File Open Error +ProjectSettingsImportStrategy_importError=Import Error +ProjectSettingsImportStrategy_saveError=Could not save imported data + +ProjectSettingsWizardPage_Import_title=Import +ProjectSettingsWizardPage_Import_message=Import C/C++ project settings +ProjectSettingsWizardPage_Import_selectSettings=Select settings to import +ProjectSettingsWizardPage_Import_checkBox=Import folder and file specific settings +ProjectSettingsWizardPage_Import_file=Settings file +ProjectSettingsWizardPage_Import_parseError=File could not be parsed +ProjectSettingsWizardPage_Import_openError=File could not be opened + +ProjectSettingsWizardPage_Export_title=Export +ProjectSettingsWizardPage_Export_message=Export C/C++ project settings for use in another workspace +ProjectSettingsWizardPage_Export_selectSettings=Select settings to export +ProjectSettingsWizardPage_Export_checkBox=Export folder and file specific settings +ProjectSettingsWizardPage_Export_file=Export destination + +ProjectSettingsWizardPage_selectAll=Select All +ProjectSettingsWizardPage_deselectAll=Deselect All +ProjectSettingsWizardPage_selectProject=Select Project +ProjectSettingsWizardPage_selectConfiguration=Select Configuration +ProjectSettingsWizardPage_browse=Browse... + +ProjectSettingsWizardPage_Processor_Macros=Symbols +ProjectSettingsWizardPage_Processor_Includes=Include Paths \ No newline at end of file diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties index c11dfaccc42..3ab258552cf 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.properties +++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties @@ -173,7 +173,6 @@ RestoredefaultRegisterGroupsAction.label=Restore Default Register Groups RestoredefaultRegisterGroupsAction.tooltip=Restore Default Register Groups # Import Executable -importCPPCategory.name=C/C++ importExecutableWizard.name=C/C++ Executable importExecutableWizard.description=Imports a C/C++ executable file. Will create a project and launch configuration for debugging. diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index d30e6aaae3d..33e1d82bee4 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -1501,7 +1501,7 @@ -