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