diff --git a/platform/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties b/platform/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties index 6ee765b30a9a..c1b26db18555 100644 --- a/platform/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties +++ b/platform/core.ui/src/org/netbeans/core/ui/options/general/Bundle.properties @@ -37,6 +37,9 @@ AD_Usage_Statistics=Usage Statistics CTL_Usage_Check=Hel&p us improve the NetBeans IDE by providing anonymous usage data AN_Usage_Check=Help us improve the NetBeans IDE by providing anonymous usage data AD_Usage_Check=Help us improve the NetBeans IDE by providing anonymous usage data +CTL_Exit_Confirmation=&Show confirmation when exiting with no unsaved files +AN_Exit_Confirmation=Show exit confirmation +AD_Exit_Confirmation=Show a confirmation dialog when exiting with no unsaved files CTL_Usage_Info=The usage statistics help us better understand user \ requirements and prioritize improvements in future releases. We will never \ reverse-engineer the collected data to find specific details about your projects. diff --git a/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.form b/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.form index a589573aa14b..86cbb73ecc0d 100644 --- a/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.form +++ b/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.form @@ -103,6 +103,7 @@ + @@ -152,6 +153,8 @@ + + @@ -350,6 +353,13 @@ + + + + + + + diff --git a/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.java b/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.java index 363cc72ba22b..7f89ca3c0f86 100644 --- a/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.java +++ b/platform/core.ui/src/org/netbeans/core/ui/options/general/GeneralOptionsPanel.java @@ -39,6 +39,7 @@ import javax.swing.event.DocumentListener; import org.netbeans.api.options.OptionsDisplayer; import org.netbeans.beaninfo.editors.HtmlBrowser; +import org.netbeans.core.ExitDialog; import org.netbeans.core.ProxySettings; import org.netbeans.spi.options.OptionsPanelController; import org.openide.DialogDescriptor; @@ -127,6 +128,7 @@ public void changedUpdate(DocumentEvent e) { loc (rbNoProxy, "No_Proxy"); loc (rbUseSystemProxy, "Use_System_Proxy_Settings"); loc (rbHTTPProxy, "Use_HTTP_Proxy"); + loc (cbExitConfirmation, "Exit_Confirmation"); loc (lUsage, "Usage_Statistics"); lUsage.getAccessibleContext ().setAccessibleDescription (loc ("AD_Usage_Statistics")); @@ -186,6 +188,7 @@ private void initComponents() { lblLearnMore = new javax.swing.JLabel(); lblUsageInfo = new javax.swing.JLabel(); jUsageCheck = new javax.swing.JCheckBox(); + cbExitConfirmation = new javax.swing.JCheckBox(); lUsage = new javax.swing.JLabel(); bReloadProxy = new javax.swing.JButton(); bTestConnection = new javax.swing.JButton(); @@ -291,6 +294,7 @@ public void mousePressed(java.awt.event.MouseEvent evt) { gridBagConstraints.insets = new java.awt.Insets(0, 15, 5, 0); jPanel1.add(jUsageCheck, gridBagConstraints); + org.openide.awt.Mnemonics.setLocalizedText(cbExitConfirmation, org.openide.util.NbBundle.getMessage(GeneralOptionsPanel.class, "CTL_Exit_Confirmation")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(lUsage, "Usage Statistics:"); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; @@ -373,7 +377,8 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addComponent(jSeparator3, javax.swing.GroupLayout.DEFAULT_SIZE, 1495, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addContainerGap()))) + .addContainerGap()) + .addComponent(cbExitConfirmation, javax.swing.GroupLayout.Alignment.LEADING))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -413,6 +418,8 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cbExitConfirmation) .addContainerGap()) ); @@ -535,6 +542,7 @@ private void bTestConnectionActionPerformed(java.awt.event.ActionEvent evt) {//G private javax.swing.JButton bReloadProxy; private javax.swing.JButton bTestConnection; private javax.swing.JComboBox cbWebBrowser; + private javax.swing.JCheckBox cbExitConfirmation; private javax.swing.JButton editBrowserButton; private javax.swing.JLabel errorLabel; private javax.swing.JPanel jPanel1; @@ -684,6 +692,7 @@ void update () { rbUseSystemProxy.setToolTipText (getUseSystemProxyToolTip ()); jUsageCheck.setSelected(model.getUsageStatistics()); + cbExitConfirmation.setSelected(ExitDialog.isExitConfirmationEnabled()); updateWebBrowsers(); } @@ -761,6 +770,7 @@ void applyChanges () { editor.setAsText ((String) cbWebBrowser.getSelectedItem ()); model.setUsageStatistics(jUsageCheck.isSelected()); + ExitDialog.setExitConfirmationEnabled(cbExitConfirmation.isSelected()); } void cancel () { @@ -774,6 +784,9 @@ boolean isChanged () { if (model == null) { return false; } + if (cbExitConfirmation.isSelected() != ExitDialog.isExitConfirmationEnabled()) { + return true; + } // web browser settings if (editor == null) { editor = Lookup.getDefault().lookup(HtmlBrowser.FactoryEditor.class); diff --git a/platform/o.n.core/src/org/netbeans/core/Bundle.properties b/platform/o.n.core/src/org/netbeans/core/Bundle.properties index 18db39811fee..bd88107cbb4c 100644 --- a/platform/o.n.core/src/org/netbeans/core/Bundle.properties +++ b/platform/o.n.core/src/org/netbeans/core/Bundle.properties @@ -49,6 +49,11 @@ MSG_AllSaved=Save All finished. CTL_Cannot_save=Cannot save {0} +# Exit confirmation shown when there are no open files with unsaved changes +TTL_ExitConfirmation=Exit IDE +MSG_ExitConfirmation=Do you want to exit the IDE? +CTL_ExitConfirmationExit=Exit +CTL_ExitConfirmationCancel=Cancel #NbAuthenticator CTL_PasswordProtected=Password Protected Site diff --git a/platform/o.n.core/src/org/netbeans/core/ExitDialog.java b/platform/o.n.core/src/org/netbeans/core/ExitDialog.java index 3c09c2f0ccde..5fb7185da581 100644 --- a/platform/o.n.core/src/org/netbeans/core/ExitDialog.java +++ b/platform/o.n.core/src/org/netbeans/core/ExitDialog.java @@ -39,6 +39,7 @@ import javax.swing.border.LineBorder; import org.netbeans.api.actions.Savable; import org.openide.DialogDescriptor; +import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.awt.Mnemonics; import org.openide.nodes.Node; @@ -53,6 +54,7 @@ */ public class ExitDialog extends JPanel implements java.awt.event.ActionListener { + private static final String CONFIRM_EXIT_PREFERENCE = "confirmExit"; // NOI18N private static final boolean isAqua = "Aqua".equals(UIManager.getLookAndFeel().getID()); private static Object[] exitOptions; @@ -197,6 +199,16 @@ public static boolean showDialog() { return innerShowDialog(); } + public static boolean isExitConfirmationEnabled() { + return org.openide.util.NbPreferences.forModule(ExitDialog.class) + .getBoolean(CONFIRM_EXIT_PREFERENCE, true); + } + + public static void setExitConfirmationEnabled(boolean enabled) { + org.openide.util.NbPreferences.forModule(ExitDialog.class) + .putBoolean(CONFIRM_EXIT_PREFERENCE, enabled); + } + /** * Opens the ExitDialog. */ @@ -252,8 +264,41 @@ private static boolean innerShowDialog() { return result; } - else - return true; + + else { + if (!isExitConfirmationEnabled()) { + return true; + } + ResourceBundle bundle = NbBundle.getBundle(ExitDialog.class); + + final JButton exitButton = new JButton(); + final JButton cancelButton = new JButton(); + Mnemonics.setLocalizedText(exitButton, bundle.getString("CTL_ExitConfirmationExit")); + Mnemonics.setLocalizedText(cancelButton, bundle.getString("CTL_ExitConfirmationCancel")); + + DialogDescriptor descriptor = new DialogDescriptor( + bundle.getString("MSG_ExitConfirmation"), + bundle.getString("TTL_ExitConfirmation"), + true, + new Object[] { exitButton, cancelButton }, + cancelButton, + DialogDescriptor.RIGHT_ALIGN, + null, + (java.awt.event.ActionListener) null); + descriptor.setMessageType(NotifyDescriptor.QUESTION_MESSAGE); + + java.awt.Dialog dialog = DialogDisplayer.getDefault().createDialog(descriptor); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowOpened(java.awt.event.WindowEvent e) { + cancelButton.requestFocusInWindow(); + } + }); + dialog.setVisible(true); + dialog.dispose(); + + return descriptor.getValue() == exitButton; + } } /** Renderer used in list box of exit dialog