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;
007import java.awt.event.KeyEvent;
008
009import javax.swing.JComponent;
010import javax.swing.JOptionPane;
011import javax.swing.JRootPane;
012
013import org.openstreetmap.josm.data.UndoRedoHandler;
014import org.openstreetmap.josm.data.UndoRedoHandler.CommandQueueListener;
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.MainApplication;
019import org.openstreetmap.josm.gui.dialogs.relation.IRelationEditor;
020import org.openstreetmap.josm.tools.ImageProvider;
021import org.openstreetmap.josm.tools.Shortcut;
022
023/**
024 * Refresh relation.
025 * @since 9657
026 */
027public class RefreshAction extends SavingAction implements CommandQueueListener {
028    private static final long serialVersionUID = 1L;
029
030    /**
031     * Constructs a new {@code RefreshAction}.
032     * @param editorAccess An interface to access the relation editor contents.
033     */
034    public RefreshAction(IRelationEditorActionAccess editorAccess) {
035        super(editorAccess);
036        // CHECKSTYLE.OFF: LineLength
037        Shortcut sc = Shortcut.registerShortcut("relationeditor:refresh", tr("Relation Editor: Refresh"), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE);
038        // CHECKSTYLE.ON: LineLength
039        sc.setTooltip(this, tr("Refresh relation from data layer"));
040        new ImageProvider("dialogs/refresh").getResource().attachImageIcon(this, true);
041        putValue(NAME, tr("Refresh"));
042        IRelationEditor editor = editorAccess.getEditor();
043        if (editor instanceof JComponent) {
044            JRootPane rootPane = ((JComponent) editor).getRootPane();
045            rootPane.getActionMap().put("refresh", this);
046            rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sc.getKeyStroke(), "refresh");
047        }
048        UndoRedoHandler.getInstance().addCommandQueueListener(this);
049        updateEnabledState();
050    }
051
052    @Override
053    public void actionPerformed(ActionEvent e) {
054        Relation relation = editorAccess.getEditor().getRelation();
055        if (relation == null)
056            return;
057        if (relation.isDeleted()) {
058            if (confirmCloseDeletedRelation() == 0) {
059                hideEditor();
060            }
061            return;
062        }
063        if (isEditorDirty() && confirmDiscardDirtyData() != 0)
064            return;
065        editorAccess.getEditor().reloadDataFromRelation();
066    }
067
068    @Override
069    public void updateEnabledState() {
070        Relation relation = editorAccess.getEditor().getRelation();
071        Relation snapshot = editorAccess.getEditor().getRelationSnapshot();
072        setEnabled(snapshot != null && (
073            !relation.hasEqualTechnicalAttributes(snapshot) ||
074            !relation.hasEqualSemanticAttributes(snapshot)
075        ));
076    }
077
078    protected int confirmDiscardDirtyData() {
079        ButtonSpec[] options = {
080                new ButtonSpec(
081                        tr("Yes, discard changes and reload"),
082                        new ImageProvider("ok"),
083                        tr("Click to discard the changes and reload data from layer"),
084                        null /* no specific help topic */
085                ),
086                new ButtonSpec(
087                        tr("Cancel, continue editing"),
088                        new ImageProvider("cancel"),
089                        tr("Click to return to the relation editor and to resume relation editing"),
090                        null /* no specific help topic */
091                )
092        };
093
094        return HelpAwareOptionPane.showOptionDialog(
095                MainApplication.getMainFrame(),
096                tr("<html>You have unsaved changes in this editor window.<br>"+
097                   "<br>Do you want to discard these changes and reload data from layer?</html>"),
098                        tr("Unsaved changes"),
099                        JOptionPane.WARNING_MESSAGE,
100                        null,
101                        options,
102                        options[1], // Cancel is default
103                        "/Dialog/RelationEditor#Reload"
104        );
105    }
106
107    protected int confirmCloseDeletedRelation() {
108        ButtonSpec[] options = {
109                new ButtonSpec(
110                        tr("Yes"),
111                        new ImageProvider("ok"),
112                        tr("Click to close window"),
113                        null /* no specific help topic */
114                ),
115                new ButtonSpec(
116                        tr("No, continue editing"),
117                        new ImageProvider("cancel"),
118                        tr("Click to return to the relation editor and to resume relation editing"),
119                        null /* no specific help topic */
120                )
121        };
122
123        return HelpAwareOptionPane.showOptionDialog(
124                MainApplication.getMainFrame(),
125                tr("<html>Relation has been deleted outside editor.<br><br>Do you want to close this window?</html>"),
126                        tr("Deleted relation"),
127                        JOptionPane.WARNING_MESSAGE,
128                        null,
129                        options,
130                        options[0], // Yes is default
131                        "/Dialog/RelationEditor#Reload"
132        );
133    }
134
135    @Override
136    public void commandChanged(int queueSize, int redoSize) {
137        updateEnabledState();
138    }
139
140    /**
141     * Allow GC to do its work
142     */
143    public void destroy() {
144        UndoRedoHandler.getInstance().removeCommandQueueListener(this);
145    }
146}