KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > help > ui > internal > ContextHelpDialog


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.help.ui.internal;
12
13 import org.eclipse.core.runtime.Platform;
14 import org.eclipse.help.IContext;
15 import org.eclipse.help.IContext2;
16 import org.eclipse.help.IHelpResource;
17 import org.eclipse.help.UAContentFilter;
18 import org.eclipse.help.internal.base.BaseHelpSystem;
19 import org.eclipse.help.internal.base.HelpEvaluationContext;
20 import org.eclipse.help.ui.internal.views.HelpTray;
21 import org.eclipse.osgi.service.environment.Constants;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.accessibility.ACC;
24 import org.eclipse.swt.accessibility.Accessible;
25 import org.eclipse.swt.accessibility.AccessibleAdapter;
26 import org.eclipse.swt.accessibility.AccessibleControlAdapter;
27 import org.eclipse.swt.accessibility.AccessibleControlEvent;
28 import org.eclipse.swt.accessibility.AccessibleEvent;
29 import org.eclipse.swt.custom.BusyIndicator;
30 import org.eclipse.swt.custom.StyledText;
31 import org.eclipse.swt.events.ControlAdapter;
32 import org.eclipse.swt.events.ControlEvent;
33 import org.eclipse.swt.events.TraverseEvent;
34 import org.eclipse.swt.events.TraverseListener;
35 import org.eclipse.swt.graphics.Color;
36 import org.eclipse.swt.graphics.GC;
37 import org.eclipse.swt.graphics.Image;
38 import org.eclipse.swt.graphics.Point;
39 import org.eclipse.swt.graphics.Rectangle;
40 import org.eclipse.swt.layout.GridData;
41 import org.eclipse.swt.layout.GridLayout;
42 import org.eclipse.swt.widgets.Composite;
43 import org.eclipse.swt.widgets.Control;
44 import org.eclipse.swt.widgets.Display;
45 import org.eclipse.swt.widgets.Event;
46 import org.eclipse.swt.widgets.Label;
47 import org.eclipse.swt.widgets.Listener;
48 import org.eclipse.swt.widgets.Shell;
49 import org.eclipse.ui.IWorkbenchWindow;
50 import org.eclipse.ui.PlatformUI;
51
52 /**
53  * ContextHelpDialog
54  */

