diff --git a/api.debugger/manifest.mf b/api.debugger/manifest.mf
--- a/api.debugger/manifest.mf
+++ b/api.debugger/manifest.mf
@@ -2,3 +2,4 @@
OpenIDE-Module: org.netbeans.api.debugger/1
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/Bundle.properties
OpenIDE-Module-Specification-Version: 1.16
+OpenIDE-Module-Layer: org/netbeans/api/debugger/layer.xml
diff --git a/api.debugger/src/org/netbeans/api/debugger/Bundle.properties b/api.debugger/src/org/netbeans/api/debugger/Bundle.properties
--- a/api.debugger/src/org/netbeans/api/debugger/Bundle.properties
+++ b/api.debugger/src/org/netbeans/api/debugger/Bundle.properties
@@ -48,3 +48,6 @@
# {2} supported languages
# {3} created engines
USG_DEBUG_SESSION_START=Debugger session {0} started at {1} for {2}
+
+# Options export
+Debugger.Options.Export.displayName=Debugger
diff --git a/core.ui/src/org/netbeans/core/ui/options/filetypes/Bundle.properties b/core.ui/src/org/netbeans/core/ui/options/filetypes/Bundle.properties
--- a/core.ui/src/org/netbeans/core/ui/options/filetypes/Bundle.properties
+++ b/core.ui/src/org/netbeans/core/ui/options/filetypes/Bundle.properties
@@ -89,3 +89,6 @@
OpenAsPanel.title=Open as...
OpenAsPanel.open=Open
OpenAsPanel.AD=Choose type of file
+
+# display name for options export
+Files.Options.Export.displayName=Files
diff --git a/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties b/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties
--- a/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties
+++ b/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties
@@ -255,3 +255,9 @@
# Keywords for quick-search
KW_General=Proxy, General Options
+
+# Display name for options export
+General.Options.Export.Category.displayName=General
+General.Options.Export.displayName=General
+Other.Options.Export.displayName=All Other Unspecified
+netbeans.conf.Options.Export.displayName=Custom netbeans.conf
diff --git a/core.ui/src/org/netbeans/core/ui/resources/layer.xml b/core.ui/src/org/netbeans/core/ui/resources/layer.xml
--- a/core.ui/src/org/netbeans/core/ui/resources/layer.xml
+++ b/core.ui/src/org/netbeans/core/ui/resources/layer.xml
@@ -713,4 +713,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core.windows/src/org/netbeans/core/windows/resources/Bundle.properties b/core.windows/src/org/netbeans/core/windows/resources/Bundle.properties
--- a/core.windows/src/org/netbeans/core/windows/resources/Bundle.properties
+++ b/core.windows/src/org/netbeans/core/windows/resources/Bundle.properties
@@ -45,3 +45,6 @@
Actions/Window=Window
Menu/Window=&Window
+
+# Options export
+Toolbars.Options.Export.displayName=Toolbars
diff --git a/core.windows/src/org/netbeans/core/windows/resources/layer.xml b/core.windows/src/org/netbeans/core/windows/resources/layer.xml
--- a/core.windows/src/org/netbeans/core/windows/resources/layer.xml
+++ b/core.windows/src/org/netbeans/core/windows/resources/layer.xml
@@ -307,4 +307,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/db/src/org/netbeans/modules/db/explorer/Bundle.properties b/db/src/org/netbeans/modules/db/explorer/Bundle.properties
--- a/db/src/org/netbeans/modules/db/explorer/Bundle.properties
+++ b/db/src/org/netbeans/modules/db/explorer/Bundle.properties
@@ -37,3 +37,6 @@
ERR_CONN_ALREADY_EXISTS = The connection with the name {0} already exists
MSG_TestFailed = The connection {0} does not appear to have a valid connection to the database: {1}
EXC_DerbyCreateDatabaseUnicode=Unable to create the database because the Derby network driver does not support multibyte characters.
+
+# Options export
+Databases.Options.Export.displayName=Databases
diff --git a/db/src/org/netbeans/modules/db/resources/mf-layer.xml b/db/src/org/netbeans/modules/db/resources/mf-layer.xml
--- a/db/src/org/netbeans/modules/db/resources/mf-layer.xml
+++ b/db/src/org/netbeans/modules/db/resources/mf-layer.xml
@@ -614,5 +614,13 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/diff/src/org/netbeans/modules/diff/Bundle.properties b/diff/src/org/netbeans/modules/diff/Bundle.properties
--- a/diff/src/org/netbeans/modules/diff/Bundle.properties
+++ b/diff/src/org/netbeans/modules/diff/Bundle.properties
@@ -89,3 +89,6 @@
ACSD_PatchDialog=This dialog allows you to choose patch
CTL_PatchDialog_FileFilter = Patch Files (*.diff, *.patch)
+
+# Options Export
+Diff.Options.Export.displayName=Diff
diff --git a/diff/src/org/netbeans/modules/diff/mf-layer.xml b/diff/src/org/netbeans/modules/diff/mf-layer.xml
--- a/diff/src/org/netbeans/modules/diff/mf-layer.xml
+++ b/diff/src/org/netbeans/modules/diff/mf-layer.xml
@@ -79,7 +79,16 @@
-
+
+
+
+
+
+
+
+
+
+
diff --git a/editor/src/org/netbeans/modules/editor/Bundle.properties b/editor/src/org/netbeans/modules/editor/Bundle.properties
--- a/editor/src/org/netbeans/modules/editor/Bundle.properties
+++ b/editor/src/org/netbeans/modules/editor/Bundle.properties
@@ -172,3 +172,7 @@
hyperlinks=Hyperlinks
synchronized-text-blocks-ext=Text Boxes (Editable)
synchronized-text-blocks-ext-slave=Text Boxes (Synchronized)
+
+# Options Export
+Editor.Export.Category.displayName=Editor
+IndentEngine.Options.Export.displayName=Indent Engines
diff --git a/editor/src/org/netbeans/modules/editor/resources/layer.xml b/editor/src/org/netbeans/modules/editor/resources/layer.xml
--- a/editor/src/org/netbeans/modules/editor/resources/layer.xml
+++ b/editor/src/org/netbeans/modules/editor/resources/layer.xml
@@ -380,5 +380,14 @@
-
+
+
+
+
+
+
+
+
+
+
diff --git a/favorites/src/org/netbeans/modules/favorites/Bundle.properties b/favorites/src/org/netbeans/modules/favorites/Bundle.properties
--- a/favorites/src/org/netbeans/modules/favorites/Bundle.properties
+++ b/favorites/src/org/netbeans/modules/favorites/Bundle.properties
@@ -70,3 +70,8 @@
OpenIDE-Module-Display-Category=Infrastructure
OpenIDE-Module-Short-Description=Support for organizing favorite files.
OpenIDE-Module-Long-Description=Favorites module enables you to create a view of files specifically relevant to your work, simply access them at one common place.
+
+# Options Export
+Templates.Options.Export.Category.displayName=Templates
+Templates.Options.Export.displayName=Templates
+Favorites.Options.Export.displayName=Favorites
diff --git a/favorites/src/org/netbeans/modules/favorites/resources/layer.xml b/favorites/src/org/netbeans/modules/favorites/resources/layer.xml
--- a/favorites/src/org/netbeans/modules/favorites/resources/layer.xml
+++ b/favorites/src/org/netbeans/modules/favorites/resources/layer.xml
@@ -146,5 +146,22 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/form/src/org/netbeans/modules/form/Bundle.properties b/form/src/org/netbeans/modules/form/Bundle.properties
--- a/form/src/org/netbeans/modules/form/Bundle.properties
+++ b/form/src/org/netbeans/modules/form/Bundle.properties
@@ -938,3 +938,6 @@
# Null item display name for EnumEditor combobox
CTL_NullText=null
+
+# Options export
+Form.Options.Export.displayName=GUI Builder
diff --git a/form/src/org/netbeans/modules/form/resources/layer.xml b/form/src/org/netbeans/modules/form/resources/layer.xml
--- a/form/src/org/netbeans/modules/form/resources/layer.xml
+++ b/form/src/org/netbeans/modules/form/resources/layer.xml
@@ -688,4 +688,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/html/src/org/netbeans/modules/html/mf-layer.xml b/html/src/org/netbeans/modules/html/mf-layer.xml
--- a/html/src/org/netbeans/modules/html/mf-layer.xml
+++ b/html/src/org/netbeans/modules/html/mf-layer.xml
@@ -231,5 +231,13 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/html/src/org/netbeans/modules/html/palette/Bundle.properties b/html/src/org/netbeans/modules/html/palette/Bundle.properties
--- a/html/src/org/netbeans/modules/html/palette/Bundle.properties
+++ b/html/src/org/netbeans/modules/html/palette/Bundle.properties
@@ -50,4 +50,7 @@
#HTMLPaletteActions
MSG_ErrorNoFocusedDocument=No document selected. Please select a document to insert the item into.
-ACT_OpenHTMLCustomizer=&HTML/JSP Code Clips
\ No newline at end of file
+ACT_OpenHTMLCustomizer=&HTML/JSP Code Clips
+
+# Options export
+HTMLPalette.Options.Export.displayName=HTML Palette
diff --git a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/Bundle.properties b/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/Bundle.properties
--- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/Bundle.properties
+++ b/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/Bundle.properties
@@ -201,3 +201,6 @@
MSG_DeployOnSave_Deployed={0} deployed.
MSG_DeployOnSave_Failed={0} failed.
MSG_DeployOnSave_Unsupported={0} failed. Server suspended.
+
+# Options export
+J2EE.Options.Export.displayName=Java EE
diff --git a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/layer.xml b/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/layer.xml
--- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/layer.xml
+++ b/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/layer.xml
@@ -136,4 +136,12 @@
+
+
+
+
+
+
+
+
diff --git a/java.platform/src/org/netbeans/modules/java/platform/resources/Bundle.properties b/java.platform/src/org/netbeans/modules/java/platform/resources/Bundle.properties
--- a/java.platform/src/org/netbeans/modules/java/platform/resources/Bundle.properties
+++ b/java.platform/src/org/netbeans/modules/java/platform/resources/Bundle.properties
@@ -46,3 +46,6 @@
Templates/Services/Platforms/org-netbeans-api-java-Platform=Java Platforms
Templates/Services/Platforms=Platforms
Templates/Services=Services
+
+# Options export
+JavaPlatform.Options.Export.displayName=Java Platforms
diff --git a/java.platform/src/org/netbeans/modules/java/platform/resources/layer.xml b/java.platform/src/org/netbeans/modules/java/platform/resources/layer.xml
--- a/java.platform/src/org/netbeans/modules/java/platform/resources/layer.xml
+++ b/java.platform/src/org/netbeans/modules/java/platform/resources/layer.xml
@@ -82,4 +82,12 @@
+
+
+
+
+
+
+
+
diff --git a/localhistory/src/org/netbeans/modules/localhistory/resources/Bundle.properties b/localhistory/src/org/netbeans/modules/localhistory/resources/Bundle.properties
--- a/localhistory/src/org/netbeans/modules/localhistory/resources/Bundle.properties
+++ b/localhistory/src/org/netbeans/modules/localhistory/resources/Bundle.properties
@@ -40,3 +40,4 @@
## svn-layer.xml
Actions/LocalHistory=Local History
OptionsDialog/Actions/LocalHistory=Local History
+LocalHistory.Options.Export.displayName=Local History
diff --git a/localhistory/src/org/netbeans/modules/localhistory/resources/layer.xml b/localhistory/src/org/netbeans/modules/localhistory/resources/layer.xml
--- a/localhistory/src/org/netbeans/modules/localhistory/resources/layer.xml
+++ b/localhistory/src/org/netbeans/modules/localhistory/resources/layer.xml
@@ -81,5 +81,13 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/nbbuild/build.xml b/nbbuild/build.xml
--- a/nbbuild/build.xml
+++ b/nbbuild/build.xml
@@ -601,7 +601,7 @@
-
+
@@ -2070,4 +2070,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/o.n.upgrader/src/org/netbeans/upgrade/AutoUpgrade.java b/o.n.upgrader/src/org/netbeans/upgrade/AutoUpgrade.java
--- a/o.n.upgrader/src/org/netbeans/upgrade/AutoUpgrade.java
+++ b/o.n.upgrader/src/org/netbeans/upgrade/AutoUpgrade.java
@@ -79,8 +79,12 @@
if (!showUpgradeDialog (sourceFolder)) {
throw new org.openide.util.UserCancelException ();
}
- doUpgrade (sourceFolder, version[0]);
- //support for non standard configuration files
+ // less than 6.5
+ if (version[0].compareTo("6.5") < 0) { //NOI18N
+ doUpgrade (sourceFolder, version[0]);
+ }
+ // Till 6.1 support for non standard configuration files and since
+ // 6.5 it is standard way of import.
doNonStandardUpgrade(sourceFolder, version[0]);
//#75324 NBplatform settings are not imported
upgradeBuildProperties(sourceFolder, version);
@@ -215,8 +219,17 @@
File userdir = new File(System.getProperty("netbeans.user", "")); // NOI18N
java.util.Set includeExclude;
try {
- InputStream is = AutoUpgrade.class.getResourceAsStream("nonstandard" + oldVersion);
- if (is == null) return;
+ InputStream is;
+ if (oldVersion.compareTo("6.5") < 0) { //NOI18N
+ // less than 6.5
+ is = AutoUpgrade.class.getResourceAsStream("nonstandard" + oldVersion); // NOI18N
+ if (is == null) return;
+ } else {
+ // 6.5 or greater
+ File netBeansDir = InstalledFileLocator.getDefault().locate("modules", null, false).getParentFile().getParentFile(); //NOI18N
+ File importFile = new File(netBeansDir, "etc/netbeans.import"); //NOI18N
+ is = new FileInputStream(importFile);
+ }
Reader r = new InputStreamReader(is, "utf-8"); // NOI18N
includeExclude = IncludeExclude.create(r);
r.close();
diff --git a/options.api/arch.xml b/options.api/arch.xml
--- a/options.api/arch.xml
+++ b/options.api/arch.xml
@@ -45,7 +45,7 @@
]>
@@ -1099,6 +1099,32 @@
your implementation of AdvancedCategory there (*.instance file). Standard
file systems sorting mechanism is used.
+
+ Use OptionsExport/<MyCategory> folder for registration of items for export/import
+ of options. Registration in layers looks as follows
+
+ <folder name="OptionsExport">
+ <!-- category -->
+ <folder name="MyCategory">
+ <!-- category display name -->
+ <attr name="displayName"
+ bundlevalue="org.netbeans.modules.mymodule.options.Bundle#Category_Display_Name"/>
+ <!-- item -->
+ <file name="MyItem">
+ <attr name="displayName" stringvalue="org.netbeans.modules.mymodule.options.Bundle#Item_Display_Name"/>
+ <!-- include regex pattern rooted to userdir -->
+ <attr name="include" stringvalue="config/Preferences/org/netbeans/modules/mymodule/.*|config/mymodule/.*"/>
+ <!-- exclude regex pattern rooted to userdir -->
+ <attr name="exclude" stringvalue="config/mymodule/obsolete/.*"/>
+ </file>
+ </folder>
+ </folder>
+
+
@@ -1137,4 +1163,49 @@
+
+
+
+
+
+
+ No deprecation.
+
+
+
+
+
+
+
+
+ Uses org.netbeans.modules.options.api.OptionsHeight and OptionsWidth properties.
+
+
+
diff --git a/options.api/nbproject/project.xml b/options.api/nbproject/project.xml
--- a/options.api/nbproject/project.xml
+++ b/options.api/nbproject/project.xml
@@ -47,6 +47,15 @@
org.netbeans.modules.options.api
+ org.jdesktop.layout
+
+
+
+ 1
+ 1.7
+
+
+
org.netbeans.spi.quicksearch
@@ -55,6 +64,14 @@
+ org.netbeans.swing.outline
+
+
+
+ 1.3
+
+
+
org.openide.awt
diff --git a/options.api/src/org/netbeans/modules/options/Bundle.properties b/options.api/src/org/netbeans/modules/options/Bundle.properties
--- a/options.api/src/org/netbeans/modules/options/Bundle.properties
+++ b/options.api/src/org/netbeans/modules/options/Bundle.properties
@@ -63,9 +63,15 @@
CTL_Font_And_Color_Options_Title=Fonts & Colors
CTL_Keymap_Options=&Keymap
CTL_Keymap_Options_Title=Keymap
+
+CTL_Export=Expor&t
+CTL_Import=&Import
+
#A11Y
ACS_OKButton=OK
ACS_ClassicButton= Invokes Advanced Options dialog
ACS_OptionsPanel=Options Dialog
+ACS_Export=Export Options
+ACS_Import=Import Options
QuickSearch/GoToOption=Options
diff --git a/options.api/src/org/netbeans/modules/options/OptionsDisplayerImpl.java b/options.api/src/org/netbeans/modules/options/OptionsDisplayerImpl.java
--- a/options.api/src/org/netbeans/modules/options/OptionsDisplayerImpl.java
+++ b/options.api/src/org/netbeans/modules/options/OptionsDisplayerImpl.java
@@ -57,6 +57,7 @@
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import org.netbeans.api.options.OptionsDisplayer;
+import org.netbeans.modules.options.export.OptionsChooserPanel;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.DialogDescriptor;
@@ -93,6 +94,10 @@
static final LookupListener lookupListener = new LookupListenerImpl();
/** Advanced Options button. */
private JButton bClassic;
+ /** Export Options button */
+ private JButton btnExport;
+ /** Import Options button */
+ private JButton btnImport;
public OptionsDisplayerImpl (boolean modal) {
this.modal = modal;
@@ -149,14 +154,18 @@
bClassic = (JButton) loc(new JButton(), "CTL_Classic");//NOI18N
bClassic.getAccessibleContext().setAccessibleDescription(loc("ACS_ClassicButton"));//NOI18N
setVisibleAdvancedOptionsButton();
+ btnExport = (JButton) loc(new JButton(), "CTL_Export");//NOI18N
+ btnExport.getAccessibleContext().setAccessibleDescription(loc("ACS_Export"));//NOI18N
+ btnImport = (JButton) loc(new JButton(), "CTL_Import");//NOI18N
+ btnImport.getAccessibleContext().setAccessibleDescription(loc("ACS_Import"));//NOI18N
boolean isMac = Utilities.isMac();
Object[] options = new Object[2];
options[0] = isMac ? DialogDescriptor.CANCEL_OPTION : bOK;
options[1] = isMac ? bOK : DialogDescriptor.CANCEL_OPTION;
descriptor = new DialogDescriptor(optionsPanel,title,modal,options,DialogDescriptor.OK_OPTION,DialogDescriptor.DEFAULT_ALIGN, null, null, false);
- descriptor.setAdditionalOptions(new Object[] {bClassic});
+ descriptor.setAdditionalOptions(new Object[] {bClassic, btnExport, btnImport});
descriptor.setHelpCtx(optionsPanel.getHelpCtx());
- OptionsPanelListener listener = new OptionsPanelListener(descriptor, optionsPanel, bOK, bClassic);
+ OptionsPanelListener listener = new OptionsPanelListener(descriptor, optionsPanel, bOK, bClassic, btnExport, btnImport);
descriptor.setButtonListener(listener);
optionsPanel.addPropertyChangeListener(listener);
synchronized(lookupListener) {
@@ -227,18 +236,24 @@
private OptionsPanel optionsPanel;
private JButton bOK;
private JButton bClassic;
+ private JButton btnExport;
+ private JButton btnImport;
OptionsPanelListener (
DialogDescriptor descriptor,
OptionsPanel optionsPanel,
JButton bOK,
- JButton bClassic
+ JButton bClassic,
+ JButton btnExport,
+ JButton btnImport
) {
this.descriptor = descriptor;
this.optionsPanel = optionsPanel;
this.bOK = bOK;
this.bClassic = bClassic;
+ this.btnExport = btnExport;
+ this.btnImport = btnImport;
}
public void propertyChange (PropertyChangeEvent ev) {
@@ -309,6 +324,11 @@
Exceptions.printStackTrace(ex);
}
} // classic
+ else if (e.getSource() == btnExport) {
+ OptionsChooserPanel.showExportDialog();
+ } else if (e.getSource() == btnImport) {
+ OptionsChooserPanel.showImportDialog();
+ }
}
}
diff --git a/options.api/src/org/netbeans/modules/options/advanced/Bundle.properties b/options.api/src/org/netbeans/modules/options/advanced/Bundle.properties
--- a/options.api/src/org/netbeans/modules/options/advanced/Bundle.properties
+++ b/options.api/src/org/netbeans/modules/options/advanced/Bundle.properties
@@ -43,3 +43,4 @@
CTL_Advanced_Options_Title=Miscellaneous
CTL_Advanced_Options_Description=Miscellaneous
AdvancedPanel.tabbedPanel.AD=Miscellaneous tabbed panel
+Advanced.Export.Category=Miscellaneous
diff --git a/options.api/src/org/netbeans/modules/options/export/Bundle.properties b/options.api/src/org/netbeans/modules/options/export/Bundle.properties
new file mode 100644
--- /dev/null
+++ b/options.api/src/org/netbeans/modules/options/export/Bundle.properties
@@ -0,0 +1,63 @@
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+#
+# The contents of this file are subject to the terms of either the GNU
+# General Public License Version 2 only ("GPL") or the Common
+# Development and Distribution License("CDDL") (collectively, the
+# "License"). You may not use this file except in compliance with the
+# License. You can obtain a copy of the License at
+# http://www.netbeans.org/cddl-gplv2.html
+# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+# specific language governing permissions and limitations under the
+# License. When distributing the software, include this License Header
+# Notice in each file and include the License file at
+# nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the GPL Version 2 section of the License file that
+# accompanied this code. If applicable, add the following below the
+# License Header, with the fields enclosed by brackets [] replaced by
+# your own identifying information:
+# "Portions Copyrighted [year] [name of copyright owner]"
+#
+# Contributor(s):
+#
+# The Original Software is NetBeans. The Initial Developer of the Original
+# Software is Sun Microsystems, Inc. Portions Copyright 1997-2009 Sun
+# Microsystems, Inc. All Rights Reserved.
+#
+# If you wish your version of this file to be governed by only the CDDL
+# or only the GPL Version 2, indicate your decision by adding
+# "[Contributor] elects to include this software in this distribution
+# under the [CDDL or GPL Version 2] license." If you do not indicate a
+# single choice of license, a recipient has the option to distribute
+# your version of this file under either the CDDL, the GPL Version 2 or
+# to extend the choice of license to its licensees as provided above.
+# However, if you add GPL Version 2 code and therefore, elected the GPL
+# Version 2 license, then the option applies only if the new code is
+# made subject to such option by the copyright holder.
+
+OptionsChooserPanel.lblHint.text=Select Options for Export:
+OptionsChooserPanel.outline.header.tree=Available Options
+OptionsChooserPanel.outline.header.included=Included
+OptionsChooserPanel.lblFile.text=Target zip file:
+OptionsChooserPanel.btnBrowse=Browse...
+OptionsChooserPanel.file.warning=Please, select a valid target zip file
+OptionsChooserPanel.nooption.warning=Please, select something to export
+OptionsChooserPanel.file.chooser.title=Select target zip file
+OptionsChooserPanel.file.chooser.approve=OK
+# 0 - zip file path
+OptionsChooserPanel.invalid.zipfile=Invalid zip file: {0}
+# 0 - file path
+OptionsChooserPanel.export.zip.error=Writing to file {0} failed.
+OptionsChooserPanel.export.title=Select Options to Export
+OptionsChooserPanel.export.status.text=Options Export Finished.
+OptionsChooserPanel.import.title=Select Options to Import
+OptionsChooserPanel.import.lblFile.text=Import Source:
+OptionsChooserPanel.import.lblHint.text=Select Options for Import:
+OptionsChooserPanel.import.file.warning=Please, select a valid zip file or userdir
+OptionsChooserPanel.import.nooption.warning=Please, select something to import
+OptionsChooserPanel.import.error=Error while importing options.
+OptionsChooserPanel.import.file.chooser.title=Select zip file or userdir
+OptionsChooserPanel.restart.title=Import successfully finished
+OptionsChooserPanel.restart.message=Restart of application is needed to initiate imported options. Would you like to restart now?
diff --git a/options.api/src/org/netbeans/modules/options/export/OptionsChooserPanel.form b/options.api/src/org/netbeans/modules/options/export/OptionsChooserPanel.form
new file mode 100644
--- /dev/null
+++ b/options.api/src/org/netbeans/modules/options/export/OptionsChooserPanel.form
@@ -0,0 +1,86 @@
+
+
+
diff --git a/options.api/src/org/netbeans/modules/options/export/OptionsChooserPanel.java b/options.api/src/org/netbeans/modules/options/export/OptionsChooserPanel.java
new file mode 100644
--- /dev/null
+++ b/options.api/src/org/netbeans/modules/options/export/OptionsChooserPanel.java
@@ -0,0 +1,571 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2009 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.options.export;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.logging.Logger;
+import javax.swing.Icon;
+import javax.swing.JCheckBox;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTable;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.filechooser.FileFilter;
+import javax.swing.plaf.UIResource;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreeNode;
+import org.netbeans.swing.outline.DefaultOutlineModel;
+import org.netbeans.swing.outline.Outline;
+import org.netbeans.swing.outline.RenderDataProvider;
+import org.netbeans.swing.outline.RowModel;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.LifecycleManager;
+import org.openide.awt.StatusDisplayer;
+import org.openide.filesystems.FileChooserBuilder;
+import org.openide.util.Exceptions;
+import org.openide.util.ImageUtilities;
+import org.openide.util.NbBundle;
+
+/**
+ * Export/import options panel.
+ * @author Jiri Skrivanek
+ */
+public final class OptionsChooserPanel extends JPanel {
+
+ private static final Logger LOGGER = Logger.getLogger(OptionsChooserPanel.class.getName());
+ private DialogDescriptor dialogDescriptor;
+ private PanelType panelType;
+
+ /** To distinguish between import and export panels. */
+ private enum PanelType {
+
+ EXPORT, IMPORT
+ };
+
+ private OptionsChooserPanel() {
+ initComponents();
+ }
+
+ /** Shows panel for export of options. */
+ public static void showExportDialog() {
+ LOGGER.fine("showExportDialog"); //NOI18N
+ File sourceUserdir = new File(System.getProperty("netbeans.user")); // NOI18N
+ final OptionsChooserPanel optionsChooserPanel = new OptionsChooserPanel();
+ optionsChooserPanel.scrollPaneOptions.setViewportView(optionsChooserPanel.getOutline(sourceUserdir));
+ optionsChooserPanel.txtFile.getDocument().addDocumentListener(new DocumentListener() {
+
+ public void insertUpdate(DocumentEvent e) {
+ optionsChooserPanel.dialogDescriptor.setValid(optionsChooserPanel.isPanelValid());
+ }
+
+ public void removeUpdate(DocumentEvent e) {
+ optionsChooserPanel.dialogDescriptor.setValid(optionsChooserPanel.isPanelValid());
+ }
+
+ public void changedUpdate(DocumentEvent e) {
+ optionsChooserPanel.dialogDescriptor.setValid(optionsChooserPanel.isPanelValid());
+ }
+ });
+
+ DialogDescriptor dd = new DialogDescriptor(
+ optionsChooserPanel,
+ NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.export.title"),
+ true,
+ new Object[]{DialogDescriptor.OK_OPTION, DialogDescriptor.CANCEL_OPTION},
+ DialogDescriptor.OK_OPTION,
+ DialogDescriptor.DEFAULT_ALIGN,
+ null,
+ null);
+ // add bottom user notification area
+ dd.createNotificationLineSupport();
+ dd.setValid(false);
+ optionsChooserPanel.setDialogDescriptor(dd);
+ DialogDisplayer.getDefault().createDialog(dd).setVisible(true);
+
+ if (DialogDescriptor.OK_OPTION.equals(dd.getValue())) {
+ String targetPath = optionsChooserPanel.getSelectedFilePath();
+ try {
+ OptionsExportModel.getInstance().createZipFile(new File(targetPath), sourceUserdir);
+ } catch (IOException ex) {
+ Exceptions.attachLocalizedMessage(ex,
+ NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.export.zip.error", targetPath));
+ Exceptions.printStackTrace(ex);
+ }
+ StatusDisplayer.getDefault().setStatusText(
+ NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.export.status.text"));
+ LOGGER.fine("Export finished."); //NOI18N
+ }
+ }
+
+ /** Shows panel for import of options. */
+ public static void showImportDialog() {
+ LOGGER.fine("showImportDialog"); //NOI18N
+ OptionsChooserPanel optionsChooserPanel = new OptionsChooserPanel();
+ optionsChooserPanel.txtFile.setEditable(false);
+ optionsChooserPanel.lblFile.setText(NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.import.lblFile.text"));
+ optionsChooserPanel.lblHint.setText(NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.import.lblHint.text"));
+ optionsChooserPanel.panelType = PanelType.IMPORT;
+
+ DialogDescriptor dd = new DialogDescriptor(
+ optionsChooserPanel,
+ NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.import.title"),
+ true,
+ new Object[]{DialogDescriptor.OK_OPTION, DialogDescriptor.CANCEL_OPTION},
+ DialogDescriptor.OK_OPTION,
+ DialogDescriptor.DEFAULT_ALIGN,
+ null,
+ null);
+ dd.createNotificationLineSupport();
+ dd.setValid(false);
+ optionsChooserPanel.setDialogDescriptor(dd);
+ DialogDisplayer.getDefault().createDialog(dd).setVisible(true);
+
+ if (DialogDescriptor.OK_OPTION.equals(dd.getValue())) {
+ File targetUserdir = new File(System.getProperty("netbeans.user")); // NOI18N
+ try {
+ String sourcePath = optionsChooserPanel.getSelectedFilePath();
+ File source = new File(sourcePath);
+ if (source.isFile()) {
+ // zip file
+ OptionsExportModel.getInstance().extractZipFile(source, targetUserdir);
+ } else {
+ // userdir
+ OptionsExportModel.getInstance().copy(source, targetUserdir);
+ }
+ } catch (IOException ex) {
+ Exceptions.attachLocalizedMessage(ex,
+ NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.import.error"));
+ Exceptions.printStackTrace(ex);
+ }
+ LOGGER.fine("Import finished."); //NOI18N
+ // restart IDE
+ String title = NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.restart.title");
+ String message = NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.restart.message");
+ int restartNow = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
+ if (restartNow == JOptionPane.YES_OPTION) {
+ try {
+ new File(targetUserdir, "var/restart").createNewFile(); //NOI18N
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ LifecycleManager.getDefault().exit();
+ }
+ }
+ }
+
+ /** Returns outline view for displaying options for export/import. */
+ private Outline getOutline(File source) {
+ Outline outline = new Outline();
+ outline.setModel(DefaultOutlineModel.createOutlineModel(
+ getOptionsTreeModel(source),
+ new OptionsRowModel(),
+ true,
+ NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.outline.header.tree")));
+ outline.setRenderDataProvider(new OptionsTreeDataProvider());
+ outline.setRootVisible(false);
+ outline.getTableHeader().setReorderingAllowed(false);
+ outline.setColumnHidingAllowed(false);
+ outline.setDefaultRenderer(Boolean.class, new BooleanRenderer());
+ return outline;
+ }
+
+ /** Returns tree model based on current state of this model. */
+ private TreeModel getOptionsTreeModel(File source) {
+ LOGGER.fine("getOptionsTreeModel - source=" + source); //NOI18N
+ List relativePaths = null;
+ if (source.isFile()) {
+ try {
+ // zip file
+ relativePaths = OptionsExportModel.listZipFile(source);
+ } catch (IOException ex) {
+ Exceptions.attachLocalizedMessage(ex, NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.invalid.zipfile", source));
+ Exceptions.printStackTrace(ex);
+ }
+ } else {
+ // userdir
+ relativePaths = OptionsExportModel.getRelativePaths(source);
+ }
+ LOGGER.fine("relativePaths=" + relativePaths); //NOI18N
+ DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
+ for (OptionsExportModel.Category category : OptionsExportModel.getInstance().getCategories()) {
+ LOGGER.fine("category=" + category); //NOI18N
+ DefaultMutableTreeNode categoryNode = new DefaultMutableTreeNode(category);
+ List items = category.getItems();
+ for (OptionsExportModel.Item item : items) {
+ LOGGER.fine(" item=" + item); //NOI18N
+ if (item.isApplicable(relativePaths)) {
+ categoryNode.add(new DefaultMutableTreeNode(item));
+ }
+ }
+ if (categoryNode.getChildCount() != 0) {
+ // do not show category node if it has no children
+ rootNode.add(categoryNode);
+ updateCategoryNode(categoryNode);
+ }
+ }
+ return new DefaultTreeModel(rootNode);
+ }
+
+ private String getSelectedFilePath() {
+ return txtFile.getText();
+ }
+
+ private void setDialogDescriptor(DialogDescriptor dd) {
+ this.dialogDescriptor = dd;
+ }
+
+ /** Returns true if all user inputs in this panel are valid. */
+ private boolean isPanelValid() {
+ if (panelType == PanelType.IMPORT) {
+ if (txtFile.getText().length() == 0) {
+ dialogDescriptor.getNotificationLineSupport().setWarningMessage(NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.import.file.warning"));
+ } else if (!OptionsExportModel.getInstance().isEnabled()) {
+ dialogDescriptor.getNotificationLineSupport().setWarningMessage(NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.import.nooption.warning"));
+ } else {
+ dialogDescriptor.getNotificationLineSupport().clearMessages();
+ return true;
+ }
+ } else {
+ if (txtFile.getText().length() == 0 || !txtFile.getText().endsWith(".zip")) { //NOI18N
+ dialogDescriptor.getNotificationLineSupport().setWarningMessage(NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.file.warning"));
+ } else if (!OptionsExportModel.getInstance().isEnabled()) {
+ dialogDescriptor.getNotificationLineSupport().setWarningMessage(NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.nooption.warning"));
+ } else {
+ dialogDescriptor.getNotificationLineSupport().clearMessages();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ lblHint = new javax.swing.JLabel();
+ scrollPaneOptions = new javax.swing.JScrollPane();
+ lblFile = new javax.swing.JLabel();
+ txtFile = new javax.swing.JTextField();
+ btnBrowse = new javax.swing.JButton();
+
+ lblHint.setText(org.openide.util.NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.lblHint.text")); // NOI18N
+
+ lblFile.setText(org.openide.util.NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.lblFile.text")); // NOI18N
+
+ btnBrowse.setText(org.openide.util.NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.btnBrowse")); // NOI18N
+ btnBrowse.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnBrowseActionPerformed(evt);
+ }
+ });
+
+ org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+ .add(layout.createSequentialGroup()
+ .addContainerGap()
+ .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+ .add(scrollPaneOptions, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 580, Short.MAX_VALUE)
+ .add(layout.createSequentialGroup()
+ .add(lblFile)
+ .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
+ .add(txtFile, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 422, Short.MAX_VALUE)
+ .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
+ .add(btnBrowse))
+ .add(lblHint, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 580, Short.MAX_VALUE))
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+ .add(layout.createSequentialGroup()
+ .addContainerGap()
+ .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
+ .add(lblFile)
+ .add(txtFile, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+ .add(btnBrowse))
+ .add(18, 18, 18)
+ .add(lblHint)
+ .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
+ .add(scrollPaneOptions, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 370, Short.MAX_VALUE)
+ .addContainerGap())
+ );
+ }// //GEN-END:initComponents
+
+ private void btnBrowseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnBrowseActionPerformed
+ FileChooserBuilder fileChooserBuilder = new FileChooserBuilder(OptionsChooserPanel.class);
+ fileChooserBuilder.setDefaultWorkingDirectory(new File(System.getProperty("user.home"))); //NOI18N
+ fileChooserBuilder.setFileFilter(new FileNameExtensionFilter("*.zip", "zip")); //NOI18N
+ fileChooserBuilder.setApproveText(NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.file.chooser.approve"));
+ if (panelType == PanelType.IMPORT) {
+ fileChooserBuilder.setTitle(NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.import.file.chooser.title"));
+ } else {
+ fileChooserBuilder.setTitle(NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.file.chooser.title"));
+ }
+
+ JFileChooser fileChooser = fileChooserBuilder.createFileChooser();
+ if (JFileChooser.APPROVE_OPTION == fileChooser.showOpenDialog(this)) {
+ txtFile.setText(fileChooser.getSelectedFile().getAbsolutePath());
+ if (panelType == PanelType.IMPORT) {
+ scrollPaneOptions.setViewportView(getOutline(fileChooser.getSelectedFile()));
+ }
+ dialogDescriptor.setValid(isPanelValid());
+ }
+ }//GEN-LAST:event_btnBrowseActionPerformed
+
+
+ /** Custom BooleanRenderer to visualize PARTIAL state. Inspired by org.openide.explorer.propertysheet.Boolean3WayEditor. */
+ private static class BooleanRenderer extends JCheckBox implements TableCellRenderer, UIResource {
+
+ private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
+
+ public BooleanRenderer() {
+ super();
+ setHorizontalAlignment(JLabel.CENTER);
+ setBorderPainted(true);
+ }
+
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ if (isSelected) {
+ setForeground(table.getSelectionForeground());
+ super.setBackground(table.getSelectionBackground());
+ } else {
+ setForeground(table.getForeground());
+ setBackground(table.getBackground());
+ }
+ setSelected((value != null && ((Boolean) value).booleanValue()));
+ if (value == null) {
+ // visualize PARTIAL state
+ getModel().setArmed(true);
+ getModel().setPressed(true);
+ setSelected(true);
+ } else {
+ getModel().setArmed(false);
+ getModel().setPressed(false);
+ }
+
+ if (hasFocus) {
+ setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); //NOI18N
+ } else {
+ setBorder(noFocusBorder);
+ }
+
+ return this;
+ }
+ }
+
+ /** Defines presentation of table. */
+ private class OptionsRowModel implements RowModel {
+
+ public Class getColumnClass(int column) {
+ return Boolean.class;
+ }
+
+ public int getColumnCount() {
+ return 1;
+ }
+
+ public String getColumnName(int column) {
+ return NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.outline.header.included");
+ }
+
+ public Object getValueFor(Object node, int column) {
+ Object userObject = ((DefaultMutableTreeNode) node).getUserObject();
+ if (userObject instanceof OptionsExportModel.Category) {
+ // 3 states - see BooleanRenderer
+ if (((OptionsExportModel.Category) userObject).getState() == OptionsExportModel.State.ENABLED) {
+ return true;
+ } else if (((OptionsExportModel.Category) userObject).getState() == OptionsExportModel.State.DISABLED) {
+ return false;
+ } else {
+ return null;
+ }
+ } else if (userObject instanceof OptionsExportModel.Item) {
+ return ((OptionsExportModel.Item) userObject).isEnabled();
+ }
+ // root node
+ return null;
+ }
+
+ public boolean isCellEditable(Object node, int column) {
+ return column == 0;
+ }
+
+ public void setValueFor(Object node, int column, Object value) {
+ assert column == 0;
+ Object userObject = ((DefaultMutableTreeNode) node).getUserObject();
+ if (userObject instanceof OptionsExportModel.Category) {
+ if (Boolean.valueOf(value.toString())) {
+ ((OptionsExportModel.Category) userObject).setState(OptionsExportModel.State.ENABLED);
+ } else {
+ ((OptionsExportModel.Category) userObject).setState(OptionsExportModel.State.DISABLED);
+ }
+ } else if (userObject instanceof OptionsExportModel.Item) {
+ ((OptionsExportModel.Item) userObject).setEnabled(Boolean.valueOf(value.toString()));
+ // update parent category
+ Object parent = ((TreeNode) node).getParent();
+ updateCategoryNode((DefaultMutableTreeNode) parent);
+
+ }
+ dialogDescriptor.setValid(isPanelValid());
+ }
+ }
+
+ /** Update state of category node according to state of sub items. */
+ private static void updateCategoryNode(DefaultMutableTreeNode categoryNode) {
+ int enabledCount = 0;
+ for (int i = 0; i < categoryNode.getChildCount(); i++) {
+ Object userObject = ((DefaultMutableTreeNode) categoryNode.getChildAt(i)).getUserObject();
+ if (((OptionsExportModel.Item) userObject).isEnabled()) {
+ enabledCount++;
+ }
+ }
+ Object userObject = categoryNode.getUserObject();
+ OptionsExportModel.Category category = ((OptionsExportModel.Category) userObject);
+ if (enabledCount == 0) {
+ category.setState(OptionsExportModel.State.DISABLED);
+ } else if (enabledCount == categoryNode.getChildCount()) {
+ category.setState(OptionsExportModel.State.ENABLED);
+ } else {
+ category.setState(OptionsExportModel.State.PARTIAL);
+ }
+ }
+
+ /** Defines visual appearance of tree. */
+ private static class OptionsTreeDataProvider implements RenderDataProvider {
+
+ private static final Icon ICON = ImageUtilities.loadImageIcon("org/netbeans/modules/options/export/defaultNode.gif", true); //NOI18N
+
+ public Color getBackground(Object node) {
+ return null;
+ }
+
+ public String getDisplayName(Object node) {
+ Object userObject = ((DefaultMutableTreeNode) node).getUserObject();
+ if (userObject instanceof OptionsExportModel.Category) {
+ return ((OptionsExportModel.Category) userObject).getDisplayName();
+ }
+ if (userObject instanceof OptionsExportModel.Item) {
+ return ((OptionsExportModel.Item) userObject).getDisplayName();
+ }
+ // root node
+ return node.toString();
+ }
+
+ public Color getForeground(Object node) {
+ return null;
+ }
+
+ public Icon getIcon(Object o) {
+ return ICON;
+ }
+
+ public String getTooltipText(Object o) {
+ return null;
+ }
+
+ public boolean isHtmlDisplayName(Object o) {
+ return false;
+ }
+ }
+
+ /** FileFile for single extension. Remove it when JDK5 is obsolete and
+ * use FileNameExtensionFilter from JDK6. */
+ private static class FileNameExtensionFilter extends FileFilter {
+
+ private final String description;
+ private final String lowerCaseExtension;
+
+ public FileNameExtensionFilter(String description, String extension) {
+ assert extension != null;
+ this.description = description;
+ this.lowerCaseExtension = extension.toLowerCase();
+ }
+
+ @Override
+ public boolean accept(File f) {
+ if (f != null) {
+ if (f.isDirectory()) {
+ return true;
+ }
+ String fileName = f.getName();
+ int i = fileName.lastIndexOf('.');
+ if (i > 0 && i < fileName.length() - 1) {
+ String desiredExtension = fileName.substring(i + 1).toLowerCase();
+ if (desiredExtension.equals(lowerCaseExtension)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton btnBrowse;
+ private javax.swing.JLabel lblFile;
+ private javax.swing.JLabel lblHint;
+ private javax.swing.JScrollPane scrollPaneOptions;
+ private javax.swing.JTextField txtFile;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/options.api/src/org/netbeans/modules/options/export/OptionsExportModel.java b/options.api/src/org/netbeans/modules/options/export/OptionsExportModel.java
new file mode 100644
--- /dev/null
+++ b/options.api/src/org/netbeans/modules/options/export/OptionsExportModel.java
@@ -0,0 +1,588 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2009 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.options.export;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+import org.openide.filesystems.FileChangeAdapter;
+import org.openide.filesystems.FileChangeListener;
+import org.openide.filesystems.FileEvent;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileRenameEvent;
+import org.openide.filesystems.FileUtil;
+
+/**
+ * Model for export/import options. It reads {@code OptionsExport//- }
+ * from layers and evaluates whether items are applicable for export/import.
+ *
+ * @author Jiri Skrivanek
+ */
+public final class OptionsExportModel {
+
+ private static final Logger LOGGER = Logger.getLogger(OptionsExportModel.class.getName());
+ /** folder in layer file system where provider are searched for */
+ private static final String OPTIONS_EXPORT_FOLDER = "OptionsExport"; //NOI18N
+ private static OptionsExportModel instance;
+ // keep instance to not loose listener
+ private FileObject exportFolderFO;
+ private List categories;
+ // listen to changes in system filesystem (e.g. new module installed)
+ private final FileChangeListener exportFolderListener = new FileChangeAdapter() {
+
+ @Override
+ public void fileDeleted(FileEvent fe) {
+ categories = null;
+ }
+
+ @Override
+ public void fileRenamed(FileRenameEvent fe) {
+ categories = null;
+ }
+
+ @Override
+ public void fileDataCreated(FileEvent fe) {
+ categories = null;
+ }
+
+ @Override
+ public void fileChanged(FileEvent fe) {
+ categories = null;
+ }
+ };
+
+ private OptionsExportModel() {
+ exportFolderFO = FileUtil.getConfigFile(OPTIONS_EXPORT_FOLDER);
+ if (exportFolderFO != null) {
+ exportFolderFO.addFileChangeListener(FileUtil.weakFileChangeListener(exportFolderListener, exportFolderFO));
+ }
+ }
+
+ /** Returns instance of export options model.
+ * @return instance of export options model
+ */
+ static synchronized OptionsExportModel getInstance() {
+ if (instance == null) {
+ instance = new OptionsExportModel();
+ }
+ return instance;
+ }
+
+ /**
+ * Gets list of categories
+ * @return list of categories
+ */
+ List getCategories() {
+ if (categories == null) {
+ categories = loadCategories();
+ }
+ return categories;
+ }
+
+ /** Returns true if at least one item in this model is enabled.
+ * @return true if at least one item in this model is enabled.
+ */
+ boolean isEnabled() {
+ for (OptionsExportModel.Category category : getCategories()) {
+ for (OptionsExportModel.Item item : category.getItems()) {
+ if (item.isEnabled()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /** Copies files from source dir to target dir according to current state
+ * of model, i.e. only include/exclude patterns from enabled items are
+ * considered.
+ * @param targetUserdir target userdir
+ * @param sourceUserdir source userdir
+ * @throws java.io.IOException
+ */
+ void copy(File sourceUserdir, File targetUserdir) throws IOException {
+ LOGGER.fine("Copying from: "+ sourceUserdir + "\nto:" + targetUserdir); //NOI18N
+ List relativePaths = getApplicablePaths(getRelativePaths(sourceUserdir), getIncludePatterns(), getExcludePatterns());
+ if (!relativePaths.isEmpty() && !targetUserdir.exists()) {
+ if (!targetUserdir.mkdirs()) {
+ throw new IOException("Cannot create folder: " + targetUserdir.getAbsolutePath()); //NOI18N
+ }
+ }
+ for (String path : relativePaths) {
+ LOGGER.fine("Path=" + path); //NOI18N
+ copyFile(new File(sourceUserdir, path), new File(targetUserdir, path));
+ }
+ }
+
+ /** Extracts files from source zip file to target dir according to current state
+ * of model, i.e. only include/exclude patterns from enabled items are
+ * considered.
+ * @param sourceFile source zip file
+ * @param targetUserdir target userdir
+ */
+ void extractZipFile(File sourceFile, File targetUserdir) throws IOException {
+ LOGGER.fine("Extracting from:" + sourceFile + " to:" + targetUserdir); //NOI18N
+ List applicablePaths = getApplicablePaths(listZipFile(sourceFile), getIncludePatterns(), getExcludePatterns());
+ extractZipFile(sourceFile, targetUserdir, applicablePaths);
+ }
+
+ /** Creates zip file from source userdir according to current state
+ * of model, i.e. only include/exclude patterns from enabled items are
+ * considered.
+ * @param sourceUserdir source userdir
+ * @param targetFile target zip file
+ */
+ void createZipFile(File targetFile, File sourceUserdir) throws IOException {
+ LOGGER.fine("Creating file:" + targetFile + " from:" + sourceUserdir); //NOI18N
+ List applicablePaths = getApplicablePaths(getRelativePaths(sourceUserdir), getIncludePatterns(), getExcludePatterns());
+ createZipFile(targetFile, sourceUserdir, applicablePaths);
+ }
+
+ /** Returns set of include patterns in this model. */
+ private Set getIncludePatterns() {
+ Set includePatterns = new HashSet();
+ for (OptionsExportModel.Category category : getCategories()) {
+ for (OptionsExportModel.Item item : category.getItems()) {
+ if (item.isEnabled()) {
+ String include = item.getInclude();
+ if (include != null && include.length() > 0) {
+ includePatterns.add(Pattern.compile(include));
+ }
+ }
+ }
+ }
+ return includePatterns;
+ }
+
+ /** Returns set of exclude patterns in this model. */
+ private Set getExcludePatterns() {
+ Set excludePatterns = new HashSet();
+ for (OptionsExportModel.Category category : getCategories()) {
+ for (OptionsExportModel.Item item : category.getItems()) {
+ if (item.isEnabled()) {
+ String exclude = item.getExclude();
+ if (exclude != null && exclude.length() > 0) {
+ excludePatterns.add(Pattern.compile(exclude));
+ }
+ }
+ }
+ }
+ return excludePatterns;
+ }
+
+ /** Represents one item in UI and hold include/exclude patterns. */
+ static class Item {
+
+ private String displayName;
+ private String include;
+ private String exclude;
+ private boolean enabled = false;
+
+ public Item(String displayName, String include, String exclude) {
+ assert displayName != null : "Display name of export option item not defined in layer."; //NOI18N
+ this.displayName = displayName;
+ if (include == null) {
+ include = ""; //NOI18N
+ }
+ this.include = include;
+ if (exclude == null) {
+ exclude = ""; //NOI18N
+ }
+ this.exclude = exclude;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public String getInclude() {
+ return include;
+ }
+
+ public String getExclude() {
+ return exclude;
+ }
+
+ /** Returns true if at least one path in given list of relative paths
+ * matches include/exclude patterns.
+ * @param relativePaths list of paths relative to userdir root
+ * @return true if at least one path in given list of relative paths
+ * matches include/exclude patterns, false otherwise
+ */
+ public boolean isApplicable(List relativePaths) {
+ List applicablePaths = getApplicablePaths(relativePaths,
+ Collections.singleton(Pattern.compile(include)),
+ Collections.singleton(Pattern.compile(exclude)));
+ LOGGER.fine(" applicablePaths=" + applicablePaths); //NOI18N
+ return !applicablePaths.isEmpty();
+ }
+
+ /** Returns true if user selected this item for export/import.
+ * @return returns true if user selected this item for export/import,
+ * false otherwise
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /** Sets whether user selects this item for export/import.
+ * @param newState if selected or not
+ */
+ public void setEnabled(boolean newState) {
+ enabled = newState;
+ }
+
+ /** Just for debugging. */
+ @Override
+ public String toString() {
+ return getDisplayName() + ", enabled=" + isEnabled(); //NOI18N
+ }
+ }
+
+ /** Represents 3 state of category. */
+ static enum State {
+
+ ENABLED, DISABLED, PARTIAL
+ };
+
+ /** Represents category in UI holding several items. */
+ static class Category {
+
+ //xml entry names
+ private static final String INCLUDE = "include"; // NOI18N
+ private static final String EXCLUDE = "exclude"; // NOI18N
+ private static final String DISPLAY_NAME = "displayName"; // NOI18N
+ private FileObject categoryFO;
+ private String displayName;
+ private List
- items;
+ private State state = State.DISABLED;
+
+ public Category(FileObject fo, String displayName) {
+ this.categoryFO = fo;
+ this.displayName = displayName;
+ }
+
+ private void addItem(String displayName, String includes, String excludes) {
+ items.add(new Item(displayName, includes, excludes));
+ }
+
+ /** Returns items under OptionsExport/. **/
+ public List
- getItems() {
+ if (items == null) {
+ items = new ArrayList
- ();
+ FileObject[] itemsFOs = categoryFO.getChildren();
+ for (FileObject itemFO : itemsFOs) {
+ addItem((String) itemFO.getAttribute(DISPLAY_NAME),
+ (String) itemFO.getAttribute(INCLUDE),
+ (String) itemFO.getAttribute(EXCLUDE));
+ }
+ }
+ return items;
+ }
+
+ public String getName() {
+ return categoryFO.getNameExt();
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setState(State state) {
+ this.state = state;
+ updateItems(state);
+ }
+
+ public State getState() {
+ return state;
+ }
+
+ /** Just for debugging. */
+ @Override
+ public String toString() {
+ return getDisplayName() + ", state=" + getState(); //NOI18N
+ }
+
+ private void updateItems(State state) {
+ for (Item item : getItems()) {
+ if (state == State.DISABLED) {
+ item.setEnabled(false);
+ } else if (state == State.ENABLED) {
+ item.setEnabled(true);
+ }
+ }
+ }
+ } // end of Category
+
+ /** Load categories from filesystem. */
+ private static List loadCategories() {
+ FileObject[] categoryFOs = FileUtil.getConfigFile(OPTIONS_EXPORT_FOLDER).getChildren();
+ // respect ordering defined in layers
+ List sortedCats = FileUtil.getOrder(Arrays.asList(categoryFOs), false);
+ List categories = new ArrayList(sortedCats.size());
+ for (FileObject curFO : sortedCats) {
+ String displayName = (String) curFO.getAttribute(Category.DISPLAY_NAME);
+ categories.add(new Category(curFO, displayName));
+ }
+ return categories;
+ }
+
+ /** Filters given relative paths and returns only ones which match given
+ * include/exclude patterns.
+ * @param relativePaths relative paths
+ * @param includePatterns include patterns
+ * @param excludePatterns exclude patterns
+ * @return relative patsh which match include/exclude patterns
+ */
+ private static List getApplicablePaths(List relativePaths, Set includePatterns, Set excludePatterns) {
+ List applicablePaths = new ArrayList();
+ for (String relativePath : relativePaths) {
+ if (include(relativePath, includePatterns, excludePatterns)) {
+ applicablePaths.add(relativePath);
+ }
+ }
+ return applicablePaths;
+ }
+
+ /** Returns list of file path relative to given source root. It scans
+ * sub folders recursively.
+ * @param sourceRoot source root
+ * @return list of file path relative to given source root
+ */
+ static List getRelativePaths(File sourceRoot) {
+ List relativePaths = new ArrayList();
+ getRelativePaths(sourceRoot, sourceRoot, relativePaths);
+ return relativePaths;
+ }
+
+ private static void getRelativePaths(File source, File sourceRoot, List relativePaths) {
+ if (source.isDirectory()) {
+ File[] children = source.listFiles();
+ if (children == null) {
+ return;
+ }
+ for (File child : children) {
+ getRelativePaths(child, sourceRoot, relativePaths);
+ }
+ } else {
+ relativePaths.add(getRelativePath(sourceRoot, source));
+ }
+ }
+
+ /** Returns slash separated path relative to given root. */
+ private static String getRelativePath(File root, File file) {
+ String result = file.getAbsolutePath().substring(root.getAbsolutePath().length());
+ result = result.replace('\\', '/'); //NOI18N
+ if (result.startsWith("/") && !result.startsWith("//")) { //NOI18N
+ result = result.substring(1);
+ }
+ return result;
+ }
+
+ /** Returns true if given relative path matches at least one of given include
+ * patterns and doesn't match all exclude patterns.
+ * @param relativePath relative path
+ * @param includePatterns include patterns
+ * @param excludePatterns exclude patterns
+ * @return true if given relative path matches at least one of given include
+ * patterns and doesn't match all exclude patterns, false otherwise
+ */
+ private static boolean include(String relativePath, Set includePatterns, Set excludePatterns) {
+ boolean include = false;
+ for (Pattern pattern : includePatterns) {
+ Matcher matcher = pattern.matcher(relativePath);
+ if (matcher.matches()) {
+ include = true;
+ break;
+ }
+ }
+ if (include) {
+ // check excludes
+ for (Pattern pattern : excludePatterns) {
+ Matcher matcher = pattern.matcher(relativePath);
+ if (matcher.matches()) {
+ return false;
+ }
+ }
+ }
+ return include;
+ }
+
+ /** Copy source file to target file. It creates necessary sub folders.
+ * @param sourceFile source file
+ * @param targetFile target file
+ * @throws java.io.IOException if copying fails
+ */
+ private static void copyFile(File sourceFile, File targetFile) throws IOException {
+ ensureParent(targetFile);
+ InputStream ins = null;
+ OutputStream out = null;
+ try {
+ ins = new FileInputStream(sourceFile);
+ out = new FileOutputStream(targetFile);
+ FileUtil.copy(ins, out);
+ } finally {
+ if (ins != null) {
+ ins.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ /** Creates parent of given file, if doesn't exist. */
+ private static void ensureParent(File file) throws IOException {
+ final File parent = file.getParentFile();
+ if (parent != null && !parent.exists()) {
+ if (!parent.mkdirs()) {
+ throw new IOException("Cannot create folder: " + parent.getAbsolutePath()); //NOI18N
+ }
+ }
+ }
+
+ /** Extracts given zip file to target directory but only those files which
+ * match given list.
+ * @param sourceFile source zip file
+ * @param targetDir target directory
+ * @param applicablePaths list of files to be extracted
+ */
+ private static void extractZipFile(File sourceFile, File targetDir, List applicablePaths) throws IOException {
+ ZipFile zipFile = new ZipFile(sourceFile);
+ Enumeration enumeration = zipFile.entries();
+ while (enumeration.hasMoreElements()) {
+ ZipEntry zipEntry = (ZipEntry) enumeration.nextElement();
+ if (!applicablePaths.contains(zipEntry.getName())) {
+ // skip not matching entries
+ continue;
+ }
+ LOGGER.fine("Extracting:" + zipEntry.getName()); //NOI18N
+ InputStream in = null;
+ FileOutputStream out = null;
+ try {
+ in = zipFile.getInputStream(zipEntry);
+ File outFile = new File(targetDir, zipEntry.getName());
+ ensureParent(outFile);
+ out = new FileOutputStream(outFile);
+ FileUtil.copy(in, out);
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+ }
+
+ /** Returns list of paths from given zip file.
+ * @param file zip file
+ * @return list of paths from given zip file
+ * @throws java.io.IOException
+ */
+ static List listZipFile(File file) throws IOException {
+ List relativePaths = new ArrayList();
+ // Open the ZIP file
+ ZipFile zipFile = new ZipFile(file);
+ // Enumerate each entry
+ Enumeration entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ // Get the entry name
+ String zipEntryName = ((ZipEntry) entries.nextElement()).getName();
+ relativePaths.add(zipEntryName);
+ }
+ return relativePaths;
+ }
+
+ /** Creates zip file containing only selected files from given source dir.
+ * @param targetFile target zip file
+ * @param sourceDir source dir
+ * @param relativePaths paths to be added to zip file
+ * @throws java.io.IOException
+ */
+ private static void createZipFile(File targetFile, File sourceDir, List relativePaths) throws IOException {
+ ensureParent(targetFile);
+ ZipOutputStream out = null;
+ try {
+ // Create the ZIP file
+ out = new ZipOutputStream(new FileOutputStream(targetFile));
+ // Compress the files
+ for (String relativePath : relativePaths) {
+ LOGGER.fine("Adding to zip:" + relativePath); //NOI18N
+ // Add ZIP entry to output stream.
+ out.putNextEntry(new ZipEntry(relativePath));
+ // Transfer bytes from the file to the ZIP file
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream(new File(sourceDir, relativePath));
+ FileUtil.copy(in, out);
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ // Complete the entry
+ out.closeEntry();
+ }
+ // Complete the ZIP file
+ out.close();
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+}
diff --git a/options.api/src/org/netbeans/modules/options/export/defaultNode.gif b/options.api/src/org/netbeans/modules/options/export/defaultNode.gif
new file mode 100644
index 0000000000000000000000000000000000000000..3ebebf55d4269fc64082d1156c78b0a34864ee99
GIT binary patch
literal 401
zc%17D@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL
zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+AuIMDto#(hE&{2`t$$4J+mrCDalx69uDj1P+A6-sgo;}>wa!8B3uNsd6p&sV00kDs3}apUGq$%u#ui3N{(PINIc
zaYRe}VgLE_+umxP_xI}=vj6@3tbTaDef@#NM!624?H#I$jWI_9W3T_Xdh8rqhOu$L
z=lC||_CA9xW>=e;KCzo990dAqgCs+L>!mKK3Z0VjEeXA>4Gc*~CQj+}V+T4=TQO1N
p2rC0q$D<`Y0uCb53=krLA#eU>X8WlJvVdXA;OXk;vd$@?2>|yUo7?~Z
diff --git a/options.api/src/org/netbeans/modules/options/resources/mf-layer.xml b/options.api/src/org/netbeans/modules/options/resources/mf-layer.xml
--- a/options.api/src/org/netbeans/modules/options/resources/mf-layer.xml
+++ b/options.api/src/org/netbeans/modules/options/resources/mf-layer.xml
@@ -69,6 +69,13 @@
+
+
+
+
+
+
+
diff --git a/options.editor/src/org/netbeans/modules/options/colors/Bundle.properties b/options.editor/src/org/netbeans/modules/options/colors/Bundle.properties
--- a/options.editor/src/org/netbeans/modules/options/colors/Bundle.properties
+++ b/options.editor/src/org/netbeans/modules/options/colors/Bundle.properties
@@ -132,4 +132,6 @@
# QuickSearch keywords
KW_FontsAndColorsOptions=Fonts & Colors Options
-
+# Options Export
+FontsAndColors.Options.Export.Category.displayName=Fonts & Colors
+FontsAndColors.Options.Export.displayName=Fonts & Colors
diff --git a/options.editor/src/org/netbeans/modules/options/editor/Bundle.properties b/options.editor/src/org/netbeans/modules/options/editor/Bundle.properties
--- a/options.editor/src/org/netbeans/modules/options/editor/Bundle.properties
+++ b/options.editor/src/org/netbeans/modules/options/editor/Bundle.properties
@@ -93,3 +93,9 @@
OptionsDialog/Actions/Window=Window
OptionsDialog/Actions/System=System
OptionsDialog/Actions/XML=XML
+
+# Options Export
+Editor.Options.Export.Category.displayName=Editor
+Editor.Options.Export.Macros.displayName=Macros
+Editor.Options.Export.CodeTemplates.displayName=Code Templates
+Editor.Options.Export.Other.displayName=Other
diff --git a/options.editor/src/org/netbeans/modules/options/editor/mf-layer.xml b/options.editor/src/org/netbeans/modules/options/editor/mf-layer.xml
--- a/options.editor/src/org/netbeans/modules/options/editor/mf-layer.xml
+++ b/options.editor/src/org/netbeans/modules/options/editor/mf-layer.xml
@@ -228,6 +228,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/options.keymap/src/org/netbeans/modules/options/keymap/Bundle.properties b/options.keymap/src/org/netbeans/modules/options/keymap/Bundle.properties
--- a/options.keymap/src/org/netbeans/modules/options/keymap/Bundle.properties
+++ b/options.keymap/src/org/netbeans/modules/options/keymap/Bundle.properties
@@ -178,3 +178,7 @@
SpecialkeyPanel.enterButton.text=
SpecialkeyPanel.leftButton.text_1=
SpecialkeyPanel.rightButton.text=
+
+# Keymap Options Export
+Keymaps.Options.Export.Category.displayName=Keymaps
+Keymaps.Options.Export.Profiles.displayName=Keymap Profiles
diff --git a/options.keymap/src/org/netbeans/modules/options/keymap/mf-layer.xml b/options.keymap/src/org/netbeans/modules/options/keymap/mf-layer.xml
--- a/options.keymap/src/org/netbeans/modules/options/keymap/mf-layer.xml
+++ b/options.keymap/src/org/netbeans/modules/options/keymap/mf-layer.xml
@@ -91,9 +91,20 @@
-
+
+
+
+
+
+
+
+
+
+
+
-
+
+
diff --git a/project.libraries/src/org/netbeans/modules/project/libraries/Bundle.properties b/project.libraries/src/org/netbeans/modules/project/libraries/Bundle.properties
--- a/project.libraries/src/org/netbeans/modules/project/libraries/Bundle.properties
+++ b/project.libraries/src/org/netbeans/modules/project/libraries/Bundle.properties
@@ -39,3 +39,6 @@
MSG_libraryCreatedError=The library provider has thrown the following exception during library initialization, the created library may not work correctly.
MSG_libraryDeletedError=The library provider has thrown the following exception during library removal.
+
+# Options export
+ProjectLibraries.Options.Export.displayName=Project Libraries
diff --git a/project.libraries/src/org/netbeans/modules/project/libraries/resources/mf-layer.xml b/project.libraries/src/org/netbeans/modules/project/libraries/resources/mf-layer.xml
--- a/project.libraries/src/org/netbeans/modules/project/libraries/resources/mf-layer.xml
+++ b/project.libraries/src/org/netbeans/modules/project/libraries/resources/mf-layer.xml
@@ -68,4 +68,12 @@
+
+
+
+
+
+
+
+
diff --git a/vmd.midpnb/src/org/netbeans/modules/vmd/midpnb/Bundle.properties b/vmd.midpnb/src/org/netbeans/modules/vmd/midpnb/Bundle.properties
--- a/vmd.midpnb/src/org/netbeans/modules/vmd/midpnb/Bundle.properties
+++ b/vmd.midpnb/src/org/netbeans/modules/vmd/midpnb/Bundle.properties
@@ -40,3 +40,6 @@
OpenIDE-Module-Display-Category=Mobility
OpenIDE-Module-Name=VMD MIDP NB
OpenIDE-Module-Short-Description=Visual Mobile Designer - MIDP NetBeans Components
+
+# Options export
+VmdMidp.Options.Export.displayName=MIDP Palette
diff --git a/vmd.midpnb/src/org/netbeans/modules/vmd/midpnb/layer.xml b/vmd.midpnb/src/org/netbeans/modules/vmd/midpnb/layer.xml
--- a/vmd.midpnb/src/org/netbeans/modules/vmd/midpnb/layer.xml
+++ b/vmd.midpnb/src/org/netbeans/modules/vmd/midpnb/layer.xml
@@ -145,4 +145,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/web.core/src/org/netbeans/modules/web/core/Bundle.properties b/web.core/src/org/netbeans/modules/web/core/Bundle.properties
--- a/web.core/src/org/netbeans/modules/web/core/Bundle.properties
+++ b/web.core/src/org/netbeans/modules/web/core/Bundle.properties
@@ -111,3 +111,6 @@
Templates/JSP_Servlet/TagLibrary.tld=Tag Library Descriptor
Templates/JSP_Servlet/TagHandler.java=Tag Handler
+
+# Options export
+JSPPalette.Options.Export.displayName=JSP Palette
diff --git a/web.core/src/org/netbeans/modules/web/core/resources/layer.xml b/web.core/src/org/netbeans/modules/web/core/resources/layer.xml
--- a/web.core/src/org/netbeans/modules/web/core/resources/layer.xml
+++ b/web.core/src/org/netbeans/modules/web/core/resources/layer.xml
@@ -614,4 +614,12 @@
+
+
+
+
+
+
+
+
diff --git a/welcome/src/org/netbeans/modules/welcome/Bundle.properties b/welcome/src/org/netbeans/modules/welcome/Bundle.properties
--- a/welcome/src/org/netbeans/modules/welcome/Bundle.properties
+++ b/welcome/src/org/netbeans/modules/welcome/Bundle.properties
@@ -73,3 +73,6 @@
ACSD_FeedbackSurvey_Yes=Goes to survey
ACSD_FeedbackSurvey_Later=Reminds later
ACSD_FeedbackSurvey_Never=Skips survey
+
+# Display name for options export
+Welcome.Options.Export.displayName=Start Page
diff --git a/welcome/src/org/netbeans/modules/welcome/resources/layer.xml b/welcome/src/org/netbeans/modules/welcome/resources/layer.xml
--- a/welcome/src/org/netbeans/modules/welcome/resources/layer.xml
+++ b/welcome/src/org/netbeans/modules/welcome/resources/layer.xml
@@ -178,4 +178,14 @@
+
+
+
+
+
+
+
+
+
+