1) Moved net.sourceforge.phpeclipse.ui\src\net\sourceforge\phpdt back to net.sourcefo...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / text / java / hover / SourceViewerInformationControl.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.text.java.hover;
12
13 import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
14 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
15 import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
16
17 import org.eclipse.jface.preference.IPreferenceStore;
18 import org.eclipse.jface.text.Document;
19 import org.eclipse.jface.text.IDocument;
20 import org.eclipse.jface.text.IInformationControl;
21 import org.eclipse.jface.text.IInformationControlExtension;
22 import org.eclipse.jface.text.source.ISourceViewer;
23 import org.eclipse.jface.text.source.SourceViewer;
24 import org.eclipse.swt.SWT;
25 import org.eclipse.swt.custom.StyledText;
26 import org.eclipse.swt.events.DisposeEvent;
27 import org.eclipse.swt.events.DisposeListener;
28 import org.eclipse.swt.events.FocusListener;
29 import org.eclipse.swt.events.KeyEvent;
30 import org.eclipse.swt.events.KeyListener;
31 import org.eclipse.swt.graphics.Color;
32 import org.eclipse.swt.graphics.Font;
33 import org.eclipse.swt.graphics.FontData;
34 import org.eclipse.swt.graphics.Point;
35 import org.eclipse.swt.graphics.Rectangle;
36 import org.eclipse.swt.layout.GridData;
37 import org.eclipse.swt.layout.GridLayout;
38 import org.eclipse.swt.widgets.Composite;
39 import org.eclipse.swt.widgets.Display;
40 import org.eclipse.swt.widgets.Label;
41 import org.eclipse.swt.widgets.Shell;
42
43 /**
44  * Source viewer based implementation of <code>IInformationControl</code>.
45  * Displays information in a source viewer.
46  * 
47  * @since 3.0
48  */
49 public class SourceViewerInformationControl implements IInformationControl,
50                 IInformationControlExtension, DisposeListener {
51
52         /** Border thickness in pixels. */
53         private static final int BORDER = 1;
54
55         /** The control's shell */
56         private Shell fShell;
57
58         /** The control's text widget */
59         private StyledText fText;
60
61         /** The control's source viewer */
62         private SourceViewer fViewer;
63
64         /**
65          * The optional status field.
66          * 
67          * @since 3.0
68          */
69         private Label fStatusField;
70
71         /**
72          * The separator for the optional status field.
73          * 
74          * @since 3.0
75          */
76         private Label fSeparator;
77
78         /**
79          * The font of the optional status text label.
80          * 
81          * @since 3.0
82          */
83         private Font fStatusTextFont;
84
85         /**
86          * Creates a default information control with the given shell as parent. The
87          * given information presenter is used to process the information to be
88          * displayed. The given styles are applied to the created styled text
89          * widget.
90          * 
91          * @param parent
92          *            the parent shell
93          * @param shellStyle
94          *            the additional styles for the shell
95          * @param style
96          *            the additional styles for the styled text widget
97          */
98         public SourceViewerInformationControl(Shell parent, int shellStyle,
99                         int style) {
100                 this(parent, shellStyle, style, null);
101         }
102
103         /**
104          * Creates a default information control with the given shell as parent. The
105          * given information presenter is used to process the information to be
106          * displayed. The given styles are applied to the created styled text
107          * widget.
108          * 
109          * @param parent
110          *            the parent shell
111          * @param shellStyle
112          *            the additional styles for the shell
113          * @param style
114          *            the additional styles for the styled text widget
115          * @param statusFieldText
116          *            the text to be used in the optional status field or
117          *            <code>null</code> if the status field should be hidden
118          * @since 3.0
119          */
120         public SourceViewerInformationControl(Shell parent, int shellStyle,
121                         int style, String statusFieldText) {
122                 GridLayout layout;
123                 GridData gd;
124
125                 fShell = new Shell(parent, SWT.NO_FOCUS | SWT.ON_TOP | shellStyle);
126                 Display display = fShell.getDisplay();
127                 fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
128
129                 Composite composite = fShell;
130                 layout = new GridLayout(1, false);
131                 int border = ((shellStyle & SWT.NO_TRIM) == 0) ? 0 : BORDER;
132                 layout.marginHeight = border;
133                 layout.marginWidth = border;
134                 composite.setLayout(layout);
135                 gd = new GridData(GridData.FILL_HORIZONTAL);
136                 composite.setLayoutData(gd);
137
138                 if (statusFieldText != null) {
139                         composite = new Composite(composite, SWT.NONE);
140                         layout = new GridLayout(1, false);
141                         layout.marginHeight = 0;
142                         layout.marginWidth = 0;
143                         composite.setLayout(layout);
144                         gd = new GridData(GridData.FILL_BOTH);
145                         composite.setLayoutData(gd);
146                         composite.setForeground(display
147                                         .getSystemColor(SWT.COLOR_INFO_FOREGROUND));
148                         composite.setBackground(display
149                                         .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
150                 }
151
152                 // Source viewer
153                 IPreferenceStore store = PHPeclipsePlugin.getDefault()
154                                 .getCombinedPreferenceStore();
155                 fViewer = new JavaSourceViewer(composite, null, null, false, style,
156                                 store);
157                 fViewer.configure(new PHPSourceViewerConfiguration(PHPeclipsePlugin
158                                 .getDefault().getJavaTextTools().getColorManager(), store,
159                                 null, null));
160                 fViewer.setEditable(false);
161
162                 fText = fViewer.getTextWidget();
163                 gd = new GridData(GridData.BEGINNING | GridData.FILL_BOTH);
164                 fText.setLayoutData(gd);
165                 fText.setForeground(parent.getDisplay().getSystemColor(
166                                 SWT.COLOR_INFO_FOREGROUND));
167                 fText.setBackground(parent.getDisplay().getSystemColor(
168                                 SWT.COLOR_INFO_BACKGROUND));
169
170                 fText.addKeyListener(new KeyListener() {
171
172                         public void keyPressed(KeyEvent e) {
173                                 if (e.character == 0x1B) // ESC
174                                         fShell.dispose();
175                         }
176
177                         public void keyReleased(KeyEvent e) {
178                         }
179                 });
180
181                 // Status field
182                 if (statusFieldText != null) {
183
184                         // Horizontal separator line
185                         fSeparator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL
186                                         | SWT.LINE_DOT);
187                         fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
188
189                         // Status field label
190                         fStatusField = new Label(composite, SWT.RIGHT);
191                         fStatusField.setText(statusFieldText);
192                         Font font = fStatusField.getFont();
193                         FontData[] fontDatas = font.getFontData();
194                         for (int i = 0; i < fontDatas.length; i++)
195                                 fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
196                         fStatusTextFont = new Font(fStatusField.getDisplay(), fontDatas);
197                         fStatusField.setFont(fStatusTextFont);
198                         GridData gd2 = new GridData(GridData.FILL_VERTICAL
199                                         | GridData.FILL_HORIZONTAL
200                                         | GridData.HORIZONTAL_ALIGN_BEGINNING
201                                         | GridData.VERTICAL_ALIGN_BEGINNING);
202                         fStatusField.setLayoutData(gd2);
203
204                         // Regarding the color see bug 41128
205                         fStatusField.setForeground(display
206                                         .getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
207
208                         fStatusField.setBackground(display
209                                         .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
210                 }
211
212                 addDisposeListener(this);
213         }
214
215         /**
216          * Creates a default information control with the given shell as parent. The
217          * given information presenter is used to process the information to be
218          * displayed. The given styles are applied to the created styled text
219          * widget.
220          * 
221          * @param parent
222          *            the parent shell
223          * @param style
224          *            the additional styles for the styled text widget
225          */
226         public SourceViewerInformationControl(Shell parent, int style) {
227                 this(parent, SWT.NO_TRIM, style);
228         }
229
230         /**
231          * Creates a default information control with the given shell as parent. The
232          * given information presenter is used to process the information to be
233          * displayed. The given styles are applied to the created styled text
234          * widget.
235          * 
236          * @param parent
237          *            the parent shell
238          * @param style
239          *            the additional styles for the styled text widget
240          * @param statusFieldText
241          *            the text to be used in the optional status field or
242          *            <code>null</code> if the status field should be hidden
243          * @since 3.0
244          */
245         public SourceViewerInformationControl(Shell parent, int style,
246                         String statusFieldText) {
247                 this(parent, SWT.NO_TRIM, style, statusFieldText);
248         }
249
250         /**
251          * Creates a default information control with the given shell as parent. No
252          * information presenter is used to process the information to be displayed.
253          * No additional styles are applied to the styled text widget.
254          * 
255          * @param parent
256          *            the parent shell
257          */
258         public SourceViewerInformationControl(Shell parent) {
259                 this(parent, SWT.NONE);
260         }
261
262         /**
263          * Creates a default information control with the given shell as parent. No
264          * information presenter is used to process the information to be displayed.
265          * No additional styles are applied to the styled text widget.
266          * 
267          * @param parent
268          *            the parent shell
269          * @param statusFieldText
270          *            the text to be used in the optional status field or
271          *            <code>null</code> if the status field should be hidden
272          * @since 3.0
273          */
274 //      public SourceViewerInformationControl(Shell parent, String statusFieldText) {
275 //              this(parent, SWT.NONE, statusFieldText);
276 //      }
277
278         /*
279          * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
280          */
281         public void setInput(Object input) {
282                 if (input instanceof String)
283                         setInformation((String) input);
284                 else
285                         setInformation(null);
286         }
287
288         /*
289          * @see IInformationControl#setInformation(String)
290          */
291         public void setInformation(String content) {
292                 if (content == null) {
293                         fViewer.setInput(null);
294                         return;
295                 }
296
297                 IDocument doc = new Document(content);
298                 PHPeclipsePlugin.getDefault().getJavaTextTools()
299                                 .setupJavaDocumentPartitioner(doc);
300
301                 fViewer.setInput(doc);
302         }
303
304         /*
305          * @see IInformationControl#setVisible(boolean)
306          */
307         public void setVisible(boolean visible) {
308                 fShell.setVisible(visible);
309         }
310
311         /**
312          * {@inheritDoc}
313          * 
314          * @since 3.0
315          */
316         public void widgetDisposed(DisposeEvent event) {
317                 if (fStatusTextFont != null && !fStatusTextFont.isDisposed())
318                         fStatusTextFont.dispose();
319
320                 fStatusTextFont = null;
321                 fShell = null;
322                 fText = null;
323         }
324
325         /**
326          * {@inheritDoc}
327          */
328         public final void dispose() {
329                 if (fShell != null && !fShell.isDisposed())
330                         fShell.dispose();
331                 else
332                         widgetDisposed(null);
333         }
334
335         /*
336          * @see IInformationControl#setSize(int, int)
337          */
338         public void setSize(int width, int height) {
339
340                 if (fStatusField != null) {
341                         GridData gd = (GridData) fViewer.getTextWidget().getLayoutData();
342                         Point statusSize = fStatusField.computeSize(SWT.DEFAULT,
343                                         SWT.DEFAULT, true);
344                         Point separatorSize = fSeparator.computeSize(SWT.DEFAULT,
345                                         SWT.DEFAULT, true);
346                         gd.heightHint = height - statusSize.y - separatorSize.y;
347                 }
348                 fShell.setSize(width, height);
349
350                 if (fStatusField != null)
351                         fShell.pack(true);
352         }
353
354         /*
355          * @see IInformationControl#setLocation(Point)
356          */
357         public void setLocation(Point location) {
358                 Rectangle trim = fShell.computeTrim(0, 0, 0, 0);
359                 Point textLocation = fText.getLocation();
360                 location.x += trim.x - textLocation.x;
361                 location.y += trim.y - textLocation.y;
362                 fShell.setLocation(location);
363         }
364
365         /*
366          * @see IInformationControl#setSizeConstraints(int, int)
367          */
368         public void setSizeConstraints(int maxWidth, int maxHeight) {
369                 maxWidth = maxHeight;
370         }
371
372         /*
373          * @see IInformationControl#computeSizeHint()
374          */
375         public Point computeSizeHint() {
376                 return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
377         }
378
379         /*
380          * @see IInformationControl#addDisposeListener(DisposeListener)
381          */
382         public void addDisposeListener(DisposeListener listener) {
383                 fShell.addDisposeListener(listener);
384         }
385
386         /*
387          * @see IInformationControl#removeDisposeListener(DisposeListener)
388          */
389         public void removeDisposeListener(DisposeListener listener) {
390                 fShell.removeDisposeListener(listener);
391         }
392
393         /*
394          * @see IInformationControl#setForegroundColor(Color)
395          */
396         public void setForegroundColor(Color foreground) {
397                 fText.setForeground(foreground);
398         }
399
400         /*
401          * @see IInformationControl#setBackgroundColor(Color)
402          */
403         public void setBackgroundColor(Color background) {
404                 fText.setBackground(background);
405         }
406
407         /*
408          * @see IInformationControl#isFocusControl()
409          */
410         public boolean isFocusControl() {
411                 return fText.isFocusControl();
412         }
413
414         /*
415          * @see IInformationControl#setFocus()
416          */
417         public void setFocus() {
418                 fShell.forceFocus();
419                 fText.setFocus();
420         }
421
422         /*
423          * @see IInformationControl#addFocusListener(FocusListener)
424          */
425         public void addFocusListener(FocusListener listener) {
426                 fText.addFocusListener(listener);
427         }
428
429         /*
430          * @see IInformationControl#removeFocusListener(FocusListener)
431          */
432         public void removeFocusListener(FocusListener listener) {
433                 fText.removeFocusListener(listener);
434         }
435
436         /*
437          * @see IInformationControlExtension#hasContents()
438          */
439         public boolean hasContents() {
440                 return fText.getCharCount() > 0;
441         }
442
443         protected ISourceViewer getViewer() {
444                 return fViewer;
445         }
446 }