This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 226998
Collapse All | Expand All

(-)a/ide.branding/options.api/src/org/netbeans/modules/options/export/Bundle_nb.properties (+2 lines)
Lines 2-4 Link Here
2
ImportConfirmationPanel.cbRestart.text=<html>&Restart IDE now<br>(without restart imported settings may not work)</html>
2
ImportConfirmationPanel.cbRestart.text=<html>&Restart IDE now<br>(without restart imported settings may not work)</html>
3
ImportConfirmationPanel.cbRestart.AD=Decide whether restart IDE now or later
3
ImportConfirmationPanel.cbRestart.AD=Decide whether restart IDE now or later
4
ImportConfirmationPanel.cbRestart.AN=Restart IDE now?
4
ImportConfirmationPanel.cbRestart.AN=Restart IDE now?
5
OPT_RestartAfterImport=true
6
(-)a/options.api/apichanges.xml (+21 lines)
Lines 75-80 Link Here
75
<!-- ACTUAL CHANGES BEGIN HERE: -->
75
<!-- ACTUAL CHANGES BEGIN HERE: -->
76
76
77
<changes>
77
<changes>
78
    <change id="Import.restart">
79
        <api name="OptionsAPI"/>
80
        <summary>Should Import Require Restart?</summary>
81
        <version major="1" minor="34"/>
82
        <date day="15" month="3" year="2013"/>
83
        <author login="jtulach"/>
84
        <compatibility addition="yes" semantic="incompatible">
85
            Compared to previous versions, the default changed - now 
86
            the restart is not needed. Applications can change that by using
87
            <a href="architecture-summary.html#branding-OPT_RestartAfterImport">
88
            this branding API</a> and specifying <code>false</code> as the value
89
            of associated key.
90
        </compatibility>
91
        <description>
92
            Should an import of settings require a restart? Some applications 
93
            need that, some don't. There is a 
94
            <a href="architecture-summary.html#branding-OPT_RestartAfterImport">
95
            branding API</a> to control such behavior now.
96
        </description>
97
        <issue number="226998"/>
98
    </change>
78
    <change id="OptionsDisplayer.openModal">
99
    <change id="OptionsDisplayer.openModal">
79
        <api name="OptionsAPI"/>
100
        <api name="OptionsAPI"/>
80
        <summary>API to control whether the options window should be modal or not when opened</summary>
101
        <summary>API to control whether the options window should be modal or not when opened</summary>
(-)a/options.api/arch.xml (+7 lines)
Lines 1144-1149 Link Here
1144
        can have the following structure
1144
        can have the following structure
1145
        <code>filePattern1#keyPattern1#|filePattern2|filePattern3#keyPattern3</code>.
1145
        <code>filePattern1#keyPattern1#|filePattern2|filePattern3#keyPattern3</code>.
1146
   </api>
1146
   </api>
1147
   <api category="devel" group="branding" name="OPT_RestartAfterImport" type="export">
1148
       By default importing settings (as described by <a href="layer-OptionsExportLayers">OptionsExport</a>
1149
       API does not require restart. Some systems may however support complex
1150
       modifications to the installation structure. Then they should brand the 
1151
       <code>OPT_RestartAfterImport</code> to <code>true</code>. NetBeans IDE
1152
       does require restart after settings import.
1153
   </api>
1147
  </p>
1154
  </p>
1148
 </answer>
1155
 </answer>
1149
1156
(-)a/options.api/manifest.mf (-1 / +1 lines)
Lines 2-7 Link Here
2
OpenIDE-Module: org.netbeans.modules.options.api/1
2
OpenIDE-Module: org.netbeans.modules.options.api/1
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/options/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/options/Bundle.properties
4
OpenIDE-Module-Layer: org/netbeans/modules/options/resources/mf-layer.xml
4
OpenIDE-Module-Layer: org/netbeans/modules/options/resources/mf-layer.xml
5
OpenIDE-Module-Specification-Version: 1.33
5
OpenIDE-Module-Specification-Version: 1.34
6
AutoUpdate-Show-In-Client: false
6
AutoUpdate-Show-In-Client: false
7
AutoUpdate-Essential-Module: true
7
AutoUpdate-Essential-Module: true
(-)a/options.api/src/org/netbeans/modules/options/export/OptionsChooserPanel.java (-19 / +48 lines)
Lines 51-56 Link Here
51
import java.util.List;
51
import java.util.List;
52
import java.util.logging.Level;
52
import java.util.logging.Level;
53
import java.util.logging.Logger;
53
import java.util.logging.Logger;
54
import javax.swing.Action;
54
import javax.swing.Icon;
55
import javax.swing.Icon;
55
import javax.swing.JLabel;
56
import javax.swing.JLabel;
56
import javax.swing.JPanel;
57
import javax.swing.JPanel;
Lines 73-81 Link Here
73
import org.openide.DialogDisplayer;
74
import org.openide.DialogDisplayer;
74
import org.openide.LifecycleManager;
75
import org.openide.LifecycleManager;
75
import org.openide.NotifyDescriptor;
76
import org.openide.NotifyDescriptor;
77
import org.openide.awt.Actions;
76
import org.openide.awt.Mnemonics;
78
import org.openide.awt.Mnemonics;
77
import org.openide.awt.NotificationDisplayer;
79
import org.openide.awt.NotificationDisplayer;
78
import org.openide.filesystems.FileChooserBuilder;
80
import org.openide.filesystems.FileChooserBuilder;
81
import org.openide.filesystems.FileStateInvalidException;
82
import org.openide.filesystems.FileUtil;
79
import org.openide.modules.Places;
83
import org.openide.modules.Places;
80
import org.openide.util.Exceptions;
84
import org.openide.util.Exceptions;
81
import org.openide.util.ImageUtilities;
85
import org.openide.util.ImageUtilities;
Lines 197-214 Link Here
197
                LOGGER.fine("Export canceled.");  //NOI18N
201
                LOGGER.fine("Export canceled.");  //NOI18N
198
                return;
202
                return;
199
            }
