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 snapshot = getEditor().getRelationSnapshot(); 071 Relation relation = getEditor().getRelation(); 072 if (relation != null && relation.getDataSet() == null) 073 relation = null; // see #19915 074 if (relation != null && snapshot != null && snapshot.getDataSet() == null) { 075 // relation was changed outside of the editor 076 // either it was modified or deleted or changed by an undo 077 setEnabled(!snapshot.hasEqualSemanticAttributes(relation, false /* don't ignore uninteresting keys */)); 078 return; 079 } 080 setEnabled(false); 081 } 082 083 protected int confirmDiscardDirtyData() { 084 ButtonSpec[] options = { 085 new ButtonSpec( 086 tr("Yes, discard changes and reload"), 087 new ImageProvider("ok"), 088 tr("Click to discard the changes and reload data from layer"), 089 null /* no specific help topic */ 090 ), 091 new ButtonSpec( 092 tr("Cancel, continue editing"), 093 new ImageProvider("cancel"), 094 tr("Click to return to the relation editor and to resume relation editing"), 095 null /* no specific help topic */ 096 ) 097 }; 098 099 return HelpAwareOptionPane.showOptionDialog( 100 MainApplication.getMainFrame(), 101 tr("<html>You have unsaved changes in this editor window.<br>"+ 102 "<br>Do you want to discard these changes and reload data from layer?</html>"), 103 tr("Unsaved changes"), 104 JOptionPane.WARNING_MESSAGE, 105 null, 106 options, 107 options[1], // Cancel is default 108 "/Dialog/RelationEditor#Reload" 109 ); 110 } 111 112 protected int confirmCloseDeletedRelation() { 113 ButtonSpec[] options = { 114 new ButtonSpec( 115 tr("Yes"), 116 new ImageProvider("ok"), 117 tr("Click to close window"), 118 null /* no specific help topic */ 119 ), 120 new ButtonSpec( 121 tr("No, continue editing"), 122 new ImageProvider("cancel"), 123 tr("Click to return to the relation editor and to resume relation editing"), 124 null /* no specific help topic */ 125 ) 126 }; 127 128 return HelpAwareOptionPane.showOptionDialog( 129 MainApplication.getMainFrame(), 130 tr("<html>Relation has been deleted outside editor.<br><br>Do you want to close this window?</html>"), 131 tr("Deleted relation"), 132 JOptionPane.WARNING_MESSAGE, 133 null, 134 options, 135 options[0], // Yes is default 136 "/Dialog/RelationEditor#Reload" 137 ); 138 } 139 140 @Override 141 public void commandChanged(int queueSize, int redoSize) { 142 updateEnabledState(); 143 } 144 145 /** 146 * Allow GC to do its work 147 */ 148 public void destroy() { 149 UndoRedoHandler.getInstance().removeCommandQueueListener(this); 150 } 151}