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