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