Mercurial > projects > dwt-addons
annotate dwtx/jface/internal/text/link/contentassist/AdditionalInfoController2.d @ 167:862b05e0334a
Add a wrapper for Thread
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 09 Sep 2008 15:59:16 +0200 |
parents | 1a5b8f8129df |
children | cef27f663573 |
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 | |
131 | 14 |
151 | 15 module dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; |
16 | |
131 | 17 import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport |
18 import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport | |
19 import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport | |
20 import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport | |
21 import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport | |
22 import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport | |
23 import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport | |
24 import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport | |
25 import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport | |
26 | |
129 | 27 import dwt.dwthelper.utils; |
167 | 28 import dwtx.dwtxhelper.JThread; |
129 | 29 |
30 import dwt.events.SelectionEvent; | |
31 import dwt.events.SelectionListener; | |
32 import dwt.graphics.Point; | |
33 import dwt.graphics.Rectangle; | |
34 import dwt.widgets.Control; | |
35 import dwt.widgets.Table; | |
36 import dwt.widgets.TableItem; | |
37 import dwtx.core.runtime.Assert; | |
38 import dwtx.jface.text.AbstractInformationControlManager; | |
39 import dwtx.jface.text.IInformationControl; | |
40 import dwtx.jface.text.IInformationControlCreator; | |
41 import dwtx.jface.text.contentassist.ICompletionProposal; | |
42 import dwtx.jface.text.contentassist.ICompletionProposalExtension3; | |
43 | |
44 | |
45 /** | |
46 * Displays the additional information available for a completion proposal. | |
47 * | |
48 * @since 2.0 | |
49 */ | |
50 class AdditionalInfoController2 : AbstractInformationControlManager , Runnable { | |
51 | |
52 /** | |
53 * Internal table selection listener. | |
54 */ | |
55 private class TableSelectionListener : SelectionListener { | |
56 | |
57 /* | |
58 * @see SelectionListener#widgetSelected(SelectionEvent) | |
59 */ | |
60 public void widgetSelected(SelectionEvent e) { | |
61 handleTableSelectionChanged(); | |
62 } | |
63 | |
64 /* | |
65 * @see SelectionListener#widgetDefaultSelected(SelectionEvent) | |
66 */ | |
67 public void widgetDefaultSelected(SelectionEvent e) { | |
68 } | |
69 } | |
70 | |
71 | |
72 /** The proposal table */ | |
73 private Table fProposalTable; | |
74 /** The thread controlling the delayed display of the additional info */ | |
167 | 75 private JThread fThread; |
129 | 76 /** Indicates whether the display delay has been reset */ |
77 private bool fIsReset= false; | |
78 /** Object to synchronize display thread and table selection changes */ | |
159 | 79 private const Object fMutex; |
129 | 80 /** Thread access lock. */ |
159 | 81 private const Object fThreadAccess; |
129 | 82 /** Object to synchronize initial display of additional info */ |
83 private Object fStartSignal; | |
84 /** The table selection listener */ | |
159 | 85 private SelectionListener fSelectionListener; |
129 | 86 /** The delay after which additional information is displayed */ |
87 private int fDelay; | |
88 | |
89 | |
90 /** | |
91 * Creates a new additional information controller. | |
92 * | |
93 * @param creator the information control creator to be used by this controller | |
94 * @param delay time in milliseconds after which additional info should be displayed | |
95 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
96 this(IInformationControlCreator creator, int delay) { |
159 | 97 fSelectionListener= new TableSelectionListener(); |
98 fThreadAccess= new Object(); | |
99 fMutex= new Object(); | |
129 | 100 super(creator); |
101 fDelay= delay; | |
102 setAnchor(ANCHOR_RIGHT); | |
130 | 103 setFallbackAnchors([ANCHOR_RIGHT, ANCHOR_LEFT, ANCHOR_BOTTOM ]); |
129 | 104 } |
105 | |
106 /* | |
107 * @see AbstractInformationControlManager#install(Control) | |
108 */ | |
109 public void install(Control control) { | |
110 | |
111 if (fProposalTable is control) { | |
112 // already installed | |
113 return; | |
114 } | |
115 | |
116 super.install(control); | |
117 | |
162 | 118 Assert.isTrue( null !is cast(Table)control ); |
134 | 119 fProposalTable= cast(Table) control; |
129 | 120 fProposalTable.addSelectionListener(fSelectionListener); |
121 synchronized (fThreadAccess) { | |
122 if (fThread !is null) | |
123 fThread.interrupt(); | |
167 | 124 fThread= new JThread(this, ContentAssistMessages.getString("InfoPopup.info_delay_timer_name")); //$NON-NLS-1$ |
129 | 125 |
126 fStartSignal= new Object(); | |
127 synchronized (fStartSignal) { | |
128 fThread.start(); | |
129 try { | |
130 // wait until thread is ready | |
131 fStartSignal.wait(); | |
132 } catch (InterruptedException x) { | |
133 } | |
134 } | |
135 } | |
136 } | |
137 | |
138 /* | |
139 * @see AbstractInformationControlManager#disposeInformationControl() | |
140 */ | |
141 public void disposeInformationControl() { | |
142 | |
143 synchronized (fThreadAccess) { | |
144 if (fThread !is null) { | |
145 fThread.interrupt(); | |
146 fThread= null; | |
147 } | |
148 } | |
149 | |
150 if (fProposalTable !is null && !fProposalTable.isDisposed()) { | |
151 fProposalTable.removeSelectionListener(fSelectionListener); | |
152 fProposalTable= null; | |
153 } | |
154 | |
155 super.disposeInformationControl(); | |
156 } | |
157 | |
158 /* | |
159 * @see java.lang.Runnable#run() | |
160 */ | |
161 public void run() { | |
162 try { | |
163 while (true) { | |
164 | |
165 synchronized (fMutex) { | |
166 | |
167 if (fStartSignal !is null) { | |
168 synchronized (fStartSignal) { | |
169 fStartSignal.notifyAll(); | |
170 fStartSignal= null; | |
171 } | |
172 } | |
173 | |
174 // Wait for a selection event to occur. | |
175 fMutex.wait(); | |
176 | |
177 while (true) { | |
178 fIsReset= false; | |
179 // Delay before showing the popup. | |
180 fMutex.wait(fDelay); | |
181 if (!fIsReset) | |
182 break; | |
183 } | |
184 } | |
185 | |
186 if (fProposalTable !is null && !fProposalTable.isDisposed()) { | |
135 | 187 fProposalTable.getDisplay().asyncExec(new class() Runnable { |
129 | 188 public void run() { |
189 if (!fIsReset) | |
190 showInformation(); | |
191 } | |
192 }); | |
193 } | |
194 | |
195 } | |
196 } catch (InterruptedException e) { | |
197 } | |
198 | |
199 synchronized (fThreadAccess) { | |
200 // only null fThread if it is us! | |
167 | 201 if (JThread.currentThread() is fThread) |
129 | 202 fThread= null; |
203 } | |
204 } | |
205 | |
206 /** | |
207 *Handles a change of the line selected in the associated selector. | |
208 */ | |
209 public void handleTableSelectionChanged() { | |
210 | |
211 if (fProposalTable !is null && !fProposalTable.isDisposed() && fProposalTable.isVisible()) { | |
212 synchronized (fMutex) { | |
213 fIsReset= true; | |
214 fMutex.notifyAll(); | |
215 } | |
216 } | |
217 } | |
218 | |
219 /* | |
220 * @see AbstractInformationControlManager#computeInformation() | |
221 */ | |
222 protected void computeInformation() { | |
223 | |
224 if (fProposalTable is null || fProposalTable.isDisposed()) | |
225 return; | |
226 | |
227 TableItem[] selection= fProposalTable.getSelection(); | |
228 if (selection !is null && selection.length > 0) { | |
229 | |
230 TableItem item= selection[0]; | |
231 | |
232 // compute information | |
233 String information= null; | |
234 Object d= item.getData(); | |
235 | |
138 | 236 if ( cast(ICompletionProposal)d ) { |
134 | 237 ICompletionProposal p= cast(ICompletionProposal) d; |
129 | 238 information= p.getAdditionalProposalInfo(); |
239 } | |
240 | |
138 | 241 if ( cast(ICompletionProposalExtension3)d ) |
134 | 242 setCustomInformationControlCreator((cast(ICompletionProposalExtension3) d).getInformationControlCreator()); |
129 | 243 else |
244 setCustomInformationControlCreator(null); | |
245 | |
246 // compute subject area | |
247 setMargins(4, -1); | |
248 Rectangle area= fProposalTable.getBounds(); | |
249 area.x= 0; // subject area is the whole subject control | |
250 area.y= 0; | |
251 | |
252 // set information & subject area | |
253 setInformation(information, area); | |
254 } | |
255 } | |
256 | |
257 /* | |
258 * @see dwtx.jface.text.AbstractInformationControlManager#computeSizeConstraints(Control, IInformationControl) | |
259 */ | |
260 protected Point computeSizeConstraints(Control subjectControl, IInformationControl informationControl) { | |
261 // at least as big as the proposal table | |
262 Point sizeConstraint= super.computeSizeConstraints(subjectControl, informationControl); | |
263 Point size= subjectControl.getSize(); | |
264 if (sizeConstraint.x < size.x) | |
265 sizeConstraint.x= size.x; | |
266 if (sizeConstraint.y < size.y) | |
267 sizeConstraint.y= size.y; | |
268 return sizeConstraint; | |
269 } | |
270 } | |
271 | |
272 |