/**
* Copyright (C) 2001-2017 by RapidMiner and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapidminer.com
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU Affero General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program.
* If not, see http://www.gnu.org/licenses/.
*/
package com.rapidminer.gui.tools.dialogs;
import java.awt.BorderLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import com.rapidminer.RapidMiner;
import com.rapidminer.gui.ApplicationFrame;
import com.rapidminer.gui.properties.SettingsDialog;
import com.rapidminer.gui.tools.ResourceActionAdapter;
import com.rapidminer.gui.tools.SwingTools;
import com.rapidminer.parameter.ParameterTypeCategory;
import com.rapidminer.tools.I18N;
import com.rapidminer.tools.ParameterService;
/**
* A dialog that asks the user a question which can be answered with yes or no and remembers its
* decision. The user can decide whether or not their answer is remembered. If it is remembered, the
* dialog will not be displayed the next time.
*
* To use this class, define "gui.dialog.KEY.title" and "gui.dialog.KEY.message" in the GUI
* properties file. Also, register a property using
* {@link RapidMiner#registerRapidMinerProperty(com.rapidminer.parameter.ParameterType)} with a
* {@link ParameterTypeCategory} where the categories are {@link #PROPERTY_VALUES} (yes, no, ask).
* Preferrably, the default value should be {@link #ASK}. Pass the i18n key and the key of this
* property to {@link #confirmAction(String, String)}.
*
* The behaviour of this dialog depends on the current value of the property.
* <ul>
* <li>If its value is either "true" or "false", nothing will happen and the method will simply
* return true or false, depending on this value.</li>
* <li>If the value is "ask", a dialog will pop up, and either true (yes) or false (false) will be
* returned. Furthermore, if the user checks the "Remember my decision" checkbox, the property will
* be set to the users decision ("true" or "false"), and the property will be saved to the users
* private property file. Hence, the next call to {@link #confirmAction(String, String)} will return
* without showing a dialog.</li>
* </ul>
*
* In order to make the dialog shown again, the user must set the value back to "ask" in the
* {@link SettingsDialog}.
*
* @author Simon Fischer, Marco Boeck
*
*/
public class DecisionRememberingConfirmDialog extends ButtonDialog {
/**
* The type of the dialog.
*/
private enum DialogType {
/** yes/no option */
CONFIRM,
/** only OK option, just for user information */
ACKNOWLEDGE;
}
private static final long serialVersionUID = 1L;
private static final String VALUE_TRUE = "true";
private static final String VALUE_FALSE = "false";
private static final String VALUE_ASK = "ask";
private static final String VALUE_SHOW = "show";
private static final String VALUE_HIDE = "hide";
public static final String[] PROPERTY_VALUES = { VALUE_TRUE, VALUE_FALSE, VALUE_ASK };
public static final String[] PROPERTY_VALUES_ACK = { VALUE_SHOW, VALUE_HIDE };
public static final int TRUE = 0;
public static final int FALSE = 1;
public static final int ASK = 2;
public static final int SHOW = 0;
public static final int HIDE = 1;
private JCheckBox dontAskAgainBox;
private DialogType type;
private final String propertyName;
private boolean confirmed;
private DecisionRememberingConfirmDialog(String i18nKey, String property, DialogType type, Object... arguments) {
super(ApplicationFrame.getApplicationFrame(), i18nKey, ModalityType.APPLICATION_MODAL, arguments);
if (i18nKey == null) {
throw new IllegalArgumentException("i18nKey must not be null!");
}
if (property == null) {
throw new IllegalArgumentException("property must not be null!");
}
if (type == null) {
throw new IllegalArgumentException("type must not be null!");
}
this.propertyName = property;
this.type = type;
JButton toFocus = null;
JPanel buttonPanel = new JPanel(new BorderLayout());
if (type == DialogType.CONFIRM) {
dontAskAgainBox = new JCheckBox(new ResourceActionAdapter("remember_decision"));
dontAskAgainBox.setSelected(false);
JButton yesButton = makeOkButton("yes");
JButton noButton = makeCancelButton("no");
buttonPanel.add(dontAskAgainBox, BorderLayout.WEST);
buttonPanel.add(makeButtonPanel(yesButton, noButton), BorderLayout.EAST);
toFocus = noButton;
} else if (type == DialogType.ACKNOWLEDGE) {
dontAskAgainBox = new JCheckBox(new ResourceActionAdapter("dont_show_again"));
dontAskAgainBox.setSelected(false);
JButton okButton = makeOkButton("ok");
buttonPanel.add(dontAskAgainBox, BorderLayout.WEST);
buttonPanel.add(makeButtonPanel(okButton), BorderLayout.EAST);
toFocus = okButton;
}
layoutDefault(null, buttonPanel);
if (toFocus != null) {
toFocus.requestFocusInWindow();
}
}
@Override
public void ok() {
confirmed = true;
saveIfDesired();
dispose();
}
@Override
public void cancel() {
saveIfDesired();
confirmed = false;
dispose();
}
@Override
protected Icon getInfoIcon() {
// constants not possible because this class is referenced too early
if (type == DialogType.CONFIRM) {
return SwingTools.createIcon("48/" + I18N.getGUIMessage("gui.dialog.confirm.icon"));
} else if (type == DialogType.ACKNOWLEDGE) {
return SwingTools.createIcon("48/" + I18N.getGUIMessage("gui.dialog.ack.icon"));
}
return null;
}
private void saveIfDesired() {
if (dontAskAgainBox.isSelected()) {
String value = null;
if (type == DialogType.CONFIRM) {
value = confirmed ? VALUE_TRUE : VALUE_FALSE;
} else if (type == DialogType.ACKNOWLEDGE) {
value = VALUE_HIDE;
}
if (value != null) {
ParameterService.setParameterValue(propertyName, value);
ParameterService.saveParameters();
}
}
}
/**
* Shows a dialog which can be confirmed or not via yes/no buttons. If the user selects the
* "don't ask me again" checkbox, the user choice is remembered and applied automatically in the
* future.
*
* @param i18nKey
* @param propertyKey
* the key which is used to remember the user choice
* @return <code>true</code> if the dialog was confirmed; <code>false</code> otherwise
*/
public static boolean confirmAction(String i18nKey, String propertyKey) {
return confirmAction(i18nKey, propertyKey, new Object[0]);
}
/**
* Shows a dialog which can be confirmed or not via yes/no buttons. If the user selects the
* "don't ask me again" checkbox, the user choice is remembered and applied automatically in the
* future.
*
* @param i18nKey
* i18n key
* @param propertyKey
* the key which is used to remember the user choice
* @param arguments
* optional i18n arguments
* @return <code>true</code> if the dialog was confirmed; <code>false</code> otherwise
*/
public static boolean confirmAction(String i18nKey, String propertyKey, Object... arguments) {
String propValue = ParameterService.getParameterValue(propertyKey);
if (propValue != null) {
if (propValue.equals(VALUE_TRUE)) {
return true;
} else if (propValue.equals(VALUE_FALSE)) {
return false;
}
}
DecisionRememberingConfirmDialog d = new DecisionRememberingConfirmDialog(i18nKey, propertyKey, DialogType.CONFIRM,
arguments);
d.setVisible(true);
return d.confirmed;
}
/**
* Shows a dialog which can only be acknowledged via OK button. If the user selects the
* "don't tell me again" checkbox, this dialog will no longer be shown.
*
* @param i18nKey
* i18n key
* @param propertyKey
* the key which is used to remember the user choice
* @param arguments
* optional i18n arguments
*/
public static void acknowledgeAction(String i18nKey, String propertyKey, Object... arguments) {
String propValue = ParameterService.getParameterValue(propertyKey);
if (VALUE_HIDE.equals(propValue)) {
return;
}
DecisionRememberingConfirmDialog d = new DecisionRememberingConfirmDialog(i18nKey, propertyKey,
DialogType.ACKNOWLEDGE, arguments);
d.setVisible(true);
}
}