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

Last change on this file since 10861 was 10861, checked in by Don-vip, 3 years ago

fix #13394 - fix some memory leaks (patch by Gerd Petermann)

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