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.Color; 007import java.awt.GridBagConstraints; 008import java.awt.GridBagLayout; 009import java.awt.Insets; 010import java.awt.event.ItemEvent; 011import java.awt.event.ItemListener; 012 013import javax.swing.BorderFactory; 014import javax.swing.ButtonGroup; 015import javax.swing.JLabel; 016import javax.swing.JOptionPane; 017import javax.swing.JPanel; 018import javax.swing.JRadioButton; 019 020import org.openstreetmap.josm.data.UserIdentityManager; 021import org.openstreetmap.josm.gui.HelpAwareOptionPane; 022import org.openstreetmap.josm.gui.help.HelpUtil; 023import org.openstreetmap.josm.gui.preferences.server.UserNameValidator; 024import org.openstreetmap.josm.gui.widgets.JMultilineLabel; 025import org.openstreetmap.josm.gui.widgets.JosmTextField; 026import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator; 027import org.openstreetmap.josm.io.ChangesetQuery; 028import org.openstreetmap.josm.spi.preferences.Config; 029import org.openstreetmap.josm.tools.CheckParameterUtil; 030 031/** 032 * This is the panel for selecting whether the query should be restricted to a specific user. 033 * @since 11326 (extracted from AdvancedChangesetQueryPanel) 034 */ 035public class UserRestrictionPanel extends JPanel implements RestrictionPanel { 036 private static final String PREF_ROOT = "changeset-query.advanced.user-restrictions"; 037 private static final String PREF_QUERY_TYPE = PREF_ROOT + ".query-type"; 038 039 private final ButtonGroup bgUserRestrictions = new ButtonGroup(); 040 private final JRadioButton rbRestrictToMyself = new JRadioButton(); 041 private final JRadioButton rbRestrictToUid = new JRadioButton(); 042 private final JRadioButton rbRestrictToUserName = new JRadioButton(); 043 private final JosmTextField tfUid = new JosmTextField(10); 044 private transient UidInputFieldValidator valUid; 045 private final JosmTextField tfUserName = new JosmTextField(10); 046 private transient UserNameValidator valUserName; 047 private final JMultilineLabel lblRestrictedToMyself = new JMultilineLabel(tr("Only changesets owned by myself")); 048 049 /** 050 * Constructs a new {@code UserRestrictionPanel}. 051 */ 052 public UserRestrictionPanel() { 053 build(); 054 } 055 056 protected JPanel buildUidInputPanel() { 057 JPanel pnl = new JPanel(new GridBagLayout()); 058 GridBagConstraints gc = new GridBagConstraints(); 059 gc.fill = GridBagConstraints.HORIZONTAL; 060 gc.weightx = 0.0; 061 gc.insets = new Insets(0, 0, 0, 3); 062 pnl.add(new JLabel(tr("User ID:")), gc); 063 064 gc.gridx = 1; 065 pnl.add(tfUid, gc); 066 SelectAllOnFocusGainedDecorator.decorate(tfUid); 067 valUid = UidInputFieldValidator.decorate(tfUid); 068 069 // grab remaining space 070 gc.gridx = 2; 071 gc.weightx = 1.0; 072 pnl.add(new JPanel(), gc); 073 return pnl; 074 } 075 076 protected JPanel buildUserNameInputPanel() { 077 JPanel pnl = new JPanel(new GridBagLayout()); 078 GridBagConstraints gc = new GridBagConstraints(); 079 gc.fill = GridBagConstraints.HORIZONTAL; 080 gc.weightx = 0.0; 081 gc.insets = new Insets(0, 0, 0, 3); 082 pnl.add(new JLabel(tr("User name:")), gc); 083 084 gc.gridx = 1; 085 pnl.add(tfUserName, gc); 086 SelectAllOnFocusGainedDecorator.decorate(tfUserName); 087 valUserName = new UserNameValidator(tfUserName); 088 089 // grab remaining space 090 gc.gridx = 2; 091 gc.weightx = 1.0; 092 pnl.add(new JPanel(), gc); 093 return pnl; 094 } 095 096 protected void build() { 097 setLayout(new GridBagLayout()); 098 setBorder(BorderFactory.createCompoundBorder( 099 BorderFactory.createEmptyBorder(3, 3, 3, 3), 100 BorderFactory.createCompoundBorder( 101 BorderFactory.createLineBorder(Color.GRAY), 102 BorderFactory.createEmptyBorder(5, 5, 5, 5) 103 ) 104 )); 105 106 ItemListener userRestrictionChangeHandler = new UserRestrictionChangedHandler(); 107 GridBagConstraints gc = new GridBagConstraints(); 108 gc.anchor = GridBagConstraints.NORTHWEST; 109 gc.gridx = 0; 110 gc.fill = GridBagConstraints.HORIZONTAL; 111 gc.weightx = 0.0; 112 add(rbRestrictToMyself, gc); 113 rbRestrictToMyself.addItemListener(userRestrictionChangeHandler); 114 115 gc.gridx = 1; 116 gc.fill = GridBagConstraints.HORIZONTAL; 117 gc.weightx = 1.0; 118 add(lblRestrictedToMyself, gc); 119 120 gc.gridx = 0; 121 gc.gridy = 1; 122 gc.fill = GridBagConstraints.HORIZONTAL; 123 gc.weightx = 0.0; 124 add(rbRestrictToUid, gc); 125 rbRestrictToUid.addItemListener(userRestrictionChangeHandler); 126 127 gc.gridx = 1; 128 gc.fill = GridBagConstraints.HORIZONTAL; 129 gc.weightx = 1.0; 130 add(new JMultilineLabel(tr("Only changesets owned by the user with the following user ID")), gc); 131 132 gc.gridx = 1; 133 gc.gridy = 2; 134 gc.fill = GridBagConstraints.HORIZONTAL; 135 gc.weightx = 1.0; 136 add(buildUidInputPanel(), gc); 137 138 gc.gridx = 0; 139 gc.gridy = 3; 140 gc.fill = GridBagConstraints.HORIZONTAL; 141 gc.weightx = 0.0; 142 add(rbRestrictToUserName, gc); 143 rbRestrictToUserName.addItemListener(userRestrictionChangeHandler); 144 145 gc.gridx = 1; 146 gc.fill = GridBagConstraints.HORIZONTAL; 147 gc.weightx = 1.0; 148 add(new JMultilineLabel(tr("Only changesets owned by the user with the following user name")), gc); 149 150 gc.gridx = 1; 151 gc.gridy = 4; 152 gc.fill = GridBagConstraints.HORIZONTAL; 153 gc.weightx = 1.0; 154 add(buildUserNameInputPanel(), gc); 155 156 bgUserRestrictions.add(rbRestrictToMyself); 157 bgUserRestrictions.add(rbRestrictToUid); 158 bgUserRestrictions.add(rbRestrictToUserName); 159 } 160 161 /** 162 * Initializes HMI for user input. 163 */ 164 public void startUserInput() { 165 if (UserIdentityManager.getInstance().isAnonymous()) { 166 lblRestrictedToMyself.setText(tr("Only changesets owned by myself (disabled. JOSM is currently run by an anonymous user)")); 167 rbRestrictToMyself.setEnabled(false); 168 if (rbRestrictToMyself.isSelected()) { 169 rbRestrictToUid.setSelected(true); 170 } 171 } else { 172 lblRestrictedToMyself.setText(tr("Only changesets owned by myself")); 173 rbRestrictToMyself.setEnabled(true); 174 rbRestrictToMyself.setSelected(true); 175 } 176 restoreFromSettings(); 177 } 178 179 /** 180 * Sets the query restrictions on <code>query</code> for changeset owner based restrictions. 181 * 182 * @param query the query. Must not be null. 183 * @throws IllegalArgumentException if query is null 184 * @throws IllegalStateException if one of the available values for query parameters in this panel isn't valid 185 */ 186 @Override 187 public void fillInQuery(ChangesetQuery query) { 188 CheckParameterUtil.ensureParameterNotNull(query, "query"); 189 if (rbRestrictToMyself.isSelected()) { 190 UserIdentityManager im = UserIdentityManager.getInstance(); 191 if (im.isPartiallyIdentified()) { 192 query.forUser(im.getUserName()); 193 } else if (im.isFullyIdentified()) { 194 query.forUser(im.getUserId()); 195 } else 196 throw new IllegalStateException( 197 tr("Cannot restrict changeset query to the current user because the current user is anonymous")); 198 } else if (rbRestrictToUid.isSelected()) { 199 int uid = valUid.getUid(); 200 if (uid > 0) { 201 query.forUser(uid); 202 } else 203 throw new IllegalStateException(tr("Current value ''{0}'' for user ID is not valid", tfUid.getText())); 204 } else if (rbRestrictToUserName.isSelected()) { 205 if (!valUserName.isValid()) 206 throw new IllegalStateException( 207 tr("Cannot restrict the changeset query to the user name ''{0}''", tfUserName.getText())); 208 query.forUser(tfUserName.getText()); 209 } 210 } 211 212 /** 213 * Determines if the changeset query time information is valid. 214 * @return {@code true} if the changeset query time information is valid. 215 */ 216 @Override 217 public boolean isValidChangesetQuery() { 218 if (rbRestrictToUid.isSelected()) 219 return valUid.isValid(); 220 else if (rbRestrictToUserName.isSelected()) 221 return valUserName.isValid(); 222 return true; 223 } 224 225 protected void alertInvalidUid() { 226 HelpAwareOptionPane.showOptionDialog( 227 this, 228 tr("Please enter a valid user ID"), 229 tr("Invalid user ID"), 230 JOptionPane.ERROR_MESSAGE, 231 HelpUtil.ht("/Dialog/ChangesetQueryDialog#InvalidUserId") 232 ); 233 } 234 235 protected void alertInvalidUserName() { 236 HelpAwareOptionPane.showOptionDialog( 237 this, 238 tr("Please enter a non-empty user name"), 239 tr("Invalid user name"), 240 JOptionPane.ERROR_MESSAGE, 241 HelpUtil.ht("/Dialog/ChangesetQueryDialog#InvalidUserName") 242 ); 243 } 244 245 @Override 246 public void displayMessageIfInvalid() { 247 if (rbRestrictToUid.isSelected()) { 248 if (!valUid.isValid()) { 249 alertInvalidUid(); 250 } 251 } else if (rbRestrictToUserName.isSelected()) { 252 if (!valUserName.isValid()) { 253 alertInvalidUserName(); 254 } 255 } 256 } 257 258 /** 259 * Remember settings in preferences. 260 */ 261 public void rememberSettings() { 262 if (rbRestrictToMyself.isSelected()) { 263 Config.getPref().put(PREF_QUERY_TYPE, "mine"); 264 } else if (rbRestrictToUid.isSelected()) { 265 Config.getPref().put(PREF_QUERY_TYPE, "uid"); 266 } else if (rbRestrictToUserName.isSelected()) { 267 Config.getPref().put(PREF_QUERY_TYPE, "username"); 268 } 269 Config.getPref().put(PREF_ROOT + ".uid", tfUid.getText()); 270 Config.getPref().put(PREF_ROOT + ".username", tfUserName.getText()); 271 } 272 273 /** 274 * Restore settings from preferences. 275 */ 276 public void restoreFromSettings() { 277 String v = Config.getPref().get(PREF_QUERY_TYPE, "mine"); 278 if ("mine".equals(v)) { 279 UserIdentityManager im = UserIdentityManager.getInstance(); 280 if (im.isAnonymous()) { 281 rbRestrictToUid.setSelected(true); 282 } else { 283 rbRestrictToMyself.setSelected(true); 284 } 285 } else if ("uid".equals(v)) { 286 rbRestrictToUid.setSelected(true); 287 } else if ("username".equals(v)) { 288 rbRestrictToUserName.setSelected(true); 289 } 290 tfUid.setText(Config.getPref().get(PREF_ROOT + ".uid", "")); 291 if (!valUid.isValid()) { 292 tfUid.setText(""); 293 } 294 tfUserName.setText(Config.getPref().get(PREF_ROOT + ".username", "")); 295 } 296 297 class UserRestrictionChangedHandler implements ItemListener { 298 @Override 299 public void itemStateChanged(ItemEvent e) { 300 tfUid.setEnabled(rbRestrictToUid.isSelected()); 301 tfUserName.setEnabled(rbRestrictToUserName.isSelected()); 302 if (rbRestrictToUid.isSelected()) { 303 tfUid.requestFocusInWindow(); 304 } else if (rbRestrictToUserName.isSelected()) { 305 tfUserName.requestFocusInWindow(); 306 } 307 } 308 } 309}