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