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 org.eclipse.swt.widgets.TableColumn; 14 15 import java.lang.all; 16 17 18 19 import org.eclipse.swt.SWT; 20 import org.eclipse.swt.SWTException; 21 import org.eclipse.swt.events.ControlListener; 22 import org.eclipse.swt.events.SelectionEvent; 23 import org.eclipse.swt.events.SelectionListener; 24 import org.eclipse.swt.graphics.Image; 25 import org.eclipse.swt.internal.gtk.OS; 26 import org.eclipse.swt.widgets.Item; 27 import org.eclipse.swt.widgets.Table; 28 import org.eclipse.swt.widgets.Shell; 29 import org.eclipse.swt.widgets.TypedListener; 30 import org.eclipse.swt.widgets.TableItem; 31 import org.eclipse.swt.widgets.ImageList; 32 33 34 /** 35 * Instances of this class represent a column in a table widget. 36 * <p><dl> 37 * <dt><b>Styles:</b></dt> 38 * <dd>LEFT, RIGHT, CENTER</dd> 39 * <dt><b>Events:</b></dt> 40 * <dd> Move, Resize, Selection</dd> 41 * </dl> 42 * </p><p> 43 * Note: Only one of the styles LEFT, RIGHT and CENTER may be specified. 44 * </p><p> 45 * IMPORTANT: This class is <em>not</em> intended to be subclassed. 46 * </p> 47 * 48 * @see <a href="http://www.eclipse.org/swt/snippets/#table">Table, TableItem, TableColumn snippets</a> 49 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> 50 */ 51 public class TableColumn : Item { 52 GtkWidget* labelHandle, imageHandle, buttonHandle; 53 Table parent; 54 int modelIndex, lastButton, lastTime, lastX, lastWidth; 55 bool customDraw, useFixedWidth; 56 String toolTipText; 57 58 /** 59 * Constructs a new instance of this class given its parent 60 * (which must be a <code>Table</code>) and a style value 61 * describing its behavior and appearance. The item is added 62 * to the end of the items maintained by its parent. 63 * <p> 64 * The style value is either one of the style constants defined in 65 * class <code>SWT</code> which is applicable to instances of this 66 * class, or must be built by <em>bitwise OR</em>'ing together 67 * (that is, using the <code>int</code> "|" operator) two or more 68 * of those <code>SWT</code> style constants. The class description 69 * lists the style constants that are applicable to the class. 70 * Style bits are also inherited from superclasses. 71 * </p> 72 * 73 * @param parent a composite control which will be the parent of the new instance (cannot be null) 74 * @param style the style of control to construct 75 * 76 * @exception IllegalArgumentException <ul> 77 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 78 * </ul> 79 * @exception SWTException <ul> 80 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 81 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> 82 * </ul> 83 * 84 * @see SWT#LEFT 85 * @see SWT#RIGHT 86 * @see SWT#CENTER 87 * @see Widget#checkSubclass 88 * @see Widget#getStyle 89 */ 90 public this (Table parent, int style) { 91 super (parent, checkStyle (style)); 92 this.parent = parent; 93 createWidget (parent.getColumnCount ()); 94 } 95 96 /** 97 * Constructs a new instance of this class given its parent 98 * (which must be a <code>Table</code>), a style value 99 * describing its behavior and appearance, and the index 100 * at which to place it in the items maintained by its parent. 101 * <p> 102 * The style value is either one of the style constants defined in 103 * class <code>SWT</code> which is applicable to instances of this 104 * class, or must be built by <em>bitwise OR</em>'ing together 105 * (that is, using the <code>int</code> "|" operator) two or more 106 * of those <code>SWT</code> style constants. The class description 107 * lists the style constants that are applicable to the class. 108 * Style bits are also inherited from superclasses. 109 * </p> 110 * <p> 111 * Note that due to a restriction on some platforms, the first column 112 * is always left aligned. 113 * </p> 114 * @param parent a composite control which will be the parent of the new instance (cannot be null) 115 * @param style the style of control to construct 116 * @param index the zero-relative index to store the receiver in its parent 117 * 118 * @exception IllegalArgumentException <ul> 119 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 120 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> 121 * </ul> 122 * @exception SWTException <ul> 123 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 124 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> 125 * </ul> 126 * 127 * @see SWT#LEFT 128 * @see SWT#RIGHT 129 * @see SWT#CENTER 130 * @see Widget#checkSubclass 131 * @see Widget#getStyle 132 */ 133 public this (Table parent, int style, int index) { 134 super (parent, checkStyle (style)); 135 this.parent = parent; 136 createWidget (index); 137 } 138 139 /** 140 * Adds the listener to the collection of listeners who will 141 * be notified when the control is moved or resized, by sending 142 * it one of the messages defined in the <code>ControlListener</code> 143 * interface. 144 * 145 * @param listener the listener which should be notified 146 * 147 * @exception IllegalArgumentException <ul> 148 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> 149 * </ul> 150 * @exception SWTException <ul> 151 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 152 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 153 * </ul> 154 * 155 * @see ControlListener 156 * @see #removeControlListener 157 */ 158 public void addControlListener(ControlListener listener) { 159 checkWidget(); 160 if (listener is null) error (SWT.ERROR_NULL_ARGUMENT); 161 TypedListener typedListener = new TypedListener (listener); 162 addListener (SWT.Resize,typedListener); 163 addListener (SWT.Move,typedListener); 164 } 165 166 /** 167 * Adds the listener to the collection of listeners who will 168 * be notified when the control is selected by the user, by sending 169 * it one of the messages defined in the <code>SelectionListener</code> 170 * interface. 171 * <p> 172 * <code>widgetSelected</code> is called when the column header is selected. 173 * <code>widgetDefaultSelected</code> is not called. 174 * </p> 175 * 176 * @param listener the listener which should be notified when the control is selected by the user 177 * 178 * @exception IllegalArgumentException <ul> 179 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> 180 * </ul> 181 * @exception SWTException <ul> 182 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 183 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 184 * </ul> 185 * 186 * @see SelectionListener 187 * @see #removeSelectionListener 188 * @see SelectionEvent 189 */ 190 public void addSelectionListener (SelectionListener listener) { 191 checkWidget(); 192 if (listener is null) error (SWT.ERROR_NULL_ARGUMENT); 193 TypedListener typedListener = new TypedListener (listener); 194 addListener (SWT.Selection,typedListener); 195 addListener (SWT.DefaultSelection,typedListener); 196 } 197 198 static int checkStyle (int style) { 199 return checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0); 200 } 201 202 protected override void checkSubclass () { 203 if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); 204 } 205 206 override void createWidget (int index) { 207 parent.createItem (this, index); 208 setOrientation (); 209 hookEvents (); 210 register (); 211 text = ""; 212 } 213 214 override void deregister() { 215 super.deregister (); 216 display.removeWidget (handle); 217 if (buttonHandle !is null) display.removeWidget (buttonHandle); 218 if (labelHandle !is null) display.removeWidget (labelHandle); 219 } 220 221 override void destroyWidget () { 222 parent.destroyItem (this); 223 releaseHandle (); 224 } 225 226 /** 227 * Returns a value which describes the position of the 228 * text or image in the receiver. The value will be one of 229 * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>. 230 * 231 * @return the alignment 232 * 233 * @exception SWTException <ul> 234 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 235 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 236 * </ul> 237 */ 238 public int getAlignment () { 239 checkWidget(); 240 if ((style & SWT.LEFT) !is 0) return SWT.LEFT; 241 if ((style & SWT.CENTER) !is 0) return SWT.CENTER; 242 if ((style & SWT.RIGHT) !is 0) return SWT.RIGHT; 243 return SWT.LEFT; 244 } 245 246 /** 247 * Gets the moveable attribute. A column that is 248 * not moveable cannot be reordered by the user 249 * by dragging the header but may be reordered 250 * by the programmer. 251 * 252 * @return the moveable attribute 253 * 254 * @exception SWTException <ul> 255 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 256 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 257 * </ul> 258 * 259 * @see Table#getColumnOrder() 260 * @see Table#setColumnOrder(int[]) 261 * @see TableColumn#setMoveable(bool) 262 * @see SWT#Move 263 * 264 * @since 3.1 265 */ 266 public bool getMoveable() { 267 checkWidget(); 268 return cast(bool)OS.gtk_tree_view_column_get_reorderable (handle); 269 } 270 271 /** 272 * Returns the receiver's parent, which must be a <code>Table</code>. 273 * 274 * @return the receiver's parent 275 * 276 * @exception SWTException <ul> 277 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 278 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 279 * </ul> 280 */ 281 public Table getParent () { 282 checkWidget(); 283 return parent; 284 } 285 286 /** 287 * Gets the resizable attribute. A column that is 288 * not resizable cannot be dragged by the user but 289 * may be resized by the programmer. 290 * 291 * @return the resizable attribute 292 * 293 * @exception SWTException <ul> 294 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 295 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 296 * </ul> 297 */ 298 public bool getResizable () { 299 checkWidget(); 300 return cast(bool)OS.gtk_tree_view_column_get_resizable (handle); 301 } 302 303 /** 304 * Returns the receiver's tool tip text, or null if it has 305 * not been set. 306 * 307 * @return the receiver's tool tip text 308 * 309 * @exception SWTException <ul> 310 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 311 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 312 * </ul> 313 * 314 * @since 3.2 315 */ 316 public String getToolTipText () { 317 checkWidget(); 318 return toolTipText; 319 } 320 321 /** 322 * Gets the width of the receiver. 323 * 324 * @return the width 325 * 326 * @exception SWTException <ul> 327 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 328 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 329 * </ul> 330 */ 331 public int getWidth () { 332 checkWidget(); 333 if (!OS.gtk_tree_view_column_get_visible (handle)) { 334 return 0; 335 } 336 if (useFixedWidth) return OS.gtk_tree_view_column_get_fixed_width (handle); 337 return OS.gtk_tree_view_column_get_width (handle); 338 } 339 340 override int gtk_clicked (GtkWidget* widget) { 341 /* 342 * There is no API to get a double click on a table column. Normally, when 343 * the mouse is double clicked, this is indicated by GDK_2BUTTON_PRESS 344 * but the table column sends the click signal on button release. The fix is to 345 * test for double click by remembering the last click time and mouse button 346 * and testing for the double click interval. 347 */ 348 bool doubleClick = false; 349 bool postEvent_ = true; 350 auto eventPtr = OS.gtk_get_current_event (); 351 if (eventPtr !is null) { 352 GdkEventButton* gdkEvent = cast(GdkEventButton*)eventPtr; 353 switch (gdkEvent.type) { 354 case OS.GDK_BUTTON_RELEASE: { 355 int clickTime = display.getDoubleClickTime (); 356 int eventTime = gdkEvent.time, eventButton = gdkEvent.button; 357 if (lastButton is eventButton && lastTime !is 0 && Math.abs (lastTime - eventTime) <= clickTime) { 358 doubleClick = true; 359 } 360 lastTime = eventTime is 0 ? 1: eventTime; 361 lastButton = eventButton; 362 break; 363 } 364 case OS.GDK_MOTION_NOTIFY: { 365 /* 366 * Bug in GTK. Dragging a column in a GtkTreeView causes a clicked 367 * signal to be emitted even though the mouse button was never released. 368 * The fix to ignore the signal if the current GDK event is a motion notify. 369 * The GTK bug was fixed in version 2.6 370 */ 371 if (OS.GTK_VERSION < OS.buildVERSION (2, 6, 0)) postEvent_ = false; 372 break; 373 } 374 default: 375 } 376 OS.gdk_event_free (eventPtr); 377 } 378 if (postEvent_) postEvent (doubleClick ? SWT.DefaultSelection : SWT.Selection); 379 return 0; 380 } 381 382 override int gtk_mnemonic_activate (GtkWidget* widget, ptrdiff_t arg1) { 383 return parent.gtk_mnemonic_activate (widget, arg1); 384 } 385 386 override int gtk_size_allocate (GtkWidget* widget, ptrdiff_t allocation) { 387 useFixedWidth = false; 388 int x = OS.GTK_WIDGET_X (widget); 389 int width = OS.GTK_WIDGET_WIDTH (widget); 390 if (x !is lastX) { 391 lastX = x; 392 sendEvent (SWT.Move); 393 } 394 if (width !is lastWidth) { 395 lastWidth = width; 396 sendEvent (SWT.Resize); 397 } 398 return 0; 399 } 400 401 override void hookEvents () { 402 super.hookEvents (); 403 OS.g_signal_connect_closure (handle, OS.clicked.ptr, display.closures [CLICKED], false); 404 if (buttonHandle !is null) OS.g_signal_connect_closure_by_id (buttonHandle, display.signalIds [SIZE_ALLOCATE], 0, display.closures [SIZE_ALLOCATE], false); 405 if (labelHandle !is null) OS.g_signal_connect_closure_by_id (labelHandle, display.signalIds [MNEMONIC_ACTIVATE], 0, display.closures [MNEMONIC_ACTIVATE], false); 406 } 407 408 /** 409 * Causes the receiver to be resized to its preferred size. 410 * For a composite, this involves computing the preferred size 411 * from its layout, if there is one. 412 * 413 * @exception SWTException <ul> 414 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 415 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 416 * </ul> 417 * 418 */ 419 public void pack () { 420 checkWidget(); 421 int width = 0; 422 if (buttonHandle !is null) { 423 GtkRequisition requisition; 424 OS.gtk_widget_size_request (buttonHandle, &requisition); 425 width = requisition.width; 426 } 427 if ((parent.style & SWT.VIRTUAL) !is 0) { 428 for (int i=0; i<parent.items.length; i++) { 429 TableItem item = parent.items [i]; 430 if (item !is null && item.cached) { 431 width = Math.max (width, parent.calculateWidth ( cast(GtkTreeViewColumn*)handle, cast(GtkTreeIter*)item.handle)); 432 } 433 } 434 } else { 435 GtkTreeIter iter; 436 if (OS.gtk_tree_model_get_iter_first (parent.modelHandle, &iter)) { 437 do { 438 width = Math.max (width, parent.calculateWidth (cast(GtkTreeViewColumn*)handle, &iter)); 439 } while (OS.gtk_tree_model_iter_next(parent.modelHandle, &iter)); 440 } 441 } 442 setWidth(width); 443 } 444 445 override void register () { 446 super.register (); 447 display.addWidget (handle, this); 448 if (buttonHandle !is null) display.addWidget (buttonHandle, this); 449 if (labelHandle !is null) display.addWidget (labelHandle, this); 450 } 451 452 override void releaseHandle () { 453 super.releaseHandle (); 454 handle = buttonHandle = labelHandle = imageHandle = null; 455 modelIndex = -1; 456 parent = null; 457 } 458 459 override void releaseParent () { 460 super.releaseParent (); 461 if (parent.sortColumn is this) { 462 parent.sortColumn = null; 463 } 464 } 465 466 /** 467 * Removes the listener from the collection of listeners who will 468 * be notified when the control is moved or resized. 469 * 470 * @param listener the listener which should no longer be notified 471 * 472 * @exception IllegalArgumentException <ul> 473 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> 474 * </ul> 475 * @exception SWTException <ul> 476 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 477 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 478 * </ul> 479 * 480 * @see ControlListener 481 * @see #addControlListener 482 */ 483 public void removeControlListener (ControlListener listener) { 484 checkWidget(); 485 if (listener is null) error (SWT.ERROR_NULL_ARGUMENT); 486 if (eventTable is null) return; 487 eventTable.unhook (SWT.Move, listener); 488 eventTable.unhook (SWT.Resize, listener); 489 } 490 491 /** 492 * Removes the listener from the collection of listeners who will 493 * be notified when the control is selected by the user. 494 * 495 * @param listener the listener which should no longer be notified 496 * 497 * @exception IllegalArgumentException <ul> 498 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> 499 * </ul> 500 * @exception SWTException <ul> 501 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 502 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 503 * </ul> 504 * 505 * @see SelectionListener 506 * @see #addSelectionListener 507 */ 508 public void removeSelectionListener(SelectionListener listener) { 509 checkWidget(); 510 if (listener is null) error (SWT.ERROR_NULL_ARGUMENT); 511 if (eventTable is null) return; 512 eventTable.unhook (SWT.Selection, listener); 513 eventTable.unhook (SWT.DefaultSelection,listener); 514 } 515 516 /** 517 * Controls how text and images will be displayed in the receiver. 518 * The argument should be one of <code>LEFT</code>, <code>RIGHT</code> 519 * or <code>CENTER</code>. 520 * <p> 521 * Note that due to a restriction on some platforms, the first column 522 * is always left aligned. 523 * </p> 524 * @param alignment the new alignment 525 * 526 * @exception SWTException <ul> 527 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 528 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 529 * </ul> 530 */ 531 public void setAlignment (int alignment) { 532 checkWidget(); 533 if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) is 0) return; 534 int index = parent.indexOf (this); 535 if (index is -1 || index is 0) return; 536 style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER); 537 style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER); 538 parent.createRenderers ( cast(GtkTreeViewColumn*)handle, modelIndex, index is 0, style); 539 } 540 541 void setFontDescription (PangoFontDescription* font) { 542 OS.gtk_widget_modify_font (labelHandle, font); 543 OS.gtk_widget_modify_font (imageHandle, font); 544 } 545 546 public override void setImage (Image image) { 547 checkWidget (); 548 super.setImage (image); 549 if (image !is null) { 550 ImageList headerImageList = parent.headerImageList; 551 if (headerImageList is null) { 552 headerImageList = parent.headerImageList = new ImageList (); 553 } 554 int imageIndex = headerImageList.indexOf (image); 555 if (imageIndex is -1) imageIndex = headerImageList.add (image); 556 auto pixbuf = headerImageList.getPixbuf (imageIndex); 557 OS.gtk_image_set_from_pixbuf (imageHandle, pixbuf); 558 OS.gtk_widget_show (imageHandle); 559 } else { 560 OS.gtk_image_set_from_pixbuf (imageHandle, null); 561 OS.gtk_widget_hide (imageHandle); 562 } 563 } 564 565 /** 566 * Sets the resizable attribute. A column that is 567 * resizable can be resized by the user dragging the 568 * edge of the header. A column that is not resizable 569 * cannot be dragged by the user but may be resized 570 * by the programmer. 571 * 572 * @param resizable the resize attribute 573 * 574 * @exception SWTException <ul> 575 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 576 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 577 * </ul> 578 */ 579 public void setResizable (bool resizable) { 580 checkWidget(); 581 OS.gtk_tree_view_column_set_resizable (handle, resizable); 582 } 583 584 /** 585 * Sets the moveable attribute. A column that is 586 * moveable can be reordered by the user by dragging 587 * the header. A column that is not moveable cannot be 588 * dragged by the user but may be reordered 589 * by the programmer. 590 * 591 * @param moveable the moveable attribute 592 * 593 * @exception SWTException <ul> 594 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 595 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 596 * </ul> 597 * 598 * @see Table#setColumnOrder(int[]) 599 * @see Table#getColumnOrder() 600 * @see TableColumn#getMoveable() 601 * @see SWT#Move 602 * 603 * @since 3.1 604 */ 605 public void setMoveable (bool moveable) { 606 checkWidget(); 607 OS.gtk_tree_view_column_set_reorderable (handle, moveable); 608 } 609 610 override void setOrientation() { 611 if ((parent.style & SWT.RIGHT_TO_LEFT) !is 0) { 612 if (buttonHandle !is null) { 613 OS.gtk_widget_set_direction (buttonHandle, OS.GTK_TEXT_DIR_RTL); 614 display.doSetDirectionProc( buttonHandle, OS.GTK_TEXT_DIR_RTL); 615 } 616 } 617 } 618 619 public override void setText (String string) { 620 checkWidget(); 621 // SWT extension: allow null for zero length string 622 //if (string is null) error (SWT.ERROR_NULL_ARGUMENT); 623 super.setText (string); 624 char [] chars = fixMnemonic (string); 625 OS.gtk_label_set_text_with_mnemonic (labelHandle, chars.toStringzValidPtr() ); 626 if (string.length !is 0) { 627 OS.gtk_widget_show (labelHandle); 628 } else { 629 OS.gtk_widget_hide (labelHandle); 630 } 631 } 632 633 /** 634 * Sets the receiver's tool tip text to the argument, which 635 * may be null indicating that no tool tip text should be shown. 636 * 637 * @param string the new tool tip text (or null) 638 * 639 * @exception SWTException <ul> 640 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 641 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 642 * </ul> 643 * 644 * @since 3.2 645 */ 646 public void setToolTipText (String string) { 647 checkWidget(); 648 Shell shell = parent._getShell (); 649 setToolTipText (shell, string); 650 toolTipText = string; 651 } 652 653 void setToolTipText (Shell shell, String newString) { 654 shell.setToolTipText (buttonHandle, newString); 655 } 656 657 /** 658 * Sets the width of the receiver. 659 * 660 * @param width the new width 661 * 662 * @exception SWTException <ul> 663 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 664 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 665 * </ul> 666 */ 667 public void setWidth (int width) { 668 checkWidget(); 669 if (width < 0) return; 670 if (width is lastWidth) return; 671 if (width > 0) { 672 useFixedWidth = true; 673 OS.gtk_tree_view_column_set_fixed_width (handle, width); 674 } 675 /* 676 * Bug in GTK. For some reason, calling gtk_tree_view_column_set_visible() 677 * when the parent is not realized fails to show the column. The fix is to 678 * ensure that the table has been realized. 679 */ 680 if (width !is 0) OS.gtk_widget_realize (parent.handle); 681 OS.gtk_tree_view_column_set_visible (handle, width !is 0); 682 lastWidth = width; 683 sendEvent (SWT.Resize); 684 } 685 686 }