source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java @ 12528

Last change on this file since 12528 was 12528, checked in by Don-vip, 5 months ago

fix #10780 - display undeleted relations in relation list

  • Property svn:eol-style set to native
File size: 26.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Component;
8import java.awt.event.ActionEvent;
9import java.awt.event.KeyEvent;
10import java.awt.event.MouseEvent;
11import java.util.ArrayList;
12import java.util.Arrays;
13import java.util.Collection;
14import java.util.Collections;
15import java.util.HashSet;
16import java.util.List;
17import java.util.Set;
18
19import javax.swing.AbstractAction;
20import javax.swing.AbstractListModel;
21import javax.swing.DefaultListSelectionModel;
22import javax.swing.FocusManager;
23import javax.swing.JComponent;
24import javax.swing.JList;
25import javax.swing.JMenuItem;
26import javax.swing.JPanel;
27import javax.swing.JPopupMenu;
28import javax.swing.JScrollPane;
29import javax.swing.KeyStroke;
30import javax.swing.ListSelectionModel;
31
32import org.openstreetmap.josm.Main;
33import org.openstreetmap.josm.actions.ExpertToggleAction;
34import org.openstreetmap.josm.actions.relation.AddSelectionToRelations;
35import org.openstreetmap.josm.actions.relation.DeleteRelationsAction;
36import org.openstreetmap.josm.actions.relation.DownloadMembersAction;
37import org.openstreetmap.josm.actions.relation.DownloadSelectedIncompleteMembersAction;
38import org.openstreetmap.josm.actions.relation.DuplicateRelationAction;
39import org.openstreetmap.josm.actions.relation.EditRelationAction;
40import org.openstreetmap.josm.actions.relation.RecentRelationsAction;
41import org.openstreetmap.josm.actions.relation.SelectMembersAction;
42import org.openstreetmap.josm.actions.relation.SelectRelationAction;
43import org.openstreetmap.josm.actions.search.SearchCompiler;
44import org.openstreetmap.josm.data.osm.DataSet;
45import org.openstreetmap.josm.data.osm.OsmPrimitive;
46import org.openstreetmap.josm.data.osm.Relation;
47import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
48import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
49import org.openstreetmap.josm.data.osm.event.DataSetListener;
50import org.openstreetmap.josm.data.osm.event.DatasetEventManager;
51import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
52import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
53import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
54import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
55import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
56import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
57import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
58import org.openstreetmap.josm.gui.DefaultNameFormatter;
59import org.openstreetmap.josm.gui.MapView;
60import org.openstreetmap.josm.gui.NavigatableComponent;
61import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
62import org.openstreetmap.josm.gui.PopupMenuHandler;
63import org.openstreetmap.josm.gui.SideButton;
64import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
65import org.openstreetmap.josm.gui.layer.Layer;
66import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
67import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
68import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
69import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
70import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
71import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
72import org.openstreetmap.josm.gui.layer.OsmDataLayer;
73import org.openstreetmap.josm.gui.util.GuiHelper;
74import org.openstreetmap.josm.gui.util.HighlightHelper;
75import org.openstreetmap.josm.gui.widgets.CompileSearchTextDecorator;
76import org.openstreetmap.josm.gui.widgets.DisableShortcutsOnFocusGainedTextField;
77import org.openstreetmap.josm.gui.widgets.JosmTextField;
78import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
79import org.openstreetmap.josm.tools.ImageProvider;
80import org.openstreetmap.josm.tools.InputMapUtils;
81import org.openstreetmap.josm.tools.Shortcut;
82import org.openstreetmap.josm.tools.SubclassFilteredCollection;
83
84/**
85 * A dialog showing all known relations, with buttons to add, edit, and delete them.
86 *
87 * We don't have such dialogs for nodes, segments, and ways, because those
88 * objects are visible on the map and can be selected there. Relations are not.
89 */
90public class RelationListDialog extends ToggleDialog
91        implements DataSetListener, NavigatableComponent.ZoomChangeListener, ExpertToggleAction.ExpertModeChangeListener {
92    /** The display list. */
93    private final JList<Relation> displaylist;
94    /** the list model used */
95    private final RelationListModel model;
96
97    private final NewAction newAction;
98
99    /** the popup menu and its handler */
100    private final JPopupMenu popupMenu = new JPopupMenu();
101    private final transient PopupMenuHandler popupMenuHandler = new PopupMenuHandler(popupMenu);
102
103    private final JosmTextField filter;
104
105    // Actions
106    /** the edit action */
107    private final EditRelationAction editAction = new EditRelationAction();
108    /** the delete action */
109    private final DeleteRelationsAction deleteRelationsAction = new DeleteRelationsAction();
110    /** the duplicate action */
111    private final DuplicateRelationAction duplicateAction = new DuplicateRelationAction();
112    private final DownloadMembersAction downloadMembersAction = new DownloadMembersAction();
113    private final DownloadSelectedIncompleteMembersAction downloadSelectedIncompleteMembersAction =
114            new DownloadSelectedIncompleteMembersAction();
115    private final SelectMembersAction selectMembersAction = new SelectMembersAction(false);
116    private final SelectMembersAction addMembersToSelectionAction = new SelectMembersAction(true);
117    private final SelectRelationAction selectRelationAction = new SelectRelationAction(false);
118    private final SelectRelationAction addRelationToSelectionAction = new SelectRelationAction(true);
119    /** add all selected primitives to the given relations */
120    private final AddSelectionToRelations addSelectionToRelations = new AddSelectionToRelations();
121    private transient JMenuItem addSelectionToRelationMenuItem;
122
123    private final transient HighlightHelper highlightHelper = new HighlightHelper();
124    private final boolean highlightEnabled = Main.pref.getBoolean("draw.target-highlight", true);
125    private final transient RecentRelationsAction recentRelationsAction;
126
127    /**
128     * Constructs <code>RelationListDialog</code>
129     */
130    public RelationListDialog() {
131        super(tr("Relations"), "relationlist", tr("Open a list of all relations."),
132                Shortcut.registerShortcut("subwindow:relations", tr("Toggle: {0}", tr("Relations")),
133                KeyEvent.VK_R, Shortcut.ALT_SHIFT), 150, true);
134
135        // create the list of relations
136        //
137        DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
138        model = new RelationListModel(selectionModel);
139        displaylist = new JList<>(model);
140        displaylist.setSelectionModel(selectionModel);
141        displaylist.setCellRenderer(new NoTooltipOsmRenderer());
142        displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
143        displaylist.addMouseListener(new MouseEventHandler());
144
145        // the new action
146        //
147        newAction = new NewAction();
148
149        filter = setupFilter();
150
151        displaylist.addListSelectionListener(e -> {
152            if (!e.getValueIsAdjusting()) updateActionsRelationLists();
153        });
154
155        // Setup popup menu handler
156        setupPopupMenuHandler();
157
158        JPanel pane = new JPanel(new BorderLayout());
159        pane.add(filter, BorderLayout.NORTH);
160        pane.add(new JScrollPane(displaylist), BorderLayout.CENTER);
161
162        SideButton editButton = new SideButton(editAction, false);
163        recentRelationsAction = new RecentRelationsAction(editButton);
164
165        createLayout(pane, false, Arrays.asList(
166                new SideButton(newAction, false),
167                editButton,
168                new SideButton(duplicateAction, false),
169                new SideButton(deleteRelationsAction, false),
170                new SideButton(selectRelationAction, false)
171        ));
172
173        InputMapUtils.unassignCtrlShiftUpDown(displaylist, JComponent.WHEN_FOCUSED);
174
175        // Select relation on Enter
176        InputMapUtils.addEnterAction(displaylist, selectRelationAction);
177
178        // Edit relation on Ctrl-Enter
179        displaylist.getActionMap().put("edit", editAction);
180        displaylist.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_DOWN_MASK), "edit");
181
182        // Do not hide copy action because of default JList override (fix #9815)
183        displaylist.getActionMap().put("copy", Main.main.menu.copy);
184        displaylist.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, GuiHelper.getMenuShortcutKeyMaskEx()), "copy");
185
186        updateActionsRelationLists();
187    }
188
189    @Override
190    public void destroy() {
191        recentRelationsAction.destroy();
192        model.clear();
193        super.destroy();
194    }
195
196    /**
197     * Enable the "recent relations" dropdown menu next to edit button.
198     */
199    public void enableRecentRelations() {
200        recentRelationsAction.enableArrow();
201    }
202
203    // inform all actions about list of relations they need
204    private void updateActionsRelationLists() {
205        List<Relation> sel = model.getSelectedRelations();
206        popupMenuHandler.setPrimitives(sel);
207
208        Component focused = FocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
209
210        //update highlights
211        if (highlightEnabled && focused == displaylist && Main.isDisplayingMapView() && highlightHelper.highlightOnly(sel)) {
212            Main.map.mapView.repaint();
213        }
214    }
215
216    @Override
217    public void showNotify() {
218        Main.getLayerManager().addLayerChangeListener(newAction);
219        Main.getLayerManager().addActiveLayerChangeListener(newAction);
220        MapView.addZoomChangeListener(this);
221        newAction.updateEnabledState();
222        DatasetEventManager.getInstance().addDatasetListener(this, FireMode.IN_EDT);
223        DataSet.addSelectionListener(addSelectionToRelations);
224        dataChanged(null);
225        ExpertToggleAction.addExpertModeChangeListener(this);
226        expertChanged(ExpertToggleAction.isExpert());
227    }
228
229    @Override
230    public void hideNotify() {
231        Main.getLayerManager().removeActiveLayerChangeListener(newAction);
232        Main.getLayerManager().removeLayerChangeListener(newAction);
233        MapView.removeZoomChangeListener(this);
234        DatasetEventManager.getInstance().removeDatasetListener(this);
235        DataSet.removeSelectionListener(addSelectionToRelations);
236        ExpertToggleAction.removeExpertModeChangeListener(this);
237    }
238
239    private void resetFilter() {
240        filter.setText(null);
241    }
242
243    /**
244     * Initializes the relation list dialog from a layer. If <code>layer</code> is null
245     * or if it isn't an {@link OsmDataLayer} the dialog is reset to an empty dialog.
246     * Otherwise it is initialized with the list of non-deleted and visible relations
247     * in the layer's dataset.
248     *
249     * @param layer the layer. May be null.
250     */
251    protected void initFromLayer(Layer layer) {
252        if (!(layer instanceof OsmDataLayer)) {
253            model.setRelations(null);
254            return;
255        }
256        OsmDataLayer l = (OsmDataLayer) layer;
257        model.setRelations(l.data.getRelations());
258        model.updateTitle();
259        updateActionsRelationLists();
260    }
261
262    /**
263     * @return The selected relation in the list
264     */
265    private Relation getSelected() {
266        if (model.getSize() == 1) {
267            displaylist.setSelectedIndex(0);
268        }
269        return displaylist.getSelectedValue();
270    }
271
272    /**
273     * Selects the relation <code>relation</code> in the list of relations.
274     *
275     * @param relation  the relation
276     */
277    public void selectRelation(Relation relation) {
278        selectRelations(Collections.singleton(relation));
279    }
280
281    /**
282     * Selects the relations in the list of relations.
283     * @param relations  the relations to be selected
284     */
285    public void selectRelations(Collection<Relation> relations) {
286        if (relations == null || relations.isEmpty()) {
287            model.setSelectedRelations(null);
288        } else {
289            model.setSelectedRelations(relations);
290            Integer i = model.getVisibleRelationIndex(relations.iterator().next());
291            if (i != null) {
292                // Not all relations have to be in the list
293                // (for example when the relation list is hidden, it's not updated with new relations)
294                displaylist.scrollRectToVisible(displaylist.getCellBounds(i, i));
295            }
296        }
297    }
298
299    private JosmTextField setupFilter() {
300        final JosmTextField f = new DisableShortcutsOnFocusGainedTextField();
301        f.setToolTipText(tr("Relation list filter"));
302        final CompileSearchTextDecorator decorator = CompileSearchTextDecorator.decorate(f);
303        f.addPropertyChangeListener("filter", evt -> model.setFilter(decorator.getMatch()));
304        return f;
305    }
306
307    static final class NoTooltipOsmRenderer extends OsmPrimitivRenderer {
308        @Override
309        protected String getComponentToolTipText(OsmPrimitive value) {
310            // Don't show the default tooltip in the relation list
311            return null;
312        }
313    }
314
315    class MouseEventHandler extends PopupMenuLauncher {
316
317        MouseEventHandler() {
318            super(popupMenu);
319        }
320
321        @Override
322        public void mouseExited(MouseEvent me) {
323            if (highlightEnabled) highlightHelper.clear();
324        }
325
326        protected void setCurrentRelationAsSelection() {
327            Main.getLayerManager().getEditDataSet().setSelected(displaylist.getSelectedValue());
328        }
329
330        protected void editCurrentRelation() {
331            EditRelationAction.launchEditor(getSelected());
332        }
333
334        @Override
335        public void mouseClicked(MouseEvent e) {
336            if (Main.getLayerManager().getEditLayer() == null) return;
337            if (isDoubleClick(e)) {
338                if (e.isControlDown()) {
339                    editCurrentRelation();
340                } else {
341                    setCurrentRelationAsSelection();
342                }
343            }
344        }
345    }
346
347    /**
348     * The action for creating a new relation.
349     */
350    static class NewAction extends AbstractAction implements LayerChangeListener, ActiveLayerChangeListener {
351        NewAction() {
352            putValue(SHORT_DESCRIPTION, tr("Create a new relation"));
353            putValue(NAME, tr("New"));
354            new ImageProvider("dialogs", "addrelation").getResource().attachImageIcon(this, true);
355            updateEnabledState();
356        }
357
358        public void run() {
359            RelationEditor.getEditor(Main.getLayerManager().getEditLayer(), null, null).setVisible(true);
360        }
361
362        @Override
363        public void actionPerformed(ActionEvent e) {
364            run();
365        }
366
367        protected void updateEnabledState() {
368            setEnabled(Main.getLayerManager().getEditLayer() != null);
369        }
370
371        @Override
372        public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
373            updateEnabledState();
374        }
375
376        @Override
377        public void layerAdded(LayerAddEvent e) {
378            updateEnabledState();
379        }
380
381        @Override
382        public void layerRemoving(LayerRemoveEvent e) {
383            updateEnabledState();
384        }
385
386        @Override
387        public void layerOrderChanged(LayerOrderChangeEvent e) {
388            // Do nothing
389        }
390    }
391
392    /**
393     * The list model for the list of relations displayed in the relation list dialog.
394     */
395    private class RelationListModel extends AbstractListModel<Relation> {
396        private final transient List<Relation> relations = new ArrayList<>();
397        private transient List<Relation> filteredRelations;
398        private final DefaultListSelectionModel selectionModel;
399        private transient SearchCompiler.Match filter;
400
401        RelationListModel(DefaultListSelectionModel selectionModel) {
402            this.selectionModel = selectionModel;
403        }
404
405        /**
406         * Clears the model.
407         */
408        public void clear() {
409            relations.clear();
410            if (filteredRelations != null)
411                filteredRelations.clear();
412            filter = null;
413        }
414
415        /**
416         * Sorts the model using {@link DefaultNameFormatter} relation comparator.
417         */
418        public void sort() {
419            relations.sort(DefaultNameFormatter.getInstance().getRelationComparator());
420        }
421
422        private boolean isValid(Relation r) {
423            return !r.isDeleted() && !r.isIncomplete();
424        }
425
426        public void setRelations(Collection<Relation> relations) {
427            List<Relation> sel = getSelectedRelations();
428            this.relations.clear();
429            this.filteredRelations = null;
430            if (relations == null) {
431                selectionModel.clearSelection();
432                fireContentsChanged(this, 0, getSize());
433                return;
434            }
435            for (Relation r: relations) {
436                if (isValid(r)) {
437                    this.relations.add(r);
438                }
439            }
440            sort();
441            updateFilteredRelations();
442            fireIntervalAdded(this, 0, getSize());
443            setSelectedRelations(sel);
444        }
445
446        /**
447         * Add all relations in <code>addedPrimitives</code> to the model for the
448         * relation list dialog
449         *
450         * @param addedPrimitives the collection of added primitives. May include nodes,
451         * ways, and relations.
452         */
453        public void addRelations(Collection<? extends OsmPrimitive> addedPrimitives) {
454            boolean added = false;
455            for (OsmPrimitive p: addedPrimitives) {
456                if (!(p instanceof Relation)) {
457                    continue;
458                }
459
460                Relation r = (Relation) p;
461                if (relations.contains(r)) {
462                    continue;
463                }
464                if (isValid(r)) {
465                    relations.add(r);
466                    added = true;
467                }
468            }
469            if (added) {
470                List<Relation> sel = getSelectedRelations();
471                sort();
472                updateFilteredRelations();
473                fireIntervalAdded(this, 0, getSize());
474                setSelectedRelations(sel);
475            }
476        }
477
478        /**
479         * Removes all relations in <code>removedPrimitives</code> from the model
480         *
481         * @param removedPrimitives the removed primitives. May include nodes, ways,
482         *   and relations
483         */
484        public void removeRelations(Collection<? extends OsmPrimitive> removedPrimitives) {
485            if (removedPrimitives == null) return;
486            // extract the removed relations
487            //
488            Set<Relation> removedRelations = new HashSet<>();
489            for (OsmPrimitive p: removedPrimitives) {
490                if (!(p instanceof Relation)) {
491                    continue;
492                }
493                removedRelations.add((Relation) p);
494            }
495            if (removedRelations.isEmpty())
496                return;
497            int size = relations.size();
498            relations.removeAll(removedRelations);
499            if (filteredRelations != null) {
500                filteredRelations.removeAll(removedRelations);
501            }
502            if (size != relations.size()) {
503                List<Relation> sel = getSelectedRelations();
504                sort();
505                fireContentsChanged(this, 0, getSize());
506                setSelectedRelations(sel);
507            }
508        }
509
510        private void updateFilteredRelations() {
511            if (filter != null) {
512                filteredRelations = new ArrayList<>(SubclassFilteredCollection.filter(relations, filter::match));
513            } else if (filteredRelations != null) {
514                filteredRelations = null;
515            }
516        }
517
518        public void setFilter(final SearchCompiler.Match filter) {
519            this.filter = filter;
520            updateFilteredRelations();
521            List<Relation> sel = getSelectedRelations();
522            fireContentsChanged(this, 0, getSize());
523            setSelectedRelations(sel);
524            updateTitle();
525        }
526
527        private List<Relation> getVisibleRelations() {
528            return filteredRelations == null ? relations : filteredRelations;
529        }
530
531        private Relation getVisibleRelation(int index) {
532            if (index < 0 || index >= getVisibleRelations().size()) return null;
533            return getVisibleRelations().get(index);
534        }
535
536        @Override
537        public Relation getElementAt(int index) {
538            return getVisibleRelation(index);
539        }
540
541        @Override
542        public int getSize() {
543            return getVisibleRelations().size();
544        }
545
546        /**
547         * Replies the list of selected relations. Empty list,
548         * if there are no selected relations.
549         *
550         * @return the list of selected, non-new relations.
551         */
552        public List<Relation> getSelectedRelations() {
553            List<Relation> ret = new ArrayList<>();
554            for (int i = 0; i < getSize(); i++) {
555                if (!selectionModel.isSelectedIndex(i)) {
556                    continue;
557                }
558                ret.add(getVisibleRelation(i));
559            }
560            return ret;
561        }
562
563        /**
564         * Sets the selected relations.
565         *
566         * @param sel the list of selected relations
567         */
568        public void setSelectedRelations(Collection<Relation> sel) {
569            selectionModel.setValueIsAdjusting(true);
570            selectionModel.clearSelection();
571            if (sel != null && !sel.isEmpty()) {
572                if (!getVisibleRelations().containsAll(sel)) {
573                    resetFilter();
574                }
575                for (Relation r: sel) {
576                    Integer i = getVisibleRelationIndex(r);
577                    if (i != null) {
578                        selectionModel.addSelectionInterval(i, i);
579                    }
580                }
581            }
582            selectionModel.setValueIsAdjusting(false);
583        }
584
585        private Integer getVisibleRelationIndex(Relation rel) {
586            int i = getVisibleRelations().indexOf(rel);
587            if (i < 0)
588                return null;
589            return i;
590        }
591
592        public void updateTitle() {
593            if (!relations.isEmpty() && relations.size() != getSize()) {
594                RelationListDialog.this.setTitle(tr("Relations: {0}/{1}", getSize(), relations.size()));
595            } else if (getSize() > 0) {
596                RelationListDialog.this.setTitle(tr("Relations: {0}", getSize()));
597            } else {
598                RelationListDialog.this.setTitle(tr("Relations"));
599            }
600        }
601    }
602
603    private void setupPopupMenuHandler() {
604
605        // -- select action
606        popupMenuHandler.addAction(selectRelationAction);
607        popupMenuHandler.addAction(addRelationToSelectionAction);
608
609        // -- select members action
610        popupMenuHandler.addAction(selectMembersAction);
611        popupMenuHandler.addAction(addMembersToSelectionAction);
612
613        popupMenuHandler.addSeparator();
614        // -- download members action
615        popupMenuHandler.addAction(downloadMembersAction);
616
617        // -- download incomplete members action
618        popupMenuHandler.addAction(downloadSelectedIncompleteMembersAction);
619
620        popupMenuHandler.addSeparator();
621        popupMenuHandler.addAction(editAction).setVisible(false);
622        popupMenuHandler.addAction(duplicateAction).setVisible(false);
623        popupMenuHandler.addAction(deleteRelationsAction).setVisible(false);
624
625        addSelectionToRelationMenuItem = popupMenuHandler.addAction(addSelectionToRelations);
626    }
627
628    /* ---------------------------------------------------------------------------------- */
629    /* Methods that can be called from plugins                                            */
630    /* ---------------------------------------------------------------------------------- */
631
632    /**
633     * Replies the popup menu handler.
634     * @return The popup menu handler
635     */
636    public PopupMenuHandler getPopupMenuHandler() {
637        return popupMenuHandler;
638    }
639
640    /**
641     * Replies the list of selected relations. Empty list, if there are no selected relations.
642     * @return the list of selected, non-new relations.
643     */
644    public Collection<Relation> getSelectedRelations() {
645        return model.getSelectedRelations();
646    }
647
648    /* ---------------------------------------------------------------------------------- */
649    /* DataSetListener                                                                    */
650    /* ---------------------------------------------------------------------------------- */
651
652    @Override
653    public void nodeMoved(NodeMovedEvent event) {
654        /* irrelevant in this context */
655    }
656
657    @Override
658    public void wayNodesChanged(WayNodesChangedEvent event) {
659        /* irrelevant in this context */
660    }
661
662    @Override
663    public void primitivesAdded(final PrimitivesAddedEvent event) {
664        model.addRelations(event.getPrimitives());
665        model.updateTitle();
666    }
667
668    @Override
669    public void primitivesRemoved(final PrimitivesRemovedEvent event) {
670        model.removeRelations(event.getPrimitives());
671        model.updateTitle();
672    }
673
674    @Override
675    public void relationMembersChanged(final RelationMembersChangedEvent event) {
676        List<Relation> sel = model.getSelectedRelations();
677        model.sort();
678        model.setSelectedRelations(sel);
679        displaylist.repaint();
680    }
681
682    @Override
683    public void tagsChanged(TagsChangedEvent event) {
684        OsmPrimitive prim = event.getPrimitive();
685        if (!(prim instanceof Relation))
686            return;
687        // trigger a sort of the relation list because the display name may have changed
688        //
689        List<Relation> sel = model.getSelectedRelations();
690        model.sort();
691        model.setSelectedRelations(sel);
692        displaylist.repaint();
693    }
694
695    @Override
696    public void dataChanged(DataChangedEvent event) {
697        initFromLayer(Main.getLayerManager().getEditLayer());
698    }
699
700    @Override
701    public void otherDatasetChange(AbstractDatasetChangedEvent event) {
702        /* ignore */
703    }
704
705    @Override
706    public void zoomChanged() {
707        // re-filter relations
708        if (model.filter != null) {
709            model.setFilter(model.filter);
710        }
711    }
712
713    @Override
714    public void expertChanged(boolean isExpert) {
715        addSelectionToRelationMenuItem.setVisible(isExpert);
716    }
717}
Note: See TracBrowser for help on using the repository browser.