001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui.dialogs.changeset;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    
006    import java.awt.Color;
007    import java.awt.FlowLayout;
008    import java.awt.event.ActionEvent;
009    import java.util.Collections;
010    
011    import javax.swing.AbstractAction;
012    import javax.swing.BorderFactory;
013    import javax.swing.JLabel;
014    import javax.swing.JPanel;
015    import javax.swing.JTextField;
016    import javax.swing.event.DocumentEvent;
017    import javax.swing.event.DocumentListener;
018    import javax.swing.text.JTextComponent;
019    
020    import org.openstreetmap.josm.gui.SideButton;
021    import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
022    import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
023    import org.openstreetmap.josm.tools.ImageProvider;
024    
025    /**
026     * This panel allows to enter the ID of single changeset and to download
027     * the respective changeset.
028     *
029     */
030    public class SingleChangesetDownloadPanel extends JPanel {
031    
032        private JTextField tfChangesetId;
033        private DownloadAction actDownload;
034        private ChangesetIdValidator valChangesetId;
035    
036        protected void build() {
037            setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
038            setBorder(
039                    BorderFactory.createCompoundBorder(
040                            BorderFactory.createLineBorder(Color.GRAY),
041                            BorderFactory.createEmptyBorder(0,3,0,3)
042                    )
043            );
044    
045            add(new JLabel(tr("Changeset ID: ")));
046            add(tfChangesetId = new JTextField(10));
047            tfChangesetId.setToolTipText(tr("Enter a changeset id"));
048            valChangesetId  =ChangesetIdValidator.decorate(tfChangesetId);
049            SelectAllOnFocusGainedDecorator.decorate(tfChangesetId);
050    
051            actDownload = new DownloadAction();
052            SideButton btn = new SideButton(actDownload);
053            tfChangesetId.addActionListener(actDownload);
054            tfChangesetId.getDocument().addDocumentListener(actDownload);
055            add(btn);
056        }
057    
058        public SingleChangesetDownloadPanel() {
059            build();
060        }
061    
062        /**
063         * Replies the changeset id entered in this panel. 0 if no changeset id
064         * or an invalid changeset id is currently entered.
065         *
066         * @return the changeset id entered in this panel
067         */
068        public int getChangesetId() {
069            return valChangesetId.getChangesetId();
070        }
071    
072        /**
073         * Downloads the single changeset from the OSM API
074         */
075        class DownloadAction extends AbstractAction implements DocumentListener{
076    
077            public DownloadAction() {
078                putValue(SMALL_ICON, ImageProvider.get("dialogs/changeset", "downloadchangesetcontent"));
079                putValue(SHORT_DESCRIPTION, tr("Download the changeset with the specified id, including the changeset content"));
080                updateEnabledState();
081            }
082    
083            public void actionPerformed(ActionEvent arg0) {
084                if (!isEnabled())
085                    return;
086                int id = getChangesetId();
087                if (id == 0) return;
088                ChangesetContentDownloadTask task =  new ChangesetContentDownloadTask(
089                        SingleChangesetDownloadPanel.this,
090                        Collections.singleton(id)
091                );
092                ChangesetCacheManager.getInstance().runDownloadTask(task);
093            }
094    
095            protected void updateEnabledState() {
096                String v = tfChangesetId.getText();
097                if (v == null || v.trim().length() == 0) {
098                    setEnabled(false);
099                    return;
100                }
101                setEnabled(valChangesetId.isValid());
102            }
103    
104            public void changedUpdate(DocumentEvent arg0) {
105                updateEnabledState();
106            }
107    
108            public void insertUpdate(DocumentEvent arg0) {
109                updateEnabledState();
110            }
111    
112            public void removeUpdate(DocumentEvent arg0) {
113                updateEnabledState();
114            }
115        }
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        }
159    }