55 public class ContextHelpDialog {
56     //private static ImageRegistry imgRegistry = null;
57

58     private Color backgroundColour = null;
59
60     private IContext context;
61
62     private Color foregroundColour = null;
63
64     private Color linkColour = null;
65
66     private static HyperlinkHandler linkManager = new HyperlinkHandler();
67
68     protected Shell parentShell;
69
70     protected Shell shell;
71
72     protected String JavaDoc infopopText;
73
74     /**
75      * Listener for hyperlink selection.
76      */

77     class LinkListener extends HyperlinkAdapter {
78         IHelpResource topic;
79
80         public LinkListener(IHelpResource topic) {
81             this.topic = topic;
82         }
83
84         public void linkActivated(Control c) {
85             launchLinks(topic);
86         }
87
88     }
89
90     /**
91      * Constructor:
92      *
93      * @param context
94      * an array of String or an array of IContext
95      * @param x
96      * the x mouse location in the current display
97      * @param y
98      * the y mouse location in the current display
99      */

100     ContextHelpDialog(IContext context, int x, int y) {
101         this.context = context;
102         Display display = Display.getCurrent();
103         if (display == null) {
104             return;
105         }
106         backgroundColour = display.getSystemColor(SWT.COLOR_INFO_BACKGROUND);
107         foregroundColour = display.getSystemColor(SWT.COLOR_INFO_FOREGROUND);
108         linkColour = display.getSystemColor(SWT.COLOR_BLUE);
109         parentShell = display.getActiveShell();
110
111         if (parentShell != null) {
112             boolean isModal = 0 < (parentShell.getStyle() & (SWT.APPLICATION_MODAL
113                     | SWT.PRIMARY_MODAL | SWT.SYSTEM_MODAL));
114             if (HelpUIPlugin.DEBUG_INFOPOP) {
115                 System.out
116                         .println("ContextHelpDialog.ContextHelpDialog(): ParentShell: " //$NON-NLS-1$
117
+ parentShell.toString() + " is " //$NON-NLS-1$
118
+ (isModal ? "modal" : "modeless")); //$NON-NLS-1$ //$NON-NLS-2$
119
}
120         }
121
122         shell = new Shell(parentShell, SWT.NONE);
123         if (HelpUIPlugin.DEBUG_INFOPOP) {
124             System.out
125                     .println("ContextHelpDialog.ContextHelpDialog(): Shell is:" //$NON-NLS-1$
126
+ shell.toString());
127         }
128         PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IHelpUIConstants.F1_SHELL);
129
130         shell.addListener(SWT.Deactivate, new Listener() {
131             public void handleEvent(Event e) {
132                 if (HelpUIPlugin.DEBUG_INFOPOP) {
133                     System.out
134                             .println("ContextHelpDialog shell deactivate listener: SWT.Deactivate called. "); //$NON-NLS-1$
135
}
136                 close();
137             }
138         });
139
140         shell.addTraverseListener(new TraverseListener() {
141             public void keyTraversed(TraverseEvent e) {
142                 if (e.detail == SWT.TRAVERSE_ESCAPE) {
143                     if (HelpUIPlugin.DEBUG_INFOPOP) {
144                         System.out
145                                 .println("ContextHelpDialog: shell traverse listener: SWT.TRAVERSE_ESCAPE called. "); //$NON-NLS-1$
146
}
147                     e.doit = true;
148                 }
149             }
150         });
151
152         shell.addControlListener(new ControlAdapter() {
153             public void controlMoved(ControlEvent e) {
154                 if (HelpUIPlugin.DEBUG_INFOPOP) {
155                     System.out
156                             .println("ContextHelpDialog: shell control adapter called."); //$NON-NLS-1$
157
}
158                 Rectangle clientArea = shell.getClientArea();
159                 shell.redraw(clientArea.x, clientArea.y, clientArea.width,
160                         clientArea.height, true);
161                 shell.update();
162             }
163         });
164         if (HelpUIPlugin.DEBUG_INFOPOP) {
165             System.out
166                     .println("ContextHelpDialog.ContextHelpDialog(): Focus owner is: " //$NON-NLS-1$
167
+ Display.getCurrent().getFocusControl().toString());
168         }
169         linkManager
170                 .setHyperlinkUnderlineMode(HyperlinkHandler.UNDERLINE_ALWAYS);
171         createContents(shell);
172         shell.pack();
173         // Correct x and y of the shell if it not contained within the screen
174
int width = shell.getBounds().width;
175         int height = shell.getBounds().height;
176         
177         Rectangle screen = display.getClientArea();
178         // check lower boundaries
179
x = x >= screen.x ? x : screen.x;
180         y = y >= screen.y ? y : screen.y;
181         // check upper boundaries
182
x = x + width <= screen.width ? x : screen.width - width;
183         y = y + height <= screen.height ? y : screen.height - height;
184         shell.setLocation(x, y);
185
186         initAccessible(shell);
187     }
188
189     public synchronized void close() {
190         try {
191             if (HelpUIPlugin.DEBUG_INFOPOP) {
192                 System.out.println("ContextHelpDialog.close()"); //$NON-NLS-1$
193
}
194             if (shell != null) {
195                 shell.close();
196                 if (!shell.isDisposed())
197                     shell.dispose();
198                 shell = null;
199             }
200         } catch (Throwable JavaDoc ex) {
201         }
202     }
203
204     protected Control createContents(Composite contents) {
205         initAccessible(contents);
206         contents.setBackground(backgroundColour);
207         GridLayout layout = new GridLayout();
208         layout.marginHeight = 5;
209         layout.marginWidth = 5;
210         contents.setLayout(layout);
211         contents.setLayoutData(new GridData(GridData.FILL_BOTH));
212         // create the dialog area and button bar
213
createInfoArea(contents);
214         Control c = createLinksArea(contents);
215         if (c != null) {
216             // links exist, make them the only focusable controls
217
contents.setTabList(new Control[] { c });
218         }
219         return contents;
220     }
221
222     private Control createInfoArea(Composite parent) {
223         // Create the text field.
224
String JavaDoc styledText;
225         if (context instanceof IContext2) {
226             styledText = ((IContext2) context).getStyledText();
227             if (styledText == null) {
228                 styledText = context.getText();
229             }
230         } else {
231             styledText = context.getText();
232         }
233         if (styledText == null) { // no description found in context objects.
234
styledText = Messages.ContextHelpPart_noDescription;
235         }
236         Description text = new Description(parent, SWT.MULTI | SWT.READ_ONLY);
237         text.addTraverseListener(new TraverseListener() {
238             public void keyTraversed(TraverseEvent e) {
239                 if (e.detail == SWT.TRAVERSE_ESCAPE) {
240                     if (HelpUIPlugin.DEBUG_INFOPOP) {
241                         System.out
242                                 .println("ContextHelpDialog text TraverseListener.handleEvent(): SWT.TRAVERSE_ESCAPE."); //$NON-NLS-1$
243
}
244                     e.doit = true;
245                 }
246             }
247         });
248
249         text.getCaret().setVisible(false);
250         text.setBackground(backgroundColour);
251         text.setForeground(foregroundColour);
252         text.setFont(parent.getFont());
253         int linkWidth = getLinksWidth(text);
254         StyledLineWrapper content = new StyledLineWrapper(styledText, text,
255                 linkWidth + 70);
256         text.setContent(content);
257         text.setStyleRanges(content.getStyles());
258
259         infopopText = text.getText();
260         initAccessible(text);
261
262         return text;
263     }
264
265     /**
266      * Measures the longest label of related links
267      *
268      * @param text
269      * @return
270      */

