1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

project settings import/export wizards, bug 242010

This commit is contained in:
Mike Kucera 2008-08-12 18:29:20 +00:00
parent ca75909f2c
commit 433174325e
25 changed files with 2129 additions and 9 deletions

View file

@ -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());
}
}

View file

@ -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<ISettingsProcessor> selectedSettingsProcessors;
private ICConfigurationDescription selectedConfiguration;
private List<ISettingsProcessor> 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<ISettingsProcessor> processors) {
this.selectedSettingsProcessors = processors;
}
public List<ISettingsProcessor> getSelectedSettingsProcessors() {
return selectedSettingsProcessors;
}
public void setSettingsProcessors(List<ISettingsProcessor> processors) {
this.settingsProcessors = processors;
}
public List<ISettingsProcessor> getSettingsProcessors() {
return settingsProcessors;
}
public void setDisplayedSettingsProcessors( List<ISettingsProcessor> processors) {
// do nothing
}
public void setMessage(String message, int flag) {
// do nothing
}
public void showErrorDialog(String dialogTitle, String message) {
// do nothing
}
}

View file

@ -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<ISettingsProcessor> processors = Arrays.<ISettingsProcessor>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}
// <cdtprojectproperties></cdtprojectproperties>
//
// {badXML3}
// <cdtprojectproperties>
// <section name="invalidsectionname">
// </section>
// </cdtprojectproperties>
//
// {badXML4}
// <cdtprojectproperties>
// <section name="org.eclipse.cdt.internal.ui.wizards.settingswizards.Macros">
// <invalidtag>
// </invalidtag>
// </section>
// </cdtprojectproperties>
//
// {badXML5}
// <cdtprojectproperties>
// <section name="org.eclipse.cdt.internal.ui.wizards.settingswizards.Macros">
// <macro>
// <name>aaaa</name><value></value>
// </macro>
// </section>
// </cdtprojectproperties>
//
// {badXML6}
// <cdtprojectproperties>
// <section name="org.eclipse.cdt.internal.ui.wizards.settingswizards.Macros">
// <language name="GNU C++">
// <macro>
// <name>aaaa</name>
// </macro>
// </language>
// </section>
// </cdtprojectproperties>
//
// {badXML7}
// <cdtprojectproperties>
// <section name="org.eclipse.cdt.internal.ui.wizards.settingswizards.Macros">
// <language name="GNU C++">
// <macro>
// <name>aaaa</name><value></value><value></value>
// </macro>
// </language>
// </section>
// </cdtprojectproperties>
//
// {badXML8}
// <cdtprojectproperties>
// <section name="org.eclipse.cdt.internal.ui.wizards.settingswizards.IncludePaths">
// <language name="GNU C++">
// <includepath>C:\WINDOWS</includepath><invalid></invalid>
// </language>
// </section>
// </cdtprojectproperties>
public void testNotValid() throws Exception {
vaidateCorrectErrorHandling(readTaggedComment("badXML1"));
vaidateCorrectErrorHandling(readTaggedComment("badXML2"));
vaidateCorrectErrorHandling(readTaggedComment("badXML3"));
vaidateCorrectErrorHandling(readTaggedComment("badXML4"));
vaidateCorrectErrorHandling(readTaggedComment("badXML5")); // missing <language> tag
vaidateCorrectErrorHandling(readTaggedComment("badXML6")); // missing <value> tag
vaidateCorrectErrorHandling(readTaggedComment("badXML7")); // extra <value> tag
vaidateCorrectErrorHandling(readTaggedComment("badXML8"));
}
}

View file

@ -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);
}
}

View file

@ -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,

View file

@ -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

View file

@ -2841,6 +2841,10 @@
</extension>
<extension
point="org.eclipse.ui.exportWizards">
<category
id="org.eclipse.cdt.ui.exportWizardCategory"
name="%exportWizard.CDTCategory.name">
</category>
<wizard
category="org.eclipse.cdt.ui.exportWizardCategory"
class="org.eclipse.cdt.internal.ui.wizards.indexwizards.TeamProjectIndexExportWizard"
@ -2854,10 +2858,16 @@
%teamProjectIndexExportWizard.description
</description>
</wizard>
<category
id="org.eclipse.cdt.ui.exportWizardCategory"
name="%exportWizard.CDTCategory.name">
</category>
<wizard
category="org.eclipse.cdt.ui.exportWizardCategory"
class="org.eclipse.cdt.internal.ui.wizards.settingswizards.ProjectSettingsExportWizard"
icon="icons/obj16/hfolder_obj.gif"
id="org.eclipse.cdt.ui.projectSettingsExportWizard"
name="%projectSettingsIndexExportWizard.name">
<selection
class="org.eclipse.core.resources.IProject">
</selection>
</wizard>
</extension>
<extension
id="TemplateEngineWizard"
@ -2970,5 +2980,22 @@
targetId="org.eclipse.cdt.ui.cCode">
</hyperlinkDetector>
</extension>
<extension
point="org.eclipse.ui.importWizards">
<category
id="org.eclipse.cdt.ui.importWizardCategory"
name="%importWizard.CDTCategory.name">
</category>
<wizard
category="org.eclipse.cdt.ui.importWizardCategory"
class="org.eclipse.cdt.internal.ui.wizards.settingswizards.ProjectSettingsImportWizard"
icon="icons/obj16/hfolder_obj.gif"
id="org.eclipse.cdt.ui.projectSettingsImportWizard"
name="%projectSettingsIndexExportWizard.name">
<selection
class="org.eclipse.core.resources.IProject">
</selection>
</wizard>
</extension>
</plugin>

