Mercurial > projects > dwt-addons
annotate dwtx/jface/text/hyperlink/DefaultHyperlinkPresenter.d @ 134:51e6e63f930e
Regex fix for casts
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 24 Aug 2008 01:46:20 +0200 |
parents | 7d818bd32d63 |
children | 65801ad2b265 |
rev | line source |
---|---|
129 | 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 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; | |
14 | |
131 | 15 import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport |
16 import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport | |
17 import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport | |
18 import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport | |
19 import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport | |
20 import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport | |
21 import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport | |
22 import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport | |
23 import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport | |
24 import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport | |
25 import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport | |
26 import dwtx.jface.text.hyperlink.IHyperlink; // packageimport | |
27 | |
28 | |
129 | 29 import dwt.dwthelper.utils; |
30 | |
31 | |
32 | |
33 | |
34 | |
35 import dwt.DWT; | |
36 import dwt.custom.StyleRange; | |
37 import dwt.custom.StyledText; | |
38 import dwt.graphics.Color; | |
39 import dwt.graphics.Cursor; | |
40 import dwt.graphics.RGB; | |
41 import dwt.widgets.Display; | |
42 import dwtx.core.runtime.Assert; | |
43 import dwtx.jface.preference.IPreferenceStore; | |
44 import dwtx.jface.preference.PreferenceConverter; | |
45 import dwtx.jface.text.BadLocationException; | |
46 import dwtx.jface.text.DocumentEvent; | |
47 import dwtx.jface.text.IDocument; | |
48 import dwtx.jface.text.IDocumentListener; | |
49 import dwtx.jface.text.IRegion; | |
50 import dwtx.jface.text.ITextInputListener; | |
51 import dwtx.jface.text.ITextPresentationListener; | |
52 import dwtx.jface.text.ITextViewer; | |
53 import dwtx.jface.text.ITextViewerExtension2; | |
54 import dwtx.jface.text.ITextViewerExtension4; | |
55 import dwtx.jface.text.Position; | |
56 import dwtx.jface.text.Region; | |
57 import dwtx.jface.text.TextPresentation; | |
58 import dwtx.jface.util.IPropertyChangeListener; | |
59 import dwtx.jface.util.PropertyChangeEvent; | |
60 | |
61 | |
62 /** | |
63 * The default hyperlink presenter underlines the | |
64 * link and colors the line and the text with | |
65 * the given color. | |
66 * <p> | |
67 * It can only be used together with the {@link HyperlinkManager#FIRST} | |
68 * or the {@link HyperlinkManager#LONGEST_REGION_FIRST} hyperlink strategy. | |
69 * </p> | |
70 * | |
71 * @since 3.1 | |
72 */ | |
73 public class DefaultHyperlinkPresenter : IHyperlinkPresenter, IHyperlinkPresenterExtension, ITextPresentationListener, ITextInputListener, IDocumentListener, IPropertyChangeListener { | |
74 | |
75 /** | |
76 * A named preference that holds the color used for hyperlinks. | |
77 * <p> | |
78 * Value is of type <code>String</code>. A RGB color value encoded as a string | |
79 * using class <code>PreferenceConverter</code> | |
80 * </p> | |
81 * | |
82 * @see dwtx.jface.resource.StringConverter | |
83 * @see dwtx.jface.preference.PreferenceConverter | |
84 */ | |
85 public final static String HYPERLINK_COLOR= "hyperlinkColor"; //$NON-NLS-1$ | |
86 | |
87 | |
88 /** The text viewer. */ | |
89 private ITextViewer fTextViewer; | |
90 /** The hand cursor. */ | |
91 private Cursor fCursor; | |
92 /** The link color. */ | |
93 private Color fColor; | |
94 /** The link color specification. May be <code>null</code>. */ | |
95 private RGB fRGB; | |
96 /** Tells whether to dispose the color on uninstall. */ | |
97 private bool fDisposeColor; | |
98 /** The currently active region. */ | |
99 private IRegion fActiveRegion; | |
100 /** The currently active style range as position. */ | |
101 private Position fRememberedPosition; | |
102 /** The optional preference store. May be <code>null</code>. */ | |
103 private IPreferenceStore fPreferenceStore; | |
104 | |
105 | |
106 /** | |
107 * Creates a new default hyperlink presenter which uses | |
108 * {@link #HYPERLINK_COLOR} to read the color from the given preference store. | |
109 * | |
110 * @param store the preference store | |
111 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
112 public this(IPreferenceStore store) { |
129 | 113 fPreferenceStore= store; |
114 fDisposeColor= true; | |
115 } | |
116 | |
117 /** | |
118 * Creates a new default hyperlink presenter. | |
119 * | |
120 * @param color the hyperlink color, to be disposed by the caller | |
121 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
122 public this(Color color) { |
129 | 123 fDisposeColor= false; |
124 fColor= color; | |
125 } | |
126 | |
127 /** | |
128 * Creates a new default hyperlink presenter. | |
129 * | |
130 * @param color the hyperlink color | |
131 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
132 public this(RGB color) { |
129 | 133 fRGB= color; |
134 fDisposeColor= true; | |
135 } | |
136 | |
137 /* | |
138 * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#canShowMultipleHyperlinks() | |
139 */ | |
140 public bool canShowMultipleHyperlinks() { | |
141 return false; | |
142 } | |
143 | |
144 /* | |
145 * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#activate(dwtx.jdt.internal.ui.javaeditor.IHyperlink[]) | |
146 */ | |
147 public void showHyperlinks(IHyperlink[] hyperlinks) { | |
148 Assert.isLegal(hyperlinks !is null && hyperlinks.length is 1); | |
149 highlightRegion(hyperlinks[0].getHyperlinkRegion()); | |
150 activateCursor(); | |
151 } | |
152 | |
153 /** | |
154 * {@inheritDoc} | |
155 * | |
156 * @since 3.4 | |
157 */ | |
158 public bool canHideHyperlinks() { | |
159 return true; | |
160 } | |
161 | |
162 /* | |
163 * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#deactivate() | |
164 */ | |
165 public void hideHyperlinks() { | |
166 repairRepresentation(); | |
167 fRememberedPosition= null; | |
168 } | |
169 | |
170 /* | |
171 * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#install(dwtx.jface.text.ITextViewer) | |
172 */ | |
173 public void install(ITextViewer textViewer) { | |
174 Assert.isNotNull(textViewer); | |
175 fTextViewer= textViewer; | |
176 fTextViewer.addTextInputListener(this); | |
177 if (fTextViewer instanceof ITextViewerExtension4) | |
134 | 178 (cast(ITextViewerExtension4)fTextViewer).addTextPresentationListener(this); |
129 | 179 |
180 StyledText text= fTextViewer.getTextWidget(); | |
181 if (text !is null && !text.isDisposed()) { | |
182 if (fPreferenceStore !is null) | |
183 fColor= createColor(fPreferenceStore, HYPERLINK_COLOR, text.getDisplay()); | |
184 else if (fRGB !is null) | |
185 fColor= new Color(text.getDisplay(), fRGB); | |
186 } | |
187 | |
188 if (fPreferenceStore !is null) | |
189 fPreferenceStore.addPropertyChangeListener(this); | |
190 } | |
191 | |
192 /* | |
193 * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#uninstall() | |
194 */ | |
195 public void uninstall() { | |
196 fTextViewer.removeTextInputListener(this); | |
197 IDocument document= fTextViewer.getDocument(); | |
198 if (document !is null) | |
199 document.removeDocumentListener(this); | |
200 | |
201 if (fColor !is null) { | |
202 if (fDisposeColor) | |
203 fColor.dispose(); | |
204 fColor= null; | |
205 } | |
206 | |
207 if (fCursor !is null) { | |
208 fCursor.dispose(); | |
209 fCursor= null; | |
210 } | |
211 | |
212 if (fTextViewer instanceof ITextViewerExtension4) | |
134 | 213 (cast(ITextViewerExtension4)fTextViewer).removeTextPresentationListener(this); |
129 | 214 fTextViewer= null; |
215 | |
216 if (fPreferenceStore !is null) | |
217 fPreferenceStore.removePropertyChangeListener(this); | |
218 } | |
219 | |
220 public void setColor(Color color) { | |
221 Assert.isNotNull(fTextViewer); | |
222 fColor= color; | |
223 } | |
224 | |
225 /* | |
226 * @see dwtx.jface.text.ITextPresentationListener#applyTextPresentation(dwtx.jface.text.TextPresentation) | |
227 */ | |
228 public void applyTextPresentation(TextPresentation textPresentation) { | |
229 if (fActiveRegion is null) | |
230 return; | |
231 IRegion region= textPresentation.getExtent(); | |
232 if (fActiveRegion.getOffset() + fActiveRegion.getLength() >= region.getOffset() && region.getOffset() + region.getLength() > fActiveRegion.getOffset()) { | |
233 StyleRange styleRange= new StyleRange(fActiveRegion.getOffset(), fActiveRegion.getLength(), fColor, null); | |
234 styleRange.underline= true; | |
235 textPresentation.mergeStyleRange(styleRange); | |
236 } | |
237 } | |
238 | |
239 private void highlightRegion(IRegion region) { | |
240 | |
241 if (region.equals(fActiveRegion)) | |
242 return; | |
243 | |
244 repairRepresentation(); | |
245 | |
246 StyledText text= fTextViewer.getTextWidget(); | |
247 if (text is null || text.isDisposed()) | |
248 return; | |
249 | |
250 // Invalidate region is> apply text presentation | |
251 fActiveRegion= region; | |
252 if (fTextViewer instanceof ITextViewerExtension2) | |
134 | 253 (cast(ITextViewerExtension2)fTextViewer).invalidateTextPresentation(region.getOffset(), region.getLength()); |
129 | 254 else |
255 fTextViewer.invalidateTextPresentation(); | |
256 } | |
257 | |
258 private void activateCursor() { | |
259 StyledText text= fTextViewer.getTextWidget(); | |
260 if (text is null || text.isDisposed()) | |
261 return; | |
262 Display display= text.getDisplay(); | |
263 if (fCursor is null) | |
264 fCursor= new Cursor(display, DWT.CURSOR_HAND); | |
265 text.setCursor(fCursor); | |
266 } | |
267 | |
268 private void resetCursor() { | |
269 StyledText text= fTextViewer.getTextWidget(); | |
270 if (text !is null && !text.isDisposed()) | |
271 text.setCursor(null); | |
272 | |
273 if (fCursor !is null) { | |
274 fCursor.dispose(); | |
275 fCursor= null; | |
276 } | |
277 } | |
278 | |
279 private void repairRepresentation() { | |
280 | |
281 if (fActiveRegion is null) | |
282 return; | |
283 | |
284 int offset= fActiveRegion.getOffset(); | |
285 int length= fActiveRegion.getLength(); | |
286 fActiveRegion= null; | |
287 | |
288 resetCursor(); | |
289 | |
290 // Invalidate is> remove applied text presentation | |
291 if (fTextViewer instanceof ITextViewerExtension2) | |
134 | 292 (cast(ITextViewerExtension2) fTextViewer).invalidateTextPresentation(offset, length); |
129 | 293 else |
294 fTextViewer.invalidateTextPresentation(); | |
295 | |
296 } | |
297 | |
298 /* | |
299 * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent) | |
300 */ | |
301 public void documentAboutToBeChanged(DocumentEvent event) { | |
302 if (fActiveRegion !is null) { | |
303 fRememberedPosition= new Position(fActiveRegion.getOffset(), fActiveRegion.getLength()); | |
304 try { | |
305 event.getDocument().addPosition(fRememberedPosition); | |
306 } catch (BadLocationException x) { | |
307 fRememberedPosition= null; | |
308 } | |
309 } | |
310 } | |
311 | |
312 /* | |
313 * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent) | |
314 */ | |
315 public void documentChanged(DocumentEvent event) { | |
316 if (fRememberedPosition !is null) { | |
317 if (!fRememberedPosition.isDeleted()) { | |
318 event.getDocument().removePosition(fRememberedPosition); | |
319 fActiveRegion= new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength()); | |
320 } else { | |
321 fActiveRegion= new Region(event.getOffset(), event.getLength()); | |
322 } | |
323 fRememberedPosition= null; | |
324 | |
325 StyledText widget= fTextViewer.getTextWidget(); | |
326 if (widget !is null && !widget.isDisposed()) { | |
327 widget.getDisplay().asyncExec(new Runnable() { | |
328 public void run() { | |
329 hideHyperlinks(); | |
330 } | |
331 }); | |
332 } | |
333 } | |
334 } | |
335 | |
336 /* | |
337 * @see dwtx.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) | |
338 */ | |
339 public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { | |
340 if (oldInput is null) | |
341 return; | |
342 hideHyperlinks(); | |
343 oldInput.removeDocumentListener(this); | |
344 } | |
345 | |
346 /* | |
347 * @see dwtx.jface.text.ITextInputListener#inputDocumentChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument) | |
348 */ | |
349 public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { | |
350 if (newInput is null) | |
351 return; | |
352 newInput.addDocumentListener(this); | |
353 } | |
354 | |
355 /** | |
356 * Creates a color from the information stored in the given preference store. | |
357 * | |
358 * @param store the preference store | |
359 * @param key the key | |
360 * @param display the display | |
361 * @return the color or <code>null</code> if there is no such information available | |
362 */ | |
363 private Color createColor(IPreferenceStore store, String key, Display display) { | |
364 | |
365 RGB rgb= null; | |
366 | |
367 if (store.contains(key)) { | |
368 | |
369 if (store.isDefault(key)) | |
370 rgb= PreferenceConverter.getDefaultColor(store, key); | |
371 else | |
372 rgb= PreferenceConverter.getColor(store, key); | |
373 | |
374 if (rgb !is null) | |
375 return new Color(display, rgb); | |
376 } | |
377 | |
378 return null; | |
379 } | |
380 | |
381 /* | |
382 * @see dwtx.jface.util.IPropertyChangeListener#propertyChange(dwtx.jface.util.PropertyChangeEvent) | |
383 */ | |
384 public void propertyChange(PropertyChangeEvent event) { | |
385 if (!HYPERLINK_COLOR.equals(event.getProperty())) | |
386 return; | |
387 | |
388 if (fDisposeColor && fColor !is null && !fColor.isDisposed()) | |
389 fColor.dispose(); | |
390 fColor= null; | |
391 | |
392 StyledText textWidget= fTextViewer.getTextWidget(); | |
393 if (textWidget !is null && !textWidget.isDisposed()) | |
394 fColor= createColor(fPreferenceStore, HYPERLINK_COLOR, textWidget.getDisplay()); | |
395 } | |
396 } |