Ticket #12410: RefreshRelationEditor.patch
File RefreshRelationEditor.patch, 21.3 KB (added by , 5 years ago) |
---|
-
src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java b/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java index be435fc..77a0643 100644
a b import org.openstreetmap.josm.gui.dialogs.relation.actions.OKAction; 78 78 import org.openstreetmap.josm.gui.dialogs.relation.actions.PasteMembersAction; 79 79 import org.openstreetmap.josm.gui.dialogs.relation.actions.RemoveAction; 80 80 import org.openstreetmap.josm.gui.dialogs.relation.actions.RemoveSelectedAction; 81 import org.openstreetmap.josm.gui.dialogs.relation.actions.RefreshAction; 81 82 import org.openstreetmap.josm.gui.dialogs.relation.actions.ReverseAction; 82 83 import org.openstreetmap.josm.gui.dialogs.relation.actions.SelectPrimitivesForSelectedMembersAction; 83 84 import org.openstreetmap.josm.gui.dialogs.relation.actions.SelectedMembersForSelectionAction; … … public class GenericRelationEditor extends RelationEditor { 127 128 */ 128 129 private JButton sortBelowButton; 129 130 /** 131 * Action for performing the {@link RefreshAction} 132 */ 133 private RefreshAction refreshAction; 134 /** 135 * Action for performing the {@link ApplyAction} 136 */ 137 private ApplyAction applyAction; 138 /** 130 139 * Action for performing the {@link CancelAction} 131 140 */ 132 141 private CancelAction cancelAction; … … public class GenericRelationEditor extends RelationEditor { 171 180 referrerModel = new ReferringRelationsBrowserModel(relation); 172 181 173 182 tagEditorPanel = new TagEditorPanel(relation, presetHandler); 174 175 // populate the models 176 // 177 if (relation != null) { 178 tagEditorPanel.getModel().initFromPrimitive(relation); 179 this.memberTableModel.populate(relation); 180 if (!getLayer().data.getRelations().contains(relation)) { 181 // treat it as a new relation if it doesn't exist in the 182 // data set yet. 183 setRelation(null); 184 } 185 } else { 186 tagEditorPanel.getModel().clear(); 187 this.memberTableModel.populate(null); 188 } 183 populateModels(relation); 189 184 tagEditorPanel.getModel().ensureOneTag(); 190 185 191 186 JSplitPane pane = buildSplitPane(); … … public class GenericRelationEditor extends RelationEditor { 258 253 HelpUtil.setHelpContext(getRootPane(), ht("/Dialog/RelationEditor")); 259 254 } 260 255 261 protected void cancel() { 256 public void reloadDataFromRelation() { 257 setRelation(getRelation()); 258 populateModels(getRelation()); 259 refreshAction.updateEnabledState(); 260 } 261 262 private void populateModels(Relation relation) { 263 if (relation != null) { 264 tagEditorPanel.getModel().initFromPrimitive(relation); 265 this.memberTableModel.populate(relation); 266 if (!getLayer().data.getRelations().contains(relation)) { 267 // treat it as a new relation if it doesn't exist in the 268 // data set yet. 269 setRelation(null); 270 } 271 } else { 272 tagEditorPanel.getModel().clear(); 273 this.memberTableModel.populate(null); 274 } 275 } 276 277 public void apply() { 278 applyAction.actionPerformed(null); 279 } 280 281 public void cancel() { 262 282 cancelAction.actionPerformed(null); 263 283 } 264 284 … … public class GenericRelationEditor extends RelationEditor { 270 290 protected JToolBar buildToolBar() { 271 291 JToolBar tb = new JToolBar(); 272 292 tb.setFloatable(false); 273 tb.add(new ApplyAction(memberTable, memberTableModel, tagEditorPanel.getModel(), getLayer(), this)); 293 tb.add(refreshAction = new RefreshAction(memberTable, memberTableModel, tagEditorPanel.getModel(), getLayer(), this)); 294 tb.add(applyAction = new ApplyAction(memberTable, memberTableModel, tagEditorPanel.getModel(), getLayer(), this)); 274 295 tb.add(new DuplicateRelationAction(memberTableModel, tagEditorPanel.getModel(), getLayer())); 275 296 DeleteCurrentRelationAction deleteAction = new DeleteCurrentRelationAction(getLayer(), this); 276 297 addPropertyChangeListener(deleteAction); -
src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java index 06bad08..cd6a190 100644
a b implements TableModelListener, SelectionChangedListener, DataSetListener, OsmPri 234 234 return; 235 235 } 236 236 RelationMember member = members.get(rowIndex); 237 RelationMember newMember = new RelationMember(value.toString(), member.getMember()); 237 String role = value.toString(); 238 if (member.hasRole(role)) return; 239 RelationMember newMember = new RelationMember(role, member.getMember()); 238 240 members.remove(rowIndex); 239 241 members.add(rowIndex, newMember); 242 fireTableDataChanged(); 240 243 } 241 244 242 245 @Override -
src/org/openstreetmap/josm/gui/dialogs/relation/actions/ApplyAction.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/actions/ApplyAction.java b/src/org/openstreetmap/josm/gui/dialogs/relation/actions/ApplyAction.java index 0e68e10..3777829 100644
a b package org.openstreetmap.josm.gui.dialogs.relation.actions; 3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.Component;7 6 import java.awt.event.ActionEvent; 8 7 8 import java.beans.PropertyChangeEvent; 9 import java.beans.PropertyChangeListener; 10 11 import javax.swing.event.TableModelEvent; 12 import javax.swing.event.TableModelListener; 13 14 import org.openstreetmap.josm.gui.dialogs.relation.GenericRelationEditor; 9 15 import org.openstreetmap.josm.gui.dialogs.relation.MemberTable; 10 16 import org.openstreetmap.josm.gui.dialogs.relation.MemberTableModel; 11 17 import org.openstreetmap.josm.gui.dialogs.relation.RelationAware; … … import org.openstreetmap.josm.tools.ImageProvider; 17 23 * Apply the current updates. 18 24 * @since 9496 19 25 */ 20 public class ApplyAction extends SavingAction {26 public class ApplyAction extends SavingAction implements PropertyChangeListener, TableModelListener { 21 27 22 28 /** 23 29 * Constructs a new {@code ApplyAction}. … … public class ApplyAction extends SavingAction { 33 39 putValue(SHORT_DESCRIPTION, tr("Apply the current updates")); 34 40 putValue(SMALL_ICON, ImageProvider.get("save")); 35 41 putValue(NAME, tr("Apply")); 36 setEnabled(true); 42 updateEnabledState(); 43 memberTableModel.addTableModelListener(this); 44 tagModel.addPropertyChangeListener(this); 37 45 } 38 46 39 47 @Override 40 48 public void actionPerformed(ActionEvent e) { 41 if (editor.getRelation() == null) { 42 applyNewRelation(tagModel); 43 } else if (!memberTableModel.hasSameMembersAs(editor.getRelationSnapshot()) || tagModel.isDirty()) { 44 if (editor.isDirtyRelation()) { 45 if (confirmClosingBecauseOfDirtyState()) { 46 if (layer.getConflicts().hasConflictForMy(editor.getRelation())) { 47 warnDoubleConflict(); 48 return; 49 } 50 applyExistingConflictingRelation(tagModel); 51 if (editor instanceof Component) { 52 ((Component) editor).setVisible(false); 53 } 54 } 55 } else { 56 applyExistingNonConflictingRelation(tagModel); 57 } 49 if (applyChanges()) { 50 ((GenericRelationEditor) editor).reloadDataFromRelation(); 58 51 } 59 52 } 53 54 @Override 55 protected void updateEnabledState() { 56 setEnabled(isEditorDirty()); 57 } 58 59 @Override 60 public void propertyChange(PropertyChangeEvent evt) { 61 updateEnabledState(); 62 } 63 64 @Override 65 public void tableChanged(TableModelEvent e) { 66 updateEnabledState(); 67 } 60 68 } -
src/org/openstreetmap/josm/gui/dialogs/relation/actions/CancelAction.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/actions/CancelAction.java b/src/org/openstreetmap/josm/gui/dialogs/relation/actions/CancelAction.java index 980d5a5..8632285 100644
a b package org.openstreetmap.josm.gui.dialogs.relation.actions; 3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.Component;7 6 import java.awt.event.ActionEvent; 8 7 9 8 import javax.swing.JComponent; … … public class CancelAction extends SavingAction { 65 64 if (ret == 0) { //Yes, save the changes 66 65 //copied from OKAction.run() 67 66 Main.pref.put("relation.editor.generic.lastrole", tfRole.getText()); 68 if (editor.getRelation() == null) { 69 applyNewRelation(tagModel); 70 } else if (!memberTableModel.hasSameMembersAs(snapshot) || tagModel.isDirty()) { 71 if (editor.isDirtyRelation()) { 72 if (confirmClosingBecauseOfDirtyState()) { 73 if (layer.getConflicts().hasConflictForMy(editor.getRelation())) { 74 warnDoubleConflict(); 75 return; 76 } 77 applyExistingConflictingRelation(tagModel); 78 } else 79 return; 80 } else { 81 applyExistingNonConflictingRelation(tagModel); 82 } 83 } 67 if (!applyChanges()) return; 84 68 } else if (ret == 2 || ret == JOptionPane.CLOSED_OPTION) //Cancel, continue editing 85 69 return; 86 70 //in case of "No, discard", there is no extra action to be performed here. 87 71 } 88 if (editor instanceof Component) { 89 ((Component) editor).setVisible(false); 90 } 72 hideEditor(); 91 73 } 92 74 93 75 protected int confirmClosingByCancel() { -
src/org/openstreetmap/josm/gui/dialogs/relation/actions/OKAction.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/actions/OKAction.java b/src/org/openstreetmap/josm/gui/dialogs/relation/actions/OKAction.java index 0cc65f3..5df5c69 100644
a b package org.openstreetmap.josm.gui.dialogs.relation.actions; 3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.Component;7 6 import java.awt.event.ActionEvent; 8 7 9 8 import org.openstreetmap.josm.Main; … … public class OKAction extends SavingAction { 42 41 public void actionPerformed(ActionEvent e) { 43 42 Main.pref.put("relation.editor.generic.lastrole", tfRole.getText()); 44 43 memberTable.stopHighlighting(); 45 if (editor.getRelation() == null) { 46 applyNewRelation(tagModel); 47 } else if (!memberTableModel.hasSameMembersAs(editor.getRelationSnapshot()) || tagModel.isDirty()) { 48 if (editor.isDirtyRelation()) { 49 if (confirmClosingBecauseOfDirtyState()) { 50 if (layer.getConflicts().hasConflictForMy(editor.getRelation())) { 51 warnDoubleConflict(); 52 return; 53 } 54 applyExistingConflictingRelation(tagModel); 55 } else 56 return; 57 } else { 58 applyExistingNonConflictingRelation(tagModel); 59 } 60 } 61 if (editor instanceof Component) { 62 ((Component) editor).setVisible(false); 63 } 44 if (!applyChanges()) return; 45 hideEditor(); 64 46 } 65 47 } -
new file src/org/openstreetmap/josm/gui/dialogs/relation/actions/RefreshAction.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/actions/RefreshAction.java b/src/org/openstreetmap/josm/gui/dialogs/relation/actions/RefreshAction.java new file mode 100644 index 0000000..5734311
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.dialogs.relation.actions; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 6 import java.awt.Component; 7 import java.awt.event.ActionEvent; 8 import java.awt.event.KeyEvent; 9 10 import javax.swing.JComponent; 11 import javax.swing.JOptionPane; 12 13 import org.openstreetmap.josm.Main; 14 import org.openstreetmap.josm.data.osm.Relation; 15 import org.openstreetmap.josm.gui.dialogs.relation.GenericRelationEditor; 16 import org.openstreetmap.josm.gui.dialogs.relation.MemberTable; 17 import org.openstreetmap.josm.gui.dialogs.relation.MemberTableModel; 18 import org.openstreetmap.josm.gui.dialogs.relation.RelationAware; 19 import org.openstreetmap.josm.gui.HelpAwareOptionPane; 20 import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec; 21 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 22 import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener; 23 import org.openstreetmap.josm.gui.tagging.TagEditorModel; 24 import org.openstreetmap.josm.tools.ImageProvider; 25 import org.openstreetmap.josm.tools.Shortcut; 26 27 /** 28 * Refresh relation. 29 */ 30 public class RefreshAction extends SavingAction implements CommandQueueListener { 31 32 /** 33 * Constructs a new {@code ApplyAction}. 34 * @param memberTable member table 35 * @param memberTableModel member table model 36 * @param layer OSM data layer 37 * @param editor relation editor 38 * @param tagModel tag editor model 39 */ 40 public RefreshAction(MemberTable memberTable, MemberTableModel memberTableModel, TagEditorModel tagModel, OsmDataLayer layer, 41 RelationAware editor) { 42 super(memberTable, memberTableModel, tagModel, layer, editor, null); 43 Shortcut sc = Shortcut.registerShortcut("relationeditor:refresh", tr("Relation Editor: Refresh"), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE); 44 putValue(SHORT_DESCRIPTION, Main.platform.makeTooltip(tr("Refresh relation from data layer"), sc)); 45 putValue(SMALL_ICON, ImageProvider.get("dialogs/refresh")); 46 putValue(NAME, tr("Refresh")); 47 getEditor().getRootPane().getActionMap().put("refresh", this); 48 getEditor().getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sc.getKeyStroke(), "refresh"); 49 Main.main.undoRedo.addCommandQueueListener(this); 50 updateEnabledState(); 51 } 52 53 private GenericRelationEditor getEditor() { 54 return (GenericRelationEditor) editor; 55 } 56 57 @Override 58 public void actionPerformed(ActionEvent e) { 59 Relation relation = editor.getRelation(); 60 if (relation == null) return; 61 if (relation.isDeleted()) { 62 if (confirmCloseDeletedRelation() == 0) { 63 hideEditor(); 64 } 65 return; 66 } 67 if (isEditorDirty() && confirmDiscardDirtyData() != 0) return; 68 getEditor().reloadDataFromRelation(); 69 } 70 71 @Override 72 public void updateEnabledState() { 73 Relation relation = editor.getRelation(); 74 Relation snapshot = editor.getRelationSnapshot(); 75 setEnabled(snapshot != null && ( 76 !relation.hasEqualTechnicalAttributes(snapshot) || 77 !relation.hasEqualSemanticAttributes(snapshot) 78 )); 79 } 80 81 protected int confirmDiscardDirtyData() { 82 ButtonSpec[] options = new ButtonSpec[] { 83 new ButtonSpec( 84 tr("Yes, discard changes and reload"), 85 ImageProvider.get("ok"), 86 tr("Click to discard the changes and reload data from layer"), 87 null /* no specific help topic */ 88 ), 89 new ButtonSpec( 90 tr("Cancel, continue editing"), 91 ImageProvider.get("cancel"), 92 tr("Click to return to the relation editor and to resume relation editing"), 93 null /* no specific help topic */ 94 ) 95 }; 96 97 return HelpAwareOptionPane.showOptionDialog( 98 Main.parent, 99 tr("<html>You have unsaved changes in this editor window.<br><br>Do you want to discard these changes and reload data from layer?</html>"), 100 tr("Unsaved changes"), 101 JOptionPane.WARNING_MESSAGE, 102 null, 103 options, 104 options[1], // Cancel is default 105 "/Dialog/RelationEditor#Reload" 106 ); 107 } 108 109 protected int confirmCloseDeletedRelation() { 110 ButtonSpec[] options = new ButtonSpec[] { 111 new ButtonSpec( 112 tr("Yes"), 113 ImageProvider.get("ok"), 114 tr("Click to close window"), 115 null /* no specific help topic */ 116 ), 117 new ButtonSpec( 118 tr("No, continue editing"), 119 ImageProvider.get("cancel"), 120 tr("Click to return to the relation editor and to resume relation editing"), 121 null /* no specific help topic */ 122 ) 123 }; 124 125 return HelpAwareOptionPane.showOptionDialog( 126 Main.parent, 127 tr("<html>Relation has been deleted outside editor.<br><br>Do you want to close this window?</html>"), 128 tr("Deleted relation"), 129 JOptionPane.WARNING_MESSAGE, 130 null, 131 options, 132 options[0], // Yes is default 133 "/Dialog/RelationEditor#Reload" 134 ); 135 } 136 137 @Override 138 public void commandChanged(int queueSize, int redoSize) { 139 updateEnabledState(); 140 } 141 } -
src/org/openstreetmap/josm/gui/dialogs/relation/actions/SavingAction.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/actions/SavingAction.java b/src/org/openstreetmap/josm/gui/dialogs/relation/actions/SavingAction.java index e7525d2..96c51af 100644
a b package org.openstreetmap.josm.gui.dialogs.relation.actions; 3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.Component; 6 7 import java.util.ArrayList; 7 8 import java.util.List; 8 9 … … abstract class SavingAction extends AbstractRelationEditorAction { 110 111 memberTableModel.applyToRelation(editedRelation); 111 112 Main.main.undoRedo.add(new ChangeCommand(editor.getRelation(), editedRelation)); 112 113 layer.data.fireSelectionChanged(); 113 // this will refresh the snapshot and update the dialog title114 //115 editor.setRelation(editor.getRelation());116 114 } 117 115 118 116 protected boolean confirmClosingBecauseOfDirtyState() { … … abstract class SavingAction extends AbstractRelationEditorAction { 165 163 protected void updateEnabledState() { 166 164 // Do nothing 167 165 } 166 167 protected boolean applyChanges() { 168 if (editor.getRelation() == null) { 169 applyNewRelation(tagModel); 170 } else if (isEditorDirty()) { 171 if (editor.isDirtyRelation()) { 172 if (confirmClosingBecauseOfDirtyState()) { 173 if (layer.getConflicts().hasConflictForMy(editor.getRelation())) { 174 warnDoubleConflict(); 175 return false; 176 } 177 applyExistingConflictingRelation(tagModel); 178 hideEditor(); 179 } else 180 return false; 181 } else { 182 applyExistingNonConflictingRelation(tagModel); 183 } 184 } 185 editor.setRelation(editor.getRelation()); 186 return true; 187 } 188 189 protected void hideEditor() { 190 if (editor instanceof Component) { 191 ((Component) editor).setVisible(false); 192 } 193 } 194 195 protected boolean isEditorDirty() { 196 Relation snapshot = editor.getRelationSnapshot(); 197 return (snapshot != null && !memberTableModel.hasSameMembersAs(snapshot)) || tagModel.isDirty(); 198 } 168 199 } -
src/org/openstreetmap/josm/gui/tagging/TagEditorModel.java
diff --git a/src/org/openstreetmap/josm/gui/tagging/TagEditorModel.java b/src/org/openstreetmap/josm/gui/tagging/TagEditorModel.java index 6ad4926..954f42c 100644
a b public class TagEditorModel extends AbstractTableModel { 165 165 * removes all tags in the model 166 166 */ 167 167 public void clear() { 168 boolean wasEmpty = tags.isEmpty(); 168 169 tags.clear(); 169 setDirty(true); 170 fireTableDataChanged(); 170 if (!wasEmpty) { 171 setDirty(true); 172 fireTableDataChanged(); 173 } 171 174 } 172 175 173 176 /** … … public class TagEditorModel extends AbstractTableModel { 334 337 TagModel tag = new TagModel(); 335 338 tags.add(tag); 336 339 fireTableDataChanged(); 337 setDirty(true);338 340 } 339 341 340 342 /**