Mercurial > projects > dwt-addons
annotate dwtx/jface/text/contentassist/AdditionalInfoController.d @ 168:cef27f663573
jface.text ...
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 09 Sep 2008 17:44:11 +0200 |
parents | 862b05e0334a |
children | 284c2e810329 |
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.contentassist.AdditionalInfoController; | |
14 | |
131 | 15 import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport |
16 import dwtx.jface.text.contentassist.Helper; // packageimport | |
17 import dwtx.jface.text.contentassist.PopupCloser; // packageimport | |
18 import dwtx.jface.text.contentassist.IContentAssistant; // packageimport | |
19 import dwtx.jface.text.contentassist.CompletionProposal; // packageimport | |
20 import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport | |
21 import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport | |
22 import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport | |
23 import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport | |
24 import dwtx.jface.text.contentassist.ICompletionListener; // packageimport | |
25 import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport | |
26 import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport | |
27 import dwtx.jface.text.contentassist.ContextInformation; // packageimport | |
28 import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport | |
29 import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport | |
30 import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport | |
31 import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport | |
32 import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport | |
33 import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport | |
34 import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport | |
35 import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport | |
36 import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport | |
37 import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport | |
38 import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport | |
39 import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport | |
40 import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport | |
41 import dwtx.jface.text.contentassist.IContextInformation; // packageimport | |
42 import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport | |
43 import dwtx.jface.text.contentassist.ContentAssistant; // packageimport | |
44 import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport | |
45 import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport | |
46 | |
129 | 47 import dwt.dwthelper.utils; |
167 | 48 import dwtx.dwtxhelper.JThread; |
129 | 49 |
50 import dwt.events.SelectionEvent; | |
51 import dwt.events.SelectionListener; | |
52 import dwt.graphics.Point; | |
53 import dwt.graphics.Rectangle; | |
54 import dwt.widgets.Control; | |
55 import dwt.widgets.Display; | |
56 import dwt.widgets.Shell; | |
57 import dwt.widgets.Table; | |
58 import dwt.widgets.TableItem; | |
59 import dwtx.core.runtime.Assert; | |
60 import dwtx.core.runtime.IProgressMonitor; | |
61 import dwtx.core.runtime.IStatus; | |
62 import dwtx.core.runtime.Status; | |
63 import dwtx.core.runtime.jobs.Job; | |
64 import dwtx.jface.internal.text.InformationControlReplacer; | |
65 import dwtx.jface.text.AbstractInformationControlManager; | |
66 import dwtx.jface.text.AbstractReusableInformationControlCreator; | |
67 import dwtx.jface.text.DefaultInformationControl; | |
68 import dwtx.jface.text.IInformationControl; | |
69 import dwtx.jface.text.IInformationControlCreator; | |
70 import dwtx.jface.text.IInformationControlExtension3; | |
71 | |
72 | |
73 /** | |
74 * Displays the additional information available for a completion proposal. | |
75 * | |
76 * @since 2.0 | |
77 */ | |
78 class AdditionalInfoController : AbstractInformationControlManager { | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
79 |
129 | 80 /** |
81 * A timer thread. | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
82 * |
129 | 83 * @since 3.2 |
84 */ | |
85 private static abstract class Timer { | |
147 | 86 private static const int DELAY_UNTIL_JOB_IS_SCHEDULED= 50; |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
87 |
129 | 88 /** |
89 * A <code>Task</code> is {@link Task#run() run} when {@link #delay()} milliseconds have | |
90 * elapsed after it was scheduled without a {@link #reset(ICompletionProposal) reset} | |
91 * to occur. | |
92 */ | |
162 | 93 private static abstract class Task : Runnable { |
129 | 94 /** |
95 * @return the delay in milliseconds before this task should be run | |
96 */ | |
97 public abstract long delay(); | |
98 /** | |
99 * Runs this task. | |
100 */ | |
101 public abstract void run(); | |
102 /** | |
103 * @return the task to be scheduled after this task has been run | |
104 */ | |
105 public abstract Task nextTask(); | |
106 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
107 |
129 | 108 /** |
109 * IDLE: the initial task, and active whenever the info has been shown. It cannot be run, | |
110 * but specifies an infinite delay. | |
111 */ | |
159 | 112 private Task IDLE; |
113 private void IDLE_init(){ | |
114 IDLE = new class() Task { | |
115 public void run() { | |
116 Assert.isTrue(false); | |
117 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
118 |
159 | 119 public Task nextTask() { |
120 Assert.isTrue(false); | |
121 return null; | |
122 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
123 |
159 | 124 public long delay() { |
125 return Long.MAX_VALUE; | |
126 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
127 |
160 | 128 public override String toString() { |
159 | 129 return "IDLE"; //$NON-NLS-1$ |
130 } | |
131 }; | |
132 } | |
129 | 133 /** |
134 * FIRST_WAIT: Schedules a platform {@link Job} to fetch additional info from an {@link ICompletionProposalExtension5}. | |
135 */ | |
159 | 136 private Task FIRST_WAIT; |
137 private void FIRST_WAIT_init() { | |
138 FIRST_WAIT = new class() Task { | |
139 public void run() { | |
140 final ICompletionProposalExtension5 proposal= getCurrentProposalEx(); | |
141 Job job= new class(JFaceTextMessages.getString("AdditionalInfoController.job_name")) Job { //$NON-NLS-1$ | |
142 this( String txt ){ | |
143 super( txt ); | |
129 | 144 } |
159 | 145 protected IStatus run(IProgressMonitor monitor) { |
146 Object info; | |
147 try { | |
148 info= proposal.getAdditionalProposalInfo(monitor); | |
149 } catch (RuntimeException x) { | |
150 /* | |
151 * XXX: This is the safest fix at this point so close to end of 3.2. | |
152 * Will be revisited when fixing https://bugs.eclipse.org/bugs/show_bug.cgi?id=101033 | |
153 */ | |
154 return new Status(IStatus.WARNING, "dwtx.jface.text", IStatus.OK, "", x); //$NON-NLS-1$ //$NON-NLS-2$ | |
155 } | |
156 setInfo(cast(ICompletionProposal) proposal, info); | |
157 return new Status(IStatus.OK, "dwtx.jface.text", IStatus.OK, "", null); //$NON-NLS-1$ //$NON-NLS-2$ | |
158 } | |
159 }; | |
160 job.schedule(); | |
161 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
162 |
159 | 163 public Task nextTask() { |
164 return SECOND_WAIT; | |
165 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
166 |
159 | 167 public long delay() { |
168 return DELAY_UNTIL_JOB_IS_SCHEDULED; | |
169 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
170 |
160 | 171 public override String toString() { |
159 | 172 return "FIRST_WAIT"; //$NON-NLS-1$ |
173 } | |
174 }; | |
175 } | |
129 | 176 /** |
177 * SECOND_WAIT: Allows display of additional info obtained from an | |
178 * {@link ICompletionProposalExtension5}. | |
179 */ | |
159 | 180 private Task SECOND_WAIT; |
181 private void SECOND_WAIT_init() { | |
182 SECOND_WAIT = new class() Task { | |
183 public void run() { | |
184 // show the info | |
185 allowShowing(); | |
186 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
187 |
159 | 188 public Task nextTask() { |
189 return IDLE; | |
190 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
191 |
159 | 192 public long delay() { |
193 return fDelay - DELAY_UNTIL_JOB_IS_SCHEDULED; | |
194 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
195 |
160 | 196 public override String toString() { |
159 | 197 return "SECOND_WAIT"; //$NON-NLS-1$ |
198 } | |
199 }; | |
200 } | |
129 | 201 /** |
202 * LEGACY_WAIT: Posts a runnable into the display thread to fetch additional info from non-{@link ICompletionProposalExtension5}s. | |
203 */ | |
159 | 204 private Task LEGACY_WAIT; |
205 private void LEGACY_WAIT_init() { | |
206 LEGACY_WAIT = new class() Task { | |
207 public void run() { | |
208 final ICompletionProposal proposal= getCurrentProposal(); | |
209 if (!fDisplay.isDisposed()) { | |
210 fDisplay.asyncExec(new class() Runnable { | |
211 public void run() { | |
212 synchronized (this.outer) { | |
213 if (proposal is getCurrentProposal()) { | |
162 | 214 Object info= stringcast(proposal.getAdditionalProposalInfo()); |
159 | 215 showInformation(proposal, info); |
216 } | |
129 | 217 } |
218 } | |
159 | 219 }); |
220 } | |
129 | 221 } |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
222 |
159 | 223 public Task nextTask() { |
224 return IDLE; | |
225 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
226 |
159 | 227 public long delay() { |
228 return fDelay; | |
229 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
230 |
160 | 231 public override String toString() { |
159 | 232 return "LEGACY_WAIT"; //$NON-NLS-1$ |
233 } | |
234 }; | |
235 } | |
129 | 236 /** |
237 * EXIT: The task that triggers termination of the timer thread. | |
238 */ | |
159 | 239 private Task EXIT; |
240 private void EXIT_init() { | |
241 EXIT = new class() Task { | |
242 public long delay() { | |
243 return 1; | |
244 } | |
129 | 245 |
159 | 246 public Task nextTask() { |
247 Assert.isTrue(false); | |
248 return EXIT; | |
249 } | |
129 | 250 |
159 | 251 public void run() { |
252 Assert.isTrue(false); | |
253 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
254 |
160 | 255 public override String toString() { |
159 | 256 return "EXIT"; //$NON-NLS-1$ |
257 } | |
258 }; | |
259 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
260 |
129 | 261 /** The timer thread. */ |
167 | 262 private const JThread fThread; |
129 | 263 |
264 /** The currently waiting / active task. */ | |
265 private Task fTask; | |
266 /** The next wake up time. */ | |
267 private long fNextWakeup; | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
268 |
129 | 269 private ICompletionProposal fCurrentProposal= null; |
270 private Object fCurrentInfo= null; | |
271 private bool fAllowShowing= false; | |
272 | |
146 | 273 private const Display fDisplay; |
274 private const int fDelay; | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
275 |
129 | 276 /** |
277 * Creates a new timer. | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
278 * |
129 | 279 * @param display the display to use for display thread posting. |
280 * @param delay the delay until to show additional info | |
281 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
282 public this(Display display, int delay) { |
159 | 283 // DWT instance init |
284 IDLE_init(); | |
285 FIRST_WAIT_init(); | |
286 SECOND_WAIT_init(); | |
287 LEGACY_WAIT_init(); | |
288 EXIT_init(); | |
289 | |
129 | 290 fDisplay= display; |
291 fDelay= delay; | |
292 long current= System.currentTimeMillis(); | |
293 schedule(IDLE, current); | |
294 | |
168 | 295 fThread= new JThread( &threadrun ); |
296 fThread.serName( JFaceTextMessages.getString("InfoPopup.info_delay_timer_name")); //$NON-NLS-1$ | |
297 fThread.start(); | |
298 } | |
299 void threadrun() { | |
300 try { | |
301 loop(); | |
302 } catch (InterruptedException x) { | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
303 } |
129 | 304 } |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
305 |
129 | 306 /** |
307 * Terminates the timer thread. | |
308 */ | |
309 public synchronized final void terminate() { | |
310 schedule(EXIT, System.currentTimeMillis()); | |
311 notifyAll(); | |
312 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
313 |
129 | 314 /** |
315 * Resets the timer thread as the selection has changed to a new proposal. | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
316 * |
129 | 317 * @param p the new proposal |
318 */ | |
319 public final synchronized void reset(ICompletionProposal p) { | |
320 if (fCurrentProposal !is p) { | |
321 fCurrentProposal= p; | |
322 fCurrentInfo= null; | |
323 fAllowShowing= false; | |
324 | |
325 long oldWakeup= fNextWakeup; | |
326 Task task= taskOnReset(p); | |
327 schedule(task, System.currentTimeMillis()); | |
328 if (fNextWakeup < oldWakeup) | |
329 notifyAll(); | |
330 } | |
331 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
332 |
129 | 333 private Task taskOnReset(ICompletionProposal p) { |
334 if (p is null) | |
335 return IDLE; | |
336 if (isExt5(p)) | |
337 return FIRST_WAIT; | |
338 return LEGACY_WAIT; | |
339 } | |
340 | |
136
6dcb0baaa031
Regex removal of throws decls, some instanceof
Frank Benoit <benoit@tionex.de>
parents:
135
diff
changeset
|
341 private synchronized void loop() { |
129 | 342 long current= System.currentTimeMillis(); |
343 Task task= currentTask(); | |
344 | |
345 while (task !is EXIT) { | |
346 long delay= fNextWakeup - current; | |
347 if (delay <= 0) { | |
348 task.run(); | |
349 task= task.nextTask(); | |
350 schedule(task, current); | |
351 } else { | |
352 wait(delay); | |
353 current= System.currentTimeMillis(); | |
354 task= currentTask(); | |
355 } | |
356 } | |
357 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
358 |
129 | 359 private Task currentTask() { |
360 return fTask; | |
361 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
362 |
129 | 363 private void schedule(Task task, long current) { |
364 fTask= task; | |
365 long nextWakeup= current + task.delay(); | |
366 if (nextWakeup <= current) | |
367 fNextWakeup= Long.MAX_VALUE; | |
368 else | |
369 fNextWakeup= nextWakeup; | |
370 } | |
371 | |
372 private bool isExt5(ICompletionProposal p) { | |
139
93a6ec48fd28
Regexp throws removal in interfaces
Frank Benoit <benoit@tionex.de>
parents:
138
diff
changeset
|
373 return cast(ICompletionProposalExtension5)p; |
129 | 374 } |
375 | |
376 ICompletionProposal getCurrentProposal() { | |
377 return fCurrentProposal; | |
378 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
379 |
129 | 380 ICompletionProposalExtension5 getCurrentProposalEx() { |
138 | 381 Assert.isTrue( cast(ICompletionProposalExtension5)fCurrentProposal ); |
134 | 382 return cast(ICompletionProposalExtension5) fCurrentProposal; |
129 | 383 } |
384 | |
385 synchronized void setInfo(ICompletionProposal proposal, Object info) { | |
386 if (proposal is fCurrentProposal) { | |
387 fCurrentInfo= info; | |
388 if (fAllowShowing) { | |
389 triggerShowing(); | |
390 } | |
391 } | |
392 } | |
393 | |
394 private void triggerShowing() { | |
395 final Object info= fCurrentInfo; | |
396 if (!fDisplay.isDisposed()) { | |
135 | 397 fDisplay.asyncExec(new class() Runnable { |
129 | 398 public void run() { |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
399 synchronized (this.outer) { |
129 | 400 if (info is fCurrentInfo) { |
401 showInformation(fCurrentProposal, info); | |
402 } | |
403 } | |
404 } | |
405 }); | |
406 } | |
407 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
408 |
129 | 409 /** |
410 * Called in the display thread to show additional info. | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
411 * |
129 | 412 * @param proposal the proposal to show information about |
413 * @param info the information about <code>proposal</code> | |
414 */ | |
415 protected abstract void showInformation(ICompletionProposal proposal, Object info); | |
416 | |
417 void allowShowing() { | |
418 fAllowShowing= true; | |
419 triggerShowing(); | |
420 } | |
421 } | |
422 /** | |
423 * Internal table selection listener. | |
424 */ | |
425 private class TableSelectionListener : SelectionListener { | |
426 | |
427 /* | |
428 * @see SelectionListener#widgetSelected(SelectionEvent) | |
429 */ | |
430 public void widgetSelected(SelectionEvent e) { | |
431 handleTableSelectionChanged(); | |
432 } | |
433 | |
434 /* | |
435 * @see SelectionListener#widgetDefaultSelected(SelectionEvent) | |
436 */ | |
437 public void widgetDefaultSelected(SelectionEvent e) { | |
438 } | |
439 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
440 |
129 | 441 /** |
442 * Default control creator for the information control replacer. | |
443 * @since 3.4 | |
444 */ | |
445 private static class DefaultPresenterControlCreator : AbstractReusableInformationControlCreator { | |
446 public IInformationControl doCreateInformationControl(Shell shell) { | |
447 return new DefaultInformationControl(shell, true); | |
448 } | |
449 } | |
450 | |
451 /** The proposal table. */ | |
452 private Table fProposalTable; | |
453 /** The table selection listener */ | |
159 | 454 private SelectionListener fSelectionListener; |
129 | 455 /** The delay after which additional information is displayed */ |
146 | 456 private const int fDelay; |
129 | 457 /** |
458 * The timer thread. | |
459 * @since 3.2 | |
460 */ | |
461 private Timer fTimer; | |
462 /** | |
463 * The proposal most recently set by {@link #showInformation(ICompletionProposal, Object)}, | |
464 * possibly <code>null</code>. | |
465 * @since 3.2 | |
466 */ | |
467 private ICompletionProposal fProposal; | |
468 /** | |
469 * The information most recently set by {@link #showInformation(ICompletionProposal, Object)}, | |
470 * possibly <code>null</code>. | |
471 * @since 3.2 | |
472 */ | |
473 private Object fInformation; | |
474 | |
475 /** | |
476 * Creates a new additional information controller. | |
477 * | |
478 * @param creator the information control creator to be used by this controller | |
479 * @param delay time in milliseconds after which additional info should be displayed | |
480 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
481 this(IInformationControlCreator creator, int delay) { |
159 | 482 |
483 fSelectionListener= new TableSelectionListener(); | |
484 | |
129 | 485 super(creator); |
486 fDelay= delay; | |
487 setAnchor(ANCHOR_RIGHT); | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
488 setFallbackAnchors([ ANCHOR_RIGHT, ANCHOR_LEFT, ANCHOR_BOTTOM ]); |
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
489 |
129 | 490 /* |
491 * Adjust the location by one pixel towards the proposal popup, so that the single pixel | |
492 * border of the additional info popup overlays with the border of the popup. This avoids | |
493 * having a double black line. | |
494 */ | |
495 int spacing= -1; | |
496 setMargins(spacing, spacing); // see also adjustment in #computeLocation | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
497 |
129 | 498 InformationControlReplacer replacer= new InformationControlReplacer(new DefaultPresenterControlCreator()); |
499 getInternalAccessor().setInformationControlReplacer(replacer); | |
500 } | |
501 | |
502 /* | |
503 * @see AbstractInformationControlManager#install(Control) | |
504 */ | |
505 public void install(Control control) { | |
506 | |
507 if (fProposalTable is control) { | |
508 // already installed | |
509 return; | |
510 } | |
511 | |
512 super.install(control.getShell()); | |
513 | |
138 | 514 Assert.isTrue( cast(Table)control ); |
134 | 515 fProposalTable= cast(Table) control; |
129 | 516 fProposalTable.addSelectionListener(fSelectionListener); |
517 getInternalAccessor().getInformationControlReplacer().install(fProposalTable); | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
518 |
135 | 519 fTimer= new class(fProposalTable.getDisplay(), fDelay) Timer { |
129 | 520 protected void showInformation(ICompletionProposal proposal, Object info) { |
521 InformationControlReplacer replacer= getInternalAccessor().getInformationControlReplacer(); | |
522 if (replacer !is null) | |
523 replacer.hideInformationControl(); | |
137 | 524 this.outer.showInformation(proposal, info); |
129 | 525 } |
526 }; | |
527 } | |
528 | |
529 /* | |
530 * @see AbstractInformationControlManager#disposeInformationControl() | |
531 */ | |
532 public void disposeInformationControl() { | |
533 | |
534 if (fTimer !is null) { | |
535 fTimer.terminate(); | |
536 fTimer= null; | |
537 } | |
538 | |
539 fProposal= null; | |
540 fInformation= null; | |
541 | |
542 if (fProposalTable !is null && !fProposalTable.isDisposed()) { | |
543 fProposalTable.removeSelectionListener(fSelectionListener); | |
544 fProposalTable= null; | |
545 } | |
546 | |
547 super.disposeInformationControl(); | |
548 } | |
549 | |
550 /** | |
551 *Handles a change of the line selected in the associated selector. | |
552 */ | |
553 public void handleTableSelectionChanged() { | |
554 | |
555 if (fProposalTable !is null && !fProposalTable.isDisposed() && fProposalTable.isVisible()) { | |
556 TableItem[] selection= fProposalTable.getSelection(); | |
557 if (selection !is null && selection.length > 0) { | |
558 | |
559 TableItem item= selection[0]; | |
560 | |
561 Object d= item.getData(); | |
138 | 562 if ( cast(ICompletionProposal)d ) { |
134 | 563 ICompletionProposal p= cast(ICompletionProposal) d; |
129 | 564 fTimer.reset(p); |
565 } | |
566 } | |
567 } | |
568 } | |
569 | |
570 void showInformation(ICompletionProposal proposal, Object info) { | |
571 if (fProposalTable is null || fProposalTable.isDisposed()) | |
572 return; | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
573 |
129 | 574 if (fProposal is proposal && ((info is null && fInformation is null) || (info !is null && info.equals(fInformation)))) |
575 return; | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
576 |
129 | 577 fInformation= info; |
578 fProposal= proposal; | |
579 showInformation(); | |
580 } | |
581 | |
582 /* | |
583 * @see AbstractInformationControlManager#computeInformation() | |
584 */ | |
585 protected void computeInformation() { | |
138 | 586 if ( cast(ICompletionProposalExtension3)fProposal ) |
134 | 587 setCustomInformationControlCreator((cast(ICompletionProposalExtension3) fProposal).getInformationControlCreator()); |
129 | 588 else |
589 setCustomInformationControlCreator(null); | |
590 | |
591 // compute subject area | |
592 Point size= fProposalTable.getShell().getSize(); | |
593 | |
594 // set information & subject area | |
595 setInformation(fInformation, new Rectangle(0, 0, size.x, size.y)); | |
596 } | |
597 | |
598 /* | |
599 * @see dwtx.jface.text.AbstractInformationControlManager#computeLocation(dwt.graphics.Rectangle, dwt.graphics.Point, dwtx.jface.text.AbstractInformationControlManager.Anchor) | |
600 */ | |
601 protected Point computeLocation(Rectangle subjectArea, Point controlSize, Anchor anchor) { | |
602 Point location= super.computeLocation(subjectArea, controlSize, anchor); | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
603 |
129 | 604 /* |
605 * The location is computed using subjectControl.toDisplay(), which does not include the | |
606 * trim of the subject control. As we want the additional info popup aligned with the outer | |
607 * coordinates of the proposal popup, adjust this here | |
608 */ | |
609 Rectangle trim= fProposalTable.getShell().computeTrim(0, 0, 0, 0); | |
610 location.x += trim.x; | |
611 location.y += trim.y; | |
612 | |
613 return location; | |
614 } | |
615 | |
616 /* | |
617 * @see dwtx.jface.text.AbstractInformationControlManager#computeSizeConstraints(Control, IInformationControl) | |
618 */ | |
619 protected Point computeSizeConstraints(Control subjectControl, IInformationControl informationControl) { | |
620 // at least as big as the proposal table | |
621 Point sizeConstraint= super.computeSizeConstraints(subjectControl, informationControl); | |
622 Point size= subjectControl.getShell().getSize(); | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
623 |
129 | 624 // AbstractInformationControlManager#internalShowInformationControl(Rectangle, Object) adds trims |
625 // to the computed constraints. Need to remove them here, to make the outer bounds of the additional | |
626 // info shell fit the bounds of the proposal shell: | |
138 | 627 if ( cast(IInformationControlExtension3)fInformationControl ) { |
134 | 628 Rectangle shellTrim= (cast(IInformationControlExtension3) fInformationControl).computeTrim(); |
129 | 629 size.x -= shellTrim.width; |
630 size.y -= shellTrim.height; | |
631 } | |
632 | |
633 if (sizeConstraint.x < size.x) | |
634 sizeConstraint.x= size.x; | |
635 if (sizeConstraint.y < size.y) | |
636 sizeConstraint.y= size.y; | |
637 return sizeConstraint; | |
638 } | |
140
26688fec6d23
Following dsss compile errors
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
639 |
129 | 640 /* |
641 * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl() | |
642 */ | |
643 protected void hideInformationControl() { | |
644 super.hideInformationControl(); | |
645 } | |
162 | 646 package void hideInformationControl_package() { |
647 this.hideInformationControl(); | |
648 } | |
129 | 649 |
650 /** | |
651 * @return the current information control, or <code>null</code> if none available | |
652 */ | |
653 public IInformationControl getCurrentInformationControl2() { | |
654 return getInternalAccessor().getCurrentInformationControl(); | |
655 } | |
656 } | |
657 | |
658 |