0468435ce82478e5244db3e5778706760a1c02c1
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpdt / internal / ui / text / CustomSourceInformationControl.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;
12
13 import net.sourceforge.phpdt.internal.ui.text.java.hover.SourceViewerInformationControl;
14
15 import org.eclipse.jface.resource.JFaceResources;
16 //incastrix
17 //import org.eclipse.jface.text.Assert;
18 import org.eclipse.core.runtime.Assert;
19 import org.eclipse.jface.text.BadLocationException;
20 import org.eclipse.jface.text.IDocument;
21 import org.eclipse.jface.text.IRegion;
22 import org.eclipse.jface.text.ITextViewerExtension;
23 import org.eclipse.swt.custom.StyledText;
24 import org.eclipse.swt.graphics.Font;
25 import org.eclipse.swt.graphics.GC;
26 import org.eclipse.swt.graphics.Point;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Control;
29 import org.eclipse.swt.widgets.Shell;
30
31 /**
32  * Source viewer used to display quick diff hovers.
33  * 
34  * @since 3.0
35  */
36 public class CustomSourceInformationControl extends
37                 SourceViewerInformationControl {
38
39         /** The font name for the viewer font - the same as the java editor's. */
40         private static final String SYMBOLIC_FONT_NAME = "net.sourceforge.phpdt.ui.editors.textfont"; //$NON-NLS-1$
41
42         /**
43          * The maximum width of the control, set in
44          * <code>setSizeConstraints(int, int)</code>.
45          */
46         int fMaxWidth = Integer.MAX_VALUE;
47
48         /**
49          * The maximum height of the control, set in
50          * <code>setSizeConstraints(int, int)</code>.
51          */
52         int fMaxHeight = Integer.MAX_VALUE;
53
54         /**
55          * The partition type to be used as the starting partition type by the
56          * paritition scanner.
57          */
58         private String fPartition;
59
60         /** The horizontal scroll index. */
61         private int fHorizontalScrollPixel;
62
63         /*
64          * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int,
65          *      int)
66          */
67         public void setSizeConstraints(int maxWidth, int maxHeight) {
68                 fMaxWidth = maxWidth;
69                 fMaxHeight = maxHeight;
70         }
71
72         /**
73          * Creates a new information control.
74          * 
75          * @param parent
76          *            the shell that is the parent of this hover / control
77          * @param partition
78          *            the initial partition type to be used for the underlying
79          *            viewer
80          */
81         public CustomSourceInformationControl(Shell parent, String partition) {
82                 super(parent);
83                 setViewerFont();
84                 setStartingPartitionType(partition);
85         }
86
87         /*
88          * @see org.eclipse.jface.text.IInformationControl#computeSizeHint()
89          */
90         public Point computeSizeHint() {
91                 Point size = super.computeSizeHint();
92                 size.x = Math.min(size.x, fMaxWidth);
93                 size.y = Math.min(size.y, fMaxHeight);
94                 return size;
95         }
96
97         /**
98          * Sets the font for this viewer sustaining selection and scroll position.
99          */
100         private void setViewerFont() {
101                 Font font = JFaceResources.getFont(SYMBOLIC_FONT_NAME);
102
103                 if (getViewer().getDocument() != null) {
104
105                         Point selection = getViewer().getSelectedRange();
106                         int topIndex = getViewer().getTopIndex();
107
108                         StyledText styledText = getViewer().getTextWidget();
109                         Control parent = styledText;
110                         if (getViewer() instanceof ITextViewerExtension) {
111                                 ITextViewerExtension extension = (ITextViewerExtension) getViewer();
112                                 parent = extension.getControl();
113                         }
114
115                         parent.setRedraw(false);
116
117                         styledText.setFont(font);
118
119                         getViewer().setSelectedRange(selection.x, selection.y);
120                         getViewer().setTopIndex(topIndex);
121
122                         if (parent instanceof Composite) {
123                                 Composite composite = (Composite) parent;
124                                 composite.layout(true);
125                         }
126
127                         parent.setRedraw(true);
128
129                 } else {
130                         StyledText styledText = getViewer().getTextWidget();
131                         styledText.setFont(font);
132                 }
133         }
134
135         /**
136          * Sets the initial partition for the underlying source viewer.
137          * 
138          * @param partition
139          *            the partition type
140          */
141         public void setStartingPartitionType(String partition) {
142                 if (partition == null)
143                         fPartition = IDocument.DEFAULT_CONTENT_TYPE;
144                 else
145                         fPartition = partition;
146         }
147
148         /*
149          * @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String)
150          */
151         public void setInformation(String content) {
152                 super.setInformation(content);
153                 IDocument doc = getViewer().getDocument();
154                 if (doc == null)
155                         return;
156
157                 // ensure that we can scroll enough
158                 ensureScrollable();
159
160                 String start = null;
161                 if (IPHPPartitions.PHP_PHPDOC_COMMENT.equals(fPartition)) {
162                         start = "/**" + doc.getLegalLineDelimiters()[0]; //$NON-NLS-1$
163                 } else if (IPHPPartitions.PHP_MULTILINE_COMMENT.equals(fPartition)) {
164                         start = "/*" + doc.getLegalLineDelimiters()[0]; //$NON-NLS-1$
165                 }
166                 if (start != null) {
167                         try {
168                                 doc.replace(0, 0, start);
169                                 int startLen = start.length();
170                                 getViewer().setDocument(doc, startLen,
171                                                 doc.getLength() - startLen);
172                         } catch (BadLocationException e) {
173                                 // impossible
174                                 Assert.isTrue(false);
175                         }
176                 }
177
178                 getViewer().getTextWidget().setHorizontalPixel(fHorizontalScrollPixel);
179         }
180
181         /**
182          * Ensures that the control can be scrolled at least to
183          * <code>fHorizontalScrollPixel</code> and adjusts <code>fMaxWidth</code>
184          * accordingly.
185          */
186         private void ensureScrollable() {
187                 IDocument doc = getViewer().getDocument();
188                 if (doc == null)
189                         return;
190
191                 StyledText widget = getViewer().getTextWidget();
192                 if (widget == null || widget.isDisposed())
193                         return;
194
195                 int last = doc.getNumberOfLines() - 1;
196                 GC gc = new GC(widget);
197                 gc.setFont(widget.getFont());
198                 int maxWidth = 0;
199                 String content = new String();
200
201                 try {
202                         for (int i = 0; i <= last; i++) {
203                                 IRegion line;
204                                 line = doc.getLineInformation(i);
205                                 content = doc.get(line.getOffset(), line.getLength());
206                                 int width = gc.textExtent(content).x;
207                                 if (width > maxWidth) {
208                                         maxWidth = width;
209                                 }
210                         }
211                 } catch (BadLocationException e) {
212                         return;
213                 } finally {
214                         gc.dispose();
215                 }
216
217                 // limit the size of the window to the maximum width minus scrolling,
218                 // but never more than the configured max size (viewport size).
219                 fMaxWidth = Math.max(0, Math.min(fMaxWidth, maxWidth
220                                 - fHorizontalScrollPixel + 8));
221         }
222
223         /*
224          * @see net.sourceforge.phpdt.internal.ui.text.java.hover.SourceViewerInformationControl#hasContents()
225          */
226         public boolean hasContents() {
227                 return super.hasContents() && fMaxWidth > 0;
228         }
229
230         /**
231          * Sets the horizontal scroll index in pixels.
232          * 
233          * @param scrollIndex
234          *            the new horizontal scroll index
235          */
236 //      public void setHorizontalScrollPixel(int scrollIndex) {
237 //              scrollIndex = Math.max(0, scrollIndex);
238 //              fHorizontalScrollPixel = scrollIndex;
239 //      }
240 }