Changeset 18413 in josm for trunk/src/org


Ignore:
Timestamp:
2022-03-23T17:07:59+01:00 (3 years ago)
Author:
taylor.smock
Message:

fix #21825: delete non-useful relations

This offers to delete relations when users have either removed all
members or all tags.

Location:
trunk/src/org/openstreetmap/josm
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/IRelation.java

    r16445 r18413  
    139139                .map(IRelationMember::getMember).collect(Collectors.toList());
    140140    }
     141
     142    /**
     143     * Check if this relation is useful
     144     * @return {@code true} if this relation is useful
     145     * @since 18413
     146     */
     147    default boolean isUseful() {
     148        return !this.isEmpty() && this.hasKeys();
     149    }
    141150}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java

    r18211 r18413  
    4848import javax.swing.JToolBar;
    4949import javax.swing.KeyStroke;
     50import javax.swing.event.TableModelListener;
    5051
    5152import org.openstreetmap.josm.actions.JosmAction;
     
    5556import org.openstreetmap.josm.data.UndoRedoHandler.CommandQueueListener;
    5657import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
     58import org.openstreetmap.josm.data.osm.IRelation;
    5759import org.openstreetmap.josm.data.osm.OsmPrimitive;
    5860import org.openstreetmap.josm.data.osm.Relation;
     
    133135
    134136    private final AutoCompletingTextField tfRole;
     137    private final RelationEditorActionAccess actionAccess;
    135138
    136139    /**
     
    263266        });
    264267
    265         IRelationEditorActionAccess actionAccess = new RelationEditorActionAccess();
     268        actionAccess = new RelationEditorActionAccess();
    266269
    267270        refreshAction = new RefreshAction(actionAccess);
     
    270273        duplicateAction = new DuplicateRelationAction(actionAccess);
    271274        deleteAction = new DeleteCurrentRelationAction(actionAccess);
     275
     276        this.memberTableModel.addTableModelListener(applyAction);
     277        this.tagEditorPanel.getModel().addTableModelListener(applyAction);
     278
    272279        addPropertyChangeListener(deleteAction);
    273280
     
    277284        getContentPane().add(buildToolBar(refreshAction, applyAction, selectAction, duplicateAction, deleteAction), BorderLayout.NORTH);
    278285        getContentPane().add(tabbedPane, BorderLayout.CENTER);
    279         getContentPane().add(buildOkCancelButtonPanel(okAction, cancelAction), BorderLayout.SOUTH);
     286        getContentPane().add(buildOkCancelButtonPanel(okAction, deleteAction, cancelAction), BorderLayout.SOUTH);
    280287
    281288        setSize(findMaxDialogSize());
     
    408415     * @return the panel with the OK and the Cancel button
    409416     */
    410     protected static JPanel buildOkCancelButtonPanel(OKAction okAction, CancelAction cancelAction) {
    411         JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
    412         pnl.add(new JButton(okAction));
     417    protected final JPanel buildOkCancelButtonPanel(OKAction okAction, DeleteCurrentRelationAction deleteAction,
     418            CancelAction cancelAction) {
     419        final JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
     420        final JButton okButton = new JButton(okAction);
     421        final JButton deleteButton = new JButton(deleteAction);
     422        okButton.setPreferredSize(deleteButton.getPreferredSize());
     423        pnl.add(okButton);
     424        pnl.add(deleteButton);
    413425        pnl.add(new JButton(cancelAction));
    414426        pnl.add(new JButton(new ContextSensitiveHelpAction(ht("/Dialog/RelationEditor"))));
     427        // Keep users from saving invalid relations -- a relation MUST have at least a tag with the key "type"
     428        // AND must contain at least one other OSM object.
     429        final TableModelListener listener = l -> updateOkPanel(this.actionAccess.getChangedRelation(), okButton, deleteButton);
     430        listener.tableChanged(null);
     431        this.memberTableModel.addTableModelListener(listener);
     432        this.tagEditorPanel.getModel().addTableModelListener(listener);
    415433        return pnl;
     434    }
     435
     436    /**
     437     * Update the OK panel area
     438     * @param newRelation What the new relation would "look" like if it were to be saved now
     439     * @param okButton The OK button
     440     * @param deleteButton The delete button
     441     */
     442    private void updateOkPanel(IRelation<?> newRelation, JButton okButton, JButton deleteButton) {
     443        okButton.setVisible(newRelation.isUseful() || this.getRelationSnapshot() == null);
     444        deleteButton.setVisible(!newRelation.isUseful() && this.getRelationSnapshot() != null);
     445        if (this.getRelationSnapshot() == null && !newRelation.isUseful()) {
     446            okButton.setText(tr("Delete"));
     447        } else {
     448            okButton.setText(tr("OK"));
     449        }
    416450    }
    417451
     
    10021036        public void mouseClicked(MouseEvent e) {
    10031037            if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
    1004                 new EditAction(new RelationEditorActionAccess()).actionPerformed(null);
     1038                new EditAction(actionAccess).actionPerformed(null);
    10051039            }
    10061040        }
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/ApplyAction.java

    r17172 r18413  
    3636    @Override
    3737    public void updateEnabledState() {
    38         setEnabled(isEditorDirty());
     38        setEnabled(this.editorAccess.getChangedRelation().isUseful() && isEditorDirty());
    3939    }
    4040}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/CancelAction.java

    r17555 r18413  
    99import javax.swing.RootPaneContainer;
    1010
     11import org.openstreetmap.josm.data.osm.IRelation;
    1112import org.openstreetmap.josm.data.osm.Relation;
    1213import org.openstreetmap.josm.gui.HelpAwareOptionPane;
     
    4849         && !(snapshot == null && getTagModel().getTags().isEmpty())) {
    4950            //give the user a chance to save the changes
    50             int ret = confirmClosingByCancel();
     51            int ret = confirmClosingByCancel(this.editorAccess.getChangedRelation());
    5152            if (ret == 0) { //Yes, save the changes
    5253                //copied from OKAction.run()
     
    6162    }
    6263
    63     protected int confirmClosingByCancel() {
     64    protected int confirmClosingByCancel(final IRelation<?> newRelation) {
    6465        ButtonSpec[] options = {
    6566                new ButtonSpec(
     
    8384        };
    8485
     86        // Keep users from saving invalid relations -- a relation MUST have at least a tag with the key "type"
     87        // AND must contain at least one other OSM object.
     88        options[0].setEnabled(newRelation.isUseful());
     89
    8590        return HelpAwareOptionPane.showOptionDialog(
    8691                MainApplication.getMainFrame(),
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/IRelationEditorActionAccess.java

    r18118 r18413  
    44import javax.swing.Action;
    55
     6import org.openstreetmap.josm.data.osm.IRelation;
     7import org.openstreetmap.josm.data.osm.Relation;
    68import org.openstreetmap.josm.gui.dialogs.relation.IRelationEditor;
    79import org.openstreetmap.josm.gui.dialogs.relation.MemberTable;
     
    6769
    6870    /**
     71     * Get the changed relation
     72     * @return The changed relation (note: will not be part of a dataset). This should never be {@code null}.
     73     * @since 18413
     74     */
     75    default IRelation<?> getChangedRelation() {
     76        final Relation newRelation;
     77        if (getEditor().getRelation() != null) {
     78            newRelation = new Relation(getEditor().getRelation());
     79        } else {
     80            newRelation = new Relation();
     81        }
     82        getTagModel().applyToPrimitive(newRelation);
     83        getMemberTableModel().applyToRelation(newRelation);
     84        return newRelation;
     85    }
     86
     87    /**
    6988     * Get the text field that is used to edit the role.
    7089     * @return The role text field.
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/SavingAction.java

    r18177 r18413  
    5555        getMemberTableModel().applyToRelation(newRelation);
    5656        // If the user wanted to create a new relation, but hasn't added any members or
    57         // tags, don't add an empty relation
    58         if (newRelation.isEmpty() && !newRelation.hasKeys())
     57        // tags (specifically the "type" tag), don't add the relation
     58        if (!newRelation.isUseful())
    5959            return;
    6060        UndoRedoHandler.getInstance().add(new AddCommand(getLayer().getDataSet(), newRelation));
Note: See TracChangeset for help on using the changeset viewer.