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