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.event.ItemEvent; 010import java.awt.event.ItemListener; 011 012import javax.swing.BorderFactory; 013import javax.swing.JCheckBox; 014import javax.swing.JPanel; 015import javax.swing.JScrollPane; 016 017import org.openstreetmap.josm.Main; 018import org.openstreetmap.josm.gui.util.GuiHelper; 019import org.openstreetmap.josm.gui.widgets.JMultilineLabel; 020import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel; 021import org.openstreetmap.josm.io.ChangesetQuery; 022 023/** 024 * This panel allows to specify a changeset query 025 * @since 2689 026 */ 027public class AdvancedChangesetQueryPanel extends JPanel { 028 029 private final JCheckBox cbUserRestriction = new JCheckBox(); 030 private final JCheckBox cbOpenAndCloseRestrictions = new JCheckBox(); 031 private final JCheckBox cbTimeRestrictions = new JCheckBox(); 032 private final JCheckBox cbBoundingBoxRestriction = new JCheckBox(); 033 private final UserRestrictionPanel pnlUserRestriction = new UserRestrictionPanel(); 034 private final OpenAndCloseStateRestrictionPanel pnlOpenAndCloseRestriction = new OpenAndCloseStateRestrictionPanel(); 035 private final TimeRestrictionPanel pnlTimeRestriction = new TimeRestrictionPanel(); 036 private final BBoxRestrictionPanel pnlBoundingBoxRestriction = new BBoxRestrictionPanel(); 037 038 /** 039 * Constructs a new {@code AdvancedChangesetQueryPanel}. 040 */ 041 public AdvancedChangesetQueryPanel() { 042 build(); 043 } 044 045 protected JPanel buildQueryPanel() { 046 ItemListener stateChangeHandler = new RestrictionGroupStateChangeHandler(); 047 JPanel pnl = new VerticallyScrollablePanel(new GridBagLayout()); 048 pnl.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 049 GridBagConstraints gc = new GridBagConstraints(); 050 051 // -- select changesets by a specific user 052 // 053 gc.anchor = GridBagConstraints.NORTHWEST; 054 gc.weightx = 0.0; 055 gc.fill = GridBagConstraints.HORIZONTAL; 056 pnl.add(cbUserRestriction, gc); 057 cbUserRestriction.addItemListener(stateChangeHandler); 058 059 gc.gridx = 1; 060 gc.weightx = 1.0; 061 pnl.add(new JMultilineLabel(tr("Select changesets owned by specific users")), gc); 062 063 gc.gridy = 1; 064 gc.gridx = 1; 065 gc.weightx = 1.0; 066 pnl.add(pnlUserRestriction, gc); 067 068 // -- restricting the query to open and closed changesets 069 // 070 gc.gridy = 2; 071 gc.gridx = 0; 072 gc.anchor = GridBagConstraints.NORTHWEST; 073 gc.weightx = 0.0; 074 gc.fill = GridBagConstraints.HORIZONTAL; 075 pnl.add(cbOpenAndCloseRestrictions, gc); 076 cbOpenAndCloseRestrictions.addItemListener(stateChangeHandler); 077 078 gc.gridx = 1; 079 gc.weightx = 1.0; 080 pnl.add(new JMultilineLabel(tr("Select changesets depending on whether they are open or closed")), gc); 081 082 gc.gridy = 3; 083 gc.gridx = 1; 084 gc.weightx = 1.0; 085 pnl.add(pnlOpenAndCloseRestriction, gc); 086 087 // -- restricting the query to a specific time 088 // 089 gc.gridy = 4; 090 gc.gridx = 0; 091 gc.anchor = GridBagConstraints.NORTHWEST; 092 gc.weightx = 0.0; 093 gc.fill = GridBagConstraints.HORIZONTAL; 094 pnl.add(cbTimeRestrictions, gc); 095 cbTimeRestrictions.addItemListener(stateChangeHandler); 096 097 gc.gridx = 1; 098 gc.weightx = 1.0; 099 pnl.add(new JMultilineLabel(tr("Select changesets based on the date/time they have been created or closed")), gc); 100 101 gc.gridy = 5; 102 gc.gridx = 1; 103 gc.weightx = 1.0; 104 pnl.add(pnlTimeRestriction, gc); 105 106 107 // -- restricting the query to a specific bounding box 108 // 109 gc.gridy = 6; 110 gc.gridx = 0; 111 gc.anchor = GridBagConstraints.NORTHWEST; 112 gc.weightx = 0.0; 113 gc.fill = GridBagConstraints.HORIZONTAL; 114 pnl.add(cbBoundingBoxRestriction, gc); 115 cbBoundingBoxRestriction.addItemListener(stateChangeHandler); 116 117 gc.gridx = 1; 118 gc.weightx = 1.0; 119 pnl.add(new JMultilineLabel(tr("Select only changesets related to a specific bounding box")), gc); 120 121 gc.gridy = 7; 122 gc.gridx = 1; 123 gc.weightx = 1.0; 124 pnl.add(pnlBoundingBoxRestriction, gc); 125 126 127 gc.gridy = 8; 128 gc.gridx = 0; 129 gc.gridwidth = 2; 130 gc.fill = GridBagConstraints.BOTH; 131 gc.weightx = 1.0; 132 gc.weighty = 1.0; 133 pnl.add(new JPanel(), gc); 134 135 return pnl; 136 } 137 138 protected final void build() { 139 setLayout(new BorderLayout()); 140 JScrollPane spQueryPanel = GuiHelper.embedInVerticalScrollPane(buildQueryPanel()); 141 add(spQueryPanel, BorderLayout.CENTER); 142 } 143 144 /** 145 * Initializes HMI for user input. 146 */ 147 public void startUserInput() { 148 restoreFromSettings(); 149 pnlBoundingBoxRestriction.setVisible(cbBoundingBoxRestriction.isSelected()); 150 pnlOpenAndCloseRestriction.setVisible(cbOpenAndCloseRestrictions.isSelected()); 151 pnlTimeRestriction.setVisible(cbTimeRestrictions.isSelected()); 152 pnlUserRestriction.setVisible(cbUserRestriction.isSelected()); 153 pnlOpenAndCloseRestriction.startUserInput(); 154 pnlUserRestriction.startUserInput(); 155 pnlTimeRestriction.startUserInput(); 156 } 157 158 /** 159 * Display error message if a field is invalid. 160 */ 161 public void displayMessageIfInvalid() { 162 if (cbUserRestriction.isSelected()) { 163 if (!pnlUserRestriction.isValidChangesetQuery()) { 164 pnlUserRestriction.displayMessageIfInvalid(); 165 } 166 } else if (cbTimeRestrictions.isSelected()) { 167 if (!pnlTimeRestriction.isValidChangesetQuery()) { 168 pnlTimeRestriction.displayMessageIfInvalid(); 169 } 170 } else if (cbBoundingBoxRestriction.isSelected()) { 171 if (!pnlBoundingBoxRestriction.isValidChangesetQuery()) { 172 pnlBoundingBoxRestriction.displayMessageIfInvalid(); 173 } 174 } 175 } 176 177 /** 178 * Builds the changeset query based on the data entered in the form. 179 * 180 * @return the changeset query. null, if the data entered doesn't represent 181 * a valid changeset query. 182 */ 183 public ChangesetQuery buildChangesetQuery() { 184 ChangesetQuery query = new ChangesetQuery(); 185 if (cbUserRestriction.isSelected()) { 186 if (!pnlUserRestriction.isValidChangesetQuery()) 187 return null; 188 pnlUserRestriction.fillInQuery(query); 189 } 190 if (cbOpenAndCloseRestrictions.isSelected()) { 191 // don't have to check whether it's valid. It always is. 192 pnlOpenAndCloseRestriction.fillInQuery(query); 193 } 194 if (cbBoundingBoxRestriction.isSelected()) { 195 if (!pnlBoundingBoxRestriction.isValidChangesetQuery()) 196 return null; 197 pnlBoundingBoxRestriction.fillInQuery(query); 198 } 199 if (cbTimeRestrictions.isSelected()) { 200 if (!pnlTimeRestriction.isValidChangesetQuery()) 201 return null; 202 pnlTimeRestriction.fillInQuery(query); 203 } 204 return query; 205 } 206 207 /** 208 * Remember settings in preferences. 209 */ 210 public void rememberSettings() { 211 Main.pref.put("changeset-query.advanced.user-restrictions", cbUserRestriction.isSelected()); 212 Main.pref.put("changeset-query.advanced.open-restrictions", cbOpenAndCloseRestrictions.isSelected()); 213 Main.pref.put("changeset-query.advanced.time-restrictions", cbTimeRestrictions.isSelected()); 214 Main.pref.put("changeset-query.advanced.bbox-restrictions", cbBoundingBoxRestriction.isSelected()); 215 216 pnlUserRestriction.rememberSettings(); 217 pnlOpenAndCloseRestriction.rememberSettings(); 218 pnlTimeRestriction.rememberSettings(); 219 } 220 221 /** 222 * Restore settings from preferences. 223 */ 224 public void restoreFromSettings() { 225 cbUserRestriction.setSelected(Main.pref.getBoolean("changeset-query.advanced.user-restrictions", false)); 226 cbOpenAndCloseRestrictions.setSelected(Main.pref.getBoolean("changeset-query.advanced.open-restrictions", false)); 227 cbTimeRestrictions.setSelected(Main.pref.getBoolean("changeset-query.advanced.time-restrictions", false)); 228 cbBoundingBoxRestriction.setSelected(Main.pref.getBoolean("changeset-query.advanced.bbox-restrictions", false)); 229 } 230 231 class RestrictionGroupStateChangeHandler implements ItemListener { 232 protected void userRestrictionStateChanged() { 233 if (pnlUserRestriction == null) 234 return; 235 pnlUserRestriction.setVisible(cbUserRestriction.isSelected()); 236 } 237 238 protected void openCloseRestrictionStateChanged() { 239 if (pnlOpenAndCloseRestriction == null) 240 return; 241 pnlOpenAndCloseRestriction.setVisible(cbOpenAndCloseRestrictions.isSelected()); 242 } 243 244 protected void timeRestrictionsStateChanged() { 245 if (pnlTimeRestriction == null) 246 return; 247 pnlTimeRestriction.setVisible(cbTimeRestrictions.isSelected()); 248 } 249 250 protected void boundingBoxRestrictionChanged() { 251 if (pnlBoundingBoxRestriction == null) 252 return; 253 pnlBoundingBoxRestriction.setVisible(cbBoundingBoxRestriction.isSelected()); 254 } 255 256 @Override 257 public void itemStateChanged(ItemEvent e) { 258 if (e.getSource() == cbUserRestriction) { 259 userRestrictionStateChanged(); 260 } else if (e.getSource() == cbOpenAndCloseRestrictions) { 261 openCloseRestrictionStateChanged(); 262 } else if (e.getSource() == cbTimeRestrictions) { 263 timeRestrictionsStateChanged(); 264 } else if (e.getSource() == cbBoundingBoxRestriction) { 265 boundingBoxRestrictionChanged(); 266 } 267 validate(); 268 repaint(); 269 } 270 } 271}