Mercurial > projects > dwt-addons
annotate dwtx/jface/text/source/projection/ProjectionSummary.d @ 157:7f75eaa8103a
volatile and cast Map.Entry
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 25 Aug 2008 19:06:44 +0200 |
parents | f70d9508c95c |
children | 25f1f92fa3df |
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.source.projection.ProjectionSummary; | |
14 | |
131 | 15 import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport |
16 import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport | |
17 import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport | |
18 import dwtx.jface.text.source.projection.AnnotationBag; // packageimport | |
19 import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport | |
20 import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport | |
21 import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport | |
22 import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport | |
23 import dwtx.jface.text.source.projection.IProjectionListener; // packageimport | |
24 import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport | |
25 | |
26 | |
129 | 27 import dwt.dwthelper.utils; |
28 | |
29 | |
153
f70d9508c95c
Fix java Collection imports
Frank Benoit <benoit@tionex.de>
parents:
143
diff
changeset
|
30 import dwtx.dwtxhelper.Collection; |
f70d9508c95c
Fix java Collection imports
Frank Benoit <benoit@tionex.de>
parents:
143
diff
changeset
|
31 |
f70d9508c95c
Fix java Collection imports
Frank Benoit <benoit@tionex.de>
parents:
143
diff
changeset
|
32 |
f70d9508c95c
Fix java Collection imports
Frank Benoit <benoit@tionex.de>
parents:
143
diff
changeset
|
33 |
f70d9508c95c
Fix java Collection imports
Frank Benoit <benoit@tionex.de>
parents:
143
diff
changeset
|
34 |
129 | 35 |
36 import dwtx.core.runtime.IProgressMonitor; | |
37 import dwtx.core.runtime.NullProgressMonitor; | |
38 import dwtx.jface.text.IDocument; | |
39 import dwtx.jface.text.IRegion; | |
40 import dwtx.jface.text.ISynchronizable; | |
41 import dwtx.jface.text.Position; | |
42 import dwtx.jface.text.source.Annotation; | |
43 import dwtx.jface.text.source.IAnnotationAccess; | |
44 import dwtx.jface.text.source.IAnnotationAccessExtension; | |
45 import dwtx.jface.text.source.IAnnotationModel; | |
46 import dwtx.jface.text.source.IAnnotationModelExtension; | |
47 | |
48 | |
49 /** | |
50 * Strategy for managing annotation summaries for collapsed ranges. | |
51 * | |
52 * @since 3.0 | |
53 */ | |
54 class ProjectionSummary { | |
55 | |
56 private class Summarizer : Thread { | |
57 | |
58 private bool fReset= true; | |
59 | |
60 /** | |
61 * Creates a new thread. | |
62 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
63 public this() { |
129 | 64 fProgressMonitor= new NullProgressMonitor(); // might be given by client in the future |
65 setDaemon(true); | |
66 start(); | |
67 } | |
68 | |
69 /** | |
70 * Resets the thread. | |
71 */ | |
72 public void reset() { | |
73 synchronized (fLock) { | |
74 fReset= true; | |
75 fProgressMonitor.setCanceled(true); | |
76 } | |
77 } | |
78 | |
79 /* | |
80 * @see java.lang.Thread#run() | |
81 */ | |
82 public void run() { | |
83 while (true) { | |
84 synchronized (fLock) { | |
85 if (!fReset) | |
86 break; | |
87 fReset= false; | |
88 fProgressMonitor.setCanceled(false); | |
89 } | |
90 internalUpdateSummaries(fProgressMonitor); | |
91 } | |
92 | |
93 synchronized (fLock) { | |
94 fSummarizer= null; | |
95 } | |
96 } | |
97 } | |
98 | |
99 | |
100 private ProjectionViewer fProjectionViewer; | |
101 private IAnnotationModel fAnnotationModel; | |
102 private IAnnotationAccess fAnnotationAccess; | |
103 private List fConfiguredAnnotationTypes; | |
104 | |
105 private Object fLock= new Object(); | |
106 private IProgressMonitor fProgressMonitor; | |
157
7f75eaa8103a
volatile and cast Map.Entry
Frank Benoit <benoit@tionex.de>
parents:
153
diff
changeset
|
107 private /+volatile+/ Summarizer fSummarizer; |
129 | 108 |
109 /** | |
110 * Creates a new projection summary. | |
111 * | |
112 * @param projectionViewer the projection viewer | |
113 * @param annotationAccess the annotation access | |
114 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
115 public this(ProjectionViewer projectionViewer, IAnnotationAccess annotationAccess) { |
129 | 116 super(); |
117 fProjectionViewer= projectionViewer; | |
118 fAnnotationAccess= annotationAccess; | |
119 } | |
120 | |
121 /** | |
122 * Adds the given annotation type. For now on, annotations of that type are | |
123 * also reflected in their enclosing collapsed regions. | |
124 * | |
125 * @param annotationType the annotation type to add | |
126 */ | |
127 public void addAnnotationType(String annotationType) { | |
128 synchronized(fLock) { | |
129 if (fConfiguredAnnotationTypes is null) { | |
130 fConfiguredAnnotationTypes= new ArrayList(); | |
131 fConfiguredAnnotationTypes.add(annotationType); | |
132 } else if (!fConfiguredAnnotationTypes.contains(annotationType)) | |
133 fConfiguredAnnotationTypes.add(annotationType); | |
134 } | |
135 } | |
136 | |
137 /** | |
138 * Removes the given annotation. Annotation of that type are no | |
139 * longer reflected in their enclosing collapsed region. | |
140 * | |
141 * @param annotationType the annotation type to remove | |
142 */ | |
143 public void removeAnnotationType(String annotationType) { | |
144 synchronized (fLock) { | |
145 if (fConfiguredAnnotationTypes !is null) { | |
146 fConfiguredAnnotationTypes.remove(annotationType); | |
147 if (fConfiguredAnnotationTypes.size() is 0) | |
148 fConfiguredAnnotationTypes= null; | |
149 } | |
150 } | |
151 } | |
152 | |
153 /** | |
154 * Forces an updated of the annotation summary. | |
155 */ | |
156 public void updateSummaries() { | |
157 synchronized (fLock) { | |
158 if (fConfiguredAnnotationTypes !is null) { | |
159 if (fSummarizer is null) | |
160 fSummarizer= new Summarizer(); | |
161 fSummarizer.reset(); | |
162 } | |
163 } | |
164 } | |
165 | |
166 private void internalUpdateSummaries(IProgressMonitor monitor) { | |
167 | |
168 Object previousLockObject= null; | |
169 fAnnotationModel= fProjectionViewer.getVisualAnnotationModel(); | |
170 if (fAnnotationModel is null) | |
171 return; | |
172 | |
173 try { | |
174 | |
175 | |
176 IDocument document= fProjectionViewer.getDocument(); | |
143 | 177 if ( cast(ISynchronizable)document && cast(ISynchronizable)fAnnotationModel ) { |
134 | 178 ISynchronizable sync= cast(ISynchronizable) fAnnotationModel; |
129 | 179 previousLockObject= sync.getLockObject(); |
134 | 180 sync.setLockObject((cast(ISynchronizable) document).getLockObject()); |
129 | 181 } |
182 | |
183 | |
184 removeSummaries(monitor); | |
185 | |
186 if (isCanceled(monitor)) | |
187 return; | |
188 | |
189 createSummaries(monitor); | |
190 | |
191 } finally { | |
192 | |
138 | 193 if ( cast(ISynchronizable)fAnnotationModel ) { |
134 | 194 ISynchronizable sync= cast(ISynchronizable) fAnnotationModel; |
129 | 195 sync.setLockObject(previousLockObject); |
196 } | |
197 fAnnotationModel= null; | |
198 | |
199 } | |
200 } | |
201 | |
202 private bool isCanceled(IProgressMonitor monitor) { | |
203 return monitor !is null && monitor.isCanceled(); | |
204 } | |
205 | |
206 private void removeSummaries(IProgressMonitor monitor) { | |
207 IAnnotationModelExtension extension= null; | |
208 List bags= null; | |
209 | |
138 | 210 if ( cast(IAnnotationModelExtension)fAnnotationModel ) { |
134 | 211 extension= cast(IAnnotationModelExtension) fAnnotationModel; |
129 | 212 bags= new ArrayList(); |
213 } | |
214 | |
215 Iterator e= fAnnotationModel.getAnnotationIterator(); | |
216 while (e.hasNext()) { | |
134 | 217 Annotation annotation= cast(Annotation) e.next(); |
138 | 218 if ( cast(AnnotationBag)annotation ) { |
129 | 219 if (bags is null) |
220 fAnnotationModel.removeAnnotation(annotation); | |
221 else | |
222 bags.add(annotation); | |
223 } | |
224 | |
225 if (isCanceled(monitor)) | |
226 return; | |
227 } | |
228 | |
229 if (bags !is null && bags.size() > 0) { | |
230 Annotation[] deletions= new Annotation[bags.size()]; | |
231 bags.toArray(deletions); | |
232 if (!isCanceled(monitor)) | |
233 extension.replaceAnnotations(deletions, null); | |
234 } | |
235 } | |
236 | |
237 private void createSummaries(IProgressMonitor monitor) { | |
238 ProjectionAnnotationModel model= fProjectionViewer.getProjectionAnnotationModel(); | |
239 if (model is null) | |
240 return; | |
241 | |
242 Map additions= new HashMap(); | |
243 | |
244 Iterator e= model.getAnnotationIterator(); | |
245 while (e.hasNext()) { | |
134 | 246 ProjectionAnnotation projection= cast(ProjectionAnnotation) e.next(); |
129 | 247 if (projection.isCollapsed()) { |
248 Position position= model.getPosition(projection); | |
249 if (position !is null) { | |
250 IRegion[] summaryRegions= fProjectionViewer.computeCollapsedRegions(position); | |
251 if (summaryRegions !is null) { | |
252 Position summaryAnchor= fProjectionViewer.computeCollapsedRegionAnchor(position); | |
253 if (summaryAnchor !is null) | |
254 createSummary(additions, summaryRegions, summaryAnchor); | |
255 } | |
256 } | |
257 } | |
258 | |
259 if (isCanceled(monitor)) | |
260 return; | |
261 } | |
262 | |
263 if (additions.size() > 0) { | |
138 | 264 if ( cast(IAnnotationModelExtension)fAnnotationModel ) { |
134 | 265 IAnnotationModelExtension extension= cast(IAnnotationModelExtension) fAnnotationModel; |
129 | 266 if (!isCanceled(monitor)) |
267 extension.replaceAnnotations(null, additions); | |
268 } else { | |
269 Iterator e1= additions.keySet().iterator(); | |
270 while (e1.hasNext()) { | |
134 | 271 AnnotationBag bag= cast(AnnotationBag) e1.next(); |
272 Position position= cast(Position) additions.get(bag); | |
129 | 273 if (isCanceled(monitor)) |
274 return; | |
275 fAnnotationModel.addAnnotation(bag, position); | |
276 } | |
277 } | |
278 } | |
279 } | |
280 | |
281 private void createSummary(Map additions, IRegion[] summaryRegions, Position summaryAnchor) { | |
282 | |
283 int size= 0; | |
284 Map map= null; | |
285 | |
286 synchronized (fLock) { | |
287 if (fConfiguredAnnotationTypes !is null) { | |
288 size= fConfiguredAnnotationTypes.size(); | |
289 map= new HashMap(); | |
290 for (int i= 0; i < size; i++) { | |
134 | 291 String type= cast(String) fConfiguredAnnotationTypes.get(i); |
129 | 292 map.put(type, new AnnotationBag(type)); |
293 } | |
294 } | |
295 } | |
296 | |
297 if (map is null) | |
298 return; | |
299 | |
300 IAnnotationModel model= fProjectionViewer.getAnnotationModel(); | |
301 if (model is null) | |
302 return; | |
303 Iterator e= model.getAnnotationIterator(); | |
304 while (e.hasNext()) { | |
134 | 305 Annotation annotation= cast(Annotation) e.next(); |
129 | 306 AnnotationBag bag= findBagForType(map, annotation.getType()); |
307 if (bag !is null) { | |
308 Position position= model.getPosition(annotation); | |
309 if (includes(summaryRegions, position)) | |
310 bag.add(annotation); | |
311 } | |
312 } | |
313 | |
314 for (int i= 0; i < size; i++) { | |
134 | 315 AnnotationBag bag= cast(AnnotationBag) map.get(fConfiguredAnnotationTypes.get(i)); |
129 | 316 if (!bag.isEmpty()) |
317 additions.put(bag, new Position(summaryAnchor.getOffset(), summaryAnchor.getLength())); | |
318 } | |
319 } | |
320 | |
321 private AnnotationBag findBagForType(Map bagMap, String annotationType) { | |
134 | 322 AnnotationBag bag= cast(AnnotationBag) bagMap.get(annotationType); |
143 | 323 if (bag is null && cast(IAnnotationAccessExtension)fAnnotationAccess ) { |
134 | 324 IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess; |
129 | 325 Object[] superTypes= extension.getSupertypes(annotationType); |
326 for (int i= 0; i < superTypes.length && bag is null; i++) { | |
134 | 327 bag= cast(AnnotationBag) bagMap.get(superTypes[i]); |
129 | 328 } |
329 } | |
330 return bag; | |
331 } | |
332 | |
333 private bool includes(IRegion[] regions, Position position) { | |
334 for (int i= 0; i < regions.length; i++) { | |
335 IRegion region= regions[i]; | |
336 if (position !is null && !position.isDeleted() | |
337 && region.getOffset() <= position.getOffset() && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength()) | |
338 return true; | |
339 } | |
340 return false; | |
341 } | |
342 } |