Changeset 18283 in josm for trunk/src/org
- Timestamp:
- 2021-10-17T15:17:42+02:00 (3 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 1 deleted
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/UploadAction.java
r18173 r18283 36 36 import org.openstreetmap.josm.spi.preferences.Config; 37 37 import org.openstreetmap.josm.tools.ImageProvider; 38 import org.openstreetmap.josm.tools.Logging; 38 39 import org.openstreetmap.josm.tools.Shortcut; 39 40 import org.openstreetmap.josm.tools.Utils; … … 240 241 241 242 final UploadDialog dialog = UploadDialog.getUploadDialog(); 243 dialog.setUploadedPrimitives(apiData); 242 244 dialog.initLifeCycle(layer.getDataSet()); 243 dialog.setUploadedPrimitives(apiData);244 245 dialog.setVisible(true); 245 246 dialog.rememberUserInput(); … … 267 268 268 269 UploadStrategySpecification uploadStrategySpecification = dialog.getUploadStrategySpecification(); 270 Logging.info("Starting upload with tags {0}", changesetTags); 271 Logging.info(uploadStrategySpecification.toString()); 272 Logging.info(cs.toString()); 269 273 dialog.clean(); 270 274 -
trunk/src/org/openstreetmap/josm/data/osm/Changeset.java
r17749 r18283 318 318 throw new IllegalArgumentException("Changeset tag value is too long: "+value); 319 319 }); 320 this.tags = keys;320 this.tags = new HashMap<>(keys); 321 321 } 322 322 -
trunk/src/org/openstreetmap/josm/data/osm/ChangesetCache.java
r18208 r18283 13 13 14 14 import org.openstreetmap.josm.data.UserIdentityManager; 15 import org.openstreetmap.josm.io.ChangesetQuery; 16 import org.openstreetmap.josm.io.OsmServerChangesetReader; 17 import org.openstreetmap.josm.io.OsmTransferException; 15 18 import org.openstreetmap.josm.spi.preferences.Config; 16 19 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent; 17 20 import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener; 21 import org.openstreetmap.josm.tools.Logging; 18 22 import org.openstreetmap.josm.tools.SubclassFilteredCollection; 19 23 import org.openstreetmap.josm.tools.Utils; … … 255 259 } 256 260 261 /** 262 * Refreshes the changesets from the server. 263 * <p> 264 * The server automatically closes changesets after a timeout. We don't get notified of this 265 * fact when it happens. This method requests a fresh list from the server and updates the 266 * local list. Calling this method reduces (but does not eliminate) the probability of 267 * attempting an upload to an already closed changeset. 268 * 269 * @throws OsmTransferException on server error 270 */ 271 public void refreshChangesetsFromServer() throws OsmTransferException { 272 OsmServerChangesetReader reader; 273 synchronized (this) { 274 reader = new OsmServerChangesetReader(); 275 } 276 List<Changeset> server = reader.queryChangesets(ChangesetQuery.forCurrentUser().beingOpen(true), null); 277 Logging.info("{0} open changesets on server", server.size()); 278 279 DefaultChangesetCacheEvent e = new DefaultChangesetCacheEvent(this); 280 // flag timed out changesets 281 for (Changeset cs : getOpenChangesetsForCurrentUser()) { 282 if (!server.contains(cs)) 283 remove(cs.getId(), e); 284 } 285 for (Changeset cs: server) { 286 update(cs, e); 287 } 288 fireChangesetCacheEvent(e); 289 } 290 257 291 /* ------------------------------------------------------------------------- */ 258 292 /* interface PreferenceChangedListener */ -
trunk/src/org/openstreetmap/josm/gui/io/BasicUploadSettingsPanel.java
r18221 r18283 103 103 } 104 104 105 protected void build() { 106 setLayout(new GridBagLayout()); 107 setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); 108 GBC gbc = GBC.eop().fill(GBC.HORIZONTAL); 109 add(buildUploadCommentPanel(), gbc); 110 add(buildUploadSourcePanel(), gbc); 111 add(pnlUploadParameterSummary, gbc); 112 if (Config.getPref().getBoolean("upload.show.review.request", true)) { 113 add(cbRequestReview, gbc); 114 cbRequestReview.addItemListener(this); 115 } 116 add(areaValidatorFeedback, gbc); 117 add(new JPanel(), GBC.std().fill(GBC.BOTH)); 118 } 119 105 120 protected JPanel buildUploadCommentPanel() { 106 121 JPanel pnl = new JPanel(new GridBagLayout()); … … 114 129 editor.addFocusListener(this); 115 130 editor.addActionListener(this); 116 pnl.add(hcbUploadComment, GBC.eol().fill(GBC.HORIZONTAL)); 117 pnl.add(uploadCommentFeedback, GBC.eol().insets(0, 3, 0, 0).fill(GBC.HORIZONTAL)); 131 GBC gbc = GBC.eol().insets(3).fill(GBC.HORIZONTAL); 132 pnl.add(hcbUploadComment, gbc); 133 pnl.add(uploadCommentFeedback, gbc); 118 134 return pnl; 119 135 } … … 142 158 obtainSource.add(obtainSourceOnce, GBC.std().anchor(GBC.WEST)); 143 159 obtainSource.add(new JLabel(), GBC.eol().fill(GBC.HORIZONTAL)); 144 if (Config.getPref().getBoolean("upload.show.automatic.source", true)) {145 pnl.add(obtainSource, GBC.eol().insets(0, 0, 10, 3).fill(GBC.HORIZONTAL));146 }147 160 148 161 hcbUploadSource.setToolTipText(tr("Enter a source")); … … 153 166 editor.addFocusListener(this); 154 167 editor.addActionListener(this); 155 pnl.add(hcbUploadSource, GBC.eol().fill(GBC.HORIZONTAL)); 156 pnl.add(hcbUploadSourceFeedback, GBC.eol().insets(0, 3, 0, 0).fill(GBC.HORIZONTAL)); 157 168 GBC gbc = GBC.eol().insets(3).fill(GBC.HORIZONTAL); 169 if (Config.getPref().getBoolean("upload.show.automatic.source", true)) { 170 pnl.add(obtainSource, gbc); 171 } 172 pnl.add(hcbUploadSource, gbc); 173 pnl.add(hcbUploadSourceFeedback, gbc); 158 174 return pnl; 159 175 } … … 162 178 * Initializes this life cycle of the panel. 163 179 * 164 * Adds any changeset tags to the map. 180 * Adds the comment and source tags from history, and/or obtains the source from the layer if 181 * the user said so. 165 182 * 166 183 * @param map Map where tags are added to. … … 179 196 hcbUploadSource.getModel().prefs().load(SOURCE_HISTORY_KEY, getDefaultSources()); 180 197 hcbUploadSource.discardAllUndoableEdits(); 198 hcbUploadComment.getEditorComponent().requestFocusInWindow(); 199 uploadCommentValidator.validate(); 200 uploadSourceValidator.validate(); 181 201 } 182 202 … … 233 253 protected List<UploadTextComponentValidator> getUploadTextValidators() { 234 254 return Arrays.asList(areaValidator, uploadCommentValidator, uploadSourceValidator); 235 }236 237 protected void build() {238 setLayout(new GridBagLayout());239 setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));240 GBC gbc = GBC.eol().insets(0, 0, 0, 20).fill(GBC.HORIZONTAL);241 add(buildUploadCommentPanel(), gbc);242 add(buildUploadSourcePanel(), gbc);243 add(pnlUploadParameterSummary, gbc);244 if (Config.getPref().getBoolean("upload.show.review.request", true)) {245 add(cbRequestReview, gbc);246 cbRequestReview.addItemListener(this);247 }248 add(areaValidatorFeedback, gbc);249 add(new JPanel(), GBC.std().fill(GBC.BOTH));250 255 } 251 256 … … 266 271 // store current value of obtaining source automatically 267 272 Config.getPref().putBoolean("upload.source.obtainautomatically", obtainSourceAutomatically.isSelected()); 268 }269 270 /**271 * Initializes the panel for user input272 */273 public void startUserInput() {274 hcbUploadComment.getEditorComponent().requestFocusInWindow();275 uploadCommentValidator.validate();276 uploadSourceValidator.validate();277 273 } 278 274 -
trunk/src/org/openstreetmap/josm/gui/io/ChangesetCellRenderer.java
r17717 r18283 63 63 if (cs != null) { 64 64 setIcon(icon); 65 StringBuilder sb = new StringBuilder(); 66 String comment = cs.getComment(); 67 if (!comment.isEmpty()) { 68 sb.append(cs.getId()).append(" - ").append(comment); 69 } else if (cs.get("name") != null) { 70 sb.append(cs.getId()).append(" - ").append(cs.get("name")); 65 if (cs.getId() == 0) { 66 setText("New changeset"); 71 67 } else { 72 sb.append(tr("Changeset {0}", cs.getId())); 68 StringBuilder sb = new StringBuilder(); 69 String comment = cs.getComment(); 70 if (!comment.isEmpty()) { 71 sb.append(cs.getId()).append(" - ").append(comment); 72 } else if (cs.get("name") != null) { 73 sb.append(cs.getId()).append(" - ").append(cs.get("name")); 74 } else { 75 sb.append(tr("Changeset {0}", cs.getId())); 76 } 77 setText(sb.toString()); 73 78 } 74 setText(sb.toString());75 79 setToolTipText(buildToolTipText(cs)); 76 80 } else { 77 setText(tr("No open changesets")); 81 setIcon(null); 82 setText(""); 78 83 } 79 84 return this; -
trunk/src/org/openstreetmap/josm/gui/io/ChangesetManagementPanel.java
r18174 r18283 12 12 import java.awt.event.ItemListener; 13 13 import java.util.Collections; 14 import java.util.Optional; 14 15 15 16 import javax.swing.AbstractAction; 16 17 import javax.swing.BorderFactory; 17 import javax.swing.ButtonGroup;18 18 import javax.swing.JButton; 19 19 import javax.swing.JCheckBox; 20 20 import javax.swing.JPanel; 21 import javax.swing.JRadioButton; 22 import javax.swing.event.ListDataEvent; 23 import javax.swing.event.ListDataListener; 21 import javax.swing.SwingUtilities; 24 22 25 23 import org.openstreetmap.josm.data.osm.Changeset; 26 24 import org.openstreetmap.josm.data.osm.ChangesetCache; 25 import org.openstreetmap.josm.data.osm.ChangesetCacheEvent; 26 import org.openstreetmap.josm.data.osm.ChangesetCacheListener; 27 27 import org.openstreetmap.josm.gui.MainApplication; 28 28 import org.openstreetmap.josm.gui.widgets.JMultilineLabel; 29 29 import org.openstreetmap.josm.gui.widgets.JosmComboBox; 30 import org.openstreetmap.josm.gui.widgets.JosmComboBoxModel; 31 import org.openstreetmap.josm.io.OsmTransferException; 30 32 import org.openstreetmap.josm.spi.preferences.Config; 31 33 import org.openstreetmap.josm.tools.ImageProvider; … … 45 47 * </ul> 46 48 */ 47 public class ChangesetManagementPanel extends JPanel implements ListDataListener {49 public class ChangesetManagementPanel extends JPanel implements ItemListener, ChangesetCacheListener { 48 50 static final String SELECTED_CHANGESET_PROP = ChangesetManagementPanel.class.getName() + ".selectedChangeset"; 49 51 static final String CLOSE_CHANGESET_AFTER_UPLOAD = ChangesetManagementPanel.class.getName() + ".closeChangesetAfterUpload"; 50 52 51 private JRadioButton rbUseNew;52 private JRadioButton rbExisting;53 53 private JosmComboBox<Changeset> cbOpenChangesets; 54 private JosmComboBoxModel<Changeset> model; 54 55 private JCheckBox cbCloseAfterUpload; 55 private OpenChangesetComboBoxModel model; 56 57 /** the changeset comment model */ 58 private final transient UploadDialogModel uploadDialogModel; 56 private JButton btnClose; 59 57 60 58 /** 61 59 * Constructs a new {@code ChangesetManagementPanel}. 62 60 * 63 * @param uploadDialogModel The tag editor model. 64 * 65 * @since 18173 (signature) 66 */ 67 public ChangesetManagementPanel(UploadDialogModel uploadDialogModel) { 68 this.uploadDialogModel = uploadDialogModel; 61 * @since 18283 (signature) 62 */ 63 public ChangesetManagementPanel() { 69 64 build(); 70 refreshGUI(); 65 } 66 67 /** 68 * Initializes this life cycle of the panel. 69 * 70 * @since 18283 71 */ 72 public void initLifeCycle() { 73 refreshChangesets(); 74 } 75 76 /** 77 * Returns the model in use. 78 * @return the model 79 */ 80 public JosmComboBoxModel<Changeset> getModel() { 81 return model; 71 82 } 72 83 … … 76 87 protected void build() { 77 88 setLayout(new GridBagLayout()); 89 setBorder(BorderFactory.createTitledBorder(tr("Please select a changeset:"))); 90 78 91 GridBagConstraints gc = new GridBagConstraints(); 79 setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));80 81 ButtonGroup bgUseNewOrExisting = new ButtonGroup();82 83 gc.gridwidth = 4;84 92 gc.gridx = 0; 85 93 gc.gridy = 0; 86 gc.fill = GridBagConstraints.HORIZONTAL;87 94 gc.weightx = 1.0; 88 95 gc.weighty = 0.0; 89 gc.insets = new Insets(0, 0, 5, 0);90 add(new JMultilineLabel(91 tr("Please decide what changeset the data is uploaded to and whether to close the changeset after the next upload.")), gc);92 93 gc.gridwidth = 4;94 gc.gridy = 1;95 96 gc.fill = GridBagConstraints.HORIZONTAL; 96 gc.weightx = 1.0; 97 gc.weighty = 0.0; 98 gc.insets = new Insets(0, 0, 0, 0); 99 gc.anchor = GridBagConstraints.FIRST_LINE_START; 100 rbUseNew = new JRadioButton(tr("Upload to a new changeset")); 101 rbUseNew.setToolTipText(tr("Open a new changeset and use it in the next upload")); 102 bgUseNewOrExisting.add(rbUseNew); 103 add(rbUseNew, gc); 104 105 gc.gridx = 0; 106 gc.gridy = 2; 97 gc.anchor = GridBagConstraints.NORTHWEST; 98 gc.insets = new Insets(3, 3, 3, 3); 99 100 gc.gridwidth = 3; 101 add(new JMultilineLabel(tr( 102 "Please select which changeset the data shall be uploaded to and whether to close that changeset after the next upload." 103 )), gc); 104 107 105 gc.gridwidth = 1; 108 gc.weightx = 0.0; 109 gc.fill = GridBagConstraints.HORIZONTAL; 110 rbExisting = new JRadioButton(tr("Upload to an existing changeset")); 111 rbExisting.setToolTipText(tr("Upload data to an already existing and open changeset")); 112 bgUseNewOrExisting.add(rbExisting); 113 add(rbExisting, gc); 114 115 gc.gridx = 1; 116 gc.gridy = 2; 117 gc.gridwidth = 1; 118 gc.weightx = 1.0; 119 model = new OpenChangesetComboBoxModel(); 120 ChangesetCache.getInstance().addChangesetCacheListener(model); 106 gc.gridy++; 107 model = new JosmComboBoxModel<>(); 121 108 cbOpenChangesets = new JosmComboBox<>(model); 122 cbOpenChangesets.setToolTipText(tr("Select a n openchangeset"));109 cbOpenChangesets.setToolTipText(tr("Select a changeset")); 123 110 cbOpenChangesets.setRenderer(new ChangesetCellRenderer()); 124 cbOpenChangesets.addItemListener(new ChangesetListItemStateListener());125 111 Dimension d = cbOpenChangesets.getPreferredSize(); 126 112 d.width = 200; … … 128 114 d.width = 100; 129 115 cbOpenChangesets.setMinimumSize(d); 130 model.addListDataListener(this);131 116 add(cbOpenChangesets, gc); 132 133 gc.gridx = 2; 134 gc.gridy = 2; 135 gc.weightx = 0.0; 136 gc.gridwidth = 1; 117 int h = cbOpenChangesets.getPreferredSize().height; 118 Dimension prefSize = new Dimension(h, h); 119 120 gc.gridx++; 137 121 gc.weightx = 0.0; 138 122 JButton btnRefresh = new JButton(new RefreshAction()); 139 btnRefresh.setMargin(new Insets(0, 0, 0, 0)); 123 btnRefresh.setPreferredSize(prefSize); 124 btnRefresh.setMinimumSize(prefSize); 140 125 add(btnRefresh, gc); 141 126 142 gc.gridx = 3; 143 gc.gridy = 2; 144 gc.gridwidth = 1; 127 gc.gridx++; 145 128 CloseChangesetAction closeChangesetAction = new CloseChangesetAction(); 146 JButton btnClose = new JButton(closeChangesetAction); 147 btnClose.setMargin(new Insets(0, 0, 0, 0)); 148 cbOpenChangesets.addItemListener(closeChangesetAction); 149 rbExisting.addItemListener(closeChangesetAction); 129 btnClose = new JButton(closeChangesetAction); 130 btnClose.setPreferredSize(prefSize); 131 btnClose.setMinimumSize(prefSize); 150 132 add(btnClose, gc); 151 133 134 gc.gridy++; 152 135 gc.gridx = 0; 153 gc.gridy = 3; 154 gc.gridwidth = 4; 136 gc.gridwidth = 3; 155 137 gc.weightx = 1.0; 156 138 cbCloseAfterUpload = new JCheckBox(tr("Close changeset after upload")); 157 139 cbCloseAfterUpload.setToolTipText(tr("Select to close the changeset after the next upload")); 158 140 add(cbCloseAfterUpload, gc); 141 142 cbOpenChangesets.addItemListener(this); 143 cbOpenChangesets.addItemListener(closeChangesetAction); 144 159 145 cbCloseAfterUpload.setSelected(Config.getPref().getBoolean("upload.changeset.close", true)); 160 146 cbCloseAfterUpload.addItemListener(new CloseAfterUploadItemStateListener()); 161 147 162 rbUseNew.getModel().addItemListener(new RadioButtonHandler()); 163 rbExisting.getModel().addItemListener(new RadioButtonHandler()); 164 } 165 166 protected void refreshGUI() { 167 rbExisting.setEnabled(model.getSize() > 0); 168 if (model.getSize() == 0 && !rbUseNew.isSelected()) { 169 rbUseNew.setSelected(true); 170 } 171 cbOpenChangesets.setEnabled(model.getSize() > 0 && rbExisting.isSelected()); 148 ChangesetCache.getInstance().addChangesetCacheListener(this); 172 149 } 173 150 174 151 /** 175 152 * Sets the changeset to be used in the next upload 153 * <p> 154 * Note: The changeset may be a new changeset that was automatically opened because the old 155 * changeset overflowed. In that case it was already added to the changeset cache and the 156 * combobox. 176 157 * 177 158 * @param cs the changeset 159 * @see UploadPrimitivesTask#handleChangesetFullResponse 178 160 */ 179 161 public void setSelectedChangesetForNextUpload(Changeset cs) { 180 int idx = model.getIndexOf(cs); 181 if (idx >= 0) { 182 rbExisting.setSelected(true); 183 model.setSelectedItem(cs); 184 } 185 } 186 187 /** 188 * Replies the currently selected changeset. null, if no changeset is 189 * selected or if the user has chosen to use a new changeset. 190 * 191 * @return the currently selected changeset. null, if no changeset is 192 * selected. 162 model.setSelectedItem(cs); 163 } 164 165 /** 166 * Returns the currently selected changeset or an empty new one. 167 * 168 * @return the currently selected changeset 193 169 */ 194 170 public Changeset getSelectedChangeset() { 195 if (rbUseNew.isSelected()) 196 return null; 197 return (Changeset) cbOpenChangesets.getSelectedItem(); 171 return Optional.ofNullable((Changeset) model.getSelectedItem()).orElse(new Changeset()); 198 172 } 199 173 … … 206 180 } 207 181 208 /* ---------------------------------------------------------------------------- */209 /* Interface ListDataListener */210 /* ----------------------------------------------------------------------------*/182 /** 183 * Listens to changes in the selected changeset and fires property change events. 184 */ 211 185 @Override 212 public void contentsChanged(ListDataEvent e) { 213 refreshGUI(); 214 } 215 216 @Override 217 public void intervalAdded(ListDataEvent e) { 218 refreshGUI(); 219 } 220 221 @Override 222 public void intervalRemoved(ListDataEvent e) { 223 refreshGUI(); 224 } 225 226 /** 227 * Listens to changes in the selected changeset and fires property change events. 228 */ 229 class ChangesetListItemStateListener implements ItemListener { 230 @Override 231 public void itemStateChanged(ItemEvent e) { 232 Changeset cs = (Changeset) cbOpenChangesets.getSelectedItem(); 233 if (cs == null) return; 234 if (rbExisting.isSelected()) { 235 firePropertyChange(SELECTED_CHANGESET_PROP, null, cs); 236 } 237 } 186 public void itemStateChanged(ItemEvent e) { 187 firePropertyChange(SELECTED_CHANGESET_PROP, null, model.getSelectedItem()); 238 188 } 239 189 … … 261 211 262 212 /** 263 * Listens to changes in the two radio buttons rbUseNew and rbUseExisting.264 */265 class RadioButtonHandler implements ItemListener {266 @Override267 public void itemStateChanged(ItemEvent e) {268 if (rbUseNew.isSelected()) {269 cbOpenChangesets.setEnabled(false);270 firePropertyChange(SELECTED_CHANGESET_PROP, null, null);271 } else if (rbExisting.isSelected()) {272 cbOpenChangesets.setEnabled(true);273 if (cbOpenChangesets.getSelectedItem() == null) {274 model.selectFirstChangeset();275 }276 Changeset cs = (Changeset) cbOpenChangesets.getSelectedItem();277 if (cs == null) return;278 uploadDialogModel.putAll(cs.getKeys());279 firePropertyChange(SELECTED_CHANGESET_PROP, null, cs);280 }281 }282 }283 284 /**285 213 * Refreshes the list of open changesets 286 214 */ … … 315 243 316 244 protected void refreshEnabledState() { 317 setEnabled( 318 cbOpenChangesets.getModel().getSize() > 0 319 && cbOpenChangesets.getSelectedItem() != null 320 && rbExisting.isSelected() 321 ); 245 setEnabled(!getSelectedChangeset().isNew()); 322 246 } 323 247 … … 327 251 } 328 252 } 253 254 /** 255 * Refreshes the changesets combobox form the server. 256 * <p> 257 * Note: This calls into {@link #refreshCombo} through {@link #changesetCacheUpdated} 258 * 259 * @see ChangesetCache#refreshChangesetsFromServer 260 */ 261 protected void refreshChangesets() { 262 try { 263 ChangesetCache.getInstance().refreshChangesetsFromServer(); 264 } catch (OsmTransferException e) { 265 return; 266 } 267 } 268 269 private void refreshCombo() { 270 Changeset selected = (Changeset) cbOpenChangesets.getSelectedItem(); 271 model.removeAllElements(); 272 model.addElement(new Changeset()); 273 model.addAllElements(ChangesetCache.getInstance().getOpenChangesetsForCurrentUser()); 274 cbOpenChangesets.setSelectedItem(selected != null && model.getIndexOf(selected) != -1 ? selected : model.getElementAt(0)); 275 } 276 277 @Override 278 public void changesetCacheUpdated(ChangesetCacheEvent event) { 279 // This listener might have been called by a background task. 280 SwingUtilities.invokeLater(() -> refreshCombo()); 281 } 329 282 } -
trunk/src/org/openstreetmap/josm/gui/io/UploadDialog.java
r18173 r18283 10 10 import java.awt.Dimension; 11 11 import java.awt.FlowLayout; 12 import java.awt.GridBagConstraints; 12 13 import java.awt.GridBagLayout; 13 14 import java.awt.event.ActionEvent; … … 24 25 import java.util.Map; 25 26 import java.util.Map.Entry; 26 import java.util.Optional;27 27 import java.util.stream.Collectors; 28 28 … … 34 34 import javax.swing.JSplitPane; 35 35 import javax.swing.JTabbedPane; 36 import javax.swing.border.TitledBorder;37 36 38 37 import org.openstreetmap.josm.data.APIDataSet; … … 58 57 import org.openstreetmap.josm.tools.ImageProvider; 59 58 import org.openstreetmap.josm.tools.InputMapUtils; 60 import org.openstreetmap.josm.tools.Logging;61 59 import org.openstreetmap.josm.tools.Utils; 62 60 … … 66 64 * @since 2025 67 65 */ 68 public class UploadDialog extends AbstractUploadDialog implements Pr opertyChangeListener, PreferenceChangedListener {66 public class UploadDialog extends AbstractUploadDialog implements PreferenceChangedListener, PropertyChangeListener { 69 67 /** the unique instance of the upload dialog */ 70 68 private static UploadDialog uploadDialog; … … 72 70 /** the panel with the objects to upload */ 73 71 private UploadedObjectsSummaryPanel pnlUploadedObjects; 72 73 /** the "description" tab */ 74 private BasicUploadSettingsPanel pnlBasicUploadSettings; 75 74 76 /** the panel to select the changeset used */ 75 77 private ChangesetManagementPanel pnlChangesetManagement; 76 77 private BasicUploadSettingsPanel pnlBasicUploadSettings; 78 78 /** the panel to select the upload strategy */ 79 79 private UploadStrategySelectionPanel pnlUploadStrategySelectionPanel; 80 80 81 private TitledBorder tagSettingsBorder;82 /** a border around the tag editor panel */83 private JPanel pnlTagEditorBorder;84 81 /** the tag editor panel */ 85 82 private TagEditorPanel pnlTagEditor; … … 97 94 * Constructs a new {@code UploadDialog}. 98 95 */ 99 p ublicUploadDialog() {96 protected UploadDialog() { 100 97 super(GuiHelper.getFrameForComponent(MainApplication.getMainFrame()), ModalityType.DOCUMENT_MODAL); 101 98 build(); … … 139 136 140 137 JPanel pnlSettings = new JPanel(new GridBagLayout()); 141 pnl TagEditorBorder = new JPanel(new BorderLayout());142 tagSettingsBorder = BorderFactory.createTitledBorder(tr("Tags of new changeset"));143 pnlTagEditorBorder.setBorder( tagSettingsBorder);138 pnlSettings.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); 139 JPanel pnlTagEditorBorder = new JPanel(new BorderLayout()); 140 pnlTagEditorBorder.setBorder(BorderFactory.createTitledBorder(tr("Changeset tags:"))); 144 141 pnlTagEditor = new TagEditorPanel(model, null, Changeset.MAX_CHANGESET_TAG_LENGTH); 145 142 pnlTagEditorBorder.add(pnlTagEditor, BorderLayout.CENTER); 146 143 147 pnlChangesetManagement = new ChangesetManagementPanel( model);144 pnlChangesetManagement = new ChangesetManagementPanel(); 148 145 pnlUploadStrategySelectionPanel = new UploadStrategySelectionPanel(); 149 pnlSettings.add(pnlChangesetManagement, GBC.eop().fill(G BC.HORIZONTAL));150 pnlSettings.add(pnlUploadStrategySelectionPanel, GBC.eop().fill(G BC.HORIZONTAL));151 pnlSettings.add(pnlTagEditorBorder, GBC.eol().fill(G BC.BOTH));146 pnlSettings.add(pnlChangesetManagement, GBC.eop().fill(GridBagConstraints.HORIZONTAL)); 147 pnlSettings.add(pnlUploadStrategySelectionPanel, GBC.eop().fill(GridBagConstraints.HORIZONTAL)); 148 pnlSettings.add(pnlTagEditorBorder, GBC.eol().fill(GridBagConstraints.BOTH)); 152 149 153 150 tpConfigPanels.add(pnlSettings); … … 197 194 addWindowListener(new WindowEventHandler()); 198 195 199 // make sure the configuration panels listen to each other changes196 // make sure the configuration panels listen to each others changes 200 197 // 198 UploadParameterSummaryPanel sp = pnlBasicUploadSettings.getUploadParameterSummaryPanel(); 199 // the summary panel must know everything 200 pnlChangesetManagement.addPropertyChangeListener(sp); 201 pnlUploadedObjects.addPropertyChangeListener(sp); 202 pnlUploadStrategySelectionPanel.addPropertyChangeListener(sp); 203 204 // update tags from selected changeset 201 205 pnlChangesetManagement.addPropertyChangeListener(this); 202 pnlChangesetManagement.addPropertyChangeListener(203 pnlBasicUploadSettings.getUploadParameterSummaryPanel()204 );205 pnlUploadedObjects.addPropertyChangeListener(pnlUploadStrategySelectionPanel);206 pnlUploadedObjects.addPropertyChangeListener(207 pnlBasicUploadSettings.getUploadParameterSummaryPanel()208 );209 pnlUploadStrategySelectionPanel.addPropertyChangeListener(this);210 pnlUploadStrategySelectionPanel.addPropertyChangeListener(211 pnlBasicUploadSettings.getUploadParameterSummaryPanel()212 );213 206 214 207 // users can click on either of two links in the upload parameter … … 242 235 this.dataSet = dataSet; 243 236 pnlBasicUploadSettings.initLifeCycle(map); 237 pnlChangesetManagement.initLifeCycle(); 244 238 model.clear(); 245 model.putAll(map); 246 model.putAll(this.dataSet); 239 model.putAll(map); // init with tags from history 240 model.putAll(this.dataSet); // overwrite with tags from the dataset 241 242 tpConfigPanels.setSelectedIndex(0); 243 pnlTagEditor.initAutoCompletion(MainApplication.getLayerManager().getEditLayer()); 244 pnlUploadStrategySelectionPanel.initFromPreferences(); 245 246 // update the summary 247 UploadParameterSummaryPanel sumPnl = pnlBasicUploadSettings.getUploadParameterSummaryPanel(); 248 sumPnl.setUploadStrategySpecification(pnlUploadStrategySelectionPanel.getUploadStrategySpecification()); 249 sumPnl.setCloseChangesetAfterNextUpload(pnlChangesetManagement.isCloseChangesetAfterUpload()); 247 250 } 248 251 … … 255 258 */ 256 259 public void setUploadedPrimitives(APIDataSet toUpload) { 260 UploadParameterSummaryPanel sumPnl = pnlBasicUploadSettings.getUploadParameterSummaryPanel(); 257 261 if (toUpload == null) { 258 262 if (pnlUploadedObjects != null) { 259 263 List<OsmPrimitive> emptyList = Collections.emptyList(); 260 264 pnlUploadedObjects.setUploadedPrimitives(emptyList, emptyList, emptyList); 265 sumPnl.setNumObjects(0); 261 266 } 262 267 return; 263 268 } 264 pnlBasicUploadSettings.setUploadedPrimitives(toUpload.getPrimitives()); 269 List<OsmPrimitive> l = toUpload.getPrimitives(); 270 pnlBasicUploadSettings.setUploadedPrimitives(l); 265 271 pnlUploadedObjects.setUploadedPrimitives( 266 272 toUpload.getPrimitivesToAdd(), … … 268 274 toUpload.getPrimitivesToDelete() 269 275 ); 276 sumPnl.setNumObjects(l.size()); 277 pnlUploadStrategySelectionPanel.setNumUploadedObjects(l.size()); 270 278 } 271 279 … … 285 293 286 294 /** 287 * Initializes the panel for user input 288 */ 289 public void startUserInput() { 290 tpConfigPanels.setSelectedIndex(0); 291 pnlBasicUploadSettings.startUserInput(); 292 pnlTagEditor.initAutoCompletion(MainApplication.getLayerManager().getEditLayer()); 293 pnlUploadStrategySelectionPanel.initFromPreferences(); 294 UploadParameterSummaryPanel pnl = pnlBasicUploadSettings.getUploadParameterSummaryPanel(); 295 pnl.setUploadStrategySpecification(pnlUploadStrategySelectionPanel.getUploadStrategySpecification()); 296 pnl.setCloseChangesetAfterNextUpload(pnlChangesetManagement.isCloseChangesetAfterUpload()); 297 pnl.setNumObjects(pnlUploadedObjects.getNumObjectsToUpload()); 298 } 299 300 /** 301 * Replies the current changeset 302 * 303 * @return the current changeset 295 * Returns the changeset to use complete with tags 296 * 297 * @return the changeset to use 304 298 */ 305 299 public Changeset getChangeset() { 306 Changeset cs = Optional.ofNullable(pnlChangesetManagement.getSelectedChangeset()).orElseGet(Changeset::new);307 cs.setKeys( model.getTags(false));300 Changeset cs = pnlChangesetManagement.getSelectedChangeset(); 301 cs.setKeys(getTags(true)); 308 302 return cs; 309 303 } … … 337 331 @Override 338 332 public String getUploadComment() { 339 return model.getValue( "comment");333 return model.getValue(UploadDialogModel.COMMENT); 340 334 } 341 335 342 336 @Override 343 337 public String getUploadSource() { 344 return model.getValue( "source");338 return model.getValue(UploadDialogModel.SOURCE); 345 339 } 346 340 … … 355 349 ) 356 350 ).applySafe(this); 357 startUserInput();358 351 } else if (isShowing()) { // Avoid IllegalComponentStateException like in #8775 359 352 new WindowGeometry(this).remember(getClass().getName() + ".geometry"); … … 437 430 public void actionPerformed(ActionEvent e) { 438 431 Map<String, String> tags = dialog.getTags(true); 439 Logging.info("Starting upload with tags {0}", tags); 440 441 /* test for empty tags in the changeset metadata and proceed only after user's confirmation. 442 * though, accept if key and value are empty (cf. xor). */ 432 433 // If there are empty tags in the changeset proceed only after user's confirmation. 443 434 List<String> emptyChangesetTags = new ArrayList<>(); 444 435 for (final Entry<String, String> i : tags.entrySet()) { 445 436 final boolean isKeyEmpty = Utils.isStripEmpty(i.getKey()); 446 437 final boolean isValueEmpty = Utils.isStripEmpty(i.getValue()); 447 final boolean ignoreKey = "comment".equals(i.getKey()) || "source".equals(i.getKey());448 if ((isKeyEmpty ^isValueEmpty) && !ignoreKey) {438 final boolean ignoreKey = UploadDialogModel.isCommentOrSource(i.getKey()); 439 if ((isKeyEmpty || isValueEmpty) && !ignoreKey) { 449 440 emptyChangesetTags.add(tr("{0}={1}", i.getKey(), i.getValue())); 450 441 } … … 528 519 public void propertyChange(PropertyChangeEvent evt) { 529 520 if (evt.getPropertyName().equals(ChangesetManagementPanel.SELECTED_CHANGESET_PROP)) { 521 // put the tags from the newly selected changeset into the model 530 522 Changeset cs = (Changeset) evt.getNewValue(); 531 if (cs == null) { 532 tagSettingsBorder.setTitle(tr("Tags of new changeset")); 533 } else { 534 tagSettingsBorder.setTitle(tr("Tags of changeset {0}", cs.getId())); 523 if (cs != null) { 524 for (Map.Entry<String, String> entry : cs.getKeys().entrySet()) { 525 String key = entry.getKey(); 526 // do NOT overwrite comment and source when selecting a changeset, it is confusing 527 if (!UploadDialogModel.isCommentOrSource(key)) 528 model.put(key, entry.getValue()); 529 } 535 530 } 536 531 } -
trunk/src/org/openstreetmap/josm/gui/io/UploadDialogModel.java
r18205 r18283 24 24 /** the "created_by" changeset OSM key */ 25 25 private static final String CREATED_BY = "created_by"; 26 /** the "comment" changeset OSM key */ 27 public static final String COMMENT = "comment"; 28 /** the "source" changeset OSM key */ 29 public static final String SOURCE = "source"; 26 30 /** the user-agent */ 27 31 private final String agent = Version.getInstance().getAgentString(false); … … 39 43 // add "hashtags" if any 40 44 if (hashtags) { 41 put("hashtags", findHashTags(getValue( "comment")));45 put("hashtags", findHashTags(getValue(COMMENT))); 42 46 } 43 47 // add/update "created_by" … … 116 120 if (!l.isEmpty()) { 117 121 if (value != null) 118 l.get(0).setValue(value); 122 for (TagModel tm : l) { 123 tm.setValue(value); 124 } 119 125 else 120 tags.remove (l.get(0));126 tags.removeIf(tm -> tm.getName().equals(key)); 121 127 } else if (value != null) { 122 128 tags.add(new TagModel(key, value)); … … 163 169 if (dataSet != null) { 164 170 putAll(dataSet.getChangeSetTags()); 165 put( "comment", addHashTagsFromDataSet(getValue("comment"), dataSet));171 put(COMMENT, addHashTagsFromDataSet(getValue(COMMENT), dataSet)); 166 172 } 167 173 } 174 175 /** 176 * Determines if the key is "comment" or "source". 177 * @param key changeset key 178 * @return {@code true} if the key is "comment" or "source" 179 * @since 18283 180 */ 181 public static boolean isCommentOrSource(String key) { 182 return COMMENT.equals(key) || SOURCE.equals(key); 183 } 168 184 } -
trunk/src/org/openstreetmap/josm/gui/io/UploadParameterSummaryPanel.java
r18211 r18283 54 54 return tr("Objects are uploaded to a <strong>new changeset</strong>."); 55 55 } else { 56 return tr("Objects are uploaded to the <strong>open changeset</strong> {0} with upload comment''{1}''.",56 return tr("Objects are uploaded to the <strong>open changeset</strong> {0} ''{1}''.", 57 57 selectedChangeset.getId(), 58 58 selectedChangeset.getComment() … … 200 200 closeChangesetAfterNextUpload = (Boolean) evt.getNewValue(); 201 201 updateSummary(); 202 } else if (evt.getPropertyName().equals(UploadedObjectsSummaryPanel.NUM_OBJECTS_TO_UPLOAD_PROP)) {203 numObjects = (Integer) evt.getNewValue();204 updateSummary();205 202 } else if (evt.getPropertyName().equals(UploadStrategySelectionPanel.UPLOAD_STRATEGY_SPECIFICATION_PROP)) { 206 203 this.spec = (UploadStrategySpecification) evt.getNewValue(); -
trunk/src/org/openstreetmap/josm/gui/io/UploadPrimitivesTask.java
r16807 r18283 83 83 } 84 84 85 protected MaxChangesetSizeExceededPolicy askMaxChangesetSizeExceedsPolicy() { 85 /** 86 * Prompt the user about how to proceed. 87 * 88 * @return the policy selected by the user 89 */ 90 protected MaxChangesetSizeExceededPolicy promptUserForPolicy() { 86 91 ButtonSpec[] specs = { 87 92 new ButtonSpec( … … 146 151 147 152 /** 148 * Opens a new changeset. 149 */ 150 protected void openNewChangeset() { 151 // make sure the current changeset is removed from the upload dialog. 152 ChangesetCache.getInstance().update(changeset); 153 Changeset newChangeSet = new Changeset(); 154 newChangeSet.setKeys(this.changeset.getKeys()); 155 this.changeset = newChangeSet; 156 } 157 158 protected boolean recoverFromChangesetFullException() throws OsmTransferException { 159 if (toUpload.getSize() - processedPrimitives.size() == 0) { 153 * Handles a server changeset full response. 154 * <p> 155 * Handles a server changeset full response by either aborting or opening a new changeset, if the 156 * user requested it so. 157 * 158 * @return true if the upload process should continue with the new changeset, false if the 159 * upload should be interrupted 160 * @throws OsmTransferException "if something goes wrong." 161 */ 162 protected boolean handleChangesetFullResponse() throws OsmTransferException { 163 if (processedPrimitives.size() == toUpload.getSize()) { 160 164 strategy.setPolicy(MaxChangesetSizeExceededPolicy.ABORT); 161 165 return false; 162 166 } 163 167 if (strategy.getPolicy() == null || strategy.getPolicy() == MaxChangesetSizeExceededPolicy.ABORT) { 164 strategy.setPolicy( askMaxChangesetSizeExceedsPolicy());168 strategy.setPolicy(promptUserForPolicy()); 165 169 } 166 170 switch(strategy.getPolicy()) { 167 171 case AUTOMATICALLY_OPEN_NEW_CHANGESETS: 168 // prepare the state of the task for a next iteration in uploading. 169 closeChangesetIfRequired(); 170 openNewChangeset(); 172 Changeset newChangeSet = new Changeset(); 173 newChangeSet.setKeys(changeset.getKeys()); 174 closeChangeset(); 175 this.changeset = newChangeSet; 171 176 toUpload.removeProcessed(processedPrimitives); 172 177 return true; … … 260 265 } 261 266 writer.uploadOsm(strategy, toUpload.getPrimitives(), changeset, getProgressMonitor().createSubTaskMonitor(1, false)); 262 267 // If the changeset was new, now it is open. 268 ChangesetCache.getInstance().update(changeset); 263 269 // if we get here we've successfully uploaded the data. Exit the loop. 264 270 break; … … 277 283 case UPLOAD_DATA: 278 284 // Most likely the changeset is full. Try to recover and continue 279 // with a new changeset, but let the user decide first (see 280 // recoverFromChangesetFullException) 281 if (recoverFromChangesetFullException()) { 285 // with a new changeset, but let the user decide first. 286 if (handleChangesetFullResponse()) { 282 287 continue; 283 288 } 284 289 lastException = e; 285 290 break uploadloop; 291 case UPDATE_CHANGESET: 292 case CLOSE_CHANGESET: 286 293 case UNSPECIFIED: 287 case UPDATE_CHANGESET:288 294 default: 289 295 // The changeset was closed when we tried to update it. Probably, our … … 292 298 // Rethrow exception - this will be handled later. 293 299 changeset.setOpen(false); 300 ChangesetCache.getInstance().update(changeset); 294 301 throw e; 295 302 } … … 320 327 } 321 328 329 /** 330 * Closes the changeset on the server and locally. 331 * 332 * @throws OsmTransferException "if something goes wrong." 333 */ 334 private void closeChangeset() throws OsmTransferException { 335 if (changeset != null && !changeset.isNew() && changeset.isOpen()) { 336 try { 337 OsmApi.getOsmApi().closeChangeset(changeset, progressMonitor.createSubTaskMonitor(0, false)); 338 } catch (ChangesetClosedException e) { 339 // Do not raise a stink, probably the changeset timed out. 340 Logging.trace(e); 341 } finally { 342 changeset.setOpen(false); 343 ChangesetCache.getInstance().update(changeset); 344 } 345 } 346 } 347 322 348 private void closeChangesetIfRequired() throws OsmTransferException { 323 if (strategy.isCloseChangesetAfterUpload() && changeset != null && !changeset.isNew() && changeset.isOpen()) { 324 OsmApi.getOsmApi().closeChangeset(changeset, progressMonitor.createSubTaskMonitor(0, false)); 325 } 326 } 327 328 @Override protected void finish() { 329 330 // depending on the success of the upload operation and on the policy for 331 // multi changeset uploads this will sent the user back to the appropriate 332 // place in JOSM, either 333 // - to an error dialog 334 // - to the Upload Dialog 335 // - to map editing 349 if (strategy.isCloseChangesetAfterUpload()) { 350 closeChangeset(); 351 } 352 } 353 354 /** 355 * Depending on the success of the upload operation and on the policy for 356 * multi changeset uploads this will send the user back to the appropriate 357 * place in JOSM, either: 358 * <ul> 359 * <li>to an error dialog, 360 * <li>to the Upload Dialog, or 361 * <li>to map editing. 362 * </ul> 363 */ 364 @Override 365 protected void finish() { 336 366 GuiHelper.runInEDT(() -> { 337 367 // if the changeset is still open after this upload we want it to be selected on the next upload -
trunk/src/org/openstreetmap/josm/gui/io/UploadStrategySelectionPanel.java
r17709 r18283 11 11 import java.awt.event.ActionEvent; 12 12 import java.awt.event.ActionListener; 13 import java.awt.event.FocusAdapter;14 13 import java.awt.event.FocusEvent; 14 import java.awt.event.FocusListener; 15 15 import java.awt.event.ItemEvent; 16 16 import java.awt.event.ItemListener; 17 import java.beans.PropertyChangeEvent;18 import java.beans.PropertyChangeListener;19 17 import java.util.EnumMap; 20 18 import java.util.Map; … … 45 43 * {@link #UPLOAD_STRATEGY_SPECIFICATION_PROP}. 46 44 */ 47 public class UploadStrategySelectionPanel extends JPanel implements PropertyChangeListener{45 public class UploadStrategySelectionPanel extends JPanel { 48 46 49 47 /** … … 57 55 private final JosmTextField tfChunkSize = new JosmTextField(4); 58 56 private final JPanel pnlMultiChangesetPolicyPanel = new JPanel(new GridBagLayout()); 59 private final JRadioButton rbFillOneChangeset = new JRadioButton( 60 tr("Fill up one changeset and return to the Upload Dialog")); 61 private final JRadioButton rbUseMultipleChangesets = new JRadioButton( 62 tr("Open and use as many new changesets as necessary")); 57 private final JRadioButton rbFillOneChangeset = new JRadioButton(); 58 private final JRadioButton rbUseMultipleChangesets = new JRadioButton(); 63 59 private JMultilineLabel lblMultiChangesetPoliciesHeader; 64 60 … … 92 88 gc.gridwidth = 1; 93 89 gc.fill = GridBagConstraints.HORIZONTAL; 94 gc.insets = new Insets( 0, 0, 3, 0);90 gc.insets = new Insets(3, 3, 3, 3); 95 91 gc.anchor = GridBagConstraints.FIRST_LINE_START; 96 92 JRadioButton radioButton = rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY); 97 radioButton.setText(tr("Upload data in one request")); 98 pnl.add(radioButton, gc); 99 gc.gridx = 3; 100 gc.gridy = 1; 101 gc.weightx = 1.0; 102 gc.weighty = 0.0; 103 gc.gridwidth = 1; 104 pnl.add(lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY), gc); 105 106 // -- chunked dataset strategy 107 gc.gridx = 0; 108 gc.gridy = 2; 109 gc.weightx = 0.0; 110 gc.weighty = 0.0; 111 radioButton = rbStrategy.get(UploadStrategy.CHUNKED_DATASET_STRATEGY); 112 radioButton.setText(tr("Upload data in chunks of objects. Chunk size: ")); 93 radioButton.setText(tr("Upload all objects in one request")); 113 94 pnl.add(radioButton, gc); 114 95 gc.gridx = 2; 115 gc.gridy = 2; 96 gc.weightx = 1.0; 97 pnl.add(lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY), gc); 98 99 // -- chunked dataset strategy 100 gc.gridy++; 101 gc.gridx = 0; 116 102 gc.weightx = 0.0; 117 gc.weighty = 0.0; 118 gc.gridwidth = 1; 103 radioButton = rbStrategy.get(UploadStrategy.CHUNKED_DATASET_STRATEGY); 104 radioButton.setText(tr("Upload objects in chunks of size: ")); 105 pnl.add(radioButton, gc); 106 gc.gridx = 1; 119 107 pnl.add(tfChunkSize, gc); 120 gc.gridx = 3; 121 gc.gridy = 2; 122 gc.weightx = 0.0; 123 gc.weighty = 0.0; 124 gc.gridwidth = 1; 108 gc.gridx = 2; 125 109 pnl.add(lblNumRequests.get(UploadStrategy.CHUNKED_DATASET_STRATEGY), gc); 126 110 127 111 // -- single request strategy 112 gc.gridy++; 128 113 gc.gridx = 0; 129 gc.gridy = 3;130 gc.weightx = 0.0;131 gc.weighty = 0.0;132 114 radioButton = rbStrategy.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY); 133 115 radioButton.setText(tr("Upload each object individually")); 134 116 pnl.add(radioButton, gc); 135 gc.gridx = 3; 136 gc.gridy = 3; 137 gc.weightx = 0.0; 138 gc.weighty = 0.0; 139 gc.gridwidth = 1; 117 gc.gridx = 2; 140 118 pnl.add(lblNumRequests.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY), gc); 141 119 142 tfChunkSize.addFocusListener(new TextFieldFocusHandler());143 120 new ChunkSizeValidator(tfChunkSize); 144 121 … … 159 136 gc.fill = GridBagConstraints.HORIZONTAL; 160 137 gc.anchor = GridBagConstraints.FIRST_LINE_START; 138 gc.insets = new Insets(3, 3, 3, 3); 161 139 gc.weightx = 1.0; 162 140 lblMultiChangesetPoliciesHeader = new JMultilineLabel( 163 tr("<html> There are <strong>multiple changesets</strong> necessary in orderto upload {0} objects. " +164 " Which strategy do you want to use?</html>",141 tr("<html><strong>Multiple changesets</strong> are necessary to upload {0} objects. " + 142 "Please select a strategy:</html>", 165 143 numUploadedObjects)); 166 144 pnlMultiChangesetPolicyPanel.add(lblMultiChangesetPoliciesHeader, gc); 167 gc.gridy = 1; 145 gc.gridy++; 146 rbFillOneChangeset.setText(tr("Fill up one changeset and return to the Upload Dialog")); 168 147 pnlMultiChangesetPolicyPanel.add(rbFillOneChangeset, gc); 169 gc.gridy = 2; 148 gc.gridy++; 149 rbUseMultipleChangesets.setText(tr("Open and use as many new changesets as necessary")); 170 150 pnlMultiChangesetPolicyPanel.add(rbUseMultipleChangesets, gc); 171 151 … … 185 165 gc.weighty = 0.0; 186 166 gc.anchor = GridBagConstraints.NORTHWEST; 187 gc.insets = new Insets(3, 3, 3, 3);188 167 189 168 add(buildUploadStrategyPanel(), gc); 190 169 gc.gridy = 1; 191 170 add(buildMultiChangesetPolicyPanel(), gc); 192 193 // consume remaining space194 gc.gridy = 2;195 gc.fill = GridBagConstraints.BOTH;196 gc.weightx = 1.0;197 gc.weighty = 1.0;198 add(new JPanel(), gc);199 171 200 172 Capabilities capabilities = OsmApi.getOsmApi().getCapabilities(); … … 313 285 rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setEnabled(false); 314 286 JRadioButton lbl = rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY); 315 lbl.set Text(tr("Upload in one request not possible (too many objects to upload)"));287 lbl.setEnabled(false); 316 288 lbl.setToolTipText(tr("<html>Cannot upload {0} objects in one request because the<br>" 317 289 + "max. changeset size {1} on server ''{2}'' is exceeded.</html>", … … 334 306 rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setEnabled(true); 335 307 JRadioButton lbl = rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY); 336 lbl.set Text(tr("Upload data in one request"));308 lbl.setEnabled(true); 337 309 lbl.setToolTipText(null); 338 310 lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setVisible(true); … … 369 341 } 370 342 371 @Override372 public void propertyChange(PropertyChangeEvent evt) {373 if (evt.getPropertyName().equals(UploadedObjectsSummaryPanel.NUM_OBJECTS_TO_UPLOAD_PROP)) {374 setNumUploadedObjects((Integer) evt.getNewValue());375 }376 }377 378 static class TextFieldFocusHandler extends FocusAdapter {379 @Override380 public void focusGained(FocusEvent e) {381 Component c = e.getComponent();382 if (c instanceof JosmTextField) {383 JosmTextField tf = (JosmTextField) c;384 tf.selectAll();385 }386 }387 }388 389 343 class ChunkSizeValidator extends AbstractTextComponentValidator { 390 344 ChunkSizeValidator(JTextComponent tc) { … … 424 378 } 425 379 426 class StrategyChangeListener extends FocusAdapter implementsItemListener, ActionListener {380 class StrategyChangeListener implements FocusListener, ItemListener, ActionListener { 427 381 428 382 protected void notifyStrategy() { … … 447 401 448 402 @Override 403 public void focusGained(FocusEvent e) { 404 Component c = e.getComponent(); 405 if (c instanceof JosmTextField) { 406 JosmTextField tf = (JosmTextField) c; 407 tf.selectAll(); 408 } 409 } 410 411 @Override 449 412 public void focusLost(FocusEvent e) { 450 413 notifyStrategy(); -
trunk/src/org/openstreetmap/josm/gui/io/UploadedObjectsSummaryPanel.java
r13660 r18283 29 29 */ 30 30 public class UploadedObjectsSummaryPanel extends JPanel { 31 /**32 * The swing property name for the number of objects to upload33 */34 public static final String NUM_OBJECTS_TO_UPLOAD_PROP = UploadedObjectsSummaryPanel.class.getName() + ".numObjectsToUpload";35 36 31 /** the list with the added primitives */ 37 32 private PrimitiveList lstAdd; … … 146 141 add(spDelete, gcList); 147 142 } 148 149 firePropertyChange(NUM_OBJECTS_TO_UPLOAD_PROP, 0, getNumObjectsToUpload()); 143 revalidate(); 150 144 } 151 145 -
trunk/src/org/openstreetmap/josm/gui/tagging/TagEditorModel.java
r18173 r18283 31 31 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetType; 32 32 import org.openstreetmap.josm.tools.CheckParameterUtil; 33 import org.openstreetmap.josm.tools.Utils; 33 34 34 35 /** … … 54 55 private transient OsmPrimitive primitive; 55 56 56 private EndEditListener endEditListener;57 private transient EndEditListener endEditListener; 57 58 58 59 /** … … 279 280 */ 280 281 public void deleteTagNames(int... tagIndices) { 281 if (tags == null)282 return;283 282 commitPendingEdit(); 284 283 for (int tagIdx : tagIndices) { … … 298 297 */ 299 298 public void deleteTagValues(int... tagIndices) { 300 if (tags == null)301 return;302 299 commitPendingEdit(); 303 300 for (int tagIdx : tagIndices) { … … 333 330 */ 334 331 public void deleteTags(int... tagIndices) { 335 if (tags == null)336 return;337 332 commitPendingEdit(); 338 333 List<TagModel> toDelete = Arrays.stream(tagIndices).mapToObj(tags::get).filter(Objects::nonNull).collect(Collectors.toList()); … … 442 437 continue; 443 438 } 439 boolean isKeyEmpty = Utils.isStripEmpty(tag.getName()); 440 boolean isValueEmpty = Utils.isStripEmpty(tag.getValue()); 441 442 // just the empty line at the bottom of the JTable 443 if (isKeyEmpty && isValueEmpty) { 444 continue; 445 } 444 446 445 447 // tag name holds an empty key. Don't apply it to the selection. 446 if (!keepEmpty && ( tag.getName().trim().isEmpty() || tag.getValue().trim().isEmpty())) {448 if (!keepEmpty && (isKeyEmpty || isValueEmpty)) { 447 449 continue; 448 450 } 449 result.put( tag.getName().trim(), tag.getValue().trim());451 result.put(Utils.strip(tag.getName()), Utils.strip(tag.getValue())); 450 452 } 451 453 return result; … … 497 499 // tag name holds an empty key. Don't apply it to the selection. 498 500 // 499 if ( tag.getName().trim().isEmpty())501 if (Utils.isStripEmpty(tag.getName())) 500 502 return null; 501 503 … … 529 531 public List<String> getKeys() { 530 532 return tags.stream() 531 .filter(tag -> ! tag.getName().trim().isEmpty())533 .filter(tag -> !Utils.isStripEmpty(tag.getName())) 532 534 .map(TagModel::getName) 533 535 .collect(Collectors.toList()); -
trunk/src/org/openstreetmap/josm/gui/tagging/TagTable.java
r17709 r18283 36 36 import org.openstreetmap.josm.tools.ImageProvider; 37 37 import org.openstreetmap.josm.tools.Logging; 38 import org.openstreetmap.josm.tools.Utils; 38 39 39 40 /** … … 89 90 // we are at the end. Append an empty row and move the focus to its second column 90 91 String key = ((TagModel) model.getValueAt(row, 0)).getName(); 91 if (! key.trim().isEmpty()) {92 if (!Utils.isStripEmpty(key)) { 92 93 model.appendNewTag(); 93 94 col = 0; … … 243 244 } 244 245 final int rowIdx = model.getRowCount()-1; 245 if (rowIdx < 0 || ! ((TagModel) model.getValueAt(rowIdx, 0)).getName().trim().isEmpty()) {246 if (rowIdx < 0 || !Utils.isStripEmpty(((TagModel) model.getValueAt(rowIdx, 0)).getName())) { 246 247 model.appendNewTag(); 247 248 } -
trunk/src/org/openstreetmap/josm/gui/widgets/JosmComboBoxModel.java
r18221 r18283 55 55 * 56 56 * @param element the element to get the index of 57 * @return an int representing the index position, where 0 is the first position 57 * @return the index of the first occurrence of the specified element in this model, 58 * or -1 if this model does not contain the element 58 59 */ 59 60 public int getIndexOf(E element) { … … 61 62 } 62 63 64 protected void doAddElement(E element) { 65 if (element != null && (maxSize == -1 || getSize() < maxSize)) { 66 elements.add(element); 67 } 68 } 69 63 70 // 64 71 // interface java.lang.Iterable … … 79 86 @Override 80 87 public void addElement(E element) { 81 if (element != null && (maxSize == -1 || getSize() < maxSize)) { 82 elements.add(element); 83 } 88 doAddElement(element); 89 fireIntervalAdded(this, elements.size() - 1, elements.size() - 1); 84 90 } 85 91 86 92 @Override 87 93 public void removeElement(Object elem) { 88 elements.remove(elem); 94 int index = elements.indexOf(elem); 95 if (elem == selected) { 96 if (index == 0) { 97 setSelectedItem(getSize() == 1 ? null : getElementAt(index + 1)); 98 } else { 99 setSelectedItem(getElementAt(index - 1)); 100 } 101 } 102 if (elements.remove(elem)) 103 fireIntervalRemoved(this, index, index); 89 104 } 90 105 … … 115 130 } 116 131 elements.add(index, element); 132 fireIntervalAdded(this, index, index); 117 133 } 118 134 … … 167 183 */ 168 184 public void addAllElements(Collection<E> elems) { 169 elems.forEach(e -> addElement(e)); 185 int index0 = elements.size(); 186 elems.forEach(e -> doAddElement(e)); 187 int index1 = elements.size() - 1; 188 if (index0 <= index1) 189 fireIntervalAdded(this, index0, index1); 170 190 } 171 191 … … 178 198 */ 179 199 public void addAllElements(Collection<String> strings, Function<String, E> buildE) { 180 strings.forEach(s -> addElement(buildE.apply(s))); 200 int index0 = elements.size(); 201 strings.forEach(s -> doAddElement(buildE.apply(s))); 202 int index1 = elements.size() - 1; 203 if (index0 <= index1) 204 fireIntervalAdded(this, index0, index1); 181 205 } 182 206 … … 205 229 public void removeAllElements() { 206 230 if (!elements.isEmpty()) { 207 int firstIndex = 0;208 231 int lastIndex = elements.size() - 1; 209 232 elements.clear(); 210 233 selected = null; 211 fireIntervalRemoved(this, firstIndex, lastIndex);234 fireIntervalRemoved(this, 0, lastIndex); 212 235 } else { 213 236 selected = null; -
trunk/src/org/openstreetmap/josm/io/ChangesetClosedException.java
r17840 r18283 31 31 public static final String ERROR_HEADER_PATTERN = "The changeset (\\d+) was closed at (.*)"; 32 32 33 /** 34 * Identifies when the changeset exception occurred. 35 */ 33 36 public enum Source { 34 37 /** … … 43 46 */ 44 47 UPLOAD_DATA, 48 /** 49 * The exception was thrown when we tried to close a changeset. Probably the changeset 50 * already timed out on the server. 51 * @since 18283 52 */ 53 CLOSE_CHANGESET, 45 54 /** 46 55 * Unspecified source … … 163 172 } 164 173 174 /** 175 * Sets the source where the exception was thrown 176 * 177 * @param source the source where the exception was thrown 178 */ 165 179 public void setSource(Source source) { 166 180 this.source = source == null ? Source.UNSPECIFIED : source; -
trunk/src/org/openstreetmap/josm/io/OsmApi.java
r17506 r18283 388 388 } 389 389 } 390 } catch (ChangesetClosedException e) { 391 e.setSource(ChangesetClosedException.Source.UPDATE_CHANGESET); 392 throw e; 390 393 } catch (NumberFormatException e) { 391 394 throw new OsmTransferException(errHandler.apply(ret), e); … … 529 532 // send "\r\n" instead of empty string, so we don't send zero payload - workaround bugs in proxy software 530 533 sendPutRequest("changeset/" + changeset.getId() + "/close", "\r\n", monitor); 534 } catch (ChangesetClosedException e) { 535 e.setSource(ChangesetClosedException.Source.CLOSE_CHANGESET); 536 throw e; 537 } finally { 531 538 changeset.setOpen(false); 532 } finally {533 539 monitor.finishTask(); 534 540 } … … 565 571 throws OsmTransferException { 566 572 try { 573 ensureValidChangeset(); 567 574 monitor.beginTask("", list.size() * 2); 568 if (changeset == null)569 throw new OsmTransferException(tr("No changeset present for diff upload."));570 575 571 576 initialize(monitor); … … 594 599 monitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false) 595 600 ); 596 } catch (OsmTransferException e) { 601 } catch (ChangesetClosedException e) { 602 e.setSource(ChangesetClosedException.Source.UPLOAD_DATA); 597 603 throw e; 598 604 } catch (XmlParsingException e) { … … 752 758 case HttpURLConnection.HTTP_CONFLICT: 753 759 if (ChangesetClosedException.errorHeaderMatchesPattern(errorHeader)) 754 throw new ChangesetClosedException(errorBody, ChangesetClosedException.Source.U PLOAD_DATA);760 throw new ChangesetClosedException(errorBody, ChangesetClosedException.Source.UNSPECIFIED); 755 761 else 756 762 throw new OsmApiException(retCode, errorHeader, errorBody); -
trunk/src/org/openstreetmap/josm/io/UploadStrategySpecification.java
r12687 r18283 151 151 152 152 @Override 153 public String toString() { 154 return String.format("Strategy: %s, ChunkSize: %d, Policy: %s, Close after: %b", 155 strategy.toString(), chunkSize, policy == null ? "none" : policy.toString(), closeChangesetAfterUpload); 156 } 157 158 @Override 153 159 public int hashCode() { 154 160 return Objects.hash(strategy, chunkSize, policy, closeChangesetAfterUpload);
Note:
See TracChangeset
for help on using the changeset viewer.