KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > texteditor > SourceViewerInformationControl


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.ui.internal.texteditor;
12
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.custom.StyledText;
15 import org.eclipse.swt.events.DisposeEvent;
16 import org.eclipse.swt.events.DisposeListener;
17 import org.eclipse.swt.events.FocusListener;
18 import org.eclipse.swt.events.KeyEvent;
19 import org.eclipse.swt.events.KeyListener;
20 import org.eclipse.swt.graphics.Color;
21 import org.eclipse.swt.graphics.Font;
22 import org.eclipse.swt.graphics.FontData;
23 import org.eclipse.swt.graphics.GC;
24 import org.eclipse.swt.graphics.Point;
25 import org.eclipse.swt.layout.GridData;
26 import org.eclipse.swt.layout.GridLayout;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Display;
29 import org.eclipse.swt.widgets.Label;
30 import org.eclipse.swt.widgets.Shell;
31
32 import org.eclipse.jface.resource.JFaceResources;
33
34 import org.eclipse.jface.text.BadLocationException;
35 import org.eclipse.jface.text.Document;
36 import org.eclipse.jface.text.IDocument;
37 import org.eclipse.jface.text.IInformationControl;
38 import org.eclipse.jface.text.IInformationControlExtension;
39 import org.eclipse.jface.text.IRegion;
40 import org.eclipse.jface.text.source.SourceViewer;
41
42 import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
43
44 import org.eclipse.ui.internal.editors.text.EditorsPlugin;
45
46 /**
47  * Source viewer based implementation of <code>IInformationControl</code>.
48  * Displays information in a source viewer configured with the text editor
49  * preference store.
50  *
51  * @since 3.0
52  */

