|
1 /* |
|
2 * Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 package com.nokia.mj.impl.installer.ui.eswt2; |
|
20 |
|
21 import org.eclipse.swt.SWT; |
|
22 import org.eclipse.swt.events.DisposeEvent; |
|
23 import org.eclipse.swt.events.DisposeListener; |
|
24 import org.eclipse.swt.events.FocusEvent; |
|
25 import org.eclipse.swt.events.FocusListener; |
|
26 import org.eclipse.swt.events.KeyEvent; |
|
27 import org.eclipse.swt.events.KeyListener; |
|
28 import org.eclipse.swt.events.SelectionEvent; |
|
29 import org.eclipse.swt.events.SelectionListener; |
|
30 import org.eclipse.swt.graphics.Point; |
|
31 import org.eclipse.swt.graphics.Rectangle; |
|
32 import org.eclipse.swt.layout.GridData; |
|
33 import org.eclipse.swt.widgets.Composite; |
|
34 import org.eclipse.swt.widgets.Control; |
|
35 import org.eclipse.swt.widgets.Button; |
|
36 |
|
37 /** |
|
38 * Base class for confirmation views. |
|
39 */ |
|
40 abstract public class ConfirmationViewBase extends ViewBase |
|
41 { |
|
42 protected Button iOkCommand = null; |
|
43 protected Button iCancelCommand = null; |
|
44 private KeyListener iViewKeyListener = null; |
|
45 private KeyListener iSoftKeyListener = null; |
|
46 private String iOkText = InstallerUiTexts.get(InstallerUiTexts.OK); |
|
47 private String iCancelText = InstallerUiTexts.get(InstallerUiTexts.CANCEL); |
|
48 private boolean iCancelled = false; |
|
49 private boolean iUserHasAnswered = false; |
|
50 /** Object for thread synchronization. */ |
|
51 private Object iSynchObject = new Object(); |
|
52 |
|
53 /** Constructor */ |
|
54 protected ConfirmationViewBase() |
|
55 { |
|
56 super(); |
|
57 } |
|
58 |
|
59 /** Constructor */ |
|
60 protected ConfirmationViewBase(InstallerUiEswt aInstaller, Composite aParent, int aColumns) |
|
61 { |
|
62 this(aInstaller, aParent, aColumns, false); |
|
63 } |
|
64 |
|
65 /** Constructor */ |
|
66 protected ConfirmationViewBase(InstallerUiEswt aInstaller, Composite aParent, int aColumns, boolean aScrollable) |
|
67 { |
|
68 super(aInstaller, aParent, aColumns, aScrollable); |
|
69 } |
|
70 |
|
71 /** |
|
72 * Set user visible command names for OK and Cancel commands. |
|
73 * If either parameter is null, then default value is used. |
|
74 */ |
|
75 public void setCommands(String aOkText, String aCancelText) |
|
76 { |
|
77 iOkText = aOkText; |
|
78 iCancelText = aCancelText; |
|
79 } |
|
80 |
|
81 /** |
|
82 * Synchoronous method for asking user confirmation. |
|
83 * This method will call createView() before opening the view |
|
84 * and getDataFromView() after user has answered. |
|
85 */ |
|
86 public boolean confirm() |
|
87 { |
|
88 if (isDisposed()) |
|
89 { |
|
90 return false; |
|
91 } |
|
92 // Open the dialog from the UI thread. |
|
93 getComposite().getDisplay().syncExec |
|
94 (new Runnable() |
|
95 { |
|
96 public void run() |
|
97 { |
|
98 if (iOkCommand == null && iCancelCommand == null) |
|
99 { |
|
100 createView(); |
|
101 createCommands(); |
|
102 setDefaultCommand(); |
|
103 } |
|
104 setVisible(true); |
|
105 } |
|
106 }); |
|
107 // The UI thread must not be blocked. Let's wait for the answer |
|
108 // in the client thread. |
|
109 synchronized (iSynchObject) |
|
110 { |
|
111 try |
|
112 { |
|
113 iSynchObject.wait(); |
|
114 } |
|
115 catch (InterruptedException ie) |
|
116 { |
|
117 // Ignore silently. |
|
118 } |
|
119 } |
|
120 if (commandDisposed()) |
|
121 { |
|
122 // Widget got disposed, no confirmation available. |
|
123 return false; |
|
124 } |
|
125 // Hide the dialog. |
|
126 getComposite().getDisplay().syncExec |
|
127 (new Runnable() |
|
128 { |
|
129 public void run() |
|
130 { |
|
131 if (commandDisposed()) |
|
132 { |
|
133 return; |
|
134 } |
|
135 getDataFromView(); |
|
136 setVisible(false); |
|
137 } |
|
138 }); |
|
139 // And return the result to the client. |
|
140 boolean result = true; |
|
141 if (iCancelled) |
|
142 { |
|
143 result = false; |
|
144 } |
|
145 return result; |
|
146 } |
|
147 |
|
148 /** |
|
149 * Returns true if user has answered to this dialog. |
|
150 */ |
|
151 public boolean userHasAnswered() |
|
152 { |
|
153 return iUserHasAnswered; |
|
154 } |
|
155 |
|
156 /** |
|
157 * This method is called once before view is opened. |
|
158 * Inheriting class must implement this method. |
|
159 */ |
|
160 abstract protected void createView(); |
|
161 |
|
162 /** |
|
163 * This method is called after user has answered |
|
164 * to confirmation. |
|
165 * Inheriting class must implement this method. |
|
166 */ |
|
167 abstract protected void getDataFromView(); |
|
168 |
|
169 /** |
|
170 * Creates the commands for confirmation dialogs. |
|
171 */ |
|
172 private void createCommands() |
|
173 { |
|
174 if (iOkText == null && iCancelText == null) |
|
175 { |
|
176 return; |
|
177 } |
|
178 int horizontalSpan = 1; |
|
179 if (iOkText == null || iCancelText == null) |
|
180 { |
|
181 // Only one button, let it fill the whole composite width. |
|
182 horizontalSpan = 2; |
|
183 } |
|
184 |
|
185 if (iOkText != null) |
|
186 { |
|
187 iOkCommand = new Button(getCommandComposite(), SWT.PUSH); |
|
188 GridData gridData = new GridData(GridData.FILL_HORIZONTAL); |
|
189 gridData.horizontalSpan = horizontalSpan; |
|
190 iOkCommand.setLayoutData(gridData); |
|
191 iOkCommand.addDisposeListener(new DisposeListener() |
|
192 { |
|
193 public void widgetDisposed(DisposeEvent aEvent) |
|
194 { |
|
195 confirmCancel(); |
|
196 } |
|
197 }); |
|
198 iOkCommand.addSelectionListener(new SelectionListener() |
|
199 { |
|
200 public void widgetDefaultSelected(SelectionEvent aEvent) |
|
201 { |
|
202 widgetSelected(aEvent); |
|
203 } |
|
204 public void widgetSelected(SelectionEvent aEvent) |
|
205 { |
|
206 confirmOk(); |
|
207 } |
|
208 }); |
|
209 iOkCommand.addFocusListener(new FocusListener() |
|
210 { |
|
211 public void focusGained(FocusEvent aEvent) |
|
212 { |
|
213 okCommandFocused(aEvent); |
|
214 } |
|
215 public void focusLost(FocusEvent aEvent) |
|
216 { |
|
217 // nop |
|
218 } |
|
219 }); |
|
220 if (iOkText != null) |
|
221 { |
|
222 iOkCommand.setText(iOkText); |
|
223 } |
|
224 else |
|
225 { |
|
226 iOkCommand.setEnabled(false); |
|
227 } |
|
228 addSoftKeyListenerFor(iOkCommand); |
|
229 } |
|
230 |
|
231 if (iCancelText != null) |
|
232 { |
|
233 iCancelCommand = new Button(getCommandComposite(), SWT.PUSH); |
|
234 GridData gridData = new GridData(GridData.FILL_HORIZONTAL); |
|
235 gridData.horizontalSpan = horizontalSpan; |
|
236 iCancelCommand.setLayoutData(gridData); |
|
237 iCancelCommand.addDisposeListener(new DisposeListener() |
|
238 { |
|
239 public void widgetDisposed(DisposeEvent aEvent) |
|
240 { |
|
241 confirmCancel(); |
|
242 } |
|
243 }); |
|
244 iCancelCommand.addSelectionListener(new SelectionListener() |
|
245 { |
|
246 public void widgetDefaultSelected(SelectionEvent aEvent) |
|
247 { |
|
248 widgetSelected(aEvent); |
|
249 } |
|
250 public void widgetSelected(SelectionEvent aEvent) |
|
251 { |
|
252 confirmCancel(); |
|
253 } |
|
254 }); |
|
255 iCancelCommand.addFocusListener(new FocusListener() |
|
256 { |
|
257 public void focusGained(FocusEvent aEvent) |
|
258 { |
|
259 cancelCommandFocused(aEvent); |
|
260 } |
|
261 public void focusLost(FocusEvent aEvent) |
|
262 { |
|
263 // nop |
|
264 } |
|
265 }); |
|
266 if (iCancelText != null) |
|
267 { |
|
268 iCancelCommand.setText(iCancelText); |
|
269 } |
|
270 else |
|
271 { |
|
272 iCancelCommand.setEnabled(false); |
|
273 } |
|
274 addSoftKeyListenerFor(iCancelCommand); |
|
275 } |
|
276 |
|
277 // Add a KeyListener to handle selection key, LSK and RSK events. |
|
278 addViewKeyListenerFor(getContainer()); |
|
279 } |
|
280 |
|
281 /** |
|
282 * This method is called when user accepts the dialog. |
|
283 */ |
|
284 protected void confirmOk() |
|
285 { |
|
286 synchronized (iSynchObject) |
|
287 { |
|
288 iUserHasAnswered = true; |
|
289 iCancelled = false; |
|
290 iSynchObject.notify(); |
|
291 } |
|
292 } |
|
293 |
|
294 /** |
|
295 * This method is called when user cancels the dialog. |
|
296 */ |
|
297 protected void confirmCancel() |
|
298 { |
|
299 synchronized (iSynchObject) |
|
300 { |
|
301 iUserHasAnswered = true; |
|
302 iCancelled = true; |
|
303 iSynchObject.notify(); |
|
304 } |
|
305 } |
|
306 |
|
307 /** |
|
308 * Called after view and commands have been created. Subclasses |
|
309 * can overrride this method to set focus to their own default |
|
310 * commands. |
|
311 */ |
|
312 protected void setDefaultCommand() |
|
313 { |
|
314 if (iOkText != null) |
|
315 { |
|
316 iOkCommand.setFocus(); |
|
317 getShell().setDefaultButton(iOkCommand); |
|
318 } |
|
319 else |
|
320 { |
|
321 iCancelCommand.setFocus(); |
|
322 getShell().setDefaultButton(iCancelCommand); |
|
323 } |
|
324 } |
|
325 |
|
326 /** |
|
327 * Adds KeyListener for given control. This KeyListener handles |
|
328 * selection key, LSK and RSK. |
|
329 */ |
|
330 protected void addViewKeyListenerFor(Control aControl) |
|
331 { |
|
332 if (aControl == null) |
|
333 { |
|
334 return; |
|
335 } |
|
336 if (iViewKeyListener == null) |
|
337 { |
|
338 iViewKeyListener = new KeyListener() |
|
339 { |
|
340 public void keyPressed(KeyEvent aEvent) |
|
341 { |
|
342 switch (aEvent.keyCode) |
|
343 { |
|
344 case SWT.ARROW_UP: // up |
|
345 case SWT.ARROW_DOWN: // down |
|
346 case SWT.ARROW_LEFT: // left |
|
347 case SWT.ARROW_RIGHT: // right |
|
348 // When View has focus and user presses arrow |
|
349 // keys, set focus to the default command button. |
|
350 if (iOkText != null) |
|
351 { |
|
352 iOkCommand.setFocus(); |
|
353 } |
|
354 else |
|
355 { |
|
356 iCancelCommand.setFocus(); |
|
357 } |
|
358 break; |
|
359 case -5: // selection key |
|
360 selectionKeyPressed(aEvent); |
|
361 break; |
|
362 } |
|
363 } |
|
364 public void keyReleased(KeyEvent aEvent) |
|
365 { |
|
366 } |
|
367 }; |
|
368 } |
|
369 aControl.addKeyListener(iViewKeyListener); |
|
370 addSoftKeyListenerFor(aControl); |
|
371 } |
|
372 |
|
373 /** |
|
374 * Adds KeyListener for given control. This KeyListener handles |
|
375 * LSK and RSK. |
|
376 */ |
|
377 protected void addSoftKeyListenerFor(Control aControl) |
|
378 { |
|
379 if (aControl == null) |
|
380 { |
|
381 return; |
|
382 } |
|
383 if (iSoftKeyListener == null) |
|
384 { |
|
385 iSoftKeyListener = new KeyListener() |
|
386 { |
|
387 public void keyPressed(KeyEvent aEvent) |
|
388 { |
|
389 switch (aEvent.keyCode) |
|
390 { |
|
391 case -6: // LSK |
|
392 lskPressed(aEvent); |
|
393 break; |
|
394 case -7: // RSK |
|
395 rskPressed(aEvent); |
|
396 break; |
|
397 } |
|
398 } |
|
399 public void keyReleased(KeyEvent aEvent) |
|
400 { |
|
401 } |
|
402 }; |
|
403 } |
|
404 aControl.addKeyListener(iSoftKeyListener); |
|
405 } |
|
406 |
|
407 /** |
|
408 * Called when user presses selection key for the Shell. |
|
409 */ |
|
410 protected void selectionKeyPressed(KeyEvent aEvent) |
|
411 { |
|
412 if (iOkText != null) |
|
413 { |
|
414 confirmOk(); |
|
415 } |
|
416 else |
|
417 { |
|
418 confirmCancel(); |
|
419 } |
|
420 } |
|
421 |
|
422 /** |
|
423 * Called when user presses left soft key. |
|
424 */ |
|
425 protected void lskPressed(KeyEvent aEvent) |
|
426 { |
|
427 if (iOkText != null) |
|
428 { |
|
429 confirmOk(); |
|
430 } |
|
431 } |
|
432 |
|
433 /** |
|
434 * Called when user presses right soft key. |
|
435 */ |
|
436 protected void rskPressed(KeyEvent aEvent) |
|
437 { |
|
438 if (iCancelText != null) |
|
439 { |
|
440 confirmCancel(); |
|
441 } |
|
442 } |
|
443 |
|
444 /** |
|
445 * Called when the OK command gets focus. |
|
446 */ |
|
447 protected void okCommandFocused(FocusEvent aEvent) |
|
448 { |
|
449 } |
|
450 |
|
451 /** |
|
452 * Called when the Cancel command gets focus. |
|
453 */ |
|
454 protected void cancelCommandFocused(FocusEvent aEvent) |
|
455 { |
|
456 } |
|
457 |
|
458 /** |
|
459 * Returns true if a command from this view has been disposed. |
|
460 */ |
|
461 private boolean commandDisposed() |
|
462 { |
|
463 if ((iOkCommand != null && iOkCommand.isDisposed()) || |
|
464 (iCancelCommand != null && iCancelCommand.isDisposed())) |
|
465 { |
|
466 return true; |
|
467 } |
|
468 return false; |
|
469 } |
|
470 } |