1{ $Id: qtwscomctrls.pp 59909 2018-12-24 22:50:09Z maxim $}
2{
3 *****************************************************************************
4 *                              QtWSComCtrls.pp                              *
5 *                              ---------------                              *
6 *                                                                           *
7 *                                                                           *
8 *****************************************************************************
9
10 *****************************************************************************
11  This file is part of the Lazarus Component Library (LCL)
12
13  See the file COPYING.modifiedLGPL.txt, included in this distribution,
14  for details about the license.
15 *****************************************************************************
16}
17unit QtWSComCtrls;
18
19{$mode objfpc}{$H+}
20
21interface
22
23{$I qtdefines.inc}
24
25uses
26  // Bindings
27  qt4,
28  qtwidgets, qtobjects, qtproc,
29  // LCL
30  SysUtils, Classes, Types, ComCtrls, Controls, LCLType, Graphics, StdCtrls,
31  LCLProc, LCLIntf, Forms, ImgList,
32  // Widgetset
33  WSProc, WSComCtrls, WSLCLClasses;
34
35type
36  { TQtWSCustomPage }
37
38  TQtWSCustomPage = class(TWSCustomPage)
39  protected
40    class procedure UpdateTabFontColor(APage: TCustomPage; AFont: TFont);
41  published
42    class function CreateHandle(const AWinControl: TWinControl;
43          const AParams: TCreateParams): TLCLIntfHandle; override;
44    class procedure DestroyHandle(const AWinControl: TWinControl); override;
45    class procedure SetFont(const AWinControl: TWinControl; const AFont: TFont); override;
46    class procedure UpdateProperties(const ACustomPage: TCustomPage); override;
47  end;
48
49  { TQtWSCustomTabControl }
50
51  TQtWSCustomTabControl = class(TWSCustomTabControl)
52  published
53    class function  CreateHandle(const AWinControl: TWinControl;
54          const AParams: TCreateParams): TLCLIntfHandle; override;
55    class function GetDefaultClientRect(const AWinControl: TWinControl;
56             const {%H-}aLeft, {%H-}aTop, aWidth, aHeight: integer; var aClientRect: TRect
57             ): boolean; override;
58    class procedure AddPage(const ATabControl: TCustomTabControl;
59      const AChild: TCustomPage; const AIndex: integer); override;
60    class procedure MovePage(const ATabControl: TCustomTabControl;
61      const AChild: TCustomPage; const NewIndex: integer); override;
62    class procedure RemovePage(const ATabControl: TCustomTabControl;
63      const AIndex: integer); override;
64
65    class function GetNotebookMinTabHeight(const AWinControl: TWinControl
66      ): integer; override;
67    class function GetNotebookMinTabWidth(const AWinControl: TWinControl
68      ): integer; override;
69    class function GetCapabilities: TCTabControlCapabilities; override;
70    class function GetDesignInteractive(const AWinControl: TWinControl; AClientPos: TPoint): Boolean; override;
71    class function GetTabIndexAtPos(const ATabControl: TCustomTabControl; const AClientPos: TPoint): integer; override;
72    class function GetTabRect(const ATabControl: TCustomTabControl; const AIndex: Integer): TRect; override;
73    class procedure SetPageIndex(const ATabControl: TCustomTabControl; const AIndex: integer); override;
74    class procedure SetTabCaption(const ATabControl: TCustomTabControl; const AChild: TCustomPage; const AText: string); override;
75    class procedure SetTabPosition(const ATabControl: TCustomTabControl; const ATabPosition: TTabPosition); override;
76    class procedure SetTabSize(const ATabControl: TCustomTabControl; const ATabWidth, ATabHeight: integer); override;
77    class procedure ShowTabs(const ATabControl: TCustomTabControl; AShowTabs: boolean); override;
78    class procedure UpdateProperties(const ATabControl: TCustomTabControl); override;
79  end;
80
81  { TQtWSStatusBar }
82
83  TQtWSStatusBar = class(TWSStatusBar)
84  protected
85    class procedure ClearPanels(const Widget: TQtStatusBar);
86    class procedure RecreatePanels(const AStatusBar: TStatusBar; const Widget: TQtStatusBar);
87  published
88    class function  CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
89    class procedure DestroyHandle(const AWinControl: TWinControl); override;
90    class procedure PanelUpdate(const AStatusBar: TStatusBar; PanelIndex: integer); override;
91    class procedure SetPanelText(const AStatusBar: TStatusBar; PanelIndex: integer); override;
92    class procedure SetSizeGrip(const AStatusBar: TStatusBar; SizeGrip: Boolean); override;
93    class procedure Update(const AStatusBar: TStatusBar); override;
94  end;
95
96  { TQtWSTabSheet }
97
98  TQtWSTabSheet = class(TWSTabSheet)
99  published
100  end;
101
102  { TQtWSPageControl }
103
104  TQtWSPageControl = class(TWSPageControl)
105  published
106  end;
107
108  { TQtWSCustomListView }
109
110  TQtWSCustomListView = class(TWSCustomListView)
111  protected
112    class function IsIconView(const AList: TCustomListView): boolean;
113    class procedure InternalUpdateItems(const AList: TCustomListView);
114    class procedure GetCurrentImages(const ALV: TCustomListView;
115      out AImgListRes: TScaledImageListResolution);
116  published
117    class function CreateHandle(const AWinControl: TWinControl;
118     const AParams: TCreateParams): TLCLIntfHandle; override;
119    class procedure ColumnDelete(const ALV: TCustomListView; const AIndex: Integer); override;
120    class procedure ColumnInsert(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn); override;
121    class function  ColumnGetWidth(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn): Integer; override;
122    class procedure ColumnSetWidth(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn; const AWidth: Integer); override;
123    class procedure ColumnSetVisible(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn; const AVisible: Boolean); override;
124    class procedure ColumnSetAlignment(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn; const AAlignment: TAlignment); override;
125    class procedure ColumnSetAutoSize(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn; const AAutoSize: Boolean); override;
126    class procedure ColumnSetCaption(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn; const ACaption: String); override;
127    class procedure ColumnSetImage(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn; const AImageIndex: Integer); override;
128
129    class procedure ColumnSetMinWidth(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn; const AMinWidth: integer); override;
130    class procedure ColumnMove(const ALV: TCustomListView; const AOldIndex, ANewIndex: Integer; const AColumn: TListColumn); override;
131
132
133    {items}
134    class procedure ItemInsert(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem); override;
135    class procedure ItemDelete(const ALV: TCustomListView; const AIndex: Integer); override;
136    class procedure ItemExchange(const ALV: TCustomListView; AItem: TListItem; const AIndex1, AIndex2: Integer); override;
137    class procedure ItemMove(const ALV: TCustomListView; AItem: TListItem; const AFromIndex, AToIndex: Integer); override;
138    class function  ItemGetChecked(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem): Boolean; override;
139    class procedure ItemSetChecked(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AChecked: Boolean); override;
140    class function  ItemGetPosition(const ALV: TCustomListView; const AIndex: Integer): TPoint; override;
141    class function  ItemGetState(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; out AIsSet: Boolean): Boolean; override; // returns True if supported
142    class procedure ItemSetImage(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex, AImageIndex: Integer); override;
143    class procedure ItemSetState(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; const AIsSet: Boolean); override;
144    class procedure ItemSetStateImage(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex, AStateImageIndex: Integer); override;
145    class procedure ItemSetText(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex: Integer; const AText: String); override;
146    class procedure ItemShow(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const PartialOK: Boolean); override;
147    class function  ItemDisplayRect(const ALV: TCustomListView; const AIndex, ASubItem: Integer; ACode: TDisplayCode): TRect; override;
148
149    {parent}
150    class procedure BeginUpdate(const ALV: TCustomListView); override;
151    class procedure EndUpdate(const ALV: TCustomListView); override;
152
153    class function GetFocused(const ALV: TCustomListView): Integer; override;
154    class function GetHitTestInfoAt( const ALV: TCustomListView; X, Y: Integer ) : THitTests; override;
155    class function GetItemAt(const ALV: TCustomListView; x,y: integer): Integer; override;
156    class function GetSelCount(const ALV: TCustomListView): Integer; override;
157    class function GetSelection(const ALV: TCustomListView): Integer; override;
158    class function GetTopItem(const ALV: TCustomListView): Integer; override;
159    class procedure SetSort(const ALV: TCustomListView; const AType: TSortType; const AColumn: Integer;
160      const ASortDirection: TSortDirection); override;
161
162    class function GetBoundingRect(const ALV: TCustomListView): TRect; override;
163    class function GetViewOrigin(const ALV: TCustomListView): TPoint; override;
164    class function GetVisibleRowCount(const ALV: TCustomListView): Integer; override;
165
166    class procedure SelectAll(const ALV: TCustomListView; const AIsSet: Boolean); override;
167
168    class procedure SetAllocBy(const ALV: TCustomListView; const AValue: Integer); override;
169    class procedure SetIconArrangement(const ALV: TCustomListView; const AValue: TIconArrangement); override;
170    class procedure SetImageList(const ALV: TCustomListView; const AList: TListViewImageList; const AValue: TCustomImageListResolution); override;
171    class procedure SetItemsCount(const ALV: TCustomListView; const Avalue: Integer); override;
172    class procedure SetOwnerData(const ALV: TCustomListView; const AValue: Boolean); override;
173
174    class procedure SetProperty(const ALV: TCustomListView; const AProp: TListViewProperty; const AIsSet: Boolean); override;
175    class procedure SetProperties(const ALV: TCustomListView; const AProps: TListViewProperties); override;
176
177    class procedure SetScrollBars(const ALV: TCustomListView; const AValue: TScrollStyle); override;
178    class procedure SetViewStyle(const ALV: TCustomListView; const Avalue: TViewStyle); override;
179
180    (*
181    // Column
182
183    class procedure ColumnSetMaxWidth(const ALV: TCustomListView; const AIndex: Integer; const AColumn: TListColumn; const AMaxWidth: Integer); override;
184
185
186    // Item
187    class function ItemSetPosition(const ALV: TCustomListView; const AIndex: Integer; const ANewPosition: TPoint): Boolean; virtual;
188
189    // LV
190
191    class function GetDropTarget(const ALV: TCustomListView): Integer; virtual;
192
193    class function GetHoverTime(const ALV: TCustomListView): Integer; virtual;
194    class function GetViewOrigin(const ALV: TCustomListView): TPoint; virtual;
195
196    class procedure SetDefaultItemHeight(const ALV: TCustomListView; const AValue: Integer); virtual;
197    class procedure SetHotTrackStyles(const ALV: TCustomListView; const AValue: TListHotTrackStyles); virtual;
198    class procedure SetHoverTime(const ALV: TCustomListView; const AValue: Integer); virtual;
199    class procedure SetImageList(const ALV: TCustomListView; const AList: TListViewImageList; const AValue: TCustomImageList); virtual;
200
201    class procedure SetViewOrigin(const ALV: TCustomListView; const AValue: TPoint); virtual;
202    *)
203  end;
204
205  { TQtWSListView }
206
207  TQtWSListView = class(TWSListView)
208  published
209  end;
210
211  { TQtWSProgressBar }
212
213  TQtWSProgressBar = class(TWSProgressBar)
214  protected
215    class procedure SetRangeStyle(AProgressBar: TQtProgressBar;
216      AStyle: TProgressBarStyle; AMin, AMax: Integer; const AIsDesign: Boolean);
217  published
218    class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
219    class procedure ApplyChanges(const AProgressBar: TCustomProgressBar); override;
220    class procedure SetPosition(const AProgressBar: TCustomProgressBar; const NewPosition: integer); override;
221    class procedure SetStyle(const AProgressBar: TCustomProgressBar; const NewStyle: TProgressBarStyle); override;
222  end;
223
224  { TQtWSCustomUpDown }
225
226  TQtWSCustomUpDown = class(TWSCustomUpDown)
227  published
228  end;
229
230  { TQtWSUpDown }
231
232  TQtWSUpDown = class(TWSUpDown)
233  published
234  end;
235
236  { TQtWSToolButton }
237
238  TQtWSToolButton = class(TWSToolButton)
239  published
240  end;
241
242  { TQtWSToolBar }
243
244  TQtWSToolBar = class(TWSToolBar)
245  published
246    class function  CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
247  end;
248
249  { TQtWSTrackBar }
250
251  TQtWSTrackBar = class(TWSTrackBar)
252  published
253    class function  CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
254    class procedure ApplyChanges(const ATrackBar: TCustomTrackBar); override;
255    class function  GetPosition(const ATrackBar: TCustomTrackBar): integer; override;
256    class procedure SetPosition(const ATrackBar: TCustomTrackBar; const NewPosition: integer); override;
257    class procedure SetOrientation(const ATrackBar: TCustomTrackBar; const AOrientation: TTrackBarOrientation); override;
258  end;
259
260  { TQtWSCustomTreeView }
261
262  TQtWSCustomTreeView = class(TWSCustomTreeView)
263  published
264  end;
265
266  { TQtWSTreeView }
267
268  TQtWSTreeView = class(TWSTreeView)
269  published
270  end;
271
272
273implementation
274uses qtint, math;
275
276{$include qtpagecontrol.inc}
277
278const
279  TickMarkToQtSliderTickPositionMap: array[TTickMark] of QSliderTickPosition =
280  (
281{tmBottomRight} QSliderTicksBelow,
282{tmTopLeft    } QSliderTicksAbove,
283{tmBoth       } QSliderTicksBothSides
284  );
285
286  TrackBarOrientationToQtOrientationMap: array[TTrackBarOrientation] of QtOrientation =
287  (
288{trHorizontal} QtHorizontal,
289{trVertical  } QtVertical
290  );
291
292  AlignmentToQtAlignmentMap: array[TAlignment] of QtAlignment =
293  (
294{taLeftJustify } QtAlignLeft,
295{taRightJustify} QtAlignRight,
296{taCenter      } QtAlignCenter
297  );
298
299  IconArngToQListFlow: array[TIconArrangement] of QListViewFlow =
300  (
301{iaTop} QListViewLeftToRight,
302{iaLeft}QListViewTopToBottom
303  );
304
305{ TQtWSToolBar }
306
307class function TQtWSToolBar.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
308var
309  QtToolBar: TQtCustomControl;
310begin
311  {$note TToolBar implementation under LCL is wrong. TToolBar isn't
312  TCustomControl but TWinControl.
313  To avoid theoretical crashes we use TQtCustomControl here, but indeed it
314  should be TQtWidget - so no viewport.}
315  QtToolBar := TQtCustomControl.Create(AWinControl, AParams);
316  QtToolBar.setFrameShape(QFrameNoFrame);
317  QtToolBar.viewportNeeded;
318  QtToolBar.setFocusPolicy(QtTabFocus);
319  QtToolBar.AttachEvents;
320  Result := TLCLIntfHandle(QtToolBar);
321end;
322
323{ TQtWSTrackBar }
324
325class function TQtWSTrackBar.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
326var
327  QtTrackBar: TQtTrackBar;
328begin
329  QtTrackBar := TQtTrackBar.Create(AWinControl, AParams);
330  QtTrackBar.AttachEvents;
331
332  Result := TLCLIntfHandle(QtTrackBar);
333end;
334
335function TrackBarReversed(const ATrackBar: TCustomTrackBar;
336  const AQtTrackBar: TQtTrackBar): Boolean;
337begin
338  Result :=
339    ((ATrackBar.Orientation = trHorizontal) and
340    (AQtTrackbar.getInvertedAppereance <> ATrackBar.Reversed))
341    or
342    ((ATrackBar.Orientation = trVertical) and
343    (AQtTrackbar.getInvertedAppereance <> not ATrackBar.Reversed))
344end;
345
346class procedure TQtWSTrackBar.ApplyChanges(const ATrackBar: TCustomTrackBar);
347var
348  QtTrackBar: TQtTrackBar;
349begin
350
351  if not WSCheckHandleAllocated(ATrackBar, 'ApplyChanges') then
352    Exit;
353
354  QtTrackBar := TQtTrackBar(ATrackBar.Handle);
355
356  QtTrackBar.BeginUpdate;
357  try
358    QtTrackBar.setRange(ATrackBar.Min, ATrackBar.Max);
359
360    if ATrackBar.TickStyle = tsNone then
361      QtTrackBar.SetTickPosition(QSliderNoTicks)
362    else
363      QtTrackBar.SetTickPosition(TickMarkToQtSliderTickPositionMap[ATrackBar.TickMarks]);
364
365    if QtTrackBar.getPageStep <> ATrackBar.PageSize then
366      QtTrackBar.setPageStep(ATrackBar.PageSize);
367    if QtTrackBar.getSingleStep <> ATrackBar.LineSize then
368      QtTrackBar.setSingleStep(ATrackBar.LineSize);
369    if QtTrackBar.getTickInterval <> ATrackBar.Frequency then
370      QtTrackBar.setTickInterval(ATrackBar.Frequency);
371    if QtTrackBar.getSliderPosition <> ATrackBar.Position then
372      QtTrackBar.setSliderPosition(ATrackBar.Position);
373
374    if (QtTrackBar.getOrientation <>
375      TrackBarOrientationToQtOrientationMap[ATrackBar.Orientation])
376      or TrackBarReversed(ATrackBar, QtTrackBar) then
377    begin
378      QtTrackBar.Hide;
379      QtTrackBar.setOrientation(TrackBarOrientationToQtOrientationMap[ATrackBar.Orientation]);
380      if ATrackBar.Orientation = trHorizontal then
381        QtTrackBar.setInvertedAppereance(ATrackBar.Reversed)
382      else
383        {make it delphi and msdn compatibile when vertical then 0 = top}
384        QtTrackBar.setInvertedAppereance(not ATrackBar.Reversed);
385      QtTrackBar.setInvertedControls(False);
386      QtTrackBar.Show;
387    end;
388  finally
389    QtTrackBar.EndUpdate;
390  end;
391end;
392
393class function  TQtWSTrackBar.GetPosition(const ATrackBar: TCustomTrackBar): integer;
394var
395  QtTrackBar: TQtTrackBar;
396begin
397  Result := 0;
398  if not WSCheckHandleAllocated(ATrackBar, 'GetPosition') then
399    Exit;
400  QtTrackBar := TQtTrackBar(ATrackBar.Handle);
401  Result := QtTrackBar.getSliderPosition;
402end;
403
404class procedure TQtWSTrackBar.SetPosition(const ATrackBar: TCustomTrackBar; const NewPosition: integer);
405var
406  QtTrackBar: TQtTrackBar;
407begin
408  if not WSCheckHandleAllocated(ATrackBar, 'SetPosition') then
409    Exit;
410  QtTrackBar := TQtTrackBar(ATrackBar.Handle);
411  QtTrackBar.BeginUpdate;
412  try
413    QtTrackBar.setSliderPosition(NewPosition);
414  finally
415    QtTrackBar.EndUpdate;
416  end;
417end;
418
419class procedure TQtWSTrackBar.SetOrientation(const ATrackBar: TCustomTrackBar;
420  const AOrientation: TTrackBarOrientation);
421var
422  QtTrackBar: TQtTrackBar;
423begin
424  if not WSCheckHandleAllocated(ATrackBar, 'SetOrientation') then
425    Exit;
426  QtTrackBar := TQtTrackBar(ATrackBar.Handle);
427  QtTrackBar.BeginUpdate;
428  try
429    if (QtTrackBar.getOrientation <>
430      TrackBarOrientationToQtOrientationMap[ATrackBar.Orientation])
431      or TrackBarReversed(ATrackBar, QtTrackBar) then
432    begin
433      QtTrackBar.Hide;
434      QtTrackBar.setOrientation(TrackBarOrientationToQtOrientationMap[ATrackBar.Orientation]);
435      if ATrackBar.Orientation = trHorizontal then
436        QtTrackBar.setInvertedAppereance(ATrackBar.Reversed)
437      else
438        {make it delphi and msdn compatibile when vertical then 0 = top}
439        QtTrackBar.setInvertedAppereance(not ATrackBar.Reversed);
440      QtTrackBar.setInvertedControls(False);
441      QtTrackBar.Show;
442    end;
443  finally
444    QtTrackBar.EndUpdate;
445  end;
446end;
447
448{ TQtWSProgressBar }
449
450class procedure TQtWSProgressBar.SetRangeStyle(AProgressBar: TQtProgressBar;
451  AStyle: TProgressBarStyle; AMin, AMax: Integer; const AIsDesign: Boolean);
452begin
453  if AStyle = pbstNormal then
454  begin
455    if (AMin = 0) and (AMax = 0) then
456      AProgressBar.setRange(0, 1)
457    else
458      AProgressBar.setRange(AMin, AMax)
459  end
460  else
461    AProgressBar.setRange(0, Integer(AIsDesign));
462end;
463
464class function TQtWSProgressBar.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
465var
466  QtProgressBar: TQtProgressBar;
467begin
468  QtProgressBar := TQtProgressBar.Create(AWinControl, AParams);
469  QtProgressBar.AttachEvents;
470  Result := TLCLIntfHandle(QtProgressBar);
471end;
472
473class procedure TQtWSProgressBar.ApplyChanges(const AProgressBar: TCustomProgressBar);
474var
475  QtProgressBar: TQtProgressBar;
476begin
477  QtProgressBar := TQtProgressBar(AProgressBar.Handle);
478
479  // AProgressBar.Smooth is not supported by qt
480
481  case AProgressBar.Orientation of
482    pbVertical:
483      begin
484        QtProgressBar.setOrientation(QtVertical);
485        QtProgressBar.setInvertedAppearance(False);
486      end;
487    pbRightToLeft:
488      begin
489        QtProgressBar.setOrientation(QtHorizontal);
490        QtProgressBar.setInvertedAppearance(True);
491      end;
492    pbTopDown:
493      begin
494        QtProgressBar.setOrientation(QtVertical);
495        QtProgressBar.setInvertedAppearance(True);
496      end;
497  else { pbHorizontal is default }
498    begin
499      QtProgressBar.setOrientation(QtHorizontal);
500      QtProgressBar.setInvertedAppearance(False);
501    end;
502  end;
503
504  QtProgressBar.setTextVisible(AProgressBar.BarShowText);
505
506  // The position, minumum and maximum values
507  SetRangeStyle(QtProgressBar, AProgressBar.Style,
508    AProgressBar.Min, AProgressBar.Max,
509    csDesigning in AProgressBar.ComponentState);
510  QtProgressBar.BeginUpdate;
511  QtProgressBar.setValue(AProgressBar.Position);
512  QtProgressBar.EndUpdate;
513end;
514
515class procedure TQtWSProgressBar.SetPosition(const AProgressBar: TCustomProgressBar; const NewPosition: integer);
516begin
517  TQtProgressBar(AProgressBar.Handle).BeginUpdate;
518  TQtProgressBar(AProgressBar.Handle).setValue(NewPosition);
519  TQtProgressBar(AProgressBar.Handle).EndUpdate;
520end;
521
522class procedure TQtWSProgressBar.SetStyle(
523  const AProgressBar: TCustomProgressBar; const NewStyle: TProgressBarStyle);
524var
525  QProgressBar: TQtProgressBar;
526begin
527  if not WSCheckHandleAllocated(AProgressBar, 'SetStyle') then
528    Exit;
529  QProgressBar := TQtProgressBar(AProgressBar.Handle);
530  QProgressBar.reset;
531  SetRangeStyle(QProgressBar, NewStyle, AProgressBar.Min, AProgressBar.Max,
532    csDesigning in AProgressBar.ComponentState);
533  if NewStyle = pbstNormal then
534    QProgressBar.setValue(AProgressBar.Position);
535end;
536
537{ TQtWSStatusBar }
538
539class procedure TQtWSStatusBar.ClearPanels(const Widget: TQtStatusBar);
540var
541  i: integer;
542begin
543  if length(Widget.Panels) > 0 then
544  begin
545    Widget.setUpdatesEnabled(False);
546    for i := High(Widget.Panels) downto 0 do
547    begin
548      Widget.removeWidget(Widget.Panels[i].Widget);
549      Widget.Panels[i].DetachEvents;
550      QLabel_destroy(QLabelH(Widget.Panels[i].Widget));
551      Widget.Panels[i].Widget := nil;
552      Widget.Panels[i].Free;
553    end;
554    Widget.setUpdatesEnabled(True);
555    SetLength(Widget.Panels, 0);
556  end;
557end;
558
559class procedure TQtWSStatusBar.RecreatePanels(const AStatusBar: TStatusBar;
560  const Widget: TQtStatusBar);
561var
562  Str: WideString;
563  i: Integer;
564begin
565  // issues #18683 and #28307
566  QStatusBar_clearMessage(QStatusBarH(Widget.Widget));
567  ClearPanels(Widget);
568  if AStatusBar.SimplePanel then
569  begin
570    Str := AStatusBar{%H-}.SimpleText;
571    Widget.showMessage(@Str);
572  end else
573  if AStatusBar.Panels.Count > 0 then
574  begin
575    Widget.setUpdatesEnabled(False);
576    SetLength(Widget.Panels, AStatusBar.Panels.Count);
577    for i := 0 to AStatusBar.Panels.Count - 1 do
578    begin
579      Str := AStatusBar{%H-}.Panels[i].Text;
580      Widget.Panels[i] := TQtStatusBarPanel.CreateFrom(AStatusBar,
581        QLabel_create(@Str, Widget.Widget));
582      Widget.Panels[i].HasPaint := AStatusBar.Panels[i].Style = psOwnerDraw;
583      Widget.Panels[i].ID := AStatusBar.Panels[i].ID;
584      QLabel_setText(QLabelH(Widget.Panels[i].Widget), @Str);
585      QLabel_setAlignment(QLabelH(Widget.Panels[i].Widget),
586        AlignmentToQtAlignmentMap[AStatusBar.Panels[i].Alignment]);
587      QWidget_setMinimumWidth(Widget.Panels[i].Widget, Max(0, AStatusBar.Panels[i].Width));
588      QWidget_setVisible(Widget.Panels[i].Widget,
589        AStatusBar.Panels[i].Width > 0);
590      Widget.Panels[i].AttachEvents;
591      Widget.addWidget(Widget.Panels[i].Widget, ord(i = AStatusBar.Panels.Count - 1));
592    end;
593    Widget.setUpdatesEnabled(True);
594  end;
595end;
596
597class function TQtWSStatusBar.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
598var
599  QtStatusBar: TQtStatusBar;
600begin
601  QtStatusBar := TQtStatusBar.Create(AWinControl, AParams);
602  QtStatusBar.setSizeGripEnabled(TStatusBar(AWinControl).SizeGrip and
603    TStatusBar(AWinControl).SizeGripEnabled);
604
605  RecreatePanels(TStatusBar(AWinControl), QtStatusBar);
606
607  QtStatusBar.AttachEvents;
608
609  // Return handle
610
611  Result := TLCLIntfHandle(QtStatusBar);
612end;
613
614class procedure TQtWSStatusBar.DestroyHandle(const AWinControl: TWinControl);
615var
616  QtStatusBar: TQtStatusBar;
617begin
618  QtStatusBar := TQtStatusBar(AWinControl.Handle);
619  ClearPanels(QtStatusBar);
620  QtStatusBar.Release;
621end;
622
623class procedure TQtWSStatusBar.PanelUpdate(const AStatusBar: TStatusBar; PanelIndex: integer);
624var
625  QtStatusBar: TQtStatusBar;
626  Str: Widestring;
627begin
628  QtStatusBar := TQtStatusBar(AStatusBar.Handle);
629  if AStatusBar.SimplePanel then
630  begin
631    ClearPanels(QtStatusBar);
632    Str := AStatusBar{%H-}.SimpleText;
633    QtStatusBar.showMessage(@Str);
634  end else
635  if AStatusBar.Panels.Count > 0 then
636  begin
637    QStatusBar_clearMessage(QStatusBarH(QtStatusBar.Widget));
638
639    if (PanelIndex >= Low(QtStatusBar.Panels)) and
640      (PanelIndex <= High(QtStatusBar.Panels)) then
641    begin
642      Str := AStatusBar{%H-}.Panels[PanelIndex].Text;
643      QLabel_setText(QLabelH(QtStatusBar.Panels[PanelIndex].Widget), @Str);
644      QLabel_setAlignment(QLabelH(QtStatusBar.Panels[PanelIndex].Widget),
645        AlignmentToQtAlignmentMap[AStatusBar.Panels[PanelIndex].Alignment]);
646      QWidget_setMinimumWidth(QtStatusBar.Panels[PanelIndex].Widget,
647        Max(0, AStatusBar.Panels[PanelIndex].Width));
648      QWidget_setVisible(QtStatusBar.Panels[PanelIndex].Widget,
649        AStatusBar.Panels[PanelIndex].Width > 0);
650    end;
651  end;
652end;
653
654class procedure TQtWSStatusBar.SetPanelText(const AStatusBar: TStatusBar; PanelIndex: integer);
655var
656  QtStatusBar: TQtStatusBar;
657  Str: Widestring;
658begin
659  QtStatusBar := TQtStatusBar(AStatusBar.Handle);
660  if AStatusBar.SimplePanel then
661  begin
662    Str := AStatusBar{%H-}.SimpleText;
663    QtStatusBar.showMessage(@Str);
664  end else
665  begin
666    if (PanelIndex >= Low(QtStatusBar.Panels)) and
667      (PanelIndex <= High(QtStatusBar.Panels)) then
668    begin
669      Str := AStatusBar{%H-}.Panels[PanelIndex].Text;
670      QLabel_setText(QLabelH(QtStatusBar.Panels[PanelIndex].Widget), @Str);
671    end;
672  end;
673end;
674
675class procedure TQtWSStatusBar.SetSizeGrip(const AStatusBar: TStatusBar;
676  SizeGrip: Boolean);
677var
678  QtStatusBar: TQtStatusBar;
679begin
680  if not WSCheckHandleAllocated(AStatusBar, 'SetSizeGrip') then
681    Exit;
682  QtStatusBar := TQtStatusBar(AStatusBar.Handle);
683  QtStatusBar.setSizeGripEnabled(SizeGrip and AStatusBar.SizeGripEnabled);
684end;
685
686class procedure TQtWSStatusBar.Update(const AStatusBar: TStatusBar);
687var
688  QtStatusBar: TQtStatusBar;
689begin
690  QtStatusBar := TQtStatusBar(AStatusBar.Handle);
691  RecreatePanels(AStatusBar, QtStatusBar);
692end;
693
694{ TQtWSCustomListView }
695
696type
697  TCustomListViewHack = class(TCustomListView);
698
699class function TQtWSCustomListView.IsIconView(const AList: TCustomListView): boolean;
700begin
701  Result := TCustomListViewHack(AList).ViewStyle <> vsReport;
702end;
703
704{------------------------------------------------------------------------------
705  Method: TQtWSCustomListView.CreateHandle
706  Params:  None
707  Returns: Nothing
708 ------------------------------------------------------------------------------}
709class function TQtWSCustomListView.CreateHandle(const AWinControl: TWinControl;
710  const AParams: TCreateParams): TLCLIntfHandle;
711var
712  QtTreeWidget: TQtTreeWidget;
713  QtListWidget: TQtListWidget;
714  ALV: TCustomListViewHack;
715begin
716  ALV := TCustomListViewHack(AWinControl);
717  if IsIconView(TCustomListView(AWinControl)) then
718  begin
719    QtListWidget := TQtListWidget.Create(AWinControl, AParams);
720    QtListWidget.ViewStyle := Ord(TCustomListViewHack(AWinControl).ViewStyle);
721    if TCustomListViewHack(AWinControl).ViewStyle in [vsIcon, vsSmallIcon] then
722    begin
723      // emabarcadero docs says
724      // vsIcon, vsSmallIcon
725      // Each item appears as a full-sized icon with a label below it.
726      // The user can drag the items to any location in the list view window.
727      QtListWidget.setViewMode(QListViewIconMode);
728      QtListWidget.setResizeMode(QListViewAdjust);
729      QtListWidget.setMovement(QListViewFree);
730
731      with TCustomListView(AWinControl) do
732      begin
733        QtListWidget.setWrapping(IconOptions.AutoArrange);
734        QtListWidget.setViewFlow(IconArngToQListFlow[IconOptions.Arrangement]);
735        QtListWidget.setWordWrap(IconOptions.WrapText);
736      end;
737
738    end else
739      QtListWidget.setViewMode(QListViewListMode);
740
741    QtListWidget.Checkable := TCustomListView(AWinControl).Checkboxes;
742    QtListWidget.OwnerDrawn := ALV.IsCustomDrawn(dtControl, cdPrePaint);
743    QtListWidget.AttachEvents;
744    Result := TLCLIntfHandle(QtListWidget);
745  end else
746  begin
747    QtTreeWidget := TQtTreeWidget.Create(AWinControl, AParams);
748    QtTreeWidget.ViewStyle := Ord(TCustomListViewHack(AWinControl).ViewStyle);
749    QtTreeWidget.OwnerDrawn := ALV.IsCustomDrawn(dtControl, cdPrePaint) or (ALV.OwnerDraw and
750      (ALV.ViewStyle = vsReport));
751    QtTreeWidget.setStretchLastSection(False);
752    QTreeView_setItemsExpandable(QTreeViewH(QtTreeWidget.Widget), False);
753    QtTreeWidget.setRootIsDecorated(False);
754    QtTreeWidget.AttachEvents;
755    Result := TLCLIntfHandle(QtTreeWidget);
756  end;
757end;
758
759{------------------------------------------------------------------------------
760  Method: TQtWSCustomListView.ColumnDelete
761  Params:  None
762  Returns: Nothing
763 ------------------------------------------------------------------------------}
764class procedure TQtWSCustomListView.ColumnDelete(const ALV: TCustomListView;
765  const AIndex: Integer);
766begin
767  if not WSCheckHandleAllocated(ALV, 'ColumnDelete') then
768    Exit;
769
770  // TODO: columns in vsIcon mode
771  if IsIconView(ALV) then
772    exit;
773
774  // we must recreate handle since there's no column removal support
775  // in our bindings (protected methods in qt).
776  RecreateWnd(ALV);
777end;
778
779{------------------------------------------------------------------------------
780  Method: TQtWSCustomListView.ColumnInsert
781  Params:  None
782  Returns: Nothing
783 ------------------------------------------------------------------------------}
784class procedure TQtWSCustomListView.ColumnInsert(const ALV: TCustomListView;
785  const AIndex: Integer; const AColumn: TListColumn);
786var
787  QtTreeWidget: TQtTreeWidget;
788  TWI: QTreeWidgetItemH;
789  TWIChild: QTreeWidgetItemH;
790  Str: WideString;
791begin
792  if not WSCheckHandleAllocated(ALV, 'ColumnInsert') then
793    Exit;
794
795  // TODO: columns in vsIcon mode
796  if IsIconView(ALV) then
797    exit;
798
799  QtTreeWidget := TQtTreeWidget(ALV.Handle);
800
801  if QtTreeWidget.ColCount <> TCustomListViewHack(ALV).Columns.Count then
802    QtTreeWidget.ColCount := TCustomListViewHack(ALV).Columns.Count;
803
804  if (QtTreeWidget.ColCount <= 1) and TCustomListViewHack(ALV).ShowColumnHeaders then
805    QtTreeWidget.setHeaderVisible(True);
806
807  TWI := QtTreeWidget.headerItem;
808
809  if QTreeWidgetItem_childCount(TWI) < (AIndex + 1) then
810  begin
811    TWIChild := QTreeWidgetItem_create(QTreeWidgetItemType);
812    QTreeWidgetItem_setFlags(TWIChild, QtItemIsEnabled);
813    QTreeWidgetItem_addChild(TWI, TWIChild);
814    Str := ALV{%H-}.Column[AIndex].Caption;
815    QTreeWidgetItem_setText(TWI, AIndex, @Str);
816  end;
817
818  if (csDesigning in ALV.ComponentState) then
819    exit;
820
821  QtTreeWidget.Header.Clickable := TCustomListViewHack(ALV).ColumnClick;
822end;
823
824{------------------------------------------------------------------------------
825  Method: TQtWSCustomListView.ColumnGetWidth
826  Params:  None
827  Returns: Integer
828 ------------------------------------------------------------------------------}
829class function  TQtWSCustomListView.ColumnGetWidth(const ALV: TCustomListView;
830  const AIndex: Integer; const AColumn: TListColumn): Integer;
831var
832  QtTreeWidget: TQtTreeWidget;
833begin
834  if not WSCheckHandleAllocated(ALV, 'ColumnGetWidth') then
835    Exit(-1);
836
837  // TODO: columns in vsIcon mode
838  if IsIconView(ALV) then
839    exit(0);
840
841  QtTreeWidget := TQtTreeWidget(ALV.Handle);
842  Result := QtTreeWidget.ColWidth[AIndex];
843end;
844
845{------------------------------------------------------------------------------
846  Method: TQtWSCustomListView.ColumnMove
847  Params:  None
848  Returns: Nothing
849 ------------------------------------------------------------------------------}
850class procedure TQtWSCustomListView.ColumnMove(const ALV: TCustomListView;
851  const AOldIndex, ANewIndex: Integer; const AColumn: TListColumn);
852var
853  QtTreeWidget: TQtTreeWidget;
854begin
855  if not WSCheckHandleAllocated(ALV, 'ColumnMove') then
856    Exit;
857
858  if (csDesigning in ALV.ComponentState) then
859    exit;
860
861  // TODO: columns in vsIcon mode
862  if IsIconView(ALV) then
863    exit;
864
865  QtTreeWidget := TQtTreeWidget(ALV.Handle);
866  QtTreeWidget.Header.moveSection(AOldIndex, ANewIndex);
867end;
868
869{------------------------------------------------------------------------------
870  Method: TQtWSCustomListView.ColumnSetAlignment
871  Params:  None
872  Returns: Nothing
873 ------------------------------------------------------------------------------}
874class procedure TQtWSCustomListView.ColumnSetAlignment(const ALV: TCustomListView;
875  const AIndex: Integer; const AColumn: TListColumn; const AAlignment: TAlignment);
876var
877  QtTreeWidget: TQtTreeWidget;
878  TWI: QTreeWidgetItemH;
879  i: Integer;
880begin
881  if not WSCheckHandleAllocated(ALV, 'ColumnSetAlignment') then
882    Exit;
883
884  // TODO: columns in vsIcon mode
885  if IsIconView(ALV) then
886    exit;
887
888  QtTreeWidget := TQtTreeWidget(ALV.Handle);
889  TWI := QtTreeWidget.headerItem;
890  QTreeWidgetItem_setTextAlignment(TWI, AIndex,
891    AlignmentToQtAlignmentMap[AAlignment]);
892
893
894  if not (csLoading in ALV.ComponentState) then
895    for i := 0 to QtTreeWidget.ItemCount - 1 do
896    begin
897      TWI := QtTreeWidget.topLevelItem(i);
898      if TWI <> nil then
899        QTreeWidgetItem_setTextAlignment(TWI, AIndex,
900          AlignmentToQtAlignmentMap[AAlignment]);
901    end;
902end;
903
904{------------------------------------------------------------------------------
905  Method: TQtWSCustomListView.ColumnSetAutoSize
906  Params:  None
907  Returns: Nothing
908 ------------------------------------------------------------------------------}
909class procedure TQtWSCustomListView.ColumnSetAutoSize(const ALV: TCustomListView;
910  const AIndex: Integer; const AColumn: TListColumn; const AAutoSize: Boolean);
911var
912  QtTreeWidget: TQtTreeWidget;
913begin
914  if not WSCheckHandleAllocated(ALV, 'ColumnSetAutoSize') then
915    Exit;
916
917  if (csDesigning in ALV.ComponentState) then
918    exit;
919
920  // TODO: columns in vsIcon mode
921  if IsIconView(ALV) then
922    exit;
923
924  QtTreeWidget := TQtTreeWidget(ALV.Handle);
925  if AAutoSize then
926    QtTreeWidget.Header.setResizeMode(AIndex, QHeaderViewResizeToContents)
927  else
928    QtTreeWidget.Header.setResizeMode(AIndex, QHeaderViewInteractive);
929end;
930
931{------------------------------------------------------------------------------
932  Method: TQtWSCustomListView.ColumnSetCaption
933  Params:  None
934  Returns: Nothing
935 ------------------------------------------------------------------------------}
936class procedure TQtWSCustomListView.ColumnSetCaption(const ALV: TCustomListView;
937  const AIndex: Integer; const AColumn: TListColumn; const ACaption: String);
938var
939  Str: WideString;
940  QtTreeWidget: TQtTreeWidget;
941  TWI: QTreeWidgetItemH;
942begin
943  if not WSCheckHandleAllocated(ALV, 'ColumnSetCaption') then
944    Exit;
945
946  // TODO: columns in vsIcon mode
947  if IsIconView(ALV) then
948    exit;
949
950  QtTreeWidget := TQtTreeWidget(ALV.Handle);
951  TWI := QtTreeWidget.headerItem;
952  if TWI <> NiL then
953  begin
954    Str := {%H-}ACaption;
955    QTreeWidgetItem_setText(TWI, AIndex, @Str);
956  end;
957end;
958
959{------------------------------------------------------------------------------
960  Method: TQtWSCustomListView.ColumnSetImage
961  Params:  None
962  Returns: Nothing
963 ------------------------------------------------------------------------------}
964class procedure TQtWSCustomListView.ColumnSetImage(const ALV: TCustomListView;
965  const AIndex: Integer; const AColumn: TListColumn; const AImageIndex: Integer);
966var
967  QtTreeWidget: TQtTreeWidget;
968  TWI: QTreeWidgetItemH;
969  Bmp: TBitmap;
970  ImgListRes: TScaledImageListResolution;
971begin
972  if not WSCheckHandleAllocated(ALV, 'ColumnSetImage') then
973    Exit;
974
975  // TODO: columns in vsIcon mode
976  if IsIconView(ALV) then
977    exit;
978
979  QtTreeWidget := TQtTreeWidget(ALV.Handle);
980  TWI := QtTreeWidget.headerItem;
981  if TWI <> NiL then
982  begin
983    GetCurrentImages(ALV, ImgListRes);
984    if ImgListRes.Valid and (ImgListRes.Count > 0) and
985      ((AImageIndex >= 0) and (AImageIndex < ImgListRes.Count)) then
986    begin
987      Bmp := TBitmap.Create;
988      try
989        ImgListRes.GetBitmap(AImageIndex, Bmp);
990        QTreeWidgetItem_setIcon(TWI, AIndex, TQtImage(Bmp.Handle).AsIcon);
991      finally
992        Bmp.Free;
993      end;
994    end;
995  end;
996end;
997
998{------------------------------------------------------------------------------
999  Method: TQtWSCustomListView.ColumnSetMinWidth
1000  Params:  None
1001  Returns: Nothing
1002 ------------------------------------------------------------------------------}
1003class procedure TQtWSCustomListView.ColumnSetMinWidth(const ALV: TCustomListView;
1004  const AIndex: Integer; const AColumn: TListColumn; const AMinWidth: integer);
1005var
1006  QtTreeWidget: TQtTreeWidget;
1007begin
1008  if not WSCheckHandleAllocated(ALV, 'ColumnSetMinWidth') then
1009    Exit;
1010
1011  // TODO: columns in vsIcon mode
1012  if IsIconView(ALV) then
1013    exit;
1014
1015  QtTreeWidget := TQtTreeWidget(ALV.Handle);
1016  QtTreeWidget.MinColSize[AIndex] := AMinWidth;
1017end;
1018
1019{------------------------------------------------------------------------------
1020  Method: TQtWSCustomListView.ColumnSetWidth
1021  Params:  None
1022  Returns: Nothing
1023 ------------------------------------------------------------------------------}
1024class procedure TQtWSCustomListView.ColumnSetWidth(const ALV: TCustomListView;
1025  const AIndex: Integer; const AColumn: TListColumn; const AWidth: Integer);
1026var
1027  QtTreeWidget: TQtTreeWidget;
1028begin
1029  if not WSCheckHandleAllocated(ALV, 'ColumnSetWidth') then
1030    Exit;
1031
1032  // TODO: columns in vsIcon mode
1033  if IsIconView(ALV) then
1034    exit;
1035
1036  QtTreeWidget := TQtTreeWidget(ALV.Handle);
1037  QtTreeWidget.ColWidth[AIndex] := AWidth;
1038end;
1039
1040{------------------------------------------------------------------------------
1041  Method: TQtWSCustomListView.ColumnSetVisible
1042  Params:  None
1043  Returns: Nothing
1044 ------------------------------------------------------------------------------}
1045class procedure TQtWSCustomListView.ColumnSetVisible(const ALV: TCustomListView;
1046  const AIndex: Integer; const AColumn: TListColumn; const AVisible: Boolean);
1047var
1048  QtTreeWidget: TQtTreeWidget;
1049begin
1050  if not WSCheckHandleAllocated(ALV, 'ColumnSetVisible') then
1051    Exit;
1052
1053  // TODO: columns in vsIcon mode
1054  if IsIconView(ALV) then
1055    exit;
1056
1057  QtTreeWidget := TQtTreeWidget(ALV.Handle);
1058  QtTreeWidget.ColVisible[AIndex] := AVisible;
1059end;
1060
1061{------------------------------------------------------------------------------
1062  Method: TQtWSCustomListView.ItemDelete
1063  Params:  None
1064  Returns: Nothing
1065 ------------------------------------------------------------------------------}
1066class procedure TQtWSCustomListView.ItemDelete(const ALV: TCustomListView;
1067  const AIndex: Integer);
1068var
1069  QtTreeWidget: TQtTreeWidget;
1070begin
1071  if not WSCheckHandleAllocated(ALV, 'ItemDelete') then
1072    Exit;
1073  if IsIconView(ALV) then
1074    TQtListWidget(ALV.Handle).removeItem(AIndex)
1075  else
1076  begin
1077    TQtListWidget(ALV.Handle).BeginUpdate;
1078    try
1079      QtTreeWidget := TQtTreeWidget(ALV.Handle);
1080      QtTreeWidget.DeleteItem(AIndex);
1081    finally
1082      TQtListWidget(ALV.Handle).EndUpdate;
1083    end;
1084  end;
1085end;
1086
1087class procedure TQtWSCustomListView.ItemExchange(const ALV: TCustomListView;
1088  AItem: TListItem; const AIndex1, AIndex2: Integer);
1089var
1090  QtTreeWidget: TQtTreeWidget;
1091  QtListWidget: TQtListWidget;
1092begin
1093  if not WSCheckHandleAllocated(ALV, 'ItemExchange') then
1094    Exit;
1095  if IsIconView(ALV) then
1096  begin
1097    QtListWidget := TQtListWidget(ALV.Handle);
1098    QtListWidget.BeginUpdate;
1099    QtListWidget.ExchangeItems(AIndex1, AIndex2);
1100    QtListWidget.EndUpdate;
1101  end else
1102  begin
1103    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1104    QtTreeWidget.BeginUpdate;
1105    QtTreeWidget.ExchangeItems(AIndex1, AIndex2);
1106    QtTreeWidget.EndUpdate;
1107  end;
1108end;
1109
1110class procedure TQtWSCustomListView.ItemMove(const ALV: TCustomListView;
1111  AItem: TListItem; const AFromIndex, AToIndex: Integer);
1112var
1113  QtTreeWidget: TQtTreeWidget;
1114  QtListWidget: TQtListWidget;
1115begin
1116  if not WSCheckHandleAllocated(ALV, 'ItemMove') then
1117    Exit;
1118  if IsIconView(ALV) then
1119  begin
1120    QtListWidget := TQtListWidget(ALV.Handle);
1121    QtListWidget.BeginUpdate;
1122    QtListWidget.MoveItem(AFromIndex, AToIndex);
1123    QtListWidget.EndUpdate;
1124  end else
1125  begin
1126    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1127    QtTreeWidget.BeginUpdate;
1128    QtTreeWidget.MoveItem(AFromIndex, AToIndex);
1129    QtTreeWidget.EndUpdate;
1130  end;
1131end;
1132
1133{------------------------------------------------------------------------------
1134  Method: TQtWSCustomListView.ItemGetChecked
1135  Params:  None
1136  Returns: Nothing
1137 ------------------------------------------------------------------------------}
1138class function  TQtWSCustomListView.ItemGetChecked(const ALV: TCustomListView;
1139  const AIndex: Integer; const AItem: TListItem): Boolean;
1140var
1141  QtTreeWidget: TQtTreeWidget;
1142  LWI: QListWidgetItemH;
1143  AState: QtCheckState;
1144begin
1145  if not WSCheckHandleAllocated(ALV, 'ItemGetChecked') then
1146    Exit(False);
1147
1148  Result := ALV.CheckBoxes;
1149  if not Result then
1150    exit;
1151
1152  if IsIconView(ALV) then
1153  begin
1154    AState := QtUnChecked;
1155    LWI := TQtListWidget(ALV.Handle).getItem(AIndex);
1156    if LWI <> nil then
1157      AState := TQtListWidget(ALV.Handle).GetItemLastCheckState(LWI);
1158    Result := AState = QtChecked;
1159  end else
1160  begin
1161    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1162    Result := QtTreeWidget.ItemChecked[AIndex];
1163  end;
1164end;
1165
1166{------------------------------------------------------------------------------
1167  Method: TQtWSCustomListView.ItemGetPosition
1168  Params:  None
1169  Returns: TPoint
1170 ------------------------------------------------------------------------------}
1171class function  TQtWSCustomListView.ItemGetPosition(const ALV: TCustomListView;
1172  const AIndex: Integer): TPoint;
1173var
1174  QtListWidget: TQtListWidget;
1175  QtTreeWidget: TQtTreeWidget;
1176  TWI: QTreeWidgetItemH;
1177  R: TRect;
1178begin
1179  if not WSCheckHandleAllocated(ALV, 'ItemGetPosition') then
1180    Exit(Point(-1,-1));
1181
1182  R := Rect(0, 0, 0, 0);
1183  if IsIconView(ALV) then
1184  begin
1185    QtListWidget := TQtListWidget(ALV.Handle);
1186    R := QtListWidget.getVisualItemRect(QtListWidget.getItem(AIndex));
1187  end else
1188  begin
1189    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1190    TWI := QtTreeWidget.topLevelItem(AIndex);
1191    R := QtTreeWidget.visualItemRect(TWI);
1192  end;
1193  Result.X := R.Left;
1194  Result.Y := R.Top;
1195end;
1196
1197{------------------------------------------------------------------------------
1198  Method: TQtWSCustomListView.ItemGetState
1199  Params:  None
1200  Returns: TPoint
1201 ------------------------------------------------------------------------------}
1202class function  TQtWSCustomListView.ItemGetState(const ALV: TCustomListView;
1203  const AIndex: Integer; const AItem: TListItem;
1204  const AState: TListItemState; out AIsSet: Boolean): Boolean;
1205var
1206  QtListWidget: TQtListWidget;
1207  LWI: QListWidgetItemH;
1208  QtTreeWidget: TQtTreeWidget;
1209  TWI: QTreeWidgetItemH;
1210  i: Integer;
1211  Arr: TPtrIntArray;
1212begin
1213  if not WSCheckHandleAllocated(ALV, 'ItemGetState') then
1214    Exit(False);
1215
1216  AIsSet := False;
1217  if IsIconView(ALV) then
1218  begin
1219    QtListWidget := TQtListWidget(ALV.Handle);
1220    LWI := QtListWidget.getItem(AIndex);
1221    if LWI <> nil then
1222      case AState of
1223        lisFocused: AIsSet := LWI = QtListWidget.currentItem;
1224        lisSelected: AIsSet := QtListWidget.getItemSelected(LWI);
1225      end;
1226  end else
1227  begin
1228    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1229    TWI := QtTreeWidget.topLevelItem(AIndex);
1230    if TWI <> nil then
1231    begin
1232      case AState of
1233        lisFocused: AIsSet := TWI = QtTreeWidget.currentItem;
1234        lisSelected:
1235        begin
1236          Arr := QtTreeWidget.selectedItems;
1237          for i := 0 to High(Arr) do
1238          begin
1239            TWI := QTreeWidgetItemH(Arr[i]);
1240            if AIndex = QtTreeWidget.getRow(TWI) then
1241            begin
1242              AIsSet := True;
1243              break;
1244            end;
1245          end;
1246        end;
1247      end;
1248    end;
1249  end;
1250  Result := True;
1251
1252end;
1253
1254class procedure TQtWSCustomListView.ItemSetImage(const ALV: TCustomListView;
1255  const AIndex: Integer; const AItem: TListItem; const ASubIndex,
1256  AImageIndex: Integer);
1257var
1258  QtListWidget: TQtListWidget;
1259  LWI: QListWidgetItemH;
1260  QtTreeWidget: TQtTreeWidget;
1261  TWI: QTreeWidgetItemH;
1262  Bmp: TBitmap;
1263  ImgListRes: TScaledImageListResolution;
1264begin
1265  if not WSCheckHandleAllocated(ALV, 'ItemSetImage') then
1266    Exit;
1267
1268  if not Assigned(TCustomListViewHack(ALV).LargeImages) and not
1269    Assigned(TCustomListViewHack(ALV).SmallImages) then
1270      exit;
1271  TWI := nil;
1272  LWI := nil;
1273  if IsIconView(ALV) then
1274  begin
1275    if ASubIndex > 0 then
1276      exit;
1277    QtListWidget := TQtListWidget(ALV.Handle);
1278    LWI := QtListWidget.getItem(AIndex);
1279  end else
1280  begin
1281    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1282    TWI := QtTreeWidget.topLevelItem(AIndex);
1283  end;
1284  if (TWI <> nil) or (LWI <> nil) then
1285  begin
1286    GetCurrentImages(ALV, ImgListRes);
1287
1288    if ImgListRes.Valid and
1289      ((AImageIndex >= 0) and (AImageIndex < ImgListRes.Count)) then
1290    begin
1291      Bmp := TBitmap.Create;
1292      try
1293        ImgListRes.GetBitmap(AImageIndex, Bmp);
1294        if LWI <> nil then
1295          QListWidgetItem_setIcon(LWI, TQtImage(Bmp.Handle).AsIcon)
1296        else
1297          QTreeWidgetItem_setIcon(TWI, ASubIndex, TQtImage(Bmp.Handle).AsIcon);
1298      finally
1299        Bmp.Free;
1300      end;
1301    end else
1302    begin
1303      if Assigned(TCustomListViewHack(ALV).StateImages) and (AItem.StateIndex >= 0) then
1304        exit;
1305      if LWI <> nil then
1306        QListWidgetItem_setIcon(LWI, nil)
1307      else
1308        QTreeWidgetItem_setIcon(TWI, ASubIndex, nil);
1309    end;
1310  end;
1311end;
1312
1313{------------------------------------------------------------------------------
1314  Method: TQtWSCustomListView.ItemSetChecked
1315  Params:  None
1316  Returns: Nothing
1317 ------------------------------------------------------------------------------}
1318class procedure TQtWSCustomListView.ItemSetChecked(const ALV: TCustomListView;
1319  const AIndex: Integer; const AItem: TListItem; const AChecked: Boolean);
1320var
1321  QtListWidget: TQtListWidget;
1322  QtTreeWidget: TQtTreeWidget;
1323  B: Boolean;
1324begin
1325  if not WSCheckHandleAllocated(ALV, 'ItemSetChecked') then
1326    Exit;
1327
1328  if not ALV.CheckBoxes then
1329    exit;
1330
1331  if IsIconView(ALV) then
1332  begin
1333    QtListWidget := TQtListWidget(ALV.Handle);
1334    B := QtListWidget.GetItemLastCheckState(QtListWidget.getItem(AIndex)) = QtChecked;
1335    if B <> AChecked then
1336      QtListWidget.ItemChecked[AIndex] := AChecked;
1337  end else
1338  begin
1339    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1340    if QtTreeWidget.ItemChecked[AIndex] <> AChecked then
1341      QtTreeWidget.ItemChecked[AIndex] := AChecked;
1342  end;
1343end;
1344
1345{------------------------------------------------------------------------------
1346  Method: TQtWSCustomListView.ItemSetState
1347  Params:  None
1348  Returns: Nothing
1349 ------------------------------------------------------------------------------}
1350class procedure TQtWSCustomListView.ItemSetState(const ALV: TCustomListView;
1351  const AIndex: Integer; const AItem: TListItem;
1352  const AState: TListItemState; const AIsSet: Boolean);
1353var
1354  QtListWidget: TQtListWidget;
1355  LWI: QListWidgetItemH;
1356  QtTreeWidget: TQtTreeWidget;
1357  TWI: QTreeWidgetItemH;
1358begin
1359  if not WSCheckHandleAllocated(ALV, 'ItemSetState') then
1360    Exit;
1361  if IsIconView(ALV) then
1362  begin
1363    QtListWidget := TQtListWidget(ALV.Handle);
1364    LWI := QtListWidget.getItem(AIndex);
1365    QtListWidget.BeginUpdate;
1366    case AState of
1367      lisFocused: QtListWidget.setCurrentItem(LWI, AIsSet);
1368      lisSelected:
1369      begin
1370        if AIsSet and not ALV.MultiSelect then
1371          QtListWidget.setCurrentItem(LWI);
1372        QtListWidget.setItemSelected(LWI, AIsSet);
1373      end;
1374    end;
1375    QtListWidget.EndUpdate;
1376  end else
1377  begin
1378    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1379    TWI := QtTreeWidget.topLevelItem(AIndex);
1380    QtTreeWidget.BeginUpdate;
1381    case AState of
1382      lisFocused: QtTreeWidget.setCurrentItem(TWI);
1383      lisSelected:
1384      begin
1385        if ALV.RowSelect and AIsSet and not ALV.MultiSelect then
1386          QtTreeWidget.setCurrentItem(TWI);
1387        QtTreeWidget.setItemSelected(TWI, AIsSet);
1388      end;
1389    end;
1390    QtTreeWidget.EndUpdate;
1391  end;
1392end;
1393
1394class procedure TQtWSCustomListView.ItemSetStateImage(
1395  const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem;
1396  const ASubIndex, AStateImageIndex: Integer);
1397var
1398  QtListWidget: TQtListWidget;
1399  LWI: QListWidgetItemH;
1400  QtTreeWidget: TQtTreeWidget;
1401  TWI: QTreeWidgetItemH;
1402  Bmp: TBitmap;
1403  ImgListRes: TScaledImageListResolution;
1404  AImgList: TCustomImageList;
1405  AImgListWidth: Integer;
1406begin
1407  if not WSCheckHandleAllocated(ALV, 'ItemSetStateImage') then
1408    Exit;
1409
1410  if not Assigned(TCustomListViewHack(ALV).StateImages) then
1411    exit;
1412  TWI := nil;
1413  LWI := nil;
1414  if IsIconView(ALV) then
1415  begin
1416    if ASubIndex > 0 then
1417      exit;
1418    QtListWidget := TQtListWidget(ALV.Handle);
1419    LWI := QtListWidget.getItem(AIndex);
1420  end else
1421  begin
1422    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1423    TWI := QtTreeWidget.topLevelItem(AIndex);
1424  end;
1425  if (TWI <> nil) or (LWI <> nil) then
1426  begin
1427    AImgList := TCustomListViewHack(ALV).StateImages;
1428    AImgListWidth := TCustomListViewHack(ALV).StateImagesWidth;
1429    ImgListRes := AImgList.ResolutionForControl[AImgListWidth, ALV];
1430
1431    if ImgListRes.Valid and
1432      ((AStateImageIndex >= 0) and (AStateImageIndex < ImgListRes.Count)) then
1433    begin
1434      Bmp := TBitmap.Create;
1435      try
1436        ImgListRes.GetBitmap(AStateImageIndex, Bmp);
1437        if LWI <> nil then
1438          QListWidgetItem_setIcon(LWI, TQtImage(Bmp.Handle).AsIcon)
1439        else
1440          QTreeWidgetItem_setIcon(TWI, ASubIndex, TQtImage(Bmp.Handle).AsIcon);
1441      finally
1442        Bmp.Free;
1443      end;
1444    end else
1445    begin
1446      if LWI <> nil then
1447        QListWidgetItem_setIcon(LWI, nil)
1448      else
1449        QTreeWidgetItem_setIcon(TWI, ASubIndex, nil);
1450    end;
1451  end;
1452end;
1453
1454{------------------------------------------------------------------------------
1455  Method: TQtWSCustomListView.ItemInsert
1456  Params:  None
1457  Returns: Nothing
1458 ------------------------------------------------------------------------------}
1459class procedure TQtWSCustomListView.ItemInsert(const ALV: TCustomListView;
1460  const AIndex: Integer; const AItem: TListItem);
1461var
1462  QtListWidget: TQtListWidget;
1463  QtTreeWidget: TQtTreeWidget;
1464  TWI: QTreeWidgetItemH;
1465  Str: WideString;
1466  i: Integer;
1467  AAlignment: QtAlignment;
1468  //AIconWidth: Integer;
1469begin
1470  if not WSCheckHandleAllocated(ALV, 'ItemInsert') then
1471    Exit;
1472
1473  if IsIconView(ALV) then
1474  begin
1475    QtListWidget := TQtListWidget(ALV.Handle);
1476    QtListWidget.Checkable := ALV.Checkboxes;
1477    QtListWidget.insertItem(AIndex, AItem.Caption);
1478  end else
1479  begin
1480    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1481    TWI := QTreeWidgetItem_create(QTreeWidgetItemType);
1482    Str := AItem{%H-}.Caption;
1483
1484    if ALV.CheckBoxes then
1485    begin
1486      if AItem.Checked then
1487      	QTreeWidgetItem_setCheckState(TWI, 0, QtChecked)
1488      else
1489      	QTreeWidgetItem_setCheckState(TWI, 0, QtUnchecked);
1490    end;
1491
1492    AAlignment := QtAlignLeft or QtAlignVCenter;
1493    if TCustomListViewHack(ALV).Columns.Count > 0 then
1494      AAlignment := AlignmentToQtAlignmentMap[ALV.Column[0].Alignment] or QtAlignVCenter;
1495
1496    if Str <> '' then
1497      QtTreeWidget.setItemText(TWI, 0, Str, AAlignment);
1498
1499    QtTreeWidget.setItemData(TWI, 0, AItem);
1500
1501    for i := 0 to AItem.SubItems.Count - 1 do
1502    begin
1503      AAlignment := QtAlignLeft or QtAlignVCenter;
1504      if (TCustomListViewHack(ALV).Columns.Count > 0) and (i + 1 < TCustomListViewHack(ALV).Columns.Count) then
1505        AAlignment := AlignmentToQtAlignmentMap[ALV.Column[i + 1].Alignment] or QtAlignVCenter;
1506      if AItem.Subitems.Strings[i] <> '' then
1507      begin
1508        Str := AItem{%H-}.Subitems.Strings[i];
1509        QtTreeWidget.setItemText(TWI, i + 1, Str, AAlignment);
1510        QtTreeWidget.setItemData(TWI, i + 1, AItem);
1511      end;
1512    end;
1513
1514    QtTreeWidget.insertTopLevelItem(AIndex, TWI);
1515  end;
1516end;
1517
1518{------------------------------------------------------------------------------
1519  Method: TQtWSCustomListView.ItemSetText
1520  Params:  None
1521  Returns: Nothing
1522 ------------------------------------------------------------------------------}
1523class procedure TQtWSCustomListView.ItemSetText(const ALV: TCustomListView;
1524  const AIndex: Integer; const AItem: TListItem; const ASubIndex: Integer;
1525  const AText: String);
1526var
1527  QtListWidget: TQtListWidget;
1528  QtTreeWidget: TQtTreeWidget;
1529  TWI: QTreeWidgetItemH;
1530  Str: WideString;
1531  AAlignment: QtAlignment;
1532begin
1533  if not WSCheckHandleAllocated(ALV, 'ItemSetText') then
1534    Exit;
1535
1536  if IsIconView(ALV) then
1537  begin
1538    if ASubIndex >0 Then exit;
1539    QtListWidget := TQtListWidget(ALV.Handle);
1540    if not QtListWidget.Checkable and (TCustomListViewHack(ALV).ViewStyle = vsIcon) then
1541      AAlignment := QtAlignHCenter
1542    else
1543      AAlignment := QtAlignLeft;
1544    if (TCustomListViewHack(ALV).Columns.Count > 0) and (ASubIndex < TCustomListViewHack(ALV).Columns.Count)  then
1545      AAlignment := AlignmentToQtAlignmentMap[ALV.Column[ASubIndex].Alignment];
1546    QtListWidget.setItemText(AIndex, AText, AAlignment);
1547  end else
1548  begin
1549    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1550    Str := {%H-}AText;
1551    TWI := QtTreeWidget.topLevelItem(AIndex);
1552    if TWI <> NiL then
1553    begin
1554      AAlignment := QtAlignLeft or QtAlignVCenter;
1555      if (TCustomListViewHack(ALV).Columns.Count > 0) and (ASubIndex < TCustomListViewHack(ALV).Columns.Count)  then
1556        AAlignment := AlignmentToQtAlignmentMap[ALV.Column[ASubIndex].Alignment]  or QtAlignVCenter;
1557      QtTreeWidget.setItemText(TWI, ASubIndex, Str, AAlignment);
1558    end;
1559  end;
1560end;
1561
1562{------------------------------------------------------------------------------
1563  Method: TQtWSCustomListView.ItemShow
1564  Params:  None
1565  Returns: Nothing
1566 ------------------------------------------------------------------------------}
1567class procedure TQtWSCustomListView.ItemShow(const ALV: TCustomListView;
1568  const AIndex: Integer; const AItem: TListItem; const PartialOK: Boolean);
1569var
1570  QtListWidget: TQtListWidget;
1571  LWI: QListWidgetItemH;
1572  QtTreeWidget: TQtTreeWidget;
1573  TWI: QTreeWidgetItemH;
1574begin
1575  if not WSCheckHandleAllocated(ALV, 'ItemShow') then
1576    Exit;
1577  if IsIconView(ALV) then
1578  begin
1579    QtListWidget := TQtListWidget(ALV.Handle);
1580    LWI := QtListWidget.getItem(AIndex);
1581    QtListWidget.setItemVisible(LWI, True);
1582    if not PartialOK then
1583      QtListWidget.scrollToItem(AIndex, QAbstractItemViewEnsureVisible);
1584  end else
1585  begin
1586    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1587    TWI := QtTreeWidget.topLevelItem(AIndex);
1588    QtTreeWidget.setItemVisible(TWI, True);
1589    if not PartialOK then
1590      QtTreeWidget.scrollToItem(TWI, QAbstractItemViewEnsureVisible);
1591  end;
1592end;
1593
1594
1595{------------------------------------------------------------------------------
1596  Method: TQtWSCustomListView.ItemDisplayRect
1597  Params:  None
1598  Returns: Nothing
1599 ------------------------------------------------------------------------------}
1600class function  TQtWSCustomListView.ItemDisplayRect(const ALV: TCustomListView;
1601  const AIndex, ASubItem: Integer; ACode: TDisplayCode): TRect;
1602var
1603  QtListWidget: TQtListWidget;
1604  LWI: QListWidgetItemH;
1605  QtTreeWidget: TQtTreeWidget;
1606  TWI: QTreeWidgetItemH;
1607  Size: TSize;
1608  AIcon: QIconH;
1609  IconRect, ChkBoxRect: TRect;
1610  i: Integer;
1611  APixelMetric: Integer;
1612  ImgListRes: TScaledImageListResolution;
1613begin
1614  if not WSCheckHandleAllocated(ALV, 'ItemDisplayRect') then
1615    Exit;
1616
1617  GetCurrentImages(ALV, ImgListRes);
1618  if IsIconView(ALV) then
1619  begin
1620    QtListWidget := TQtListWidget(ALV.Handle);
1621    LWI := QtListWidget.getItem(AIndex);
1622    Result := QtListWidget.getVisualItemRect(LWI);
1623    if TCustomListViewHack(ALV).ViewStyle = vsList then
1624    begin
1625      if ACode in [drBounds, drSelectBounds] then
1626        exit;
1627      APixelMetric := QStyle_pixelMetric(QApplication_style(), QStylePM_FocusFrameHMargin, nil, QtListWidget.Widget);
1628      IconRect := Result;
1629      // always get icon size
1630      AIcon := QIcon_create();
1631      try
1632        QListWidgetItem_icon(LWI, AIcon);
1633        if QIcon_isNull(AIcon) then
1634          IconRect := Rect(Result.Left, Result.Top, Result.Right, Result.Bottom)
1635        else
1636        begin
1637          Size.cx := 0;
1638          Size.cy := 0;
1639          QIcon_actualSize(AIcon, @Size, @Size);
1640          if (Size.cx = 0) or (Size.cy = 0) then
1641          begin
1642            if ImgListRes.Valid then
1643              IconRect.Right := IconRect.Left + ImgListRes.Width;
1644          end else
1645          begin
1646            IconRect.Right := IconRect.Left + Size.cx;
1647            IconRect.Bottom := IconRect.Top + Size.cy;
1648          end;
1649        end;
1650      finally
1651        QIcon_destroy(AIcon);
1652      end;
1653
1654      IconRect.Left += APixelMetric;
1655      IconRect.Right += APixelMetric;
1656
1657      if ACode = drLabel then
1658      begin
1659        inc(Result.Left, APixelMetric + (IconRect.Right - IconRect.Left));
1660        if (IconRect.Right - IconRect.Left > 0) then
1661          Result.Left += APixelMetric;
1662      end else
1663      if ACode in [drIcon] then
1664        Result := IconRect;
1665    end;
1666  end else
1667  begin
1668    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1669    TWI := QtTreeWidget.topLevelItem(AIndex);
1670    if (QTreeWidgetItem_columnCount(TWI) > 1) and (ASubItem >= 0) then
1671    begin
1672      Result := QtTreeWidget.visualItemRect(TWI);
1673      Result.Left := QTreeView_columnViewportPosition(QTreeWidgetH(QtTreeWidget.Widget), ASubItem);
1674      Result.Right := QtTreeWidget.ColWidth[ASubItem] + Result.Left;
1675    end else
1676    begin
1677      Result := QtTreeWidget.visualItemRect(TWI);
1678    end;
1679
1680    if ACode = drBounds then
1681    begin
1682      QWidget_rect(QtTreeWidget.viewportWidget, @IconRect);
1683      for i := ASubItem + 1 to QtTreeWidget.ColCount - 1 do
1684        Result.Right += QtTreeWidget.ColWidth[i];
1685      if Result.Right > IconRect.Right - IconRect.Left then
1686        Result.Right := IconRect.Right - IconRect.Left;
1687      exit;
1688    end else
1689    begin
1690      IconRect := Result;
1691      // always get icon size
1692      AIcon := QIcon_create();
1693      try
1694        QTreeWidgetItem_icon(TWI, AIcon, ASubItem);
1695        if QIcon_isNull(AIcon) then
1696          IconRect := Rect(0, 0, 0, 0)
1697        else
1698        begin
1699          Size.cx := 0;
1700          Size.cy := 0;
1701          QIcon_actualSize(AIcon, @Size, @Size);
1702          if (Size.cx = 0) or (Size.cy = 0) then
1703          begin
1704            if ImgListRes.Valid then
1705              IconRect.Right := IconRect.Left + ImgListRes.Width;
1706          end else
1707          begin
1708            IconRect.Right := IconRect.Left + Size.cx;
1709            IconRect.Bottom := IconRect.Top + Size.cy;
1710          end;
1711        end;
1712      finally
1713        QIcon_destroy(AIcon);
1714      end;
1715    end;
1716
1717    ChkBoxRect := Rect(0, 0, 0, 0);
1718    if QtTreeWidget.Checkable then
1719    begin
1720      APixelMetric := QStyle_pixelMetric(QApplication_style(), QStylePM_IndicatorWidth, nil, QtTreeWidget.Widget);
1721      APixelMetric += QStyle_pixelMetric(QApplication_style(), QStylePM_CheckBoxLabelSpacing, nil, QtTreeWidget.Widget);
1722      ChkBoxRect := Rect(0, 0, APixelMetric, APixelMetric);
1723      if (ChkBoxRect.Bottom > Result.Bottom - Result.Top) then
1724        ChkBoxRect.Bottom := Result.Bottom - Result.Top;
1725    end;
1726
1727    APixelMetric := QStyle_pixelMetric(QApplication_style(), QStylePM_FocusFrameHMargin, nil, QtTreeWidget.Widget);
1728    if ACode = drLabel then
1729    begin
1730      inc(Result.Left, APixelMetric + (IconRect.Right - IconRect.Left) + (ChkBoxRect.Right - ChkBoxRect.Left));
1731      if (IconRect.Right - IconRect.Left > 0) then
1732        Result.Left += APixelMetric;
1733    end else
1734    if ACode = drSelectBounds then
1735    begin
1736      Result.Left += APixelMetric + (ChkBoxRect.Right - ChkBoxRect.Left);
1737      Result.Right := Result.Left + (QtTreeWidget.ColWidth[ASubItem] - APixelMetric);
1738    end else
1739    if ACode in [drIcon] then
1740    begin
1741      if IsRectEmpty(IconRect) and ImgListRes.Valid and
1742        (QtTreeWidget.OwnerData or QtTreeWidget.OwnerDrawn) then
1743      begin
1744        IconRect := Rect(0, 0, ImgListRes.Width, ImgListRes.Height);
1745        OffsetRect(IconRect, Result.Left, Result.Top + APixelMetric);
1746      end;
1747      IconRect.Left += APixelMetric + (ChkBoxRect.Right - ChkBoxRect.Left);
1748      IconRect.Right += APixelMetric;
1749      Result := IconRect;
1750    end;
1751  end;
1752end;
1753
1754class procedure TQtWSCustomListView.BeginUpdate(const ALV: TCustomListView);
1755var
1756  QtWidget: TQtWidget;
1757begin
1758  if not WSCheckHandleAllocated(ALV, 'BeginUpdate') then
1759    Exit;
1760  QtWidget := TQtWidget(ALV.Handle);
1761  if not QtWidget.InUpdate then
1762    QtWidget.setUpdatesEnabled(False);
1763  QtWidget.BeginUpdate;
1764end;
1765
1766class procedure TQtWSCustomListView.EndUpdate(const ALV: TCustomListView);
1767var
1768  QtWidget: TQtWidget;
1769begin
1770  if not WSCheckHandleAllocated(ALV, 'EndUpdate') then
1771    Exit;
1772  QtWidget := TQtWidget(ALV.Handle);
1773  QtWidget.EndUpdate;
1774  if not QtWidget.InUpdate then
1775    QtWidget.setUpdatesEnabled(True);
1776end;
1777
1778{------------------------------------------------------------------------------
1779  Method: TQtWSCustomListView.GetFocused
1780  Params:  None
1781  Returns: Nothing
1782 ------------------------------------------------------------------------------}
1783class function TQtWSCustomListView.GetFocused(const ALV: TCustomListView): Integer;
1784var
1785  QtListWidget: TQtListWidget;
1786  LWI: QListWidgetItemH;
1787  QtTreeWidget: TQtTreeWidget;
1788  TWI: QTreeWidgetItemH;
1789  i: Integer;
1790begin
1791  if not WSCheckHandleAllocated(ALV, 'GetFocused') then
1792    Exit(-1);
1793
1794  if IsIconView(ALV) then
1795  begin
1796    QtListWidget := TQtListWidget(ALV.Handle);
1797    LWI := QtListWidget.currentItem;
1798    if QtListWidget.getItemSelected(LWI) then
1799      Result := QtListWidget.getRow(LWI)
1800    else
1801      Result := -1;
1802  end else
1803  begin
1804    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1805    TWI := QtTreeWidget.currentItem;
1806    i := QtTreeWidget.getRow(TWI);
1807    if QTreeWidgetItem_isSelected(TWI) then
1808      Result := i
1809    else
1810      Result := -1;
1811  end;
1812end;
1813
1814class function TQtWSCustomListView.GetHitTestInfoAt(const ALV: TCustomListView;
1815  X, Y: Integer): THitTests;
1816var
1817  I, AImgListWidth, Ax: Integer;
1818  QtListWidget: TQtListWidget;
1819  QtTreeWidget: TQtTreeWidget;
1820  LWI: QListWidgetItemH;
1821  TWI: QTreeWidgetItemH;
1822  AImgList: TCustomImageList;
1823  AImgListRes: TScaledImageListResolution;
1824  AListSpacing, AFocusFrame: integer;
1825begin
1826  Result := [];
1827  if not WSCheckHandleAllocated(ALV, 'GetHitTestInfoAt') then
1828    Exit;
1829  I := GetItemAt(ALV, x, y);
1830  AFocusFrame := 2;
1831  AListSpacing := 4; {default, we are using pixelMetric() for real spacing}
1832  AX := 0;
1833  if I >= 0 then
1834  begin
1835    Include(Result, htOnItem);
1836    if Assigned(TCustomListViewHack(ALV).LargeImages) or Assigned(TCustomListViewHack(ALV).SmallImages) or
1837      Assigned(TCustomListViewHack(ALV).StateImages) then
1838    begin
1839
1840      if IsIconView(ALV) then
1841      begin
1842        QtListWidget := TQtListWidget(ALV.Handle);
1843        LWI := QtListWidget.getItem(I);
1844        AFocusFrame := QStyle_pixelMetric(QApplication_style(), QStylePM_FocusFrameHMargin, nil, QtListWidget.Widget);
1845        AListSpacing := QStyle_pixelMetric(QApplication_style(), QStylePM_CheckBoxLabelSpacing, nil, QtListWidget.Widget);
1846        // AItemRect := QtListWidget.getVisualItemRect(LWI);
1847      end else
1848      begin
1849        QtTreeWidget := TQtTreeWidget(ALV.Handle);
1850        TWI := QtTreeWidget.topLevelItem(I);
1851        AFocusFrame := QStyle_pixelMetric(QApplication_style(), QStylePM_FocusFrameHMargin, nil, QtTreeWidget.Widget);
1852        AListSpacing := QStyle_pixelMetric(QApplication_style(), QStylePM_CheckBoxLabelSpacing, nil, QtTreeWidget.Widget);
1853        // AItemRect := QtTreeWidget.visualItemRect(TWI);
1854      end;
1855
1856      if Assigned(TCustomListViewHack(ALV).StateImages) and (ALV.Items[I].StateIndex >= 0) then
1857      begin
1858        if Assigned(TWI) or Assigned(LWI) then
1859        begin
1860          AImgList := TCustomListViewHack(ALV).StateImages;
1861          AImgListWidth := TCustomListViewHack(ALV).StateImagesWidth;
1862          AImgListRes := AImgList.ResolutionForControl[AImgListWidth, ALV];
1863          if AImgListRes.Valid then
1864          begin
1865            if (x >= AListSpacing) and (x <= AImgListRes.Width + AFocusFrame) then
1866              include(Result, htOnStateIcon);
1867            Ax += AImgListRes.Width + AListSpacing;
1868          end;
1869        end;
1870      end;
1871
1872      if Assigned(TCustomListViewHack(ALV).SmallImages) and (ALV.Items[I].ImageIndex >= 0) then
1873      begin
1874        if Assigned(TWI) or Assigned(LWI) then
1875        begin
1876          AImgList := TCustomListViewHack(ALV).SmallImages;
1877          AImgListWidth := TCustomListViewHack(ALV).SmallImagesWidth;
1878          AImgListRes := AImgList.ResolutionForControl[AImgListWidth, ALV];
1879
1880          if AImgListRes.Valid and (x >= AListSpacing) and (x <= AImgListRes.Width + AFocusFrame) then
1881          begin
1882            include(Result, htOnIcon);
1883            Ax += AImgListRes.Width + AListSpacing;
1884          end;
1885        end;
1886      end else
1887
1888      if Assigned(TCustomListViewHack(ALV).LargeImages) and (ALV.Items[I].ImageIndex >= 0) then
1889      begin
1890        if Assigned(TWI) or Assigned(LWI) then
1891        begin
1892          AImgList := TCustomListViewHack(ALV).LargeImages;
1893          AImgListWidth := TCustomListViewHack(ALV).LargeImagesWidth;
1894          AImgListRes := AImgList.ResolutionForControl[AImgListWidth, ALV];
1895
1896          if AImgListRes.Valid and (x >= AListSpacing) and (x <= AImgListRes.Width + AFocusFrame) then
1897          begin
1898            include(Result, htOnIcon);
1899            Ax += AImgListRes.Width + AListSpacing;
1900          end;
1901        end;
1902      end;
1903
1904      if [htOnIcon, htOnStateIcon] * Result = [] then
1905      begin
1906        if x >= (AX + AFocusFrame) then
1907          include(Result, htOnLabel);
1908      end;
1909    end;
1910  end else
1911  begin
1912    if PtInRect(ALV.ClientRect, Point(x, y)) then
1913      Result := [THitTest.htNowhere];
1914  end;
1915end;
1916
1917{------------------------------------------------------------------------------
1918  Method: TQtWSCustomListView.GetItemAt
1919  Params:  None
1920  Returns: Nothing
1921 ------------------------------------------------------------------------------}
1922class function TQtWSCustomListView.GetItemAt(const ALV: TCustomListView; x,y: integer): Integer;
1923var
1924  QtListWidget: TQtListWidget;
1925  LWI: QListWidgetItemH;
1926  QtTreeWidget: TQtTreeWidget;
1927  TWI: QTreeWidgetItemH;
1928begin
1929  if not WSCheckHandleAllocated(ALV, 'GetItemAt') then
1930    Exit(-1);
1931  if IsIconView(ALV) then
1932  begin
1933    QtListWidget := TQtListWidget(ALV.Handle);
1934    LWI := QtListWidget.itemAt(x, y);
1935    Result := QtListWidget.getRow(LWI);
1936  end else
1937  begin
1938    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1939    TWI := QtTreeWidget.itemAt(x, y);
1940    Result := QtTreeWidget.getRow(TWI);
1941  end;
1942end;
1943
1944{------------------------------------------------------------------------------
1945  Method: TQtWSCustomListView.GetSelCount
1946  Params:  None
1947  Returns: Nothing
1948 ------------------------------------------------------------------------------}
1949class function TQtWSCustomListView.GetSelCount(const ALV: TCustomListView): Integer;
1950begin
1951  if not WSCheckHandleAllocated(ALV, 'GetSelCount') then
1952    Exit(-1);
1953  if IsIconView(ALV) then
1954    Result := TQtListWidget(ALV.Handle).getSelCount
1955  else
1956    Result := TQtTreeWidget(ALV.Handle).selCount;
1957end;
1958
1959{------------------------------------------------------------------------------
1960  Method: TQtWSCustomListView.GetSelection
1961  Params:  None
1962  Returns: Nothing
1963 ------------------------------------------------------------------------------}
1964class function TQtWSCustomListView.GetSelection(const ALV: TCustomListView): Integer;
1965var
1966  QtListWidget: TQtListWidget;
1967  QtTreeWidget: TQtTreeWidget;
1968  FPInts: TPtrIntArray;
1969begin
1970  if not WSCheckHandleAllocated(ALV, 'GetSelection') then
1971    Exit(-1);
1972  if IsIconView(ALV) then
1973  begin
1974    QtListWidget := TQtListWidget(ALV.Handle);
1975    FPInts := QtListWidget.selectedItems;
1976  end else
1977  begin
1978    {implement selection event so we can return Alv.Selected.Index}
1979    QtTreeWidget := TQtTreeWidget(ALV.Handle);
1980    FPInts := QtTreeWidget.selectedItems;
1981  end;
1982  if Length(FPInts)>0 then
1983    Result := FPInts[0]
1984  else
1985    Result := -1;
1986end;
1987
1988class function TQtWSCustomListView.GetTopItem(const ALV: TCustomListView): Integer;
1989var
1990  QtItemView: TQtAbstractItemView;
1991begin
1992  Result := -1;
1993  if not WSCheckHandleAllocated(ALV, 'GetTopItem') then
1994    Exit;
1995  // according to embarcadero docs this should return
1996  // only for vsList and vsReport
1997  if not (TCustomListViewHack(ALV).ViewStyle in [vsList, vsReport]) then
1998    exit;
1999  QtItemView := TQtAbstractItemView(ALV.Handle);
2000  Result := QtItemView.getTopItem;
2001end;
2002
2003
2004{------------------------------------------------------------------------------
2005  Method: TQtWSCustomListView.InternalUpdateItems
2006  Params:  TCustomListView
2007  Returns: Nothing
2008  Sync TCustomListView with QTreeWidget items.
2009 ------------------------------------------------------------------------------}
2010class procedure TQtWSCustomListView.InternalUpdateItems(
2011  const AList: TCustomListView);
2012var
2013  QtTreeWidget: TQtTreeWidget;
2014  i, j: Integer;
2015  AItem: TListItem;
2016  Str: WideString;
2017  Item: QTreeWidgetItemH;
2018  AAlignment: QtAlignment;
2019  Bmp: TBitmap;
2020  ImgListRes: TScaledImageListResolution;
2021begin
2022  QtTreeWidget := TQtTreeWidget(AList.Handle);
2023
2024  GetCurrentImages(AList, ImgListRes);
2025
2026  BeginUpdate(AList);
2027  try
2028    for i := 0 to AList.Items.Count - 1 do
2029    begin
2030      AItem := AList.Items[i];
2031      Str := AItem{%H-}.Caption;
2032      Item := QtTreeWidget.topLevelItem(i);
2033      QtTreeWidget.setItemText(Item, 0, Str, AlignmentToQtAlignmentMap[AList.Column[0].Alignment]);
2034      QtTreeWidget.setItemData(Item, 0, AItem);
2035      if AList.Checkboxes then
2036      begin
2037        if AItem.Checked then
2038          QTreeWidgetItem_setCheckState(Item, 0, QtChecked)
2039        else
2040          QTreeWidgetItem_setCheckState(Item, 0, QtUnChecked);
2041      end;
2042
2043      if ImgListRes.Valid and (ImgListRes.Count > 0) and
2044        ((AItem.ImageIndex >= 0) and (AItem.ImageIndex < ImgListRes.Count)) then
2045      begin
2046        Bmp := TBitmap.Create;
2047        try
2048          ImgListRes.GetBitmap(AItem.ImageIndex, Bmp);
2049          QTreeWidgetItem_setIcon(Item, 0, TQtImage(Bmp.Handle).AsIcon);
2050        finally
2051          Bmp.Free;
2052        end;
2053      end else
2054        QTreeWidgetItem_setIcon(Item, 0, nil);
2055
2056      // subitems
2057      for j := 0 to AItem.SubItems.Count - 1 do
2058      begin
2059        AAlignment := QtAlignLeft;
2060        if (TCustomListViewHack(AList).Columns.Count > 0) and (j + 1 < TCustomListViewHack(AList).Columns.Count) then
2061          AAlignment := AlignmentToQtAlignmentMap[TCustomListViewHack(AList).Column[j + 1].Alignment];
2062        Str := AItem{%H-}.Subitems.Strings[j];
2063        QtTreeWidget.setItemText(Item, j + 1, Str, AAlignment);
2064        QtTreeWidget.setItemData(Item, j + 1, AItem);
2065      end;
2066    end;
2067
2068  finally
2069    EndUpdate(AList);
2070  end;
2071end;
2072
2073class procedure TQtWSCustomListView.GetCurrentImages(
2074  const ALV: TCustomListView; out AImgListRes: TScaledImageListResolution);
2075var
2076  LV: TCustomListViewHack;
2077  AImgList: TCustomImageList;
2078  AImgListWidth: Integer;
2079begin
2080  LV := TCustomListViewHack(ALV);
2081  case LV.ViewStyle of
2082    vsIcon:
2083    begin
2084      AImgList := LV.LargeImages;
2085      AImgListWidth := LV.LargeImagesWidth;
2086    end;
2087    vsSmallIcon, vsReport, vsList:
2088    begin
2089      AImgList := LV.SmallImages;
2090      AImgListWidth := LV.SmallImagesWidth;
2091    end;
2092  else
2093    AImgList := nil;
2094    AImgListWidth := 0;
2095  end;
2096  if AImgList = nil then
2097  begin
2098    AImgList := LV.StateImages;
2099    AImgListWidth := LV.StateImagesWidth;
2100  end;
2101  if AImgList<>nil then
2102    AImgListRes := AImgList.ResolutionForControl[AImgListWidth, ALV]
2103  else
2104    AImgListRes := TScaledImageListResolution.Create(nil, 0);
2105end;
2106
2107{------------------------------------------------------------------------------
2108  Method: TQtWSCustomListView.SetSort
2109  Params:  None
2110  Returns: Nothing
2111 ------------------------------------------------------------------------------}
2112class procedure TQtWSCustomListView.SetSort(const ALV: TCustomListView;
2113  const AType: TSortType; const AColumn: Integer; const ASortDirection: TSortDirection);
2114var
2115  QtTreeWidget: TQtTreeWidget;
2116  {$IFDEF TEST_QT_SORTING}
2117  StdModel: QStandardItemModelH;
2118  {$ENDIF}
2119begin
2120  if not WSCheckHandleAllocated(ALV, 'SetSort') then
2121    Exit;
2122
2123  if (csDesigning in ALV.ComponentState) then
2124    exit;
2125
2126  if IsIconView(ALV) then
2127    exit;
2128
2129  QtTreeWidget := TQtTreeWidget(ALV.Handle);
2130
2131  if AType = stNone then
2132    QtTreeWidget.Header.SetSortIndicatorVisible(False)
2133  else
2134  begin
2135    {$IFDEF TEST_QT_SORTING}
2136    // QTreeWidget crashes sometimes on changing sort role (possible qt bug).
2137    // need deeper investigation.
2138    if QtTreeWidget.ItemCount > 0 then
2139    begin
2140      StdModel := QStandardItemModelH(QtTreeWidget.getModel);
2141      if QStandardItemModel_sortRole(StdModel) <> Ord(QtUserRole) then
2142        QStandardItemModel_setSortRole(StdModel, Ord(QtUserRole));
2143    end;
2144    {$ELSE}
2145    with QtTreeWidget do
2146    begin
2147      Header.SetSortIndicatorVisible(True);
2148      if (AColumn >= 0) and (AColumn < ColCount) then
2149      begin
2150        Header.SetSortIndicator(AColumn, QtSortOrder(Ord(ASortDirection)));
2151        if ItemCount > 0 then
2152          InternalUpdateItems(ALV);
2153      end;
2154    end;
2155    {$ENDIF}
2156  end;
2157end;
2158
2159
2160{------------------------------------------------------------------------------
2161  Method: TQtWSCustomListView.GetBoundingRect
2162  Params:  None
2163  Returns: Nothing
2164 ------------------------------------------------------------------------------}
2165class function TQtWSCustomListView.GetBoundingRect(const ALV: TCustomListView): TRect;
2166begin
2167  if not WSCheckHandleAllocated(ALV, 'GetBoundingRect') then
2168    Exit(Rect(0,0,0,0));
2169  Result := TQtWidget(ALV.Handle).getFrameGeometry;
2170end;
2171
2172class function TQtWSCustomListView.GetViewOrigin(const ALV: TCustomListView): TPoint;
2173var
2174  QtItemView: TQtAbstractItemView;
2175begin
2176  Result := Point(0, 0);
2177  if not WSCheckHandleAllocated(ALV, 'GetViewOrigin') then
2178    Exit;
2179  QtItemView := TQtAbstractItemView(ALV.Handle);
2180  Result := QtItemView.getViewOrigin;
2181end;
2182
2183class function TQtWSCustomListView.GetVisibleRowCount(const ALV: TCustomListView
2184  ): Integer;
2185begin
2186  Result := 0;
2187  if not WSCheckHandleAllocated(ALV, 'GetVisibleRowCount') then
2188    Exit;
2189  Result := TQtAbstractItemView(ALV.Handle).getVisibleRowCount;
2190end;
2191
2192class procedure TQtWSCustomListView.SelectAll(const ALV: TCustomListView;
2193  const AIsSet: Boolean);
2194begin
2195  if not WSCheckHandleAllocated(ALV, 'SelectAll') then
2196    Exit;
2197  if AIsSet then
2198    QAbstractItemView_selectAll(QAbstractItemViewH(TQtWidget(ALV.Handle).Widget))
2199  else
2200    QAbstractItemView_clearSelection(QAbstractItemViewH(TQtWidget(ALV.Handle).Widget));
2201end;
2202
2203class procedure TQtWSCustomListView.SetAllocBy(const ALV: TCustomListView;
2204  const AValue: Integer);
2205var
2206  QtList: TQtListWidget;
2207  NewValue: integer;
2208begin
2209  if not WSCheckHandleAllocated(ALV, 'SetAllocBy') then
2210    Exit;
2211  if TCustomListViewHack(ALV).ViewStyle <> vsReport then
2212  begin
2213    NewValue := AValue;
2214    if NewValue < 0 then
2215      NewValue := 0;
2216    QtList := TQtListWidget(ALV.Handle);
2217    if NewValue > 0 then
2218    begin
2219      QtList.setLayoutMode(QListViewBatched);
2220      QtList.BatchSize := NewValue;
2221    end else
2222      QtList.setLayoutMode(QListViewSinglePass);
2223  end;
2224end;
2225
2226class procedure TQtWSCustomListView.SetIconArrangement(
2227  const ALV: TCustomListView; const AValue: TIconArrangement);
2228var
2229  QtList: TQtListWidget;
2230begin
2231  if not WSCheckHandleAllocated(ALV, 'SetIconArrangement') then
2232    Exit;
2233  if IsIconView(ALV) then
2234  begin
2235    // hm...seem that QListView have bug, doesn't want to rearrange items
2236    // in any case when iaTop and AutoArrange=True (then it looks same as
2237    // iaLeft without arrange, so we must set GridSize in that case
2238    // update: bug is fixed in Qt-4.6.2
2239    {$note set workaround for QListView bug via QtList.GridSize}
2240    QtList := TQtListWidget(ALV.Handle);
2241    if QtList.ViewStyle <> Ord(vsList) then
2242      QtList.setViewFlow(IconArngToQListFlow[AValue]);
2243  end;
2244end;
2245
2246class procedure TQtWSCustomListView.SetImageList(const ALV: TCustomListView;
2247  const AList: TListViewImageList; const AValue: TCustomImageListResolution);
2248begin
2249  if not WSCheckHandleAllocated(ALV, 'SetImageList') then
2250    Exit;
2251  if not ALV.OwnerData then
2252    RecreateWnd(ALV);
2253end;
2254
2255class procedure TQtWSCustomListView.SetItemsCount(const ALV: TCustomListView;
2256  const Avalue: Integer);
2257var
2258  QtListWidget: TQtListWidget;
2259  QtTreeWidget: TQtTreeWidget;
2260begin
2261  if not WSCheckHandleAllocated(ALV, 'SetItemsCount') then
2262    Exit;
2263  if IsIconView(ALV) then
2264  begin
2265    QtListWidget := TQtListWidget(ALV.Handle);
2266    QtListWidget.ItemCount := AValue;
2267  end else
2268  begin
2269    QtTreeWidget := TQtTreeWidget(ALV.Handle);
2270    QtTreeWidget.ItemCount := AValue;
2271  end;
2272end;
2273
2274class procedure TQtWSCustomListView.SetOwnerData(const ALV: TCustomListView;
2275  const AValue: Boolean);
2276var
2277  QtItemView: TQtAbstractItemView;
2278begin
2279  if not WSCheckHandleAllocated(ALV, 'SetOwnerData') then
2280    Exit;
2281  QtItemView := TQtAbstractItemView(ALV.Handle);
2282  QtItemView.OwnerData := AValue;
2283end;
2284
2285class procedure TQtWSCustomListView.SetProperty(const ALV: TCustomListView;
2286  const AProp: TListViewProperty; const AIsSet: Boolean);
2287const
2288  BoolToSelectionMode: array[Boolean] of QAbstractItemViewSelectionMode =
2289  (
2290    QAbstractItemViewSingleSelection,
2291    QAbstractItemViewExtendedSelection
2292  );
2293  BoolToSelectionBehavior: array[Boolean] of QAbstractItemViewSelectionBehavior =
2294  (
2295    QAbstractItemViewSelectItems,
2296    QAbstractItemViewSelectRows
2297  );
2298  BoolToEditTriggers: array[Boolean] of QAbstractItemViewEditTriggers =
2299  (
2300    QAbstractItemViewNoEditTriggers, // QAbstractItemViewSelectedClicked,
2301    QAbstractItemViewNoEditTriggers
2302  );
2303var
2304  SavedCheckable: Boolean;
2305  QtItemView: TQtAbstractItemView;
2306begin
2307  if not WSCheckHandleAllocated(ALV, 'SetProperty')
2308  then Exit;
2309  QtItemView := TQtAbstractItemView(ALV.Handle);
2310  case AProp of
2311    lvpAutoArrange:
2312      begin
2313        if IsIconView(ALV) and
2314          (TQtListWidget(ALV.Handle).ViewStyle <> Ord(vsList)) then
2315          TQtListWidget(ALV.Handle).setWrapping(AIsSet);
2316      end;
2317    lvpCheckboxes:
2318      begin
2319        SavedCheckable := QtItemView.Checkable;
2320        QtItemView.Checkable := AIsSet;
2321        if SavedCheckable <> AIsSet then
2322          RecreateWnd(ALV);
2323      end;
2324    lvpMultiSelect:
2325      begin
2326        if (QtItemView.getSelectionMode <> QAbstractItemViewNoSelection) then
2327          QtItemView.setSelectionMode(BoolToSelectionMode[AIsSet]);
2328      end;
2329    lvpShowColumnHeaders:
2330      begin
2331        if not IsIconView(ALV) then
2332          with TQtTreeWidget(ALV.Handle) do
2333            setHeaderVisible(AIsSet and (TCustomListViewHack(ALV).ViewStyle = vsReport)
2334              and (TCustomListViewHack(ALV).Columns.Count > 0) );
2335      end;
2336    lvpOwnerDraw: ; // utilized automatically.
2337    lvpReadOnly: QtItemView.setEditTriggers(BoolToEditTriggers[AIsSet]);
2338    lvpRowSelect:
2339      begin
2340        if not IsIconView(ALV) then
2341          TQtTreeWidget(ALV.Handle).setAllColumnsShowFocus(AIsSet);
2342        QtItemView.setSelectionBehavior(BoolToSelectionBehavior[AIsSet]);
2343      end;
2344    lvpWrapText: QtItemView.setWordWrap(AIsSet);
2345    lvpHideSelection: QtItemView.HideSelection := AIsSet;
2346  end;
2347end;
2348
2349class procedure TQtWSCustomListView.SetProperties(const ALV: TCustomListView;
2350  const AProps: TListViewProperties);
2351var
2352  i: TListViewProperty;
2353begin
2354  if not WSCheckHandleAllocated(ALV, 'SetProperties')
2355  then Exit;
2356  for i := Low(TListViewProperty) to High(TListViewProperty) do
2357    SetProperty(ALV, i, i in AProps);
2358end;
2359
2360class procedure TQtWSCustomListView.SetScrollBars(const ALV: TCustomListView;
2361  const AValue: TScrollStyle);
2362var
2363  QtItemView: TQtAbstractItemView;
2364begin
2365  if not WSCheckHandleAllocated(ALV, 'SetScrollBars') then
2366    Exit;
2367  QtItemView := TQtAbstractItemView(ALV.Handle);
2368  {always reset before applying new TScrollStyle}
2369  QtItemView.setScrollStyle(ssNone);
2370  if AValue <> ssNone then
2371    QtItemView.setScrollStyle(AValue);
2372end;
2373
2374class procedure TQtWSCustomListView.SetViewStyle(const ALV: TCustomListView;
2375  const Avalue: TViewStyle);
2376var
2377  QtItemView: TQtAbstractItemView;
2378  QtListWidget: TQtListWidget;
2379  LWI: QListWidgetItemH;
2380  QtTreeWidget: TQtTreeWidget;
2381  ItemViewWidget: QAbstractItemViewH;
2382  Item: QTreeWidgetItemH;
2383  Size: TSize;
2384  x: Integer;
2385  j: Integer;
2386  ImgListRes: TScaledImageListResolution;
2387begin
2388  if not WSCheckHandleAllocated(ALV, 'SetViewStyle') then
2389    Exit;
2390  QtItemView := TQtAbstractItemView(ALV.Handle);
2391
2392  if (QtItemView.ViewStyle <> Ord(AValue)) then
2393  begin
2394    RecreateWnd(ALV);
2395    exit;
2396  end;
2397
2398  if IsIconView(ALV) then
2399  begin
2400    QtTreeWidget := Nil; // Suppress compiler warning.
2401    QtListWidget := TQtListWidget(ALV.Handle);
2402    ItemViewWidget := QListWidgetH(QtListWidget.Widget);
2403    QtListWidget.OwnerDrawn := False;
2404  end else
2405  begin
2406    QtListWidget := Nil; // Suppress compiler warning.
2407    QtTreeWidget := TQtTreeWidget(ALV.Handle);
2408    ItemViewWidget := QTreeWidgetH(QtTreeWidget.Widget);
2409    with QtTreeWidget do
2410      setHeaderVisible(TCustomListViewHack(ALV).ShowColumnHeaders and (AValue = vsReport)
2411        and (TCustomListViewHack(ALV).Columns.Count > 0) );
2412  end;
2413  GetCurrentImages(ALV, ImgListRes);
2414  if ImgListRes.Valid then
2415  begin
2416    Size.cy := ImgListRes.Height;
2417    Size.cx := ImgListRes.Width;
2418  end else
2419  begin
2420    case AValue of
2421      vsIcon: Size.cx := GetPixelMetric(QStylePM_IconViewIconSize, nil, ItemViewWidget);
2422      vsSmallIcon: Size.cx := GetPixelMetric(QStylePM_ListViewIconSize, nil, ItemViewWidget);
2423    else
2424      Size.cx := 0;
2425    end;
2426    Size.cy := Size.cx;
2427  end;
2428  if AValue in [vsList, vsReport] then
2429    TQtAbstractItemView(ALV.Handle).OwnerDrawn :=
2430      TCustomListViewHack(ALV).IsCustomDrawn(dtControl, cdPrePaint) or
2431      (TCustomListViewHack(ALV).OwnerDraw and
2432      (TCustomListViewHack(ALV).ViewStyle = vsReport));
2433  TQtAbstractItemView(ALV.Handle).IconSize := Size;
2434
2435  if IsIconView(ALV) then
2436  begin
2437    LWI := QtListWidget.getItem(0);
2438    if LWI <> nil then
2439    begin
2440      X := Size.CY;
2441      QListWidgetItem_sizeHint(LWI, @Size);
2442      Size.Cy := X;
2443      QListWidgetItem_setSizeHint(LWI, @Size);
2444    end;
2445  end else
2446  begin
2447    Item := QtTreeWidget.topLevelItem(0);
2448    if Item <> nil then
2449    begin
2450      X := Size.CY;
2451      QTreeWidgetItem_sizeHint(Item, @Size, 0);
2452      Size.Cy := X;
2453      QTreeWidgetItem_setSizeHint(Item, 0, @Size);
2454
2455      for j := 0 to QtTreeWidget.ColCount - 1 do
2456      begin
2457        Item := QtTreeWidget.itemAt(j, 0);
2458        QTreeWidgetItem_setSizeHint(Item, j, @Size);
2459      end;
2460    end;
2461    QtTreeWidget.UniformRowHeights := True;
2462  end;
2463end;
2464
2465end.
2466