source: josm/trunk/src/org/openstreetmap/josm/gui/io/UploadDialog.java@ 2711

Last change on this file since 2711 was 2711, checked in by stoecker, 14 years ago

fix bad line endings

File size: 17.1 KB
Line 
1package org.openstreetmap.josm.gui.io;
2
3import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
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.KeyEvent;
11import java.awt.event.WindowAdapter;
12import java.awt.event.WindowEvent;
13import java.beans.PropertyChangeEvent;
14import java.beans.PropertyChangeListener;
15import java.util.Collections;
16import java.util.List;
17import java.util.logging.Logger;
18
19import javax.swing.AbstractAction;
20import javax.swing.BorderFactory;
21import javax.swing.InputMap;
22import javax.swing.JButton;
23import javax.swing.JComponent;
24import javax.swing.JDialog;
25import javax.swing.JOptionPane;
26import javax.swing.JPanel;
27import javax.swing.JTabbedPane;
28import javax.swing.KeyStroke;
29
30import org.openstreetmap.josm.Main;
31import org.openstreetmap.josm.data.APIDataSet;
32import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
33import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
34import org.openstreetmap.josm.data.osm.Changeset;
35import org.openstreetmap.josm.data.osm.OsmPrimitive;
36import org.openstreetmap.josm.gui.HelpAwareOptionPane;
37import org.openstreetmap.josm.gui.SideButton;
38import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
39import org.openstreetmap.josm.gui.help.HelpUtil;
40import org.openstreetmap.josm.io.OsmApi;
41import org.openstreetmap.josm.tools.ImageProvider;
42import org.openstreetmap.josm.tools.WindowGeometry;
43
44/**
45 * This is a dialog for entering upload options like the parameters for
46 * the upload changeset and the strategy for opening/closing a changeset.
47 *
48 */
49public class UploadDialog extends JDialog implements PropertyChangeListener, PreferenceChangedListener{
50 protected static final Logger logger = Logger.getLogger(UploadDialog.class.getName());
51
52 /** the unique instance of the upload dialog */
53 static private UploadDialog uploadDialog;
54
55 /**
56 * Replies the unique instance of the upload dialog
57 *
58 * @return the unique instance of the upload dialog
59 */
60 static public UploadDialog getUploadDialog() {
61 if (uploadDialog == null) {
62 uploadDialog = new UploadDialog();
63 }
64 return uploadDialog;
65 }
66
67 /** the panel with the objects to upload */
68 private UploadedObjectsSummaryPanel pnlUploadedObjects;
69 /** the panel to select the changeset used */
70 private ChangesetManagementPanel pnlChangesetManagement;
71
72 private BasicUploadSettingsPanel pnlBasicUploadSettings;
73
74 private UploadStrategySelectionPanel pnlUploadStrategySelectionPanel;
75
76 /** checkbox for selecting whether an atomic upload is to be used */
77 private TagSettingsPanel pnlTagSettings;
78 /** the tabbed pane used below of the list of primitives */
79 private JTabbedPane tpConfigPanels;
80 /** the upload button */
81 private JButton btnUpload;
82
83 private boolean canceled = false;
84
85 /**
86 * builds the content panel for the upload dialog
87 *
88 * @return the content panel
89 */
90 protected JPanel buildContentPanel() {
91 JPanel pnl = new JPanel();
92 pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
93 pnl.setLayout(new BorderLayout());
94
95 // the panel with the list of uploaded objects
96 //
97 pnl.add(pnlUploadedObjects = new UploadedObjectsSummaryPanel(), BorderLayout.CENTER);
98
99 // a tabbed pane with two configuration panels in the
100 // lower half
101 //
102 tpConfigPanels = new JTabbedPane() {
103 @Override
104 public Dimension getPreferredSize() {
105 // make sure the tabbed pane never grabs more space than necessary
106 //
107 return super.getMinimumSize();
108 }
109 };
110 tpConfigPanels.add(new JPanel());
111 tpConfigPanels.add(new JPanel());
112 tpConfigPanels.add(new JPanel());
113 tpConfigPanels.add(new JPanel());
114
115 tpConfigPanels.setComponentAt(0, pnlBasicUploadSettings = new BasicUploadSettingsPanel());
116 tpConfigPanels.setTitleAt(0, tr("Settings"));
117 tpConfigPanels.setToolTipTextAt(0, tr("Decide how to upload the data and which changeset to use"));
118
119 tpConfigPanels.setComponentAt(1,pnlTagSettings = new TagSettingsPanel());
120 tpConfigPanels.setTitleAt(1, tr("Tags of new changeset"));
121 tpConfigPanels.setToolTipTextAt(1, tr("Apply tags to the changeset data is uploaded to"));
122
123 tpConfigPanels.setComponentAt(2,pnlChangesetManagement = new ChangesetManagementPanel());
124 tpConfigPanels.setTitleAt(2, tr("Changesets"));
125 tpConfigPanels.setToolTipTextAt(2, tr("Manage open changesets and select a changeset to upload to"));
126
127 tpConfigPanels.setComponentAt(3, pnlUploadStrategySelectionPanel = new UploadStrategySelectionPanel());
128 tpConfigPanels.setTitleAt(3, tr("Advanced"));
129 tpConfigPanels.setToolTipTextAt(3, tr("Configure advanced settings"));
130
131 pnl.add(tpConfigPanels, BorderLayout.SOUTH);
132 return pnl;
133 }
134
135 /**
136 * builds the panel with the OK and CANCEL buttons
137 *
138 * @return
139 */
140 protected JPanel buildActionPanel() {
141 JPanel pnl = new JPanel();
142 pnl.setLayout(new FlowLayout(FlowLayout.CENTER));
143 pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
144
145 // -- upload button
146 UploadAction uploadAction = new UploadAction();
147 pnl.add(btnUpload = new SideButton(uploadAction));
148 btnUpload.setFocusable(true);
149 InputMap inputMap = btnUpload.getInputMap();
150 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), "doUpload");
151 btnUpload.getActionMap().put("doUpload", uploadAction);
152
153 // -- cancel button
154 CancelAction cancelAction = new CancelAction();
155 pnl.add(new SideButton(cancelAction));
156 getRootPane().registerKeyboardAction(
157 cancelAction,
158 KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0),
159 JComponent.WHEN_IN_FOCUSED_WINDOW
160 );
161 pnl.add(new SideButton(new ContextSensitiveHelpAction(ht("/Dialog/UploadDialog"))));
162 HelpUtil.setHelpContext(getRootPane(),ht("/Dialog/UploadDialog"));
163 return pnl;
164 }
165
166 /**
167 * builds the gui
168 */
169 protected void build() {
170 setTitle(tr("Upload to ''{0}''", OsmApi.getOsmApi().getBaseUrl()));
171 getContentPane().setLayout(new BorderLayout());
172 getContentPane().add(buildContentPanel(), BorderLayout.CENTER);
173 getContentPane().add(buildActionPanel(), BorderLayout.SOUTH);
174
175 addWindowListener(new WindowEventHandler());
176
177 // synchronized input of upload comments
178 //
179 //UploadCommentSynchronizer synchronizer = new UploadCommentSynchronizer();
180 //pnlTagSettings.getModeaddTableModelListener(synchronizer);
181 pnlTagSettings.addPropertyChangeListener(pnlBasicUploadSettings);
182 pnlBasicUploadSettings.addPropertyChangeListener(pnlTagSettings);
183
184 // make sure the the configuration panels listen to each other
185 // changes
186 //
187 pnlChangesetManagement.addPropertyChangeListener(
188 pnlBasicUploadSettings.getUploadParameterSummaryPanel()
189 );
190 pnlChangesetManagement.addPropertyChangeListener(pnlTagSettings);
191 pnlChangesetManagement.addPropertyChangeListener(this);
192 pnlUploadedObjects.addPropertyChangeListener(
193 pnlBasicUploadSettings.getUploadParameterSummaryPanel()
194 );
195 pnlUploadedObjects.addPropertyChangeListener(pnlUploadStrategySelectionPanel);
196 pnlUploadStrategySelectionPanel.addPropertyChangeListener(
197 pnlBasicUploadSettings.getUploadParameterSummaryPanel()
198 );
199
200 // users can click on either of two links in the upload parameter
201 // summary handler. This installs the handler for these two events.
202 // We simply select the appropriate tab in the tabbed pane with the
203 // configuration dialogs.
204 //
205 pnlBasicUploadSettings.getUploadParameterSummaryPanel().setConfigurationParameterRequestListener(
206 new ConfigurationParameterRequestHandler() {
207 public void handleUploadStrategyConfigurationRequest() {
208 tpConfigPanels.setSelectedIndex(3);
209 }
210 public void handleChangesetConfigurationRequest() {
211 tpConfigPanels.setSelectedIndex(2);
212 }
213 }
214 );
215
216 pnlBasicUploadSettings.setUploadCommentDownFocusTraversalHandler(
217 new AbstractAction() {
218 public void actionPerformed(ActionEvent e) {
219 btnUpload.requestFocusInWindow();
220 }
221 }
222 );
223
224 Main.pref.addPreferenceChangeListener(this);
225 }
226
227 /**
228 * constructor
229 */
230 public UploadDialog() {
231 super(JOptionPane.getFrameForComponent(Main.parent), true /* modal */);
232 build();
233 }
234
235 /**
236 * Sets the collection of primitives to upload
237 *
238 * @param toUpload the dataset with the objects to upload. If null, assumes the empty
239 * set of objects to upload
240 *
241 */
242 public void setUploadedPrimitives(APIDataSet toUpload) {
243 if (toUpload == null) {
244 List<OsmPrimitive> emptyList = Collections.emptyList();
245 pnlUploadedObjects.setUploadedPrimitives(emptyList, emptyList, emptyList);
246 return;
247 }
248 pnlUploadedObjects.setUploadedPrimitives(
249 toUpload.getPrimitivesToAdd(),
250 toUpload.getPrimitivesToUpdate(),
251 toUpload.getPrimitivesToDelete()
252 );
253 }
254
255 /**
256 * Remembers the user input in the preference settings
257 */
258 public void rememberUserInput() {
259 pnlBasicUploadSettings.rememberUserInput();
260 pnlUploadStrategySelectionPanel.rememberUserInput();
261 }
262
263 /**
264 * Initializes the panel for user input
265 */
266 public void startUserInput() {
267 tpConfigPanels.setSelectedIndex(0);
268 pnlBasicUploadSettings.startUserInput();
269 pnlTagSettings.startUserInput();
270 pnlTagSettings.setUploadComment(getUploadComment());
271 pnlTagSettings.initFromChangeset(pnlChangesetManagement.getSelectedChangeset());
272 pnlUploadStrategySelectionPanel.initFromPreferences();
273 UploadParameterSummaryPanel pnl = pnlBasicUploadSettings.getUploadParameterSummaryPanel();
274 pnl.setUploadStrategySpecification(pnlUploadStrategySelectionPanel.getUploadStrategySpecification());
275 pnl.setCloseChangesetAfterNextUpload(pnlChangesetManagement.isCloseChangesetAfterUpload());
276 pnl.setNumObjects(pnlUploadedObjects.getNumObjectsToUpload());
277 }
278
279 /**
280 * Replies the current changeset
281 *
282 * @return the current changeset
283 */
284 public Changeset getChangeset() {
285 Changeset cs = pnlChangesetManagement.getSelectedChangeset();
286 if (cs == null) {
287 cs = new Changeset();
288 }
289 cs.setKeys(pnlTagSettings.getTags());
290 return cs;
291 }
292
293 public void setSelectedChangesetForNextUpload(Changeset cs) {
294 pnlChangesetManagement.setSelectedChangesetForNextUpload(cs);
295 }
296
297 /**
298 * Replies the {@see UploadStrategySpecification} the user entered in the dialog.
299 *
300 * @return the {@see UploadStrategySpecification} the user entered in the dialog.
301 */
302 public UploadStrategySpecification getUploadStrategySpecification() {
303 UploadStrategySpecification spec = pnlUploadStrategySelectionPanel.getUploadStrategySpecification();
304 spec.setCloseChangesetAfterUpload(pnlChangesetManagement.isCloseChangesetAfterUpload());
305 return spec;
306 }
307
308 /**
309 * Replies the current value for the upload comment
310 *
311 * @return the current value for the upload comment
312 */
313 protected String getUploadComment() {
314 return pnlBasicUploadSettings.getUploadComment();
315 }
316
317 /**
318 * Replies true, if the dialog was canceled
319 *
320 * @return true, if the dialog was canceled
321 */
322 public boolean isCanceled() {
323 return canceled;
324 }
325
326 /**
327 * Sets whether the dialog was canceled
328 *
329 * @param canceled true, if the dialog is canceled
330 */
331 protected void setCanceled(boolean canceled) {
332 this.canceled = canceled;
333 }
334
335 @Override
336 public void setVisible(boolean visible) {
337 if (visible) {
338 new WindowGeometry(
339 getClass().getName() + ".geometry",
340 WindowGeometry.centerInWindow(
341 Main.parent,
342 new Dimension(400,600)
343 )
344 ).apply(this);
345 startUserInput();
346 } else if (!visible && isShowing()){
347 new WindowGeometry(this).remember(getClass().getName() + ".geometry");
348 }
349 super.setVisible(visible);
350 }
351
352 /**
353 * Handles an upload
354 *
355 */
356 class UploadAction extends AbstractAction {
357 public UploadAction() {
358 putValue(NAME, tr("Upload Changes"));
359 putValue(SMALL_ICON, ImageProvider.get("upload"));
360 putValue(SHORT_DESCRIPTION, tr("Upload the changed primitives"));
361 }
362
363 protected void warnIllegalUploadComment() {
364 HelpAwareOptionPane.showOptionDialog(
365 UploadDialog.this,
366 tr("Please enter a comment for this upload changeset (min. 3 characters)"),
367 tr("Illegal upload comment"),
368 JOptionPane.ERROR_MESSAGE,
369 ht("/Dialog/UploadDialog#IllegalUploadComment")
370 );
371 }
372
373 protected void warnIllegalChunkSize() {
374 HelpAwareOptionPane.showOptionDialog(
375 UploadDialog.this,
376 tr("Please enter a valid chunk size first"),
377 tr("Illegal chunk size"),
378 JOptionPane.ERROR_MESSAGE,
379 ht("/Dialog/UploadDialog#IllegalChunkSize")
380 );
381 }
382
383 public void actionPerformed(ActionEvent e) {
384 if (getUploadComment().trim().length() < 3) {
385 warnIllegalUploadComment();
386 tpConfigPanels.setSelectedIndex(0);
387 pnlBasicUploadSettings.initEditingOfUploadComment(getUploadComment());
388 return;
389 }
390 UploadStrategySpecification strategy = getUploadStrategySpecification();
391 if (strategy.getStrategy().equals(UploadStrategy.CHUNKED_DATASET_STRATEGY)) {
392 if (strategy.getChunkSize() == UploadStrategySpecification.UNSPECIFIED_CHUNK_SIZE) {
393 warnIllegalChunkSize();
394 tpConfigPanels.setSelectedIndex(0);
395 return;
396 }
397 }
398 setCanceled(false);
399 setVisible(false);
400 }
401 }
402
403 /**
404 * Action for canceling the dialog
405 *
406 */
407 class CancelAction extends AbstractAction {
408 public CancelAction() {
409 putValue(NAME, tr("Cancel"));
410 putValue(SMALL_ICON, ImageProvider.get("cancel"));
411 putValue(SHORT_DESCRIPTION, tr("Cancel the upload and resume editing"));
412 }
413
414 public void actionPerformed(ActionEvent e) {
415 setCanceled(true);
416 setVisible(false);
417 }
418 }
419
420 /**
421 * Listens to window closing events and processes them as cancel events.
422 * Listens to window open events and initializes user input
423 *
424 */
425 class WindowEventHandler extends WindowAdapter {
426 @Override
427 public void windowClosing(WindowEvent e) {
428 setCanceled(true);
429 }
430
431 @Override
432 public void windowOpened(WindowEvent e) {
433 //startUserInput();
434 }
435
436 @Override
437 public void windowActivated(WindowEvent arg0) {
438 if (tpConfigPanels.getSelectedIndex() == 0) {
439 pnlBasicUploadSettings.initEditingOfUploadComment(getUploadComment());
440 }
441 }
442 }
443
444 /* -------------------------------------------------------------------------- */
445 /* Interface PropertyChangeListener */
446 /* -------------------------------------------------------------------------- */
447 public void propertyChange(PropertyChangeEvent evt) {
448 if (evt.getPropertyName().equals(ChangesetManagementPanel.SELECTED_CHANGESET_PROP)) {
449 Changeset cs = (Changeset)evt.getNewValue();
450 if (cs == null) {
451 tpConfigPanels.setTitleAt(1, tr("Tags of new changeset"));
452 } else {
453 tpConfigPanels.setTitleAt(1, tr("Tags of changeset {0}", cs.getId()));
454 }
455 }
456 }
457
458 /* -------------------------------------------------------------------------- */
459 /* Interface PreferenceChangedListener */
460 /* -------------------------------------------------------------------------- */
461 public void preferenceChanged(PreferenceChangeEvent e) {
462 if (e.getKey() == null || ! e.getKey().equals("osm-server.url"))
463 return;
464 if (e.getNewValue() == null) {
465 setTitle(tr("Upload"));
466 } else {
467 setTitle(tr("Upload to ''{0}''", e.getNewValue()));
468 }
469 }
470}
Note: See TracBrowser for help on using the repository browser.