comparison dwtx/jface/internal/text/html/BrowserInformationControl.d @ 150:5cf141e43417

...
author Frank Benoit <benoit@tionex.de>
date Sun, 24 Aug 2008 23:05:26 +0200
parents 000f9136b8f7
children f70d9508c95c
comparison
equal deleted inserted replaced
149:b411f1c62131 150:5cf141e43417
76 * <ul> 76 * <ul>
77 * <li>the size computation is too small</li> 77 * <li>the size computation is too small</li>
78 * <li>focusLost event is not sent - see https://bugs.eclipse.org/bugs/show_bug.cgi?id=84532</li> 78 * <li>focusLost event is not sent - see https://bugs.eclipse.org/bugs/show_bug.cgi?id=84532</li>
79 * </ul> 79 * </ul>
80 * </p> 80 * </p>
81 * 81 *
82 * @since 3.2 82 * @since 3.2
83 */ 83 */
84 public class BrowserInformationControl : AbstractInformationControl , IInformationControlExtension2, IDelayedInputChangeProvider { 84 public class BrowserInformationControl : AbstractInformationControl , IInformationControlExtension2, IDelayedInputChangeProvider {
85 85
86 86
95 if (!fgAvailabilityChecked) { 95 if (!fgAvailabilityChecked) {
96 try { 96 try {
97 Browser browser= new Browser(parent, DWT.NONE); 97 Browser browser= new Browser(parent, DWT.NONE);
98 browser.dispose(); 98 browser.dispose();
99 fgIsAvailable= true; 99 fgIsAvailable= true;
100 100
101 Slider sliderV= new Slider(parent, DWT.VERTICAL); 101 Slider sliderV= new Slider(parent, DWT.VERTICAL);
102 Slider sliderH= new Slider(parent, DWT.HORIZONTAL); 102 Slider sliderH= new Slider(parent, DWT.HORIZONTAL);
103 int width= sliderV.computeSize(DWT.DEFAULT, DWT.DEFAULT).x; 103 int width= sliderV.computeSize(DWT.DEFAULT, DWT.DEFAULT).x;
104 int height= sliderH.computeSize(DWT.DEFAULT, DWT.DEFAULT).y; 104 int height= sliderH.computeSize(DWT.DEFAULT, DWT.DEFAULT).y;
105 fgScrollBarSize= new Point(width, height); 105 fgScrollBarSize= new Point(width, height);
121 * @since 3.2 121 * @since 3.2
122 */ 122 */
123 private static const int MIN_WIDTH= 80; 123 private static const int MIN_WIDTH= 80;
124 private static const int MIN_HEIGHT= 50; 124 private static const int MIN_HEIGHT= 50;
125 125
126 126
127 /** 127 /**
128 * Availability checking cache. 128 * Availability checking cache.
129 */ 129 */
130 private static bool fgIsAvailable= false; 130 private static bool fgIsAvailable= false;
131 private static bool fgAvailabilityChecked= false; 131 private static bool fgAvailabilityChecked= false;
133 /** 133 /**
134 * Cached scroll bar width and height 134 * Cached scroll bar width and height
135 * @since 3.4 135 * @since 3.4
136 */ 136 */
137 private static Point fgScrollBarSize; 137 private static Point fgScrollBarSize;
138 138
139 /** The control's browser widget */ 139 /** The control's browser widget */
140 private Browser fBrowser; 140 private Browser fBrowser;
141 /** Tells whether the browser has content */ 141 /** Tells whether the browser has content */
142 private bool fBrowserHasContent; 142 private bool fBrowserHasContent;
143 /** Text layout used to approximate size of content when rendered in browser */ 143 /** Text layout used to approximate size of content when rendered in browser */
173 private const String fSymbolicFontName; 173 private const String fSymbolicFontName;
174 174
175 175
176 /** 176 /**
177 * Creates a browser information control with the given shell as parent. 177 * Creates a browser information control with the given shell as parent.
178 * 178 *
179 * @param parent the parent shell 179 * @param parent the parent shell
180 * @param symbolicFontName the symbolic name of the font used for size computations 180 * @param symbolicFontName the symbolic name of the font used for size computations
181 * @param resizable <code>true</code> if the control should be resizable 181 * @param resizable <code>true</code> if the control should be resizable
182 * @since 3.4 182 * @since 3.4
183 */ 183 */
184 public this(Shell parent, String symbolicFontName, bool resizable) { 184 public this(Shell parent, String symbolicFontName, bool resizable) {
185 super(parent, resizable); 185 super(parent, resizable);
186 fSymbolicFontName= symbolicFontName; 186 fSymbolicFontName= symbolicFontName;
187 create(); 187 create();
188 } 188 }
189 189
190 /** 190 /**
191 * Creates a browser information control with the given shell as parent. 191 * Creates a browser information control with the given shell as parent.
192 * 192 *
193 * @param parent the parent shell 193 * @param parent the parent shell
194 * @param symbolicFontName the symbolic name of the font used for size computations 194 * @param symbolicFontName the symbolic name of the font used for size computations
195 * @param statusFieldText the text to be used in the optional status field 195 * @param statusFieldText the text to be used in the optional status field
196 * or <code>null</code> if the status field should be hidden 196 * or <code>null</code> if the status field should be hidden
197 * @since 3.4 197 * @since 3.4
199 public this(Shell parent, String symbolicFontName, String statusFieldText) { 199 public this(Shell parent, String symbolicFontName, String statusFieldText) {
200 super(parent, statusFieldText); 200 super(parent, statusFieldText);
201 fSymbolicFontName= symbolicFontName; 201 fSymbolicFontName= symbolicFontName;
202 create(); 202 create();
203 } 203 }
204 204
205 /** 205 /**
206 * Creates a browser information control with the given shell as parent. 206 * Creates a browser information control with the given shell as parent.
207 * 207 *
208 * @param parent the parent shell 208 * @param parent the parent shell
209 * @param symbolicFontName the symbolic name of the font used for size computations 209 * @param symbolicFontName the symbolic name of the font used for size computations
210 * @param toolBarManager the manager or <code>null</code> if toolbar is not desired 210 * @param toolBarManager the manager or <code>null</code> if toolbar is not desired
211 * @since 3.4 211 * @since 3.4
212 */ 212 */
213 public this(Shell parent, String symbolicFontName, ToolBarManager toolBarManager) { 213 public this(Shell parent, String symbolicFontName, ToolBarManager toolBarManager) {
214 super(parent, toolBarManager); 214 super(parent, toolBarManager);
215 fSymbolicFontName= symbolicFontName; 215 fSymbolicFontName= symbolicFontName;
216 create(); 216 create();
217 } 217 }
218 218
219 /* 219 /*
220 * @see dwtx.jface.text.AbstractInformationControl#createContent(dwt.widgets.Composite) 220 * @see dwtx.jface.text.AbstractInformationControl#createContent(dwt.widgets.Composite)
221 */ 221 */
222 protected void createContent(Composite parent) { 222 protected void createContent(Composite parent) {
223 fBrowser= new Browser(parent, DWT.NONE); 223 fBrowser= new Browser(parent, DWT.NONE);
224 224
225 Display display= getShell().getDisplay(); 225 Display display= getShell().getDisplay();
226 fBrowser.setForeground(display.getSystemColor(DWT.COLOR_INFO_FOREGROUND)); 226 fBrowser.setForeground(display.getSystemColor(DWT.COLOR_INFO_FOREGROUND));
227 fBrowser.setBackground(display.getSystemColor(DWT.COLOR_INFO_BACKGROUND)); 227 fBrowser.setBackground(display.getSystemColor(DWT.COLOR_INFO_BACKGROUND));
228 fBrowser.addKeyListener(new class() KeyListener { 228 fBrowser.addKeyListener(new class() KeyListener {
229 229
238 fBrowser.addProgressListener(new class() ProgressAdapter { 238 fBrowser.addProgressListener(new class() ProgressAdapter {
239 public void completed(ProgressEvent event) { 239 public void completed(ProgressEvent event) {
240 fCompleted= true; 240 fCompleted= true;
241 } 241 }
242 }); 242 });
243 243
244 // Replace browser's built-in context menu with none 244 // Replace browser's built-in context menu with none
245 fBrowser.setMenu(new Menu(getShell(), DWT.NONE)); 245 fBrowser.setMenu(new Menu(getShell(), DWT.NONE));
246 246
247 createTextLayout(); 247 createTextLayout();
248 } 248 }
249 249
250 /** 250 /**
251 * {@inheritDoc} 251 * {@inheritDoc}
264 public Object getInputElement() { 264 public Object getInputElement() {
265 return content; 265 return content;
266 } 266 }
267 }); 267 });
268 } 268 }
269 269
270 /** 270 /**
271 * {@inheritDoc} This control can handle {@link String} and 271 * {@inheritDoc} This control can handle {@link String} and
272 * {@link BrowserInformationControlInput}. 272 * {@link BrowserInformationControlInput}.
273 */ 273 */
274 public void setInput(Object input) { 274 public void setInput(Object input) {
275 Assert.isLegal(input is null || cast(String)input || input instanceof BrowserInformationControlInput); 275 Assert.isLegal(input is null || cast(String)input || cast(BrowserInformationControlInput)input );
276 276
277 if ( cast(String)input ) { 277 if ( cast(String)input ) {
278 setInformation(cast(String)input); 278 setInformation(cast(String)input);
279 return; 279 return;
280 } 280 }
281 281
282 fInput= cast(BrowserInformationControlInput)input; 282 fInput= cast(BrowserInformationControlInput)input;
283 283
284 String content= null; 284 String content= null;
285 if (fInput !is null) 285 if (fInput !is null)
286 content= fInput.getHtml(); 286 content= fInput.getHtml();
287 287
288 fBrowserHasContent= content !is null && content.length() > 0; 288 fBrowserHasContent= content !is null && content.length() > 0;
289 289
290 if (!fBrowserHasContent) 290 if (!fBrowserHasContent)
291 content= "<html><body ></html>"; //$NON-NLS-1$ 291 content= "<html><body ></html>"; //$NON-NLS-1$
292 292
295 295
296 // The default "overflow:auto" would not result in a predictable width for the client area 296 // The default "overflow:auto" would not result in a predictable width for the client area
297 // and the re-wrapping would cause visual noise 297 // and the re-wrapping would cause visual noise
298 String[] styles= null; 298 String[] styles= null;
299 if (RTL && resizable) 299 if (RTL && resizable)
300 styles= new String[] { "direction:rtl;", "overflow:scroll;", "word-wrap:break-word;" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 300 styles= [ "direction:rtl;", "overflow:scroll;", "word-wrap:break-word;" ]; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
301 else if (RTL && !resizable) 301 else if (RTL && !resizable)
302 styles= new String[] { "direction:rtl;", "overflow:hidden;", "word-wrap:break-word;" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 302 styles= [ "direction:rtl;", "overflow:hidden;", "word-wrap:break-word;" ]; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
303 else if (!resizable) 303 else if (!resizable)
304 //XXX: In IE, "word-wrap: break-word;" causes bogus wrapping even in non-broken words :-(see e.g. Javadoc of String). 304 //XXX: In IE, "word-wrap: break-word;" causes bogus wrapping even in non-broken words :-(see e.g. Javadoc of String).
305 // Re-check whether we really still need this now that the Javadoc Hover header already sets this style. 305 // Re-check whether we really still need this now that the Javadoc Hover header already sets this style.
306 styles= new String[] { "overflow:hidden;"/*, "word-wrap: break-word;"*/ }; //$NON-NLS-1$ 306 styles= [ "overflow:hidden;"/*, "word-wrap: break-word;"*/ ]; //$NON-NLS-1$
307 else 307 else
308 styles= new String[] { "overflow:scroll;" }; //$NON-NLS-1$ 308 styles= [ "overflow:scroll;" ]; //$NON-NLS-1$
309 309
310 StringBuffer buffer= new StringBuffer(content); 310 StringBuffer buffer= new StringBuffer(content);
311 HTMLPrinter.insertStyles(buffer, styles); 311 HTMLPrinter.insertStyles(buffer, styles);
312 content= buffer.toString(); 312 content= buffer.toString();
313 313
314 /* 314 /*
315 * XXX: Should add some JavaScript here that shows something like 315 * XXX: Should add some JavaScript here that shows something like
316 * "(continued...)" or "..." at the end of the visible area when the page overflowed 316 * "(continued...)" or "..." at the end of the visible area when the page overflowed
317 * with "overflow:hidden;". 317 * with "overflow:hidden;".
318 */ 318 */
319 319
320 fCompleted= false; 320 fCompleted= false;
321 fBrowser.setText(content); 321 fBrowser.setText(content);
322 322
323 Object[] listeners= fInputChangeListeners.getListeners(); 323 Object[] listeners= fInputChangeListeners.getListeners();
324 for (int i= 0; i < listeners.length; i++) 324 for (int i= 0; i < listeners.length; i++)
325 (cast(IInputChangedListener)listeners[i]).inputChanged(fInput); 325 (cast(IInputChangedListener)listeners[i]).inputChanged(fInput);
326 } 326 }
327 327
330 */ 330 */
331 public void setVisible(bool visible) { 331 public void setVisible(bool visible) {
332 Shell shell= getShell(); 332 Shell shell= getShell();
333 if (shell.isVisible() is visible) 333 if (shell.isVisible() is visible)
334 return; 334 return;
335 335
336 if (!visible) { 336 if (!visible) {
337 super.setVisible(false); 337 super.setVisible(false);
338 setInput(null); 338 setInput(null);
339 return; 339 return;
340 } 340 }
341 341
342 /* 342 /*
343 * The Browser widget flickers when made visible while it is not completely loaded. 343 * The Browser widget flickers when made visible while it is not completely loaded.
344 * The fix is to delay the call to setVisible until either loading is completed 344 * The fix is to delay the call to setVisible until either loading is completed
345 * (see ProgressListener in constructor), or a timeout has been reached. 345 * (see ProgressListener in constructor), or a timeout has been reached.
346 */ 346 */
347 final Display display= shell.getDisplay(); 347 final Display display= shell.getDisplay();
348 348
349 // Make sure the display wakes from sleep after timeout: 349 // Make sure the display wakes from sleep after timeout:
350 display.timerExec(100, new class() Runnable { 350 display.timerExec(100, new class() Runnable {
351 public void run() { 351 public void run() {
352 fCompleted= true; 352 fCompleted= true;
353 } 353 }
354 }); 354 });
355 355
356 while (!fCompleted) { 356 while (!fCompleted) {
357 // Drive the event loop to process the events required to load the browser widget's contents: 357 // Drive the event loop to process the events required to load the browser widget's contents:
358 if (!display.readAndDispatch()) { 358 if (!display.readAndDispatch()) {
359 display.sleep(); 359 display.sleep();
360 } 360 }
361 } 361 }
362 362
363 shell= getShell(); 363 shell= getShell();
364 if (shell is null || shell.isDisposed()) 364 if (shell is null || shell.isDisposed())
365 return; 365 return;
366 366
367 /* 367 /*
368 * Avoids flickering when replacing hovers, especially on Vista in ON_CLICK mode. 368 * Avoids flickering when replacing hovers, especially on Vista in ON_CLICK mode.
369 * Causes flickering on GTK. Carbon does not care. 369 * Causes flickering on GTK. Carbon does not care.
370 */ 370 */
371 if ("win32".equals(DWT.getPlatform())) //$NON-NLS-1$ 371 if ("win32".equals(DWT.getPlatform())) //$NON-NLS-1$
372 shell.moveAbove(null); 372 shell.moveAbove(null);
373 373
374 super.setVisible(true); 374 super.setVisible(true);
375 } 375 }
376 376
377 /* 377 /*
378 * @see dwtx.jface.text.AbstractInformationControl#setSize(int, int) 378 * @see dwtx.jface.text.AbstractInformationControl#setSize(int, int)
387 } 387 }
388 388
389 /** 389 /**
390 * Creates and initializes the text layout used 390 * Creates and initializes the text layout used
391 * to compute the size hint. 391 * to compute the size hint.
392 * 392 *
393 * @since 3.2 393 * @since 3.2
394 */ 394 */
395 private void createTextLayout() { 395 private void createTextLayout() {
396 fTextLayout= new TextLayout(fBrowser.getDisplay()); 396 fTextLayout= new TextLayout(fBrowser.getDisplay());
397 397
398 // Initialize fonts 398 // Initialize fonts
399 Font font= fSymbolicFontName is null ? JFaceResources.getDialogFont() : JFaceResources.getFont(fSymbolicFontName); 399 Font font= fSymbolicFontName is null ? JFaceResources.getDialogFont() : JFaceResources.getFont(fSymbolicFontName);
400 fTextLayout.setFont(font); 400 fTextLayout.setFont(font);
401 fTextLayout.setWidth(-1); 401 fTextLayout.setWidth(-1);
402 FontData[] fontData= font.getFontData(); 402 FontData[] fontData= font.getFontData();
403 for (int i= 0; i < fontData.length; i++) 403 for (int i= 0; i < fontData.length; i++)
404 fontData[i].setStyle(DWT.BOLD); 404 fontData[i].setStyle(DWT.BOLD);
405 font= new Font(getShell().getDisplay(), fontData); 405 font= new Font(getShell().getDisplay(), fontData);
406 fBoldStyle= new TextStyle(font, null, null); 406 fBoldStyle= new TextStyle(font, null, null);
407 407
408 // Compute and set tab width 408 // Compute and set tab width
409 fTextLayout.setText(" "); //$NON-NLS-1$ 409 fTextLayout.setText(" "); //$NON-NLS-1$
410 int tabWidth = fTextLayout.getBounds().width; 410 int tabWidth = fTextLayout.getBounds().width;
411 fTextLayout.setTabs(new int[] {tabWidth}); 411 fTextLayout.setTabs([tabWidth]);
412 412
413 fTextLayout.setText(""); //$NON-NLS-1$ 413 fTextLayout.setText(""); //$NON-NLS-1$
414 } 414 }
415 415
416 /* 416 /*
424 if (fBoldStyle !is null) { 424 if (fBoldStyle !is null) {
425 fBoldStyle.font.dispose(); 425 fBoldStyle.font.dispose();
426 fBoldStyle= null; 426 fBoldStyle= null;
427 } 427 }
428 fBrowser= null; 428 fBrowser= null;
429 429
430 super.dispose(); 430 super.dispose();
431 } 431 }
432 432
433 /* 433 /*
434 * @see IInformationControl#computeSizeHint() 434 * @see IInformationControl#computeSizeHint()
435 */ 435 */
436 public Point computeSizeHint() { 436 public Point computeSizeHint() {
437 Point sizeConstraints= getSizeConstraints(); 437 Point sizeConstraints= getSizeConstraints();
438 Rectangle trim= computeTrim(); 438 Rectangle trim= computeTrim();
439 int height= trim.height; 439 int height= trim.height;
440 440
441 //FIXME: The HTML2TextReader does not render <p> like a browser. 441 //FIXME: The HTML2TextReader does not render <p> like a browser.
442 // Instead of inserting an empty line, it just adds a single line break. 442 // Instead of inserting an empty line, it just adds a single line break.
443 // Furthermore, the indentation of <dl><dd> elements is too small (e.g with a long @see line) 443 // Furthermore, the indentation of <dl><dd> elements is too small (e.g with a long @see line)
444 TextPresentation presentation= new TextPresentation(); 444 TextPresentation presentation= new TextPresentation();
445 HTML2TextReader reader= new HTML2TextReader(new StringReader(fInput.getHtml()), presentation); 445 HTML2TextReader reader= new HTML2TextReader(new StringReader(fInput.getHtml()), presentation);
456 while (iter.hasNext()) { 456 while (iter.hasNext()) {
457 StyleRange sr= cast(StyleRange)iter.next(); 457 StyleRange sr= cast(StyleRange)iter.next();
458 if (sr.fontStyle is DWT.BOLD) 458 if (sr.fontStyle is DWT.BOLD)
459 fTextLayout.setStyle(fBoldStyle, sr.start, sr.start + sr.length - 1); 459 fTextLayout.setStyle(fBoldStyle, sr.start, sr.start + sr.length - 1);
460 } 460 }
461 461
462 Rectangle bounds= fTextLayout.getBounds(); // does not return minimum width, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=217446 462 Rectangle bounds= fTextLayout.getBounds(); // does not return minimum width, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=217446
463 int lineCount= fTextLayout.getLineCount(); 463 int lineCount= fTextLayout.getLineCount();
464 int textWidth= 0; 464 int textWidth= 0;
465 for (int i= 0; i < lineCount; i++) { 465 for (int i= 0; i < lineCount; i++) {
466 Rectangle rect= fTextLayout.getLineBounds(i); 466 Rectangle rect= fTextLayout.getLineBounds(i);
469 lineWidth += fInput.getLeadingImageWidth(); 469 lineWidth += fInput.getLeadingImageWidth();
470 textWidth= Math.max(textWidth, lineWidth); 470 textWidth= Math.max(textWidth, lineWidth);
471 } 471 }
472 bounds.width= textWidth; 472 bounds.width= textWidth;
473 fTextLayout.setText(""); //$NON-NLS-1$ 473 fTextLayout.setText(""); //$NON-NLS-1$
474 474
475 int minWidth= bounds.width; 475 int minWidth= bounds.width;
476 height= height + bounds.height; 476 height= height + bounds.height;
477 477
478 // Add some air to accommodate for different browser renderings 478 // Add some air to accommodate for different browser renderings
479 minWidth+= 15; 479 minWidth+= 15;
480 height+= 15; 480 height+= 15;
481 481
482 482
483 // Apply max size constraints 483 // Apply max size constraints
484 if (sizeConstraints !is null) { 484 if (sizeConstraints !is null) {
485 if (sizeConstraints.x !is DWT.DEFAULT) 485 if (sizeConstraints.x !is DWT.DEFAULT)
486 minWidth= Math.min(sizeConstraints.x, minWidth + trim.width); 486 minWidth= Math.min(sizeConstraints.x, minWidth + trim.width);
487 if (sizeConstraints.y !is DWT.DEFAULT) 487 if (sizeConstraints.y !is DWT.DEFAULT)
489 } 489 }
490 490
491 // Ensure minimal size 491 // Ensure minimal size
492 int width= Math.max(MIN_WIDTH, minWidth); 492 int width= Math.max(MIN_WIDTH, minWidth);
493 height= Math.max(MIN_HEIGHT, height); 493 height= Math.max(MIN_HEIGHT, height);
494 494
495 return new Point(width, height); 495 return new Point(width, height);
496 } 496 }
497 497
498 /* 498 /*
499 * @see dwtx.jface.text.IInformationControlExtension3#computeTrim() 499 * @see dwtx.jface.text.IInformationControlExtension3#computeTrim()
500 */ 500 */
501 public Rectangle computeTrim() { 501 public Rectangle computeTrim() {
502 Rectangle trim= super.computeTrim(); 502 Rectangle trim= super.computeTrim();
503 if (isResizable()) { 503 if (isResizable()) {
504 bool RTL= (getShell().getStyle() & DWT.RIGHT_TO_LEFT) !is 0; 504 bool RTL= (getShell().getStyle() & DWT.RIGHT_TO_LEFT) !is 0;
505 if cast(RTL) { 505 if (RTL) {
506 trim.x-= fgScrollBarSize.x; 506 trim.x-= fgScrollBarSize.x;
507 } 507 }
508 trim.width+= fgScrollBarSize.x; 508 trim.width+= fgScrollBarSize.x;
509 trim.height+= fgScrollBarSize.y; 509 trim.height+= fgScrollBarSize.y;
510 } 510 }
511 return trim; 511 return trim;
512 } 512 }
513 513
514 /** 514 /**
515 * Adds the listener to the collection of listeners who will be 515 * Adds the listener to the collection of listeners who will be
516 * notified when the current location has changed or is about to change. 516 * notified when the current location has changed or is about to change.
517 * 517 *
518 * @param listener the location listener 518 * @param listener the location listener
519 * @since 3.4 519 * @since 3.4
520 */ 520 */
521 public void addLocationListener(LocationListener listener) { 521 public void addLocationListener(LocationListener listener) {
522 fBrowser.addLocationListener(listener); 522 fBrowser.addLocationListener(listener);
542 * @see IInformationControlExtension#hasContents() 542 * @see IInformationControlExtension#hasContents()
543 */ 543 */
544 public bool hasContents() { 544 public bool hasContents() {
545 return fBrowserHasContent; 545 return fBrowserHasContent;
546 } 546 }
547 547
548 /** 548 /**
549 * Adds a listener for input changes to this input change provider. 549 * Adds a listener for input changes to this input change provider.
550 * Has no effect if an identical listener is already registered. 550 * Has no effect if an identical listener is already registered.
551 * 551 *
552 * @param inputChangeListener the listener to add 552 * @param inputChangeListener the listener to add
553 * @since 3.4 553 * @since 3.4
554 */ 554 */
555 public void addInputChangeListener(IInputChangedListener inputChangeListener) { 555 public void addInputChangeListener(IInputChangedListener inputChangeListener) {
556 Assert.isNotNull(inputChangeListener); 556 Assert.isNotNull(inputChangeListener);
557 fInputChangeListeners.add(inputChangeListener); 557 fInputChangeListeners.add(inputChangeListener);
558 } 558 }
559 559
560 /** 560 /**
561 * Removes the given input change listener from this input change provider. 561 * Removes the given input change listener from this input change provider.
562 * Has no effect if an identical listener is not registered. 562 * Has no effect if an identical listener is not registered.
563 * 563 *
564 * @param inputChangeListener the listener to remove 564 * @param inputChangeListener the listener to remove
565 * @since 3.4 565 * @since 3.4
566 */ 566 */
567 public void removeInputChangeListener(IInputChangedListener inputChangeListener) { 567 public void removeInputChangeListener(IInputChangedListener inputChangeListener) {
568 fInputChangeListeners.remove(inputChangeListener); 568 fInputChangeListeners.remove(inputChangeListener);
569 } 569 }
570 570
571 /* 571 /*
572 * @see dwtx.jface.text.IDelayedInputChangeProvider#setDelayedInputChangeListener(dwtx.jface.text.IInputChangedListener) 572 * @see dwtx.jface.text.IDelayedInputChangeProvider#setDelayedInputChangeListener(dwtx.jface.text.IInputChangedListener)
573 * @since 3.4 573 * @since 3.4
574 */ 574 */
575 public void setDelayedInputChangeListener(IInputChangedListener inputChangeListener) { 575 public void setDelayedInputChangeListener(IInputChangedListener inputChangeListener) {
576 fDelayedInputChangeListener= inputChangeListener; 576 fDelayedInputChangeListener= inputChangeListener;
577 } 577 }
578 578
579 /** 579 /**
580 * Tells whether a delayed input change listener is registered. 580 * Tells whether a delayed input change listener is registered.
581 * 581 *
582 * @return <code>true</code> iff a delayed input change 582 * @return <code>true</code> iff a delayed input change
583 * listener is currently registered 583 * listener is currently registered
584 * @since 3.4 584 * @since 3.4
585 */ 585 */
586 public bool hasDelayedInputChangeListener() { 586 public bool hasDelayedInputChangeListener() {
587 return fDelayedInputChangeListener !is null; 587 return fDelayedInputChangeListener !is null;
588 } 588 }
589 589
590 /** 590 /**
591 * Notifies listeners of a delayed input change. 591 * Notifies listeners of a delayed input change.
592 * 592 *
593 * @param newInput the new input, or <code>null</code> to request cancellation 593 * @param newInput the new input, or <code>null</code> to request cancellation
594 * @since 3.4 594 * @since 3.4
595 */ 595 */
596 public void notifyDelayedInputChange(Object newInput) { 596 public void notifyDelayedInputChange(Object newInput) {
597 if (fDelayedInputChangeListener !is null) 597 if (fDelayedInputChangeListener !is null)
598 fDelayedInputChangeListener.inputChanged(newInput); 598 fDelayedInputChangeListener.inputChanged(newInput);
599 } 599 }
600 600
601 /* 601 /*
602 * @see java.lang.Object#toString() 602 * @see java.lang.Object#toString()
603 * @since 3.4 603 * @since 3.4
604 */ 604 */
605 public String toString() { 605 public String toString() {
611 * @return the current browser input or <code>null</code> 611 * @return the current browser input or <code>null</code>
612 */ 612 */
613 public BrowserInformationControlInput getInput() { 613 public BrowserInformationControlInput getInput() {
614 return fInput; 614 return fInput;
615 } 615 }
616 616
617 /* 617 /*
618 * @see dwtx.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int) 618 * @see dwtx.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int)
619 */ 619 */
620 public Point computeSizeConstraints(int widthInChars, int heightInChars) { 620 public Point computeSizeConstraints(int widthInChars, int heightInChars) {
621 if (fSymbolicFontName is null) 621 if (fSymbolicFontName is null)
622 return null; 622 return null;
623 623
624 GC gc= new GC(fBrowser); 624 GC gc= new GC(fBrowser);
625 Font font= fSymbolicFontName is null ? JFaceResources.getDialogFont() : JFaceResources.getFont(fSymbolicFontName); 625 Font font= fSymbolicFontName is null ? JFaceResources.getDialogFont() : JFaceResources.getFont(fSymbolicFontName);
626 gc.setFont(font); 626 gc.setFont(font);
627 int width= gc.getFontMetrics().getAverageCharWidth(); 627 int width= gc.getFontMetrics().getAverageCharWidth();
628 int height= gc.getFontMetrics().getHeight(); 628 int height= gc.getFontMetrics().getHeight();
629 gc.dispose(); 629 gc.dispose();
630 630
631 return new Point(widthInChars * width, heightInChars * height); 631 return new Point(widthInChars * width, heightInChars * height);
632 } 632 }
633 633
634 } 634 }