001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui.dialogs.relation;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    
006    import java.awt.BorderLayout;
007    import java.awt.FlowLayout;
008    import java.awt.event.ActionEvent;
009    import java.awt.event.MouseAdapter;
010    import java.awt.event.MouseEvent;
011    
012    import javax.swing.AbstractAction;
013    import javax.swing.JCheckBox;
014    import javax.swing.JList;
015    import javax.swing.JPanel;
016    import javax.swing.JScrollPane;
017    import javax.swing.ListSelectionModel;
018    import javax.swing.event.ListDataEvent;
019    import javax.swing.event.ListDataListener;
020    import javax.swing.event.ListSelectionEvent;
021    import javax.swing.event.ListSelectionListener;
022    
023    import org.openstreetmap.josm.Main;
024    import org.openstreetmap.josm.data.osm.Relation;
025    import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
026    import org.openstreetmap.josm.gui.SideButton;
027    import org.openstreetmap.josm.gui.layer.OsmDataLayer;
028    import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
029    import org.openstreetmap.josm.tools.ImageProvider;
030    
031    /**
032     * This is browser for a list of relations which refer to another relations
033     *
034     *
035     */
036    public class ReferringRelationsBrowser extends JPanel {
037    
038        /** the list of relations */
039        private JList referrers;
040        private ReferringRelationsBrowserModel model;
041        private OsmDataLayer layer;
042        private JCheckBox cbReadFull;
043        private EditAction editAction;
044    
045        /**
046         * build the GUI
047         */
048        protected void build() {
049            setLayout(new BorderLayout());
050            referrers = new JList(model);
051            referrers.setCellRenderer(new OsmPrimitivRenderer());
052            add(new JScrollPane(referrers), BorderLayout.CENTER);
053            referrers.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
054            referrers.addMouseListener(new DblClickMouseAdapter());
055    
056            JPanel pnl = new JPanel();
057            pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
058    
059            ReloadAction reloadAction = new ReloadAction();
060            referrers.getModel().addListDataListener(reloadAction);
061            pnl.add(new SideButton(reloadAction));
062            pnl.add(cbReadFull = new JCheckBox(tr("including immediate children of parent relations")));
063    
064            editAction = new EditAction();
065            referrers.getSelectionModel().addListSelectionListener(editAction);
066            pnl.add(new SideButton(editAction));
067            add(pnl, BorderLayout.SOUTH);
068        }
069    
070        public ReferringRelationsBrowser(OsmDataLayer layer, ReferringRelationsBrowserModel model, GenericRelationEditor relationEditor) {
071            this.model = model;
072            this.layer = layer;
073            build();
074        }
075    
076        public void init() {
077            model.populate(getLayer().data);
078        }
079    
080        protected OsmDataLayer getLayer() {
081            return layer;
082        }
083    
084        /**
085         * Action for loading the parent relations of a relation
086         *
087         */
088        class ReloadAction extends AbstractAction implements ListDataListener {
089            public ReloadAction() {
090                putValue(SHORT_DESCRIPTION, tr("Load parent relations"));
091                putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh"));
092                putValue(NAME, tr("Reload"));
093                refreshEnabled();
094            }
095    
096            protected void refreshEnabled() {
097                setEnabled(model.canReload());
098            }
099    
100            public void actionPerformed(ActionEvent e) {
101                boolean full = cbReadFull.isSelected();
102                final ParentRelationLoadingTask task = new ParentRelationLoadingTask(
103                        model.getRelation(),
104                        getLayer(),
105                        full,
106                        new PleaseWaitProgressMonitor(tr("Loading parent relations"))
107                );
108                task.setContinuation(
109                        new Runnable() {
110                            public void run() {
111                                if (task.isCanceled() || task.hasError())
112                                    return;
113                                model.populate(task.getParents());
114                            }
115                        }
116                );
117                Main.worker.submit(task);
118            }
119    
120            public void contentsChanged(ListDataEvent e) {
121                refreshEnabled();
122            }
123    
124            public void intervalAdded(ListDataEvent e) {
125                refreshEnabled();
126            }
127    
128            public void intervalRemoved(ListDataEvent e) {
129                refreshEnabled();
130            }
131        }
132    
133        /**
134         * Action for editing the currently selected relation
135         *
136         */
137        class EditAction extends AbstractAction implements ListSelectionListener {
138            public EditAction() {
139                putValue(SHORT_DESCRIPTION, tr("Edit the currently selected relation"));
140                putValue(SMALL_ICON, ImageProvider.get("dialogs", "edit"));
141                putValue(NAME, tr("Edit"));
142                refreshEnabled();
143            }
144    
145            protected void refreshEnabled() {
146                setEnabled(referrers.getSelectionModel().getMinSelectionIndex() >=0);
147            }
148    
149            public void actionPerformed(ActionEvent e) {
150                run();
151            }
152    
153            public void run() {
154                int idx = referrers.getSelectedIndex();
155                if (idx < 0) return;
156                Relation r = model.get(idx);
157                if (r == null) return;
158                RelationEditor editor = RelationEditor.getEditor(getLayer(), r, null);
159                editor.setVisible(true);
160            }
161    
162            public void valueChanged(ListSelectionEvent e) {
163                refreshEnabled();
164            }
165        }
166    
167        class DblClickMouseAdapter extends MouseAdapter {
168            @Override
169            public void mouseClicked(MouseEvent e) {
170                if (e.getClickCount() == 2)  {
171                    editAction.run();
172                }
173            }
174        }
175    }