203
            }
204
            
205
            Action save = Actions.forID("Window", "org.netbeans.core.windows.actions.SaveWindowsAction"); // NOI18N
206
            if (save != null) {
207
                save.actionPerformed(new ActionEvent(optionsChooserPanel, 0, ""));
208
            }
209
            
200
            final String targetPath = optionsChooserPanel.getSelectedFilePath();
210
            final String targetPath = optionsChooserPanel.getSelectedFilePath();
201
	    RequestProcessor RP = new RequestProcessor("OptionsChooserPanel Export", 1); // NOI18N
211
            RequestProcessor RP = new RequestProcessor("OptionsChooserPanel Export", 1); // NOI18N
202
	    Runnable runnable = new Runnable() {
212
            Runnable runnable = new Runnable() {
203
		@Override
213
                @Override
204
		public void run() {
214
                public void run() {
205
		    optionsChooserPanel.getOptionsExportModel().doExport(new File(targetPath));
215
                    optionsChooserPanel.getOptionsExportModel().doExport(new File(targetPath));
206
		    NotificationDisplayer.getDefault().notify(
216
                    NotificationDisplayer.getDefault().notify(
207
			    NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.export.status.text"),  //NOI18N
217
                        NbBundle.getMessage(OptionsChooserPanel.class, "OptionsChooserPanel.export.status.text"), //NOI18N
208
			    OPTIONS_ICON, Bundle.Export_Notification_DetailsText(targetPath), null);
218
                        OPTIONS_ICON, Bundle.Export_Notification_DetailsText(targetPath), null);
209
		    LOGGER.fine("Export finished.");  //NOI18N
219
                    LOGGER.fine("Export finished.");  //NOI18N
210
		}
220
                }
211
	    };
221
            };
212
	    exportTask = RP.create(runnable);
222
	    exportTask = RP.create(runnable);
213
223
214
	    final ProgressHandle ph = ProgressHandleFactory.createHandle(Bundle.ProgressHandle_Export_DisplayName(), exportTask);
224
	    final ProgressHandle ph = ProgressHandleFactory.createHandle(Bundle.ProgressHandle_Export_DisplayName(), exportTask);
Lines 224-229 Link Here
224
        }
234
        }
225
    }
235
    }
226
236
237
    @NbBundle.Messages({
238
        "OPT_RestartAfterImport=false"
239
    })
227
    /** Shows panel for import of options. */
240
    /** Shows panel for import of options. */
228
    public static void showImportDialog() {
241
    public static void showImportDialog() {
229
        LOGGER.fine("showImportDialog");  //NOI18N
242
        LOGGER.fine("showImportDialog");  //NOI18N
Lines 244-254 Link Here
244
                null);
257
                null);
245
        dd.createNotificationLineSupport();
258
        dd.createNotificationLineSupport();
246
        dd.setValid(false);
259
        dd.setValid(false);
260
        boolean ok;
261
        final boolean willRestart = "true".equals(Bundle.OPT_RestartAfterImport()); // NOI18N
247
        final ImportConfirmationPanel confirmationPanel = new ImportConfirmationPanel();
262
        final ImportConfirmationPanel confirmationPanel = new ImportConfirmationPanel();
