Ignore:
Timestamp:
2009-12-09T21:25:40+01:00 (16 years ago)
Author:
Gubaer
Message:

fixed #4130: Chunked upload mode counter is wrong
fixed #4118: Upload dialog too complicated
fixed #4129: Hide the new "Upload data in one request/chunks/individually" behind an expanding "Upload method" box
fixed #2075: API 0.6: don't upload more than 50K edits at once
fixed #4044: Huge uploads never end [should be solved with chunked upload mode]
fixed #4110: Upload dialog spacing wrong
fixed #3386: Upload dialog has empty areas when the changeset doesn't include all of add/modify/delete operations
see #3369: bulk import helper [JOSM now supports multi changesets uploads]

See online help for more details.

Completes r2598

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/io/UploadStrategySelectionPanel.java

    r2569 r2599  
    99import java.awt.GridBagLayout;
    1010import java.awt.Insets;
     11import java.awt.event.ActionEvent;
     12import java.awt.event.ActionListener;
    1113import java.awt.event.FocusEvent;
    1214import java.awt.event.FocusListener;
     15import java.awt.event.ItemEvent;
     16import java.awt.event.ItemListener;
    1317import java.beans.PropertyChangeEvent;
    1418import java.beans.PropertyChangeListener;
     
    2327import javax.swing.JTextField;
    2428import javax.swing.UIManager;
    25 import javax.swing.event.ChangeEvent;
    26 import javax.swing.event.ChangeListener;
    2729import javax.swing.event.DocumentEvent;
    2830import javax.swing.event.DocumentListener;
    2931
    3032import org.openstreetmap.josm.Main;
    31 
    32 public class UploadStrategySelectionPanel extends JPanel {
     33import org.openstreetmap.josm.gui.JMultilineLabel;
     34import org.openstreetmap.josm.io.OsmApi;
     35import org.openstreetmap.josm.tools.ImageProvider;
     36
     37/**
     38 * UploadStrategySelectionPanel is a panel for selecting an upload strategy.
     39 *
     40 * Clients can listen for property change events for the property
     41 * {@see #UPLOAD_STRATEGY_SPECIFICATION_PROP}.
     42 */
     43public class UploadStrategySelectionPanel extends JPanel implements PropertyChangeListener {
     44
     45    /**
     46     * The property for the upload strategy
     47     */
     48    public final static String UPLOAD_STRATEGY_SPECIFICATION_PROP =
     49        UploadStrategySelectionPanel.class.getName() + ".uploadStrategySpecification";
     50
    3351    private static final Color BG_COLOR_ERROR = new Color(255,224,224);
    3452
    3553    private ButtonGroup bgStrategies;
     54    private ButtonGroup bgMultiChangesetPolicies;
    3655    private Map<UploadStrategy, JRadioButton> rbStrategy;
    3756    private Map<UploadStrategy, JLabel> lblNumRequests;
     57    private Map<UploadStrategy, JMultilineLabel> lblStrategies;
    3858    private JTextField tfChunkSize;
     59    private JPanel pnlMultiChangesetPolicyPanel;
     60    private JRadioButton rbFillOneChangeset;
     61    private JRadioButton rbUseMultipleChangesets;
     62    private JMultilineLabel lblMultiChangesetPoliciesHeader;
    3963
    4064    private long numUploadedObjects = 0;
     
    4468    }
    4569
    46     protected void build() {
    47         setLayout(new GridBagLayout());
     70    protected JPanel buildUploadStrategyPanel() {
     71        JPanel pnl = new JPanel();
     72        pnl.setLayout(new GridBagLayout());
    4873        bgStrategies = new ButtonGroup();
    4974        rbStrategy = new HashMap<UploadStrategy, JRadioButton>();
     75        lblStrategies = new HashMap<UploadStrategy, JMultilineLabel>();
    5076        lblNumRequests = new HashMap<UploadStrategy, JLabel>();
    5177        for (UploadStrategy strategy: UploadStrategy.values()) {
    5278            rbStrategy.put(strategy, new JRadioButton());
    5379            lblNumRequests.put(strategy, new JLabel());
     80            lblStrategies.put(strategy, new JMultilineLabel(""));
    5481            bgStrategies.add(rbStrategy.get(strategy));
    5582        }
     
    5986        gc.gridx = 0;
    6087        gc.gridy = 0;
    61         gc.weightx = 0.0;
    62         gc.weighty = 0.0;
    63         gc.insets = new Insets(0,5,0,5);
     88        gc.weightx = 1.0;
     89        gc.weighty = 0.0;
     90        gc.gridwidth = 4;
     91        gc.insets = new Insets(0,0,3,0);
    6492        gc.anchor = GridBagConstraints.FIRST_LINE_START;
    65         add(rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY), gc);
    66         gc.gridx = 1;
    67         gc.gridy = 0;
    68         gc.weightx = 0.0;
    69         gc.weighty = 0.0;
    70         gc.gridwidth = 2;
    71         add(new JLabel(tr("Upload data in one request")), gc);
    72         gc.gridx = 3;
    73         gc.gridy = 0;
    74         gc.weightx = 1.0;
    75         gc.weighty = 0.0;
    76         gc.gridwidth = 1;
    77         add(lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY), gc);
    78 
    79         // -- chunked dataset strategy
     93        pnl.add(new JMultilineLabel(tr("Please select the upload strategy:")), gc);
     94
     95        // -- single request strategy
    8096        gc.gridx = 0;
    8197        gc.gridy = 1;
    8298        gc.weightx = 0.0;
    8399        gc.weighty = 0.0;
    84         add(rbStrategy.get(UploadStrategy.CHUNKED_DATASET_STRATEGY), gc);
     100        gc.gridwidth = 1;
     101        gc.anchor = GridBagConstraints.FIRST_LINE_START;
     102        pnl.add(rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY), gc);
    85103        gc.gridx = 1;
    86104        gc.gridy = 1;
    87105        gc.weightx = 0.0;
    88106        gc.weighty = 0.0;
    89         gc.gridwidth = 1;
    90         add(new JLabel(tr("Upload data in chunks of objects. Chunk size: ")), gc);
    91         gc.gridx = 2;
    92         gc.gridy = 1;
    93         gc.weightx = 0.0;
    94         gc.weighty = 0.0;
    95         gc.gridwidth = 1;
    96         add(tfChunkSize = new JTextField(4), gc);
     107        gc.gridwidth = 2;
     108        JLabel lbl = lblStrategies.get(UploadStrategy.SINGLE_REQUEST_STRATEGY);
     109        lbl.setText(tr("Upload data in one request"));
     110        pnl.add(lbl, gc);
    97111        gc.gridx = 3;
    98112        gc.gridy = 1;
     
    100114        gc.weighty = 0.0;
    101115        gc.gridwidth = 1;
    102         add(lblNumRequests.get(UploadStrategy.CHUNKED_DATASET_STRATEGY), gc);
     116        pnl.add(lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY), gc);
     117
     118        // -- chunked dataset strategy
     119        gc.gridx = 0;
     120        gc.gridy = 2;
     121        gc.weightx = 0.0;
     122        gc.weighty = 0.0;
     123        pnl.add(rbStrategy.get(UploadStrategy.CHUNKED_DATASET_STRATEGY), gc);
     124        gc.gridx = 1;
     125        gc.gridy = 2;
     126        gc.weightx = 0.0;
     127        gc.weighty = 0.0;
     128        gc.gridwidth = 1;
     129        lbl = lblStrategies.get(UploadStrategy.CHUNKED_DATASET_STRATEGY);
     130        lbl.setText(tr("Upload data in chunks of objects. Chunk size: "));
     131        pnl.add(lbl, gc);
     132        gc.gridx = 2;
     133        gc.gridy = 2;
     134        gc.weightx = 0.0;
     135        gc.weighty = 0.0;
     136        gc.gridwidth = 1;
     137        pnl.add(tfChunkSize = new JTextField(4), gc);
     138        gc.gridx = 3;
     139        gc.gridy = 2;
     140        gc.weightx = 1.0;
     141        gc.weighty = 0.0;
     142        gc.gridwidth = 1;
     143        pnl.add(lblNumRequests.get(UploadStrategy.CHUNKED_DATASET_STRATEGY), gc);
    103144
    104145        // -- single request strategy
    105146        gc.gridx = 0;
    106         gc.gridy = 2;
    107         gc.weightx = 0.0;
    108         gc.weighty = 0.0;
    109         add(rbStrategy.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY), gc);
     147        gc.gridy = 3;
     148        gc.weightx = 0.0;
     149        gc.weighty = 0.0;
     150        pnl.add(rbStrategy.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY), gc);
    110151        gc.gridx = 1;
    111         gc.gridy = 2;
     152        gc.gridy = 3;
    112153        gc.weightx = 0.0;
    113154        gc.weighty = 0.0;
    114155        gc.gridwidth = 2;
    115         add(new JLabel(tr("Upload each object individually")), gc);
     156        lbl = lblStrategies.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY);
     157        lbl.setText(tr("Upload each object individually"));
     158        pnl.add(lbl, gc);
    116159        gc.gridx = 3;
    117         gc.gridy = 2;
    118         gc.weightx = 1.0;
    119         gc.weighty = 0.0;
    120         gc.gridwidth = 1;
    121         add(lblNumRequests.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY), gc);
    122 
     160        gc.gridy = 3;
     161        gc.weightx = 1.0;
     162        gc.weighty = 0.0;
     163        gc.gridwidth = 1;
     164        pnl.add(lblNumRequests.get(UploadStrategy.INDIVIDUAL_OBJECTS_STRATEGY), gc);
    123165
    124166        tfChunkSize.addFocusListener(new TextFieldFocusHandler());
    125167        tfChunkSize.getDocument().addDocumentListener(new ChunkSizeInputVerifier());
     168
    126169        StrategyChangeListener strategyChangeListener = new StrategyChangeListener();
     170        tfChunkSize.addFocusListener(strategyChangeListener);
     171        tfChunkSize.addActionListener(strategyChangeListener);
    127172        for(UploadStrategy strategy: UploadStrategy.values()) {
    128             rbStrategy.get(strategy).addChangeListener(strategyChangeListener);
    129         }
    130 
     173            rbStrategy.get(strategy).addItemListener(strategyChangeListener);
     174        }
     175
     176        return pnl;
     177    }
     178
     179    protected JPanel buildMultiChangesetPolicyPanel() {
     180        pnlMultiChangesetPolicyPanel = new JPanel();
     181        pnlMultiChangesetPolicyPanel.setLayout(new GridBagLayout());
     182        GridBagConstraints gc = new GridBagConstraints();
     183        gc.gridx = 0;
     184        gc.gridy = 0;
     185        gc.fill = GridBagConstraints.HORIZONTAL;
     186        gc.anchor = GridBagConstraints.FIRST_LINE_START;
     187        gc.weightx = 1.0;
     188        pnlMultiChangesetPolicyPanel.add(lblMultiChangesetPoliciesHeader = new JMultilineLabel(tr("<html>There are <strong>multiple changesets</strong> necessary in order to upload {0} objects. What policy shall be used?</html>", numUploadedObjects)), gc);
     189        gc.gridy = 1;
     190        pnlMultiChangesetPolicyPanel.add(rbFillOneChangeset = new JRadioButton(tr("Fill up one changeset and return to the Upload Dialog")),gc);
     191        gc.gridy = 2;
     192        pnlMultiChangesetPolicyPanel.add(rbUseMultipleChangesets = new JRadioButton(tr("Open and use as many new changesets as necessary")),gc);
     193
     194        bgMultiChangesetPolicies = new ButtonGroup();
     195        bgMultiChangesetPolicies.add(rbFillOneChangeset);
     196        bgMultiChangesetPolicies.add(rbUseMultipleChangesets);
     197        return pnlMultiChangesetPolicyPanel;
     198    }
     199
     200    protected void build() {
     201        setLayout(new GridBagLayout());
     202        GridBagConstraints gc = new GridBagConstraints();
     203        gc.gridx = 0;
     204        gc.gridy = 0;
     205        gc.fill = GridBagConstraints.HORIZONTAL;
     206        gc.weightx = 1.0;
     207        gc.weighty = 0.0;
     208        gc.anchor = GridBagConstraints.NORTHWEST;
     209        gc.insets = new Insets(3,3,3,3);
     210
     211        add(buildUploadStrategyPanel(), gc);
     212        gc.gridy = 1;
     213        add(buildMultiChangesetPolicyPanel(), gc);
     214
     215        // consume remaining space
     216        gc.gridy = 2;
     217        gc.fill = GridBagConstraints.BOTH;
     218        gc.weightx = 1.0;
     219        gc.weighty = 1.0;
     220        add(new JPanel(), gc);
     221
     222        int maxChunkSize = OsmApi.getOsmApi().getCapabilities().getMaxChangsetSize();
     223        pnlMultiChangesetPolicyPanel.setVisible(
     224                maxChunkSize > 0 && numUploadedObjects > maxChunkSize
     225        );
    131226    }
    132227
     
    139234        if (strategy == null) return;
    140235        rbStrategy.get(strategy.getStrategy()).setSelected(true);
     236        tfChunkSize.setEnabled(strategy.equals(UploadStrategy.CHUNKED_DATASET_STRATEGY));
    141237        if (strategy.getStrategy().equals(UploadStrategy.CHUNKED_DATASET_STRATEGY)) {
    142             tfChunkSize.setEnabled(strategy.equals(UploadStrategy.CHUNKED_DATASET_STRATEGY));
    143238            if (strategy.getChunkSize() != UploadStrategySpecification.UNSPECIFIED_CHUNK_SIZE) {
    144239                tfChunkSize.setText(Integer.toString(strategy.getChunkSize()));
     
    152247        UploadStrategy strategy = getUploadStrategy();
    153248        int chunkSize = getChunkSize();
     249        UploadStrategySpecification spec = new UploadStrategySpecification();
    154250        switch(strategy) {
    155         case INDIVIDUAL_OBJECTS_STRATEGY: return UploadStrategySpecification.createIndividualObjectStrategy();
    156         case SINGLE_REQUEST_STRATEGY: return UploadStrategySpecification.createSingleRequestUploadStrategy();
    157         case CHUNKED_DATASET_STRATEGY: return UploadStrategySpecification.createChunkedUploadStrategy(chunkSize);
    158         }
    159         // should not happen
    160         return null;
     251        case INDIVIDUAL_OBJECTS_STRATEGY:
     252            spec.setStrategy(strategy);
     253            break;
     254        case SINGLE_REQUEST_STRATEGY:
     255            spec.setStrategy(strategy);
     256            break;
     257        case CHUNKED_DATASET_STRATEGY:
     258            spec.setStrategy(strategy).setChunkSize(chunkSize);
     259            break;
     260        }
     261        if(pnlMultiChangesetPolicyPanel.isVisible()) {
     262            if (rbFillOneChangeset.isSelected()) {
     263                spec.setPolicy(MaxChangesetSizeExceededPolicy.FILL_ONE_CHANGESET_AND_RETURN_TO_UPLOAD_DIALOG);
     264            } else if (rbUseMultipleChangesets.isSelected()) {
     265                spec.setPolicy(MaxChangesetSizeExceededPolicy.AUTOMATICALLY_OPEN_NEW_CHANGESETS);
     266            } else {
     267                spec.setPolicy(null); // unknown policy
     268            }
     269        } else {
     270            spec.setPolicy(null);
     271        }
     272        return spec;
    161273    }
    162274
     
    171283        return strategy;
    172284    }
    173 
    174285
    175286    protected int getChunkSize() {
     
    191302    }
    192303
    193     public void saveToPreferences() {
     304    public void rememberUserInput() {
    194305        UploadStrategy strategy = getUploadStrategy();
    195306        UploadStrategy.saveToPreferences(strategy);
     
    204315
    205316    protected void updateNumRequestsLabels() {
     317        int maxChunkSize = OsmApi.getOsmApi().getCapabilities().getMaxChangsetSize();
     318        if (maxChunkSize > 0 && numUploadedObjects > maxChunkSize) {
     319            rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setEnabled(false);
     320            JLabel lbl = lblStrategies.get(UploadStrategy.SINGLE_REQUEST_STRATEGY);
     321            lbl.setIcon(ImageProvider.get("warning-small.png"));
     322            lbl.setText(tr("Upload in one request not possible (too many objects to upload)"));
     323            lbl.setToolTipText(tr("<html>Can''t upload {0} objects in one request because the<br>"
     324                    + "max. changeset size {1} on server ''{2}'' is exceeded.</html>",
     325                    numUploadedObjects,
     326                    maxChunkSize,
     327                    OsmApi.getOsmApi().getBaseUrl()
     328            )
     329            );
     330            rbStrategy.get(UploadStrategy.CHUNKED_DATASET_STRATEGY).setSelected(true);
     331            lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setVisible(false);
     332
     333            lblMultiChangesetPoliciesHeader.setText(tr("<html>There are <strong>multiple changesets</strong> necessary in order to upload {0} objects. What policy shall be used?</html>", numUploadedObjects));
     334            if (!rbFillOneChangeset.isSelected() && ! rbUseMultipleChangesets.isSelected()) {
     335                rbUseMultipleChangesets.setSelected(true);
     336            }
     337            pnlMultiChangesetPolicyPanel.setVisible(true);
     338
     339        } else {
     340            rbStrategy.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setEnabled(true);
     341            JLabel lbl = lblStrategies.get(UploadStrategy.SINGLE_REQUEST_STRATEGY);
     342            lbl.setText(tr("Upload data in one request"));
     343            lbl.setIcon(null);
     344            lbl.setToolTipText("");
     345            lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setVisible(true);
     346
     347            pnlMultiChangesetPolicyPanel.setVisible(false);
     348        }
     349
    206350        lblNumRequests.get(UploadStrategy.SINGLE_REQUEST_STRATEGY).setText(tr("(1 request)"));
    207351        if (numUploadedObjects == 0) {
     
    229373    }
    230374
     375    public void propertyChange(PropertyChangeEvent evt) {
     376        if (evt.getPropertyName().equals(UploadedObjectsSummaryPanel.NUM_OBJECTS_TO_UPLOAD_PROP)) {
     377            setNumUploadedObjects((Integer)evt.getNewValue());
     378        }
     379    }
     380
    231381    class TextFieldFocusHandler implements FocusListener {
    232382        public void focusGained(FocusEvent e) {
     
    241391
    242392    class ChunkSizeInputVerifier implements DocumentListener, PropertyChangeListener {
    243 
    244393        protected void setErrorFeedback(JTextField tf, String message) {
    245394            tf.setBorder(BorderFactory.createLineBorder(Color.RED, 1));
     
    257406            try {
    258407                int chunkSize = Integer.parseInt(tfChunkSize.getText().trim());
     408                int maxChunkSize = OsmApi.getOsmApi().getCapabilities().getMaxChangsetSize();
    259409                if (chunkSize <= 0) {
    260410                    setErrorFeedback(tfChunkSize, tr("Illegal chunk size <= 0. Please enter an integer > 1"));
     411                } else if (maxChunkSize > 0 && chunkSize > maxChunkSize) {
     412                    setErrorFeedback(tfChunkSize, tr("Chunk size {0} exceeds max. changeset size {1} for server ''{2}''", chunkSize, maxChunkSize, OsmApi.getOsmApi().getBaseUrl()));
    261413                } else {
    262414                    clearErrorFeedback(tfChunkSize, tr("Please enter an integer > 1"));
     415                }
     416
     417                if (maxChunkSize > 0 && chunkSize > maxChunkSize) {
     418                    setErrorFeedback(tfChunkSize, tr("Chunk size {0} exceeds max. changeset size {1} for server ''{2}''", chunkSize, maxChunkSize, OsmApi.getOsmApi().getBaseUrl()));
    263419                }
    264420            } catch(NumberFormatException e) {
     
    291447    }
    292448
    293     class StrategyChangeListener implements ChangeListener {
    294         public void stateChanged(ChangeEvent e) {
     449    class StrategyChangeListener implements ItemListener, FocusListener, ActionListener {
     450
     451        protected void notifyStrategy() {
     452            firePropertyChange(UPLOAD_STRATEGY_SPECIFICATION_PROP, null, getUploadStrategySpecification());
     453        }
     454
     455        public void itemStateChanged(ItemEvent e) {
    295456            UploadStrategy strategy = getUploadStrategy();
    296457            if (strategy == null) return;
     
    303464                tfChunkSize.setEnabled(false);
    304465            }
     466            notifyStrategy();
     467        }
     468
     469        public void focusGained(FocusEvent arg0) {}
     470
     471        public void focusLost(FocusEvent arg0) {
     472            notifyStrategy();
     473        }
     474
     475        public void actionPerformed(ActionEvent arg0) {
     476            notifyStrategy();
    305477        }
    306478    }
Note: See TracChangeset for help on using the changeset viewer.