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 final ReferringRelationsBrowserModel model; 040 private final 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(new FlowLayout(FlowLayout.LEFT)); 056 057 ReloadAction reloadAction = new ReloadAction(); 058 referrers.getModel().addListDataListener(reloadAction); 059 pnl.add(new SideButton(reloadAction)); 060 pnl.add(cbReadFull = new JCheckBox(tr("including immediate children of parent relations"))); 061 062 editAction = new EditAction(); 063 referrers.getSelectionModel().addListSelectionListener(editAction); 064 pnl.add(new SideButton(editAction)); 065 add(pnl, BorderLayout.SOUTH); 066 } 067 068 public ReferringRelationsBrowser(OsmDataLayer layer, ReferringRelationsBrowserModel model) { 069 this.model = model; 070 this.layer = layer; 071 build(); 072 } 073 074 public void init() { 075 model.populate(getLayer().data); 076 } 077 078 protected OsmDataLayer getLayer() { 079 return layer; 080 } 081 082 /** 083 * Action for loading the parent relations of a relation 084 * 085 */ 086 class ReloadAction extends AbstractAction implements ListDataListener { 087 ReloadAction() { 088 putValue(SHORT_DESCRIPTION, tr("Load parent relations")); 089 putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh")); 090 putValue(NAME, tr("Reload")); 091 refreshEnabled(); 092 } 093 094 protected void refreshEnabled() { 095 setEnabled(model.canReload()); 096 } 097 098 @Override 099 public void actionPerformed(ActionEvent e) { 100 boolean full = cbReadFull.isSelected(); 101 final ParentRelationLoadingTask task = new ParentRelationLoadingTask( 102 model.getRelation(), 103 getLayer(), 104 full, 105 new PleaseWaitProgressMonitor(tr("Loading parent relations")) 106 ); 107 task.setContinuation( 108 new Runnable() { 109 @Override 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 @Override 121 public void contentsChanged(ListDataEvent e) { 122 refreshEnabled(); 123 } 124 125 @Override 126 public void intervalAdded(ListDataEvent e) { 127 refreshEnabled(); 128 } 129 130 @Override 131 public void intervalRemoved(ListDataEvent e) { 132 refreshEnabled(); 133 } 134 } 135 136 /** 137 * Action for editing the currently selected relation 138 * 139 */ 140 class EditAction extends AbstractAction implements ListSelectionListener { 141 EditAction() { 142 putValue(SHORT_DESCRIPTION, tr("Edit the currently selected relation")); 143 putValue(SMALL_ICON, ImageProvider.get("dialogs", "edit")); 144 putValue(NAME, tr("Edit")); 145 refreshEnabled(); 146 } 147 148 protected void refreshEnabled() { 149 setEnabled(referrers.getSelectionModel().getMinSelectionIndex() >= 0); 150 } 151 152 @Override 153 public void actionPerformed(ActionEvent e) { 154 run(); 155 } 156 157 public void run() { 158 int idx = referrers.getSelectedIndex(); 159 if (idx < 0) return; 160 Relation r = model.getElementAt(idx); 161 if (r == null) return; 162 RelationEditor editor = RelationEditor.getEditor(getLayer(), r, null); 163 editor.setVisible(true); 164 } 165 166 @Override 167 public void valueChanged(ListSelectionEvent e) { 168 refreshEnabled(); 169 } 170 } 171 172 class DblClickMouseAdapter extends MouseAdapter { 173 @Override 174 public void mouseClicked(MouseEvent e) { 175 if (e.getClickCount() == 2) { 176 editAction.run(); 177 } 178 } 179 } 180}