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

Last change on this file since 16438 was 16438, checked in by simon04, 4 years ago

see #19251 - Java 8: use Stream

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