[2711] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
| 2 | package org.openstreetmap.josm.gui.io;
|
---|
[6901] | 3 |
|
---|
[2711] | 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 5 | import static org.openstreetmap.josm.tools.I18n.trn;
|
---|
| 6 |
|
---|
| 7 | import java.awt.Color;
|
---|
| 8 | import java.awt.Component;
|
---|
| 9 | import java.awt.GridBagConstraints;
|
---|
| 10 | import java.awt.GridBagLayout;
|
---|
| 11 | import java.awt.Insets;
|
---|
| 12 | import java.awt.event.ActionEvent;
|
---|
| 13 | import java.awt.event.ActionListener;
|
---|
[10173] | 14 | import java.awt.event.FocusAdapter;
|
---|
[2711] | 15 | import java.awt.event.FocusEvent;
|
---|
| 16 | import java.awt.event.ItemEvent;
|
---|
| 17 | import java.awt.event.ItemListener;
|
---|
| 18 | import java.beans.PropertyChangeEvent;
|
---|
| 19 | import java.beans.PropertyChangeListener;
|
---|
[8388] | 20 | import java.util.EnumMap;
|
---|
[2711] | 21 | import java.util.Map;
|
---|
[8332] | 22 | import java.util.Map.Entry;
|
---|
[2711] | 23 |
|
---|
| 24 | import javax.swing.BorderFactory;
|
---|
| 25 | import javax.swing.ButtonGroup;
|
---|
| 26 | import javax.swing.JLabel;
|
---|
| 27 | import javax.swing.JPanel;
|
---|
| 28 | import javax.swing.JRadioButton;
|
---|
| 29 | import javax.swing.UIManager;
|
---|
| 30 | import javax.swing.event.DocumentEvent;
|
---|
| 31 | import javax.swing.event.DocumentListener;
|
---|
| 32 |
|
---|
| 33 | import org.openstreetmap.josm.Main;
|
---|
[6340] | 34 | import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
|
---|
[5886] | 35 | import org.openstreetmap.josm.gui.widgets.JosmTextField;
|
---|
[9575] | 36 | import org.openstreetmap.josm.io.Capabilities;
|
---|
[12687] | 37 | import org.openstreetmap.josm.io.MaxChangesetSizeExceededPolicy;
|
---|
[6901] | 38 | import org.openstreetmap.josm.io.OsmApi;
|
---|
[12687] | 39 | import org.openstreetmap.josm.io.UploadStrategy;
|
---|
| 40 | import org.openstreetmap.josm.io.UploadStrategySpecification;
|
---|
[12620] | 41 | import org.openstreetmap.josm.tools.Logging;
|
---|
[2711] | 42 |
|
---|
| 43 | /**
|
---|
| 44 | * UploadStrategySelectionPanel is a panel for selecting an upload strategy.
|
---|
[2801] | 45 | *
|
---|
[2711] | 46 | * Clients can listen for property change events for the property
|
---|
[5266] | 47 | * {@link #UPLOAD_STRATEGY_SPECIFICATION_PROP}.
|
---|
[2711] | 48 | */
|
---|
| 49 | public class UploadStrategySelectionPanel extends JPanel implements PropertyChangeListener {
|
---|
| 50 |
|
---|
| 51 | /**
|
---|
| 52 | * The property for the upload strategy
|
---|
| 53 | */
|
---|
[6889] | 54 | public static final String UPLOAD_STRATEGY_SPECIFICATION_PROP =
|
---|
[2711] | 55 | UploadStrategySelectionPanel.class.getName() + ".uploadStrategySpecification";
|
---|
| 56 |
|
---|
[8510] | 57 | private static final Color BG_COLOR_ERROR = new Color(255, 224, 224);
|
---|
[2711] | 58 |
|
---|
[8308] | 59 | private transient Map<UploadStrategy, JRadioButton> rbStrategy;
|
---|
| 60 | private transient Map<UploadStrategy, JLabel> lblNumRequests;
|
---|
| 61 | private transient Map<UploadStrategy, JMultilineLabel> lblStrategies;
|
---|
[10179] | 62 | private final JosmTextField tfChunkSize = new JosmTextField(4);
|
---|
| 63 | private final JPanel pnlMultiChangesetPolicyPanel = new JPanel(new GridBagLayout());
|
---|
| 64 | private final JRadioButton rbFillOneChangeset = new JRadioButton(
|
---|
| 65 | tr("Fill up one changeset and return to the Upload Dialog"));
|
---|
| 66 | private final JRadioButton rbUseMultipleChangesets = new JRadioButton(
|
---|
| 67 | tr("Open and use as many new changesets as necessary"));
|
---|
[2711] | 68 | private JMultilineLabel lblMultiChangesetPoliciesHeader;
|
---|
| 69 |
|
---|
[8840] | 70 | private long numUploadedObjects;
|
---|
[2711] | 71 |
|
---|
[6267] | 72 | /**
|
---|
| 73 | * Constructs a new {@code UploadStrategySelectionPanel}.
|
---|
| 74 | */
|
---|
[2711] | 75 | public UploadStrategySelectionPanel() {
|
---|
| 76 | build();
|
---|
| 77 | }
|
---|
| 78 |
|
---|
| 79 | protected JPanel buildUploadStrategyPanel() {
|
---|
[9543] | 80 | JPanel pnl = new JPanel(new GridBagLayout());
|
---|
[6267] | 81 | ButtonGroup bgStrategies = new ButtonGroup();
|
---|
[8388] | 82 | rbStrategy = new EnumMap<>(UploadStrategy.class);
|
---|
| 83 | lblStrategies = new EnumMap<>(UploadStrategy.class);
|
---|
| 84 | lblNumRequests = new EnumMap<>(UploadStrategy.class);
|
---|
[2711] | 85 | for (UploadStrategy strategy: UploadStrategy.values()) {
|
---|
| 86 | rbStrategy.put(strategy, new JRadioButton());
|
---|
| 87 | lblNumRequests.put(strategy, new JLabel());
|
---|
| 88 | lblStrategies.put(strategy, new JMultilineLabel(""));
|
---|
| 89 | bgStrategies.add(rbStrategy.get(strategy));
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 | // -- headline
|
---|
| 93 | GridBagConstraints gc = new GridBagConstraints();
|
---|
| 94 | gc.gridx = 0;
|
---|
| 95 | gc.gridy = 0;
|
---|
| 96 | gc.weightx = 1.0;
|
---|
| 97 | gc.weighty = 0.0;
|
---|
| 98 | gc.gridwidth = 4;
|
---|
| 99 | gc.fill = GridBagConstraints.HORIZONTAL;
|
---|
[8510] | 100 | gc.insets = new Insets(0, 0, 3, 0);
|
---|
[2711] | 101 | gc.anchor = GridBagConstraints.FIRST_LINE_START;
|
---|
| 102 | pnl.add(new JMultilineLabel(tr("Please select the upload strategy:")), gc);
|
---|
| 103 |
|
---|
| 104 | // -- single request strategy
|
---|
| 105 | gc.gridx = 0;
|
---|
| 106 | gc.gridy = 1;
|
---|
| 107 | gc.weightx = 0.0;
|
---|
| 108 | gc.weighty = 0.0;
|
---|
| 109 | gc.gridwidth = 1;
|
---|
| 110 | gc.anchor = GridBagConstraints.FIRST_LINE_START;
|
---|
| 111 | pnl.add(rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY), gc);
|
---|
| 112 | gc.gridx = 1;
|
---|
| 113 | gc.gridy = 1;
|
---|
[7375] | 114 | gc.weightx = 1.0;
|
---|
[2711] | 115 | gc.weighty = 0.0;
|
---|
| 116 | gc.gridwidth = 2;
|
---|
[6901] | 117 | JMultilineLabel lbl = lblStrategies.get(UploadStrategy.SINGLE_REQUEST_STRATEGY);
|
---|
[2711] | 118 | lbl.setText(tr("Upload data in one request"));
|
---|
| 119 | pnl.add(lbl, gc);
|
---|
| 120 | gc.gridx = 3;
|
---|
| 121 | gc.gridy = 1;
|
---|
[7375] | 122 | gc.weightx = 0.0;
|
---|
[2711] | 123 | gc.weighty = 0.0;
|
---|
| 124 | gc.gridwidth = 1;
|
---|
| 125 | pnl.add(lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY), gc);
|
---|
| 126 |
|
---|
| 127 | // -- chunked dataset strategy
|
---|
| 128 | gc.gridx = 0;
|
---|
| 129 | gc.gridy = 2;
|
---|
| 130 | gc.weightx = 0.0;
|
---|
| 131 | gc.weighty = 0.0;
|
---|
| 132 | pnl.add(rbStrategy.get(UploadStrategy.CHUNKED_DATASET_STRATEGY), gc);
|
---|
| 133 | gc.gridx = 1;
|
---|
| 134 | gc.gridy = 2;
|
---|
[7375] | 135 | gc.weightx = 1.0;
|
---|
[2711] | 136 | gc.weighty = 0.0;
|
---|
| 137 | gc.gridwidth = 1;
|
---|
| 138 | lbl = lblStrategies.get(UploadStrategy.CHUNKED_DATASET_STRATEGY);
|
---|
| 139 | lbl.setText(tr("Upload data in chunks of objects. Chunk size: "));
|
---|
| 140 | pnl.add(lbl, gc);
|
---|
| 141 | gc.gridx = 2;
|
---|
| 142 | gc.gridy = 2;
|
---|
| 143 | gc.weightx = 0.0;
|
---|
| 144 | gc.weighty = 0.0;
|
---|
| 145 | gc.gridwidth = 1;
|
---|
[10179] | 146 | pnl.add(tfChunkSize, gc);
|
---|
[2711] | 147 | gc.gridx = 3;
|
---|
| 148 | gc.gridy = 2;
|
---|
[7375] | 149 | gc.weightx = 0.0;
|
---|
[2711] | 150 | gc.weighty = 0.0;
|
---|
| 151 | gc.gridwidth = 1;
|
---|
| 152 | pnl.add(lblNumRequests.get(UploadStrategy.CHUNKED_DATASET_STRATEGY), gc);
|
---|
| 153 |
|
---|
| 154 | // -- single request strategy
|
---|
| 155 | gc.gridx = 0;
|
---|
| 156 | gc.gridy = 3;
|
---|
| 157 | gc.weightx = 0.0;
|
---|
| 158 | gc.weighty = 0.0;
|
---|
| 159 | pnl.add(rbStrategy.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY), gc);
|
---|
| 160 | gc.gridx = 1;
|
---|
| 161 | gc.gridy = 3;
|
---|
[7375] | 162 | gc.weightx = 1.0;
|
---|
[2711] | 163 | gc.weighty = 0.0;
|
---|
| 164 | gc.gridwidth = 2;
|
---|
| 165 | lbl = lblStrategies.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY);
|
---|
| 166 | lbl.setText(tr("Upload each object individually"));
|
---|
| 167 | pnl.add(lbl, gc);
|
---|
| 168 | gc.gridx = 3;
|
---|
| 169 | gc.gridy = 3;
|
---|
[7375] | 170 | gc.weightx = 0.0;
|
---|
[2711] | 171 | gc.weighty = 0.0;
|
---|
| 172 | gc.gridwidth = 1;
|
---|
| 173 | pnl.add(lblNumRequests.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY), gc);
|
---|
| 174 |
|
---|
| 175 | tfChunkSize.addFocusListener(new TextFieldFocusHandler());
|
---|
| 176 | tfChunkSize.getDocument().addDocumentListener(new ChunkSizeInputVerifier());
|
---|
| 177 |
|
---|
| 178 | StrategyChangeListener strategyChangeListener = new StrategyChangeListener();
|
---|
| 179 | tfChunkSize.addFocusListener(strategyChangeListener);
|
---|
| 180 | tfChunkSize.addActionListener(strategyChangeListener);
|
---|
[8510] | 181 | for (UploadStrategy strategy: UploadStrategy.values()) {
|
---|
[2711] | 182 | rbStrategy.get(strategy).addItemListener(strategyChangeListener);
|
---|
| 183 | }
|
---|
| 184 |
|
---|
| 185 | return pnl;
|
---|
| 186 | }
|
---|
| 187 |
|
---|
| 188 | protected JPanel buildMultiChangesetPolicyPanel() {
|
---|
| 189 | GridBagConstraints gc = new GridBagConstraints();
|
---|
| 190 | gc.gridx = 0;
|
---|
| 191 | gc.gridy = 0;
|
---|
| 192 | gc.fill = GridBagConstraints.HORIZONTAL;
|
---|
| 193 | gc.anchor = GridBagConstraints.FIRST_LINE_START;
|
---|
| 194 | gc.weightx = 1.0;
|
---|
[10179] | 195 | lblMultiChangesetPoliciesHeader = new JMultilineLabel(
|
---|
[8510] | 196 | tr("<html>There are <strong>multiple changesets</strong> necessary in order to upload {0} objects. " +
|
---|
| 197 | "Which strategy do you want to use?</html>",
|
---|
[10179] | 198 | numUploadedObjects));
|
---|
| 199 | pnlMultiChangesetPolicyPanel.add(lblMultiChangesetPoliciesHeader, gc);
|
---|
[2711] | 200 | gc.gridy = 1;
|
---|
[10179] | 201 | pnlMultiChangesetPolicyPanel.add(rbFillOneChangeset, gc);
|
---|
[2711] | 202 | gc.gridy = 2;
|
---|
[10179] | 203 | pnlMultiChangesetPolicyPanel.add(rbUseMultipleChangesets, gc);
|
---|
[2711] | 204 |
|
---|
[6267] | 205 | ButtonGroup bgMultiChangesetPolicies = new ButtonGroup();
|
---|
[2711] | 206 | bgMultiChangesetPolicies.add(rbFillOneChangeset);
|
---|
| 207 | bgMultiChangesetPolicies.add(rbUseMultipleChangesets);
|
---|
| 208 | return pnlMultiChangesetPolicyPanel;
|
---|
| 209 | }
|
---|
| 210 |
|
---|
| 211 | protected void build() {
|
---|
| 212 | setLayout(new GridBagLayout());
|
---|
| 213 | GridBagConstraints gc = new GridBagConstraints();
|
---|
| 214 | gc.gridx = 0;
|
---|
| 215 | gc.gridy = 0;
|
---|
| 216 | gc.fill = GridBagConstraints.HORIZONTAL;
|
---|
| 217 | gc.weightx = 1.0;
|
---|
| 218 | gc.weighty = 0.0;
|
---|
| 219 | gc.anchor = GridBagConstraints.NORTHWEST;
|
---|
[8510] | 220 | gc.insets = new Insets(3, 3, 3, 3);
|
---|
[2711] | 221 |
|
---|
| 222 | add(buildUploadStrategyPanel(), gc);
|
---|
| 223 | gc.gridy = 1;
|
---|
| 224 | add(buildMultiChangesetPolicyPanel(), gc);
|
---|
| 225 |
|
---|
| 226 | // consume remaining space
|
---|
| 227 | gc.gridy = 2;
|
---|
| 228 | gc.fill = GridBagConstraints.BOTH;
|
---|
| 229 | gc.weightx = 1.0;
|
---|
| 230 | gc.weighty = 1.0;
|
---|
| 231 | add(new JPanel(), gc);
|
---|
| 232 |
|
---|
[9575] | 233 | Capabilities capabilities = OsmApi.getOsmApi().getCapabilities();
|
---|
| 234 | int maxChunkSize = capabilities != null ? capabilities.getMaxChangesetSize() : -1;
|
---|
[2711] | 235 | pnlMultiChangesetPolicyPanel.setVisible(
|
---|
| 236 | maxChunkSize > 0 && numUploadedObjects > maxChunkSize
|
---|
| 237 | );
|
---|
| 238 | }
|
---|
| 239 |
|
---|
[12370] | 240 | /**
|
---|
| 241 | * Sets the number of uploaded objects to display
|
---|
| 242 | * @param numUploadedObjects The number of objects
|
---|
| 243 | */
|
---|
[2711] | 244 | public void setNumUploadedObjects(int numUploadedObjects) {
|
---|
[8510] | 245 | this.numUploadedObjects = Math.max(numUploadedObjects, 0);
|
---|
[2711] | 246 | updateNumRequestsLabels();
|
---|
| 247 | }
|
---|
| 248 |
|
---|
[12370] | 249 | /**
|
---|
| 250 | * Fills the inputs using a {@link UploadStrategySpecification}
|
---|
| 251 | * @param strategy The strategy
|
---|
| 252 | */
|
---|
[2711] | 253 | public void setUploadStrategySpecification(UploadStrategySpecification strategy) {
|
---|
[9841] | 254 | if (strategy == null)
|
---|
| 255 | return;
|
---|
[2711] | 256 | rbStrategy.get(strategy.getStrategy()).setSelected(true);
|
---|
| 257 | tfChunkSize.setEnabled(strategy.getStrategy() == UploadStrategy.CHUNKED_DATASET_STRATEGY);
|
---|
| 258 | if (strategy.getStrategy().equals(UploadStrategy.CHUNKED_DATASET_STRATEGY)) {
|
---|
| 259 | if (strategy.getChunkSize() != UploadStrategySpecification.UNSPECIFIED_CHUNK_SIZE) {
|
---|
| 260 | tfChunkSize.setText(Integer.toString(strategy.getChunkSize()));
|
---|
| 261 | } else {
|
---|
| 262 | tfChunkSize.setText("1");
|
---|
| 263 | }
|
---|
| 264 | }
|
---|
| 265 | }
|
---|
| 266 |
|
---|
[12370] | 267 | /**
|
---|
| 268 | * Gets the upload strategy the user chose
|
---|
| 269 | * @return The strategy
|
---|
| 270 | */
|
---|
[2711] | 271 | public UploadStrategySpecification getUploadStrategySpecification() {
|
---|
| 272 | UploadStrategy strategy = getUploadStrategy();
|
---|
| 273 | UploadStrategySpecification spec = new UploadStrategySpecification();
|
---|
[9841] | 274 | if (strategy != null) {
|
---|
| 275 | switch(strategy) {
|
---|
[10217] | 276 | case CHUNKED_DATASET_STRATEGY:
|
---|
| 277 | spec.setStrategy(strategy).setChunkSize(getChunkSize());
|
---|
| 278 | break;
|
---|
[9841] | 279 | case INDIVIDUAL_OBJECTS_STRATEGY:
|
---|
| 280 | case SINGLE_REQUEST_STRATEGY:
|
---|
[10217] | 281 | default:
|
---|
[9841] | 282 | spec.setStrategy(strategy);
|
---|
| 283 | break;
|
---|
| 284 | }
|
---|
[2711] | 285 | }
|
---|
[8510] | 286 | if (pnlMultiChangesetPolicyPanel.isVisible()) {
|
---|
[2711] | 287 | if (rbFillOneChangeset.isSelected()) {
|
---|
| 288 | spec.setPolicy(MaxChangesetSizeExceededPolicy.FILL_ONE_CHANGESET_AND_RETURN_TO_UPLOAD_DIALOG);
|
---|
| 289 | } else if (rbUseMultipleChangesets.isSelected()) {
|
---|
| 290 | spec.setPolicy(MaxChangesetSizeExceededPolicy.AUTOMATICALLY_OPEN_NEW_CHANGESETS);
|
---|
| 291 | } else {
|
---|
| 292 | spec.setPolicy(null); // unknown policy
|
---|
| 293 | }
|
---|
| 294 | } else {
|
---|
| 295 | spec.setPolicy(null);
|
---|
| 296 | }
|
---|
| 297 | return spec;
|
---|
| 298 | }
|
---|
| 299 |
|
---|
| 300 | protected UploadStrategy getUploadStrategy() {
|
---|
| 301 | UploadStrategy strategy = null;
|
---|
[8332] | 302 | for (Entry<UploadStrategy, JRadioButton> e : rbStrategy.entrySet()) {
|
---|
| 303 | if (e.getValue().isSelected()) {
|
---|
| 304 | strategy = e.getKey();
|
---|
[2711] | 305 | break;
|
---|
| 306 | }
|
---|
| 307 | }
|
---|
| 308 | return strategy;
|
---|
| 309 | }
|
---|
| 310 |
|
---|
| 311 | protected int getChunkSize() {
|
---|
| 312 | try {
|
---|
[8375] | 313 | return Integer.parseInt(tfChunkSize.getText().trim());
|
---|
[8510] | 314 | } catch (NumberFormatException e) {
|
---|
[2711] | 315 | return UploadStrategySpecification.UNSPECIFIED_CHUNK_SIZE;
|
---|
| 316 | }
|
---|
| 317 | }
|
---|
| 318 |
|
---|
[12370] | 319 | /**
|
---|
| 320 | * Load the panel contents from preferences
|
---|
| 321 | */
|
---|
[2711] | 322 | public void initFromPreferences() {
|
---|
| 323 | UploadStrategy strategy = UploadStrategy.getFromPreferences();
|
---|
| 324 | rbStrategy.get(strategy).setSelected(true);
|
---|
[12841] | 325 | int chunkSize = Main.pref.getInt("osm-server.upload-strategy.chunk-size", 1);
|
---|
[2711] | 326 | tfChunkSize.setText(Integer.toString(chunkSize));
|
---|
| 327 | updateNumRequestsLabels();
|
---|
| 328 | }
|
---|
| 329 |
|
---|
[12370] | 330 | /**
|
---|
| 331 | * Stores the values that the user has input into the preferences
|
---|
| 332 | */
|
---|
[2711] | 333 | public void rememberUserInput() {
|
---|
| 334 | UploadStrategy strategy = getUploadStrategy();
|
---|
| 335 | UploadStrategy.saveToPreferences(strategy);
|
---|
| 336 | int chunkSize;
|
---|
| 337 | try {
|
---|
| 338 | chunkSize = Integer.parseInt(tfChunkSize.getText().trim());
|
---|
[12841] | 339 | Main.pref.putInt("osm-server.upload-strategy.chunk-size", chunkSize);
|
---|
[8510] | 340 | } catch (NumberFormatException e) {
|
---|
[2711] | 341 | // don't save invalid value to preferences
|
---|
[12620] | 342 | Logging.trace(e);
|
---|
[2711] | 343 | }
|
---|
| 344 | }
|
---|
| 345 |
|
---|
| 346 | protected void updateNumRequestsLabels() {
|
---|
[2915] | 347 | int maxChunkSize = OsmApi.getOsmApi().getCapabilities().getMaxChangesetSize();
|
---|
[2711] | 348 | if (maxChunkSize > 0 && numUploadedObjects > maxChunkSize) {
|
---|
| 349 | rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setEnabled(false);
|
---|
[6901] | 350 | JMultilineLabel lbl = lblStrategies.get(UploadStrategy.SINGLE_REQUEST_STRATEGY);
|
---|
[2711] | 351 | lbl.setText(tr("Upload in one request not possible (too many objects to upload)"));
|
---|
[2848] | 352 | lbl.setToolTipText(tr("<html>Cannot upload {0} objects in one request because the<br>"
|
---|
[2711] | 353 | + "max. changeset size {1} on server ''{2}'' is exceeded.</html>",
|
---|
[8510] | 354 | numUploadedObjects, maxChunkSize, OsmApi.getOsmApi().getBaseUrl()
|
---|
[2711] | 355 | )
|
---|
| 356 | );
|
---|
| 357 | rbStrategy.get(UploadStrategy.CHUNKED_DATASET_STRATEGY).setSelected(true);
|
---|
| 358 | lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setVisible(false);
|
---|
| 359 |
|
---|
[8509] | 360 | lblMultiChangesetPoliciesHeader.setText(
|
---|
[8510] | 361 | tr("<html>There are <strong>multiple changesets</strong> necessary in order to upload {0} objects. " +
|
---|
| 362 | "Which strategy do you want to use?</html>",
|
---|
[8509] | 363 | numUploadedObjects));
|
---|
[8444] | 364 | if (!rbFillOneChangeset.isSelected() && !rbUseMultipleChangesets.isSelected()) {
|
---|
[2711] | 365 | rbUseMultipleChangesets.setSelected(true);
|
---|
| 366 | }
|
---|
| 367 | pnlMultiChangesetPolicyPanel.setVisible(true);
|
---|
| 368 |
|
---|
| 369 | } else {
|
---|
| 370 | rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setEnabled(true);
|
---|
[6901] | 371 | JMultilineLabel lbl = lblStrategies.get(UploadStrategy.SINGLE_REQUEST_STRATEGY);
|
---|
[2711] | 372 | lbl.setText(tr("Upload data in one request"));
|
---|
[7712] | 373 | lbl.setToolTipText(null);
|
---|
[2711] | 374 | lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setVisible(true);
|
---|
| 375 |
|
---|
| 376 | pnlMultiChangesetPolicyPanel.setVisible(false);
|
---|
| 377 | }
|
---|
| 378 |
|
---|
| 379 | lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setText(tr("(1 request)"));
|
---|
| 380 | if (numUploadedObjects == 0) {
|
---|
| 381 | lblNumRequests.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY).setText(tr("(# requests unknown)"));
|
---|
| 382 | lblNumRequests.get(UploadStrategy.CHUNKED_DATASET_STRATEGY).setText(tr("(# requests unknown)"));
|
---|
| 383 | } else {
|
---|
| 384 | lblNumRequests.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY).setText(
|
---|
| 385 | trn("({0} request)", "({0} requests)", numUploadedObjects, numUploadedObjects)
|
---|
| 386 | );
|
---|
| 387 | lblNumRequests.get(UploadStrategy.CHUNKED_DATASET_STRATEGY).setText(tr("(# requests unknown)"));
|
---|
| 388 | int chunkSize = getChunkSize();
|
---|
| 389 | if (chunkSize == UploadStrategySpecification.UNSPECIFIED_CHUNK_SIZE) {
|
---|
| 390 | lblNumRequests.get(UploadStrategy.CHUNKED_DATASET_STRATEGY).setText(tr("(# requests unknown)"));
|
---|
| 391 | } else {
|
---|
[8510] | 392 | int chunks = (int) Math.ceil((double) numUploadedObjects / (double) chunkSize);
|
---|
[2711] | 393 | lblNumRequests.get(UploadStrategy.CHUNKED_DATASET_STRATEGY).setText(
|
---|
| 394 | trn("({0} request)", "({0} requests)", chunks, chunks)
|
---|
| 395 | );
|
---|
| 396 | }
|
---|
| 397 | }
|
---|
| 398 | }
|
---|
| 399 |
|
---|
[12370] | 400 | /**
|
---|
| 401 | * Sets the focus on the chunk size field
|
---|
| 402 | */
|
---|
[2711] | 403 | public void initEditingOfChunkSize() {
|
---|
| 404 | tfChunkSize.requestFocusInWindow();
|
---|
| 405 | }
|
---|
| 406 |
|
---|
[6084] | 407 | @Override
|
---|
[2711] | 408 | public void propertyChange(PropertyChangeEvent evt) {
|
---|
| 409 | if (evt.getPropertyName().equals(UploadedObjectsSummaryPanel.NUM_OBJECTS_TO_UPLOAD_PROP)) {
|
---|
[8510] | 410 | setNumUploadedObjects((Integer) evt.getNewValue());
|
---|
[2711] | 411 | }
|
---|
| 412 | }
|
---|
| 413 |
|
---|
[10173] | 414 | static class TextFieldFocusHandler extends FocusAdapter {
|
---|
[6084] | 415 | @Override
|
---|
[2711] | 416 | public void focusGained(FocusEvent e) {
|
---|
| 417 | Component c = e.getComponent();
|
---|
[5886] | 418 | if (c instanceof JosmTextField) {
|
---|
[8510] | 419 | JosmTextField tf = (JosmTextField) c;
|
---|
[2711] | 420 | tf.selectAll();
|
---|
| 421 | }
|
---|
| 422 | }
|
---|
| 423 | }
|
---|
| 424 |
|
---|
| 425 | class ChunkSizeInputVerifier implements DocumentListener, PropertyChangeListener {
|
---|
[5886] | 426 | protected void setErrorFeedback(JosmTextField tf, String message) {
|
---|
[2711] | 427 | tf.setBorder(BorderFactory.createLineBorder(Color.RED, 1));
|
---|
| 428 | tf.setToolTipText(message);
|
---|
| 429 | tf.setBackground(BG_COLOR_ERROR);
|
---|
| 430 | }
|
---|
| 431 |
|
---|
[5886] | 432 | protected void clearErrorFeedback(JosmTextField tf, String message) {
|
---|
[2711] | 433 | tf.setBorder(UIManager.getBorder("TextField.border"));
|
---|
| 434 | tf.setToolTipText(message);
|
---|
| 435 | tf.setBackground(UIManager.getColor("TextField.background"));
|
---|
| 436 | }
|
---|
| 437 |
|
---|
[6990] | 438 | protected void validateChunkSize() {
|
---|
[2711] | 439 | try {
|
---|
| 440 | int chunkSize = Integer.parseInt(tfChunkSize.getText().trim());
|
---|
[2915] | 441 | int maxChunkSize = OsmApi.getOsmApi().getCapabilities().getMaxChangesetSize();
|
---|
[2711] | 442 | if (chunkSize <= 0) {
|
---|
| 443 | setErrorFeedback(tfChunkSize, tr("Illegal chunk size <= 0. Please enter an integer > 1"));
|
---|
| 444 | } else if (maxChunkSize > 0 && chunkSize > maxChunkSize) {
|
---|
[8509] | 445 | setErrorFeedback(tfChunkSize, tr("Chunk size {0} exceeds max. changeset size {1} for server ''{2}''",
|
---|
| 446 | chunkSize, maxChunkSize, OsmApi.getOsmApi().getBaseUrl()));
|
---|
[2711] | 447 | } else {
|
---|
| 448 | clearErrorFeedback(tfChunkSize, tr("Please enter an integer > 1"));
|
---|
| 449 | }
|
---|
| 450 |
|
---|
| 451 | if (maxChunkSize > 0 && chunkSize > maxChunkSize) {
|
---|
[8509] | 452 | setErrorFeedback(tfChunkSize, tr("Chunk size {0} exceeds max. changeset size {1} for server ''{2}''",
|
---|
| 453 | chunkSize, maxChunkSize, OsmApi.getOsmApi().getBaseUrl()));
|
---|
[2711] | 454 | }
|
---|
[8510] | 455 | } catch (NumberFormatException e) {
|
---|
[8509] | 456 | setErrorFeedback(tfChunkSize, tr("Value ''{0}'' is not a number. Please enter an integer > 1",
|
---|
| 457 | tfChunkSize.getText().trim()));
|
---|
[2711] | 458 | } finally {
|
---|
| 459 | updateNumRequestsLabels();
|
---|
| 460 | }
|
---|
| 461 | }
|
---|
| 462 |
|
---|
[6084] | 463 | @Override
|
---|
[2711] | 464 | public void changedUpdate(DocumentEvent arg0) {
|
---|
[6990] | 465 | validateChunkSize();
|
---|
[2711] | 466 | }
|
---|
| 467 |
|
---|
[6084] | 468 | @Override
|
---|
[2711] | 469 | public void insertUpdate(DocumentEvent arg0) {
|
---|
[6990] | 470 | validateChunkSize();
|
---|
[2711] | 471 | }
|
---|
| 472 |
|
---|
[6084] | 473 | @Override
|
---|
[2711] | 474 | public void removeUpdate(DocumentEvent arg0) {
|
---|
[6990] | 475 | validateChunkSize();
|
---|
[2711] | 476 | }
|
---|
| 477 |
|
---|
[6084] | 478 | @Override
|
---|
[2711] | 479 | public void propertyChange(PropertyChangeEvent evt) {
|
---|
| 480 | if (evt.getSource() == tfChunkSize
|
---|
[6990] | 481 | && "enabled".equals(evt.getPropertyName())
|
---|
[8510] | 482 | && (Boolean) evt.getNewValue()
|
---|
[2711] | 483 | ) {
|
---|
[6990] | 484 | validateChunkSize();
|
---|
[2711] | 485 | }
|
---|
| 486 | }
|
---|
| 487 | }
|
---|
| 488 |
|
---|
[10173] | 489 | class StrategyChangeListener extends FocusAdapter implements ItemListener, ActionListener {
|
---|
[2711] | 490 |
|
---|
| 491 | protected void notifyStrategy() {
|
---|
| 492 | firePropertyChange(UPLOAD_STRATEGY_SPECIFICATION_PROP, null, getUploadStrategySpecification());
|
---|
| 493 | }
|
---|
| 494 |
|
---|
[6084] | 495 | @Override
|
---|
[2711] | 496 | public void itemStateChanged(ItemEvent e) {
|
---|
| 497 | UploadStrategy strategy = getUploadStrategy();
|
---|
[10179] | 498 | if (strategy == null)
|
---|
| 499 | return;
|
---|
[2711] | 500 | switch(strategy) {
|
---|
| 501 | case CHUNKED_DATASET_STRATEGY:
|
---|
| 502 | tfChunkSize.setEnabled(true);
|
---|
| 503 | tfChunkSize.requestFocusInWindow();
|
---|
| 504 | break;
|
---|
| 505 | default:
|
---|
| 506 | tfChunkSize.setEnabled(false);
|
---|
| 507 | }
|
---|
| 508 | notifyStrategy();
|
---|
| 509 | }
|
---|
| 510 |
|
---|
[6084] | 511 | @Override
|
---|
[2711] | 512 | public void focusLost(FocusEvent arg0) {
|
---|
| 513 | notifyStrategy();
|
---|
| 514 | }
|
---|
| 515 |
|
---|
[6084] | 516 | @Override
|
---|
[2711] | 517 | public void actionPerformed(ActionEvent arg0) {
|
---|
| 518 | notifyStrategy();
|
---|
| 519 | }
|
---|
| 520 | }
|
---|
| 521 | }
|
---|