]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/widgets/TreeColumn.java
Remove invalid SHA-256-Digests
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / widgets / TreeColumn.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2017 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.widgets;
15
16
17 import org.eclipse.swt.*;
18 import org.eclipse.swt.events.*;
19 import org.eclipse.swt.graphics.*;
20 import org.eclipse.swt.internal.*;
21 import org.eclipse.swt.internal.win32.*;
22
23 /**
24  * Instances of this class represent a column in a tree widget.
25  * <dl>
26  * <dt><b>Styles:</b></dt>
27  * <dd>LEFT, RIGHT, CENTER</dd>
28  * <dt><b>Events:</b></dt>
29  * <dd> Move, Resize, Selection</dd>
30  * </dl>
31  * <p>
32  * Note: Only one of the styles LEFT, RIGHT and CENTER may be specified.
33  * </p><p>
34  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
35  * </p>
36  *
37  * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem, TreeColumn snippets</a>
38  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
39  *
40  * @since 3.1
41  * @noextend This class is not intended to be subclassed by clients.
42  */
43 public class TreeColumn extends Item {
44         Tree parent;
45         boolean resizable, moveable;
46         String toolTipText;
47         int id;
48
49 /**
50  * Constructs a new instance of this class given its parent
51  * (which must be a <code>Tree</code>) and a style value
52  * describing its behavior and appearance. The item is added
53  * to the end of the items maintained by its parent.
54  * <p>
55  * The style value is either one of the style constants defined in
56  * class <code>SWT</code> which is applicable to instances of this
57  * class, or must be built by <em>bitwise OR</em>'ing together
58  * (that is, using the <code>int</code> "|" operator) two or more
59  * of those <code>SWT</code> style constants. The class description
60  * lists the style constants that are applicable to the class.
61  * Style bits are also inherited from superclasses.
62  * </p>
63  *
64  * @param parent a composite control which will be the parent of the new instance (cannot be null)
65  * @param style the style of control to construct
66  *
67  * @exception IllegalArgumentException <ul>
68  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
69  * </ul>
70  * @exception SWTException <ul>
71  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
72  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
73  * </ul>
74  *
75  * @see SWT#LEFT
76  * @see SWT#RIGHT
77  * @see SWT#CENTER
78  * @see Widget#checkSubclass
79  * @see Widget#getStyle
80  */
81 public TreeColumn (Tree parent, int style) {
82         super (parent, checkStyle (style));
83         resizable = true;
84         this.parent = parent;
85         parent.createItem (this, parent.getColumnCount ());
86 }
87
88 /**
89  * Constructs a new instance of this class given its parent
90  * (which must be a <code>Tree</code>), a style value
91  * describing its behavior and appearance, and the index
92  * at which to place it in the items maintained by its parent.
93  * <p>
94  * The style value is either one of the style constants defined in
95  * class <code>SWT</code> which is applicable to instances of this
96  * class, or must be built by <em>bitwise OR</em>'ing together
97  * (that is, using the <code>int</code> "|" operator) two or more
98  * of those <code>SWT</code> style constants. The class description
99  * lists the style constants that are applicable to the class.
100  * Style bits are also inherited from superclasses.
101  * </p>
102  * <p>
103  * Note that due to a restriction on some platforms, the first column
104  * is always left aligned.
105  * </p>
106  * @param parent a composite control which will be the parent of the new instance (cannot be null)
107  * @param style the style of control to construct
108  * @param index the zero-relative index to store the receiver in its parent
109  *
110  * @exception IllegalArgumentException <ul>
111  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
112  *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
113  * </ul>
114  * @exception SWTException <ul>
115  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
116  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
117  * </ul>
118  *
119  * @see SWT#LEFT
120  * @see SWT#RIGHT
121  * @see SWT#CENTER
122  * @see Widget#checkSubclass
123  * @see Widget#getStyle
124  */
125 public TreeColumn (Tree parent, int style, int index) {
126         super (parent, checkStyle (style));
127         resizable = true;
128         this.parent = parent;
129         parent.createItem (this, index);
130 }
131
132 /**
133  * Adds the listener to the collection of listeners who will
134  * be notified when the control is moved or resized, by sending
135  * it one of the messages defined in the <code>ControlListener</code>
136  * interface.
137  *
138  * @param listener the listener which should be notified
139  *
140  * @exception IllegalArgumentException <ul>
141  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
142  * </ul>
143  * @exception SWTException <ul>
144  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
145  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
146  * </ul>
147  *
148  * @see ControlListener
149  * @see #removeControlListener
150  */
151 public void addControlListener(ControlListener listener) {
152         checkWidget ();
153         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
154         TypedListener typedListener = new TypedListener (listener);
155         addListener (SWT.Resize,typedListener);
156         addListener (SWT.Move,typedListener);
157 }
158
159 /**
160  * Adds the listener to the collection of listeners who will
161  * be notified when the control is selected by the user, by sending
162  * it one of the messages defined in the <code>SelectionListener</code>
163  * interface.
164  * <p>
165  * <code>widgetSelected</code> is called when the column header is selected.
166  * <code>widgetDefaultSelected</code> is not called.
167  * </p>
168  *
169  * @param listener the listener which should be notified when the control is selected by the user
170  *
171  * @exception IllegalArgumentException <ul>
172  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
173  * </ul>
174  * @exception SWTException <ul>
175  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
176  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
177  * </ul>
178  *
179  * @see SelectionListener
180  * @see #removeSelectionListener
181  * @see SelectionEvent
182  */
183 public void addSelectionListener (SelectionListener listener) {
184         checkWidget ();
185         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
186         TypedListener typedListener = new TypedListener (listener);
187         addListener (SWT.Selection,typedListener);
188         addListener (SWT.DefaultSelection,typedListener);
189 }
190
191 static int checkStyle (int style) {
192         return checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0);
193 }
194
195 @Override
196 protected void checkSubclass () {
197         if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
198 }
199
200 @Override
201 void destroyWidget () {
202         parent.destroyItem (this);
203         releaseHandle ();
204 }
205
206 /**
207  * Returns a value which describes the position of the
208  * text or image in the receiver. The value will be one of
209  * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>.
210  *
211  * @return the alignment
212  *
213  * @exception SWTException <ul>
214  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
215  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
216  * </ul>
217  */
218 public int getAlignment () {
219         checkWidget ();
220         if ((style & SWT.LEFT) != 0) return SWT.LEFT;
221         if ((style & SWT.CENTER) != 0) return SWT.CENTER;
222         if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
223         return SWT.LEFT;
224 }
225
226 /**
227  * Gets the moveable attribute. A column that is
228  * not moveable cannot be reordered by the user
229  * by dragging the header but may be reordered
230  * by the programmer.
231  *
232  * @return the moveable attribute
233  *
234  * @exception SWTException <ul>
235  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
236  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
237  * </ul>
238  *
239  * @see Tree#getColumnOrder()
240  * @see Tree#setColumnOrder(int[])
241  * @see TreeColumn#setMoveable(boolean)
242  * @see SWT#Move
243  *
244  * @since 3.2
245  */
246 public boolean getMoveable () {
247         checkWidget ();
248         return moveable;
249 }
250
251 @Override
252 String getNameText () {
253         return getText ();
254 }
255
256 /**
257  * Returns the receiver's parent, which must be a <code>Tree</code>.
258  *
259  * @return the receiver's parent
260  *
261  * @exception SWTException <ul>
262  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
263  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
264  * </ul>
265  */
266 public Tree getParent () {
267         checkWidget ();
268         return parent;
269 }
270
271 /**
272  * Gets the resizable attribute. A column that is
273  * not resizable cannot be dragged by the user but
274  * may be resized by the programmer.
275  *
276  * @return the resizable attribute
277  *
278  * @exception SWTException <ul>
279  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
280  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
281  * </ul>
282  */
283 public boolean getResizable () {
284         checkWidget ();
285         return resizable;
286 }
287
288 /**
289  * Returns the receiver's tool tip text, or null if it has
290  * not been set.
291  *
292  * @return the receiver's tool tip text
293  *
294  * @exception SWTException <ul>
295  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
296  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
297  * </ul>
298  *
299  * @since 3.2
300  */
301 public String getToolTipText () {
302         checkWidget();
303         return toolTipText;
304 }
305
306 /**
307  * Gets the width of the receiver.
308  *
309  * @return the width
310  *
311  * @exception SWTException <ul>
312  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
313  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
314  * </ul>
315  */
316 public int getWidth () {
317         checkWidget ();
318         return DPIUtil.autoScaleDown(getWidthInPixels());
319 }
320
321 int getWidthInPixels () {
322         int index = parent.indexOf (this);
323         if (index == -1) return 0;
324         long hwndHeader = parent.hwndHeader;
325         if (hwndHeader == 0) return 0;
326         HDITEM hdItem = new HDITEM ();
327         hdItem.mask = OS.HDI_WIDTH;
328         OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem);
329         return hdItem.cxy;
330 }
331
332 /**
333  * Causes the receiver to be resized to its preferred size.
334  * For a composite, this involves computing the preferred size
335  * from its layout, if there is one.
336  *
337  * @exception SWTException <ul>
338  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
339  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
340  * </ul>
341  *
342  */
343 public void pack () {
344         checkWidget ();
345         int index = parent.indexOf (this);
346         if (index == -1) return;
347         int columnWidth = 0;
348         long hwnd = parent.handle, hwndHeader = parent.hwndHeader;
349         RECT headerRect = new RECT ();
350         OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect);
351         long hDC = OS.GetDC (hwnd);
352         long oldFont = 0, newFont = OS.SendMessage (hwnd, OS.WM_GETFONT, 0, 0);
353         if (newFont != 0) oldFont = OS.SelectObject (hDC, newFont);
354         TVITEM tvItem = new TVITEM ();
355         tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM | OS.TVIF_STATE;
356         tvItem.hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0);
357         while (tvItem.hItem != 0) {
358                 OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem);
359                 TreeItem item = tvItem.lParam != -1 ? parent.items [(int)tvItem.lParam] : null;
360                 if (item != null) {
361                         int itemRight = 0;
362                         if (parent.hooks (SWT.MeasureItem)) {
363                                 int detail = (tvItem.state & OS.TVIS_SELECTED) != 0 ? SWT.SELECTED : 0;
364                                 Event event = parent.sendMeasureItemEvent (item, index, hDC, detail);
365                                 if (isDisposed () || parent.isDisposed ()) break;
366                                 Rectangle bounds = event.getBoundsInPixels();
367                                 itemRight = bounds.x + bounds.width;
368                         } else {
369                                 long hFont = item.fontHandle (index);
370                                 if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
371                                 RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC);
372                                 if (hFont != -1) OS.SelectObject (hDC, hFont);
373                                 itemRight = itemRect.right;
374                         }
375                         columnWidth = Math.max (columnWidth, itemRight - headerRect.left);
376                 }
377                 tvItem.hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, tvItem.hItem);
378         }
379         RECT rect = new RECT ();
380         int flags = OS.DT_CALCRECT | OS.DT_NOPREFIX;
381         char [] buffer = text.toCharArray ();
382         OS.DrawText (hDC, buffer, buffer.length, rect, flags);
383         int headerWidth = rect.right - rect.left + Tree.HEADER_MARGIN;
384         if (OS.IsAppThemed ()) headerWidth += Tree.HEADER_EXTRA;
385         if (image != null || parent.sortColumn == this) {
386                 Image headerImage = null;
387                 if (parent.sortColumn == this && parent.sortDirection != SWT.NONE) {
388                         headerWidth += Tree.SORT_WIDTH;
389                 } else {
390                         headerImage = image;
391                 }
392                 if (headerImage != null) {
393                         Rectangle bounds = headerImage.getBoundsInPixels ();
394                         headerWidth += bounds.width;
395                 }
396                 int margin = 0;
397                 if (hwndHeader != 0) {
398                         margin = (int)OS.SendMessage (hwndHeader, OS.HDM_GETBITMAPMARGIN, 0, 0);
399                 } else {
400                         margin = OS.GetSystemMetrics (OS.SM_CXEDGE) * 3;
401                 }
402                 headerWidth += margin * 2;
403         }
404         if (newFont != 0) OS.SelectObject (hDC, oldFont);
405         OS.ReleaseDC (hwnd, hDC);
406         int gridWidth = parent.linesVisible ? Tree.GRID_WIDTH : 0;
407         setWidthInPixels (Math.max (headerWidth, columnWidth + gridWidth));
408 }
409
410 @Override
411 void releaseHandle () {
412         super.releaseHandle ();
413         parent = null;
414 }
415
416 @Override
417 void releaseParent () {
418         super.releaseParent ();
419         if (parent.sortColumn == this) {
420                 parent.sortColumn = null;
421         }
422 }
423
424 /**
425  * Removes the listener from the collection of listeners who will
426  * be notified when the control is moved or resized.
427  *
428  * @param listener the listener which should no longer be notified
429  *
430  * @exception IllegalArgumentException <ul>
431  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
432  * </ul>
433  * @exception SWTException <ul>
434  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
435  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
436  * </ul>
437  *
438  * @see ControlListener
439  * @see #addControlListener
440  */
441 public void removeControlListener (ControlListener listener) {
442         checkWidget ();
443         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
444         if (eventTable == null) return;
445         eventTable.unhook (SWT.Move, listener);
446         eventTable.unhook (SWT.Resize, listener);
447 }
448
449 /**
450  * Removes the listener from the collection of listeners who will
451  * be notified when the control is selected by the user.
452  *
453  * @param listener the listener which should no longer be notified
454  *
455  * @exception IllegalArgumentException <ul>
456  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
457  * </ul>
458  * @exception SWTException <ul>
459  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
460  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
461  * </ul>
462  *
463  * @see SelectionListener
464  * @see #addSelectionListener
465  */
466 public void removeSelectionListener(SelectionListener listener) {
467         checkWidget ();
468         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
469         if (eventTable == null) return;
470         eventTable.unhook (SWT.Selection, listener);
471         eventTable.unhook (SWT.DefaultSelection,listener);
472 }
473
474 /**
475  * Controls how text and images will be displayed in the receiver.
476  * The argument should be one of <code>LEFT</code>, <code>RIGHT</code>
477  * or <code>CENTER</code>.
478  * <p>
479  * Note that due to a restriction on some platforms, the first column
480  * is always left aligned.
481  * </p>
482  * @param alignment the new alignment
483  *
484  * @exception SWTException <ul>
485  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
486  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
487  * </ul>
488  */
489 public void setAlignment (int alignment) {
490         checkWidget ();
491         if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return;
492         int index = parent.indexOf (this);
493         if (index == -1 || index == 0) return;
494         style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
495         style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
496         long hwndHeader = parent.hwndHeader;
497         if (hwndHeader == 0) return;
498         HDITEM hdItem = new HDITEM ();
499         hdItem.mask = OS.HDI_FORMAT;
500         OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem);
501         hdItem.fmt &= ~OS.HDF_JUSTIFYMASK;
502         if ((style & SWT.LEFT) == SWT.LEFT) hdItem.fmt |= OS.HDF_LEFT;
503         if ((style & SWT.CENTER) == SWT.CENTER) hdItem.fmt |= OS.HDF_CENTER;
504         if ((style & SWT.RIGHT) == SWT.RIGHT) hdItem.fmt |= OS.HDF_RIGHT;
505         OS.SendMessage (hwndHeader, OS.HDM_SETITEM, index, hdItem);
506         if (index != 0) {
507                 long hwnd = parent.handle;
508                 parent.forceResize ();
509                 RECT rect = new RECT (), headerRect = new RECT ();
510                 OS.GetClientRect (hwnd, rect);
511                 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect);
512                 rect.left = headerRect.left;
513                 rect.right = headerRect.right;
514                 OS.InvalidateRect (hwnd, rect, true);
515         }
516 }
517
518 @Override
519 public void setImage (Image image) {
520         checkWidget();
521         if (image != null && image.isDisposed ()) {
522                 error (SWT.ERROR_INVALID_ARGUMENT);
523         }
524         super.setImage (image);
525         if (parent.sortColumn != this || parent.sortDirection != SWT.NONE) {
526                 setImage (image, false, false);
527         }
528 }
529
530 void setImage (Image image, boolean sort, boolean right) {
531         int index = parent.indexOf (this);
532         if (index == -1) return;
533         long hwndHeader = parent.hwndHeader;
534         if (hwndHeader == 0) return;
535         HDITEM hdItem = new HDITEM ();
536         hdItem.mask = OS.HDI_FORMAT | OS.HDI_IMAGE | OS.HDI_BITMAP;
537         OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem);
538         hdItem.fmt &= ~OS.HDF_BITMAP_ON_RIGHT;
539         if (image != null) {
540                 if (sort) {
541                         hdItem.mask &= ~OS.HDI_IMAGE;
542                         hdItem.fmt &= ~OS.HDF_IMAGE;
543                         hdItem.fmt |= OS.HDF_BITMAP;
544                         hdItem.hbm = image.handle;
545                 } else {
546                         hdItem.mask &= ~OS.HDI_BITMAP;
547                         hdItem.fmt &= ~OS.HDF_BITMAP;
548                         hdItem.fmt |= OS.HDF_IMAGE;
549                         hdItem.iImage = parent.imageIndexHeader (image);
550                 }
551                 if (right) hdItem.fmt |= OS.HDF_BITMAP_ON_RIGHT;
552         } else {
553                 hdItem.mask &= ~(OS.HDI_IMAGE | OS.HDI_BITMAP);
554                 hdItem.fmt &= ~(OS.HDF_IMAGE | OS.HDF_BITMAP);
555         }
556         OS.SendMessage (hwndHeader, OS.HDM_SETITEM, index, hdItem);
557 }
558
559 /**
560  * Sets the moveable attribute.  A column that is
561  * moveable can be reordered by the user by dragging
562  * the header. A column that is not moveable cannot be
563  * dragged by the user but may be reordered
564  * by the programmer.
565  *
566  * @param moveable the moveable attribute
567  *
568  * @exception SWTException <ul>
569  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
570  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
571  * </ul>
572  *
573  * @see Tree#setColumnOrder(int[])
574  * @see Tree#getColumnOrder()
575  * @see TreeColumn#getMoveable()
576  * @see SWT#Move
577  *
578  * @since 3.2
579  */
580 public void setMoveable (boolean moveable) {
581         checkWidget ();
582         this.moveable = moveable;
583 }
584
585 /**
586  * Sets the resizable attribute.  A column that is
587  * not resizable cannot be dragged by the user but
588  * may be resized by the programmer.
589  *
590  * @param resizable the resize attribute
591  *
592  * @exception SWTException <ul>
593  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
594  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
595  * </ul>
596  */
597 public void setResizable (boolean resizable) {
598         checkWidget ();
599         this.resizable = resizable;
600 }
601
602 void setSortDirection (int direction) {
603         long hwndHeader = parent.hwndHeader;
604         if (hwndHeader != 0) {
605                 int index = parent.indexOf (this);
606                 if (index == -1) return;
607                 HDITEM hdItem = new HDITEM ();
608                 hdItem.mask = OS.HDI_FORMAT | OS.HDI_IMAGE;
609                 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem);
610                 switch (direction) {
611                         case SWT.UP:
612                                 hdItem.fmt &= ~(OS.HDF_IMAGE | OS.HDF_SORTDOWN);
613                                 hdItem.fmt |= OS.HDF_SORTUP;
614                                 if (image == null) hdItem.mask &= ~OS.HDI_IMAGE;
615                                 break;
616                         case SWT.DOWN:
617                                 hdItem.fmt &= ~(OS.HDF_IMAGE | OS.HDF_SORTUP);
618                                 hdItem.fmt |= OS.HDF_SORTDOWN;
619                                 if (image == null) hdItem.mask &= ~OS.HDI_IMAGE;
620                                 break;
621                         case SWT.NONE:
622                                 hdItem.fmt &= ~(OS.HDF_SORTUP | OS.HDF_SORTDOWN);
623                                 if (image != null) {
624                                         hdItem.fmt |= OS.HDF_IMAGE;
625                                         hdItem.iImage = parent.imageIndexHeader (image);
626                                 } else {
627                                         hdItem.fmt &= ~OS.HDF_IMAGE;
628                                         hdItem.mask &= ~OS.HDI_IMAGE;
629                                 }
630                                 break;
631                 }
632                 OS.SendMessage (hwndHeader, OS.HDM_SETITEM, index, hdItem);
633                 if (OS.IsAppThemed ()) {
634                         long hwnd = parent.handle;
635                         parent.forceResize ();
636                         RECT rect = new RECT (), headerRect = new RECT ();
637                         OS.GetClientRect (hwnd, rect);
638                         OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect);
639                         rect.left = headerRect.left;
640                         rect.right = headerRect.right;
641                         OS.InvalidateRect (hwnd, rect, true);
642                 }
643         }
644 }
645
646 @Override
647 public void setText (String string) {
648         checkWidget ();
649         if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
650         if (string.equals (text)) return;
651         int index = parent.indexOf (this);
652         if (index == -1) return;
653         super.setText (string);
654         /*
655         * Bug in Windows.  When a column header contains a
656         * mnemonic character, Windows does not measure the
657         * text properly.  This causes '...' to always appear
658         * at the end of the text.  The fix is to remove
659         * mnemonic characters.
660         */
661         long hHeap = OS.GetProcessHeap ();
662         char [] buffer = fixMnemonic (string);
663         int byteCount = buffer.length * TCHAR.sizeof;
664         long pszText = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
665         OS.MoveMemory (pszText, buffer, byteCount);
666         long hwndHeader = parent.hwndHeader;
667         if (hwndHeader == 0) return;
668         HDITEM hdItem = new HDITEM ();
669         hdItem.mask = OS.HDI_TEXT;
670         hdItem.pszText = pszText;
671         long result = OS.SendMessage (hwndHeader, OS.HDM_SETITEM, index, hdItem);
672         if (pszText != 0) OS.HeapFree (hHeap, 0, pszText);
673         if (result == 0) error (SWT.ERROR_CANNOT_SET_TEXT);
674 }
675
676 /**
677  * Sets the receiver's tool tip text to the argument, which
678  * may be null indicating that the default tool tip for the
679  * control will be shown. For a control that has a default
680  * tool tip, such as the Tree control on Windows, setting
681  * the tool tip text to an empty string replaces the default,
682  * causing no tool tip text to be shown.
683  * <p>
684  * The mnemonic indicator (character '&amp;') is not displayed in a tool tip.
685  * To display a single '&amp;' in the tool tip, the character '&amp;' can be
686  * escaped by doubling it in the string.
687  * </p>
688  * <p>
689  * NOTE: This operation is a hint and behavior is platform specific, on Windows
690  * for CJK-style mnemonics of the form " (&amp;C)" at the end of the tooltip text
691  * are not shown in tooltip.
692  * </p>
693  *
694  * @param string the new tool tip text (or null)
695  *
696  * @exception SWTException <ul>
697  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
698  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
699  * </ul>
700  *
701  * @since 3.2
702  */
703 public void setToolTipText (String string) {
704         checkWidget();
705         toolTipText = string;
706         long hwndHeaderToolTip = parent.headerToolTipHandle;
707         if (hwndHeaderToolTip == 0) {
708                 parent.createHeaderToolTips ();
709                 parent.updateHeaderToolTips ();
710         }
711 }
712
713 /**
714  * Sets the width of the receiver.
715  *
716  * @param width the new width
717  *
718  * @exception SWTException <ul>
719  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
720  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
721  * </ul>
722  */
723 public void setWidth (int width) {
724         checkWidget ();
725         setWidthInPixels(DPIUtil.autoScaleUp(width));
726 }
727
728 void setWidthInPixels (int width) {
729         if (width < 0) return;
730         int index = parent.indexOf (this);
731         if (index == -1) return;
732         long hwndHeader = parent.hwndHeader;
733         if (hwndHeader == 0) return;
734         HDITEM hdItem = new HDITEM ();
735         hdItem.mask = OS.HDI_WIDTH;
736         hdItem.cxy = width;
737         OS.SendMessage (hwndHeader, OS.HDM_SETITEM, index, hdItem);
738         RECT headerRect = new RECT ();
739         OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect);
740         parent.forceResize ();
741         long hwnd = parent.handle;
742         RECT rect = new RECT ();
743         OS.GetClientRect (hwnd, rect);
744         rect.left = headerRect.left;
745         OS.InvalidateRect (hwnd, rect, true);
746         parent.setScrollWidth ();
747 }
748
749 void updateToolTip (int index) {
750         long hwndHeaderToolTip = parent.headerToolTipHandle;
751         if (hwndHeaderToolTip != 0) {
752                 long hwndHeader = parent.hwndHeader;
753                 RECT rect = new RECT ();
754                 if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, rect) != 0) {
755                         TOOLINFO lpti = new TOOLINFO ();
756                         lpti.cbSize = TOOLINFO.sizeof;
757                         lpti.hwnd = hwndHeader;
758                         lpti.uId = id;
759                         lpti.left = rect.left;
760                         lpti.top = rect.top;
761                         lpti.right = rect.right;
762                         lpti.bottom = rect.bottom;
763                         OS.SendMessage (hwndHeaderToolTip, OS.TTM_NEWTOOLRECT, 0, lpti);
764                 }
765         }
766 }
767 }