Added
Link Here
|
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2000, 2008 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 |
|
12 |
package org.eclipse.jface.text.hyperlink; |
13 |
|
14 |
import org.eclipse.core.runtime.Assert; |
15 |
import org.eclipse.jface.dialogs.Dialog; |
16 |
import org.eclipse.jface.dialogs.PopupDialog; |
17 |
import org.eclipse.jface.resource.JFaceResources; |
18 |
import org.eclipse.jface.text.IInformationControl; |
19 |
import org.eclipse.jface.text.IInformationControlExtension; |
20 |
import org.eclipse.jface.text.IInformationControlExtension2; |
21 |
import org.eclipse.jface.text.IInformationControlExtension3; |
22 |
import org.eclipse.jface.text.IInformationControlExtension5; |
23 |
import org.eclipse.swt.SWT; |
24 |
import org.eclipse.swt.events.DisposeEvent; |
25 |
import org.eclipse.swt.events.DisposeListener; |
26 |
import org.eclipse.swt.events.FocusListener; |
27 |
import org.eclipse.swt.events.SelectionAdapter; |
28 |
import org.eclipse.swt.events.SelectionEvent; |
29 |
import org.eclipse.swt.graphics.Color; |
30 |
import org.eclipse.swt.graphics.Font; |
31 |
import org.eclipse.swt.graphics.FontMetrics; |
32 |
import org.eclipse.swt.graphics.GC; |
33 |
import org.eclipse.swt.graphics.Point; |
34 |
import org.eclipse.swt.graphics.Rectangle; |
35 |
import org.eclipse.swt.layout.GridData; |
36 |
import org.eclipse.swt.layout.GridLayout; |
37 |
import org.eclipse.swt.widgets.Composite; |
38 |
import org.eclipse.swt.widgets.Control; |
39 |
import org.eclipse.swt.widgets.Layout; |
40 |
import org.eclipse.swt.widgets.Link; |
41 |
import org.eclipse.swt.widgets.Shell; |
42 |
|
43 |
import com.ibm.icu.text.MessageFormat; |
44 |
|
45 |
|
46 |
/** |
47 |
* An information control capable of showing a list of links. The links can be opened. |
48 |
* |
49 |
* @since 3.4 |
50 |
*/ |
51 |
public class LinkListInformationControl implements IInformationControl, IInformationControlExtension, IInformationControlExtension2, IInformationControlExtension3, IInformationControlExtension5, DisposeListener { |
52 |
|
53 |
private PopupDialog fPopupDialog; |
54 |
|
55 |
private Composite fLinkComposite; |
56 |
|
57 |
/** |
58 |
* Creates a link list information control with the given shell as parent. |
59 |
* |
60 |
* @param parentShell the parent shell |
61 |
* @param shellStyle the additional styles for the shell |
62 |
* @param statusFieldText the text to be used in the optional status field |
63 |
* or <code>null</code> if the status field should be hidden |
64 |
*/ |
65 |
public LinkListInformationControl(Shell parentShell, int shellStyle, String statusFieldText) { |
66 |
shellStyle= shellStyle | SWT.NO_FOCUS | SWT.ON_TOP; |
67 |
fPopupDialog= new PopupDialog(parentShell, shellStyle, false, false, false, false, null, statusFieldText) { |
68 |
|
69 |
protected Control createDialogArea(Composite parent) { |
70 |
fLinkComposite= new Composite(parent, SWT.NONE); |
71 |
fLinkComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
72 |
fLinkComposite.setLayout(new GridLayout(1, false)); |
73 |
|
74 |
return fLinkComposite; |
75 |
} |
76 |
}; |
77 |
|
78 |
// Force create early so that listeners can be added at all times with API. |
79 |
fPopupDialog.create(); |
80 |
} |
81 |
|
82 |
/* |
83 |
* @see IInformationControl#setInformation(String) |
84 |
*/ |
85 |
public void setInformation(String content) { |
86 |
Assert.isTrue(false, "Must implement IInformationProviderExtension and provide array of linkes as input"); //$NON-NLS-1$ |
87 |
} |
88 |
|
89 |
/* |
90 |
* @see IInformationControl#setVisible(boolean) |
91 |
*/ |
92 |
public void setVisible(boolean visible) { |
93 |
if (visible) { |
94 |
|
95 |
Point currentSize= fPopupDialog.getShell().getSize(); |
96 |
fPopupDialog.getShell().pack(true); |
97 |
Point newSize= fPopupDialog.getShell().getSize(); |
98 |
if (newSize.x > currentSize.x || newSize.y > currentSize.y) |
99 |
setSize(currentSize.x, currentSize.y); // restore previous size |
100 |
|
101 |
fPopupDialog.open(); |
102 |
} else |
103 |
fPopupDialog.getShell().setVisible(false); |
104 |
} |
105 |
|
106 |
/* |
107 |
* @see IInformationControl#dispose() |
108 |
*/ |
109 |
public void dispose() { |
110 |
fPopupDialog.close(); |
111 |
fPopupDialog= null; |
112 |
} |
113 |
|
114 |
/* |
115 |
* @see IInformationControl#setSize(int, int) |
116 |
*/ |
117 |
public void setSize(int width, int height) { |
118 |
fPopupDialog.getShell().setSize(width, height); |
119 |
} |
120 |
|
121 |
/* |
122 |
* @see IInformationControl#setLocation(Point) |
123 |
*/ |
124 |
public void setLocation(Point location) { |
125 |
fPopupDialog.getShell().setLocation(location); |
126 |
} |
127 |
|
128 |
/* |
129 |
* @see IInformationControl#setSizeConstraints(int, int) |
130 |
*/ |
131 |
public void setSizeConstraints(int maxWidth, int maxHeight) { |
132 |
} |
133 |
|
134 |
/* |
135 |
* @see IInformationControl#computeSizeHint() |
136 |
*/ |
137 |
public Point computeSizeHint() { |
138 |
// see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=117602 |
139 |
int widthHint= SWT.DEFAULT; |
140 |
|
141 |
|
142 |
return fPopupDialog.getShell().computeSize(widthHint, SWT.DEFAULT, true); |
143 |
} |
144 |
|
145 |
/* |
146 |
* @see org.eclipse.jface.text.IInformationControlExtension3#computeTrim() |
147 |
* @since 3.0 |
148 |
*/ |
149 |
public Rectangle computeTrim() { |
150 |
Shell shell= fPopupDialog.getShell(); |
151 |
Rectangle trim= shell.computeTrim(0, 0, 0, 0); |
152 |
|
153 |
// PopupDialog adds a 1 pixel border when SWT.NO_TRIM is set: |
154 |
Layout layout= shell.getLayout(); |
155 |
if (layout instanceof GridLayout) { |
156 |
GridLayout gridLayout= (GridLayout) layout; |
157 |
int left= gridLayout.marginLeft + gridLayout.marginWidth; |
158 |
int top= gridLayout.marginTop + gridLayout.marginHeight; |
159 |
trim.x-= left; |
160 |
trim.y-= top; |
161 |
trim.width+= left + gridLayout.marginRight + 2 * gridLayout.marginWidth; |
162 |
trim.height+= top + gridLayout.marginBottom + 2 * gridLayout.marginHeight; |
163 |
} |
164 |
return trim; |
165 |
} |
166 |
|
167 |
/* |
168 |
* @see org.eclipse.jface.text.IInformationControlExtension3#getBounds() |
169 |
* @since 3.0 |
170 |
*/ |
171 |
public Rectangle getBounds() { |
172 |
return fPopupDialog.getShell().getBounds(); |
173 |
} |
174 |
|
175 |
/* |
176 |
* @see org.eclipse.jface.text.IInformationControlExtension3#restoresLocation() |
177 |
* @since 3.0 |
178 |
*/ |
179 |
public boolean restoresLocation() { |
180 |
return false; |
181 |
} |
182 |
|
183 |
/* |
184 |
* @see org.eclipse.jface.text.IInformationControlExtension3#restoresSize() |
185 |
* @since 3.0 |
186 |
*/ |
187 |
public boolean restoresSize() { |
188 |
return false; |
189 |
} |
190 |
|
191 |
/* |
192 |
* @see IInformationControl#addDisposeListener(DisposeListener) |
193 |
*/ |
194 |
public void addDisposeListener(DisposeListener listener) { |
195 |
fPopupDialog.getShell().addDisposeListener(listener); |
196 |
} |
197 |
|
198 |
/* |
199 |
* @see IInformationControl#removeDisposeListener(DisposeListener) |
200 |
*/ |
201 |
public void removeDisposeListener(DisposeListener listener) { |
202 |
fPopupDialog.getShell().removeDisposeListener(listener); |
203 |
} |
204 |
|
205 |
/* |
206 |
* @see IInformationControl#setForegroundColor(Color) |
207 |
*/ |
208 |
public void setForegroundColor(Color foreground) { |
209 |
fLinkComposite.setForeground(foreground); |
210 |
} |
211 |
|
212 |
/* |
213 |
* @see IInformationControl#setBackgroundColor(Color) |
214 |
*/ |
215 |
public void setBackgroundColor(Color background) { |
216 |
fLinkComposite.setBackground(background); |
217 |
} |
218 |
|
219 |
/* |
220 |
* @see IInformationControl#isFocusControl() |
221 |
*/ |
222 |
public boolean isFocusControl() { |
223 |
Shell shell= fPopupDialog.getShell(); |
224 |
return shell.getDisplay().getActiveShell() == shell; |
225 |
} |
226 |
|
227 |
/* |
228 |
* @see IInformationControl#setFocus() |
229 |
*/ |
230 |
public void setFocus() { |
231 |
fPopupDialog.getShell().forceFocus(); |
232 |
fLinkComposite.setFocus(); |
233 |
} |
234 |
|
235 |
/* |
236 |
* @see IInformationControl#addFocusListener(FocusListener) |
237 |
*/ |
238 |
public void addFocusListener(FocusListener listener) { |
239 |
fLinkComposite.addFocusListener(listener); |
240 |
} |
241 |
|
242 |
/* |
243 |
* @see IInformationControl#removeFocusListener(FocusListener) |
244 |
*/ |
245 |
public void removeFocusListener(FocusListener listener) { |
246 |
fLinkComposite.removeFocusListener(listener); |
247 |
} |
248 |
|
249 |
/* |
250 |
* @see IInformationControlExtension#hasContents() |
251 |
*/ |
252 |
public boolean hasContents() { |
253 |
return fLinkComposite.getChildren().length > 0; |
254 |
} |
255 |
|
256 |
/** |
257 |
* @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) |
258 |
* @deprecated As of 3.2, no longer used and called |
259 |
*/ |
260 |
public void widgetDisposed(DisposeEvent event) { |
261 |
} |
262 |
|
263 |
/* |
264 |
* @see org.eclipse.jface.text.IInformationControlExtension5#containsControl(org.eclipse.swt.widgets.Control) |
265 |
* @since 3.4 |
266 |
*/ |
267 |
public boolean containsControl(Control control) { |
268 |
do { |
269 |
Shell popupShell= fPopupDialog.getShell(); |
270 |
if (control == popupShell) |
271 |
return true; |
272 |
if (control instanceof Shell) |
273 |
return false; |
274 |
control= control.getParent(); |
275 |
} while (control != null); |
276 |
return false; |
277 |
} |
278 |
|
279 |
/* |
280 |
* @see org.eclipse.jface.text.IInformationControlExtension5#isVisible() |
281 |
* @since 3.4 |
282 |
*/ |
283 |
public boolean isVisible() { |
284 |
Shell popupShell= fPopupDialog.getShell(); |
285 |
return popupShell != null && !popupShell.isDisposed() && popupShell.isVisible(); |
286 |
} |
287 |
|
288 |
/* |
289 |
* @see org.eclipse.jface.text.IInformationControlExtension5#allowMoveIntoControl() |
290 |
* @since 3.4 |
291 |
*/ |
292 |
public boolean allowMoveIntoControl() { |
293 |
return true; |
294 |
} |
295 |
|
296 |
/* (non-Javadoc) |
297 |
* @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object) |
298 |
*/ |
299 |
public void setInput(Object input) { |
300 |
if (!(input instanceof IHyperlink[])) |
301 |
Assert.isTrue(false, "Must provide an array of IHyperlink as input"); //$NON-NLS-1$ |
302 |
|
303 |
IHyperlink[] links= (IHyperlink[]) input; |
304 |
for (int i= 0; i < links.length; i++) { |
305 |
final IHyperlink link= links[i]; |
306 |
|
307 |
Link linkControl= new Link(fLinkComposite, SWT.NONE); |
308 |
linkControl.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); |
309 |
|
310 |
String text= link.getHyperlinkText(); |
311 |
if (text == null) |
312 |
text= HyperlinkMessages.getString("LinkListInformationControl.unknownLink"); //$NON-NLS-1$ |
313 |
|
314 |
if (i == 0) { |
315 |
text= MessageFormat.format(HyperlinkMessages.getString("LinkListInformationControl.defaultLinkPattern"), new Object[] { text }); //$NON-NLS-1$ |
316 |
} |
317 |
|
318 |
linkControl.setText("<a>" + text + "</a>"); //$NON-NLS-1$ //$NON-NLS-2$ |
319 |
linkControl.setBackground(fLinkComposite.getBackground()); |
320 |
linkControl.setForeground(fLinkComposite.getForeground()); |
321 |
|
322 |
linkControl.addSelectionListener(new SelectionAdapter() { |
323 |
/* (non-Javadoc) |
324 |
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
325 |
*/ |
326 |
public void widgetSelected(SelectionEvent e) { |
327 |
LinkListInformationControl.this.dispose(); |
328 |
link.open(); |
329 |
} |
330 |
}); |
331 |
|
332 |
} |
333 |
} |
334 |
|
335 |
/* (non-Javadoc) |
336 |
* @see org.eclipse.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int) |
337 |
*/ |
338 |
public Point computeSizeConstraints(int widthInChars, int heightInChars) { |
339 |
Font font= JFaceResources.getDialogFont(); |
340 |
|
341 |
GC gc= new GC(font.getDevice()); |
342 |
gc.setFont(font); |
343 |
FontMetrics metrics= gc.getFontMetrics(); |
344 |
gc.dispose(); |
345 |
|
346 |
int width= Dialog.convertWidthInCharsToPixels(metrics, widthInChars); |
347 |
int height= Dialog.convertHeightInCharsToPixels(metrics, heightInChars); |
348 |
|
349 |
return new Point(width, height); |
350 |
} |
351 |
} |