2936e54e814a4d8379a4558f3767aacaf1fbcc40
[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.phpeclipse.PHPeclipsePlugin;
14 import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
15 import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
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, IInformationControlExtension, DisposeListener {
50         
51         /** Border thickness in pixels. */
52         private static final int BORDER= 1;
53         /** The control's shell */
54         private Shell fShell;
55         /** The control's text widget */
56         private StyledText fText;
57         /** The control's source viewer */
58         private SourceViewer fViewer;   
59         /**
60          * The optional status field.
61          * 
62          * @since 3.0
63          */
64         private Label fStatusField; 
65         /**
66          * The separator for the optional status field.
67          * 
68          * @since 3.0
69          */
70         private Label fSeparator; 
71         /**
72          * The font of the optional status text label.
73          * 
74          * @since 3.0
75          */
76         private Font fStatusTextFont;
77         
78         /**
79          * Creates a default information control with the given shell as parent. The given
80          * information presenter is used to process the information to be displayed. The given
81          * styles are applied to the created styled text widget.
82          * 
83          * @param parent the parent shell
84          * @param shellStyle the additional styles for the shell
85          * @param style the additional styles for the styled text widget
86          */
87         public SourceViewerInformationControl(Shell parent, int shellStyle, int style) {
88                 this(parent, shellStyle, style, null);
89         }
90         
91         /**
92          * Creates a default information control with the given shell as parent. The given
93          * information presenter is used to process the information to be displayed. The given
94          * styles are applied to the created styled text widget.
95          * 
96          * @param parent the parent shell
97          * @param shellStyle the additional styles for the shell
98          * @param style the additional styles for the styled text widget
99          * @param statusFieldText the text to be used in the optional status field
100          *                         or <code>null</code> if the status field should be hidden
101          * @since 3.0
102          */
103         public SourceViewerInformationControl(Shell parent, int shellStyle, int style, String statusFieldText) {
104                 GridLayout layout;
105                 GridData gd;
106
107                 fShell= new Shell(parent, SWT.NO_FOCUS | SWT.ON_TOP | shellStyle);
108                 Display display= fShell.getDisplay();           
109                 fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
110
111                 Composite composite= fShell;
112                 layout= new GridLayout(1, false);
113                 int border= ((shellStyle & SWT.NO_TRIM) == 0) ? 0 : BORDER;
114                 layout.marginHeight= border;
115                 layout.marginWidth= border;
116                 composite.setLayout(layout);
117                 gd= new GridData(GridData.FILL_HORIZONTAL);
118                 composite.setLayoutData(gd);
119
120                 if (statusFieldText != null) {
121                         composite= new Composite(composite, SWT.NONE);
122                         layout= new GridLayout(1, false);
123                         layout.marginHeight= 0;
124                         layout.marginWidth= 0;
125                         composite.setLayout(layout);
126                         gd= new GridData(GridData.FILL_BOTH);
127                         composite.setLayoutData(gd);
128                         composite.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
129                         composite.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
130                 }               
131
132                 // Source viewer
133                 IPreferenceStore store= PHPeclipsePlugin.getDefault().getCombinedPreferenceStore();
134                 fViewer= new JavaSourceViewer(composite, null, null, false, style, store);
135                 fViewer.configure(new PHPSourceViewerConfiguration(PHPeclipsePlugin.getDefault().getJavaTextTools().getColorManager(), store, null, null));
136                 fViewer.setEditable(false);
137                 
138                 fText= fViewer.getTextWidget();
139                 gd= new GridData(GridData.BEGINNING | GridData.FILL_BOTH);
140                 fText.setLayoutData(gd);
141                 fText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
142                 fText.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
143                         
144                 fText.addKeyListener(new KeyListener() {
145                                 
146                         public void keyPressed(KeyEvent e)  {
147                                 if (e.character == 0x1B) // ESC
148                                         fShell.dispose();
149                         }
150                                 
151                         public void keyReleased(KeyEvent e) {}
152                 });
153
154                 // Status field
155                 if (statusFieldText != null) {
156
157                         // Horizontal separator line
158                         fSeparator= new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_DOT);
159                         fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
160
161                         // Status field label
162                         fStatusField= new Label(composite, SWT.RIGHT);
163                         fStatusField.setText(statusFieldText);
164                         Font font= fStatusField.getFont();
165                         FontData[] fontDatas= font.getFontData();
166                         for (int i= 0; i < fontDatas.length; i++)
167                                 fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
168                         fStatusTextFont= new Font(fStatusField.getDisplay(), fontDatas);
169                         fStatusField.setFont(fStatusTextFont);
170                         GridData gd2= new GridData(GridData.FILL_VERTICAL | GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
171                         fStatusField.setLayoutData(gd2);
172
173                         // Regarding the color see bug 41128
174                         fStatusField.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
175
176                         fStatusField.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
177                 }
178                 
179                 addDisposeListener(this);
180         }
181
182         /**
183          * Creates a default information control with the given shell as parent. The given
184          * information presenter is used to process the information to be displayed. The given
185          * styles are applied to the created styled text widget.
186          * 
187          * @param parent the parent shell
188          * @param style the additional styles for the styled text widget
189          */     
190         public SourceViewerInformationControl(Shell parent,int style) {
191                 this(parent, SWT.NO_TRIM, style);
192         }
193         
194         /**
195          * Creates a default information control with the given shell as parent. The given
196          * information presenter is used to process the information to be displayed. The given
197          * styles are applied to the created styled text widget.
198          * 
199          * @param parent the parent shell
200          * @param style the additional styles for the styled text widget
201          * @param statusFieldText the text to be used in the optional status field
202          *                         or <code>null</code> if the status field should be hidden
203          * @since 3.0
204          */     
205         public SourceViewerInformationControl(Shell parent,int style, String statusFieldText) {
206                 this(parent, SWT.NO_TRIM, style, statusFieldText);
207         }
208
209         /**
210          * Creates a default information control with the given shell as parent.
211          * No information presenter is used to process the information
212          * to be displayed. No additional styles are applied to the styled text widget.
213          * 
214          * @param parent the parent shell
215          */
216         public SourceViewerInformationControl(Shell parent) {
217                 this(parent, SWT.NONE);
218         }
219
220         /**
221          * Creates a default information control with the given shell as parent.
222          * No information presenter is used to process the information
223          * to be displayed. No additional styles are applied to the styled text widget.
224          * 
225          * @param parent the parent shell
226          * @param statusFieldText the text to be used in the optional status field
227          *                         or <code>null</code> if the status field should be hidden
228          * @since 3.0
229          */
230         public SourceViewerInformationControl(Shell parent, String statusFieldText) {
231                 this(parent, SWT.NONE, statusFieldText);
232         }
233         
234         /*
235          * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
236          */
237         public void setInput(Object input) {
238                 if (input instanceof String)
239                         setInformation((String)input);
240                 else
241                         setInformation(null);
242         }
243
244         /*
245          * @see IInformationControl#setInformation(String)
246          */
247         public void setInformation(String content) {
248                 if (content == null) {
249                         fViewer.setInput(null);
250                         return;
251                 }
252                                 
253                 IDocument doc= new Document(content);
254                 PHPeclipsePlugin.getDefault().getJavaTextTools().setupJavaDocumentPartitioner(doc);
255                 
256                 fViewer.setInput(doc);
257         }
258         
259         /*
260          * @see IInformationControl#setVisible(boolean)
261          */
262         public void setVisible(boolean visible) {
263                         fShell.setVisible(visible);
264         }
265
266         /**
267          * {@inheritDoc}
268          * @since 3.0
269          */
270         public void widgetDisposed(DisposeEvent event) {
271                 if (fStatusTextFont != null && !fStatusTextFont.isDisposed())
272                         fStatusTextFont.dispose();
273                 
274                 fStatusTextFont= null;
275                 fShell= null;
276                 fText= null;
277         }
278                 
279         /**
280          * {@inheritDoc}
281          */
282         public final void dispose() {
283                 if (fShell != null && !fShell.isDisposed())
284                         fShell.dispose();
285                 else
286                         widgetDisposed(null);
287         }
288         
289         /*
290          * @see IInformationControl#setSize(int, int)
291          */
292         public void setSize(int width, int height) {
293                 
294                 if (fStatusField != null) {
295                         GridData gd= (GridData)fViewer.getTextWidget().getLayoutData();
296                         Point statusSize= fStatusField.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
297                         Point separatorSize= fSeparator.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
298                         gd.heightHint= height - statusSize.y - separatorSize.y;
299                 }
300                 fShell.setSize(width, height);
301                 
302                 if (fStatusField != null)
303                         fShell.pack(true);
304         }
305         
306         /*
307          * @see IInformationControl#setLocation(Point)
308          */
309         public void setLocation(Point location) {
310                 Rectangle trim= fShell.computeTrim(0, 0, 0, 0);
311                 Point textLocation= fText.getLocation();                                
312                 location.x += trim.x - textLocation.x;          
313                 location.y += trim.y - textLocation.y;          
314                 fShell.setLocation(location);           
315         }
316         
317         /*
318          * @see IInformationControl#setSizeConstraints(int, int)
319          */
320         public void setSizeConstraints(int maxWidth, int maxHeight) {
321                 maxWidth= maxHeight;
322         }
323         
324         /*
325          * @see IInformationControl#computeSizeHint()
326          */
327         public Point computeSizeHint() {
328                 return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
329         }
330         
331         /*
332          * @see IInformationControl#addDisposeListener(DisposeListener)
333          */
334         public void addDisposeListener(DisposeListener listener) {
335                 fShell.addDisposeListener(listener);
336         }
337         
338         /*
339          * @see IInformationControl#removeDisposeListener(DisposeListener)
340          */
341         public void removeDisposeListener(DisposeListener listener) {
342                 fShell.removeDisposeListener(listener);
343         }
344         
345         /*
346          * @see IInformationControl#setForegroundColor(Color)
347          */
348         public void setForegroundColor(Color foreground) {
349                 fText.setForeground(foreground);
350         }
351         
352         /*
353          * @see IInformationControl#setBackgroundColor(Color)
354          */
355         public void setBackgroundColor(Color background) {
356                 fText.setBackground(background);
357         }
358         
359         /*
360          * @see IInformationControl#isFocusControl()
361          */
362         public boolean isFocusControl() {
363                 return fText.isFocusControl();
364         }
365         
366         /*
367          * @see IInformationControl#setFocus()
368          */
369         public void setFocus() {
370                 fShell.forceFocus();
371                 fText.setFocus();
372         }
373         
374         /*
375          * @see IInformationControl#addFocusListener(FocusListener)
376          */
377         public void addFocusListener(FocusListener listener) {
378                 fText.addFocusListener(listener);
379         }
380         
381         /*
382          * @see IInformationControl#removeFocusListener(FocusListener)
383          */
384         public void removeFocusListener(FocusListener listener) {
385                 fText.removeFocusListener(listener);
386         }
387         
388         /*
389          * @see IInformationControlExtension#hasContents()
390          */
391         public boolean hasContents() {
392                 return fText.getCharCount() > 0;
393         }
394         
395         protected ISourceViewer getViewer()  {
396                 return fViewer;
397         }
398 }