248
        dd.setButtonListener(new ActionListener() {
263
        dd.setButtonListener(new ActionListener() {
249
264
            @Override
250
            public void actionPerformed(ActionEvent e) {
265
            public void actionPerformed(ActionEvent e) {
251
                if (e.getSource() == DialogDescriptor.OK_OPTION) {
266
                if (willRestart && e.getSource() == DialogDescriptor.OK_OPTION) {
252
                    // show confirmation dialog when user click OK
267
                    // show confirmation dialog when user click OK
253
                    confirmationPanel.showConfirmation();
268
                    confirmationPanel.showConfirmation();
254
                }
269
                }
Lines 256-267 Link Here
256
        });
271
        });
257
        optionsChooserPanel.setDialogDescriptor(dd);
272
        optionsChooserPanel.setDialogDescriptor(dd);
258
        DialogDisplayer.getDefault().createDialog(dd).setVisible(true);
273
        DialogDisplayer.getDefault().createDialog(dd).setVisible(true);
259
274
        ok = DialogDescriptor.OK_OPTION.equals(dd.getValue());
260
        if (DialogDescriptor.OK_OPTION.equals(dd.getValue())) {
275
        if (willRestart) {
261
            if (!confirmationPanel.confirmed()) {
276
            if (!confirmationPanel.confirmed()) {
262
                LOGGER.fine("Import canceled.");  //NOI18N
277
                LOGGER.fine("Import canceled.");  //NOI18N
263
                return;
278
                ok = false;
264
            }
279
            }
280
        }
281
282
        if (ok) {
265
            // do import
283
            // do import
266
            File targetUserdir = Places.getUserDirectory();
284
            File targetUserdir = Places.getUserDirectory();
267
            try {
285
            try {
Lines 274-282 Link Here
274
                return;
292
                return;
275
            }
293
            }
276
            LOGGER.fine("Import finished.");  //NOI18N
294
            LOGGER.fine("Import finished.");  //NOI18N
277
            // restart IDE
295
            if (willRestart) { // NOI18N
278
            LifecycleManager.getDefault().markForRestart();
296
                // restart IDE
279
            LifecycleManager.getDefault().exit();
297
                LifecycleManager.getDefault().markForRestart();
298
                LifecycleManager.getDefault().exit();
299
            }
300
            try {
301
                FileUtil.getConfigRoot().getFileSystem().refresh(true);
302
            } catch (FileStateInvalidException ex) {
303
                Exceptions.printStackTrace(ex);
304
            }
305
            Action reload = Actions.forID("Window", "org.netbeans.core.windows.actions.ReloadWindowsAction");
306
            if (reload != null) {
307
                reload.actionPerformed(new ActionEvent(optionsChooserPanel, 0, ""));
308
            }
280
        }
309
        }
281
    }
310
    }
