Skip to content

Commit

Permalink
Automatically refresh relation editor when relation is changed outsid…
Browse files Browse the repository at this point in the history
…e of editor

Relation in editor is automatically refreshed when no changes have
been made in the editor yet. Display a warning notification about
required conflict resolution otherwise.
  • Loading branch information
Woazboat committed Feb 8, 2022
1 parent c4af10f commit 45c7cf7
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -316,17 +316,17 @@ public final Collection<Conflict<? extends OsmPrimitive>> getNodeConflicts() {
}

/**
* Returns the list of conflicts involving nodes.
* @return The list of conflicts involving nodes.
* Returns the list of conflicts involving ways.
* @return The list of conflicts involving ways.
* @since 6555
*/
public final Collection<Conflict<? extends OsmPrimitive>> getWayConflicts() {
return SubclassFilteredCollection.filter(conflicts, c -> c != null && c.getMy() instanceof Way);
}

/**
* Returns the list of conflicts involving nodes.
* @return The list of conflicts involving nodes.
* Returns the list of conflicts involving relations.
* @return The list of conflicts involving relations.
* @since 6555
*/
public final Collection<Conflict<? extends OsmPrimitive>> getRelationConflicts() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.MainMenu;
import org.openstreetmap.josm.gui.Notification;
import org.openstreetmap.josm.gui.ScrollViewport;
import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
import org.openstreetmap.josm.gui.dialogs.relation.actions.AbstractRelationEditorAction;
Expand Down Expand Up @@ -1048,10 +1049,27 @@ public AutoCompletingTextField getTextFieldRole() {
@Override
public void commandChanged(int queueSize, int redoSize) {
Relation r = getRelation();
if (r != null && r.getDataSet() == null) {
// see #19915
setRelation(null);
applyAction.updateEnabledState();
if (r != null) {
if (r.getDataSet() == null) {
// see #19915
setRelation(null);
applyAction.updateEnabledState();
} else if (isDirtyRelation()) {
if (!isDirtyEditor()) {
reloadDataFromRelation();
} else {
new Notification(tr("Relation modified outside of relation editor with pending changes. Conflict resolution required."))
.setIcon(JOptionPane.WARNING_MESSAGE).show();
}
}
}
}

@Override
public boolean isDirtyEditor() {
Relation snapshot = getRelationSnapshot();
Relation relation = getRelation();
return (snapshot != null && !memberTableModel.hasSameMembersAs(snapshot)) ||
tagEditorPanel.getModel().isDirty() || relation == null || relation.getDataSet() == null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@ public interface IRelationEditor {
*/
boolean isDirtyRelation();

/**
* Replies true if the currently edited relation has been changed elsewhere.
*
* In this case a relation editor can't apply updates to the relation directly. Rather,
* it has to create a conflict.
*
* @param ignoreUninterestingTags whether to ignore uninteresting tag changes
* @return true if the currently edited relation has been changed elsewhere.
*/
boolean isDirtyRelation(boolean ignoreUninterestingTags);

/**
* Replies true if the relation has been changed in the editor (but not yet applied).
*
* Reloading data from the relation would cause the pending changes to be lost.
*
* @return true if the currently edited relation has been changed in the editor.
*/
boolean isDirtyEditor();

/**
* Reloads data from relation.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,17 @@ protected final void setRelationSnapshot(Relation snapshot) {

@Override
public final boolean isDirtyRelation() {
return !relation.hasEqualSemanticAttributes(relationSnapshot);
return isDirtyRelation(false);
}

@Override
public final boolean isDirtyRelation(boolean ignoreUninterestingTags) {
if (relation != null && relation.getDataSet() == null &&
relationSnapshot != null && relationSnapshot.getDataSet() == null) {
return false;
}

return !relation.hasEqualSemanticAttributes(relationSnapshot, ignoreUninterestingTags);
}

/* ----------------------------------------------------------------------- */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,7 @@ public void actionPerformed(ActionEvent e) {

@Override
public void updateEnabledState() {
Relation snapshot = getEditor().getRelationSnapshot();
Relation relation = getEditor().getRelation();
if (relation != null && relation.getDataSet() == null)
relation = null; // see #19915
if (relation != null && snapshot != null && snapshot.getDataSet() == null) {
// relation was changed outside of the editor
// either it was modified or deleted or changed by an undo
setEnabled(!snapshot.hasEqualSemanticAttributes(relation, false /* don't ignore uninteresting keys */));
return;
}
setEnabled(false);
setEnabled(getEditor().isDirtyRelation());
}

protected int confirmDiscardDirtyData() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,6 @@ protected void hideEditor() {
}

protected boolean isEditorDirty() {
Relation snapshot = editorAccess.getEditor().getRelationSnapshot();
return (snapshot != null && !getMemberTableModel().hasSameMembersAs(snapshot)) || getTagModel().isDirty()
|| getEditor().getRelation() == null || getEditor().getRelation().getDataSet() == null;
return editorAccess.getEditor().isDirtyEditor();
}
}

0 comments on commit 45c7cf7

Please sign in to comment.