source: josm/trunk/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorizationWizard.java@ 3501

Last change on this file since 3501 was 3501, checked in by bastiK, 14 years ago

fixed #4632 - Button Help puts help window under main window

  • Property svn:eol-style set to native
File size: 14.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.oauth;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Component;
8import java.awt.Dimension;
9import java.awt.FlowLayout;
10import java.awt.Font;
11import java.awt.GridBagConstraints;
12import java.awt.GridBagLayout;
13import java.awt.Insets;
14import java.awt.event.ActionEvent;
15import java.awt.event.ComponentEvent;
16import java.awt.event.ComponentListener;
17import java.awt.event.ItemEvent;
18import java.awt.event.ItemListener;
19import java.awt.event.KeyEvent;
20import java.awt.event.WindowAdapter;
21import java.awt.event.WindowEvent;
22import java.beans.PropertyChangeEvent;
23import java.beans.PropertyChangeListener;
24import java.util.logging.Logger;
25
26import javax.swing.AbstractAction;
27import javax.swing.BorderFactory;
28import javax.swing.JComponent;
29import javax.swing.JDialog;
30import javax.swing.JLabel;
31import javax.swing.JOptionPane;
32import javax.swing.JPanel;
33import javax.swing.JScrollPane;
34import javax.swing.KeyStroke;
35import javax.swing.UIManager;
36import javax.swing.event.HyperlinkEvent;
37import javax.swing.event.HyperlinkListener;
38
39import org.openstreetmap.josm.Main;
40import org.openstreetmap.josm.data.oauth.OAuthParameters;
41import org.openstreetmap.josm.data.oauth.OAuthToken;
42import org.openstreetmap.josm.gui.SideButton;
43import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
44import org.openstreetmap.josm.gui.help.HelpUtil;
45import org.openstreetmap.josm.gui.widgets.HtmlPanel;
46import org.openstreetmap.josm.tools.CheckParameterUtil;
47import org.openstreetmap.josm.tools.ImageProvider;
48import org.openstreetmap.josm.tools.OpenBrowser;
49import org.openstreetmap.josm.tools.WindowGeometry;
50
51/**
52 * This wizard walks the user to the necessary steps to retrieve an OAuth Access Token which
53 * allows JOSM to access the OSM API on the users behalf.
54 *
55 */
56public class OAuthAuthorizationWizard extends JDialog {
57 @SuppressWarnings("unused")
58 static private final Logger logger = Logger.getLogger(OAuthAuthorizationWizard.class.getName());
59
60 private HtmlPanel pnlMessage;
61 private boolean canceled;
62 private String apiUrl;
63
64 private AuthorizationProcedureComboBox cbAuthorisationProcedure;
65 private FullyAutomaticAuthorizationUI pnlFullyAutomaticAuthorisationUI;
66 private SemiAutomaticAuthorizationUI pnlSemiAutomaticAuthorisationUI;
67 private ManualAuthorizationUI pnlManualAuthorisationUI;
68 private JScrollPane spAuthorisationProcedureUI;
69
70 /**
71 * Builds the row with the action buttons
72 *
73 * @return
74 */
75 protected JPanel buildButtonRow(){
76 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
77
78 AcceptAccessTokenAction actAcceptAccessToken = new AcceptAccessTokenAction();
79 pnlFullyAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
80 pnlSemiAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
81 pnlManualAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
82
83 pnl.add(new SideButton(actAcceptAccessToken));
84 pnl.add(new SideButton(new CancelAction()));
85 pnl.add(new SideButton(new ContextSensitiveHelpAction(HelpUtil.ht("/Dialog/OAuthAuthorisationWizard"))));
86
87 return pnl;
88 }
89
90 /**
91 * Builds the panel with general information in the header
92 *
93 * @return
94 */
95 protected JPanel buildHeaderInfoPanel() {
96 JPanel pnl = new JPanel(new GridBagLayout());
97 pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
98 GridBagConstraints gc = new GridBagConstraints();
99
100 // the oauth logo in the header
101 gc.anchor = GridBagConstraints.NORTHWEST;
102 gc.fill = GridBagConstraints.HORIZONTAL;
103 gc.weightx = 1.0;
104 gc.gridwidth = 2;
105 JLabel lbl = new JLabel();
106 lbl.setIcon(ImageProvider.get("oauth", "oauth-logo"));
107 lbl.setOpaque(true);
108 pnl.add(lbl, gc);
109
110 // OAuth in a nutshell ...
111 gc.gridy = 1;
112 gc.insets = new Insets(5,0,0,5);
113 pnlMessage = new HtmlPanel();
114 pnlMessage.setText("<html><body>"
115 + tr("With OAuth you grant JOSM the right to upload map data and GPS tracks "
116 + "on your behalf (<a href=\"{0}\">more info...</a>).", "http://oauth.net/")
117 + "</body></html>"
118 );
119 pnlMessage.getEditorPane().addHyperlinkListener(new ExternalBrowserLauncher());
120 pnl.add(pnlMessage, gc);
121
122 // the authorisation procedure
123 gc.gridy = 2;
124 gc.gridwidth = 1;
125 gc.weightx = 0.0;
126 lbl = new JLabel(tr("Please select an authorization procedure: "));
127 lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));
128 pnl.add(lbl,gc);
129
130 gc.gridx = 1;
131 gc.gridwidth = 1;
132 gc.weightx = 1.0;
133 pnl.add(cbAuthorisationProcedure = new AuthorizationProcedureComboBox(),gc);
134 cbAuthorisationProcedure.addItemListener(new AuthorisationProcedureChangeListener());
135 return pnl;
136 }
137
138 /**
139 * Refreshes the view of the authorisation panel, depending on the authorisation procedure
140 * currently selected
141 */
142 protected void refreshAuthorisationProcedurePanel() {
143 AuthorizationProcedure procedure = (AuthorizationProcedure)cbAuthorisationProcedure.getSelectedItem();
144 switch(procedure) {
145 case FULLY_AUTOMATIC:
146 spAuthorisationProcedureUI.getViewport().setView(pnlFullyAutomaticAuthorisationUI);
147 pnlFullyAutomaticAuthorisationUI.revalidate();
148 break;
149 case SEMI_AUTOMATIC:
150 spAuthorisationProcedureUI.getViewport().setView(pnlSemiAutomaticAuthorisationUI);
151 pnlSemiAutomaticAuthorisationUI.revalidate();
152 break;
153 case MANUALLY:
154 spAuthorisationProcedureUI.getViewport().setView(pnlManualAuthorisationUI);
155 pnlManualAuthorisationUI.revalidate();
156 break;
157 }
158 validate();
159 repaint();
160 }
161
162 /**
163 * builds the UI
164 */
165 protected void build() {
166 getContentPane().setLayout(new BorderLayout());
167 getContentPane().add(buildHeaderInfoPanel(), BorderLayout.NORTH);
168
169 pnlFullyAutomaticAuthorisationUI = new FullyAutomaticAuthorizationUI();
170 pnlFullyAutomaticAuthorisationUI.setApiUrl(apiUrl);
171
172 pnlSemiAutomaticAuthorisationUI = new SemiAutomaticAuthorizationUI();
173 pnlSemiAutomaticAuthorisationUI.setApiUrl(apiUrl);
174
175 pnlManualAuthorisationUI = new ManualAuthorizationUI();
176 pnlManualAuthorisationUI.setApiUrl(apiUrl);
177
178 spAuthorisationProcedureUI = new JScrollPane(new JPanel());
179 spAuthorisationProcedureUI.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
180 spAuthorisationProcedureUI.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
181 spAuthorisationProcedureUI.getVerticalScrollBar().addComponentListener(
182 new ComponentListener() {
183 public void componentShown(ComponentEvent e) {
184 spAuthorisationProcedureUI.setBorder(UIManager.getBorder("ScrollPane.border"));
185 }
186
187 public void componentHidden(ComponentEvent e) {
188 spAuthorisationProcedureUI.setBorder(null);
189 }
190
191 public void componentResized(ComponentEvent e) {}
192 public void componentMoved(ComponentEvent e) {}
193 }
194 );
195 getContentPane().add(spAuthorisationProcedureUI, BorderLayout.CENTER);
196 getContentPane().add(buildButtonRow(), BorderLayout.SOUTH);
197
198 addWindowListener(new WindowEventHandler());
199 getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel");
200 getRootPane().getActionMap().put("cancel", new CancelAction());
201
202 refreshAuthorisationProcedurePanel();
203
204 HelpUtil.setHelpContext(getRootPane(), HelpUtil.ht("/Dialog/OAuthAuthorisationWizard"));
205 }
206
207 /**
208 * Creates the wizard.
209 *
210 * @param apiUrl the API URL. Must not be null.
211 * @throws IllegalArgumentException thrown if apiUrl is null
212 */
213 public OAuthAuthorizationWizard(String apiUrl) throws IllegalArgumentException {
214 super(JOptionPane.getFrameForComponent(Main.parent), ModalityType.DOCUMENT_MODAL);
215 CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
216 build();
217 setApiUrl(apiUrl);
218 }
219
220 /**
221 * Creates the wizard.
222 *
223 * @param parent the component relative to which the dialog is displayed
224 * @param apiUrl the API URL. Must not be null.
225 * @throws IllegalArgumentException thrown if apiUrl is null
226 */
227 public OAuthAuthorizationWizard(Component parent, String apiUrl) {
228 super(JOptionPane.getFrameForComponent(parent), ModalityType.DOCUMENT_MODAL);
229 CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
230 build();
231 setApiUrl(apiUrl);
232 }
233
234 /**
235 * Sets the API URL for the API for which this wizard is generating
236 * an Access Token.
237 *
238 * @param apiUrl the API URL. Must not be null.
239 * @throws IllegalArgumentException thrown if apiUrl is null
240 */
241 public void setApiUrl(String apiUrl) throws IllegalArgumentException{
242 CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
243 this.apiUrl = apiUrl;
244 setTitle(tr("Get an Access Token for ''{0}''", apiUrl));
245 if (pnlFullyAutomaticAuthorisationUI != null) {
246 pnlFullyAutomaticAuthorisationUI.setApiUrl(apiUrl);
247 }
248 if (pnlSemiAutomaticAuthorisationUI != null) {
249 pnlSemiAutomaticAuthorisationUI.setApiUrl(apiUrl);
250 }
251 if (pnlManualAuthorisationUI != null) {
252 pnlManualAuthorisationUI.setApiUrl(apiUrl);
253 }
254 }
255
256 /**
257 * Replies true if the dialog was cancelled
258 *
259 * @return true if the dialog was cancelled
260 */
261 public boolean isCanceled() {
262 return canceled;
263 }
264
265 protected AbstractAuthorizationUI getCurrentAuthorisationUI() {
266 switch((AuthorizationProcedure)cbAuthorisationProcedure.getSelectedItem()) {
267 case FULLY_AUTOMATIC: return pnlFullyAutomaticAuthorisationUI;
268 case MANUALLY: return pnlManualAuthorisationUI;
269 case SEMI_AUTOMATIC: return pnlSemiAutomaticAuthorisationUI;
270 default: return null;
271 }
272 }
273
274 /**
275 * Replies the Access Token entered using the wizard
276 *
277 * @return the access token. May be null if the wizard was canceled.
278 */
279 public OAuthToken getAccessToken() {
280 return getCurrentAuthorisationUI().getAccessToken();
281 }
282
283 /**
284 * Replies the current OAuth parameters.
285 *
286 * @return the current OAuth parameters.
287 */
288 public OAuthParameters getOAuthParameters() {
289 return getCurrentAuthorisationUI().getOAuthParameters();
290 }
291
292 /**
293 * Replies true if the currently selected Access Token shall be saved to
294 * the preferences.
295 *
296 * @return true if the currently selected Access Token shall be saved to
297 * the preferences
298 */
299 public boolean isSaveAccessTokenToPreferences() {
300 return getCurrentAuthorisationUI().isSaveAccessTokenToPreferences();
301 }
302
303 /**
304 * Initializes the dialog with values from the preferences
305 *
306 */
307 public void initFromPreferences() {
308 pnlFullyAutomaticAuthorisationUI.initFromPreferences(Main.pref);
309 pnlSemiAutomaticAuthorisationUI.initFromPreferences(Main.pref);
310 pnlManualAuthorisationUI.initFromPreferences(Main.pref);
311 }
312
313 @Override
314 public void setVisible(boolean visible) {
315 if (visible) {
316 new WindowGeometry(
317 getClass().getName() + ".geometry",
318 WindowGeometry.centerInWindow(
319 Main.parent,
320 new Dimension(450,540)
321 )
322 ).applySafe(this);
323 initFromPreferences();
324 } else if (!visible && isShowing()){
325 new WindowGeometry(this).remember(getClass().getName() + ".geometry");
326 }
327 super.setVisible(visible);
328 }
329
330 protected void setCanceled(boolean canceled) {
331 this.canceled = canceled;
332 }
333
334 class AuthorisationProcedureChangeListener implements ItemListener {
335 public void itemStateChanged(ItemEvent arg0) {
336 refreshAuthorisationProcedurePanel();
337 }
338 }
339
340 class CancelAction extends AbstractAction {
341 public CancelAction() {
342 putValue(NAME, tr("Cancel"));
343 putValue(SMALL_ICON, ImageProvider.get("cancel"));
344 putValue(SHORT_DESCRIPTION, tr("Close the dialog and cancel authorization"));
345 }
346
347 public void cancel() {
348 setCanceled(true);
349 setVisible(false);
350 }
351
352 public void actionPerformed(ActionEvent evt) {
353 cancel();
354 }
355 }
356
357 class AcceptAccessTokenAction extends AbstractAction implements PropertyChangeListener {
358 private OAuthToken token;
359
360 public AcceptAccessTokenAction() {
361 putValue(NAME, tr("Accept Access Token"));
362 putValue(SMALL_ICON, ImageProvider.get("ok"));
363 putValue(SHORT_DESCRIPTION, tr("Close the dialog and accept the Access Token"));
364 updateEnabledState(null);
365 }
366
367 public void actionPerformed(ActionEvent evt) {
368 setCanceled(false);
369 setVisible(false);
370 }
371
372 public void updateEnabledState(OAuthToken token) {
373 setEnabled(token != null);
374 }
375
376 public void propertyChange(PropertyChangeEvent evt) {
377 if (!evt.getPropertyName().equals(AbstractAuthorizationUI.ACCESS_TOKEN_PROP))
378 return;
379 token = (OAuthToken)evt.getNewValue();
380 updateEnabledState(token);
381 }
382 }
383
384 class WindowEventHandler extends WindowAdapter {
385 @Override
386 public void windowClosing(WindowEvent arg0) {
387 new CancelAction().cancel();
388 }
389 }
390
391 static class ExternalBrowserLauncher implements HyperlinkListener {
392 public void hyperlinkUpdate(HyperlinkEvent e) {
393 if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) {
394 String url = e.getDescription();
395 OpenBrowser.displayUrl(url);
396 }
397 }
398 }
399}
Note: See TracBrowser for help on using the repository browser.