53 class SourceViewerInformationControl implements IInformationControl, IInformationControlExtension, DisposeListener {
54
55     /** Border thickness in pixels. */
56     private static final int BORDER= 1;
57
58
59     /** The control's shell */
60     private Shell fShell;
61     /** The control's text widget */
62     private StyledText fText;
63     /** The control's source viewer */
64     private SourceViewer fViewer;
65     /** The optional status field. */
66     private Label fStatusField;
67     /** The separator for the optional status field. */
68     private Label fSeparator;
69     /** The font of the optional status text label.*/
70     private Font fStatusTextFont;
71     /** The maximal widget width. */
72     private int fMaxWidth;
73     /** The maximal widget height. */
74     private int fMaxHeight;
75     /** The horizontal scroll index. */
76     private int fHorizontalScrollPixel;
77
78     /**
79      * Creates a source viewer information control with the given shell as
80      * parent and the given font.
81      *
82      * @param parent the parent shell
83      * @param symbolicFontName the symbolic font name
84      */

85     public SourceViewerInformationControl(Shell parent, String JavaDoc symbolicFontName) {
86         this(parent, SWT.NO_TRIM | SWT.TOOL, SWT.NONE, symbolicFontName, null);
87     }
88
89     /**
90      * Creates a source viewer information control with the given shell as
91      * parent. The given shell styles are applied to the created shell. The
92      * given styles are applied to the created styled text widget. The text
93      * widget will be initialized with the given font. The status field will
94      * contain the given text or be hidden.
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 symbolicFontName the symbolic font name
100      * @param statusFieldText the text to be used in the optional status field
101      * or <code>null</code> if the status field should be hidden
102      */

103     public SourceViewerInformationControl(Shell parent, int shellStyle, int style, String JavaDoc symbolicFontName, String JavaDoc 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
fViewer= new SourceViewer(composite, null, style);
134         fViewer.configure(new TextSourceViewerConfiguration(EditorsPlugin.getDefault().getPreferenceStore()));
135         fViewer.setEditable(false);
136
137         fText= fViewer.getTextWidget();
138         gd= new GridData(GridData.BEGINNING | GridData.FILL_BOTH);
139         fText.setLayoutData(gd);
140         fText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
141         fText.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
142         fText.setFont(JFaceResources.getFont(symbolicFontName));
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      * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
184      */

185     public void setInput(Object JavaDoc input) {
186         if (input instanceof String JavaDoc)
187             setInformation((String JavaDoc)input);
188         else
189             setInformation(null);
190     }
191
192     /*
193      * @see IInformationControl#setInformation(String)
194      */

195     public void setInformation(String JavaDoc content) {
196         if (content == null) {
197             fViewer.setInput(null);
198             return;
199         }
200
201         IDocument doc= new Document(content);
202         fViewer.setInput(doc);
203         
204         // ensure that we can scroll enough
205
ensureScrollable();
206
207         fViewer.getTextWidget().setHorizontalPixel(fHorizontalScrollPixel);
208     }
209
210     /*
211      * @see IInformationControl#setVisible(boolean)
212      */

213     public void setVisible(boolean visible) {
214             fShell.setVisible(visible);
215     }
216
217     /*
218      * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
219      */

220     public void widgetDisposed(DisposeEvent event) {
221         if (fStatusTextFont != null && !fStatusTextFont.isDisposed())
222             fStatusTextFont.dispose();
223
224         fStatusTextFont= null;
225         fShell= null;
226         fText= null;
227     }
228
229     /*
230      * @see org.eclipse.jface.text.IInformationControl#dispose()
231      */

232     public final void dispose() {
233         if (fShell != null && !fShell.isDisposed())
234             fShell.dispose();
235         else
236             widgetDisposed(null);
237     }
238
239     /*
240      * @see IInformationControl#setSize(int, int)
241      */

242     public void setSize(int width, int height) {
243
244         if (fStatusField != null) {
245             GridData gd= (GridData)fViewer.getTextWidget().getLayoutData();
246             Point statusSize= fStatusField.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
247             Point separatorSize= fSeparator.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
248             gd.heightHint= height - statusSize.y - separatorSize.y;
249         }
250         fShell.setSize(width, height);
251
252         if (fStatusField != null)
253             fShell.pack(true);
254     }
255
256     /*
257      * @see IInformationControl#setLocation(Point)
258      */

259     public void setLocation(Point location) {
260         fShell.setLocation(location);
261     }
262
263     /*
264      * @see IInformationControl#setSizeConstraints(int, int)
265      */

266     public void setSizeConstraints(int maxWidth, int maxHeight) {
267         fMaxWidth= maxWidth;
268         fMaxHeight= maxHeight;
269     }
270
271     /*
272      * @see IInformationControl#computeSizeHint()
273      */

274     public Point computeSizeHint() {
275         Point size= fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
276         size.x= Math.min(size.x, fMaxWidth);
277         size.y= Math.min(size.y, fMaxHeight);
278         return size;
279     }
280
281     /*
282      * @see IInformationControl#addDisposeListener(DisposeListener)
283      */

284     public void addDisposeListener(DisposeListener listener) {
285         fShell.addDisposeListener(listener);
286     }
287
288     /*
289      * @see IInformationControl#removeDisposeListener(DisposeListener)
290      */

291     public void removeDisposeListener(DisposeListener listener) {
292         fShell.removeDisposeListener(listener);
293     }
294
295     /*
296      * @see IInformationControl#setForegroundColor(Color)
297      */

298     public void setForegroundColor(Color foreground) {
299         fText.setForeground(foreground);
300     }
301
302     /*
303      * @see IInformationControl#setBackgroundColor(Color)
304      */

305     public void setBackgroundColor(Color background) {
306         fText.setBackground(background);
307     }
308
309     /*
310      * @see IInformationControl#isFocusControl()
311      */

312     public boolean isFocusControl() {
313         return fText.isFocusControl();
314     }
315
316     /*
317      * @see IInformationControl#setFocus()
318      */

319     public void setFocus() {
320         fShell.forceFocus();
321         fText.setFocus();
322     }
323
324     /*
325      * @see IInformationControl#addFocusListener(FocusListener)
326      */

327     public void addFocusListener(FocusListener listener) {
328         fText.addFocusListener(listener);
329     }
330
331     /*
332      * @see IInformationControl#removeFocusListener(FocusListener)
333      */

334     public void removeFocusListener(FocusListener listener) {
335         fText.removeFocusListener(listener);
336     }
337
338     /*
339      * @see IInformationControlExtension#hasContents()
340      */

341     public boolean hasContents() {
342         return fText.getCharCount() > 0;
343     }
344
345     /**
346      * @param scrollIndex the new horizontal scroll index.
347      */

348     void setHorizontalScrollPixel(int scrollIndex) {
349         scrollIndex= Math.max(0, scrollIndex);
350         fHorizontalScrollPixel= scrollIndex;
351     }
352     
353     /**
354      * Ensures that the control can be scrolled at least to
355      * <code>fHorizontalScrollPixel</code> and adjusts <code>fMaxWidth</code>
356      * accordingly.
357      *
358      * @since 3.3
359      */

360     private void ensureScrollable() {
361         IDocument doc= fViewer.getDocument();
362         if (doc == null)
363             return;
364
365         StyledText widget= fViewer.getTextWidget();
366         if (widget == null || widget.isDisposed())
367             return;
368
369         int last= doc.getNumberOfLines() - 1;
370         GC gc= new GC(widget);
371         gc.setFont(widget.getFont());
372         int maxWidth= 0;
373         String JavaDoc content= new String JavaDoc();
374
375         try {
376             for (int i= 0; i <= last; i++) {
377                 IRegion line;
378                 line= doc.getLineInformation(i);
379                 content= doc.get(line.getOffset(), line.getLength());
380                 int width= gc.textExtent(content).x;
381                 if (width > maxWidth) {
382                     maxWidth= width;
383                 }
384             }
385         } catch (BadLocationException e) {
386             return;
387         } finally {
388             gc.dispose();
389         }
390
391         // limit the size of the window to the maximum width minus scrolling,
392
// but never more than the configured max size (viewport size).
393
fMaxWidth= Math.max(0, Math.min(fMaxWidth, maxWidth - fHorizontalScrollPixel + 8));
394     }
395     
396 }
397
Popular Tags