Changeset 2115 in josm for trunk/src/org/openstreetmap/josm/gui/io/UploadDialog.java
- Timestamp:
- 2009-09-13T19:30:36+02:00 (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/io/UploadDialog.java
r2081 r2115 6 6 7 7 import java.awt.BorderLayout; 8 import java.awt.Component; 8 9 import java.awt.Dimension; 9 10 import java.awt.FlowLayout; … … 12 13 import java.awt.event.ActionEvent; 13 14 import java.awt.event.ActionListener; 15 import java.awt.event.ItemEvent; 16 import java.awt.event.ItemListener; 14 17 import java.awt.event.WindowAdapter; 15 18 import java.awt.event.WindowEvent; 19 import java.text.SimpleDateFormat; 16 20 import java.util.ArrayList; 17 import java.util.HashMap; 21 import java.util.Collection; 22 import java.util.Collections; 18 23 import java.util.LinkedList; 19 24 import java.util.List; 20 import java.util.Map;21 25 22 26 import javax.swing.AbstractAction; 23 27 import javax.swing.AbstractListModel; 24 28 import javax.swing.BorderFactory; 25 import javax.swing.BoxLayout;26 29 import javax.swing.ButtonGroup; 30 import javax.swing.DefaultComboBoxModel; 31 import javax.swing.ImageIcon; 32 import javax.swing.JButton; 27 33 import javax.swing.JCheckBox; 34 import javax.swing.JComboBox; 28 35 import javax.swing.JDialog; 29 36 import javax.swing.JLabel; … … 34 41 import javax.swing.JScrollPane; 35 42 import javax.swing.JTabbedPane; 43 import javax.swing.ListCellRenderer; 44 import javax.swing.UIManager; 36 45 import javax.swing.event.ChangeEvent; 37 46 import javax.swing.event.ChangeListener; 47 import javax.swing.event.ListDataEvent; 48 import javax.swing.event.ListDataListener; 38 49 39 50 import org.openstreetmap.josm.Main; … … 46 57 import org.openstreetmap.josm.gui.tagging.TagEditorPanel; 47 58 import org.openstreetmap.josm.gui.tagging.TagModel; 48 import org.openstreetmap.josm.io.ChangesetProcessingType;49 59 import org.openstreetmap.josm.io.OsmApi; 50 60 import org.openstreetmap.josm.tools.GBC; … … 60 70 public class UploadDialog extends JDialog { 61 71 72 62 73 public static final String HISTORY_KEY = "upload.comment.history"; 74 75 /** the unique instance of the upload dialog */ 76 static private UploadDialog uploadDialog; 77 78 /** 79 * Replies the unique instance of the upload dialog 80 * 81 * @return the unique instance of the upload dialog 82 */ 83 static public UploadDialog getUploadDialog() { 84 if (uploadDialog == null) { 85 uploadDialog = new UploadDialog(); 86 } 87 return uploadDialog; 88 } 63 89 64 90 /** the list with the added primitives */ … … 77 103 private JPanel pnlLists; 78 104 /** checkbox for selecting whether an atomic upload is to be used */ 79 private JCheckBox cbUseAtomicUpload;80 /** input field for changeset comment */81 private SuggestingJHistoryComboBox cmt;82 /** ui component for editing changeset tags */83 105 private TagEditorPanel tagEditorPanel; 84 106 /** the tabbed pane used below of the list of primitives */ 85 107 private JTabbedPane southTabbedPane; 86 /** the button group with the changeset processing types */ 87 private ButtonGroup bgChangesetHandlingOptions; 88 /** radio buttons for selecting a changeset processing type */ 89 private Map<ChangesetProcessingType, JRadioButton> rbChangesetHandlingOptions; 108 109 private ChangesetSelectionPanel pnlChangesetSelection; 90 110 91 111 private boolean canceled = false; … … 104 124 } 105 125 106 /**107 * builds the panel with the ui components for controlling how the changeset108 * should be processed (opening/closing a changeset)109 *110 * @return the panel with the ui components for controlling how the changeset111 * should be processed112 */113 protected JPanel buildChangesetHandlingControlPanel() {114 JPanel pnl = new JPanel();115 pnl.setLayout(new BoxLayout(pnl, BoxLayout.Y_AXIS));116 bgChangesetHandlingOptions = new ButtonGroup();117 rbChangesetHandlingOptions = new HashMap<ChangesetProcessingType, JRadioButton>();118 ChangesetProcessingTypeChangedAction a = new ChangesetProcessingTypeChangedAction();119 for(ChangesetProcessingType type: ChangesetProcessingType.values()) {120 rbChangesetHandlingOptions.put(type, new JRadioButton());121 rbChangesetHandlingOptions.get(type).addActionListener(a);122 }123 JRadioButton rb = rbChangesetHandlingOptions.get(ChangesetProcessingType.USE_NEW_AND_CLOSE);124 rb.setText(tr("Use a new changeset and close it"));125 rb.setToolTipText(tr("Select to upload the data using a new changeset and to close the changeset after the upload"));126 127 rb = rbChangesetHandlingOptions.get(ChangesetProcessingType.USE_NEW_AND_LEAVE_OPEN);128 rb.setText(tr("Use a new changeset and leave it open"));129 rb.setToolTipText(tr("Select to upload the data using a new changeset and to leave the changeset open after the upload"));130 131 pnl.add(new JLabel(tr("Upload to a new or to an existing changeset?")));132 pnl.add(rbChangesetHandlingOptions.get(ChangesetProcessingType.USE_NEW_AND_CLOSE));133 pnl.add(rbChangesetHandlingOptions.get(ChangesetProcessingType.USE_NEW_AND_LEAVE_OPEN));134 pnl.add(rbChangesetHandlingOptions.get(ChangesetProcessingType.USE_EXISTING_AND_CLOSE));135 pnl.add(rbChangesetHandlingOptions.get(ChangesetProcessingType.USE_EXISTING_AND_LEAVE_OPEN));136 137 for(ChangesetProcessingType type: ChangesetProcessingType.values()) {138 rbChangesetHandlingOptions.get(type).setVisible(false);139 bgChangesetHandlingOptions.add(rbChangesetHandlingOptions.get(type));140 }141 return pnl;142 }143 144 /**145 * build the panel with the widgets for controlling how the changeset should be processed146 * (atomic upload or not, comment, opening/closing changeset)147 *148 * @return149 */150 protected JPanel buildChangesetControlPanel() {151 JPanel pnl = new JPanel();152 pnl.setLayout(new BoxLayout(pnl, BoxLayout.Y_AXIS));153 pnl.add(cbUseAtomicUpload = new JCheckBox(tr("upload all changes in one request")));154 cbUseAtomicUpload.setToolTipText(tr("Enable to upload all changes in one request, disable to use one request per changed primitive"));155 boolean useAtomicUpload = Main.pref.getBoolean("osm-server.atomic-upload", true);156 cbUseAtomicUpload.setSelected(useAtomicUpload);157 cbUseAtomicUpload.setEnabled(OsmApi.getOsmApi().hasSupportForDiffUploads());158 159 pnl.add(buildChangesetHandlingControlPanel());160 return pnl;161 }162 163 /**164 * builds the upload control panel165 *166 * @return167 */168 protected JPanel buildUploadControlPanel() {169 JPanel pnl = new JPanel();170 pnl.setLayout(new GridBagLayout());171 pnl.add(new JLabel(tr("Provide a brief comment for the changes you are uploading:")), GBC.eol().insets(0, 5, 10, 3));172 cmt = new SuggestingJHistoryComboBox();173 List<String> cmtHistory = new LinkedList<String>(Main.pref.getCollection(HISTORY_KEY, new LinkedList<String>()));174 cmt.setHistory(cmtHistory);175 cmt.getEditor().addActionListener(176 new ActionListener() {177 public void actionPerformed(ActionEvent e) {178 TagModel tm = tagEditorPanel.getModel().get("comment");179 if (tm == null) {180 tagEditorPanel.getModel().add(new TagModel("comment", cmt.getText()));181 } else {182 tm.setValue(cmt.getText());183 }184 tagEditorPanel.getModel().fireTableDataChanged();185 }186 }187 );188 pnl.add(cmt, GBC.eol().fill(GBC.HORIZONTAL));189 190 // configuration options for atomic upload191 //192 pnl.add(buildChangesetControlPanel(), GBC.eol().fill(GridBagConstraints.HORIZONTAL));193 return pnl;194 }195 126 196 127 protected JPanel buildContentPanel() { … … 211 142 // 212 143 southTabbedPane = new JTabbedPane(); 213 southTabbedPane.add( buildUploadControlPanel());144 southTabbedPane.add(new JPanel()); 214 145 tagEditorPanel = new TagEditorPanel(); 215 146 southTabbedPane.add(tagEditorPanel); 147 southTabbedPane.setComponentAt(0, pnlChangesetSelection = new ChangesetSelectionPanel()); 216 148 southTabbedPane.setTitleAt(0, tr("Settings")); 217 149 southTabbedPane.setTitleAt(1, tr("Tags of new changeset")); … … 340 272 341 273 /** 342 * Replies true if a valid changeset comment has been entered in this dialog343 *344 * @return true if a valid changeset comment has been entered in this dialog345 */346 public boolean hasChangesetComment() {347 if (!getChangesetProcessingType().isUseNew())348 return true;349 return cmt.getText().trim().length() >= 3;350 }351 352 /**353 274 * Remembers the user input in the preference settings 354 275 */ 355 276 public void rememberUserInput() { 356 // store the history of comments 357 cmt.addCurrentItemToHistory(); 358 Main.pref.putCollection(HISTORY_KEY, cmt.getHistory()); 359 Main.pref.put("osm-server.atomic-upload", cbUseAtomicUpload.isSelected()); 277 pnlChangesetSelection.rememberUserInput(); 360 278 } 361 279 … … 365 283 public void startUserInput() { 366 284 tagEditorPanel.initAutoCompletion(Main.main.getEditLayer()); 367 initChangesetProcessingType(); 368 cmt.getEditor().selectAll(); 369 cmt.requestFocus(); 370 } 371 372 /** 373 * Replies the current changeset processing type 374 * 375 * @return the current changeset processing type 376 */ 377 public ChangesetProcessingType getChangesetProcessingType() { 378 ChangesetProcessingType changesetProcessingType = null; 379 for (ChangesetProcessingType type: ChangesetProcessingType.values()) { 380 if (rbChangesetHandlingOptions.get(type).isSelected()) { 381 changesetProcessingType = type; 382 break; 383 } 384 } 385 return changesetProcessingType == null ? 386 ChangesetProcessingType.USE_NEW_AND_CLOSE : 387 changesetProcessingType; 285 pnlChangesetSelection.startUserInput(); 388 286 } 389 287 … … 394 292 */ 395 293 public Changeset getChangeset() { 396 Changeset changeset = new Changeset(); 397 tagEditorPanel.getModel().applyToPrimitive(changeset); 398 changeset.put("comment", cmt.getText()); 399 return changeset; 400 } 401 402 /** 403 * initializes the panel depending on the possible changeset processing 404 * types 405 */ 406 protected void initChangesetProcessingType() { 407 for (ChangesetProcessingType type: ChangesetProcessingType.values()) { 408 // show options for new changeset, disable others 409 // 410 rbChangesetHandlingOptions.get(type).setVisible(type.isUseNew()); 411 } 412 if (OsmApi.getOsmApi().getCurrentChangeset() != null) { 413 Changeset cs = OsmApi.getOsmApi().getCurrentChangeset(); 414 for (ChangesetProcessingType type: ChangesetProcessingType.values()) { 415 // show options for using existing changeset 416 // 417 if (!type.isUseNew()) { 418 rbChangesetHandlingOptions.get(type).setVisible(true); 419 } 420 } 421 JRadioButton rb = rbChangesetHandlingOptions.get(ChangesetProcessingType.USE_EXISTING_AND_CLOSE); 422 rb.setText(tr("Use the existing changeset {0} and close it after upload",cs.getId())); 423 rb.setToolTipText(tr("Select to upload to the existing changeset {0} and to close the changeset after this upload",cs.getId())); 424 425 rb = rbChangesetHandlingOptions.get(ChangesetProcessingType.USE_EXISTING_AND_LEAVE_OPEN); 426 rb.setText(tr("Use the existing changeset {0} and leave it open",cs.getId())); 427 rb.setToolTipText(tr("Select to upload to the existing changeset {0} and to leave the changeset open for further uploads",cs.getId())); 428 429 rbChangesetHandlingOptions.get(getChangesetProcessingType()).setSelected(true); 430 431 } else { 432 ChangesetProcessingType type = getChangesetProcessingType(); 433 if (!type.isUseNew()) { 434 type = ChangesetProcessingType.USE_NEW_AND_CLOSE; 435 } 436 rbChangesetHandlingOptions.get(type).setSelected(true); 437 } 438 ChangesetProcessingType type = getChangesetProcessingType(); 439 if (type.isUseNew() || (! type.isUseNew() && OsmApi.getOsmApi().getCurrentChangeset() == null)) { 440 Changeset cs = new Changeset(); 441 cs.put("created_by", getDefaultCreatedBy()); 442 tagEditorPanel.getModel().initFromPrimitive(cs); 443 } else { 444 Changeset cs = OsmApi.getOsmApi().getCurrentChangeset(); 445 tagEditorPanel.getModel().initFromPrimitive(cs); 446 } 294 Changeset cs = pnlChangesetSelection.getChangeset(); 295 tagEditorPanel.getModel().applyToPrimitive(cs); 296 cs.put("comment", getUploadComment()); 297 return cs; 298 } 299 300 /** 301 * Sets or updates the changeset cs. 302 * If cs is null, does nothing. 303 * If cs.getId() == 0 does nothing. 304 * If cs.getId() > 0 and cs is open, adds it to the list of open 305 * changesets. If it is closed, removes it from the list of open 306 * changesets. 307 * 308 * @param cs the changeset 309 */ 310 public void setOrUpdateChangeset(Changeset cs) { 311 pnlChangesetSelection.setOrUpdateChangeset(cs); 312 } 313 314 public boolean isDoCloseAfterUpload() { 315 return pnlChangesetSelection.isCloseAfterUpload(); 447 316 } 448 317 … … 457 326 } 458 327 459 /** 460 * refreshes the panel depending on a changeset processing type 461 * 462 * @param type the changeset processing type 463 */ 464 protected void switchToProcessingType(ChangesetProcessingType type) { 465 if (type.isUseNew()) { 466 southTabbedPane.setTitleAt(1, tr("Tags of new changeset")); 467 // init a new changeset from the currently edited tags 468 // and the comment field 469 // 470 Changeset cs = new Changeset(getChangeset()); 471 if (cs.get("created_by") == null) { 472 cs.put("created_by", getDefaultCreatedBy()); 473 } 474 cs.put("comment", this.cmt.getText()); 475 tagEditorPanel.getModel().initFromPrimitive(cs); 476 } else { 477 Changeset cs = OsmApi.getOsmApi().getCurrentChangeset(); 478 if (cs != null) { 479 cs.put("comment", this.cmt.getText()); 480 cs.setKeys(getChangeset().getKeys()); 481 southTabbedPane.setTitleAt(1, tr("Tags of changeset {0}", cs.getId())); 482 tagEditorPanel.getModel().initFromPrimitive(cs); 483 } 484 } 485 } 486 487 public String getUploadComment() { 328 protected String getUploadComment() { 488 329 switch(southTabbedPane.getSelectedIndex()) { 489 case 0: return cmt.getText(); 490 case 1: 491 TagModel tm = tagEditorPanel.getModel().get("comment"); 492 return tm == null? "" : tm.getValue(); 330 case 0: 331 pnlChangesetSelection.getUploadComment(); 332 case 1: 333 TagModel tm = tagEditorPanel.getModel().get("comment"); 334 return tm == null? "" : tm.getValue(); 493 335 } 494 336 return ""; … … 509 351 getClass().getName() + ".geometry", 510 352 WindowGeometry.centerInWindow( 511 JOptionPane.getFrameForComponent(Main.parent),353 Main.parent, 512 354 new Dimension(400,600) 513 355 ) … … 520 362 } 521 363 522 class ChangesetProcessingTypeChangedAction implements ActionListener {523 public void actionPerformed(ActionEvent e) {524 ChangesetProcessingType type = getChangesetProcessingType();525 switchToProcessingType(type);526 }527 }528 529 364 /** 365 * This change listener is triggered when current tab in the tabbed pane in 366 * the lower half of the dialog is changed. 367 * 368 * It's main purpose is to keep the content in the text field for the changeset 369 * comment in sync with the changeset tag "comment". 370 * 371 */ 530 372 class TabbedPaneChangeLister implements ChangeListener { 531 373 … … 560 402 TagModel tm = getOrCreateCommentTag(); 561 403 tm.setName("comment"); 562 tm.setValue( cmt.getText().trim());563 if ( cmt.getText().trim().equals("")) {404 tm.setValue(pnlChangesetSelection.getUploadComment().trim()); 405 if (pnlChangesetSelection.getUploadComment().trim().equals("")) { 564 406 removeCommentTag(); 565 407 } 566 408 tagEditorPanel.getModel().fireTableDataChanged(); 567 409 } 568 569 410 570 411 public void stateChanged(ChangeEvent e) { 571 412 if (southTabbedPane.getSelectedIndex() ==0) { 572 413 TagModel tm = tagEditorPanel.getModel().get("comment"); 573 cmt.setText(tm == null ? "" : tm.getValue()); 574 cmt.getEditor().selectAll(); 575 cmt.requestFocus(); 414 pnlChangesetSelection.initEditingOfUploadComment(tm == null ? "" : tm.getValue()); 576 415 } else if (southTabbedPane.getSelectedIndex() == 1) { 577 416 refreshCommentTag(); … … 580 419 } 581 420 421 /** 422 * Handles an upload 423 * 424 */ 582 425 class UploadAction extends AbstractAction { 583 426 public UploadAction() { … … 599 442 if (getUploadComment().trim().length() < 3) { 600 443 warnIllegalUploadComment(); 601 cmt.getEditor().selectAll();602 cmt.requestFocus();444 southTabbedPane.setSelectedIndex(0); 445 pnlChangesetSelection.initEditingOfUploadComment(getUploadComment()); 603 446 return; 604 447 } … … 609 452 } 610 453 454 /** 455 * Action for canceling the dialog 456 * 457 */ 611 458 class CancelAction extends AbstractAction { 612 459 public CancelAction() { … … 623 470 } 624 471 472 /** 473 * A simple list of OSM primitives. 474 * 475 */ 625 476 class PrimitiveList extends JList { 626 477 public PrimitiveList() { … … 633 484 } 634 485 486 /** 487 * A list model for a list of OSM primitives. 488 * 489 */ 635 490 class PrimitiveListModel extends AbstractListModel{ 636 491 private List<OsmPrimitive> primitives; … … 664 519 } 665 520 521 /** 522 * Listens to window closing events and processes them as cancel events 523 * 524 */ 666 525 class WindowClosingAdapter extends WindowAdapter { 667 526 @Override … … 670 529 } 671 530 } 531 532 /** 533 * The panel which provides various UI widgets for controlling how to use 534 * changesets during upload. 535 * 536 */ 537 class ChangesetSelectionPanel extends JPanel implements ListDataListener{ 538 539 private ButtonGroup bgUseNewOrExisting; 540 private JRadioButton rbUseNew; 541 private JRadioButton rbExisting; 542 private JComboBox cbOpenChangesets; 543 private JButton btnRefresh; 544 private JButton btnClose; 545 private JCheckBox cbCloseAfterUpload; 546 private OpenChangesetModel model; 547 private SuggestingJHistoryComboBox cmt; 548 private JCheckBox cbUseAtomicUpload; 549 550 /** 551 * build the panel with the widgets for controlling whether an atomic upload 552 * should be used or not 553 * 554 * @return the panel 555 */ 556 protected JPanel buildAtomicUploadControlPanel() { 557 JPanel pnl = new JPanel(); 558 pnl.setLayout(new GridBagLayout()); 559 GridBagConstraints gc = new GridBagConstraints(); 560 gc.fill = GridBagConstraints.HORIZONTAL; 561 gc.weightx = 1.0; 562 gc.anchor = GridBagConstraints.FIRST_LINE_START; 563 pnl.add(cbUseAtomicUpload = new JCheckBox(tr("Upload all changes in one request")), gc); 564 cbUseAtomicUpload.setToolTipText(tr("Enable to upload all changes in one request, disable to use one request per changed primitive")); 565 boolean useAtomicUpload = Main.pref.getBoolean("osm-server.atomic-upload", true); 566 cbUseAtomicUpload.setSelected(useAtomicUpload); 567 cbUseAtomicUpload.setEnabled(OsmApi.getOsmApi().hasSupportForDiffUploads()); 568 return pnl; 569 } 570 571 protected JPanel buildUploadCommentPanel() { 572 JPanel pnl = new JPanel(); 573 pnl.setLayout(new GridBagLayout()); 574 pnl.add(new JLabel(tr("Provide a brief comment for the changes you are uploading:")), GBC.eol().insets(0, 5, 10, 3)); 575 cmt = new SuggestingJHistoryComboBox(); 576 List<String> cmtHistory = new LinkedList<String>(Main.pref.getCollection(HISTORY_KEY, new LinkedList<String>())); 577 cmt.setHistory(cmtHistory); 578 cmt.getEditor().addActionListener( 579 new ActionListener() { 580 public void actionPerformed(ActionEvent e) { 581 TagModel tm = tagEditorPanel.getModel().get("comment"); 582 if (tm == null) { 583 tagEditorPanel.getModel().add(new TagModel("comment", cmt.getText())); 584 } else { 585 tm.setValue(cmt.getText()); 586 } 587 tagEditorPanel.getModel().fireTableDataChanged(); 588 } 589 } 590 ); 591 pnl.add(cmt, GBC.eol().fill(GBC.HORIZONTAL)); 592 return pnl; 593 } 594 595 protected void build() { 596 setLayout(new GridBagLayout()); 597 GridBagConstraints gc = new GridBagConstraints(); 598 599 bgUseNewOrExisting = new ButtonGroup(); 600 601 // -- atomic upload 602 gc.gridwidth = 4; 603 gc.gridy = 0; 604 gc.fill = GridBagConstraints.HORIZONTAL; 605 gc.weightx = 1.0; 606 gc.anchor = GridBagConstraints.FIRST_LINE_START; 607 add(buildAtomicUploadControlPanel(), gc); 608 609 // -- changeset command 610 gc.gridwidth = 4; 611 gc.gridy = 1; 612 gc.fill = GridBagConstraints.HORIZONTAL; 613 gc.weightx = 1.0; 614 gc.anchor = GridBagConstraints.FIRST_LINE_START; 615 add(buildUploadCommentPanel(), gc); 616 617 gc.gridwidth = 4; 618 gc.gridy = 2; 619 gc.fill = GridBagConstraints.HORIZONTAL; 620 gc.weightx = 0.0; 621 gc.anchor = GridBagConstraints.FIRST_LINE_START; 622 rbUseNew = new JRadioButton(tr("Open a new changeset")); 623 rbUseNew.setToolTipText(tr("Open a new changeset and use it in the next upload")); 624 bgUseNewOrExisting.add(rbUseNew); 625 add(rbUseNew, gc); 626 627 gc.gridx = 0; 628 gc.gridy = 3; 629 gc.gridwidth = 1; 630 rbExisting = new JRadioButton(tr("Use an open changeset")); 631 rbExisting.setToolTipText(tr("Upload data to an already opened changeset")); 632 bgUseNewOrExisting.add(rbExisting); 633 add(rbExisting, gc); 634 635 gc.gridx = 1; 636 gc.gridy = 3; 637 gc.gridwidth = 1; 638 gc.weightx = 1.0; 639 model = new OpenChangesetModel(); 640 cbOpenChangesets = new JComboBox(model); 641 cbOpenChangesets.setToolTipText("Select an open changeset"); 642 cbOpenChangesets.setRenderer(new ChangesetCellRenderer()); 643 cbOpenChangesets.addItemListener(new ChangesetListItemStateListener()); 644 Dimension d = cbOpenChangesets.getPreferredSize(); 645 d.width = 200; 646 cbOpenChangesets.setPreferredSize(d); 647 d.width = 100; 648 cbOpenChangesets.setMinimumSize(d); 649 model.addListDataListener(this); 650 add(cbOpenChangesets, gc); 651 652 gc.gridx = 3; 653 gc.gridy = 3; 654 gc.gridwidth = 1; 655 gc.weightx = 0.0; 656 btnRefresh = new JButton(new RefreshAction()); 657 add(btnRefresh, gc); 658 659 gc.gridx = 4; 660 gc.gridy = 3; 661 gc.gridwidth = 1; 662 gc.weightx = 0.0; 663 CloseChangesetAction closeChangesetAction = new CloseChangesetAction(); 664 btnClose = new JButton(closeChangesetAction); 665 cbOpenChangesets.addItemListener(closeChangesetAction); 666 add(btnClose, gc); 667 668 gc.gridx = 0; 669 gc.gridy = 4; 670 gc.gridwidth = 4; 671 cbCloseAfterUpload = new JCheckBox(tr("Close changeset after upload")); 672 cbCloseAfterUpload.setToolTipText(tr("Select to close the changeset after the next upload")); 673 add(cbCloseAfterUpload, gc); 674 cbCloseAfterUpload.setSelected(true); 675 676 rbUseNew.getModel().addItemListener(new RadioButtonHandler()); 677 rbExisting.getModel().addItemListener(new RadioButtonHandler()); 678 679 refreshGUI(); 680 } 681 682 public ChangesetSelectionPanel() { 683 build(); 684 } 685 686 /** 687 * Remembers the user input in the preference settings 688 */ 689 public void rememberUserInput() { 690 // store the history of comments 691 cmt.addCurrentItemToHistory(); 692 Main.pref.putCollection(HISTORY_KEY, cmt.getHistory()); 693 Main.pref.put("osm-server.atomic-upload", cbUseAtomicUpload.isSelected()); 694 } 695 696 /** 697 * Initializes the panel for user input 698 */ 699 public void startUserInput() { 700 cmt.getEditor().selectAll(); 701 cmt.requestFocus(); 702 } 703 704 /** 705 * Replies the current upload comment 706 * 707 * @return 708 */ 709 public String getUploadComment() { 710 return cmt.getText(); 711 } 712 713 /** 714 * Replies the current upload comment 715 * 716 * @return 717 */ 718 public void setUploadComment(String uploadComment) { 719 cmt.setText(uploadComment); 720 } 721 722 public void initEditingOfUploadComment(String comment) { 723 setUploadComment(comment); 724 cmt.getEditor().selectAll(); 725 cmt.requestFocus(); 726 } 727 728 protected void refreshGUI() { 729 rbExisting.setEnabled(model.getSize() > 0); 730 if (model.getSize() == 0) { 731 if (!rbUseNew.isSelected()) { 732 rbUseNew.setSelected(true); 733 } 734 } 735 cbOpenChangesets.setEnabled(model.getSize() > 0 && rbExisting.isSelected()); 736 } 737 738 public void contentsChanged(ListDataEvent e) { 739 refreshGUI(); 740 } 741 742 public void intervalAdded(ListDataEvent e) { 743 refreshGUI(); 744 } 745 746 public void intervalRemoved(ListDataEvent e) { 747 refreshGUI(); 748 } 749 750 public Changeset getChangeset() { 751 if (rbUseNew.isSelected() || cbOpenChangesets.getSelectedItem() == null) 752 return new Changeset(); 753 Changeset cs = (Changeset)cbOpenChangesets.getSelectedItem(); 754 if (cs == null) 755 return new Changeset(); 756 return cs; 757 } 758 759 public void setOrUpdateChangeset(Changeset cs) { 760 if (cs == null) { 761 tagEditorPanel.getModel().clear(); 762 tagEditorPanel.getModel().add("created_by", getDefaultCreatedBy()); 763 tagEditorPanel.getModel().appendNewTag(); 764 rbUseNew.setSelected(true); 765 } else if (cs.getId() == 0) { 766 if (cs.get("created_by") == null) { 767 cs.put("created_by", getDefaultCreatedBy()); 768 } 769 tagEditorPanel.getModel().initFromPrimitive(cs); 770 tagEditorPanel.getModel().appendNewTag(); 771 rbUseNew.setSelected(true); 772 } else if (cs.getId() > 0 && cs.isOpen()){ 773 if (cs.get("created_by") == null) { 774 cs.put("created_by", getDefaultCreatedBy()); 775 } 776 tagEditorPanel.getModel().initFromPrimitive(cs); 777 model.addOrUpdate(cs); 778 cs = model.getChangesetById(cs.getId()); 779 cbOpenChangesets.setSelectedItem(cs); 780 } else if (cs.getId() > 0 && !cs.isOpen()){ 781 if (cs.get("created_by") == null) { 782 cs.put("created_by", getDefaultCreatedBy()); 783 } 784 tagEditorPanel.getModel().initFromPrimitive(cs); 785 model.removeChangeset(cs); 786 if (model.getSize() == 0) { 787 rbUseNew.setSelected(true); 788 model.setSelectedItem(null); 789 southTabbedPane.setTitleAt(1, tr("Tags of new changeset")); 790 } 791 } 792 } 793 794 public void setUseNew() { 795 rbUseNew.setSelected(true); 796 } 797 798 public void setUseExisting() { 799 rbExisting.setSelected(true); 800 if (cbOpenChangesets.getSelectedItem() == null && model.getSize() > 0) { 801 cbOpenChangesets.setSelectedItem(model.getElementAt(0)); 802 } 803 } 804 805 public boolean isCloseAfterUpload() { 806 return cbCloseAfterUpload.isSelected(); 807 } 808 809 class RadioButtonHandler implements ItemListener { 810 public void itemStateChanged(ItemEvent e) { 811 if (rbUseNew.isSelected()) { 812 southTabbedPane.setTitleAt(1, tr("Tags of new changeset")); 813 // init a new changeset from the currently edited tags 814 // and the comment field 815 // 816 Changeset cs = new Changeset(); 817 tagEditorPanel.getModel().applyToPrimitive(cs); 818 if (cs.get("created_by") == null) { 819 cs.put("created_by", getDefaultCreatedBy()); 820 } 821 cs.put("comment", cmt.getText()); 822 tagEditorPanel.getModel().initFromPrimitive(cs); 823 } else { 824 if (cbOpenChangesets.getSelectedItem() == null) { 825 model.selectFirstChangeset(); 826 } 827 Changeset cs = (Changeset)cbOpenChangesets.getSelectedItem(); 828 if (cs != null) { 829 cs.put("comment", cmt.getText()); 830 southTabbedPane.setTitleAt(1, tr("Tags of changeset {0}", cs.getId())); 831 tagEditorPanel.getModel().initFromPrimitive(cs); 832 } 833 } 834 refreshGUI(); 835 } 836 } 837 838 class ChangesetListItemStateListener implements ItemListener { 839 public void itemStateChanged(ItemEvent e) { 840 841 Changeset cs = (Changeset)cbOpenChangesets.getSelectedItem(); 842 if (cs == null) { 843 southTabbedPane.setTitleAt(1, tr("Tags of new changeset")); 844 // init a new changeset from the currently edited tags 845 // and the comment field 846 // 847 cs = new Changeset(); 848 tagEditorPanel.getModel().applyToPrimitive(cs); 849 if (cs.get("created_by") == null) { 850 cs.put("created_by", getDefaultCreatedBy()); 851 } 852 cs.put("comment", cmt.getText()); 853 tagEditorPanel.getModel().initFromPrimitive(cs); 854 } else { 855 southTabbedPane.setTitleAt(1, tr("Tags of changeset {0}", cs.getId())); 856 cs.put("comment", cmt.getText()); 857 southTabbedPane.setTitleAt(1, tr("Tags of changeset {0}", cs.getId())); 858 if (cs.get("created_by") == null) { 859 cs.put("created_by", getDefaultCreatedBy()); 860 } 861 tagEditorPanel.getModel().initFromPrimitive(cs); 862 } 863 } 864 } 865 866 class RefreshAction extends AbstractAction { 867 public RefreshAction() { 868 //putValue(NAME, tr("Reload")); 869 putValue(SHORT_DESCRIPTION, tr("Load the list of your open changesets from the server")); 870 putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh")); 871 } 872 873 public void actionPerformed(ActionEvent e) { 874 DownloadOpenChangesetsTask task = new DownloadOpenChangesetsTask(model); 875 Main.worker.submit(task); 876 } 877 } 878 879 class CloseChangesetAction extends AbstractAction implements ItemListener{ 880 public CloseChangesetAction() { 881 putValue(NAME, tr("Close")); 882 putValue(SHORT_DESCRIPTION, tr("Close the currently selected open changeset")); 883 refreshEnabledState(); 884 } 885 886 public void actionPerformed(ActionEvent e) { 887 Changeset cs = (Changeset)cbOpenChangesets.getSelectedItem(); 888 if (cs == null) return; 889 CloseChangesetTask task = new CloseChangesetTask(Collections.singletonList(cs)); 890 Main.worker.submit(task); 891 } 892 893 protected void refreshEnabledState() { 894 setEnabled(cbOpenChangesets.getModel().getSize() > 0 && cbOpenChangesets.getSelectedItem() != null); 895 } 896 897 public void itemStateChanged(ItemEvent e) { 898 refreshEnabledState(); 899 } 900 } 901 } 902 903 public class OpenChangesetModel extends DefaultComboBoxModel { 904 private List<Changeset> changesets; 905 private long uid; 906 private Changeset selectedChangeset = null; 907 908 protected Changeset getChangesetById(long id) { 909 for (Changeset cs : changesets) { 910 if (cs.getId() == id) return cs; 911 } 912 return null; 913 } 914 915 public OpenChangesetModel() { 916 this.changesets = new ArrayList<Changeset>(); 917 } 918 919 protected void internalAddOrUpdate(Changeset cs) { 920 Changeset other = getChangesetById(cs.getId()); 921 if (other != null) { 922 cs.cloneFrom(other); 923 } else { 924 changesets.add(cs); 925 } 926 } 927 928 public void addOrUpdate(Changeset cs) { 929 if (cs.getId() <= 0 ) 930 throw new IllegalArgumentException(tr("changeset id > 0 expected. Got {1}", "id", cs.getId())); 931 internalAddOrUpdate(cs); 932 fireContentsChanged(this, 0, getSize()); 933 } 934 935 public void remove(long id) { 936 Changeset cs = getChangesetById(id); 937 if (cs != null) { 938 changesets.remove(cs); 939 } 940 fireContentsChanged(this, 0, getSize()); 941 } 942 943 public void addOrUpdate(Collection<Changeset> changesets) { 944 for (Changeset cs: changesets) { 945 internalAddOrUpdate(cs); 946 } 947 fireContentsChanged(this, 0, getSize()); 948 if (getSelectedItem() == null && !this.changesets.isEmpty()) { 949 setSelectedItem(this.changesets.get(0)); 950 } else { 951 setSelectedItem(null); 952 } 953 } 954 955 public void setUserId(long uid) { 956 this.uid = uid; 957 } 958 959 public long getUserId() { 960 return uid; 961 } 962 963 public void selectFirstChangeset() { 964 if (changesets == null || changesets.isEmpty()) return; 965 setSelectedItem(changesets.get(0)); 966 } 967 968 public void removeChangeset(Changeset cs) { 969 if (cs == null) return; 970 changesets.remove(cs); 971 if (selectedChangeset == cs) { 972 selectFirstChangeset(); 973 } 974 fireContentsChanged(this, 0, getSize()); 975 } 976 /* ------------------------------------------------------------------------------------ */ 977 /* ComboBoxModel */ 978 /* ------------------------------------------------------------------------------------ */ 979 @Override 980 public Object getElementAt(int index) { 981 return changesets.get(index); 982 } 983 984 @Override 985 public int getIndexOf(Object anObject) { 986 return changesets.indexOf(anObject); 987 } 988 989 @Override 990 public int getSize() { 991 return changesets.size(); 992 } 993 994 @Override 995 public Object getSelectedItem() { 996 return selectedChangeset; 997 } 998 999 @Override 1000 public void setSelectedItem(Object anObject) { 1001 if (anObject == null) { 1002 this.selectedChangeset = null; 1003 super.setSelectedItem(null); 1004 return; 1005 } 1006 if (! (anObject instanceof Changeset)) return; 1007 Changeset cs = (Changeset)anObject; 1008 if (cs.getId() == 0 || ! cs.isOpen()) return; 1009 Changeset candidate = getChangesetById(cs.getId()); 1010 if (candidate == null) return; 1011 this.selectedChangeset = candidate; 1012 super.setSelectedItem(selectedChangeset); 1013 } 1014 } 672 1015 }
Note:
See TracChangeset
for help on using the changeset viewer.
