comparison dwtx/jface/text/contentassist/ContextInformationPopup.d @ 158:25f1f92fa3df

...
author Frank Benoit <benoit@tionex.de>
date Tue, 26 Aug 2008 02:46:34 +0200
parents f70d9508c95c
children 3678e4f1a766
comparison
equal deleted inserted replaced
157:7f75eaa8103a 158:25f1f92fa3df
70 import dwt.widgets.TableItem; 70 import dwt.widgets.TableItem;
71 import dwtx.jface.contentassist.IContentAssistSubjectControl; 71 import dwtx.jface.contentassist.IContentAssistSubjectControl;
72 import dwtx.jface.text.ITextViewer; 72 import dwtx.jface.text.ITextViewer;
73 import dwtx.jface.text.TextPresentation; 73 import dwtx.jface.text.TextPresentation;
74 74
75 75 /**
76 * Represents the state necessary for embedding contexts.
77 *
78 * @since 2.0
79 */
80 static class ContextFrame {
81
82 final int fBeginOffset;
83 final int fOffset;
84 final int fVisibleOffset;
85 final IContextInformation fInformation;
86 final IContextInformationValidator fValidator;
87 final IContextInformationPresenter fPresenter;
88
89 /*
90 * @since 3.1
91 */
92 public this(IContextInformation information, int beginOffset, int offset, int visibleOffset, IContextInformationValidator validator, IContextInformationPresenter presenter) {
93 fInformation = information;
94 fBeginOffset = beginOffset;
95 fOffset = offset;
96 fVisibleOffset = visibleOffset;
97 fValidator = validator;
98 fPresenter = presenter;
99 }
100
101 /*
102 * @see java.lang.Object#equals(java.lang.Object)
103 * @since 3.0
104 */
105 public bool equals(Object obj) {
106 if ( cast(ContextFrame)obj ) {
107 ContextFrame frame= cast(ContextFrame) obj;
108 return fInformation.equals(frame.fInformation) && fBeginOffset is frame.fBeginOffset;
109 }
110 return super.equals(obj);
111 }
112
113 /*
114 * @see java.lang.Object#hashCode()
115 * @since 3.1
116 */
117 public int hashCode() {
118 return (fInformation.hashCode() << 16) | fBeginOffset;
119 }
120 }
121
122 alias ContextFrame ContextInformationPopup_ContextFrame;
76 /** 123 /**
77 * This class is used to present context information to the user. 124 * This class is used to present context information to the user.
78 * If multiple contexts are valid at the current cursor location, 125 * If multiple contexts are valid at the current cursor location,
79 * a list is presented from which the user may choose one context. 126 * a list is presented from which the user may choose one context.
80 * Once the user makes their choice, or if there was only a single 127 * Once the user makes their choice, or if there was only a single
89 * @see IContextInformationValidator 136 * @see IContextInformationValidator
90 */ 137 */
91 class ContextInformationPopup : IContentAssistListener { 138 class ContextInformationPopup : IContentAssistListener {
92 139
93 140
94 /**
95 * Represents the state necessary for embedding contexts.
96 *
97 * @since 2.0
98 */
99 static class ContextFrame {
100
101 final int fBeginOffset;
102 final int fOffset;
103 final int fVisibleOffset;
104 final IContextInformation fInformation;
105 final IContextInformationValidator fValidator;
106 final IContextInformationPresenter fPresenter;
107
108 /*
109 * @since 3.1
110 */
111 public this(IContextInformation information, int beginOffset, int offset, int visibleOffset, IContextInformationValidator validator, IContextInformationPresenter presenter) {
112 fInformation = information;
113 fBeginOffset = beginOffset;
114 fOffset = offset;
115 fVisibleOffset = visibleOffset;
116 fValidator = validator;
117 fPresenter = presenter;
118 }
119
120 /*
121 * @see java.lang.Object#equals(java.lang.Object)
122 * @since 3.0
123 */
124 public bool equals(Object obj) {
125 if ( cast(ContextFrame)obj ) {
126 ContextFrame frame= cast(ContextFrame) obj;
127 return fInformation.equals(frame.fInformation) && fBeginOffset is frame.fBeginOffset;
128 }
129 return super.equals(obj);
130 }
131
132 /*
133 * @see java.lang.Object#hashCode()
134 * @since 3.1
135 */
136 public int hashCode() {
137 return (fInformation.hashCode() << 16) | fBeginOffset;
138 }
139 }
140 141
141 private ITextViewer fViewer; 142 private ITextViewer fViewer;
142 private ContentAssistant fContentAssistant; 143 private ContentAssistant fContentAssistant;
143 144
144 private PopupCloser fPopupCloser= new PopupCloser(); 145 private PopupCloser fPopupCloser= new PopupCloser();
210 * Shows all possible contexts for the given cursor position of the viewer. 211 * Shows all possible contexts for the given cursor position of the viewer.
211 * 212 *
212 * @param autoActivated <code>true</code> if auto activated 213 * @param autoActivated <code>true</code> if auto activated
213 * @return a potential error message or <code>null</code> in case of no error 214 * @return a potential error message or <code>null</code> in case of no error
214 */ 215 */
215 public String showContextProposals(final bool autoActivated) { 216 public String showContextProposals(bool autoActivated) {
216 final Control control= fContentAssistSubjectControlAdapter.getControl(); 217 final Control control= fContentAssistSubjectControlAdapter.getControl();
217 BusyIndicator.showWhile(control.getDisplay(), new class() Runnable { 218 BusyIndicator.showWhile(control.getDisplay(), dgRunnable( {
218 public void run() { 219 int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
219 220
220 int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x; 221 IContextInformation[] contexts= computeContextInformation(offset);
221 222 int count = (contexts is null ? 0 : contexts.length);
222 IContextInformation[] contexts= computeContextInformation(offset); 223 if (count is 1) {
223 int count = (contexts is null ? 0 : contexts.length); 224
224 if (count is 1) { 225 ContextFrame frame= createContextFrame(contexts[0], offset);
225 226 if (isDuplicate(frame))
226 ContextFrame frame= createContextFrame(contexts[0], offset); 227 validateContextInformation();
227 if (isDuplicate(frame)) 228 else
229 // Show context information directly
230 internalShowContextInfo(frame);
231
232 } else if (count > 0) {
233
234 // if any of the proposed context matches any of the contexts on the stack,
235 // assume that one (so, if context info is invoked repeatedly, the current
236 // info is kept)
237 for (int i= 0; i < contexts.length; i++) {
238 IContextInformation info= contexts[i];
239 ContextFrame frame= createContextFrame(info, offset);
240
241 // check top of stack and stored context
242 if (isDuplicate(frame)) {
228 validateContextInformation(); 243 validateContextInformation();
229 else 244 return;
230 // Show context information directly 245 }
246
247 if (isLastFrame(frame)) {
231 internalShowContextInfo(frame); 248 internalShowContextInfo(frame);
232 249 return;
233 } else if (count > 0) { 250 }
234 251
235 // if any of the proposed context matches any of the contexts on the stack, 252 // also check all other contexts
236 // assume that one (so, if context info is invoked repeatedly, the current 253 for (Iterator it= fContextFrameStack.iterator(); it.hasNext(); ) {
237 // info is kept) 254 ContextFrame stackFrame= cast(ContextFrame) it.next();
238 for (int i= 0; i < contexts.length; i++) { 255 if (stackFrame.equals(frame)) {
239 IContextInformation info= contexts[i];
240 ContextFrame frame= createContextFrame(info, offset);
241
242 // check top of stack and stored context
243 if (isDuplicate(frame)) {
244 validateContextInformation(); 256 validateContextInformation();
245 return; 257 return;
246 } 258 }
247
248 if (isLastFrame(frame)) {
249 internalShowContextInfo(frame);
250 return;
251 }
252
253 // also check all other contexts
254 for (Iterator it= fContextFrameStack.iterator(); it.hasNext(); ) {
255 ContextFrame stackFrame= cast(ContextFrame) it.next();
256 if (stackFrame.equals(frame)) {
257 validateContextInformation();
258 return;
259 }
260 }
261 } 259 }
262
263 // otherwise:
264 // Precise context must be selected
265
266 if (fLineDelimiter is null)
267 fLineDelimiter= fContentAssistSubjectControlAdapter.getLineDelimiter();
268
269 createContextSelector();
270 setContexts(contexts);
271 displayContextSelector();
272 } 260 }
273 } 261
274 }); 262 // otherwise:
263 // Precise context must be selected
264
265 if (fLineDelimiter is null)
266 fLineDelimiter= fContentAssistSubjectControlAdapter.getLineDelimiter();
267
268 createContextSelector();
269 setContexts(contexts);
270 displayContextSelector();
271 }
272 }));
275 273
276 return getErrorMessage(); 274 return getErrorMessage();
277 } 275 }
278 276
279 /** 277 /**
281 * 279 *
282 * @param info the context information 280 * @param info the context information
283 * @param offset the offset 281 * @param offset the offset
284 * @since 2.0 282 * @since 2.0
285 */ 283 */
286 public void showContextInformation(final IContextInformation info, final int offset) { 284 public void showContextInformation(IContextInformation info, int offset) {
287 Control control= fContentAssistSubjectControlAdapter.getControl(); 285 Control control= fContentAssistSubjectControlAdapter.getControl();
288 BusyIndicator.showWhile(control.getDisplay(), new class() Runnable { 286 BusyIndicator.showWhile(control.getDisplay(), dgRunnable( {
289 public void run() { 287 if (info_ is null)
290 if (info is null) 288 validateContextInformation();
289 else {
290 ContextFrame frame= createContextFrame(info_, offset_);
291 if (isDuplicate(frame))
291 validateContextInformation(); 292 validateContextInformation();
292 else { 293 else
293 ContextFrame frame= createContextFrame(info, offset); 294 internalShowContextInfo(frame);
294 if (isDuplicate(frame)) 295 hideContextSelector();
295 validateContextInformation(); 296 }
296 else 297 }, info, offset ));
297 internalShowContextInfo(frame);
298 hideContextSelector();
299 }
300 }
301 });
302 } 298 }
303 299
304 /** 300 /**
305 * Displays the given context information for the given offset. 301 * Displays the given context information for the given offset.
306 * 302 *
474 size.x += PAD; 470 size.x += PAD;
475 Rectangle bounds= fContentAssistant.getLayoutManager().computeBoundsAboveBelow(fContextInfoPopup, size, offset); 471 Rectangle bounds= fContentAssistant.getLayoutManager().computeBoundsAboveBelow(fContextInfoPopup, size, offset);
476 if (bounds.width < size.x) 472 if (bounds.width < size.x)
477 // we don't fit on the screen - try again and wrap 473 // we don't fit on the screen - try again and wrap
478 size= fContextInfoText.computeSize(bounds.width - PAD, DWT.DEFAULT, true); 474 size= fContextInfoText.computeSize(bounds.width - PAD, DWT.DEFAULT, true);
479 475
480 size.x += TEXT_PAD; 476 size.x += TEXT_PAD;
481 fContextInfoText.setSize(size); 477 fContextInfoText.setSize(size);
482 fContextInfoText.setLocation(1,1); 478 fContextInfoText.setLocation(1,1);
483 size.x += BORDER_PAD; 479 size.x += BORDER_PAD;
484 size.y += BORDER_PAD; 480 size.y += BORDER_PAD;
577 } 573 }
578 574
579 /** 575 /**
580 * Returns the minimal required height for the popup, may return 0 if the popup has not been 576 * Returns the minimal required height for the popup, may return 0 if the popup has not been
581 * created yet. 577 * created yet.
582 * 578 *
583 * @return the minimal height 579 * @return the minimal height
584 * @since 3.3 580 * @since 3.3
585 */ 581 */
586 int getMinimalHeight() { 582 int getMinimalHeight() {
587 int height= 0; 583 int height= 0;