271     private int getLinksWidth(Description text) {
272         int linkWidth = 0;
273         IHelpResource relatedTopics[] = context.getRelatedTopics();
274         if (relatedTopics != null) {
275             GC gc = new GC(text);
276             for (int i = 0; i < relatedTopics.length; i++) {
277                 linkWidth = Math.max(linkWidth, gc.textExtent(relatedTopics[i]
278                         .getLabel()).x);
279             }
280             gc.dispose();
281         }
282         return linkWidth;
283     }
284
285     private Control createLink(Composite parent, IHelpResource topic) {
286         Label image = new Label(parent, SWT.NONE);
287         image.setImage(getImage());
288         image.setBackground(backgroundColour);
289         GridData data = new GridData();
290         data.horizontalAlignment = GridData.HORIZONTAL_ALIGN_BEGINNING;
291         data.verticalAlignment = GridData.VERTICAL_ALIGN_BEGINNING;
292         //data.horizontalIndent = 4;
293
image.setLayoutData(data);
294         HyperlinkLabel link = new HyperlinkLabel(parent, SWT.NONE);
295         link.setText(topic.getLabel());
296         link.setBackground(backgroundColour);
297         link.setForeground(linkColour);
298         link.setFont(parent.getFont());
299         linkManager.registerHyperlink(link, new LinkListener(topic));
300         return link;
301     }
302
303     private Control createLinksArea(Composite parent) {
304         IHelpResource[] relatedTopics = context.getRelatedTopics();
305         if (relatedTopics == null)
306             return null;
307         // Create control
308
Composite composite = new Composite(parent, SWT.NONE);
309         initAccessible(composite);
310
311         composite.setBackground(backgroundColour);
312         GridLayout layout = new GridLayout();
313         layout.marginHeight = 2;
314         layout.marginWidth = 0;
315         layout.verticalSpacing = 3;
316         layout.horizontalSpacing = 2;
317         layout.numColumns = 2;
318         composite.setLayout(layout);
319         composite.setFont(parent.getFont());
320         GridData data = new GridData(GridData.FILL_BOTH
321                 | GridData.HORIZONTAL_ALIGN_BEGINNING
322                 | GridData.VERTICAL_ALIGN_CENTER);
323         composite.setLayoutData(data);
324         // Create separator.
325
Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
326         label.setBackground(backgroundColour);
327         label.setForeground(foregroundColour);
328         data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING
329                 | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
330         data.horizontalSpan = 2;
331         label.setLayoutData(data);
332         // Create related links
333
for (int i = 0; i < relatedTopics.length; i++) {
334             if (!UAContentFilter.isFiltered(relatedTopics[i], HelpEvaluationContext.getContext())) {
335                 createLink(composite, relatedTopics[i]);
336             }
337         }
338
339         // create dynamic help link if current context allows dynamic help
340
IWorkbenchWindow wbWindow = HelpUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
341         if (DefaultHelpUI.isActiveShell(parentShell, wbWindow) || HelpTray.isAppropriateFor(parentShell)) {
342             // Create separator.
343
label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
344             label.setBackground(backgroundColour);
345             label.setForeground(foregroundColour);
346             data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING
347                     | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
348             data.horizontalSpan = 2;
349             label.setLayoutData(data);
350
351             // create link to the dynamic help
352
createDynamicHelpLink(composite);
353         }
354         
355         return composite;
356     }
357
358     private Control createDynamicHelpLink(Composite parent) {
359         Label image = new Label(parent, SWT.NONE);
360         Image img = HelpUIResources.getImage(IHelpUIConstants.IMAGE_DHELP);
361         image.setImage(img);
362         image.setBackground(backgroundColour);
363         GridData data = new GridData();
364         data.horizontalAlignment = GridData.HORIZONTAL_ALIGN_BEGINNING;
365         data.verticalAlignment = GridData.VERTICAL_ALIGN_BEGINNING;
366         //data.horizontalIndent = 4;
367
image.setLayoutData(data);
368         HyperlinkLabel link = new HyperlinkLabel(parent, SWT.NONE);
369         link.setText(Messages.ContextHelpDialog_showInDynamicHelp);
370         link.setBackground(backgroundColour);
371         link.setForeground(linkColour);
372         link.setFont(parent.getFont());
373         linkManager.registerHyperlink(link, new HyperlinkAdapter() {
374             public void linkActivated(Control label) {
375                 openDynamicHelp();
376             }
377         });
378         return link;
379     }
380
381     /**
382      * Called when related link has been chosen Opens help viewer with list of
383      * all related topics
384      */