View file

@ -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<ISettingsProcessor> processors);
/**
* Returns a list of all the available settings processors.
*/
List<ISettingsProcessor> getSettingsProcessors();
/**
* Returns a list of the settings processors that were selected by the user.
*/
List<ISettingsProcessor> 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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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<ICLanguageSettingEntry> includes = new ArrayList<ICLanguageSettingEntry>();
List<Element> 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);
}
}

View file

@ -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<ICLanguageSettingEntry> macros = new ArrayList<ICLanguageSettingEntry>();
List<Element> 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 <name> element"); //$NON-NLS-1$
if(value == null)
throw new SettingsImportExportException("There must be one <value> 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);
}
}

View file

@ -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;
}

View file

@ -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<ISettingsProcessor> 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$
}
}

View file

@ -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();
}
}

View file

@ -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.<ISettingsProcessor>emptyList());
}
/*
* Collects the importers that can be applied to the file and displays
* them to the user.
*/
public void fileSelected(IProjectSettingsWizardPage page) {
List<ImporterSectionPair> 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<ISettingsProcessor> importersToDisplay = new ArrayList<ISettingsProcessor>();
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<ISettingsProcessor> selectedImporters = page.getSelectedSettingsProcessors();
try {
List<ImporterSectionPair> 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<ImporterSectionPair> extractSectionsFromFile(IProjectSettingsWizardPage page) throws FileNotFoundException, SettingsImportExportException {
// get the file path that the user input
String filePath = page.getDestinationFilePath();
// get all the importers
Map<String,ISettingsProcessor> importers = new HashMap<String,ISettingsProcessor>();
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 <section> elements
Element root = document.getDocumentElement();
List<Element> sections = XMLUtils.extractChildElements(root, ProjectSettingsExportStrategy.SECTION_ELEMENT);
List<ImporterSectionPair> pairs = new ArrayList<ImporterSectionPair>();
// 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);
}
}
}

View file

@ -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();
}
}

View file

@ -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);
}
}

View file

@ -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<ISettingsProcessor> 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.<ISettingsProcessor>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<ISettingsProcessor> getSettingsProcessors() {
return Collections.unmodifiableList(processors);
}
public List<ISettingsProcessor> getSelectedSettingsProcessors() {
List<ISettingsProcessor> selected = new ArrayList<ISettingsProcessor>();
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<ISettingsProcessor> 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<ICProject> 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<ICConfigurationDescription> 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<ICProject> getAllOpenCProjects() {
List<ICProject> projects = new ArrayList<ICProject>();
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());
// }
// });
// }
}

View file

@ -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);
}
}

View file

@ -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<String,ICLanguageSetting> languageMap = new HashMap<String,ICLanguageSetting>();
for(ICLanguageSetting language : languageSettings) {
languageMap.put(language.getName(), language);
}
List<Element> 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);
}
}
}

View file

@ -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<Element> extractChildElements(Element node, String childElementName) throws SettingsImportExportException {
List<Element> extracted = new ArrayList<Element>();
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;
}
}

View file

@ -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

View file

@ -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.

View file

@ -1501,7 +1501,7 @@
<extension
point="org.eclipse.ui.importWizards">
<wizard
category="org.eclipse.cdt.ui.import"
category="org.eclipse.cdt.ui.importWizardCategory"
icon="icons/obj16/c_app.gif"
name="%importExecutableWizard.name"
class="org.eclipse.cdt.debug.ui.importexecutable.ImportExecutableWizard"
@ -1510,9 +1510,6 @@
%importExecutableWizard.description
</description>
</wizard>
<category
id="org.eclipse.cdt.ui.import"
name="%importCPPCategory.name"/>
</extension>
<!-- Source Not Found Editor -->
<extension