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