Mercurial > projects > dwt-addons
comparison dwtx/jface/text/PaintManager.d @ 129:eb30df5ca28b
Added JFace Text sources
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 23 Aug 2008 19:10:48 +0200 |
parents | |
children | c4fb132a086c |
comparison
equal
deleted
inserted
replaced
128:8df1d4193877 | 129:eb30df5ca28b |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2005 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.PaintManager; | |
14 | |
15 import dwt.dwthelper.utils; | |
16 | |
17 | |
18 import java.util.ArrayList; | |
19 import java.util.Iterator; | |
20 import java.util.List; | |
21 | |
22 import dwt.custom.StyledText; | |
23 import dwt.events.KeyEvent; | |
24 import dwt.events.KeyListener; | |
25 import dwt.events.MouseEvent; | |
26 import dwt.events.MouseListener; | |
27 import dwt.widgets.Control; | |
28 import dwtx.jface.viewers.ISelectionChangedListener; | |
29 import dwtx.jface.viewers.ISelectionProvider; | |
30 import dwtx.jface.viewers.SelectionChangedEvent; | |
31 | |
32 | |
33 /** | |
34 * Manages the {@link dwtx.jface.text.IPainter} object registered with an | |
35 * {@link dwtx.jface.text.ITextViewer}. | |
36 * <p> | |
37 * Clients usually instantiate and configure objects of this type.</p> | |
38 * | |
39 * @since 2.1 | |
40 */ | |
41 public final class PaintManager : KeyListener, MouseListener, ISelectionChangedListener, ITextListener, ITextInputListener { | |
42 | |
43 /** | |
44 * Position updater used by the position manager. This position updater differs from the default position | |
45 * updater in that it extends a position when an insertion happens at the position's offset and right behind | |
46 * the position. | |
47 */ | |
48 static class PaintPositionUpdater : DefaultPositionUpdater { | |
49 | |
50 /** | |
51 * Creates the position updater for the given category. | |
52 * | |
53 * @param category the position category | |
54 */ | |
55 protected PaintPositionUpdater(String category) { | |
56 super(category); | |
57 } | |
58 | |
59 /** | |
60 * If an insertion happens at a position's offset, the | |
61 * position is extended rather than shifted. Also, if something is added | |
62 * right behind the end of the position, the position is extended rather | |
63 * than kept stable. | |
64 */ | |
65 protected void adaptToInsert() { | |
66 | |
67 int myStart= fPosition.offset; | |
68 int myEnd= fPosition.offset + fPosition.length; | |
69 myEnd= Math.max(myStart, myEnd); | |
70 | |
71 int yoursStart= fOffset; | |
72 int yoursEnd= fOffset + fReplaceLength;// - 1; | |
73 yoursEnd= Math.max(yoursStart, yoursEnd); | |
74 | |
75 if (myEnd < yoursStart) | |
76 return; | |
77 | |
78 if (myStart <= yoursStart) | |
79 fPosition.length += fReplaceLength; | |
80 else | |
81 fPosition.offset += fReplaceLength; | |
82 } | |
83 } | |
84 | |
85 /** | |
86 * The paint position manager used by this paint manager. The paint position | |
87 * manager is installed on a single document and control the creation/disposed | |
88 * and updating of a position category that will be used for managing positions. | |
89 */ | |
90 static class PositionManager : IPaintPositionManager { | |
91 | |
92 // /** The document this position manager works on */ | |
93 private IDocument fDocument; | |
94 /** The position updater used for the managing position category */ | |
95 private IPositionUpdater fPositionUpdater; | |
96 /** The managing position category */ | |
97 private String fCategory; | |
98 | |
99 /** | |
100 * Creates a new position manager. Initializes the managing | |
101 * position category using its class name and its hash value. | |
102 */ | |
103 public PositionManager() { | |
104 fCategory= getClass().getName() + hashCode(); | |
105 fPositionUpdater= new PaintPositionUpdater(fCategory); | |
106 } | |
107 | |
108 /** | |
109 * Installs this position manager in the given document. The position manager stays | |
110 * active until <code>uninstall</code> or <code>dispose</code> | |
111 * is called. | |
112 * | |
113 * @param document the document to be installed on | |
114 */ | |
115 public void install(IDocument document) { | |
116 fDocument= document; | |
117 fDocument.addPositionCategory(fCategory); | |
118 fDocument.addPositionUpdater(fPositionUpdater); | |
119 } | |
120 | |
121 /** | |
122 * Disposes this position manager. The position manager is automatically | |
123 * removed from the document it has previously been installed | |
124 * on. | |
125 */ | |
126 public void dispose() { | |
127 uninstall(fDocument); | |
128 } | |
129 | |
130 /** | |
131 * Uninstalls this position manager form the given document. If the position | |
132 * manager has no been installed on this document, this method is without effect. | |
133 * | |
134 * @param document the document form which to uninstall | |
135 */ | |
136 public void uninstall(IDocument document) { | |
137 if (document is fDocument && document !is null) { | |
138 try { | |
139 fDocument.removePositionUpdater(fPositionUpdater); | |
140 fDocument.removePositionCategory(fCategory); | |
141 } catch (BadPositionCategoryException x) { | |
142 // should not happen | |
143 } | |
144 fDocument= null; | |
145 } | |
146 } | |
147 | |
148 /* | |
149 * @see IPositionManager#addManagedPosition(Position) | |
150 */ | |
151 public void managePosition(Position position) { | |
152 try { | |
153 fDocument.addPosition(fCategory, position); | |
154 } catch (BadPositionCategoryException x) { | |
155 // should not happen | |
156 } catch (BadLocationException x) { | |
157 // should not happen | |
158 } | |
159 } | |
160 | |
161 /* | |
162 * @see IPositionManager#removeManagedPosition(Position) | |
163 */ | |
164 public void unmanagePosition(Position position) { | |
165 try { | |
166 fDocument.removePosition(fCategory, position); | |
167 } catch (BadPositionCategoryException x) { | |
168 // should not happen | |
169 } | |
170 } | |
171 } | |
172 | |
173 | |
174 /** The painters managed by this paint manager. */ | |
175 private List fPainters= new ArrayList(2); | |
176 /** The position manager used by this paint manager */ | |
177 private PositionManager fManager; | |
178 /** The associated text viewer */ | |
179 private ITextViewer fTextViewer; | |
180 | |
181 /** | |
182 * Creates a new paint manager for the given text viewer. | |
183 * | |
184 * @param textViewer the text viewer associated to this newly created paint manager | |
185 */ | |
186 public PaintManager(ITextViewer textViewer) { | |
187 fTextViewer= textViewer; | |
188 } | |
189 | |
190 | |
191 /** | |
192 * Adds the given painter to the list of painters managed by this paint manager. | |
193 * If the painter is already registered with this paint manager, this method is | |
194 * without effect. | |
195 * | |
196 * @param painter the painter to be added | |
197 */ | |
198 public void addPainter(IPainter painter) { | |
199 if (!fPainters.contains(painter)) { | |
200 fPainters.add(painter); | |
201 if (fPainters.size() is 1) | |
202 install(); | |
203 painter.setPositionManager(fManager); | |
204 painter.paint(IPainter.INTERNAL); | |
205 } | |
206 } | |
207 | |
208 /** | |
209 * Removes the given painter from the list of painters managed by this | |
210 * paint manager. If the painter has not previously been added to this | |
211 * paint manager, this method is without effect. | |
212 * | |
213 * @param painter the painter to be removed | |
214 */ | |
215 public void removePainter(IPainter painter) { | |
216 if (fPainters.remove(painter)) { | |
217 painter.deactivate(true); | |
218 painter.setPositionManager(null); | |
219 } | |
220 if (fPainters.size() is 0) | |
221 dispose(); | |
222 } | |
223 | |
224 /** | |
225 * Installs/activates this paint manager. Is called as soon as the | |
226 * first painter is to be managed by this paint manager. | |
227 */ | |
228 private void install() { | |
229 | |
230 fManager= new PositionManager(); | |
231 if (fTextViewer.getDocument() !is null) | |
232 fManager.install(fTextViewer.getDocument()); | |
233 | |
234 fTextViewer.addTextInputListener(this); | |
235 | |
236 addListeners(); | |
237 } | |
238 | |
239 /** | |
240 * Installs our listener set on the text viewer and the text widget, | |
241 * respectively. | |
242 */ | |
243 private void addListeners() { | |
244 ISelectionProvider provider= fTextViewer.getSelectionProvider(); | |
245 provider.addSelectionChangedListener(this); | |
246 | |
247 fTextViewer.addTextListener(this); | |
248 | |
249 StyledText text= fTextViewer.getTextWidget(); | |
250 text.addKeyListener(this); | |
251 text.addMouseListener(this); | |
252 } | |
253 | |
254 /** | |
255 * Disposes this paint manager. The paint manager uninstalls itself | |
256 * and clears all registered painters. This method is also called when the | |
257 * last painter is removed from the list of managed painters. | |
258 */ | |
259 public void dispose() { | |
260 | |
261 if (fManager !is null) { | |
262 fManager.dispose(); | |
263 fManager= null; | |
264 } | |
265 | |
266 for (Iterator e = fPainters.iterator(); e.hasNext();) | |
267 ((IPainter) e.next()).dispose(); | |
268 fPainters.clear(); | |
269 | |
270 fTextViewer.removeTextInputListener(this); | |
271 | |
272 removeListeners(); | |
273 } | |
274 | |
275 /** | |
276 * Removes our set of listeners from the text viewer and widget, | |
277 * respectively. | |
278 */ | |
279 private void removeListeners() { | |
280 ISelectionProvider provider= fTextViewer.getSelectionProvider(); | |
281 if (provider !is null) | |
282 provider.removeSelectionChangedListener(this); | |
283 | |
284 fTextViewer.removeTextListener(this); | |
285 | |
286 StyledText text= fTextViewer.getTextWidget(); | |
287 if (text !is null && !text.isDisposed()) { | |
288 text.removeKeyListener(this); | |
289 text.removeMouseListener(this); | |
290 } | |
291 } | |
292 | |
293 /** | |
294 * Triggers all registered painters for the given reason. | |
295 * | |
296 * @param reason the reason | |
297 * @see IPainter | |
298 */ | |
299 private void paint(int reason) { | |
300 for (Iterator e = fPainters.iterator(); e.hasNext();) | |
301 ((IPainter) e.next()).paint(reason); | |
302 } | |
303 | |
304 /* | |
305 * @see KeyListener#keyPressed(KeyEvent) | |
306 */ | |
307 public void keyPressed(KeyEvent e) { | |
308 paint(IPainter.KEY_STROKE); | |
309 } | |
310 | |
311 /* | |
312 * @see KeyListener#keyReleased(KeyEvent) | |
313 */ | |
314 public void keyReleased(KeyEvent e) { | |
315 } | |
316 | |
317 /* | |
318 * @see MouseListener#mouseDoubleClick(MouseEvent) | |
319 */ | |
320 public void mouseDoubleClick(MouseEvent e) { | |
321 } | |
322 | |
323 /* | |
324 * @see MouseListener#mouseDown(MouseEvent) | |
325 */ | |
326 public void mouseDown(MouseEvent e) { | |
327 paint(IPainter.MOUSE_BUTTON); | |
328 } | |
329 | |
330 /* | |
331 * @see MouseListener#mouseUp(MouseEvent) | |
332 */ | |
333 public void mouseUp(MouseEvent e) { | |
334 } | |
335 | |
336 /* | |
337 * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent) | |
338 */ | |
339 public void selectionChanged(SelectionChangedEvent event) { | |
340 paint(IPainter.SELECTION); | |
341 } | |
342 | |
343 /* | |
344 * @see ITextListener#textChanged(TextEvent) | |
345 */ | |
346 public void textChanged(TextEvent event) { | |
347 | |
348 if (!event.getViewerRedrawState()) | |
349 return; | |
350 | |
351 Control control= fTextViewer.getTextWidget(); | |
352 if (control !is null) { | |
353 control.getDisplay().asyncExec(new Runnable() { | |
354 public void run() { | |
355 if (fTextViewer !is null) | |
356 paint(IPainter.TEXT_CHANGE); | |
357 } | |
358 }); | |
359 } | |
360 } | |
361 | |
362 /* | |
363 * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument) | |
364 */ | |
365 public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { | |
366 if (oldInput !is null) { | |
367 for (Iterator e = fPainters.iterator(); e.hasNext();) | |
368 ((IPainter) e.next()).deactivate(false); | |
369 fManager.uninstall(oldInput); | |
370 removeListeners(); | |
371 } | |
372 } | |
373 | |
374 /* | |
375 * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument) | |
376 */ | |
377 public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { | |
378 if (newInput !is null) { | |
379 fManager.install(newInput); | |
380 paint(IPainter.TEXT_CHANGE); | |
381 addListeners(); | |
382 } | |
383 } | |
384 } | |
385 |