Changeset 5765 in josm for trunk


Ignore:
Timestamp:
2013-03-08T23:04:51+01:00 (11 years ago)
Author:
Don-vip
Message:

see #8494 - Refactor of OSM id text fields / changeset id text fields management, add changeset id auto paste in changeset manager, fix EDT violations

Location:
trunk/src/org/openstreetmap/josm
Files:
3 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/DownloadPrimitiveAction.java

    r5373 r5765  
    44import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    55import static org.openstreetmap.josm.tools.I18n.tr;
    6 import static org.openstreetmap.josm.tools.I18n.trc;
    76import static org.openstreetmap.josm.tools.I18n.trn;
    87
     
    109import java.awt.GridBagLayout;
    1110import java.awt.event.ActionEvent;
    12 import java.awt.event.ItemEvent;
    13 import java.awt.event.ItemListener;
    1411import java.awt.event.KeyEvent;
    1512import java.lang.reflect.InvocationTargetException;
    16 import java.util.Collections;
    17 import java.util.LinkedList;
    1813import java.util.List;
    1914import java.util.Set;
    2015import java.util.TreeSet;
    21 import javax.swing.BorderFactory;
    22 import javax.swing.GroupLayout;
    2316
    24 import javax.swing.JCheckBox;
    2517import javax.swing.JLabel;
    2618import javax.swing.JOptionPane;
     
    2820import javax.swing.JScrollPane;
    2921import javax.swing.JTextArea;
    30 import javax.swing.JTextField;
    31 import javax.swing.KeyStroke;
    3222import javax.swing.SwingUtilities;
    33 import javax.swing.border.EtchedBorder;
    34 import javax.swing.plaf.basic.BasicComboBoxEditor;
    3523
    3624import org.openstreetmap.josm.Main;
     
    3826import org.openstreetmap.josm.data.osm.DataSet;
    3927import org.openstreetmap.josm.data.osm.OsmPrimitive;
    40 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    4128import org.openstreetmap.josm.data.osm.PrimitiveId;
    4229import org.openstreetmap.josm.gui.ExtendedDialog;
     30import org.openstreetmap.josm.gui.download.DownloadObjectDialog;
    4331import org.openstreetmap.josm.gui.io.DownloadPrimitivesTask;
    4432import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    45 import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
    4633import org.openstreetmap.josm.gui.widgets.HtmlPanel;
    47 import org.openstreetmap.josm.gui.widgets.OsmIdTextField;
    48 import org.openstreetmap.josm.gui.widgets.OsmPrimitiveTypesComboBox;
    4934import org.openstreetmap.josm.tools.GBC;
    5035import org.openstreetmap.josm.tools.Shortcut;
     
    6449    }
    6550
    66     /**
    67      * Restore the current history from the preferences
    68      *
    69      * @param cbHistory
    70      */
    71     protected void restorePrimitivesHistory(HistoryComboBox cbHistory) {
    72         List<String> cmtHistory = new LinkedList<String>(Main.pref.getCollection(getClass().getName() + ".primitivesHistory", new LinkedList<String>()));
    73         // we have to reverse the history, because ComboBoxHistory will reverse it again
    74         // in addElement()
    75         //
    76         Collections.reverse(cmtHistory);
    77         cbHistory.setPossibleItems(cmtHistory);
    78     }
    79 
    80     /**
    81      * Remind the current history in the preferences
    82      * @param cbHistory
    83      */
    84     protected void remindPrimitivesHistory(HistoryComboBox cbHistory) {
    85         cbHistory.addCurrentItemToHistory();
    86         Main.pref.putCollection(getClass().getName() + ".primitivesHistory", cbHistory.getHistory());
    87     }
    88 
    8951    public void actionPerformed(ActionEvent e) {
    9052
    91         JPanel all = new JPanel();
    92         GroupLayout layout = new GroupLayout(all);
    93         all.setLayout(layout);
    94         layout.setAutoCreateGaps(true);
    95         layout.setAutoCreateContainerGaps(true);
     53        DownloadObjectDialog dialog = new DownloadObjectDialog();
     54        if (dialog.showDialog().getValue() != 1) return;
    9655
    97         JLabel lbl1 = new JLabel(tr("Object type:"));
    98         final OsmPrimitiveTypesComboBox cbType = new OsmPrimitiveTypesComboBox();
    99         cbType.addItem(trc("osm object types", "mixed"));
    100         cbType.setToolTipText(tr("Choose the OSM object type"));
    101         JLabel lbl2 = new JLabel(tr("Object ID:"));
    102         final OsmIdTextField tfId = new OsmIdTextField();
    103         HistoryComboBox cbId = new HistoryComboBox();
    104         cbId.setEditor(new BasicComboBoxEditor() {
    105             @Override
    106             protected JTextField createEditorComponent() {
    107                 return tfId;
    108             }
    109         });
    110         cbId.setToolTipText(tr("Enter the ID of the object that should be downloaded"));
    111         restorePrimitivesHistory(cbId);
    112         // forward the enter key stroke to the download button
    113         tfId.getKeymap().removeKeyStrokeBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false));
    114         JCheckBox layer = new JCheckBox(tr("Separate Layer"));
    115         layer.setToolTipText(tr("Select if the data should be downloaded into a new layer"));
    116         layer.setSelected(Main.pref.getBoolean("download.newlayer"));
    117         final JCheckBox referrers = new JCheckBox(tr("Download referrers (parent relations)"));
    118         referrers.setToolTipText(tr("Select if the referrers of the object should be downloaded as well, i.e.,"
    119                 + "parent relations and for nodes, additionally, parent ways"));
    120         referrers.setSelected(Main.pref.getBoolean("downloadprimitive.referrers", true));
    121         JCheckBox full = new JCheckBox(tr("Download relation members"));
    122         full.setToolTipText(tr("Select if the members of a relation should be downloaded as well"));
    123         full.setSelected(Main.pref.getBoolean("downloadprimitive.full", true));
    124         HtmlPanel help = new HtmlPanel(tr("Object IDs can be separated by comma or space.<br/>"
    125                 + " Examples: <b><ul><li>1 2 5</li><li>1,2,5</li></ul><br/></b>"
    126                 + " In mixed mode, specify objects like this: <b>w123, n110, w12, r15</b><br/>"));
    127         help.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
    128 
    129         layout.setVerticalGroup(layout.createSequentialGroup()
    130             .addGroup(layout.createParallelGroup()
    131                 .addComponent(lbl1)
    132                 .addComponent(cbType, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
    133             .addGroup(layout.createParallelGroup()
    134                 .addComponent(lbl2)
    135                 .addComponent(cbId, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
    136             .addComponent(referrers)
    137             .addComponent(full)
    138             .addComponent(layer)
    139             .addComponent(help)
    140         );
    141 
    142         cbType.addItemListener(new ItemListener() {
    143 
    144             @Override
    145             public void itemStateChanged(ItemEvent e) {
    146                 tfId.setType(cbType.getType());
    147                 tfId.performValidation();
    148                 referrers.setText(cbType.getType() == OsmPrimitiveType.NODE
    149                         ? tr("Download referrers (parent relations and ways)")
    150                         : tr("Download referrers (parent relations)"));
    151             }
    152         });
    153 
    154         layout.setHorizontalGroup(layout.createParallelGroup()
    155             .addGroup(layout.createSequentialGroup()
    156                 .addGroup(layout.createParallelGroup()
    157                     .addComponent(lbl1)
    158                     .addComponent(lbl2)
    159                 )
    160                 .addGroup(layout.createParallelGroup()
    161                     .addComponent(cbType)
    162                     .addComponent(cbId))
    163                 )
    164             .addComponent(referrers)
    165             .addComponent(full)
    166             .addComponent(layer)
    167             .addComponent(help)
    168         );
    169 
    170         ExtendedDialog dialog = new ExtendedDialog(Main.parent,
    171                 tr("Download object"),
    172                 new String[] {tr("Download object"), tr("Cancel")}
    173         );
    174         dialog.setContent(all, false);
    175         dialog.setButtonIcons(new String[] {"download.png", "cancel.png"});
    176         dialog.setToolTipTexts(new String[] {
    177                 tr("Start downloading"),
    178                 tr("Close dialog and cancel downloading")
    179         });
    180         dialog.setDefaultButton(1);
    181         dialog.configureContextsensitiveHelp("/Action/DownloadObject", true /* show help button */);
    182         cbType.setSelectedIndex(Main.pref.getInteger("downloadprimitive.lasttype", 0));
    183         tfId.setType(cbType.getType());
    184         if (Main.pref.getBoolean("downloadprimitive.autopaste", true)) {
    185             tryToPasteFromClipboard(tfId, cbType);
    186         }
    187        
    188         dialog.showDialog();
    189         if (dialog.getValue() != 1) return;
    190         Main.pref.putInteger("downloadprimitive.lasttype", cbType.getSelectedIndex());
    191         Main.pref.put("downloadprimitive.referrers", referrers.isSelected());
    192         Main.pref.put("downloadprimitive.full", full.isSelected());
    193         Main.pref.put("download.newlayer", layer.isSelected());
    194 
    195         tfId.setType(cbType.getType());
    196         if(!tfId.readOsmIds()) {
    197             JOptionPane.showMessageDialog(
    198                     Main.parent,
    199                     tr("Invalid ID list specified\n"
    200                     + "Cannot download object."),
    201                     tr("Information"),
    202                     JOptionPane.INFORMATION_MESSAGE
    203             );
    204             return;
    205         }
    206         remindPrimitivesHistory(cbId);
    207         processItems(layer.isSelected(), tfId.getIds(), referrers.isSelected(), full.isSelected());
     56        processItems(dialog.isNewLayerRequested(), dialog.getOsmIds(), dialog.isReferrersRequested(), dialog.isFullRelationRequested());
    20857    }
    20958
     
    23281            @Override
    23382            public void run() {
    234                 Set<PrimitiveId> errs = task.getMissingPrimitives();
     83                final Set<PrimitiveId> errs = task.getMissingPrimitives();
    23584                if (errs != null && !errs.isEmpty()) {
    236                     final ExtendedDialog dlg = reportProblemDialog(errs,
    237                             trn("Object could not be downloaded", "Some objects could not be downloaded", errs.size()),
    238                             trn("One object could not be downloaded.<br>",
    239                                 "{0} objects could not be downloaded.<br>",
    240                                 errs.size(),
    241                                 errs.size())
    242                             + tr("The server replied with response code 404.<br>"
    243                                 + "This usually means, the server does not know an object with the requested id."),
    244                             tr("missing objects:"),
    245                             JOptionPane.ERROR_MESSAGE
    246                     );
    24785                    try {
    24886                        SwingUtilities.invokeAndWait(new Runnable() {
    24987                            @Override
    25088                            public void run() {
    251                                 dlg.showDialog();
     89                                reportProblemDialog(errs,
     90                                        trn("Object could not be downloaded", "Some objects could not be downloaded", errs.size()),
     91                                        trn("One object could not be downloaded.<br>",
     92                                            "{0} objects could not be downloaded.<br>",
     93                                            errs.size(),
     94                                            errs.size())
     95                                        + tr("The server replied with response code 404.<br>"
     96                                            + "This usually means, the server does not know an object with the requested id."),
     97                                        tr("missing objects:"),
     98                                        JOptionPane.ERROR_MESSAGE
     99                                ).showDialog();
    252100                            }
    253101                        });
     
    257105                }
    258106
    259                 Set<PrimitiveId> del = new TreeSet<PrimitiveId>();
     107                final Set<PrimitiveId> del = new TreeSet<PrimitiveId>();
    260108                DataSet ds = getCurrentDataSet();
    261109                for (PrimitiveId id : ids) {
     
    266114                }
    267115                if (!del.isEmpty()) {
    268                     final ExtendedDialog dlg = reportProblemDialog(del,
    269                             trn("Object deleted", "Objects deleted", del.size()),
    270                             trn(
    271                                 "One downloaded object is deleted.",
    272                                 "{0} downloaded objects are deleted.",
    273                                 del.size(),
    274                                 del.size()),
    275                             null,
    276                             JOptionPane.WARNING_MESSAGE
    277                     );
    278116                    SwingUtilities.invokeLater(new Runnable() {
    279117                        @Override
    280118                        public void run() {
    281                             dlg.showDialog();
     119                            reportProblemDialog(del,
     120                                    trn("Object deleted", "Objects deleted", del.size()),
     121                                    trn(
     122                                        "One downloaded object is deleted.",
     123                                        "{0} downloaded objects are deleted.",
     124                                        del.size(),
     125                                        del.size()),
     126                                    null,
     127                                    JOptionPane.WARNING_MESSAGE
     128                            ).showDialog();
    282129                        }
    283130                    });
     
    315162            .setContent(p, false);
    316163    }
    317 
    318     private void tryToPasteFromClipboard(OsmIdTextField tfId, OsmPrimitiveTypesComboBox cbType) {
    319         String buf = Utils.getClipboardContent();
    320         if (buf != null) {
    321             if (buf.contains("node")) cbType.setSelectedIndex(0);
    322             if (buf.contains("way")) cbType.setSelectedIndex(1);
    323             if (buf.contains("relation")) cbType.setSelectedIndex(2);
    324             String[] res = buf.split("/");
    325             String txt;
    326             if (res.length>0) {
    327                 txt = res[res.length-1];
    328                 if (txt.isEmpty() && txt.length()>1) txt=res[res.length-2];
    329             } else {
    330                 txt=buf;
    331             }
    332             tfId.setText(txt);
    333             tfId.clearTextIfInvalid();
    334         }
    335     }
    336164}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/SingleChangesetDownloadPanel.java

    r5266 r5765  
    1313import javax.swing.JLabel;
    1414import javax.swing.JPanel;
    15 import javax.swing.JTextField;
    1615import javax.swing.event.DocumentEvent;
    1716import javax.swing.event.DocumentListener;
    18 import javax.swing.text.JTextComponent;
    1917
     18import org.openstreetmap.josm.Main;
    2019import org.openstreetmap.josm.gui.SideButton;
    21 import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
     20import org.openstreetmap.josm.gui.widgets.ChangesetIdTextField;
    2221import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
    2322import org.openstreetmap.josm.tools.ImageProvider;
     
    3029public class SingleChangesetDownloadPanel extends JPanel {
    3130
    32     private JTextField tfChangesetId;
     31    private ChangesetIdTextField tfChangesetId;
    3332    private DownloadAction actDownload;
    34     private ChangesetIdValidator valChangesetId;
    3533
    3634    protected void build() {
     
    4442
    4543        add(new JLabel(tr("Changeset ID: ")));
    46         add(tfChangesetId = new JTextField(10));
     44        add(tfChangesetId = new ChangesetIdTextField());
    4745        tfChangesetId.setToolTipText(tr("Enter a changeset id"));
    48         valChangesetId  =ChangesetIdValidator.decorate(tfChangesetId);
    4946        SelectAllOnFocusGainedDecorator.decorate(tfChangesetId);
    5047
     
    5451        tfChangesetId.getDocument().addDocumentListener(actDownload);
    5552        add(btn);
     53       
     54        if (Main.pref.getBoolean("downloadchangeset.autopaste", true)) {
     55            tfChangesetId.tryToPasteFromClipboard();
     56        }
    5657    }
    5758
     59    /**
     60     * Constructs a new {@link SingleChangesetDownloadPanel}
     61     */
    5862    public SingleChangesetDownloadPanel() {
    5963        build();
     
    6771     */
    6872    public int getChangesetId() {
    69         return valChangesetId.getChangesetId();
     73        return tfChangesetId.getChangesetId();
    7074    }
    7175
     
    9498
    9599        protected void updateEnabledState() {
    96             String v = tfChangesetId.getText();
    97             if (v == null || v.trim().length() == 0) {
    98                 setEnabled(false);
    99                 return;
    100             }
    101             setEnabled(valChangesetId.isValid());
     100            setEnabled(tfChangesetId.readIds());
    102101        }
    103102
     
    114113        }
    115114    }
    116 
    117     /**
    118      * Validator for a changeset ID entered in a {@link JTextComponent}.
    119      *
    120      */
    121     static private class ChangesetIdValidator extends AbstractTextComponentValidator {
    122         static public ChangesetIdValidator decorate(JTextComponent tc) {
    123             return new ChangesetIdValidator(tc);
    124         }
    125 
    126         public ChangesetIdValidator(JTextComponent tc) {
    127             super(tc);
    128         }
    129 
    130         @Override
    131         public boolean isValid() {
    132             String value  = getComponent().getText();
    133             if (value == null || value.trim().length() == 0)
    134                 return true;
    135             return getChangesetId() > 0;
    136         }
    137 
    138         @Override
    139         public void validate() {
    140             if (!isValid()) {
    141                 feedbackInvalid(tr("The current value is not a valid changeset ID. Please enter an integer value > 0"));
    142             } else {
    143                 feedbackValid(tr("Please enter an integer value > 0"));
    144             }
    145         }
    146 
    147         public int getChangesetId() {
    148             String value  = getComponent().getText();
    149             if (value == null || value.trim().length() == 0) return 0;
    150             try {
    151                 int changesetId = Integer.parseInt(value.trim());
    152                 if (changesetId > 0) return changesetId;
    153                 return 0;
    154             } catch(NumberFormatException e) {
    155                 return 0;
    156             }
    157         }
    158     }
    159115}
  • trunk/src/org/openstreetmap/josm/gui/widgets/OsmIdTextField.java

    r5561 r5765  
    88import java.util.StringTokenizer;
    99
    10 import javax.swing.JTextField;
    1110import javax.swing.text.JTextComponent;
    1211
     
    1615
    1716/**
     17 * A text field designed to enter one or several OSM primitive IDs.
    1818 * @author Matthias Julius
    1919 */
    20 public class OsmIdTextField extends JTextField {
     20public class OsmIdTextField extends AbstractIdTextField<OsmIdTextField.OsmIdValidator> {
    2121
    22     private OsmIdValidator validator;
    23 
     22    /**
     23     * Constructs a new {@link OsmIdTextField}
     24     */
    2425    public OsmIdTextField() {
    25         validator = OsmIdValidator.decorate(this);
     26        super(OsmIdValidator.class);
    2627    }
    2728
     29    /**
     30     * Sets the type of primitive object
     31     * @param type The type of primitive object (
     32     *      {@link OsmPrimitiveType#NODE NODE},
     33     *      {@link OsmPrimitiveType#WAY WAY},
     34     *      {@link OsmPrimitiveType#RELATION RELATION})
     35     */
    2836    public void setType(OsmPrimitiveType type) {
    2937        validator.type = type;
     
    3442     * @return list of id's
    3543     */
    36     public List<PrimitiveId> getIds() {
     44    public final List<PrimitiveId> getIds() {
    3745        return validator.ids;
    3846    }
    3947
    40     public boolean readOsmIds() {
     48    /**
     49     * Reads the OSM primitive id(s)
     50     * @return true if valid OSM objects IDs have been read, false otherwise
     51     * @see OsmIdValidator#readOsmIds
     52     */
     53    @Override
     54    public boolean readIds() {
    4155        return validator.readOsmIds();
    4256    }
    4357
    44     public void performValidation() {
    45         validator.validate();
    46     }
     58    /**
     59     * Validator for an OSM primitive ID entered in a {@link JTextComponent}.
     60     */
     61    public static class OsmIdValidator extends AbstractTextComponentValidator {
    4762
    48     public void clearTextIfInvalid() {
    49         if (!validator.isValid())
    50             setText("");
    51         validator.validate();
    52     }
    53 
    54     /**
    55      * Validator for a changeset ID entered in a {@link JTextComponent}.
    56      *
    57      */
    58     static private class OsmIdValidator extends AbstractTextComponentValidator {
    59 
    60         static public OsmIdValidator decorate(JTextComponent tc) {
    61             return new OsmIdValidator(tc);
    62         }
    63 
    64         private List<PrimitiveId> ids = new ArrayList<PrimitiveId>();
     63        private final List<PrimitiveId> ids = new ArrayList<PrimitiveId>();
    6564        private OsmPrimitiveType type;
    6665
     66        /**
     67         * Constructs a new {@link OsmIdValidator}
     68         * @param tc The text component to validate
     69         */
    6770        public OsmIdValidator(JTextComponent tc) {
    6871            super(tc, false);
     
    8386        }
    8487
     88        /**
     89         * Reads the OSM primitive id(s)
     90         * @return true if valid OSM objects IDs have been read, false otherwise
     91         */
    8592        public boolean readOsmIds() {
    8693            String value = getComponent().getText();
    8794            char c;
    88             if (value == null || value.trim().length() == 0) {
     95            if (value == null || value.trim().isEmpty()) {
    8996                return false;
    9097            }
     
    108115                            } else if (type == OsmPrimitiveType.NODE) {
    109116                                ids.add(new SimplePrimitiveId(id, OsmPrimitiveType.NODE));
    110                             } else if (type == OsmPrimitiveType.WAY) {
     117                            } else if (type == OsmPrimitiveType.WAY || type == OsmPrimitiveType.CLOSEDWAY) {
    111118                                ids.add(new SimplePrimitiveId(id, OsmPrimitiveType.WAY));
    112                             } else if (type == OsmPrimitiveType.RELATION) {
     119                            } else if (type == OsmPrimitiveType.RELATION || type == OsmPrimitiveType.MULTIPOLYGON) {
    113120                                ids.add(new SimplePrimitiveId(id, OsmPrimitiveType.RELATION));
    114121                            } else {
Note: See TracChangeset for help on using the changeset viewer.