001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.relation.actions;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.event.ActionEvent;
007
008import javax.swing.JComponent;
009import javax.swing.JOptionPane;
010import javax.swing.JRootPane;
011import javax.swing.KeyStroke;
012import javax.swing.RootPaneContainer;
013
014import org.openstreetmap.josm.Main;
015import org.openstreetmap.josm.data.osm.Relation;
016import org.openstreetmap.josm.gui.HelpAwareOptionPane;
017import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
018import org.openstreetmap.josm.gui.dialogs.relation.MemberTable;
019import org.openstreetmap.josm.gui.dialogs.relation.MemberTableModel;
020import org.openstreetmap.josm.gui.dialogs.relation.IRelationEditor;
021import org.openstreetmap.josm.gui.layer.OsmDataLayer;
022import org.openstreetmap.josm.gui.tagging.TagEditorModel;
023import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingTextField;
024import org.openstreetmap.josm.tools.ImageProvider;
025
026/**
027 * Cancel the updates and close the dialog
028 * @since 9496
029 */
030public class CancelAction extends SavingAction {
031
032    /**
033     * Constructs a new {@code CancelAction}.
034     * @param memberTable member table
035     * @param memberTableModel member table model
036     * @param tagModel tag editor model
037     * @param layer OSM data layer
038     * @param editor relation editor
039     * @param tfRole role text field
040     */
041    public CancelAction(MemberTable memberTable, MemberTableModel memberTableModel, TagEditorModel tagModel, OsmDataLayer layer,
042            IRelationEditor editor, AutoCompletingTextField tfRole) {
043        super(memberTable, memberTableModel, tagModel, layer, editor, tfRole);
044        putValue(SHORT_DESCRIPTION, tr("Cancel the updates and close the dialog"));
045        putValue(SMALL_ICON, ImageProvider.get("cancel"));
046        putValue(NAME, tr("Cancel"));
047
048        if (editor instanceof RootPaneContainer) {
049            JRootPane root = ((RootPaneContainer) editor).getRootPane();
050            root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ESCAPE"), "ESCAPE");
051            root.getActionMap().put("ESCAPE", this);
052        }
053        setEnabled(true);
054    }
055
056    @Override
057    public void actionPerformed(ActionEvent e) {
058        memberTable.stopHighlighting();
059        Relation snapshot = editor.getRelationSnapshot();
060        if ((!memberTableModel.hasSameMembersAs(snapshot) || tagModel.isDirty())
061         && !(snapshot == null && tagModel.getTags().isEmpty())) {
062            //give the user a chance to save the changes
063            int ret = confirmClosingByCancel();
064            if (ret == 0) { //Yes, save the changes
065                //copied from OKAction.run()
066                Main.pref.put("relation.editor.generic.lastrole", tfRole.getText());
067                if (!applyChanges())
068                    return;
069            } else if (ret == 2 || ret == JOptionPane.CLOSED_OPTION) //Cancel, continue editing
070                return;
071            //in case of "No, discard", there is no extra action to be performed here.
072        }
073        hideEditor();
074    }
075
076    protected int confirmClosingByCancel() {
077        ButtonSpec[] options = new ButtonSpec[] {
078                new ButtonSpec(
079                        tr("Yes, save the changes and close"),
080                        ImageProvider.get("ok"),
081                        tr("Click to save the changes and close this relation editor"),
082                        null /* no specific help topic */
083                ),
084                new ButtonSpec(
085                        tr("No, discard the changes and close"),
086                        ImageProvider.get("cancel"),
087                        tr("Click to discard the changes and close this relation editor"),
088                        null /* no specific help topic */
089                ),
090                new ButtonSpec(
091                        tr("Cancel, continue editing"),
092                        ImageProvider.get("cancel"),
093                        tr("Click to return to the relation editor and to resume relation editing"),
094                        null /* no specific help topic */
095                )
096        };
097
098        return HelpAwareOptionPane.showOptionDialog(
099                Main.parent,
100                tr("<html>The relation has been changed.<br><br>Do you want to save your changes?</html>"),
101                        tr("Unsaved changes"),
102                        JOptionPane.WARNING_MESSAGE,
103                        null,
104                        options,
105                        options[0], // OK is default,
106                        "/Dialog/RelationEditor#DiscardChanges"
107        );
108    }
109}