001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui.dialogs.changeset.query;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    
006    import java.awt.BorderLayout;
007    import java.awt.GridBagConstraints;
008    import java.awt.GridBagLayout;
009    import java.awt.Insets;
010    import java.awt.event.ItemEvent;
011    import java.awt.event.ItemListener;
012    import java.util.HashMap;
013    import java.util.Map;
014    
015    import javax.swing.BorderFactory;
016    import javax.swing.ButtonGroup;
017    import javax.swing.JCheckBox;
018    import javax.swing.JPanel;
019    import javax.swing.JRadioButton;
020    
021    import org.openstreetmap.josm.Main;
022    import org.openstreetmap.josm.data.Bounds;
023    import org.openstreetmap.josm.gui.JMultilineLabel;
024    import org.openstreetmap.josm.gui.JosmUserIdentityManager;
025    import org.openstreetmap.josm.gui.widgets.HtmlPanel;
026    import org.openstreetmap.josm.io.ChangesetQuery;
027    
028    /**
029     * This panel presents a list of basic queries for changests.
030     *
031     */
032    public class BasicChangesetQueryPanel extends JPanel {
033    
034        /**
035         * Enumeration of basic, predefined queries
036         */
037        private static enum BasicQuery {
038            MOST_RECENT_CHANGESETS,
039            MY_OPEN_CHANGESETS,
040            CHANGESETS_IN_MAP_VIEW;
041        }
042    
043        private ButtonGroup bgQueries;
044        private Map<BasicQuery, JRadioButton> rbQueries;
045        private Map<BasicQuery, JMultilineLabel> lblQueries;
046        private JCheckBox cbMyChangesetsOnly;
047        private HtmlPanel pnlInfos;
048    
049    
050        protected JPanel buildQueriesPanel() {
051            JPanel pnl = new JPanel(new GridBagLayout());
052    
053            bgQueries = new ButtonGroup();
054            rbQueries = new HashMap<BasicQuery, JRadioButton>();
055            lblQueries = new HashMap<BasicQuery, JMultilineLabel>();
056            SelectQueryHandler selectedQueryHandler = new SelectQueryHandler();
057            for (BasicQuery q: BasicQuery.values()) {
058                JRadioButton rb = new JRadioButton();
059                rb.addItemListener(selectedQueryHandler);
060                rbQueries.put(q, rb);
061                bgQueries.add(rb);
062                lblQueries.put(q, new JMultilineLabel(""));
063            }
064    
065            GridBagConstraints gc = new GridBagConstraints();
066            // -- most recent changes
067            gc.fill = GridBagConstraints.NONE;
068            gc.anchor = GridBagConstraints.NORTHWEST;
069            gc.insets = new Insets(0,0,5,3);
070            pnl.add(rbQueries.get(BasicQuery.MOST_RECENT_CHANGESETS), gc);
071    
072            gc.gridx = 1;
073            gc.fill = GridBagConstraints.HORIZONTAL;
074            gc.weightx = 1.0;
075            pnl.add(lblQueries.get(BasicQuery.MOST_RECENT_CHANGESETS), gc);
076    
077            // -- most recent changes
078            gc.gridx = 0;
079            gc.gridy = 1;
080            gc.fill = GridBagConstraints.NONE;
081            gc.weightx = 0.0;
082            pnl.add(rbQueries.get(BasicQuery.MY_OPEN_CHANGESETS), gc);
083    
084            gc.gridx = 1;
085            gc.fill = GridBagConstraints.HORIZONTAL;
086            gc.weightx = 1.0;
087            pnl.add(lblQueries.get(BasicQuery.MY_OPEN_CHANGESETS), gc);
088    
089            // -- changesets in map view
090            gc.gridx = 0;
091            gc.gridy = 2;
092            gc.fill = GridBagConstraints.NONE;
093            gc.weightx = 0.0;
094            pnl.add(rbQueries.get(BasicQuery.CHANGESETS_IN_MAP_VIEW), gc);
095    
096            gc.gridx = 1;
097            gc.fill = GridBagConstraints.HORIZONTAL;
098            gc.weightx = 1.0;
099            pnl.add(lblQueries.get(BasicQuery.CHANGESETS_IN_MAP_VIEW), gc);
100    
101            // -- checkbox my changesets only
102            gc.gridx = 0;
103            gc.gridy = 3;
104            gc.gridwidth = 2;
105            gc.insets = new Insets(5,0,3,3);
106            gc.fill = GridBagConstraints.HORIZONTAL;
107            gc.weightx = 1.0;
108            pnl.add(cbMyChangesetsOnly = new JCheckBox(tr("Download my changesets only")), gc);
109            cbMyChangesetsOnly.setToolTipText(tr("<html>Select to restrict the query to your changesets only.<br>Unselect to include all changesets in the query.</html>"));
110    
111            // grab remaining space
112            gc.gridx = 0;
113            gc.gridy = 4;
114            gc.gridwidth = 2;
115            gc.insets = new Insets(5,0,3,3);
116            gc.fill = GridBagConstraints.BOTH;
117            gc.weightx = 1.0;
118            gc.weighty = 1.0;
119            pnl.add(new JPanel(), gc);
120    
121            return pnl;
122        }
123    
124        protected JPanel buildInfoPanel() {
125            pnlInfos = new HtmlPanel();
126            pnlInfos.setText(tr("<html>Please select one the following <strong>standard queries</strong>."
127                    + "Select <strong>Download my changesets only</strong>"
128                    + " if you only want to download changesets created by yourself.<br>"
129                    + "Note that JOSM will download max. 100 changesets.</html>")
130            );
131            return pnlInfos;
132        }
133    
134        protected void build() {
135            setLayout(new BorderLayout(0,5));
136            setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
137            add(buildInfoPanel(), BorderLayout.NORTH);
138            add(buildQueriesPanel(), BorderLayout.CENTER);
139        }
140    
141        public BasicChangesetQueryPanel() {
142            build();
143        }
144    
145        public void init() {
146            JMultilineLabel lbl = lblQueries.get(BasicQuery.MOST_RECENT_CHANGESETS);
147            lbl.setText(tr("<html>Download the latest changesets</html>"));
148    
149            // query for open changesets only possible if we have a current user which is at least
150            // partially identified
151            lbl = lblQueries.get(BasicQuery.MY_OPEN_CHANGESETS);
152            if (JosmUserIdentityManager.getInstance().isAnonymous()) {
153                rbQueries.get(BasicQuery.MY_OPEN_CHANGESETS).setEnabled(false);
154                lbl.setText(tr("<html>Download my open changesets<br><em>Disabled. Please enter your OSM user name in the preferences first.</em></html>"));
155            } else {
156                rbQueries.get(BasicQuery.MY_OPEN_CHANGESETS).setEnabled(true);
157                lbl.setText(tr("<html>Download my open changesets</html>"));
158            }
159    
160            // query for changesets in the current map view only if there *is* a current
161            // map view
162            lbl = lblQueries.get(BasicQuery.CHANGESETS_IN_MAP_VIEW);
163            if (Main.map == null || Main.map.mapView == null) {
164                rbQueries.get(BasicQuery.CHANGESETS_IN_MAP_VIEW).setEnabled(false);
165                lbl.setText(tr("<html>Download changesets in the current map view.<br><em>Disabled. There is currently no map view active.</em></html>"));
166            } else {
167                rbQueries.get(BasicQuery.CHANGESETS_IN_MAP_VIEW).setEnabled(true);
168                lbl.setText(tr("<html>Download changesets in the current map view</html>"));
169            }
170    
171            restoreFromPreferences();
172        }
173    
174        public void rememberInPreferences() {
175            BasicQuery q = getSelectedQuery();
176            if (q == null) {
177                Main.pref.put("changeset-query.basic.query", null);
178            } else {
179                Main.pref.put("changeset-query.basic.query", q.toString());
180            }
181            Main.pref.put("changeset-query.basic.my-changesets-only", cbMyChangesetsOnly.isSelected());
182        }
183    
184        public void restoreFromPreferences() {
185            BasicQuery q;
186            String value =  Main.pref.get("changeset-query.basic.query", null);
187            if (value == null) {
188                q = BasicQuery.MOST_RECENT_CHANGESETS;
189            } else {
190                try {
191                    q = BasicQuery.valueOf(BasicQuery.class, value);
192                } catch(IllegalArgumentException e) {
193                    System.err.println(tr("Warning: unexpected value for preference ''{0}'', got ''{1}''. Resetting to default query.","changeset-query.basic.query", value));
194                    q = BasicQuery.MOST_RECENT_CHANGESETS;
195                }
196            }
197            rbQueries.get(q).setSelected(true);
198            boolean mineOnly = Main.pref.getBoolean("changeset-query.basic.my-changesets-only", false);
199            mineOnly = mineOnly || q.equals(BasicQuery.MY_OPEN_CHANGESETS);
200            cbMyChangesetsOnly.setSelected(mineOnly);
201        }
202    
203        protected BasicQuery getSelectedQuery() {
204            for (BasicQuery q : BasicQuery.values()) {
205                if (rbQueries.get(q).isSelected())
206                    return q;
207            }
208            return null;
209        }
210    
211        public ChangesetQuery buildChangesetQuery() {
212            BasicQuery q = getSelectedQuery();
213            ChangesetQuery query = new ChangesetQuery();
214            JosmUserIdentityManager im = JosmUserIdentityManager.getInstance();
215            if (q == null)
216                return query;
217            switch(q) {
218            case MOST_RECENT_CHANGESETS:
219                break;
220            case MY_OPEN_CHANGESETS:
221                query = query.beingOpen(true);
222                break;
223            case CHANGESETS_IN_MAP_VIEW:
224                Bounds b = Main.map.mapView.getLatLonBounds(Main.map.mapView.getBounds());
225                query = query.inBbox(b);
226                break;
227            }
228    
229            if (cbMyChangesetsOnly.isSelected()) {
230                if (im.isPartiallyIdentified()) {
231                    query = query.forUser(im.getUserName());
232                } else if (im.isFullyIdentified()) {
233                    query = query.forUser(im.getUserId()).beingOpen(true);
234                } else
235                    // anonymous -- can happen with a fresh config.
236                    throw new IllegalStateException(tr("Cannot create changeset query for open changesets of anonymous user"));
237            }
238    
239            return query;
240        }
241    
242        /**
243         * Responds to changes in the selected query
244         *
245         */
246        class SelectQueryHandler implements ItemListener {
247            public void itemStateChanged(ItemEvent e) {
248                BasicQuery q = getSelectedQuery();
249                if (q == null) return;
250                if (q.equals(BasicQuery.MY_OPEN_CHANGESETS)) {
251                    cbMyChangesetsOnly.setSelected(true);
252                    cbMyChangesetsOnly.setEnabled(false);
253                } else {
254                    if (! cbMyChangesetsOnly.isEnabled()) {
255                        cbMyChangesetsOnly.setEnabled(true);
256                    }
257                }
258            }
259        }
260    }