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

Last change on this file since 5799 was 5799, checked in by akks, 6 years ago

Membership tabled in properties toggle dialog supports multiselect (and multiple membership deletion)
Property toggle dialog refactoring - methods splitting and reordering
see #7846: more RelationListDialog refactoring, all other relation-related actions separated from dialogs, @Override, JavaDocs

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