282
311
(-)a/options.api/src/org/netbeans/modules/options/export/OptionsExportModel.java (-45 / +32 lines)
Lines 59-65 Link Here
59
import java.util.Set;
59
import java.util.Set;
60
import java.util.logging.Level;
60
import java.util.logging.Level;
61
import java.util.logging.Logger;
61
import java.util.logging.Logger;
62
import java.util.prefs.*;
63
import java.util.regex.Matcher;
62
import java.util.regex.Matcher;
64
import java.util.regex.Pattern;
63
import java.util.regex.Pattern;
65
import java.util.zip.ZipEntry;
64
import java.util.zip.ZipEntry;
Lines 69-75 Link Here
69
import org.openide.util.EditableProperties;
68
import org.openide.util.EditableProperties;
70
import org.openide.util.Exceptions;
69
import org.openide.util.Exceptions;
71
import org.openide.util.NbBundle;
70
import org.openide.util.NbBundle;
72
import org.openide.util.NbPreferences;
73
71
74
/**
72
/**
75
 * Model for export/import options. It reads {@code OptionsExport/<category>/<item>}
73
 * Model for export/import options. It reads {@code OptionsExport/<category>/<item>}
Lines 175-219 Link Here
175
    void doImport(File targetUserdir) throws IOException {
173
    void doImport(File targetUserdir) throws IOException {
176
        LOGGER.fine("Copying from: " + source + "\n    to: " + targetUserdir);  //NOI18N
174
        LOGGER.fine("Copying from: " + source + "\n    to: " + targetUserdir);  //NOI18N
177
        this.targetUserdir = targetUserdir;
175
        this.targetUserdir = targetUserdir;
178
        FileUtil.getConfigRoot().addRecursiveListener(new FileChangeListener() {
179
180
            @Override
181
            public void fileFolderCreated(FileEvent fe) {
182
                String path = fe.getFile().getPath();
183
                Preferences pref = Preferences.userRoot().node(path);
184
            }
185
186
            @Override
187
            public void fileDataCreated(FileEvent fe) {
188
                String path = fe.getFile().getPath();
189
                Preferences pref = NbPreferences.root().node("config").node(path);
190
            }
191
192
            @Override
193
            public void fileChanged(FileEvent fe) {
194
                String path = fe.getFile().getPath();
195
                Preferences pref = NbPreferences.root().node("config").node(path);
196
            }
197
198
            @Override
199
            public void fileDeleted(FileEvent fe) {
200
                String path = fe.getFile().getPath();
201
                Preferences pref = NbPreferences.root().node("config").node(path);
202
                try {
203
                    pref.removeNode();
204
                } catch (BackingStoreException ex) {
205
                    Exceptions.printStackTrace(ex);
206
                }
207
            }
208
209
            @Override
210
            public void fileRenamed(FileRenameEvent fe) {
211
            }
212
213
            @Override
214
            public void fileAttributeChanged(FileAttributeEvent fe) {
215
            }
216
        });
217
        copyFiles();
176
        copyFiles();
218
    }
177
    }
219
178
Lines 225-231 Link Here
225
        try {
184
        try {
226
            ensureParent(targetZipFile);
185
            ensureParent(targetZipFile);
227
            // Create the ZIP file
186
            // Create the ZIP file
228
            zipOutputStream = new ZipOutputStream(new FileOutputStream(targetZipFile));
187
            zipOutputStream = new ZipOutputStream(createOutputStream(targetZipFile));
229
            copyFiles();
188
            copyFiles();
230
            createProductInfo(zipOutputStream);
189
            createProductInfo(zipOutputStream);
231
            // Complete the ZIP file
190
            // Complete the ZIP file
Lines 869-875 Link Here
869
            if (includeKeys.isEmpty() && excludeKeys.isEmpty()) {
828
            if (includeKeys.isEmpty() && excludeKeys.isEmpty()) {
870
                // copy entire file
829
                // copy entire file
871
                try {
830
                try {
872
                    out = new FileOutputStream(targetFile);
831
                    out = createOutputStream(targetFile);
873
                    copyFile(relativePath, out);
832
                    copyFile(relativePath, out);
874
                } finally {
833
                } finally {
875
                    if (out != null) {
834
                    if (out != null) {
Lines 915-921 Link Here
915
        }
874
        }
916
        OutputStream out = null;
875
        OutputStream out = null;
917
        try {
876
        try {
918
            out = new FileOutputStream(targetFile);
877
            out = createOutputStream(targetFile);
919
            targetProperties.store(out);
878
            targetProperties.store(out);
920
        } finally {
879
        } finally {
921
            if (out != null) {
880
            if (out != null) {
Lines 1041-1047 Link Here
1041
        ZipOutputStream out = null;
1000
        ZipOutputStream out = null;
1042
        try {
1001
        try {
1043
            // Create the ZIP file
1002
            // Create the ZIP file
1044
            out = new ZipOutputStream(new FileOutputStream(targetFile));
1003
            out = new ZipOutputStream(createOutputStream(targetFile));
1045
            // Compress the files
1004
            // Compress the files
1046
            for (String relativePath : relativePaths) {
1005
            for (String relativePath : relativePaths) {
1047
                LOGGER.finest("Adding to zip: " + relativePath);  //NOI18N
1006
                LOGGER.finest("Adding to zip: " + relativePath);  //NOI18N
Lines 1091-1094 Link Here
1091
        // Complete the entry
1050
        // Complete the entry
1092
        out.closeEntry();
1051
        out.closeEntry();
1093
    }
1052
    }
1053
    
1054
    private static OutputStream createOutputStream(File file) throws IOException {
1055
        if (containsConfig(file)) {
1056
            file = file.getCanonicalFile();
1057
            File root = FileUtil.toFile(FileUtil.getConfigRoot());
1058
            String filePath = file.getPath();
1059
            String rootPath = root.getPath();
1060
            if (filePath.startsWith(rootPath)) {
1061
                String res = filePath.substring(rootPath.length()).replace(File.separatorChar, '/');
1062
                FileObject fo = FileUtil.createData(FileUtil.getConfigRoot(), res);
1063
                if (fo != null) {
1064
                    return fo.getOutputStream();
1065
                }
1066
            }
1067
        }
1068
        return new FileOutputStream(file);
1069
    }
1070
    private static boolean containsConfig(File file) {
1071
        for (;;) {
1072
            if (file == null) {
1073
                return false;
1074
            }
1075
            if (file.getName().equals("config")) {
1076
                return true;
1077
            }
1078
            file = file.getParentFile();
1079
        }
1080
    }
1094
}
1081
}

Return to bug 226998