385     protected void launchLinks(IHelpResource selectedTopic) {
386         close();
387         if (HelpUIPlugin.DEBUG_INFOPOP) {
388             System.out.println("ContextHelpDialog.launchLinks(): closed shell"); //$NON-NLS-1$
389
}
390         BaseHelpSystem.getHelpDisplay().displayHelp(
391                 context,
392                 selectedTopic,
393                 DefaultHelpUI.isDisplayModal(parentShell)
394                 && !Constants.OS_WIN32.equalsIgnoreCase(Platform
395                                 .getOS()));
396     }
397     
398     private void openDynamicHelp() {
399         BusyIndicator.showWhile(shell.getDisplay(), new Runnable JavaDoc() {
400             public void run() {
401                 close();
402                 DefaultHelpUI.getInstance().displayContext(context, 0, 0, true);
403             }
404         });
405     }
406
407     public synchronized void open() {
408         try {
409             shell.open();
410             if (HelpUIPlugin.DEBUG_INFOPOP) {
411                 System.out
412                         .println("ContextHelpDialog.open(): Focus owner after open is: " //$NON-NLS-1$
413
+ Display.getCurrent().getFocusControl()
414                                         .toString());
415             }
416         } catch (Throwable JavaDoc e) {
417             HelpUIPlugin
418                     .logError(
419                             "An error occurred when opening context-sensitive help pop-up.", //$NON-NLS-1$
420
e);
421         }
422     }
423
424     private Image getImage() {
425         return HelpUIResources.getImage(IHelpUIConstants.IMAGE_FILE_F1TOPIC);
426     }
427
428     public boolean isShowing() {
429         return (shell != null && !shell.isDisposed() && shell.isVisible());
430     }
431
432     private void initAccessible(final Control control) {
433         Accessible accessible = control.getAccessible();
434         accessible.addAccessibleListener(new AccessibleAdapter() {
435             public void getName(AccessibleEvent e) {
436                 e.result = infopopText;
437             }
438
439             public void getHelp(AccessibleEvent e) {
440                 e.result = control.getToolTipText();
441             }
442         });
443
444         accessible.addAccessibleControlListener(new AccessibleControlAdapter() {
445             public void getChildAtPoint(AccessibleControlEvent e) {
446                 Point pt = control.toControl(new Point(e.x, e.y));
447                 e.childID = (control.getBounds().contains(pt)) ? ACC.CHILDID_MULTIPLE
448                         : ACC.CHILDID_NONE;
449             }
450
451             public void getLocation(AccessibleControlEvent e) {
452                 Rectangle location = control.getBounds();
453                 Point pt = control.toDisplay(new Point(location.x, location.y));
454                 e.x = pt.x;
455                 e.y = pt.y;
456                 e.width = location.width;
457                 e.height = location.height;
458             }
459
460             public void getChildCount(AccessibleControlEvent e) {
461                 e.detail = 1;
462             }
463
464             public void getRole(AccessibleControlEvent e) {
465                 e.detail = ACC.ROLE_LABEL;
466             }
467
468             public void getState(AccessibleControlEvent e) {
469                 e.detail = ACC.STATE_READONLY;
470             }
471         });
472     }
473
474     public class Description extends StyledText {
475         /**
476          * @param parent
477          * @param style
478          */

479         public Description(Composite parent, int style) {
480             super(parent, style);
481         }
482
483         public boolean setFocus() {
484             return false;
485         }
486
487         public boolean isFocusControl() {
488             return false;
489         }
490     }
491
492 }
493
Popular Tags