source: josm/trunk/src/org/openstreetmap/josm/gui/io/UploadSelectionDialog.java@ 10791

Last change on this file since 10791 was 10791, checked in by simon04, 8 years ago

see #13319 - Use InputMapUtils where applicable (VK_ESCAPE)

  • Property svn:eol-style set to native
File size: 10.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Dimension;
8import java.awt.FlowLayout;
9import java.awt.event.ActionEvent;
10import java.awt.event.WindowAdapter;
11import java.awt.event.WindowEvent;
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.Collections;
15import java.util.Comparator;
16import java.util.List;
17
18import javax.swing.AbstractAction;
19import javax.swing.AbstractListModel;
20import javax.swing.Action;
21import javax.swing.BorderFactory;
22import javax.swing.JDialog;
23import javax.swing.JLabel;
24import javax.swing.JList;
25import javax.swing.JPanel;
26import javax.swing.JScrollPane;
27import javax.swing.JSplitPane;
28import javax.swing.ListSelectionModel;
29import javax.swing.event.ListSelectionEvent;
30import javax.swing.event.ListSelectionListener;
31
32import org.openstreetmap.josm.Main;
33import org.openstreetmap.josm.data.osm.OsmPrimitive;
34import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
35import org.openstreetmap.josm.gui.DefaultNameFormatter;
36import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
37import org.openstreetmap.josm.gui.SideButton;
38import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
39import org.openstreetmap.josm.gui.help.HelpUtil;
40import org.openstreetmap.josm.gui.util.GuiHelper;
41import org.openstreetmap.josm.tools.ImageProvider;
42import org.openstreetmap.josm.tools.InputMapUtils;
43import org.openstreetmap.josm.tools.WindowGeometry;
44
45/**
46 * This dialog can be used to select individual object for uploading.
47 *
48 * @since 2250
49 */
50public class UploadSelectionDialog extends JDialog {
51
52 private final OsmPrimitiveList lstSelectedPrimitives = new OsmPrimitiveList();
53 private final OsmPrimitiveList lstDeletedPrimitives = new OsmPrimitiveList();
54 private JSplitPane spLists;
55 private boolean canceled;
56 private SideButton btnContinue;
57
58 /**
59 * Constructs a new {@code UploadSelectionDialog}.
60 */
61 public UploadSelectionDialog() {
62 super(GuiHelper.getFrameForComponent(Main.parent), ModalityType.DOCUMENT_MODAL);
63 build();
64 }
65
66 protected JPanel buildSelectedPrimitivesPanel() {
67 JPanel pnl = new JPanel(new BorderLayout());
68 JLabel lbl = new JLabel(
69 tr("<html>Mark modified objects <strong>from the current selection</strong> to be uploaded to the server.</html>"));
70 lbl.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
71 pnl.add(lbl, BorderLayout.NORTH);
72 pnl.add(new JScrollPane(lstSelectedPrimitives), BorderLayout.CENTER);
73 lbl.setLabelFor(lstSelectedPrimitives);
74 return pnl;
75 }
76
77 protected JPanel buildDeletedPrimitivesPanel() {
78 JPanel pnl = new JPanel(new BorderLayout());
79 JLabel lbl = new JLabel(tr("<html>Mark <strong>locally deleted objects</strong> to be deleted on the server.</html>"));
80 lbl.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
81 pnl.add(lbl, BorderLayout.NORTH);
82 pnl.add(new JScrollPane(lstDeletedPrimitives), BorderLayout.CENTER);
83 lbl.setLabelFor(lstDeletedPrimitives);
84 return pnl;
85 }
86
87 protected JPanel buildButtonPanel() {
88 JPanel pnl = new JPanel(new FlowLayout());
89 ContinueAction continueAction = new ContinueAction();
90 btnContinue = new SideButton(continueAction);
91 pnl.add(btnContinue);
92 btnContinue.setFocusable(true);
93 lstDeletedPrimitives.getSelectionModel().addListSelectionListener(continueAction);
94 lstSelectedPrimitives.getSelectionModel().addListSelectionListener(continueAction);
95
96 pnl.add(new SideButton(new CancelAction()));
97 pnl.add(new SideButton(new ContextSensitiveHelpAction(HelpUtil.ht("/Dialog/UploadSelection"))));
98 return pnl;
99 }
100
101 protected void build() {
102 setLayout(new BorderLayout());
103 spLists = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
104 spLists.setTopComponent(buildSelectedPrimitivesPanel());
105 spLists.setBottomComponent(buildDeletedPrimitivesPanel());
106 add(spLists, BorderLayout.CENTER);
107 add(buildButtonPanel(), BorderLayout.SOUTH);
108 addWindowListener(
109 new WindowAdapter() {
110 @Override
111 public void windowOpened(WindowEvent e) {
112 spLists.setDividerLocation(0.5);
113 btnContinue.requestFocusInWindow();
114 }
115
116 @Override
117 public void windowClosing(WindowEvent e) {
118 setCanceled(true);
119 }
120 }
121 );
122 setTitle(tr("Select objects to upload"));
123 HelpUtil.setHelpContext(getRootPane(), HelpUtil.ht("/Dialog/UploadSelection"));
124 }
125
126 public void populate(Collection<OsmPrimitive> selected, Collection<OsmPrimitive> deleted) {
127 if (selected != null) {
128 lstSelectedPrimitives.getOsmPrimitiveListModel().setPrimitives(new ArrayList<>(selected));
129 if (!selected.isEmpty()) {
130 lstSelectedPrimitives.getSelectionModel().setSelectionInterval(0, selected.size()-1);
131 } else {
132 lstSelectedPrimitives.getSelectionModel().clearSelection();
133 }
134 } else {
135 lstSelectedPrimitives.getOsmPrimitiveListModel().setPrimitives(null);
136 lstSelectedPrimitives.getSelectionModel().clearSelection();
137 }
138
139 if (deleted != null) {
140 lstDeletedPrimitives.getOsmPrimitiveListModel().setPrimitives(new ArrayList<>(deleted));
141 } else {
142 lstDeletedPrimitives.getOsmPrimitiveListModel().setPrimitives(null);
143 }
144 }
145
146 public boolean isCanceled() {
147 return canceled;
148 }
149
150 protected void setCanceled(boolean canceled) {
151 this.canceled = canceled;
152 }
153
154 public List<OsmPrimitive> getSelectedPrimitives() {
155 List<OsmPrimitive> ret = new ArrayList<>();
156 ret.addAll(lstSelectedPrimitives.getOsmPrimitiveListModel().getPrimitives(lstSelectedPrimitives.getSelectedIndices()));
157 ret.addAll(lstDeletedPrimitives.getOsmPrimitiveListModel().getPrimitives(lstDeletedPrimitives.getSelectedIndices()));
158 return ret;
159 }
160
161 @Override
162 public void setVisible(boolean visible) {
163 if (visible) {
164 new WindowGeometry(
165 getClass().getName() + ".geometry",
166 WindowGeometry.centerInWindow(
167 Main.parent,
168 new Dimension(200, 400)
169 )
170 ).applySafe(this);
171 } else if (isShowing()) { // Avoid IllegalComponentStateException like in #8775
172 new WindowGeometry(this).remember(getClass().getName() + ".geometry");
173 }
174 super.setVisible(visible);
175 }
176
177 static class OsmPrimitiveList extends JList<OsmPrimitive> {
178 OsmPrimitiveList() {
179 this(new OsmPrimitiveListModel());
180 }
181
182 OsmPrimitiveList(OsmPrimitiveListModel model) {
183 super(model);
184 init();
185 }
186
187 protected void init() {
188 setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
189 setCellRenderer(new OsmPrimitivRenderer());
190 }
191
192 public OsmPrimitiveListModel getOsmPrimitiveListModel() {
193 return (OsmPrimitiveListModel) getModel();
194 }
195 }
196
197 static class OsmPrimitiveListModel extends AbstractListModel<OsmPrimitive> {
198 private transient List<OsmPrimitive> data;
199
200 protected void sort() {
201 if (data == null)
202 return;
203 data.sort(new Comparator<OsmPrimitive>() {
204 private DefaultNameFormatter formatter = DefaultNameFormatter.getInstance();
205 @Override
206 public int compare(OsmPrimitive o1, OsmPrimitive o2) {
207 int ret = OsmPrimitiveType.from(o1).compareTo(OsmPrimitiveType.from(o2));
208 if (ret != 0)
209 return ret;
210 return o1.getDisplayName(formatter).compareTo(o1.getDisplayName(formatter));
211 }
212 }
213 );
214 }
215
216 public void setPrimitives(List<OsmPrimitive> data) {
217 this.data = data;
218 sort();
219 if (data != null) {
220 fireContentsChanged(this, 0, data.size());
221 } else {
222 fireContentsChanged(this, 0, 0);
223 }
224 }
225
226 @Override
227 public OsmPrimitive getElementAt(int index) {
228 if (data == null)
229 return null;
230 return data.get(index);
231 }
232
233 @Override
234 public int getSize() {
235 if (data == null)
236 return 0;
237 return data.size();
238 }
239
240 public List<OsmPrimitive> getPrimitives(int ... indices) {
241 if (indices == null || indices.length == 0)
242 return Collections.emptyList();
243 List<OsmPrimitive> ret = new ArrayList<>(indices.length);
244 for (int i: indices) {
245 if (i < 0) {
246 continue;
247 }
248 ret.add(data.get(i));
249 }
250 return ret;
251 }
252 }
253
254 class CancelAction extends AbstractAction {
255 CancelAction() {
256 putValue(Action.SHORT_DESCRIPTION, tr("Cancel uploading"));
257 putValue(Action.NAME, tr("Cancel"));
258 new ImageProvider("cancel").getResource().attachImageIcon(this);
259 InputMapUtils.addEscapeAction(getRootPane(), this);
260 setEnabled(true);
261 }
262
263 @Override
264 public void actionPerformed(ActionEvent e) {
265 setCanceled(true);
266 setVisible(false);
267 }
268 }
269
270 class ContinueAction extends AbstractAction implements ListSelectionListener {
271 ContinueAction() {
272 putValue(Action.SHORT_DESCRIPTION, tr("Continue uploading"));
273 putValue(Action.NAME, tr("Continue"));
274 new ImageProvider("upload").getResource().attachImageIcon(this);
275 updateEnabledState();
276 }
277
278 @Override
279 public void actionPerformed(ActionEvent e) {
280 setCanceled(false);
281 setVisible(false);
282 }
283
284 protected void updateEnabledState() {
285 setEnabled(lstSelectedPrimitives.getSelectedIndex() >= 0
286 || lstDeletedPrimitives.getSelectedIndex() >= 0);
287 }
288
289 @Override
290 public void valueChanged(ListSelectionEvent e) {
291 updateEnabledState();
292 }
293 }
294}
Note: See TracBrowser for help on using the repository browser.