1 {
2  *****************************************************************************
3  *                              QtWidgets.pas                                *
4  *                              --------------                               *
5  *                                                                           *
6  *                                                                           *
7  *****************************************************************************
8 
9  *****************************************************************************
10   This file is part of the Lazarus Component Library (LCL)
11 
12   See the file COPYING.modifiedLGPL.txt, included in this distribution,
13   for details about the license.
14  *****************************************************************************
15 }
16 unit qtwidgets;
17 
18 {$mode objfpc}{$H+}
19 
20 interface
21 
22 {$I qtdefines.inc}
23 
24 uses
25   // Bindings
26   qt5,
27   qtobjects, qtint,
28   // Free Pascal
29   Classes, SysUtils, Types,
30   // LCL
31   LCLType, LCLProc, LazUTF8, LCLIntf, LMessages, Graphics, Forms, Controls,
32   ComCtrls, ExtCtrls, StdCtrls, Menus, Dialogs, ImgList;
33 
34 type
35   // forward declarations
36   TQtListWidget = class;
37   TQtViewPort = class;
38 
39   TByteSet = set of byte;
40 
41   {Used to know if our widget is part of some complex widget.
42    Only for TQtWidgets created by CreateFrom & attach it's events.
43    For now only combobox added for it's lineedit but not for droplist
44    which doesn't attach it's event filter.
45    We'll need it later for TQtScrollBar and probably TQtTabWidget}
46   TChildOfComplexWidget = (ccwNone,
47                           ccwComboBox,
48                           ccwTreeWidget,
49                           ccwAbstractScrollArea,
50                           ccwCustomControl,
51                           ccwScrollingWinControl,
52                           ccwScrollingWindow,
53                           ccwTabWidget,
54                           ccwTTabControl);
55 
56   TQtGroupBoxType = (tgbtNormal,
57                    tgbtCheckGroup,
58                    tgbtRadioGroup);
59 
60   {state is setted up only when LCL is doing changes.}
61   TQtWidgetState = (qtwsColorUpdating, qtwsFontUpdating, qtwsSizeUpdating,
62     qtwsPositionUpdating, qtwsInsideRightMouseButtonPressEvent,
63     qtwsHiddenInsideRightMouseButtonPressEvent,
64     qtwsForceSendMove {mantis #34589 , LM_MOVE from ScrollWindowEx(SW_SCROLLCHILDREN)});
65 
66   TQtWidgetStates = set of TQtWidgetState;
67 
68   // records
69   TPaintData = record
70     PaintWidget: QWidgetH;
71     ClipRect: Prect;
72     ClipRegion: QRegionH;
73   end;
74 
75   // interfaces
76 
77   { IQtTextEdit }
78 
79   { IQtEdit }
80 
81   IQtEdit = interface
82     ['{035CA259-4442-4E82-9E70-96A114DD3BC6}']
getCursorPositionnull83     function getCursorPosition: TPoint;
getMaxLengthnull84     function getMaxLength: Integer;
getSelectionStartnull85     function getSelectionStart: Integer;
getSelectionLengthnull86     function getSelectionLength: Integer;
isUndoAvailablenull87     function isUndoAvailable: Boolean;
88     procedure setEchoMode(const AMode: QLineEditEchoMode);
89     procedure setMaxLength(const ALength: Integer);
90     procedure setReadOnly(const AReadOnly: Boolean);
91     procedure setSelection(const AStart, ALength: Integer);
92     procedure setBorder(const ABorder: Boolean);
93     procedure setCursorPosition(const ACursorPosition: Integer);
94     procedure setTextHint(const ATextHint: string);
95     procedure Cut;
96     procedure Copy;
97     procedure Paste;
98     procedure Undo;
99   end;
100 
101   // classes
102 
103   { TQtWidget }
104 
105   TQtWidget = class(TQtObject, IUnknown)
106   private
107     FInResizeEvent: boolean;
108     FWidgetState: TQtWidgetStates;
109     FWidgetDefaultFont: TQtFont;
110     FWidgetLCLFont: TQtFont;
111     FWidgetNeedFontColorInitialization: Boolean;
112     FChildOfComplexWidget: TChildOfComplexWidget;
113     FOwnWidget: Boolean;
114     FProps: TStringList;
115     FPaintData: TPaintData;
116     FCentralWidget: QWidgetH;
117     FContext: HDC;
118     FParams: TCreateParams;
119     FDefaultCursor: QCursorH;
120     FKeysToEat: TByteSet;
121     FText: WideString;
122     FHasCaret: Boolean;
123     FLastCaretPos: TQtPoint;
124     FHasPaint: Boolean;
125     FOwner: TQtWidget;
126 
127     FWidgetColorRole: QPaletteColorRole;
128     FTextColorRole: QPaletteColorRole;
129     FPalette: TQtWidgetPalette;
130 
131     {TQtWidget.scroll() info}
132     FScrollX: Integer;
133     FScrollY: Integer;
134 
GetPalettenull135     function GetPalette: TQtWidgetPalette;
GetPropsnull136     function GetProps(const AnIndex: String): pointer;
getScrolledOffsetnull137     function getScrolledOffset: TPoint;
GetStyleSheetnull138     function GetStyleSheet: WideString;
GetWidgetnull139     function GetWidget: QWidgetH;
LCLKeyToQtKeynull140     function LCLKeyToQtKey(AKey: Word): Integer;
QtButtonsToLCLButtonsnull141     function QtButtonsToLCLButtons(AButtons: QtMouseButton): PtrInt;
QtKeyModifiersToKeyStatenull142     function QtKeyModifiersToKeyState(AModifiers: QtKeyboardModifiers;
143       const AIsKeyEvent: Boolean;
144       AEvent: QKeyEventH = nil): PtrInt;
QtKeyToLCLKeynull145     function QtKeyToLCLKey(AKey: Integer; AText: WideString;
146       AEvent: QKeyEventH): Word;
147     procedure SetLastCaretPos(const AValue: TQtPoint);
148     procedure SetProps(const AnIndex: String; const AValue: pointer);
149     procedure SetStyleSheet(const AValue: WideString);
150     procedure SetWidget(const AValue: QWidgetH);
ShiftStateToQtModifiersnull151     function ShiftStateToQtModifiers(Shift: TShiftState): QtModifier;
152   protected
153     // IUnknown implementation
QueryInterfacenull154     function QueryInterface(constref iid: TGuid; out obj): LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
_AddRefnull155     function _AddRef: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
_Releasenull156     function _Release: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
GetContextnull157     function GetContext: HDC; virtual;
CreateWidgetnull158     function CreateWidget(const Params: TCreateParams):QWidgetH; virtual;
159     procedure DestroyWidget; virtual;
160     procedure SetHasCaret(const AValue: Boolean);
ProcessArrowKeysnull161     function ProcessArrowKeys: Boolean; virtual;
162 
163     class procedure removeProperty(AObject: QObjectH; APropName: PAnsiChar);
164     class procedure setProperty(AObject: QObjectH; APropName: PAnsiChar; APropValue: Int64);
165   public
166     LCLObject: TWinControl;
167   public
168     constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); virtual; overload;
169     constructor CreateFrom(const AWinControl: TWinControl; AWidget: QWidgetH); virtual;
170     procedure InitializeAccessibility; virtual;
171     procedure InitializeWidget; virtual;
172     procedure DeInitializeWidget; virtual;
173     procedure RecreateWidget;
174     procedure DestroyNotify(AWidget: TQtWidget); virtual;
175 
176     destructor Destroy; override;
GetContainerWidgetnull177     function GetContainerWidget: QWidgetH; virtual;
178     procedure Release; override;
179     procedure Destroyed; cdecl; override;
180   public
WinIDNeedednull181     function WinIDNeeded: boolean; virtual;
CanAdjustClientRectOnResizenull182     function CanAdjustClientRectOnResize: Boolean; virtual;
CanChangeFontColornull183     function CanChangeFontColor: Boolean; virtual;
CanSendLCLMessagenull184     function CanSendLCLMessage: Boolean;
CanPaintBackgroundnull185     function CanPaintBackground: Boolean; virtual;
186     {delays resize event of complex widgets or when LCLObject have caspComputingBounds in AutoSizePhases}
187     procedure DelayResizeEvent(AWidget: QWidgetH; ANewSize: TSize);
DeliverMessagenull188     function DeliverMessage(var Msg; const AIsInputEvent: Boolean = False): LRESULT; virtual;
EventFilternull189     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
getAcceptDropFilesnull190     function getAcceptDropFiles: Boolean; virtual;
191     {precise measure of text with widget''s current font when canvas.handle isn''t available}
measureTextnull192     function measureText(AText: WideString; AFlags: cardinal): TRect;
193     procedure SetNoMousePropagation(Sender: QWidgetH; const ANoMousePropagation: Boolean); virtual;
194     procedure SetLCLFont(AFont: TQtFont);
195     procedure SlotShow(vShow: Boolean); cdecl;
SlotClosenull196     function SlotClose: Boolean; cdecl; virtual;
197     procedure SlotDestroy; cdecl;
slotDropFilesnull198     function slotDropFiles(Sender: QObjectH; Event: QEventH): Boolean;
SlotHovernull199     function SlotHover(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotKeynull200     function SlotKey(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotInputMethodnull201     function SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotMousenull202     function SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; virtual; cdecl;
203     procedure SlotNCMouse(Sender: QObjectH; Event: QEventH); cdecl;
SlotMouseEnternull204     function SlotMouseEnter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotMouseMovenull205     function SlotMouseMove(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotMouseWheelnull206     function SlotMouseWheel(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
207     procedure SlotMove(Event: QEventH); cdecl;
208     procedure SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl; virtual;
209     procedure SlotPaint(Sender: QObjectH; Event: QEventH); cdecl; virtual;
210     procedure SlotResize(Event: QEventH); cdecl;
SlotContextMenunull211     function SlotContextMenu(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
212     procedure SlotWhatsThis(Sender: QObjectH; Event: QEventH); cdecl;
213     procedure SlotLCLMessage(Sender: QObjectH; Event: QEventH); cdecl;
214   public
215     procedure Activate; virtual;
216     procedure BringToFront;
217     procedure clearMask;
218     procedure OffsetMousePos(APoint: PQtPoint); virtual;
219     procedure Update(ARect: PRect = nil); virtual;
220     procedure UpdateRegion(ARgn: QRegionH); virtual;
221     procedure Repaint(ARect: PRect = nil); virtual;
222     procedure setWindowTitle(Str: PWideString);
223     procedure WindowTitle(Str: PWideString);
224     procedure Hide;
225     procedure Show;
226     procedure ShowNormal;
227     procedure ShowMinimized;
228     procedure ShowMaximized;
229     procedure ShowFullScreen;
getActionByIndexnull230     function getActionByIndex(AIndex: Integer): QActionH;
getAutoFillBackgroundnull231     function getAutoFillBackground: Boolean;
getClientBoundsnull232     function getClientBounds: TRect; virtual;
getClientOffsetnull233     function getClientOffset: TPoint; virtual;
getEnablednull234     function getEnabled: Boolean;
getFontnull235     function getFont: QFontH;
getFocusPolicynull236     function getFocusPolicy: QtFocusPolicy;
getFrameGeometrynull237     function getFrameGeometry: TRect; virtual;
getGeometrynull238     function getGeometry: TRect; virtual;
getLayoutDirectionnull239     function getLayoutDirection: QtLayoutDirection;
getVisiblenull240     function getVisible: Boolean; virtual;
getVisibleTonull241     function getVisibleTo(AWidget: QWidgetH): Boolean; virtual;
getOwnernull242     function getOwner: TQtWidget;
getParentnull243     function getParent: QWidgetH;
getPosnull244     function getPos: TQtPoint;
getFrameSizenull245     function getFrameSize: TSize; virtual;
getSizenull246     function getSize: TSize;
getTextnull247     function getText: WideString; virtual;
getTextStaticnull248     function getTextStatic: Boolean; virtual;
getHeightnull249     function getHeight: Integer;
getUpdatesEnablednull250     function getUpdatesEnabled: Boolean;
getWidthnull251     function getWidth: Integer;
getWindownull252     function getWindow: TQtWidget;
getWindowStatenull253     function getWindowState: QtWindowStates; {$IFDEF QTSCROLLABLEFORMS}virtual;{$ENDIF}
254     procedure grabMouse; virtual;
hasFocusnull255     function hasFocus: Boolean; virtual;
IsActiveWindownull256     function IsActiveWindow: Boolean;
isMinimizednull257     function isMinimized: Boolean;
isMaximizednull258     function isMaximized: Boolean;
IsFramedWidgetnull259     function IsFramedWidget: boolean; virtual;
isFullScreennull260     function isFullScreen: Boolean;
IsWindownull261     function IsWindow: Boolean;
262     procedure lowerWidget; virtual;
MapToGlobalnull263     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; virtual;
MapFromGlobalnull264     function MapFromGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; virtual;
265     procedure move(ANewLeft, ANewTop: Integer); virtual;
266     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); virtual;
267     procedure raiseWidget; virtual;
268     procedure stackUnder(AWidget: QWidgetH); virtual;
269     procedure frame_resize(ANewWidth, ANewHeight: Integer);
270     procedure Resize(ANewWidth, ANewHeight: Integer); virtual;
271     procedure releaseMouse;
272     procedure scroll(dx, dy: integer; ARect: PRect = nil); virtual;
273     procedure setAutoFillBackground(const AValue: Boolean);
274     procedure setAttribute(const Attr: QtWidgetAttribute; const TurnOn: Boolean = True);
275     procedure setBackgroundRole(const ARole: QPaletteColorRole);
276     procedure setDefaultColor(const DefaultColorType: TDefaultColorType);
277     procedure setColor(const Value: PQColor); virtual;
getContextMenuPolicynull278     function getContextMenuPolicy: QtContextMenuPolicy; virtual;
279     procedure setContextMenuPolicy(const AValue: QtContextMenuPolicy); virtual;
280     procedure setCursor(const ACursor: QCursorH); virtual;
281     procedure setDefaultColorRoles; virtual;
282     procedure setEnabled(p1: Boolean);
283     procedure setFocus;
284     procedure setFocusPolicy(const APolicy: QtFocusPolicy); virtual;
285     procedure setFocusProxy(const AWidget: QWidgetH);
286     procedure setFont(AFont: QFontH);
287     procedure setGeometry(ARect: TRect); virtual;
288     procedure setInitialFontColor(AControl: TWinControl); virtual;
289     procedure setLayoutDirection(ADirection: QtLayoutDirection);
290     procedure setMaximumSize(AWidth, AHeight: Integer);
291     procedure setMask(AMask: QBitmapH); overload;
292     procedure setMask(AMask: QRegionH); overload;
293     procedure setMinimumSize(AWidth, AHeight: Integer);
294     procedure setParent(parent: QWidgetH); virtual;
295     procedure setText(const W: WideString); virtual;
296     procedure setTextColor(const Value: PQColor); virtual;
297     procedure setVisible(AVisible: Boolean); virtual;
298     procedure setWindowFlags(_type: QtWindowFlags);
299     procedure setWindowIcon(AIcon: QIconH);
300     procedure setWindowModality(windowModality: QtWindowModality);
301     procedure setWindowOpacity(opacity: double);
302     procedure setWidth(p1: Integer);
303     procedure setHeight(p1: Integer);
304     procedure setUpdatesEnabled(const AEnabled: Boolean);
305     procedure setWindowState(AState: QtWindowStates);
306     procedure sizeHint(size: PSize);
testAttributenull307     function testAttribute(const AAttribute: QtWidgetAttribute): boolean;
windowFlagsnull308     function windowFlags: QtWindowFlags;
windowModalitynull309     function windowModality: QtWindowModality;
grabWindownull310     function grabWindow(const X, Y, Width, Height: integer; AWidget: QWidgetH=
311       nil): QPixmapH;
312     property ChildOfComplexWidget: TChildOfComplexWidget read FChildOfComplexWidget write FChildOfComplexWidget;
313     property Context: HDC read GetContext;
314     property HasCaret: Boolean read FHasCaret write SetHasCaret;
315     property HasPaint: Boolean read FHasPaint write FHasPaint;
316     property InResizeEvent: boolean read FInResizeEvent write FInResizeEvent;
317     property KeysToEat: TByteSet read FKeysToEat write FKeysToEat;
318     property LastCaretPos: TQtPoint read FLastCaretPos write SetLastCaretPos;
319     property ScrolledOffset: TPoint read getScrolledOffset;
320     property StyleSheet: WideString read GetStyleSheet write SetStyleSheet;
321     property PaintData: TPaintData read FPaintData write FPaintData;
322     property Palette: TQtWidgetPalette read GetPalette;
323     property Props[AnIndex:String]:pointer read GetProps write SetProps;
324     property TextColorRole: QPaletteColorRole read FTextColorRole write FTextColorRole;
325     property Widget: QWidgetH read GetWidget write SetWidget;
326     property WidgetColorRole: QPaletteColorRole read FWidgetColorRole write FWidgetColorRole;
327     property WidgetState: TQtWidgetStates read FWidgetState write FWidgetState;
328   end;
329 
330   { TQtAbstractSlider , inherited by TQtScrollBar, TQtTrackBar }
331 
332   TQtAbstractSlider = class(TQtWidget)
333   private
334     FSliderPressed: Boolean;
335     FSliderReleased: Boolean;
336     FRangeChangedHook: QAbstractSlider_hookH;
337     FSliderMovedHook:  QAbstractSlider_hookH;
338     FSliderPressedHook: QAbstractSlider_hookH;
339     FSliderReleasedHook: QAbstractSlider_hookH;
340     FValueChangedHook: QAbstractSlider_hookH;
341     FActionTriggeredHook: QAbstractSlider_hookH;
342   protected
CreateWidgetnull343     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
344   public
345     procedure AttachEvents; override;
346     procedure DetachEvents; override;
347 
348     procedure SlotSliderMoved(p1: Integer); cdecl; virtual;
349     procedure SlotValueChanged(p1: Integer); cdecl; virtual;
350     procedure SlotActionTriggered(action: Integer); cdecl; virtual;
351     procedure SlotRangeChanged(minimum: Integer; maximum: Integer); cdecl; virtual;
352     procedure SlotSliderPressed; cdecl;
353     procedure SlotSliderReleased; cdecl; virtual;
354   public
CanChangeFontColornull355     function CanChangeFontColor: Boolean; override;
getInvertedAppereancenull356     function getInvertedAppereance: Boolean;
getInvertedControlsnull357     function getInvertedControls: Boolean;
getOrientationnull358     function getOrientation: QtOrientation;
getValuenull359     function getValue: Integer;
getPageStepnull360     function getPageStep: Integer;
getMinnull361     function getMin: Integer;
getMaxnull362     function getMax: Integer;
getSingleStepnull363     function getSingleStep: Integer;
getSliderDownnull364     function getSliderDown: Boolean;
getSliderPositionnull365     function getSliderPosition: Integer;
getTrackingnull366     function getTracking: Boolean;
367 
368     procedure setInvertedAppereance(p1: Boolean); virtual;
369     procedure setInvertedControls(p1: Boolean); virtual;
370 
371     procedure setMaximum(p1: Integer); virtual;
372     procedure setMinimum(p1: Integer); virtual;
373 
374     procedure setOrientation(p1: QtOrientation); virtual;
375     procedure setPageStep(p1: Integer); virtual;
376     procedure setRange(minimum: Integer; maximum: Integer); virtual;
377     procedure setSingleStep(p1: Integer); virtual;
378     procedure setSliderDown(p1: Boolean); virtual;
379     procedure setSliderPosition(p1: Integer); virtual;
380     procedure setTracking(p1: Boolean); virtual;
381     procedure setValue(p1: Integer); virtual;
382     property SliderPressed: Boolean read FSliderPressed;
383     property SliderReleased: Boolean read FSliderReleased;
384   end;
385 
386   { TQtScrollBar }
387 
388   TQtScrollBar = class(TQtAbstractSlider)
389   private
390     FTrackPos: Integer;
391   protected
CreateWidgetnull392     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
393   public
394     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
395     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
396     procedure SlotSliderReleased; cdecl; override;
EventFilternull397     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
398     procedure AttachEvents; override;
399     property TrackPos: Integer read FTrackPos write FTrackPos;
400   end;
401 
402   { TQtFrame }
403 
404   TQtFrame = class(TQtWidget)
405   private
406   protected
CreateWidgetnull407     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
408   public
CanPaintBackgroundnull409     function CanPaintBackground: Boolean; override;
410     procedure SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl; override;
411     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
412     procedure setFrameStyle(p1: Integer);
413     procedure setFrameShape(p1: QFrameShape);
414     procedure setFrameShadow(p1: QFrameShadow);
415   end;
416 
417   { TQtAbstractScrollArea }
418 
419   TQtAbstractScrollArea = class(TQtFrame)
420   private
getScrollBarsPolicynull421     function getScrollBarsPolicy(AIndex: Boolean): QtScrollBarPolicy;
422   protected
423     FHScrollbar: TQtScrollBar;
424     FVScrollbar: TQtScrollbar;
425     procedure setScrollBarPolicy(AIndex: Boolean;
426       const AValue: QtScrollBarPolicy);
427   public
EventFilternull428     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
429     procedure grabMouse; override;
GetContainerWidgetnull430     function GetContainerWidget: QWidgetH; override;
getClientOffsetnull431     function getClientOffset: TPoint; override;
getClientBoundsnull432     function getClientBounds: TRect; override;
getScrollFrameOffsetnull433     function getScrollFrameOffset: Integer;
getViewOriginnull434     function getViewOrigin: TPoint;
viewportWidgetnull435     function viewportWidget: QWidgetH;
horizontalScrollBarnull436     function horizontalScrollBar: TQtScrollBar;
437     procedure InitializeAccessibility; override;
verticalScrollBarnull438     function verticalScrollBar: TQtScrollBar;
439     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
440     procedure setHorizontalScrollBar(AScrollBar: TQtScrollBar);
441     procedure setVerticalScrollBar(AScrollBar: TQtScrollBar);
442     procedure setScrollStyle(AScrollStyle: TScrollStyle);
443     procedure SetNoMousePropagation(Sender: QWidgetH; const ANoMousePropagation: Boolean); override;
444     procedure DestroyNotify(AWidget: TQtWidget); override;
445     destructor Destroy; override;
446     procedure Update(ARect: PRect = nil); override;
447     procedure UpdateRegion(ARgn: QRegionH); override;
448     procedure Repaint(ARect: PRect = nil); override;
449     property ScrollBarPolicy[AIndex: Boolean]: QtScrollBarPolicy read getScrollBarsPolicy write setScrollBarPolicy;
450   end;
451 
452   { TQtCustomControl }
453 
454   TQtCustomControl = class(TQtAbstractScrollArea)
455   private
456     FCornerWidget: TQtWidget;
457     FViewPortWidget: TQtViewPort;
458   protected
CreateWidgetnull459     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
ProcessArrowKeysnull460     function ProcessArrowKeys: Boolean; override;
461   public
462     destructor Destroy; override;
EventFilternull463     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
464     procedure ViewPortEventFilter(event: QEventH; retval: PBoolean); cdecl;
465     procedure Destroyed; cdecl; override;
466     procedure DestroyNotify(AWidget: TQtWidget); override;
467   public
CanAdjustClientRectOnResizenull468     function CanAdjustClientRectOnResize: Boolean; override;
cornerWidgetnull469     function cornerWidget: TQtWidget;
470     procedure InitializeAccessibility; override;
MapToGlobalnull471     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
MapFromGlobalnull472     function MapFromGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
viewportnull473     function viewport: TQtViewPort;
474     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); override;
475     procedure setCornerWidget(AWidget: TQtWidget);
476     procedure setCursor(const ACursor: QCursorH); override;
477     procedure setViewport(const AViewPort: QWidgetH);
478     procedure setVisible(AVisible: Boolean); override;
479     procedure viewportNeeded; virtual;
480     procedure viewportDelete; virtual;
481   end;
482 
483   { TQtViewPort }
484 
485   TQtViewPort = class(TQtWidget)
486   private
487     {when our viewport is invisible then we must keep track of scrolling. issue #29239}
488     FInvisibleX: integer;
489     FInvisibleY: integer;
490   public
CanPaintBackgroundnull491     function CanPaintBackground: Boolean; override;
EventFilternull492     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
493     procedure InitializeWidget; override;
494     procedure scroll(dx, dy: integer; ARect: PRect = nil); override;
495     procedure stackUnder(AWidget: QWidgetH); override;
496   end;
497 
498   { TQtGraphicView }
499 
500   TQtGraphicsView = class(TQtAbstractScrollArea)
501   protected
CreateWidgetnull502     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
503   end;
504 
505   { TQtArrow }
506 
507   TQtArrow = class(TQtFrame)
508   protected
CreateWidgetnull509     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
510   public
511     ArrowType: Integer;
512   end;
513 
514   { TQtAbstractButton }
515 
516   TQtAbstractButton = class(TQtWidget)
517   protected
ProcessArrowKeysnull518     function ProcessArrowKeys: Boolean; override;
519   public
CanPaintBackgroundnull520     function CanPaintBackground: Boolean; override;
getIconSizenull521     function getIconSize: TSize; virtual;
getTextnull522     function getText: WideString; override;
523     procedure setIcon(AIcon: QIconH); virtual;
524     procedure setIconSize(Size: PSize); virtual;
525     procedure setShortcut(AShortCutK1, AShortCutK2: TShortcut);
526     procedure setText(const W: WideString); override;
527     procedure Toggle;
isCheckednull528     function isChecked: Boolean;
isDownnull529     function isDown: Boolean;
530     procedure setCheckable(p1: Boolean);
531     procedure setChecked(p1: Boolean);
532     procedure setDefaultColorRoles; override;
533     procedure setDown(p1: Boolean);
534     procedure SignalPressed; cdecl;
535     procedure SignalReleased; cdecl;
536     procedure SignalClicked({%H-}Checked: Boolean = False); cdecl;
537     procedure SignalClicked2; cdecl;
538   end;
539 
540   { TQtPushButton }
541 
542   TQtPushButton = class(TQtAbstractButton)
543   private
544     FClickedHook: QAbstractButton_hookH;
545     FToggledHook: QAbstractButton_hookH;
546   protected
CreateWidgetnull547     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
548   public
549     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
550   public
551     procedure SetDefault(const ADefault: Boolean);
552     procedure AttachEvents; override;
553     procedure DetachEvents; override;
554     procedure SlotClicked; cdecl; virtual;
555     procedure SlotToggled({%H-}AChecked: Boolean); cdecl; virtual;
556   end;
557 
558   { TQtBitBtn }
559 
560   TQtBitBtn = class(TQtPushButton)
561   private
562     FGlyphLayout: Integer;
563     FIcon: QIconH;
564     FIconSize: TSize;
565   protected
CreateWidgetnull566     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
567   public
568     destructor Destroy; override;
EventFilternull569     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
570     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
571 
getIconSizenull572     function getIconSize: TSize; override;
getTextnull573     function getText: WideString; override;
574     procedure setIcon(AIcon: QIconH); override;
575     procedure setIconSize(Size: PSize); override;
576     procedure setText(const W: WideString); override;
577 
578     property GlyphLayout: Integer read FGlyphLayout write FGlyphLayout;
579   end;
580 
581   { TQtToggleBox }
582 
583   TQtToggleBox = class(TQtPushButton)
584   public
585     procedure SlotClicked; cdecl; override;
586     procedure SlotToggled({%H-}AChecked: Boolean); cdecl; override;
587   end;
588 
589   { TQtMainWindow }
590 
591   TQtMenuBar = class;
592   TQtToolBar = class;
593   TQtStatusBar = class;
594 
595   { TQtMDIArea }
596 
597   TQtMDIArea = class(TQtAbstractScrollArea)
598   private
599     FViewPortEventHook: QObject_hookH;
600     FSubWindowActivationHook: QMdiArea_hookH;
601     procedure SubWindowActivated(AWindow: QMDISubWindowH); cdecl;
602   protected
ScrollViewEventFilternull603     function ScrollViewEventFilter(Sender: QObjectH; Event: QEventH): boolean; cdecl;
604   public
605     constructor Create(const AParent: QWidgetH); overload;
606     destructor Destroy; override;
getClientOffsetnull607     function getClientOffset: TPoint; override;
EventFilternull608     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
609     procedure AttachEvents; override;
610     procedure DetachEvents; override;
ActiveSubWindownull611     function ActiveSubWindow: QMdiSubWindowH;
612     procedure ActivateSubWindow(AMdiWindow: QMdiSubWindowH);
613   end;
614 
615   {$IFDEF QTSCROLLABLEFORMS}
616   { TQtWindowArea }
617 
618   {Scrollbars on qt forms}
619   TQtWindowArea = class(TQtAbstractScrollArea)
620   private
621     FViewPortEventHook: QObject_hookH;
622   public
623     procedure AttachEvents; override;
CanAdjustClientRectOnResizenull624     function CanAdjustClientRectOnResize: Boolean; override;
625     procedure DetachEvents; override;
MapToGlobalnull626     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
627     procedure scroll(dx, dy: integer; ARect: PRect = nil); override;
628     {abstractscrollarea events}
EventFilternull629     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
630     {viewport events}
ScrollViewEventFilternull631     function ScrollViewEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
getWindowStatenull632     function getWindowState: QtWindowStates; override;
633   end;
634   {$ENDIF}
635 
636   TQtMainWindow = class(TQtWidget)
637   private
638     FBlocked: Boolean;
639     FFirstPaintEvent: boolean;
640     FIsFrameWindow: Boolean;
641     LayoutWidget: QBoxLayoutH;
642     FCWEventHook: QObject_hookH;
643     FShowOnTaskBar: Boolean;
644     FPopupParent: QWidgetH;
645     FMDIStateHook: QMdiSubWindow_hookH;
646   protected
CreateWidgetnull647     function CreateWidget(const {%H-}AParams: TCreateParams):QWidgetH; override;
648     procedure ChangeParent(NewParent: QWidgetH);
649     procedure UpdateParent;
650   public
651     QtFormBorderStyle: Integer;
652     QtFormStyle: Integer;
653     IsMainForm: Boolean;
654     MDIAreaHandle: TQtMDIArea; // valid only if we are fsMDIForm
655     MDIChildArea: TQtMDIArea; // valid only if we are fsMDIChild
656     MenuBar: TQtMenuBar;
657     ToolBar: TQtToolBar;
658     {$IFDEF QTSCROLLABLEFORMS}
659     ScrollArea: TQtWindowArea;
660     {$ENDIF}
661     destructor Destroy; override;
662 
663     procedure BeginUpdate; override;
664     procedure EndUpdate; override;
665 
666     procedure Activate; override;
CanAdjustClientRectOnResizenull667     function CanAdjustClientRectOnResize: Boolean; override;
getAcceptDropFilesnull668     function getAcceptDropFiles: Boolean; override;
GetContainerWidgetnull669     function GetContainerWidget: QWidgetH; override;
670     procedure grabMouse; override;
getClientBoundsnull671     function getClientBounds: TRect; override;
getClientOffsetnull672     function getClientOffset: TPoint; override;
673 
getTextnull674     function getText: WideString; override;
getTextStaticnull675     function getTextStatic: Boolean; override;
676 
MapToGlobalnull677     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
678 
679     procedure Update(ARect: PRect = nil); override;
680     procedure UpdateRegion(ARgn: QRegionH); override;
681     procedure Repaint(ARect: PRect = nil); override;
682 
683     procedure Resize(ANewWidth, ANewHeight: Integer); override;
684     procedure setText(const W: WideString); override;
685     procedure setMenuBar(AMenuBar: QMenuBarH);
EventFilternull686     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
687     procedure MDIChildWindowStateChanged(AOldState: QtWindowStates; ANewState: QtWindowStates); cdecl;
IsMdiChildnull688     function IsMdiChild: Boolean;
IsModalnull689     function IsModal: Boolean;
MdiChildCountnull690     function MdiChildCount: integer;
691     procedure OffsetMousePos(APoint: PQtPoint); override;
692     procedure setAcceptDropFiles(AValue: Boolean);
693     procedure setColor(const Value: PQColor); override;
694     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
695     procedure SlotActivateWindow(vActivate: Boolean); cdecl;
696     procedure slotWindowStateChange; cdecl;
697     procedure setShowInTaskBar(AValue: Boolean);
698     procedure setRealPopupParent(NewParent: QWidgetH);
699     property Blocked: Boolean read FBlocked write FBlocked;
700     property IsFrameWindow: Boolean read FIsFrameWindow write FIsFrameWindow; {check if our LCLObject is TCustomFrame}
701     property FirstPaintEvent: boolean read FFirstPaintEvent write FFirstPaintEvent; {only for x11 - if firstpaintevent arrived we are 100% sure that frame is 100% accurate}
702     property ShowOnTaskBar: Boolean read FShowOnTaskBar;
703   public
WinIDNeedednull704     function WinIDNeeded: boolean; override;
705     procedure AttachEvents; override;
706     procedure DetachEvents; override;
CWEventFilternull707     function CWEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
708   end;
709 
710   { TQtHintWindow }
711 
712   TQtHintWindow = class(TQtMainWindow)
713   private
714     FNeedRestoreVisible: Boolean;
715   protected
CreateWidgetnull716     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
717   public
WinIDNeedednull718     function WinIDNeeded: boolean; override;
719     procedure InitializeWidget; override;
720     procedure DeInitializeWidget; override;
CanPaintBackgroundnull721     function CanPaintBackground: Boolean; override;
722     procedure SetDefaultColorRoles; override;
723     procedure setVisible(AVisible: Boolean); override;
724     property NeedRestoreVisible: Boolean read FNeedRestoreVisible write FNeedRestoreVisible;
725   end;
726 
727   { TQtStaticText }
728 
729   TQtStaticText = class(TQtFrame)
730   private
GetWordWrapnull731     function GetWordWrap: Boolean;
732     procedure SetWordWrap(AValue: Boolean);
733   protected
CreateWidgetnull734     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
735   public
CanPaintBackgroundnull736     function CanPaintBackground: Boolean; override;
getTextnull737     function getText: WideString; override;
738     procedure setText(const W: WideString); override;
739     procedure setAlignment(const AAlignment: QtAlignment);
740     property WordWrap: Boolean read GetWordWrap write SetWordWrap;
741   end;
742 
743   { TQtCheckBox }
744 
745   TQtCheckBox = class(TQtAbstractButton)
746   private
747     FStateChangedHook : QCheckBox_hookH;
748   protected
CreateWidgetnull749     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
750   public
CheckStatenull751     function CheckState: QtCheckState;
752     procedure setCheckState(state: QtCheckState);
753     procedure setTriState(AAllowGrayed: Boolean);
754   public
755     procedure AttachEvents; override;
756     procedure DetachEvents; override;
757     procedure signalStateChanged(p1: Integer); cdecl;
758   end;
759 
760   { TQtRadioButton }
761 
762   TQtRadioButton = class(TQtAbstractButton)
763   private
764     FToggledHook: QAbstractButton_hookH;
765   protected
CreateWidgetnull766     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
767   public
768     procedure AttachEvents; override;
769     procedure DetachEvents; override;
770     procedure SignalToggled(Checked: Boolean); cdecl;
EventFilternull771     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
772   end;
773 
774   { TQtGroupBox }
775 
776   TQtGroupBox = class(TQtWidget)
777   private
778     FGroupBoxType: TQtGroupBoxType;
779     FCWEventHook: QObject_hookH;
GetCheckBoxStatenull780     function GetCheckBoxState: boolean;
GetCheckBoxVisiblenull781     function GetCheckBoxVisible: boolean;
782     procedure SetCheckBoxState(AValue: boolean);
783     procedure SetCheckBoxVisible(AValue: boolean);
784     procedure setLayoutThemeMargins(ALayout: QLayoutH; AWidget: QWidgetH);
785   protected
CreateWidgetnull786     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
787   public
788     procedure AttachEvents; override;
789     procedure DetachEvents; override;
CanPaintBackgroundnull790     function CanPaintBackground: Boolean; override;
EventFilternull791     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
getClientBoundsnull792     function getClientBounds: TRect; override;
getTextnull793     function getText: WideString; override;
794     procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
795       {%H-}WithThemeSpace: Boolean); override;
796     procedure setText(const W: WideString); override;
797     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
798     procedure Update(ARect: PRect = nil); override;
799     procedure UpdateRegion(ARgn: QRegionH); override;
800     procedure Repaint(ARect: PRect = nil); override;
801 
802     property GroupBoxType: TQtGroupBoxType read FGroupBoxType write FGroupBoxType;
803     property CheckBoxState: boolean read GetCheckBoxState write SetCheckBoxState;
804     property CheckBoxVisible: boolean read GetCheckBoxVisible write SetCheckBoxVisible;
805   end;
806 
807   { TQtToolBar }
808 
809   TQtToolBar = class(TQtWidget)
810   private
811   protected
CreateWidgetnull812     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
813   end;
814 
815   { TQtToolButton }
816 
817   TQtToolButton = class(TQtAbstractButton)
818   private
819   protected
CreateWidgetnull820     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
821   end;
822 
823   { TQtTrackBar }
824 
825   TQtTrackBar = class(TQtAbstractSlider)
826   protected
CreateWidgetnull827     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
828   public
getTickIntervalnull829     function getTickInterval: Integer;
830     procedure setTickPosition(Value: QSliderTickPosition);
831     procedure setTickInterval(Value: Integer);
832   public
833     procedure AttachEvents; override;
834 
835     procedure SlotSliderMoved(p1: Integer); cdecl; override;
836     procedure SlotValueChanged(p1: Integer); cdecl; override;
837   end;
838 
839   { TQtLineEdit }
840 
841   TQtLineEdit = class(TQtWidget, IQtEdit)
842   private
843     FCachedSelectionLen: integer;
844     FCachedSelectionStart: integer;
845     FNumbersOnly: boolean;
846     FIntValidator: QIntValidatorH;
847     FTextChanged: QLineEdit_hookH;
getTextMarginsnull848     function getTextMargins: TRect;
849     procedure SetNumbersOnly(AValue: boolean);
850     procedure setTextMargins(ARect: TRect);
851   protected
CreateWidgetnull852     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
853     procedure setTextHint(const ATextHint: string);
854   public
getAlignmentnull855     function getAlignment: QtAlignment;
getCursorPositionnull856     function getCursorPosition: TPoint;
getMaxLengthnull857     function getMaxLength: Integer;
getSelectedTextnull858     function getSelectedText: WideString;
getSelectionStartnull859     function getSelectionStart: Integer;
getSelectionLengthnull860     function getSelectionLength: Integer;
getTextnull861     function getText: WideString; override;
getTextStaticnull862     function getTextStatic: Boolean; override;
isUndoAvailablenull863     function isUndoAvailable: Boolean;
hasSelectedTextnull864     function hasSelectedText: Boolean;
865     procedure selectAll;
866     procedure setAlignment(const AAlignment: QtAlignment);
867     procedure setBorder(const ABorder: Boolean);
868     procedure setCursorPosition(const ACursorPosition: Integer);
869     procedure setDefaultColorRoles; override;
870     procedure setEchoMode(const AMode: QLineEditEchoMode);
871     procedure setInputMask(const AMask: WideString);
872     procedure setMaxLength(const ALength: Integer);
873     procedure setReadOnly(const AReadOnly: Boolean);
874     procedure setSelection(const AStart, ALength: Integer);
875     procedure setText(const AText: WideString); override;
876     procedure Cut;
877     procedure Copy;
878     procedure Paste;
879     procedure Undo;
880   public
881     destructor Destroy; override;
882     procedure AttachEvents; override;
883     procedure DetachEvents; override;
EventFilternull884     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
885     procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
886       {%H-}WithThemeSpace: Boolean); override;
887     procedure SignalTextChanged(p1: PWideString); cdecl;
888     property CachedSelectionStart: integer read FCachedSelectionStart write FCachedSelectionStart;
889     property CachedSelectionLen: integer read FCachedSelectionLen write FCachedSelectionLen;
890     property NumbersOnly: boolean read FNumbersOnly write SetNumbersOnly;
891     property TextMargins: TRect read GetTextMargins write SetTextMargins;
892   end;
893 
894   { TQtTextEdit }
895 
896   TQtTextEdit = class(TQtAbstractScrollArea, IQtEdit)
897   private
898     FViewportEventHook: QObject_hookH;
899     FUndoAvailableHook: QTextEdit_hookH;
900     FTextChangedHook: QTextEdit_hookH;
901     FUndoAvailable: Boolean;
GetAcceptRichTextnull902     function GetAcceptRichText: Boolean;
903     procedure SetAcceptRichText(AValue: Boolean);
904   protected
CreateWidgetnull905     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
906     procedure setTextHint(const ATextHint: string);
907   public
908     FList: TStrings;
909     procedure Append(const AStr: WideString);
910     procedure ClearText;
getAlignmentnull911     function getAlignment: QtAlignment;
getBlockCountnull912     function getBlockCount: Integer;
getCursorPositionnull913     function getCursorPosition: TPoint;
getMaxLengthnull914     function getMaxLength: Integer;
getTextnull915     function getText: WideString; override;
getTextStaticnull916     function getTextStatic: Boolean; override;
getSelectionStartnull917     function getSelectionStart: Integer;
getSelectionEndnull918     function getSelectionEnd: Integer;
getSelectionLengthnull919     function getSelectionLength: Integer;
920     procedure appendLine(AText: WideString);
921     procedure insertLine(const AIndex: integer; AText: WideString);
isUndoAvailablenull922     function isUndoAvailable: Boolean;
923     procedure removeLine(const AIndex: integer);
924     procedure setAlignment(const AAlignment: QtAlignment);
925     procedure setBorder(const ABorder: Boolean);
926     procedure setCursorPosition(const ACursorPosition: Integer);
927     procedure setDefaultColorRoles; override;
928     procedure setEchoMode(const AMode: QLineEditEchoMode);
929     procedure setLineWrapMode(const AMode: QTextEditLineWrapMode);
930     procedure setMaxLength(const ALength: Integer);
931     procedure setLineText(const AIndex: integer; AText: WideString);
932     procedure setText(const AText: WideString); override;
933     procedure setReadOnly(const AReadOnly: Boolean);
934     procedure setSelection(const AStart, ALength: Integer);
935     procedure setTabChangesFocus(const AValue: Boolean);
936     procedure Cut;
937     procedure Copy;
938     procedure Paste;
939     procedure Undo;
940   public
941     procedure AttachEvents; override;
942     procedure DetachEvents; override;
viewportEventFilternull943     function viewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
getContextMenuPolicynull944     function getContextMenuPolicy: QtContextMenuPolicy; override;
945     procedure setContextMenuPolicy(const AValue: QtContextMenuPolicy); override;
946     procedure SignalUndoAvailable(b: Boolean); cdecl;
947     procedure SignalTextChanged(); cdecl;
948     property AcceptRichText: Boolean read GetAcceptRichText write SetAcceptRichText;
949   end;
950 
951   { TQtTabBar }
952   TQtTabBar = class(TQtWidget)
953   private
954     FSavedIndexOnPageChanging: Integer; // used to handle OnPageChanging AllowChange param
955     FTabBarChangedHook: QTabBar_hookH;
956     FTabBarMovedHook: QTabBar_hookH;
957   public
958     procedure AttachEvents; override;
959     procedure DetachEvents; override;
GetTabRectnull960     function GetTabRect(const AIndex: integer): TRect;
961     // under some themes tabs doesn't start at 0,0 (eg. MacOSX)
962     function TabBarOffset: TPoint;
963     procedure SignalTabBarMoved(fromIndex: integer; toIndex: Integer); cdecl;
964     procedure SignalTabBarCurrentChanged(Index: Integer); cdecl;
965     function SlotTabBarMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
966     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
967     procedure SetTabFontColor(AIndex: Integer; AColor: TQColor);
968   end;
969 
970   { TQtTabWidget }
971 
972   TQtTabWidget = class(TQtWidget)
973   private
974     FCurrentChangedHook: QTabWidget_hookH;
975     FCloseRequestedHook: QTabWidget_hookH;
976     FStackedWidgetHook: QObject_hookH;
977     FSwitchTabsByKeyboard: boolean;
978     FTabBar: TQtTabBar;
979     FStackWidget: QWidgetH;
980     function getShowTabs: Boolean;
981     function getStackWidget: QWidgetH;
982     function getTabBar: TQtTabBar;
983     procedure setShowTabs(const AValue: Boolean);
984   protected
985     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
986   public
987     destructor Destroy; override;
988     procedure DestroyNotify(AWidget: TQtWidget); override;
989     procedure AttachEvents; override;
990     procedure DetachEvents; override;
991 
992     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
993     procedure SignalCurrentChanged(Index: Integer); cdecl;
994     procedure SignalCloseRequested(Index: Integer); cdecl;
995   public
996     function indexOf(const AWidget: QWidgetH): integer;
997     function insertTab(index: Integer; page: QWidgetH; p2: WideString): Integer; overload;
998     function insertTab(index: Integer; page: QWidgetH; icon: QIconH; p2: WideString): Integer; overload;
999     function getCount: Integer;
1000     function getClientBounds: TRect; override;
1001     function getCurrentIndex: Integer;
1002     function GetLCLPageIndex(AIndex: Integer): Integer;
1003     function getTabPosition: QTabWidgetTabPosition;
1004     procedure removeTab(AIndex: Integer);
1005     procedure setCurrentIndex(AIndex: Integer);
1006     procedure setCurrentWidget(APage: TQtWidget; const AIsMoved: Boolean);
1007     procedure setTabPosition(ATabPosition: QTabWidgetTabPosition);
1008     procedure setTabIcon(index: Integer; icon: QIconH);
1009     procedure setTabText(index: Integer; p2: WideString);
1010     procedure setTabsClosable(AValue: Boolean);
1011     function tabAt(APoint: TPoint): Integer;
1012 
1013     property ShowTabs: Boolean read getShowTabs write setShowTabs;
1014     property TabBar: TQtTabBar read getTabBar;
1015     property StackWidget: QWidgetH read getStackWidget;
1016     property SwitchTabsByKeyboard: boolean read FSwitchTabsByKeyboard write FSwitchTabsByKeyboard;
1017   end;
1018 
1019   { TQtComboBox }
1020 
1021   TQtComboBox = class(TQtWidget, IQtEdit)
1022   private
1023     FKeyEnterFix: boolean; {issue #31574}
1024     FMouseFixPos: TQtPoint;
1025     // hooks
1026     FChangeHook: QComboBox_hookH;
1027     FActivateHook: QComboBox_hookH;
1028     FOwnerDrawn: Boolean;
1029     FSelectHook: QComboBox_hookH;
1030     FDropListEventHook: QObject_hookH;
1031     // parts
1032     FLineEdit: TQtLineEdit;
1033     FDropList: TQtListWidget;
1034     FDropListVisibleInternal: Boolean;
1035     function GetDropList: TQtListWidget;
1036     function GetLineEdit: TQtLineEdit;
1037     procedure InternalIntfGetItems; // calls TCustomComboBox(LCLObject).IntfGetItems
1038     procedure SetOwnerDrawn(const AValue: Boolean);
1039     procedure slotPaintCombo(Sender: QObjectH; Event: QEventH); cdecl;
1040   protected
1041     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1042     // IQtEdit implementation
1043     function getCursorPosition: TPoint;
1044     function getMaxLength: Integer;
1045     function getSelectionStart: Integer;
1046     function getSelectionLength: Integer;
1047     function isUndoAvailable: Boolean;
1048     procedure setEchoMode(const AMode: QLineEditEchoMode);
1049     procedure setMaxLength(const ALength: Integer);
1050     procedure setReadOnly(const AReadOnly: Boolean);
1051     procedure setSelection(const AStart, ALength: Integer);
1052     procedure setCursorPosition(const ACursorPosition: Integer);
1053     procedure setTextHint(const ATextHint: string);
1054     procedure Cut;
1055     procedure Copy;
1056     procedure Paste;
1057     procedure Undo;
1058   public
1059     FList: TStrings;
1060     destructor Destroy; override;
1061     procedure DestroyNotify(AWidget: TQtWidget); override;
1062     procedure ClearItems;
1063     procedure setBorder(const ABorder: Boolean);
1064     function currentIndex: Integer;
1065     function findText(AText: WideString): Integer;
1066     function getDroppedDown: Boolean;
1067     function getEditable: Boolean;
1068     function getItemText(AIndex: Integer): WideString;
1069     function getMaxVisibleItems: Integer;
1070     function getText: WideString; override;
1071     function getTextStatic: Boolean; override;
1072     procedure insertItem(AIndex: Integer; AText: String); overload;
1073     procedure insertItem(AIndex: Integer; AText: PWideString); overload;
1074     procedure setCurrentIndex(index: Integer);
1075     procedure setDefaultColorRoles; override;
1076     procedure setDroppedDown(const ADroppedDown: Boolean);
1077     procedure setMaxVisibleItems(ACount: Integer);
1078     procedure setEditable(const AValue: Boolean);
1079     procedure setItemText(AIndex: Integer; AText: String);
1080     procedure setText(const W: WideString); override;
1081     procedure removeItem(AIndex: Integer);
1082 
1083     property DropList: TQtListWidget read GetDropList;
1084     property LineEdit: TQtLineEdit read GetLineEdit;
1085     property OwnerDrawn: Boolean read FOwnerDrawn write SetOwnerDrawn;
1086   public
1087     procedure AttachEvents; override;
1088     procedure DetachEvents; override;
1089     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1090     procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
1091       {%H-}WithThemeSpace: Boolean); override;
1092 
1093     procedure SlotActivate(index: Integer); cdecl;
1094     procedure SlotChange(p1: PWideString); cdecl;
1095     procedure SlotSelect(index: Integer); cdecl;
1096     procedure SlotDropListVisibility(AVisible: Boolean); cdecl;
1097     procedure FixMouseUp; // qt eats MouseRelease event when popup is shown, so we'll fix it
1098   end;
1099 
1100   { TQtAbstractSpinBox}
1101 
1102   TQtAbstractSpinBox = class(TQtWidget, IQtEdit)
1103   private
1104     {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
1105     FParentShowPassed: PtrInt;
1106     {$ENDIF}
1107     FEditingFinishedHook: QAbstractSpinBox_hookH;
1108     FLineEditHook: QObject_hookH;
1109     FTextChangedHook: QLineEdit_hookH;
1110     // parts
1111     FLineEdit: QLineEditH;
1112     FTextChangedByValueChanged: Boolean;
GetLineEditnull1113     function GetLineEdit: QLineEditH;
LineEditEventFilternull1114     function LineEditEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
1115   protected
CreateWidgetnull1116     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1117     // IQtEdit implementation
getCursorPositionnull1118     function getCursorPosition: TPoint;
getMaxLengthnull1119     function getMaxLength: Integer;
getSelectionStartnull1120     function getSelectionStart: Integer;
getSelectionLengthnull1121     function getSelectionLength: Integer;
isUndoAvailablenull1122     function isUndoAvailable: Boolean;
1123     procedure setEchoMode(const AMode: QLineEditEchoMode);
1124     procedure setMaxLength(const ALength: Integer);
1125     procedure setSelection(const AStart, ALength: Integer);
1126     procedure setCursorPosition(const ACursorPosition: Integer);
1127     procedure SignalLineEditTextChanged(AnonParam1: PWideString); virtual; cdecl;
1128     procedure setTextHint(const ATextHint: string);
1129     procedure Cut;
1130     procedure Copy;
1131     procedure Paste;
1132     procedure Undo;
1133     property TextChangedByValueChanged: Boolean read FTextChangedByValueChanged write FTextChangedByValueChanged;
1134   public
getValuenull1135     function getValue: Double; virtual; abstract;
getReadOnlynull1136     function getReadOnly: Boolean;
getTextnull1137     function getText: WideString; override;
getTextStaticnull1138     function getTextStatic: Boolean; override;
1139     procedure setAlignment(const AAlignment: QtAlignment);
1140     procedure setBorder(const ABorder: Boolean);
1141     procedure setDefaultColorRoles; override;
1142     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
1143     procedure setMinimum(const v: Double); virtual; abstract;
1144     procedure setMaximum(const v: Double); virtual; abstract;
1145     procedure setSingleStep(const v: Double); virtual; abstract;
1146     procedure setReadOnly(const r: Boolean);
1147     procedure setValue(const v: Double); virtual; abstract;
1148     procedure setText(const W: WideString); override;
1149 
1150     property LineEdit: QLineEditH read GetLineEdit;
1151   public
1152     procedure AttachEvents; override;
1153     procedure DetachEvents; override;
EventFilternull1154     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1155 
1156     procedure SignalEditingFinished; cdecl;
1157   end;
1158 
1159   { TQtFloatSpinBox }
1160 
1161   TQtFloatSpinBox = class(TQtAbstractSpinBox)
1162   private
1163     FValue: Double;
1164     FValueChangedHook: QDoubleSpinBox_hookH;
1165   protected
CreateWidgetnull1166     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1167   public
getValuenull1168     function getValue: Double; override;
1169     procedure setDecimals(const v: integer);
1170     procedure setMinimum(const v: Double); override;
1171     procedure setMaximum(const v: Double); override;
1172     procedure setSingleStep(const v: Double); override;
1173     procedure setValue(const v: Double); override;
1174   public
1175     procedure AttachEvents; override;
1176     procedure DetachEvents; override;
1177     procedure SignalValueChanged(p1: Double); cdecl;
1178   end;
1179 
1180   { TQtSpinBox }
1181 
1182   TQtSpinBox = class(TQtAbstractSpinBox)
1183   private
1184     FValue: Integer;
1185     FValueChangedHook: QSpinBox_hookH;
1186   protected
CreateWidgetnull1187     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1188   public
getValuenull1189     function getValue: Double; override;
1190     procedure setMinimum(const v: Double); override;
1191     procedure setMaximum(const v: Double); override;
1192     procedure setSingleStep(const v: Double); override;
1193     procedure setValue(const v: Double); override;
1194   public
1195     procedure AttachEvents; override;
1196     procedure DetachEvents; override;
1197 
1198     procedure SignalValueChanged(p1: Integer); cdecl;
1199   end;
1200 
1201   { TQtAbstractItemView }
1202 
1203   TQtAbstractItemView = class(TQtAbstractScrollArea)
1204   private
1205     FAllowGrayed: boolean;
1206     FSavedEvent: QMouseEventH;
1207     FSavedEventTimer: QTimerH;
1208     FSavedEventTimerHook: QTimer_hookH;
1209     FCheckable: boolean;
1210     FHideSelection: Boolean;
1211     FOldDelegate: QAbstractItemDelegateH;
1212     FNewDelegate: QLCLItemDelegateH;
1213     FOwnerData: Boolean;
1214     FSignalActivated: QAbstractItemView_hookH;
1215     FSignalClicked: QAbstractItemView_hookH;
1216     FSignalDoubleClicked: QAbstractItemView_hookH;
1217     FSignalEntered: QAbstractItemView_hookH;
1218     FSignalPressed: QAbstractItemView_hookH;
1219     FSignalViewportEntered: QAbstractItemView_hookH;
1220     FAbstractItemViewportEventHook: QObject_hookH;
1221     FSyncingItems: Boolean;
1222     FViewStyle: Integer;
getIconSizenull1223     function getIconSize: TSize;
GetOwnerDrawnnull1224     function GetOwnerDrawn: Boolean;
1225     procedure setIconSize(const AValue: TSize);
1226     procedure SetOwnerDrawn(const AValue: Boolean);
1227   protected
GetItemFlagsnull1228     function GetItemFlags(AIndex: Integer): QtItemFlags; virtual;
1229     procedure SetItemFlags(AIndex: Integer; AValue: QtItemFlags); virtual;
1230     procedure OwnerDataNeeded(ARect: TRect); virtual;
1231     procedure PostponedMouseRelease(AEvent: QEventH); virtual;
1232     procedure PostponedMouseReleaseTimerEvent(); cdecl; virtual;
1233   public
1234     constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); override;
1235     destructor Destroy; override;
1236     procedure signalActivated(index: QModelIndexH); cdecl; virtual;
1237     procedure signalClicked(index: QModelIndexH); cdecl; virtual;
1238     procedure signalDoubleClicked(index: QModelIndexH); cdecl; virtual;
1239     procedure signalEntered(index: QModelIndexH); cdecl; virtual;
1240     procedure signalPressed(index: QModelIndexH); cdecl; virtual;
1241     procedure signalViewportEntered; cdecl; virtual;
1242     procedure AttachEvents; override;
1243     procedure DetachEvents; override;
1244 
itemViewViewportEventFilternull1245     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; virtual;
1246     procedure setDefaultColorRoles; override;
1247   public
1248     procedure clearSelection; virtual;
getModelnull1249     function getModel: QAbstractItemModelH;
getRowHeightnull1250     function getRowHeight(ARowIndex: integer): integer;
getSelectionModenull1251     function getSelectionMode: QAbstractItemViewSelectionMode;
getTopItemnull1252     function getTopItem: integer; virtual;
getVisibleRowCountnull1253     function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; virtual;
1254 
1255     procedure modelIndex(retval: QModelIndexH; row, column: Integer; parent: QModelIndexH = nil);
visualRectnull1256     function visualRect(Index: QModelIndexH): TRect;
1257     procedure setEditTriggers(ATriggers: QAbstractItemViewEditTriggers);
1258     procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); virtual;
1259     procedure setSelectionBehavior(ABehavior: QAbstractItemViewSelectionBehavior);
1260     procedure setWordWrap(const AValue: Boolean); virtual;
1261     property AllowGrayed: boolean read FAllowGrayed write FAllowGrayed;
1262     property Checkable: boolean read FCheckable write FCheckable;
1263     property HideSelection: Boolean read FHideSelection write FHideSelection;
1264     property IconSize: TSize read getIconSize write setIconSize;
1265     property ItemFlags[AIndex: Integer]: QtItemFlags read GetItemFlags write SetItemFlags;
1266     property OwnerDrawn: Boolean read GetOwnerDrawn write SetOwnerDrawn;
1267     property OwnerData: Boolean read FOwnerData write FOwnerData;
1268     property SyncingItems: Boolean read FSyncingItems write FSyncingItems;
1269     property ViewStyle: Integer read FViewStyle write FViewStyle;
1270   public
1271     procedure ItemDelegateSizeHint(option: QStyleOptionViewItemH; index: QModelIndexH; Size: PSize); cdecl; virtual;
1272     procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; virtual;
1273   end;
1274 
1275   { TQtListView }
1276 
1277   TQtListView = class(TQtAbstractItemView)
1278   private
getBatchSizenull1279     function getBatchSize: integer;
getGridSizenull1280     function getGridSize: TSize;
getSpacingnull1281     function getSpacing: Integer;
1282     procedure setBatchSize(const AValue: integer);
1283     procedure setSpacing(const AValue: integer);
1284     procedure setGridSize(const AValue: TSize);
1285   public
1286     procedure setLayoutMode(const ALayoutMode: QListViewLayoutMode);
1287     procedure setMovement(const AMovement: QListViewMovement);
1288     procedure setResizeMode(const AResizeMode: QListViewResizeMode);
1289     procedure setUniformItemSizes(const AEnable: Boolean);
1290     procedure setViewFlow(const AFlow: QListViewFlow);
1291     procedure setViewMode(const AMode: QListViewViewMode);
1292     procedure setWordWrap(const AValue: Boolean); override;
1293     procedure setWrapping(const AWrapping: Boolean);
1294     procedure LayoutItems;
1295     property BatchSize: integer read getBatchSize write setBatchSize;
1296     property GridSize: TSize read getGridSize write setGridSize;
1297     property Spacing: Integer read getSpacing write setSpacing;
1298   end;
1299 
1300   { TQtListWidget }
1301 
1302   TQtListWidget = class(TQtListView)
1303   private
1304     FCheckBoxClicked: Boolean;
1305     FSavedSelection: TPtrIntArray;
1306     FCurrentItemChangedHook: QListWidget_hookH;
1307     FSelectionChangeHook: QListWidget_hookH;
1308     FItemClickedHook: QListWidget_hookH;
1309     FItemTextChangedHook: QListWidget_hookH;
1310     FDelayedCheckItem: QListWidgetItemH;
1311     FDontPassSelChange: Boolean;
1312     procedure HandleCheckChangedEvent(const AMousePos: TQtPoint;
1313         AItem: QListWidgetItemH; AEvent: QEventH);
GetItemCheckednull1314     function GetItemChecked(AIndex: Integer): Boolean;
getItemCountnull1315     function getItemCount: Integer;
GetItemEnablednull1316     function GetItemEnabled(AIndex: Integer): Boolean;
GetSelectednull1317     function GetSelected(AIndex: Integer): Boolean;
1318     procedure SetItemChecked(AIndex: Integer; AValue: Boolean);
1319     procedure setItemCount(const AValue: Integer);
1320     procedure SetItemEnabled(AIndex: Integer; AValue: Boolean);
1321     procedure SetSelected(AIndex: Integer; AValue: Boolean);
1322   protected
CreateWidgetnull1323     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1324     procedure OwnerDataNeeded(ARect: TRect); override;
GetItemFlagsnull1325     function GetItemFlags(AIndex: Integer): QtItemFlags; override;
1326     procedure SetItemFlags(AIndex: Integer; AValue: QtItemFlags); override;
1327     procedure SetItemLastCheckState(AItem: QListWidgetItemH);
1328     procedure SetItemLastCheckStateInternal(AItem: QListWidgetItemH; AState: QtCheckState);
1329     procedure SetNextStateMap(AItem: QListWidgetItemH); virtual;
1330   public
1331     FList: TStrings;
1332   public
1333     procedure AttachEvents; override;
1334     procedure DetachEvents; override;
1335     procedure InitializeWidget; override;
EventFilternull1336     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1337     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1338 
1339     procedure signalCurrentItemChanged(current: QListWidgetItemH; previous: QListWidgetItemH); cdecl; virtual;
1340     procedure signalItemTextChanged(ANewText: PWideString); cdecl; virtual;
1341     procedure signalItemClicked(item: QListWidgetItemH); cdecl; virtual;
1342     procedure signalSelectionChanged(); cdecl; virtual;
1343     procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; override;
1344   public
1345     procedure clearSelection; override;
1346     procedure ClearItems;
currentRownull1347     function currentRow: Integer;
currentItemnull1348     function currentItem: QListWidgetItemH;
GetItemLastCheckStatenull1349     function GetItemLastCheckState(AItem: QListWidgetItemH): QtCheckState;
IndexAtnull1350     function IndexAt(APoint: PQtPoint): Integer;
1351     procedure insertItem(AIndex: Integer; AText: String); overload;
1352     procedure insertItem(AIndex: Integer; AText: PWideString); overload;
itemAtnull1353     function itemAt(APoint: TPoint): QListWidgetItemH; overload;
itemAtnull1354     function itemAt(x: Integer; y: Integer): QListWidgetItemH; overload;
getItemnull1355     function getItem(AIndex: Integer): QListWidgetItemH;
getItemSelectednull1356     function getItemSelected(AItem: QListWidgetItemH): Boolean;
getItemVisiblenull1357     function getItemVisible(AItem: QListWidgetItemH): Boolean;
getRownull1358     function getRow(AItem: QListWidgetItemH): integer;
getSelCountnull1359     function getSelCount: Integer;
getTopItemnull1360     function getTopItem: integer; override;
getVisibleRowCountnull1361     function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; override;
getVisualItemRectnull1362     function getVisualItemRect(AItem: QListWidgetItemH): TRect;
selectedItemsnull1363     function selectedItems: TPtrIntArray;
1364     procedure setCurrentRow(row: Integer);
1365     procedure setCurrentItem(AItem: QListWidgetItemH; const AIsSet: Boolean = True);
1366     procedure setItemText(AIndex: Integer; AText: String); overload;
1367     procedure setItemText(AIndex: Integer; AText: String; AAlignment: Integer); overload;
1368     procedure setItemSelected(AItem: QListWidgetItemH; const ASelect: Boolean);
1369     procedure setItemVisible(AItem: QListWidgetItemH; const AVisible: Boolean);
1370     procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); override;
1371     procedure scrollToItem(row: integer; hint: QAbstractItemViewScrollHint);
1372     procedure removeItem(AIndex: Integer);
rowCountnull1373     function rowCount: integer;
1374     procedure ExchangeItems(const AIndex1, AIndex2: Integer);
1375     procedure MoveItem(const AFromIndex, AToIndex: Integer);
1376     property ItemCount: Integer read getItemCount write setItemCount;
1377     property ItemChecked[AIndex: Integer]: Boolean read GetItemChecked write SetItemChecked;
1378     property Enabled[AIndex: Integer]: Boolean read GetItemEnabled write SetItemEnabled;
1379     property Selected[AIndex: Integer]: Boolean read GetSelected write SetSelected;
1380   end;
1381 
1382   { TQtCheckListBox }
1383 
1384   TQtCheckListBox = class (TQtListWidget)
1385   private
1386     FItemChangedHook: QListWidget_hookH;
GetItemCheckStatenull1387     function GetItemCheckState(AIndex: Integer): QtCheckState;
1388     procedure SetItemCheckState(AIndex: Integer; AValue: QtCheckState);
1389   protected
CreateWidgetnull1390     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1391     procedure SetNextStateMap(AItem: QListWidgetItemH); override;
1392   public
1393     procedure AttachEvents; override;
1394     procedure DetachEvents; override;
1395 
EventFilternull1396     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1397     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1398 
1399     procedure signalCurrentItemChanged(current: QListWidgetItemH; previous: QListWidgetItemH); cdecl; override;
1400     procedure signalItemClicked(item: QListWidgetItemH); cdecl; override;
1401     procedure signalSelectionChanged(); cdecl; override;
1402     procedure signalItemChanged(item: QListWidgetItemH); cdecl;
1403     property ItemCheckState[AIndex: Integer]: QtCheckState read GetItemCheckState write SetItemCheckState;
1404   end;
1405 
1406   { TQtHeaderView }
1407 
1408   TQtHeaderView = class (TQtAbstractItemView)
1409   private
1410     FSectionClicked: QHeaderView_hookH;
getClickablenull1411     function getClickable: Boolean;
getMinSectionSizenull1412     function getMinSectionSize: Integer;
1413     procedure setClickable(const AValue: Boolean);
1414     procedure setMinSectionSize(const AValue: Integer);
1415   protected
CreateWidgetnull1416     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1417   public
1418     procedure AttachEvents; override;
1419     procedure DetachEvents; override;
EventFilternull1420     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1421     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1422     procedure SignalSectionClicked(logicalIndex: Integer); cdecl;
getResizeModenull1423     function getResizeMode(AIndex: Integer): QHeaderViewResizeMode;
1424     procedure setResizeMode(AResizeMode: QHeaderViewResizeMode); overload;
1425     procedure setResizeMode(AIndex: Integer; AResizeMode: QHeaderViewResizeMode); overload;
sectionSizenull1426     function sectionSize(AIndex: Integer): Integer;
sectionSizeHintnull1427     function sectionSizeHint(AIndex: Integer): Integer;
1428     procedure moveSection(AFromIndex: Integer; AToIndex: Integer);
1429     procedure resizeSection(ASection: Integer; ASize: Integer);
1430     procedure setHighlightSections(AValue: Boolean);
1431     procedure setDefaultSectionSize(AValue: Integer);
SortIndicatorOrdernull1432     function SortIndicatorOrder: QtSortOrder;
1433     procedure SetSortIndicator(const AColumn: Integer; const AOrder: QtSortOrder);
1434     procedure SetSortIndicatorVisible(AVisible: Boolean);
1435     procedure setStretchLastSection(AValue: Boolean);
1436     property Clickable: Boolean read getClickable write setClickable;
1437     property MinSectionSize: Integer read getMinSectionSize write setMinSectionSize;
1438   end;
1439 
1440   { TQtTreeView }
1441 
1442   TQtTreeView = class (TQtAbstractItemView)
1443   private
getColVisiblenull1444     function getColVisible(AIndex: Integer): Boolean;
getColWidthnull1445     function getColWidth(AIndex: Integer): Integer;
GetUniformRowHeightsnull1446     function GetUniformRowHeights: Boolean;
1447     procedure setColVisible(AIndex: Integer; const AValue: Boolean);
1448     procedure setColWidth(AIndex: Integer; const AValue: Integer);
1449     procedure SetUniformRowHeights(const AValue: Boolean);
1450   protected
CreateWidgetnull1451     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1452   public
1453     procedure setAllColumnsShowFocus(AValue: Boolean);
1454     procedure setWordWrap(const AValue: Boolean); override;
1455     procedure setRootIsDecorated(AValue: Boolean);
1456     property ColWidth[AIndex: Integer]: Integer read getColWidth write setColWidth;
1457     property ColVisible[AIndex: Integer]: Boolean read getColVisible write setColVisible;
1458     property UniformRowHeights: Boolean read GetUniformRowHeights write SetUniformRowHeights;
1459   end;
1460 
1461   { TQtTreeWidget }
1462 
1463   TQtTreeWidget = class(TQtTreeView)
1464   private
1465     FSelection: TFPList;
1466     FHeader: TQtHeaderView;
1467     {$IFDEF TEST_QT_SORTING}
1468     FCanSort: Boolean; // it can sort items only when LCL says so !
1469     FSorting: Boolean;
1470     FSortChanged: QHeaderView_hookH;
1471     {$ENDIF}
1472     FItemActivatedHook: QTreeWidget_hookH;
1473     FItemEnteredHook: QTreeWidget_hookH;
1474     FSelectionChangedHook: QTreeWidget_hookH;
1475     FDelayedCheckItem: QTreeWidgetItemH;
1476 
1477     procedure HandleCheckChangedEvent(const AMousePos: TQtPoint;
1478         AItem: QTreeWidgetItemH; AEvent: QEventH);
1479 
GetItemLastCheckStateInternalnull1480     function GetItemLastCheckStateInternal(AItem: QTreeWidgetItemH): QtCheckState;
1481     procedure SetItemLastCheckStateInternal(AItem: QTreeWidgetItemH; AState: QtCheckState);
1482 
getColCountnull1483     function getColCount: Integer;
getHeadernull1484     function getHeader: TQtHeaderView;
GetItemCheckednull1485     function GetItemChecked(AIndex: Integer): Boolean;
getItemCountnull1486     function getItemCount: Integer;
getMaxColSizenull1487     function getMaxColSize(ACol: Integer): Integer;
getMinColSizenull1488     function getMinColSize(ACol: Integer): Integer;
getSortEnablednull1489     function getSortEnabled: Boolean;
1490     procedure setColCount(const AValue: Integer);
1491     procedure SetItemChecked(AIndex: Integer; AValue: Boolean);
1492     procedure setItemCount(const AValue: Integer);
1493     procedure setMaxColSize(ACol: Integer; const AValue: Integer);
1494     procedure setMinColSize(ACol: Integer; const AValue: Integer);
1495     procedure setSortEnabled(const AValue: Boolean);
1496   protected
CreateWidgetnull1497     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1498     procedure OwnerDataNeeded(ARect: TRect); override;
1499   public
1500     destructor Destroy; override;
1501     procedure DestroyNotify(AWidget: TQtWidget); override;
EventFilternull1502     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1503     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1504     procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; override;
1505     procedure ClearItems;
1506     procedure clearSelection; override;
1507     procedure DeleteItem(const AIndex: integer);
currentRownull1508     function currentRow: Integer;
1509     procedure setCurrentRow(row: Integer);
currentItemnull1510     function currentItem: QTreeWidgetItemH;
1511     procedure setCurrentItem(AItem: QTreeWidgetItemH);
1512 
getRownull1513     function getRow(AItem: QTreeWidgetItemH): integer;
headerItemnull1514     function headerItem: QTreeWidgetItemH;
itemAtnull1515     function itemAt(APoint: TPoint): QTreeWidgetItemH; overload;
itemAtnull1516     function itemAt(x: Integer; y: Integer): QTreeWidgetItemH; overload;
1517     procedure insertTopLevelItem(AIndex: Integer; AItem: QTreeWidgetItemH);
takeTopLevelItemnull1518     function takeTopLevelItem(AIndex: Integer): QTreeWidgetItemH;
topLevelItemnull1519     function topLevelItem(AIndex: Integer): QTreeWidgetItemH;
visualItemRectnull1520     function visualItemRect(AItem: QTreeWidgetItemH): TRect;
getHeaderHeightnull1521     function getHeaderHeight(out AOrientation: QtOrientation): Integer;
getItemVisiblenull1522     function getItemVisible(AItem: QTreeWidgetItemH): Boolean;
getTopItemnull1523     function getTopItem: integer; override;
getVisibleRowCountnull1524     function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; override;
1525     procedure setItemVisible(AItem: QTreeWidgetItemH; Const AVisible: Boolean);
1526     procedure setItemText(AItem: QTreeWidgetItemH; const AColumn: Integer;
1527       const AText: WideString; const AAlignment: QtAlignment);
1528     procedure setItemData(AItem: QTreeWidgetItemH; const AColumn: Integer;
1529        Data: Pointer; const ARole: Integer = Ord(QtUserRole));
selCountnull1530     function selCount: Integer;
selectedItemsnull1531     function selectedItems: TPtrIntArray;
1532     procedure setHeaderVisible(AVisible: Boolean);
1533     procedure setItemSelected(AItem: QTreeWidgetItemH; ASelect: Boolean);
1534     procedure setStretchLastSection(AValue: Boolean);
1535     procedure scrollToItem(Item: QTreeWidgetItemH; hint: QAbstractItemViewScrollHint);
1536     {$IFDEF TEST_QT_SORTING}
1537     // direct Qt sorting via QtUserData ptr = our TListItem, crashes sometimes - qt bug.
1538     procedure sortItems(Acolumn: Integer; AOrder: QtSortOrder);
1539     {$ENDIF}
1540   public
1541     procedure AttachEvents; override;
1542     procedure DetachEvents; override;
1543     procedure ExchangeItems(const AIndex1, AIndex2: Integer);
1544     procedure MoveItem(const AFromIndex, AToIndex: Integer);
getClientBoundsnull1545     function getClientBounds: TRect; override;
getClientOffsetnull1546     function getClientOffset: TPoint; override;
1547 
1548     procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); override;
1549     procedure SignalItemActivated(item: QTreeWidgetItemH; column: Integer); cdecl;
1550     procedure SignalItemEntered(item: QTreeWidgetItemH; column: Integer); cdecl;
1551     procedure SignalCurrentItemChanged(current: QTreeWidgetItemH; previous: QTreeWidgetItemH); cdecl;
1552     procedure SignalSelectionChanged(); cdecl;
1553     {$IFDEF TEST_QT_SORTING}
1554     procedure SignalSortIndicatorChanged(ALogicalIndex: Integer; AOrder: QtSortOrder); cdecl;
1555     property CanSort: Boolean read FCanSort write FCanSort;
1556     {$ENDIF}
1557     property ColCount: Integer read getColCount write setColCount;
1558     property Header: TQtHeaderView read getHeader;
1559     property ItemChecked[AIndex: Integer]: Boolean read GetItemChecked write SetItemChecked;
1560     property ItemCount: Integer read getItemCount write setItemCount;
1561     property MaxColSize[ACol: Integer]: Integer read getMaxColSize write setMaxColSize;
1562     property MinColSize[ACol: Integer]: Integer read getMinColSize write setMinColSize;
1563     property SortEnabled: Boolean read getSortEnabled write setSortEnabled;
1564     {$IFDEF TEST_QT_SORTING}
1565     property Sorting: Boolean read FSorting write FSorting;
1566     {$ENDIF}
1567   end;
1568 
1569   {TQtTableView}
1570 
1571   TQtTableView = class(TQtAbstractItemView)
1572   private
1573     FVerticalHeader: TQtHeaderView;
1574     FHorizontalHeader: TQtHeaderView;
1575   public
verticalHeadernull1576     function verticalHeader: TQtHeaderView;
horizontalHeadernull1577     function horizontalHeader: TQtHeaderView;
CreateWidgetnull1578     function CreateWidget(const Params: TCreateParams): QWidgetH; override;
getViewPortnull1579     function getViewPort: QWidgetH;
getClientBoundsnull1580     function getClientBounds: TRect; override;
1581     procedure grabMouse; override;
1582     procedure setVisible(AVisible: Boolean); override;
getGridStylenull1583     function getGridStyle: QtPenStyle;
1584     procedure setGridStyle(ANewStyle: QtPenStyle);
1585   public
1586     destructor Destroy; override;
1587   end;
1588 
1589   { TQtMenu }
1590 
1591   TQtMenu = class(TQtWidget)
1592   private
1593     FLastTick: QWord; // issue #22872
1594     FActions: TFPList;
1595     FIcon: QIconH;
1596     FTriggeredHook: QAction_hookH;
1597     FHoveredHook: QAction_hookH;
1598     FAboutToShowHook: QMenu_hookH;
1599     FAboutToHideHook: QMenu_hookH;
1600     FActionEventFilter: QObject_hookH;
1601     FActionHandle: QActionH;
1602     FMenuItem: TMenuItem;
1603     FTrackButton: QtMouseButtons;
1604     procedure setActionGroups(AItem: TMenuItem);
1605   protected
CreateWidgetnull1606     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1607     procedure DoPopupClose;
1608   public
1609     constructor Create(const AMenuItem: TMenuItem); overload;
1610     destructor Destroy; override;
1611     procedure InitializeWidget; override;
1612   public
1613     procedure AttachEvents; override;
1614     procedure DetachEvents; override;
1615 
1616     procedure SlotHovered; cdecl;
1617     procedure SlotAboutToShow; cdecl;
1618     procedure SlotAboutToHide; cdecl;
1619     procedure SlotDestroy; cdecl;
1620     procedure SlotTriggered(checked: Boolean = False); cdecl;
ActionEventFilternull1621     function ActionEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
EventFilternull1622     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1623   public
actionHandlenull1624     function actionHandle: QActionH;
addMenunull1625     function addMenu(AMenu: QMenuH): QActionH;
insertMenunull1626     function insertMenu(AIndex: Integer; AMenu: QMenuH; AItem: TMenuItem): QActionH;
getHasSubMenunull1627     function getHasSubMenu: boolean;
getTextnull1628     function getText: WideString; override;
getVisiblenull1629     function getVisible: Boolean; override;
MenuItemEnablednull1630     function MenuItemEnabled: boolean;
1631     procedure PopUp(pos: PQtPoint; at: QActionH = nil);
1632     procedure Exec(pos: PQtPoint; at: QActionH = nil);
1633     procedure removeActionGroup;
1634     procedure setChecked(p1: Boolean);
1635     procedure setCheckable(p1: Boolean);
1636     procedure setHasSubmenu(AValue: Boolean);
1637     procedure setIcon(AIcon: QIconH);
1638     procedure setImage(AImage: TQtImage);
1639     procedure setSeparator(AValue: Boolean);
1640     procedure setShortcut(AShortCutK1, AShortCutK2: TShortcut);
1641     procedure setText(const W: WideString); override;
1642     procedure setVisible(AVisible: Boolean); override;
1643     property trackButton: QtMouseButton read FTrackButton write FTrackButton;
1644   end;
1645 
1646   { TQtMenuBar }
1647 
1648   TQtMenuBar = class(TQtWidget)
1649   private
1650     {$IFNDEF DARWIN}
1651     FCatchNextResizeEvent: Boolean; {needed during design time}
1652     FNumOfActions: PtrInt;
1653     {$ENDIF}
1654     FVisible: Boolean;
1655     FHeight: Integer;
1656     FIsApplicationMainMenu: Boolean;
1657   public
1658     constructor Create(const AParent: QWidgetH); overload;
1659   public
1660     {$IFNDEF DARWIN}
IsDesigningnull1661     function IsDesigning: Boolean;
1662     {$ENDIF}
EventFilternull1663     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
addMenunull1664     function addMenu(AMenu: QMenuH): QActionH;
insertMenunull1665     function insertMenu(AIndex: Integer; AMenu: QMenuH): QActionH;
getGeometrynull1666     function getGeometry: TRect; override;
1667   end;
1668 
1669   { TQtProgressBar }
1670 
1671   TQtProgressBar = class(TQtWidget)
1672   private
1673     FValueChangedHook: QProgressBar_hookH;
1674   protected
CreateWidgetnull1675     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1676   public
1677     procedure AttachEvents; override;
1678     procedure DetachEvents; override;
1679     procedure SignalValueChanged(Value: Integer); cdecl;
1680     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
1681   public
1682     procedure reset;
1683     procedure setRange(minimum: Integer; maximum: Integer);
1684     procedure setTextVisible(visible: Boolean);
1685     procedure setAlignment(const AAlignment: QtAlignment);
1686     procedure setTextDirection(textDirection: QProgressBarDirection);
1687     procedure setValue(value: Integer);
1688     procedure setOrientation(p1: QtOrientation);
1689     procedure setInvertedAppearance(invert: Boolean);
1690   end;
1691 
1692   { TQtStatusBarPanel }
1693 
1694   TQtStatusBarPanel = class(TQtFrame)
1695   private
1696     FId: Integer;
1697     procedure DrawItem(Sender: QObjectH; Event: QEventH);
1698   protected
CreateWidgetnull1699     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1700   public
EventFilternull1701     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1702     property ID: Integer read FId write FId;
1703   end;
1704 
1705   { TQtStatusBar }
1706 
1707   TQtStatusBar = class(TQtWidget)
1708   protected
CreateWidgetnull1709     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1710   public
1711     Panels: array of TQtStatusBarPanel;
1712     procedure setColor(const Value: PQColor); override;
1713     procedure showMessage(text: PWideString; timeout: Integer = 0);
1714     procedure addWidget(AWidget: QWidgetH; AStretch: Integer = 0);
1715     procedure removeWidget(AWidget: QWidgetH);
isSizeGripEnablednull1716     function isSizeGripEnabled: Boolean;
1717     procedure setSizeGripEnabled(const Value: Boolean);
SlotMousenull1718     function SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; override; cdecl;
1719   end;
1720 
1721   { TQtDialog }
1722 
1723   TQtDialog = class(TQtWidget)
1724   private
1725     FDialogEventHook: QObject_hookH;
1726   protected
1727     FDialog: TCommonDialog;
CreateWidgetnull1728     function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; virtual; overload;
1729   public
1730     constructor Create(ADialog: TCommonDialog; parent: QWidgetH = nil; f: QtWindowFlags = 0); overload;
1731     procedure AttachEvents; override;
1732     procedure DetachEvents; override;
DeliverMessagenull1733     function DeliverMessage(var Msg; const AIsInputEvent: Boolean = False): LRESULT; override;
SlotClosenull1734     function SlotClose: Boolean; cdecl; override;
1735   public
EventFilternull1736     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
execnull1737     function exec: Integer;
1738     procedure setSizeGripEnabled(const AEnabled: Boolean);
1739   end;
1740 
1741   { TQtFileDialog }
1742 
1743   TQtFileDialog = class(TQtDialog)
1744   private
1745     {$ifndef QT_NATIVE_DIALOGS}
1746     FBackBtn: QWidgetH;
1747     FForwardBtn: QWidgetH;
1748     FUpBtn: QWidgetH;
1749     FFileNameEdit: QWidgetH;
1750     FComboType: QWidgetH;
1751     FComboHistory: QWidgetH;
1752     FSideView: QWidgetH;
1753     FTreeView: QWidgetH;
1754     FListView: QWidgetH;
1755     FTreeViewEventFilter: QObject_hookH;
1756     FListViewEventFilter: QObject_hookH;
1757     FSideViewEventFilter: QObject_hookH;
1758     FFileNameEditEventFilter: QObject_hookH;
1759     FComboTypeEventFilter: QObject_hookH;
1760     FComboHistoryEventFilter: QObject_hookH;
1761     {$endif}
1762     FCurrentChangedHook: QFileDialog_hookH;
1763     FDirecotyEnteredHook: QFileDialog_hookH;
1764     FFilterSelectedHook: QFileDialog_hookH;
1765   protected
CreateWidgetnull1766     function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; override;
1767   public
1768     procedure AttachEvents; override;
1769     procedure DetachEvents; override;
1770     {$ifndef QT_NATIVE_DIALOGS}
EventFilternull1771     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1772     {$endif}
1773     procedure CurrentChangedEvent(path: PWideString); cdecl; virtual;
1774     procedure FilterSelectedEvent(filter: PWideString); cdecl;
1775     procedure DirectoryEnteredEvent(directory: PWideString); cdecl;
1776   public
1777     procedure getFilters(const retval: QStringListH);
selectFilenull1778     function selectFile: WideString;
1779     procedure selectedFiles(retval: QStringListH);
1780     procedure setAcceptMode(const AMode: QFileDialogAcceptMode);
1781     procedure setConfirmOverwrite(const AValue: Boolean);
1782     procedure setDirectory(const ADirectory: WideString);
1783     procedure setHistory(AList: TStrings);
1784     procedure setFileMode(const AMode: QFileDialogFileMode);
1785     procedure setFilter(const AFilter: WideString);
1786     procedure setLabelText(const ALabel: QFileDialogDialogLabel; const AText: WideString);
1787     procedure setReadOnly(const AReadOnly: Boolean);
1788     procedure setSelectedFilter(const ASelFilter: WideString);
1789     procedure setViewMode(const AMode: QFileDialogViewMode);
1790     {$ifndef QT_NATIVE_DIALOGS}
1791     procedure setShortcuts(const AIsOpenDialog: Boolean);
1792     {$endif}
1793   end;
1794 
1795   { TQtFilePreviewDialog }
1796 
1797   TQtFilePreviewDialog = class(TQtFileDialog)
1798   private
1799     {$ifndef QT_NATIVE_DIALOGS}
1800     FTextWidget: QLabelH;
1801     FPreviewWidget: QLabelH;
1802     {$ENDIF}
1803   protected
CreateWidgetnull1804     function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; override;
1805   public
1806     {$ifndef QT_NATIVE_DIALOGS}
1807     procedure initializePreview(const APreviewControl: TWinControl);
1808     procedure CurrentChangedEvent(path: PWideString); cdecl; override;
1809     property PreviewWidget: QLabelH read FPreviewWidget;
1810     property TextWidget: QLabelH read FTextWidget;
1811     {$ENDIF}
1812   end;
1813 
1814   { TQtMessageBox }
1815 
1816   TQtMessageBox = class(TQtWidget)
1817   private
1818     FMBEventHook: QObject_hookH;
1819     FTitle: WideString;
getDetailTextnull1820     function getDetailText: WideString;
getMessageStrnull1821     function getMessageStr: WideString;
getMsgBoxTypenull1822     function getMsgBoxType: QMessageBoxIcon;
GetTextFormatnull1823     function GetTextFormat: QtTextFormat;
1824     procedure setDetailText(const AValue: WideString);
1825     procedure setMessageStr(const AValue: WideString);
1826     procedure setMsgBoxType(const AValue: QMessageBoxIcon);
1827     procedure SetTextFormat(AValue: QtTextFormat);
1828     procedure setTitle(const AValue: WideString);
1829   protected
CreateWidgetnull1830     function CreateWidget(AParent: QWidgetH):QWidgetH; overload;
1831   public
1832     constructor Create(AParent: QWidgetH); overload;
1833     procedure AttachEvents; override;
1834     procedure DetachEvents; override;
EventFilternull1835     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1836   public
AddButtonnull1837     function AddButton(ACaption: WideString; ABtnType: QMessageBoxStandardButton; AResult: Int64;
1838       const ADefaultBtn: Boolean; const AEscapeBtn: Boolean = False): QPushButtonH; overload;
AddButtonnull1839     function AddButton(ACaption: WideString; AResult: Int64;
1840       const ADefaultBtn: Boolean; const AEscapeBtn: Boolean = False): QPushButtonH;
1841     procedure SetButtonProps(ABtn: QPushButtonH; AResult: Int64; const ADefaultBtn: Boolean;
1842       const AEscapeBtn: Boolean);
execnull1843     function exec: Int64;
1844     property DetailText: WideString read getDetailText write setDetailText;
1845     property MessageStr: WideString read getMessageStr write setMessageStr;
1846     property MsgBoxType:QMessageBoxIcon read getMsgBoxType write setMsgBoxType;
1847     property Title: WideString read FTitle write setTitle;
1848     property TextFormat: QtTextFormat read GetTextFormat write SetTextFormat;
1849   end;
1850 
1851   { TQtCalendar }
1852 
1853   TQtCalendar = class(TQtWidget)
1854   private
1855     FMouseDoubleClicked: Boolean;
1856     FCalViewportEventHook: QObject_hookH;
1857     FCalViewAreaEventHook: QObject_hookH;
1858     FClickedHook: QCalendarWidget_hookH;
1859     FActivatedHook: QCalendarWidget_hookH;
1860     FSelectionChangedHook: QCalendarWidget_hookH;
1861     FCurrentPageChangedHook: QCalendarWidget_hookH;
DeliverDayChangednull1862     function DeliverDayChanged(ADate: QDateH): boolean;
GetDateTimenull1863     function GetDateTime: TDateTime;
1864     procedure SetDateTime(const AValue: TDateTime);
1865     procedure SetSelectedDate(const AValue: QDateH);
1866   protected
CreateWidgetnull1867     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1868   public
1869     AYear, AMonth, ADay: Word;
1870     procedure AttachEvents; override;
1871     procedure DetachEvents; override;
EventFilternull1872     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
AreaViewEventFilternull1873     function AreaViewEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
calViewportEventFilternull1874     function calViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
HitTestnull1875     function HitTest(const APoint: TPoint): byte;
1876     procedure SetDisplaySettings(
1877       const AHHdrFmt: QCalendarWidgetHorizontalHeaderFormat;
1878       const AVHdrFmt: QCalendarWidgetVerticalHeaderFormat;
1879       const ASelMode: QCalendarWidgetSelectionMode;
1880       const ANavBarVisible: Boolean; const AGridVisible: Boolean);
1881     procedure SetFirstDayOfWeek(const ADayOfWeek: QtDayOfWeek);
1882     procedure SignalActivated(ADate: QDateH); cdecl;
1883     procedure SignalClicked(ADate: QDateH); cdecl;
1884     procedure SignalSelectionChanged; cdecl;
1885     procedure SignalCurrentPageChanged(p1, p2: Integer); cdecl;
1886     property DateTime: TDateTime read GetDateTime write SetDateTime;
1887   end;
1888 
1889   // for page control / notebook
1890 
1891   { TQtPage }
1892 
1893   TQtPage = class(TQtWidget)
1894   protected
1895     FIcon: QIconH;
CreateWidgetnull1896     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1897   public
EventFilternull1898     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
getIconnull1899     function getIcon: QIconH;
getIndexnull1900     function getIndex(const ATextChanging: Boolean = False): Integer;
getTabWidgetnull1901     function getTabWidget: QTabWidgetH;
1902     procedure setIcon(const AIcon: QIconH);
1903     procedure setText(const W: WideString); override;
1904   end;
1905 
1906   { TQtRubberBand }
1907 
1908   TQtRubberBand = class(TQtWidget)
1909   private
1910     FShape: QRubberBandShape;
1911   protected
CreateWidgetnull1912     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1913   public
1914     constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); override;
1915 
1916     // QRubberBand have it's own move,resize and setGeometry
1917     procedure move(ANewLeft, ANewTop: Integer); override;
1918     procedure Resize(ANewWidth, ANewHeight: Integer); override;
1919     procedure setGeometry(ARect: TRect); override;
1920 
1921     function getShape: QRubberBandShape;
1922     procedure setShape(AShape: QRubberBandShape);
1923   end;
1924 
1925   { TQtDesignWidget }
1926 
1927   TQtDesignWidget = class(TQtMainWindow)
1928   protected
1929     FDesignControlEventHook: QObject_hookH;
1930     FDesignControl: QWidgetH;
1931     FDesignContext: HDC;
1932     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1933     procedure DestroyWidget; override;
1934     procedure SlotDesignControlPaint(Sender: QObjectH; Event: QEventH); cdecl;
1935     procedure BringDesignerToFront;
1936     procedure ResizeDesigner;
1937     function GetContext: HDC; override;
1938   public
1939     function DesignControlEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
1940     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1941 
1942     procedure AttachEvents; override;
1943     procedure DetachEvents; override;
1944 
1945     procedure lowerWidget; override;
1946     procedure raiseWidget; override;
1947   public
1948     property DesignContext: HDC read FDesignContext;
1949   end;
1950 
1951 const
1952   AlignmentMap: array[TAlignment] of QtAlignment =
1953   (
1954 {taLeftJustify } QtAlignLeft,
1955 {taRightJustify} QtAlignRight,
1956 {taCenter      } QtAlignHCenter
1957   );
1958 
1959   QtCheckStateRole = Ord(QtUserRole) + 1;
1960   QtListViewOwnerDataRole = Ord(QtUserRole) + 2;
1961 
1962 {$IFDEF QTACCESSIBILITY}
1963 const
1964   QtAXObjectName           = 'AxObject';
1965   axActionNamePress        = 'Press';
1966   axActionNameIncrease     = 'Increase';
1967   axActionNameDecrease     = 'Decrease';
1968   axActionNameShowMenu     = 'ShowMenu';
1969   axActionNameSetFocus     = 'SetFocus';
1970   axActionNameToggle       = 'Toggle';
1971   axActionNameScrolLeft    = 'Scroll Left';
1972   axActionNameScrollRight  = 'Scroll Right';
1973   axActionNameScrollUp     = 'Scroll Up';
1974   axActionNameScrollDown   = 'Scroll Down';
1975   axActionNamePreviousPage = 'Previous Page';
1976   axActionNameNextPage     = 'Next Page';
1977 
1978 function LazRoleToQtRole(ALazRole: TLazAccessibilityRole): QAccessibleRole;
1979 function CreateAccessibleName(AObject: TLazAccessibleObject): String;
1980 function QtAxFactory(name: QStringH; obj: QObjectH): QAccessibleInterfaceH; cdecl;
1981 
1982 type
1983   TQtAccessibleObject = class(TObject)
1984   private
1985     FLazAxObject: TLazAccessibleObject;
1986     FAxWidget: QWidgetH;
1987   public
1988     constructor Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
1989     destructor Destroy; override;
1990     procedure actionNamesOverride(names: PWideString) cdecl; virtual; abstract;
1991     procedure childOverride(index: integer; out child:  QAccessibleInterfaceH) cdecl; virtual;
1992     procedure childAtOverride(x: integer; y: integer; out child: QAccessibleInterfaceH) cdecl; virtual; abstract;
1993     procedure childCountOverride(count: PInteger) cdecl; virtual;
1994     procedure doActionOverride(name: PWideString) cdecl; virtual; abstract;
1995     procedure indexOfChildOverride() cdecl; virtual; abstract;
1996     procedure parentOverride(out parent: QAccessibleInterfaceH) cdecl; virtual; abstract;
1997     procedure rectOverride(left, top, width, height: PInteger) cdecl; virtual; abstract;
1998     procedure roleOverride(out role: QAccessibleRole) cdecl; virtual;
1999     procedure stateOverride(out state: QAccessibleState) cdecl; virtual; abstract;
2000     procedure textOverride(text: QAccessibleText; retval: PWideString) cdecl; virtual;
2001     function isVisible: Boolean; virtual;
2002   end;
2003 
2004   TQtAccessibleTree = class(TQtAccessibleObject)
2005   public
2006     constructor Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
2007     procedure childOverride(index: integer; out child:  QAccessibleInterfaceH) cdecl; virtual;
2008     procedure childCountOverride(count: PInteger) cdecl; virtual;
2009   end;
2010 
2011   TQtAccessibleTreeRow = class(TQtAccessibleObject)
2012   public
2013     constructor Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
2014     procedure actionNamesOverride(names: PWideString)cdecl; override;
2015     procedure childCountOverride(count: PInteger)cdecl; override;
2016     procedure doActionOverride(name: PWideString)cdecl; override;
2017     procedure parentOverride(out parent: QAccessibleInterfaceH)cdecl; override;
2018     procedure rectOverride(left, top, width, height: PInteger) cdecl; override;
2019     procedure roleOverride(out role: QAccessibleRole)cdecl; override;
2020     procedure textOverride(text: QAccessibleText; retval: PWideString) cdecl; override;
2021     function isVisible: Boolean; override;
2022   end;
2023 {$ENDIF}
2024 
2025 implementation
2026 
2027 uses
2028   Buttons,
2029   math,
2030   qtCaret,
2031   qtproc,
2032   qtprivate,
2033   WSControls
2034   {$IFDEF HASX11}
2035   ,keysym
2036   {$ENDIF}
2037   ;
2038 
2039 const
2040   Forbid_TCN_SELCHANGE = -3;
2041   Allow_TCN_SELCHANGE = -2;
2042 
2043 type
2044   TWinControlAccess = class(TWinControl)
2045   end;
2046   TCustomListViewAccess = class(TCustomListView);
2047 
2048 var
2049   LastMouse: TLastMouseInfo;
2050 
2051 { TQtWidget }
2052 
2053 {------------------------------------------------------------------------------
2054   Function: TQtWidget.Create
2055   Params:  None
2056   Returns: Nothing
2057  ------------------------------------------------------------------------------}
2058 constructor TQtWidget.Create(const AWinControl: TWinControl; const AParams: TCreateParams);
2059 begin
2060   inherited Create;
2061   FOwner := nil;
2062   FCentralWidget := nil;
2063   FOwnWidget := True;
2064   // Initializes the properties
2065   FProps := nil;
2066   LCLObject := AWinControl;
2067   FKeysToEat := [VK_TAB, VK_RETURN, VK_ESCAPE];
2068   FHasPaint := False;
2069 
2070   FParams := AParams;
2071   InitializeWidget;
2072   InitializeAccessibility;
2073 end;
2074 
2075 constructor TQtWidget.CreateFrom(const AWinControl: TWinControl;
2076   AWidget: QWidgetH);
2077 begin
2078   inherited Create;
2079 
2080   FOwner := nil;
2081   FOwnWidget := False;
2082   FCentralWidget := nil;
2083   // Initializes the properties
2084   FProps := niL;
2085   LCLObject := AWinControl;
2086   FKeysToEat := [VK_TAB, VK_RETURN, VK_ESCAPE];
2087 
2088   // Creates the widget
2089   Widget := AWidget;
2090 
2091   FDefaultCursor := QCursor_create();
2092   QWidget_cursor(Widget, FDefaultCursor);
2093   FWidgetLCLFont := nil;
2094   FWidgetDefaultFont := TQtFont.Create(QWidget_font(AWidget));
2095 
2096   // set Handle->QWidget map
2097   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
2098   FillChar(FPaintData, sizeOf(FPaintData), 0);
2099 
2100   QtWidgetSet.AddHandle(Self);
2101   // set focus policy
2102   if (LCLObject <> nil) and not (Self is TQtMainWindow) then
2103     setFocusPolicy(QtClickFocus);
2104 
2105   // Set mouse move messages policy
2106   QWidget_setMouseTracking(Widget, True);
2107 
2108   InitializeAccessibility;
2109 end;
2110 
2111 procedure TQtWidget.InitializeAccessibility;
2112 {$IFDEF QTACCESSIBILITY}
2113 var
2114   WStr: WideString;
2115   LCLAxObject: TLazAccessibleObject;
2116 {$ENDIF}
2117 begin
2118   {$IFDEF QTACCESSIBILITY}
2119   if Assigned(LCLObject) then begin
2120     LCLAxObject := LCLObject.GetAccessibleObject;
2121     if (LCLAxObject <> nil) then begin
2122       WStr := GetUtf8String(CreateAccessibleName(LCLAxObject));
2123       QWidget_setAccessibleName(Widget, @WStr);
2124       WStr := GetUtf8String(LCLAxObject.AccessibleDescription);
2125       QWidget_setAccessibleDescription(Widget, @WStr);
2126      end;
2127   end
2128   else begin
2129     WStr := GetUtf8String(ClassName);
2130     QWidget_setAccessibleName(Widget, @WStr);
2131   end;
2132   {$ENDIF}
2133 end;
2134 
2135 procedure TQtWidget.InitializeWidget;
2136 begin
2137   FInResizeEvent := False;
2138   // default states
2139   FWidgetState := [];
2140   // default color roles
2141   FWidgetNeedFontColorInitialization := False;
2142   SetDefaultColorRoles;
2143   FPalette := nil;
2144   FHasCaret := False;
2145   FLastCaretPos := QtPoint(-1, -1);
2146   ChildOfComplexWidget := ccwNone;
2147   // creates the widget
2148   Widget := CreateWidget(FParams);
2149 
2150   // retrieve default cursor on create
2151   FDefaultCursor := QCursor_create();
2152   QWidget_cursor(Widget, FDefaultCursor);
2153 
2154   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
2155   FWidgetLCLFont := nil;
2156 
2157 
2158   // apply initial position and size
2159   move(FParams.X, FParams.Y);
2160   if GetContainerWidget <> Widget then
2161     QWidget_resize(GetContainerWidget, FParams.Width, FParams.Height);
2162 
2163   Resize(FParams.Width, FParams.Height);
2164 
2165   FScrollX := 0;
2166   FScrollY := 0;
2167 
2168   {$ifdef VerboseQt}
2169   DebugLn('TQtWidget.InitializeWidget: Self:%x Widget:%x was created for control %s',
2170     [PtrUInt(Self), PtrUInt(Widget), LCLObject.Name]);
2171   {$endif}
2172 
2173   // set Handle->QWidget map
2174   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
2175   QtWidgetSet.AddHandle(Self);
2176 
2177   FillChar(FPaintData, sizeOf(FPaintData), 0);
2178 
2179   // Sets it's initial properties
2180 
2181   // set focus policy
2182   if Assigned(LCLObject) then
2183   begin
2184     if (Self is TQtMainWindow) and
2185       (
2186       TQtMainWindow(Self).IsMDIChild or
2187       Assigned(TQtMainWindow(Self).MDIAreaHandle) or
2188        (csNoFocus in LCLObject.ControlStyle)
2189       ) then
2190     begin
2191       if TQtMainWindow(Self).IsMDIChild or
2192         Assigned(TQtMainWindow(Self).MDIAreaHandle) then
2193       begin
2194         QWidget_setFocusPolicy(FCentralWidget, QtNoFocus);
2195       end else
2196       begin
2197         if LCLObject.TabStop then
2198           setFocusPolicy(QtWheelFocus)
2199         else
2200           setFocusPolicy(QtNoFocus);
2201       end;
2202     end else
2203     begin
2204       if (Self is TQtMainWindow) then
2205         setFocusPolicy(QtTabFocus) // issue #28880
2206       else
2207       if (csNoFocus in LCLObject.ControlStyle) then
2208       begin
2209         if LCLObject.TabStop then
2210           setFocusPolicy(QtTabFocus)
2211         else
2212           setFocusPolicy(QtNoFocus);
2213       end else
2214       if (Self is TQtTabWidget) then
2215         setFocusPolicy(QtTabFocus)
2216       else
2217         setFocusPolicy(QtClickFocus);
2218     end;
2219 
2220     if LCLObject.Perform(LM_NCHITTEST, 0, 0)=HTTRANSPARENT then
2221     begin
2222       setAttribute(QtWA_TransparentForMouseEvents);
2223       setWindowFlags(windowFlags or QtWindowTransparentForInput);
2224     end;
2225 
2226     if (csDesigning in LCLObject.ComponentState) and not
2227        (Self is TQtMainWindow) and
2228        HasPaint and
2229        getAutoFillBackground or
2230        ((csDesigning in LCLObject.ComponentState) and
2231         (ClassType = TQtTabWidget)) then
2232       setAutoFillBackground(False);
2233   end;
2234 
2235 
2236   // Set mouse move messages policy
2237   QWidget_setMouseTracking(Widget, True);
2238 
2239   if Assigned(LCLObject) and FWidgetNeedFontColorInitialization then
2240     setInitialFontColor(LCLObject);
2241   if (FParams.Style and WS_VISIBLE) = 0 then
2242     QWidget_hide(Widget)
2243   else
2244     QWidget_show(Widget);
2245 end;
2246 
2247 procedure TQtWidget.DeInitializeWidget;
2248 begin
2249   QtWidgetSet.RemoveHandle(Self);
2250   DetachEvents;
2251 
2252   if Widget <> nil then
2253     removeProperty(Widget, 'lclwidget');
2254 
2255   QCursor_destroy(FDefaultCursor);
2256 
2257   if HasCaret then
2258     DestroyCaret;
2259 
2260   if Assigned(FWidgetDefaultFont) then
2261     FreeThenNil(FWidgetDefaultFont);
2262   if Assigned(FWidgetLCLFont) then
2263     FreeThenNil(FWidgetLCLFont);
2264 
2265   if FPalette <> nil then
2266   begin
2267     FPalette.Free;
2268     FPalette := nil;
2269   end;
2270 
2271   DestroyWidget;
2272 end;
2273 
2274 procedure TQtWidget.RecreateWidget;
2275 var
2276   Parent: QWidgetH;
2277 begin
2278   // update createparams
2279   with getPos do
2280   begin
2281     FParams.X := X;
2282     FParams.Y := Y;
2283   end;
2284   with getSize do
2285   begin
2286     FParams.Width := cx;
2287     FParams.Height := cy;
2288   end;
2289 
2290   if Widget <> nil then
2291     Parent := QWidget_parentWidget(Widget)
2292   else
2293     Parent := nil;
2294   FParams.WndParent := HwndFromWidgetH(Parent);
2295   DeinitializeWidget;
2296   InitializeWidget;
2297   InitializeAccessibility;
2298 end;
2299 
2300 procedure TQtWidget.DestroyNotify(AWidget: TQtWidget);
2301 begin
2302   if AWidget = FOwner then
2303     FOwner := nil;
2304 end;
2305 
2306 {------------------------------------------------------------------------------
2307   Function: TQtWidget.Destroy
2308   Params:  None
2309   Returns: Nothing
2310  ------------------------------------------------------------------------------}
2311 destructor TQtWidget.Destroy;
2312 begin
2313   DeinitializeWidget;
2314 
2315   if FProps <> nil then
2316   begin
2317     FProps.Free;
2318     FProps:=nil;
2319   end;
2320 
2321   if FPaintData.ClipRegion <> nil then
2322   begin
2323     QRegion_Destroy(FPaintData.ClipRegion);
2324     FPaintData.ClipRegion:=nil;
2325   end;
2326 
2327   if FOwner <> nil then
2328     FOwner.DestroyNotify(Self);
2329 
2330   inherited Destroy;
2331 end;
2332 
2333 {------------------------------------------------------------------------------
2334   Function: TQtWidget.GetContainerWidget
2335   Params:  None
2336   Returns: The widget of the control on top of which other controls
2337            should be placed
2338  ------------------------------------------------------------------------------}
GetContainerWidgetnull2339 function TQtWidget.GetContainerWidget: QWidgetH;
2340 begin
2341   if FCentralWidget <> nil then
2342     Result := FCentralWidget
2343   else
2344     Result := Widget;
2345 end;
2346 
2347 procedure TQtWidget.Release;
2348 begin
2349   LCLObject := nil;
2350   {always hide widget since we use QObject_deleteLater(). issue #27781}
2351   if (Widget <> nil) then
2352     Hide;
2353   inherited Release;
2354 end;
2355 
2356 procedure TQtWidget.Destroyed; cdecl;
2357 begin
2358   Widget := nil;
2359   Release;
2360 end;
2361 
TQtWidget.WinIDNeedednull2362 function TQtWidget.WinIDNeeded: boolean;
2363 begin
2364   Result := False;
2365 end;
2366 
2367 {------------------------------------------------------------------------------
2368   Function: TQtWidget.CanAdjustClientRectOnResize
2369   Params:  None
2370   Returns: Boolean
2371   Checks if our control can call LCLObject.DoAdjustClientRect from SlotResize.
2372   This avoids deadlocks with autosizing.
2373  ------------------------------------------------------------------------------}
CanAdjustClientRectOnResizenull2374 function TQtWidget.CanAdjustClientRectOnResize: Boolean;
2375 begin
2376   Result := True;
2377 end;
2378 
CanChangeFontColornull2379 function TQtWidget.CanChangeFontColor: Boolean;
2380 begin
2381   Result := True;
2382 end;
2383 
2384 {------------------------------------------------------------------------------
2385   Function: TQtWidget.CanSendLCLMessage
2386   Params:  None
2387   Returns: Boolean
2388   If returns FALSE then we should not send any message to LCL since our
2389   LCLObject is probably being destroyed or it has csDestroying flag on.
2390   This is very important to know before calling NotifyApplicationUserInput,
2391   which is often called from mouse & keyboard events.
2392  ------------------------------------------------------------------------------}
CanSendLCLMessagenull2393 function TQtWidget.CanSendLCLMessage: Boolean;
2394 begin
2395   Result := (LCLObject <> nil) and (Widget <> nil) and getVisible and
2396     not ((csDestroying in LCLObject.ComponentState) or
2397          (csDestroyingHandle in LCLObject.ControlState));
2398 end;
2399 
2400 {------------------------------------------------------------------------------
2401   Function: TQtWidget.CanPaintBackground
2402   Params:  None
2403   Returns: Boolean
2404   Makes decision if control background need to be painted.
2405   Look at SlotPaintBg().
2406  ------------------------------------------------------------------------------}
TQtWidget.CanPaintBackgroundnull2407 function TQtWidget.CanPaintBackground: Boolean;
2408 begin
2409   {TODO: we must override this function for some classes
2410    until clDefault is implemented in LCL.Then we can easy
2411    ask EqualTQColor() for diff between
2412    Palette.DefaultColor and current LCLObject.Color}
2413   Result := False;
2414 end;
2415 
2416 procedure TQtWidget.DelayResizeEvent(AWidget: QWidgetH; ANewSize: TSize);
2417 var
2418   ALCLResizeEvent: QLCLMessageEventH;
2419 begin
2420   ALCLResizeEvent := QLCLMessageEvent_create(LCLQt_DelayResizeEvent, 0, PtrUInt(ANewSize.cx), PtrUInt(ANewSize.cy), 0);
2421   QCoreApplication_postEvent(AWidget, ALCLResizeEvent);
2422 end;
2423 
2424 {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtKeys)}
EventTypeToStrnull2425 function EventTypeToStr(Event:QEventH):string;
2426 // Qt 3 events
2427 const
2428   QEventChildInsertedRequest = 67;
2429   QEventChildInserted = 70;
2430   QEventLayoutHint = 72;
2431 begin
2432   case QEvent_type(Event) of
2433     QEventNone: result:='QEventNone';
2434     QEventTimer: result:='QEventTimer';
2435     QEventMouseButtonPress: result:='QEventMouseButtonPress';
2436     QEventMouseButtonRelease: result:='QEventMouseButtonRelease';
2437     QEventMouseButtonDblClick: result:='QEventMouseButtonDblClick';
2438     QEventMouseMove: result:='QEventMouseMove';
2439     QEventKeyPress: result:='QEventKeyPress';
2440     QEventKeyRelease: result:='QEventKeyRelease';
2441     QEventFocusIn: result:='QEventFocusIn';
2442     QEventFocusOut: result:='QEventFocusOut';
2443     QEventEnter: result:='QEventEnter';
2444     QEventLeave: result:='QEventLeave';
2445     QEventPaint: result:='QEventPaint';
2446     QEventMove: result:='QEventMove';
2447     QEventResize: result:='QEventResize';
2448     QEventCreate: result:='QEventCreate';
2449     QEventDestroy: result:='QEventDestroy';
2450     QEventShow: result:='QEventShow';
2451     QEventHide: result:='QEventHide';
2452     QEventClose: result:='QEventClose';
2453     QEventQuit: result:='QEventQuit';
2454     QEventParentChange: result:='QEventParentChange';
2455     QEventThreadChange: result:='QEventThreadChange';
2456     QEventWindowActivate: result:='QEventWindowActivate';
2457     QEventWindowDeactivate: result:='QEventWindowDeactivate';
2458     QEventShowToParent: result:='QEventShowToParent';
2459     QEventHideToParent: result:='QEventHideToParent';
2460     QEventWheel: result:='QEventWheel';
2461     QEventWindowTitleChange: result:='QEventWindowTitleChange';
2462     QEventWindowIconChange: result:='QEventWindowIconChange';
2463     QEventApplicationWindowIconChange: result:='QEventApplicationWindowIconChange';
2464     QEventApplicationFontChange: result:='QEventApplicationFontChange';
2465     QEventApplicationLayoutDirectionChange: result:='QEventApplicationLayoutDirectionChange';
2466     QEventApplicationPaletteChange: result:='QEventApplicationPaletteChange';
2467     QEventPaletteChange: result:='QEventPaletteChange';
2468     QEventClipboard: result:='QEventClipboard';
2469     QEventSpeech: result:='QEventSpeech';
2470     QEventMetaCall: result:='QEventMetaCall';
2471     QEventSockAct: result:='QEventSockAct';
2472     QEventShortcutOverride: result:='QEventShortcutOverride';
2473     QEventDeferredDelete: result:='QEventDeferredDelete';
2474     QEventDragEnter: result:='QEventDragEnter';
2475     QEventDragMove: result:='QEventDragMove';
2476     QEventDragLeave: result:='QEventDragLeave';
2477     QEventDrop: result:='QEventDrop';
2478     QEventDragResponse: result:='QEventDragResponse';
2479     //    QEventChildInsertedRequest: result:='(Qt3) QEventChildAdded'; //qt3
2480     QEventChildAdded: result:='QEventChildAdded';
2481     QEventChildPolished: result:='QEventChildPolished';
2482     //    QEventChildInserted: result:='(Qt3) QEventChildAdded'; // qt3
2483     //    QEventLayoutHint: result:='(Qt3) QEventChildAdded'; // qt3
2484     QEventChildRemoved: result:='QEventChildRemoved';
2485     QEventShowWindowRequest: result:='QEventShowWindowRequest';
2486     QEventPolishRequest: result:='QEventPolishRequest';
2487     QEventPolish: result:='QEventPolish';
2488     QEventLayoutRequest: result:='QEventLayoutRequest';
2489     QEventUpdateRequest: result:='QEventUpdateRequest';
2490     QEventUpdateLater: result:='QEventUpdateLater';
2491     QEventEmbeddingControl: result:='QEventEmbeddingControl';
2492     QEventActivateControl: result:='QEventActivateControl';
2493     QEventDeactivateControl: result:='QEventDeactivateControl';
2494     QEventContextMenu: result:='QEventContextMenu';
2495     QEventInputMethod: result:='QEventInputMethod';
2496     QEventTabletMove: result:='QEventTabletMove';
2497     QEventLocaleChange: result:='QEventLocaleChange';
2498     QEventLanguageChange: result:='QEventLanguageChange';
2499     QEventLayoutDirectionChange: result:='QEventLayoutDirectionChange';
2500     QEventStyle: result:='QEventStyle';
2501     QEventTabletPress: result:='QEventTabletPress';
2502     QEventTabletRelease: result:='QEventTabletRelease';
2503     QEventOkRequest: result:='QEventOkRequest';
2504     QEventHelpRequest: result:='QEventHelpRequest';
2505     QEventIconDrag: result:='QEventIconDrag';
2506     QEventFontChange: result:='QEventFontChange';
2507     QEventEnabledChange: result:='QEventEnabledChange';
2508     QEventActivationChange: result:='QEventActivationChange';
2509     QEventStyleChange: result:='QEventStyleChange';
2510     QEventIconTextChange: result:='QEventIconTextChange';
2511     QEventModifiedChange: result:='QEventModifiedChange';
2512     QEventWindowBlocked: result:='QEventWindowBlocked';
2513     QEventWindowUnblocked: result:='QEventWindowUnblocked';
2514     QEventWindowStateChange: result:='QEventWindowStateChange';
2515     QEventMouseTrackingChange: result:='QEventMouseTrackingChange';
2516     QEventToolTip: result:='QEventToolTip';
2517     QEventWhatsThis: result:='QEventWhatsThis';
2518     QEventStatusTip: result:='QEventStatusTip';
2519     QEventActionChanged: result:='QEventActionChanged';
2520     QEventActionAdded: result:='QEventActionAdded';
2521     QEventActionRemoved: result:='QEventActionRemoved';
2522     QEventFileOpen: result:='QEventFileOpen';
2523     QEventShortcut: result:='QEventShortcut';
2524     QEventWhatsThisClicked: result:='QEventWhatsThisClicked';
2525     QEventToolBarChange: result:='QEventToolBarChange';
2526     QEventApplicationActivated: result:='QEventApplicationActivated';
2527     QEventApplicationDeactivated: result:='QEventApplicationDeactivated';
2528     QEventQueryWhatsThis: result:='QEventQueryWhatsThis';
2529     QEventEnterWhatsThisMode: result:='QEventEnterWhatsThisMode';
2530     QEventLeaveWhatsThisMode: result:='QEventLeaveWhatsThisMode';
2531     QEventZOrderChange: result:='QEventZOrderChange';
2532     QEventHoverEnter: result:='QEventHoverEnter';
2533     QEventHoverLeave: result:='QEventHoverLeave';
2534     QEventHoverMove: result:='QEventHoverMove';
2535     QEventParentAboutToChange: result:='QEventParentAboutToChange';
2536     QEventWinEventAct: result:='QEventWinEventAct';
2537     QEventAcceptDropsChange: result:='QEventAcceptDropsChange';
2538     QEventZeroTimerEvent: result:='QEventZeroTimerEvent';
2539     QEventNonClientAreaMouseMove: result:='QEventNonClientAreaMouseMove';
2540     QEventNonClientAreaMouseButtonPress: result:='QEventNonClientAreaMouseButtonPress';
2541     QEventNonClientAreaMouseButtonRelease: result:='QEventNonClientAreaMouseButtonRelease';
2542     QEventNonClientAreaMouseButtonDblClick: result:='QEventNonClientAreaMouseButtonDblClick';
2543     QEventMacSizeChange: result := 'QEventMacSizeChange';
2544     QEventContentsRectChange: result := 'QEventContentsRectChange';
2545     QEventMacGLWindowChange: result := 'QEventMacGLWindowChange';
2546     QEventFutureCallOut: result := 'QEventFutureCallOut';
2547     QEventGraphicsSceneResize: result := 'QEventGraphicsSceneResize';
2548     QEventGraphicsSceneMove: result := 'QEventGraphicsSceneMove';
2549     QEventCursorChange: result := 'QEventCursorChange';
2550     QEventToolTipChange: result := 'QEventToolTipChange';
2551     QEventNetworkReplyUpdated: result := 'QEventNetworkReplyUpdated';
2552     QEventGrabMouse: result := 'QEventGrabMouse';
2553     QEventUngrabMouse: result := 'QEventUngrabMouse';
2554     QEventGrabKeyboard: result := 'QEventGrabKeyboard';
2555     QEventUngrabKeyboard: result := 'QEventUngrabKeyboard';
2556     QEventUser: result:='QEventUser';
2557     QEventMaxUser: result:='QEventMaxUser';
2558     200: Result := 'QEventCloseSoftwareInputPanel';
2559     203: Result := 'QEventWinIdChange';
2560   else
2561     Result := Format('Unknown event: %d', [QEvent_type(Event)]);
2562   end;
2563 end;
2564 {$ENDIF}
2565 
2566 {------------------------------------------------------------------------------
2567   Function: TQtWidget.EventFilter
2568   Params:  None
2569   Returns: Nothing
2570  ------------------------------------------------------------------------------}
TQtWidget.EventFilternull2571 function TQtWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
2572 var
2573   {$IFDEF MSWINDOWS}
2574   AContextEvent: QContextMenuEventH;
2575   {$ENDIF}
2576   QColor, OldColor: TQColor;
2577   ColorRef: TColorRef;
2578   QtEdit: IQtEdit;
2579   R: TRect;
2580   Pt: TQtPoint;
2581   ANewSize: TSize;
2582   AResizeEvent: QResizeEventH;
2583 begin
2584   Result := False;
2585   QEvent_accept(Event);
2586 
2587   BeginEventProcessing;
2588   try
2589     {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
2590     WriteLn('TQtWidget.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
2591       ' LCLObject=', dbgsName(LCLObject),
2592       ' Event=', EventTypeToStr(Event),' inUpdate=',InUpdate);
2593     {$endif}
2594 
2595     if LCLObject <> nil then
2596     begin
2597       case QEvent_type(Event) of
2598         LCLQt_DelayResizeEvent:
2599         begin
2600           ANewSize.cx := LongInt(QLCLMessageEvent_getWParam(QLCLMessageEventH(Event)));
2601           ANewSize.cy := LongInt(QLCLMessageEvent_getLParam(QLCLMessageEventH(Event)));
2602           AResizeEvent := QResizeEvent_create(@ANewSize, @ANewSize);
2603           try
2604             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2605             DebugLn('>LCLQt_DelayResizeEvent: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
2606             {$ENDIF}
2607             SlotResize(AResizeEvent);
2608             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2609             DebugLn('<LCLQt_DelayResizeEvent: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
2610             {$ENDIF}
2611           finally
2612             QResizeEvent_destroy(AResizeEvent);
2613           end;
2614           Result := True;
2615         end;
2616         QEventFontChange:
2617           begin
2618             //explanation for this event usage: issue #19695
2619             if not (qtwsFontUpdating in WidgetState) and
2620               not LCLObject.IsParentFont then
2621             begin
2622               if Assigned(FWidgetLCLFont) then
2623                 AssignQtFont(FWidgetLCLFont.FHandle, QWidget_font(QWidgetH(Sender)))
2624               else
2625                 AssignQtFont(FWidgetDefaultFont.FHandle, QWidget_font(QWidgetH(Sender)));
2626             end;
2627           end;
2628         QEventEnabledChange:
2629           begin
2630             // if we are disabled, imediatelly invalidate widgetAt cache
2631             if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
2632               QtWidgetSet.InvalidateWidgetAtCache
2633             else
2634             if QtWidgetSet.IsValidWidgetAtCachePointer then
2635             begin
2636               Pt := QtPoint(0, 0);
2637               QWidget_mapToGlobal(Widget, @Pt, @Pt);
2638               QWidget_geometry(Widget, @R);
2639               R := Rect(Pt.X, Pt.Y, Pt.X + (R.Right - R.Left), Pt.Y + (R.Bottom - R.Top));
2640               if PtInRect(R, QtWidgetSet.GetWidgetAtCachePoint) then
2641                 QtWidgetSet.InvalidateWidgetAtCache;
2642             end;
2643             // issue #25922
2644             if Assigned(FPalette) and Assigned(LCLObject) then
2645             begin
2646               // DebugLn('QEventEnabledChange: ',dbgsName(LCLObject),' enabled ',dbgs(getEnabled));
2647               if not getEnabled then
2648                 Palette.setTextColor(@Palette.DisabledTextColor)
2649               else
2650                 setInitialFontColor(LCLObject);
2651             end;
2652           end;
2653         QEventShow:
2654           begin
2655             SlotShow(True);
2656             {$IFDEF MSWINDOWS}
2657             if (qtwsInsideRightMouseButtonPressEvent in FWidgetState) and
2658                (qtwsHiddenInsideRightMouseButtonPressEvent in FWidgetState) then
2659             begin
2660               Exclude(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
2661               Exclude(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
2662               if (LastMouse.WinControl = LCLObject) and
2663                 (QGUIApplication_mouseButtons and QtRightButton <> 0) then
2664               begin
2665                 Pt := QtPoint(LastMouse.MousePos.X, LastMouse.MousePos.Y);
2666                 AContextEvent := QContextMenuEvent_create(QContextMenuEventMouse, @Pt);
2667                 QCoreApplication_postEvent(Sender, AContextEvent);
2668                 LastMouse.MousePos := Point(Pt.X, Pt.Y);
2669               end;
2670             end;
2671             {$ENDIF}
2672           end;
2673         QEventHide:
2674           begin
2675             if QWidget_mouseGrabber() = Widget then
2676               ReleaseCapture;
2677             SlotShow(False);
2678             {$IFDEF MSWINDOWS}
2679             if qtwsInsideRightMouseButtonPressEvent in FWidgetState then
2680               Include(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
2681             {$ENDIF}
2682           end;
2683         QEventClose:
2684           if not SlotClose then
2685           begin
2686             QEvent_ignore(Event);
2687             Result := True;
2688           end;
2689         QEventDestroy: SlotDestroy;
2690         QEventEnter,
2691         QEventLeave: Result := SlotMouseEnter(Sender, Event);
2692 
2693         QEventHoverEnter,
2694         QEventHoverLeave,
2695         QEventHoverMove: Result := SlotHover(Sender, Event);
2696 
2697         QEventDrop,
2698         QEventDragMove,
2699         QEventDragEnter:
2700         begin
2701           Result := getAcceptDropFiles;
2702           if (Result) and (QEvent_type(Event) = QEventDrop) then
2703             Result := slotDropFiles(Sender, Event);
2704         end;
2705 
2706         QEventKeyPress,
2707         QEventKeyRelease:
2708           begin
2709             {non-spontaneous key events are garbage in Qt >= 4.4 for non edits}
2710             Result := QEvent_spontaneous(Event) or Supports(Self, IQtEdit, QtEdit);
2711             if Result then
2712               Result := SlotKey(Sender, Event) or (LCLObject is TCustomControl);
2713           end;
2714 
2715         //Dead keys (used to compose chars like "ó" by pressing 'o)  do not trigger EventKeyPress
2716         //and therefore no KeyDown,Utf8KeyPress,KeyPress
2717         QEventInputMethod:
2718           begin
2719             Result := SlotInputMethod(Sender, Event);
2720           end;
2721 
2722         QEventMouseButtonPress,
2723         QEventMouseButtonRelease,
2724         QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
2725         QEventMouseMove: Result := SlotMouseMove(Sender, Event);
2726         QEventWheel:
2727           begin
2728             if not getEnabled then
2729             begin
2730               QEvent_ignore(Event);
2731               QWidget_setAttribute(QWidgetH(Sender), QtWA_NoMousePropagation, False);
2732             end else
2733               Result := SlotMouseWheel(Sender, Event);
2734           end;
2735         QEventMove: SlotMove(Event);
2736         QEventResize: SlotResize(Event);
2737         QEventContentsRectChange:
2738         begin
2739           if ChildOfComplexWidget = ccwScrollingWinControl then
2740           begin
2741             // Result := (caspComputingBounds in LCLObject.AutoSizePhases);
2742             QEvent_ignore(Event);
2743           end;
2744           if LCLObject.ClientRectNeedsInterfaceUpdate then
2745           begin
2746             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
2747             if ChildOfComplexWidget = ccwScrollingWinControl then
2748             begin
2749               if Self is TQtViewport then
2750                 QWidget_rect(Widget, @R)
2751               else
2752                 QWidget_rect(TQtAbstractScrollArea(Self).viewportWidget, @R);
2753               DebugLn('WARNING: QEventContentsRectChange(',dbgsName(Self),') adjusting rect for ',dbgsName(LCLObject),' PHASE ? ',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' inUpdate=',dbgs(inUpdate),' Time: ',dbgs(GetTickCount),' Mapped ',dbgs(testAttribute(QtWA_Mapped)),' SCROLLINGWIN R=',dbgs(R),' LCLObject R=',dbgs(LCLObject.ClientRect),' ***InResize=',dbgs(InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent)));
2754             end else
2755               DebugLn('WARNING: QEventContentsRectChange(',dbgsName(Self),') adjusting rect for ',dbgsName(LCLObject),' PHASE ? ',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' inUpdate=',dbgs(inUpdate),' Time: ',dbgs(GetTickCount),' Mapped ',dbgs(testAttribute(QtWA_Mapped)),' clientRect=',dbgs(getClientBounds));
2756             {$ENDIF}
2757             if not (caspComputingBounds in LCLObject.AutoSizePhases) then
2758             begin
2759               {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2760               DebugLn('  QEventContentsRectChange(',dbgsName(LCLObject),' call DoAdjustClientRectChange !');
2761               {$ENDIF}
2762               if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
2763               else
2764                 LCLObject.DoAdjustClientRectChange(True);
2765             end else
2766             begin
2767               {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2768               DebugLn('  QEventContentsRectChange(',dbgsName(LCLObject),' call InvalidatePrefferedSize !');
2769               {$ENDIF}
2770               if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
2771               else
2772                 LCLObject.InvalidatePreferredSize;
2773             end;
2774           end;
2775         end;
2776         QEventPaint:
2777           begin
2778             if canPaintBackground and (LCLObject.Color <> clDefault) then
2779               SlotPaintBg(Sender, Event);
2780             if FHasPaint then
2781               SlotPaint(Sender, Event);
2782           end;
2783         QEventContextMenu:
2784             Result := SlotContextMenu(Sender, Event);
2785         QEventNonClientAreaMouseButtonPress:
2786           begin
2787             SlotNCMouse(Sender, Event);
2788           end;
2789         QEventPaletteChange,
2790         QEventStyleChange:
2791           begin
2792             if (FPalette <> nil) and not InUpdate and not Palette.InReload then
2793             begin
2794               OldColor := Palette.CurrentColor;
2795               // now set our fpalette ColorRef from LCL
2796               if LCLObject.Color <> clDefault then
2797               begin
2798                 ColorRef := ColorToRGB(LCLObject.Color);
2799                 QColor_fromRgb(@QColor,Red(ColorRef),Green(ColorRef),Blue(ColorRef));
2800               end else
2801                 QColor := Palette.DefaultColor;
2802               if not EqualTQColor(OldColor, QColor) then
2803               begin
2804                 Palette.ReloadPaletteBegin;
2805                 try
2806                   SetColor(@QColor);
2807                   Result := True;
2808                   QEvent_accept(Event);
2809                 finally
2810                   Palette.ReloadPaletteEnd;
2811                 end;
2812               end;
2813             end;
2814           end;
2815         QEventQueryWhatsThis: Result := True;
2816         QEventWhatsThis:
2817           begin
2818             SlotWhatsThis(Sender, Event);
2819             // TODO: we need to stop event by Result := True; but then we also need
2820             // to ask qt to leave Whats This mode. Currently we have no means to do so
2821           end;
2822         QEventLCLMessage:
2823           begin
2824             SlotLCLMessage(Sender, Event);
2825             Result := True;
2826           end;
2827       else
2828         QEvent_ignore(Event);
2829       end;
2830     end
2831     else
2832       QEvent_ignore(Event);
2833 
2834     {fixes #14544 and others when we loose our LCLObject
2835      after delivering message to LCL.}
2836     if (LCLObject = nil) and
2837        ((QEvent_type(Event) = QEventMouseButtonPress) or
2838        (QEvent_type(Event) = QEventMouseButtonRelease) or
2839        (QEvent_type(Event) = QEventMouseButtonDblClick) or
2840        (QEvent_type(Event) = QEventMouseMove) or
2841        (QEvent_type(Event) = QEventHoverEnter) or
2842        (QEvent_type(Event) = QEventHoverLeave) or
2843        (QEvent_type(Event) = QEventHoverMove) or
2844        (QEvent_type(Event) = QEventKeyPress) or
2845        (QEvent_type(Event) = QEventKeyRelease)) then
2846       Result := True;
2847   finally
2848     EndEventProcessing;
2849   end;
2850 end;
2851 
getAcceptDropFilesnull2852 function TQtWidget.getAcceptDropFiles: Boolean;
2853 var
2854   Form: TCustomForm;
2855 begin
2856   Result := False;
2857   Form := GetParentForm(LCLObject);
2858   if Assigned(Form) and (Form.HandleAllocated) then
2859     Result := TQtMainWindow(Form.Handle).getAcceptDropFiles;
2860 end;
2861 
measureTextnull2862 function TQtWidget.measureText(AText: WideString; AFlags: cardinal): TRect;
2863 var
2864   AMetrics: QFontMetricsH;
2865   AFont: QFontH;
2866 begin
2867   Result := Rect(0, 0, 0, 0);
2868   if Assigned(LCLObject) and Assigned(LCLObject.Font) and
2869     LCLObject.Font.HandleAllocated then
2870       AFont := TQtFont(LCLObject.Font.Reference.Handle).FHandle
2871   else
2872     AFont := QWidget_font(Widget);
2873   AMetrics := QFontMetrics_create(AFont);
2874   try
2875     QFontMetrics_boundingRect(AMetrics, @Result, @AText);
2876   finally
2877     QFontMetrics_destroy(AMetrics);
2878   end;
2879 end;
2880 
2881 procedure TQtWidget.SetNoMousePropagation(Sender: QWidgetH;
2882   const ANoMousePropagation: Boolean);
2883 begin
2884   QWidget_setAttribute(Sender, QtWA_NoMousePropagation, ANoMousePropagation);
2885 end;
2886 
2887 {------------------------------------------------------------------------------
2888   Function: TQtWidget.SetLCLFont
2889   Params:  None
2890   Returns: Nothing
2891   Sets FWidgetLCLFont , font which is different from FWidgetDefaultFont
2892   so we can keep track over it inside QEventFontChange.
2893   This routine does nothing if called outside of TQtWSControl.SetFont,
2894   since qtwdFontUpdating must be in WidgetState
2895  ------------------------------------------------------------------------------}
2896 procedure TQtWidget.SetLCLFont(AFont: TQtFont);
2897 begin
2898   if not (qtwsFontUpdating in FWidgetState) then
2899     exit;
2900   if Assigned(FWidgetLCLFont) then
2901     FreeThenNil(FWidgetLCLFont);
2902   if not IsFontEqual(FWidgetDefaultFont, AFont) and (AFont.FHandle <> nil) then
2903     FWidgetLCLFont := TQtFont.Create(AFont.FHandle);
2904 end;
2905 
2906 {------------------------------------------------------------------------------
2907   Function: TQtWidget.SlotShow
2908   Params:  None
2909   Returns: Nothing
2910  ------------------------------------------------------------------------------}
2911 procedure TQtWidget.SlotShow(vShow: Boolean); cdecl;
2912 var
2913   Msg: TLMShowWindow;
2914 begin
2915   {$ifdef VerboseQt}
2916     WriteLn('TQtWidget.SlotShow Name', LCLObject.Name, ' vShow: ', dbgs(vShow));
2917   {$endif}
2918 
2919   {do not pass message to LCL if LCL setted up control visibility}
2920   if inUpdate then
2921     exit;
2922 
2923   FillChar(Msg{%H-}, SizeOf(Msg), #0);
2924 
2925   Msg.Msg := LM_SHOWWINDOW;
2926   Msg.Show := vShow;
2927 
2928   DeliverMessage(Msg);
2929 end;
2930 
2931 {------------------------------------------------------------------------------
2932   Function: TQtWidget.Close
2933   Params:  None
2934   Returns: Nothing
2935 
2936   Note: LCL uses LM_CLOSEQUERY to set the form visibility and if we don�t send this
2937  message, you won�t be able to show a form twice.
2938  ------------------------------------------------------------------------------}
SlotClosenull2939 function TQtWidget.SlotClose: Boolean; cdecl;
2940 var
2941   Msg : TLMessage;
2942 begin
2943   {$ifdef VerboseQt}
2944     WriteLn('TQtWidget.SlotClose');
2945   {$endif}
2946   FillChar(Msg{%H-}, SizeOf(Msg), 0);
2947 
2948   Msg.Msg := LM_CLOSEQUERY;
2949 
2950   DeliverMessage(Msg);
2951 
2952   Result := False;
2953 end;
2954 
2955 {------------------------------------------------------------------------------
2956   Function: TQtWidget.SlotDestroy
2957   Params:  None
2958   Returns: Nothing
2959 
2960   Currently commented because it was raising exception on software exit
2961  ------------------------------------------------------------------------------}
2962 procedure TQtWidget.SlotDestroy; cdecl;
2963 var
2964   Msg: TLMessage;
2965 begin
2966   {$ifdef VerboseQt}
2967     WriteLn('TQtWidget.SlotDestroy');
2968   {$endif}
2969 
2970   FillChar(Msg{%H-}, SizeOf(Msg), #0);
2971   Msg.Msg := LM_DESTROY;
2972   DeliverMessage(Msg);
2973   Release;
2974 end;
2975 
slotDropFilesnull2976 function TQtWidget.slotDropFiles(Sender: QObjectH; Event: QEventH): Boolean;
2977 var
2978   MimeData: QMimeDataH;
2979   QStrList: QStringListH;
2980   ByteArr: QByteArrayH;
2981   i: Integer;
2982   WStr: WideString;
2983   GotFiles: Boolean;
2984   FilesList: TStrings;
2985   Files: Array of String;
2986   ParentForm: TCustomForm;
2987   Url: QUrlH;
2988 begin
2989   Result := False;
2990   GotFiles := False;
2991   MimeData := QDropEvent_mimeData(QDropEventH(Event));
2992   QStrList := QStringList_create();
2993   try
2994     QMimeData_formats(MimeData, QStrList);
2995     for i := QStringList_size(QStrList) - 1 downto 0 do
2996     begin
2997       QStringList_at(QStrList, @WStr, i);
2998       GotFiles := (WStr = 'text/plain') or (WStr = 'text/uri-list');
2999       if GotFiles then
3000         break;
3001     end;
3002   finally
3003     QStringList_destroy(QStrList);
3004   end;
3005   if not GotFiles then
3006     exit;
3007   ByteArr := QByteArray_create();
3008   try
3009     QMimeData_data(MimeData, ByteArr, @WStr);
3010     if not QByteArray_isNull(ByteArr) then
3011     begin
3012       WStr := QByteArray_constData(ByteArr);
3013       FilesList := TStringList.Create;
3014       try
3015         FilesList.Text := UTF16ToUTF8(WStr);
3016 
3017         if (FilesList.Count > 0) and
3018           ( (FilesList[FilesList.Count-1] = #0)
3019             or
3020             (FilesList[FilesList.Count-1] = '') ) then
3021           SetLength(Files, FilesList.Count - 1)
3022         else
3023           SetLength(Files, FilesList.Count);
3024         for i := 0 to High(Files) do
3025         begin
3026           WStr := GetUTF8String(FilesList.Strings[i]);
3027           Url := QUrl_create(@WStr);
3028           QUrl_toLocalFile(Url, @WStr);
3029           Files[i] := UTF16ToUTF8(WStr);
3030           QUrl_destroy(Url);
3031         end;
3032       finally
3033         FilesList.Free;
3034       end;
3035       QDropEvent_setDropAction(QDropEventH(Event), QtCopyAction);
3036       QDropEvent_acceptProposedAction(QDropEventH(Event));
3037 
3038       Application.IntfDropFiles(Files);
3039       if ClassType = TQtMainWindow then
3040         TCustomForm(LCLObject).IntfDropFiles(Files)
3041       else
3042       begin
3043         ParentForm := TCustomForm(LCLObject.IntfGetDropFilesTarget);
3044         if ParentForm is TCustomForm then
3045           ParentForm.IntfDropFiles(Files);
3046       end;
3047 
3048       Result := True;
3049     end;
3050   finally
3051     QByteArray_destroy(ByteArr);
3052   end;
3053 end;
3054 
SlotHovernull3055 function TQtWidget.SlotHover(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3056 var
3057   Msg: TLMessage;
3058   MouseMsg: TLMMouseMove absolute Msg;
3059   MousePos: TQtPoint;
3060 begin
3061   Result := False;
3062   if not CanSendLCLMessage then
3063     Exit(True);
3064 
3065   if (QGUIApplication_mouseButtons() = 0) and
3066      not QWidget_hasMouseTracking(QWidgetH(Sender)) then // in other case MouseMove will be hooked
3067   begin
3068     FillChar(Msg{%H-}, SizeOf(Msg), #0);
3069 
3070     // MousePos :=
3071     QHoverEvent_pos(QHoverEventH(Event), @MousePos);
3072     OffsetMousePos(@MousePos);
3073 
3074     case QEvent_type(Event) of
3075       QEventHoverEnter: Msg.Msg := LM_MOUSEENTER;
3076       QEventHoverLeave: Msg.Msg := LM_MOUSELEAVE;
3077       QEventHoverMove:
3078         begin
3079           MouseMsg.Msg := LM_MOUSEMOVE;
3080           MouseMsg.XPos := SmallInt(MousePos.X);
3081           MouseMsg.YPos := SmallInt(MousePos.Y);
3082         end;
3083     end;
3084     NotifyApplicationUserInput(LCLObject, Msg.Msg);
3085     if not CanSendLCLMessage then
3086       exit(True);
3087     DeliverMessage(Msg);
3088     SetNoMousePropagation(QWidgetH(Sender), True);
3089   end;
3090 end;
3091 
3092 {------------------------------------------------------------------------------
3093   Function: TQtWidget.SlotKey
3094   Params:  None
3095   Returns: Nothing
3096  ------------------------------------------------------------------------------}
SlotKeynull3097 function TQtWidget.SlotKey(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3098 const
3099   CN_KeyDownMsgs: array[Boolean] of UINT = (CN_KEYDOWN, CN_SYSKEYDOWN);
3100   CN_KeyUpMsgs: array[Boolean] of UINT = (CN_KEYUP, CN_SYSKEYUP);
3101   LM_KeyDownMsgs: array[Boolean] of UINT = (LM_KEYDOWN, LM_SYSKEYDOWN);
3102   LM_KeyUpMsgs: array[Boolean] of UINT = (LM_KEYUP, LM_SYSKEYUP);
3103   CN_CharMsg: array[Boolean] of UINT = (CN_CHAR, CN_SYSCHAR);
3104   LM_CharMsg: array[Boolean] of UINT = (LM_CHAR, LM_SYSCHAR);
3105 var
3106   KeyMsg: TLMKey;
3107   CharMsg: TLMChar;
3108   Modifiers: QtKeyboardModifiers;
3109   IsSysKey: Boolean;
3110   Text: WideString;
3111   UTF8Text: String; // use to prevent 3 time convertion from WideString to utf8 string
3112   UTF8Char: TUTF8Char;
3113   ACharCode: Word;
3114   AKeyCode: Word;
3115   LCLModifiers: Word;
3116   {$IFDEF UNIX}
3117   ScanCode: LongWord;
3118   {$ENDIF}
3119   AChar: Char;
3120   AKeyEvent: QKeyEventH;
3121   GlobalAction: Integer;
3122   {$IFDEF VerboseQtKeys}
3123   s: String;
3124   s1: String;
3125   NativeModifiers: LongWord;
3126   {$ENDIF}
3127 
3128   function IsControlKey: Boolean;
3129   var
3130     AQtKey: Cardinal;
3131   begin
3132     // do not send UTF8KeyPress for control keys
3133     AQtKey := QKeyEvent_key(QKeyEventH(Event));
3134 
3135     // Enter, Return and Backspace should be sent to LCL in UTF8KeyPress,
3136     // so skip them here
3137 
3138     Result := (AQtKey = QtKey_Backtab) or // issue #35448
3139       // ((AQtKey >= QtKey_Escape) and (AQtKey <= QtKey_Backtab)) or
3140       ((AQtKey >= QtKey_Insert) and (AQtKey <= QtKey_Clear)) or
3141       ((AQtKey >= QtKey_Home) and (AQtKey <= QtKey_PageDown)) or
3142       ((AQtKey >= QtKey_F1) and (AQtKey <= QtKey_Direction_L)) or
3143       (AQtKey = QtKey_Direction_R);
3144   end;
3145 
3146   function EatArrowKeys: Boolean;
3147   var
3148     AQtKey: Cardinal;
3149   begin
3150     AQtKey := QKeyEvent_key(QKeyEventH(Event));
3151     Result := not ProcessArrowKeys and ((AQtKey = QtKey_Left) or (AQtKey = QtKey_Right)
3152       or (AQtKey = QtKey_Up) or (AQtKey = QtKey_Down));
3153   end;
3154 
3155   function SendChangedKey: boolean;
3156   begin
3157     if UTF8Char <> UTF8Text then
3158       Text := UTF8ToUTF16(Utf8Char)
3159     else
3160     if Word(AChar) <> CharMsg.CharCode then
3161       Text := Char(CharMsg.CharCode);
3162 
3163     AKeyEvent := QKeyEvent_create( {ExtendedKeyEvent(}
3164       QEvent_type(Event),
3165       LCLKeyToQtKey(KeyMsg.CharCode),
3166       Modifiers,
3167       0,
3168       KeyMsg.CharCode,
3169       0,
3170       @Text,
3171       QKeyEvent_isAutoRepeat(QKeyEventH(Event)),
3172       QKeyEvent_count(QKeyEventH(Event))
3173       );
3174     try
3175       Result := QObject_event(Sender, AKeyEvent);
3176     finally
3177       QKeyEvent_destroy(AKeyEvent);
3178     end;
3179 
3180   end;
3181 
3182 begin
3183   {$ifdef VerboseQt}
3184     DebugLn('TQtWidget.SlotKey ', dbgsname(LCLObject));
3185   {$endif}
3186 
3187   Result := True;
3188 
3189   if not CanSendLCLMessage then
3190     exit;
3191 
3192   FillChar(KeyMsg{%H-}, SizeOf(KeyMsg), #0);
3193   FillChar(CharMsg{%H-}, SizeOf(CharMsg), #0);
3194   UTF8Text := '';
3195   UTF8Char := '';
3196   AChar := #0;
3197 
3198   // Detects special keys (shift, alt, control, etc)
3199   Modifiers := QKeyEvent_modifiers(QKeyEventH(Event));
3200   {$IFDEF HASX11}
3201   //qt reports WRONG combination under X11 sometimes when Shift + LeftAlt
3202   //are pressed, so we must fix modifiers, ssMeta will be reported in keys.
3203   if (QtShiftModifier and Modifiers <> 0) and (QtMetaModifier and Modifiers <> 0) then
3204   begin
3205     if (QtAltModifier and Modifiers = 0) and
3206       (QKeyEvent_nativeVirtualKey(QKeyEventH(Event)) = XK_Meta_L) then
3207         Modifiers := (Modifiers and not QtMetaModifier) or QtAltModifier;
3208   end;
3209   {$ENDIF}
3210   IsSysKey := (QtAltModifier and Modifiers) <> $0;
3211 
3212   AKeyCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
3213 
3214   LCLModifiers := QtKeyModifiersToKeyState(Modifiers, True, QKeyEventH(Event));
3215 
3216   if QKeyEvent_isAutoRepeat(QKeyEventH(Event)) then
3217     LCLModifiers := LCLModifiers or KF_REPEAT;
3218 
3219   if QEvent_type(Event) = QEventKeyRelease then
3220     LCLModifiers := LCLModifiers or KF_UP;
3221 
3222   {$ifdef windows}
3223   ACharCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
3224   KeyMsg.CharCode := ACharCode;
3225   if (Modifiers = QtAltModifier or QtControlModifier) then
3226   begin
3227     if (QtWidgetSet.GetWinKeyState(VK_RMENU) < 0) and
3228       (QtWidgetSet.GetWinKeyState(VK_LCONTROL) < 0) then
3229     begin
3230       IsSysKey := False;
3231       LCLModifiers := 0;
3232       Modifiers := QtGroupSwitchModifier;
3233 
3234       if QKeyEvent_isAutoRepeat(QKeyEventH(Event)) then
3235         LCLModifiers := LCLModifiers or KF_REPEAT;
3236 
3237       if QEvent_type(Event) = QEventKeyRelease then
3238         LCLModifiers := LCLModifiers or KF_UP;
3239     end;
3240   end;
3241   {$endif}
3242   KeyMsg.KeyData := PtrInt((AKeyCode shl 16) or (LCLModifiers shl 16) or $0001);
3243 
3244   // Loads the UTF-8 character associated with the keypress, if any
3245   QKeyEvent_text(QKeyEventH(Event), @Text);
3246 
3247   {$IFDEF DARWIN}
3248   // qt on mac passes #3 instead of #13 when QtKey_Enter (numpad) is pressed
3249   // so our keypress get wrong about key. issue #20896
3250   if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Enter) and (length(Text) = 1) then
3251     Text := #13;
3252 
3253   ScanCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
3254   {$IFDEF VerboseQtKeys}
3255   // ScanCode := QKeyEvent_key(QKeyEventH(Event));
3256   writeln('!!!**** NATIVEVIRTUALKEY=',ScanCode,' lenText=',length(Text),' Modifiers ',Modifiers,' AKEYCODE=',AKeyCode);
3257   {$ENDIF}
3258 
3259   // set groupswitch for Shift+Option.
3260   if (length(Text) = 1) and
3261     ((Modifiers = QtAltModifier or QtShiftModifier) or ((Modifiers = QtAltModifier) and (ScanCode > 0))) then
3262   begin
3263     ScanCode := QKeyEvent_key(QKeyEventH(Event));
3264     // Arrow keys are reserved by macOSX keyboard commands
3265     // http://support.apple.com/kb/ht1343
3266     if (ScanCode <> QtKey_Left) and (ScanCode <> QtKey_Up) and
3267       (ScanCode <> QtKey_Right) and (ScanCode <> QtKey_Down) then
3268     begin
3269       Modifiers := QtGroupSwitchModifier;
3270       LCLModifiers := QtKeyModifiersToKeyState(Modifiers, True, QKeyEventH(Event));
3271       KeyMsg.KeyData := PtrInt((LCLModifiers shl 16) or $0001);
3272       IsSysKey := False; // was true above
3273     end;
3274     ScanCode := 0;
3275   end;
3276   {$ENDIF}
3277 
3278   {$IFDEF VerboseQtKeys}
3279   writeln('> TQtWidget.SlotKey dump begin event=',EventTypeToStr(Event),' IsSysKey ',IsSysKey);
3280 
3281   S := '';
3282   if Modifiers and QtShiftModifier <> 0 then
3283     S := 'SHIFT,';
3284   if Modifiers and QtControlModifier <> 0 then
3285     S := S + 'CONTROL,';
3286 
3287   if Modifiers and QtAltModifier <> 0 then
3288     S := S + 'ALT,';
3289 
3290   if Modifiers and QtMetaModifier <> 0 then
3291     S := S + 'META,';
3292 
3293   if Modifiers and QtKeypadModifier <> 0 then
3294     S := S + 'KEYPAD,';
3295 
3296   if Modifiers and QtGroupSwitchModifier <> 0 then
3297     S := S + 'GROUPSWITCH,';
3298 
3299   if Modifiers and QtKeyboardModifierMask <> 0 then
3300     S := S + 'KEYBOARDMODIFIERMASK,';
3301 
3302   if S <> '' then
3303     Delete(S, length(S), 1)
3304   else
3305     S := 'NONE';
3306 
3307 
3308   NativeModifiers := QKeyEvent_NativeModifiers(QKeyEventH(Event));
3309   S1 := '';
3310 
3311   if NativeModifiers and QtShiftModifier <> 0 then
3312     S1 := 'SHIFT,';
3313   if NativeModifiers and QtControlModifier <> 0 then
3314     S1 := S1 + 'CONTROL,';
3315 
3316   if NativeModifiers and QtAltModifier <> 0 then
3317     S1 := S1 + 'ALT,';
3318 
3319   if NativeModifiers and QtMetaModifier <> 0 then
3320     S1 := S1 + 'META,';
3321 
3322   if NativeModifiers and QtKeypadModifier <> 0 then
3323     S1 := S1 + 'KEYPAD,';
3324 
3325   if NativeModifiers and QtGroupSwitchModifier <> 0 then
3326     S1 := S1 + 'GROUPSWITCH,';
3327 
3328   if NativeModifiers and QtKeyboardModifierMask <> 0 then
3329     S1 := S1 + 'KEYBOARDMODIFIERMASK,';
3330 
3331   if S1 <> '' then
3332     Delete(S1, length(S1), 1)
3333   else
3334     S1 := 'NONE';
3335 
3336   writeln(' KEY=',QKeyEvent_key(QKeyEventH(Event)),' COUNT=',
3337     QKeyEvent_count(QKeyEventH(Event)),' TEXT=',Text);
3338   writeln(' LCLKEY=',QtKeyToLCLKey(QKeyEvent_key(QKeyEventH(Event)), Text,
3339     QKeyEventH(Event)),' SPONTANEOUS ', QEvent_spontaneous(Event));
3340   writeln(' MODIFIERS: ',S,' NATIVEMODIFIERS: ',S1);
3341   writeln(' HASEXTENDEDINFO: ',QKeyEvent_hasExtendedInfo(QKeyEventH(Event)),
3342     ' ISAUTOREPEAT: ',QKeyEvent_isAutoRepeat(QKeyEventH(Event)));
3343   writeln(' NATIVESCANCODE: ',QKeyEvent_nativeScanCode(QKeyEventH(Event)),
3344     ' NATIVEVIRTUALKEY: ',QKeyEvent_nativeVirtualKey(QKeyEventH(Event)));
3345 
3346   writeln('Key compression ? ',
3347     QWidget_testAttribute(QWidgetH(Sender), QtWA_KeyCompression));
3348   writeln('< TQtWidget.SlotKey dump end event=',EventTypeToStr(Event));
3349   {$ENDIF}
3350 
3351   {we must intercept modifiers for main form menu (if any). issue #18709}
3352   if (Modifiers = QtAltModifier) then
3353   begin
3354     if (QApplication_activeModalWidget() = nil) and
3355       (QEvent_type(Event) <> QEventKeyRelease) and
3356       QtWidgetSet.ShortcutInGlobalActions('Alt+'+Text, GlobalAction) then
3357     begin
3358       QtWidgetSet.TriggerGlobalAction(GlobalAction);
3359       exit;
3360     end;
3361   end;
3362 
3363   {$note TQtWidget.SlotKey: this is workaround for Qt bug which reports
3364    wrong keys with Shift+Ctrl pressed. Fixes #13470.
3365    LAST REVISION: Qt-4.7.4 20111023 fc14. zeljko}
3366   {$IFDEF UNIX}
3367   {$IFDEF DARWIN}
3368   // under darwin we must use nativeVirtualKey since nativeScanCode
3369   // isn't returned under carbon and cocoa.
3370   if (QtVersionMajor = 5) and (QtVersionMinor >= 2) and
3371     (Modifiers = QtShiftModifier or QtControlModifier) then
3372   begin
3373     ScanCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
3374     if (length(Text) = 1) and (ScanCode in [10,18..23,25,26,28,29]) then
3375     begin
3376       if ScanCode = 10 then
3377         ScanCode := VK_UNDEFINED
3378       else
3379       if ScanCode in [18..21] then
3380         ScanCode := ScanCode + 31
3381       else
3382       if ScanCode = 23 then
3383         ScanCode := 53
3384       else
3385       if ScanCode = 22 then
3386         ScanCode := 54
3387       else
3388       if ScanCode = 26 then
3389         ScanCode := 55
3390       else
3391       if ScanCode = 28 then
3392         ScanCode := 56
3393       else
3394       if ScanCode = 25 then
3395         ScanCode := 57
3396       else
3397       if ScanCode = 29 then
3398         ScanCode := 48;
3399 
3400       KeyMsg.CharCode := Word(ScanCode);
3401       if (Modifiers = QtShiftModifier or QtControlModifier) then
3402         Text := '';
3403     end;
3404   end;
3405   {$ELSE}
3406   if (Modifiers = QtShiftModifier or QtControlModifier) or
3407     (Modifiers = QtShiftModifier) then
3408   begin
3409     ScanCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
3410     if (length(Text) = 1) and (ScanCode in [10..19]) then
3411     begin
3412       if ScanCode = 19 then
3413         ScanCode := 48
3414       else
3415         ScanCode := ScanCode + 39;
3416       KeyMsg.CharCode := Word(ScanCode);
3417       if (Modifiers = QtShiftModifier or QtControlModifier) then
3418         Text := '';
3419     end;
3420   end else
3421   if (Modifiers = QtShiftModifier or QtAltModifier) then
3422   begin
3423     ScanCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
3424     if (length(Text) = 1) and (ScanCode in [10..19]) then
3425     begin
3426       if ScanCode = 19 then
3427         ScanCode := 48
3428       else
3429         ScanCode := ScanCode + 39;
3430       KeyMsg.CharCode := Word(ScanCode);
3431       if (Modifiers = QtShiftModifier or QtAltModifier) then
3432         Text := '';
3433     end;
3434   end;
3435   {$ENDIF}
3436   {$ENDIF}
3437 
3438   // Translates a Qt4 Key to a LCL VK_* key
3439   if KeyMsg.CharCode = 0 then
3440   begin
3441     ACharCode := QtKeyToLCLKey(QKeyEvent_key(QKeyEventH(Event)), Text, QKeyEventH(Event));
3442     KeyMsg.CharCode := ACharCode;
3443   end;
3444 
3445   {------------------------------------------------------------------------------
3446    Sends the adequate key messages
3447    ------------------------------------------------------------------------------}
3448   case QEvent_type(Event) of
3449     QEventKeyPress: KeyMsg.Msg := CN_KeyDownMsgs[IsSysKey];
3450     QEventKeyRelease: KeyMsg.Msg := CN_KeyUpMsgs[IsSysKey];
3451   end;
3452 
3453   {$ifdef VerboseQt}
3454   WriteLn(' message CN_Keys: ', KeyMsg.Msg);
3455   {$endif}
3456   if KeyMsg.CharCode <> VK_UNKNOWN then
3457   begin
3458     NotifyApplicationUserInput(LCLObject, KeyMsg.Msg);
3459 
3460     if not CanSendLCLMessage or (Sender = nil) then
3461       exit;
3462 
3463     if (DeliverMessage(KeyMsg, True) <> 0) or (KeyMsg.CharCode=VK_UNKNOWN) then
3464     begin
3465   {$ifdef VerboseQt}
3466       WriteLn('handled CN_Keys');
3467   {$endif}
3468       Exit;
3469     end;
3470 
3471     if not CanSendLCLMessage or (Sender = nil) then
3472       exit;
3473 
3474     // here we should let widgetset to handle key
3475     //...
3476     case QEvent_type(Event) of
3477       QEventKeyPress: KeyMsg.Msg := LM_KeyDownMsgs[IsSysKey];
3478       QEventKeyRelease: KeyMsg.Msg := LM_KeyUpMsgs[IsSysKey];
3479     end;
3480     {$ifdef VerboseQt}
3481     WriteLn(' message LM_Keys: ', KeyMsg.Msg);
3482     {$endif}
3483     if not EatArrowKeys then
3484     begin
3485       NotifyApplicationUserInput(LCLObject, KeyMsg.Msg);
3486 
3487       if not CanSendLCLMessage or (Sender = nil) then
3488         exit;
3489 
3490       if (DeliverMessage(KeyMsg, True) <> 0) or (KeyMsg.CharCode=VK_UNKNOWN) then
3491       begin
3492         // the LCL handled the key
3493         {$ifdef VerboseQt}
3494         WriteLn('handled LM_Keys');
3495         {$endif}
3496         Result := KeyMsg.CharCode=VK_UNKNOWN;
3497         Exit;
3498       end;
3499     end;
3500   end;
3501 
3502   { if our LCLObject dissappeared in the meantime just exit, otherwise
3503     we'll run into problems.}
3504   if not CanSendLCLMessage or (Sender = nil) then
3505     exit;
3506 
3507 
3508   { Also sends a utf-8 key event for key down }
3509   if (QEvent_type(Event) = QEventKeyPress) and (Length(Text) <> 0) then
3510   begin
3511     UTF8Text := UTF16ToUTF8(Text);
3512     UTF8Char := UTF8Text;
3513     {$ifdef VerboseQt}
3514     WriteLn('sending char ', UTF8Char);
3515     {$endif}
3516     if not IsControlKey and LCLObject.IntfUTF8KeyPress(UTF8Char, 1, IsSysKey) then
3517     begin
3518       // the LCL has handled the key
3519       {$ifdef VerboseQt}
3520       WriteLn('handled!');
3521       {$endif}
3522       Exit;
3523     end;
3524 
3525     if not CanSendLCLMessage or (Sender = nil) then
3526       exit;
3527 
3528     if (UTF8Char <> UTF8Text) then
3529     begin
3530       // process changed key and exit.
3531       // issue #26103
3532       SendChangedKey;
3533       exit;
3534     end;
3535 
3536     // create the CN_CHAR / CN_SYSCHAR message
3537     FillChar(CharMsg, SizeOf(CharMsg), 0);
3538     CharMsg.Msg := CN_CharMsg[IsSysKey];
3539     CharMsg.KeyData := KeyMsg.KeyData;
3540     AChar := Text[1];
3541     CharMsg.CharCode := Word(AChar);
3542 
3543     //Send message to LCL
3544     {$ifdef VerboseQt}
3545     WriteLn(' message: ', CharMsg.Msg);
3546     {$endif}
3547     NotifyApplicationUserInput(LCLObject, CharMsg.Msg);
3548 
3549     if not CanSendLCLMessage or (Sender = nil) then
3550       exit;
3551 
3552     if (DeliverMessage(CharMsg, True) <> 0) or (CharMsg.CharCode = VK_UNKNOWN) then
3553     begin
3554       // the LCL has handled the key
3555       {$ifdef VerboseQt}
3556       WriteLn('handled!');
3557       {$endif}
3558       Exit;
3559     end;
3560 
3561     //Here is where we (interface) can do something with the key
3562     //...
3563 
3564     //Send a LM_(SYS)CHAR
3565     CharMsg.Msg := LM_CharMsg[IsSysKey];
3566 
3567     {$ifdef VerboseQt}
3568     WriteLn(' message: ', CharMsg.Msg);
3569     {$endif}
3570     if not CanSendLCLMessage or (Sender = nil) then
3571       exit;
3572 
3573     NotifyApplicationUserInput(LCLObject, CharMsg.Msg);
3574 
3575     if not CanSendLCLMessage or (Sender = nil) then
3576       exit;
3577 
3578     DeliverMessage(CharMsg, True);
3579     if not CanSendLCLMessage or (Sender = nil) then
3580       exit;
3581   end;
3582 
3583   // check if data was changed during key handling
3584   if CanSendLCLMessage and (Sender <> nil) and
3585     ((KeyMsg.CharCode <> ACharCode) or (UTF8Char <> UTF8Text) or
3586       (Word(AChar) <> CharMsg.CharCode)) then
3587   begin
3588     // data was changed
3589     // moved to nested proc because of issue #26103
3590     SendChangedKey;
3591   end else
3592   begin
3593     Result := KeyMsg.CharCode in KeysToEat;
3594   end;
3595 end;
3596 
TQtWidget.SlotInputMethodnull3597 function TQtWidget.SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3598 var
3599   InputEvent: QInputMethodEventH;
3600   WStr: WideString;
3601   UnicodeChar: Cardinal;
3602   UnicodeOutLen: integer;
3603   KeyEvent: QKeyEventH;
3604 begin
3605   Result := True;
3606   if not (QEvent_type(Event) = QEventInputMethod) then Exit;
3607   {$ifdef VerboseQt}
3608     DebugLn('TQtWidget.SlotInputMethod ', dbgsname(LCLObject));
3609   {$endif}
3610   InputEvent := QInputMethodEventH(Event);
3611   QInputMethodEvent_commitString(InputEvent, @WStr);
3612   UnicodeChar := UTF8CodepointToUnicode(PChar(WStr), UnicodeOutLen);
3613   {$IFDEF VerboseQtKeys}
3614   writeln('> TQtWidget.SlotInputMethod ',dbgsname(LCLObject),' event=QEventInputMethod:');
3615   writeln('   commmitString ',WStr,' len ',length(WStr),' UnicodeChar ',UnicodeChar,
3616     ' UnicodeLen ',UnicodeOutLen);
3617   writeln('   sending QEventKeyPress');
3618   {$ENDIF}
3619 
3620   KeyEvent := QKeyEvent_create(QEventKeyPress, PtrInt(UnicodeChar), QGUIApplication_keyboardModifiers, @WStr, False, 1);
3621   try
3622     // do not send it to queue, just pass it to SlotKey
3623     Result := SlotKey(Sender, KeyEvent);
3624   finally
3625     QKeyEvent_destroy(KeyEvent);
3626   end;
3627   {$IFDEF VerboseQtKeys}
3628   writeln('< TQtWidget.SlotInputMethod End: ',dbgsname(LCLObject),' event=QEventInputMethod, sent QEventKeyPress');
3629   {$ENDIF}
3630 end;
3631 
3632 {------------------------------------------------------------------------------
3633   Function: TQtWidget.SlotMouse
3634   Params:  None
3635   Returns: Nothing
3636  ------------------------------------------------------------------------------}
TQtWidget.SlotMousenull3637 function TQtWidget.SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3638 var
3639   Msg: TLMMouse;
3640   MousePos: TQtPoint;
3641   MButton: QTMouseButton;
3642   Modifiers: QtKeyboardModifiers;
3643   SaveWidget: QWidgetH;
3644   LazButton: Byte;
3645   LazPos: TPoint;
3646 begin
3647   {$ifdef VerboseQt}
3648   WriteLn('TQtWidget.SlotMouse ',DbgSName(Self));
3649   {$endif}
3650 
3651   Result := False; // allow qt to handle message
3652 
3653   if not CanSendLCLMessage then
3654     exit(True);
3655 
3656   if (LCLObject <> nil) and
3657     (not (csDesigning in LCLObject.ComponentState) and not getEnabled) then
3658     Exit;
3659 
3660   // idea of multi click implementation is taken from gtk
3661 
3662   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3663 
3664   // MousePos :=
3665   QMouseEvent_pos(QMouseEventH(Event), @MousePos);
3666   OffsetMousePos(@MousePos);
3667 
3668   Modifiers := QInputEvent_modifiers(QInputEventH(Event));
3669   Msg.Keys := QtKeyModifiersToKeyState(Modifiers, False, nil);
3670 
3671   Msg.XPos := SmallInt(MousePos.X);
3672   Msg.YPos := SmallInt(MousePos.Y);
3673 
3674   MButton := QMouseEvent_Button(QMouseEventH(Event));
3675   LazPos := Point(MousePos.X, MousePos.Y);
3676   case MButton of
3677     QtLeftButton: LazButton := 1;
3678     QtRightButton: LazButton := 2;
3679     QtMidButton: LazButton := 3;
3680     QtXButton1, QtXButton2: LazButton := 4;
3681     else Exit; // Sometimes mouse wheel triggers an invalid button value. Ignore it.
3682   end;
3683   // do not pass mouse button into keys (TShiftState). issue #20916
3684   if (QEvent_type(Event) <> QEventMouseButtonRelease)
3685   or (((MButton and QtLeftButton) = 0) and ((MButton and QtRightButton) = 0) and
3686       ((MButton and QtMidButton) = 0))
3687   then
3688     Msg.Keys := Msg.Keys or QtButtonsToLCLButtons(MButton);
3689   Msg.Msg := CheckMouseButtonDownUp(TLCLIntfHandle(Self), LCLObject, LastMouse, LazPos, LazButton,
3690     QEvent_type(Event) in [QEventMouseButtonPress, QEventMouseButtonDblClick]);
3691   case LastMouse.ClickCount of
3692     2: Msg.Keys := Msg.Keys or MK_DOUBLECLICK;
3693     3: Msg.Keys := Msg.Keys or MK_TRIPLECLICK;
3694     4: Msg.Keys := Msg.Keys or MK_QUADCLICK;
3695   end;
3696 
3697   case QEvent_type(Event) of
3698     QEventMouseButtonPress, QEventMouseButtonDblClick:
3699     begin
3700       {$IFDEF MSWINDOWS}
3701       if (QEvent_type(Event) = QEventMouseButtonPress) and
3702           (MButton = QtRightButton) then
3703         Include(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
3704       try
3705       {$ENDIF}
3706 
3707       NotifyApplicationUserInput(LCLObject, Msg.Msg);
3708 
3709       if not CanSendLCLMessage or (Sender = nil) then
3710         exit(True);
3711 
3712       DeliverMessage(Msg, True);
3713 
3714       {$IFDEF MSWINDOWS}
3715       finally
3716         if (QEvent_type(Event) = QEventMouseButtonPress) and
3717           (MButton = QtRightButton) then
3718         begin
3719           Exclude(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
3720           Exclude(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
3721         end;
3722       end;
3723       {$ENDIF}
3724 
3725       // Check if our objects exists since LCL can destroy object during
3726       // mouse events...
3727       if CanSendLCLMessage and (Sender <> nil) then
3728         SetNoMousePropagation(QWidgetH(Sender), True)
3729       else
3730         exit(True);
3731     end;
3732     QEventMouseButtonRelease:
3733     begin
3734       SaveWidget := nil;
3735       if (FChildOfComplexWidget = ccwCustomControl) and (FOwner <> nil) then
3736         SaveWidget := Widget;
3737 
3738       NotifyApplicationUserInput(LCLObject, Msg.Msg);
3739 
3740       if (SaveWidget <> nil) and (SaveWidget <> Widget) then
3741         exit(True);
3742 
3743       if not CanSendLCLMessage or (Sender = nil) then
3744         exit(True);
3745 
3746       DeliverMessage(Msg, True);
3747       if (SaveWidget <> nil) and (SaveWidget <> Widget) then
3748         exit(True);
3749 
3750       // Check if our objects exists since LCL can destroy object during
3751       // mouse events...
3752       if CanSendLCLMessage and (Sender <> nil) then
3753         SetNoMousePropagation(QWidgetH(Sender), True)
3754       else
3755         exit(True);
3756 
3757       { Clicking on buttons operates differently, because QEventMouseButtonRelease
3758         is sent if you click a control, drag the mouse out of it and release, but
3759         buttons should not be clicked on this case. }
3760       if CanSendLCLMessage and (Sender <> nil) and
3761         not (LCLObject is TCustomButton) then
3762       begin
3763         Msg.Msg := LM_CLICKED;
3764         DeliverMessage(Msg, True);
3765       end;
3766     end;
3767   end;
3768 end;
3769 
3770 procedure TQtWidget.SlotNCMouse(Sender: QObjectH; Event: QEventH); cdecl;
3771 var
3772   AHeader: TRect;
3773   APoint: TQtPoint;
3774 begin
3775   //Drag&Dock support TCustomForm => Start BeginDrag()
3776   if (LCLObject is TCustomForm) and
3777      not (csDesigning in LCLObject.ComponentState) and
3778      (TWinControlAccess(LCLObject).DragKind = dkDock) and
3779      (TWinControlAccess(LCLObject).DragMode = dmAutomatic) and
3780      (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
3781   begin
3782     QMouseEvent_globalPos(QMouseEventH(Event), @APoint);
3783     AHeader := getGeometry;
3784     with getFrameGeometry do
3785       AHeader.Top := Top;
3786 
3787     // remove various buttons from header (how to request their pos cross platform?):
3788     Inc(AHeader.Left, 20);  // system menu
3789     Dec(AHeader.Right, 80); // close, min, max buttons
3790     if AHeader.Right < AHeader.Left then
3791       AHeader.Right := AHeader.Left + 1;
3792 
3793     // we can skip translation of coords to global since we already working with window
3794     // check for title
3795     if PtInRect(AHeader, Point(APoint.x, APoint.y)) then
3796       LCLObject.BeginDrag(true);
3797   end;
3798 end;
3799 
SlotMouseEnternull3800 function TQtWidget.SlotMouseEnter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3801 var
3802   Msg: TLMessage;
3803 begin
3804   Result := False;
3805   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3806   case QEvent_type(Event) of
3807     QEventEnter: Msg.Msg := LM_MOUSEENTER;
3808     QEventLeave: Msg.Msg := LM_MOUSELEAVE;
3809   end;
3810   DeliverMessage(Msg);
3811 end;
3812 
TQtWidget.QtButtonsToLCLButtonsnull3813 function TQtWidget.QtButtonsToLCLButtons(AButtons: QtMouseButton): PtrInt;
3814 begin
3815   Result := 0;
3816   if (QtLeftButton and AButtons) <> 0 then
3817     Result := Result or MK_LBUTTON;
3818 
3819   if (QtRightButton and AButtons) <> 0 then
3820     Result := Result or MK_RBUTTON;
3821 
3822   if (QtMidButton and AButtons) <> 0 then
3823     Result := Result or MK_MBUTTON;
3824 
3825   if (QtXButton1 and AButtons) <> 0 then
3826     Result := Result or MK_XBUTTON1;
3827 
3828   if (QtXButton2 and AButtons) <> 0 then
3829     Result := Result or MK_XBUTTON2;
3830 end;
3831 
QtKeyModifiersToKeyStatenull3832 function TQtWidget.QtKeyModifiersToKeyState(AModifiers: QtKeyboardModifiers;
3833   const AIsKeyEvent: Boolean; AEvent: QKeyEventH = nil): PtrInt;
3834 begin
3835 // TODO: remove AIsKeyEvent later
3836   Result := 0;
3837   if AModifiers and QtShiftModifier <> 0 then
3838     Result := Result or MK_SHIFT;
3839   if AModifiers and QtControlModifier <> 0 then
3840     Result := Result or MK_CONTROL;
3841   if AModifiers and QtAltModifier <> 0 then
3842   begin
3843     if AIsKeyEvent then
3844       Result := Result or KF_ALTDOWN
3845     else
3846       Result := Result or MK_ALT;
3847   end;
3848     // $20000000;
3849   { TODO: add support for ALT, META and NUMKEYPAD }
3850 end;
3851 
3852 {------------------------------------------------------------------------------
3853   Function: TQtWidget.SlotMouseMove
3854   Params:  None
3855   Returns: Nothing
3856  ------------------------------------------------------------------------------}
SlotMouseMovenull3857 function TQtWidget.SlotMouseMove(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3858 var
3859   Msg: TLMMouseMove;
3860   MousePos: TQtPoint;
3861   GlobPos: TQtPoint;
3862   R: TRect;
3863   P: TPoint;
3864   NewEvent: QEventH;
3865   W: QWidgetH;
3866   FrameBorder: Integer;
3867   TitleBarHeight: Integer;
3868   SenderWidget: QWidgetH;
3869   SavedLCLObject: PtrUint;
3870 begin
3871   Result := False;
3872   if not CanSendLCLMessage or (Sender = nil) or
3873     not QObject_isWidgetType(Sender) then
3874     Exit(True);
3875 
3876   SenderWidget := QWidgetH(Sender);
3877 
3878   if not (csCaptureMouse in LCLObject.ControlStyle) and
3879     not QWidget_isWindow(SenderWidget) and
3880     not DragManager.IsDragging then
3881   begin
3882     QMouseEvent_pos(QMouseEventH(Event), @MousePos);
3883     QMouseEvent_globalPos(QMouseEventH(Event), @GlobPos);
3884 
3885     // get parent form, so check if mouse is out of parent form first.
3886     W := QWidget_window(SenderWidget);
3887 
3888     if W <> nil then
3889     begin
3890       QWidget_frameGeometry(W, @R);
3891 
3892       // exclude borders from frame
3893       FrameBorder := GetPixelMetric(QStylePM_DefaultFrameWidth, nil, W);
3894       TitleBarHeight := GetPixelMetric(QStylePM_TitleBarHeight, nil, W);
3895 
3896       inc(R.Left, FrameBorder);
3897       inc(R.Top, TitleBarHeight);
3898       dec(R.Right, FrameBorder);
3899       dec(R.Bottom, FrameBorder);
3900 
3901       P := Point(GlobPos.X, GlobPos.Y);
3902       if not PtInRect(R, P) then
3903         MousePos := QtPoint(-1, -1);
3904 
3905       if not QWidget_underMouse(SenderWidget) then
3906       begin
3907         if (MousePos.X >= 0) and (MousePos.Y >= 0) then
3908         begin
3909           QWidget_setAttribute(SenderWidget, QtWA_UnderMouse, True);
3910           NewEvent := QEvent_create(QEventEnter);
3911           QCoreApplication_postEvent(SenderWidget, NewEvent, 100);
3912         end;
3913       end;
3914     end;
3915 
3916     if not (csCaptureMouse in LCLObject.ControlStyle) and
3917       (QGUIApplication_mouseButtons() <> QtNoButton) and
3918       (((MousePos.X < 0) or (MousePos.Y < 0)) or
3919       ((MousePos.X > getWidth) or (MousePos.Y > getHeight))) then
3920     begin
3921       if not QWidget_underMouse(SenderWidget) then
3922         exit;
3923       setCursor(FDefaultCursor);
3924       NewEvent := QEvent_create(QEventLeave);
3925       QCoreApplication_postEvent(SenderWidget, NewEvent, 100);
3926       exit;
3927     end;
3928   end;
3929 
3930   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3931 
3932   // MousePos :=
3933   QMouseEvent_pos(QMouseEventH(Event), @MousePos);
3934   OffsetMousePos(@MousePos);
3935 
3936   Msg.XPos := SmallInt(MousePos.X);
3937   Msg.YPos := SmallInt(MousePos.Y);
3938 
3939   Msg.Keys := QtButtonsToLCLButtons(QMouseEvent_Buttons(QMouseEventH(Event)))
3940     or QtKeyModifiersToKeyState(QInputEvent_modifiers(QInputEventH(Event)), False, nil);
3941 
3942   Msg.Msg := LM_MOUSEMOVE;
3943 
3944   SetNoMousePropagation(SenderWidget, True);
3945   SavedLCLObject := PtrUInt(LCLObject);
3946 
3947   NotifyApplicationUserInput(LCLObject, Msg.Msg);
3948 
3949   if (SavedLCLObject <> PtrUInt(LCLObject)) or not CanSendLCLMessage then
3950     exit(True);
3951 
3952   DeliverMessage(Msg, True);
3953 
3954   if (SavedLCLObject <> PtrUInt(LCLObject)) or not CanSendLCLMessage then
3955     exit(True);
3956 end;
3957 
3958 {------------------------------------------------------------------------------
3959   Function: TQtWidget.SlotMouseWheel
3960   Params:  None
3961   Returns: Nothing
3962 
3963   Qt stores the delta in 1/8 of a degree
3964   Most mouses scroll 15 degrees each time
3965 
3966   Msg.WheelDelta: -1 for up, 1 for down
3967  ------------------------------------------------------------------------------}
SlotMouseWheelnull3968 function TQtWidget.SlotMouseWheel(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3969 var
3970   Msg: TLMMouseEvent;
3971   MousePos: TQtPoint;
3972   Modifiers: QtKeyboardModifiers;
3973   ModifierState: PtrInt;
3974   {$IFDEF DARWIN}
3975   CCtl: TQtAbstractScrollArea;
3976   {$ENDIF}
3977 begin
3978   Result := False;
3979   if not CanSendLCLMessage then
3980     exit;
3981 
3982   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3983 
3984   QWheelEvent_Pos(QWheelEventH(Event), @MousePos);
3985   OffsetMousePos(@MousePos);
3986 
3987   Modifiers := QInputEvent_modifiers(QInputEventH(Event));
3988   Msg.State := [];
3989   ModifierState := QtKeyModifiersToKeyState(Modifiers, False, nil);
3990   if (ModifierState and MK_SHIFT) <> 0 then
3991     Msg.State := [ssShift];
3992   if (ModifierState and MK_CONTROL) <> 0 then
3993     Msg.State := [ssCtrl] + Msg.State;
3994   if (ModifierState and MK_ALT) <> 0 then
3995     Msg.State := [ssAlt] + Msg.State;
3996 
3997   LastMouse.WinControl := LCLObject;
3998   LastMouse.WinHandle := TLCLIntfHandle(Self);
3999   LastMouse.MousePos := Point(MousePos.X, MousePos.Y);
4000 
4001   Msg.X := SmallInt(MousePos.X);
4002   Msg.Y := SmallInt(MousePos.Y);
4003 
4004   Msg.WheelDelta := SmallInt(QWheelEvent_delta(QWheelEventH(Event)));
4005 
4006   Msg.Msg := LM_MOUSEWHEEL;
4007   if QWheelEvent_orientation(QWheelEventH(Event)) = QtHorizontal then
4008   begin
4009     Msg.Msg := LM_MOUSEHWHEEL;
4010     Msg.WheelDelta := -Msg.WheelDelta;
4011   end;
4012 
4013   {$IFDEF DARWIN}
4014   // LCL expects delta +-120, we must fix it. issue #20888
4015   if (ChildOfComplexWidget in [ccwCustomControl, ccwAbstractScrollArea,
4016       ccwScrollingWinControl]) then
4017   begin
4018     if (Msg.WheelDelta > 0) then
4019       Msg.WheelDelta := 1
4020     else
4021       Msg.WheelDelta := -1;
4022     Msg.WheelDelta := (120 * Msg.WheelDelta) div Mouse.WheelScrollLines;
4023     if FOwner <> nil then
4024     begin
4025       {$IFDEF QTSCROLLABLEFORMS}
4026       if (FOwner is TQtMainWindow) then
4027         CCtl := TQtMainWindow(FOwner).ScrollArea
4028       else
4029       {$ENDIF}
4030         CCtl := TQtAbstractScrollArea(FOwner);
4031     end else
4032       CCtl := TQtAbstractScrollArea(Self);
4033     //now fix ugly behaviour.
4034     if (Msg.WheelDelta > 0) and (CCtl.FVScrollbar.getVisible) and
4035         ((CCtl.FVScrollBar = Self) or
4036          (Assigned(CCtl.FVScrollbar) and (Self <> CCtl.FHScrollbar))) then
4037     begin
4038       if CCtl.FVScrollbar.getSliderPosition <= 1 then
4039         Msg.WheelDelta := 120;
4040     end;
4041   end;
4042   {$ENDIF}
4043 
4044   NotifyApplicationUserInput(LCLObject, Msg.Msg);
4045 
4046   if not CanSendLCLMessage then
4047     exit(True);
4048 
4049   Result := DeliverMessage(Msg, True) <> 0;
4050 
4051   if not CanSendLCLMessage then
4052     exit(True);
4053 
4054   SetNoMousePropagation(QWidgetH(Sender), False);
4055 
4056   {propagate mousewheel to parent if our sender is TPanel,
4057    fixes problem with mousewheel scroll with lazreport}
4058   if (LCLObject <> nil) and
4059     not (csDesigning in LCLObject.ComponentState) and
4060     (LCLObject is TPanel) and
4061     Assigned(LCLObject.Parent) then
4062       Result := TQtWidget(LCLObject.Parent.Handle).DeliverMessage(Msg) <> 0;
4063 end;
4064 
4065 procedure TQtWidget.SlotMove(Event: QEventH); cdecl;
4066 var
4067   Msg: TLMMove;
4068   APos: TQtPoint;
4069   {$IFDEF HASX11}
4070   ACurrPos: TQtPoint;
4071   {$ENDIF}
4072   FrameRect, WindowRect: TRect;
4073   ForceSendMove: boolean;
4074 begin
4075   {$ifdef VerboseQt}
4076     WriteLn('TQtWidget.SlotMove');
4077   {$endif}
4078 
4079   if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
4080     QtWidgetSet.InvalidateWidgetAtCache;
4081   // do not loop with LCL
4082   if InUpdate {$ifdef darwin} and not (qtwsForceSendMove in WidgetState){$endif} then
4083     exit;
4084 
4085   ForceSendMove := False; {mantis #34589}
4086   if not QEvent_spontaneous(Event) and Assigned(LCLObject) and Assigned(LCLObject.Parent) then
4087     // only children of 1st level should move.
4088     ForceSendMove := qtwsForceSendMove in TQtWidget(LCLObject.Parent.Handle).WidgetState;
4089 
4090   {$ifdef darwin}
4091   // issue #34698
4092   if not ForceSendMove and not QEvent_spontaneous(Event) and Assigned(LCLObject) and
4093     (Self is TQtMainWindow) and not TQtMainWindow(Self).IsMdiChild then
4094   begin
4095     ForceSendMove := qtwsForceSendMove in WidgetState;
4096     Exclude(FWidgetState, qtwsForceSendMove);
4097   end;
4098   {$endif}
4099 
4100   if ForceSendMove then
4101     // send message mantis #34589
4102   else
4103   if not QEvent_spontaneous(Event) or
4104     (not QEvent_spontaneous(Event) and
4105     ((Self is TQtMainWindow) and not
4106     TQtMainWindow(Self).IsMdiChild)) then
4107     Exit;
4108 
4109   FillChar(Msg{%H-}, SizeOf(Msg), #0);
4110 
4111   Msg.Msg := LM_MOVE;
4112 
4113   Msg.MoveType := Msg.MoveType or Move_SourceIsInterface;
4114 
4115   APos := QMoveEvent_pos(QMoveEventH(Event))^;
4116   FrameRect := getFrameGeometry;
4117   WindowRect := getGeometry;
4118 
4119   // here is explanation why frameGeometry sometimes
4120   // doesn't return correct results under X11
4121   // http://doc.qt.nokia.com/4.7/application-windows.html#window-geometry
4122   // issue #18658
4123   {$IFDEF HASX11}
4124   if (LCLObject is TCustomForm) and EqualRect(FrameRect, WindowRect) and
4125     (TCustomForm(LCLObject).BorderStyle <> bsNone) and
4126     (not (TCustomForm(LCLObject).FormStyle in [fsMDIChild,fsSplash]) or
4127       (csDesigning in LCLObject.ComponentState)) then
4128   begin
4129     ACurrPos := getPos;
4130     // do not send garbage to LCL. This window isn't decorated yet by WM.
4131     if (ACurrPos.X = WindowRect.Left) and (ACurrPos.Y = WindowRect.Top) then
4132       exit;
4133   end;
4134   {$ENDIF}
4135 
4136   Msg.XPos := SmallInt(APos.x - (WindowRect.Left - FrameRect.Left));
4137   Msg.YPos := SmallInt(APos.y - (WindowRect.Top - FrameRect.Top));
4138 
4139   DeliverMessage(Msg);
4140 end;
4141 
4142 {------------------------------------------------------------------------------
4143   Function: TQtWidget.SlotPaintBg
4144   Params:  None
4145   Returns: Nothing.
4146 
4147   Paints widget background.
4148   Only for classes which have HasPaint=False and AutoFillBackground=False
4149   and solid color different to default one (eg. clBtnFace for buttons).
4150   Current allowed classes are: All TQtCheckBox,TQtRadioButton,
4151   TQtPushButton (X11 only), TQtStaticText and TQtGroupBox.
4152  ------------------------------------------------------------------------------}
4153 procedure TQtWidget.SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl;
4154 var
4155   Painter: QPainterH;
4156   Brush: QBrushH;
4157   Color: TQColor;
4158   R: TRect;
4159 begin
4160   if CanSendLCLMessage and (LCLObject is TWinControl) and (FContext = 0) then
4161   begin
4162     if LCLObject.Color = clDefault then
4163       Color := Palette.DefaultColor
4164     else
4165       ColorRefToTQColor(ColorToRGB(LCLObject.Color), Color);
4166     Painter := QPainter_create(QWidget_to_QPaintDevice(QWidgetH(Sender)));
4167     {$IFDEF USEQT4COMPATIBILEPAINTER}
4168     QPainter_setRenderHint(Painter, QPainterQt4CompatiblePainting);
4169     {$ENDIF}
4170     Brush := QBrush_create(@Color, QtSolidPattern);
4171     try
4172       QPaintEvent_rect(QPaintEventH(Event), @R);
4173       QPainter_fillRect(Painter, @R, Brush);
4174       QPainter_end(Painter);
4175     finally
4176       QBrush_destroy(Brush);
4177       QPainter_destroy(Painter);
4178     end;
4179   end;
4180 end;
4181 
4182 {------------------------------------------------------------------------------
4183   Function: TQtWidget.SlotPaint
4184   Params:  None
4185   Returns: Nothing
4186 
4187   Sends a LM_PAINT message to the LCL. This is for windowed controls only
4188  ------------------------------------------------------------------------------}
4189 procedure TQtWidget.SlotPaint(Sender: QObjectH; Event: QEventH); cdecl;
4190 var
4191   Msg: TLMPaint;
4192   AStruct: PPaintStruct;
4193   P: TPoint;
4194   B: Boolean;
4195 begin
4196   {$ifdef VerboseQt}
4197     WriteLn('TQtWidget.SlotPaint ', dbgsName(LCLObject));
4198   {$endif}
4199   if CanSendLCLMessage and (LCLObject is TWinControl) and (FContext = 0) then
4200   begin
4201     FillChar(Msg{%H-}, SizeOf(Msg), #0);
4202 
4203     Msg.Msg := LM_PAINT;
4204     New(AStruct);
4205     FillChar(AStruct^, SizeOf(TPaintStruct), 0);
4206     Msg.PaintStruct := AStruct;
4207 
4208     with PaintData do
4209     begin
4210       PaintWidget := QWidgetH(Sender);
4211       ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
4212       if ClipRect = nil then
4213         New(ClipRect);
4214       QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
4215     end;
4216 
4217     Msg.DC := BeginPaint(THandle(Self), AStruct^);
4218     FContext := Msg.DC;
4219 
4220     Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
4221     Msg.PaintStruct^.hdc := FContext;
4222 
4223     P := getClientOffset;
4224 
4225     if (Self is TQtGroupBox) and (QWidgetH(Sender) = FCentralWidget) then
4226     begin
4227       P.X := 0;
4228       P.Y := 0;
4229     end;
4230     inc(P.X, FScrollX);
4231     inc(P.Y, FScrollY);
4232     TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
4233 
4234     // send paint message
4235     try
4236       // Saving clip rect and clip region
4237       try
4238         LCLObject.WindowProc(TLMessage(Msg));
4239         if HasCaret then
4240         begin
4241           if GlobalCaretDirty then
4242             QtCaret.ShowCaret(Self);
4243           QtCaret.DrawCaret;
4244         end;
4245       finally
4246         Dispose(PaintData.ClipRect);
4247         Fillchar(FPaintData, SizeOf(FPaintData), 0);
4248         FContext := 0;
4249         EndPaint(THandle(Self), AStruct^);
4250         Dispose(AStruct);
4251       end;
4252     except
4253       // prevent recursive repainting !
4254       B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
4255       if B then
4256         QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
4257       try
4258         Application.HandleException(nil);
4259       finally
4260         if B and Assigned(Application) and not Application.Terminated then
4261           QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
4262       end;
4263     end;
4264   end;
4265 end;
4266 
4267 {------------------------------------------------------------------------------
4268   Function: TQtWidget.SlotResize
4269   Params:  None
4270   Returns: Nothing
4271 
4272   Sends a LM_SIZE message to the LCL.
4273  ------------------------------------------------------------------------------}
4274 procedure TQtWidget.SlotResize(Event: QEventH); cdecl;
4275 var
4276   Msg: TLMSize;
4277   NewSize: TSize;
4278   {$IFDEF VerboseQtResizeError}
4279   R: TRect;
4280   {$ENDIF}
4281   B: Boolean;
4282   AQtClientRect: TRect;
4283 begin
4284   {$ifdef VerboseQt}
4285     WriteLn('TQtWidget.SlotResize');
4286   {$endif}
4287 
4288   if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
4289     QtWidgetSet.InvalidateWidgetAtCache;
4290 
4291   // return size w/o frame
4292   NewSize := QResizeEvent_size(QResizeEventH(Event))^;
4293 
4294   if not Assigned(LCLObject) then exit;
4295 
4296   if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
4297   begin
4298     {$IFDEF VerboseQtResizeError}
4299     if not InUpdate then
4300     begin
4301       DebugLn('============================================================================');
4302       DebugLn('W A R N I N G !    W A R N I N G !    W A R N I N G !    W A R N I N G !');
4303       DebugLn(dbgsName(LCLObject),' self=',dbgsName(Self),' already in SlotResize needClientRectAdjust',dbgs(LCLObject.ClientRectNeedsInterfaceUpdate),
4304       ' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
4305       R := getClientBounds;
4306       DebugLn('LCL CACHED CLIENT WxH=',dbgs(LCLObject.CachedClientWidth),'x',dbgs(LCLObject.CachedClientHeight),
4307       ' QtClient=',dbgs(R));
4308       DebugLn('============================================================================');
4309     end;
4310     {$ENDIF}
4311     exit;
4312   end;
4313   if Assigned(FOwner) then
4314     FOwner.InResizeEvent := True;
4315   InResizeEvent := True;
4316   try
4317     // do not loop with LCL but do not apply it to TQtMainWindow !
4318     if not (csDesigning in LCLObject.ComponentState) and
4319       not ((ClassType = TQtMainWindow) {$IFDEF QTSCROLLABLEFORMS} or (ClassType = TQtWindowArea){$ENDIF})
4320       and InUpdate then
4321     begin
4322       AQtClientRect := Rect(0, 0, 0, 0);
4323       if FOwner <> nil then
4324         B := GetClientRect(HWND(Self.FOwner), AQtClientRect)
4325       else
4326         B := GetClientRect(HWND(Self), AQtClientRect);
4327       if B and EqualRect(LCLObject.ClientRect, AQtClientRect) then
4328       begin
4329         {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
4330         DebugLn('==========',dbgsName(LCLObject),'.SlotResize inUpdate.LCLObject.ClientRect is ok,do not send LMSize');
4331         {$ENDIF}
4332         exit;
4333       end else
4334       begin
4335         {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
4336         DebugLn('====***====',dbgsName(LCLObject),'.SlotResize inUpdate but LCL.ClientRect isn''t adjusted. CanAdjust=',dbgs(CanAdjustClientRectOnResize),' CAPS=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' NeedUpd ',dbgs(LCLObject.ClientRectNeedsInterfaceUpdate));
4337         {$ENDIF}
4338         if LCLObject.ClientRectNeedsInterfaceUpdate and
4339           not (caspComputingBounds in LCLObject.AutoSizePhases) then
4340         begin
4341           LCLObject.DoAdjustClientRectChange(True);
4342           exit;
4343         end;
4344       end;
4345     end;
4346 
4347     {keep LCL value while designing pageControl}
4348     if (csDesigning in LCLObject.ComponentState) and InUpdate and
4349       ((Self is TQtPage) or (Self is TQtTabWidget)) then
4350         exit;
4351 
4352     if CanAdjustClientRectOnResize and
4353       LCLObject.ClientRectNeedsInterfaceUpdate then
4354     begin
4355       // postpone resize event if we are computingbounds otherwise
4356       // we can run into infinite size loop.
4357       if (caspComputingBounds in LCLObject.AutoSizePhases) then
4358       begin
4359         {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
4360         DebugLn('WARNING: *TQtWidget.SlotResize caspComputingBounds=true* ! ',dbgsname(LCLObject),':',dbgsName(Self),' inUpdate=',dbgs(inUpdate),' Time: ',dbgs(GetTickCount));
4361         {$ENDIF}
4362         if ChildOfComplexWidget <> ccwScrollingWinControl then
4363           DelayResizeEvent(Widget, NewSize);
4364         exit;
4365       end else
4366       begin
4367         LCLObject.DoAdjustClientRectChange;
4368       end;
4369     end;
4370 
4371     FillChar(Msg{%H-}, SizeOf(Msg), #0);
4372 
4373     Msg.Msg := LM_SIZE;
4374 
4375     case getWindowState of
4376       QtWindowMinimized: Msg.SizeType := SIZE_MINIMIZED;
4377       QtWindowMaximized: Msg.SizeType := SIZE_MAXIMIZED;
4378       QtWindowFullScreen: Msg.SizeType := SIZE_FULLSCREEN;
4379     else
4380       Msg.SizeType := SIZE_RESTORED;
4381     end;
4382 
4383     Msg.SizeType := Msg.SizeType or Size_SourceIsInterface;
4384 
4385     Msg.Width := Word(NewSize.cx);
4386     Msg.Height := Word(NewSize.cy);
4387 
4388     DeliverMessage(Msg);
4389   finally
4390     if ASsigned(FOwner) then
4391       FOwner.InResizeEvent := False;
4392     InResizeEvent := False;
4393   end;
4394 end;
4395 
TQtWidget.SlotContextMenunull4396 function TQtWidget.SlotContextMenu(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
4397 var
4398   Msg: TLMContextMenu;
4399   MousePos: TQtPoint;
4400 
4401   procedure SendMouseReleaseEventToSelf;
4402   var
4403     AEvent: QEventH;
4404     Modifiers: QtKeyboardModifiers;
4405     APos, AGlobalPos: TQtPoint;
4406     APosF, AGlobalPosF: TQtPointF;
4407   begin
4408     APos := QContextMenuEvent_pos(QContextMenuEventH(Event))^;
4409     AGlobalPos := QContextMenuEvent_globalPos(QContextMenuEventH(Event))^;
4410     APosF.X := APos.X;
4411     APosF.Y := APos.Y;
4412     AGlobalPosF.X := AGlobalPos.x;
4413     AGlobalPosF.Y := AGlobalPos.y;
4414     Modifiers := QInputEvent_modifiers(QInputEventH(Event));
4415     AEvent := QMouseEvent_create(QEventMouseButtonRelease,
4416       @APosF,
4417       @AGlobalPosF,
4418       QtRightButton,
4419       QtRightButton,
4420       Modifiers);
4421     QCoreApplication_postEvent(Widget, AEvent, 1);
4422   end;
4423 
4424 begin
4425   if not CanSendLCLMessage then
4426     Exit(False);
4427 
4428   FillChar(Msg{%H-}, SizeOf(Msg), #0);
4429   MousePos := QContextMenuEvent_globalPos(QContextMenuEventH(Event))^;
4430 
4431   Msg.Msg := LM_CONTEXTMENU;
4432   if FOwner <> nil then
4433     Msg.hWnd := HWND(FOwner)
4434   else
4435     Msg.hWnd := HWND(Self);
4436   if QContextMenuEvent_reason(QContextMenuEventH(Event)) = QContextMenuEventKeyboard then
4437   begin
4438     Msg.XPos := -1;
4439     Msg.YPos := -1;
4440   end
4441   else
4442   begin
4443     Msg.XPos := SmallInt(MousePos.X);
4444     Msg.YPos := SmallInt(MousePos.Y);
4445   end;
4446 
4447   Result := DeliverMessage(Msg) <> 0;
4448 
4449   if Result then
4450     QEvent_accept(Event)
4451   else
4452   begin
4453     if Assigned(LCLObject.PopupMenu) then
4454       QEvent_ignore(Event);
4455     SetNoMousePropagation(QWidgetH(Sender), False);
4456     if (FOwner <> nil) and
4457       ((FChildOfComplexWidget = ccwCustomControl) or
4458       (FChildOfComplexWidget = ccwScrollingWinControl)) then
4459       SetNoMousePropagation(FOwner.Widget, False);
4460   end;
4461 
4462   if Result and (csDesigning in LCLObject.ComponentState) then
4463     SendMouseReleaseEventToSelf;
4464 end;
4465 
4466 procedure TQtWidget.SlotWhatsThis(Sender: QObjectH; Event: QEventH); cdecl;
4467 var
4468   Data: THelpInfo;
4469 begin
4470   if not CanSendLCLMessage then
4471     exit;
4472   Data.cbSize := SizeOf(Data);
4473   Data.iContextType := HELPINFO_WINDOW;
4474   Data.iCtrlId := 0;
4475   Data.hItemHandle := THandle(Sender);
4476   Data.dwContextId := 0;
4477   with QHelpEvent_globalPos(QHelpEventH(Event))^ do
4478     Data.MousePos := Point(X, Y);
4479   Application.HelpCommand(0, {%H-}PtrInt(@Data));
4480 end;
4481 
4482 procedure TQtWidget.SlotLCLMessage(Sender: QObjectH; Event: QEventH); cdecl;
4483 var
4484   MessageEvent: QLCLMessageEventH absolute Event;
4485   Msg: TLMessage;
4486 begin
4487   Msg.msg := Cardinal(QLCLMessageEvent_getMsg(MessageEvent));
4488   Msg.wParam := PtrInt(QLCLMessageEvent_getWParam(MessageEvent));
4489   Msg.lParam := PtrInt(QLCLMessageEvent_getLParam(MessageEvent));
4490   Msg.Result := 0;
4491   QLCLMessageEvent_setMsgResult(MessageEvent, PtrUInt(DeliverMessage(Msg)));
4492 end;
4493 
4494 procedure TQtWidget.Activate;
4495 begin
4496   QWidget_activateWindow(Widget);
4497 end;
4498 
4499 procedure TQtWidget.BringToFront;
4500 begin
4501   Activate;
4502   raiseWidget;
4503 end;
4504 
4505 procedure TQtWidget.clearMask;
4506 begin
4507   QWidget_clearMask(Widget);
4508 end;
4509 
4510 procedure TQtWidget.OffsetMousePos(APoint: PQtPoint);
4511 begin
4512   with getClientOffset do
4513   begin
4514     dec(APoint^.x, x);
4515     dec(APoint^.y, y);
4516   end;
4517 end;
4518 
4519 {------------------------------------------------------------------------------
4520   Function: TQtWidget.SetColor
4521   Params:  QColorH
4522   Returns: Nothing
4523 
4524   Changes the color of a widget
4525  ------------------------------------------------------------------------------}
4526 procedure TQtWidget.setColor(const Value: PQColor);
4527 begin
4528   Palette.setColor(Value);
4529 end;
4530 
getContextMenuPolicynull4531 function TQtWidget.getContextMenuPolicy: QtContextMenuPolicy;
4532 begin
4533   Result := QWidget_contextMenuPolicy(Widget);
4534 end;
4535 
4536 procedure TQtWidget.setContextMenuPolicy(const AValue: QtContextMenuPolicy);
4537 begin
4538   QWidget_setContextMenuPolicy(Widget, AValue);
4539 end;
4540 
4541 {------------------------------------------------------------------------------
4542   Function: TQtWidget.SetTextColor
4543   Params:  QColorH
4544   Returns: Nothing
4545 
4546   Changes the text color of a widget
4547  ------------------------------------------------------------------------------}
4548 procedure TQtWidget.setTextColor(const Value: PQColor);
4549 begin
4550   Palette.setTextColor(Value);
4551 end;
4552 
4553 procedure TQtWidget.setCursor(const ACursor: QCursorH);
4554 begin
4555   {$IFDEF DARWIN}
4556   if not QWidget_isVisible(Widget) then
4557     exit;
4558   {$ENDIF}
4559   if ACursor <> nil then
4560     QWidget_setCursor(Widget, ACursor)
4561   else
4562     QWidget_setCursor(Widget, FDefaultCursor);
4563 end;
4564 
4565 procedure TQtWidget.setDefaultColorRoles;
4566 begin
4567   FWidgetColorRole := QPaletteWindow;
4568   FTextColorRole := QPaletteWindowText;
4569 end;
4570 
4571 {------------------------------------------------------------------------------
4572   Function: TQtWidget.Update
4573   Params:  None
4574   Returns: Nothing
4575 
4576   Schedules a paint event for processing when Qt returns to the main event loop
4577  ------------------------------------------------------------------------------}
4578 procedure TQtWidget.Update(ARect: PRect = nil);
4579 begin
4580   if ARect <> nil then
4581     QWidget_update(Widget, ARect)
4582   else
4583     QWidget_update(Widget);
4584 end;
4585 
4586 procedure TQtWidget.UpdateRegion(ARgn: QRegionH);
4587 begin
4588   if ARgn <> nil then
4589     QWidget_update(Widget, ARgn)
4590   else
4591     QWidget_update(Widget);
4592 end;
4593 
4594 {------------------------------------------------------------------------------
4595   Function: TQtWidget.Repaint
4596   Params:  None
4597   Returns: Nothing
4598 
4599   Repaints the control imediately
4600  ------------------------------------------------------------------------------}
4601 procedure TQtWidget.Repaint(ARect: PRect = nil);
4602 begin
4603   if ARect <> nil then
4604     QWidget_repaint(Widget, ARect)
4605   else
4606     QWidget_repaint(Widget);
4607 end;
4608 
4609 procedure TQtWidget.setWindowTitle(Str: PWideString);
4610 begin
4611   QWidget_setWindowTitle(Widget, Str);
4612 end;
4613 
4614 procedure TQtWidget.WindowTitle(Str: PWideString);
4615 begin
4616   QWidget_WindowTitle(Widget, Str);
4617 end;
4618 
4619 procedure TQtWidget.Hide;
4620 begin
4621   QWidget_hide(Widget);
4622 end;
4623 
4624 procedure TQtWidget.Show;
4625 begin
4626   QWidget_show(Widget);
4627 end;
4628 
4629 procedure TQtWidget.ShowNormal;
4630 begin
4631   QWidget_showNormal(Widget);
4632 end;
4633 
4634 procedure TQtWidget.ShowMinimized;
4635 begin
4636   QWidget_showMinimized(Widget);
4637 end;
4638 
4639 procedure TQtWidget.ShowMaximized;
4640 begin
4641   QWidget_showMaximized(Widget);
4642 end;
4643 
4644 procedure TQtWidget.ShowFullScreen;
4645 begin
4646   QWidget_showFullScreen(Widget);
4647 end;
4648 
TQtWidget.getActionByIndexnull4649 function TQtWidget.getActionByIndex(AIndex: Integer): QActionH;
4650 var
4651   ActionList: TPtrIntArray;
4652 begin
4653   QWidget_actions(Widget, @ActionList);
4654   if (AIndex >= 0) and (AIndex < Length(ActionList)) then
4655     Result := QActionH(ActionList[AIndex])
4656   else
4657     Result := nil;
4658 end;
4659 
getAutoFillBackgroundnull4660 function TQtWidget.getAutoFillBackground: Boolean;
4661 begin
4662   Result := QWidget_autoFillBackground(Widget);
4663 end;
4664 
getEnablednull4665 function TQtWidget.getEnabled: Boolean;
4666 begin
4667   if Widget = nil then
4668     exit(False);
4669   Result := QWidget_isEnabled(Widget);
4670 end;
4671 
TQtWidget.getFontnull4672 function TQtWidget.getFont: QFontH;
4673 begin
4674   Result := QWidget_font(Widget);
4675 end;
4676 
TQtWidget.getFocusPolicynull4677 function TQtWidget.getFocusPolicy: QtFocusPolicy;
4678 begin
4679   Result := QWidget_focusPolicy(Widget);
4680 end;
4681 
getFrameGeometrynull4682 function TQtWidget.getFrameGeometry: TRect;
4683 begin
4684   QWidget_frameGeometry(Widget, @Result);
4685 end;
4686 
getGeometrynull4687 function TQtWidget.getGeometry: TRect;
4688 begin
4689   QWidget_geometry(Widget, @Result);
4690 end;
4691 
getLayoutDirectionnull4692 function TQtWidget.getLayoutDirection: QtLayoutDirection;
4693 begin
4694   Result := QWidget_layoutDirection(Widget);
4695 end;
4696 
getVisiblenull4697 function TQtWidget.getVisible: Boolean;
4698 begin
4699   if Widget = nil then
4700     exit(False);
4701   Result := QWidget_isVisible(Widget);
4702 end;
4703 
getVisibleTonull4704 function TQtWidget.getVisibleTo(AWidget: QWidgetH): Boolean;
4705 begin
4706   if Widget = nil then
4707     exit(False);
4708   Result := QWidget_isVisibleTo(Widget, AWidget);
4709 end;
4710 
TQtWidget.getOwnernull4711 function TQtWidget.getOwner: TQtWidget;
4712 begin
4713   Result := FOwner;
4714 end;
4715 
getParentnull4716 function TQtWidget.getParent: QWidgetH;
4717 begin
4718   Result := QWidget_parentWidget(Widget);
4719 end;
4720 
getPosnull4721 function TQtWidget.getPos: TQtPoint;
4722 begin
4723   QWidget_pos(Widget, @Result);
4724 end;
4725 
TQtWidget.getFrameSizenull4726 function TQtWidget.getFrameSize: TSize;
4727 begin
4728   QWidget_frameSize(Widget, @Result);
4729 end;
4730 
getSizenull4731 function TQtWidget.getSize: TSize;
4732 begin
4733   QWidget_size(Widget, @Result);
4734 end;
4735 
getTextnull4736 function TQtWidget.getText: WideString;
4737 begin
4738   Result := FText;
4739 end;
4740 
TQtWidget.getTextStaticnull4741 function TQtWidget.getTextStatic: Boolean;
4742 begin
4743   Result := True;
4744 end;
4745 
getHeightnull4746 function TQtWidget.getHeight: Integer;
4747 begin
4748   Result := QWidget_height(Widget);
4749 end;
4750 
getUpdatesEnablednull4751 function TQtWidget.getUpdatesEnabled: Boolean;
4752 begin
4753   Result := QWidget_updatesEnabled(Widget);
4754 end;
4755 
TQtWidget.getWidthnull4756 function TQtWidget.getWidth: Integer;
4757 begin
4758   Result := QWidget_width(Widget);
4759 end;
4760 
TQtWidget.getWindownull4761 function TQtWidget.getWindow: TQtWidget;
4762 var
4763   W: QWidgetH;
4764 begin
4765   Result := nil;
4766   W := QWidget_window(Widget);
4767   if W <> nil then
4768     Result := TQtWidget(HwndFromWidgetH(W));
4769 end;
4770 
getWindowStatenull4771 function TQtWidget.getWindowState: QtWindowStates;
4772 begin
4773   Result := QWidget_windowState(Widget);
4774 end;
4775 
getClientBoundsnull4776 function TQtWidget.getClientBounds: TRect;
4777 {$IFDEF VerboseQtResizeError}
4778 var
4779   R: TRect;
4780 {$ENDIF}
4781 begin
4782   QWidget_contentsRect(getContainerWidget, @Result);
4783   {only when FOwner implements it's own getClientBounds !
4784    Valid for FOwner: TQtTabWidget, TQtAbstractScrollArea and it's successors}
4785   if (FOwner <> nil) and
4786     not (ChildOfComplexWidget in [ccwComboBox]) then
4787   begin
4788     {$IFDEF VerboseQtResizeError}
4789     R := FOwner.getClientBounds;
4790     if not EqualRect(R, Result) then
4791       DebugLn('WARNING: Providing wrong clientRect ',dbgs(Result),' for ',dbgsName(LCLObject),' from ',dbgsName(Self),' FOwner ',dbgsName(FOwner),' ==>',dbgs(R));
4792     Result := R;
4793     {$ELSE}
4794     Result := FOwner.getClientBounds;
4795     {$ENDIF}
4796   end;
4797 end;
4798 
TQtWidget.getClientOffsetnull4799 function TQtWidget.getClientOffset: TPoint;
4800 var
4801   P: TQtPoint;
4802   R: TRect;
4803   {$IFDEF VerboseQtResizeError}
4804   Pt: TPoint;
4805   {$ENDIF}
4806 begin
4807   // we need an offset of container inside widget, but if container = widget then
4808   // offset = 0
4809   {$IFDEF VerboseQtResizeError}
4810   if Widget <> GetContainerWidget then
4811     QWidget_pos(GetContainerWidget, @P)
4812   else
4813     P := QtPoint(0, 0);
4814   R := getClientBounds;
4815   Result := Point(P.x + R.Left, P.y + R.Top);
4816   if (FOwner <> nil) and
4817     not (ChildOfComplexWidget in [ccwComboBox]) then
4818   begin
4819     Pt := FOwner.getClientOffset;
4820     if (Pt.x <> Result.x) or (Pt.y <> Result.y) then
4821       DebugLn('WARNING: Providing wrong clientOffset ',dbgs(Result),' for ',dbgsName(LCLObject),' from ',dbgsName(Self),' FOwner ',dbgsName(FOwner),' ==>',dbgs(Pt));
4822     Result := Pt;
4823   end;
4824   {$ELSE}
4825   if (FOwner <> nil) and
4826     not (ChildOfComplexWidget in [ccwComboBox]) then
4827   begin
4828     Result := FOwner.getClientOffset;
4829   end else
4830   begin
4831     if Widget <> GetContainerWidget then
4832       QWidget_pos(GetContainerWidget, @P)
4833     else
4834       P := QtPoint(0, 0);
4835     R := getClientBounds;
4836     Result := Point(P.x + R.Left, P.y + R.Top);
4837   end;
4838   {$ENDIF}
4839 end;
4840 
4841 procedure TQtWidget.grabMouse;
4842 begin
4843   //DumpStack;
4844   //DebugLn(['current grab is: ', dbgs(QWidget_mouseGrabber())]);
4845   //DebugLn(['grab mouse for: ', dbgsName(LCLObject), ' : ', dbgs(Widget)]);
4846   QWidget_grabMouse(Widget);
4847 end;
4848 
TQtWidget.hasFocusnull4849 function TQtWidget.hasFocus: Boolean;
4850 begin
4851   Result := QWidget_hasFocus(Widget);
4852 end;
4853 
IsActiveWindownull4854 function TQtWidget.IsActiveWindow: Boolean;
4855 begin
4856   Result := QWidget_isActiveWindow(Widget);
4857 end;
4858 
TQtWidget.isMinimizednull4859 function TQtWidget.isMinimized: Boolean;
4860 begin
4861   Result := QWidget_isMinimized(Widget);
4862 end;
4863 
isMaximizednull4864 function TQtWidget.isMaximized: Boolean;
4865 begin
4866   Result := QWidget_isMaximized(Widget);
4867 end;
4868 
TQtWidget.IsFramedWidgetnull4869 function TQtWidget.IsFramedWidget: boolean;
4870 begin
4871   Result := False;
4872 end;
4873 
TQtWidget.isFullScreennull4874 function TQtWidget.isFullScreen: Boolean;
4875 begin
4876   Result := QWidget_isFullScreen(Widget);
4877 end;
4878 
IsWindownull4879 function TQtWidget.IsWindow: Boolean;
4880 begin
4881   Result := QWidget_isWindow(Widget);
4882 end;
4883 
4884 procedure TQtWidget.lowerWidget;
4885 begin
4886   QWidget_lower(Widget);
4887 end;
4888 
MapToGlobalnull4889 function TQtWidget.MapToGlobal(APt: TPoint;
4890   const AWithScrollOffset: Boolean = False): TPoint;
4891 var
4892   Pt: TQtPoint;
4893   NewPt: TQtPoint;
4894 begin
4895   Pt := QtPoint(APt.X, APt.Y);
4896   NewPt := QtPoint(0, 0);
4897   QWidget_mapToGlobal(GetContainerWidget, @NewPt, @Pt);
4898   Result := Point(NewPt.x, NewPt.y);
4899 end;
4900 
MapFromGlobalnull4901 function TQtWidget.MapFromGlobal(APt: TPoint;
4902   const AWithScrollOffset: Boolean = False): TPoint;
4903 var
4904   Pt: TQtPoint;
4905   NewPt: TQtPoint;
4906 begin
4907   Pt := QtPoint(APt.X, APt.Y);
4908   NewPt := QtPoint(0, 0);
4909   QWidget_mapFromGlobal(GetContainerWidget, @NewPt, @Pt);
4910   Result := Point(NewPt.x, NewPt.y);
4911 end;
4912 
4913 procedure TQtWidget.move(ANewLeft, ANewTop: Integer);
4914 begin
4915   QWidget_move(Widget, ANewLeft, ANewTop);
4916 end;
4917 
4918 procedure TQtWidget.preferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean);
4919 var
4920   PrefSize: TSize;
4921 begin
4922   sizeHint(@PrefSize);
4923   if (PrefSize.cx >= 0) and (PrefSize.cy >=0) then
4924   begin
4925     PreferredWidth := PrefSize.cx;
4926     PreferredHeight := PrefSize.cy;
4927   end;
4928 end;
4929 
4930 procedure TQtWidget.raiseWidget;
4931 begin
4932   QWidget_raise(Widget);
4933 end;
4934 
4935 procedure TQtWidget.stackUnder(AWidget: QWidgetH);
4936 begin
4937   QWidget_stackUnder(Widget, AWidget);
4938 end;
4939 
4940 procedure TQtWidget.frame_resize(ANewWidth, ANewHeight: Integer);
4941 var
4942   R1, R2: TRect;
4943   dw, dh: integer;
4944 begin
4945   R1 := getGeometry;
4946   R2 := getFrameGeometry;
4947   dw := (R1.Left - R2.Left) + (R2.Right - R1.Right);
4948   dh := (R1.Top - R2.Top) + (R2.Bottom - R1.Bottom);
4949   QWidget_resize(Widget, ANewWidth - dw, ANewHeight - dh);
4950 end;
4951 
4952 procedure TQtWidget.Resize(ANewWidth, ANewHeight: Integer);
4953 begin
4954   QWidget_resize(Widget, ANewWidth, ANewHeight);
4955 end;
4956 
4957 procedure TQtWidget.releaseMouse;
4958 var
4959   AGrabWidget: QWidgetH;
4960 begin
4961   // capture widget can be one of children of Widget if Widget is complex control
4962   // so better to look for current Capture widget to release it
4963   // instead of pass Widget as argument
4964   AGrabWidget := QWidget_mouseGrabber();
4965   //DebugLn(['releasing current grab: ', dbgs(AGrabWidget)]);
4966   if AGrabWidget <> nil then
4967     QWidget_releaseMouse(AGrabWidget);
4968 end;
4969 
4970 procedure TQtWidget.scroll(dx, dy: integer; ARect: PRect = nil);
4971 begin
4972   if ARect = nil then
4973     QWidget_scroll(getContainerWidget, dx, dy)
4974   else
4975     QWidget_scroll(getContainerWidget, dx, dy, ARect);
4976 end;
4977 
4978 procedure TQtWidget.setAutoFillBackground(const AValue: Boolean);
4979 begin
4980   QWidget_setAutoFillBackground(Widget, AValue);
4981 end;
4982 
4983 procedure TQtWidget.setAttribute(const Attr: QtWidgetAttribute;
4984   const TurnOn: Boolean);
4985 begin
4986   QWidget_setAttribute(Widget, Attr, TurnOn);
4987 end;
4988 
4989 procedure TQtWidget.setBackgroundRole(const ARole: QPaletteColorRole);
4990 begin
4991   QWidget_setBackgroundRole(Widget, ARole);
4992 end;
4993 
4994 procedure TQtWidget.setDefaultColor(const DefaultColorType: TDefaultColorType);
4995 begin
4996   case DefaultColorType of
4997     dctBrush: setColor(@Palette.DefaultColor);
4998     dctFont: setTextColor(@Palette.DefaultTextColor);
4999   end;
5000 end;
5001 
5002 procedure TQtWidget.setEnabled(p1: Boolean);
5003 begin
5004   if not p1 and (HWND(Self) = GetCapture) then
5005     ReleaseCapture;
5006   QWidget_setEnabled(Widget, p1);
5007 end;
5008 
5009 procedure TQtWidget.setFocus;
5010 begin
5011   if getFocusPolicy <> QtNoFocus then
5012     QWidget_setFocus(Widget, QtTabFocusReason)
5013   else
5014     QWidget_setFocus(Widget);
5015 end;
5016 
5017 procedure TQtWidget.setFocusPolicy(const APolicy: QtFocusPolicy);
5018 begin
5019   QWidget_setFocusPolicy(Widget, APolicy);
5020 end;
5021 
5022 procedure TQtWidget.setFocusProxy(const AWidget: QWidgetH);
5023 begin
5024   QWidget_setFocusProxy(Widget, AWidget);
5025 end;
5026 
5027 procedure TQtWidget.setFont(AFont: QFontH);
5028 begin
5029   QWidget_setFont(Widget, AFont);
5030 end;
5031 
5032 procedure TQtWidget.setGeometry(ARect: TRect);
5033 begin
5034   QWidget_setGeometry(Widget, @ARect);
5035 end;
5036 
5037 procedure TQtWidget.setInitialFontColor(AControl: TWinControl);
5038 var
5039   QColor: TQColor;
5040   ColorRef: TColorRef;
5041 begin
5042   if AControl.Font.Color = clDefault then
5043   begin
5044     BeginUpdate;
5045     Palette.ForceColor := True;
5046     SetDefaultColor(dctFont);
5047     Palette.ForceColor := False;
5048     EndUpdate;
5049   end
5050   else
5051   begin
5052     ColorRef := ColorToRGB(AControl.Font.Color);
5053     QColor_fromRgb(@QColor,Red(ColorRef),Green(ColorRef),Blue(ColorRef));
5054     BeginUpdate;
5055     Palette.ForceColor := True;
5056     SetTextColor(@QColor);
5057     Palette.ForceColor := False;
5058     EndUpdate;
5059   end;
5060 end;
5061 
5062 procedure TQtWidget.setLayoutDirection(ADirection: QtLayoutDirection);
5063 begin
5064   QWidget_setLayoutDirection(Widget, ADirection);
5065 end;
5066 
5067 procedure TQtWidget.setMaximumSize(AWidth, AHeight: Integer);
5068 begin
5069   QWidget_setMaximumSize(Widget, AWidth, AHeight);
5070 end;
5071 
5072 procedure TQtWidget.setMask(AMask: QBitmapH);
5073 begin
5074   QWidget_setMask(Widget, AMask);
5075 end;
5076 
5077 procedure TQtWidget.setMask(AMask: QRegionH);
5078 begin
5079   QWidget_setMask(Widget, AMask);
5080 end;
5081 
5082 procedure TQtWidget.setMinimumSize(AWidth, AHeight: Integer);
5083 begin
5084   QWidget_setMinimumSize(Widget, AWidth, AHeight);
5085 end;
5086 
5087 procedure TQtWidget.setVisible(AVisible: Boolean);
5088 begin
5089   QWidget_setVisible(Widget, AVisible);
5090 end;
5091 
windowModalitynull5092 function TQtWidget.windowModality: QtWindowModality;
5093 begin
5094   Result := QWidget_windowModality(Widget);
5095 end;
5096 
grabWindownull5097 function TQtWidget.grabWindow(const X, Y, Width, Height: integer; AWidget: QWidgetH): QPixmapH;
5098 var
5099   AWidgetID: PtrUInt;
5100   AWindow: QWindowH;
5101   AScreen: QScreenH;
5102 begin
5103   if AWidget = nil then
5104     AWidget := Widget;
5105   if (Width > 0) and (Height > 0) then
5106     Result := QPixmap_create(Width, Height)
5107   else
5108     Result := QPixmap_create();
5109   AWidgetID := QWidget_winId(AWidget);
5110   AWindow := QWidget_windowHandle(AWidget);
5111   if AWindow <> nil then
5112     AScreen := QWindow_screen(AWindow)
5113   else
5114     AScreen := QGuiApplication_primaryScreen();
5115 
5116   if (Width > 0) and (Height > 0) then
5117     QScreen_grabWindow(AScreen, Result, AWidgetID, X,  Y, Width, Height)
5118   else
5119     QScreen_grabWindow(AScreen, Result, AWidgetID, X,  Y);
5120 end;
5121 
5122 procedure TQtWidget.setWindowModality(windowModality: QtWindowModality);
5123 begin
5124   QWidget_setWindowModality(Widget, windowModality);
5125 end;
5126 
5127 procedure TQtWidget.setWindowOpacity(opacity: double);
5128 begin
5129   QWidget_setWindowOpacity(Widget, opacity);
5130 end;
5131 
5132 procedure TQtWidget.setParent(parent: QWidgetH);
5133 begin
5134   QWidget_setParent(Widget, parent);
5135 end;
5136 
5137 procedure TQtWidget.setText(const W: WideString);
5138 begin
5139   FText := W;
5140 end;
5141 
5142 procedure TQtWidget.setWindowFlags(_type: QtWindowFlags);
5143 begin
5144   QWidget_setWindowFlags(Widget, _type);
5145 end;
5146 
5147 procedure TQtWidget.setWindowIcon(AIcon: QIconH);
5148 var
5149   DestroyIcon: Boolean;
5150 begin
5151   DestroyIcon := AIcon = nil;
5152   if DestroyIcon then
5153     AIcon := QIcon_create();
5154   QWidget_setWindowIcon(Widget, AIcon);
5155   if DestroyIcon then
5156     QIcon_destroy(AIcon);
5157 end;
5158 
TQtWidget.windowFlagsnull5159 function TQtWidget.windowFlags: QtWindowFlags;
5160 begin
5161   Result := QWidget_windowFlags(Widget);
5162 end;
5163 
5164 procedure TQtWidget.setWidth(p1: Integer);
5165 var
5166   R: TRect;
5167 begin
5168   R := getGeometry;
5169   R.Right := R.Left + p1;
5170   setGeometry(R);
5171 end;
5172 
5173 procedure TQtWidget.setHeight(p1: Integer);
5174 var
5175   R: TRect;
5176 begin
5177   R := getGeometry;
5178   R.Bottom := R.Top + p1;
5179   setGeometry(R);
5180 end;
5181 
5182 procedure TQtWidget.setUpdatesEnabled(const AEnabled: Boolean);
5183 begin
5184   QWidget_setUpdatesEnabled(Widget, AEnabled);
5185 end;
5186 
5187 procedure TQtWidget.setWindowState(AState: QtWindowStates);
5188 begin
5189   QWidget_setWindowState(Widget, AState);
5190 end;
5191 
5192 procedure TQtWidget.sizeHint(size: PSize);
5193 begin
5194   QWidget_sizeHint(Widget, size);
5195 end;
5196 
TQtWidget.testAttributenull5197 function TQtWidget.testAttribute(const AAttribute: QtWidgetAttribute): boolean;
5198 begin
5199   Result := QWidget_testAttribute(Widget, AAttribute);
5200 end;
5201 
5202 {------------------------------------------------------------------------------
5203   Function: TQtWidget.QtKeyToLCLKey
5204   Params:  None
5205   Returns: Nothing
5206  ------------------------------------------------------------------------------}
QtKeyToLCLKeynull5207 function TQtWidget.QtKeyToLCLKey(AKey: Integer; AText: WideString;
5208   AEvent: QKeyEventH): Word;
5209 begin
5210   // The big problem here with unicode keys
5211   // Example: for Russian letter A qt returns AKey = $0410 and this is
5212   // absolutely correct: 0400 - 04FF - is russian unicode space and
5213   // 0410 is defined as "CYRILLIC CAPITAL LETTER A"
5214 
5215   Result := VK_UNKNOWN;
5216   case AKey of
5217     QtKey_0..QtKey_9: Result := VK_0 + (AKey - QtKey_0);
5218     QtKey_At: Result := VK_2; // some bug, but Ctrl + Shit + 2 produce QtKey_At
5219     QtKey_Escape: Result := VK_ESCAPE;
5220     QtKey_Tab: Result := VK_TAB;
5221     QtKey_Backtab: Result := VK_TAB; // ???
5222     QtKey_Backspace: Result := VK_BACK;
5223     QtKey_Return: Result := VK_RETURN;
5224     QtKey_Enter: Result := VK_RETURN;
5225     QtKey_Insert: Result := VK_INSERT;
5226     QtKey_Delete: Result := VK_DELETE;
5227     QtKey_Pause: Result := VK_PAUSE;
5228     QtKey_Print: Result := VK_PRINT;
5229     QtKey_SysReq: Result := VK_UNKNOWN; // ???
5230     QtKey_Clear: Result := VK_CLEAR;
5231     QtKey_Home: Result := VK_HOME;
5232     QtKey_End: Result := VK_END;
5233     QtKey_Left: Result := VK_LEFT;
5234     QtKey_Up: Result := VK_UP;
5235     QtKey_Right: Result := VK_RIGHT;
5236     QtKey_Down: Result := VK_DOWN;
5237     QtKey_PageUp: Result := VK_PRIOR;
5238     QtKey_PageDown: Result := VK_NEXT;
5239     QtKey_Shift: Result := VK_SHIFT;     // There is also RSHIFT
5240     QtKey_Control: Result := VK_CONTROL; // There is also RCONTROL
5241     QtKey_Meta:
5242     begin
5243       //TODO: Qt sends meta key, but info about left & right is in nativeScanCode
5244       {$IFDEF HASX11}
5245       if QKeyEvent_nativeVirtualKey(AEvent) = XK_Super_L then
5246         Result := VK_LWIN
5247       else
5248       if QKeyEvent_nativeVirtualKey(AEvent) = XK_Super_R then
5249         Result := VK_RWIN
5250       else
5251         Result := VK_MENU;
5252       {$ELSE}
5253       Result := VK_LWIN;
5254       {$ENDIF}
5255     end;
5256     QtKey_Alt: Result := VK_MENU;
5257     QtKey_AltGr: Result := VK_RMENU;
5258     QtKey_CapsLock: Result := VK_CAPITAL;
5259     QtKey_NumLock: Result := VK_NUMLOCK;
5260     QtKey_ScrollLock: Result := VK_SCROLL;
5261     QtKey_F1..QtKey_F24: Result := VK_F1 + (AKey - QtKey_F1);
5262     QtKey_F25..
5263     QtKey_F35: Result := VK_UNKNOWN;
5264     QtKey_Super_L: Result := VK_LWIN;
5265     QtKey_Super_R: Result := VK_RWIN;
5266     QtKey_Menu: Result := VK_APPS;
5267     QtKey_Hyper_L,
5268     QtKey_Hyper_R: Result := VK_UNKNOWN;
5269     QtKey_Help: Result := VK_HELP;
5270     QtKey_Direction_L,
5271     QtKey_Direction_R,
5272     QtKey_Exclam,QtKey_NumberSign..
5273     QtKey_AmperSand,
5274     QtKey_ParenLeft,
5275     QtKey_ParenRight: Result := VK_UNKNOWN;
5276     QtKey_Asterisk: Result := VK_MULTIPLY;
5277     QtKey_Plus: Result := VK_ADD;
5278     QtKey_Comma: Result := VK_SEPARATOR;
5279     QtKey_Minus: Result := VK_SUBTRACT;
5280     QtKey_Period: Result := VK_DECIMAL;
5281     QtKey_Slash: Result := VK_DIVIDE;
5282     QtKey_Equal: Result := VK_OEM_PLUS;
5283 
5284     QtKey_Colon,
5285     QtKey_Semicolon: Result := VK_OEM_1;
5286     QtKey_AsciiTilde: Result := VK_OEM_3;
5287     QtKey_BraceLeft,
5288     QtKey_BracketLeft: Result := VK_OEM_4;
5289     QtKey_BackSlash: Result := VK_OEM_5;
5290     QtKey_BraceRight,
5291     QtKey_BracketRight: Result := VK_OEM_6;
5292     QtKey_QuoteDbl,
5293     QtKey_Apostrophe: Result := VK_OEM_7;
5294     QtKey_Less: Result := VK_OEM_COMMA;
5295     QtKey_Greater: Result := VK_OEM_PERIOD;
5296 
5297     QtKey_ydiaeresis,
5298     QtKey_Multi_key..
5299     QtKey_No: Result := VK_UNKNOWN;
5300     QtKey_Cancel: Result := VK_CANCEL;
5301     QtKey_Printer: Result := VK_PRINT;
5302     QtKey_Execute: Result := VK_EXECUTE;
5303     QtKey_Sleep: Result := VK_SLEEP;
5304     QtKey_Play: Result := VK_PLAY;
5305     QtKey_Zoom: Result := VK_ZOOM;
5306     QtKey_Context1..
5307     QtKey_Flip,
5308     QtKey_unknown: Result := VK_UNKNOWN;
5309   else
5310     if AKey in [0..255] then // Qt:AKey = VK_KEY in many cases
5311       Result := AKey
5312     else
5313     if AText <> '' then
5314     begin
5315       // use QChar to understand whether we have unicode letter or number here or no
5316       // then try to map that char to VK_ code
5317     end;
5318   end;
5319 end;
5320 
5321 procedure TQtWidget.SetLastCaretPos(const AValue: TQtPoint);
5322 begin
5323   FLastCaretPos := AValue;
5324 end;
5325 
5326 procedure TQtWidget.SetHasCaret(const AValue: Boolean);
5327 begin
5328   FHasCaret := AValue;
5329 end;
5330 
ProcessArrowKeysnull5331 function TQtWidget.ProcessArrowKeys: Boolean;
5332 begin
5333   Result := False;
5334 end;
5335 
5336 class procedure TQtWidget.removeProperty(AObject: QObjectH; APropName: PAnsiChar);
5337 var
5338   AVariant: QVariantH;
5339 begin
5340   AVariant := QVariant_create;
5341   QObject_setProperty(AObject, APropName, AVariant);
5342   QVariant_destroy(AVariant);
5343 end;
5344 
5345 class procedure TQtWidget.setProperty(AObject: QObjectH; APropName: PAnsiChar; APropValue: Int64);
5346 var
5347   AVariant: QVariantH;
5348 begin
5349   AVariant := QVariant_create(APropValue);
5350   QObject_setProperty(AObject, APropName, AVariant);
5351   QVariant_destroy(AVariant);
5352 end;
5353 
LCLKeyToQtKeynull5354 function TQtWidget.LCLKeyToQtKey(AKey: Word): Integer;
5355 const
5356   VKKeyToQtKeyMap: array[0..255] of Integer = // Keyboard mapping table
5357    (
5358     QtKey_unknown,
5359     QtKey_unknown,
5360     QtKey_unknown,
5361     QtKey_Cancel,
5362     QtKey_unknown,
5363     QtKey_unknown,
5364     QtKey_unknown,
5365     QtKey_unknown,
5366     QtKey_Backspace,
5367     QtKey_Tab,
5368     QtKey_unknown,
5369     QtKey_unknown,
5370     QtKey_Clear,
5371     QtKey_Return,
5372     QtKey_unknown,
5373     QtKey_unknown,
5374     QtKey_Shift,
5375     QtKey_Control,
5376     QtKey_Alt,
5377     QtKey_Pause,
5378     QtKey_CapsLock,
5379     QtKey_unknown,
5380     QtKey_unknown,
5381     QtKey_unknown,
5382     QtKey_unknown,
5383     QtKey_unknown,
5384     QtKey_unknown,
5385     QtKey_Escape,
5386     QtKey_unknown,
5387     QtKey_unknown,
5388     QtKey_unknown,
5389     QtKey_Mode_switch,
5390     QtKey_Space,
5391     QtKey_PageUp,
5392     QtKey_PageDown,
5393     QtKey_End,
5394     QtKey_Home,
5395     QtKey_Left,
5396     QtKey_Up,
5397     QtKey_Right,
5398     QtKey_Down,
5399     QtKey_Select,
5400     QtKey_Printer,
5401     QtKey_Execute,
5402     QtKey_Print,
5403     QtKey_Insert,
5404     QtKey_Delete,
5405     QtKey_Help,
5406     QtKey_0,
5407     QtKey_1,
5408     QtKey_2,
5409     QtKey_3,
5410     QtKey_4,
5411     QtKey_5,
5412     QtKey_6,
5413     QtKey_7,
5414     QtKey_8,
5415     QtKey_9,
5416     QtKey_unknown,
5417     QtKey_unknown,
5418     QtKey_unknown,
5419     QtKey_unknown,
5420     QtKey_unknown,
5421     QtKey_unknown,
5422     QtKey_unknown,
5423     QtKey_A,
5424     QtKey_B,
5425     QtKey_C,
5426     QtKey_D,
5427     QtKey_E,
5428     QtKey_F,
5429     QtKey_G,
5430     QtKey_H,
5431     QtKey_I,
5432     QtKey_J,
5433     QtKey_K,
5434     QtKey_L,
5435     QtKey_M,
5436     QtKey_N,
5437     QtKey_O,
5438     QtKey_P,
5439     QtKey_Q,
5440     QtKey_R,
5441     QtKey_S,
5442     QtKey_T,
5443     QtKey_U,
5444     QtKey_V,
5445     QtKey_W,
5446     QtKey_X,
5447     QtKey_Y,
5448     QtKey_Z,
5449     QtKey_Meta,
5450     QtKey_Meta,
5451     QtKey_Menu,
5452     QtKey_unknown,
5453     QtKey_Sleep,
5454     QtKey_0,
5455     QtKey_1,
5456     QtKey_2,
5457     QtKey_3,
5458     QtKey_4,
5459     QtKey_5,
5460     QtKey_6,
5461     QtKey_7,
5462     QtKey_8,
5463     QtKey_9,
5464     QtKey_Asterisk,
5465     QtKey_Plus,
5466     QtKey_Comma,
5467     QtKey_Minus,
5468     QtKey_Period,
5469     QtKey_Slash,
5470     QtKey_F1,
5471     QtKey_F2,
5472     QtKey_F3,
5473     QtKey_F4,
5474     QtKey_F5,
5475     QtKey_F6,
5476     QtKey_F7,
5477     QtKey_F8,
5478     QtKey_F9,
5479     QtKey_F10,
5480     QtKey_F11,
5481     QtKey_F12,
5482     QtKey_F13,
5483     QtKey_F14,
5484     QtKey_F15,
5485     QtKey_F16,
5486     QtKey_F17,
5487     QtKey_F18,
5488     QtKey_F19,
5489     QtKey_F20,
5490     QtKey_F21,
5491     QtKey_F22,
5492     QtKey_F23,
5493     QtKey_F24,
5494     QtKey_unknown,
5495     QtKey_unknown,
5496     QtKey_unknown,
5497     QtKey_unknown,
5498     QtKey_unknown,
5499     QtKey_unknown,
5500     QtKey_unknown,
5501     QtKey_unknown,
5502     QtKey_NumLock,
5503     QtKey_ScrollLock,
5504     QtKey_unknown,
5505     QtKey_Massyo,
5506     QtKey_Touroku,
5507     QtKey_unknown,
5508     QtKey_unknown,
5509     QtKey_unknown,
5510     QtKey_unknown,
5511     QtKey_unknown,
5512     QtKey_unknown,
5513     QtKey_unknown,
5514     QtKey_unknown,
5515     QtKey_unknown,
5516     QtKey_unknown,
5517     QtKey_unknown,
5518     QtKey_Shift,
5519     QtKey_Shift,
5520     QtKey_Control,
5521     QtKey_Control,
5522     QtKey_Alt,
5523     QtKey_Alt,
5524     QtKey_Back,
5525     QtKey_Forward,
5526     QtKey_Refresh,
5527     QtKey_Stop,
5528     QtKey_Search,
5529     QtKey_Favorites,
5530     QtKey_HomePage,
5531     QtKey_VolumeMute,
5532     QtKey_VolumeDown,
5533     QtKey_VolumeUp,
5534     QtKey_MediaNext,
5535     QtKey_MediaPrevious,
5536     QtKey_MediaStop,
5537     QtKey_MediaPlay,
5538     QtKey_LaunchMail,
5539     QtKey_LaunchMedia,
5540     QtKey_Launch0,
5541     QtKey_Launch1,
5542     QtKey_unknown,
5543     QtKey_unknown,
5544     QtKey_1,
5545     QtKey_Plus,
5546     QtKey_Comma,
5547     QtKey_Minus,
5548     QtKey_Period,
5549     QtKey_2,
5550     QtKey_3,
5551     QtKey_unknown,
5552     QtKey_unknown,
5553     QtKey_unknown,
5554     QtKey_unknown,
5555     QtKey_unknown,
5556     QtKey_unknown,
5557     QtKey_unknown,
5558     QtKey_unknown,
5559     QtKey_unknown,
5560     QtKey_unknown,
5561     QtKey_unknown,
5562     QtKey_unknown,
5563     QtKey_unknown,
5564     QtKey_unknown,
5565     QtKey_unknown,
5566     QtKey_unknown,
5567     QtKey_unknown,
5568     QtKey_unknown,
5569     QtKey_unknown,
5570     QtKey_unknown,
5571     QtKey_unknown,
5572     QtKey_unknown,
5573     QtKey_unknown,
5574     QtKey_unknown,
5575     QtKey_unknown,
5576     QtKey_unknown,
5577     QtKey_4,
5578     QtKey_5,
5579     QtKey_6,
5580     QtKey_7,
5581     QtKey_8,
5582     QtKey_unknown,
5583     QtKey_unknown,
5584     QtKey_unknown,
5585     QtKey_unknown,
5586     QtKey_unknown,
5587     QtKey_unknown,
5588     QtKey_unknown,
5589     QtKey_unknown,
5590     QtKey_unknown,
5591     QtKey_unknown,
5592     QtKey_unknown,
5593     QtKey_unknown,
5594     QtKey_unknown,
5595     QtKey_unknown,
5596     QtKey_unknown,
5597     QtKey_unknown,
5598     QtKey_unknown,
5599     QtKey_unknown,
5600     QtKey_unknown,
5601     QtKey_unknown,
5602     QtKey_unknown,
5603     QtKey_unknown,
5604     QtKey_unknown,
5605     QtKey_unknown,
5606     QtKey_unknown,
5607     QtKey_unknown,
5608     QtKey_Play,
5609     QtKey_Zoom,
5610     QtKey_unknown,
5611     QtKey_unknown,
5612     QtKey_Clear,
5613     QtKey_unknown
5614    );
5615 begin
5616   if AKey > 255 then
5617     Result := QtKey_unknown
5618   else
5619     Result := VKKeyToQtKeyMap[AKey];
5620 end;
5621 
TQtWidget.ShiftStateToQtModifiersnull5622 function TQtWidget.ShiftStateToQtModifiers(Shift: TShiftState): QtModifier;
5623 begin
5624   Result := 0;
5625   if ssCtrl  in Shift then inc(Result, QtCTRL);
5626   if ssShift in Shift then Inc(Result, QtSHIFT);
5627   if ssMeta  in Shift then Inc(Result, QtMETA);
5628   if ssAlt   in Shift then Inc(Result, QtALT);
5629 end;
5630 
TQtWidget.QueryInterfacenull5631 function TQtWidget.QueryInterface(constref iid: TGuid; out obj): LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
5632 begin
5633   if GetInterface(iid, obj) then
5634     Result := 0
5635   else
5636     Result := E_NOINTERFACE;
5637 end;
5638 
_AddRefnull5639 function TQtWidget._AddRef: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
5640 begin
5641   Result := -1; // no ref counting
5642 end;
5643 
_Releasenull5644 function TQtWidget._Release: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
5645 begin
5646   Result := -1;
5647 end;
5648 
TQtWidget.GetPropsnull5649 function TQtWidget.GetProps(const AnIndex: String): pointer;
5650 var
5651   i: Integer;
5652 begin
5653   if (Fprops<>nil) then
5654   begin
5655     i:=Fprops.IndexOf(AnIndex);
5656     if i>=0 then
5657     begin
5658       result:=Fprops.Objects[i];
5659       exit;
5660     end;
5661   end;
5662   result := nil;
5663 end;
5664 
TQtWidget.getScrolledOffsetnull5665 function TQtWidget.getScrolledOffset: TPoint;
5666 begin
5667   Result := Point(-FScrollX, -FScrollY);
5668 end;
5669 
TQtWidget.GetStyleSheetnull5670 function TQtWidget.GetStyleSheet: WideString;
5671 var
5672   WStr: WideString;
5673 begin
5674   QWidget_styleSheet(Widget, @WStr);
5675   Result := UTF16ToUTF8(WStr);
5676 end;
5677 
5678 {------------------------------------------------------------------------------
5679   Function: TQtWidget.GetPalette
5680   Params:  Nothing
5681   Returns: TQtWidgetPalette
5682 
5683   Assigns default widget palette, also takes care of widget colors changing.
5684  ------------------------------------------------------------------------------}
GetPalettenull5685 function TQtWidget.GetPalette: TQtWidgetPalette;
5686 begin
5687   if not Assigned(FPalette) then
5688   begin
5689     if (ClassType = TQtCustomControl) then
5690       FPalette := TQtWidgetPalette.Create(WidgetColorRole, TextColorRole,
5691         TQtCustomControl(Self).viewport.Widget)
5692     else
5693       FPalette := TQtWidgetPalette.Create(WidgetColorRole, TextColorRole, Widget);
5694   end;
5695   Result := FPalette;
5696 end;
5697 
TQtWidget.GetContextnull5698 function TQtWidget.GetContext: HDC;
5699 begin
5700   Result := FContext;
5701 end;
5702 
TQtWidget.GetWidgetnull5703 function TQtWidget.GetWidget: QWidgetH;
5704 begin
5705   Result := QWidgetH(TheObject);
5706 end;
5707 
TQtWidget.DeliverMessagenull5708 function TQtWidget.DeliverMessage(var Msg;
5709   const AIsInputEvent: Boolean = False): LRESULT;
5710 var
5711   AEvent: Cardinal;
5712 begin
5713   Result := LRESULT(AIsInputEvent);
5714   if LCLObject = nil then
5715     Exit;
5716   AEvent := TLMessage(Msg).Msg;
5717   try
5718     if LCLObject.HandleAllocated then
5719     begin
5720       LCLObject.WindowProc(TLMessage(Msg));
5721       Result := TLMessage(Msg).Result;
5722     end;
5723   except
5724     Result := 1;
5725     if AIsInputEvent and (LCLObject = nil) and (PtrUInt(Widget) = 0) and
5726       QtWidgetSet.IsValidHandle(HWND(Self)) then
5727     begin
5728       DebugLn(Format('WARNING: %s has been destroyed while processing input event %u result %u',
5729         [ClassName, AEvent, Result]));
5730     end else
5731       Application.HandleException(nil);
5732   end;
5733 end;
5734 
5735 procedure TQtWidget.SetProps(const AnIndex: String; const AValue: pointer);
5736 var
5737   i: Integer;
5738 begin
5739   if FProps=nil then
5740   begin
5741     FProps:=TStringList.Create;
5742     FProps.Sorted:=true;
5743   end;
5744   i := Fprops.IndexOf(AnIndex);
5745   if i < 0 then
5746     i := FProps.Add(AnIndex);
5747   Fprops.Objects[i] := TObject(AValue);
5748 end;
5749 
5750 procedure TQtWidget.SetStyleSheet(const AValue: WideString);
5751 var
5752   WStr: WideString;
5753 begin
5754   WStr := GetUTF8String(AValue);
5755   QWidget_setStyleSheet(Widget, @WStr);
5756 end;
5757 
5758 procedure TQtWidget.SetWidget(const AValue: QWidgetH);
5759 begin
5760   TheObject := AValue;
5761 end;
5762 
TQtWidget.CreateWidgetnull5763 function TQtWidget.CreateWidget(const Params: TCreateParams): QWidgetH;
5764 var
5765   Parent: QWidgetH;
5766 begin
5767   FHasPaint := True;
5768 
5769   if Params.WndParent <> 0 then
5770     Parent := TQtWidget(Params.WndParent).GetContainerWidget
5771   else
5772     Parent := nil;
5773 
5774   Widget := QWidget_create(Parent);
5775   Result := Widget;
5776 end;
5777 
5778 procedure TQtWidget.DestroyWidget;
5779 begin
5780   if (Widget <> nil) and FOwnWidget then
5781     QObject_deleteLater(Widget);
5782   Widget := nil;
5783 end;
5784 
5785 { TQtAbstractButton }
5786 
5787 procedure TQtAbstractButton.setIcon(AIcon: QIconH);
5788 begin
5789   QAbstractButton_setIcon(QAbstractButtonH(Widget), AIcon);
5790 end;
5791 
5792 procedure TQtAbstractButton.setIconSize(Size: PSize);
5793 begin
5794   QAbstractButton_setIconSize(QAbstractButtonH(Widget), Size);
5795 end;
5796 
5797 procedure TQtAbstractButton.setShortcut(AShortCutK1, AShortCutK2: TShortcut);
5798 var
5799   Key: Word;
5800   Shift: TShiftState;
5801   QtK1, QtK2: integer;
5802   KeySequence: QKeySequenceH;
5803 begin
5804   QtK1 := 0;
5805   QtK2 := 0;
5806   if AShortCutK1 <> 0 then
5807   begin
5808     ShortCutToKey(AShortCutK1, Key, Shift);
5809     QtK1 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
5810     if AShortCutK2 <> 0 then
5811     begin
5812       ShortCutToKey(AShortCutK2, Key, Shift);
5813       QtK2 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
5814     end;
5815   end;
5816   KeySequence := QKeySequence_create(QtK1, QtK2);
5817   QAbstractButton_setShortcut(QAbstractButtonH(Widget), KeySequence);
5818   QKeySequence_destroy(KeySequence);
5819 end;
5820 
5821 {------------------------------------------------------------------------------
5822   Function: TQtAbstractButton.SetText
5823   Params:  None
5824   Returns: Nothing
5825  ------------------------------------------------------------------------------}
5826 procedure TQtAbstractButton.SetText(const W: WideString);
5827 begin
5828   QAbstractButton_setText(QAbstractButtonH(Widget), @W);
5829 end;
5830 
TQtAbstractButton.ProcessArrowKeysnull5831 function TQtAbstractButton.ProcessArrowKeys: Boolean;
5832 begin
5833   Result := True;
5834 end;
5835 
TQtAbstractButton.CanPaintBackgroundnull5836 function TQtAbstractButton.CanPaintBackground: Boolean;
5837 begin
5838   Result := CanSendLCLMessage and getEnabled and
5839     (LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
5840     // DO NOT REMOVE ! QCheckBox,QRadioButton default = clBackground  !
5841 end;
5842 
TQtAbstractButton.getIconSizenull5843 function TQtAbstractButton.getIconSize: TSize;
5844 begin
5845   QAbstractButton_iconSize(QAbstractButtonH(Widget), @Result);
5846 end;
5847 
5848 {------------------------------------------------------------------------------
5849   Function: TQtAbstractButton.Text
5850   Params:  None
5851   Returns: Nothing
5852  ------------------------------------------------------------------------------}
getTextnull5853 function TQtAbstractButton.getText: WideString;
5854 begin
5855   QAbstractButton_text(QAbstractButtonH(Widget), @Result);
5856 end;
5857 
5858 procedure TQtAbstractButton.Toggle;
5859 begin
5860   QAbstractButton_toggle(QAbstractButtonH(Widget));
5861 end;
5862 
5863 {------------------------------------------------------------------------------
5864   Function: TQtAbstractButton.isChecked
5865   Params:  None
5866   Returns: Nothing
5867  ------------------------------------------------------------------------------}
TQtAbstractButton.isCheckednull5868 function TQtAbstractButton.isChecked: Boolean;
5869 begin
5870   Result := QAbstractButton_isChecked(QAbstractButtonH(Widget));
5871 end;
5872 
TQtAbstractButton.isDownnull5873 function TQtAbstractButton.isDown: Boolean;
5874 begin
5875   Result := QAbstractButton_isDown(QAbstractButtonH(Widget));
5876 end;
5877 
5878 procedure TQtAbstractButton.setCheckable(p1: Boolean);
5879 begin
5880   QAbstractButton_setCheckable(QAbstractButtonH(Widget), p1);
5881 end;
5882 
5883 {------------------------------------------------------------------------------
5884   Function: TQtAbstractButton.setChecked
5885   Params:  None
5886   Returns: Nothing
5887  ------------------------------------------------------------------------------}
5888 procedure TQtAbstractButton.setChecked(p1: Boolean);
5889 begin
5890   QAbstractButton_setChecked(QAbstractButtonH(Widget), p1);
5891 end;
5892 
5893 procedure TQtAbstractButton.setDefaultColorRoles;
5894 begin
5895   WidgetColorRole := QPaletteButton;
5896   TextColorRole := QPaletteButtonText;
5897 end;
5898 
5899 procedure TQtAbstractButton.setDown(p1: Boolean);
5900 begin
5901   QAbstractButton_setDown(QAbstractButtonH(Widget), p1);
5902 end;
5903 
5904 {------------------------------------------------------------------------------
5905   Function: TQtAbstractButton.SignalPressed
5906   Params:  None
5907   Returns: Nothing
5908  ------------------------------------------------------------------------------}
5909 procedure TQtAbstractButton.SignalPressed; cdecl;
5910 var
5911   Msg: TLMessage;
5912 begin
5913   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5914   Msg.Msg := LM_KEYDOWN;
5915   DeliverMessage(Msg);
5916 end;
5917 
5918 {------------------------------------------------------------------------------
5919   Function: TQtAbstractButton.SignalReleased
5920   Params:  None
5921   Returns: Nothing
5922  ------------------------------------------------------------------------------}
5923 procedure TQtAbstractButton.SignalReleased; cdecl;
5924 var
5925   Msg: TLMessage;
5926 begin
5927   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5928   Msg.Msg := LM_KEYUP;
5929   DeliverMessage(Msg);
5930 end;
5931 
5932 {------------------------------------------------------------------------------
5933   Function: TQtAbstractButton.SignalClicked
5934   Params:  None
5935   Returns: Nothing
5936  ------------------------------------------------------------------------------}
5937 procedure TQtAbstractButton.SignalClicked(Checked: Boolean = False); cdecl;
5938 var
5939   Msg: TLMessage;
5940 begin
5941   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5942   Msg.Msg := LM_CHANGED;
5943   DeliverMessage(Msg);
5944 end;
5945 
5946 {------------------------------------------------------------------------------
5947   Function: TQtAbstractButton.SignalClicked2
5948   Params:  None
5949   Returns: Nothing
5950  ------------------------------------------------------------------------------}
5951 procedure TQtAbstractButton.SignalClicked2; cdecl;
5952 var
5953   Msg: TLMessage;
5954 begin
5955   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5956   Msg.Msg := LM_CLICKED;
5957   DeliverMessage(Msg);
5958 end;
5959 
5960 { TQtPushButton }
5961 
TQtPushButton.CreateWidgetnull5962 function TQtPushButton.CreateWidget(const AParams: TCreateParams): QWidgetH;
5963 var
5964   Parent: QWidgetH;
5965 begin
5966   if AParams.WndParent <> 0 then
5967     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
5968   else
5969     Parent := nil;
5970   Result := QPushButton_create(Parent);
5971 end;
5972 
5973 procedure TQtPushButton.preferredSize(var PreferredWidth,
5974   PreferredHeight: integer; WithThemeSpace: Boolean);
5975 var
5976   Size: TSize;
5977 
AutoSizeButtonFromStylenull5978   function AutoSizeButtonFromStyle(const ASize: TSize): TSize;
5979   var
5980     AOpt: QStyleOptionButtonH;
5981     AText: WideString;
5982     AMetrics: QFontMetricsH;
5983     BtnWidth: Integer;
5984     BtnHeight: Integer;
5985     AIcon: QIconH;
5986     IconSize: TSize;
5987     {style pixel metrics}
5988     BtnMargin, FocusH, FocusV, ShiftH, ShiftV: Integer;
5989   begin
5990     Result := ASize;
5991     AOpt := QStyleOptionButton_create();
5992     QStyleOption_initFrom(AOpt, Widget);
5993     AText := getText;
5994     QStyleOptionButton_setText(AOpt, @AText);
5995     AMetrics := QFontMetrics_create(QWidget_font(Widget));
5996     try
5997       QStyleOption_fontMetrics(AOpt, AMetrics);
5998       BtnWidth := QFontMetrics_width(AMetrics, PWideString(@AText));
5999       BtnHeight := QFontMetrics_height(AMetrics);
6000       Result.cx := BtnWidth;
6001       Result.cy := BtnHeight;
6002 
6003       BtnMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
6004       FocusV := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
6005       FocusH := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
6006       ShiftH := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
6007       ShiftV := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
6008 
6009       if ShiftH = 0 then
6010         ShiftH := FocusH;
6011 
6012       //writeln('ButtonSizeFromStyle:  Metrics W=',BtnWidth,' H=',BtnHeight,
6013       //  ' BtnMargin ',BtnMargin,' FocusV ',FocusV,' FocusH ',FocusH,
6014       //  ' ShiftH ',ShiftH,' ShiftV ',ShiftV);
6015 
6016       Result.cx := Result.cx + BtnMargin + (FocusH * 2) + (ShiftH * 2);
6017       Result.cy := Result.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2);
6018 
6019       // now check if we have icon
6020       AIcon := QIcon_create();
6021       try
6022         QAbstractButton_icon(QPushButtonH(Widget), AIcon);
6023         if not QIcon_isNull(AIcon) then
6024         begin
6025           QAbstractButton_iconSize(QPushButtonH(Widget), @IconSize);
6026           Result.cx := Result.cx + IconSize.cx + (FocusH * 2) + (ShiftH * 2);
6027           if IconSize.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2) > Result.cy then
6028             Result.cy := IconSize.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2);
6029         end;
6030       finally
6031         QIcon_destroy(AIcon);
6032       end;
6033 
6034     finally
6035       QStyleOptionButton_destroy(AOpt);
6036       QFontMetrics_destroy(AMetrics);
6037     end;
6038   end;
6039 begin
6040   // qt doesn't return proper autosize for us.QSizePolicy class is missing.
6041   QPushButton_sizeHint(QPushButtonH(Widget), @Size);
6042   {qtlcl implementation of buttons autosizing, replace if/when we
6043    get QSizePolicy class into bindings}
6044   if Assigned(LCLObject) and LCLObject.AutoSize then
6045     Size := AutoSizeButtonFromStyle(Size);
6046   PreferredWidth := Size.cx;
6047   PreferredHeight := Size.cy;
6048 end;
6049 
6050 procedure TQtPushButton.SetDefault(const ADefault: Boolean);
6051 begin
6052   QPushButton_setDefault(QPushButtonH(Widget), ADefault);
6053 end;
6054 
6055 procedure TQtPushButton.AttachEvents;
6056 begin
6057   inherited AttachEvents;
6058 
6059   FClickedHook := QAbstractButton_hook_create(Widget);
6060   QAbstractButton_hook_hook_clicked2(FClickedHook, @SlotClicked);
6061 
6062   FToggledHook := QAbstractButton_hook_create(Widget);
6063   QAbstractButton_hook_hook_toggled(FToggledHook, @SlotToggled);
6064 end;
6065 
6066 procedure TQtPushButton.DetachEvents;
6067 begin
6068   if FClickedHook <> nil then
6069   begin
6070     QAbstractButton_hook_destroy(FClickedHook);
6071     FClickedHook := nil;
6072   end;
6073   if FToggledHook <> nil then
6074   begin
6075     QAbstractButton_hook_destroy(FToggledHook);
6076     FToggledHook := nil;
6077   end;
6078   inherited DetachEvents;
6079 end;
6080 
6081 {------------------------------------------------------------------------------
6082   Function: TQtPushButton.SlotClicked
6083   Params:  None
6084   Returns: Nothing
6085  ------------------------------------------------------------------------------}
6086 procedure TQtPushButton.SlotClicked; cdecl;
6087 var
6088   Msg: TLMessage;
6089 begin
6090   FillChar(Msg{%H-}, SizeOf(Msg), 0);
6091   Msg.Msg := LM_CLICKED;
6092   DeliverMessage(Msg);
6093 end;
6094 
6095 procedure TQtPushButton.SlotToggled(AChecked: Boolean); cdecl;
6096 begin
6097   // override later (eg. TQtToggleBox)
6098 end;
6099 
6100 { TQtBitBtn }
6101 
CreateWidgetnull6102 function TQtBitBtn.CreateWidget(const AParams: TCreateParams): QWidgetH;
6103 var
6104   Parent: QWidgetH;
6105 begin
6106   HasPaint := True;
6107   FGlyphLayout := 0;
6108   FText := '';
6109   FIcon := nil;
6110   FIconSize.cx := 0;
6111   FIconSize.cy := 0;
6112   if AParams.WndParent <> 0 then
6113     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
6114   else
6115     Parent := nil;
6116   Result := QPushButton_create(Parent);
6117 end;
6118 
6119 destructor TQtBitBtn.Destroy;
6120 begin
6121   if Assigned(FIcon) then
6122     QIcon_destroy(FIcon);
6123   inherited Destroy;
6124 end;
6125 
EventFilternull6126 function TQtBitBtn.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
6127   cdecl;
6128 
6129   function IconValid: boolean;
6130   begin
6131     Result := Assigned(FIcon) and not QIcon_isNull(FIcon) and
6132       (FIconSize.cx > 0) and (FIconSize.cy > 0);
6133   end;
6134 
6135   function PaintBtn: Boolean;
6136   var
6137     APainter: QPainterH;
6138     R: TRect;
6139     R2: TRect;
6140     R3: TRect;
6141     BMargin, HMargin, VMargin, SHorz, SVert: Integer;
6142     IconMode: QIconMode;
6143     IconAlign: QtAlignment;
6144     CenterOffset, W {, H}: Integer;
6145     AFontMetrics: QFontMetricsH;
6146     AText: WideString;
6147     DTFLAGS: DWord;
6148     ContentSize: TSize;
6149     IconDistance: Integer;
6150     IconMargin: Integer;
6151   begin
6152     Result := False;
6153     if (FIcon = nil) then
6154       exit;
6155 
6156     // paint button
6157     QObject_event(Widget, Event);
6158 
6159     IconDistance := TCustomBitBtn(LCLObject).Spacing;
6160     if IconDistance < 0 then
6161       IconDistance := 4; {qt default}
6162 
6163     IconMargin := TCustomBitBtn(LCLObject).Margin;
6164 
6165     // now we paint icon & text
6166     APainter := QPainter_create(QWidget_to_QPaintDevice(Widget));
6167     {$IFDEF USEQT4COMPATIBILEPAINTER}
6168     QPainter_setRenderHint(APainter, QPainterQt4CompatiblePainting);
6169     {$ENDIF}
6170     AText := FText;
6171     try
6172       QPainter_setBackgroundMode(APainter, QtTransparentMode);
6173       QWidget_rect(Widget, @R);
6174 
6175       BMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
6176       VMargin := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
6177       HMargin := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
6178       SHorz := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
6179       SVert := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
6180 
6181       if SHorz = 0 then
6182         SHorz := HMargin;
6183 
6184       if not getEnabled then
6185         IconMode := QIconDisabled
6186       else
6187       if QWidget_underMouse(Widget) then
6188         IconMode := QIconActive
6189       else
6190         IconMode := QIconNormal;
6191 
6192       inc(R.Left, HMargin + SHorz);
6193       inc(R.Top, VMargin + SVert);
6194       dec(R.Right, HMargin + SHorz);
6195       dec(R.Bottom, VMargin + SVert);
6196 
6197       W := R.Right - R.Left;
6198       // H := R.Bottom - R.Top;
6199 
6200       ContentSize.CX := 0;
6201       ContentSize.CY := 0;
6202       R3 := Rect(0, 0, 0, 0);
6203 
6204       DTFlags := DT_CENTER or DT_VCENTER;
6205       if IconValid then
6206       begin
6207         R2 := R;
6208         AFontMetrics := QFontMetrics_create(QPainter_font(APainter));
6209         QPainter_fontMetrics(APainter, AFontMetrics);
6210 
6211         // QtTextShowMnemonic = $0800
6212         if FText = '' then
6213           R3 := Rect(0, 0, 0, 0)
6214         else
6215           QFontMetrics_boundingRect(AFontMetrics, PRect(@R3), 0, 0,
6216             QWidget_width(Widget), QWidget_height(Widget), QtAlignLeft or $0800,
6217             PWideString(@AText));
6218 
6219         QFontMetrics_destroy(AFontMetrics);
6220 
6221         ContentSize.cx := (R3.Right - R3.Left) + FIconSize.cx + IconDistance;
6222         ContentSize.cy := FIconSize.cy + IconDistance + (R3.Bottom - R3.Top);
6223 
6224         if FText = '' then
6225           IconAlign := QtAlignHCenter or QtAlignVCenter
6226         else
6227         case GlyphLayout of
6228           1: // right
6229           begin
6230             DTFLAGS := DT_RIGHT or DT_VCENTER;
6231             dec(R2.Right, BMargin div 2);
6232             IconAlign := QtAlignRight or QtAlignVCenter;
6233             dec(R2.Right, FIconSize.cx);
6234           end;
6235           2: // top
6236           begin
6237             inc(R2.Top, BMargin div 2);
6238             IconAlign := QtAlignTop or QtAlignHCenter;
6239             inc(R2.Top, FIconSize.cy);
6240           end;
6241           3: // bottom
6242           begin
6243             dec(R2.Bottom, BMargin div 2);
6244             IconAlign := QtAlignBottom or QtAlignHCenter;
6245             dec(R2.Bottom, FIconSize.cy);
6246           end;
6247           else
6248           begin // left
6249             DTFLAGS := DT_LEFT or DT_VCENTER;
6250             inc(R2.Left, BMargin div 2);
6251             IconAlign := QtAlignLeft or QtAlignVCenter;
6252             inc(R2.Left, FIconSize.cx);
6253           end;
6254         end;
6255       end;
6256 
6257       if IconValid then
6258       begin
6259         if FGlyphLayout in [0, 1] then
6260         begin
6261           CenterOffset := ((R.Right - R.Left) div 2) - (ContentSize.cx div 2);
6262           if W - ContentSize.cx - CenterOffset < 0 then
6263             CenterOffset := 0;
6264         end else
6265           CenterOffset := ((R.Bottom - R.Top) div 2) - (ContentSize.cy div 2);
6266 
6267         if IconMargin >= 0 then
6268           CenterOffset := IconMargin;
6269 
6270         if FText <> '' then
6271         begin
6272           if FGlyphLayout = 0 then
6273             inc(R.Left, CenterOffset)
6274           else
6275           if FGlyphLayout = 1 then
6276             dec(R.Right, CenterOffset)
6277           else
6278           if FGlyphLayout = 2 then
6279             inc(R.Top, CenterOffset)
6280           else
6281           if FGlyphLayout = 3 then
6282             dec(R.Bottom, CenterOffset);
6283         end;
6284 
6285         QIcon_paint(FIcon, APainter, @R, IconAlign, IconMode);
6286 
6287         R := R2;
6288         if FGlyphLayout = 0 then
6289           inc(R.Left, CenterOffset + IconDistance)
6290         else
6291         if FGlyphLayout = 1 then
6292           dec(R.Right, CenterOffset + IconDistance)
6293         else
6294         if FGlyphLayout = 2 then
6295           inc(R.Top, CenterOffset + IconDistance)
6296         else
6297         if FGlyphLayout = 3 then
6298           dec(R.Bottom, CenterOffset + IconDistance);
6299       end;
6300 
6301       if AText <> '' then
6302         QPainter_drawText(APainter, R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
6303           DTFlagsToQtFlags(DTFLAGS), @AText);
6304 
6305       QPainter_end(APainter);
6306       Result := True;
6307     finally
6308       QPainter_destroy(APainter);
6309     end;
6310   end;
6311 begin
6312   Result := False;
6313   if (LCLObject <> nil) and (QEvent_type(Event) = QEventPaint) and (FContext = 0) then
6314     Result := PaintBtn
6315   else
6316     Result:=inherited EventFilter(Sender, Event);
6317 end;
6318 
6319 procedure TQtBitBtn.preferredSize(var PreferredWidth, PreferredHeight: integer;
6320   WithThemeSpace: Boolean);
6321 const
6322   IconDistance = 4; // hardcoded in qt libs
6323 var
6324   AOpt: QStyleOptionButtonH;
6325   AText: WideString;
6326   AMetrics: QFontMetricsH;
6327   TextSize: TSize;
6328   {style pixel metrics}
6329   BtnMargin, FocusH, FocusV, ShiftH, ShiftV, fsh, fsvm: Integer;
6330 begin
6331   AOpt := QStyleOptionButton_create();
6332   QStyleOption_initFrom(AOpt, Widget);
6333   AText := getText;
6334   QStyleOptionButton_setText(AOpt, @AText);
6335   AMetrics := QFontMetrics_create(QWidget_font(Widget));
6336   try
6337     QStyleOption_fontMetrics(AOpt, AMetrics);
6338 
6339     // QtTextShowMnemonic = $0800
6340     if AText <> '' then
6341       QFontMetrics_size(AMetrics, PSize(@TextSize),
6342         QtAlignLeft or $0800, PWideString(@AText))
6343     else
6344       TextSize := Size(0, 0);
6345     BtnMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
6346     FocusV := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
6347     FocusH := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
6348     ShiftH := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
6349     ShiftV := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
6350     if ShiftH = 0 then
6351       ShiftH := FocusH;
6352     fsh  := (FocusH * 2) + (ShiftH * 2);
6353     fsvm := (FocusV * 2) + (ShiftV * 2) + BtnMargin;
6354     PreferredWidth  := TextSize.cx + fsh + BtnMargin;
6355     PreferredHeight := TextSize.cy + fsvm;
6356 
6357     // now check if we have icon
6358     if Assigned(FIcon) and not QIcon_isNull(FIcon) then
6359     begin
6360       Inc(PreferredWidth, FIconSize.cx + fsh);
6361       if FIconSize.cy + fsvm > PreferredHeight then
6362         PreferredHeight := FIconSize.cy + fsvm;
6363       if FText <> '' then
6364       begin
6365         if FGlyphLayout in [2, 3] then
6366           Inc(PreferredHeight, TextSize.cy + IconDistance)
6367         else
6368           Inc(PreferredWidth, IconDistance);
6369       end;
6370     end;
6371 
6372     if ShiftV = 0 then
6373       Inc(PreferredHeight, 1);
6374   finally
6375     QStyleOptionButton_destroy(AOpt);
6376     QFontMetrics_destroy(AMetrics);
6377   end;
6378 end;
6379 
getIconSizenull6380 function TQtBitBtn.getIconSize: TSize;
6381 begin
6382   Result := FIconSize;
6383 end;
6384 
getTextnull6385 function TQtBitBtn.getText: WideString;
6386 begin
6387   Result := FText;
6388 end;
6389 
6390 procedure TQtBitBtn.setIcon(AIcon: QIconH);
6391 begin
6392   if Assigned(FIcon) then
6393   begin
6394     QIcon_destroy(FIcon);
6395     FIcon := nil;
6396   end;
6397   FIcon := QIcon_create(AIcon);
6398   if getVisible then
6399     Update(nil);
6400 end;
6401 
6402 procedure TQtBitBtn.setIconSize(Size: PSize);
6403 begin
6404   FIconSize.cx := 0;
6405   FIconSize.cy := 0;
6406   if Size <> nil then
6407     FIconSize := Size^;
6408   if getVisible then
6409     Update(nil);
6410 end;
6411 
6412 procedure TQtBitBtn.setText(const W: WideString);
6413 begin
6414   FText := W;
6415   if getVisible then
6416     Update(nil);
6417 end;
6418 
6419 { TQtToggleBox }
6420 
6421 procedure TQtToggleBox.SlotClicked; cdecl;
6422 begin
6423   // do nothing with ToggleBox
6424 end;
6425 
6426 procedure TQtToggleBox.SlotToggled(AChecked: Boolean); cdecl;
6427 var
6428   Msg: TLMessage;
6429 begin
6430   if InUpdate then
6431     exit;
6432 
6433   FillChar(Msg{%H-}, SizeOf(Msg), #0);
6434   Msg.Msg := LM_CHANGED;
6435   DeliverMessage(Msg);
6436 end;
6437 
6438 
6439 { TQtMDIArea }
6440 
6441 procedure TQtMDIArea.SubWindowActivated(AWindow: QMDISubWindowH); cdecl;
6442 var
6443   ActiveChild: TQtMainWindow;
6444   H: HWND;
6445   W: QWidgetH;
6446   WW: TQtWidget;
6447 begin
6448   {we must fix qt bugs here. QWidget_focusWidget() is lost when
6449    activating mdichild via BringToFront (eg from menu)}
6450   if AWindow <> nil then
6451   begin
6452     H := HwndFromWidgetH(AWindow);
6453     if H <> 0 then
6454       ActiveChild := TQtMainWindow(H)
6455     else
6456       ActiveChild := nil;
6457 
6458     if ActiveChild = nil then
6459       exit;
6460 
6461     W := QWidget_focusWidget(AWindow);
6462     if (W <> nil) and (W <> AWindow) then
6463     begin
6464       H := HwndFromWidgetH(W);
6465       if H <> 0 then
6466       begin
6467         WW := TQtWidget(H);
6468         {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
6469         writeln('TQtMDIArea.SubWindowActivated: *=* Current focus widget ',dbgsName(WW.LCLObject));
6470         {$ENDIF}
6471         {trigger QMDIArea to update it's focusWidget (it could be nil) }
6472         QWidget_setFocus(WW.Widget, QtActiveWindowFocusReason);
6473       end;
6474     end else
6475     begin
6476       // fallback when qt completely looses it's mind about focusWidget() inside
6477       // mdi form.
6478       {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
6479       writeln('TQtMDIArea.SubWindowActivated: fallback - ask TCustomForm.ActiveControl ',
6480         dbgsName(TCustomForm(ActiveChild.LCLObject).ActiveControl));
6481       {$ENDIF}
6482       if Assigned(ActiveChild.LCLObject) and
6483         Assigned(TCustomForm(ActiveChild.LCLObject).ActiveControl) and
6484         TCustomForm(ActiveChild.LCLObject).ActiveControl.HandleAllocated then
6485       begin
6486         WW := TQtWidget(TCustomForm(ActiveChild.LCLObject).ActiveControl.Handle);
6487         {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
6488         writeln('**** SUCCESSFULLY ACTIVATED FOCUS PATCH ****');
6489         {$ENDIF}
6490         QWidget_setFocus(WW.Widget, QtActiveWindowFocusReason);
6491       end;
6492     end;
6493   end;
6494 end;
6495 
6496 constructor TQtMDIArea.Create(const AParent: QWidgetH);
6497 begin
6498   Create;
6499   Widget := QMdiArea_create(AParent);
6500   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
6501   FWidgetLCLFont := nil;
6502   Palette.ForceColor := True;
6503   setDefaultColor(dctFont);
6504   Palette.ForceColor := False;
6505   FSubWindowActivationHook := QMdiArea_hook_create(Widget);
6506   QMdiArea_hook_hook_subWindowActivated(FSubWindowActivationHook, @SubWindowActivated);
6507   QWidget_setMouseTracking(Widget, True);
6508   FillChar(FPaintData, sizeOf(FPaintData), 0);
6509   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
6510   setProperty(viewportWidget, 'lclwidget', Int64(PtrUInt(Self)));
6511   QtWidgetSet.AddHandle(Self);
6512 end;
6513 
6514 destructor TQtMDIArea.Destroy;
6515 begin
6516   if FSubWindowActivationHook <> nil then
6517   begin
6518     QMdiArea_hook_destroy(FSubWindowActivationHook);
6519     FSubWindowActivationHook := nil;
6520   end;
6521   inherited Destroy;
6522 end;
6523 
getClientOffsetnull6524 function TQtMDIArea.getClientOffset: TPoint;
6525 begin
6526   if Assigned(FOwner) then
6527     Result := FOwner.getClientOffset
6528   else
6529     Result := inherited getClientOffset;
6530 end;
6531 
6532 procedure TQtMDIArea.AttachEvents;
6533 begin
6534   inherited AttachEvents;
6535   FViewPortEventHook := QObject_hook_create(QAbstractScrollArea_viewport(QAbstractScrollAreaH(Widget)));
6536   QObject_hook_hook_events(FViewPortEventHook, @ScrollViewEventFilter);
6537 end;
6538 
6539 procedure TQtMDIArea.DetachEvents;
6540 begin
6541   if Assigned(FViewPortEventHook) then
6542   begin
6543     QObject_hook_destroy(FViewPortEventHook);
6544     FViewPortEventHook := nil;
6545   end;
6546   inherited DetachEvents;
6547 end;
6548 
EventFilternull6549 function TQtMDIArea.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
6550   cdecl;
6551 begin
6552   Result := False;
6553   QEvent_accept(Event);
6554   case QEvent_type(Event) of
6555     QEventPaint: ;
6556     QEventMouseButtonPress, QEventMouseButtonRelease,
6557     QEventMouseButtonDblClick: ;
6558     QEventMouseMove, QEventWheel: ;
6559     QEventEnter,
6560     QEventLeave: Result := SlotMouseEnter(Sender, Event);
6561     else
6562       Result:=inherited EventFilter(Sender, Event);
6563   end;
6564 end;
6565 
ScrollViewEventFilternull6566 function TQtMDIArea.ScrollViewEventFilter(Sender: QObjectH; Event: QEventH
6567   ): boolean; cdecl;
6568 var
6569   R: TRect;
6570   Brush: QBrushH;
6571   Color: TQColor;
6572   Painter: QPainterH;
6573   APoint, APos, AOldPos, ANewPos, AGlobalPos: TQtPoint;
6574   APosF, AGlobalPosF: TQtPointF;
6575   AEvent: QEventH;
6576   APaintEvent: QPaintEventH;
6577 begin
6578   Result := False;
6579   QEvent_accept(Event);
6580   case QEvent_type(Event) of
6581     QEventMouseButtonPress, QEventMouseButtonRelease,
6582     QEventMouseButtonDblClick:
6583     begin
6584       // new event with parent coordinates
6585       QMouseEvent_pos(QMouseEventH(Event), @APos);
6586       QWidget_mapToParent(Widget, @APoint, @APos);
6587       APosF.x := APoint.X;
6588       APosF.y := APoint.y;
6589       QMouseEvent_globalPos(QMouseEventH(Event), @AGlobalPos);
6590       AGlobalPosF.X := AGlobalPos.X;
6591       AGlobalPosF.Y := AGlobalPos.Y;
6592       AEvent := QMouseEvent_create(QEvent_type(Event), @APosF, @AGlobalPosF,
6593         QMouseEvent_button(QMouseEventH(Event)), QMouseEvent_buttons(QMouseEventH(Event)), QInputEvent_modifiers(QInputEventH(Event)));
6594       try
6595         Result := SlotMouse(Sender, AEvent);
6596       finally
6597         QEvent_destroy(AEvent);
6598       end;
6599     end;
6600     QEventMouseMove:
6601     begin
6602       QMouseEvent_globalPos(QMouseEventH(Event), @AGlobalPos);
6603       QMouseEvent_pos(QMouseEventH(Event), @APos);
6604       QWidget_mapToParent(Widget, @APoint, @APos);
6605       APosF.x := APoint.X;
6606       APosF.y := APoint.y;
6607       AGlobalPosF.X := AGlobalPos.X;
6608       AGlobalPosF.Y := AGlobalPos.Y;
6609       AEvent := QMouseEvent_create(QEvent_type(Event), @APosF, @AGlobalPosF,
6610         QMouseEvent_button(QMouseEventH(Event)), QMouseEvent_buttons(QMouseEventH(Event)), QInputEvent_modifiers(QInputEventH(Event)));
6611       try
6612         Result := SlotMouseMove(Sender, AEvent);
6613       finally
6614         QEvent_destroy(AEvent);
6615       end;
6616     end;
6617 
6618     QEventWheel:
6619     begin
6620       // APos :=
6621       QWheelEvent_pos(QWheelEventH(Event), @APos);
6622       QWidget_mapToParent(Widget, @APoint, @APos);
6623       APosF.X := APoint.X;
6624       APosF.Y := APoint.Y;
6625       AEvent := QWheelEvent_create(@APosF, QWheelEvent_delta(QWheelEventH(Event)), QWheelEvent_buttons(QWheelEventH(Event)),
6626         QInputEvent_modifiers(QInputEventH(Event)), QWheelEvent_orientation(QWheelEventH(Event)));
6627       try
6628         Result := SlotMouseWheel(Sender, AEvent);
6629       finally
6630         QEvent_destroy(AEvent);
6631       end;
6632     end;
6633 
6634     QEventEnter,
6635     QEventLeave: Result := SlotMouseEnter(Sender, Event);
6636     QEventHoverEnter,
6637     QEventHoverLeave,
6638     QEventHoverMove:
6639     begin
6640       // APos :=
6641       QHoverEvent_pos(QHoverEventH(Event), @APos);
6642       QHoverEvent_oldPos(QHoverEventH(Event), @AOldPos);
6643       QWidget_mapToParent(Widget, @APoint, @APos);
6644       QWidget_mapToParent(Widget, @ANewPos, @AOldPos);
6645       APosF.X := APoint.X;
6646       APosF.Y := APoint.Y;
6647       AGlobalPosF.X := ANewPos.X;
6648       AGlobalPosF.Y := ANewPos.Y;
6649       QHoverEvent_create(QEvent_type(Event), @APosF, @AGlobalPosF);
6650       try
6651         Result := SlotHover(Sender, AEvent);
6652       finally
6653         QEvent_destroy(AEvent);
6654       end;
6655     end;
6656     QEventPaint:
6657     begin
6658       QPaintEvent_rect(QPaintEventH(Event), @R);
6659       if CanSendLCLMessage and (LCLObject is TWinControl) then
6660       begin
6661         Brush := QBrush_create;
6662         QMdiArea_background(QMDIAreaH(Widget), Brush);
6663         Color := QBrush_color(Brush)^;
6664         QBrush_destroy(Brush);
6665         Painter := QPainter_create(QWidget_to_QPaintDevice(QWidgetH(Sender)));
6666         {$IFDEF USEQT4COMPATIBILEPAINTER}
6667         QPainter_setRenderHint(Painter, QPainterQt4CompatiblePainting);
6668         {$ENDIF}
6669         Brush := QBrush_create(@Color, QtSolidPattern);
6670         try
6671           QPaintEvent_rect(QPaintEventH(Event), @R);
6672           QPainter_fillRect(Painter, @R, Brush);
6673           QPainter_end(Painter);
6674         finally
6675           QBrush_destroy(Brush);
6676           QPainter_destroy(Painter);
6677         end;
6678         APos.X := 0;
6679         APos.Y := 0;
6680         QWidget_mapToParent(Widget, @APoint, @APos);
6681         FScrollX := -APoint.x;
6682         FScrollY := -APoint.Y;
6683         APaintEvent := QPaintEvent_create(PRect(@R));
6684         try
6685           SlotPaint(Sender, Event);
6686         finally
6687           FScrollX := 0;
6688           FScrollY := 0;
6689           QPaintEvent_destroy(APaintEvent);
6690         end;
6691         Result := True; // do not paint MDIArea again
6692       end;
6693     end;
6694   end;
6695 end;
6696 
ActiveSubWindownull6697 function TQtMDIArea.ActiveSubWindow: QMdiSubWindowH;
6698 begin
6699   Result := QMdiArea_activeSubWindow(QMdiAreaH(Widget));
6700 end;
6701 
6702 procedure TQtMDIArea.ActivateSubWindow(AMdiWindow: QMdiSubWindowH);
6703 begin
6704   if AMdiWindow <> nil then
6705     QMdiArea_setActiveSubWindow(QMdiAreaH(Widget), AMdiWindow);
6706 end;
6707 
6708 {$IFDEF QTSCROLLABLEFORMS}
6709 
6710 { TQtWindowArea }
6711 
6712 procedure TQtWindowArea.AttachEvents;
6713 begin
6714   inherited AttachEvents;
6715   FViewPortEventHook := QObject_hook_create(viewportWidget);
6716   QObject_hook_hook_events(FViewPortEventHook, @ScrollViewEventFilter);
6717 end;
6718 
CanAdjustClientRectOnResizenull6719 function TQtWindowArea.CanAdjustClientRectOnResize: Boolean;
6720 begin
6721   Result := True;
6722 end;
6723 
6724 procedure TQtWindowArea.DetachEvents;
6725 begin
6726   if Assigned(FViewPortEventHook) then
6727   begin
6728     QObject_hook_destroy(FViewPortEventHook);
6729     FViewPortEventHook := nil;
6730   end;
6731   inherited DetachEvents;
6732 end;
6733 
MapToGlobalnull6734 function TQtWindowArea.MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean
6735   ): TPoint;
6736 var
6737   Pt: TPoint;
6738   ARet, AParam: TQtPoint;
6739   R: TRect;
6740 begin
6741   Result := inherited MapToGlobal(APt);
6742 
6743   if ((Result.X < 0) or (Result.Y < 0)) and Assigned(FOwner) and (FOwner is TQtMainWindow) and
6744     not TQtMainWindow(FOwner).IsMDIChild and
6745     not (csDesigning in TQtMainWindow(FOwner).LCLObject.ComponentState)  then
6746   begin
6747     QWidget_geometry(Widget, @R);
6748     if (R.Left >=0) and (R.Top >=0) then {this is valid geometry}
6749       exit;
6750     {all we know is when mapToGlobal returns wrong result is that geometry is wrong}
6751     if Assigned(FOwner) and (FOwner is TQtMainWindow) and not TQtMainWindow(FOwner).IsMdiChild then
6752     begin
6753       ARet.X := 0;
6754       ARet.Y := 0;
6755       AParam.X := APt.X;
6756       AParam.Y := APt.Y;
6757       if Assigned(TQtMainWindow(FOwner).MenuBar) and TQtMainWindow(FOwner).MenuBar.getVisible then
6758       begin
6759         QWidget_mapToGlobal(TQtMainWindow(FOwner).MenuBar.Widget, @ARet, @AParam);
6760         inc(ARet.Y, QWidget_height(TQtMainWindow(FOwner).MenuBar.Widget));
6761         Result.X := ARet.X;
6762         Result.Y := ARet.Y;
6763       end else
6764       begin
6765         QWidget_mapToGlobal(TQtMainWindow(FOwner).Widget, @ARet, @AParam);
6766         Result.X := ARet.X;
6767         Result.Y := ARet.Y;
6768       end;
6769     end;
6770   end;
6771 
6772   if AWithScrollOffset then
6773   begin
6774     Pt := ScrolledOffset;
6775     dec(Result.X, Pt.X);
6776     dec(Result.Y, Pt.Y);
6777   end;
6778 end;
6779 
6780 procedure TQtWindowArea.scroll(dx, dy: integer; ARect: PRect);
6781 begin
6782   inherited scroll(dx, dy, ARect);
6783   FScrollX := FScrollX + dx;
6784   FScrollY := FScrollY + dy;
6785 end;
6786 
EventFilternull6787 function TQtWindowArea.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
6788   cdecl;
6789 begin
6790   Result := False;
6791   if (LCLObject = nil) then
6792     exit;
6793   if (QEvent_Type(Event) in [QEventMouseButtonPress, QEventMouseButtonRelease,
6794     QEventMouseButtonDblClick, QEventMouseMove, QEventWheel, QEventPaint,
6795     QEventHoverEnter, QEventHoverMove, QEventHoverLeave, QEventResize]) then
6796     exit;
6797 
6798   {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
6799   if (QEvent_type(Event)=QEventWindowActivate) or
6800     (QEvent_type(Event)=QEventWindowDeactivate) or
6801     (QEvent_type(Event)=QEventShow) or
6802     (QEvent_type(Event)=QEventShowToParent) or
6803     (QEvent_type(Event)=QEventShowWindowRequest) or
6804     (QEvent_type(Event)=QEventResize) or
6805     (QEvent_type(Event)=QEventContentsRectChange) or
6806     (QEvent_type(Event)=QEventUpdateLater) or
6807     (QEvent_type(Event)=QEventUpdateRequest) or
6808     (QEvent_type(Event)=QEventPaint) or
6809     (QEvent_type(Event)=QEventWinIdChange) or
6810     (QEvent_type(Event)=QEventExpose) or
6811     (QEvent_type(Event)=QEventWindowTitleChange) or
6812     (QEvent_type(Event)=QEventActivationChange) or
6813     (QEvent_type(Event)=QEventWindowStateChange) then
6814       WriteLn(' TQtWindowArea.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
6815       ' LCLObject=', dbgsName(LCLObject),
6816       ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
6817   {$endif}
6818 
6819   Result := inherited EventFilter(Sender, Event);
6820 end;
6821 
ScrollViewEventFilternull6822 function TQtWindowArea.ScrollViewEventFilter(Sender: QObjectH; Event: QEventH
6823   ): Boolean; cdecl;
6824 var
6825   ASize: TSize;
6826   AResizeEvent: QResizeEventH;
6827 begin
6828   Result := False;
6829   if LCLObject = nil then
6830     exit;
6831 
6832   {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
6833   if (QEvent_type(Event)=QEventWindowActivate) or
6834     (QEvent_type(Event)=QEventWindowDeactivate) or
6835     (QEvent_type(Event)=QEventShow) or
6836     (QEvent_type(Event)=QEventShowToParent) or
6837     (QEvent_type(Event)=QEventShowWindowRequest) or
6838     (QEvent_type(Event)=QEventResize) or
6839     (QEvent_type(Event)=QEventContentsRectChange) or
6840     (QEvent_type(Event)=QEventUpdateLater) or
6841     (QEvent_type(Event)=QEventUpdateRequest) or
6842     (QEvent_type(Event)=QEventPaint) or
6843     (QEvent_type(Event)=QEventWinIdChange) or
6844     (QEvent_type(Event)=QEventExpose) or
6845     (QEvent_type(Event)=QEventWindowTitleChange) or
6846     (QEvent_type(Event)=QEventActivationChange) or
6847     (QEvent_type(Event)=QEventWindowStateChange) then
6848       WriteLn('  TQtWindowAreaViewport.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
6849       ' LCLObject=', dbgsName(LCLObject),
6850       ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
6851   {$endif}
6852 
6853   BeginEventProcessing;
6854   try
6855     if (QEvent_Type(Event) in [QEventContextMenu, QEventHoverEnter, QEventPaint,
6856                                QEventHoverMove, QEventHoverLeave, QEventHide,
6857                                {must be added, see issue #29159}
6858                                QEventMouseMove]) then
6859     begin
6860       if (FOwner is TQtMainWindow) and not TQtMainWindow(FOwner).IsFrameWindow and
6861         (TCustomForm(LCLObject).FormStyle = fsMDIForm) and
6862         (TQtMainWindow(FOwner).MDIAreaHandle <> nil) then
6863         // paint via MDIAreaHandle viewport hook
6864       else
6865         Result := inherited EventFilter(Sender, Event);
6866     end else
6867     case QEvent_type(Event) of
6868       QEventResize:
6869       begin
6870         if FOwner <> nil then
6871         begin
6872           {TQtMainWindow does not send resize event if ScrollArea is assigned,
6873            it is done here when viewport geometry is finally updated by Qt.}
6874           ASize := FOwner.getSize;
6875           AResizeEvent := QResizeEvent_create(@ASize, @ASize);
6876           try
6877             // issue #28596 and others of TCustomControl clientrect related
6878             if CanAdjustClientRectOnResize and
6879               LCLObject.ClientRectNeedsInterfaceUpdate then
6880             begin
6881               {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
6882               DebugLn('TQtWindowArea.ScrollViewEventFilter invalidatingClientRectCache ',dbgsName(Self),' LCL=',dbgsName(LCLObject));
6883               {$ENDIF}
6884               LCLObject.InvalidateClientRectCache(False);
6885             end;
6886             SlotResize(AResizeEvent);
6887           finally
6888             QEvent_destroy(AResizeEvent);
6889           end;
6890         end else
6891           LCLObject.DoAdjustClientRectChange;
6892       end;
6893       QEventWheel:
6894         if not getEnabled then
6895           inherited EventFilter(Sender, Event);
6896       QEventLayoutRequest:
6897       begin
6898         if FOwner <> nil then
6899         begin
6900           if LCLObject.ClientRectNeedsInterfaceUpdate then
6901           begin
6902             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
6903             DebugLn('TQtWindowArea.Viewport: ',dbgsName(LCLObject),' QEventLayoutRequest calling DoAdjustClientRectChange CASP=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' ***** !!!! ');
6904             {$ENDIF}
6905             Self.LCLObject.DoAdjustClientRectChange(True);
6906           end;
6907         end;
6908       end;
6909     end;
6910   finally
6911     EndEventProcessing;
6912   end;
6913 end;
6914 
getWindowStatenull6915 function TQtWindowArea.getWindowState: QtWindowStates;
6916 begin
6917   Result := inherited getWindowState;
6918   if Assigned(LCLObject) then
6919     Result := TQtMainWindow(LCLObject.Handle).getWindowState;
6920 end;
6921 
6922 {$ENDIF}
6923 
6924 
6925 { TQtMainWindow }
6926 
CreateWidgetnull6927 function TQtMainWindow.CreateWidget(const AParams: TCreateParams): QWidgetH;
6928   {$IFDEF QTSCROLLABLEFORMS}
6929   procedure SetScrollAreaRules;
6930   begin
6931     FCentralWidget := ScrollArea.Widget;
6932     ScrollArea.ChildOfComplexWidget := ccwAbstractScrollArea;
6933     ScrollArea.LCLObject := LCLObject;
6934 
6935     QFrame_setFrameShape(QAbstractScrollAreaH(ScrollArea.Widget), QFrameNoFrame);
6936     QWidget_setBackgroundRole(ScrollArea.viewportWidget, QPaletteNoRole);
6937     QWidget_setAutoFillBackground(ScrollArea.viewportWidget, False);
6938     setProperty(ScrollArea.viewportWidget, 'lclwidget', Int64(PtrUInt(Self)));
6939 
6940     // we must set minimum heigth / width to 1 otherwise we'll have strange
6941     // effect eg. with main ide bar window (small size and cannot resize).
6942     //QWidget_setMinimumHeight(FCentralWidget, 1);
6943     //QWidget_setMinimumWidth(FCentralWidget, 1);
6944     QWidget_setSizePolicy(FCentralWidget, QSizePolicyIgnored, QSizePolicyIgnored);
6945 
6946     ScrollArea.setScrollBarPolicy(True, QtScrollBarAlwaysOff);
6947     ScrollArea.setScrollBarPolicy(False, QtScrollBarAlwaysOff);
6948     ScrollArea.HasPaint := True;
6949     ScrollArea.FOwner := Self;
6950   end;
6951   {$ENDIF}
6952 var
6953   p: QPaletteH;
6954 begin
6955   // Creates the widget
6956   {$ifdef VerboseQt}
6957     WriteLn('TQtMainWindow.CreateWidget Name: ', LCLObject.Name);
6958   {$endif}
6959 
6960   FFirstPaintEvent := False;
6961   FBlocked := False;
6962   FShowOnTaskBar := False;
6963   QtFormBorderStyle := Ord(bsSizeable);
6964   QtFormStyle := Ord(fsNormal);
6965   FHasPaint := True;
6966   FPopupParent := nil;
6967   MDIAreaHandle := nil;
6968   MDIChildArea := nil;
6969   FMDIStateHook := nil;
6970   {$IFDEF QTSCROLLABLEFORMS}
6971   ScrollArea := nil;
6972   {$ENDIF}
6973 
6974   IsMainForm := (LCLObject <> nil) and (LCLObject = Application.MainForm);
6975 
6976   IsFrameWindow := not IsMainForm and (LCLObject is TCustomFrame);
6977   if IsFrameWindow then
6978     QtFormBorderStyle := Ord(bsNone);
6979 
6980   if IsMainForm then
6981   begin
6982 
6983     Result := QMainWindow_create(nil, QtWindow);
6984 
6985     MenuBar := TQtMenuBar.Create(Result);
6986 
6987     if not (csDesigning in LCLObject.ComponentState) then
6988       MenuBar.FIsApplicationMainMenu := True
6989     else
6990       {$IFNDEF DARWIN}
6991       MenuBar.setProperty(MenuBar.Widget,'lcldesignmenubar',1)
6992       {$ENDIF}
6993       ;
6994 
6995     if (Application.MainForm <> nil) and
6996        (Application.MainForm.FormStyle = fsMDIForm) and
6997        not (csDesigning in LCLObject.ComponentState) then
6998     begin
6999       FCentralWidget := QWidget_create(Result);
7000       MDIAreaHandle := TQtMDIArea.Create(Result);
7001       MDIAreaHandle.FOwner := Self;
7002       MDIAreaHandle.LCLObject := LCLObject;
7003       MDIAreaHandle.AttachEvents;
7004       p := QWidget_palette(FCentralWidget);
7005       if p <> nil then
7006         QMdiArea_setBackground(QMdiAreaH(MdiAreaHandle.Widget), QPalette_background(P));
7007       QWidget_setParent(MdiAreaHandle.Widget, FCentralWidget);
7008       QMdiArea_setActivationOrder(QMdiAreaH(MdiAreaHandle.Widget), QMdiAreaActivationHistoryOrder);
7009       QMdiArea_setOption(QMdiAreaH(MdiAreaHandle.Widget),
7010         QMdiAreaDontMaximizeSubWindowOnActivation, True);
7011     end
7012     else
7013     begin
7014       {$IFDEF QTSCROLLABLEFORMS}
7015       ScrollArea := TQtWindowArea.CreateFrom(LCLObject, QAbstractScrollArea_create(Result));
7016       SetScrollAreaRules;
7017       {$ELSE}
7018       FCentralWidget := QWidget_create(Result);
7019       {$ENDIF}
7020       MDIAreaHandle := nil;
7021     end;
7022 
7023     if FCentralWidget <> nil then
7024     begin
7025       QMainWindow_setCentralWidget(QMainWindowH(Result), FCentralWidget);
7026       QWidget_setMouseTracking(FCentralWidget, True);
7027     end;
7028 
7029     if not (csDesigning in LCLObject.ComponentState) then
7030       QMainWindow_setDockOptions(QMainWindowH(Result), QMainWindowAnimatedDocks);
7031   end else
7032   begin
7033     if IsMdiChild then
7034     begin
7035 
7036       if TQtMainWindow(Application.MainForm.Handle).MDIAreaHandle = nil then
7037         raise Exception.Create('MDIChild can be added to MDIForm only !');
7038 
7039       FFirstPaintEvent := True;
7040 
7041       Result := QMdiSubWindow_create(nil, QtWindow);
7042 
7043       // QMdiSubWindow already have an layout
7044 
7045       LayoutWidget := QBoxLayoutH(QWidget_layout(Result));
7046       if LayoutWidget <> nil then
7047         QBoxLayout_destroy(LayoutWidget);
7048     end else
7049     begin
7050       if not IsFrameWindow and (TCustomForm(LCLObject).FormStyle = fsSplash) and
7051         not (csDesigning in LCLObject.ComponentState) then
7052       begin
7053         FFirstPaintEvent := True;
7054         Result := QWidget_create(nil, QtSplashScreen);
7055       end else
7056         Result := QWidget_create(nil, QtWindow);
7057 
7058       QWidget_setAttribute(Result, QtWA_Hover);
7059       QWidget_setMouseTracking(Result, True);
7060     end;
7061 
7062     // Main menu bar
7063     {$IFDEF DARWIN}
7064     MenuBar := TQtMenuBar.Create(nil);
7065     {$ELSE}
7066     MenuBar := TQtMenuBar.Create(Result);
7067     if (csDesigning in LCLObject.ComponentState) then
7068       MenuBar.setProperty(MenuBar.Widget,'lcldesignmenubar',1);
7069     {$ENDIF}
7070 
7071     {$IFDEF QTSCROLLABLEFORMS}
7072     if QWidget_windowType(Result) = QtSplashScreen then
7073       FCentralWidget := QWidget_create(Result)
7074     else
7075     begin
7076       ScrollArea := TQtWindowArea.CreateFrom(LCLObject, QAbstractScrollArea_create(Result));
7077       SetScrollAreaRules;
7078     end;
7079     {$ELSE}
7080     FCentralWidget := QWidget_create(Result);
7081     {$ENDIF}
7082     QWidget_setMouseTracking(FCentralWidget, True);
7083 
7084     LayoutWidget := QBoxLayout_create(QBoxLayoutTopToBottom, Result);
7085 
7086     QBoxLayout_setSpacing(LayoutWidget, 0);
7087     QLayout_setContentsMargins(LayoutWidget, 0, 0, 0, 0);
7088 
7089     // we must fix mouse events in QMDISubWindow by
7090     // adding FCentralWidget as it''s widget
7091     if IsMdiChild then
7092       QMdiSubWindow_setWidget(QMdiSubWindowH(Result), FCentralWidget);
7093 
7094     QLayout_addWidget(LayoutWidget, FCentralWidget);
7095     QWidget_setLayout(Result, QLayoutH(LayoutWidget));
7096     QWidget_setAttribute(Result, QtWA_DeleteOnClose);
7097   end;
7098 end;
7099 
7100 procedure TQtMainWindow.ChangeParent(NewParent: QWidgetH);
7101 var
7102   Flags: QtWindowFlags;
7103   Visible: Boolean;
7104 begin
7105   if NewParent <> Widget then
7106   begin
7107     Visible := getVisible;
7108     Flags := windowFlags;
7109     setParent(NewParent);
7110     setWindowFlags(Flags);
7111     setVisible(Visible);
7112   end;
7113 end;
7114 
7115 procedure TQtMainWindow.UpdateParent;
7116 begin
7117   ChangeParent(FPopupParent);
7118 end;
7119 
7120 {------------------------------------------------------------------------------
7121   Function: TQtMainWindow.Destroy
7122   Params:  None
7123   Returns: Nothing
7124  ------------------------------------------------------------------------------}
7125 destructor TQtMainWindow.Destroy;
7126 begin
7127   // The main window takes care of the menubar handle
7128   {handle validator is added since we added events to
7129    menubar in r33309 (because of font changes).
7130    Events are attached in TQtWSCustomForm.CreateHandle
7131    Sometimes in various combinations we can
7132    crash here because MenuBar <> nil but not valid handle.
7133    Now it's totally safe.}
7134   if QtWidgetSet.IsValidHandle(HWND(MenuBar)) then
7135   begin
7136     MenuBar.DetachEvents;
7137     if FOwnWidget and (MenuBar.Widget <> nil) then
7138       QObject_deleteLater(MenuBar.Widget);
7139     MenuBar.Widget := nil;
7140     FreeThenNil(MenuBar);
7141   end;
7142 
7143   if MDIAreaHandle <> nil then
7144   begin
7145     MDIAreaHandle.DetachEvents;
7146     MDIAreaHandle.Widget := nil;
7147     FreeThenNil(MDIAreaHandle);
7148   end;
7149   {$IFDEF QTSCROLLABLEFORMS}
7150   if QtWidgetSet.IsValidHandle(HWND(ScrollArea)) then
7151   begin
7152     ScrollArea.DetachEvents;
7153     ScrollArea.Widget := nil;
7154     FreeAndNil(ScrollArea);
7155   end;
7156   {$ENDIF}
7157 
7158   inherited Destroy;
7159 end;
7160 
7161 procedure TQtMainWindow.BeginUpdate;
7162 begin
7163   inherited BeginUpdate;
7164   {$IFDEF QTSCROLLABLEFORMS}
7165   if Assigned(ScrollArea) then
7166     ScrollArea.BeginUpdate;
7167   {$ENDIF}
7168 end;
7169 
7170 procedure TQtMainWindow.EndUpdate;
7171 begin
7172   {$IFDEF QTSCROLLABLEFORMS}
7173   if Assigned(ScrollArea) then
7174     ScrollArea.EndUpdate;
7175   {$ENDIF}
7176   inherited EndUpdate;
7177 end;
7178 
7179 procedure TQtMainWindow.Activate;
7180 begin
7181   if IsMDIChild then
7182     QMdiArea_setActiveSubWindow(QMdiSubWindow_mdiArea(QMdiSubWindowH(Widget)),
7183       QMdiSubWindowH(Widget))
7184   else
7185     inherited Activate;
7186   {$IFDEF DARWIN}
7187   QWidget_raise(Widget);
7188   {$ENDIF}
7189   {$IFDEF HASX11}
7190   if IsWayland then
7191     QWidget_raise(Widget)
7192   else
7193   if (QtWidgetSet.WindowManagerName = 'xfwm4') and not IsMDIChild and
7194     QWidget_isModal(Widget) then
7195   begin
7196     if X11GetActivewindow <> Widget then
7197       X11Raise(QWidget_winID(Widget));
7198   end else
7199   if not QWidget_isModal(Widget) then
7200   begin
7201     if (QtWidgetSet.WindowManagerName = 'metacity') and not IsMDIChild then
7202         X11Raise(QWidget_winID(Widget))
7203     else
7204       QWidget_raise(Widget);
7205   end;
7206   {$ENDIF}
7207 end;
7208 
CanAdjustClientRectOnResizenull7209 function TQtMainWindow.CanAdjustClientRectOnResize: Boolean;
7210 begin
7211   {$IFDEF QTSCROLLABLEFORMS}
7212   Result := not Assigned(ScrollArea);
7213   {$ELSE}
7214   Result:=inherited CanAdjustClientRectOnResize;
7215   {$ENDIF}
7216 end;
7217 
TQtMainWindow.getAcceptDropFilesnull7218 function TQtMainWindow.getAcceptDropFiles: Boolean;
7219 begin
7220   Result := QWidget_acceptDrops(Widget);
7221 end;
7222 
GetContainerWidgetnull7223 function TQtMainWindow.GetContainerWidget: QWidgetH;
7224 begin
7225   {$IFDEF QTSCROLLABLEFORMS}
7226   if IsFrameWindow then
7227     Result := ScrollArea.GetContainerWidget
7228   else
7229   if not Assigned(ScrollArea) or (QWidget_windowType(Widget) = QtToolTip) or
7230     (QWidget_windowType(Widget) = QtSplashScreen) or
7231     (TCustomForm(LCLObject).FormStyle = fsMdiForm) then
7232     Result := inherited GetContainerWidget
7233   else
7234     Result := ScrollArea.GetContainerWidget;
7235   {$ELSE}
7236   Result := inherited GetContainerWidget;
7237   {$ENDIF}
7238 end;
7239 
7240 procedure TQtMainWindow.grabMouse;
7241 begin
7242   {$IFDEF QTSCROLLABLEFORMS}
7243   if not Assigned(ScrollArea) then
7244     inherited grabMouse
7245   else
7246     ScrollArea.grabMouse;
7247   {$ELSE}
7248   inherited grabMouse;
7249   {$ENDIF}
7250 end;
7251 
getClientBoundsnull7252 function TQtMainWindow.getClientBounds: TRect;
7253 begin
7254   {$IFDEF QTSCROLLABLEFORMS}
7255   if Assigned(ScrollArea) then
7256   begin
7257     if not ScrollArea.testAttribute(QtWA_PendingResizeEvent) then
7258       Result := ScrollArea.getClientBounds
7259     else
7260       Result := inherited GetClientBounds;
7261   end else
7262   {$ENDIF}
7263   Result:=inherited getClientBounds;
7264 end;
7265 
getClientOffsetnull7266 function TQtMainWindow.getClientOffset: TPoint;
7267 begin
7268   {$IFDEF QTSCROLLABLEFORMS}
7269   if Assigned(ScrollArea) then
7270     Result := ScrollArea.getClientOffset
7271   else
7272     Result := inherited getClientOffset;
7273   if Assigned(ScrollArea) and Assigned(MenuBar) and
7274     (MenuBar.getVisible) then
7275       inc(Result.Y, MenuBar.getHeight);
7276   {$ELSE}
7277   Result:=inherited getClientOffset;
7278   {$ENDIF}
7279 end;
7280 
getTextnull7281 function TQtMainWindow.getText: WideString;
7282 begin
7283   WindowTitle(@Result);
7284 end;
7285 
TQtMainWindow.getTextStaticnull7286 function TQtMainWindow.getTextStatic: Boolean;
7287 begin
7288   Result := False;
7289 end;
7290 
TQtMainWindow.MapToGlobalnull7291 function TQtMainWindow.MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean
7292   ): TPoint;
7293 begin
7294   {$IFDEF QTSCROLLABLEFORMS}
7295   if Assigned(ScrollArea) then
7296     Result := ScrollArea.MapToGlobal(APt, AWithScrollOffset)
7297   else
7298     Result := inherited MapToGlobal(APt, AWithScrollOffset);
7299   {$ELSE}
7300   Result := inherited MapToGlobal(APt, AWithScrollOffset);
7301   {$ENDIF}
7302 end;
7303 
7304 procedure TQtMainWindow.Update(ARect: PRect);
7305 var
7306   R,R1: TRect;
7307 begin
7308   if Assigned(MDIAreaHandle) and not IsMDIChild then
7309   begin
7310     if ARect = nil then
7311       QWidget_update(MDIAreaHandle.viewportWidget)
7312     else
7313     begin
7314       R1 := ARect^;
7315       QWidget_geometry(MDIAreaHandle.Widget, @R);
7316       OffsetRect(R1, -R.Left, -R.Top);
7317       QWidget_update(MDIAreaHandle.viewportWidget, @R1);
7318     end;
7319   end else
7320     inherited Update(ARect);
7321 end;
7322 
7323 procedure TQtMainWindow.UpdateRegion(ARgn: QRegionH);
7324 var
7325   R1, R: TRect;
7326   ANewRgn: QRegionH;
7327 begin
7328   if Assigned(MDIAreaHandle) and not IsMDIChild then
7329   begin
7330     if ARgn = nil then
7331       QWidget_update(MDIAreaHandle.viewportWidget)
7332     else
7333     begin
7334       QRegion_boundingRect(ARgn, @R1);
7335       QWidget_geometry(MDIAreaHandle.Widget, @R);
7336       OffsetRect(R1, -R.Left, -R.Top);
7337       ANewRgn := QRegion_create(PRect(@R1));
7338       QWidget_update(MDIAreaHandle.viewportWidget, ANewRgn);
7339       QRegion_destroy(ANewRgn);
7340     end;
7341   end else
7342     inherited UpdateRegion(ARgn);
7343 end;
7344 
7345 procedure TQtMainWindow.Repaint(ARect: PRect);
7346 var
7347   R, R1: TRect;
7348 begin
7349   if Assigned(MDIAreaHandle) and not IsMDIChild then
7350   begin
7351     if ARect = nil then
7352       QWidget_repaint(MDIAreaHandle.viewportWidget)
7353     else
7354     begin
7355       R1 := ARect^;
7356       QWidget_geometry(MDIAreaHandle.Widget, @R);
7357       OffsetRect(R1, -R.Left, -R.Top);
7358       QWidget_repaint(MDIAreaHandle.viewportWidget, @R1);
7359     end;
7360   end else
7361     inherited Repaint(ARect);
7362 end;
7363 
7364 procedure TQtMainWindow.Resize(ANewWidth, ANewHeight: Integer);
7365 begin
7366   if not IsMDIChild and not IsFrameWindow and
7367     (TCustomForm(LCLObject).BorderStyle in [bsDialog, bsNone, bsSingle]) and
7368      not (csDesigning in LCLObject.ComponentState) then
7369     QWidget_setFixedSize(Widget, ANewWidth, ANewHeight)
7370   else
7371     inherited Resize(ANewWidth, ANewHeight);
7372 end;
7373 
7374 procedure TQtMainWindow.setText(const W: WideString);
7375 begin
7376   setWindowTitle(@W);
7377 end;
7378 
7379 procedure TQtMainWindow.setMenuBar(AMenuBar: QMenuBarH);
7380 begin
7381   if IsMainForm then
7382     QMainWindow_setMenuBar(QMainWindowH(Widget), AMenuBar)
7383   else
7384     QLayout_setMenuBar(LayoutWidget, AMenuBar);
7385 end;
7386 
7387 {------------------------------------------------------------------------------
7388   Function: TQtMainWindow.EventFilter
7389   Params:  None
7390   Returns: Nothing
7391  ------------------------------------------------------------------------------}
TQtMainWindow.EventFilternull7392 function TQtMainWindow.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
7393   cdecl;
7394 var
7395   AStateEvent: QWindowStateChangeEventH;
7396   AState: QtWindowStates;
7397   AOldState: QtWindowStates;
7398   CanSendEvent: Boolean;
7399   {$IFDEF MSWINDOWS}
7400   i: Integer;
7401   AForm: TCustomForm;
7402   w: QWidgetH;
7403   {$ENDIF}
7404   {$IFDEF HASX11}
7405   IsMinimizeEvent: Boolean;
7406   {$ENDIF}
7407 begin
7408   Result := False;
7409   QEvent_accept(Event);
7410   if LCLObject = nil then
7411     exit;
7412 
7413   {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
7414   if (QEvent_type(Event)=QEventWindowActivate) or
7415     (QEvent_type(Event)=QEventWindowDeactivate) or
7416     (QEvent_type(Event)=QEventShow) or
7417     (QEvent_type(Event)=QEventShowToParent) or
7418     (QEvent_type(Event)=QEventShowWindowRequest) or
7419     (QEvent_type(Event)=QEventResize) or
7420     (QEvent_type(Event)=QEventContentsRectChange) or
7421     (QEvent_type(Event)=QEventUpdateLater) or
7422     (QEvent_type(Event)=QEventUpdateRequest) or
7423     (QEvent_type(Event)=QEventPaint) or
7424     (QEvent_type(Event)=QEventWinIdChange) or
7425     (QEvent_type(Event)=QEventExpose) or
7426     (QEvent_type(Event)=QEventWindowTitleChange) or
7427     (QEvent_type(Event)=QEventActivationChange) or
7428     (QEvent_type(Event)=QEventWindowStateChange) then
7429       WriteLn('TQtMainWindow.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
7430       ' LCLObject=', dbgsName(LCLObject),
7431       ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
7432   {$endif}
7433 
7434   {$IFDEF MSWINDOWS}
7435   if (QEvent_type(Event) = QEventWinIDChange) and not FFirstPaintEvent then
7436      FFirstPaintEvent := True;
7437   {$ENDIF}
7438 
7439   {$IFDEF HASX11}
7440   if (QEvent_type(Event) = QEventPaint) and not FFirstPaintEvent then
7441     FFirstPaintEvent := True;
7442   {$ENDIF}
7443 
7444   {$IFDEF QTSCROLLABLEFORMS}
7445   if Assigned(ScrollArea) and not IsMDIChild then
7446   begin
7447     if QEvent_type(Event) in
7448       [QEventPaint, QEventContextMenu, QEventWheel] then
7449       exit;
7450   end;
7451   {$ENDIF}
7452 
7453   BeginEventProcessing;
7454   try
7455     case QEvent_type(Event) of
7456       QEventHide:
7457       begin
7458         Result := inherited EventFilter(Sender, Event);
7459         {as of r46623 (issue #26893) we use QObject_deleteLater
7460          instead of QWidget_destroy.
7461          QMDIArea does not respond after that, so we must activate next mdichild
7462          according to mdi standards.Looks like Qt4 bug.}
7463         if not Application.Terminated and IsMDIChild then
7464         begin
7465           if Assigned(MDIChildArea) then
7466           begin
7467             if (MDIChildArea.ActiveSubWindow = nil) or
7468               (MDIChildArea.ActiveSubWindow = Widget) then
7469             begin
7470               if not QWidget_isVisibleTo(Widget, MDIChildArea.Widget) then
7471                 QMdiArea_activatePreviousSubWindow(QMDIAreaH(MDIChildArea.Widget));
7472             end;
7473           end;
7474         end;
7475       end;
7476       {$IFDEF QTSCROLLABLEFORMS}
7477       QEventMouseMove: // issue #29159
7478       begin
7479         if (Self is TQtHintWindow) or (IsMdiChild or
7480           (Assigned(LCLObject) and (csDesigning in LCLObject.ComponentState))) then
7481           Result := inherited EventFilter(Sender, Event)
7482         else
7483           Result := False;
7484       end;
7485       {$ENDIF}
7486       QEventMouseButtonPress,
7487       QEventMouseButtonRelease,
7488       QEventMouseButtonDblClick:
7489       begin
7490         if IsMdiChild then
7491         begin
7492           if QMouseEvent_y(QMouseEventH(Event)) <= GetPixelMetric(
7493             QStylePM_TitleBarHeight, nil, Widget) then
7494             QEvent_ignore(Event)
7495           else
7496             Result := SlotMouse(Sender, Event);
7497         end else
7498           Result := SlotMouse(Sender, Event);
7499       end;
7500       QEventWindowUnblocked: Blocked := False;
7501       QEventWindowBlocked: Blocked := True;
7502       QEventWindowActivate:
7503       begin
7504         if not IsMDIChild then
7505         begin
7506           {$IFDEF MSWINDOWS}
7507           // issues #26463, #29744, must restore app if we activate non modal window from taskbar
7508           if (Application.ModalLevel > 0) and
7509             (QApplication_activeModalWidget <> nil) and QWidget_isMinimized(QApplication_activeModalWidget) then
7510           begin
7511             W := QApplication_activeModalWidget;
7512             // back to tray
7513             BeginUpdate;
7514             ShowMinimized;
7515             EndUpdate;
7516             AState := QWidget_windowState(W);
7517             AState := AState and not QtWindowMinimized;
7518             QWidget_setWindowState(W, AState);
7519           end else
7520           {$ENDIF}
7521           SlotActivateWindow(True);
7522         end;
7523       end;
7524       QEventWindowDeactivate: if not IsMDIChild then SlotActivateWindow(False);
7525       QEventShowToParent: ; // do nothing for TQtMainWindow, but leave it unhandled
7526       QEventWindowStateChange:
7527       begin
7528         if IsMDIChild then
7529         begin
7530           //do not process QEventWindowStateChange for MDI children !
7531           //we are doing that job in MDIChildWindowStateChanged slot.
7532           exit;
7533         end;
7534 
7535         CanSendEvent := True;
7536         {$IFDEF HASX11}
7537         // for X11 we must ask state of each modified window.
7538         AState := getWindowState;
7539 
7540         IsMinimizeEvent := AState and QtWindowMinimized <> 0;
7541         if IsMinimizeEvent then
7542         begin
7543           CanSendEvent := IsCurrentDesktop(Widget);
7544           QtWidgetSet.FMinimizedByPager := not CanSendEvent;
7545           if IsMainForm and QtWidgetSet.FMinimizedByPager then
7546             QtWidgetSet.HideAllHints;
7547         end;
7548         {$ENDIF}
7549         if IsMainForm and CanSendEvent then
7550         begin
7551           {$IFNDEF HASX11}
7552           AState := getWindowState;
7553           {$ENDIF}
7554           AStateEvent := QWindowStateChangeEventH(Event);
7555           AOldState := QWindowStateChangeEvent_oldState(AStateEvent);
7556           if AState and QtWindowMinimized <> 0 then
7557           begin
7558             {$IFDEF MSWINDOWS}
7559             for i := 0 to Screen.CustomFormZOrderCount - 1 do
7560             begin
7561               AForm := Screen.CustomFormsZOrdered[i];
7562               if (AForm <> Application.MainForm) and
7563                 // (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and
7564                 AForm.HandleAllocated and AForm.Visible then
7565               begin
7566                 W := TQtWidget(AForm.Handle).Widget;
7567                 if not QWidget_isMinimized(W) then
7568                 begin
7569                   TQtWidget(AForm.Handle).BeginUpdate;
7570                   try
7571                     QWidget_showMinimized(W);
7572                   finally
7573                     TQtWidget(AForm.Handle).EndUpdate;
7574                   end;
7575                 end;
7576               end;
7577             end;
7578             {$ENDIF}
7579             Application.IntfAppMinimize;
7580           end
7581           else
7582           if (AOldState and QtWindowMinimized <> 0) or
7583             (AOldState and QtWindowMaximized <> 0) or
7584             (AOldState and QtWindowFullScreen <> 0) then
7585           begin
7586             {$IFDEF MSWINDOWS}
7587             for i := 0 to Screen.CustomFormZOrderCount - 1 do
7588             begin
7589               AForm := Screen.CustomFormsZOrdered[i];
7590               if (AForm <> Application.MainForm) and
7591                 // (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and
7592                 AForm.HandleAllocated and AForm.Visible then
7593               begin
7594                 W := TQtWidget(AForm.Handle).Widget;
7595                 if QWidget_isMinimized(W) then
7596                 begin
7597                   TQtWidget(AForm.Handle).BeginUpdate;
7598                   try
7599                     QWidget_showNormal(W);
7600                   finally
7601                     TQtWidget(AForm.Handle).EndUpdate;
7602                   end;
7603                 end;
7604               end;
7605             end;
7606             Application.IntfAppRestore;
7607             {$ELSE}
7608 
7609             {$IFDEF HASX11}
7610             // do not activate lazarus app if it wasn't active during
7611             // pager switch !
7612             if (AOldState and QtWindowMinimized <> 0) and
7613               QtWidgetSet.FMinimizedByPager then
7614             begin
7615               QtWidgetSet.FMinimizedByPager := False;
7616               QtWidgetSet.RestoreAllHints;
7617             end else
7618             {$ENDIF}
7619               Application.IntfAppRestore;
7620             {$ENDIF}
7621           end;
7622         end;
7623         if CanSendEvent and not IsFrameWindow then
7624         begin
7625           {$IFDEF MSWINDOWS}
7626           AForm := TCustomForm(LCLObject);
7627           if (fsModal in AForm.FormState) then
7628           begin
7629             AOldState := QWindowStateChangeEvent_oldState(QWindowStateChangeEventH(Event));
7630             AState := GetWindowState;
7631             SlotWindowStateChange;
7632             if (AState and QtWindowMinimized = QtWindowMinimized) and (AOldState and QtWindowMinimized = 0) then
7633               Application.Minimize
7634             else
7635             if (AOldState and QtWindowMinimized = QtWindowMinimized) and (AState and QtWindowMinimized = 0) then
7636               Application.Restore;
7637           end else
7638           if (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and InUpdate then
7639             // do not trigger LCL
7640           else
7641           {$ENDIF}
7642           SlotWindowStateChange;
7643         end;
7644       end;
7645       QEventDrop,
7646       QEventDragMove,
7647       QEventDragEnter:
7648       begin
7649         Result := getAcceptDropFiles;
7650         if (Result) and (QEvent_type(Event) = QEventDrop) then
7651           Result := slotDropFiles(Sender, Event);
7652       end;
7653       QEventResize:
7654       begin
7655         // issue #34698
7656         {$ifdef darwin}
7657         if (QResizeEvent_oldSize(QResizeEventH(Event))^.cx = -1) and (QResizeEvent_oldSize(QResizeEventH(Event))^.cy = -1) then
7658           include(FWidgetState, qtwsForceSendMove);
7659         {$endif}
7660         {$IFDEF QTSCROLLABLEFORMS}
7661         if not Assigned(ScrollArea) then
7662         {$ENDIF}
7663           Result := inherited EventFilter(Sender, Event);
7664       end;
7665       QEventPaint:
7666       begin
7667         {do not send paint or resize event to LCL if we are pure TCustomForm,
7668          CWEvent or ScrollArea.EventFilter will process it.
7669          So call SlotPaint only if we are eg TQtHintWindow.}
7670         if (FCentralWidget = nil) or (FCentralWidget = Widget) then
7671           Result := inherited EventFilter(Sender, Event);
7672       end;
7673     else
7674       Result := inherited EventFilter(Sender, Event);
7675     end;
7676   finally
7677     EndEventProcessing;
7678   end;
7679 end;
7680 
7681 procedure TQtMainWindow.MDIChildWindowStateChanged(AOldState: QtWindowStates;
7682   ANewState: QtWindowStates); cdecl;
7683 var
7684   AOld, ANew: QtWindowStates;
7685   Arr: TPtrIntArray;
7686   i: Integer;
7687   W: QMDISubWindowH;
7688   B: Boolean;
7689   FoundWin: Boolean;
7690 begin
7691   // check if state is same without active flag, in that case don't inform lcl.
7692   AOld := AOldState and not QtWindowActive;
7693   ANew := ANewState and not QtWindowActive;
7694   if AOld = ANew then
7695     exit;
7696 
7697   {inform LCL about change}
7698   SlotWindowStateChange;
7699 
7700   if (AOldState and QtWindowMinimized <> 0) and (ANewState and QtWindowMinimized = 0) and
7701     (ANewState and QtWindowMaximized = 0) and LCLObject.ClientRectNeedsInterfaceUpdate then
7702     LCLObject.DoAdjustClientRectChange(True);
7703 
7704   {activate next mdi in chain if we are minimized}
7705   if Assigned(MDIChildArea) and
7706     (ANewState and QtWindowMinimized = QtWindowMinimized) and
7707     (ANewState and QtWindowActive = QtWindowActive) then
7708   begin
7709     QMdiArea_subWindowList(QMdiAreaH(MDIChildArea.Widget), @Arr);
7710     // activate only if MDIChild is not minimized !
7711     // we are using *history activation order*,
7712     // so we must take into account index of
7713     // current minimized win.
7714     B := False;
7715     FoundWin := False;
7716     for i := High(Arr) downto 0 do
7717     begin
7718       W := QMdiSubWindowH(Arr[i]);
7719       AOld := QWidget_windowState(W);
7720       B := W = Widget;
7721       if B and (W <> Widget) and (AOld and QtWindowMinimized = 0) then
7722       begin
7723         FoundWin := True;
7724         MDIChildArea.ActivateSubWindow(W);
7725         break;
7726       end;
7727     end;
7728     // not found lower index window, search for higher one
7729     if not FoundWin then
7730     begin
7731       for i := High(Arr) downto 0 do
7732       begin
7733         W := QMdiSubWindowH(Arr[i]);
7734         AOld := QWidget_windowState(W);
7735         if (W <> Widget) and (AOld and QtWindowMinimized = 0) then
7736         begin
7737           MDIChildArea.ActivateSubWindow(W);
7738           break;
7739         end;
7740       end;
7741     end;
7742 
7743   end;
7744 end;
7745 
IsMdiChildnull7746 function TQtMainWindow.IsMdiChild: Boolean;
7747 begin
7748   Result := (LCLObject <> nil) and not IsFrameWindow and not
7749     (csDesigning in LCLObject.ComponentState) and
7750     (TCustomForm(LCLObject).FormStyle = fsMDIChild) and not IsFormDesign(LCLObject);
7751 end;
7752 
IsModalnull7753 function TQtMainWindow.IsModal: Boolean;
7754 begin
7755   Result := QWidget_isModal(Widget);
7756 end;
7757 
MdiChildCountnull7758 function TQtMainWindow.MdiChildCount: integer;
7759 var
7760   Arr: TPtrIntArray;
7761   Area: QMdiAreaH;
7762 begin
7763   Result := 0;
7764   if IsMdiChild then
7765     Area := QMdiSubWindow_mdiArea(QMdiSubWindowH(Widget))
7766   else
7767     Area := QMDIAreaH(MDIAreaHandle.Widget);
7768   if Area <> nil then
7769   begin
7770     QMdiArea_subWindowList(Area, @Arr);
7771     Result := High(Arr);
7772   end;
7773 end;
7774 
7775 procedure TQtMainWindow.OffsetMousePos(APoint: PQtPoint);
7776 begin
7777   if not IsMdiChild then
7778     inherited OffsetMousePos(APoint);
7779 end;
7780 
7781 procedure TQtMainWindow.setAcceptDropFiles(AValue: Boolean);
7782 begin
7783   QWidget_setAcceptDrops(Widget, AValue);
7784 end;
7785 
7786 procedure TQtMainWindow.setColor(const Value: PQColor);
7787 var
7788   p: QPaletteH;
7789 begin
7790   inherited setColor(Value);
7791   if Assigned(MDIAreaHandle) and Assigned(FCentralWidget) then
7792   begin
7793     p := QWidget_palette(FCentralWidget);
7794     if p <> nil then
7795       QMdiArea_setBackground(QMdiAreaH(MdiAreaHandle.Widget), QPalette_background(P));
7796   end;
7797 end;
7798 
7799 procedure TQtMainWindow.setFocusPolicy(const APolicy: QtFocusPolicy);
7800 begin
7801   {$IFDEF QTSCROLLABLEFORMS}
7802   if Assigned(ScrollArea) then
7803     ScrollArea.setFocusPolicy(APolicy)
7804   else
7805     inherited setFocusPolicy(APolicy);
7806   {$ELSE}
7807   inherited setFocusPolicy(APolicy);
7808   {$ENDIF}
7809 end;
7810 
7811 procedure TQtMainWindow.SlotActivateWindow(vActivate: Boolean); cdecl;
7812 var
7813   Msg: TLMActivate;
7814   FIsActivated: Boolean;
7815 begin
7816   {$ifdef VerboseQt}
7817   WriteLn('TQtWidget.SlotActivateWindow Name', LCLObject.Name, ' vActivate: ', dbgs(vActivate));
7818   {$endif}
7819 
7820   if IsFrameWindow then
7821     exit;
7822 
7823   FillChar(Msg{%H-}, SizeOf(Msg), #0);
7824 
7825   FIsActivated := TCustomForm(LCLObject).Active;
7826   {do not send activate if form is already activated,
7827    also do not send activate if TCustomForm.Parent is assigned
7828    since it's form embedded into another control or form}
7829   if (vActivate = FIsActivated) or (LCLObject.Parent <> nil) then
7830     exit;
7831 
7832   Msg.Msg := LM_ACTIVATE;
7833   if vActivate then
7834     Msg.Active := WA_ACTIVE
7835   else
7836     Msg.Active := WA_INACTIVE;
7837   Msg.ActiveWindow := LCLObject.Handle;
7838 
7839   DeliverMessage(Msg);
7840 end;
7841 
7842 {------------------------------------------------------------------------------
7843   Function: TQtMainWindow.SlotWindowStateChange
7844   Params:  None
7845   Returns: Nothing
7846  ------------------------------------------------------------------------------}
7847 procedure TQtMainWindow.slotWindowStateChange; cdecl;
7848 var
7849   Msg: TLMSize;
7850 begin
7851   {$ifdef VerboseQt}
7852     WriteLn('TQtMainWindow.SlotWindowStateChange');
7853   {$endif}
7854 
7855   FillChar(Msg{%H-}, SizeOf(Msg), #0);
7856 
7857   Msg.Msg := LM_SIZE;
7858   Msg.SizeType := SIZE_RESTORED;
7859 
7860   if getWindowState and QtWindowMinimized <> 0 then
7861     Msg.SizeType := SIZE_MINIMIZED
7862   else
7863   if (getWindowState and QtWindowFullScreen <> 0) then
7864     Msg.SizeType := SIZE_FULLSCREEN
7865   else
7866   if (getWindowState and QtWindowMaximized <> 0) then
7867     Msg.SizeType := SIZE_MAXIMIZED;
7868 
7869   Msg.SizeType := Msg.SizeType or Size_SourceIsInterface;
7870 
7871   {Mdichild sends size of minimized title, and that's bad, after restore client
7872    rect is mismatched and provokes OnResize events.We are sending
7873    to the LCL Width and Height of LCLObject so resize event won't trigger.
7874    issue #27518}
7875   if IsMDIChild and Assigned(LCLObject) and
7876     (getWindowState and QtWindowMinimized <> 0) then
7877   begin
7878     Msg.Width := Word(LCLObject.Width);
7879     Msg.Height := Word(LCLObject.Height);
7880   end else
7881   begin
7882     Msg.Width := Word(getWidth);
7883     Msg.Height := Word(getHeight);
7884   end;
7885   DeliverMessage(Msg);
7886 end;
7887 
7888 procedure TQtMainWindow.setShowInTaskBar(AValue: Boolean);
7889 begin
7890   FShowOnTaskBar := AValue;
7891   {$IFNDEF HASX11}
7892   if not QWidget_isModal(Widget) then
7893     UpdateParent;
7894   {$ENDIF}
7895 end;
7896 
7897 procedure TQtMainWindow.setRealPopupParent(NewParent: QWidgetH);
7898 begin
7899   FPopupParent := NewParent;
7900   UpdateParent;
7901 end;
7902 
TQtMainWindow.WinIDNeedednull7903 function TQtMainWindow.WinIDNeeded: boolean;
7904 begin
7905   Result := False;
7906   {$IFDEF HASX11}
7907   if Assigned(LCLObject) and not IsFormDesign(LCLObject) and
7908     not IsMdiChild and (LCLObject.Parent = nil) and not testAttribute(QtWA_Mapped) and
7909     QWidget_isTopLevel(Widget) then
7910     Result := True;
7911   {$ENDIF}
7912 end;
7913 
7914 procedure TQtMainWindow.AttachEvents;
7915 begin
7916   inherited AttachEvents;
7917   {$IFDEF QTSCROLLABLEFORMS}
7918   FCWEventHook := nil;
7919   {$ENDIF}
7920   if (FCentralWidget <> nil)
7921     {$IFDEF QTSCROLLABLEFORMS} and not Assigned(ScrollArea){$ENDIF} then
7922   begin
7923     FCWEventHook := QObject_hook_create(FCentralWidget);
7924     QObject_hook_hook_events(FCWEventHook, @CWEventFilter);
7925   end;
7926   if IsMDIChild then
7927   begin
7928     FMDIStateHook := QMdiSubWindow_hook_create(Widget);
7929     QMdiSubWindow_hook_hook_windowStateChanged(FMDIStateHook,
7930       @MDIChildWindowStateChanged);
7931   end;
7932 end;
7933 
7934 procedure TQtMainWindow.DetachEvents;
7935 begin
7936   if FCWEventHook <> nil then
7937   begin
7938     QObject_hook_destroy(FCWEventHook);
7939     FCWEventHook := nil;
7940   end;
7941 
7942   if FMDIStateHook <> nil then
7943   begin
7944     QMdiSubWindow_hook_destroy(FMDIStateHook);
7945     FMDIStateHook := nil;
7946   end;
7947 
7948   inherited DetachEvents;
7949 end;
7950 
TQtMainWindow.CWEventFilternull7951 function TQtMainWindow.CWEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
7952 var
7953   R: TRect;
7954   R2: TRect;
7955   i: Integer;
7956 begin
7957   Result := False;
7958 
7959   if LCLObject <> nil then
7960   begin
7961     case QEvent_type(Event) of
7962       QEventPaint: Result := inherited EventFilter(Sender, Event);
7963       QEventResize:
7964         begin
7965           {mdi area part begins}
7966           if MdiAreaHandle <> nil then
7967           begin
7968             {first must get contents rect - all except main menu}
7969             QWidget_contentsRect(FCentralWidget, @R);
7970             {TODO: find better way to find out which controls are top,left,right & bottom aligned ...}
7971             for i := 0 to LCLObject.ControlCount - 1 do
7972             begin
7973               if (LCLObject.Controls[i] is TWinControl) and
7974                 (TWinControl(LCLObject.Controls[i]).Align in [alTop, alLeft, alRight, alBottom]) then
7975               begin
7976                 R2 := TWinControl(LCLObject.Controls[i]).BoundsRect;
7977                 case TWinControl(LCLObject.Controls[i]).Align of
7978                   alLeft: R.Left := R.Left + (R2.Right - R2.Left);
7979                   alTop: R.Top := R.Top + (R2.Bottom - R2.Top);
7980                   alRight: R.Right := R.Right - (R2.Right - R2.Left);
7981                   alBottom: R.Bottom := R.Bottom - (R2.Bottom - R2.Top);
7982                 end;
7983               end;
7984             end; {components loop}
7985             QWidget_setGeometry(MDIAreaHandle.Widget, @R);
7986           end;
7987           {mdi area part end}
7988         end;
7989     end;
7990   end;
7991 end;
7992 
7993 { TQtStaticText }
7994 
TQtStaticText.GetWordWrapnull7995 function TQtStaticText.GetWordWrap: Boolean;
7996 begin
7997   Result := QLabel_wordWrap(QLabelH(Widget));
7998 end;
7999 
8000 procedure TQtStaticText.SetWordWrap(AValue: Boolean);
8001 begin
8002   QLabel_setWordWrap(QLabelH(Widget), AValue);
8003 end;
8004 
CreateWidgetnull8005 function TQtStaticText.CreateWidget(const AParams: TCreateParams): QWidgetH;
8006 var
8007   Parent: QWidgetH;
8008 begin
8009   // Creates the widget
8010   {$ifdef VerboseQt}
8011     WriteLn('TQtStaticText.Create');
8012   {$endif}
8013   FWidgetNeedFontColorInitialization := True;
8014   if AParams.WndParent <> 0 then
8015     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8016   else
8017     Parent := nil;
8018   Result := QLabel_create(Parent);
8019 end;
8020 
TQtStaticText.CanPaintBackgroundnull8021 function TQtStaticText.CanPaintBackground: Boolean;
8022 begin
8023   Result := CanSendLCLMessage and getEnabled and
8024     (LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
8025 end;
8026 
8027 {------------------------------------------------------------------------------
8028   Function: TQtStaticText.SetText
8029   Params:  None
8030   Returns: Nothing
8031  ------------------------------------------------------------------------------}
8032 procedure TQtStaticText.SetText(const W: WideString);
8033 var
8034   AmpersandPos: Integer;
8035   LocalW: WideString;
8036 begin
8037   LocalW := W;
8038   if TCustomStaticText(LCLObject).ShowAccelChar then
8039   begin
8040     // replace '&' by underline
8041     AmpersandPos := Pos('&', W);
8042     if AmpersandPos > 0 then
8043     begin
8044       LocalW := Copy(W, 1, AmpersandPos - 1) + '<u>';
8045       if AmpersandPos < Length(W) then
8046         LocalW := LocalW + W[AmpersandPos + 1];
8047       LocalW := LocalW + '</u>' + Copy(W, AmpersandPos + 2, Length(W));
8048     end;
8049   end;
8050   QLabel_setText(QLabelH(Widget), @LocalW);
8051 end;
8052 
8053 procedure TQtStaticText.setAlignment(const AAlignment: QtAlignment);
8054 begin
8055   QLabel_setAlignment(QLabelH(Widget), AAlignment);
8056 end;
8057 
8058 {------------------------------------------------------------------------------
8059   Function: TQtStaticText.Text
8060   Params:  None
8061   Returns: Nothing
8062  ------------------------------------------------------------------------------}
TQtStaticText.getTextnull8063 function TQtStaticText.getText: WideString;
8064 begin
8065   QLabel_text(QLabelH(Widget), @Result);
8066 end;
8067 
8068 { TQtCheckBox }
8069 
CreateWidgetnull8070 function TQtCheckBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
8071 var
8072   Parent: QWidgetH;
8073 begin
8074   // Creates the widget
8075   {$ifdef VerboseQt}
8076     WriteLn('TQtCheckBox.Create');
8077   {$endif}
8078   TextColorRole := QPaletteWindowText;
8079   FWidgetNeedFontColorInitialization := True;
8080   if AParams.WndParent <> 0 then
8081     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8082   else
8083     Parent := nil;
8084 
8085   Result := QCheckBox_create(Parent);
8086 end;
8087 
8088 {------------------------------------------------------------------------------
8089   Function: TQtCheckBox.CheckState
8090   Params:  None
8091   Returns: Nothing
8092  ------------------------------------------------------------------------------}
TQtCheckBox.CheckStatenull8093 function TQtCheckBox.CheckState: QtCheckState;
8094 begin
8095   Result := QCheckBox_checkState(QCheckBoxH(Widget));
8096 end;
8097 
8098 {------------------------------------------------------------------------------
8099   Function: TQtCheckBox.setCheckState
8100   Params:  None
8101   Returns: Nothing
8102  ------------------------------------------------------------------------------}
8103 procedure TQtCheckBox.setCheckState(state: QtCheckState);
8104 begin
8105   QCheckBox_setCheckState(QCheckBoxH(Widget), state);
8106 end;
8107 
8108 procedure TQtCheckBox.setTriState(AAllowGrayed: Boolean);
8109 begin
8110   QCheckBox_setTristate(QCheckBoxH(Widget), AAllowGrayed);
8111 end;
8112 
8113 procedure TQtCheckBox.AttachEvents;
8114 begin
8115   inherited AttachEvents;
8116   FStateChangedHook := QCheckBox_hook_create(Widget);
8117   QCheckBox_hook_hook_stateChanged(FStateChangedHook, @SignalStateChanged);
8118 end;
8119 
8120 procedure TQtCheckBox.DetachEvents;
8121 begin
8122   if FStateChangedHook <> nil then
8123   begin
8124     QCheckBox_hook_destroy(FStateChangedHook);
8125     FStateChangedHook := nil;
8126   end;
8127   inherited DetachEvents;
8128 end;
8129 
8130 {------------------------------------------------------------------------------
8131   Function: TQtCheckBox.signalStateChanged
8132   Params:  None
8133   Returns: Nothing
8134  ------------------------------------------------------------------------------}
8135 procedure TQtCheckBox.signalStateChanged(p1: Integer); cdecl;
8136 var
8137   Msg: TLMessage;
8138 begin
8139   if not InUpdate then
8140   begin
8141     FillChar(Msg{%H-}, SizeOf(Msg), #0);
8142     Msg.Msg := LM_CHANGED;
8143     DeliverMessage(Msg);
8144   end;
8145 end;
8146 
8147 { TQtRadioButton }
8148 
TQtRadioButton.CreateWidgetnull8149 function TQtRadioButton.CreateWidget(const AParams: TCreateParams): QWidgetH;
8150 var
8151   Parent: QWidgetH;
8152 begin
8153   // Creates the widget
8154   {$ifdef VerboseQt}
8155     WriteLn('TQtRadioButton.Create');
8156   {$endif}
8157   TextColorRole := QPaletteWindowText;
8158   FWidgetNeedFontColorInitialization := True;
8159   if AParams.WndParent <> 0 then
8160     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8161   else
8162     Parent := nil;
8163   Result := QRadioButton_create(Parent);
8164   // hide widget by default
8165   QWidget_hide(Result);
8166 end;
8167 
8168 procedure TQtRadioButton.AttachEvents;
8169 begin
8170   inherited AttachEvents;
8171   FToggledHook := QAbstractButton_hook_create(Widget);
8172   QAbstractButton_hook_hook_toggled(FToggledHook, @SignalToggled);
8173 end;
8174 
8175 procedure TQtRadioButton.DetachEvents;
8176 begin
8177   if FToggledHook <> nil then
8178   begin
8179     QAbstractButton_hook_destroy(FToggledHook);
8180     FToggledHook := nil;
8181   end;
8182   inherited DetachEvents;
8183 end;
8184 
8185 procedure TQtRadioButton.SignalToggled(Checked: Boolean); cdecl;
8186 var
8187   Msg: TLMessage;
8188 begin
8189   if not InUpdate then
8190   begin
8191     FillChar(Msg{%H-}, SizeOf(Msg), #0);
8192     Msg.Msg := LM_CHANGED;
8193     DeliverMessage(Msg);
8194   end;
8195 end;
8196 
TQtRadioButton.EventFilternull8197 function TQtRadioButton.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
8198 begin
8199   Result := inherited EventFilter(Sender, Event);
8200   if (LCLObject <> nil) and
8201     ((QEvent_type(Event) in [QEventMouseButtonPress, QEventMouseButtonRelease])
8202     or
8203     ((QEvent_type(Event) in [QEventKeyPress, QEventKeyRelease]) and
8204      (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
8205      isChecked))
8206   then
8207     Result := False;
8208 end;
8209 
8210 { TQtGroupBox }
8211 
8212 procedure TQtGroupBox.setLayoutThemeMargins(ALayout: QLayoutH; AWidget: QWidgetH);
8213 var
8214   LeftMargin: Integer;
8215   TopMargin: Integer;
8216   RightMargin: Integer;
8217   BottomMargin, AStyleMetric: Integer;
8218 begin
8219   if ALayout = nil then
8220     exit;
8221   QWidget_getContentsMargins(AWidget,@LeftMargin, @TopMargin, @RightMargin, @BottomMargin);
8222 
8223   AStyleMetric := QStyle_pixelMetric(QApplication_style(), QStyleSE_DockWidgetTitleBarText, nil, Widget);
8224 
8225   {issue #37576}
8226   {if (AStyle = 'fusion') or (AStyle = 'gtk2') or
8227     (AStyle = 'qt5ct-style') then}
8228   if AStyleMetric = 0 then
8229   else
8230   if (getText = '') then
8231     TopMargin := BottomMargin;
8232 
8233   QLayout_setContentsMargins(ALayout, LeftMargin, TopMargin, RightMargin, BottomMargin);
8234   QLayout_invalidate(ALayout);
8235 
8236   if (LCLObject <> nil) and testAttribute(QtWA_Mapped) then
8237   begin
8238     {$IFDEF VerboseQtResize}
8239     DebugLn('TQtGroupBox.setLayoutThemeMargins: ',dbgsName(LCLObject),' casp: ',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' mapped ',dbgs(testAttribute(QtWA_Mapped)));
8240     {$ENDIF}
8241     LCLObject.DoAdjustClientRectChange(False);
8242     LCLObject.InvalidateClientRectCache(True);
8243   end;
8244 end;
8245 
TQtGroupBox.GetCheckBoxVisiblenull8246 function TQtGroupBox.GetCheckBoxVisible: boolean;
8247 begin
8248   Result := QGroupBox_isCheckable(QGroupBoxH(Widget));
8249 end;
8250 
GetCheckBoxStatenull8251 function TQtGroupBox.GetCheckBoxState: boolean;
8252 begin
8253   Result := CheckBoxVisible and QGroupBox_isChecked(QGroupBoxH(Widget));
8254 end;
8255 
8256 procedure TQtGroupBox.SetCheckBoxState(AValue: boolean);
8257 begin
8258   if CheckBoxVisible then
8259     QGroupBox_setChecked(QGroupBoxH(Widget), AValue);
8260 end;
8261 
8262 procedure TQtGroupBox.SetCheckBoxVisible(AValue: boolean);
8263 begin
8264   QGroupBox_setCheckable(QGroupBoxH(Widget), AValue);
8265 end;
8266 
TQtGroupBox.CreateWidgetnull8267 function TQtGroupBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
8268 var
8269   Layout: QBoxLayoutH;
8270   Parent: QWidgetH;
8271 begin
8272   // Creates the widget
8273   {$ifdef VerboseQt}
8274     WriteLn('TQtGroupBox.Create ');
8275   {$endif}
8276   FGroupBoxType := tgbtNormal;
8277   FHasPaint := True;
8278   if AParams.WndParent <> 0 then
8279     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8280   else
8281     Parent := nil;
8282   Result := QGroupBox_create(Parent);
8283   FCentralWidget := QStackedWidget_create(Result);
8284   QWidget_setMouseTracking(FCentralWidget, True);
8285   {we set QtNoFocus by default, since we don't want
8286   FCentralWidget grabs focus on mouse click}
8287   QWidget_setFocusPolicy(FCentralWidget, QtNoFocus);
8288 
8289   Layout := QVBoxLayout_create(Result);
8290   QLayout_addWidget(Layout, FCentralWidget);
8291   QWidget_setLayout(Result, QLayoutH(Layout));
8292   QWidget_setAttribute(Result, QtWA_LayoutOnEntireRect, True);
8293 end;
8294 
8295 procedure TQtGroupBox.AttachEvents;
8296 begin
8297   inherited AttachEvents;
8298   if FCentralWidget <> nil then
8299   begin
8300     FCWEventHook := QObject_hook_create(FCentralWidget);
8301     QObject_hook_hook_events(FCWEventHook, @EventFilter);
8302   end;
8303 end;
8304 
8305 procedure TQtGroupBox.DetachEvents;
8306 begin
8307   if FCWEventHook <> nil then
8308   begin
8309     QObject_hook_destroy(FCWEventHook);
8310     FCWEventHook := nil;
8311   end;
8312   inherited DetachEvents;
8313 end;
8314 
TQtGroupBox.CanPaintBackgroundnull8315 function TQtGroupBox.CanPaintBackground: Boolean;
8316 begin
8317   Result := CanSendLCLMessage and getEnabled and
8318     (LCLObject.Color <> clDefault);
8319 end;
8320 
TQtGroupBox.EventFilternull8321 function TQtGroupBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
8322   cdecl;
8323 var
8324   ResizeEvent: QResizeEventH;
8325   NewSize, OldSize: TSize;
8326 begin
8327   Result := False;
8328   QEvent_accept(Event);
8329   if LCLObject = nil then
8330     exit;
8331 
8332   if (Sender = FCentralWidget) then
8333   begin
8334     case QEvent_type(Event) of
8335       QEventPaint: Result := inherited EventFilter(Sender, Event);
8336     end;
8337     exit;
8338   end;
8339   {For possible problems with Mouse events check issue #29572 and #32186}
8340   case QEvent_type(Event) of
8341     QEventPaint:
8342       begin
8343         Result := False;
8344         // paint complete background, like gtk2 does
8345         if CanPaintBackground then
8346           SlotPaintBg(Sender, Event);
8347         // issue #28155, we are painting our FCentralWidget, not QGroupBox
8348         // Result := inherited EventFilter(Sender, Event);
8349       end;
8350     QEventFontChange:
8351       begin
8352         Result := inherited EventFilter(Sender, Event);
8353         setLayoutThemeMargins(QWidget_layout(Widget), Widget);
8354       end;
8355     QEventStyleChange: setLayoutThemeMargins(QWidget_layout(Widget), Widget);
8356     QEventContentsRectChange:
8357       begin
8358         if testAttribute(QtWA_Mapped) then
8359           Result := inherited EventFilter(Sender, Event);
8360       end;
8361     QEventShow:
8362       begin
8363         {$IFDEF VerboseQtResize}
8364         DebugLn('TQtGroupBox.QEventShow: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' mapped=',dbgs(testAttribute(QtWA_Mapped)));
8365         {$ENDIF}
8366         LCLObject.DoAdjustClientRectChange(False);
8367         SlotShow(True);
8368         {send dummy LM_SIZE to LCL}
8369         if (FGroupBoxType <> tgbtNormal) and
8370           LCLObject.ClientRectNeedsInterfaceUpdate then
8371         begin
8372           OldSize.cx := LCLObject.Height;
8373           OldSize.cy := LCLObject.Width;
8374           NewSize := OldSize;
8375           inc(OldSize.cx);
8376           inc(OldSize.cy);
8377           ResizeEvent := QResizeEvent_create(@NewSize, @OldSize);
8378           QCoreApplication_postEvent(Widget, ResizeEvent, -1);
8379         end;
8380       end;
8381     else
8382       Result := inherited EventFilter(Sender, Event);
8383   end;
8384 end;
8385 
getClientBoundsnull8386 function TQtGroupBox.getClientBounds: TRect;
8387 var
8388   R, R1: TRect;
8389   L: Integer;
8390   T: Integer;
8391   aRight: Integer;
8392   B: Integer;
8393   AStyleOption: QStyleOptionGroupBoxH;
8394   APixelMetric: Integer;
8395 begin
8396   QWidget_contentsRect(Widget, @R);
8397   if Assigned(FCentralWidget) then
8398     QWidget_rect(FCentralWidget, @R1)
8399   else
8400     R1 := Rect(0, 0, 0, 0);
8401   Result := R;
8402   OffsetRect(Result, -Result.Left, -Result.Top);
8403   {$IFNDEF HASX11}
8404   if testAttribute(QtWA_Mapped) and QWidget_testAttribute(FCentralWidget, QtWA_Mapped) then
8405     QWidget_rect(FCentralWidget, @Result)
8406   else
8407   {$ENDIF}
8408   begin
8409     if Assigned(FCentralWidget) and not IsRectEmpty(R1) then
8410     begin
8411       R := R1;
8412       R1.Left := 0;
8413       R1.Top := 0;
8414       R1.Right := R1.Right - R.Left;
8415       R1.Bottom := R1.Bottom - R.Top;
8416       QWidget_getContentsMargins(Widget,@L, @T, @aRight, @B);
8417       AStyleOption := QStyleOptionGroupBox_create;
8418       APixelMetric := QStyle_pixelMetric(QApplication_style(), QStylePM_DefaultChildMargin, AStyleOption, Widget);
8419       if APixelMetric = 4 then
8420         APixelMetric := 9
8421       else
8422         APixelMetric := 0;
8423       QStyleOptionGroupBox_destroy(AStyleOption);
8424       inc(Result.Bottom, APixelMetric);
8425       {$IFDEF VerboseQtResize}
8426       DebugLn('>>>>>>>>>>> TQtGroupBox.getClientBounds(',dbgsName(LCLObject),') setting clientBounds was ',dbgs(R),' changed to ',dbgs(R1),' from result ',dbgs(Result));
8427       DebugLn('    MARGINS ARE ',Format('l %d t %d r %d b %d',[L, T, ARight, B]),' APixelMetric=',dbgs(APixelMetric));
8428       {$ENDIF}
8429       exit;
8430     end;
8431   end;
8432   {$IFDEF VerboseQtResize}
8433   DebugLn('TQtGroupBox.getClientBounds(',dbgsName(LCLObject),') R=',dbgs(R),' Result=',dbgs(Result),' CENTRALWIDGET=',dbgs(R1),' mapped ',dbgs(testAttribute(QtWA_Mapped)));
8434   {$ENDIF}
8435 end;
8436 
getTextnull8437 function TQtGroupBox.getText: WideString;
8438 begin
8439   QGroupBox_title(QGroupBoxH(Widget), @Result);
8440 end;
8441 
8442 procedure TQtGroupBox.preferredSize(var PreferredWidth,
8443   PreferredHeight: integer; WithThemeSpace: Boolean);
8444 var
8445   L, T, R, B: Integer;
8446   ASize: TSize;
8447 begin
8448   if WithThemeSpace then
8449     QWidget_getContentsMargins(Widget,@L, @T, @R, @B)
8450   else
8451   begin
8452     L := 0;
8453     T := 0;
8454     R := 0;
8455     B := 0;
8456   end;
8457   QGroupBox_minimumSizeHint(QGroupBoxH(Widget), @ASize);
8458   PreferredWidth := ASize.cx + L + R;
8459   PreferredHeight := ASize.cy + B + T;
8460   {$IFDEF VerboseQtResize}
8461   DebugLn('TQtGroupBox.preferredSize(',dbgsName(LCLObject),' PrefW=',dbgs(PreferredWidth),
8462     ' PrefH=',dbgs(PreferredHeight),' Mapped ? ',dbgs(testAttribute(QtWA_Mapped)),
8463     ' SizeHint ',dbgs(ASize),' casp ',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
8464   {$ENDIF}
8465 end;
8466 
8467 procedure TQtGroupBox.setText(const W: WideString);
8468 begin
8469   QGroupBox_setTitle(QGroupBoxH(Widget), @W);
8470   setLayoutThemeMargins(QWidget_Layout(Widget), Widget);
8471 end;
8472 
8473 procedure TQtGroupBox.setFocusPolicy(const APolicy: QtFocusPolicy);
8474 begin
8475   if Assigned(LCLObject) and not LCLObject.TabStop then
8476     inherited setFocusPolicy(QtNoFocus)
8477   else
8478     inherited setFocusPolicy(APolicy);
8479 end;
8480 
8481 procedure TQtGroupBox.Update(ARect: PRect);
8482 var
8483   P: TPoint;
8484   R: TRect;
8485 begin
8486   if Assigned(FCentralWidget) then
8487   begin
8488     if ARect <> nil then
8489     begin
8490       P := getClientOffset;
8491       R := ARect^;
8492       OffsetRect(R, -P.X, -P.Y);
8493       QWidget_update(FCentralWidget, @R);
8494     end else
8495       QWidget_update(FCentralWidget);
8496   end else
8497     inherited Update(ARect);
8498 end;
8499 
8500 procedure TQtGroupBox.UpdateRegion(ARgn: QRegionH);
8501 var
8502   P: TPoint;
8503 begin
8504   if Assigned(FCentralWidget) then
8505   begin
8506     if ARgn <> nil then
8507     begin
8508       P := getClientOffset;
8509       QRegion_translate(ARgn, -P.X, -P.Y);
8510       QWidget_update(FCentralWidget, ARgn)
8511     end else
8512       QWidget_update(FCentralWidget);
8513   end else
8514     inherited UpdateRegion(ARgn);
8515 end;
8516 
8517 procedure TQtGroupBox.Repaint(ARect: PRect);
8518 var
8519   P: TPoint;
8520   R: TRect;
8521 begin
8522   if Assigned(FCentralWidget) then
8523   begin
8524     if ARect <> nil then
8525     begin
8526       P := getClientOffset;
8527       R := ARect^;
8528       OffsetRect(R, -P.X, -P.Y);
8529       QWidget_repaint(FCentralWidget, @R);
8530     end else
8531       QWidget_repaint(FCentralWidget);
8532   end else
8533   inherited Repaint(ARect);
8534 end;
8535 
8536 { TQtFrame }
8537 
CreateWidgetnull8538 function TQtFrame.CreateWidget(const AParams: TCreateParams): QWidgetH;
8539 var
8540   Parent: QWidgetH;
8541 begin
8542   // Creates the widget
8543   {$ifdef VerboseQt}
8544     WriteLn('TQtFrame.Create');
8545   {$endif}
8546   FHasPaint := True;
8547   if AParams.WndParent <> 0 then
8548     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8549   else
8550     Parent := nil;
8551   Result := QFrame_create(Parent);
8552 end;
8553 
TQtFrame.CanPaintBackgroundnull8554 function TQtFrame.CanPaintBackground: Boolean;
8555 begin
8556   Result := CanSendLCLMessage and {getEnabled and}
8557     (LCLObject.Color <> clBackground) and (LCLObject.Color <> clDefault);
8558 end;
8559 
8560 procedure TQtFrame.SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl;
8561 var
8562   Painter: QPainterH;
8563   Brush: QBrushH;
8564   Color: TQColor;
8565   R: TRect;
8566 begin
8567   if CanSendLCLMessage and (LCLObject is TWinControl) then
8568   begin
8569     if LCLObject.Color = clDefault then
8570       Color := Palette.DefaultColor
8571     else
8572       ColorRefToTQColor(ColorToRGB(LCLObject.Color), Color);
8573     Painter := QPainter_create(QWidget_to_QPaintDevice(QWidgetH(Sender)));
8574     Brush := QBrush_create(@Color, QtSolidPattern);
8575     try
8576       QPaintEvent_rect(QPaintEventH(Event), @R);
8577       QPainter_fillRect(Painter, @R, Brush);
8578       if (LCLObject is TCustomPanel) and (TCustomPanel(LCLObject).BorderStyle <> bsNone) then
8579         q_DrawShadePanel(Painter, PRect(@R), Palette.Handle, True, 2);
8580       QPainter_end(Painter);
8581     finally
8582       QBrush_destroy(Brush);
8583       QPainter_destroy(Painter);
8584     end;
8585   end;
8586 end;
8587 
8588 procedure TQtFrame.setFocusPolicy(const APolicy: QtFocusPolicy);
8589 begin
8590   if Assigned(LCLObject) and not LCLObject.TabStop then
8591     inherited setFocusPolicy(QtNoFocus)
8592   else
8593     inherited setFocusPolicy(APolicy);
8594 end;
8595 
8596 {------------------------------------------------------------------------------
8597   Function: TQtFrame.setFrameStyle
8598   Params:  None
8599   Returns: Nothing
8600  ------------------------------------------------------------------------------}
8601 procedure TQtFrame.setFrameStyle(p1: Integer);
8602 begin
8603   QFrame_setFrameStyle(QFrameH(Widget), p1);
8604 end;
8605 
8606 {------------------------------------------------------------------------------
8607   Function: TQtFrame.setFrameShape
8608   Params:  None
8609   Returns: Nothing
8610  ------------------------------------------------------------------------------}
8611 procedure TQtFrame.setFrameShape(p1: QFrameShape);
8612 begin
8613   QFrame_setFrameShape(QFrameH(Widget), p1);
8614 end;
8615 
8616 {------------------------------------------------------------------------------
8617   Function: TQtFrame.setFrameShadow
8618   Params:  None
8619   Returns: Nothing
8620  ------------------------------------------------------------------------------}
8621 procedure TQtFrame.setFrameShadow(p1: QFrameShadow);
8622 begin
8623   QFrame_setFrameShadow(QFrameH(Widget), p1);
8624 end;
8625 
8626 {------------------------------------------------------------------------------
8627   Function: TQtArrow.CreateWidget
8628   Params:  None
8629   Returns: Nothing
8630  ------------------------------------------------------------------------------}
TQtArrow.CreateWidgetnull8631 function TQtArrow.CreateWidget(const AParams: TCreateParams):QWidgetH;
8632 var
8633   Parent: QWidgetH;
8634 begin
8635   // Creates the widget
8636   {$ifdef VerboseQt}
8637     WriteLn('TQtArrow.Create');
8638   {$endif}
8639   FHasPaint := True;
8640   if AParams.WndParent <> 0 then
8641     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8642   else
8643     Parent := nil;
8644   Result := QFrame_create(Parent);
8645 end;
8646 
CreateWidgetnull8647 function TQtAbstractSlider.CreateWidget(const AParams: TCreateParams): QWidgetH;
8648 var
8649   Parent: QWidgetH;
8650 begin
8651   // Creates the widget
8652   {$ifdef VerboseQt}
8653     WriteLn('TQtAbstractSlider.Create');
8654   {$endif}
8655 
8656   FSliderPressed := False;
8657   FSliderReleased:= False;
8658 
8659   if AParams.WndParent <> 0 then
8660     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8661   else
8662     Parent := nil;
8663   Result := QAbstractSlider_create(Parent);
8664 end;
8665 
8666 procedure TQtAbstractSlider.AttachEvents;
8667 begin
8668   inherited AttachEvents;
8669   FRangeChangedHook := QAbstractSlider_hook_create(Widget);
8670   FSliderMovedHook :=  QAbstractSlider_hook_create(Widget);
8671   FSliderPressedHook := QAbstractSlider_hook_create(Widget);
8672   FSliderReleasedHook := QAbstractSlider_hook_create(Widget);
8673   FValueChangedHook := QAbstractSlider_hook_create(Widget);
8674   FActionTriggeredHook := QAbstractSlider_hook_create(Widget);
8675 end;
8676 
8677 procedure TQtAbstractSlider.DetachEvents;
8678 begin
8679   if FRangeChangedHook <> nil then
8680   begin
8681     QAbstractSlider_hook_destroy(FRangeChangedHook);
8682     FRangeChangedHook := nil;
8683   end;
8684   if FSliderMovedHook <> nil then
8685   begin
8686     QAbstractSlider_hook_destroy(FSliderMovedHook);
8687     FSliderMovedHook := nil;
8688   end;
8689   if FSliderPressedHook <> nil then
8690   begin
8691     QAbstractSlider_hook_destroy(FSliderPressedHook);
8692     FSliderPressedHook := nil;
8693   end;
8694   if FSliderReleasedHook <> nil then
8695   begin
8696     QAbstractSlider_hook_destroy(FSliderReleasedHook);
8697     FSliderReleasedHook := nil;
8698   end;
8699   if FValueChangedHook <> nil then
8700   begin
8701     QAbstractSlider_hook_destroy(FValueChangedHook);
8702     FValueChangedHook := nil;
8703   end;
8704   if FActionTriggeredHook <> nil then
8705   begin
8706     QAbstractSlider_hook_destroy(FActionTriggeredHook);
8707     FActionTriggeredHook := nil;
8708   end;
8709   inherited DetachEvents;
8710 end;
8711 
getValuenull8712 function TQtAbstractSlider.getValue: Integer;
8713 begin
8714   Result := QAbstractSlider_value(QAbstractSliderH(Widget));
8715 end;
8716 
getPageStepnull8717 function TQtAbstractSlider.getPageStep: Integer;
8718 begin
8719   Result := QAbstractSlider_pageStep(QAbstractSliderH(Widget));
8720 end;
8721 
getMinnull8722 function TQtAbstractSlider.getMin: Integer;
8723 begin
8724   Result := QAbstractSlider_minimum(QAbstractSliderH(Widget));
8725 end;
8726 
TQtAbstractSlider.getMaxnull8727 function TQtAbstractSlider.getMax: Integer;
8728 begin
8729   Result := QAbstractSlider_maximum(QAbstractSliderH(Widget));
8730 end;
8731 
TQtAbstractSlider.getSingleStepnull8732 function TQtAbstractSlider.getSingleStep: Integer;
8733 begin
8734   Result := QAbstractSlider_singleStep(QAbstractSliderH(Widget));
8735 end;
8736 
getSliderDownnull8737 function TQtAbstractSlider.getSliderDown: Boolean;
8738 begin
8739   Result := QAbstractSlider_isSliderDown(QAbstractSliderH(Widget));
8740 end;
8741 
getSliderPositionnull8742 function TQtAbstractSlider.getSliderPosition: Integer;
8743 begin
8744   Result := QAbstractSlider_sliderPosition(QAbstractSliderH(Widget));
8745 end;
8746 
getTrackingnull8747 function TQtAbstractSlider.getTracking: Boolean;
8748 begin
8749   Result := QAbstractSlider_hasTracking(QAbstractSliderH(Widget));
8750 end;
8751 
8752 {------------------------------------------------------------------------------
8753   Function: TQtAbstractSlider.rangeChanged
8754   Params:  minimum,maximum: Integer
8755   Returns: Nothing
8756  ------------------------------------------------------------------------------}
8757 procedure TQtAbstractSlider.SlotRangeChanged(minimum: Integer; maximum: Integer); cdecl;
8758 begin
8759   { TODO: find out what needs to be done on rangeChanged event
8760     Possibilities: repaint or recount pageSize() }
8761   {$ifdef VerboseQt}
8762   writeln('TQtAbstractSlider.rangeChanged() to min=',minimum,' max=',maximum);
8763   {$endif}
8764 end;
8765 
8766 {------------------------------------------------------------------------------
8767   Function: TQtAbstractSlider.setInvertedAppereance
8768   Params:  p1: Boolean
8769   Returns: Nothing
8770  ------------------------------------------------------------------------------}
8771 procedure TQtAbstractSlider.setInvertedAppereance(p1: Boolean);
8772 begin
8773   QAbstractSlider_setInvertedAppearance(QAbstractSliderH(Widget), p1);
8774 end;
8775 
8776 {------------------------------------------------------------------------------
8777   Function: TQtAbstractSlider.setInvertedControls
8778   Params:  p1: Boolean
8779   Returns: Nothing
8780  ------------------------------------------------------------------------------}
8781 procedure TQtAbstractSlider.setInvertedControls(p1: Boolean);
8782 begin
8783   QAbstractSlider_setInvertedControls(QAbstractSliderH(Widget), p1);
8784 end;
8785 
8786 {------------------------------------------------------------------------------
8787   Function: TQtAbstractSlider.setMaximum
8788   Params:  p1: Integer
8789   Returns: Nothing
8790  ------------------------------------------------------------------------------}
8791 procedure TQtAbstractSlider.setMaximum(p1: Integer);
8792 begin
8793   QAbstractSlider_setMaximum(QAbstractSliderH(Widget), p1);
8794 end;
8795 
8796 {------------------------------------------------------------------------------
8797   Function: TQtAbstractSlider.setMinimum
8798   Params:  p1: Integer
8799   Returns: Nothing
8800  ------------------------------------------------------------------------------}
8801 procedure TQtAbstractSlider.setMinimum(p1: Integer);
8802 begin
8803   QAbstractSlider_setMinimum(QAbstractSliderH(Widget), p1);
8804 end;
8805 
8806 {------------------------------------------------------------------------------
8807   Function: TQtAbstractSlider.setOrientation
8808   Params:  p1: QtOrientation (QtHorizontal or QtVertical)
8809   Returns: Nothing
8810  ------------------------------------------------------------------------------}
8811 procedure TQtAbstractSlider.setOrientation(p1: QtOrientation);
8812 begin
8813   QAbstractSlider_setOrientation(QAbstractSliderH(Widget), p1);
8814 end;
8815 
8816 {------------------------------------------------------------------------------
8817   Function: TQtAbstractSlider.setPageStep
8818   Params:  p1: Integer
8819   Returns: Nothing
8820  ------------------------------------------------------------------------------}
8821 procedure TQtAbstractSlider.setPageStep(p1: Integer);
8822 begin
8823   QAbstractSlider_setPageStep(QAbstractSliderH(Widget), p1);
8824 end;
8825 
8826 {------------------------------------------------------------------------------
8827   Function: TQtAbstractSlider.setRange
8828   Params:  minimum,maximum: Integer
8829   Returns: Nothing
8830  ------------------------------------------------------------------------------}
8831 procedure TQtAbstractSlider.setRange(minimum: Integer; maximum: Integer);
8832 begin
8833   QAbstractSlider_setRange(QAbstractSliderH(Widget), minimum, maximum);
8834 end;
8835 
8836 {------------------------------------------------------------------------------
8837   Function: TQtAbstractSlider.setSingleStep
8838   Params:  p1: Integer
8839   Returns: Nothing
8840  ------------------------------------------------------------------------------}
8841 procedure TQtAbstractSlider.setSingleStep(p1: Integer);
8842 begin
8843   QAbstractSlider_setSingleStep(QAbstractSliderH(Widget), p1);
8844 end;
8845 
8846 {------------------------------------------------------------------------------
8847   Function: TQtAbstractSlider.setSliderDown
8848   Params:  p1: Boolean
8849   Returns: Nothing
8850  ------------------------------------------------------------------------------}
8851 procedure TQtAbstractSlider.setSliderDown(p1: Boolean);
8852 begin
8853   QAbstractSlider_setSliderDown(QAbstractSliderH(Widget), p1);
8854 end;
8855 
8856 
8857 {------------------------------------------------------------------------------
8858   Function: TQtAbstractSlider.setSliderPosition
8859   Params:  p1: Integer
8860   Returns: Nothing
8861  ------------------------------------------------------------------------------}
8862 procedure TQtAbstractSlider.setSliderPosition(p1: Integer);
8863 begin
8864   QAbstractSlider_setSliderPosition(QAbstractSliderH(Widget), p1);
8865 end;
8866 
8867 {------------------------------------------------------------------------------
8868   Function: TQtAbstractSlider.setTracking
8869   Params:  p1: Boolean
8870   Returns: Nothing
8871  ------------------------------------------------------------------------------}
8872 procedure TQtAbstractSlider.setTracking(p1: Boolean);
8873 begin
8874   QAbstractSlider_setTracking(QAbstractSliderH(Widget), p1);
8875 end;
8876 
8877 {-----------------------------------------------------------------------------
8878   Function: TQtAbstractSlider.setValue
8879   Params:  p1: Integer
8880   Returns: Nothing
8881  ------------------------------------------------------------------------------}
8882 procedure TQtAbstractSlider.setValue(p1: Integer);
8883 begin
8884   QAbstractSlider_setValue(QAbstractSliderH(Widget), p1);
8885 end;
8886 
8887 procedure TQtAbstractSlider.SlotSliderMoved(p1: Integer); cdecl;
8888 begin
8889  {$ifdef VerboseQt}
8890   writeln('TQtAbstractSlider.sliderMoved() to pos=',p1);
8891  {$endif}
8892 
8893  // there's no need to deliver this message
8894  // since ValueChanged does it's job correct, also for tracking on/off
8895  // this signal must stay empty because of ttrackbar !
8896 end;
8897 
8898 procedure TQtAbstractSlider.SlotSliderPressed; cdecl;
8899 begin
8900   {$ifdef VerboseQt}
8901    writeln('TQtAbstractSlider.sliderPressed()');
8902   {$endif}
8903   FSliderPressed := True;
8904   FSliderReleased := False;
8905 end;
8906 
8907 procedure TQtAbstractSlider.SlotSliderReleased; cdecl;
8908 begin
8909   {$ifdef VerboseQt}
8910    writeln('TQtAbstractSlider.sliderReleased()');
8911   {$endif}
8912   FSliderPressed := False;
8913   FSliderReleased := True;
8914 end;
8915 
CanChangeFontColornull8916 function TQtAbstractSlider.CanChangeFontColor: Boolean;
8917 begin
8918   Result := False;
8919 end;
8920 
getInvertedAppereancenull8921 function TQtAbstractSlider.getInvertedAppereance: Boolean;
8922 begin
8923   Result := QAbstractSlider_invertedAppearance(QAbstractSliderH(Widget));
8924 end;
8925 
getInvertedControlsnull8926 function TQtAbstractSlider.getInvertedControls: Boolean;
8927 begin
8928   Result := QAbstractSlider_invertedControls(QAbstractSliderH(Widget));
8929 end;
8930 
getOrientationnull8931 function TQtAbstractSlider.getOrientation: QtOrientation;
8932 begin
8933   Result := QAbstractSlider_orientation(QAbstractSliderH(Widget));
8934 end;
8935 
8936 procedure TQtAbstractSlider.SlotValueChanged(p1: Integer); cdecl;
8937 var
8938   LMScroll: TLMScroll;
8939   b: Boolean;
8940 begin
8941   {$ifdef VerboseQt}
8942   writeln('TQtAbstractSlider.SlotValueChanged() to value ',p1,' inUpdate ',inUpdate,' maxIs ',getMax,
8943   ' FChildOfComplexWidget ',FChildOfComplexWidget);
8944   {$endif}
8945 
8946   FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
8947 
8948   LMScroll.ScrollBar := PtrUInt(Self);
8949 
8950   if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
8951     LMScroll.Msg := LM_HSCROLL
8952   else
8953     LMScroll.Msg := LM_VSCROLL;
8954 
8955   LMScroll.Pos := p1;
8956   LMScroll.ScrollCode := SIF_POS;
8957 
8958   if not InUpdate then
8959     DeliverMessage(LMScroll);
8960 
8961   b := p1 = getMax;
8962 
8963   if not InUpdate or (getVisible and ((p1=getMin) or b)) then
8964   begin
8965     if b and (FChildOfComplexWidget = ccwAbstractScrollArea) and
8966       not InUpdate and getVisible then
8967         QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
8968           QAbstractSliderSliderToMaximum);
8969   end;
8970 end;
8971 
8972 procedure TQtAbstractSlider.SlotActionTriggered(action: Integer); cdecl;
8973 const
8974   SliderActions: Array[0..7] of QAbstractSliderSliderAction = (
8975     QAbstractSliderSliderNoAction, QAbstractSliderSliderSingleStepAdd,
8976     QAbstractSliderSliderSingleStepSub, QAbstractSliderSliderPageStepAdd,
8977     QAbstractSliderSliderPageStepSub, QAbstractSliderSliderToMinimum,
8978     QAbstractSliderSliderToMaximum, QAbstractSliderSliderMove );
8979 var
8980   LMScroll: TLMScroll;
8981   SliderAction: QAbstractSliderSliderAction;
8982 begin
8983 
8984   if InUpdate then
8985     exit;
8986 
8987   {$ifdef VerboseQt}
8988   writeln('TQtAbstractSlider.SlotActionTriggered() action = ',action,' inUpdate ',inUpdate);
8989   {$endif}
8990 
8991   FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
8992 
8993   LMScroll.ScrollBar := PtrUInt(Self);
8994 
8995   if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
8996     LMScroll.Msg := LM_HSCROLL
8997   else
8998     LMScroll.Msg := LM_VSCROLL;
8999 
9000   if SliderPressed then
9001     LMScroll.Pos := getSliderPosition
9002   else
9003     LMScroll.Pos := getValue;
9004 
9005   SliderAction := SliderActions[Action];
9006 
9007   case SliderAction of
9008     QAbstractSliderSliderNoAction:
9009     begin
9010       // this is called from mouse release while qt still thinks that
9011       // slider is pressed, we must update position.issue #14728, #21610
9012       if getSliderDown then
9013       begin
9014         LMScroll.ScrollCode := SB_THUMBPOSITION;
9015         DeliverMessage(LMScroll);
9016       end;
9017       LMScroll.ScrollCode := SB_ENDSCROLL;
9018     end;
9019     QAbstractSliderSliderSingleStepAdd:
9020       begin
9021         if LMScroll.Msg = LM_HSCROLL then
9022           LMScroll.ScrollCode := SB_LINERIGHT
9023         else
9024           LMScroll.ScrollCode := SB_LINEDOWN;
9025       end;
9026     QAbstractSliderSliderSingleStepSub:
9027       begin
9028         if LMScroll.Msg = LM_HSCROLL then
9029           LMScroll.ScrollCode := SB_LINELEFT
9030         else
9031           LMScroll.ScrollCode := SB_LINEUP;
9032       end;
9033     QAbstractSliderSliderPageStepAdd:
9034       begin
9035         if LMScroll.Msg = LM_HSCROLL then
9036           LMScroll.ScrollCode := SB_PAGERIGHT
9037         else
9038           LMScroll.ScrollCode := SB_PAGEDOWN;
9039       end;
9040     QAbstractSliderSliderPageStepSub:
9041       begin
9042         if LMScroll.Msg = LM_HSCROLL then
9043           LMScroll.ScrollCode := SB_PAGELEFT
9044         else
9045           LMScroll.ScrollCode := SB_PAGEUP;
9046       end;
9047     QAbstractSliderSliderToMinimum:
9048       begin
9049         if LMScroll.Msg = LM_HSCROLL then
9050           LMScroll.ScrollCode := SB_LEFT
9051         else
9052           LMScroll.ScrollCode := SB_TOP;
9053       end;
9054     QAbstractSliderSliderToMaximum:
9055       begin
9056         // issue #21610
9057         // if we are reaching maximum with eg. mouse wheel
9058         // and our parent is TScrollingWinControl then update thumbposition.
9059         if not getSliderDown then
9060         begin
9061           LMScroll.ScrollCode := SB_THUMBPOSITION;
9062           DeliverMessage(LMScroll);
9063         end;
9064 
9065         if LMScroll.Msg = LM_HSCROLL then
9066           LMScroll.ScrollCode := SB_RIGHT
9067         else
9068           LMScroll.ScrollCode := SB_BOTTOM;
9069       end;
9070     QAbstractSliderSliderMove:
9071       begin
9072         if getTracking then
9073           LMScroll.ScrollCode := SB_THUMBTRACK
9074         else
9075         if not getSliderDown then
9076           LMScroll.ScrollCode := SB_THUMBPOSITION;
9077       end;
9078   end;
9079 
9080   DeliverMessage(LMScroll);
9081 end;
9082 
9083 { TQtScrollBar }
9084 
TQtScrollBar.CreateWidgetnull9085 function TQtScrollBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
9086 var
9087   Parent: QWidgetH;
9088 begin
9089   // Creates the widget
9090   {$ifdef VerboseQt}
9091     WriteLn('TQtScrollBar.Create');
9092   {$endif}
9093   if AParams.WndParent <> 0 then
9094     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9095   else
9096     Parent := nil;
9097   FTrackPos := 0;
9098   Result := QScrollBar_create(Parent);
9099   QWidget_setFocusPolicy(Result, QtNoFocus);
9100   FHasPaint := True;
9101 end;
9102 
9103 procedure TQtScrollBar.preferredSize(var PreferredWidth,
9104   PreferredHeight: integer; WithThemeSpace: Boolean);
9105 var
9106   Size: TSize;
9107 begin
9108   QScrollBar_sizeHint(QScrollBarH(Widget), @Size);
9109   PreferredWidth := Size.cx;
9110   PreferredHeight := Size.cy;
9111 end;
9112 
9113 procedure TQtScrollBar.setFocusPolicy(const APolicy: QtFocusPolicy);
9114 begin
9115   if FOwnWidget and Assigned(LCLObject) and not LCLObject.TabStop then
9116     inherited setFocusPolicy(QtNoFocus)
9117   else
9118     inherited setFocusPolicy(APolicy);
9119 end;
9120 
9121 procedure TQtScrollBar.SlotSliderReleased; cdecl;
9122 var
9123   AValue: Integer;
9124   LMScroll: TLMScroll;
9125 begin
9126   inherited SlotSliderReleased;
9127   if
9128   {$IFDEF QTSCROLLABLEFORMS}
9129    ((ChildOfComplexWidget = ccwAbstractScrollArea) and (FOwner <> nil) and
9130     (FOwner is TQtWindowArea)) or
9131   {$ENDIF}
9132    ((ChildOfComplexWidget = ccwAbstractScrollArea) and (FOwner <> nil) and
9133     (FOwner.ChildOfComplexWidget in [ccwCustomControl])) then
9134   begin
9135     AValue := getValue;
9136     if AValue <= getMin then
9137       QAbstractSlider_triggerAction(QAbstractSliderH(Widget), QAbstractSliderSliderToMinimum)
9138     else
9139     if AValue >= getMax then
9140       QAbstractSlider_triggerAction(QAbstractSliderH(Widget), QAbstractSliderSliderToMaximum)
9141     else
9142     begin
9143       FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
9144 
9145       LMScroll.ScrollBar := PtrUInt(Self);
9146 
9147       if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
9148         LMScroll.Msg := LM_HSCROLL
9149       else
9150         LMScroll.Msg := LM_VSCROLL;
9151 
9152       LMScroll.Pos := getSliderPosition;
9153       if not GetTracking then
9154         LMScroll.ScrollCode := SB_THUMBPOSITION
9155       else
9156         LMScroll.ScrollCode := SB_THUMBTRACK;
9157       DeliverMessage(LMScroll);
9158     end;
9159   end;
9160 end;
9161 
EventFilternull9162 function TQtScrollBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
9163   cdecl;
9164 begin
9165   Result := False;
9166   QEvent_accept(Event);
9167 
9168   if LCLObject = nil then
9169     exit;
9170 
9171   case QEvent_type(Event) of
9172     {if any of those events returs TRUE our scrollbar becomes invisible.}
9173     QEventMouseMove,
9174     QEventWheel,
9175     QEventPaint,
9176     QEventKeyPress,
9177     QEventKeyRelease:
9178     begin
9179       if FOwnWidget and (FOwner = nil) and
9180         ((QEvent_type(Event) = QEventKeyPress) or
9181         (QEvent_type(Event) = QEventKeyRelease)) then
9182         Result := inherited EventFilter(Sender, Event)
9183       else
9184       if (QEvent_type(Event) = QEventWheel) and Assigned(FOwner) and
9185         (
9186         (FOwner is TQtAbstractScrollArea)
9187         ) then
9188       begin
9189 
9190         // issue #25992
9191         if not getVisible then
9192           Result := FOwner.SlotMouseWheel(FOwner.Widget, Event)
9193         else
9194         begin
9195           // issue #27675.Do not send wheel event from cbox when dropped down.
9196           // LCL thinks that combobox sent that event so we have undesirable effects.
9197           if (FOwner.ChildOfComplexWidget = ccwComboBox) and getEnabled then
9198             Result := False
9199           else
9200             Result := inherited EventFilter(Sender, Event);
9201         end;
9202         // do not scroll when disabled or issue #25992
9203         if not getEnabled then
9204           Result := True
9205         else
9206         if not getVisible then
9207         begin
9208           if {$IFDEF QTSCROLLABLEFORMS}(FOwner is TQtWindowArea) or {$ENDIF}
9209            (FOwner.ChildOfComplexWidget in
9210            [ccwScrollingWinControl, ccwScrollingWindow]) then
9211             Result := True;
9212         end;
9213       end else
9214         Result := False;
9215       if (QEvent_type(Event) = QEventKeyRelease) and not
9216         (QKeyEvent_isAutoRepeat(QKeyEventH(event))) then
9217         begin
9218           case QKeyEvent_key(QKeyEventH(Event)) of
9219             QtKey_Left, QtKey_Up, QtKey_Right, QtKey_Down,
9220             QtKey_PageUp, QtKey_PageDown, QtKey_Home, QtKey_End:
9221               QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
9222                        QAbstractSliderSliderNoAction);
9223           end;
9224         end;
9225     end;
9226 
9227     QEventMouseButtonRelease:
9228       QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
9229                         QAbstractSliderSliderNoAction);
9230   else
9231     if FOwnWidget then
9232       Result := inherited EventFilter(Sender, Event);
9233   end;
9234 end;
9235 
9236 procedure TQtScrollBar.AttachEvents;
9237 begin
9238   inherited AttachEvents;
9239   QAbstractSlider_hook_hook_rangeChanged(FRangeChangedHook, @SlotRangeChanged);
9240 
9241   QAbstractSlider_hook_hook_sliderMoved(FSliderMovedHook, @SlotSliderMoved);
9242 
9243   QAbstractSlider_hook_hook_sliderPressed(FSliderPressedHook, @SlotSliderPressed);
9244 
9245   QAbstractSlider_hook_hook_sliderReleased(FSliderReleasedHook, @SlotSliderReleased);
9246 
9247   QAbstractSlider_hook_hook_valueChanged(FValueChangedHook, @SlotValueChanged);
9248 
9249   QAbstractSlider_hook_hook_actionTriggered(FActionTriggeredHook, @SlotActionTriggered);
9250 end;
9251 
9252 { TQtToolBar }
9253 
TQtToolBar.CreateWidgetnull9254 function TQtToolBar.CreateWidget(const AParams: TCreateParams):QWidgetH;
9255 var
9256   Parent: QWidgetH;
9257 begin
9258   // Creates the widget
9259   {$ifdef VerboseQt}
9260     WriteLn('TQtToolBar.Create');
9261   {$endif}
9262   if AParams.WndParent <> 0 then
9263     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9264   else
9265     Parent := nil;
9266   Result := QToolBar_create(Parent);
9267 end;
9268 
9269 { TQtToolButton }
9270 
CreateWidgetnull9271 function TQtToolButton.CreateWidget(const AParams: TCreateParams):QWidgetH;
9272 var
9273   Parent: QWidgetH;
9274 begin
9275   // Creates the widget
9276   {$ifdef VerboseQt}
9277     WriteLn('TQtToolButton.Create');
9278   {$endif}
9279   if AParams.WndParent <> 0 then
9280     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9281   else
9282     Parent := nil;
9283   Result := QToolButton_create(Parent);
9284 end;
9285 
9286 { TQtTrackBar }
9287 
TQtTrackBar.CreateWidgetnull9288 function TQtTrackBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
9289 var
9290   Parent: QWidgetH;
9291 begin
9292   // Creates the widget
9293   {$ifdef VerboseQt}
9294     WriteLn('TQtTrackBar.Create');
9295   {$endif}
9296   if AParams.WndParent <> 0 then
9297     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9298   else
9299     Parent := nil;
9300   Result := QSlider_create(Parent);
9301 end;
9302 
TQtTrackBar.getTickIntervalnull9303 function TQtTrackBar.getTickInterval: Integer;
9304 begin
9305   Result := QSlider_tickInterval(QSliderH(Widget));
9306 end;
9307 
9308 {------------------------------------------------------------------------------
9309   Function: TQtTrackBar.setTickPosition
9310   Params:  Value: QSliderTickPosition
9311   Returns: Nothing
9312  ------------------------------------------------------------------------------ }
9313 procedure TQtTrackBar.setTickPosition(Value: QSliderTickPosition);
9314 begin
9315   QSlider_setTickPosition(QSliderH(Widget), Value);
9316 end;
9317 
9318 {------------------------------------------------------------------------------
9319   Function: TQtTrackBar.setTickInterval
9320   Params:  Value: Integer
9321   Returns: Nothing
9322  ------------------------------------------------------------------------------ }
9323 procedure TQtTrackBar.SetTickInterval(Value: Integer);
9324 begin
9325   QSlider_setTickInterval(QSliderH(Widget), Value);
9326 end;
9327 
9328 procedure TQtTrackBar.AttachEvents;
9329 begin
9330   inherited AttachEvents;
9331 
9332   QAbstractSlider_hook_hook_sliderMoved(FSliderMovedHook, @SlotSliderMoved);
9333 
9334   QAbstractSlider_hook_hook_sliderPressed(FSliderPressedHook, @SlotSliderPressed);
9335 
9336   QAbstractSlider_hook_hook_sliderReleased(FSliderReleasedHook, @SlotSliderReleased);
9337 
9338   QAbstractSlider_hook_hook_valueChanged(FValueChangedHook, @SlotValueChanged);
9339 end;
9340 
9341 procedure TQtTrackBar.SlotSliderMoved(p1: Integer); cdecl;
9342 var
9343   Msg: TLMessage;
9344 begin
9345  {$ifdef VerboseQt}
9346   writeln('TQtTrackBar.SlotSliderMoved() p1=',p1);
9347  {$endif}
9348   if SliderPressed and not InUpdate then
9349   begin
9350     Msg.Msg := 0; // shutup compiler
9351     FillChar(Msg, SizeOf(Msg), #0);
9352     Msg.Msg := LM_CHANGED;
9353     DeliverMessage(Msg);
9354   end;
9355 end;
9356 
9357 procedure TQtTrackBar.SlotValueChanged(p1: Integer); cdecl;
9358 var
9359   Msg: TLMessage;
9360 begin
9361  {$ifdef VerboseQt}
9362   writeln('TQtTrackBar.SlotValueChanged() p1=',p1);
9363  {$endif}
9364 
9365   if not SliderPressed and not InUpdate then
9366   begin
9367     FillChar(Msg{%H-}, SizeOf(Msg), #0);
9368     Msg.Msg := LM_CHANGED;
9369     DeliverMessage(Msg);
9370   end;
9371 end;
9372 
9373 { TQtLineEdit }
9374 
TQtLineEdit.CreateWidgetnull9375 function TQtLineEdit.CreateWidget(const AParams: TCreateParams): QWidgetH;
9376 var
9377   Parent: QWidgetH;
9378 begin
9379   FCachedSelectionStart := -1;
9380   FCachedSelectionLen := -1;
9381   FIntValidator := nil;
9382   FNumbersOnly := False;
9383   if AParams.WndParent <> 0 then
9384     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9385   else
9386     Parent := nil;
9387   Result := QLineEdit_create(Parent);
9388 end;
9389 
getAlignmentnull9390 function TQtLineEdit.getAlignment: QtAlignment;
9391 begin
9392   Result := QLineEdit_alignment(QLineEditH(Widget));
9393 end;
9394 
getCursorPositionnull9395 function TQtLineEdit.getCursorPosition: TPoint;
9396 begin
9397   Result.Y := 0;
9398   Result.X := QLineEdit_cursorPosition(QLineEditH(Widget));
9399 end;
9400 
TQtLineEdit.getMaxLengthnull9401 function TQtLineEdit.getMaxLength: Integer;
9402 begin
9403   Result := QLineEdit_maxLength(QLineEditH(Widget));
9404 end;
9405 
getSelectedTextnull9406 function TQtLineEdit.getSelectedText: WideString;
9407 begin
9408   Result := '';
9409   QLineEdit_selectedText(QLineEditH(Widget), @Result);
9410 end;
9411 
getSelectionStartnull9412 function TQtLineEdit.getSelectionStart: Integer;
9413 begin
9414   if hasSelectedText then
9415     Result := QLineEdit_selectionStart(QLineEditH(Widget))
9416   else
9417   begin
9418     if (CachedSelectionStart <> -1) and not hasFocus then
9419       Result := CachedSelectionStart
9420     else
9421       Result := getCursorPosition.X;
9422   end;
9423 end;
9424 
getSelectionLengthnull9425 function TQtLineEdit.getSelectionLength: Integer;
9426 var
9427   W: WideString;
9428 begin
9429   if hasSelectedText then
9430   begin
9431     W := getSelectedText;
9432     Result := UTF16Length(W);
9433   end else
9434   begin
9435     if (CachedSelectionStart <> -1) and (CachedSelectionLen <> -1) then
9436       Result := CachedSelectionLen
9437     else
9438       Result := 0;
9439   end;
9440 end;
9441 
TQtLineEdit.getTextnull9442 function TQtLineEdit.getText: WideString;
9443 begin
9444   Result := '';
9445   QLineEdit_text(QLineEditH(Widget), @Result);
9446 end;
9447 
getTextMarginsnull9448 function TQtLineEdit.getTextMargins: TRect;
9449 var
9450   L, T, R, B: Integer;
9451 begin
9452   QLineEdit_getTextMargins(QLineEditH(Widget), @L, @T, @R, @B);
9453   Result := Rect(L, T, R, B);
9454 end;
9455 
9456 procedure TQtLineEdit.SetNumbersOnly(AValue: boolean);
9457 begin
9458   if FNumbersOnly=AValue then Exit;
9459   FNumbersOnly:=AValue;
9460   if Assigned(FIntValidator) then
9461   begin
9462     QLineEdit_setValidator(QLineEditH(Widget), nil);
9463     QIntValidator_destroy(FIntValidator);
9464     FIntValidator := nil;
9465   end;
9466   if FNumbersOnly then
9467   begin
9468     FIntValidator := QIntValidator_create(0, MAXINT, Widget);
9469     QLineEdit_setValidator(QLineEditH(Widget), FIntValidator);
9470   end;
9471 end;
9472 
getTextStaticnull9473 function TQtLineEdit.getTextStatic: Boolean;
9474 begin
9475   Result := False;
9476 end;
9477 
TQtLineEdit.isUndoAvailablenull9478 function TQtLineEdit.isUndoAvailable: Boolean;
9479 begin
9480   Result := QLineEdit_isUndoAvailable(QLineEditH(Widget));
9481 end;
9482 
hasSelectedTextnull9483 function TQtLineEdit.hasSelectedText: Boolean;
9484 begin
9485   Result := QLineEdit_hasSelectedText(QLineEditH(Widget));
9486 end;
9487 
9488 procedure TQtLineEdit.selectAll;
9489 begin
9490   QLineEdit_selectAll(QLineEditH(Widget));
9491 end;
9492 
9493 procedure TQtLineEdit.setAlignment(const AAlignment: QtAlignment);
9494 begin
9495   QLineEdit_setAlignment(QLineEditH(Widget), AAlignment);
9496 end;
9497 
9498 procedure TQtLineEdit.setBorder(const ABorder: Boolean);
9499 begin
9500   QLineEdit_setFrame(QLineEditH(Widget), ABorder);
9501 end;
9502 
9503 procedure TQtLineEdit.AttachEvents;
9504 begin
9505   inherited AttachEvents;
9506 
9507   FTextChanged := QLineEdit_hook_create(Widget);
9508   QLineEdit_hook_hook_textChanged(FTextChanged, @SignalTextChanged);
9509 end;
9510 
9511 procedure TQtLineEdit.DetachEvents;
9512 begin
9513   if FTextChanged <> nil then
9514   begin
9515     QLineEdit_hook_destroy(FTextChanged);
9516     FTextChanged := nil;
9517   end;
9518   inherited DetachEvents;
9519 end;
9520 
TQtLineEdit.EventFilternull9521 function TQtLineEdit.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
9522   cdecl;
9523 begin
9524   Result := False;
9525   QEvent_accept(Event);
9526   if LCLObject = nil then
9527     exit;
9528 
9529   if (QEvent_type(Event) = QEventFocusOut) then
9530   begin
9531     CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(Widget));
9532     CachedSelectionLen := UTF16Length(getSelectedText);
9533   end else
9534   if (QEvent_type(Event) = QEventFocusIn) then
9535   begin
9536     CachedSelectionStart := -1;
9537     CachedSelectionLen := -1;
9538   end;
9539 
9540   if (ChildOfComplexWidget = ccwComboBox) and (QEvent_type(Event) = QEventMove) then
9541     exit;
9542 
9543   if (ChildOfComplexWidget = ccwComboBox) and
9544     ((QEvent_type(Event) = QEventPaint) or (QEvent_type(Event) = QEventResize))
9545     and (LCLObject.HandleAllocated) then
9546   begin
9547     Result := TQtComboBox(LCLObject.Handle).InUpdate or
9548       (csDesigning in LCLObject.ComponentState);
9549     if (QEvent_type(Event) = QEventPaint) and (csDesigning in LCLObject.ComponentState) then
9550       QObject_event(Sender, Event);
9551     if Result then
9552       QEvent_ignore(Event)
9553     else
9554     begin
9555       // issue #26040
9556       if (QEvent_type(Event) = QEventResize) then
9557         LCLObject.DoAdjustClientRectChange
9558       else
9559         Result:=inherited EventFilter(Sender, Event);
9560     end;
9561   end else
9562     Result:=inherited EventFilter(Sender, Event);
9563 end;
9564 
9565 procedure TQtLineEdit.preferredSize(var PreferredWidth,
9566   PreferredHeight: integer; WithThemeSpace: Boolean);
9567 var
9568   Size: TSize;
9569 begin
9570   QLineEdit_sizeHint(QLineEditH(Widget), @Size);
9571   PreferredHeight := Size.cy;
9572   PreferredWidth := Size.cx;
9573 end;
9574 
9575 procedure TQtLineEdit.setCursorPosition(const ACursorPosition: Integer);
9576 begin
9577   QLineEdit_setCursorPosition(QLineEditH(Widget), ACursorPosition);
9578 end;
9579 
9580 procedure TQtLineEdit.setDefaultColorRoles;
9581 begin
9582   WidgetColorRole := QPaletteBase;
9583   TextColorRole := QPaletteText;
9584 end;
9585 
9586 procedure TQtLineEdit.setEchoMode(const AMode: QLineEditEchoMode);
9587 begin
9588   QLineEdit_setEchoMode(QLineEditH(Widget), AMode);
9589 end;
9590 
9591 procedure TQtLineEdit.setInputMask(const AMask: WideString);
9592 begin
9593   QLineEdit_setInputMask(QLineEditH(Widget), @AMask);
9594 end;
9595 
9596 procedure TQtLineEdit.setMaxLength(const ALength: Integer);
9597 begin
9598   QLineEdit_setMaxLength(QLineEditH(Widget), ALength);
9599 end;
9600 
9601 procedure TQtLineEdit.setReadOnly(const AReadOnly: Boolean);
9602 begin
9603   QLineEdit_setReadOnly(QLineEditH(Widget), AReadOnly);
9604 end;
9605 
9606 procedure TQtLineEdit.setSelection(const AStart, ALength: Integer);
9607 begin
9608   if AStart >= 0 then
9609   begin
9610     if ALength > 0 then
9611       QLineEdit_setSelection(QLineEditH(Widget), AStart, ALength)
9612     else
9613       setCursorPosition(AStart);
9614   end;
9615 end;
9616 
9617 procedure TQtLineEdit.setText(const AText: WideString);
9618 begin
9619   QLineEdit_setText(QLineEditH(Widget), @AText);
9620   if not getEnabled then
9621     setSelection(0, 0);
9622 end;
9623 
9624 procedure TQtLineEdit.setTextHint(const ATextHint: string);
9625 var
9626   W: WideString;
9627 begin
9628   W := UTF8ToUTF16(ATextHint);
9629   QLineEdit_setPlaceholderText(QLineEditH(Widget), @W);
9630 end;
9631 
9632 procedure TQtLineEdit.setTextMargins(ARect: TRect);
9633 begin
9634   with ARect do
9635     QLineEdit_setTextMargins(QLineEditH(Widget), Left, Top, Right, Bottom);
9636 end;
9637 
9638 procedure TQtLineEdit.Cut;
9639 begin
9640   QLineEdit_cut(QLineEditH(Widget));
9641 end;
9642 
9643 procedure TQtLineEdit.Copy;
9644 begin
9645   QLineEdit_copy(QLineEditH(Widget));
9646 end;
9647 
9648 procedure TQtLineEdit.Paste;
9649 begin
9650   QLineEdit_paste(QLineEditH(Widget));
9651 end;
9652 
9653 procedure TQtLineEdit.Undo;
9654 begin
9655   QLineEdit_undo(QLineEditH(Widget));
9656 end;
9657 
9658 destructor TQtLineEdit.Destroy;
9659 begin
9660   if Assigned(FIntValidator) then
9661   begin
9662     QIntValidator_destroy(FIntValidator);
9663     FIntValidator := nil;
9664   end;
9665   inherited Destroy;
9666 end;
9667 
9668 {------------------------------------------------------------------------------
9669   Function: TQtLineEdit.SignalTextChanged
9670   Params:  PWideString
9671   Returns: Nothing
9672 
9673   Fires OnChange() event of TCustomEdit
9674  ------------------------------------------------------------------------------}
9675 procedure TQtLineEdit.SignalTextChanged(p1: PWideString); cdecl;
9676 var
9677   Msg: TLMessage;
9678 begin
9679   FillChar(Msg{%H-}, SizeOf(Msg), #0);
9680   Msg.Msg := CM_TEXTCHANGED;
9681   DeliverMessage(Msg);
9682 end;
9683 
9684 { TQtTextEdit }
9685 
GetAcceptRichTextnull9686 function TQtTextEdit.GetAcceptRichText: Boolean;
9687 begin
9688   Result := QTextEdit_acceptRichText(QTextEditH(Widget));
9689 end;
9690 
9691 procedure TQtTextEdit.SetAcceptRichText(AValue: Boolean);
9692 begin
9693   QTextEdit_setAcceptRichText(QTextEditH(Widget), AValue);
9694 end;
9695 
TQtTextEdit.CreateWidgetnull9696 function TQtTextEdit.CreateWidget(const AParams: TCreateParams): QWidgetH;
9697 var
9698   Parent: QWidgetH;
9699 begin
9700   // Creates the widget
9701   {$ifdef VerboseQt}
9702     WriteLn('TQtTextEdit.Create');
9703   {$endif}
9704   if AParams.WndParent <> 0 then
9705     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9706   else
9707     Parent := nil;
9708   Result := QTextEdit_create(Parent);
9709   FKeysToEat := [];
9710   FUndoAvailable := False;
9711   {drops are handled by slotDropFiles()}
9712   QWidget_setAcceptDrops(Result, False);
9713 end;
9714 
9715 procedure TQtTextEdit.Append(const AStr: WideString);
9716 begin
9717   QTextEdit_append(QTextEditH(Widget), @AStr);
9718 end;
9719 
9720 procedure TQtTextEdit.ClearText;
9721 begin
9722   QTextEdit_clear(QTextEditH(Widget));
9723 end;
9724 
getAlignmentnull9725 function TQtTextEdit.getAlignment: QtAlignment;
9726 begin
9727   Result := QTextEdit_alignment(QTextEditH(Widget));
9728 end;
9729 
getBlockCountnull9730 function TQtTextEdit.getBlockCount: Integer;
9731 begin
9732   Result := QTextDocument_blockCount(QTextEdit_document(QTextEditH(Widget)));
9733 end;
9734 
getCursorPositionnull9735 function TQtTextEdit.getCursorPosition: TPoint;
9736 var
9737   TextCursor: QTextCursorH;
9738 begin
9739   TextCursor := QTextCursor_create();
9740   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9741   if QTextCursor_isNull(TextCursor) then
9742     Result := Point(0, 0)
9743   else
9744   begin
9745     Result.X := QTextCursor_positionInBlock(TextCursor);
9746     Result.Y := QTextCursor_blockNumber(TextCursor);
9747   end;
9748   QTextCursor_destroy(TextCursor);
9749 end;
9750 
getMaxLengthnull9751 function TQtTextEdit.getMaxLength: Integer;
9752 begin
9753   {$note implement TQtTextEdit.getMaxLength}
9754   Result := 0;
9755 end;
9756 
TQtTextEdit.getTextnull9757 function TQtTextEdit.getText: WideString;
9758 begin
9759   Result := '';
9760   QTextEdit_toPlainText(QTextEditH(Widget), @Result);
9761 end;
9762 
getTextStaticnull9763 function TQtTextEdit.getTextStatic: Boolean;
9764 begin
9765   Result := False;
9766 end;
9767 
getSelectionStartnull9768 function TQtTextEdit.getSelectionStart: Integer;
9769 var
9770   TextCursor: QTextCursorH;
9771 begin
9772   TextCursor := QTextCursor_create();
9773   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9774   Result := QTextCursor_selectionStart(TextCursor);
9775   QTextCursor_destroy(TextCursor);
9776 end;
9777 
TQtTextEdit.getSelectionEndnull9778 function TQtTextEdit.getSelectionEnd: Integer;
9779 var
9780   TextCursor: QTextCursorH;
9781 begin
9782   TextCursor := QTextCursor_create();
9783   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9784   Result := QTextCursor_selectionEnd(TextCursor);
9785   QTextCursor_destroy(TextCursor);
9786 end;
9787 
getSelectionLengthnull9788 function TQtTextEdit.getSelectionLength: Integer;
9789 begin
9790   Result := getSelectionEnd - getSelectionStart;
9791 end;
9792 
TQtTextEdit.isUndoAvailablenull9793 function TQtTextEdit.isUndoAvailable: Boolean;
9794 begin
9795   Result := QTextEdit_isUndoRedoEnabled(QTextEditH(Widget)) and FUndoAvailable;
9796 end;
9797 
9798 procedure TQtTextEdit.setEchoMode(const AMode: QLineEditEchoMode);
9799 begin
9800   {$note implement TQtTextEdit.setEchoMode}
9801 end;
9802 
9803 procedure TQtTextEdit.setLineWrapMode(const AMode: QTextEditLineWrapMode);
9804 begin
9805   QTextEdit_setLineWrapMode(QTextEditH(Widget), AMode);
9806 end;
9807 
9808 procedure TQtTextEdit.setMaxLength(const ALength: Integer);
9809 begin
9810   {$note implement TQtTextEdit.setMaxLength}
9811 end;
9812 
9813 procedure TQtTextEdit.appendLine(AText: WideString);
9814 var
9815   QtCursor: QTextCursorH;
9816   WrapMode: QTextEditLineWrapMode;
9817 begin
9818   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
9819   {we must remove wrapping to get correct line !}
9820   setLineWrapMode(QTextEditNoWrap);
9821   QtCursor := QTextCursor_create();
9822   try
9823     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
9824     QTextCursor_beginEditBlock(QtCursor);
9825     QTextCursor_movePosition(QtCursor, QTextCursorEnd,
9826         QTextCursorMoveAnchor, 1);
9827     QTextCursor_insertBlock(QtCursor);
9828     QTextCursor_insertText(QtCursor, @AText);
9829     QTextCursor_endEditBlock(QtCursor);
9830   finally
9831     QTextCursor_destroy(QtCursor);
9832     setLineWrapMode(WrapMode);
9833   end;
9834 end;
9835 
9836 procedure TQtTextEdit.insertLine(const AIndex: integer; AText: WideString);
9837 var
9838   QtCursor: QTextCursorH;
9839   WrapMode: QTextEditLineWrapMode;
9840 begin
9841   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
9842   {we must remove wrapping to get correct line !}
9843   setLineWrapMode(QTextEditNoWrap);
9844   QtCursor := QTextCursor_create();
9845   try
9846     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
9847     QTextCursor_beginEditBlock(QtCursor);
9848     // QTextCursor slowness
9849     // https://bugreports.qt-project.org/browse/QTBUG-3554
9850     // differentiate append vs. insert issue #22715
9851     // added check for AIndex. issue #29670
9852     if (AIndex > 0) and (AIndex >= FList.Count - 1) then
9853     begin
9854       QTextCursor_movePosition(QtCursor, QTextCursorEnd,
9855         QTextCursorMoveAnchor, 1);
9856       QTextCursor_insertBlock(QtCursor);
9857     end else
9858     begin
9859       QTextCursor_movePosition(QtCursor, QTextCursorStart,
9860         QTextCursorMoveAnchor, 1);
9861       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
9862         QTextCursorMoveAnchor, 1);
9863     end;
9864 
9865     QTextCursor_movePosition(QtCursor, QTextCursorDown,
9866       QTextCursorMoveAnchor, AIndex);
9867     // QTextCursor slowness
9868     // https://bugreports.qt-project.org/browse/QTBUG-3554
9869     // differentiate append vs. insert issue #22715
9870     if AIndex < FList.Count - 1 then
9871     begin
9872       QTextCursor_insertBlock(QtCursor);
9873       QTextCursor_movePosition(QtCursor, QTextCursorUp,
9874         QTextCursorMoveAnchor, 1);
9875     end;
9876     QTextCursor_insertText(QtCursor, @AText);
9877     QTextCursor_endEditBlock(QtCursor);
9878   finally
9879     QTextCursor_destroy(QtCursor);
9880     setLineWrapMode(WrapMode);
9881   end;
9882 end;
9883 
9884 procedure TQtTextEdit.removeLine(const AIndex: integer);
9885 var
9886   QtCursor: QTextCursorH;
9887   B: Boolean;
9888   WrapMode: QTextEditLineWrapMode;
9889   Diff: Integer;
9890 begin
9891   Diff := getBlockCount - AIndex;
9892   {we must remove wrapping to get correct line !}
9893   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
9894   setLineWrapMode(QTextEditNoWrap);
9895   QtCursor := QTextCursor_create();
9896   try
9897     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
9898     QTextCursor_beginEditBlock(QtCursor);
9899     // small optimization if we delete from end of list
9900     if Diff <= 2 then
9901     begin
9902       QTextCursor_movePosition(QtCursor, QTextCursorEnd,
9903         QTextCursorMoveAnchor, 1);
9904       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
9905         QTextCursorMoveAnchor, 1);
9906       QTextCursor_movePosition(QtCursor, QTextCursorUp,
9907         QTextCursorMoveAnchor, Diff - 1);
9908     end else
9909     begin
9910       QTextCursor_movePosition(QtCursor, QTextCursorStart,
9911         QTextCursorMoveAnchor, 1);
9912       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
9913         QTextCursorMoveAnchor, 1);
9914       QTextCursor_movePosition(QtCursor, QTextCursorDown,
9915         QTextCursorMoveAnchor, AIndex);
9916       QTextCursor_movePosition(QtCursor, QTextCursorEndOfLine,
9917         QTextCursorMoveAnchor, 1);
9918     end;
9919 
9920     QTextCursor_select(QtCursor, QTextCursorLineUnderCursor);
9921     B := QTextCursor_hasSelection(QtCursor);
9922     if not B then
9923       QTextCursor_deleteChar(QtCursor)
9924     else
9925       QTextCursor_deletePreviousChar(QtCursor);
9926 
9927     if (AIndex = 0) then
9928     begin
9929       QTextCursor_movePosition(QtCursor, QTextCursorStart,
9930         QTextCursorMoveAnchor, 1);
9931       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
9932         QTextCursorMoveAnchor, 1);
9933       QTextCursor_movePosition(QtCursor, QTextCursorDown,
9934         QTextCursorMoveAnchor, 1);
9935     end;
9936     if B then
9937       QTextCursor_deletePreviousChar(QtCursor);
9938     QTextCursor_endEditBlock(QtCursor);
9939   finally
9940     QTextCursor_destroy(QtCursor);
9941     setLineWrapMode(WrapMode);
9942   end;
9943 end;
9944 
9945 procedure TQtTextEdit.setLineText(const AIndex: integer; AText: WideString);
9946 var
9947   QtCursor: QTextCursorH;
9948   WrapMode: QTextEditLineWrapMode;
9949 begin
9950   {we must remove wrapping to get correct line !}
9951   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
9952   setLineWrapMode(QTextEditNoWrap);
9953   QtCursor := QTextCursor_create();
9954   try
9955     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
9956     QTextCursor_beginEditBlock(QtCursor);
9957     QTextCursor_movePosition(QtCursor, QTextCursorStart,
9958       QTextCursorMoveAnchor, 1);
9959     QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
9960       QTextCursorMoveAnchor, 1);
9961     QTextCursor_movePosition(QtCursor, QTextCursorDown,
9962       QTextCursorMoveAnchor, AIndex);
9963     QTextCursor_select(QtCursor, QTextCursorLineUnderCursor);
9964     QTextCursor_removeSelectedText(QtCursor);
9965     QTextCursor_insertText(QtCursor, @AText);
9966     QTextCursor_movePosition(QtCursor, QTextCursorEndOfLine,
9967       QTextCursorMoveAnchor, 1);
9968     QTextCursor_endEditBlock(QtCursor);
9969   finally
9970     QTextCursor_destroy(QtCursor);
9971     setLineWrapMode(WrapMode);
9972   end;
9973 end;
9974 
9975 procedure TQtTextEdit.setText(const AText: WideString);
9976 begin
9977   QTextEdit_setPlainText(QTextEditH(Widget), @AText);
9978 end;
9979 
9980 procedure TQtTextEdit.setTextHint(const ATextHint: string);
9981 var
9982   W: WideString;
9983 begin
9984   W := UTF8ToUTF16(ATextHint);
9985   QTextEdit_setPlaceholderText(QTextEditH(Widget), @W);
9986 end;
9987 
9988 procedure TQtTextEdit.setReadOnly(const AReadOnly: Boolean);
9989 begin
9990   QTextEdit_setReadOnly(QTextEditH(Widget), AReadOnly);
9991 end;
9992 
9993 procedure TQtTextEdit.setSelection(const AStart, ALength: Integer);
9994 var
9995   TextCursor: QTextCursorH;
9996   maxPosition: Integer;
9997   doc: QTextDocumentH;
9998 begin
9999   if AStart >= 0 then
10000   begin
10001     TextCursor := QTextCursor_create();
10002     QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
10003 
10004     doc := QTextCursor_document(Textcursor);
10005     maxPosition := QTextDocument_characterCount(doc) - 1;
10006 
10007     QTextCursor_clearSelection(TextCursor);
10008     QTextCursor_setPosition(TextCursor, Min(AStart, maxPosition));
10009     QTextCursor_setPosition(TextCursor, Min(AStart + ALength, maxPosition), QTextCursorKeepAnchor);
10010 
10011     QTextEdit_setTextCursor(QTextEditH(Widget), TextCursor);
10012     QTextCursor_destroy(TextCursor);
10013   end;
10014 end;
10015 
10016 procedure TQtTextEdit.setTabChangesFocus(const AValue: Boolean);
10017 begin
10018   QTextEdit_setTabChangesFocus(QTextEditH(Widget), AValue);
10019 end;
10020 
10021 procedure TQtTextEdit.Cut;
10022 begin
10023   QTextEdit_cut(QTextEditH(Widget));
10024 end;
10025 
10026 procedure TQtTextEdit.Copy;
10027 begin
10028   QTextEdit_copy(QTextEditH(Widget));
10029 end;
10030 
10031 procedure TQtTextEdit.Paste;
10032 begin
10033   QTextEdit_paste(QTextEditH(Widget));
10034 end;
10035 
10036 procedure TQtTextEdit.Undo;
10037 begin
10038   QTextEdit_undo(QTextEditH(Widget));
10039 end;
10040 
10041 procedure TQtTextEdit.setAlignment(const AAlignment: QtAlignment);
10042 var
10043   TextCursor: QTextCursorH;
10044 begin
10045   // QTextEdit supports alignment for every paragraph. We need to align all text.
10046   // So, we should select all text, set format, and clear selection
10047 
10048   // 1. Select all text
10049   QTextEdit_selectAll(QTextEditH(Widget));
10050 
10051   // 2. Set format
10052   QTextEdit_setAlignment(QTextEditH(Widget), AAlignment);
10053 
10054   // 3. Clear selection. To unselect all document we must create new text cursor,
10055   // get format from Text Edit, clear selection in cursor and set it back to Text Edit
10056   TextCursor := QTextCursor_create();
10057   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
10058   QTextCursor_clearSelection(TextCursor);
10059   QTextEdit_setTextCursor(QTextEditH(Widget), TextCursor);
10060   QTextCursor_destroy(TextCursor);
10061 end;
10062 
10063 procedure TQtTextEdit.setBorder(const ABorder: Boolean);
10064 begin
10065   if ABorder then
10066     QFrame_setFrameShape(QFrameH(Widget), QFrameStyledPanel)
10067   else
10068     QFrame_setFrameShape(QFrameH(Widget), QFrameNoFrame);
10069 end;
10070 
10071 procedure TQtTextEdit.setCursorPosition(const ACursorPosition: Integer);
10072 var
10073   TextCursor: QTextCursorH;
10074 begin
10075   TextCursor := QTextCursor_create();
10076   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
10077   if not QTextCursor_isNull(TextCursor) then
10078     QTextCursor_setPosition(TextCursor, ACursorPosition);
10079   QTextCursor_destroy(TextCursor);
10080 end;
10081 
10082 procedure TQtTextEdit.setDefaultColorRoles;
10083 begin
10084   WidgetColorRole := QPaletteBase;
10085   TextColorRole := QPaletteText;
10086 end;
10087 
10088 procedure TQtTextEdit.AttachEvents;
10089 begin
10090   inherited AttachEvents;
10091 
10092   FUndoAvailableHook := QTextEdit_hook_create(Widget);
10093   QTextEdit_hook_hook_undoAvailable(FUndoAvailableHook, @SignalUndoAvailable);
10094 
10095   FTextChangedHook := QTextEdit_hook_create(Widget);
10096   QTextEdit_hook_hook_textChanged(FTextChangedHook, @SignalTextChanged);
10097 
10098   FViewportEventHook := QObject_hook_create(viewportWidget);
10099   QObject_hook_hook_events(FViewportEventHook, @viewportEventFilter);
10100   // initialize scrollbars
10101   verticalScrollBar;
10102   horizontalScrollBar;
10103 end;
10104 
10105 procedure TQtTextEdit.DetachEvents;
10106 begin
10107   if FUndoAvailableHook <> nil then
10108   begin
10109     QTextEdit_hook_destroy(FUndoAvailableHook);
10110     FUndoAvailableHook := nil;
10111   end;
10112 
10113   if FTextChangedHook <> nil then
10114   begin
10115     QTextEdit_hook_destroy(FTextChangedHook);
10116     FTextChangedHook := nil;
10117   end;
10118 
10119   if FViewportEventHook <> nil then
10120   begin
10121     QObject_hook_destroy(FViewportEventHook);
10122     FViewportEventHook := nil;
10123   end;
10124   inherited DetachEvents;
10125 end;
10126 
TQtTextEdit.viewportEventFilternull10127 function TQtTextEdit.viewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
10128 begin
10129   Result := False;
10130   QEvent_accept(Event);
10131   case QEvent_type(Event) of
10132     QEventContextMenu: Result := SlotContextMenu(Sender, Event);
10133     QEventMouseButtonPress,
10134     QEventMouseButtonRelease,
10135     QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
10136     QEventMouseMove: Result := SlotMouseMove(Sender, Event);
10137   end;
10138 end;
10139 
getContextMenuPolicynull10140 function TQtTextEdit.getContextMenuPolicy: QtContextMenuPolicy;
10141 begin
10142   Result := QWidget_contextMenuPolicy(viewPortWidget);
10143 end;
10144 
10145 procedure TQtTextEdit.setContextMenuPolicy(const AValue: QtContextMenuPolicy);
10146 begin
10147   QWidget_setContextMenuPolicy(viewportWidget, AValue);
10148 end;
10149 
10150 procedure TQtTextEdit.SignalUndoAvailable(b: Boolean); cdecl;
10151 begin
10152   FUndoAvailable := b;
10153 end;
10154 
10155 procedure TQtTextEdit.SignalTextChanged(); cdecl;
10156 var
10157   Mess: TLMessage;
10158 begin
10159   if (LCLObject = nil) or not GetVisible then
10160     exit;
10161   if Assigned(FList) then
10162     TQtMemoStrings(FList).TextChanged := True;
10163   if not InUpdate then
10164   begin
10165     FillChar(Mess{%H-}, SizeOf(Mess), #0);
10166     Mess.Msg := CM_TEXTCHANGED;
10167     DeliverMessage(Mess);
10168   end;
10169 end;
10170 
10171 { TQtTabBar }
10172 
10173 procedure TQtTabBar.AttachEvents;
10174 begin
10175   inherited AttachEvents;
10176   FTabBarChangedHook := QTabBar_hook_create(QTabBarH(Widget));
10177   FTabBarMovedHook := QTabBar_hook_create(QTabBarH(Widget));
10178   QTabBar_hook_hook_currentChanged(FTabBarChangedHook, @SignalTabBarCurrentChanged);
10179   QTabBar_hook_hook_tabMoved(FTabBarMovedHook, @SignalTabBarMoved);
10180 end;
10181 
10182 procedure TQtTabBar.DetachEvents;
10183 begin
10184   if FTabBarMovedHook <> nil then
10185   begin
10186     QTabBar_hook_destroy(FTabBarMovedHook);
10187     FTabBarMovedHook := nil;
10188   end;
10189   if FTabBarChangedHook <> nil then
10190   begin
10191     QTabBar_hook_destroy(FTabBarChangedHook);
10192     FTabBarChangedHook := nil;
10193   end;
10194   inherited DetachEvents;
10195 end;
10196 
GetTabRectnull10197 function TQtTabBar.GetTabRect(const AIndex: integer): TRect;
10198 var
10199   Pt: TPoint;
10200 begin
10201   QTabBar_tabRect(QTabBarH(Widget), @Result, AIndex);
10202   if Assigned(FOwner) then
10203   begin
10204     Pt := TabBarOffset;
10205     OffsetRect(Result, Pt.X, Pt.Y);
10206   end;
10207 end;
10208 
TabBarOffsetnull10209 function TQtTabBar.TabBarOffset: TPoint;
10210 var
10211   R: TRect;
10212 begin
10213   Result := Point(0, 0);
10214   if Assigned(FOwner) then
10215   begin
10216     QWidget_geometry(Widget, @R);
10217     case TQtTabWidget(FOwner).getTabPosition of
10218       QTabWidgetNorth,
10219       QTabWidgetSouth:
10220         begin
10221           if R.Left < 0 then
10222             R.Left := 0;
10223           // issue #28591
10224           if QWidget_layoutDirection(Widget) = QtRightToLeft then
10225             Result.X := 0
10226           else
10227             Result.X := R.Left;
10228         end;
10229       QTabWidgetEast,
10230       QTabWidgetWest:
10231         begin
10232           if R.Top < 0 then
10233             R.Top := 0;
10234           Result.Y := R.Top;
10235         end;
10236     end;
10237   end;
10238 end;
10239 
10240 procedure TQtTabBar.SignalTabBarMoved(fromIndex: integer; toIndex: Integer);
10241   cdecl;
10242 var
10243   ANewIndex: Integer;
10244 begin
10245   if LCLObject = nil then
10246     Exit;
10247   // DebugLn('TQtTabBar.SignalTabBarMoved From=',dbgs(fromIndex),' to ',dbgs(toIndex),' FSavedIndexOnPageChanging=',dbgs(FSavedIndexOnPageChanging));
10248   if Assigned(FOwner) and not (FOwner.ChildOfComplexWidget = ccwTTabControl) then
10249   begin
10250     ANewIndex := TQtTabWidget(FOwner).GetLCLPageIndex(toIndex);
10251     TQtTabWidget(FOwner).setCurrentWidget(TQtWidget(TCustomTabControl(LCLObject).Page[ANewIndex].Handle), True);
10252   end;
10253 end;
10254 
10255 procedure TQtTabBar.SignalTabBarCurrentChanged(Index: Integer); cdecl;
10256 var
10257   Msg: TLMNotify;
10258   Hdr: TNmHdr;
10259 begin
10260   if LCLObject = nil then
10261     Exit;
10262 
10263   if TQtTabWidget(LCLObject.Handle).InUpdate then
10264     exit;
10265   FillChar(Msg{%H-}, SizeOf(Msg), 0);
10266   Msg.Msg := LM_NOTIFY;
10267   FillChar(Hdr{%H-}, SizeOf(Hdr), 0);
10268 
10269   Hdr.hwndFrom := LCLObject.Handle;
10270   Hdr.Code := TCN_SELCHANGE;
10271   Hdr.idFrom := PtrUInt(TQtTabWidget(LCLObject.Handle).GetLCLPageIndex(Index));
10272   Msg.NMHdr := @Hdr;
10273   Msg.Result := 0;
10274   if FSavedIndexOnPageChanging = Forbid_TCN_SELCHANGE then
10275     FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE
10276   else
10277     DeliverMessage(Msg);
10278 end;
10279 
SlotTabBarMousenull10280 function TQtTabBar.SlotTabBarMouse(Sender: QObjectH; Event: QEventH): Boolean;
10281   cdecl;
10282 var
10283   MousePos, AGlobalPos: TQtPoint;
10284   APosF, AGlobalPosF: TQtPointF;
10285   NewEvent: QMouseEventH;
10286   R: TRect;
10287   R1: TRect;
10288   BaseHeight: Integer;
10289   ForcedMouseGrab: Boolean;
10290 begin
10291   Result := False;
10292 
10293   if not CanSendLCLMessage then
10294     exit;
10295 
10296   // MousePos :=
10297   QMouseEvent_pos(QMouseEventH(Event), @MousePos);
10298 
10299   if Assigned(FOwner) then
10300   begin
10301     R := TQtTabWidget(FOwner).getGeometry;
10302     R1 := getGeometry;
10303     BaseHeight := GetPixelMetric(QStylePM_TabBarBaseHeight, nil, nil);
10304 
10305     case TQtTabWidget(FOwner).getTabPosition of
10306       QTabWidgetNorth:
10307         begin
10308           MousePos.Y := R.Top - (R1.Bottom - MousePos.Y);
10309           MousePos.X := MousePos.X - BaseHeight;
10310         end;
10311       QTabWidgetWest:
10312         begin
10313           MousePos.x := R.Left - (R1.Right - MousePos.X);
10314           MousePos.y := MousePos.Y - BaseHeight;
10315         end;
10316       QTabWidgetEast:
10317         begin
10318           MousePos.X := R1.Left + MousePos.X - BaseHeight;
10319           MousePos.y := MousePos.Y - BaseHeight;
10320         end;
10321       QTabWidgetSouth:
10322         begin
10323           MousePos.Y := R1.Top + MousePos.Y - BaseHeight;
10324           MousePos.X := MousePos.X - BaseHeight;
10325         end;
10326     end;
10327     QMouseEvent_globalPos(QMouseEventH(Event), @AGlobalPos);
10328     APosF.X := MousePos.X;
10329     APosF.Y := MousePos.Y;
10330     AGlobalPosF.X := AGlobalPos.X;
10331     AGlobalPosF.Y := AGlobalPos.Y;
10332     NewEvent := QMouseEvent_create(QEvent_type(Event), @APosF,
10333         @AGlobalPosF,
10334         QMouseEvent_button(QMouseEventH(Event)),
10335         QMouseEvent_buttons(QMouseEventH(Event)),
10336         QInputEvent_modifiers(QInputEventH(Event))
10337       );
10338 
10339     ForcedMouseGrab := False;
10340     if QEvent_type(Event) = QEventMouseButtonPress then
10341       ForcedMouseGrab := not ((QWidget_mouseGrabber = Widget) or
10342         (Assigned(FOwner) and (QWidget_mouseGrabber = FOwner.Widget)));
10343 
10344     SlotMouse(Sender, NewEvent);
10345     QMouseEvent_destroy(NewEvent);
10346 
10347     ForcedMouseGrab := ForcedMouseGrab and
10348         (Assigned(FOwner) and (QWidget_mouseGrabber = FOwner.Widget));
10349 
10350     if ForcedMouseGrab then
10351       QWidget_grabMouse(Widget);
10352 
10353   end else
10354     SlotMouse(Sender, Event);
10355 end;
10356 
TQtTabBar.EventFilternull10357 function TQtTabBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
10358 
StopShortcutEventnull10359   function StopShortcutEvent: boolean;
10360   begin
10361     Result := Assigned(FOwner) and (FOwner.ChildOfComplexWidget <> ccwTTabControl) and
10362       not TQtTabWidget(FOwner).FSwitchTabsByKeyboard and (QKeyEvent_matches(QKeyEventH(Event), QKeySequenceNextChild) or
10363       QKeyEvent_matches(QKeyEventH(Event), QKeySequencePreviousChild));
10364   end;
10365 
10366 {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10367 var
10368   R: TRect;
10369 {$ENDIF}
10370 begin
10371   Result := False;
10372   QEvent_accept(Event);
10373   if LCLObject = nil then
10374     exit;
10375   {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
10376   WriteLn('TQtTabBar.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
10377     ' LCLObject=', dbgsName(LCLObject),
10378     ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
10379   {$endif}
10380 
10381   BeginEventProcessing;
10382   try
10383     case QEvent_type(Event) of
10384       {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10385       QEventPaint:
10386         begin
10387           QPaintEvent_rect(QPaintEventH(Event), @R);
10388           // qt paints tab
10389           QObject_event(Sender, Event);
10390           // LCL can do whatever now
10391           SlotPaint(Sender, Event);
10392           Result := True;
10393           QEvent_ignore(Event);
10394         end;
10395       {$ENDIF}
10396       QEventShortcutOverride: Result := StopShortcutEvent;
10397       QEventKeyPress,
10398       QEventKeyRelease:
10399       begin
10400         if (QEvent_type(Event) = QEventKeyPress) then
10401           FSavedIndexOnPageChanging := QTabBar_currentIndex(QTabBarH(Widget));
10402         SlotKey(Sender, Event);
10403         if (LCLObject = nil) or
10404           ((LCLObject <> nil) and not LCLObject.HandleAllocated) then
10405           Result := True;
10406         if not Result then
10407           Result := StopShortcutEvent;
10408       end;
10409       QEventMouseButtonPress,
10410       QEventMouseButtonRelease,
10411       QEventMouseButtonDblClick:
10412         begin
10413           if QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton then
10414           begin
10415             if (QEvent_type(Event) = QEventMouseButtonPress) then
10416               FSavedIndexOnPageChanging := QTabBar_currentIndex(QTabBarH(Widget));
10417             Result := SlotTabBarMouse(Sender, Event);
10418             if (LCLObject = nil) or
10419               ((LCLObject <> nil) and not LCLObject.HandleAllocated) then
10420               Result := True
10421             else
10422               SetNoMousePropagation(QWidgetH(Sender), False);
10423           end;
10424         end;
10425     else
10426       QEvent_ignore(Event);
10427     end;
10428   finally
10429     EndEventProcessing;
10430   end;
10431 end;
10432 
10433 procedure TQtTabBar.SetTabFontColor(AIndex: Integer; AColor: TQColor);
10434 begin
10435   QTabBar_setTabTextColor(QTabBarH(Widget), AIndex, @AColor);
10436 end;
10437 
10438 { TQtTabWidget }
10439 
getTabBarnull10440 function TQtTabWidget.getTabBar: TQtTabBar;
10441 begin
10442   if FTabBar = nil then
10443   begin
10444     {$note TQtTabWidget.getTabBar: we can remove QLCLTabWidget, and get it like StackWidget,
10445      objectName is qt_tabwidget_tabbar.}
10446     FTabBar := TQtTabBar.CreateFrom(LCLObject, QLCLTabWidget_tabBarHandle(QTabWidgetH(Widget)));
10447     {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10448     FTabBar.HasPaint := True;
10449     {$ENDIF}
10450     FTabBar.FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE;
10451     FTabBar.FOwner := Self;
10452     FTabBar.AttachEvents;
10453   end;
10454   Result := FTabBar;
10455 end;
10456 
getShowTabsnull10457 function TQtTabWidget.getShowTabs: Boolean;
10458 begin
10459   Result := TabBar.getVisible;
10460 end;
10461 
getStackWidgetnull10462 function TQtTabWidget.getStackWidget: QWidgetH;
10463 var
10464   List: TPtrIntArray;
10465   Obj: QObjectH;
10466   i: Integer;
10467   WStr: WideString;
10468 begin
10469   if FStackWidget = nil then
10470   begin
10471     QObject_children(Widget, @List);
10472     for i := 0 to High(List) do
10473     begin
10474       Obj := QObjectH(List[i]);
10475       QObject_objectName(Obj, @WStr);
10476       {do not localize !}
10477       if WStr = 'qt_tabwidget_stackedwidget' then
10478       begin
10479         FStackWidget := QWidgetH(List[i]);
10480         break;
10481       end;
10482     end;
10483     FCentralWidget := FStackWidget;
10484   end;
10485   Result := FStackWidget;
10486 end;
10487 
10488 procedure TQtTabWidget.setShowTabs(const AValue: Boolean);
10489 begin
10490   TabBar.setVisible(AValue);
10491 end;
10492 
CreateWidgetnull10493 function TQtTabWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
10494 var
10495   Parent: QWidgetH;
10496 begin
10497   // Creates the widget
10498   {$ifdef VerboseQt}
10499     WriteLn('TQtTabWidget.Create');
10500   {$endif}
10501   FSwitchTabsByKeyboard := False; {shortcuts are enabled by default under qt, but not under LCL}
10502   FWidgetNeedFontColorInitialization := True;
10503   if AParams.WndParent <> 0 then
10504     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
10505   else
10506     Parent := nil;
10507   Result := QTabWidget_create(Parent);
10508 
10509   {note: for some reason tabbar scroll buttons are not enabled as default option
10510   under mac - but under linux & win are. Qt docs says that this options is enabled
10511   as default ... possible qt bug}
10512   {$ifdef darwin}
10513   QTabWidget_setUsesScrollButtons(QTabWidgetH(Result), True);
10514   {$endif}
10515 end;
10516 
10517 destructor TQtTabWidget.Destroy;
10518 begin
10519   FTabBar.Free;
10520   inherited Destroy;
10521 end;
10522 
10523 procedure TQtTabWidget.DestroyNotify(AWidget: TQtWidget);
10524 begin
10525   if AWidget = FTabBar then
10526     FTabBar := nil;
10527   inherited DestroyNotify(AWidget);
10528 end;
10529 
GetLCLPageIndexnull10530 function TQtTabWidget.GetLCLPageIndex(AIndex: Integer): Integer;
10531 var
10532   I: Integer;
10533 begin
10534   Result := AIndex;
10535   if (LCLObject = nil) or
10536      (csDesigning in LCLObject.ComponentState) or
10537      not (LCLObject is TCustomTabControl) then
10538     Exit;
10539   I := 0;
10540   while (I < TCustomTabControl(LCLObject).PageCount) and (I <= Result) do
10541   begin
10542     if not TCustomTabControl(LCLObject).Page[I].TabVisible then
10543       Inc(Result);
10544     Inc(I);
10545   end;
10546 end;
10547 
10548 procedure TQtTabWidget.AttachEvents;
10549 begin
10550   inherited AttachEvents;
10551 
10552   {initialize our tabbar}
10553   TabBar;
10554 
10555   FCurrentChangedHook := QTabWidget_hook_create(Widget);
10556   QTabWidget_hook_hook_currentChanged(FCurrentChangedHook, @SignalCurrentChanged);
10557 
10558   FCloseRequestedHook := QTabWidget_hook_create(Widget);
10559   QTabWidget_hook_hook_tabCloseRequested(FCloseRequestedHook, @SignalCloseRequested);
10560 
10561   FStackedWidgetHook := QObject_hook_create(StackWidget);
10562   QObject_hook_hook_events(FStackedWidgetHook, @EventFilter);
10563 
10564 end;
10565 
10566 procedure TQtTabWidget.DetachEvents;
10567 begin
10568 
10569   if FStackedWidgetHook <> nil then
10570   begin
10571     QObject_hook_destroy(FStackedWidgetHook);
10572     FStackedWidgetHook := nil;
10573   end;
10574   if FCurrentChangedHook <> nil then
10575   begin
10576     QTabWidget_hook_destroy(FCurrentChangedHook);
10577     FCurrentChangedHook := nil;
10578   end;
10579   if FCloseRequestedHook <> nil then
10580   begin
10581     QTabWidget_hook_destroy(FCloseRequestedHook);
10582     FCloseRequestedHook := nil;
10583   end;
10584   inherited DetachEvents;
10585 end;
10586 
TQtTabWidget.EventFilternull10587 function TQtTabWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
10588   cdecl;
10589 var
10590 {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10591   R: TRect;
10592   TabGeom: TRect;
10593   Pt: TPoint;
10594 {$ENDIF}
10595   ALCLEvent: QLCLMessageEventH;
10596   ANewSize: TSize;
10597 begin
10598 
10599   Result := False;
10600   QEvent_accept(Event);
10601   if LCLObject = nil then
10602     exit;
10603 
10604   if (Sender = FStackWidget) then
10605   begin
10606     {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
10607     WriteLn('TQtTabWidget.EventFilter: STACKWIDGET Sender=', IntToHex(PtrUInt(Sender),8),
10608       ' LCLObject=', dbgsName(LCLObject),
10609       ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
10610     {$endif}
10611     {leave this for debugging purposes}
10612     exit;
10613   end;
10614 
10615   BeginEventProcessing;
10616   try
10617     case QEvent_type(Event) of
10618       QEventResize:
10619       begin
10620         ANewSize := QResizeEvent_size(QResizeEventH(Event))^;
10621         DelayResizeEvent(QWidgetH(Sender), ANewSize); // delay resize event since we are complex widget
10622       end;
10623       {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10624       QEventPaint:
10625         begin
10626           {this paint event comes after tabbar paint event,
10627            so we have to exclude our tabs from painting}
10628           QPaintEvent_rect(QPaintEventH(Event), @R);
10629           QWidget_geometry(TabBar.Widget, @TabGeom);
10630           Pt.X := R.Left;
10631           Pt.Y := R.Top;
10632           Result := PtInRect(TabGeom, Pt) and
10633             (R.Bottom - R.Top = TabGeom.Bottom - TabGeom.Top) and
10634             (TabAt(Pt) >= 0);
10635           if Result then
10636             QEvent_ignore(Event);
10637         end;
10638       {$ENDIF}
10639       LCLQt_DelayLayoutRequest:
10640       begin
10641         if LCLObject.ClientRectNeedsInterfaceUpdate then
10642         begin
10643           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
10644           DebugLn('<*><*> TQtTabWidget calling DoAdjustClientRectChange() from LCLQt_DelayLayoutRequest ...');
10645           {$ENDIF}
10646           LCLObject.DoAdjustClientRectChange(True);
10647         end;
10648         Result := True;
10649       end;
10650       QEventLayoutRequest:
10651       begin
10652         //behaviour is changed because of issue #21805.
10653         //we send delayed event so LCL can read clientRect at the right time.
10654         ALCLEvent := QLCLMessageEvent_create(LCLQt_DelayLayoutRequest, 0,
10655           0, 0, 0);
10656         QCoreApplication_postEvent(Sender, ALCLEvent);
10657       end;
10658       QEventKeyPress,
10659       QEventKeyRelease: QEvent_ignore(Event);
10660       QEventWheel:
10661         begin
10662           if not getEnabled then
10663             inherited EventFilter(Sender, Event)
10664           else
10665             QEvent_ignore(Event);
10666         end;
10667       else
10668         Result := inherited EventFilter(Sender, Event);
10669     end;
10670   finally
10671     EndEventProcessing;
10672   end;
10673 end;
10674 
10675 {------------------------------------------------------------------------------
10676   Function: TQtTabWidget.insertTab
10677   Params:  index: Integer; page: QWidgetH; p2: PWideString
10678   Returns: Nothing
10679  ------------------------------------------------------------------------------}
insertTabnull10680 function TQtTabWidget.insertTab(index: Integer; page: QWidgetH; p2: WideString): Integer; overload;
10681 begin
10682   Result := insertTab(index, page, nil, p2);
10683 end;
10684 
10685 {------------------------------------------------------------------------------
10686   Function: TQtTabWidget.insertTab
10687   Params:  index: Integer; page: QWidgetH; icon: QIconH; p2: PWideString
10688   Returns: Nothing
10689  ------------------------------------------------------------------------------}
insertTabnull10690 function TQtTabWidget.insertTab(index: Integer; page: QWidgetH; icon: QIconH; p2: WideString): Integer; overload;
10691 var
10692   UseAdd: Boolean;
10693 begin
10694   UseAdd := Index > getCount - 1;
10695   if icon <> nil then
10696   begin
10697     if UseAdd then
10698       Result := QTabWidget_addTab(QTabWidgetH(Widget), page, icon, @p2)
10699     else
10700       Result := QTabWidget_insertTab(QTabWidgetH(Widget), index, page, icon, @p2)
10701   end else
10702   begin
10703     if UseAdd then
10704       Result := QTabWidget_addTab(QTabWidgetH(Widget), page, @p2)
10705     else
10706       Result := QTabWidget_insertTab(QTabWidgetH(Widget), index, page, @p2);
10707   end;
10708 end;
10709 
TQtTabWidget.getCountnull10710 function TQtTabWidget.getCount: Integer;
10711 begin
10712   Result := QTabWidget_count(QTabWidgetH(Widget));
10713 end;
10714 
getClientBoundsnull10715 function TQtTabWidget.getClientBounds: TRect;
10716 begin
10717   QWidget_contentsRect(StackWidget, @Result);
10718 end;
10719 
getCurrentIndexnull10720 function TQtTabWidget.getCurrentIndex: Integer;
10721 begin
10722   Result := QTabWidget_currentIndex(QTabWidgetH(Widget));
10723 end;
10724 
getTabPositionnull10725 function TQtTabWidget.getTabPosition: QTabWidgetTabPosition;
10726 begin
10727   Result := QTabWidget_tabPosition(QTabWidgetH(Widget));
10728 end;
10729 
10730 procedure TQtTabWidget.removeTab(AIndex: Integer);
10731 begin
10732   QTabWidget_removeTab(QTabWidgetH(Widget), AIndex);
10733 end;
10734 
10735 procedure TQtTabWidget.setCurrentIndex(AIndex: Integer);
10736 begin
10737   QTabWidget_setCurrentIndex(QTabWidgetH(Widget), AIndex);
10738 end;
10739 
10740 procedure TQtTabWidget.setCurrentWidget(APage: TQtWidget; const AIsMoved: Boolean);
10741 begin
10742   QTabWidget_setCurrentWidget(QTabWidgetH(Widget), APage.Widget);
10743   if AIsMoved and (Assigned(LCLObject) and not (csDesigning in LCLObject.ComponentState)) then
10744     APage.setFocus;
10745 end;
10746 
10747 {------------------------------------------------------------------------------
10748   Function: TQtTabWidget.setTabPosition
10749   Params:  None
10750   Returns: Nothing
10751  ------------------------------------------------------------------------------}
10752 procedure TQtTabWidget.setTabPosition(ATabPosition: QTabWidgetTabPosition);
10753 begin
10754   QTabWidget_setTabPosition(QTabWidgetH(Widget), ATabPosition);
10755 end;
10756 
10757 procedure TQtTabWidget.setTabIcon(index: Integer; icon: QIconH);
10758 begin
10759   QTabWidget_setTabIcon(QTabWidgetH(Widget), index, icon);
10760 end;
10761 
10762 {------------------------------------------------------------------------------
10763   Function: TQtTabWidget.SignalCurrentChanged
10764   Params:  None
10765   Returns: Nothing
10766            Changes ActivePage of TPageControl
10767  ------------------------------------------------------------------------------}
10768 procedure TQtTabWidget.SignalCurrentChanged(Index: Integer); cdecl;
10769 var
10770   Msg: TLMNotify;
10771   Hdr: TNmHdr;
10772   i: Integer;
10773 begin
10774   if (LCLObject = nil) or InUpdate or not GetVisible then
10775   begin
10776     if TabBar.FSavedIndexOnPageChanging <> Forbid_TCN_SELCHANGE then
10777       TabBar.FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE;
10778     exit;
10779   end;
10780 
10781   FillChar(Msg{%H-}, SizeOf(Msg), 0);
10782   Msg.Msg := LM_NOTIFY;
10783   FillChar(Hdr{%H-}, SizeOf(Hdr), 0);
10784 
10785   Hdr.hwndFrom := LCLObject.Handle;
10786   Hdr.Code := TCN_SELCHANGING;
10787   Hdr.idFrom := PtrUInt(GetLCLPageIndex(Index));
10788   Msg.NMHdr := @Hdr;
10789   Msg.Result := 0;
10790   if (DeliverMessage(Msg) <> 0) and (Index >= 0) and
10791     (TabBar.FSavedIndexOnPageChanging >= 0) then
10792   begin
10793     BeginUpdate;
10794     try
10795       i := TabBar.FSavedIndexOnPageChanging;
10796       FTabBar.FSavedIndexOnPageChanging := Forbid_TCN_SELCHANGE;
10797       setCurrentIndex(i);
10798     finally
10799       EndUpdate;
10800     end;
10801   end;
10802 end;
10803 
10804 procedure TQtTabWidget.SignalCloseRequested(Index: Integer); cdecl;
10805 var
10806   APage: TCustomPage;
10807 begin
10808   APage := TCustomTabControl(LCLObject).Page[GetLCLPageIndex(Index)];
10809   if not APage.HandleAllocated then
10810     Exit;
10811   TCustomTabControl(LCLObject).DoCloseTabClicked(APage);
10812 end;
10813 
TQtTabWidget.indexOfnull10814 function TQtTabWidget.indexOf(const AWidget: QWidgetH): integer;
10815 begin
10816   Result := QTabWidget_indexOf(QTabWidgetH(Widget), AWidget);
10817 end;
10818 
10819 procedure TQtTabWidget.setTabText(index: Integer; p2: WideString);
10820 begin
10821   QTabWidget_setTabText(QTabWidgetH(Widget), index, @p2);
10822 end;
10823 
10824 procedure TQtTabWidget.setTabsClosable(AValue: Boolean);
10825 begin
10826   QTabWidget_setTabsClosable(QTabWidgetH(Widget), AValue);
10827 end;
10828 
tabAtnull10829 function TQtTabWidget.tabAt(APoint: TPoint): Integer;
10830 var
10831   AQtPoint: TQtPoint;
10832   R: TRect;
10833 begin
10834   if (APoint.Y < 0) or (APoint.X < 0) then
10835   begin
10836     {some themes (eg. MacOSX) moves tab buttons
10837      into the middle of parent, so we must
10838      take it's geometry into account.}
10839     R := TabBar.getGeometry;
10840     QWidget_pos(getStackWidget, @AQtPoint);
10841     AQtPoint.x := AQtPoint.x + APoint.x;
10842     AQtPoint.y := AQtPoint.y + APoint.y;
10843 
10844     if R.Left <> 0 then
10845       dec(AQtPoint.x, R.Left);
10846     if R.Top <> 0 then
10847       dec(AQtPoint.y, R.Top);
10848   end else
10849     AQtPoint := QtPoint(APoint.x, APoint.y);
10850   Result := QTabBar_tabAt(QTabBarH(TabBar.Widget), @AQtPoint);
10851 end;
10852 
10853 { TQtComboBox }
10854 
GetLineEditnull10855 function TQtComboBox.GetLineEdit: TQtLineEdit;
10856 begin
10857   if not getEditable then
10858   begin
10859     FLineEdit := nil
10860   end
10861   else
10862   begin
10863     if FLineEdit = nil then
10864     begin
10865       FLineEdit := TQtLineEdit.CreateFrom(LCLObject, QComboBox_lineEdit(QComboBoxH(Widget)));
10866       FLineEdit.FOwner := Self;
10867       QObject_disconnect(FLineEdit.Widget, '2returnPressed()', Widget, '1_q_returnPressed()');
10868       FLineEdit.ChildOfComplexWidget := ccwComboBox;
10869       FLineEdit.AttachEvents;
10870     end;
10871   end;
10872   Result := FLineEdit;
10873 end;
10874 
10875 procedure TQtComboBox.SetOwnerDrawn(const AValue: Boolean);
10876 begin
10877   FOwnerDrawn := AValue;
10878   if FDropList <> nil then
10879     FDropList.OwnerDrawn := FOwnerDrawn;
10880 end;
10881 
TQtComboBox.GetDropListnull10882 function TQtComboBox.GetDropList: TQtListWidget;
10883 begin
10884   if FDropList = nil then
10885   begin
10886     FDropList := TQtListWidget.CreateFrom(LCLObject, QListWidget_create());
10887     FDropList.FOwner := Self;
10888     FDropList.setAttribute(QtWA_NoMousePropagation, False);
10889     FDropList.OwnerDrawn := OwnerDrawn;
10890     FDropList.ChildOfComplexWidget := ccwComboBox;
10891     QComboBox_setModel(QComboBoxH(Widget), FDropList.getModel);
10892     QComboBox_setView(QComboBoxH(Widget), QListWidgetH(FDropList.Widget));
10893     FDropList.AttachEvents;
10894   end;
10895   Result := FDropList;
10896 end;
10897 
CreateWidgetnull10898 function TQtComboBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
10899 var
10900   Parent: QWidgetH;
10901 begin
10902   // Creates the widget
10903   {$ifdef VerboseQt}
10904     WriteLn('TQtComboBox.Create');
10905   {$endif}
10906   FKeyEnterFix := False; {issue #31574}
10907   FMouseFixPos := QtPoint(-1, -1);
10908   FDropListVisibleInternal := False;
10909   if AParams.WndParent <> 0 then
10910     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
10911   else
10912     Parent := nil;
10913   Result := QComboBox_create(Parent);
10914   // disable AutoCompletion. LCL has its own
10915   QComboBox_setAutoCompletion(QComboboxH(Result), False);
10916   FLineEdit := nil;
10917   FOwnerDrawn := False;
10918 end;
10919 
getCursorPositionnull10920 function TQtComboBox.getCursorPosition: TPoint;
10921 begin
10922   Result := Point(0, 0);
10923   if LineEdit <> nil then
10924     Result.X := LineEdit.getCursorPosition.X;
10925 end;
10926 
TQtComboBox.getMaxLengthnull10927 function TQtComboBox.getMaxLength: Integer;
10928 begin
10929   if LineEdit <> nil then
10930     Result := LineEdit.getMaxLength
10931   else
10932     Result := 0;
10933 end;
10934 
getSelectionStartnull10935 function TQtComboBox.getSelectionStart: Integer;
10936 begin
10937   if (LineEdit <> nil) then
10938     Result := LineEdit.getSelectionStart
10939   else
10940     Result := 0;
10941 end;
10942 
getSelectionLengthnull10943 function TQtComboBox.getSelectionLength: Integer;
10944 begin
10945   if (LineEdit <> nil) then
10946     Result := LineEdit.getSelectionLength
10947   else
10948     Result := 0;
10949 end;
10950 
TQtComboBox.isUndoAvailablenull10951 function TQtComboBox.isUndoAvailable: Boolean;
10952 begin
10953   if LineEdit <> nil then
10954     Result := LineEdit.isUndoAvailable
10955   else
10956     Result := False;
10957 end;
10958 
10959 procedure TQtComboBox.setBorder(const ABorder: Boolean);
10960 begin
10961   QComboBox_setFrame(QComboBoxH(Widget), ABorder);
10962 end;
10963 
10964 procedure TQtComboBox.setEchoMode(const AMode: QLineEditEchoMode);
10965 begin
10966   if LineEdit <> nil then
10967     LineEdit.setEchoMode(AMode);
10968 end;
10969 
10970 procedure TQtComboBox.setMaxLength(const ALength: Integer);
10971 begin
10972   if LineEdit <> nil then
10973     LineEdit.setMaxLength(ALength);
10974 end;
10975 
10976 procedure TQtComboBox.setReadOnly(const AReadOnly: Boolean);
10977 begin
10978   setEditable(not AReadOnly);
10979 end;
10980 
10981 procedure TQtComboBox.setSelection(const AStart, ALength: Integer);
10982 begin
10983   if LineEdit <> nil then
10984     LineEdit.setSelection(AStart, ALength);
10985 end;
10986 
10987 procedure TQtComboBox.setCursorPosition(const ACursorPosition: Integer);
10988 begin
10989   if LineEdit <> nil then
10990     LineEdit.setCursorPosition(ACursorPosition);
10991 end;
10992 
10993 procedure TQtComboBox.setTextHint(const ATextHint: string);
10994 begin
10995   if getEditable then
10996     LineEdit.setTextHint(ATextHint);
10997 end;
10998 
10999 procedure TQtComboBox.Cut;
11000 begin
11001   if LineEdit <> nil then
11002     LineEdit.Cut;
11003 end;
11004 
11005 procedure TQtComboBox.Copy;
11006 begin
11007   if LineEdit <> nil then
11008     LineEdit.Copy;
11009 end;
11010 
11011 procedure TQtComboBox.Paste;
11012 begin
11013   if LineEdit <> nil then
11014     LineEdit.Paste;
11015 end;
11016 
11017 procedure TQtComboBox.Undo;
11018 begin
11019   if LineEdit <> nil then
11020     LineEdit.Undo;
11021 end;
11022 
11023 {------------------------------------------------------------------------------
11024   Function: TQtComboBox.Destroy
11025   Params:  None
11026   Returns: Nothing
11027  ------------------------------------------------------------------------------}
11028 destructor TQtComboBox.Destroy;
11029 begin
11030   FDropList.Free;
11031   FLineEdit.Free;
11032   inherited Destroy;
11033 end;
11034 
11035 procedure TQtComboBox.DestroyNotify(AWidget: TQtWidget);
11036 begin
11037   if AWidget = FLineEdit then
11038     FLineEdit := nil;
11039   if AWidget = FDropList then
11040     FDropList := nil;
11041 
11042   if Assigned(FList) then
11043     FList := nil;
11044 
11045   inherited DestroyNotify(AWidget);
11046 end;
11047 
11048 procedure TQtComboBox.InternalIntfGetItems;
11049 begin
11050   TCustomComboBox(LCLObject).IntfGetItems;
11051   // because of issue #25032 we must call it here
11052   if getEnabled then
11053     SlotDropListVisibility(True);
11054 end;
11055 
11056 procedure TQtComboBox.ClearItems;
11057 begin
11058   QComboBox_clear(QComboBoxH(Widget));
11059 end;
11060 
11061 {------------------------------------------------------------------------------
11062   Function: TQtComboBox.currentIndex
11063   Params:  None
11064   Returns: Nothing
11065  ------------------------------------------------------------------------------}
TQtComboBox.currentIndexnull11066 function TQtComboBox.currentIndex: Integer;
11067 begin
11068   Result := QComboBox_currentIndex(QComboBoxH(Widget));
11069 end;
11070 
findTextnull11071 function TQtComboBox.findText(AText: WideString): Integer;
11072 begin
11073   Result := QComboBox_findText(QComboBoxH(Widget), @AText, QtMatchStartsWith);
11074 end;
11075 
TQtComboBox.getDroppedDownnull11076 function TQtComboBox.getDroppedDown: Boolean;
11077 begin
11078   Result := QWidget_isVisible(QComboBox_view(QComboBoxH(Widget)));
11079 end;
11080 
TQtComboBox.getEditablenull11081 function TQtComboBox.getEditable: Boolean;
11082 begin
11083   Result := QComboBox_isEditable(QComboBoxH(Widget));
11084 end;
11085 
TQtComboBox.getItemTextnull11086 function TQtComboBox.getItemText(AIndex: Integer): WideString;
11087 begin
11088   Result := '';
11089   QComboBox_itemText(QComboBoxH(Widget), @Result, AIndex);
11090 end;
11091 
TQtComboBox.getMaxVisibleItemsnull11092 function TQtComboBox.getMaxVisibleItems: Integer;
11093 begin
11094   Result := QComboBox_maxVisibleItems(QComboboxH(Widget));
11095 end;
11096 
getTextnull11097 function TQtComboBox.getText: WideString;
11098 begin
11099   Result := '';
11100   QComboBox_currentText(QComboBoxH(Widget), @Result);
11101   if FOwnerDrawn and (FLineEdit = nil) and
11102     (Result = '') and (Result <> FText) then
11103     Result := FText;
11104 end;
11105 
TQtComboBox.getTextStaticnull11106 function TQtComboBox.getTextStatic: Boolean;
11107 begin
11108   Result := False;
11109 end;
11110 
11111 procedure TQtComboBox.insertItem(AIndex: Integer; AText: String);
11112 var
11113   Str: WideString;
11114 begin
11115   Str := GetUtf8String(AText);
11116   insertItem(AIndex, @Str);
11117 end;
11118 
11119 procedure TQtComboBox.insertItem(AIndex: Integer; AText: PWideString);
11120 begin
11121   QComboBox_insertItem(QComboBoxH(WIdget), AIndex, AText, QVariant_create());
11122 end;
11123 
11124 {------------------------------------------------------------------------------
11125   Function: TQtComboBox.Destroy
11126   Params:  None
11127   Returns: Nothing
11128  ------------------------------------------------------------------------------}
11129 procedure TQtComboBox.setCurrentIndex(index: Integer);
11130 begin
11131   // don't fire any events when we are changing it from the LCL side
11132   BeginUpdate;
11133   QComboBox_setCurrentIndex(QComboBoxH(Widget), index);
11134   EndUpdate;
11135 end;
11136 
11137 procedure TQtComboBox.setDefaultColorRoles;
11138 begin
11139   WidgetColorRole := QPaletteBase;
11140   TextColorRole := QPaletteText;
11141 end;
11142 
11143 procedure TQtComboBox.setDroppedDown(const ADroppedDown: Boolean);
11144 begin
11145   if ADroppedDown <> QWidget_isVisible(QComboBox_view(QComboBoxH(Widget))) then
11146   begin
11147     if ADroppedDown then
11148     begin
11149       InternalIntfGetItems;
11150       QComboBox_showPopup(QComboBoxH(Widget));
11151     end else
11152       QComboBox_hidePopup(QComboBoxH(Widget));
11153   end;
11154 end;
11155 
11156 procedure TQtComboBox.setMaxVisibleItems(ACount: Integer);
11157 begin
11158   QComboBox_setMaxVisibleItems(QComboboxH(Widget), ACount);
11159 end;
11160 
11161 procedure TQtComboBox.setEditable(const AValue: Boolean);
11162 begin
11163   QComboBox_setEditable(QComboBoxH(Widget), AValue);
11164   if not AValue then
11165     FreeAndNil(FLineEdit)
11166   else
11167   begin
11168     LineEdit.setFocusPolicy(getFocusPolicy);
11169     setText(FText);
11170   end;
11171 end;
11172 
11173 procedure TQtComboBox.setItemText(AIndex: Integer; AText: String);
11174 var
11175   Str: WideString;
11176   item: QListWidgetItemH;
11177   R: TRect;
11178 begin
11179   if (AIndex >= 0) and (AIndex < QComboBox_count(QComboBoxH(Widget))) then
11180   begin
11181     Str := GetUTF8String(AText);
11182     QComboBox_setItemText(QComboBoxH(Widget), AIndex, @Str);
11183     {we must update our custom delegate}
11184     if (FDropList <> nil) and
11185        (FDropList.getVisible) and
11186        (FDropList.OwnerDrawn) then
11187     begin
11188       Item := FDropList.getItem(AIndex);
11189       if Item <> nil then
11190       begin
11191         R := FDropList.getVisualItemRect(Item);
11192         FDropList.Update(@R);
11193       end;
11194     end;
11195   end else
11196     insertItem(AIndex, AText);
11197 end;
11198 
11199 procedure TQtComboBox.setText(const W: WideString);
11200 begin
11201   if FLineEdit = nil then
11202     FText := W
11203   else
11204     QComboBox_setEditText(QComboBoxH(Widget), @W);
11205 end;
11206 
11207 procedure TQtComboBox.removeItem(AIndex: Integer);
11208 begin
11209   QComboBox_removeItem(QComboBoxH(Widget), AIndex);
11210 end;
11211 
11212 procedure TQtComboBox.AttachEvents;
11213 begin
11214   inherited AttachEvents;
11215 
11216   FActivateHook := QComboBox_hook_create(Widget);
11217   FChangeHook := QComboBox_hook_create(Widget);
11218   FSelectHook := QComboBox_hook_create(Widget);
11219 
11220   // OnChange event if itemindex changed by mouse or kbd
11221   QComboBox_hook_hook_activated(FActivateHook, @SlotActivate);
11222 
11223   // OnChange event -> fires only when text changed
11224   QComboBox_hook_hook_editTextChanged(FChangeHook, @SlotChange);
11225   // OnSelect event
11226   QComboBox_hook_hook_currentIndexChanged(FSelectHook, @SlotSelect);
11227 
11228   // DropList events
11229   FDropListEventHook := QObject_hook_create(DropList.Widget);
11230   QObject_hook_hook_events(FDropListEventHook, @EventFilter);
11231 end;
11232 
11233 procedure TQtComboBox.DetachEvents;
11234 begin
11235   if FDropListEventHook <> nil then
11236   begin
11237     QObject_hook_destroy(FDropListEventHook);
11238     FDropListEventHook := nil;
11239   end;
11240   if FActivateHook <> nil then
11241   begin
11242     QComboBox_hook_destroy(FActivateHook);
11243     FActivateHook := nil;
11244   end;
11245   if FChangeHook <> nil then
11246   begin
11247     QComboBox_hook_destroy(FChangeHook);
11248     FChangeHook := nil;
11249   end;
11250   if FSelectHook <> nil then
11251   begin
11252     QComboBox_hook_destroy(FSelectHook);
11253     FSelectHook := nil;
11254   end;
11255 
11256   inherited DetachEvents;
11257 end;
11258 
11259 procedure TQtComboBox.slotPaintCombo(Sender: QObjectH; Event: QEventH); cdecl;
11260 var
11261   Msg: TLMPaint;
11262   AStruct: PPaintStruct;
11263   MsgItem: TLMDrawListItem;
11264   DrawStruct: TDrawListItemStruct;
11265   P: TPoint;
11266   Opt: QStyleOptionComboBoxH;
11267   R: TRect;
11268   State: QStyleState;
11269   CurrIndex: Integer;
11270 begin
11271   {$ifdef VerboseQt}
11272     WriteLn('TQtComboBox.SlotPaintCombo ', dbgsName(LCLObject));
11273   {$endif}
11274   CurrIndex := currentIndex;
11275   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11276 
11277   Msg.Msg := LM_PAINT;
11278   New(AStruct);
11279   FillChar(AStruct^, SizeOf(TPaintStruct), 0);
11280   Msg.PaintStruct := AStruct;
11281 
11282   with PaintData do
11283   begin
11284     PaintWidget := Widget;
11285     ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
11286     if ClipRect = nil then
11287       New(ClipRect);
11288     QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
11289   end;
11290 
11291   Msg.DC := BeginPaint(THandle(Self), AStruct^);
11292   FContext := Msg.DC;
11293 
11294   Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
11295   Msg.PaintStruct^.hdc := FContext;
11296 
11297   P := getClientOffset;
11298   inc(P.X, FScrollX);
11299   inc(P.Y, FScrollY);
11300   TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
11301 
11302   TQtDeviceContext(Msg.DC).save;
11303   try
11304     Opt := QStyleOptionComboBox_create();
11305     QStyleOption_initFrom(Opt, Widget);
11306     State := QStyleOption_state(opt);
11307     QStyleOption_rect(Opt, @R);
11308     QPainter_setClipRect(TQtDeviceContext(Msg.DC).Widget, @R);
11309 
11310     QStyle_drawComplexControl(QApplication_style(), QStyleCC_ComboBox, Opt,
11311       TQtDeviceContext(Msg.DC).Widget, Widget);
11312     QStyle_subControlRect(QApplication_style(), @R, QStyleCC_ComboBox, Opt,
11313       QStyleSC_ComboBoxEditField , Widget);
11314     if CurrIndex < 0 then
11315     begin
11316       QStyleOptionComboBox_setCurrentText(Opt, @FText);
11317       QStyle_drawControl(QApplication_style(), QStyleCE_ComboBoxLabel, opt,
11318         TQtDeviceContext(Msg.DC).Widget, Widget);
11319     end;
11320 
11321   finally
11322     QStyleOptionComboBox_destroy(Opt);
11323     TQtDeviceContext(Msg.DC).restore;
11324   end;
11325 
11326   inc(R.Top);
11327   dec(R.Bottom);
11328   QPainter_setClipRect(TQTDeviceContext(Msg.DC).Widget, @R);
11329 
11330   DrawStruct.ItemID := UINT(CurrIndex);
11331   DrawStruct.Area := R;
11332   DrawStruct.DC := Msg.DC;
11333 
11334   DrawStruct.ItemState := [];
11335 
11336   // selected
11337   if (State and QStyleState_Selected) <> 0 then
11338     Include(DrawStruct.ItemState, odSelected);
11339   // disabled
11340   if (State and QStyleState_Enabled) = 0 then
11341     Include(DrawStruct.ItemState, odDisabled);
11342   // focused (QStyleState_FocusAtBorder?)
11343   if ((State and QStyleState_HasFocus) <> 0) or
11344     ((State and QStyleState_FocusAtBorder) <> 0) then
11345     Include(DrawStruct.ItemState, odFocused);
11346   // hotlight
11347   if (State and QStyleState_MouseOver) <> 0 then
11348     Include(DrawStruct.ItemState, odHotLight);
11349 
11350   MsgItem.Msg := LM_DRAWLISTITEM;
11351   MsgItem.DrawListItemStruct := @DrawStruct;
11352 
11353   try
11354     if CurrIndex >= 0 then
11355       DeliverMessage(MsgItem);
11356   finally
11357     Dispose(PaintData.ClipRect);
11358     Fillchar(FPaintData, SizeOf(FPaintData), 0);
11359     FContext := 0;
11360     EndPaint(THandle(Self), AStruct^);
11361     Dispose(AStruct);
11362   end;
11363 end;
11364 
11365 {this routine is called ONLY from dropdown list viewport event filter
11366  when QEventShow occurs.It sends MouseRelease event to LCL !
11367  Should not be used in any other case.}
11368 procedure TQtComboBox.FixMouseUp;
11369 var
11370   MouseEvent: QMouseEventH;
11371   AMouseFixPosF: TQtPointF;
11372 begin
11373   if (FMouseFixPos.x = -1) and (FMouseFixPos.y = -1) then
11374     exit;
11375   if QGUIApplication_mouseButtons = QtLeftButton then
11376   begin
11377     AMouseFixPosF.X := FMouseFixPos.X;
11378     AMouseFixPosF.Y := FMouseFixPos.Y;
11379     MouseEvent := QMouseEvent_create(QEventMouseButtonRelease, @AMouseFixPosF, QtLeftButton,
11380       QtLeftButton, QGUIApplication_keyboardModifiers());
11381     QCoreApplication_postEvent(Widget, MouseEvent);
11382   end;
11383 end;
11384 
EventFilternull11385 function TQtComboBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
11386 var
11387   R, R1: TRect;
11388   ButtonRect: TRect;
11389   P: TQtPoint;
11390   Pt: TPoint;
11391   Opt: QStyleOptionComboBoxH;
11392 begin
11393 
11394   Result := False;
11395   QEvent_accept(Event);
11396 
11397   if LCLObject = nil then
11398     exit;
11399 
11400   if (FDropList <> nil) and (Sender = FDropList.Widget) then
11401   begin
11402     if (Byte(QEvent_type(Event)) in [QEventKeyPress, QEventKeyRelease,QEventFontChange]) then
11403     begin
11404       Result := inherited EventFilter(Sender, Event);
11405       if Result and (QEvent_type(Event) = QEventKeyPress) then
11406         FKeyEnterFix := True; {issue #31574}
11407     end;
11408     QEvent_ignore(Event);
11409     exit;
11410   end;
11411 
11412   BeginEventProcessing;
11413   try
11414     if FKeyEnterFix and (Byte(QEvent_type(Event)) in [QEventMouseButtonPress, QEventMouseButtonDblClick,
11415       QEventMouseButtonRelease, QEventKeyPress, QEventHide, QEventShow]) then
11416         FKeyEnterFix := False; {issue #31574}
11417     case QEvent_type(Event) of
11418       QEventFocusOut:
11419       begin
11420         if Assigned(FLineEdit) and FLineEdit.getVisible then
11421         begin
11422           FLineEdit.CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(FLineEdit.Widget));
11423           FLineEdit.CachedSelectionLen := UTF16Length(FLineEdit.getSelectedText);
11424         end;
11425         Result := inherited EventFilter(Sender, Event);
11426       end;
11427       QEventFocusIn:
11428       begin
11429         if Assigned(FLineEdit) and FLineEdit.getVisible then
11430         begin
11431           FLineEdit.CachedSelectionStart := -1;
11432           FLineEdit.CachedSelectionLen := -1;
11433         end;
11434         Result := inherited EventFilter(Sender, Event);
11435       end;
11436       QEventHide:
11437       begin
11438         if getVisible then
11439           SlotShow(False);
11440       end;
11441       QEventPaint:
11442       begin
11443         if FOwnerDrawn and not getEditable then
11444         begin
11445           SlotPaintCombo(Widget, Event);
11446           Result := True;
11447           QEvent_accept(Event);
11448         end;
11449       end;
11450       QEventMouseButtonRelease:
11451       begin
11452         FMouseFixPos := QtPoint(-1, -1);
11453         Result := inherited EventFilter(Sender, Event);
11454       end;
11455       QEventMouseButtonPress:
11456       begin
11457         if not FDropListVisibleInternal and
11458           (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
11459         begin
11460           // some themes have empty space around combo button !
11461 
11462           QMouseEvent_pos(QMouseEventH(Event), @P);
11463           FMouseFixPos := P;
11464 
11465           // our combo geometry
11466           R := getGeometry;
11467 
11468           Pt := Point(P.X, P.Y);
11469 
11470           // our combo arrow position when we are editable combobox
11471           if getEditable then
11472           begin
11473             opt := QStyleOptionComboBox_create();
11474             QStyle_subControlRect(QApplication_style(), @R1, QStyleCC_ComboBox,
11475               opt, QStyleSC_ComboBoxArrow, QComboBoxH(Widget));
11476             QStyleOptionComboBox_destroy(opt);
11477             R := Rect(0, 0, R.Right - R.Left, R.Bottom - R.Top);
11478             ButtonRect := Rect(R.Right + R1.Left, R.Top,
11479               R.Right - R1.Right, R.Bottom);
11480           end else
11481           begin
11482             ButtonRect := R;
11483             OffsetRect(ButtonRect, -R.Left, -R.Top);
11484           end;
11485 
11486           if PtInRect(ButtonRect, Pt) then
11487             InternalIntfGetItems;
11488         end;
11489         Result := inherited EventFilter(Sender, Event);
11490       end;
11491 
11492       QEventMouseButtonDblClick:
11493       begin
11494         // avoid crash on unfocused combobox raised from
11495         // eg. TStringGrid as picklist.
11496         // crash happens when combo is hidden in cell, and then we
11497         // dbl click on position of combo button. Control raises combo
11498         // and propagate dbl click to combobox which must grab focus in
11499         // that case.
11500         if CanSendLCLMessage and getEnabled and not hasFocus then
11501           setFocus;
11502         Result := inherited EventFilter(Sender, Event);
11503       end;
11504 
11505       QEventKeyPress:
11506       begin
11507         if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_F4) or
11508           ((QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
11509             not getEditable) then
11510         begin
11511           if not FDropListVisibleInternal then
11512             InternalIntfGetItems
11513           else
11514             Result := inherited EventFilter(Sender, Event);
11515         end else
11516           Result := inherited EventFilter(Sender, Event);
11517       end;
11518       QEventKeyRelease:
11519       begin
11520         {issue #31574}
11521         if not FKeyEnterFix then
11522           Result := inherited EventFilter(Sender, Event);
11523         FKeyEnterFix := False;
11524       end;
11525       else
11526         Result := inherited EventFilter(Sender, Event);
11527     end;
11528   finally
11529     EndEventProcessing;
11530   end;
11531 end;
11532 
11533 procedure TQtComboBox.preferredSize(var PreferredWidth,
11534   PreferredHeight: integer; WithThemeSpace: Boolean);
11535 var
11536   Size: TSize;
11537 begin
11538   QComboBox_sizeHint(QComboBoxH(Widget), @Size);
11539   PreferredWidth := Size.cx;
11540   PreferredHeight := Size.cy;
11541 end;
11542 
11543 procedure TQtComboBox.SlotActivate(index: Integer); cdecl;
11544 var
11545   Msg: TLMessage;
11546 begin
11547   if InUpdate then
11548     Exit;
11549 
11550   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11551   Msg.Msg := LM_ACTIVATE;
11552   DeliverMessage(Msg);
11553 end;
11554 
11555 procedure TQtComboBox.SlotChange(p1: PWideString); cdecl;
11556 var
11557   Msg: TLMessage;
11558 begin
11559   if InUpdate then
11560     Exit;
11561 
11562   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11563 
11564   Msg.Msg := LM_CHANGED;
11565 
11566   DeliverMessage(Msg);
11567 end;
11568 
11569 procedure TQtComboBox.SlotSelect(index: Integer); cdecl;
11570 var
11571   Msg: TLMessage;
11572 begin
11573   if InUpdate then
11574     exit;
11575 
11576   {we must fire OnChange() if it isn''t editable
11577    since SlotChange() fires only for editable
11578    comboboxes }
11579   if not getEditable then
11580   begin
11581     FillChar(Msg{%H-}, SizeOf(Msg), #0);
11582     Msg.Msg := LM_CHANGED;
11583     DeliverMessage(Msg);
11584   end;
11585 
11586   FillChar(Msg, SizeOf(Msg), #0);
11587 
11588   Msg.Msg := LM_SELCHANGE;
11589 
11590   DeliverMessage(Msg);
11591 end;
11592 
11593 procedure TQtComboBox.SlotDropListVisibility(AVisible: Boolean); cdecl;
11594 const
11595   VisibilityToCodeMap: array[Boolean] of Word =
11596   (
11597     CBN_CLOSEUP,
11598     CBN_DROPDOWN
11599   );
11600 var
11601   Msg : TLMCommand;
11602 begin
11603   if InUpdate then
11604     Exit;
11605 
11606   FillChar(Msg{%H-}, SizeOf(Msg), 0);
11607   Msg.Msg := CN_COMMAND;
11608   Msg.NotifyCode := VisibilityToCodeMap[AVisible];
11609 
11610   DeliverMessage(Msg);
11611   FDropListVisibleInternal := AVisible;
11612 end;
11613 
11614 { TQtAbstractSpinBox }
11615 
GetLineEditnull11616 function TQtAbstractSpinBox.GetLineEdit: QLineEditH;
11617 begin
11618   if FLineEdit = nil then
11619     FLineEdit := QLCLAbstractSpinBox_lineEditHandle(QAbstractSpinBoxH(Widget));
11620   if Assigned(FLineEdit) and not Assigned(FLineEditHook) then
11621   begin
11622     FLineEditHook := QObject_hook_create(FLineEdit);
11623     QObject_hook_hook_events(FLineEditHook, @LineEditEventFilter);
11624     FTextChangedHook := QLineEdit_hook_create(FLineEdit);
11625     QLineEdit_hook_hook_textChanged(FTextChangedHook, @SignalLineEditTextChanged);
11626   end;
11627   Result := FLineEdit;
11628 end;
11629 
LineEditEventFilternull11630 function TQtAbstractSpinBox.LineEditEventFilter(Sender: QObjectH; Event: QEventH
11631   ): Boolean; cdecl;
11632 begin
11633   Result := False;
11634   QEvent_accept(Event);
11635   if QEvent_type(Event) = QEventFontChange then
11636     Result := EventFilter(QWidgetH(Sender), Event);
11637 end;
11638 
11639 procedure TQtAbstractSpinBox.SignalLineEditTextChanged(AnonParam1: PWideString); cdecl;
11640 var
11641   Msg: TLMessage;
11642 begin
11643   if FTextChangedByValueChanged then
11644   begin
11645     FTextChangedByValueChanged := False;
11646     Exit;
11647   end;
11648   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11649   Msg.Msg := CM_TEXTCHANGED;
11650   if not InUpdate then
11651     DeliverMessage(Msg);
11652 end;
11653 
11654 procedure TQtAbstractSpinBox.setTextHint(const ATextHint: string);
11655 var
11656   W: WideString;
11657 begin
11658   if Assigned(FLineEdit) and not (csDesigning in LCLObject.ComponentState) then
11659   begin
11660     W := UTF8ToUTF16(ATextHint);
11661     QLineEdit_setPlaceholderText(FLineEdit, @W);
11662   end;
11663 end;
11664 
CreateWidgetnull11665 function TQtAbstractSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
11666 var
11667   Parent: QWidgetH;
11668 begin
11669   // Creates the widget
11670   {$ifdef VerboseQt}
11671     WriteLn('TQtAbstractSpinBox.Create');
11672   {$endif}
11673   FLineEditHook := nil;
11674   if AParams.WndParent <> 0 then
11675     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
11676   else
11677     Parent := nil;
11678   FTextChangedByValueChanged := False;
11679   Result := QAbstractSpinBox_create(Parent);
11680 end;
11681 
getMaxLengthnull11682 function TQtAbstractSpinBox.getMaxLength: Integer;
11683 begin
11684   if LineEdit <> nil then
11685     Result := QLineEdit_maxLength(LineEdit)
11686   else
11687     Result := 0;
11688 end;
11689 
getSelectionStartnull11690 function TQtAbstractSpinBox.getSelectionStart: Integer;
11691 begin
11692   if (LineEdit <> nil) then
11693   begin
11694     if QLineEdit_hasSelectedText(LineEdit) then
11695       Result := QLineEdit_selectionStart(LineEdit)
11696     else
11697       Result := QLineEdit_cursorPosition(LineEdit);
11698   end
11699   else
11700     Result := 0;
11701 end;
11702 
getSelectionLengthnull11703 function TQtAbstractSpinBox.getSelectionLength: Integer;
11704 var
11705   W: WideString;
11706 begin
11707   if (LineEdit <> nil) and QLineEdit_hasSelectedText(LineEdit) then
11708   begin
11709     QLineEdit_selectedText(LineEdit, @W);
11710     Result := UTF16Length(W);
11711   end
11712   else
11713     Result := 0;
11714 end;
11715 
isUndoAvailablenull11716 function TQtAbstractSpinBox.isUndoAvailable: Boolean;
11717 begin
11718   if LineEdit <> nil then
11719     Result := QLineEdit_isUndoAvailable(LineEdit)
11720   else
11721     Result := False;
11722 end;
11723 
11724 procedure TQtAbstractSpinBox.setBorder(const ABorder: Boolean);
11725 begin
11726   QAbstractSpinBox_setFrame(QAbstractSpinBoxH(Widget), ABorder);
11727 end;
11728 
11729 procedure TQtAbstractSpinBox.setCursorPosition(const ACursorPosition: Integer);
11730 begin
11731   if LineEdit <> nil then
11732     QLineEdit_setCursorPosition(LineEdit, ACursorPosition);
11733 end;
11734 
11735 procedure TQtAbstractSpinBox.setDefaultColorRoles;
11736 begin
11737   WidgetColorRole := QPaletteBase;
11738   TextColorRole := QPaletteText;
11739 end;
11740 
11741 procedure TQtAbstractSpinBox.setEchoMode(const AMode: QLineEditEchoMode);
11742 begin
11743   if LineEdit <> nil then
11744     QLineEdit_setEchoMode(LineEdit, AMode);
11745 end;
11746 
11747 procedure TQtAbstractSpinBox.setMaxLength(const ALength: Integer);
11748 begin
11749   if LineEdit <> nil then
11750     QLineEdit_setMaxLength(LineEdit, ALength);
11751 end;
11752 
11753 procedure TQtAbstractSpinBox.setSelection(const AStart, ALength: Integer);
11754 begin
11755   if (LineEdit <> nil) and (AStart >= 0) then
11756   begin
11757     if ALength > 0 then
11758       QLineEdit_setSelection(LineEdit, AStart, ALength)
11759     else
11760       QLineEdit_setCursorPosition(LineEdit, AStart);
11761   end;
11762 end;
11763 
11764 procedure TQtAbstractSpinBox.Cut;
11765 begin
11766   if LineEdit <> nil then
11767     QLineEdit_cut(LineEdit);
11768 end;
11769 
11770 procedure TQtAbstractSpinBox.Copy;
11771 begin
11772   if LineEdit <> nil then
11773     QLineEdit_copy(LineEdit);
11774 end;
11775 
11776 procedure TQtAbstractSpinBox.Paste;
11777 begin
11778   if LineEdit <> nil then
11779     QLineEdit_paste(LineEdit);
11780 end;
11781 
11782 procedure TQtAbstractSpinBox.Undo;
11783 begin
11784   if LineEdit <> nil then
11785     QLineEdit_undo(LineEdit);
11786 end;
11787 
getCursorPositionnull11788 function TQtAbstractSpinBox.getCursorPosition: TPoint;
11789 begin
11790   Result := Point(0, 0);
11791   if LineEdit <> nil then
11792     Result.X := QLineEdit_cursorPosition(LineEdit);
11793 end;
11794 
getReadOnlynull11795 function TQtAbstractSpinBox.getReadOnly: Boolean;
11796 begin
11797   {$ifdef VerboseQt}
11798     WriteLn('TQtAbstractSpinBox.IsReadOnly');
11799   {$endif}
11800   Result := QAbstractSpinBox_isReadOnly(QAbstractSpinBoxH(Widget));
11801 end;
11802 
getTextnull11803 function TQtAbstractSpinBox.getText: WideString;
11804 begin
11805   if LineEdit <> nil then
11806     QLineEdit_text(LineEdit, @Result)
11807   else
11808     Result := '';
11809   {$ifdef VerboseQt}
11810   WriteLn('TQtAbstractSpinBox.GetText Result=',Result);
11811   {$endif}
11812 end;
11813 
getTextStaticnull11814 function TQtAbstractSpinBox.getTextStatic: Boolean;
11815 begin
11816   Result := False;
11817 end;
11818 
11819 procedure TQtAbstractSpinBox.setAlignment(const AAlignment: QtAlignment);
11820 begin
11821   QAbstractSpinBox_setAlignment(QSpinBoxH(Widget), AAlignment);
11822 end;
11823 
11824 procedure TQtAbstractSpinBox.setFocusPolicy(const APolicy: QtFocusPolicy);
11825 begin
11826   inherited setFocusPolicy(APolicy);
11827   QWidget_setFocusPolicy(LineEdit, APolicy);
11828 end;
11829 
11830 procedure TQtAbstractSpinBox.setReadOnly(const r: Boolean);
11831 begin
11832   QAbstractSpinBox_setReadOnly(QAbstractSpinBoxH(Widget), r);
11833 end;
11834 
11835 procedure TQtAbstractSpinBox.setText(const W: WideString);
11836 begin
11837   {$ifdef VerboseQt}
11838   WriteLn('TQtAbstractSpinBox.SetText W=',w);
11839   {$endif}
11840   if (LineEdit <> nil) then
11841     QLineEdit_setText(LineEdit, @W)
11842 end;
11843 
11844 procedure TQtAbstractSpinBox.AttachEvents;
11845 begin
11846   inherited AttachEvents;
11847 
11848   FEditingFinishedHook := QAbstractSpinBox_hook_create(Widget);
11849   {TODO: find out which TLMessage should be sended }
11850   QAbstractSpinBox_hook_hook_editingFinished(FEditingFinishedHook, @SignalEditingFinished);
11851 end;
11852 
11853 procedure TQtAbstractSpinBox.DetachEvents;
11854 begin
11855   if FEditingFinishedHook <> nil then
11856   begin
11857     QAbstractSpinBox_hook_destroy(FEditingFinishedHook);
11858     FEditingFinishedHook := nil;
11859   end;
11860 
11861   if FLineEditHook <> nil then
11862   begin
11863     QObject_hook_destroy(FLineEditHook);
11864     FLineEditHook := nil;
11865   end;
11866 
11867   if FTextChangedHook <> nil then
11868   begin
11869     QLineEdit_hook_destroy(FTextChangedHook);
11870     FTextChangedHook := nil;
11871   end;
11872 
11873   inherited DetachEvents;
11874 end;
11875 
EventFilternull11876 function TQtAbstractSpinBox.EventFilter(Sender: QObjectH; Event: QEventH
11877   ): Boolean; cdecl;
11878 var
11879   IsDeleteKey: Boolean;
11880 begin
11881   if (QEvent_type(Event) = QEventKeyPress) or
11882      (QEvent_type(Event) = QEventKeyRelease) then
11883     IsDeleteKey := (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Delete) and
11884       (QKeyEvent_modifiers(QKeyEventH(Event)) = QtNoModifier)
11885   else
11886     IsDeleteKey := False;
11887   Result := inherited EventFilter(Sender, Event);
11888   {we must pass delete key to qt, qabstractspinbox doesn't like what we do}
11889   if IsDeleteKey then
11890     Result := False;
11891   {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
11892   if (FParentShowPassed = 1) then
11893   begin
11894     if QEvent_type(Event) <> QEventPaint then
11895     begin
11896       inc(FParentShowPassed);
11897       BeginUpdate;
11898       setValue(getValue);
11899       EndUpdate;
11900     end;
11901   end;
11902 
11903   if (QEvent_type(Event) = QEventShowToParent) and
11904     (FParentShowPassed = 0) then
11905     inc(FParentShowPassed);
11906   {$ENDIF}
11907 
11908 end;
11909 
11910 procedure TQtAbstractSpinBox.SignalEditingFinished; cdecl;
11911 var
11912   Msg: TLMessage;
11913 begin
11914   {$ifdef VerboseQt}
11915     WriteLn('TQtAbstractSpinBox.SignalEditingFinished');
11916   {$endif}
11917   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11918   { TODO: Find out which message should be sended here
11919     problem:
11920      everything is fine when we work with mouse, or
11921      press TabKey to select next control, but if we
11922      connect OnKeyDown and say eg. VK_RETURN: SelectNext(ActiveControl, true, true)
11923      then spinedit text is always selected, nothing important but looks ugly.}
11924   //  Msg.Msg := LM_EXIT;
11925   //  DeliverMessage(Msg);
11926 end;
11927 
11928 { TQtFloatSpinBox }
11929 
TQtFloatSpinBox.CreateWidgetnull11930 function TQtFloatSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
11931 var
11932   Parent: QWidgetH;
11933 begin
11934   // Creates the widget
11935   {$ifdef VerboseQt}
11936     WriteLn('TQtFloatSpinBox.Create');
11937   {$endif}
11938   {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
11939   FParentShowPassed := 0;
11940   {$ENDIF}
11941   FValue := 0;
11942   FLineEditHook := nil;
11943   if AParams.WndParent <> 0 then
11944     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
11945   else
11946     Parent := nil;
11947   Result := QDoubleSpinBox_create(Parent);
11948 end;
11949 
getValuenull11950 function TQtFloatSpinBox.getValue: Double;
11951 begin
11952   Result := FValue;
11953 end;
11954 
11955 procedure TQtFloatSpinBox.setDecimals(const v: integer);
11956 begin
11957   QDoubleSpinBox_setDecimals(QDoubleSpinBoxH(Widget), v);
11958 end;
11959 
11960 procedure TQtFloatSpinBox.setMinimum(const v: Double);
11961 begin
11962   QDoubleSpinBox_setMinimum(QDoubleSpinBoxH(Widget), v);
11963 end;
11964 
11965 procedure TQtFloatSpinBox.setMaximum(const v: Double);
11966 begin
11967   QDoubleSpinBox_setMaximum(QDoubleSpinBoxH(Widget), v);
11968 end;
11969 
11970 procedure TQtFloatSpinBox.setSingleStep(const v: Double);
11971 begin
11972   QDoubleSpinBox_setSingleStep(QDoubleSpinBoxH(Widget), v);
11973 end;
11974 
11975 procedure TQtFloatSpinBox.setValue(const v: Double);
11976 begin
11977   FValue := v;
11978   QDoubleSpinBox_setValue(QDoubleSpinBoxH(Widget), FValue);
11979 end;
11980 
11981 procedure TQtFloatSpinBox.AttachEvents;
11982 begin
11983   inherited AttachEvents;
11984   FValueChangedHook := QDoubleSpinBox_hook_create(Widget);
11985   QDoubleSpinBox_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
11986 end;
11987 
11988 procedure TQtFloatSpinBox.DetachEvents;
11989 begin
11990   if FValueChangedHook <> nil then
11991   begin
11992     QDoubleSpinBox_hook_destroy(FValueChangedHook);
11993     FValueChangedHook := nil;
11994   end;
11995   inherited DetachEvents;
11996 end;
11997 
11998 procedure TQtFloatSpinBox.SignalValueChanged(p1: Double); cdecl;
11999 var
12000   Msg: TLMessage;
12001 begin
12002   FValue := p1;
12003   FTextChangedByValueChanged := True;
12004   FillChar(Msg{%H-}, SizeOf(Msg), #0);
12005   Msg.Msg := CM_TEXTCHANGED;
12006   if not InUpdate then
12007     DeliverMessage(Msg);
12008 end;
12009 
12010 { TQtSpinBox }
12011 
CreateWidgetnull12012 function TQtSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
12013 var
12014   Parent: QWidgetH;
12015 begin
12016   // Creates the widget
12017   {$ifdef VerboseQt}
12018     WriteLn('TQtSpinBox.Create');
12019   {$endif}
12020   {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
12021   FParentShowPassed := 0;
12022   {$ENDIF}
12023   FLineEditHook := nil;
12024   if AParams.WndParent <> 0 then
12025     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
12026   else
12027     Parent := nil;
12028   Result := QSpinBox_create(Parent);
12029 end;
12030 
getValuenull12031 function TQtSpinBox.getValue: Double;
12032 begin
12033   Result := FValue;
12034 end;
12035 
12036 procedure TQtSpinBox.setMinimum(const v: Double);
12037 begin
12038   QSpinBox_setMinimum(QSpinBoxH(Widget), round(v));
12039 end;
12040 
12041 procedure TQtSpinBox.setMaximum(const v: Double);
12042 begin
12043   QSpinBox_setMaximum(QSpinBoxH(Widget), round(v));
12044 end;
12045 
12046 procedure TQtSpinBox.setSingleStep(const v: Double);
12047 begin
12048   QSpinBox_setSingleStep(QSpinBoxH(Widget), round(v));
12049 end;
12050 
12051 procedure TQtSpinBox.setValue(const v: Double);
12052 begin
12053   FValue := Round(v);
12054   QSpinBox_setValue(QSpinBoxH(Widget), round(v));
12055 end;
12056 
12057 procedure TQtSpinBox.AttachEvents;
12058 begin
12059   inherited AttachEvents;
12060   FValueChangedHook := QSpinBox_hook_create(Widget);
12061   QSpinBox_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
12062 end;
12063 
12064 procedure TQtSpinBox.DetachEvents;
12065 begin
12066   if FValueChangedHook <> nil then
12067   begin
12068     QSpinBox_hook_destroy(FValueChangedHook);
12069     FValueChangedHook := nil;
12070   end;
12071   inherited DetachEvents;
12072 end;
12073 
12074 procedure TQtSpinBox.SignalValueChanged(p1: Integer); cdecl;
12075 var
12076   Msg: TLMessage;
12077 begin
12078   FValue := p1;
12079   FTextChangedByValueChanged := True;
12080   FillChar(Msg{%H-}, SizeOf(Msg), #0);
12081   Msg.Msg := CM_TEXTCHANGED;
12082   if not InUpdate then
12083    DeliverMessage(Msg);
12084 end;
12085 
12086 { TQtListView }
12087 
getBatchSizenull12088 function TQtListView.getBatchSize: integer;
12089 begin
12090   Result := QListView_batchSize(QListViewH(Widget));
12091 end;
12092 
getGridSizenull12093 function TQtListView.getGridSize: TSize;
12094 begin
12095   QListView_gridSize(QListViewH(Widget), @Result);
12096 end;
12097 
getSpacingnull12098 function TQtListView.getSpacing: Integer;
12099 begin
12100   Result := QListView_spacing(QListViewH(Widget));
12101 end;
12102 
12103 procedure TQtListView.setBatchSize(const AValue: integer);
12104 begin
12105   QListView_setBatchSize(QListViewH(Widget), AValue);
12106 end;
12107 
12108 procedure TQtListView.setGridSize(const AValue: TSize);
12109 begin
12110   QListView_setGridSize(QListViewH(Widget), @AValue);
12111 end;
12112 
12113 procedure TQtListView.setLayoutMode(const ALayoutMode: QListViewLayoutMode);
12114 begin
12115   QListView_setLayoutMode(QListViewH(Widget), ALayoutMode);
12116 end;
12117 
12118 procedure TQtListView.setMovement(const AMovement: QListViewMovement);
12119 begin
12120   QListView_setMovement(QListViewH(Widget), AMovement);
12121 end;
12122 
12123 procedure TQtListView.setResizeMode(const AResizeMode: QListViewResizeMode);
12124 begin
12125   QListView_setResizeMode(QListViewH(Widget), AResizeMode);
12126 end;
12127 
12128 procedure TQtListView.setSpacing(const AValue: integer);
12129 begin
12130   QListView_setSpacing(QListViewH(Widget), AValue);
12131 end;
12132 
12133 procedure TQtListView.setUniformItemSizes(const AEnable: Boolean);
12134 begin
12135   QListView_setUniformItemSizes(QListViewH(Widget), AEnable);
12136 end;
12137 
12138 procedure TQtListView.setViewFlow(const AFlow: QListViewFlow);
12139 begin
12140   QListView_setFlow(QListViewH(Widget), AFlow);
12141 end;
12142 
12143 procedure TQtListView.setViewMode(const AMode: QListViewViewMode);
12144 begin
12145   QListView_setViewMode(QListViewH(Widget), AMode);
12146 end;
12147 
12148 procedure TQtListView.setWordWrap(const AValue: Boolean);
12149 begin
12150   QListView_setWordWrap(QListViewH(Widget), AValue);
12151 end;
12152 
12153 procedure TQtListView.setWrapping(const AWrapping: Boolean);
12154 begin
12155   QListView_setWrapping(QListViewH(Widget), AWrapping);
12156 end;
12157 
12158 procedure TQtListView.LayoutItems;
12159 begin
12160   QListView_doItemsLayout(QListViewH(Widget));
12161 end;
12162 
12163 { TQtListWidget }
12164 
TQtListWidget.getItemCountnull12165 function TQtListWidget.getItemCount: Integer;
12166 begin
12167   Result := QListWidget_count(QListWidgetH(Widget));
12168 end;
12169 
TQtListWidget.GetItemCheckednull12170 function TQtListWidget.GetItemChecked(AIndex: Integer): Boolean;
12171 var
12172   AItem: QListWidgetItemH;
12173 begin
12174   Result := False;
12175   AItem := getItem(AIndex);
12176   if Assigned(AItem) then
12177     Result := QListWidgetItem_checkState(AItem) = QtChecked;
12178 end;
12179 
GetItemEnablednull12180 function TQtListWidget.GetItemEnabled(AIndex: Integer): Boolean;
12181 var
12182   AItem: QListWidgetItemH;
12183 begin
12184   Result := False;
12185   AItem := getItem(AIndex);
12186   if Assigned(AItem) then
12187     Result := QListWidgetItem_flags(AItem) and QtItemIsEnabled <> 0;
12188 end;
12189 
TQtListWidget.GetSelectednull12190 function TQtListWidget.GetSelected(AIndex: Integer): Boolean;
12191 var
12192   AItem: QListWidgetItemH;
12193 begin
12194   Result := False;
12195   AItem := getItem(AIndex);
12196   if Assigned(AItem) then
12197     Result := getItemSelected(AItem);
12198 end;
12199 
12200 procedure TQtListWidget.SetItemChecked(AIndex: Integer; AValue: Boolean);
12201 var
12202   AItem: QListWidgetItemH;
12203 begin
12204   AItem := getItem(AIndex);
12205   if Assigned(AItem) then
12206   begin
12207     if AValue then
12208       QListWidgetItem_setCheckState(AItem, QtChecked)
12209     else
12210       QListWidgetItem_setCheckState(AItem, QtUnChecked);
12211     SetItemLastCheckState(AItem);
12212   end;
12213 end;
12214 
12215 procedure TQtListWidget.setItemCount(const AValue: Integer);
12216 var
12217   i: Integer;
12218   AList: QStringListH;
12219   WStr: WideString;
12220 begin
12221   if AValue = ItemCount then
12222     exit;
12223   BeginUpdate;
12224   try
12225     ClearItems;
12226     AList := QStringList_create();
12227     WStr := '';
12228     for i := 1 to AValue do
12229       QStringList_append(AList, @WStr);
12230     QListWidget_addItems(QListWidgetH(Widget), AList);
12231     QStringList_destroy(AList);
12232   finally
12233     EndUpdate;
12234   end;
12235 end;
12236 
12237 procedure TQtListWidget.SetItemEnabled(AIndex: Integer; AValue: Boolean);
12238 var
12239   AItem: QListWidgetItemH;
12240   Flags: QtItemFlags;
12241 begin
12242   AItem := getItem(AIndex);
12243   if Assigned(AItem) then
12244   begin
12245     Flags := QListWidgetItem_flags(AItem);
12246     if AValue then
12247       Flags := Flags or QtItemIsEnabled
12248     else
12249       Flags := Flags and not QtItemIsEnabled;
12250     QListWidgetItem_setFlags(AItem, Flags);
12251   end;
12252 end;
12253 
12254 procedure TQtListWidget.SetSelected(AIndex: Integer; AValue: Boolean);
12255 begin
12256   if (AIndex >= 0) and (AIndex < RowCount) then
12257     setItemSelected(getItem(AIndex), AValue);
12258 end;
12259 
GetItemLastCheckStatenull12260 function TQtListWidget.GetItemLastCheckState(AItem: QListWidgetItemH
12261   ): QtCheckState;
12262 var
12263   v: QVariantH;
12264   ok: Boolean;
12265 begin
12266   Result := QtUnChecked;
12267   if AItem = nil then
12268     exit;
12269   v := QVariant_create();
12270   QListWidgetItem_data(AItem, v,  QtCheckStateRole);
12271   ok := False;
12272   if QVariant_isValid(v) then
12273     Result := QtCheckState(QVariant_toInt(v, @Ok));
12274   QVariant_destroy(v);
12275 end;
12276 
12277 procedure TQtListWidget.SetItemLastCheckState(AItem: QListWidgetItemH);
12278 var
12279   AState: QtCheckState;
12280 begin
12281   if AItem = nil then
12282     exit;
12283   AState := QListWidgetItem_checkState(AItem);
12284   SetItemLastCheckStateInternal(AItem, AState);
12285 end;
12286 
12287 procedure TQtListWidget.SetItemLastCheckStateInternal(AItem: QListWidgetItemH;
12288   AState: QtCheckState);
12289 var
12290   v: QVariantH;
12291 begin
12292   v := QVariant_create(Ord(AState));
12293   QListWidgetItem_setData(AItem, QtCheckStateRole, v);
12294   QVariant_destroy(v);
12295 end;
12296 
12297 procedure TQtListWidget.SetNextStateMap(AItem: QListWidgetItemH);
12298 begin
12299   // does the job only for TQtCheckListBox
12300 end;
12301 
TQtListWidget.CreateWidgetnull12302 function TQtListWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
12303 var
12304   Parent: QWidgetH;
12305 begin
12306   FCheckBoxClicked := False;
12307   FDelayedCheckItem := nil;
12308   SetLength(FSavedSelection, 0);
12309   AllowGrayed := False;
12310   FSavedEvent := nil;
12311   FSavedEventTimer := nil;
12312   FSavedEventTimerHook := nil;
12313 
12314   FViewStyle := -1;
12315   FSyncingItems := False;
12316   FCheckable := False;
12317   FDontPassSelChange := False;
12318   FOwnerData := False;
12319   if AParams.WndParent <> 0 then
12320     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
12321   else
12322     Parent := nil;
12323   Result := QListWidget_create(Parent);
12324 end;
12325 
12326 type
12327   TCustomListViewHack = class(TCustomListView);
12328 
12329 procedure TQtListWidget.OwnerDataNeeded(ARect: TRect);
12330 var
12331   R: TRect;
12332   TopItem: Integer;
12333   i: Integer;
12334   VHeight: Integer; // viewport height
12335   RowHeight, AImagesWidth: Integer;
12336   item: QListWidgetItemH;
12337   v, v2, v3: QVariantH;
12338   WStr: WideString;
12339   DataStr: WideString;
12340   ImgList: TCustomImageList;
12341   AImageIndex: TImageIndex;
12342   Bmp: TBitmap;
12343   AIcon: QIconH;
12344   AOk, AStateImages: Boolean;
12345   ASize: TSize;
12346   ImgListRes: TScaledImageListResolution;
12347 begin
12348 
12349   {do not set items during design time}
12350   if (csDesigning in LCLObject.ComponentState) then
12351     exit;
12352 
12353   if ItemCount < 1 then
12354     exit;
12355 
12356   {TODO: add QtDecorationRole (icon) etc ... }
12357   QWidget_contentsRect(viewportWidget, @R);
12358   VHeight := R.Bottom - R.Top;
12359 
12360   item := itemAt(0, 1);
12361   if item <> nil then
12362   begin
12363     TopItem := getRow(Item);
12364     RowHeight := getRowHeight(TopItem);
12365 
12366     if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
12367       exit;
12368 
12369     i := 0;
12370 
12371     while (i < (VHeight + RowHeight)) do
12372     begin
12373       item := itemAt(0, i + 1);
12374       if (item <> nil) then
12375       begin
12376         TopItem := getRow(Item);
12377         RowHeight := getRowHeight(TopItem);
12378 
12379         if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
12380           break;
12381 
12382         AStateImages := False;
12383         ImgList := TCustomListViewHack(LCLObject).SmallImages;
12384         if Assigned(ImgList) then
12385           AImagesWidth := TCustomListViewHack(LCLObject).SmallImagesWidth
12386         else
12387         begin
12388           ImgList := TCustomListViewHack(LCLObject).StateImages;
12389           if Assigned(ImgList) then
12390             AImagesWidth := TCustomListViewHack(LCLObject).StateImagesWidth;
12391           AStateImages := True;
12392         end;
12393         if Assigned(ImgList) then
12394         begin
12395           ImgListRes := ImgList.ResolutionForPPI[
12396             AImagesWidth,
12397             TCustomListViewHack(LCLObject).Font.PixelsPerInch,
12398             TCustomListViewHack(LCLObject).GetCanvasScaleFactor];
12399           QListWidgetItem_sizeHint(item, @ASize);
12400           if (ASize.cx <> ImgListRes.Width) or (ASize.cx <> ImgListRes.Height) then
12401           begin
12402             ASize.cx := ImgListRes.Width;
12403             ASize.cy := ImgListRes.Height;
12404             QListWidgetItem_setSizeHint(item, @ASize);
12405           end;
12406           if AStateImages then
12407             AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].StateIndex
12408           else
12409             AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].ImageIndex;
12410           if (ImgListRes.Count > 0) and
12411             ((AImageIndex >= 0) and (AImageIndex < ImgListRes.Count)) then
12412           begin
12413             Bmp := TBitmap.Create;
12414             try
12415               ImgListRes.GetBitmap(AImageIndex, Bmp);
12416               v2 := QVariant_create;
12417               QListWidgetItem_data(item, v2, QtListViewOwnerDataRole);
12418               if not QVariant_isNull(v2) then
12419               begin
12420                 AOk := True;
12421                 if QVariant_toInt(v2, @AOk) <> AImageIndex then
12422                 begin
12423                   v2 := QVariant_create(AImageIndex);
12424                   QListWidgetItem_setData(item, QtListViewOwnerDataRole, v2);
12425                   QVariant_destroy(v2);
12426                   QListWidgetItem_setIcon(item, TQtImage(Bmp.Handle).AsIcon)
12427                 end;
12428                 // else we are imageIndex and that''s fine.
12429               end else
12430               begin
12431                 v2 := QVariant_create(AImageIndex);
12432                 QListWidgetItem_setData(item, QtListViewOwnerDataRole, v2);
12433                 QVariant_destroy(v2);
12434                 QListWidgetItem_setIcon(item, TQtImage(Bmp.Handle).AsIcon);
12435               end;
12436             finally
12437               Bmp.Free;
12438             end;
12439           end else
12440           if (AImageIndex < 0) then
12441           begin
12442             v2 := QVariant_create;
12443             AIcon := QIcon_create;
12444             try
12445               QListWidgetItem_data(item, v2, QtListViewOwnerDataRole);
12446               if not QVariant_isNull(v2) then
12447               begin
12448                 v3 := QVariant_create;
12449                 try
12450                   QListWidgetItem_setData(item, QtListViewOwnerDataRole, v3);
12451                 finally
12452                   QVariant_destroy(v3);
12453                 end;
12454               end;
12455               QListWidgetItem_icon(item, AIcon);
12456               if not QIcon_isNull(AIcon) then
12457                 QListWidgetItem_setIcon(item, nil);
12458             finally
12459               QVariant_destroy(v2);
12460               QIcon_destroy(AIcon);
12461             end;
12462           end;
12463         end;
12464 
12465         WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].Caption);
12466 
12467         // reduce paint overhead by checking text
12468         v := QVariant_create();
12469         QListWidgetItem_data(item, v, Ord(QtDisplayRole));
12470         if QVariant_isValid(v) then
12471           QVariant_toString(v, @DataStr)
12472         else
12473           DataStr := '';
12474         QVariant_destroy(v);
12475 
12476         // ASelected := not TCustomListViewHack(LCLObject).Items[TopItem].Selected;
12477 
12478         if (DataStr <> WStr) then
12479         begin
12480           v := QVariant_create(PWideString(@WStr));
12481           try
12482             QListWidgetItem_setData(item, Ord(QtDisplayRole), v);
12483           finally
12484             QVariant_destroy(v);
12485           end;
12486         end;
12487 
12488         // if (QListWidgetItem_isSelected(Item) <> ASelected) then
12489         //  QListWidgetItem_setSelected(Item, ASelected);
12490 
12491       end else
12492         break;
12493 
12494       inc(i, RowHeight);
12495     end;
12496   end;
12497 end;
12498 
TQtListWidget.GetItemFlagsnull12499 function TQtListWidget.GetItemFlags(AIndex: Integer): QtItemFlags;
12500 var
12501   AItem: QListWidgetItemH;
12502 begin
12503   Result := inherited GetItemFlags(AIndex);
12504   AItem := getItem(AIndex);
12505   if Assigned(AItem) then
12506     Result := QListWidgetItem_flags(AItem);
12507 end;
12508 
12509 procedure TQtListWidget.SetItemFlags(AIndex: Integer; AValue: QtItemFlags);
12510 var
12511   AItem: QListWidgetItemH;
12512 begin
12513   inherited SetItemFlags(AIndex, AValue);
12514   AItem := getItem(AIndex);
12515   if Assigned(AItem) then
12516     QListWidgetItem_setFlags(AItem, AValue);
12517 end;
12518 
12519 procedure TQtListWidget.AttachEvents;
12520 begin
12521   inherited AttachEvents;
12522 
12523   FCurrentItemChangedHook := QListWidget_hook_create(Widget);
12524   FSelectionChangeHook := QListWidget_hook_create(Widget);
12525   FItemClickedHook := QListWidget_hook_create(Widget);
12526   FItemTextChangedHook := QListWidget_hook_create(Widget);
12527 
12528   // used only when we are handle of TListView
12529   QListWidget_hook_hook_currentItemChanged(FCurrentItemChangedHook,
12530     @signalCurrentItemChanged);
12531 
12532   // OnSelectionChange event (listbox)
12533   QListWidget_hook_hook_itemSelectionChanged(FSelectionChangeHook, @signalSelectionChanged);
12534   QListWidget_hook_hook_itemClicked(FItemClickedHook, @signalItemClicked);
12535   QListWidget_hook_hook_currentTextChanged(FItemTextChangedHook, @signalItemTextChanged);
12536 end;
12537 
12538 procedure TQtListWidget.DetachEvents;
12539 begin
12540   if FCurrentItemChangedHook <> nil then
12541   begin
12542     QListWidget_hook_destroy(FCurrentItemChangedHook);
12543     FCurrentItemChangedHook := nil;
12544   end;
12545   if FSelectionChangeHook <> nil then
12546   begin
12547     QListWidget_hook_destroy(FSelectionChangeHook);
12548     FSelectionChangeHook := nil;
12549   end;
12550   if FItemClickedHook <> nil then
12551   begin
12552     QListWidget_hook_destroy(FItemClickedHook);
12553     FItemClickedHook := nil;
12554   end;
12555   if FItemTextChangedHook <> nil then
12556   begin
12557     QListWidget_hook_destroy(FItemTextChangedHook);
12558     FItemTextChangedHook := nil;
12559   end;
12560 
12561   inherited DetachEvents;
12562 end;
12563 
12564 procedure TQtListWidget.InitializeWidget;
12565 begin
12566   inherited InitializeWidget;
12567   // by default horz scrollbars is off. it is set by SetScrollWidth
12568   setScrollBarPolicy(False, QtScrollBarAlwaysOff);
12569 end;
12570 
TQtListWidget.EventFilternull12571 function TQtListWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
12572   cdecl;
12573 var
12574   ev: QEventH;
12575 begin
12576   Result := False;
12577   QEvent_accept(Event);
12578   if LCLObject = nil then
12579     exit;
12580 
12581   if (FChildOfComplexWidget = ccwComboBox) and (FOwner <> nil) then
12582   begin
12583     case QEvent_type(Event) of
12584       QEventHide:
12585       begin
12586         {we must delay SlotDropDownVisiblity according to #9574
12587          so order is OnChange(if editable)->OnSelect->OnCloseUp }
12588         ev := QEvent_create(QEventHideToParent);
12589         QCoreApplication_postEvent(Sender, ev);
12590       end;
12591       QEventHideToParent: TQtComboBox(FOwner).SlotDropListVisibility(False);
12592     end;
12593   end else
12594   begin
12595     if (QEvent_type(Event) = QEventResize) then
12596       // let the viewport send resize
12597     else
12598     if (QEvent_type(Event) = QEventMouseButtonPress) or
12599       (QEvent_type(Event) = QEventMouseButtonRelease) then
12600       {eat mouse button events when we are TListView class.
12601        Such events are handled by itemViewportEventFilter.
12602        With Qt TListBox and TCheckListBox are also affected. issue #21318}
12603     else
12604     begin
12605       Result:=inherited EventFilter(Sender, Event);
12606       if Checkable and
12607         (QEvent_type(Event) = QEventKeyPress) and
12608         (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) then
12609       begin
12610         if CurrentItem <> nil then
12611         begin
12612           HandleCheckChangedEvent(QtPoint(0, 0), currentItem, Event);
12613           if OwnerDrawn and not (Self is TQtCheckListBox) then
12614           begin
12615             if QListWidgetItem_checkState(currentItem) = QtUnChecked then
12616               QListWidgetItem_setCheckState(currentItem, QtChecked)
12617             else
12618               QListWidgetItem_setCheckState(currentItem, QtUnchecked);
12619           end;
12620         end;
12621       end;
12622     end;
12623   end;
12624 end;
12625 
12626 procedure TQtListWidget.HandleCheckChangedEvent(const AMousePos: TQtPoint;
12627   AItem: QListWidgetItemH; AEvent: QEventH);
12628 var
12629   xx: Integer;
12630   B: Boolean;
12631 
12632   procedure SendMessage(AnItem: QListWidgetItemH);
12633   var
12634     Msg: TLMNotify;
12635     NMLV: TNMListView;
12636   begin
12637     FillChar(Msg{%H-}, SizeOf(Msg), #0);
12638     FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
12639 
12640     Msg.Msg := CN_NOTIFY;
12641 
12642     NMLV.hdr.hwndfrom := HWND(Self);
12643     NMLV.hdr.code := LVN_ITEMCHANGED;
12644 
12645     NMLV.iItem := QListWidget_row(QListWidgetH(Widget), AnItem);
12646 
12647     NMLV.uNewState := UINT(B);
12648     NMLV.uChanged := LVIF_STATE;
12649 
12650     Msg.NMHdr := @NMLV.hdr;
12651 
12652     // DebugLn('HandleCheckableMouseDown sending LVN_ITEMCHANGED ...');
12653     DeliverMessage(Msg);
12654   end;
12655 begin
12656   if not Checkable or (AItem = nil) or (ViewStyle < 0) then
12657     exit;
12658 
12659   if ((QEvent_type(AEvent) = QEventMouseButtonPress) or
12660     (QEvent_type(AEvent) = QEventMouseButtonDblClick)) and
12661   (QMouseEvent_button(QMouseEventH(AEvent)) = QtLeftButton) then
12662   begin
12663     if (QListWidgetItem_flags(AItem) and QtItemIsUserCheckable) <> 0 then
12664     begin
12665       xx := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
12666       if ((AMousePos.X > 2) and (AMousePos.X <= (xx + 2))) then
12667       begin
12668         B := QListWidgetItem_checkState(AItem) = QtUnChecked;
12669         if B then
12670           SetItemLastCheckStateInternal(AItem, QtChecked)
12671         else
12672           SetItemLastCheckStateInternal(AItem, QtUnChecked);
12673 
12674         // if AItem is deleted in mouse event FDelayedCheckItem becomes nil and that's fine. issue #32869
12675         FDelayedCheckItem := AItem;
12676         SendMessage(AItem);
12677       end;
12678     end;
12679   end else
12680   if QEvent_type(AEvent) = LCLQt_ItemViewAfterMouseRelease then
12681   begin
12682     if (FDelayedCheckItem <> nil) and (FDelayedCheckItem <> AItem) then
12683     begin
12684       SetItemLastCheckStateInternal(FDelayedCheckItem, QListWidgetItem_checkState(FDelayedCheckItem));
12685       SendMessage(FDelayedCheckItem);
12686     end;
12687     FDelayedCheckItem := nil;
12688     SetItemLastCheckStateInternal(AItem, QListWidgetItem_checkState(AItem));
12689     SendMessage(AItem);
12690   end else
12691   if (QEvent_type(AEvent) = QEventKeyPress) and
12692     (QKeyEvent_key(QKeyEventH(AEvent)) = QtKey_Space) then
12693   begin
12694     FDelayedCheckItem := nil;
12695     B := QListWidgetItem_checkState(AItem) = QtUnChecked;
12696     if B then
12697       SetItemLastCheckStateInternal(AItem, QtChecked)
12698     else
12699       SetItemLastCheckStateInternal(AItem, QtUnChecked);
12700 
12701     SendMessage(AItem);
12702   end;
12703 end;
12704 
itemViewViewportEventFilternull12705 function TQtListWidget.itemViewViewportEventFilter(Sender: QObjectH;
12706   Event: QEventH): Boolean; cdecl;
12707 var
12708   Item, CurrItem: QListWidgetItemH;
12709   MousePos: TQtPoint;
12710   X: Integer;
12711   Arr: TPtrIntArray;
12712   Modifiers: QtKeyboardModifiers;
12713   ItemRow, CurrItemRow: Integer;
12714   ALCLEvent: QLCLMessageEventH;
12715   R: TRect;
12716   DC: TQtDeviceContext;
12717   AMsgData: PtrUInt;
12718 
12719   procedure SendEventToParent;
12720   begin
12721     //issue #21318
12722     SlotMouse(Widget, Event);
12723   end;
12724 
12725 begin
12726   Result := False;
12727   QEvent_accept(Event);
12728 
12729   if (FChildOfComplexWidget = ccwComboBox) and (FOwner <> nil) then
12730   begin
12731     if QEvent_type(Event) = QEventShow then
12732       TQtComboBox(FOwner).FixMouseUp;
12733     exit;
12734   end;
12735 
12736   if (LCLObject <> nil) then
12737   begin
12738     if ViewStyle >= 0 then
12739     begin
12740       if (QEvent_type(Event) = QEventPaint) and (Sender = viewportWidget) then
12741       begin
12742         HasPaint := True;
12743         QPaintEvent_rect(QPaintEventH(Event), @R);
12744         if FOwnerData then
12745           OwnerDataNeeded(R);
12746         DC := TQtDeviceContext.Create(QWidgetH(Sender), True);
12747         try
12748           TCustomListViewAccess(LCLObject).Canvas.handle := HDC(DC);
12749           TCustomListViewAccess(LCLObject).IntfCustomDraw(dtControl, cdPrePaint, 0, 0, [], @R);
12750         finally
12751           TCustomListViewAccess(LCLObject).Canvas.handle := 0;
12752           DC.Free;
12753         end;
12754       end else
12755       if getEnabled and (QEvent_type(Event) = LCLQt_ItemViewAfterMouseRelease) then
12756       begin
12757         ALCLEvent := QLCLMessageEventH(Event);
12758         Item := QListWidgetItemH(QLCLMessageEvent_getLParam(ALCLEvent));
12759         // sync lcl with qt state. This is needed only when mouse is pressed
12760         // and moved out of item, or pressed on item and released over checkbox
12761         if (Item <> nil) and (GetItemLastCheckState(Item) <>
12762           QListWidgetItem_checkState(Item)) then
12763         begin
12764           MousePos := QtPoint(0, 0); // shutup compiler
12765           if QLCLMessageEvent_getMsg(ALCLEvent) > 0 then
12766             QListWidgetItem_setCheckState(Item, GetItemLastCheckState(Item));
12767           HandleCheckChangedEvent(MousePos, Item, Event);
12768         end;
12769       end else
12770       if getEnabled and (QEvent_type(Event) = QEventMouseButtonRelease) then
12771       begin
12772         if OwnerDrawn and Checkable then
12773         begin
12774           // MousePos :=
12775           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
12776           Item := itemAt(MousePos.x, MousePos.y);
12777 
12778           if (Item <> nil) and
12779             ((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
12780           begin
12781             x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
12782             if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
12783             begin
12784               if QListWidgetItem_checkState(Item) = QtUnchecked then
12785                 QListWidgetItem_setCheckState(Item, QtChecked)
12786               else
12787                 QListWidgetItem_setCheckState(Item, QtUnChecked);
12788             end;
12789           end;
12790           Result := SlotMouse(Sender, Event);
12791         end else
12792         begin
12793           PostponedMouseRelease(Event);
12794           if Checkable then
12795           begin
12796             // MousePos :=
12797             QMouseEvent_pos(QMouseEventH(Event), @MousePos);
12798             Item := itemAt(MousePos.x, MousePos.y);
12799             if (Item <> nil) then
12800             begin
12801               if Assigned(LCLObject) and LCLObject.Dragging then
12802                 AMsgData := Ord(QListWidgetItem_checkState(Item)) + 1
12803               else
12804                 AMsgData := 0;
12805               ALCLEvent := QLCLMessageEvent_create(LCLQt_ItemViewAfterMouseRelease, AMsgData,
12806                 PtrUInt(Item), PtrUInt(Item), 0);
12807               QCoreApplication_postEvent(Sender, ALCLEvent);
12808             end;
12809           end;
12810         end;
12811       end else
12812       begin
12813         if getEnabled and (QEvent_type(Event) = QEventMouseButtonPress) then
12814         begin
12815           // MousePos :=
12816           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
12817           Item := itemAt(MousePos.x, MousePos.y);
12818           if Item = nil then
12819             FSavedSelection := selectedItems
12820           else
12821           begin
12822             // qt selection in QListWidget is ugly, and LCL needs that info
12823             // when mouse button is pressed, not after that, so we
12824             // trigger selectionChanged() here
12825             // Multiselection needs special handling to get proper
12826             // order of OnSelectItem.
12827             if (getSelectionMode > QAbstractItemViewSingleSelection) or FOwnerData then
12828             begin
12829               Modifiers := QInputEvent_modifiers(QInputEventH(Event));
12830               SlotMouse(Sender, Event);
12831 
12832               HandleCheckChangedEvent(MousePos, Item, Event);
12833 
12834               if not QListWidgetItem_isSelected(Item) then
12835               begin
12836                 if Modifiers = 0 then
12837                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
12838                     QItemSelectionModelClearAndSelect or QItemSelectionModelCurrent)
12839                 else
12840                 if (Modifiers and QtControlModifier <> 0) then
12841                 begin
12842                   X := getSelCount;
12843                   // DebugLn('**** Called SELECT IN 1 X=', dbgs(X),' is curr ? ',dbgs(CurrentItem = Item));
12844                   if CurrentItem = Item then
12845                     X := 0;
12846                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
12847                     QItemSelectionModelSelect);
12848                   if (X <= 1) then
12849                     signalCurrentItemChanged(Item, nil);
12850                 end else
12851                 if (Modifiers and QtShiftModifier <> 0) then
12852                 begin
12853                   // select this and all other's (calculate is it up or down)
12854                   X := getSelCount;
12855                   CurrItem := currentItem; //<-- doesn't smell good with QtShiftModifier
12856                   if CurrItem = nil then // <-- do not crash
12857                     CurrItem := Item;
12858                   ItemRow := getRow(Item);
12859                   CurrItemRow := getRow(CurrItem);
12860                   if (ItemRow < CurrItemRow) and (ItemRow >= 0) then
12861                   begin
12862                     for x := CurrItemRow + 1 to rowCount - 1 do
12863                     begin
12864                       CurrItem := getItem(x);
12865                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
12866                         QItemSelectionModelClear or QItemSelectionModelDeselect);
12867                     end;
12868                     for x := CurrItemRow downto ItemRow do
12869                     begin
12870                       CurrItem := getItem(x);
12871                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
12872                         QItemSelectionModelSelect);
12873                     end;
12874                   end else
12875                   if (ItemRow > CurrItemRow) then
12876                   begin
12877                     for x := 0 to CurrItemRow - 1 do
12878                     begin
12879                       CurrItem := getItem(x);
12880                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
12881                         QItemSelectionModelClear or QItemSelectionModelDeselect);
12882                     end;
12883                     for x := ItemRow downto CurrItemRow do
12884                     begin
12885                       CurrItem := getItem(x);
12886                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
12887                         QItemSelectionModelSelect);
12888                     end;
12889                   end;
12890                 end;
12891               end else
12892               begin
12893                 X := getSelCount;
12894                 if (Modifiers = 0) and (X > 1) then
12895                 begin
12896                   Arr := selectedItems;
12897                   for x := 0 to High(Arr) do
12898                   begin
12899                     if QListWidgetItemH(Arr[x]) <> Item then
12900                       QListWidget_setCurrentItem(QListWidgetH(Widget),
12901                         QListWidgetItemH(Arr[x]), QItemSelectionModelDeSelect);
12902                   end;
12903                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
12904                     QItemSelectionModelSelectCurrent);
12905                 end else
12906                 if (Modifiers and QtControlModifier <> 0) then
12907                 begin
12908                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
12909                     QItemSelectionModelDeSelect);
12910                   if (X = 1) or (currentItem = Item) then
12911                     signalCurrentItemChanged(nil, Item);
12912                 end;
12913               end;
12914               QEvent_ignore(Event);
12915               Result := True;
12916               exit;
12917             end else
12918             begin
12919               SlotMouse(Sender, Event);
12920               HandleCheckChangedEvent(MousePos, Item, Event);
12921               if not QListWidgetItem_isSelected(Item) then
12922                 QListWidget_setCurrentItem(QListWidgetH(Widget), Item, QItemSelectionModelClearAndSelect);
12923               QEvent_ignore(Event);
12924               Result := True;
12925               exit;
12926             end;
12927           end;
12928         end;
12929 
12930         if getEnabled and Checkable and (QEvent_type(Event) = QEventMouseButtonDblClick) then
12931         begin
12932           // MousePos :=
12933           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
12934           Item := itemAt(MousePos.x, MousePos.y);
12935           if Item <> nil then
12936             HandleCheckChangedEvent(MousePos, Item, Event);
12937         end;
12938 
12939         Result := inherited itemViewViewportEventFilter(Sender, Event);
12940       end;
12941     end else
12942     case QEvent_type(Event) of
12943       QEventMouseButtonPress,
12944       QEventMouseButtonRelease,
12945       QEventMouseButtonDblClick:
12946       begin
12947         if getEnabled and Checkable and
12948           (QEvent_type(Event) <> QEventMouseButtonDblClick) and
12949           (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
12950         begin
12951           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
12952           Item := itemAt(MousePos.x, MousePos.y);
12953           if (Item <> nil) and
12954             ((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
12955           begin
12956             x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
12957             if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
12958             begin
12959               FCheckBoxClicked := True;
12960               SetItemLastCheckState(Item);
12961               {signalItemClicked() fires !}
12962             end else
12963               SendEventToParent;
12964           end else
12965             SendEventToParent;
12966         end else
12967           SendEventToParent;
12968       end;
12969     else
12970       Result := inherited itemViewViewportEventFilter(Sender, Event);
12971     end;
12972   end;
12973 end;
12974 
12975 procedure TQtListWidget.signalCurrentItemChanged(current: QListWidgetItemH;
12976   previous: QListWidgetItemH); cdecl;
12977 var
12978   Msg: TLMNotify;
12979   NMLV: TNMListView;
12980   ASubIndex: Integer;
12981   AIndex: Integer;
12982 begin
12983   // only when TQtListWidget is handle of TListView !
12984   if ViewStyle = -1 then
12985     exit;
12986 
12987   FillChar(Msg{%H-}, SizeOf(Msg), #0);
12988   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
12989 
12990   Msg.Msg := CN_NOTIFY;
12991 
12992   NMLV.hdr.hwndfrom := LCLObject.Handle;
12993   NMLV.hdr.code := LVN_ITEMCHANGING;
12994 
12995   if Current <> nil then
12996     AIndex := getRow(Current)
12997   else
12998     AIndex := -1;
12999 
13000   ASubIndex := 0;
13001 
13002   NMLV.iItem := AIndex;
13003   NMLV.iSubItem := ASubIndex;
13004   NMLV.uNewState := LVIS_SELECTED;
13005   NMLV.uChanged := LVIF_STATE;
13006 
13007   Msg.NMHdr := @NMLV.hdr;
13008   DeliverMessage(Msg);
13009 
13010   // if getSelectionMode > QAbstractItemViewSingleSelection then
13011   //  DebugLn('*** MultiSelect: SignalCurrentItemChanged Current ',dbgs(Current),' Previous ',dbgs(Previous));
13012 
13013   FSyncingItems := True;
13014   try
13015     if Current <> nil then
13016     begin
13017       FillChar(Msg, SizeOf(Msg), #0);
13018       FillChar(NMLV, SizeOf(NMLV), #0);
13019       Msg.Msg := CN_NOTIFY;
13020       NMLV.hdr.hwndfrom := LCLObject.Handle;
13021       NMLV.hdr.code := LVN_ITEMCHANGED;
13022       NMLV.iItem := AIndex;
13023       NMLV.iSubItem := ASubIndex;
13024       if QListWidget_isItemSelected(QListWidgetH(Widget), Current) then
13025         NMLV.uNewState := LVIS_SELECTED
13026       else
13027         NMLV.uOldState := LVIS_SELECTED;
13028       NMLV.uChanged := LVIF_STATE;
13029       Msg.NMHdr := @NMLV.hdr;
13030       DeliverMessage(Msg);
13031 
13032       // send focused msg
13033       NMLV.uOldState := 0;
13034       NMLV.uNewState := LVIS_FOCUSED;
13035       NMLV.uChanged := LVIF_STATE;
13036       Msg.NMHdr := @NMLV.hdr;
13037       DeliverMessage(Msg);
13038 
13039     end;
13040 
13041     if Previous <> nil then
13042     begin
13043       FillChar(Msg, SizeOf(Msg), #0);
13044       FillChar(NMLV, SizeOf(NMLV), #0);
13045       Msg.Msg := CN_NOTIFY;
13046       NMLV.hdr.hwndfrom := LCLObject.Handle;
13047       NMLV.hdr.code := LVN_ITEMCHANGED;
13048       NMLV.iItem := getRow(Previous);
13049       ASubIndex := 0;
13050       NMLV.iSubItem := ASubIndex;
13051       if QListWidget_isItemSelected(QListWidgetH(Widget), Previous) then
13052         NMLV.uNewState := LVIS_SELECTED
13053       else
13054         NMLV.uOldState := LVIS_SELECTED;
13055       NMLV.uChanged := LVIF_STATE;
13056       Msg.NMHdr := @NMLV.hdr;
13057       DeliverMessage(Msg);
13058     end;
13059   finally
13060     FSyncingItems := False;
13061   end;
13062 end;
13063 
13064 {------------------------------------------------------------------------------
13065   Function: TQtListWidget.SlotSelectionChange
13066   Params:  None
13067   Returns: Nothing
13068  ------------------------------------------------------------------------------}
13069 
13070 procedure TQtListWidget.signalSelectionChanged(); cdecl;
13071 var
13072   Msg: TLMessage;
13073   i: Integer;
13074   Item: QListWidgetItemH;
13075 begin
13076   {$ifdef VerboseQt}
13077     WriteLn('TQtListWidget.signalSelectionChange');
13078   {$endif}
13079 
13080   if FDontPassSelChange then
13081   begin
13082     FDontPassSelChange := False;
13083     Exit;
13084   end;
13085 
13086   if (ViewStyle >= 0) and (InUpdate or
13087     (not InUpdate and (length(FSavedSelection) = 0)) ) then
13088     exit;
13089 
13090   FillChar(Msg{%H-}, SizeOf(Msg), #0);
13091   Msg.Msg := LM_SELCHANGE;
13092   if (FChildOfComplexWidget <> ccwComboBox) then
13093   begin
13094     if (ViewStyle < 0) and (getSelCount > 0) then
13095       DeliverMessage(Msg)
13096     else
13097     if (ViewStyle >= 0) then
13098     begin
13099       if getSelCount = 0 then
13100       begin
13101         for i := 0 to High(FSavedSelection) do
13102         begin
13103           Item := QListWidgetItemH(FSavedSelection[i]);
13104           if (Item <> nil) then
13105             signalCurrentItemChanged(nil, Item);
13106         end;
13107       end;
13108       setLength(FSavedSelection, 0);
13109     end;
13110   end;
13111 end;
13112 
13113 procedure TQtListWidget.signalItemTextChanged(ANewText: PWideString); cdecl;
13114 var
13115   Msg: TLMessage;
13116 begin
13117   {$ifdef VerboseQt}
13118     WriteLn('TQtListWidget.signalItemTextChanged');
13119   {$endif}
13120   FillChar(Msg{%H-}, SizeOf(Msg), #0);
13121   Msg.Msg := CM_TEXTCHANGED;
13122   DeliverMessage(Msg);
13123 end;
13124 
13125 procedure TQtListWidget.signalItemClicked(item: QListWidgetItemH); cdecl;
13126 var
13127   Msg: TLMessage;
13128   ItemRow: Integer;
13129   MsgN: TLMNotify;
13130   NMLV: TNMListView;
13131   R: TRect;
13132   Pt: TPoint;
13133 begin
13134   {$ifdef VerboseQt}
13135     WriteLn('TQtListWidget.signalItemClicked');
13136   {$endif}
13137   if (ViewStyle >= 0) and (FChildOfComplexWidget <> ccwComboBox) then
13138   begin
13139     FillChar(MsgN{%H-}, SizeOf(MsgN), #0);
13140     FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
13141 
13142     MsgN.Msg := LM_CLICKED;
13143 
13144     NMLV.hdr.hwndfrom := LCLObject.Handle;
13145     NMLV.hdr.code := NM_CLICK;
13146 
13147     NMLV.iItem := getRow(Item);
13148 
13149     NMLV.iSubItem := 0;
13150     NMLV.uNewState := UINT(NM_CLICK);
13151     NMLV.uChanged :=  LVIS_SELECTED;
13152 
13153     QListWidget_visualItemRect(QListWidgetH(Widget), @R, Item);
13154 
13155     pt.X := R.Left;
13156     pt.Y := R.Top;
13157 
13158     NMLV.ptAction := pt;
13159 
13160     MsgN.NMHdr := @NMLV.hdr;
13161 
13162     DeliverMessage(MsgN);
13163   end;
13164 
13165   if Checkable then
13166   begin
13167     FillChar(Msg{%H-}, SizeOf(Msg), #0);
13168     Msg.Msg := LM_CHANGED;
13169     ItemRow := QListWidget_row(QListWidgetH(Widget), Item);
13170     Msg.WParam := ItemRow;
13171     DeliverMessage(Msg);
13172   end;
13173 
13174 end;
13175 
13176 procedure TQtListWidget.ItemDelegatePaint(painter: QPainterH;
13177   option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
13178 var
13179   Msg: TLMDrawListItem;
13180   DrawStruct: TDrawListItemStruct;
13181   State: QStyleState;
13182   R: TRect;
13183   ItemIndex, SubItemIndex: Integer;
13184   ACustomState: TCustomDrawState;
13185   ATarget: TCustomDrawTarget;
13186   TmpDC1, TmpDC2: HDC;
13187   SkipDefault: Boolean;
13188   Item: QListWidgetItemH;
13189   APaintResult: TCustomDrawResult;
13190 begin
13191   if (ViewStyle >= 0) and not (FChildOfComplexWidget = ccwComboBox) then
13192   begin
13193     State := QStyleOption_state(option);
13194     ACustomState := [cdsDefault];
13195     (*
13196     cdsSelected,
13197     cdsGrayed,
13198     cdsDisabled,
13199     cdsChecked,
13200     cdsFocused,
13201     cdsDefault,
13202     cdsHot,
13203     cdsMarked,
13204     cdsIndeterminate
13205     *)
13206 
13207     if (State and QStyleState_Selected) <> 0 then
13208       Include(ACustomState, cdsSelected);
13209     // disabled
13210     if (State and QStyleState_Enabled) = 0 then
13211       Include(ACustomState, cdsDisabled);
13212     // focused (QStyleState_FocusAtBorder?)
13213     if (State and QStyleState_HasFocus) <> 0 then
13214       Include(ACustomState, cdsFocused);
13215     // hotlight
13216     if (State and QStyleState_MouseOver) <> 0 then
13217       Include(ACustomState, cdsHot);
13218 
13219     ItemIndex := QModelIndex_row(index);
13220     SubItemIndex := QModelIndex_column(index);
13221 
13222     // checked does not work under qt for some reason ?!?
13223     if Checkable then
13224     begin
13225       // if (State and QStyleState_On <> 0) then
13226       //  Include(ACustomState, cdsChecked);
13227       Item := getItem(ItemIndex);
13228       if Assigned(Item) and (QListWidgetItem_checkState(Item) = QtChecked) then
13229         Include(ACustomState, cdsChecked);
13230     end;
13231 
13232     QStyle_drawControl(QApplication_style, QStyleCE_ItemViewItem, Option, painter, viewportWidget);
13233 
13234     // NOW WE ARE DRAWING ITEMS ...
13235     QPainter_save(painter);
13236     if TCustomListView(LCLObject).Canvas.HandleAllocated then
13237       TmpDC2 := TCustomListView(LCLObject).Canvas.GetUpdatedHandle([csHandleValid])
13238     else
13239       TmpDC2 := 0;
13240     TmpDC1 := HDC(TQtDeviceContext.CreateFromPainter(painter));
13241     TCustomListView(LCLObject).Canvas.Handle := TmpDC1;
13242     try
13243       R := visualRect(index);
13244 
13245       if SubItemIndex <= 0 then
13246         ATarget := dtItem
13247       else
13248         ATarget := dtSubItem;
13249 
13250       // here we do only OnCustomDrawItem and OnCustomDrawSubItem
13251       // OnCustomDraw is done inside itemViewportEventFilter.
13252 
13253       APaintResult := TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPrePaint, ItemIndex, SubItemIndex, ACustomState, @R);
13254       SkipDefault := cdrSkipDefault in APaintResult;
13255 
13256       if not SkipDefault then // do default paint by unknown magic
13257         QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
13258 
13259       // issue #27315
13260       if cdrNotifyPostpaint in APaintResult then
13261         TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPostPaint, ItemIndex, SubItemIndex, ACustomState, @R);
13262 
13263     finally
13264       TCustomListView(LCLObject).Canvas.Handle := TmpDC2;
13265       TQtDeviceContext(TmpDC1).Free;
13266       QPainter_restore(painter);
13267     end;
13268   end else
13269   begin
13270     QPainter_save(painter);
13271     State := QStyleOption_state(option);
13272     DrawStruct.ItemID := UINT(QModelIndex_row(index));
13273 
13274     DrawStruct.Area := visualRect(index);
13275     DrawStruct.DC := HDC(TQtDeviceContext.CreateFromPainter(painter));
13276 
13277     DrawStruct.ItemState := [];
13278     // selected
13279     if (State and QStyleState_Selected) <> 0 then
13280       Include(DrawStruct.ItemState, odSelected);
13281     // disabled
13282     if (State and QStyleState_Enabled) = 0 then
13283       Include(DrawStruct.ItemState, odDisabled);
13284     // focused (QStyleState_FocusAtBorder?)
13285     if (State and QStyleState_HasFocus) <> 0 then
13286       Include(DrawStruct.ItemState, odFocused);
13287     // hotlight
13288     if (State and QStyleState_MouseOver) <> 0 then
13289       Include(DrawStruct.ItemState, odHotLight);
13290     // checked
13291     if Checkable then
13292     begin
13293       // if (State and QStyleState_On <> 0) then
13294       //  Include(ACustomState, cdsChecked);
13295       Item := getItem(QModelIndex_row(index));
13296       if Assigned(Item) and (QListWidgetItem_checkState(Item) = QtChecked) then
13297         Include(DrawStruct.ItemState, odChecked);
13298     end;
13299 
13300     { todo: over states:
13301 
13302       odGrayed, odChecked,
13303       odDefault, odInactive, odNoAccel,
13304       odNoFocusRect, odReserved1, odReserved2, odComboBoxEdit
13305     }
13306     Msg.Msg := LM_DRAWLISTITEM;
13307     Msg.DrawListItemStruct := @DrawStruct;
13308     DeliverMessage(Msg);
13309 
13310     QPainter_restore(painter);
13311 
13312     TQtDeviceContext(DrawStruct.DC).Free;
13313   end;
13314 end;
13315 
13316 procedure TQtListWidget.clearSelection;
13317 begin
13318   inherited clearSelection;
13319   SetLength(FSavedSelection, 0);
13320 end;
13321 
13322 procedure TQtListWidget.ClearItems;
13323 begin
13324   SetLength(FSavedSelection, 0);
13325   QListWidget_clear(QListWidgetH(Widget));
13326 end;
13327 
13328 {------------------------------------------------------------------------------
13329   Function: TQtListWidget.currentRow
13330   Params:  None
13331   Returns: Nothing
13332  ------------------------------------------------------------------------------}
currentRownull13333 function TQtListWidget.currentRow: Integer;
13334 begin
13335   Result := QListWidget_currentRow(QListWidgetH(Widget));
13336 end;
13337 
currentItemnull13338 function TQtListWidget.currentItem: QListWidgetItemH;
13339 begin
13340   Result := QListWidget_currentItem(QListWidgetH(Widget));
13341 end;
13342 
IndexAtnull13343 function TQtListWidget.IndexAt(APoint: PQtPoint): Integer;
13344 var
13345   AModelIndex: QModelIndexH;
13346 begin
13347   AModelIndex := QModelIndex_create();
13348   QListView_indexAt(QListWidgetH(Widget), AModelIndex, APoint);
13349   Result := QModelIndex_row(AModelIndex);
13350   QModelIndex_destroy(AModelIndex);
13351 end;
13352 
13353 procedure TQtListWidget.insertItem(AIndex: Integer; AText: String);
13354 var
13355   Str: WideString;
13356 begin
13357   Str := GetUtf8String(AText);
13358   insertItem(AIndex, @Str);
13359 end;
13360 
13361 procedure TQtListWidget.insertItem(AIndex: Integer; AText: PWideString);
13362 var
13363   Item: QListWidgetItemH;
13364 begin
13365   Item := QListWidgetItem_create(AText, nil, Ord(QListWidgetItemType));
13366   if Checkable then
13367     QListWidgetItem_setCheckState(Item, QtUnChecked)
13368   else
13369   if (ViewStyle = Ord(vsIcon)) and not (FChildOfComplexWidget = ccwComboBox) then
13370     QListWidgetItem_setTextAlignment(Item, QtAlignHCenter);
13371   QListWidget_insertItem(QListWidgetH(Widget), AIndex, Item);
13372 end;
13373 
itemAtnull13374 function TQtListWidget.itemAt(APoint: TPoint): QListWidgetItemH;
13375 begin
13376   Result := ItemAt(APoint.X, APoint.Y);
13377 end;
13378 
itemAtnull13379 function TQtListWidget.itemAt(x: Integer; y: Integer): QListWidgetItemH;
13380 begin
13381   Result := QListWidget_itemAt(QListWidgetH(Widget), x, y);
13382 end;
13383 
getItemnull13384 function TQtListWidget.getItem(AIndex: Integer): QListWidgetItemH;
13385 begin
13386   if (AIndex >= 0) and (AIndex < rowCount) then
13387     Result := QListWidget_item(QListWidgetH(Widget), AIndex)
13388   else
13389     Result := nil;
13390 end;
13391 
getItemSelectednull13392 function TQtListWidget.getItemSelected(AItem: QListWidgetItemH): Boolean;
13393 begin
13394   if AItem <> nil then
13395     Result := QListWidget_isItemSelected(QListWidgetH(Widget), AItem)
13396   else
13397     Result := False;
13398 end;
13399 
getItemVisiblenull13400 function TQtListWidget.getItemVisible(AItem: QListWidgetItemH): Boolean;
13401 begin
13402   if AItem = nil then
13403     Result := False
13404   else
13405     Result := not QListWidget_isItemHidden(QListWidgetH(Widget), AItem);
13406 end;
13407 
getRownull13408 function TQtListWidget.getRow(AItem: QListWidgetItemH): integer;
13409 begin
13410   if AItem = nil then
13411     Result := -1
13412   else
13413     Result := QListWidget_row(QListWidgetH(Widget), AItem);
13414 end;
13415 
getSelCountnull13416 function TQtListWidget.getSelCount: Integer;
13417 begin
13418   Result := length(selectedItems);
13419 end;
13420 
getTopItemnull13421 function TQtListWidget.getTopItem: integer;
13422 begin
13423   Result := getVisibleRowCount(True);
13424 end;
13425 
13426 {------------------------------------------------------------------------------
13427   Function: TQtListWidget.getVisibleRowCount
13428   Params:  Boolean
13429   Returns: if AFirstVisibleOnly = False (default) then it returns number
13430   of visible rows, or 0 if there's no visible rows.
13431   When AFirstVisibleOnly = True then it returns index of first visible row,
13432   otherwise result is -1.
13433  ------------------------------------------------------------------------------}
getVisibleRowCountnull13434 function TQtListWidget.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
13435 var
13436   R: TRect;
13437   i: integer;
13438   item: QListWidgetItemH;
13439   RowIndex: integer;
13440   RowHeight: integer;
13441 begin
13442   if AFirstVisibleOnly then
13443     Result := -1
13444   else
13445     Result := 0;
13446   QWidget_contentsRect(viewportWidget, @R);
13447   i := 0;
13448   repeat
13449     item := itemAt(0, i);
13450     if item <> nil then
13451     begin
13452       RowIndex := getRow(Item);
13453       if AFirstVisibleOnly then
13454       begin
13455         Result := RowIndex;
13456         break;
13457       end;
13458       RowHeight := getRowHeight(RowIndex);
13459       inc(Result);
13460       if RowHeight <= 0 then
13461         RowHeight := 1;
13462       inc(i, RowHeight);
13463     end else
13464       inc(i, 1);
13465   until i >= R.Bottom;
13466 end;
13467 
getVisualItemRectnull13468 function TQtListWidget.getVisualItemRect(AItem: QListWidgetItemH): TRect;
13469 begin
13470   Result := Rect(0, 0, 0, 0);
13471   if AItem <> nil then
13472     QListWidget_visualItemRect(QListWidgetH(Widget), @Result, AItem);
13473 end;
13474 
TQtListWidget.selectedItemsnull13475 function TQtListWidget.selectedItems: TPtrIntArray;
13476 begin
13477   QListWidget_selectedItems(QListWidgetH(Widget), @Result);
13478 end;
13479 
13480 {------------------------------------------------------------------------------
13481   Function: TQtListWidget.setCurrentRow
13482   Params:  None
13483   Returns: Nothing
13484  ------------------------------------------------------------------------------}
13485 procedure TQtListWidget.setCurrentRow(row: Integer);
13486 begin
13487   if (getSelectionMode <> QAbstractItemViewSingleSelection) and (row < 0) then
13488     row := 0;
13489 
13490   if currentRow <> row then
13491   begin
13492     FDontPassSelChange := True;
13493     QListWidget_setCurrentRow(QListWidgetH(Widget), row);
13494   end;
13495 end;
13496 
13497 procedure TQtListWidget.setCurrentItem(AItem: QListWidgetItemH;
13498   const AIsSet: Boolean = True);
13499 begin
13500   if AIsSet then
13501     QListWidget_setCurrentItem(QListWidgetH(Widget), AItem);
13502 end;
13503 
13504 procedure TQtListWidget.setItemText(AIndex: Integer; AText: String);
13505 var
13506   Item: QListWidgetItemH;
13507   Str: WideString;
13508   R: TRect;
13509 begin
13510   Str := GetUTF8String(AText);
13511   if (AIndex >= 0) and (AIndex < rowCount) then
13512   begin
13513     Item := getItem(AIndex);
13514     QListWidgetItem_setText(Item, @Str);
13515     {we must update our custom delegate}
13516     if OwnerDrawn then
13517     begin
13518       R := getVisualItemRect(Item);
13519       Update(@R);
13520     end;
13521   end else
13522     insertItem(AIndex, @Str);
13523 end;
13524 
13525 procedure TQtListWidget.setItemText(AIndex: Integer; AText: String;
13526   AAlignment: Integer);
13527 var
13528   Item: QListWidgetItemH;
13529   Str: WideString;
13530   R: TRect;
13531 begin
13532   Str := GetUTF8String(AText);
13533   if (AIndex >= 0) and (AIndex < rowCount) then
13534   begin
13535     Item := getItem(AIndex);
13536     QListWidgetItem_setText(Item, @Str);
13537     QListWidgetItem_setTextAlignment(Item, AAlignment);
13538     {we must update our custom delegate}
13539     if OwnerDrawn then
13540     begin
13541       R := getVisualItemRect(Item);
13542       Update(@R);
13543     end;
13544   end else
13545     insertItem(AIndex, @Str);
13546 end;
13547 
13548 procedure TQtListWidget.setItemSelected(AItem: QListWidgetItemH;
13549   const ASelect: Boolean);
13550 begin
13551   if AItem <> nil then
13552     QListWidget_setItemSelected(QListWidgetH(Widget), AItem, ASelect);
13553 end;
13554 
13555 procedure TQtListWidget.setItemVisible(AItem: QListWidgetItemH;
13556   const AVisible: Boolean);
13557 begin
13558   if AItem <> nil then
13559     QListWidget_setItemHidden(QListWidgetH(Widget), AItem, not AVisible);
13560 end;
13561 
13562 procedure TQtListWidget.setSelectionMode(AMode: QAbstractItemViewSelectionMode);
13563 var
13564   SavedItem: QListWidgetItemH;
13565   Arr: TPtrIntArray;
13566   i: Integer;
13567 begin
13568   SavedItem := nil;
13569   // this code is here due to Qt bug with QListView/QListWidget ..
13570   // QTreeWidget works correct .. clearSelection does not trigger signals
13571   // so we must do that manually.
13572   if (ViewStyle > 0) and (AMode < QAbstractItemViewMultiSelection) and
13573     (getSelectionMode > QAbstractItemViewSingleSelection) then
13574   begin
13575     SavedItem := CurrentItem;
13576     Arr := selectedItems;
13577     if not ((SavedItem <> nil) and (QListWidgetItem_isSelected(SavedItem))) then
13578     begin
13579       SavedItem := nil;
13580       if length(Arr) > 0 then
13581         SavedItem := QListWidgetItemH(Arr[0]);
13582     end;
13583     for i := 0 to High(Arr) do
13584     begin
13585       if QListWidgetItemH(Arr[i]) <> SavedItem then
13586       begin
13587         QListWidgetItem_setSelected(QListWidgetItemH(Arr[i]), False);
13588         signalCurrentItemChanged(nil, QListWidgetItemH(Arr[i]));
13589       end;
13590     end;
13591     clearSelection;
13592   end;
13593   inherited setSelectionMode(AMode);
13594   if SavedItem <> nil then
13595     setItemSelected(SavedItem, True);
13596 end;
13597 
13598 procedure TQtListWidget.scrollToItem(row: integer;
13599   hint: QAbstractItemViewScrollHint);
13600 var
13601   Item: QListWidgetItemH;
13602 begin
13603   Item := getItem(Row);
13604   QListWidget_scrollToItem(QListWidgetH(Widget), Item, hint);
13605 end;
13606 
13607 procedure TQtListWidget.removeItem(AIndex: Integer);
13608 var
13609   Item: QListWidgetItemH;
13610 begin
13611   if (currentRow = AIndex) then
13612     if (getSelectionMode = QAbstractItemViewSingleSelection) then
13613       setCurrentRow(-1);
13614   Item := QListWidget_takeitem(QListWidgetH(Widget), AIndex);
13615   if FDelayedCheckItem = Item then
13616     FDelayedCheckItem := nil;
13617   QListWidgetItem_destroy(Item);
13618 end;
13619 
TQtListWidget.rowCountnull13620 function TQtListWidget.rowCount: integer;
13621 begin
13622   Result := QListWidget_count(QListWidgetH(Widget));
13623 end;
13624 
13625 procedure TQtListWidget.ExchangeItems(const AIndex1, AIndex2: Integer);
13626 var
13627   ItemTo, ItemFrom: QListWidgetItemH;
13628   R: TRect;
13629 begin
13630   if AIndex1 = AIndex2 then
13631     exit;
13632 
13633   if AIndex1 < AIndex2 then
13634   begin
13635     ItemTo := QListWidget_takeItem(QListWidgetH(Widget), AIndex2);
13636     ItemFrom := QListWidget_takeItem(QListWidgetH(Widget), AIndex1);
13637     QListWidget_insertItem(QListWidgetH(Widget), AIndex1, ItemTo);
13638     QListWidget_insertItem(QListWidgetH(Widget), AIndex2, ItemFrom);
13639   end else
13640   begin
13641     ItemFrom := QListWidget_takeItem(QListWidgetH(Widget), AIndex1);
13642     ItemTo := QListWidget_takeItem(QListWidgetH(Widget), AIndex2);
13643     QListWidget_insertItem(QListWidgetH(Widget), AIndex2, ItemFrom);
13644     QListWidget_insertItem(QListWidgetH(Widget), AIndex1, ItemTo);
13645   end;
13646 
13647   if OwnerDrawn then
13648   begin
13649     R := getVisualItemRect(ItemTo);
13650     Update(@R);
13651     R := getVisualItemRect(ItemFrom);
13652     Update(@R);
13653   end;
13654 end;
13655 
13656 procedure TQtListWidget.MoveItem(const AFromIndex, AToIndex: Integer);
13657 var
13658   Item: QListWidgetItemH;
13659   R: TRect;
13660 begin
13661   Item := QListWidget_takeItem(QListWidgetH(Widget), AFromIndex);
13662   QListWidget_insertItem(QListWidgetH(Widget), AToIndex, Item);
13663   if OwnerDrawn then
13664   begin
13665     R := getVisualItemRect(Item);
13666     Update(@R);
13667   end;
13668 end;
13669 
13670 { TQtCheckListBox }
13671 
CreateWidgetnull13672 function TQtCheckListBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
13673 var
13674   Parent: QWidgetH;
13675 begin
13676   FCheckBoxClicked := False;
13677   FDelayedCheckItem := nil;
13678   FSavedEvent := nil;
13679   FSavedEventTimer := nil;
13680   FSavedEventTimerHook := nil;
13681 
13682   FViewStyle := -1;
13683   FSyncingItems := False;
13684   FDontPassSelChange := False;
13685   FOwnerData := False;
13686 
13687   FCheckable := True;
13688   if AParams.WndParent <> 0 then
13689     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
13690   else
13691     Parent := nil;
13692   Result := QListWidget_create(Parent);
13693 end;
13694 
13695 procedure TQtCheckListBox.SetNextStateMap(AItem: QListWidgetItemH);
13696 var
13697   ACurrState: QtCheckState;
13698 begin
13699   inherited SetNextStateMap(AItem);
13700   if (AItem = nil) or not AllowGrayed then
13701     exit;
13702   ACurrState := GetItemLastCheckState(AItem);
13703 
13704   case ACurrState of
13705     QtUnchecked: ItemCheckState[GetRow(AItem)] := QtPartiallyChecked;
13706     QtPartiallyChecked: ItemCheckState[GetRow(AItem)] := QtChecked;
13707     QtChecked: ItemCheckState[GetRow(AItem)] := QtUnChecked;
13708   end;
13709 end;
13710 
13711 procedure TQtCheckListBox.AttachEvents;
13712 begin
13713   inherited AttachEvents;
13714   FItemChangedHook := QListWidget_hook_create(Widget);
13715   QListWidget_hook_hook_itemChanged(FItemChangedHook, @signalItemChanged);
13716 end;
13717 
13718 procedure TQtCheckListBox.DetachEvents;
13719 begin
13720   if FItemChangedHook <> nil then
13721   begin
13722     QListWidget_hook_destroy(FItemChangedHook);
13723     FItemChangedHook := nil;
13724   end;
13725   inherited DetachEvents;
13726 end;
13727 
TQtCheckListBox.EventFilternull13728 function TQtCheckListBox.EventFilter(Sender: QObjectH; Event: QEventH
13729   ): Boolean; cdecl;
13730 begin
13731   Result := False;
13732   if (QEvent_type(Event) = QEventKeyPress) and
13733      ((QKeyEvent_key(QKeyEventH(Event)) = QtKey_Up) or
13734      (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Down)) then
13735   begin
13736     {issue #31697}
13737     Result:=inherited EventFilter(Sender, Event);
13738     if ItemCount > 0 then
13739     begin
13740       if (getSelCount = 0) then
13741       begin
13742         Selected[0] := True;
13743         Result := True;
13744       end;
13745       inherited signalSelectionChanged();
13746     end;
13747   end else
13748   if (QEvent_type(Event) = QEventMouseButtonDblClick) then
13749     // issue #25089
13750   else
13751     Result:=inherited EventFilter(Sender, Event);
13752 end;
13753 
TQtCheckListBox.itemViewViewportEventFilternull13754 function TQtCheckListBox.itemViewViewportEventFilter(Sender: QObjectH;
13755   Event: QEventH): Boolean; cdecl;
13756 var
13757   MousePos: TQtPoint;
13758   Item: QListWidgetItemH;
13759   x: Integer;
13760 begin
13761   Result := False;
13762   QEvent_accept(Event);
13763   if (LCLObject <> nil) then
13764   begin
13765     case QEvent_type(Event) of
13766       QEventMouseButtonRelease,
13767       QEventMouseButtonPress,
13768       QEventMouseButtonDblClick:
13769         begin
13770           // issue #21318
13771           // MousePos :=
13772           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
13773           Item := itemAt(MousePos.x, MousePos.y);
13774           if QEvent_Type(Event) = QEventMouseButtonDblClick then
13775           begin
13776             SlotMouse(Widget, Event);
13777             QEvent_ignore(Event);
13778             // qt capture locks for some reason under qt-4.7.4 ?!?
13779             // when we dbl click on viewport without checkable items
13780             if (Item = nil) and (Sender = QWidget_mouseGrabber) then
13781               QWidget_releaseMouse(QWidgetH(Sender));
13782           end else
13783           begin
13784             Result := SlotMouse(Sender, Event);
13785             if (Item <> nil) and (OwnerDrawn) and
13786               (QEvent_type(Event) = QEventMouseButtonRelease) and
13787               ((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
13788             begin
13789               x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
13790               if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
13791               begin
13792                 if QListWidgetItem_checkState(Item) = QtUnchecked then
13793                   QListWidgetItem_setCheckState(Item, QtChecked)
13794                 else
13795                   QListWidgetItem_setCheckState(Item, QtUnChecked);
13796               end;
13797             end;
13798           end;
13799 
13800           if (QEvent_Type(Event) = QEventMouseButtonPress) then
13801           begin
13802             // change current row , this works fine with qt < 4.8
13803             if Assigned(Item) and
13804               ((currentItem <> Item) or not QListWidgetItem_isSelected(Item)) then
13805             begin
13806               // DebugLn('TQtCheckListBox forced item change');
13807               {issue #31697}
13808               QListWidget_setCurrentItem(QListWidgetH(Widget), Item, QItemSelectionModelSelectCurrent);
13809               inherited signalSelectionChanged();
13810             end;
13811           end;
13812         end;
13813       else
13814       begin
13815         {do not change selection if mousepressed and mouse moved}
13816         Result := (QEvent_type(Event) = QEventMouseMove) and
13817           hasFocus and (QGUIApplication_mouseButtons() > 0);
13818          QEvent_ignore(Event);
13819       end;
13820     end;
13821   end;
13822 end;
13823 
13824 procedure TQtCheckListBox.signalCurrentItemChanged(current: QListWidgetItemH;
13825   previous: QListWidgetItemH); cdecl;
13826 begin
13827   // Do nothing
13828   // inherited signalCurrentItemChanged(current, previous);
13829 end;
13830 
13831 procedure TQtCheckListBox.signalItemClicked(item: QListWidgetItemH); cdecl;
13832 begin
13833 
13834   if InUpdate or not GetVisible then
13835     exit;
13836   {$note seem that we have qtbug with tristate listwidget items, so
13837    we must handle statemap somehow}
13838 
13839   //TODO try to fix nextstatemap
13840   if FCheckBoxClicked then
13841   begin
13842     FCheckBoxClicked := False;
13843     SetNextStateMap(item);
13844   end;
13845 end;
13846 
13847 procedure TQtCheckListBox.signalSelectionChanged(); cdecl;
13848 begin
13849   // DO NOTHING
13850   // inherited signalSelectionChanged;
13851 end;
13852 
13853 procedure TQtCheckListBox.signalItemChanged(item: QListWidgetItemH); cdecl;
13854 var
13855   Msg: TLMessage;
13856 begin
13857   if InUpdate or not GetVisible then
13858     exit;
13859   FillChar(Msg{%H-}, SizeOf(Msg), #0);
13860   Msg.Msg := LM_CHANGED;
13861   Msg.WParam := PtrInt(QListWidget_row(QListWidgetH(Widget), Item));
13862   DeliverMessage(Msg);
13863 end;
13864 
TQtCheckListBox.GetItemCheckStatenull13865 function TQtCheckListBox.GetItemCheckState(AIndex: Integer): QtCheckState;
13866 var
13867   AItem: QListWidgetItemH;
13868 begin
13869   Result := QtUnChecked;
13870   if (AIndex >= 0) and (AIndex < rowCount) then
13871   begin
13872     AItem := QListWidget_item(QListWidgetH(Widget), AIndex);
13873     if AItem <> nil then
13874       Result := QListWidgetItem_checkState(AItem);
13875   end;
13876 end;
13877 
13878 procedure TQtCheckListBox.SetItemCheckState(AIndex: Integer;
13879   AValue: QtCheckState);
13880 var
13881   AItem: QListWidgetItemH;
13882 begin
13883   if (AIndex >= 0) and (AIndex < rowCount) then
13884   begin
13885     AItem := QListWidget_item(QListWidgetH(Widget), AIndex);
13886     if AItem <> nil then
13887     begin
13888       QListWidgetItem_setCheckState(AItem, AValue);
13889       SetItemLastCheckState(AItem);
13890     end;
13891   end;
13892 end;
13893 
13894 { TQtHeaderView }
13895 
TQtHeaderView.getClickablenull13896 function TQtHeaderView.getClickable: Boolean;
13897 begin
13898   // QHeaderView_sectionsClickable();
13899   Result := QHeaderView_sectionsClickable(QHeaderViewH(Widget));
13900 end;
13901 
getMinSectionSizenull13902 function TQtHeaderView.getMinSectionSize: Integer;
13903 begin
13904   Result := QHeaderView_minimumSectionSize(QHeaderViewH(Widget));
13905 end;
13906 
TQtHeaderView.SortIndicatorOrdernull13907 function TQtHeaderView.SortIndicatorOrder: QtSortOrder;
13908 begin
13909   Result := QHeaderView_sortIndicatorOrder(QHeaderViewH(Widget));
13910 end;
13911 
13912 procedure TQtHeaderView.setClickable(const AValue: Boolean);
13913 begin
13914   QHeaderView_setSectionsClickable(QHeaderViewH(Widget), AValue);
13915   // QHeaderView_setClickable(QHeaderViewH(Widget), AValue);
13916 end;
13917 
13918 procedure TQtHeaderView.setMinSectionSize(const AValue: Integer);
13919 begin
13920   QHeaderView_setMinimumSectionSize(QHeaderViewH(Widget), AValue);
13921 end;
13922 
13923 procedure TQtHeaderView.SetSortIndicator(const AColumn: Integer;
13924   const AOrder: QtSortOrder);
13925 begin
13926   QHeaderView_setSortIndicator(QHeaderViewH(Widget), AColumn, AOrder);
13927 end;
13928 
13929 procedure TQtHeaderView.SetSortIndicatorVisible(AVisible: Boolean);
13930 begin
13931   QHeaderView_setSortIndicatorShown(QHeaderViewH(Widget), AVisible);
13932 end;
13933 
13934 {------------------------------------------------------------------------------
13935   Function: TQtHeaderView.CreateWidget
13936   Params:  None
13937   Returns: Widget (QHeaderViewH)
13938  ------------------------------------------------------------------------------}
CreateWidgetnull13939 function TQtHeaderView.CreateWidget(const AParams: TCreateParams):QWidgetH;
13940 var
13941   Parent: QWidgetH;
13942 begin
13943   // Creates the widget
13944   {$ifdef VerboseQt}
13945     WriteLn('TQtHeaderView.Create');
13946   {$endif}
13947   if AParams.WndParent <> 0 then
13948     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
13949   else
13950     Parent := nil;
13951 
13952   Result := QHeaderView_create(QtHorizontal, Parent);
13953 end;
13954 
13955 procedure TQtHeaderView.AttachEvents;
13956 begin
13957   inherited AttachEvents;
13958   FSectionClicked := QHeaderView_hook_create(Widget);
13959   QHeaderView_hook_hook_sectionClicked(FSectionClicked, @SignalSectionClicked);
13960 end;
13961 
13962 procedure TQtHeaderView.DetachEvents;
13963 begin
13964   if FSectionClicked <> nil then
13965   begin
13966     QHeaderView_hook_destroy(FSectionClicked);
13967     FSectionClicked := nil;
13968   end;
13969   inherited DetachEvents;
13970 end;
13971 
TQtHeaderView.EventFilternull13972 function TQtHeaderView.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
13973   cdecl;
13974 begin
13975   Result := False;
13976   QEvent_accept(Event);
13977   if (FOwner <> nil) and (LCLObject <> nil) then
13978   begin
13979     if (FChildOfComplexWidget = ccwTreeWidget) and
13980       (QEvent_type(Event) = QEventFocusIn) then
13981     begin
13982       Result := True;
13983       QEvent_ignore(Event);
13984       QWidget_setFocus(FOwner.Widget);
13985     end;
13986   end;
13987 end;
13988 
itemViewViewportEventFilternull13989 function TQtHeaderView.itemViewViewportEventFilter(Sender: QObjectH;
13990   Event: QEventH): Boolean; cdecl;
13991 begin
13992   Result := False;
13993   QEvent_accept(Event);
13994   case QEvent_type(Event) of
13995     QEventMouseButtonPress,
13996     QEventMouseButtonRelease,
13997     QEventMouseButtonDblClick: ; {do nothing here - signal is fired}
13998     else
13999       Result := inherited itemViewViewportEventFilter(Sender, Event);
14000   end;
14001 end;
14002 
14003 {------------------------------------------------------------------------------
14004   Function: TQtHeaderView.SignalSectionClicked
14005   Params:  None
14006   Returns: Nothing
14007  ------------------------------------------------------------------------------}
14008 procedure TQtHeaderView.SignalSectionClicked(logicalIndex: Integer); cdecl;
14009 var
14010   Msg: TLMNotify;
14011   NMLV: TNMListView;
14012 begin
14013   {$ifdef VerboseQt}
14014   writeln('TQtHeaderView.signalSectionClicked index ',logicalIndex);
14015   {$endif}
14016 
14017   FillChar(Msg{%H-}, SizeOf(Msg), #0);
14018   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
14019 
14020   Msg.Msg := CN_NOTIFY;
14021   NMLV.hdr.hwndfrom := LCLObject.Handle;
14022   NMLV.hdr.code := LVN_COLUMNCLICK;
14023   NMLV.iItem := -1;
14024   NMLV.iSubItem := logicalIndex;
14025 
14026   Msg.NMHdr := @NMLV.hdr;
14027 
14028   DeliverMessage(Msg);
14029 
14030 end;
14031 
getResizeModenull14032 function TQtHeaderView.getResizeMode(AIndex: Integer): QHeaderViewResizeMode;
14033 begin
14034   Result := QHeaderView_sectionResizeMode(QHeaderViewH(Widget), AIndex);
14035   // Result := QHeaderView_resizeMode(QHeaderViewH(Widget), AIndex);
14036 end;
14037 
14038 procedure TQtHeaderView.setResizeMode(AResizeMode: QHeaderViewResizeMode);
14039 begin
14040   QHeaderView_setSectionResizeMode(QHeaderViewH(Widget), AResizeMode);
14041   // QHeaderView_setResizeMode(QHeaderViewH(Widget), AResizeMode);
14042 end;
14043 
14044 procedure TQtHeaderView.setResizeMode(AIndex: Integer;
14045   AResizeMode: QHeaderViewResizeMode);
14046 begin
14047   QHeaderView_setSectionResizeMode(QHeaderViewH(Widget), AIndex, AResizeMode);
14048   // QHeaderView_setResizeMode(QHeaderViewH(Widget), AIndex, AResizeMode);
14049 end;
14050 
sectionSizenull14051 function TQtHeaderView.sectionSize(AIndex: Integer): Integer;
14052 begin
14053   Result := QHeaderView_sectionSize(QHeaderViewH(Widget), AIndex);
14054 end;
14055 
sectionSizeHintnull14056 function TQtHeaderView.sectionSizeHint(AIndex: Integer): Integer;
14057 begin
14058   Result := QHeaderView_sectionSizeHint(QHeaderViewH(Widget), AIndex);
14059 end;
14060 
14061 procedure TQtHeaderView.moveSection(AFromIndex: Integer; AToIndex: Integer);
14062 begin
14063   QHeaderView_moveSection(QHeaderViewH(Widget), AFromIndex, AToIndex);
14064 end;
14065 
14066 procedure TQtHeaderView.resizeSection(ASection: Integer; ASize: Integer);
14067 begin
14068   QHeaderView_resizeSection(QHeaderViewH(Widget), ASection, ASize);
14069 end;
14070 
14071 procedure TQtHeaderView.setHighlightSections(AValue: Boolean);
14072 begin
14073   QHeaderView_setHighlightSections(QHeaderViewH(Widget), AValue);
14074 end;
14075 
14076 procedure TQtHeaderView.setDefaultSectionSize(AValue: Integer);
14077 begin
14078   QHeaderView_setDefaultSectionSize(QHeaderViewH(Widget), AValue);
14079 end;
14080 
14081 procedure TQtHeaderView.setStretchLastSection(AValue: Boolean);
14082 begin
14083   QHeaderView_setStretchLastSection(QHeaderViewH(Widget), AValue);
14084 end;
14085 
14086   { TQtTreeView }
14087 
getColVisiblenull14088 function TQtTreeView.getColVisible(AIndex: Integer): Boolean;
14089 begin
14090   Result := not QTreeView_isColumnHidden(QTreeViewH(Widget), AIndex);
14091 end;
14092 
getColWidthnull14093 function TQtTreeView.getColWidth(AIndex: Integer): Integer;
14094 begin
14095   Result := QTreeView_columnWidth(QTreeViewH(Widget), AIndex);
14096 end;
14097 
GetUniformRowHeightsnull14098 function TQtTreeView.GetUniformRowHeights: Boolean;
14099 begin
14100   Result := QTreeView_uniformRowHeights(QTreeViewH(Widget));
14101 end;
14102 
14103 procedure TQtTreeView.setColVisible(AIndex: Integer; const AValue: Boolean);
14104 begin
14105   QTreeView_setColumnHidden(QTreeViewH(Widget), AIndex, not AValue);
14106 end;
14107 
14108 procedure TQtTreeView.setColWidth(AIndex: Integer; const AValue: Integer);
14109 begin
14110   QTreeView_setColumnWidth(QTreeViewH(Widget), AIndex, AValue);
14111 end;
14112 
14113 procedure TQtTreeView.SetUniformRowHeights(const AValue: Boolean);
14114 begin
14115   QTreeView_setUniformRowHeights(QTreeViewH(Widget), AValue);
14116 end;
14117 
14118 procedure TQtTreeView.setWordWrap(const AValue: Boolean);
14119 begin
14120   QTreeView_setWordWrap(QTreeViewH(Widget), AValue);
14121 end;
14122 
14123 procedure TQtTreeView.setRootIsDecorated(AValue: Boolean);
14124 begin
14125   QTreeView_setRootIsDecorated(QTreeViewH(Widget), AValue);
14126 end;
14127 
14128 procedure TQtTreeView.setAllColumnsShowFocus(AValue: Boolean);
14129 begin
14130   QTreeView_setAllColumnsShowFocus(QTreeViewH(Widget), AValue);
14131 end;
14132 
14133 {------------------------------------------------------------------------------
14134   Function: TQtTreeView.CreateWidget
14135   Params:  None
14136   Returns: Widget (QTreeViewH)
14137  ------------------------------------------------------------------------------}
TQtTreeView.CreateWidgetnull14138 function TQtTreeView.CreateWidget(const AParams: TCreateParams):QWidgetH;
14139 var
14140   Parent: QWidgetH;
14141 begin
14142   // Creates the widget
14143   {$ifdef VerboseQt}
14144     WriteLn('TQtTreeView.Create');
14145   {$endif}
14146   if AParams.WndParent <> 0 then
14147     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
14148   else
14149     Parent := nil;
14150   Result := QTreeView_create(Parent);
14151 end;
14152 
14153   { TQtTreeWidget }
14154 
14155 {------------------------------------------------------------------------------
14156   Function: TQtTreeWidget.CreateWidget
14157   Params:  None
14158   Returns: Widget (QTreeWidgetH)
14159  ------------------------------------------------------------------------------}
CreateWidgetnull14160 function TQtTreeWidget.CreateWidget(const AParams: TCreateParams):QWidgetH;
14161 var
14162   Parent: QWidgetH;
14163 begin
14164   {$ifdef VerboseQt}
14165     WriteLn('TQtTreeWidget.Create');
14166   {$endif}
14167   FDelayedCheckItem := nil;
14168   AllowGrayed := False;
14169   FSelection := TFPList.Create;
14170   FSavedEvent := nil;
14171   FSavedEventTimer := nil;
14172   FSavedEventTimerHook := nil;
14173   FViewStyle := -1;
14174   FCheckable := False;
14175   FHideSelection := False;
14176   FOwnerData := False;
14177   FSyncingItems := False;
14178   {$IFDEF TEST_QT_SORTING}
14179   FCanSort := False;
14180   FSorting := False;
14181   {$ENDIF}
14182   if AParams.WndParent <> 0 then
14183     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
14184   else
14185     Parent := nil;
14186   Result := QTreeWidget_create(Parent);
14187   FHeader := nil;
14188 end;
14189 
14190 {------------------------------------------------------------------------------
14191   Function: TQtTreeWidget.Destroy
14192   Params:  None
14193   Returns: Nothing
14194  ------------------------------------------------------------------------------}
14195 destructor TQtTreeWidget.Destroy;
14196 begin
14197   {$ifdef VerboseQt}
14198     WriteLn('TQtTreeWidget.Destroy');
14199   {$endif}
14200   FSelection.Free;
14201   if Assigned(FHeader) then
14202     FHeader.Free;
14203 
14204   inherited Destroy;
14205 end;
14206 
14207 procedure TQtTreeWidget.DestroyNotify(AWidget: TQtWidget);
14208 begin
14209   if AWidget = FHeader then
14210     FHeader := nil;
14211   inherited DestroyNotify(AWidget);
14212 end;
14213 
TQtTreeWidget.EventFilternull14214 function TQtTreeWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
14215   cdecl;
14216 var
14217   item: QTreeWidgetItemH;
14218 begin
14219   Result := False;
14220   QEvent_accept(Event);
14221   if LCLObject = nil then
14222     exit;
14223   if QEvent_Type(Event) = QEventResize then
14224     // let the viewport send resize
14225   else
14226   if Checkable then
14227   begin
14228     if (QEvent_type(Event) = QEventKeyPress) and
14229       (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
14230       (QKeyEvent_modifiers(QKeyEventH(Event)) and QtControlModifier = 0) then
14231     begin
14232       Result:=inherited EventFilter(Sender, Event);
14233       if not Result then
14234       begin
14235         Item := currentItem;
14236         if Item <> nil then
14237         begin
14238           Item := topLevelItem(getRow(Item));
14239           if (Item <> nil) and
14240             ((QTreeWidget_currentColumn(QTreeWidgetH(Widget)) = 0) or
14241             TCustomListView(LCLObject).RowSelect) then
14242           HandleCheckChangedEvent(QtPoint(0, 0), Item, Event);
14243           if OwnerDrawn then
14244           begin
14245             if QTreeWidgetItem_checkState(Item, 0) = QtUnChecked then
14246               QTreeWidgetItem_setCheckState(Item, 0, QtChecked)
14247             else
14248               QTreeWidgetItem_setCheckState(Item, 0, QtUnchecked);
14249           end;
14250         end;
14251       end else
14252         QEvent_ignore(Event);
14253     end else
14254       Result:=inherited EventFilter(Sender, Event);
14255   end else
14256   if ((QEvent_type(Event) = QEventMouseButtonPress) or
14257     (QEvent_type(Event) = QEventMouseButtonRelease))
14258     and (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
14259     {eat mouse button events -> signalItemClicked is fired}
14260   else
14261     Result:=inherited EventFilter(Sender, Event);
14262 end;
14263 
14264 procedure TQtTreeWidget.SetItemLastCheckStateInternal(AItem: QTreeWidgetItemH;
14265   AState: QtCheckState);
14266 var
14267   v: QVariantH;
14268 begin
14269   v := QVariant_create(Ord(AState));
14270   QTreeWidgetItem_setData(AItem, 0, QtCheckStateRole, v);
14271   QVariant_destroy(v);
14272 end;
14273 
14274 procedure TQtTreeWidget.HandleCheckChangedEvent(const AMousePos: TQtPoint;
14275   AItem: QTreeWidgetItemH; AEvent: QEventH);
14276 var
14277   xx: Integer;
14278   B: Boolean;
14279   R: TRect;
14280 
14281   procedure SendMessage(AnItem: QTreeWidgetItemH);
14282   var
14283     Msg: TLMNotify;
14284     NMLV: TNMListView;
14285   begin
14286 
14287     FillChar(Msg{%H-}, SizeOf(Msg), #0);
14288     FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
14289 
14290     Msg.Msg := CN_NOTIFY;
14291 
14292     NMLV.hdr.hwndfrom := LCLObject.Handle;
14293     NMLV.hdr.code := LVN_ITEMCHANGED;
14294 
14295 
14296     NMLV.iItem := GetRow(AnItem);
14297 
14298     NMLV.uOldState := UINT(Ord(not B));
14299     NMLV.uNewState := UINT(Ord(B));
14300     NMLV.uChanged := LVIF_STATE;
14301 
14302     Msg.NMHdr := @NMLV.hdr;
14303     {$IFDEF QT_DEBUGTQTTREEWIDGET}
14304     DebugLn('TQtTreeWidget.HandleCheckableMouseDown sending LVN_ITEMCHANGED Checked ',dbgs(B));
14305     {$ENDIF}
14306     DeliverMessage(Msg);
14307   end;
14308 
14309 begin
14310   if not Checkable or (AItem = nil) or (ViewStyle < 0) then
14311     exit;
14312 
14313   if ((QEvent_type(AEvent) = QEventMouseButtonPress) or
14314     (QEvent_type(AEvent) = QEventMouseButtonDblClick)) and
14315   (QMouseEvent_button(QMouseEventH(AEvent)) = QtLeftButton) then
14316   begin
14317     if (QTreeWidgetItem_flags(AItem) and QtItemIsUserCheckable) <> 0 then
14318     begin
14319       xx := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
14320       R := visualItemRect(AItem);
14321       if ((AMousePos.X > 2) and (AMousePos.X <= (xx + 2)))
14322         and (AMousePos.Y > R.Top + 1) and (AMousePos.Y < (R.Bottom - 2))  then
14323       begin
14324         B := QTreeWidgetItem_checkState(AItem, 0) = QtUnChecked;
14325         if B then
14326           SetItemLastCheckStateInternal(AItem, QtChecked)
14327         else
14328           SetItemLastCheckStateInternal(AItem, QtUnChecked);
14329 
14330         // if AItem is deleted in mouse event FDelayedCheckItem becomes nil and that's fine. issue #32869
14331         FDelayedCheckItem := AItem;
14332         SendMessage(AItem);
14333       end;
14334     end;
14335   end else
14336   if (QEvent_type(AEvent) = LCLQt_ItemViewAfterMouseRelease) then
14337   begin
14338     if (FDelayedCheckItem <> nil) and (FDelayedCheckItem <> AItem) then
14339     begin
14340       SetItemLastCheckStateInternal(FDelayedCheckItem, QTreeWidgetItem_checkState(FDelayedCheckItem, 0));
14341       SendMessage(FDelayedCheckItem);
14342     end;
14343     FDelayedCheckItem := nil;
14344     SetItemLastCheckStateInternal(AItem, QTreeWidgetItem_checkState(AItem, 0));
14345     SendMessage(AItem);
14346   end else
14347   if (QEvent_type(AEvent) = QEventKeyPress) and
14348     (QKeyEvent_key(QKeyEventH(AEvent)) = QtKey_Space) then
14349   begin
14350     FDelayedCheckItem := nil;
14351     B := QTreeWidgetItem_checkState(AItem, 0) = QtUnChecked;
14352     if B then
14353       SetItemLastCheckStateInternal(AItem, QtChecked)
14354     else
14355       SetItemLastCheckStateInternal(AItem, QtUnChecked);
14356 
14357     SendMessage(AItem);
14358   end;
14359 end;
14360 
GetItemLastCheckStateInternalnull14361 function TQtTreeWidget.GetItemLastCheckStateInternal(AItem: QTreeWidgetItemH
14362   ): QtCheckState;
14363 var
14364   v: QVariantH;
14365   ok: Boolean;
14366 begin
14367   Result := QtUnChecked;
14368   if AItem = nil then
14369     exit;
14370   v := QVariant_create();
14371   QTreeWidgetItem_data(AItem, v,  0, QtCheckStateRole);
14372   ok := False;
14373   if QVariant_isValid(v) then
14374     Result := QtCheckState(QVariant_toInt(v, @Ok));
14375   QVariant_destroy(v);
14376 end;
14377 
itemViewViewportEventFilternull14378 function TQtTreeWidget.itemViewViewportEventFilter(Sender: QObjectH;
14379   Event: QEventH): Boolean; cdecl;
14380 var
14381   MousePos: TQtPoint;
14382   Item: QTreeWidgetItemH;
14383   ALCLEvent: QLCLMessageEventH;
14384   W: QHeaderViewH;
14385   R: TRect;
14386   DC: TQtDeviceContext;
14387   x: Integer;
14388   AMsgData: PtrUInt;
14389 begin
14390   Result := False;
14391   QEvent_accept(Event);
14392   if LCLObject = nil then
14393     exit;
14394   BeginEventProcessing;
14395   try
14396     if (QEvent_type(Event) = QEventPaint) and
14397       not Self.FOwnerData and (Sender = viewportWidget) then
14398     begin
14399       HasPaint := True;
14400       QPaintEvent_rect(QPaintEventH(Event), @R);
14401       DC := TQtDeviceContext.Create(QWidgetH(Sender), True);
14402       try
14403         TCustomListViewAccess(LCLObject).Canvas.handle := HDC(DC);
14404         TCustomListViewAccess(LCLObject).IntfCustomDraw(dtControl, cdPrePaint, 0, 0, [], @R);
14405       finally
14406         TCustomListViewAccess(LCLObject).Canvas.handle := 0;
14407         DC.Free;
14408       end;
14409     end else
14410     if (ViewStyle = Ord(vsReport)) and Checkable and getEnabled then
14411     begin
14412       if QEvent_type(Event) = LCLQt_ItemViewAfterMouseRelease then
14413       begin
14414         ALCLEvent := QLCLMessageEventH(Event);
14415         Item := QTreeWidgetItemH(QLCLMessageEvent_getLParam(ALCLEvent));
14416         // sync lcl with qt state. This is needed only when mouse is pressed
14417         // and moved out of item, or pressed on item and released over checkbox
14418         if (Item <> nil) and (GetItemLastCheckStateInternal(Item) <>
14419           QTreeWidgetItem_checkState(Item, 0)) then
14420         begin
14421           MousePos := QtPoint(0, 0); // shutup compiler
14422           if QLCLMessageEvent_getMsg(ALCLEvent) > 0 then
14423             QTreeWidgetItem_setCheckState(Item, 0, GetItemLastCheckStateInternal(Item));
14424           HandleCheckChangedEvent(MousePos, Item, Event);
14425         end;
14426       end else
14427       if ((QEvent_type(Event) = QEventMouseButtonPress) or
14428       (QEvent_type(Event) = QEventMouseButtonDblClick)) then
14429       begin
14430         // MousePos :=
14431         QMouseEvent_pos(QMouseEventH(Event), @MousePos);
14432         Item := itemAt(MousePos.x, MousePos.y);
14433         Result := inherited itemViewViewportEventFilter(Sender, Event);
14434 
14435         if Item <> nil then
14436           HandleCheckChangedEvent(MousePos, Item, Event);
14437       end else
14438       if (QEvent_type(Event) = QEventMouseButtonRelease) then
14439       begin
14440         if OwnerDrawn and Checkable then
14441         begin
14442           // MousePos :=
14443           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
14444           Item := itemAt(MousePos.x, MousePos.y);
14445           if (Item <> nil) and
14446             ((QTreeWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
14447           begin
14448             x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
14449             if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
14450             begin
14451               if QTreeWidgetItem_checkState(Item, 0) = QtUnchecked then
14452                 QTreeWidgetItem_setCheckState(Item, 0, QtChecked)
14453               else
14454                 QTreeWidgetItem_setCheckState(Item, 0, QtUnChecked);
14455             end;
14456           end;
14457           Result := SlotMouse(Sender, Event);
14458         end else
14459         begin
14460           if Checkable then
14461           begin
14462             // MousePos :=
14463             QMouseEvent_pos(QMouseEventH(Event), @MousePos);
14464             Item := itemAt(MousePos.x, MousePos.y);
14465             if Item <> nil then
14466             begin
14467               Item := topLevelItem(GetRow(Item));
14468               if Assigned(LCLObject) and LCLObject.Dragging then
14469                 AMsgData := Ord(QTreeWidgetItem_checkState(Item, 0)) + 1
14470               else
14471                 AMsgData := 0;
14472               ALCLEvent := QLCLMessageEvent_create(LCLQt_ItemViewAfterMouseRelease, AMsgData,
14473                 PtrUInt(Item), PtrUInt(Item), 0);
14474               QCoreApplication_postEvent(Sender, ALCLEvent);
14475             end;
14476           end;
14477           Result := inherited itemViewViewportEventFilter(Sender, Event);
14478         end;
14479       end else
14480       if (QEvent_type(Event) = QEventMouseMove) and (LCLObject <> nil) then
14481       begin
14482         W := QTreeView_header(QTreeViewH(Widget));
14483         if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
14484         begin
14485           BeginEventProcessing;
14486           try
14487             Result := SlotMouseMove(Sender, Event);
14488             // allow dnd inside listview (vsReport and vsList only).
14489             if not Result and Assigned(LCLObject) and LCLObject.Dragging then
14490               Result := True;
14491           finally
14492             EndEventProcessing;
14493           end;
14494         end else
14495           Result := inherited itemViewViewportEventFilter(Sender, Event);
14496       end;
14497     end else
14498     begin
14499       if (QEvent_type(Event) = QEventMouseMove) and (LCLObject <> nil) then
14500       begin
14501         W := QTreeView_header(QTreeViewH(Widget));
14502         if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
14503         begin
14504           BeginEventProcessing;
14505           try
14506             Result := SlotMouseMove(Sender, Event);
14507             // allow dnd inside listview (vsReport and vsList only).
14508             if not Result and Assigned(LCLObject) and LCLObject.Dragging then
14509               Result := True;
14510           finally
14511             EndEventProcessing;
14512           end;
14513         end else
14514           Result := inherited itemViewViewportEventFilter(Sender, Event);
14515       end else
14516         Result := inherited itemViewViewportEventFilter(Sender, Event);
14517     end;
14518   finally
14519     EndEventProcessing;
14520   end;
14521 end;
14522 
14523 procedure TQtTreeWidget.OwnerDataNeeded(ARect: TRect);
14524 var
14525   R: TRect;
14526   TopItem: Integer;
14527   i: Integer;
14528   j: Integer;
14529   ChildCount: Integer;
14530   VHeight: Integer; // viewport height
14531   RowHeight, AImagesWidth: Integer;
14532   item: QTreeWidgetItemH;
14533   itemChild: QTreeWidgetItemH;
14534   v,v2,v3: QVariantH;
14535   WStr, TempStr: WideString;
14536   ASelected: Boolean;
14537   ImgList: TCustomImageList;
14538   AImageIndex: TImageIndex;
14539   Bmp: TBitmap;
14540   AOk, AStateImages: Boolean;
14541   AIcon: QIconH;
14542   ASize: TSize;
14543   ImgListRes: TScaledImageListResolution;
14544 begin
14545   {do not set items during design time}
14546   if csDesigning in LCLObject.ComponentState then
14547     exit;
14548 
14549   if QTreeWidget_topLevelItemCount(QTreeWidgetH(Widget)) < 1 then
14550     exit;
14551 
14552   {TODO: add QtDecorationRole (icon) etc ... }
14553   QWidget_contentsRect(viewportWidget, @R);
14554   VHeight := R.Bottom - R.Top;
14555 
14556   item := QTreeWidget_itemAt(QTreeWidgetH(Widget), 0, 1);
14557   if item <> nil then
14558   begin
14559 
14560     TopItem := getRow(item);
14561     RowHeight := getRowHeight(TopItem);
14562 
14563     if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
14564       exit;
14565 
14566     i := 0;
14567     while (i < (VHeight + RowHeight)) do
14568     begin
14569       item := QTreeWidget_itemAt(QTreeWidgetH(Widget), 0, i + 1);
14570       if item <> nil then
14571       begin
14572 
14573         TopItem := getRow(item);
14574         RowHeight := getRowHeight(TopItem);
14575         if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
14576           continue;
14577 
14578         WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].Caption);
14579         ASelected := TCustomListViewHack(LCLObject).Items[TopItem].Selected;
14580 
14581         v := QVariant_create(PWideString(@WStr));
14582         try
14583           v2 := QVariant_create;
14584           try
14585             TempStr := '';
14586             QTreeWidgetItem_data(item, v2, 0, Ord(QtDisplayRole));
14587             if not QVariant_isNull(v2) then
14588               QVariant_toString(v2, @TempStr);
14589             if TempStr <> WStr then
14590               QTreeWidgetItem_setData(item, 0, Ord(QtDisplayRole), v);
14591           finally
14592             QVariant_destroy(v2);
14593           end;
14594 
14595           AStateImages := False;
14596           // set imageindex, part of comment in issue #27233
14597           ImgList := TCustomListViewHack(LCLObject).SmallImages;
14598           if Assigned(ImgList) then
14599             AImagesWidth := TCustomListViewHack(LCLObject).SmallImagesWidth
14600           else
14601           begin
14602             ImgList := TCustomListViewHack(LCLObject).StateImages;
14603             if Assigned(ImgList) then
14604               AImagesWidth := TCustomListViewHack(LCLObject).StateImagesWidth;
14605             AStateImages := True;
14606           end;
14607           if Assigned(ImgList) then
14608           begin
14609             ImgListRes := ImgList.ResolutionForPPI[
14610               AImagesWidth,
14611               TCustomListViewHack(LCLObject).Font.PixelsPerInch,
14612               TCustomListViewHack(LCLObject).GetCanvasScaleFactor];
14613             QTreeWidgetItem_sizeHint(item, @ASize, 0);
14614             if (ASize.cx <> ImgListRes.Width) or (ASize.cx <> ImgListRes.Height) then
14615             begin
14616               ASize.cx := ImgListRes.Width;
14617               ASize.cy := ImgListRes.Height;
14618               QTreeWidgetItem_setSizeHint(item, 0, @ASize);
14619             end;
14620             if AStateImages then
14621               AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].StateIndex
14622             else
14623               AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].ImageIndex;
14624             if (ImgListRes.Count > 0) and
14625               ((AImageIndex >= 0) and (AImageIndex < ImgListRes.Count)) then
14626             begin
14627               Bmp := TBitmap.Create;
14628               try
14629                 ImgListRes.GetBitmap(AImageIndex, Bmp);
14630                 v2 := QVariant_create;
14631                 QTreeWidgetItem_data(item, v2, 0, QtListViewOwnerDataRole);
14632                 if not QVariant_isNull(v2) then
14633                 begin
14634                   AOk := True;
14635                   if QVariant_toInt(v2, @AOk) <> AImageIndex then
14636                   begin
14637                     v2 := QVariant_create(AImageIndex);
14638                     QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v2);
14639                     QVariant_destroy(v2);
14640                     QTreeWidgetItem_setIcon(item, 0, TQtImage(Bmp.Handle).AsIcon)
14641                   end;
14642                   // else we are imageIndex and that''s fine.
14643                 end else
14644                 begin
14645                   v2 := QVariant_create(AImageIndex);
14646                   QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v2);
14647                   QVariant_destroy(v2);
14648                   QTreeWidgetItem_setIcon(item, 0, TQtImage(Bmp.Handle).AsIcon);
14649                 end;
14650               finally
14651                 Bmp.Free;
14652               end;
14653             end else
14654             if (AImageIndex < 0) then
14655             begin
14656               v2 := QVariant_create;
14657               AIcon := QIcon_create;
14658               try
14659                 QTreeWidgetItem_data(item, v2, 0, QtListViewOwnerDataRole);
14660                 if not QVariant_isNull(v2) then
14661                 begin
14662                   v3 := QVariant_create;
14663                   try
14664                     QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v3);
14665                   finally
14666                     QVariant_destroy(v3);
14667                   end;
14668                 end;
14669                 QTreeWidgetItem_icon(item, AIcon, 0);
14670                 if not QIcon_isNull(AIcon) then
14671                   QTreeWidgetItem_setIcon(item, 0, nil);
14672               finally
14673                 QVariant_destroy(v2);
14674                 QIcon_destroy(AIcon);
14675               end;
14676             end;
14677           end;
14678 
14679           // set alignment, issue #27233
14680           if TCustomListViewHack(LCLObject).Columns.Count > 0 then
14681           begin
14682             case TCustomListViewHack(LCLObject).Column[0].Alignment of
14683               taRightJustify: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignRight);
14684               taCenter: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignCenter);
14685               taLeftJustify: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignLeft);
14686             end;
14687           end;
14688         finally
14689           QVariant_destroy(v);
14690         end;
14691 
14692         ChildCount := QTreeWidgetItem_childCount(Item);
14693         if ChildCount = TCustomListViewHack(LCLObject).Items[TopItem].SubItems.Count then
14694         begin
14695           for j := 0 to ChildCount - 1 do
14696           begin
14697             itemChild := QTreeWidgetItem_child(item, j);
14698             if itemChild <> nil then
14699             begin
14700               WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].SubItems[j]);
14701               v := QVariant_create(PWideString(@WStr));
14702               v2 := QVariant_create;
14703               try
14704                 TempStr := '';
14705                 QTreeWidgetItem_data(itemChild, v2, j, Ord(QtDisplayRole));
14706                 if not QVariant_isNull(v2) then
14707                   QVariant_toString(v2, @TempStr);
14708                 if TempStr <> WStr then
14709                   QTreeWidgetItem_setData(itemChild, j, Ord(QtDisplayRole), v);
14710               finally
14711                 QVariant_destroy(v2);
14712                 QVariant_destroy(v);
14713               end;
14714             end;
14715           end;
14716         end else
14717         begin
14718           for j := 0 to TCustomListViewHack(LCLObject).Items[TopItem].SubItems.Count - 1 do
14719           begin
14720             WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].SubItems[j]);
14721             v := QVariant_create(PWideString(@WStr));
14722             QTreeWidgetItem_setData(item, j + 1, Ord(QtDisplayRole), v);
14723 
14724             // set alignment, issue #27233
14725             if (TCustomListViewHack(LCLObject).Columns.Count > 0) then
14726             begin
14727               case TCustomListViewHack(LCLObject).Column[j + 1].Alignment of
14728                 taRightJustify: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignRight);
14729                 taCenter: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignCenter);
14730                 taLeftJustify: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignLeft);
14731               end;
14732             end;
14733             QVariant_destroy(v);
14734           end;
14735         end;
14736         if QTreeWidgetItem_isSelected(Item) <> ASelected then
14737           QTreeWidgetItem_setSelected(Item, ASelected);
14738       end;
14739 
14740       inc(i, RowHeight);
14741     end;
14742   end;
14743 end;
14744 
14745 procedure TQtTreeWidget.ItemDelegatePaint(painter: QPainterH;
14746   option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
14747 var
14748   Msg: TLMDrawListItem;
14749   DrawStruct: TDrawListItemStruct;
14750   State: QStyleState;
14751   R: TRect;
14752   ItemIndex, SubItemIndex: Integer;
14753   ACustomState: TCustomDrawState;
14754   ATarget: TCustomDrawTarget;
14755   TmpDC1, TmpDC2: HDC;
14756   SkipDefault: Boolean;
14757   APaintResult: TCustomDrawResult;
14758 
14759   function IsItemEmpty: boolean;
14760   var
14761     AText: WideString;
14762     AIcon: QIconH;
14763   begin
14764     QTreeWidgetItem_text(topLevelItem(ItemIndex), @AText, SubItemIndex);
14765     AIcon := QIcon_create;
14766     QTreeWidgetItem_icon(topLevelItem(ItemIndex), AIcon, SubItemIndex);
14767     Result := (AText = '') and QIcon_isNull(AIcon);
14768     QIcon_destroy(AIcon);
14769   end;
14770 
14771 begin
14772   if TCustomListViewAccess(LCLObject).OwnerDraw and (ViewStyle = Ord(vsReport)) then
14773   begin
14774     QPainter_save(painter);
14775     State := QStyleOption_state(option);
14776     DrawStruct.ItemID := UINT(QModelIndex_row(index));
14777 
14778     DrawStruct.Area := visualRect(index);
14779     DrawStruct.DC := HDC(TQtDeviceContext.CreateFromPainter(painter));
14780 
14781     DrawStruct.ItemState := [];
14782     // selected
14783     if (State and QStyleState_Selected) <> 0 then
14784       Include(DrawStruct.ItemState, odSelected);
14785     // disabled
14786     if (State and QStyleState_Enabled) = 0 then
14787       Include(DrawStruct.ItemState, odDisabled);
14788     // focused (QStyleState_FocusAtBorder?)
14789     if (State and QStyleState_HasFocus) <> 0 then
14790       Include(DrawStruct.ItemState, odFocused);
14791     // hotlight
14792     if (State and QStyleState_MouseOver) <> 0 then
14793       Include(DrawStruct.ItemState, odHotLight);
14794 
14795     // checked does not work as we expected.
14796     if Checkable and (QModelIndex_column(index) <= 0) then
14797     begin
14798       // if (State and QStyleState_On <> 0) and (ATarget = dtItem) then
14799       //  Include(ACustomState, cdsChecked);
14800       if  QTreeWidgetItem_checkState(topLevelItem(QModelIndex_row(index)), 0) <> QtUnchecked then
14801         Include(DrawStruct.ItemState, odChecked);
14802     end;
14803 
14804     { todo: over states:
14805 
14806       odGrayed, odChecked,
14807       odDefault, odInactive, odNoAccel,
14808       odNoFocusRect, odReserved1, odReserved2, odComboBoxEdit
14809     }
14810     Msg.Msg := CN_DRAWITEM;
14811     Msg.DrawListItemStruct := @DrawStruct;
14812     DeliverMessage(Msg);
14813 
14814     QPainter_restore(painter);
14815 
14816     TQtDeviceContext(DrawStruct.DC).Free;
14817   end else
14818   begin
14819     State := QStyleOption_state(option);
14820     ACustomState := [cdsDefault];
14821 
14822     if (State and QStyleState_Selected) <> 0 then
14823       Include(ACustomState, cdsSelected);
14824     // disabled
14825     if (State and QStyleState_Enabled) = 0 then
14826       Include(ACustomState, cdsDisabled);
14827     // focused (QStyleState_FocusAtBorder?)
14828     if (State and QStyleState_HasFocus) <> 0 then
14829       Include(ACustomState, cdsFocused);
14830     // hotlight
14831     if (State and QStyleState_MouseOver) <> 0 then
14832       Include(ACustomState, cdsHot);
14833 
14834     ItemIndex := QModelIndex_row(index);
14835     SubItemIndex := QModelIndex_column(index);
14836 
14837     if SubItemIndex <= 0 then
14838       ATarget := dtItem
14839     else
14840       ATarget := dtSubItem;
14841 
14842     // checked does not work as we expected.
14843     if Checkable and (ATarget = dtItem) then
14844     begin
14845       // if (State and QStyleState_On <> 0) and (ATarget = dtItem) then
14846       //  Include(ACustomState, cdsChecked);
14847       if  QTreeWidgetItem_checkState(topLevelItem(ItemIndex), 0) <> QtUnchecked then
14848         Include(ACustomState, cdsChecked);
14849     end;
14850 
14851     QStyle_drawControl(QApplication_style, QStyleCE_ItemViewItem, Option, painter, viewportWidget);
14852 
14853     // NOW WE ARE DRAWING ITEMS ...
14854     QPainter_save(painter);
14855     if TCustomListView(LCLObject).Canvas.HandleAllocated then
14856       TmpDC2 := TCustomListView(LCLObject).Canvas.GetUpdatedHandle([csHandleValid])
14857     else
14858       TmpDC2 := 0;
14859     TmpDC1 := HDC(TQtDeviceContext.CreateFromPainter(painter));
14860     TCustomListView(LCLObject).Canvas.Handle := TmpDC1;
14861     try
14862       R := visualRect(index);
14863       // here we do only OnCustomDrawItem and OnCustomDrawSubItem
14864       // OnCustomDraw is done inside itemViewportEventFilter.
14865       if IsItemEmpty then
14866         QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
14867 
14868       APaintResult := TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPrePaint, ItemIndex, SubItemIndex, ACustomState, @R);
14869       SkipDefault := cdrSkipDefault in APaintResult;
14870 
14871       if not SkipDefault then // do default paint by unknown magic
14872       begin
14873         if not IsItemEmpty then
14874           QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
14875       end;
14876       // issue #27315
14877       if cdrNotifyPostpaint in APaintResult then
14878         TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPostPaint, ItemIndex, SubItemIndex, ACustomState, @R);
14879     finally
14880       TCustomListView(LCLObject).Canvas.Handle := TmpDC2;
14881       TQtDeviceContext(TmpDC1).Free;
14882       QPainter_restore(painter);
14883     end;
14884   end;
14885 end;
14886 
14887 procedure TQtTreeWidget.ClearItems;
14888 begin
14889   FSelection.Clear;
14890   QTreeWidget_clear(QTreeWidgetH(Widget));
14891 end;
14892 
14893 procedure TQtTreeWidget.clearSelection;
14894 begin
14895   inherited clearSelection;
14896   FSelection.Clear;
14897 end;
14898 
14899 procedure TQtTreeWidget.DeleteItem(const AIndex: integer);
14900 var
14901   Item: QTreeWidgetItemH;
14902   Index: Integer;
14903 begin
14904   Item := topLevelItem(AIndex);
14905   if Item <> nil then
14906     Index := FSelection.IndexOf(Item)
14907   else
14908     Index := -1;
14909   if Index <> -1 then
14910     FSelection.Remove(Item);
14911   if FDelayedCheckItem = Item then
14912     FDelayedCheckItem := nil;
14913   Item := takeTopLevelItem(AIndex);
14914   if Item <> nil then
14915     QTreeWidgetItem_destroy(Item);
14916 end;
14917 
getHeadernull14918 function TQtTreeWidget.getHeader: TQtHeaderView;
14919 begin
14920   {while designing TQtHeaderView is a no-no}
14921   if not (csDesigning in LCLObject.ComponentState) and (FHeader = nil) then
14922   begin
14923     FHeader := TQtHeaderView.CreateFrom(LCLObject, QTreeView_header(QTreeViewH(Widget)));
14924     FHeader.FOwner := Self;
14925     FHeader.FChildOfComplexWidget := ccwTreeWidget;
14926     QHeaderView_setSectionsMovable(QHeaderViewH(FHeader.Widget), False);
14927     {$IFDEF TEST_QT_SORTING}
14928     FSortChanged := QHeaderView_hook_create(FHeader.Widget);
14929     QHeaderView_hook_hook_sortIndicatorChanged(FSortChanged,
14930       @SignalSortIndicatorChanged);
14931     {$ENDIF}
14932     FHeader.AttachEvents;
14933   end;
14934   Result := FHeader;
14935 end;
14936 
GetItemCheckednull14937 function TQtTreeWidget.GetItemChecked(AIndex: Integer): Boolean;
14938 var
14939   AItem: QTreeWidgetItemH;
14940 begin
14941   Result := False;
14942   AItem := topLevelItem(AIndex);
14943   if AItem <> nil then
14944     Result := GetItemLastCheckStateInternal(AItem) = QtChecked;
14945    // Result := QTreeWidgetItem_checkState(AItem, 0) = QtChecked;
14946 end;
14947 
getItemCountnull14948 function TQtTreeWidget.getItemCount: Integer;
14949 begin
14950   Result := QTreeWidget_topLevelItemCount(QTreeWidgetH(Widget));
14951 end;
14952 
getMaxColSizenull14953 function TQtTreeWidget.getMaxColSize(ACol: Integer): Integer;
14954 begin
14955   {$note QSizeH implementation missing for TQtTreeWidget.getMaxColSize}
14956   Result := MAXINT -1;
14957 end;
14958 
getMinColSizenull14959 function TQtTreeWidget.getMinColSize(ACol: Integer): Integer;
14960 begin
14961   {$note QSizeH implementation missing for TQtTreeWidget.getMinColSize}
14962   Result := 0;
14963 end;
14964 
getSortEnablednull14965 function TQtTreeWidget.getSortEnabled: Boolean;
14966 begin
14967   Result := QTreeView_isSortingEnabled(QTreeViewH(Widget));
14968 end;
14969 
getColCountnull14970 function TQtTreeWidget.getColCount: Integer;
14971 begin
14972   Result := QTreeWidget_columnCount(QTreeWidgetH(Widget));
14973 end;
14974 
14975 procedure TQtTreeWidget.setColCount(const AValue: Integer);
14976 begin
14977   QTreeWidget_setColumnCount(QTreeWidgetH(Widget), AValue);
14978 end;
14979 
14980 procedure TQtTreeWidget.SetItemChecked(AIndex: Integer; AValue: Boolean);
14981 var
14982   AItem: QTreeWidgetItemH;
14983   AState: QtCheckState;
14984 begin
14985   AItem := topLevelItem(AIndex);
14986   if AItem <> nil then
14987   begin
14988     if AValue then
14989       AState := QtChecked
14990     else
14991       AState := QtUnChecked;
14992 
14993     QTreeWidgetItem_setCheckState(AItem, 0, AState);
14994     SetItemLastCheckStateInternal(AItem, AState);
14995   end;
14996 end;
14997 
14998 procedure TQtTreeWidget.setItemCount(const AValue: Integer);
14999 var
15000   i: Integer;
15001   j: Integer;
15002   Items: TPtrIntArray;
15003   Item: QTreeWidgetItemH;
15004   ItemChild: QTreeWidgetItemH;
15005 begin
15006   if AValue = ItemCount then
15007     exit;
15008   BeginUpdate;
15009   try
15010     ClearItems;
15011     SetLength(Items, AValue);
15012     for i := 0 to High(Items) do
15013     begin
15014       Item := QTreeWidgetItem_create(QTreeWidgetH(Widget), Ord(QTreeWidgetItemType));
15015       for j := 0 to ColCount - 1 do
15016       begin
15017         ItemChild := QTreeWidgetItem_create(item, Ord(QTreeWidgetItemType));
15018         QTreeWidgetItem_addChild(item, ItemChild);
15019       end;
15020       Items[i] := PtrUInt(Item);
15021     end;
15022     if length(Items) > 0 then
15023       QTreeWidget_addTopLevelItems(QTreeWidgetH(Widget), @Items);
15024   finally
15025     EndUpdate;
15026   end;
15027 end;
15028 
15029 procedure TQtTreeWidget.setMaxColSize(ACol: Integer; const AValue: Integer);
15030 begin
15031   {$note QSizeH implementation missing for TQtTreeWidget.setMaxColSize}
15032 end;
15033 
15034 procedure TQtTreeWidget.setMinColSize(ACol: Integer; const AValue: Integer);
15035 begin
15036   QHeaderView_setMinimumSectionSize(QTreeView_header(QTreeViewH(Widget)), AValue);
15037 end;
15038 
15039 {------------------------------------------------------------------------------
15040   Function: TQtTreeWidget.setSortEnabled
15041   Params:  Boolean
15042   Returns: Nothing
15043   Enables sorting of items.
15044  ------------------------------------------------------------------------------}
15045 procedure TQtTreeWidget.setSortEnabled(const AValue: Boolean);
15046 begin
15047   QTreeView_setSortingEnabled(QTreeWidgetH(Widget), AValue);
15048 end;
15049 
15050 {------------------------------------------------------------------------------
15051   Function: TQtTreeWidget.CurrentRow
15052   Params:  None
15053   Returns: Integer
15054  ------------------------------------------------------------------------------}
currentRownull15055 function TQtTreeWidget.currentRow: Integer;
15056 var
15057   TWI: QTreeWidgetItemH;
15058 begin
15059   TWI := QTreeWidget_currentItem(QTreeWidgetH(Widget));
15060   Result := getRow(TWI);
15061 end;
15062 
15063 {------------------------------------------------------------------------------
15064   Function: TQtTreeWidget.setCurrentRow
15065   Params:  Integer
15066   Returns: Nothing
15067  ------------------------------------------------------------------------------}
15068 procedure TQtTreeWidget.setCurrentRow(row: Integer);
15069 var
15070   TWI: QTreeWidgetItemH;
15071 begin
15072   TWI := QTreeWidget_topLevelItem(QTreeWidgetH(Widget), Row);
15073   QTreeWidget_setCurrentItem(QTreeWidgetH(Widget), TWI);
15074 end;
15075 
currentItemnull15076 function TQtTreeWidget.currentItem: QTreeWidgetItemH;
15077 begin
15078   Result := QTreeWidget_currentItem(QTreeWidgetH(Widget));
15079 end;
15080 
15081 procedure TQtTreeWidget.setCurrentItem(AItem: QTreeWidgetItemH);
15082 begin
15083   QTreeWidget_setCurrentItem(QTreeWidgetH(Widget), AItem);
15084 end;
15085 
getRownull15086 function TQtTreeWidget.getRow(AItem: QTreeWidgetItemH): integer;
15087 begin
15088   Result := QTreeWidget_indexOfTopLevelItem(QTreeWidgetH(Widget), AItem);
15089 end;
15090 
headerItemnull15091 function TQtTreeWidget.headerItem: QTreeWidgetItemH;
15092 begin
15093   Result := QTreeWidget_headerItem(QTreeWidgetH(Widget));
15094 end;
15095 
itemAtnull15096 function TQtTreeWidget.itemAt(APoint: TPoint): QTreeWidgetItemH;
15097 begin
15098   Result := itemAt(APoint.X, APoint.Y);
15099 end;
15100 
itemAtnull15101 function TQtTreeWidget.itemAt(x: Integer; y: Integer): QTreeWidgetItemH;
15102 begin
15103   Result := QTreeWidget_itemAt(QTreeWidgetH(Widget), x, y);
15104 end;
15105 
15106 procedure TQtTreeWidget.insertTopLevelItem(AIndex: Integer;
15107   AItem: QTreeWidgetItemH);
15108 begin
15109   QTreeWidget_insertTopLevelItem(QTreeWidgetH(Widget), AIndex, AItem);
15110 end;
15111 
takeTopLevelItemnull15112 function TQtTreeWidget.takeTopLevelItem(AIndex: Integer): QTreeWidgetItemH;
15113 begin
15114   Result := QTreeWidget_takeTopLevelItem(QTreeWidgetH(Widget), AIndex);
15115 end;
15116 
topLevelItemnull15117 function TQtTreeWidget.topLevelItem(AIndex: Integer): QTreeWidgetItemH;
15118 begin
15119   Result := QTreeWidget_topLevelItem(QTreeWidgetH(Widget), AIndex);
15120 end;
15121 
visualItemRectnull15122 function TQtTreeWidget.visualItemRect(AItem: QTreeWidgetItemH): TRect;
15123 var
15124   ItemRect: TRect;
15125 begin
15126   QTreeWidget_visualItemRect(QTreeWidgetH(Widget), @ItemRect, AItem);
15127   Result := ItemRect;
15128 end;
15129 
getHeaderHeightnull15130 function TQtTreeWidget.getHeaderHeight(out AOrientation: QtOrientation): Integer;
15131 var
15132   W: QHeaderViewH;
15133 begin
15134   Result := 0;
15135   AOrientation := QtHorizontal;
15136   W := QTreeView_header(QTreeViewH(Widget));
15137   if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
15138   begin
15139     AOrientation := QHeaderView_orientation(W);
15140     if AOrientation = QtHorizontal then
15141       Result := QWidget_height(W)
15142     else
15143       Result := QWidget_width(W);
15144   end;
15145 end;
15146 
getItemVisiblenull15147 function TQtTreeWidget.getItemVisible(AItem: QTreeWidgetItemH): Boolean;
15148 begin
15149   Result := not QTreeWidget_isItemHidden(QTreeWidgetH(Widget), AItem);
15150 end;
15151 
getTopItemnull15152 function TQtTreeWidget.getTopItem: integer;
15153 begin
15154   Result := getVisibleRowCount(True);
15155 end;
15156 
15157 {------------------------------------------------------------------------------
15158   Function: TQtTreeWidget.getVisibleRowCount
15159   Params:  Boolean
15160   Returns: if AFirstVisibleOnly = False (default) then it returns number
15161   of visible rows, or 0 if there's no visible rows.
15162   When AFirstVisibleOnly = True then it returns index of first visible row,
15163   otherwise result is -1.
15164  ------------------------------------------------------------------------------}
getVisibleRowCountnull15165 function TQtTreeWidget.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
15166 var
15167   R: TRect;
15168   i: integer;
15169   item: QTreeWidgetItemH;
15170   RowIndex: integer;
15171   RowHeight: integer;
15172 begin
15173   if AFirstVisibleOnly then
15174     Result := -1
15175   else
15176     Result := 0;
15177   QWidget_contentsRect(viewportWidget, @R);
15178   i := 0;
15179   repeat
15180     item := itemAt(0, i);
15181     if item <> nil then
15182     begin
15183       RowIndex := getRow(Item);
15184       if AFirstVisibleOnly then
15185       begin
15186         Result := RowIndex;
15187         break;
15188       end;
15189       RowHeight := getRowHeight(RowIndex);
15190       if RowHeight <= 0 then
15191         RowHeight := 1;
15192       inc(Result);
15193       inc(i, RowHeight);
15194     end else
15195       inc(i, 1);
15196   until i >= R.Bottom;
15197 end;
15198 
15199 procedure TQtTreeWidget.setItemVisible(AItem: QTreeWidgetItemH;
15200   const AVisible: Boolean);
15201 begin
15202   QTreeWidget_setItemHidden(QTreeWidgetH(Widget), AItem, not AVisible);
15203 end;
15204 
15205 procedure TQtTreeWidget.setItemText(AItem: QTreeWidgetItemH;
15206   const AColumn: Integer; const AText: WideString; const AAlignment: QtAlignment
15207   );
15208 begin
15209   QTreeWidgetItem_setText(AItem, AColumn, @AText);
15210   QTreeWidgetItem_setTextAlignment(AItem, AColumn, AAlignment);
15211 end;
15212 
15213 procedure TQtTreeWidget.setItemData(AItem: QTreeWidgetItemH;
15214   const AColumn: Integer; Data: Pointer; const ARole: Integer = Ord(QtUserRole));
15215 var
15216   v: QVariantH;
15217 begin
15218   if Data = nil then
15219     v := QVariant_create
15220   else
15221     v := QVariant_create(Int64({%H-}PtrUInt(Data)));
15222   QTreeWidgetItem_setData(AItem, AColumn, ARole, v);
15223   QVariant_destroy(v);
15224 end;
15225 
selCountnull15226 function TQtTreeWidget.selCount: Integer;
15227 begin
15228   Result := length(selectedItems);
15229 end;
15230 
TQtTreeWidget.selectedItemsnull15231 function TQtTreeWidget.selectedItems: TPtrIntArray;
15232 begin
15233   QTreeWidget_selectedItems(QTreeWidgetH(Widget), @Result);
15234 end;
15235 
15236 procedure TQtTreeWidget.setHeaderVisible(AVisible: Boolean);
15237 begin
15238   if (csDesigning in LCLObject.ComponentState) then
15239     QTreeView_setHeaderHidden(QTreeViewH(Widget), not AVisible)
15240   else
15241     Header.setVisible(AVisible);
15242 end;
15243 
15244 procedure TQtTreeWidget.setItemSelected(AItem: QTreeWidgetItemH;
15245   ASelect: Boolean);
15246 var
15247   Msg: TLMNotify;
15248   NMLV: TNMListView;
15249   AParent: QTreeWidgetItemH;
15250   AIndex: Integer;
15251   ASubIndex: Integer;
15252 begin
15253 
15254   if not InUpdate and
15255     (((FSelection.Count > 0) and (FSelection.IndexOf(AItem) <> -1)) or
15256     (QTreeWidget_isItemSelected(QTreeWidgetH(Widget), AItem) = ASelect)) then
15257     exit;
15258 
15259   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15260   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
15261   Msg.Msg := CN_NOTIFY;
15262 
15263   NMLV.hdr.hwndfrom := LCLObject.Handle;
15264   NMLV.hdr.code := LVN_ITEMCHANGED;
15265 
15266   AIndex := getRow(AItem);
15267 
15268   if AIndex = -1 then
15269     exit;
15270 
15271   AParent := QTreeWidgetItem_parent(AItem);
15272 
15273   if AParent <> nil then
15274     ASubIndex := QTreeWidgetItem_indexOfChild(AParent, AItem)
15275   else
15276     ASubIndex := 0;
15277 
15278 
15279   NMLV.iItem := AIndex;
15280   NMLV.iSubItem := ASubIndex;
15281   if not ASelect then
15282     NMLV.uOldState := LVIS_SELECTED
15283   else
15284     NMLV.uNewState := LVIS_SELECTED;
15285   NMLV.uChanged := LVIF_STATE;
15286   Msg.NMHdr := @NMLV.hdr;
15287 
15288   QTreeWidget_setItemSelected(QTreeWidgetH(Widget), AItem, ASelect);
15289   if not FSyncingItems then
15290   begin
15291     {$IFDEF QT_DEBUGTQTTREEWIDGET}
15292     DebugLn('TQtTreeWidget.setItemSelected() delivering ASelect ',dbgs(ASelect));
15293     {$ENDIF}
15294     DeliverMessage(Msg);
15295   end;
15296 end;
15297 
15298 procedure TQtTreeWidget.setStretchLastSection(AValue: Boolean);
15299 begin
15300   if (csDesigning in LCLObject.ComponentState) then
15301     QHeaderView_setStretchLastSection(QTreeView_header(QTreeViewH(Widget)),
15302       AValue)
15303   else
15304     Header.setStretchLastSection(AValue);
15305 end;
15306 
15307 procedure TQtTreeWidget.scrollToItem(Item: QTreeWidgetItemH;
15308   hint: QAbstractItemViewScrollHint);
15309 begin
15310   QTreeWidget_scrollToItem(QTreeWidgetH(Widget), Item, hint);
15311 end;
15312 
15313 {$IFDEF TEST_QT_SORTING}
15314 procedure TQtTreeWidget.sortItems(Acolumn: Integer; AOrder: QtSortOrder);
15315 var
15316   StdModel: QStandardItemModelH;
15317 begin
15318   // there's bug with QStandardItemModel persistent index update, we
15319   // use InternalUpdate in QtWSComCtrls !
15320   if not FCanSort then
15321     exit;
15322   try
15323     if ItemCount = 0 then
15324       exit;
15325     StdModel := QStandardItemModelH(getModel);
15326     // writeln('Sorting called ...SortRole=',QStandardItemModel_sortRole(StdModel));
15327     if QStandardItemModel_sortRole(StdModel) <> Ord(QtUserRole) then
15328       QStandardItemModel_setSortRole(StdModel, Ord(QtUserRole));
15329     setUpdatesEnabled(False);
15330     QStandardItemModel_sort(StdModel, AColumn, AOrder);
15331     setUpdatesEnabled(True);
15332   finally
15333     FCanSort := False;
15334   end;
15335 end;
15336 {$ENDIF}
15337 
15338 procedure TQtTreeWidget.AttachEvents;
15339 begin
15340   inherited AttachEvents;
15341 
15342   FItemActivatedHook := QTreeWidget_hook_create(Widget);
15343   FItemEnteredHook := QTreeWidget_hook_create(Widget);
15344   FSelectionChangedHook := QTreeWidget_hook_create(Widget);
15345   QTreeWidget_hook_hook_ItemActivated(FItemActivatedHook, @SignalItemActivated);
15346   QTreeWidget_hook_hook_ItemEntered(FItemEnteredHook, @SignalItemEntered);
15347   QTreeWidget_hook_hook_itemSelectionChanged(FSelectionChangedHook, @SignalSelectionChanged);
15348 end;
15349 
15350 procedure TQtTreeWidget.DetachEvents;
15351 begin
15352   if FItemActivatedHook <> nil then
15353   begin
15354     QTreeWidget_hook_destroy(FItemActivatedHook);
15355     FItemActivatedHook := nil;
15356   end;
15357 
15358   if FItemEnteredHook <> nil then
15359   begin
15360     QTreeWidget_hook_destroy(FItemEnteredHook);
15361     FItemEnteredHook := nil;
15362   end;
15363   if FSelectionChangedHook <> nil then
15364   begin
15365     QTreeWidget_hook_destroy(FSelectionChangedHook);
15366     FSelectionChangedHook := nil;
15367   end;
15368 
15369   {$IFDEF TEST_QT_SORTING}
15370   if FSortChanged <> nil then
15371   begin
15372     QHeaderView_hook_destroy(FSortChanged);
15373     FSortChanged := nil;
15374   end;
15375   {$ENDIF}
15376 
15377   inherited DetachEvents;
15378 end;
15379 
15380 procedure TQtTreeWidget.ExchangeItems(const AIndex1, AIndex2: Integer);
15381 var
15382   ItemFrom: QTreeWidgetItemH;
15383   ItemTo: QTreeWidgetItemH;
15384   R: TRect;
15385 begin
15386 
15387   if AIndex1 = AIndex2 then
15388     exit;
15389 
15390   if AIndex1 < AIndex2 then
15391   begin
15392     ItemTo := takeTopLevelItem(AIndex2);
15393     ItemFrom := takeTopLevelItem(AIndex1);
15394     insertTopLevelItem(AIndex1, ItemTo);
15395     insertTopLevelItem(AIndex2, ItemFrom);
15396   end else
15397   begin
15398     ItemFrom := takeTopLevelItem(AIndex1);
15399     ItemTo := takeTopLevelItem(AIndex2);
15400     insertTopLevelItem(AIndex2, ItemFrom);
15401     insertTopLevelItem(AIndex1, ItemTo);
15402   end;
15403 
15404   if OwnerDrawn then
15405   begin
15406     R := VisualItemRect(ItemFrom);
15407     Update(@R);
15408     R := VisualItemRect(ItemTo);
15409     Update(@R);
15410   end;
15411 end;
15412 
15413 procedure TQtTreeWidget.MoveItem(const AFromIndex, AToIndex: Integer);
15414 var
15415   Item: QTreeWidgetItemH;
15416   R: TRect;
15417 begin
15418   Item := takeTopLevelItem(AFromIndex);
15419   insertTopLevelItem(AToIndex, Item);
15420   if OwnerDrawn then
15421   begin
15422     R := VisualItemRect(Item);
15423     Update(@R);
15424   end;
15425 end;
15426 
getClientBoundsnull15427 function TQtTreeWidget.getClientBounds: TRect;
15428 begin
15429   Result := inherited getClientBounds;
15430 end;
15431 
getClientOffsetnull15432 function TQtTreeWidget.getClientOffset: TPoint;
15433 var
15434   Offset: Integer;
15435   AOrientation: QtOrientation;
15436 begin
15437   Offset := getHeaderHeight(AOrientation);
15438   if Offset > 0 then
15439     Result := Point(0, 0)
15440   else
15441     Result := inherited getClientOffset;
15442 end;
15443 
15444 procedure TQtTreeWidget.setSelectionMode(AMode: QAbstractItemViewSelectionMode);
15445 var
15446   SavedItem: QTreeWidgetItemH;
15447   i: Integer;
15448   Arr: TPtrIntArray;
15449 begin
15450   SavedItem := nil;
15451   if (ViewStyle > 0) and (AMode < QAbstractItemViewMultiSelection) and
15452     (getSelectionMode > QAbstractItemViewSingleSelection) then
15453   begin
15454     SavedItem := CurrentItem;
15455     Arr := selectedItems;
15456     if not ((SavedItem <> nil) and (QTreeWidgetItem_isSelected(SavedItem))) then
15457     begin
15458       SavedItem := nil;
15459       if length(Arr) > 0 then
15460         SavedItem := QTreeWidgetItemH(Arr[0]);
15461     end;
15462     for i := 0 to High(Arr) do
15463     begin
15464       if QTreeWidgetItemH(Arr[i]) <> SavedItem then
15465       begin
15466         QTreeWidgetItem_setSelected(QTreeWidgetItemH(Arr[i]), False);
15467         signalCurrentItemChanged(nil, QTreeWidgetItemH(Arr[i]));
15468       end;
15469     end;
15470     clearSelection;
15471   end;
15472   inherited setSelectionMode(AMode);
15473   if SavedItem <> nil then
15474     setItemSelected(SavedItem, True);
15475 end;
15476 
15477 {------------------------------------------------------------------------------
15478   Function: TQtTreeWidget.SignalItemActivated
15479   Params:  Integer
15480   Returns: Nothing
15481  ------------------------------------------------------------------------------}
15482 procedure TQtTreeWidget.SignalItemActivated(item: QTreeWidgetItemH;
15483   column: Integer); cdecl;
15484 var
15485   Msg: TLMNotify;
15486   NMLV: TNMListView;
15487 begin
15488   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15489   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
15490 
15491   Msg.Msg := CN_NOTIFY;
15492 
15493   NMLV.hdr.hwndfrom := LCLObject.Handle;
15494   NMLV.hdr.code := LVN_ITEMCHANGED;
15495 
15496   NMLV.iItem := getRow(Item);
15497 
15498   NMLV.iSubItem := Column;
15499   NMLV.uOldState := 0;
15500   NMLV.uNewState := LVIS_FOCUSED;
15501   NMLV.uChanged := LVIF_STATE;
15502 
15503   Msg.NMHdr := @NMLV.hdr;
15504   DeliverMessage( Msg);
15505 end;
15506 
15507 {------------------------------------------------------------------------------
15508   Function: TQtTreeWidget.SignalItemEntered
15509   Params:  Integer
15510   Returns: Nothing
15511  ------------------------------------------------------------------------------}
15512 procedure TQtTreeWidget.SignalItemEntered(item: QTreeWidgetItemH;
15513   column: Integer); cdecl;
15514 var
15515   Msg: TLMessage;
15516 begin
15517   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15518   Msg.Msg := LM_ENTER;
15519   DeliverMessage(Msg);
15520 end;
15521 
15522 {------------------------------------------------------------------------------
15523   Function: TQtTreeWidget.SignalCurrentItemChanged
15524   Params:  Integer
15525   Returns: Nothing
15526  ------------------------------------------------------------------------------}
15527 procedure TQtTreeWidget.SignalCurrentItemChanged(current: QTreeWidgetItemH;
15528   previous: QTreeWidgetItemH); cdecl;
15529 var
15530   Msg: TLMNotify;
15531   NMLV: TNMListView;
15532   AParent: QTreeWidgetItemH;
15533   ASubIndex: Integer;
15534   AIndex: Integer;
15535   ListItem: TListItem;
15536   B: Boolean;
15537   Item: QTreeWidgetItemH;
15538 begin
15539   if Current = nil then
15540     Item := Previous
15541   else
15542     Item := Current;
15543   {$IFDEF QT_DEBUGTQTTREEWIDGET}
15544   writeln('SignalCurrentItemChangedNG CUR=',dbgHex(PtrUInt(Current)),
15545     ' PREV=',dbgHex(PtrUInt(Previous)),
15546     ' InUpdate ',InUpdate,' Curr=PREVIOUS ? ',Current = Previous);
15547   {$ENDIF}
15548 
15549   if (Item <> nil) and (Current = Previous) then
15550     exit;
15551 
15552   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15553   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
15554 
15555   Msg.Msg := CN_NOTIFY;
15556 
15557   NMLV.hdr.hwndfrom := LCLObject.Handle;
15558   NMLV.hdr.code := LVN_ITEMCHANGING;
15559 
15560   AIndex := getRow(Item);
15561   AParent := nil;
15562   if Item <> nil then
15563     AParent := QTreeWidgetItem_parent(Item);
15564 
15565   if AParent <> nil then
15566     ASubIndex := QTreeWidgetItem_indexOfChild(AParent, Item)
15567   else
15568     ASubIndex := 0;
15569 
15570   NMLV.iItem := AIndex;
15571   NMLV.iSubItem := ASubIndex;
15572   if (Item <> nil) and (Item = Previous) then
15573     NMLV.uOldState := LVIS_SELECTED
15574   else
15575     NMLV.uNewState := LVIS_SELECTED;
15576   NMLV.uChanged := LVIF_STATE;
15577 
15578   Msg.NMHdr := @NMLV.hdr;
15579   DeliverMessage(Msg);
15580 
15581   FSyncingItems := True;
15582   try
15583     if Current <> nil then
15584     begin
15585       ListItem := nil;
15586       B := False;
15587       if (ViewStyle = Ord(vsReport)) and (Previous <> nil) then
15588       begin
15589         ListItem := TCustomListViewHack(LCLObject).Selected;
15590         if ListItem <> nil then
15591           B := ListItem.Index = AIndex;
15592       end;
15593       FillChar(Msg, SizeOf(Msg), #0);
15594       FillChar(NMLV, SizeOf(NMLV), #0);
15595       Msg.Msg := CN_NOTIFY;
15596       NMLV.hdr.hwndfrom := LCLObject.Handle;
15597       NMLV.hdr.code := LVN_ITEMCHANGED;
15598       NMLV.iItem := AIndex;
15599       NMLV.iSubItem := ASubIndex;
15600       if (FSelection.Count > 0) and (FSelection.IndexOf(Current) <> -1) then
15601         NMLV.uNewState := LVIS_SELECTED
15602       else
15603         NMLV.uOldState := LVIS_SELECTED;
15604       NMLV.uChanged := LVIF_STATE;
15605       Msg.NMHdr := @NMLV.hdr;
15606       if not B then
15607         DeliverMessage(Msg);
15608 
15609 
15610       // send focused msg
15611       NMLV.uNewState := 0;
15612       NMLV.uOldState := 0;
15613       NMLV.iSubItem := -1;
15614       if (FSelection.Count > 0) and (FSelection.IndexOf(Current) <> -1) then
15615         NMLV.uNewState := LVIS_FOCUSED
15616       else
15617         NMLV.uOldState := LVIS_FOCUSED;
15618       NMLV.uChanged := LVIF_STATE;
15619       Msg.NMHdr := @NMLV.hdr;
15620       if not B then
15621         DeliverMessage(Msg);
15622 
15623     end;
15624 
15625     if (Previous <> nil) then
15626     begin
15627       AIndex := getRow(Previous);
15628       ListItem := nil;
15629       B := False;
15630       // From Qt docs:
15631       // This signal is emitted when the current item changes.
15632       // The current item is specified by current, and this replaces
15633       // the previous current item.
15634       // So, if Current = nil, do not ask TListView anything ! issue #18701
15635       if (ViewStyle = Ord(vsReport)) and (Current <> nil) and
15636         (Current <> Previous) then
15637       begin
15638         ListItem := TCustomListViewHack(LCLObject).Selected;
15639         if ListItem <> nil then
15640           B := ListItem.Index = AIndex;
15641       end;
15642 
15643       FillChar(Msg, SizeOf(Msg), #0);
15644       FillChar(NMLV, SizeOf(NMLV), #0);
15645       Msg.Msg := CN_NOTIFY;
15646       NMLV.hdr.hwndfrom := LCLObject.Handle;
15647       NMLV.hdr.code := LVN_ITEMCHANGED;
15648       NMLV.iItem := AIndex;
15649       AParent := QTreeWidgetItem_parent(Previous);
15650       if AParent <> nil then
15651         ASubIndex := QTreeWidgetItem_indexOfChild(AParent, Previous)
15652       else
15653         ASubIndex := 0;
15654       NMLV.iSubItem := ASubIndex;
15655 
15656       if QTreeWidget_isItemSelected(QTreeWidgetH(Widget), Previous) then
15657         NMLV.uNewState := LVIS_SELECTED
15658       else
15659         NMLV.uOldState := LVIS_SELECTED;
15660 
15661       NMLV.uChanged := LVIF_STATE;
15662       Msg.NMHdr := @NMLV.hdr;
15663       if not B then
15664         DeliverMessage(Msg);
15665     end;
15666   finally
15667     FSyncingItems := False;
15668   end;
15669 end;
15670 
15671 procedure TQtTreeWidget.SignalSelectionChanged(); cdecl;
15672 var
15673   Arr: TPtrIntArray;
15674   ItemsList: TFPList;
15675   i: Integer;
15676   j: Integer;
15677 
15678   procedure RemoveUnselectedItems;
15679   var
15680     x: Integer;
15681     Index: Integer;
15682     AnItem: QTreeWidgetItemH;
15683   begin
15684     // we are removing only items which are not in selection, to avoid
15685     // duplicated triggering of TListView.OnSelectItem
15686     for x := ItemsList.Count - 1 downto 0 do
15687     begin
15688       Index := FSelection.IndexOf(ItemsList.Items[x]);
15689       if Index = -1 then
15690       begin
15691         AnItem := QTreeWidgetItemH(ItemsList.Items[x]);
15692         SignalCurrentItemChanged(nil, AnItem);
15693         ItemsList.Remove(AnItem);
15694       end;
15695     end;
15696     ItemsList.Clear;
15697   end;
15698 begin
15699   ItemsList := TFPList.Create;
15700   try
15701     if FSelection.Count > 0 then
15702       ItemsList.Assign(FSelection);
15703     FSelection.Clear;
15704     Arr := selectedItems;
15705 
15706     {$IFDEF QT_DEBUGTQTTREEWIDGET}
15707     writeln('TQtTreeWidget.SignalSelectionChanged NewSel count ',length(Arr),
15708       ' InUpdate ',InUpdate,
15709       ' OldSel count ',ItemsList.Count);
15710     {$ENDIF}
15711 
15712     for i := 0 to High(Arr) do
15713       FSelection.Add(QTreeWidgetItemH(Arr[i]));
15714 
15715     if not InUpdate then
15716     begin
15717       if FSelection.Count = 0 then
15718         RemoveUnSelectedItems
15719       else
15720       if (getSelectionMode in [QAbstractItemViewMultiSelection,
15721                                QAbstractItemViewExtendedSelection]) and
15722         (ItemsList.Count >= 1) then // and (FSelection.Count <> ItemsList.Count) then
15723       begin
15724         RemoveUnSelectedItems;
15725         for i := 0 to FSelection.Count - 1 do
15726           SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]), nil);
15727       end else
15728       for i := 0 to FSelection.Count - 1 do
15729       begin
15730         if ItemsList.Count > 0 then
15731         begin
15732           for j := 0 to ItemsList.Count - 1 do
15733             SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]),
15734               QTreeWidgetItemH(ItemsList.Items[j]));
15735         end else
15736           SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]), nil);
15737       end;
15738     end;
15739   finally
15740     ItemsList.Free;
15741   end;
15742 end;
15743 
15744 {$IFDEF TEST_QT_SORTING}
15745 procedure TQtTreeWidget.SignalSortIndicatorChanged(ALogicalIndex: Integer;
15746   AOrder: QtSortOrder); cdecl;
15747 begin
15748   if FSorting or not Assigned(LCLObject) or not
15749     QHeaderView_isSortIndicatorShown(QHeaderViewH(Header.Widget)) then
15750     exit;
15751   if not FCanSort then
15752     exit;
15753   FSorting := True;
15754   try
15755     if ALogicalIndex >= 0 then
15756       sortItems(ALogicalIndex, AOrder);
15757   finally
15758     FSorting := False;
15759   end;
15760 end;
15761 {$ENDIF}
15762 
15763 {TQtTableView}
15764 
CreateWidgetnull15765 function TQtTableView.CreateWidget(const Params: TCreateParams): QWidgetH;
15766 var
15767   Parent: QWidgetH;
15768 begin
15769   {$ifdef VerboseQt}
15770     WriteLn('TQtTableView.CreateWidget');
15771   {$endif}
15772   HasPaint := False;
15773   if Params.WndParent <> 0 then
15774     Parent := TQtWidget(Params.WndParent).GetContainerWidget
15775   else
15776     Parent := nil;
15777   Result := QTableView_create(Parent);
15778 end;
15779 
verticalHeadernull15780 function TQtTableView.verticalHeader: TQtHeaderView;
15781 begin
15782   {$ifdef VerboseQt}
15783     WriteLn('TQtTableView.verticalHeader');
15784   {$endif}
15785   if FVerticalHeader = nil then
15786     FVerticalHeader := TQtHeaderView.CreateFrom(LCLObject, QTableView_verticalHeader(QTableViewH(Widget)));
15787   Result := FVerticalHeader;
15788 end;
15789 
horizontalHeadernull15790 function TQtTableView.horizontalHeader: TQtHeaderView;
15791 begin
15792   {$ifdef VerboseQt}
15793     WriteLn('TQtTableView.horizontalHeader');
15794   {$endif}
15795   if FHorizontalHeader = nil then
15796     FHorizontalHeader := TQtHeaderView.CreateFrom(LCLObject, QTableView_horizontalHeader(QTableViewH(Widget)));
15797   Result := FHorizontalHeader;
15798 end;
15799 
15800 procedure TQtTableView.setVisible(AVisible: Boolean);
15801 begin
15802   QWidget_setVisible(Widget, AVisible);
15803 end;
15804 
getGridStylenull15805 function TQtTableView.getGridStyle: QtPenStyle;
15806 begin
15807   Result := QTableView_gridStyle(QTableViewH(Widget));
15808 end;
15809 
15810 procedure TQtTableView.setGridStyle(ANewStyle: QtPenStyle);
15811 begin
15812   QTableView_setGridStyle(QTableViewH(Widget), ANewStyle);
15813 end;
15814 
15815 destructor TQtTableView.Destroy;
15816 begin
15817   if FVerticalHeader <> nil then
15818     FVerticalHeader.Free;
15819   if FHorizontalHeader <> nil then
15820     FHorizontalHeader.Free;
15821   inherited Destroy;
15822 end;
15823 
getViewPortnull15824 function TQtTableView.getViewPort: QWidgetH;
15825 begin
15826   Result := viewportWidget;
15827 end;
15828 
getClientBoundsnull15829 function TQtTableView.getClientBounds: TRect;
15830 begin
15831   QWidget_contentsRect(Widget, @Result);
15832 end;
15833 
15834 procedure TQtTableView.grabMouse;
15835 begin
15836   QWidget_grabMouse(Widget);
15837 end;
15838 
15839 { TQtMenu }
15840 
CreateWidgetnull15841 function TQtMenu.CreateWidget(const AParams: TCreateParams): QWidgetH;
15842 var
15843   AGroup: TQtActionGroup;
15844   Parent: QWidgetH;
15845 begin
15846   FTrackButton := QtNoButton;
15847   FLastTick := 0;
15848   FIcon := nil;
15849   if AParams.WndParent <> 0 then
15850     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
15851   else
15852     Parent := nil;
15853   Result := QMenu_create(Parent);
15854   FDeleteLater := True;
15855   FActionHandle := nil;
15856   FActions := TFPList.Create;
15857   AGroup := TQtActionGroup.Create(Result);
15858   if FMenuItem <> nil then
15859     AGroup.GroupIndex := FMenuItem.GroupIndex
15860   else
15861     AGroup.GroupIndex := -1;
15862   AGroup.Exclusive := False;
15863   FActions.Add(AGroup);
15864 end;
15865 
15866 procedure TQtMenu.InitializeWidget;
15867 begin
15868   FWidgetState := [];
15869   ChildOfComplexWidget := ccwNone;
15870   WidgetColorRole := QPaletteWindow;
15871   TextColorRole := QPaletteText;
15872   Widget := CreateWidget(FParams);
15873   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
15874   QtWidgetSet.AddHandle(Self);
15875   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
15876   FWidgetLCLFont := nil;
15877 end;
15878 
15879 constructor TQtMenu.Create(const AMenuItem: TMenuItem);
15880 var
15881   AParams: TCreateParams;
15882 begin
15883   FillChar(AParams{%H-}, SizeOf(AParams), #0);
15884   FMenuItem := AMenuItem;
15885   inherited Create(nil, AParams);
15886 end;
15887 
15888 destructor TQtMenu.Destroy;
15889 var
15890   i: integer;
15891 begin
15892   if FIcon <> nil then
15893     QIcon_destroy(FIcon);
15894 
15895   if Assigned(FActions) then
15896   begin
15897     for i := 0 to FActions.Count - 1 do
15898       TQtActionGroup(FActions.Items[i]).Free;
15899 
15900     FActions.Free;
15901   end;
15902 
15903   inherited Destroy;
15904 end;
15905 
15906 procedure TQtMenu.AttachEvents;
15907 begin
15908   FTriggeredHook := QAction_hook_create(ActionHandle);
15909   FHoveredHook := QAction_hook_create(ActionHandle);
15910   FAboutToShowHook := QMenu_hook_create(Widget);
15911   FAboutToHideHook := QMenu_hook_create(Widget);
15912   FEventHook := QObject_hook_create(Widget);
15913 
15914   QAction_hook_hook_triggered(FTriggeredHook, @SlotTriggered);
15915 
15916   QAction_hook_hook_hovered(FHoveredHook, @SlotHovered);
15917 
15918   QMenu_hook_hook_aboutToShow(FAboutToShowHook, @SlotAboutToShow);
15919 
15920   QMenu_hook_hook_aboutToHide(FAboutToHideHook, @SlotAboutToHide);
15921 
15922   QObject_hook_hook_events(FEventHook, @EventFilter);
15923 end;
15924 
15925 procedure TQtMenu.DetachEvents;
15926 begin
15927   if FActionEventFilter <> nil then
15928   begin
15929     QObject_hook_destroy(FActionEventFilter);
15930     FActionEventFilter := nil;
15931   end;
15932 
15933   if FTriggeredHook <> nil then
15934   begin
15935     QAction_hook_destroy(FTriggeredHook);
15936     FTriggeredHook := nil;
15937   end;
15938 
15939   if FHoveredHook <> nil then
15940   begin
15941     QAction_hook_destroy(FHoveredHook);
15942     FHoveredHook := nil;
15943   end;
15944 
15945   if FAboutToShowHook <> nil then
15946   begin
15947     QMenu_hook_destroy(FAboutToShowHook);
15948     FAboutToShowHook := nil;
15949   end;
15950 
15951   if FAboutToHideHook <> nil then
15952   begin
15953     QMenu_hook_destroy(FAboutToHideHook);
15954     FAboutToHideHook := nil;
15955   end;
15956   inherited DetachEvents;
15957 end;
15958 
15959 procedure TQtMenu.SlotHovered; cdecl;
15960 begin
15961   FMenuItem.IntfDoSelect;
15962 end;
15963 
15964 procedure TQtMenu.SlotAboutToShow; cdecl;
15965 var
15966   Msg: TLMessage;
15967 begin
15968   //issues #22872 (flickering), #24979 (actions)
15969   if Assigned(FMenuItem) and
15970     not (FMenuItem.Menu is TPopupMenu) then
15971   begin
15972     // DebugLn('TQtMenu.SlotAboutToShow ',dbgsName(FMenuItem));
15973     if GetTickCount64 - FLastTick > 10 then
15974     begin
15975       FLastTick := GetTickCount64;
15976       FillChar(Msg{%H-}, SizeOf(Msg), 0);
15977       Msg.msg := LM_ACTIVATE;
15978       if Assigned(FMenuItem) then
15979         FMenuItem.Dispatch(Msg);
15980       FLastTick := GetTickCount64;
15981     end;
15982   end;
15983 end;
15984 
15985 procedure TQtMenu.SlotAboutToHide; cdecl;
15986 var
15987   Event: QLCLMessageEventH;
15988 begin
15989   if FMenuItem.Menu is TPopupMenu then
15990   begin
15991     Event := QLCLMessageEvent_create(LCLQt_PopupMenuClose);
15992     QCoreApplication_postEvent(Widget, Event);
15993   end;
15994   // DebugLn('TQtMenu.SlotAboutToHide ',dbgsName(FMenuItem));
15995   FLastTick := GetTickCount64; // issue #22872, #24979
15996 end;
15997 
15998 procedure TQtMenu.DoPopupClose;
15999 begin
16000   if FMenuItem.Menu is TPopupMenu then
16001     TPopupMenu(FMenuItem.Menu).Close;
16002 end;
16003 
16004 procedure TQtMenu.SlotDestroy; cdecl;
16005 begin
16006   Widget := nil;
16007 end;
16008 
16009 procedure TQtMenu.PopUp(pos: PQtPoint; at: QActionH);
16010 begin
16011   QMenu_popup(QMenuH(Widget), pos, at);
16012 end;
16013 
16014 procedure TQtMenu.Exec(pos: PQtPoint; at: QActionH);
16015 begin
16016   QMenu_exec(QMenuH(Widget), pos, at);
16017 end;
16018 
actionHandlenull16019 function TQtMenu.actionHandle: QActionH;
16020 begin
16021   if FActionHandle = nil then
16022   begin
16023     if FActionEventFilter <> nil then
16024     begin
16025       QObject_hook_destroy(FActionEventFilter);
16026       FActionEventFilter := nil;
16027     end;
16028     FActionHandle := QMenu_menuAction(QMenuH(Widget));
16029     FActionEventFilter := QObject_hook_create(FActionHandle);
16030     QObject_hook_hook_events(FActionEventFilter, @ActionEventFilter);
16031   end;
16032   Result := FActionHandle;
16033 end;
16034 
addMenunull16035 function TQtMenu.addMenu(AMenu: QMenuH): QActionH;
16036 begin
16037   setHasSubmenu(True);
16038   Result := QMenu_addMenu(QMenuH(Widget), AMenu);
16039 end;
16040 
16041 procedure TQtMenu.removeActionGroup;
16042 var
16043   Action: QActionGroupH;
16044 begin
16045   Action := QAction_actionGroup(ActionHandle);
16046   if Action <> nil then
16047     QActionGroup_removeAction(Action, ActionHandle);
16048 end;
16049 
16050 procedure TQtMenu.setActionGroups(AItem: TMenuItem);
16051 var
16052   i: integer;
16053   b: Boolean = True;
16054   Group: TQtActionGroup;
16055 begin
16056   for i := 0 to FActions.Count - 1 do
16057   begin
16058     Group := TQtActionGroup(FActions.Items[i]);
16059     if Group.GroupIndex = AItem.GroupIndex then
16060     begin
16061       QAction_setEnabled(TQtMenu(AItem.Handle).actionHandle, AItem.Enabled);
16062       QAction_setVisible(TQtMenu(AItem.Handle).actionHandle, AItem.Visible);
16063       Group.addAction(TQtMenu(AItem.Handle).actionHandle);
16064       Group.Exclusive := AItem.RadioItem;
16065       Group.Visible := True;
16066       Group.Enabled := True;
16067       b := False;
16068       break;
16069     end;
16070   end;
16071   if b then
16072   begin
16073     Group := TQtActionGroup.Create(Widget);
16074     Group.Exclusive := AItem.RadioItem;
16075     Group.GroupIndex := AItem.GroupIndex;
16076     QAction_setEnabled(TQtMenu(AItem.Handle).actionHandle, AItem.Enabled);
16077     QAction_setVisible(TQtMenu(AItem.Handle).actionHandle, AItem.Visible);
16078     Group.addAction(TQtMenu(AItem.Handle).actionHandle);
16079     Group.Visible := True;
16080     Group.Enabled := True;
16081     FActions.Add(Group);
16082   end;
16083 end;
16084 
insertMenunull16085 function TQtMenu.insertMenu(AIndex: Integer; AMenu: QMenuH; AItem: TMenuItem): QActionH;
16086 var
16087   actionBefore: QActionH;
16088 begin
16089 
16090   setHasSubmenu(True);
16091 
16092   if (AItem <> nil) and not AItem.IsLine then
16093     setActionGroups(AItem);
16094 
16095   actionBefore := getActionByIndex(AIndex);
16096 
16097   if actionBefore <> nil then
16098     Result := QMenu_insertMenu(QMenuH(Widget), actionBefore, AMenu)
16099   else
16100     Result := QMenu_addMenu(QMenuH(Widget), AMenu);
16101 end;
16102 
getHasSubMenunull16103 function TQtMenu.getHasSubMenu: boolean;
16104 begin
16105   Result := QAction_menu(ActionHandle) <> nil;
16106 end;
16107 
getVisiblenull16108 function TQtMenu.getVisible: Boolean;
16109 begin
16110   if ActionHandle = nil then
16111     exit(False);
16112   Result := QAction_isVisible(ActionHandle);
16113 end;
16114 
getTextnull16115 function TQtMenu.getText: WideString;
16116 begin
16117   QAction_text(ActionHandle, @Result);
16118 end;
16119 
16120 procedure TQtMenu.setText(const W: WideString);
16121 begin
16122   QAction_setText(ActionHandle, @W);
16123 end;
16124 
16125 procedure TQtMenu.setVisible(AVisible: Boolean);
16126 begin
16127   QAction_setVisible(ActionHandle, AVisible);
16128 end;
16129 
16130 procedure TQtMenu.setChecked(p1: Boolean);
16131 begin
16132   setCheckable(p1);
16133   QAction_setChecked(ActionHandle, p1);
16134 end;
16135 
16136 procedure TQtMenu.setCheckable(p1: Boolean);
16137 begin
16138   if FMenuItem.RadioItem or FMenuItem.ShowAlwaysCheckable then
16139     QAction_setCheckable(ActionHandle, True)
16140   else
16141     QAction_setCheckable(ActionHandle, p1);
16142 end;
16143 
16144 procedure TQtMenu.setHasSubmenu(AValue: Boolean);
16145 begin
16146   if AValue then
16147     QAction_setMenu(ActionHandle, QMenuH(Widget))
16148   else
16149     QAction_setMenu(ActionHandle, nil);
16150 end;
16151 
16152 procedure TQtMenu.setIcon(AIcon: QIconH);
16153 begin
16154   QMenu_setIcon(QMenuH(Widget), AIcon);
16155 end;
16156 
16157 procedure TQtMenu.setImage(AImage: TQtImage);
16158 begin
16159   if FIcon <> nil then
16160   begin
16161     QIcon_destroy(FIcon);
16162     FIcon := nil;
16163   end;
16164 
16165   if AImage <> nil then
16166     FIcon := AImage.AsIcon()
16167   else
16168     FIcon := QIcon_create();
16169 
16170   setIcon(FIcon);
16171 end;
16172 
16173 procedure TQtMenu.setSeparator(AValue: Boolean);
16174 begin
16175   QAction_setSeparator(ActionHandle, AValue);
16176 end;
16177 
16178 procedure TQtMenu.setShortcut(AShortCutK1, AShortCutK2: TShortcut);
16179 var
16180   Key: Word;
16181   Shift: TShiftState;
16182   QtK1, QtK2: integer;
16183   KeySequence: QKeySequenceH;
16184 begin
16185   QtK1 := 0;
16186   QtK2 := 0;
16187   if AShortCutK1 <> 0 then
16188   begin
16189     ShortCutToKey(AShortCutK1, Key, Shift);
16190     QtK1 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
16191     if AShortCutK2 <> 0 then
16192     begin
16193       ShortCutToKey(AShortCutK2, Key, Shift);
16194       QtK2 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
16195     end;
16196   end;
16197   // there is no need in destroying QKeySequnce
16198   KeySequence := QKeySequence_create(QtK1, QtK2);
16199   QAction_setShortcut(ActionHandle, KeySequence);
16200   QKeySequence_destroy(KeySequence);
16201 end;
16202 
16203 {------------------------------------------------------------------------------
16204   Method: TQtMenu.SlotTriggered
16205 
16206   Callback for menu item click
16207  ------------------------------------------------------------------------------}
16208 procedure TQtMenu.SlotTriggered(checked: Boolean); cdecl;
16209 var
16210   Event: QLCLMessageEventH;
16211 begin
16212   Event := QLCLMessageEvent_create(LCLQt_PopupMenuTriggered);
16213   QCoreApplication_postEvent(Widget, Event, 1 {high priority});
16214 end;
16215 
ActionEventFilternull16216 function TQtMenu.ActionEventFilter(Sender: QObjectH; Event: QEventH): Boolean;
16217   cdecl;
16218 var
16219   TempAction: QActionH;
16220   Group: QActionGroupH;
16221 begin
16222   Result := False;
16223   QEvent_accept(Event);
16224   if Assigned(FMenuItem) and (QEvent_type(Event) = QEventActionChanged) then
16225   begin
16226     {qt shouldn't change checkables in any case, LCL should do that !}
16227     TempAction := QActionEvent_action(QActionEventH(Event));
16228     if (TempAction <> nil) and
16229       QAction_isCheckable(TempAction) and
16230       (QAction_isChecked(TempAction) <> FMenuItem.Checked) then
16231     begin
16232       Group := QAction_actionGroup(TempAction);
16233       if Group <> nil then
16234       begin
16235         if QActionGroup_isExclusive(Group) then
16236           QObject_blockSignals(Group, True)
16237         else
16238           QObject_blockSignals(TempAction, True);
16239       end else
16240         QObject_blockSignals(TempAction, True);
16241 
16242       QAction_setChecked(TempAction, FMenuItem.Checked);
16243 
16244       if QObject_signalsBlocked(TempAction) then
16245       begin
16246         QObject_blockSignals(TempAction, False);
16247         Result := True;
16248         QEvent_ignore(Event);
16249       end;
16250     end;
16251   end;
16252 end;
16253 
TQtMenu.MenuItemEnablednull16254 function TQtMenu.MenuItemEnabled: boolean;
16255 var
16256   AParentMenu: TMenuItem;
16257 begin
16258   if not Assigned(FMenuItem) then
16259   begin
16260     Result := getEnabled;
16261     exit;
16262   end;
16263 
16264   Result := FMenuItem.Enabled;
16265   AParentMenu := FMenuItem.Parent;
16266   while AParentMenu <> nil do
16267   begin
16268     Result := AParentMenu.Enabled;
16269     if not Result then
16270       break;
16271     AParentMenu := AParentMenu.Parent;
16272   end;
16273 end;
16274 
EventFilternull16275 function TQtMenu.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
16276 var
16277   Msg: TLMessage;
16278   TempAction: QActionH;
16279   APos: TQtPoint;
16280 begin
16281   Result := False;
16282   QEvent_accept(Event);
16283 
16284   case QEvent_type(Event) of
16285     LCLQt_PopupMenuTriggered:
16286       begin
16287         {$IFDEF HASX11}
16288         // make interface snappy after menuitem triggers
16289         if Assigned(Application) and not Application.Terminated then
16290         begin
16291           if QApplication_activePopupWidget = nil then
16292           begin
16293             if QApplication_activeModalWidget <> nil then
16294               QWidget_repaint(QApplication_activeModalWidget)
16295             else
16296             if QApplication_activeWindow <> nil then
16297               QWidget_repaint(QApplication_activeWindow);
16298             QCoreApplication_processEvents(QEventLoopAllEvents);
16299           end;
16300         end;
16301         {$ENDIF}
16302         FillChar(Msg{%H-}, SizeOf(Msg), 0);
16303         Msg.msg := LM_ACTIVATE;
16304         if MenuItemEnabled then
16305           FMenuItem.Dispatch(Msg);
16306         Result := True;
16307       end;
16308     LCLQt_PopupMenuClose:
16309       begin
16310         DoPopupClose;
16311         Result := True;
16312       end;
16313     QEventDestroy: SlotDestroy;
16314     QEventMouseButtonPress,
16315     QEventMouseButtonRelease:
16316       begin
16317         Result := (FTrackButton = QtLeftButton) and
16318           (QMouseEvent_button(QMouseEventH(Event)) <> FTrackButton);
16319         if Assigned(FMenuItem) and not (FMenuItem.Menu is TPopupMenu) then
16320         begin
16321           QMouseEvent_pos(QMouseEventH(Event), @APos);
16322           TempAction := QMenu_actionAt(QMenuH(Widget),
16323             @APos);
16324           {trigger LCL if root of menu have OnClick() connected,
16325            since qt won't do that for us.}
16326           if (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) and
16327             Assigned(FMenuItem.OnClick) and
16328             (TempAction = nil) and not (FMenuItem.IsInMenuBar) then
16329             SlotTriggered();
16330         end;
16331       end;
16332   end;
16333 end;
16334 
16335 { TQtMenuBar }
16336 
16337 constructor TQtMenuBar.Create(const AParent: QWidgetH);
16338 begin
16339   Create;
16340   Widget := QMenuBar_create(AParent);
16341   {$IFNDEF DARWIN}
16342   FCatchNextResizeEvent := False;
16343   FNumOfActions := 0;
16344   {$ENDIF}
16345   FOwnWidget := AParent = nil;
16346   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
16347   FWidgetLCLFont := nil;
16348   FHeight := getHeight;
16349   FVisible := False;
16350   FIsApplicationMainMenu := False;
16351   Palette.ForceColor := True;
16352   setDefaultColor(dctFont);
16353   Palette.ForceColor := False;
16354   setVisible(FVisible);
16355   QtWidgetSet.AddHandle(Self);
16356   InitializeAccessibility;
16357 end;
16358 
16359 {$IFNDEF DARWIN}
IsDesigningnull16360 function TQtMenuBar.IsDesigning: Boolean;
16361 var
16362   V: QVariantH;
16363   B: Boolean;
16364 begin
16365   Result := (Widget <> nil);
16366   if not Result then
16367     exit(False);
16368 
16369   Result := False;
16370   v := QVariant_create();
16371   try
16372     B := False;
16373     QObject_property(Widget, v, 'lcldesignmenubar');
16374     if QVariant_isValid(v) and not QVariant_isNull(v) then
16375       Result := QVariant_toInt(V, @B) = 1;
16376   finally
16377     QVariant_destroy(v);
16378   end;
16379 end;
16380 {$ENDIF}
16381 
TQtMenuBar.EventFilternull16382 function TQtMenuBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
16383   cdecl;
16384   {$IFNDEF DARWIN}
16385   procedure UpdateDesignerClientRect;
16386   var
16387     WParent: QWidgetH;
16388     Window: HWND;
16389     ACtl: TWinControl;
16390   begin
16391     WParent := getParent;
16392     if (WParent <> nil) then
16393     begin
16394       Window := HwndFromWidgetH(WParent);
16395       if (Window <> 0) and (TQtWidget(Window) is TQtDesignWidget) and
16396         (TQtWidget(Window).getVisible) then
16397       begin
16398         ACtl := TQtMainWindow(Window).LCLObject;
16399         if Assigned(ACtl) and not (csDestroying in ACtl.ComponentState) then
16400         begin
16401           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
16402           DebugLn('TQtMenuBar.EventFilter: before DoAdjustClientRecChange=',
16403             dbgs(ACtl.ClientRect));
16404           {$ENDIF}
16405           ACtl.DoAdjustClientRectChange(True);
16406           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
16407           DebugLn('TQtMenuBar.EventFilter: after  DoAdjustClientRecChange=',
16408             dbgs(ACtl.ClientRect));
16409           {$ENDIF}
16410         end;
16411       end;
16412     end;
16413   end;
16414   {$ENDIF}
16415 begin
16416   Result := False;
16417   QEvent_accept(Event);
16418   if (QEvent_type(Event) = QEventFontChange) then
16419     AssignQtFont(FWidgetDefaultFont.FHandle, QWidget_font(QWidgetH(Sender)));
16420 
16421   {$IFNDEF DARWIN}
16422   if (QEvent_type(Event) = QEventResize) then
16423   begin
16424     // adjusts client rect of designer form.
16425     if FCatchNextResizeEvent then
16426     begin
16427       FCatchNextResizeEvent := False;
16428       if IsDesigning then
16429         UpdateDesignerClientRect;
16430     end;
16431   end else
16432   if (QEvent_type(Event) = QEventActionAdded) then
16433   begin
16434     if IsDesigning then
16435     begin
16436       inc(FNumOfActions);
16437       FCatchNextResizeEvent := FNumOfActions = 1;
16438       {$IFDEF VerboseQtEvents}
16439       DebugLn(Format('TQtMenuBar: Added new action now have %d actions ',
16440         [FNumOfActions]));
16441       {$ENDIF}
16442     end;
16443   end else
16444   if (QEvent_type(Event) = QEventActionRemoved) then
16445   begin
16446     if IsDesigning then
16447     begin
16448       dec(FNumOfActions);
16449       {$IFDEF VerboseQtEvents}
16450       DebugLn(Format('TQtMenuBar: Removed action still have %d actions ',
16451         [FNumOfActions]));
16452       {$ENDIF}
16453       FCatchNextResizeEvent := FNumOfActions = 0;
16454     end;
16455   end;
16456   {$ENDIF}
16457 end;
16458 
addMenunull16459 function TQtMenuBar.addMenu(AMenu: QMenuH): QActionH;
16460 begin
16461   if not FVisible then
16462   begin
16463     FVisible := True;
16464     setVisible(FVisible);
16465   end;
16466   Result := QMenuBar_addMenu(QMenuBarH(Widget), AMenu);
16467 end;
16468 
TQtMenuBar.insertMenunull16469 function TQtMenuBar.insertMenu(AIndex: Integer; AMenu: QMenuH): QActionH;
16470 var
16471   actionBefore: QActionH;
16472   Actions: TPtrIntArray;
16473   Action: QActionH;
16474   i: Integer;
16475   seq: QKeySequenceH;
16476   WStr: WideString;
16477 begin
16478   if not FVisible then
16479   begin
16480     FVisible := True;
16481     setVisible(FVisible);
16482   end;
16483   actionBefore := getActionByIndex(AIndex);
16484   if actionBefore <> nil then
16485     Result := QMenuBar_insertMenu(QMenuBarH(Widget), actionBefore, AMenu)
16486   else
16487     Result := QMenuBar_addMenu(QMenuBarH(Widget), AMenu);
16488   if FIsApplicationMainMenu then
16489   begin
16490     QWidget_actions(Widget, @Actions);
16491     QtWidgetSet.ClearGlobalActions;
16492     for i := 0 to High(Actions) do
16493     begin
16494       Action := QActionH(Actions[i]);
16495       seq := QKeySequence_create();
16496       try
16497         if QKeySequence_isEmpty(seq) then
16498         begin
16499           QAction_shortcut(Action, seq);
16500           WStr := '';
16501           QAction_text(Action, @WStr);
16502           QKeySequence_destroy(seq);
16503           seq := nil;
16504           seq := QKeySequence_create();
16505           QKeySequence_mnemonic(seq, @WStr);
16506           if not QKeySequence_isEmpty(seq) then
16507           begin
16508             QAction_setShortcutContext(Action, QtApplicationShortcut);
16509             QtWidgetSet.AddGlobalAction(Action);
16510           end;
16511         end;
16512       finally
16513         QKeySequence_destroy(seq);
16514       end;
16515     end;
16516   end;
16517 end;
16518 
TQtMenuBar.getGeometrynull16519 function TQtMenuBar.getGeometry: TRect;
16520 begin
16521   Result := inherited getGeometry;
16522 
16523   // workaround since after attaching menu it takes 0 height
16524   if Result.Bottom = 0 then
16525     Result.Bottom := FHeight;
16526 end;
16527 
16528 { TQtProgressBar }
16529 
TQtProgressBar.CreateWidgetnull16530 function TQtProgressBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
16531 var
16532   Parent: QWidgetH;
16533 begin
16534   // Creates the widget
16535   {$ifdef VerboseQt}
16536     WriteLn('TQProgressBar.Create');
16537   {$endif}
16538   if AParams.WndParent <> 0 then
16539     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
16540   else
16541     Parent := nil;
16542   Result := QProgressBar_create(Parent);
16543 end;
16544 
16545 procedure TQtProgressBar.AttachEvents;
16546 begin
16547   inherited AttachEvents;
16548 
16549   FValueChangedHook := QProgressBar_hook_create(Widget);
16550   QProgressBar_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
16551 end;
16552 
16553 procedure TQtProgressBar.DetachEvents;
16554 begin
16555   if FValueChangedHook <> nil then
16556   begin
16557     QProgressBar_hook_destroy(FValueChangedHook);
16558     FValueChangedHook := nil;
16559   end;
16560   inherited DetachEvents;
16561 end;
16562 
16563 procedure TQtProgressBar.setRange(minimum: Integer; maximum: Integer);
16564 begin
16565   QProgressBar_setRange(QProgressBarH(Widget), minimum, maximum);
16566 end;
16567 
16568 procedure TQtProgressBar.setTextVisible(visible: Boolean);
16569 begin
16570   QProgressBar_setTextVisible(QProgressBarH(Widget), visible);
16571 end;
16572 
16573 procedure TQtProgressBar.setAlignment(const AAlignment: QtAlignment);
16574 begin
16575   QProgressBar_setAlignment(QProgressBarH(Widget), AAlignment);
16576 end;
16577 
16578 procedure TQtProgressBar.setTextDirection(textDirection: QProgressBarDirection);
16579 begin
16580   QProgressBar_setTextDirection(QProgressBarH(Widget), textDirection);
16581 end;
16582 
16583 procedure TQtProgressBar.setValue(value: Integer);
16584 begin
16585   QProgressBar_setValue(QProgressBarH(Widget), value);
16586 end;
16587 
16588 procedure TQtProgressBar.setOrientation(p1: QtOrientation);
16589 begin
16590   QProgressBar_setOrientation(QProgressBarH(Widget), p1);
16591 end;
16592 
16593 procedure TQtProgressBar.setInvertedAppearance(invert: Boolean);
16594 begin
16595   QProgressBar_setInvertedAppearance(QProgressBarH(Widget), invert);
16596 end;
16597 
16598 procedure TQtProgressBar.SignalValueChanged(Value: Integer); cdecl;
16599 var
16600   Msg: TLMessage;
16601 begin
16602   FillChar(Msg{%H-}, SizeOf(Msg), #0);
16603   Msg.Msg := LM_CHANGED;
16604   if not InUpdate then
16605     DeliverMessage(Msg);
16606 end;
16607 
16608 procedure TQtProgressBar.setFocusPolicy(const APolicy: QtFocusPolicy);
16609 begin
16610   if APolicy = QtNoFocus then
16611     QWidget_setFocusPolicy(Widget, APolicy)
16612   else
16613     QWidget_setFocusPolicy(Widget, QtTabFocus);
16614 end;
16615 
16616 procedure TQtProgressBar.reset;
16617 begin
16618   QProgressBar_reset(QProgressBarH(Widget));
16619 end;
16620 
16621 { TQtStatusBarPanel }
16622 
CreateWidgetnull16623 function TQtStatusBarPanel.CreateWidget(const AParams: TCreateParams
16624   ): QWidgetH;
16625 var
16626   Parent: QWidgetH;
16627 begin
16628   // Creates the widget
16629   {$ifdef VerboseQt}
16630     WriteLn('TQtStatusBarPanel.Create');
16631   {$endif}
16632 
16633   if AParams.WndParent <> 0 then
16634     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
16635   else
16636     Parent := nil;
16637   Result := QLabel_create(Parent);
16638 end;
16639 
16640 procedure TQtStatusBarPanel.DrawItem(Sender: QObjectH; Event: QEventH);
16641 var
16642   Msg: TLMDrawItems;
16643   AStruct: TPaintStruct;
16644   ItemStruct: PDrawItemStruct;
16645   P: TPoint;
16646   B: Boolean;
16647 begin
16648   {$ifdef VerboseQt}
16649     WriteLn('TQtWidget.DrawItem ', dbgsName(LCLObject));
16650   {$endif}
16651   if CanSendLCLMessage and (LCLObject is TWinControl) and (FContext = 0) then
16652   begin
16653     FillChar(Msg{%H-}, SizeOf(Msg), #0);
16654 
16655     Msg.Msg := LM_DRAWITEM;
16656     FillChar(AStruct{%H-}, SizeOf(TPaintStruct), 0);
16657     FillChar(ItemStruct{%H-}, SizeOf(TDrawItemStruct), 0);
16658     New(ItemStruct);
16659 
16660     with PaintData do
16661     begin
16662       PaintWidget := QWidgetH(Sender);
16663       ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
16664       if ClipRect = nil then
16665         New(ClipRect);
16666       QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
16667     end;
16668 
16669     ItemStruct^.itemID := UINT(ID);
16670     ItemStruct^._hDC := BeginPaint(THandle(Self), AStruct);
16671     FContext := ItemStruct^._hDC;
16672     ItemStruct^.rcItem := PaintData.ClipRect^;
16673     ItemStruct^.hwndItem := HWND(Self);
16674     Msg.Ctl := LCLObject.Handle;
16675     Msg.DrawItemStruct := ItemStruct;
16676 
16677     P := getClientOffset;
16678     inc(P.X, FScrollX);
16679     inc(P.Y, FScrollY);
16680     TQtDeviceContext(FContext).translate(P.X, P.Y);
16681 
16682     // send paint message
16683     try
16684       try
16685         LCLObject.WindowProc(TLMessage(Msg));
16686       finally
16687         Dispose(PaintData.ClipRect);
16688         Fillchar(FPaintData, SizeOf(FPaintData), 0);
16689         FContext := 0;
16690         EndPaint(THandle(Self), AStruct);
16691         Dispose(ItemStruct);
16692       end;
16693     except
16694       // prevent recursive repainting !
16695       B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
16696       if B then
16697         QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
16698       try
16699         Application.HandleException(nil);
16700       finally
16701         if B and Assigned(Application) and not Application.Terminated then
16702           QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
16703       end;
16704     end;
16705   end;
16706 end;
16707 
TQtStatusBarPanel.EventFilternull16708 function TQtStatusBarPanel.EventFilter(Sender: QObjectH; Event: QEventH
16709   ): Boolean; cdecl;
16710 begin
16711   Result := False;
16712   QEvent_accept(Event);
16713   if LCLObject = nil then
16714     exit;
16715   if HasPaint and (QEvent_type(Event) = QEventPaint) then
16716   begin
16717     DrawItem(Sender, Event);
16718     Result := True;
16719   end;
16720 end;
16721 
16722 { TQtStatusBar }
16723 
TQtStatusBar.CreateWidgetnull16724 function TQtStatusBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
16725 var
16726   Parent: QWidgetH;
16727 begin
16728   SetLength(Panels, 0);
16729   if AParams.WndParent <> 0 then
16730     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
16731   else
16732     Parent := nil;
16733   Result := QStatusBar_create(Parent);
16734   Widget := Result;
16735 end;
16736 
16737 procedure TQtStatusBar.setColor(const Value: PQColor);
16738 var
16739   I: Integer;
16740   P: QPaletteH;
16741   WP: QPaletteH;
16742 begin
16743   inherited setColor(Value);
16744   QWidget_setAutoFillBackground(Widget, not EqualTQColor(Palette.CurrentColor, Palette.DefaultColor));
16745   for i := 0 to High(self.Panels) do
16746   begin
16747     P := QWidget_palette(getContainerWidget);
16748     WP := QWidget_palette(Panels[i].Widget);
16749     QWidget_setAutoFillBackground(Panels[i].Widget, not EqualTQColor(Palette.CurrentColor, Palette.DefaultColor));
16750     QPalette_setBrush(WP, QPaletteWindow, QPalette_background(P));
16751   end;
16752 end;
16753 
16754 procedure TQtStatusBar.showMessage(text: PWideString; timeout: Integer);
16755 begin
16756   QStatusBar_showMessage(QStatusBarH(Widget), text, timeout);
16757 end;
16758 
16759 procedure TQtStatusBar.addWidget(AWidget: QWidgetH; AStretch: Integer = 0);
16760 begin
16761   QStatusBar_addWidget(QStatusBarH(Widget), AWidget, AStretch);
16762 end;
16763 
16764 procedure TQtStatusBar.removeWidget(AWidget: QWidgetH);
16765 begin
16766   QStatusBar_removeWidget(QStatusBarH(Widget), AWidget);
16767 end;
16768 
isSizeGripEnablednull16769 function TQtStatusBar.isSizeGripEnabled: Boolean;
16770 begin
16771   Result := QStatusBar_isSizeGripEnabled(QStatusBarH(Widget));
16772 end;
16773 
16774 procedure TQtStatusBar.setSizeGripEnabled(const Value: Boolean);
16775 begin
16776   QStatusBar_setSizeGripEnabled(QStatusBarH(Widget), Value);
16777 end;
16778 
SlotMousenull16779 function TQtStatusBar.SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
16780 begin
16781   inherited SlotMouse(Sender, Event);
16782   Result := True; // cancel event propagation
16783 end;
16784 
16785 { TQtDialog }
16786 
TQtDialog.CreateWidgetnull16787 function TQtDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags): QWidgetH;
16788 begin
16789   Result := QDialog_create(parent, f);
16790 end;
16791 
16792 constructor TQtDialog.Create(ADialog: TCommonDialog; parent: QWidgetH; f: QtWindowFlags);
16793 begin
16794   WidgetColorRole := QPaletteWindow;
16795   TextColorRole := QPaletteWindowText;
16796   FOwner := nil;
16797   FCentralWidget := nil;
16798   FOwnWidget := True;
16799   FProps := nil;
16800   LCLObject := nil;
16801   FKeysToEat := [];
16802   FHasPaint := False;
16803   FDialog := ADialog;
16804   Widget := CreateWidget(parent, f);
16805   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
16806   QtWidgetSet.AddHandle(Self);
16807 end;
16808 
16809 procedure TQtDialog.AttachEvents;
16810 begin
16811   inherited AttachEvents;
16812   FDialogEventHook := QObject_hook_create(Widget);
16813   QObject_hook_hook_events(FDialogEventHook, @EventFilter);
16814 end;
16815 
16816 procedure TQtDialog.DetachEvents;
16817 begin
16818   if FDialogEventHook <> nil then
16819   begin
16820     QObject_hook_destroy(FDialogEventHook);
16821     FDialogEventHook := nil;
16822   end;
16823   inherited DetachEvents;
16824 end;
16825 
TQtDialog.DeliverMessagenull16826 function TQtDialog.DeliverMessage(var Msg;
16827   const AIsInputEvent: Boolean = False): LRESULT;
16828 begin
16829   try
16830     if FDialog.HandleAllocated then
16831     begin
16832       FDialog.Dispatch(TLMessage(Msg));
16833       Result := TLMessage(Msg).Result;
16834     end else
16835       Result := 0;
16836   except
16837     Application.HandleException(nil);
16838   end;
16839 end;
16840 
TQtDialog.SlotClosenull16841 function TQtDialog.SlotClose: Boolean; cdecl;
16842 begin
16843   Result := True;
16844   FDialog.DoCanClose(Result);
16845 end;
16846 
TQtDialog.EventFilternull16847 function TQtDialog.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
16848   cdecl;
16849 begin
16850   {we'll need it later. QDialog uses it's own eventLoop !}
16851   Result := False;
16852   QEvent_accept(Event);
16853   if LCLObject <> nil then
16854     Result := inherited EventFilter(Sender, Event);
16855 end;
16856 
TQtDialog.execnull16857 function TQtDialog.exec: Integer;
16858 {$IFDEF HASX11}
16859 var
16860   AWND: HWND;
16861 {$ENDIF}
16862 begin
16863   {$IF DEFINED(DARWIN) OR DEFINED(QT_DIALOGS_USE_QT_LOOP)}
16864   Result := QDialog_exec(QDialogH(Widget));
16865   {$ELSE}
16866   if QWidget_testAttribute(Widget, QtWA_DeleteOnClose) then
16867     Result := QDialog_exec(QDialogH(Widget))
16868   else
16869   begin
16870     QWidget_setWindowModality(Widget ,QtApplicationModal);
16871     QWidget_show(Widget);
16872     repeat
16873       QCoreApplication_processEvents();
16874       Application.Idle(true);
16875     until not QWidget_isVisible(Widget) or Application.Terminated;
16876     Result := QDialog_result(QDialogH(Widget));
16877   end;
16878   {$ENDIF}
16879   {$IFDEF HASX11}
16880   if (QtWidgetSet.WindowManagerName = 'xfwm4') and (QApplication_activeModalWidget() <> nil) then
16881   begin
16882     AWND := HwndFromWidgetH(QApplication_activeModalWidget());
16883     if (AWND <> 0) and (X11GetActivewindow <> TQtWidget(AWND).Widget) then
16884       X11Raise(QWidget_winID(TQtWidget(AWND).Widget));
16885   end;
16886   {$ENDIF}
16887 end;
16888 
16889 procedure TQtDialog.setSizeGripEnabled(const AEnabled: Boolean);
16890 begin
16891   QDialog_setSizeGripEnabled(QDialogH(Widget), AEnabled);
16892 end;
16893 
16894 { TQtViewPort }
16895 
TQtViewPort.CanPaintBackgroundnull16896 function TQtViewPort.CanPaintBackground: Boolean;
16897 begin
16898   Result := CanSendLCLMessage and getEnabled and
16899     (FChildOfComplexWidget in [ccwCustomControl, ccwScrollingWinControl]) and
16900     (LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
16901 end;
16902 
TQtViewPort.EventFilternull16903 function TQtViewPort.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
16904 var
16905   ASize: TSize;
16906   AResizeEvent: QResizeEventH;
16907 begin
16908   Result := False;
16909   {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
16910   if (QEvent_type(Event) = QEventResize) or
16911     (QEvent_type(Event) = QEventLayoutRequest) or
16912     (QEvent_type(Event) = QEventWheel) then
16913     WriteLn('TQtViewPort.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
16914       ' LCLObject=', dbgsName(LCLObject),
16915       ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
16916   {$endif}
16917   case QEvent_type(Event) of
16918     QEventShow,
16919     QEventShowToParent:
16920     begin
16921       {Qt does not track scrolled offset of widget when it''s not visible.issue #29239}
16922       if (FInvisibleX <> 0) or (FInvisibleY <> 0) then
16923       begin
16924         QWidget_scroll(Widget, FInvisibleX, FInvisibleY);
16925         FInvisibleX := 0;
16926         FInvisibleY := 0;
16927       end;
16928       Result := inherited EventFilter(Sender, Event);
16929     end;
16930     QEventMove: ; // do not flood LCL with viewport position
16931     QEventResize:
16932     begin
16933       // immediate update clientRect !
16934       if FOwner <> nil then
16935       begin
16936         {TQtCustomControl does not send resize event, it is done here
16937          when viewport geometry is finally updated by Qt.}
16938         ASize := FOwner.getSize;
16939         AResizeEvent := QResizeEvent_create(@ASize, @ASize);
16940         try
16941           // issue #28596 and others of TCustomControl clientrect related
16942           if CanAdjustClientRectOnResize and
16943             LCLObject.ClientRectNeedsInterfaceUpdate then
16944           begin
16945             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
16946             DebugLn('TQtViewPort.EventFilter invalidatingClientRectCache ',dbgsName(Self),' LCL=',dbgsName(LCLObject));
16947             {$ENDIF}
16948             LCLObject.InvalidateClientRectCache(False);
16949           end;
16950           FOwner.SlotResize(AResizeEvent);
16951         finally
16952           QEvent_destroy(AResizeEvent);
16953         end;
16954       end else
16955       begin
16956         {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
16957         DebugLn('TQtViewport: QEventResize wrong call....possible ERROR');
16958         {$ENDIF}
16959         LCLObject.DoAdjustClientRectChange;
16960       end;
16961     end;
16962     QEventWheel:
16963       if not getEnabled then
16964         inherited EventFilter(Sender, Event);
16965     QEventLayoutRequest:
16966     begin
16967       if FOwner <> nil then
16968       begin
16969         if LCLObject.ClientRectNeedsInterfaceUpdate then
16970         begin
16971           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize) OR DEFINED(VerboseSizeMsg)}
16972           if caspComputingBounds in LCLObject.AutoSizePhases then
16973             DebugLn('TQtViewport of ',dbgsName(LCLObject),' QEventLayoutRequest calling DoAdjustClientRectChange. CASP=TRUE *** !!!!');
16974           {$ENDIF}
16975           LCLObject.DoAdjustClientRectChange(True);
16976         end;
16977       end;
16978     end;
16979   else
16980     Result := inherited EventFilter(Sender, Event);
16981   end;
16982 end;
16983 
16984 procedure TQtViewPort.InitializeWidget;
16985 begin
16986   FInvisibleX := 0;
16987   FInvisibleY := 0;
16988   inherited InitializeWidget;
16989 end;
16990 
16991 procedure TQtViewPort.scroll(dx, dy: integer; ARect: PRect = nil);
16992 begin
16993   if not getVisible then
16994   begin
16995     FInvisibleX += dx;
16996     FInvisibleY += dy;
16997   end else
16998     inherited scroll(dx, dy, ARect);
16999   FScrollX := FScrollX + dx;
17000   FScrollY := FScrollY + dy;
17001 end;
17002 
17003 procedure TQtViewPort.stackUnder(AWidget: QWidgetH);
17004 begin
17005   // do nothing for TQtViewPort
17006   // inherited stackUnder(AWidget);
17007 end;
17008 
17009 {------------------------------------------------------------------------------
17010   Function: TQtAbstractScrollArea.horizontalScrollbar
17011   Params:  None
17012   Returns: Nothing
17013  ------------------------------------------------------------------------------}
17014 
17015 procedure TQtAbstractScrollArea.setScrollBarPolicy(AIndex: Boolean;
17016   const AValue: QtScrollBarPolicy);
17017 var
17018   Area: QAbstractScrollAreaH;
17019 begin
17020   Area := QAbstractScrollAreaH(Widget);
17021   if getScrollBarsPolicy(AIndex) <> AValue then
17022   begin
17023     if AIndex then
17024       QAbstractScrollArea_setVerticalScrollBarPolicy(Area, AValue)
17025     else
17026       QAbstractScrollArea_setHorizontalScrollBarPolicy(Area, AValue);
17027 
17028     if Assigned(LCLObject) and LCLObject.ClientRectNeedsInterfaceUpdate then
17029     begin
17030       if not (caspComputingBounds in LCLObject.AutoSizePhases) then
17031         LCLObject.DoAdjustClientRectChange(True);
17032     end;
17033   end;
17034 end;
17035 
EventFilternull17036 function TQtAbstractScrollArea.EventFilter(Sender: QObjectH; Event: QEventH
17037   ): Boolean; cdecl;
17038 var
17039   w: QWidgetH;
17040 begin
17041   Result := False;
17042 
17043   if (QEvent_type(Event) = QEventHide) then
17044   begin
17045     // issue #28880
17046     w := QWidget_mouseGrabber;
17047     if w <> nil then
17048     begin
17049       if w = Widget then
17050         ReleaseCapture
17051       else
17052       if w = viewportWidget then
17053         ReleaseCapture;
17054     end;
17055   end else
17056   if (QEvent_type(Event) = QEventResize) then
17057     // DebugLn('***TQtAbstractScrollArea.EventFilter QEventResize(',dbgsName(LCLObject),') EAT !')
17058   else
17059   if (QEvent_type(Event) = QEventWheel) and
17060     not (FChildOfComplexWidget in
17061       [ccwCustomControl, ccwScrollingWinControl, ccwScrollingWindow]) then
17062     // issue #25992.Do not propagate wheel event to lcl, it is done via TQtScrollBar.EventFilter.
17063   else
17064     Result:=inherited EventFilter(Sender, Event);
17065 end;
17066 
17067 procedure TQtAbstractScrollArea.grabMouse;
17068 var
17069   W: QWidgetH;
17070 begin
17071   W := viewportWidget;
17072   if (W <> nil) and QWidget_isVisible(W) and QWidget_isEnabled(W) then
17073     QWidget_grabMouse(W)
17074   else
17075     inherited grabMouse;
17076 end;
17077 
GetContainerWidgetnull17078 function TQtAbstractScrollArea.GetContainerWidget: QWidgetH;
17079 begin
17080   Result := viewportWidget;
17081 end;
17082 
getClientOffsetnull17083 function TQtAbstractScrollArea.getClientOffset: TPoint;
17084 begin
17085   with getClientBounds do
17086     Result := Point(Left, Top);
17087 end;
17088 
TQtAbstractScrollArea.getScrollFrameOffsetnull17089 function TQtAbstractScrollArea.getScrollFrameOffset: Integer;
17090 begin
17091   Result := 0;
17092   if (QStyle_styleHint(QApplication_style(),
17093     QStyleSH_ScrollView_FrameOnlyAroundContents) <> 0) then
17094       Result := QStyle_pixelMetric(QApplication_style(), QStylePM_ScrollView_ScrollBarSpacing, nil, Widget);
17095 end;
17096 
TQtAbstractScrollArea.getClientBoundsnull17097 function TQtAbstractScrollArea.getClientBounds: TRect;
17098 var
17099   HaveBar: Boolean;
17100   ASize: TSize;
17101 begin
17102   if not QWidget_testAttribute(viewportWidget, QtWA_Mapped) then
17103   begin
17104     ASize := getSize;
17105     QWidget_contentsRect(Widget, @Result);
17106     if (ASize.cx > 0) and (ASize.cy > 0) and (QStyle_styleHint(QApplication_style(),
17107           QStyleSH_ScrollView_FrameOnlyAroundContents) <= 0) then
17108     begin
17109       HaveBar := Assigned(FVScrollbar);
17110       if HaveBar and (verticalScrollBar.getVisibleTo(Widget)) then
17111         dec(Result.Right, verticalScrollBar.getWidth);
17112 
17113       HaveBar := Assigned(FHScrollbar);
17114       if HaveBar and (horizontalScrollBar.getVisibleTo(Widget)) then
17115         dec(Result.Bottom, horizontalScrollBar.getHeight);
17116     end;
17117     OffsetRect(Result, -Result.Left, -Result.Top);
17118     {$IF DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
17119     DebugLn('TQtAbstractScrollArea.GetClientBounds(not mapped): ',dbgsName(LCLObject),':',dbgsName(Self),' ',dbgs(Result),' ChildComplex=',dbgs(Ord(ChildOfComplexWidget)));
17120     {$ENDIF}
17121   end else
17122   begin
17123     QWidget_rect(viewportWidget, @Result);
17124     {$IF DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
17125     DebugLn('TQtAbstractScrollArea.GetClientBounds: ',dbgsName(LCLObject),':',dbgsName(Self),' ',dbgs(Result),' ChildComplex=',dbgs(Ord(ChildOfComplexWidget)));
17126     {$ENDIF}
17127   end;
17128 end;
17129 
getViewOriginnull17130 function TQtAbstractScrollArea.getViewOrigin: TPoint;
17131 var
17132   R: TRect;
17133 begin
17134   QWidget_rect(viewportWidget, @R);
17135   // current bindings (2.1) does not assign TopLeft so it's always 0,0
17136   Result := R.TopLeft;
17137 end;
17138 
viewportWidgetnull17139 function TQtAbstractScrollArea.viewportWidget: QWidgetH;
17140 begin
17141   Result := QAbstractScrollArea_viewport(QAbstractScrollAreaH(Widget));
17142 end;
17143 
getScrollBarsPolicynull17144 function TQtAbstractScrollArea.getScrollBarsPolicy(AIndex: Boolean
17145   ): QtScrollBarPolicy;
17146 var
17147   Area: QAbstractScrollAreaH;
17148 begin
17149   Area := QAbstractScrollAreaH(Widget);
17150   if AIndex then
17151     Result := QAbstractScrollArea_verticalScrollBarPolicy(Area)
17152   else
17153     Result := QAbstractScrollArea_horizontalScrollBarPolicy(Area);
17154 end;
17155 
horizontalScrollBarnull17156 function TQtAbstractScrollArea.horizontalScrollBar: TQtScrollBar;
17157 begin
17158   {$ifdef VerboseQt}
17159     WriteLn('TQAbstractScrollArea.horizontalScrollBar');
17160   {$endif}
17161   if FHScrollBar = nil then
17162   begin
17163     FHScrollBar := TQtScrollBar.CreateFrom(LCLObject,
17164       QAbstractScrollArea_horizontalScrollBar(QAbstractScrollAreaH(Widget)));
17165 
17166     if FHScrollBar.getTracking then
17167       FHScrollBar.TrackPos := SB_POLICY_CONTINUOUS
17168     else
17169       FHScrollBar.TrackPos := SB_POLICY_DISCONTINUOUS;
17170 
17171     FHScrollBar.ChildOfComplexWidget := ccwAbstractScrollArea;
17172     FHScrollBar.FOwner := Self;
17173     FHScrollBar.setFocusPolicy(QtNoFocus);
17174 
17175     if not FHScrollBar.CanChangeFontColor then
17176     begin
17177       with FHScrollBar do
17178       begin
17179         Palette.ForceColor := True;
17180         setDefaultColor(dctFont);
17181         Palette.ForceColor := False;
17182       end;
17183     end;
17184     FHScrollBar.AttachEvents;
17185   end;
17186   Result := FHScrollBar;
17187 end;
17188 
17189 procedure TQtAbstractScrollArea.InitializeAccessibility;
17190 var
17191   WStr: WideString;
17192 begin
17193   inherited InitializeAccessibility;
17194   WStr := GetUtf8String(ClassName+':ViewPort');
17195   QWidget_setAccessibleName(viewPortWidget, @WStr);
17196 end;
17197 
17198 {------------------------------------------------------------------------------
17199   Function: TQtAbstractScrollArea.verticalScrollbar
17200   Params:  None
17201   Returns: Nothing
17202  ------------------------------------------------------------------------------}
verticalScrollBarnull17203 function TQtAbstractScrollArea.verticalScrollBar: TQtScrollBar;
17204 begin
17205   {$ifdef VerboseQt}
17206     WriteLn('TQAbstractScrollArea.verticalScrollBar');
17207   {$endif}
17208   if FVScrollBar = nil then
17209   begin
17210     FVScrollbar := TQtScrollBar.CreateFrom(LCLObject,
17211       QAbstractScrollArea_verticalScrollBar(QAbstractScrollAreaH(Widget)));;
17212     if FVScrollBar.getTracking then
17213       FVScrollBar.TrackPos := SB_POLICY_CONTINUOUS
17214     else
17215       FVScrollBar.TrackPos := SB_POLICY_DISCONTINUOUS;
17216     FVScrollBar.ChildOfComplexWidget := ccwAbstractScrollArea;
17217     FVScrollBar.FOwner := Self;
17218     FVScrollBar.setFocusPolicy(QtNoFocus);
17219     if not FVScrollBar.CanChangeFontColor then
17220     begin
17221       with FVScrollBar do
17222       begin
17223         Palette.ForceColor := True;
17224         setDefaultColor(dctFont);
17225         Palette.ForceColor := False;
17226       end;
17227     end;
17228     FVScrollbar.AttachEvents;
17229   end;
17230   Result := FVScrollBar;
17231 end;
17232 
17233 procedure TQtAbstractScrollArea.setFocusPolicy(const APolicy: QtFocusPolicy);
17234 begin
17235   QWidget_setFocusPolicy(Widget, APolicy);
17236 end;
17237 
17238 {------------------------------------------------------------------------------
17239   Function: TQtAbstractScrollArea.setHorizontalScrollbar
17240   Params:  None
17241   Returns: Nothing
17242  ------------------------------------------------------------------------------}
17243 procedure TQtAbstractScrollArea.setHorizontalScrollBar(AScrollBar: TQtScrollBar);
17244 begin
17245   {$ifdef VerboseQt}
17246     WriteLn('TQAbstractScrollArea.setHorizontalScrollBar');
17247   {$endif}
17248   FHScrollbar := AScrollBar;
17249   if Assigned(FHScrollBar) then
17250     QAbstractScrollArea_setHorizontalScrollBar(QAbstractScrollAreaH(Widget), QScrollBarH(FHScrollBar.Widget));
17251 end;
17252 
17253 {------------------------------------------------------------------------------
17254   Function: TQtAbstractScrollArea.setVerticalScrollbar
17255   Params:  None
17256   Returns: Nothing
17257  ------------------------------------------------------------------------------}
17258 procedure TQtAbstractScrollArea.setVerticalScrollBar(AScrollBar: TQtScrollBar);
17259 begin
17260   {$ifdef VerboseQt}
17261     WriteLn('TQAbstractScrollArea.setVerticalScrollBar');
17262   {$endif}
17263   FVScrollBar := AScrollBar;
17264   if Assigned(FVScrollBar) then
17265     QAbstractScrollArea_setVerticalScrollBar(QAbstractScrollAreaH(Widget), QScrollBarH(FVScrollBar.Widget));
17266 end;
17267 
17268 {------------------------------------------------------------------------------
17269   Function: TQtAbstractScrollArea.setScrollStyle
17270   Params:  None
17271   Returns: Nothing
17272            Setting scrollbar''s policy (LCL TScrollStyle)
17273  -----------------------------------------------------------------------------}
17274 procedure TQtAbstractScrollArea.setScrollStyle(AScrollStyle: TScrollStyle);
17275 begin
17276   {$ifdef VerboseQt}
17277     WriteLn('TQAbstractScrollArea.setScrollStyle');
17278   {$endif}
17279   case AScrollStyle of
17280     ssNone:
17281     begin
17282       ScrollBarPolicy[True] := QtScrollBarAlwaysOff;
17283       ScrollBarPolicy[False] := QtScrollBarAlwaysOff;
17284     end;
17285     ssHorizontal, ssVertical:
17286     begin
17287       ScrollBarPolicy[AScrollStyle = ssVertical] := QtScrollBarAlwaysOn;
17288     end;
17289     ssBoth:
17290     begin
17291       ScrollBarPolicy[True] := QtScrollBarAlwaysOn;
17292       ScrollBarPolicy[False] := QtScrollBarAlwaysOn;
17293     end;
17294     ssAutoHorizontal, ssAutoVertical:
17295     begin
17296       ScrollBarPolicy[AScrollStyle = ssAutoVertical] := QtScrollBarAsNeeded;
17297     end;
17298     ssAutoBoth:
17299     begin
17300       ScrollBarPolicy[True] := QtScrollBarAsNeeded;
17301       ScrollBarPolicy[False] := QtScrollBarAsNeeded;
17302     end;
17303   end;
17304 
17305 end;
17306 
17307 procedure TQtAbstractScrollArea.SetNoMousePropagation(Sender: QWidgetH;
17308   const ANoMousePropagation: Boolean);
17309 begin
17310   // keep it so because sender can be dangling pointer from qt inside
17311   // mouse event of viewportWidget ! issue #26466
17312   if Sender = viewportWidget then
17313     inherited SetNoMousePropagation(Sender, False)
17314   else
17315     inherited SetNoMousePropagation(Sender, ANoMousePropagation);
17316 end;
17317 
17318 procedure TQtAbstractScrollArea.DestroyNotify(AWidget: TQtWidget);
17319 begin
17320   if AWidget = FHScrollbar then
17321     FHScrollbar := nil;
17322 
17323   if AWidget = FVScrollbar then
17324     FVScrollbar := nil;
17325 
17326   inherited DestroyNotify(AWidget);
17327 end;
17328 
17329 destructor TQtAbstractScrollArea.Destroy;
17330 begin
17331   FreeAndNil(FHScrollBar);
17332   FreeAndNil(FVScrollBar);
17333   inherited Destroy;
17334 end;
17335 
17336 procedure TQtAbstractScrollArea.Update(ARect: PRect);
17337 var
17338   P: TPoint;
17339 begin
17340   if ARect <> nil then
17341   begin
17342     P := getClientOffset;
17343     OffsetRect(ARect^, -P.X , -P.Y);
17344     QWidget_update(viewportWidget, ARect);
17345   end else
17346     QWidget_update(viewportWidget);
17347 end;
17348 
17349 procedure TQtAbstractScrollArea.UpdateRegion(ARgn: QRegionH);
17350 begin
17351   if ARgn <> nil then
17352     QWidget_update(viewportWidget, ARgn)
17353   else
17354     QWidget_update(viewportWidget);
17355 end;
17356 
17357 procedure TQtAbstractScrollArea.Repaint(ARect: PRect);
17358 var
17359   P: TPoint;
17360 begin
17361   if ARect <> nil then
17362   begin
17363     P := getClientOffset;
17364     OffsetRect(ARect^, -P.X , -P.Y);
17365     QWidget_repaint(viewportWidget, ARect);
17366   end else
17367     QWidget_repaint(viewportWidget);
17368 end;
17369 
17370 { TQtCustomControl }
17371 
17372 {------------------------------------------------------------------------------
17373   Function: TQtCustomControl.CreateWidget
17374   Params:  None
17375   Returns: Nothing
17376  ------------------------------------------------------------------------------}
CreateWidgetnull17377 function TQtCustomControl.CreateWidget(const AParams: TCreateParams):QWidgetH;
17378 var
17379   Parent: QWidgetH;
17380 begin
17381   // Creates the widget
17382   {$ifdef VerboseQt}
17383     WriteLn('TQtCustomControl.CreateWidget');
17384   {$endif}
17385   FHasPaint := True;
17386   FViewPortWidget := nil;
17387   if AParams.WndParent <> 0 then
17388     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
17389   else
17390     Parent := nil;
17391   Result := QLCLAbstractScrollArea_create(Parent);
17392 
17393   FChildOfComplexWidget := ccwCustomControl;
17394 
17395   if (LCLObject is TScrollingWinControl) then
17396     FChildOfComplexWidget := ccwScrollingWinControl
17397   else
17398     QWidget_setAutoFillBackground(Result, False);
17399 
17400   QWidget_setAttribute(Result, QtWA_InputMethodEnabled);
17401 end;
17402 
ProcessArrowKeysnull17403 function TQtCustomControl.ProcessArrowKeys: Boolean;
17404 begin
17405   Result := True;
17406 end;
17407 
17408 {------------------------------------------------------------------------------
17409   Function: TQtCustomControl.Destroy
17410   Params:  None
17411   Returns: Nothing
17412  ------------------------------------------------------------------------------}
17413 destructor TQtCustomControl.Destroy;
17414 begin
17415   {$ifdef VerboseQt}
17416     WriteLn('TQtCustomControl.Destroy');
17417   {$endif}
17418   viewportDelete;
17419   inherited Destroy;
17420 end;
17421 
EventFilternull17422 function TQtCustomControl.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
17423 begin
17424   Result := False;
17425   QEvent_accept(Event);
17426   if (LCLObject = nil) then
17427     exit;
17428 
17429   if (QEvent_type(Event) in [
17430                             QEventPaint,
17431                             QEventResize, // TQtViewport.EventFilter sends resize !
17432                             QEventMouseButtonPress,
17433                             QEventMouseButtonRelease,
17434                             QEventMouseButtonDblClick,
17435                             QEventContextMenu
17436                            ]) and
17437      (ClassType = TQtCustomControl) then
17438     Result := False
17439   else
17440   if QEvent_type(Event) = QEventWheel then
17441   begin
17442     if not getEnabled then
17443      inherited EventFilter(Sender, Event)
17444     else
17445     if not horizontalScrollBar.getVisible and
17446       not verticalScrollBar.getVisible then
17447       Result := inherited EventFilter(Sender, Event)
17448     else
17449       Result := False;
17450   end else
17451   {$IFDEF MSWINDOWS}
17452   {sometimes our IDE completely freezes, after screensaver activated
17453    or OS sleep state / hibernation under Win32 (if cursor stays
17454    inside SourceEditor), so if application is deactivated by OS
17455    we must release mouse grab. }
17456   if QEvent_type(Event) = QEventApplicationDeactivate then
17457   begin
17458     if HWND(Self) = GetCapture then
17459       ReleaseCapture;
17460     Result := inherited EventFilter(Sender, Event);
17461   end else
17462   {$ENDIF}
17463     Result := inherited EventFilter(Sender, Event);
17464 end;
17465 
17466 procedure TQtCustomControl.ViewPortEventFilter(event: QEventH; retval: PBoolean); cdecl;
17467 var
17468   MouseEventTyp: Boolean;
17469 begin
17470   {$ifdef VerboseViewPortEventFilter}
17471     WriteLn('ViewPortEventFilter ',QEvent_type(Event));
17472   {$endif}
17473 
17474   QEvent_accept(Event);
17475 
17476   case QEvent_type(Event) of
17477     QEventResize,
17478     QEventMouseButtonPress,
17479     QEventMouseButtonRelease,
17480     QEventMouseButtonDblClick,
17481     QEventMouseMove,
17482     QEventWheel,
17483     QEventContextMenu,
17484     QEventPaint:
17485     begin
17486       MouseEventTyp := (QEvent_type(Event) = QEventMouseButtonPress) or
17487         (QEvent_type(Event) = QEventMouseButtonRelease) or
17488         (QEvent_type(Event) = QEventMouseButtonDblClick) or
17489         (QEvent_type(Event) = QEventWheel) or
17490         (QEvent_type(Event) = QEventMouseMove);
17491 
17492       if (QEvent_type(Event) = QEventWheel) then
17493         QLCLAbstractScrollArea_InheritedViewportEvent(QLCLAbstractScrollAreaH(Widget), event);
17494 
17495       retval^ := True;
17496 
17497       if FViewPortWidget <> nil then
17498         Viewport.EventFilter(ViewPortWidget, Event);
17499 
17500       // do not allow qt to call notifications on user input events (mouse)
17501       // otherwise we can crash since our object maybe does not exist
17502       // after mouse clicks
17503       if not MouseEventTyp then
17504         QEvent_ignore(Event);
17505     end;
17506   else
17507     retval^ := QLCLAbstractScrollArea_InheritedViewportEvent(QLCLAbstractScrollAreaH(Widget), event);
17508   end;
17509 end;
17510 
17511 procedure TQtCustomControl.Destroyed; cdecl;
17512 begin
17513   viewportDelete;
17514   inherited Destroyed;
17515 end;
17516 
17517 procedure TQtCustomControl.DestroyNotify(AWidget: TQtWidget);
17518 begin
17519   if AWidget = FCornerWidget then
17520     FCornerWidget := nil;
17521 
17522   if AWidget = FViewPortWidget then
17523     FViewPortWidget := nil;
17524 
17525   inherited DestroyNotify(AWidget);
17526 end;
17527 
CanAdjustClientRectOnResizenull17528 function TQtCustomControl.CanAdjustClientRectOnResize: Boolean;
17529 begin
17530   // DoAdjustClientRectChange(); is called from TQtViewport resize event !
17531   Result := True;
17532 end;
17533 
17534 {------------------------------------------------------------------------------
17535   Function: TQtCustomControl.cornerWidget
17536   Params:  None
17537   Returns: Nothing
17538  ------------------------------------------------------------------------------}
cornerWidgetnull17539 function TQtCustomControl.cornerWidget: TQtWidget;
17540 begin
17541   {$ifdef VerboseQt}
17542     WriteLn('TQAbstractScrollArea.cornerWidget');
17543   {$endif}
17544   Result := FCornerWidget;
17545 end;
17546 
MapToGlobalnull17547 function TQtCustomControl.MapToGlobal(APt: TPoint;
17548   const AWithScrollOffset: Boolean = False): TPoint;
17549 var
17550   Pt: TPoint;
17551 begin
17552   Result := inherited MapToGlobal(APt);
17553   if AWithScrollOffset and (ChildOfComplexWidget = ccwScrollingWinControl) then
17554   begin
17555     Pt := viewport.ScrolledOffset;
17556     dec(Result.X, Pt.X);
17557     dec(Result.Y, Pt.Y);
17558   end;
17559 end;
17560 
MapFromGlobalnull17561 function TQtCustomControl.MapFromGlobal(APt: TPoint;
17562   const AWithScrollOffset: Boolean = False): TPoint;
17563 begin
17564   //TODO: see what to do with ccwScrollingWinControl
17565   Result := inherited MapFromGlobal(APt);
17566 end;
17567 
17568 procedure TQtCustomControl.InitializeAccessibility;
17569 {$IFDEF QTACCESSIBILITY}
17570 var
17571   LCLAxObject: TLazAccessibleObject;
17572 {$ENDIF}
17573 begin
17574   inherited InitializeAccessibility;
17575   {$IFDEF QTACCESSIBILITY}
17576   if (LCLObject <> nil) then begin
17577     // TWinControl.Handle is still not set so can't do handle creation through LCLAxObject.CreateHandle
17578     LCLAxObject :=  LCLObject.GetAccessibleObject;
17579       if LCLAxObject.AccessibleRole = larTreeView then
17580         LCLAxObject.Handle :=
17581           HWND(TQtAccessibleTree.Create(LCLAxObject, Widget))
17582       else
17583         LCLAxObject.Handle :=
17584           HWND(TQtAccessibleObject.Create(LCLAxObject, Widget));
17585   end;
17586   {$ENDIF}
17587 end;
17588 
17589 {------------------------------------------------------------------------------
17590   Function: TQtCustomControl.setCornerWidget
17591   Params:  TQtWidget
17592   Returns: Nothing
17593  ------------------------------------------------------------------------------}
17594 procedure TQtCustomControl.setCornerWidget(AWidget: TQtWidget);
17595 begin
17596   {$ifdef VerboseQt}
17597     WriteLn('TQAbstractScrollArea.setCornerWidget');
17598   {$endif}
17599   FCornerWidget := AWidget;
17600   if Assigned(FCornerWidget) then
17601     QAbstractScrollArea_setCornerWidget(QAbstractScrollAreaH(Widget), FCornerWidget.Widget)
17602   else
17603     QAbstractScrollArea_setCornerWidget(QAbstractScrollAreaH(Widget), NiL);
17604 end;
17605 
17606 procedure TQtCustomControl.setCursor(const ACursor: QCursorH);
17607 begin
17608   if (LCLObject is TCustomControl) and HasPaint then
17609     viewport.setCursor(ACursor)
17610   else
17611     inherited setCursor(ACursor);
17612 end;
17613 
17614 procedure TQtCustomControl.setViewport(const AViewPort: QWidgetH);
17615 begin
17616   QAbstractScrollArea_setViewport(QAbstractScrollAreaH(Widget), AViewPort);
17617 end;
17618 
17619 procedure TQtCustomControl.setVisible(AVisible: Boolean);
17620 begin
17621   inherited setVisible(AVisible);
17622   if FViewPortWidget <> nil then
17623     FViewPortWidget.setVisible(AVisible);
17624 end;
17625 
17626 {------------------------------------------------------------------------------
17627   Function: TQtCustomControl.viewport
17628   Params:  None
17629   Returns: viewport widget of QAbstractScrollArea
17630  ------------------------------------------------------------------------------}
viewportnull17631 function TQtCustomControl.viewport: TQtViewPort;
17632 begin
17633   viewportNeeded;
17634   Result := FViewPortWidget;
17635 end;
17636 
17637 procedure TQtCustomControl.preferredSize(var PreferredWidth,
17638   PreferredHeight: integer; WithThemeSpace: Boolean);
17639 begin
17640   if LCLObject is TCustomControl then
17641   begin
17642     PreferredWidth := 0;
17643     PreferredHeight := 0;
17644   end else
17645     inherited preferredSize(PreferredWidth, PreferredHeight, WithThemeSpace);
17646 end;
17647 
17648 {------------------------------------------------------------------------------
17649   Function: TQtCustomControl.viewportNeeded
17650   Params:  None
17651   Returns: Nothing
17652            Creates viewport widget for QAbstractScrollArea
17653  ------------------------------------------------------------------------------}
17654 procedure TQtCustomControl.viewportNeeded;
17655 var
17656   AParams: TCreateParams;
17657 begin
17658   if FViewPortWidget <> niL then
17659     exit;
17660   FillChar(AParams{%H-}, SizeOf(AParams), #0);
17661   FViewPortWidget := TQtViewPort.Create(LCLObject, AParams);
17662   FViewPortWidget.setFocusProxy(Widget);
17663   FViewPortWidget.setBackgroundRole(QPaletteNoRole);
17664   FViewPortWidget.setAutoFillBackground(False);
17665   FViewPortWidget.FOwner := Self;
17666   FViewPortWidget.FChildOfComplexWidget := FChildOfComplexWidget;
17667 
17668   // some events will be redirected to scroll area
17669   FViewPortWidget.AttachEvents;
17670 
17671   QLCLAbstractScrollArea_override_viewportEvent(QLCLAbstractScrollAreaH(Widget),
17672     @ViewPortEventFilter);
17673 
17674   setViewport(FViewPortWidget.Widget);
17675 end;
17676 
17677 procedure TQtCustomControl.viewportDelete;
17678 begin
17679   if Assigned(FViewPortWidget) then
17680   begin
17681     QLCLAbstractScrollArea_override_viewportEvent(QLCLAbstractScrollAreaH(Widget),
17682       QLCLAbstractScrollArea_viewportEvent_Override(NilMethod));
17683     FViewPortWidget.FOwner := nil;
17684     FViewPortWidget.Release;
17685     FViewPortWidget := nil;
17686   end;
17687 end;
17688 
17689   { TQtCalendar }
17690 
TQtCalendar.GetDateTimenull17691 function TQtCalendar.GetDateTime: TDateTime;
17692 var
17693   Date: QDateH;
17694 begin
17695   Date := QDate_create();
17696   QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), Date);
17697   AYear := QDate_year(Date);
17698   AMonth := QDate_month(Date);
17699   ADay := QDate_day(Date);
17700   QDate_destroy(Date);
17701   Result := EncodeDate(AYear, AMonth, ADay);
17702 end;
17703 
17704 procedure TQtCalendar.SetDateTime(const AValue: TDateTime);
17705 var
17706   Date: QDateH;
17707 begin
17708   DecodeDate(AValue, AYear, AMonth, ADay);
17709   Date := QDate_create(AYear, AMonth, ADay);
17710   QCalendarWidget_setCurrentPage(QCalendarWidgetH(Widget),
17711     AYear, AMonth);
17712   SetSelectedDate(Date);
17713   QDate_destroy(Date);
17714 end;
17715 
17716 procedure TQtCalendar.SetSelectedDate(const AValue: QDateH);
17717 begin
17718   QCalendarWidget_setSelectedDate(QCalendarWidgetH(Widget), AValue);
17719 end;
17720 
17721 {------------------------------------------------------------------------------
17722   Function: TQtCalendar.CreateWidget
17723   Params:  None
17724   Returns: Nothing
17725  ------------------------------------------------------------------------------}
TQtCalendar.CreateWidgetnull17726 function TQtCalendar.CreateWidget(const AParams: TCreateParams):QWidgetH;
17727 var
17728   Parent: QWidgetH;
17729 begin
17730   // Creates the widget
17731   {$ifdef VerboseQt}
17732     WriteLn('TQtCalendar.Create');
17733   {$endif}
17734   FMouseDoubleClicked := False;
17735   if AParams.WndParent <> 0 then
17736     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
17737   else
17738     Parent := nil;
17739   Result := QCalendarWidget_create(Parent);
17740 end;
17741 
17742 procedure TQtCalendar.AttachEvents;
17743 var
17744   i: integer;
17745   Children: TPtrIntArray;
17746   AnObject: QObjectH;
17747   WP: QWidgetH;
17748 begin
17749   inherited AttachEvents;
17750 
17751   FClickedHook := QCalendarWidget_hook_create(Widget);
17752   FActivatedHook := QCalendarWidget_hook_create(Widget);
17753   FSelectionChangedHook := QCalendarWidget_hook_create(Widget);
17754   FCurrentPageChangedHook := QCalendarWidget_hook_create(Widget);
17755 
17756   QCalendarWidget_hook_hook_clicked(FClickedHook, @SignalClicked);
17757 
17758   QCalendarWidget_hook_hook_activated(FActivatedHook, @SignalActivated);
17759 
17760   QCalendarWidget_hook_hook_selectionChanged(FSelectionChangedHook, @SignalSelectionChanged);
17761 
17762   QCalendarWidget_hook_hook_currentPageChanged(FCurrentPageChangedHook, @SignalCurrentPageChanged);
17763 
17764   QObject_children(Widget, @Children);
17765   for i := 0 to High(Children) do
17766   begin
17767     AnObject := QObjectH(Children[i]);
17768     if QObject_isWidgetType(AnObject) then
17769     begin
17770       {do not localize !!}
17771       if QObject_inherits(AnObject,'QAbstractScrollArea') then
17772       begin
17773         WP := QAbstractScrollArea_viewport(QAbstractScrollAreaH(AnObject));
17774         QWidget_setMouseTracking(WP, True);
17775         FCalViewportEventHook := QObject_hook_create(WP);
17776         QObject_hook_hook_events(FCalViewportEventHook, @calViewportEventFilter);
17777         setProperty(QWidgetH(AnObject), 'lclwidget', Int64(PtrUInt(Self)));
17778         FCalViewAreaEventHook := QObject_hook_create(QWidgetH(AnObject));
17779         QObject_hook_hook_events(FCalViewAreaEventHook, @AreaViewEventFilter);
17780       end;
17781     end;
17782   end;
17783 end;
17784 
17785 procedure TQtCalendar.DetachEvents;
17786 begin
17787   if FCalViewAreaEventHook <> nil then
17788   begin
17789     QObject_hook_destroy(FCalViewAreaEventHook);
17790     FCalViewAreaEventHook := nil;
17791   end;
17792   if FCalViewportEventHook <> nil then
17793   begin
17794     QObject_hook_destroy(FCalViewportEventHook);
17795     FCalViewportEventHook := nil;
17796   end;
17797   if FClickedHook <> nil then
17798   begin
17799     QCalendarWidget_hook_destroy(FClickedHook);
17800     FClickedHook := nil;
17801   end;
17802   if FActivatedHook <> nil then
17803   begin
17804     QCalendarWidget_hook_destroy(FActivatedHook);
17805     FActivatedHook := nil;
17806   end;
17807   if FSelectionChangedHook <> nil then
17808   begin
17809     QCalendarWidget_hook_destroy(FSelectionChangedHook);
17810     FSelectionChangedHook := nil;
17811   end;
17812   if FCurrentPageChangedHook <> nil then
17813   begin
17814     QCalendarWidget_hook_destroy(FCurrentPageChangedHook);
17815     FCurrentPageChangedHook := nil;
17816   end;
17817   inherited DetachEvents;
17818 end;
17819 
TQtCalendar.EventFilternull17820 function TQtCalendar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
17821   cdecl;
17822 begin
17823   Result := False;
17824   if (QEvent_Type(Event) = QEventKeyPress) or (QEvent_Type(Event) = QEventKeyRelease) then
17825     exit;
17826   Result := inherited EventFilter(Sender, Event);
17827 end;
17828 
AreaViewEventFilternull17829 function TQtCalendar.AreaViewEventFilter(Sender: QObjectH; Event: QEventH
17830   ): Boolean; cdecl;
17831 var
17832   ADate: QDateH;
17833   AKey: Integer;
17834 begin
17835   Result := False;
17836   if (LCLObject <> nil) and ((QEvent_type(Event) = QEventKeyPress) or
17837     (QEvent_type(Event) = QEventKeyRelease)) then
17838   begin
17839     AKey := QKeyEvent_key(QKeyEventH(Event));
17840     Result := SlotKey(Widget, Event);
17841     if (QEvent_type(Event) = QEventKeyRelease) and
17842       ( (AKey = QtKey_Up) or (AKey = QtKey_Left) or
17843         (AKey = QtKey_Right) or (AKey = QtKey_Down) ) then
17844     begin
17845       ADate := QDate_create();
17846       QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), ADate);
17847       DeliverDayChanged(ADate);
17848       QDate_destroy(ADate);
17849     end;
17850   end;
17851 end;
17852 
calViewportEventFilternull17853 function TQtCalendar.calViewportEventFilter(Sender: QObjectH; Event: QEventH
17854   ): Boolean; cdecl;
17855 begin
17856   {we install only mouse dblclick event on QCalendar viewport,
17857    since inside signalActivated we don't know is it signalled from
17858    dblclick or by pressing return key.}
17859   Result := False;
17860   QEvent_accept(Event);
17861   if (LCLObject <> nil) then
17862   begin
17863     case QEvent_type(Event) of
17864       QEventMouseMove: Result := SlotMouseMove(Sender, Event);
17865       QEventEnter,
17866       QEventLeave: Result := SlotMouseEnter(Sender, Event);
17867       QEventMouseButtonDblClick: FMouseDoubleClicked := True;
17868       QEventWheel:
17869         begin
17870           if not getEnabled then
17871           begin
17872             QEvent_ignore(Event);
17873             QWidget_setAttribute(QWidgetH(Sender), QtWA_NoMousePropagation, False);
17874           end;
17875         end;
17876     end;
17877   end;
17878 end;
17879 
HitTestnull17880 function TQtCalendar.HitTest(const APoint: TPoint): byte;
17881 var
17882   Layout: QLayoutH;
17883   CalendarBody: QWidgetH;
17884   HeaderRect, BodyRect: TRect;
17885   AQtPoint: TQtPoint;
17886   Index: QModelIndexH;
17887 begin
17888   Result := 0;
17889   Layout := QWidget_layout(Widget);
17890   // layout must have 2 items:
17891   // 1 - navigation bar
17892   // 2 - calendar model
17893   if QLayout_count(Layout) <> 2 then
17894     Exit;
17895   QLayoutItem_geometry(QLayout_itemAt(Layout, 0), @HeaderRect);
17896   QLayoutItem_geometry(QLayout_itemAt(Layout, 1), @BodyRect);
17897   if PtInRect(HeaderRect, APoint) then
17898   begin
17899     // we are in the header
17900     Result := 3;
17901     // todo: detail result more - button / month / year
17902   end
17903   else
17904   if PtInRect(BodyRect, APoint) then
17905   begin
17906     CalendarBody := QLayoutItem_widget(QLayout_itemAt(Layout, 1));
17907     AQtPoint := QtPoint(APoint.X, APoint.Y);
17908     QWidget_mapFrom(CalendarBody, @AQtPoint, Widget, @AQtPoint);
17909     Index := QModelIndex_create();
17910     try
17911       QTableView_indexAt(QTableWidgetH(CalendarBody), Index, @AQtPoint);
17912       if (QCalendarWidget_horizontalHeaderFormat(QCalendarWidgetH(Widget)) = QCalendarWidgetNoHorizontalHeader) or
17913          (QModelIndex_row(Index) > 0) then
17914       begin
17915         if (QCalendarWidget_verticalHeaderFormat(QCalendarWidgetH(Widget)) = QCalendarWidgetNoVerticalHeader) or
17916            (QModelIndex_column(Index) > 0) then
17917           Result := 1
17918         else
17919           Result := 2;
17920       end;
17921     finally
17922       QModelIndex_destroy(Index);
17923     end;
17924   end;
17925 end;
17926 
17927 procedure TQtCalendar.SetDisplaySettings(
17928       const AHHdrFmt: QCalendarWidgetHorizontalHeaderFormat;
17929       const AVHdrFmt: QCalendarWidgetVerticalHeaderFormat;
17930       const ASelMode: QCalendarWidgetSelectionMode;
17931       const ANavBarVisible: Boolean; const AGridVisible: Boolean);
17932 begin
17933   QCalendarWidget_setHorizontalHeaderFormat(QCalendarWidgetH(Widget), AHHdrFmt);
17934   QCalendarWidget_setNavigationBarVisible(QCalendarWidgetH(Widget), ANavBarVisible);
17935   QCalendarWidget_setVerticalHeaderFormat(QCalendarWidgetH(Widget), AVHdrFmt);
17936   QCalendarWidget_setGridVisible(QCalendarWidgetH(Widget), AGridVisible);
17937   QCalendarWidget_setSelectionMode(QCalendarWidgetH(Widget), ASelMode);
17938 end;
17939 
17940 procedure TQtCalendar.SetFirstDayOfWeek(const ADayOfWeek: QtDayOfWeek);
17941 begin
17942   QCalendarWidget_setFirstDayOfWeek(QCalendarWidgetH(Widget), ADayOfWeek);
17943 end;
17944 
TQtCalendar.DeliverDayChangednull17945 function TQtCalendar.DeliverDayChanged(ADate: QDateH): boolean;
17946 var
17947   y,m,d: Integer;
17948   Msg: TLMessage;
17949 begin
17950   Result := False;
17951   FillChar(Msg{%H-}, SizeOf(Msg), #0);
17952   Msg.Msg := LM_DAYCHANGED;
17953   y := QDate_year(ADate);
17954   m := QDate_month(ADate);
17955   d := QDate_day(ADate);
17956   Result := (y <> aYear) or (m <> aMonth) or (d <> aDay);
17957   if Result then
17958     DeliverMessage(Msg);
17959   aYear := y;
17960   aMonth := m;
17961   aDay := d;
17962 end;
17963 
17964 {------------------------------------------------------------------------------
17965   Function: TQtCalendar.SignalActivated
17966   Params:  None
17967   Returns: Nothing
17968            Sends signal when RETURN pressed on selected date.
17969  ------------------------------------------------------------------------------}
17970 procedure TQtCalendar.SignalActivated(ADate: QDateH); cdecl;
17971 var
17972   AKeyEvent: QKeyEventH;
17973   AMouseEvent: QMouseEventH;
17974   APos, AGlobalPos: TQtPoint;
17975   APosF, AGlobalPosF: TQtPointF;
17976 begin
17977   {$IFDEF VerboseQt}
17978   writeln('TQtCalendar.signalActivated ');
17979   {$ENDIF}
17980 
17981   DeliverDayChanged(ADate);
17982 
17983   {avoid OnAcceptDate() to trigger twice if doubleclicked
17984    via FMouseDoubleClicked, also send dummy Key events to LCL when item
17985    activated (only QtKey_Return activates)}
17986   if not FMouseDoubleClicked then
17987   begin
17988     AKeyEvent := QKeyEvent_create(QEventKeyPress, QtKey_Return, QtNoModifier);
17989     SlotKey(Widget, AKeyEvent);
17990     QEvent_destroy(AKeyEvent);
17991     AKeyEvent := QKeyEvent_create(QEventKeyRelease, QtKey_Return, QtNoModifier);
17992     SlotKey(Widget, AKeyEvent);
17993     QEvent_destroy(AKeyEvent);
17994   end else
17995   begin
17996     FMouseDoubleClicked := False;
17997     if QWidget_underMouse(Widget) then
17998     begin
17999       QCursor_pos(@AGlobalPos);
18000       QWidget_mapFromGlobal(Widget, @APos, @AGlobalPos);
18001       APosF.X := APos.X;
18002       APosF.Y := APos.Y;
18003       AGlobalPosF.X := AGlobalPos.X;
18004       AGlobalPosF.Y := AGlobalPos.Y;
18005       AMouseEvent := QMouseEvent_create(QEventMouseButtonDblClick, @APosF,
18006         @AGlobalPosF, QtLeftButton, QtLeftButton,
18007         QGUIApplication_keyboardModifiers());
18008       SlotMouse(Widget, AMouseEvent);
18009       QMouseEvent_destroy(AMouseEvent);
18010     end;
18011   end;
18012 end;
18013 
18014 {------------------------------------------------------------------------------
18015   Function: TQtCalendar.SignalClicked
18016   Params:  None
18017   Returns: Nothing
18018            Sends msg LM_DAYCHANGED when OldDate<>NewDate
18019  ------------------------------------------------------------------------------}
18020 procedure TQtCalendar.SignalClicked(ADate: QDateH); cdecl;
18021 var
18022   AEvent: QMouseEventH;
18023   APos, AGlobalPos: TQtPoint;
18024   APosF, AGlobalPosF: TQtPointF;
18025 begin
18026   {$IFDEF VerboseQt}
18027   writeln('TQtCalendar.signalClicked');
18028   {$ENDIF}
18029   DeliverDayChanged(ADate);
18030 
18031   if QWidget_underMouse(Widget) then
18032   begin
18033     {we create dummy event for LCL, and call directly SlotMouse() - no need
18034     to send it via event loop}
18035     QCursor_pos(@AGlobalPos);
18036     QWidget_mapFromGlobal(Widget, @APos, @AGlobalPos);
18037     APosF.X := APos.X;
18038     APosF.Y := APos.Y;
18039     AGlobalPosF.X := AGlobalPos.X;
18040     AGlobalPosF.Y := AGlobalPos.Y;
18041     AEvent := QMouseEvent_create(QEventMouseButtonPress, @APosF, @AGlobalPosF,
18042       QtLeftButton, QtLeftButton, QGUIApplication_keyboardModifiers());
18043     SlotMouse(Widget, AEvent);
18044     QMouseEvent_destroy(AEvent);
18045     AEvent := QMouseEvent_create(QEventMouseButtonRelease, @APosF, @AGlobalPosF,
18046       QtLeftButton, QtLeftButton, QGUIApplication_keyboardModifiers());
18047     SlotMouse(Widget, AEvent);
18048     QMouseEvent_destroy(AEvent);
18049   end;
18050 end;
18051 
18052 {------------------------------------------------------------------------------
18053   Function: TQtCalendar.SignalSelectionChanged
18054   Params:  None
18055   Returns: Nothing
18056 
18057   Notes: no event for date changed by keyboard ?!?
18058    always triggers even if selection isn't changed ...
18059    this is not Qt4 bug ... tested with pure Qt C++ app
18060  ------------------------------------------------------------------------------}
18061 procedure TQtCalendar.SignalSelectionChanged; cdecl;
18062 var
18063   Msg: TLMessage;
18064 begin
18065   {$IFDEF VerboseQt}
18066   writeln('TQtCalendar.SignalSelectionChanged');
18067   {$ENDIF}
18068   if InUpdate then
18069     exit;
18070   FillChar(Msg{%H-}, SizeOf(Msg), #0);
18071   Msg.Msg := LM_SELCHANGE;
18072   DeliverMessage(Msg);
18073 end;
18074 
18075 {------------------------------------------------------------------------------
18076   Function: TQtCalendar.SignalCurrentPageChanged
18077   Params:  None
18078   Returns: Nothing
18079 
18080   Notes: fixme what's wrong with those values ?!?
18081    with pure Qt C++ app this works ok, but via bindings get
18082    impossible year & month values ...
18083  ------------------------------------------------------------------------------}
18084 procedure TQtCalendar.signalCurrentPageChanged(p1, p2: Integer); cdecl;
18085 var
18086   Msg: TLMessage;
18087   ADate: QDateH;
18088   HasChanges: Boolean;
18089   TempYear, TempMonth: Integer;
18090 begin
18091   {$IFDEF VerboseQt}
18092   writeln('TQtCalendar.SignalCurrentPageChanged p1=',p1,' p2=',p2,' AMonth=',AMonth,' AYear=',AYear);
18093   {$ENDIF}
18094   if InUpdate then
18095     exit;
18096   TempYear := AYear;
18097   TempMonth := AMonth;
18098   FillChar(Msg{%H-}, SizeOf(Msg), #0);
18099   HasChanges := (TempYear <> p1) or (TempMonth <> p2);
18100 
18101   if HasChanges then
18102   begin
18103     ADate := QDate_create();
18104     try
18105       QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), ADate);
18106       QDate_setDate(ADate, p1, p2, QDate_day(ADate));
18107       SetSelectedDate(ADate);
18108     finally
18109       QDate_destroy(ADate);
18110     end;
18111   end;
18112 
18113   if TempYear <> p1 then
18114   begin
18115     Msg.Msg := LM_YEARCHANGED;
18116     DeliverMessage(Msg);
18117   end;
18118 
18119   if TempMonth <> p2 then
18120   begin
18121     Msg.Msg := LM_MONTHCHANGED;
18122     DeliverMessage(Msg);
18123   end;
18124 
18125   if HasChanges then
18126   begin
18127     Msg.Msg := LM_CHANGED;
18128     DeliverMessage(Msg);
18129   end;
18130 end;
18131 
18132 { TQtHintWindow }
18133 
CreateWidgetnull18134 function TQtHintWindow.CreateWidget(const AParams: TCreateParams): QWidgetH;
18135 var
18136   Parent: QWidgetH;
18137 begin
18138   FFirstPaintEvent := True;
18139   FHasPaint := True;
18140   FNeedRestoreVisible := False;
18141   if AParams.WndParent <> 0 then
18142     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
18143   else
18144   if QApplication_activeModalWidget <> nil then
18145     Parent := QApplication_activeModalWidget
18146   else
18147     Parent := nil;
18148   Result := QWidget_create(Parent, QtToolTip);
18149   FDeleteLater := True;
18150   MenuBar := nil;
18151   {$IFDEF QTSCROLLABLEFORMS}
18152   ScrollArea := nil;
18153   {$ENDIF}
18154 end;
18155 
TQtHintWindow.WinIDNeedednull18156 function TQtHintWindow.WinIDNeeded: boolean;
18157 begin
18158   Result := False;
18159 end;
18160 
18161 procedure TQtHintWindow.InitializeWidget;
18162 begin
18163   inherited InitializeWidget;
18164   {$IFDEF HASX11}
18165   QtWidgetSet.AddHintHandle(Self);
18166   {$ENDIF}
18167 end;
18168 
18169 procedure TQtHintWindow.DeInitializeWidget;
18170 begin
18171   {$IFDEF HASX11}
18172   QtWidgetSet.RemoveHintHandle(Self);
18173   {$ENDIF}
18174   inherited DeInitializeWidget;
18175 end;
18176 
CanPaintBackgroundnull18177 function TQtHintWindow.CanPaintBackground: Boolean;
18178 begin
18179   Result := CanSendLCLMessage and getEnabled and
18180     (LCLObject.Color <> clDefault);
18181 end;
18182 
18183 procedure TQtHintWindow.SetDefaultColorRoles;
18184 begin
18185   WidgetColorRole := QPaletteToolTipBase;
18186   TextColorRole := QPaletteToolTipText;
18187 end;
18188 
18189 procedure TQtHintWindow.setVisible(AVisible: Boolean);
18190 var
18191   D: TRect;
18192   R: TRect;
18193   Pt: TQtPoint;
18194   ScreenNumber: integer;
18195 begin
18196   // must use ClassType comparision here since qt is buggy about hints.#16551
18197   if AVisible and
18198     ((LCLObject.ClassType = THintWindow) or
18199       (LCLObject.InheritsFrom(THintWindow))) then
18200   begin
18201     R := getGeometry;
18202 
18203     if QDesktopWidget_isVirtualDesktop(QApplication_desktop()) then
18204     begin
18205       Pt.x := R.Left;
18206       Pt.y := R.Top;
18207       ScreenNumber := QDesktopWidget_screenNumber(QApplication_desktop(), @Pt);
18208     end
18209     else
18210     begin
18211       if Widget <> nil then
18212         ScreenNumber := QDesktopWidget_screenNumber(QApplication_desktop(), Widget)
18213       else
18214         ScreenNumber := 0;
18215     end;
18216     {$IFDEF DARWIN}
18217     QDesktopWidget_availableGeometry(QApplication_desktop() ,@D, ScreenNumber);
18218     {$ELSE}
18219     QDesktopWidget_screenGeometry(QApplication_desktop() ,@D, ScreenNumber);
18220     {$ENDIF}
18221 
18222     // place hint window within monitor rect
18223     if R.Right-R.Left > D.Right-D.Left then // check width
18224       R.Right := R.Left + D.Right-D.Left;
18225     if R.Bottom-R.Top > D.Bottom-D.Top then // check height
18226       R.Bottom := R.Top + D.Bottom-D.Top;
18227     if R.Left < D.Left then
18228       OffsetRect(R, D.Left-R.Left, 0);
18229     if R.Top < D.Top then
18230       OffsetRect(R, 0, D.Top-R.Top);
18231     if (R.Right > D.Right) then
18232       OffsetRect(R, D.Right-R.Right, 0);
18233     if (R.Bottom > D.Bottom) then
18234       OffsetRect(R, 0, D.Bottom-R.Bottom);
18235 
18236     move(R.Left, R.Top);
18237   end;
18238   inherited setVisible(AVisible);
18239 end;
18240 
18241 { TQtPage }
18242 
CreateWidgetnull18243 function TQtPage.CreateWidget(const AParams: TCreateParams): QWidgetH;
18244 var
18245   Parent: QWidgetH;
18246 begin
18247   FHasPaint := True;
18248   if AParams.WndParent <> 0 then
18249     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
18250   else
18251     Parent := nil;
18252   Result := QWidget_create(Parent);
18253 end;
18254 
TQtPage.EventFilternull18255 function TQtPage.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
18256 var
18257   ASize: TSize;
18258   ACapture: HWND;
18259   B: Boolean;
18260 begin
18261   Result := False;
18262   if LCLObject = nil then
18263     exit;
18264   if (QEvent_type(Event) = QEventResize) then
18265   begin
18266     if (csDestroying in LCLObject.ComponentState) or
18267       (csDestroyingHandle in LCLObject.ControlState) then
18268         exit;
18269     if not testAttribute(QtWA_Mapped) then
18270     begin
18271       ASize := QResizeEvent_size(QResizeEventH(Event))^;
18272       {$IFDEF VerboseQtResize}
18273       DebugLn('TQtPage.EventFilter widget is not mapped, resize event size=',dbgs(ASize));
18274       {$ENDIF}
18275       if (ASize.cx = 0) and (ASize.cy = 0) then
18276       begin
18277         ASize.cx := LCLObject.Width;
18278         ASize.cy := LCLObject.Height;
18279         {$IFDEF VerboseQtResize}
18280         DebugLn('TQtPage.EventFilter sending LCL size as size=',dbgs(ASize),' since our size is still 0x0');
18281         {$ENDIF}
18282       end;
18283       DelayResizeEvent(QWidgetH(Sender), ASize);
18284       exit;
18285     end;
18286   end else
18287   if (QEvent_type(Event) = QEventShow) and Assigned(LCLObject) and
18288     not (csDesigning in LCLObject.ComponentState) then
18289   begin
18290     if Assigned(DragManager) and DragManager.IsDragging then
18291       ACapture := GetCapture
18292     else
18293       ACapture := 0;
18294     B := (ACapture <> 0) and (ACapture <> HWND(Self));
18295     Result := inherited EventFilter(Sender, Event);
18296     if B then
18297     begin
18298       QtWidgetSet.InvalidateWidgetAtCache;
18299       SetCapture(0);
18300       SetCapture(HWND(Self));
18301     end;
18302   end else
18303   Result := inherited EventFilter(Sender, Event);
18304 end;
18305 
TQtPage.getIconnull18306 function TQtPage.getIcon: QIconH;
18307 begin
18308   Result := FIcon;
18309 end;
18310 
getIndexnull18311 function TQtPage.getIndex(const ATextChanging: Boolean = False): Integer;
18312 var
18313   AParent: QTabWidgetH;
18314 
CanReturnIndexnull18315   function CanReturnIndex: Boolean;
18316   begin
18317     Result := AParent <> nil;
18318     if Result then
18319       Result := QWidget_isVisible(AParent) or LCLObject.HandleObjectShouldBeVisible;
18320   end;
18321 
18322 begin
18323   AParent := getTabWidget;
18324   if CanReturnIndex or ATextChanging then
18325     Result := QTabWidget_indexOf(AParent, Widget)
18326   else
18327   if not QObject_inherits(QWidget_parentWidget(Widget),'QStackedWidget') then
18328     Result := 0
18329   else
18330     Result := -1;
18331 end;
18332 
getTabWidgetnull18333 function TQtPage.getTabWidget: QTabWidgetH;
18334 var
18335   AParent: QWidgetH;
18336 begin
18337   // it is placed to the stack widget and stack widget into tab widget
18338   AParent := QWidget_parentWidget(Widget);
18339   // do not localize !
18340   if (AParent <> nil) and QObject_inherits(AParent,'QStackedWidget') then
18341     Result := QTabWidgetH(QWidget_parentWidget(AParent))
18342   else
18343     Result := nil;
18344 end;
18345 
18346 procedure TQtPage.setIcon(const AIcon: QIconH);
18347 var
18348   AParent: QTabWidgetH;
18349   TabWidget: TQtTabWidget;
18350 begin
18351   FIcon := AIcon;
18352   AParent := getTabWidget;
18353   if AParent <> nil then
18354   begin
18355     if ChildOfComplexWidget = ccwTabWidget then
18356     begin
18357       TabWidget := TQtTabWidget(LCLObject.Parent.Handle);
18358       TabWidget.setTabIcon(TabWidget.indexOf(Widget), AIcon);
18359     end else
18360       QTabWidget_setTabIcon(AParent, getIndex, AIcon);
18361   end;
18362 end;
18363 
18364 procedure TQtPage.setText(const W: WideString);
18365 var
18366   AParent: QTabWidgetH;
18367   Index: integer;
18368 begin
18369   inherited setText(W);
18370   AParent := getTabWidget;
18371   if (AParent <> nil) then
18372   begin
18373     Index := getIndex(True);
18374     if Index <> -1 then
18375       QTabWidget_setTabText(AParent, Index, @W);
18376   end;
18377 end;
18378 
18379 { TQtAbstractItemView }
18380 
TQtAbstractItemView.GetOwnerDrawnnull18381 function TQtAbstractItemView.GetOwnerDrawn: Boolean;
18382 begin
18383   Result := FNewDelegate <> nil;
18384 end;
18385 
TQtAbstractItemView.getIconSizenull18386 function TQtAbstractItemView.getIconSize: TSize;
18387 begin
18388   QAbstractItemView_iconSize(QAbstractItemViewH(Widget), @Result);
18389 end;
18390 
TQtAbstractItemView.GetItemFlagsnull18391 function TQtAbstractItemView.GetItemFlags(AIndex: Integer): QtItemFlags;
18392 begin
18393   Result := QtNoItemFlags;
18394 end;
18395 
18396 procedure TQtAbstractItemView.setIconSize(const AValue: TSize);
18397 begin
18398   QAbstractItemView_setIconSize(QAbstractItemViewH(Widget), @AValue);
18399 end;
18400 
18401 procedure TQtAbstractItemView.SetItemFlags(AIndex: Integer; AValue: QtItemFlags
18402   );
18403 begin
18404   // must be overrided !
18405 end;
18406 
18407 procedure TQtAbstractItemView.SetOwnerDrawn(const AValue: Boolean);
18408 begin
18409   if AValue and (FNewDelegate = nil) then
18410   begin
18411     FNewDelegate := QLCLItemDelegate_create(Widget);
18412 
18413     QLCLItemDelegate_override_sizeHint(FNewDelegate, @ItemDelegateSizeHint);
18414 
18415     QLCLItemDelegate_override_Paint(FNewDelegate, @ItemDelegatePaint);
18416 
18417     FOldDelegate := QAbstractItemView_itemDelegate(QAbstractItemViewH(Widget));
18418     QAbstractItemView_setItemDelegate(QAbstractItemViewH(Widget), FNewDelegate);
18419   end
18420   else
18421   if ((not AValue) and (FNewDelegate <> nil)) then
18422   begin
18423     {TQtAbstractItemView.SetOwnerDrawn: this call avoid sporadic AVs with
18424      QLCLItemDelegate_destroy(FNewDelegate).
18425      howto reproduce: comment next code line, recompile laz, and then in oi click
18426      in first field eg. Action (TForm), now push kbd down arrow let it pass all properties,
18427      you'll have crash at Constraints property.}
18428     FNewDelegate := QLCLItemDelegateH(QAbstractItemView_itemDelegate(QAbstractItemViewH(Widget)));
18429     QAbstractItemView_setItemDelegate(QAbstractItemViewH(Widget), FOldDelegate);
18430     QLCLItemDelegate_destroy(FNewDelegate);
18431     FNewDelegate := nil;
18432   end;
18433 end;
18434 
18435 procedure TQtAbstractItemView.OwnerDataNeeded(ARect: TRect);
18436 begin
18437   // override
18438 end;
18439 
18440 procedure TQtAbstractItemView.PostponedMouseRelease(AEvent: QEventH);
18441  // postpone mouse release for LCL
18442 var
18443   ev: QMouseEventH;
18444   APos, AGlobalPos: TQtPoint;
18445   APosF, AGlobalPosF: TQtPointF;
18446 begin
18447   if QEvent_type(AEvent) = QEventMouseButtonRelease then
18448   begin
18449     ev := QMouseEventH(AEvent);
18450     QMouseEvent_pos(ev, @APos);
18451     QMouseEvent_globalPos(ev, @AGlobalPos);
18452     APosF.X := APos.X;
18453     APosF.Y := APos.Y;
18454     AGlobalPosF.X := AGlobalPos.X;
18455     AGlobalPosF.Y := AGlobalPos.Y;
18456     FSavedEvent := QMouseEvent_create(QEventMouseButtonRelease,
18457       @APosF, @AGlobalPosF,
18458       QMouseEvent_button(ev), QMouseEvent_buttons(ev),
18459       QInputEvent_modifiers(QInputEventH(AEvent)));
18460     FSavedEventTimer := QTimer_create(Widget);
18461     FSavedEventTimerHook := QTimer_hook_create(FSavedEventTimer);
18462     QTimer_hook_hook_timeout(FSavedEventTimerHook,
18463       @PostponedMouseReleaseTimerEvent);
18464     QTimer_setInterval(FSavedEventTimer, 5);
18465     QTimer_setSingleShot(FSavedEventTimer, True);
18466     QTimer_start(FSavedEventTimer);
18467   end;
18468 end;
18469 
18470 procedure TQtAbstractItemView.PostponedMouseReleaseTimerEvent(); cdecl;
18471 begin
18472   if FSavedEvent <> nil then
18473   begin
18474     SlotMouse(Widget, FSavedEvent);
18475     QMouseEvent_destroy(FSavedEvent);
18476     FSavedEvent := nil;
18477     QTimer_hook_destroy(FSavedEventTimerHook);
18478     QTimer_destroy(FSavedEventTimer);
18479     FSavedEventTimer := nil;
18480     FSavedEventTimerHook := nil;
18481   end;
18482 end;
18483 
18484 constructor TQtAbstractItemView.Create(const AWinControl: TWinControl;
18485   const AParams: TCreateParams);
18486 begin
18487   inherited Create(AWinControl, AParams);
18488   FOldDelegate := nil;
18489   FNewDelegate := nil;
18490 end;
18491 
18492 destructor TQtAbstractItemView.Destroy;
18493 begin
18494   if FNewDelegate <> nil then
18495     SetOwnerDrawn(False);
18496   inherited Destroy;
18497 end;
18498 
18499 procedure TQtAbstractItemView.signalActivated(index: QModelIndexH); cdecl;
18500 var
18501   Msg: TLMessage;
18502 begin
18503   // writeln('SIGNAL: TQtAbstractItemView.signalActivated');
18504   FillChar(Msg{%H-}, SizeOf(Msg), 0);
18505   Msg.Msg := LM_ACTIVATE;
18506   DeliverMessage( Msg );
18507 end;
18508 
18509 procedure TQtAbstractItemView.signalClicked(index: QModelIndexH); cdecl;
18510 begin
18511   {use to be overriden by descedants, don''t implement it here,
18512    or U get in trouble with TQtListView && TQtListWidget items.}
18513 end;
18514 
18515 procedure TQtAbstractItemView.signalDoubleClicked(index: QModelIndexH); cdecl;
18516 begin
18517   {use to be overriden by descedants, don''t implement it here,
18518    or U get in trouble with TQtListView && TQtListWidget items.}
18519 end;
18520 
18521 procedure TQtAbstractItemView.signalEntered(index: QModelIndexH); cdecl;
18522 var
18523   Msg: TLMessage;
18524 begin
18525   FillChar(Msg{%H-}, SizeOf(Msg), 0);
18526   Msg.Msg := LM_ENTER;
18527   DeliverMessage( Msg );
18528 end;
18529 
18530 procedure TQtAbstractItemView.signalPressed(index: QModelIndexH); cdecl;
18531 begin
18532   {should be overriden by descedants}
18533 end;
18534 
18535 procedure TQtAbstractItemView.signalViewportEntered; cdecl;
18536 begin
18537   {should be overriden by descedants}
18538 end;
18539 
18540 procedure TQtAbstractItemView.AttachEvents;
18541 begin
18542   inherited AttachEvents;
18543   FSignalActivated := QAbstractItemView_hook_create(Widget);
18544   FSignalClicked := QAbstractItemView_hook_create(Widget);
18545   FSignalDoubleClicked := QAbstractItemView_hook_create(Widget);
18546   FSignalEntered := QAbstractItemView_hook_create(Widget);
18547   FSignalPressed := QAbstractItemView_hook_create(Widget);
18548   FSignalViewportEntered := QAbstractItemView_hook_create(Widget);
18549 
18550   QAbstractItemView_hook_hook_activated(FSignalActivated, @SignalActivated);
18551 
18552   QAbstractItemView_hook_hook_clicked(FSignalClicked, @SignalClicked);
18553 
18554   QAbstractItemView_hook_hook_doubleClicked(FSignalDoubleClicked, @SignalDoubleClicked);
18555 
18556   QAbstractItemView_hook_hook_entered(FSignalEntered, @SignalEntered);
18557 
18558   QAbstractItemView_hook_hook_pressed(FSignalPressed, @SignalPressed);
18559 
18560   QAbstractItemView_hook_hook_viewportEntered(FSignalViewportEntered, @SignalViewportEntered);
18561 
18562   FAbstractItemViewportEventHook := QObject_hook_create(viewportWidget);
18563   QObject_hook_hook_events(FAbstractItemViewportEventHook, @itemViewViewportEventFilter);
18564 
18565   // initialize scrollbars
18566   verticalScrollBar;
18567   horizontalScrollBar;
18568 
18569 end;
18570 
18571 procedure TQtAbstractItemView.DetachEvents;
18572 begin
18573   if FSignalActivated <> nil then
18574   begin
18575     QAbstractItemView_hook_destroy(FSignalActivated);
18576     FSignalActivated := nil;
18577   end;
18578   if FSignalClicked <> nil then
18579   begin
18580     QAbstractItemView_hook_destroy(FSignalClicked);
18581     FSignalClicked := nil;
18582   end;
18583   if FSignalDoubleClicked <> nil then
18584   begin
18585     QAbstractItemView_hook_destroy(FSignalDoubleClicked);
18586     FSignalDoubleClicked := nil;
18587   end;
18588   if FSignalEntered <> nil then
18589   begin
18590     QAbstractItemView_hook_destroy(FSignalEntered);
18591     FSignalEntered := nil;
18592   end;
18593   if FSignalPressed <> nil then
18594   begin
18595     QAbstractItemView_hook_destroy(FSignalPressed);
18596     FSignalPressed := nil;
18597   end;
18598   if FSignalViewportEntered <> nil then
18599   begin
18600     QAbstractItemView_hook_destroy(FSignalViewportEntered);
18601     FSignalViewportEntered := nil;
18602   end;
18603   if FAbstractItemViewportEventHook <> nil then
18604   begin
18605     QObject_hook_destroy(FAbstractItemViewportEventHook);
18606     FAbstractItemViewportEventHook := nil;
18607   end;
18608   inherited DetachEvents;
18609 end;
18610 
TQtAbstractItemView.itemViewViewportEventFilternull18611 function TQtAbstractItemView.itemViewViewportEventFilter(Sender: QObjectH;
18612   Event: QEventH): Boolean; cdecl;
18613 var
18614   R: TRect;
18615   ASize: TSize;
18616   AResizeEvent: QResizeEventH;
18617 begin
18618   {we install only mouse events on QAbstractItemView viewport}
18619   Result := False;
18620   QEvent_accept(Event);
18621 
18622   if (LCLObject = nil) then
18623     exit;
18624 
18625   BeginEventProcessing;
18626   try
18627     {ownerdata is needed only before qt paint's data}
18628     if (ViewStyle >= 0) and FOwnerData and
18629       (QEvent_type(Event) = QEventPaint) then
18630     begin
18631       QPaintEvent_rect(QPaintEventH(Event), @R);
18632       OwnerDataNeeded(R);
18633     end;
18634 
18635     case QEvent_type(Event) of
18636       QEventResize:
18637       begin
18638         if Assigned(FOwner) then
18639           ASize := FOwner.getSize
18640         else
18641           ASize := getSize;
18642         AResizeEvent := QResizeEvent_create(@ASize, @ASize);
18643         try
18644           SlotResize(AResizeEvent);
18645         finally
18646           QEvent_destroy(AResizeEvent);
18647         end;
18648       end;
18649       QEventHide:
18650         if QWidget_mouseGrabber() = QWidgetH(Sender) then
18651           ReleaseCapture;
18652       QEventMouseButtonPress,
18653       QEventMouseButtonRelease,
18654       QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
18655       QEventContextMenu: Result := SlotContextMenu(Sender, Event);
18656       else
18657       begin
18658         if not (ViewStyle in [Ord(vsIcon), Ord(vsSmallIcon)]) then
18659         begin
18660           {do not change selection if mousepressed and mouse moved}
18661           Result := (QEvent_type(Event) = QEventMouseMove) and
18662             hasFocus and (QGUIApplication_mouseButtons() > 0);
18663           QEvent_ignore(Event);
18664         end;
18665       end;
18666     end;
18667   finally
18668     EndEventProcessing;
18669   end;
18670 end;
18671 
18672 procedure TQtAbstractItemView.setDefaultColorRoles;
18673 begin
18674   WidgetColorRole := QPaletteBase;
18675   TextColorRole := QPaletteText;
18676 end;
18677 
18678 procedure TQtAbstractItemView.clearSelection;
18679 begin
18680   QAbstractItemView_clearSelection(QAbstractItemViewH(Widget));
18681 end;
18682 
getModelnull18683 function TQtAbstractItemView.getModel: QAbstractItemModelH;
18684 begin
18685   Result := QAbstractItemView_model(QAbstractItemViewH(Widget));
18686 end;
18687 
TQtAbstractItemView.getRowHeightnull18688 function TQtAbstractItemView.getRowHeight(ARowIndex: integer): integer;
18689 begin
18690   Result := QAbstractItemView_sizeHintForRow(QAbstractItemViewH(Widget),
18691     ARowIndex);
18692 end;
18693 
TQtAbstractItemView.getSelectionModenull18694 function TQtAbstractItemView.getSelectionMode: QAbstractItemViewSelectionMode;
18695 begin
18696   Result := QAbstractItemView_SelectionMode(QAbstractItemViewH(Widget));
18697 end;
18698 
getTopItemnull18699 function TQtAbstractItemView.getTopItem: integer;
18700 begin
18701   Result := -1;
18702 end;
18703 
18704 {------------------------------------------------------------------------------
18705   Function: TQtAbstractItemView.getVisibleRowCount
18706   Params:  Boolean
18707   Returns: if AFirstVisibleOnly = False (default) then it returns number
18708   of visible rows, or 0 if there's no visible rows.
18709   When AFirstVisibleOnly = True then it returns index of first visible row,
18710   otherwise result is -1.
18711   This function is used by TQtTreeWidget and TQtListWidget.
18712  ------------------------------------------------------------------------------}
getVisibleRowCountnull18713 function TQtAbstractItemView.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
18714 begin
18715   Result := 0;
18716 end;
18717 
18718 procedure TQtAbstractItemView.modelIndex(retval: QModelIndexH; row, column: Integer; parent: QModelIndexH = nil);
18719 begin
18720   QAbstractItemModel_index(getModel, retval, row, column, parent);
18721 end;
18722 
TQtAbstractItemView.visualRectnull18723 function TQtAbstractItemView.visualRect(Index: QModelIndexH): TRect;
18724 begin
18725   QAbstractItemView_visualRect(QAbstractItemViewH(Widget), @Result, Index);
18726 end;
18727 
18728 procedure TQtAbstractItemView.setEditTriggers(
18729   ATriggers: QAbstractItemViewEditTriggers);
18730 begin
18731   QAbstractItemView_setEditTriggers(QAbstractItemViewH(Widget), ATriggers);
18732 end;
18733 
18734 procedure TQtAbstractItemView.setSelectionMode(
18735   AMode: QAbstractItemViewSelectionMode);
18736 begin
18737   QAbstractItemView_setSelectionMode(QAbstractItemViewH(Widget), AMode);
18738 end;
18739 
18740 procedure TQtAbstractItemView.setSelectionBehavior(
18741   ABehavior: QAbstractItemViewSelectionBehavior);
18742 begin
18743   QAbstractItemView_setSelectionBehavior(QAbstractItemViewH(Widget), ABehavior);
18744 end;
18745 
18746 procedure TQtAbstractItemView.setWordWrap(const AValue: Boolean);
18747 begin
18748   // override
18749 end;
18750 
18751 procedure TQtAbstractItemView.ItemDelegateSizeHint(
18752   option: QStyleOptionViewItemH; index: QModelIndexH; Size: PSize); cdecl;
18753 var
18754   Msg: TLMMeasureItem;
18755   MeasureItemStruct: TMeasureItemStruct;
18756   decorationSize: TSize;
18757   Metric: Integer;
18758 begin
18759   QStyleOptionViewItem_decorationSize(option, @decorationSize);
18760   Metric := QStyle_pixelMetric(QApplication_style(), QStylePM_FocusFrameVMargin, nil, nil) * 2;
18761   MeasureItemStruct.itemID := UINT(QModelIndex_row(index));
18762   MeasureItemStruct.itemWidth := UINT(Size^.cx);
18763   MeasureItemStruct.itemHeight := UINT(Max(Size^.cy, (decorationSize.cy + Metric)));
18764   Msg.Msg := LM_MEASUREITEM;
18765   Msg.MeasureItemStruct := @MeasureItemStruct;
18766   DeliverMessage(Msg);
18767   Size^.cx := Longint(MeasureItemStruct.itemWidth);
18768   Size^.cy := Longint(MeasureItemStruct.itemHeight);
18769 end;
18770 
18771 procedure TQtAbstractItemView.ItemDelegatePaint(painter: QPainterH;
18772   option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
18773 begin
18774   // should be overrided
18775 end;
18776 
18777 { TQtRubberBand }
18778 
CreateWidgetnull18779 function TQtRubberBand.CreateWidget(const AParams: TCreateParams): QWidgetH;
18780 var
18781   Parent: QWidgetH;
18782 begin
18783   if AParams.WndParent <> 0 then
18784     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
18785   else
18786     Parent := nil;
18787   Result := QRubberBand_create(FShape, Parent);
18788 end;
18789 
18790 constructor TQtRubberBand.Create(const AWinControl: TWinControl;
18791   const AParams: TCreateParams);
18792 begin
18793   FShape := QRubberBandLine;
18794   inherited Create(AWinControl, AParams);
18795 end;
18796 
18797 procedure TQtRubberBand.move(ANewLeft, ANewTop: Integer);
18798 begin
18799   QRubberBand_move(QRubberBandH(Widget), ANewLeft, ANewTop);
18800 end;
18801 
18802 procedure TQtRubberBand.Resize(ANewWidth, ANewHeight: Integer);
18803 begin
18804   QRubberBand_resize(QRubberBandH(Widget), ANewWidth, ANewHeight);
18805 end;
18806 
18807 procedure TQtRubberBand.setGeometry(ARect: TRect);
18808 begin
18809   QRubberBand_setGeometry(QRubberBandH(Widget), @ARect);
18810 end;
18811 
TQtRubberBand.getShapenull18812 function TQtRubberBand.getShape: QRubberBandShape;
18813 begin
18814   Result := QRubberBand_shape(QRubberBandH(Widget));
18815 end;
18816 
18817 procedure TQtRubberBand.setShape(AShape: QRubberBandShape);
18818 begin
18819   if getShape <> AShape then
18820   begin
18821     // recreate widget
18822     FShape := AShape;
18823     RecreateWidget;
18824     AttachEvents;
18825   end;
18826 end;
18827 
18828 { TQtFileDialog }
18829 
TQtFileDialog.CreateWidgetnull18830 function TQtFileDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags): QWidgetH;
18831 begin
18832   Result := QFileDialog_create(parent, f);
18833   {$ifndef QT_NATIVE_DIALOGS}
18834   FBackBtn := nil;
18835   FForwardBtn := nil;
18836   FUpBtn := nil;
18837   FFileNameEdit := nil;
18838   FComboType := nil;
18839   FComboHistory := nil;
18840   FSideView := nil;;
18841   FTreeView := nil;
18842   FListView := nil;
18843 
18844   FTreeViewEventFilter := nil; // detailed view
18845   FListViewEventFilter := nil; // small icons
18846   FSideViewEventFilter := nil; // sidebar
18847   FFileNameEditEventFilter := nil; // filename editor
18848   FComboTypeEventFilter := nil;
18849   FComboHistoryEventFilter := nil;
18850   {$endif}
18851 end;
18852 
18853 procedure TQtFileDialog.AttachEvents;
18854 begin
18855   inherited AttachEvents;
18856 
18857   FCurrentChangedHook := QFileDialog_hook_create(Widget);
18858   FDirecotyEnteredHook := QFileDialog_hook_create(Widget);
18859   FFilterSelectedHook := QFileDialog_hook_create(Widget);
18860 
18861   QFileDialog_hook_hook_filterSelected(FFilterSelectedHook, @FilterSelectedEvent);
18862 
18863   QFileDialog_hook_hook_currentChanged(FCurrentChangedHook, @CurrentChangedEvent);
18864 
18865   QFileDialog_hook_hook_directoryEntered(FDirecotyEnteredHook, @DirectoryEnteredEvent);
18866 end;
18867 
18868 procedure TQtFileDialog.DetachEvents;
18869 begin
18870   if FCurrentChangedHook <> nil then
18871   begin
18872     QFileDialog_hook_destroy(FCurrentChangedHook);
18873     FCurrentChangedHook := nil;
18874   end;
18875   if FFilterSelectedHook <> nil then
18876   begin
18877     QFileDialog_hook_destroy(FFilterSelectedHook);
18878     FFilterSelectedHook := nil;
18879   end;
18880   if FDirecotyEnteredHook <> nil then
18881   begin
18882     QFileDialog_hook_destroy(FDirecotyEnteredHook);
18883     FDirecotyEnteredHook := nil;
18884   end;
18885   {$ifndef QT_NATIVE_DIALOGS}
18886   if FTreeViewEventFilter <> nil then
18887   begin
18888     QObject_hook_destroy(FTreeViewEventFilter);
18889     FTreeViewEventFilter := nil;
18890   end;
18891   if FListViewEventFilter <> nil then
18892   begin
18893     QObject_hook_destroy(FListViewEventFilter);
18894     FListViewEventFilter := nil;
18895   end;
18896   if FSideViewEventFilter <> nil then
18897   begin
18898     QObject_hook_destroy(FSideViewEventFilter);
18899     FSideViewEventFilter := nil;
18900   end;
18901   if FFileNameEditEventFilter <> nil then
18902   begin
18903     QObject_hook_destroy(FFileNameEditEventFilter);
18904     FFileNameEditEventFilter := nil;
18905   end;
18906   if FComboTypeEventFilter <> nil then
18907   begin
18908     QObject_hook_destroy(FComboTypeEventFilter);
18909     FComboTypeEventFilter := nil;
18910   end;
18911   if FComboHistoryEventFilter <> nil then
18912   begin
18913     QObject_hook_destroy(FComboHistoryEventFilter);
18914     FComboHistoryEventFilter := nil;
18915   end;
18916   {$endif}
18917   inherited DetachEvents;
18918 end;
18919 
18920 {$ifndef QT_NATIVE_DIALOGS}
TQtFileDialog.EventFilternull18921 function TQtFileDialog.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
18922   cdecl;
18923 begin
18924   Result := False;
18925   if Sender <> Widget then
18926   begin
18927     // TODO: Ctrl + Letter for Open/Save button trigger
18928     // ALT + Left, Up, Right to navigate (Backward, Up parent, Forward) in list.
18929     // ALT + E to focus fileedit
18930     // ALT + H to focus lookInCombo (history combo)
18931     // ALT + L to focus view
18932     // ALT + N to create new folder (TODO)
18933     // ALT + S to select sidebar
18934     // ALT + T to focus file type combo
18935     // ALT + V to change view style (TODO)
18936     case QEvent_type(Event) of
18937       QEventKeyPress:
18938         begin
18939           if (QKeyEvent_modifiers(QKeyEventH(Event)) and QtAltModifier <> 0) then
18940           begin
18941             case QKeyEvent_key(QKeyEventH(Event)) of
18942               QtKey_Left:
18943                 begin
18944                   if Assigned(FBackBtn) and QWidget_isVisible(FBackBtn) and
18945                     QWidget_isEnabled(FBackBtn) then
18946                     QAbstractButton_click(QAbstractButtonH(FBackBtn));
18947                   Result := True;
18948                 end;
18949               QtKey_Right:
18950                 begin
18951                   if Assigned(FForwardBtn) and QWidget_isVisible(FForwardBtn) and
18952                     QWidget_isEnabled(FForwardBtn) then
18953                     QAbstractButton_click(QAbstractButtonH(FForwardBtn));
18954                   Result := True;
18955                 end;
18956               QtKey_Up:
18957                 begin
18958                   if Assigned(FUpBtn) and QWidget_isVisible(FUpBtn) and
18959                     QWidget_isEnabled(FUpBtn) then
18960                     QAbstractButton_click(QAbstractButtonH(FUpBtn));
18961                   Result := True;
18962                 end;
18963               QtKey_E:
18964                 begin
18965                   if Assigned(FFileNameEdit) and
18966                     QWidget_isVisible(FFileNameEdit) and
18967                     QWidget_isEnabled(FFileNameEdit) and
18968                     not QWidget_hasFocus(FFileNameEdit) then
18969                     QWidget_setFocus(FFileNameEdit);
18970                   Result := True;
18971                 end;
18972               QtKey_H:
18973                 begin
18974                   if Assigned(FComboHistory) and
18975                     QWidget_isVisible(FComboHistory) and
18976                     QWidget_isEnabled(FComboHistory) and
18977                     not QWidget_hasFocus(FComboHistory) then
18978                       QWidget_setFocus(FComboHistory);
18979                   Result := True;
18980                 end;
18981               QtKey_L:
18982                 begin
18983                   if Assigned(FTreeView) and
18984                     QWidget_isVisible(FTreeView) and
18985                     QWidget_isEnabled(FTreeView) and
18986                     not QWidget_hasFocus(FTreeView) then
18987                     QWidget_setFocus(FTreeView)
18988                   else
18989                   if Assigned(FListView) and
18990                     QWidget_isVisible(FListView) and
18991                     QWidget_isEnabled(FListView) and
18992                     not QWidget_hasFocus(FListView) then
18993                     QWidget_setFocus(FListView);
18994                   Result := True;
18995                 end;
18996               QtKey_N:
18997                 begin
18998                   //TODO: create newfolder
18999                   Result := True;
19000                 end;
19001               QtKey_S:
19002                 begin
19003                   // select sidebar
19004                   if Assigned(FSideView) and
19005                     QWidget_isVisible(FSideView) and
19006                     QWidget_isEnabled(FSideView) and
19007                     not QWidget_hasFocus(FSideView) then
19008                     QWidget_setFocus(FSideView);
19009                   Result := True;
19010                 end;
19011               QtKey_T:
19012                 begin
19013                   // focus combo filetype
19014                   if Assigned(FComboType) and
19015                     QWidget_isVisible(FComboType) and
19016                     QWidget_isEnabled(FComboType) and
19017                     not QWidget_hasFocus(FComboType) then
19018                       QWidget_setFocus(FComboType);
19019                   Result := True;
19020                 end;
19021               QtKey_V:
19022                 begin
19023                   //TODO: change viewStyle
19024                   Result := True;
19025                 end;
19026             end;
19027           end;
19028         end;
19029     end;
19030   end else
19031     Result := inherited EventFilter(Sender, Event);
19032 end;
19033 {$endif}
19034 
TQtFileDialog.selectFilenull19035 function TQtFileDialog.selectFile: WideString;
19036 begin
19037   QFileDialog_selectFile(QFileDialogH(Widget), @Result);
19038 end;
19039 
19040 procedure TQtFileDialog.selectedFiles(retval: QStringListH);
19041 begin
19042   QFileDialog_selectedFiles(QFileDialogH(Widget), retval);
19043 end;
19044 
19045 procedure TQtFileDialog.setAcceptMode(const AMode: QFileDialogAcceptMode);
19046 begin
19047   QFileDialog_setAcceptMode(QFileDialogH(Widget), AMode)
19048 end;
19049 
19050 procedure TQtFileDialog.setConfirmOverwrite(const AValue: Boolean);
19051 begin
19052   QFileDialog_setConfirmOverwrite(QFileDialogH(Widget), AValue);
19053 end;
19054 
19055 procedure TQtFileDialog.setDirectory(const ADirectory: WideString);
19056 begin
19057   QFileDialog_setDirectory(QFileDialogH(Widget), @ADirectory);
19058 end;
19059 
19060 procedure TQtFileDialog.setHistory(AList: TStrings);
19061 var
19062   List: QStringListH;
19063   i: Integer;
19064   WStr: WideString;
19065 begin
19066   List := QStringList_create();
19067   try
19068     for i := 0 to AList.Count - 1 do
19069     begin
19070       WStr := GetUTF8String(AList.Strings[i]);
19071       QStringList_append(List, @WStr);
19072     end;
19073     QFileDialog_setHistory(QFileDialogH(Widget), List);
19074   finally
19075     QStringList_destroy(List);
19076   end;
19077 end;
19078 
19079 procedure TQtFileDialog.setFileMode(const AMode: QFileDialogFileMode);
19080 begin
19081   QFileDialog_setFileMode(QFileDialogH(Widget), AMode);
19082 end;
19083 
19084 procedure TQtFileDialog.setFilter(const AFilter: WideString);
19085 begin
19086   QFileDialog_setNameFilter(QFileDialogH(Widget), @AFilter);
19087 end;
19088 
19089 procedure TQtFileDialog.setLabelText(const ALabel: QFileDialogDialogLabel;
19090   const AText: WideString);
19091 begin
19092   QFileDialog_setLabelText(QFileDialogH(Widget), ALabel, @AText);
19093 end;
19094 
19095 procedure TQtFileDialog.setReadOnly(const AReadOnly: Boolean);
19096 begin
19097   QFileDialog_setReadOnly(QFileDialogH(Widget), AReadOnly);
19098 end;
19099 
19100 procedure TQtFileDialog.setSelectedFilter(const ASelFilter: WideString);
19101 begin
19102   QFileDialog_selectNameFilter(QFileDialogH(Widget), @ASelFilter);
19103 end;
19104 
19105 procedure TQtFileDialog.setViewMode(const AMode: QFileDialogViewMode);
19106 begin
19107   QFileDialog_setViewMode(QFileDialogH(Widget), AMode);
19108 end;
19109 
19110 {------------------------------------------------------------------------------
19111   Function: TQtFileDialog.setShortcuts
19112   Params:  None
19113   Returns: Nothing
19114   Qt non-native dialogs doesn't set keyboard shortcuts, so we must do that.
19115   This functions hooks eventFilter of all widgets on QFileDialog.
19116  ------------------------------------------------------------------------------}
19117 {$ifndef QT_NATIVE_DIALOGS}
19118 procedure TQtFileDialog.setShortcuts(const AIsOpenDialog: Boolean);
19119 var
19120   AnIter: TQtObjectDump;
19121   i: Integer;
19122   Obj: QObjectH;
19123   WStr: WideString;
19124   ToolTip: WideString;
19125 begin
19126   // if there's auto recognition enabled then don''t set shortcuts
19127   // cause we are maybe native dialog and then boomer.
19128   if not QFileDialog_testOption(QFileDialogH(Widget),
19129     QFileDialogDontUseNativeDialog) then
19130     exit;
19131   FForwardBtn := nil;
19132   FBackBtn := nil;
19133   FUpBtn := nil;
19134 
19135   AnIter := TQtObjectDump.Create(Widget);
19136   try
19137     AnIter.DumpObject;
19138 
19139     for i := 0 to AnIter.ObjList.Count - 1 do
19140     begin
19141       Obj := QObjectH(AnIter.Objlist.Items[i]);
19142       if AnIter.IsWidget(Obj) then
19143       begin
19144         WStr := AnIter.GetObjectName(Obj);
19145         if (WStr = 'treeView') or (WStr = 'listView') or (WStr = 'sidebar') then
19146         begin
19147           if FForwardBtn = nil then
19148           begin
19149             FForwardBtn := AnIter.FindWidgetByName('forwardButton');
19150             if FForwardBtn <> nil then
19151             begin
19152               ToolTip := 'Forward (Alt + Right)';
19153               QWidget_setToolTip(FForwardBtn, @ToolTip);
19154             end;
19155           end;
19156           if FBackBtn = nil then
19157           begin
19158             FBackBtn := AnIter.FindWidgetByName('backButton');
19159             if FBackBtn <> nil then
19160             begin
19161               ToolTip := 'Back (Alt + Left)';
19162               QWidget_setToolTip(FBackBtn, @ToolTip);
19163             end;
19164           end;
19165           if FUpBtn = nil then
19166           begin
19167             FUpBtn := AnIter.FindWidgetByName('toParentButton');
19168             if FUpBtn <> nil then
19169             begin
19170               ToolTip := 'To parent directory (Alt + Up)';
19171               QWidget_setToolTip(FUpBtn, @ToolTip);
19172             end;
19173           end;
19174 
19175           if FForwardBtn <> nil then
19176           begin
19177             if WStr = 'treeView' then
19178             begin
19179               FTreeView := QWidgetH(Obj);
19180               FTreeViewEventFilter := QObject_hook_create(Obj);
19181               QObject_hook_hook_events(FTreeViewEventFilter, @EventFilter);
19182               ToolTip := 'Alt + L to focus this widget';
19183               QWidget_setToolTip(FTreeView, @ToolTip);
19184             end else
19185             if WStr = 'listView' then
19186             begin
19187               FListView := QWidgetH(Obj);
19188               FListViewEventFilter := QObject_hook_create(Obj);
19189               QObject_hook_hook_events(FListViewEventFilter, @EventFilter);
19190               ToolTip := 'Alt + L to focus this widget';
19191               QWidget_setToolTip(FListView, @ToolTip);
19192             end else
19193             if WStr = 'sidebar' then
19194             begin
19195               FSideView := QWidgetH(Obj);
19196               FSideViewEventFilter := QObject_hook_create(Obj);
19197               QObject_hook_hook_events(FSideViewEventFilter, @EventFilter);
19198               ToolTip := 'Alt + S to focus this widget';
19199               QWidget_setToolTip(FSideView, @ToolTip);
19200             end;
19201 
19202           end;
19203         end else
19204         if WStr = 'fileNameEdit' then
19205         begin
19206           FFileNameEdit := QWidgetH(Obj);
19207           FFileNameEditEventFilter := QObject_hook_create(Obj);
19208           QObject_hook_hook_events(FFileNameEditEventFilter, @EventFilter);
19209           ToolTip := 'Alt + E to focus this widget';
19210           QWidget_setToolTip(FFileNameEdit, @ToolTip);
19211         end else
19212         if WStr = 'fileTypeCombo' then
19213         begin
19214           FComboType := QWidgetH(Obj);
19215           FComboTypeEventFilter := QObject_hook_create(Obj);
19216           QObject_hook_hook_events(FComboTypeEventFilter, @EventFilter);
19217           ToolTip := 'Alt + T to focus this widget';
19218           QWidget_setToolTip(FComboType, @ToolTip);
19219         end else
19220         if WStr = 'lookInCombo' then
19221         begin
19222           FComboHistory := QWidgetH(Obj);
19223           FComboHistoryEventFilter := QObject_hook_create(Obj);
19224           QObject_hook_hook_events(FComboHistoryEventFilter, @EventFilter);
19225           ToolTip := 'Alt + H to focus this widget';
19226           QWidget_setToolTip(FComboHistory, @ToolTip);
19227         end;
19228       end;
19229     end;
19230 
19231   finally
19232     AnIter.Free;
19233   end;
19234 end;
19235 {$endif}
19236 
19237 procedure TQtFileDialog.FilterSelectedEvent(filter: PWideString); cdecl;
19238 var
19239   List: TQtStringList;
19240   index: Integer;
19241 begin
19242   if filter <> nil then
19243   begin
19244     List := TQtStringList.Create;
19245     getFilters(List.Handle);
19246     index := List.IndexOf(UTF16ToUTF8(filter^));
19247     if index <> -1 then
19248       TFileDialog(FDialog).IntfFileTypeChanged(index + 1);
19249     List.Free;
19250   end;
19251 end;
19252 
19253 procedure TQtFileDialog.CurrentChangedEvent(path: PWideString); cdecl;
19254 begin
19255   if FDialog is TOpenDialog then
19256   begin
19257     TOpenDialog(FDialog).FileName := UTF16ToUTF8(path^);
19258     TOpenDialog(FDialog).DoSelectionChange;
19259   end;
19260 end;
19261 
19262 procedure TQtFileDialog.DirectoryEnteredEvent(directory: PWideString); cdecl;
19263 begin
19264   if FDialog is TOpenDialog then
19265     TOpenDialog(FDialog).DoFolderChange;
19266 end;
19267 
19268 procedure TQtFileDialog.getFilters(const retval: QStringListH);
19269 begin
19270   QFileDialog_nameFilters(QFileDialogH(Widget), retval);
19271 end;
19272 
19273 { TQtFilePreviewDialog }
19274 
CreateWidgetnull19275 function TQtFilePreviewDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags
19276   ): QWidgetH;
19277 begin
19278   {$ifndef QT_NATIVE_DIALOGS}
19279   FPreviewWidget := nil;
19280   FTextWidget := nil;
19281   {$endif}
19282   Result := inherited CreateWidget(parent, f);
19283 end;
19284 
19285 {$ifndef QT_NATIVE_DIALOGS}
19286 
19287 procedure TQtFilePreviewDialog.initializePreview(
19288   const APreviewControl: TWinControl);
19289 var
19290   ALayout: QGridLayoutH;
19291   ATitle: WideString;
19292   W, H: Integer;
19293 begin
19294   ALayout := QGridLayoutH(QWidget_layout(Widget));
19295   ATitle := 'No image';
19296   FTextWidget := QLabel_create(PWideString(@ATitle), Widget);
19297   QFrame_setFrameShape(FTextWidget, QFrameStyledPanel);
19298   QLabel_setWordWrap(FTextWidget, True);
19299   QLabel_setScaledContents(FTextWidget, True);
19300   QLabel_setAlignment(FTextWidget, QtAlignCenter);
19301   ATitle := '';
19302   FPreviewWidget := QLabel_create(PWideString(@ATitle), Widget);
19303   QLabel_setAlignment(FPreviewWidget, QtAlignCenter);
19304 
19305   W := QWidget_width(Widget) div 5;
19306   H := W;
19307 
19308   if Assigned(APreviewControl) then
19309   begin
19310     APreviewControl.Width := W;
19311     APreviewControl.Height := H;
19312   end;
19313 
19314   QWidget_setGeometry(FTextWidget, 0, 0, W, 32);
19315   QWidget_setMaximumHeight(FTextWidget, 32);
19316   QWidget_setMaximumWidth(FTextWidget, W);
19317   QWidget_setMinimumWidth(FTextWidget, W);
19318 
19319   QWidget_setGeometry(FPreviewWidget, 0, 0, W, H);
19320   QWidget_setMaximumHeight(FPreviewWidget, H);
19321   QWidget_setMaximumWidth(FPreviewWidget, W);
19322   QLabel_setScaledContents(FPreviewWidget, True);
19323   (*
19324   do not use layout, Qt asserts with message that another layout already exists.
19325   ABox := QVBoxLayout_create(Widget);
19326   QBoxLayout_addWidget(ABox, FTextWidget, 0, QtAlignTop);
19327   // QBoxLayout_addWidget();
19328   QBoxLayout_addWidget(ABox, FPreviewWidget, 0, QtAlignCenter);
19329   QBoxLayout_addStretch(ABox);
19330   *)
19331   QGridLayout_addWidget(ALayout, FTextWidget, 1, 3, 3, 1, QtAlignTop);
19332   QGridLayout_addWidget(ALayout, FPreviewWidget, 1, 3, 3, 1, QtAlignCenter);
19333   QGridLayout_columnStretch(ALayout, 3);
19334 end;
19335 
19336 procedure TQtFilePreviewDialog.CurrentChangedEvent(path: PWideString); cdecl;
19337 var
19338   APixmap: QPixmapH;
19339   ATitle: WideString;
19340   ASize: TSize;
19341   ANewPixmap: QPixmapH;
19342 begin
19343   if Assigned(FPreviewWidget) then
19344   begin
19345     APixmap := QPixmap_create(path);
19346     if QPixmap_isNull(APixmap) then
19347     begin
19348       ATitle := 'Not an image';
19349       QLabel_setText(FTextWidget, @ATitle);
19350       ATitle := ' ';
19351       QLabel_setText(FPreviewWidget, @ATitle);
19352       QWidget_setToolTip(FTextWidget, @ATitle);
19353       QWidget_setToolTip(FPreviewWidget, @ATitle);
19354       QPixmap_destroy(APixmap);
19355     end else
19356     begin
19357       QPixmap_size(APixmap, @ASize);
19358       if path <> nil then
19359         ATitle := '' // ExtractFileName(path^)
19360       else
19361         ATitle := 'error file';
19362       if path <> nil then
19363         ATitle := Format('%d x %d x %d',[ASize.cx, ASize.cy, QPixmap_depth(APixmap)]);
19364       QLabel_setText(FTextWidget, @ATitle);
19365       ATitle := ExtractFileName(path^);
19366       QWidget_setToolTip(FTextWidget, @ATitle);
19367       ATitle := ATitle + LineEnding + Format('w %d x h %d x %d',[ASize.cx, ASize.cy, QPixmap_depth(APixmap)]);
19368       QWidget_setToolTip(FPreviewWidget, @ATitle);
19369       ANewPixmap := QPixmap_create;
19370       // QPixmap_scaled(APixmap, ANewPixmap,
19371       //  128, 128, QtKeepAspectRatio, QtSmoothTransformation);
19372       QLabel_setPixmap(FPreviewWidget, APixmap);
19373       QPixmap_destroy(APixmap);
19374       QPixmap_destroy(ANewPixmap);
19375     end;
19376 
19377   end;
19378   TOpenDialog(FDialog).FileName := UTF16ToUTF8(path^);
19379   TOpenDialog(FDialog).DoSelectionChange;
19380 end;
19381 {$ENDIF}
19382 
19383 { TQtGraphicView }
19384 
CreateWidgetnull19385 function TQtGraphicsView.CreateWidget(const AParams: TCreateParams): QWidgetH;
19386 var
19387   Parent: QWidgetH;
19388 begin
19389   FHasPaint := True;
19390   if AParams.WndParent <> 0 then
19391     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
19392   else
19393     Parent := nil;
19394   Result := QGraphicsView_create(Parent);
19395 end;
19396 
19397 { TQtDesignWidget }
19398 
CreateWidgetnull19399 function TQtDesignWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
19400 begin
19401   Result := inherited CreateWidget(AParams);
19402   FDesignControl := QWidget_create(Result);
19403   QWidget_setMouseTracking(FDesignControl, True);
19404   setProperty(FDesignControl, 'lclwidget', Int64(PtrUInt(Self)));
19405   QtWidgetSet.AddHandle(Self);
19406   BringDesignerToFront;
19407 end;
19408 
19409 procedure TQtDesignWidget.DestroyWidget;
19410 begin
19411   inherited DestroyWidget;
19412   FDesignControl := nil;
19413 end;
19414 
19415 procedure TQtDesignWidget.SlotDesignControlPaint(Sender: QObjectH; Event: QEventH); cdecl;
19416 var
19417   Msg: TLMPaint;
19418   AStruct: PPaintStruct;
19419   P: TPoint;
19420   B: Boolean;
19421 begin
19422   {$ifdef VerboseQt}
19423     WriteLn('TQtDesignWidget.SlotDesignControlPaint ', dbgsName(LCLObject));
19424   {$endif}
19425 
19426   if (LCLObject is TWinControl) then
19427   begin
19428     FillChar(Msg{%H-}, SizeOf(Msg), #0);
19429 
19430     Msg.Msg := LM_PAINT;
19431     New(AStruct);
19432     FillChar(AStruct^, SizeOf(TPaintStruct), 0);
19433     Msg.PaintStruct := AStruct;
19434 
19435     with PaintData do
19436     begin
19437       PaintWidget := FDesignControl;
19438       ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
19439       if ClipRect = nil then
19440         New(ClipRect);
19441       QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
19442     end;
19443 
19444     Msg.DC := BeginPaint(THandle(Self), AStruct^);
19445     FDesignContext := Msg.DC;
19446 
19447     Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
19448     Msg.PaintStruct^.hdc := FDesignContext;
19449 
19450     P := getClientOffset;
19451     inc(P.X, FScrollX);
19452     inc(P.Y, FScrollY);
19453     TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
19454 
19455     // send paint message
19456     try
19457       // Saving clip rect and clip region
19458       try
19459         LCLObject.WindowProc(TLMessage(Msg));
19460       finally
19461         Dispose(PaintData.ClipRect);
19462         Fillchar(FPaintData, SizeOf(FPaintData), 0);
19463         FDesignContext := 0;
19464         EndPaint(THandle(Self), AStruct^);
19465         Dispose(AStruct);
19466       end;
19467     except
19468       // prevent recursive repainting !
19469       B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
19470       if B then
19471         QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
19472       try
19473         Application.HandleException(nil);
19474       finally
19475         if B and Assigned(Application) and not Application.Terminated then
19476           QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
19477       end;
19478     end;
19479   end;
19480 end;
19481 
19482 procedure TQtDesignWidget.BringDesignerToFront;
19483 begin
19484   if FDesignControl <> nil then
19485     QWidget_raise(FDesignControl);
19486 end;
19487 
19488 procedure TQtDesignWidget.ResizeDesigner;
19489 var
19490   R: TRect;
19491 begin
19492   if FDesignControl = nil then
19493     Exit;
19494   // FDesignControl must be same as form area,
19495   // since we use QWidget, not QMainWindow in design time.
19496   QWidget_contentsRect(Widget, @R);
19497   with R do
19498   begin
19499     QWidget_move(FDesignControl, Left, Top);
19500     QWidget_resize(FDesignControl, Right - Left, Bottom - Top);
19501   end;
19502 end;
19503 
GetContextnull19504 function TQtDesignWidget.GetContext: HDC;
19505 begin
19506   if FDesignContext <> 0 then
19507     Result := FDesignContext
19508   else
19509     Result := FContext;
19510 end;
19511 
DesignControlEventFilternull19512 function TQtDesignWidget.DesignControlEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
19513 var
19514   p, AGlobalPos: TQtPoint;
19515   APosF, AGlobalPosF: TQtPointF;
19516   pt: TPoint;
19517   R: TRect;
19518   Control: TControl;
19519   MouseEvent: QMouseEventH;
19520   WidgetToNotify: QWidgetH;
19521   WSQtWidget: TWSWinControlClass;
19522   Action: QActionH;
19523   AWidget: TQtWidget;
19524   ATabWidget: TQtTabWidget;
19525   ATabIndex: Integer;
19526 begin
19527   Result := False;
19528   QEvent_Accept(Event);
19529   if LCLObject = nil then
19530     exit;
19531   if QEvent_type(Event) = QEventDestroy then
19532   begin
19533     {FDesignControl is always destroyed by it's parent,
19534      only thing we need is to remove dynamic property.}
19535     RemoveProperty(FDesignControl,'lclwidget');
19536     exit;
19537   end;
19538   BeginEventProcessing;
19539   try
19540     case QEvent_type(Event) of
19541       QEventMouseButtonPress,
19542       QEventMouseButtonRelease:
19543       begin
19544         QMouseEvent_pos(QMouseEventH(Event), @p);
19545         OffsetMousePos(@p);
19546         pt := Point(p.x, p.y);
19547         Control := LCLObject.ControlAtPos(pt, [capfRecursive, capfAllowWinControls]);
19548 
19549         if Control is TWinControl then
19550         begin
19551           AWidget := TQtWidget(TWinControl(Control).Handle);
19552           if (Control is TCustomTabControl) and
19553             (AWidget.ChildOfComplexWidget <> ccwTTabControl) then
19554             WidgetToNotify := TQtTabWidget(TWinControl(Control).Handle).TabBar.Widget
19555           else
19556             WidgetToNotify := TQtWidget(TWinControl(Control).Handle).Widget;
19557 
19558           QMouseEvent_pos(QMouseEventH(Event), @p);
19559           QWidget_mapFrom(WidgetToNotify, @p, Widget, @p);
19560           Pt := Point(p.x, p.y);
19561 
19562           WSQtWidget := TWSWinControlClass(TWinControl(Control).WidgetSetClass);
19563 
19564           if WSQtWidget.GetDesignInteractive(TWinControl(Control), Pt) then
19565           begin
19566             if (Control is TCustomTabControl) and
19567               (AWidget.ChildOfComplexWidget <> ccwTTabControl) then
19568             begin
19569               ATabWidget := TQtTabWidget(TWinControl(Control).Handle);
19570               ATabIndex := ATabWidget.tabAt(Pt);
19571               if ATabIndex >= 0 then
19572                 ATabWidget.setCurrentIndex(ATabIndex);
19573             end else
19574             begin
19575               QMouseEvent_globalpos(QMouseEventH(Event), @AGlobalPos);
19576               APosF.X := P.X;
19577               APosF.Y := P.y;
19578               AGlobalPosF.X := AGlobalPos.X;
19579               AGlobalPosF.Y := AGlobalPos.Y;
19580               MouseEvent := QMouseEvent_create(QEvent_type(Event), @APosF,
19581                 @AGlobalPosF,
19582                 QMouseEvent_button(QMouseEventH(Event)),
19583                 QMouseEvent_buttons(QMouseEventH(Event)),
19584                 QInputEvent_modifiers(QInputEventH(Event))
19585                 );
19586               QCoreApplication_postEvent(WidgetToNotify, MouseEvent, 1);
19587             end;
19588           end;
19589         end else
19590         begin
19591           QMouseEvent_globalPos(QMouseEventH(Event), @p);
19592           WidgetToNotify := QApplication_widgetAt(@p);
19593           if (WidgetToNotify <> nil) then
19594           begin
19595             if TQtMainWindow(Self).MenuBar.Widget <> nil then
19596             begin
19597               QMouseEvent_Pos(QMouseEventH(Event), @p);
19598               QWidget_geometry(TQtMainWindow(Self).MenuBar.Widget, @R);
19599               pt := Point(P.X, P.Y);
19600               if LCLIntf.PtInRect(R, pt) then
19601               begin
19602                 Action := QMenuBar_actionAt(QMenuBarH(TQtMainWindow(Self).MenuBar.Widget), @p);
19603                 if Action <> nil then
19604                 begin
19605                   QCoreApplication_notify(QCoreApplication_instance(), TQtMainWindow(Self).MenuBar.Widget, Event);
19606                   QEvent_accept(Event);
19607                   Result := True;
19608                 end;
19609               end;
19610             end;
19611           end;
19612         end;
19613       end;
19614       QEventPaint: SlotDesignControlPaint(Sender, Event);
19615     end;
19616   finally
19617     EndEventProcessing;
19618   end;
19619 end;
19620 
TQtDesignWidget.EventFilternull19621 function TQtDesignWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
19622 begin
19623   Result := False;
19624   QEvent_accept(Event);
19625   if LCLObject = nil then
19626     exit;
19627 
19628   BeginEventProcessing;
19629   try
19630     case QEvent_type(Event) of
19631       QEventWindowActivate:
19632       begin
19633         Result := inherited EventFilter(Sender, Event);
19634         setFocus;
19635         BringDesignerToFront;
19636       end;
19637       QEventChildAdded,
19638       QEventChildRemoved: BringDesignerToFront;
19639       QEventResize:
19640         begin
19641           Result := inherited EventFilter(Sender, Event);
19642           ResizeDesigner;
19643         end;
19644       else
19645         Result := inherited EventFilter(Sender, Event);
19646     end;
19647   finally
19648     EndEventProcessing;
19649   end;
19650 end;
19651 
19652 procedure TQtDesignWidget.AttachEvents;
19653 begin
19654   inherited AttachEvents;
19655   if FDesignControl <> nil then
19656   begin
19657     FDesignControlEventHook := QObject_hook_create(FDesignControl);
19658     QObject_hook_hook_events(FDesignControlEventHook, @DesignControlEventFilter);
19659   end;
19660 end;
19661 
19662 procedure TQtDesignWidget.DetachEvents;
19663 begin
19664   if FDesignControlEventHook <> nil then
19665   begin
19666     QObject_hook_destroy(FDesignControlEventHook);
19667     FDesignControlEventHook := nil;
19668   end;
19669   inherited DetachEvents;
19670 end;
19671 
19672 procedure TQtDesignWidget.lowerWidget;
19673 begin
19674   inherited lowerWidget;
19675   BringDesignerToFront;
19676 end;
19677 
19678 procedure TQtDesignWidget.raiseWidget;
19679 begin
19680   inherited raiseWidget;
19681   BringDesignerToFront;
19682 end;
19683 
19684 { TQtMessageBox }
19685 
TQtMessageBox.getMsgBoxTypenull19686 function TQtMessageBox.getMsgBoxType: QMessageBoxIcon;
19687 begin
19688   Result := QMessageBox_icon(QMessageBoxH(Widget));
19689 end;
19690 
GetTextFormatnull19691 function TQtMessageBox.GetTextFormat: QtTextFormat;
19692 begin
19693   Result := QMessageBox_textFormat(QMessageBoxH(Widget));
19694 end;
19695 
19696 procedure TQtMessageBox.setDetailText(const AValue: WideString);
19697 var
19698   Str: WideString;
19699 begin
19700   Str := GetUTF8String(AValue);
19701   QMessageBox_setDetailedText(QMessageBoxH(Widget), @Str);
19702 end;
19703 
TQtMessageBox.getMessageStrnull19704 function TQtMessageBox.getMessageStr: WideString;
19705 var
19706   Str: WideString;
19707 begin
19708   QMessageBox_text(QMessageBoxH(Widget), @Str);
19709   Result := UTF16ToUTF8(Str);
19710 end;
19711 
TQtMessageBox.getDetailTextnull19712 function TQtMessageBox.getDetailText: WideString;
19713 var
19714   Str: WideString;
19715 begin
19716   QMessageBox_detailedText(QMessageBoxH(Widget), @Str);
19717   Result := UTF16ToUTF8(Str);
19718 end;
19719 
19720 procedure TQtMessageBox.setMessageStr(const AValue: WideString);
19721 var
19722   Str: WideString;
19723 begin
19724   Str := GetUTF8String(AValue);
19725   QMessageBox_setText(QMessageBoxH(Widget), @Str);
19726 end;
19727 
19728 procedure TQtMessageBox.setMsgBoxType(const AValue: QMessageBoxIcon);
19729 begin
19730   QMessageBox_setIcon(QMessageBoxH(Widget), AValue);
19731 end;
19732 
19733 procedure TQtMessageBox.SetTextFormat(AValue: QtTextFormat);
19734 begin
19735   QMessageBox_setTextFormat(QMessageBoxH(Widget), AValue);
19736 end;
19737 
19738 procedure TQtMessageBox.setTitle(const AValue: WideString);
19739 begin
19740   if AValue <> FTitle then
19741   begin
19742     FTitle := GetUTF8String(AValue);
19743     QMessageBox_setWindowTitle(QMessageBoxH(Widget), @FTitle);
19744   end;
19745 end;
19746 
TQtMessageBox.CreateWidgetnull19747 function TQtMessageBox.CreateWidget(AParent: QWidgetH): QWidgetH;
19748 begin
19749   FHasPaint := False;
19750   Result := QMessageBox_create(AParent);
19751   QMessageBox_setWindowModality(QMessageBoxH(Result), QtApplicationModal);
19752 end;
19753 
19754 constructor TQtMessageBox.Create(AParent: QWidgetH);
19755 begin
19756   WidgetColorRole := QPaletteWindow;
19757   TextColorRole := QPaletteWindowText;
19758   FOwner := nil;
19759   FCentralWidget := nil;
19760   FOwnWidget := True;
19761   FProps := nil;
19762   LCLObject := nil;
19763   FKeysToEat := [];
19764   FHasPaint := False;
19765   {$IFDEF TQTMESSAGEBOXUSEPARENT}
19766   if AParent = nil then
19767     AParent := QApplication_activeWindow;
19768   {$ENDIF}
19769   Widget := CreateWidget(AParent);
19770   {$IFNDEF QTDIALOGSUSEHTMLTEXT}
19771   TextFormat := QtPlainText;
19772   {$ENDIF}
19773   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
19774   QtWidgetSet.AddHandle(Self);
19775 end;
19776 
19777 procedure TQtMessageBox.AttachEvents;
19778 begin
19779   inherited AttachEvents;
19780   FMBEventHook := QObject_hook_create(Widget);
19781   QObject_hook_hook_events(FMBEventHook, @EventFilter);
19782 end;
19783 
19784 procedure TQtMessageBox.DetachEvents;
19785 begin
19786   if FMBEventHook <> nil then
19787   begin
19788     QObject_hook_destroy(FMBEventHook);
19789     FMBEventHook := nil;
19790   end;
19791   inherited DetachEvents;
19792 end;
19793 
TQtMessageBox.EventFilternull19794 function TQtMessageBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
19795   cdecl;
19796 begin
19797   {we'll need it later. QMessageBox uses it's own eventLoop !}
19798   Result := False;
19799   QEvent_accept(Event);
19800   if LCLObject <> nil then
19801     Result := inherited EventFilter(Sender, Event)
19802   else
19803   begin
19804     case QEvent_type(Event) of
19805       QEventKeyPress:
19806       begin
19807         if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Escape) and
19808           (QMessageBox_escapeButton(QMessageBoxH(Sender)) = nil) then
19809         begin
19810           QDialog_done(QDialogH(Sender), Ord(QDialogRejected));
19811           Result := True;
19812         end;
19813       end;
19814       QEventClose:
19815       begin
19816         if QMessageBox_escapeButton(QMessageBoxH(Sender)) = nil then
19817         begin
19818           QDialog_done(QDialogH(Sender), Ord(QDialogRejected));
19819           Result := True;
19820         end;
19821       end;
19822     end;
19823   end;
19824 end;
19825 
19826 procedure TQtMessageBox.SetButtonProps(ABtn: QPushButtonH; AResult: Int64; const ADefaultBtn: Boolean; const AEscapeBtn: Boolean);
19827 var
19828   v: QVariantH;
19829 begin
19830   if ADefaultBtn then
19831     QMessageBox_setDefaultButton(QMessageBoxH(Widget), ABtn);
19832 
19833   if AEscapeBtn then
19834     QMessageBox_setEscapeButton(QMessageBoxH(Widget), ABtn);
19835 
19836   v := QVariant_create(AResult);
19837   try
19838     QObject_setProperty(ABtn, 'lclmsgboxbutton', v);
19839   finally
19840     QVariant_destroy(v);
19841   end;
19842 end;
19843 
TQtMessageBox.AddButtonnull19844 function TQtMessageBox.AddButton(ACaption: WideString; ABtnType: QMessageBoxStandardButton;
19845    AResult: Int64; const ADefaultBtn: Boolean; const AEscapeBtn: Boolean): QPushButtonH;
19846 var
19847   Str: WideString;
19848 begin
19849   Result := QMessageBox_addButton(QMessageBoxH(Widget), ABtnType);
19850   Str := GetUTF8String(ACaption);
19851   QAbstractButton_setText(Result, @Str);
19852   SetButtonProps(Result, AResult, ADefaultBtn, AEscapeBtn);
19853 end;
19854 
TQtMessageBox.AddButtonnull19855 function TQtMessageBox.AddButton(ACaption: WideString; AResult: Int64; const ADefaultBtn: Boolean;
19856   const AEscapeBtn: Boolean): QPushButtonH;
19857 var
19858   Str: WideString;
19859 begin
19860   Str := GetUTF8String(ACaption);
19861   Result := QMessageBox_addButton(QMessageBoxH(Widget), @Str, QMessageBoxActionRole);
19862   SetButtonProps(Result, AResult, ADefaultBtn, AEscapeBtn);
19863 end;
19864 
TQtMessageBox.execnull19865 function TQtMessageBox.exec: Int64;
19866 var
19867   ABtn: QPushButtonH;
19868   v: QVariantH;
19869   ok: Boolean;
19870   QResult: Int64;
19871 begin
19872   Result := mrCancel;
19873   {$IFDEF QTDIALOGS_USES_QT_LOOP}
19874   QDialog_exec(QMessageBoxH(Widget));
19875   {$ELSE}
19876   QMessageBox_setWindowModality(QMessageBoxH(Widget), QtApplicationModal);
19877   QWidget_show(Widget);
19878 
19879   {$IFDEF HASX11}
19880   if (QtWidgetSet.WindowManagerName = 'metacity') then
19881       X11Raise(QWidget_winID(Widget));
19882   {$ENDIF}
19883   {$IFDEF TQTMESSAGEBOXUSEPARENT}
19884   QWidget_activateWindow(Widget);
19885   QWidget_raise(Widget);
19886   {$ENDIF}
19887 
19888   repeat
19889     QCoreApplication_processEvents();
19890     Application.Idle(true);
19891   until not QWidget_isVisible(Widget) or Application.Terminated;
19892   {$ENDIF}
19893   ABtn := QPushButtonH(QMessageBox_clickedButton(QMessageBoxH(Widget)));
19894   if ABtn <> nil then
19895   begin
19896     v := QVariant_create();
19897     try
19898       QObject_property(ABtn, v, 'lclmsgboxbutton');
19899       if QVariant_isValid(v) then
19900       begin
19901         QResult := QVariant_toLongLong(v, @Ok);
19902         if Ok then
19903           Result := QResult;
19904       end;
19905     finally
19906       QVariant_destroy(v);
19907     end;
19908   end;
19909 end;
19910 
19911 
19912 {$IFDEF QTACCESSIBILITY}
LazRoleToQtRolenull19913 function LazRoleToQtRole(ALazRole: TLazAccessibilityRole): QAccessibleRole;
19914 begin
19915   case ALazRole of
19916     larIgnore: Result := QAccessibleClient;  // Qt follows ATSPI roles and doesn't have an ignore
19917     larAnimation: Result := QAccessibleAnimation;
19918     larButton: Result := QAccessibleButton;
19919     larCell: Result := QAccessibleCell;
19920     larChart: Result := QAccessibleChart;
19921     larCheckBox: Result := QAccessibleCheckBox;
19922     larClock: Result := QAccessibleClock;
19923     larColorPicker: Result := QAccessibleColorChooser;
19924     larColumn: Result := QAccessibleColumn;
19925     larComboBox: Result := QAccessibleComboBox;
19926     larDateField: Result := QAccessibleStaticText;
19927     larGrid: Result := QAccessibleTable;
19928     larGroup: Result := QAccessibleGrouping;
19929     larImage: Result := QAccessibleGraphic;
19930     larLabel: Result := QAccessibleStaticText;
19931     larListBox: Result := QAccessibleList;
19932     larListItem: Result := QAccessibleListItem;
19933     larMenuBar: Result := QAccessibleMenuBar;
19934     larMenuItem: Result := QAccessibleMenuItem;
19935     larProgressIndicator: Result := QAccessibleProgressBar;
19936     larRadioButton: Result := QAccessibleRadioButton;
19937     larResizeGrip: Result := QAccessibleGrip;
19938     larRow: Result := QAccessibleRow;
19939     larScrollBar: Result := QAccessibleScrollBar;
19940     larSpinner: Result := QAccessibleSpinBox;
19941     larTabControl: Result := QAccessiblePageTab;
19942     larText: Result := QAccessibleSTaticText;
19943     larTextEditorMultiline: Result := QAccessibleEditableText;
19944     larTextEditorSingleline: Result := QAccessibleEditableText;
19945     larToolBar: Result := QAccessibleToolBar;
19946     larToolBarButton: Result := QAccessibleButton;
19947     larTrackBar: Result := QAccessibleSlider;
19948     larTreeView: Result := QAccessibleTree;
19949     larTreeItem: Result := QAccessibleTreeItem;
19950     larWindow: Result := QAccessibleWindow;
19951   else
19952     // including larIgnore, larUnknown
19953     Result := QAccessibleNoRole;
19954   end;
19955 end;
19956 
19957 function CreateAccessibleName(AObject: TLazAccessibleObject): String;
19958 var
19959   TargControl: TControl;
19960   S: String;
19961 begin
19962   S := '';
19963   if Assigned(AObject) then begin
19964     if AObject.AccessibleName <> '' then
19965       S := AObject.AccessibleName;
19966     if (S = '') and (AObject.OwnerControl <> nil) then begin
19967       TargControl := AObject.OwnerControl;
19968       S := TargControl.Caption;
19969       if S = '' then
19970         S := TargControl.Name;
19971       if S = '' then
19972         S := TargControl.ClassName;
19973     end;
19974   end;
19975   Result := S;
19976 end;
19977 {$ENDIF}
19978 
19979 function LCLControlRectToQtScreenRect(ARect: TRect; AControl: TControl): TRect;
19980 var
19981   Pt: TPoint;
19982 begin
19983   Pt := AControl.ClientToScreen(ARect.TopLeft);
19984   Result := Rect(Pt.X, Pt.Y, Pt.X + ARect.Width, Pt.Y + ARect.Height);
19985 end;
19986 
19987 function QtScreenPointToLCLControlPoint(APoint: TPoint; AControl: TControl): TPoint;
19988 begin
19989   Result := AControl.ScreenToClient(APoint);
19990 end;
19991 
19992 {$IFDEF QTACCESSIBILITY}
19993 function QtAxFactory(name: QStringH; obj: QObjectH): QAccessibleInterfaceH; cdecl;
19994 var
19995   CreateLCLAccessibleInterface: Boolean;
19996   H: HWND;
19997   QtObj: TQtObject;
19998   objName: string;
19999   WStr: WideString;
20000 begin
20001   Result := nil;
20002   CreateLCLAccessibleInterface := False;
20003   if QObject_isWidgetType(obj) then begin
20004     QObject_objectName(obj, @WStr);
20005     objName := UTF16ToUTF8(WStr);
20006     if (objName = QtAXObjectName) then
20007       CreateLCLAccessibleInterface := True
20008     else begin
20009       H := HwndFromWidgetH(QWidgeth(obj));
20010       if (H <> 0) then begin
20011         QtObj := TQtObject(H);
20012         if (QtObj is TQtCustomControl) then
20013           CreateLCLAccessibleInterface := True;
20014       end
20015     end
20016   end;
20017 
20018   if CreateLCLAccessibleInterface then begin
20019     Result := QLCLAccessibleWidget_Create(QWidgetH(obj), QAccessibleClient, nil);
20020   end
20021   else
20022     Result := nil;
20023 end;
20024 
20025 constructor TQtAccessibleObject.Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
20026 var
20027   WStr: WideString;
20028   AxInterface: QLCLAccessibleWidgetH;
20029 begin
20030   inherited Create;
20031   FLazAxObject := ALazAxObject;
20032   if (AWidget = QWidgetH(0)) then begin
20033     FAxWidget := QWidget_Create();
20034     WStr := GetUtf8String(QtAXObjectName);
20035     QObject_setObjectName(FAxWidget, @WStr);
20036   end
20037   else
20038     FAxWidget := AWidget;
20039 
20040   AxInterface := QLCLAccessibleWidgetH(QAccessible_queryAccessibleInterface(FAxWidget));
20041   QLCLAccessibleWidget_override_child(AxInterface, @childOverride);
20042   QLCLAccessibleWidget_override_childCount(AxInterface, @childCountOverride);
20043   QLCLAccessibleWidget_override_role(AxInterface, @roleOverride);
20044   QLCLAccessibleWidget_override_text(AxInterface, @textOverride);
20045 end;
20046 
20047 destructor TQtAccessibleObject.Destroy;
20048 var
20049   WStr: WideString;
20050   objName: string;
20051 begin
20052   QObject_objectName(FAxWidget, @WStr);
20053   objName := UTF16ToUTF8(WStr);
20054   if (objName = QtAXObjectName) then
20055     QObject_Destroy(FAxWidget);
20056 
20057   inherited Destroy;
20058 end;
20059 
20060 procedure TQtAccessibleObject.childOverride(index: integer; out child:  QAccessibleInterfaceH) cdecl;
20061 var
20062   childCount: Integer;
20063   lclAxChild: TLazAccessibleObject;
20064   qtAxObject: TQtAccessibleObject;
20065 begin
20066   child := QAccessibleInterfaceH(0);
20067   childCount := 0;
20068   lclAxChild := FLazAxObject.GetFirstChildAccessibleObject;
20069   while Assigned(lclAxChild) and (childCount < index) do begin
20070     inc(ChildCount);
20071     lclAxChild := FLazAxObject.GetNextChildAccessibleObject;
20072   end;
20073   if Assigned(lclAxChild) and (lclAxChild.Handle <> 0) then begin
20074     qtAxObject := TQtAccessibleObject(lclAxChild.Handle);
20075     child := QAccessible_queryAccessibleInterface(qtAxObject.FAxWidget);
20076   end;
20077 end;
20078 
20079 procedure TQtAccessibleObject.childCountOverride(count: PInteger) cdecl;
20080 var
20081   childCount: Integer;
20082   lclAxChild: TLazAccessibleObject;
20083 begin
20084   childCount := 0;
20085   lclAxChild := FLazAxObject.GetFirstChildAccessibleObject;
20086   while Assigned(lclAxChild) do begin
20087     inc(ChildCount);
20088     lclAxChild := FLazAxObject.GetNextChildAccessibleObject;
20089   end;
20090   count^ := childCount;
20091 end;
20092 
20093 procedure TQtAccessibleObject.roleOverride(out role: QAccessibleRole) cdecl;
20094 begin
20095   if (FLazAxObject <> nil) then
20096     role := LazRoleToQtRole(FLazAxObject.AccessibleRole)
20097   else
20098     role := QAccessibleNoRole;
20099 end;
20100 
20101 procedure TQtAccessibleObject.textOverride(text: QAccessibleText; retval: PWideString) cdecl;
20102 begin
20103   case text of
20104   QAccessibleName:
20105       retval^ := GetUtf8String(CreateAccessibleName(FLazAxObject));
20106   QAccessibleDescription:
20107     retval^ := GetUtf8String(FLazAxObject.AccessibleDescription);
20108   QAccessibleValue:
20109     retval^ := GetUtf8String(FLazAxObject.AccessibleValue);
20110   else
20111    retval^ := GetUtf8String('');
20112   end;
20113 end;
20114 
isVisiblenull20115 function TQtAccessibleObject.isVisible: Boolean;
20116 begin
20117   Result := FLazAxObject.OwnerControl.Visible;
20118 end;
20119 
20120 constructor TQtAccessibleTree.Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
20121 var
20122   AxInterface: QLCLAccessibleWidgetH;
20123 begin
20124   inherited Create(ALazAxObject, AWidget);
20125 
20126   AxInterface := QLCLAccessibleWidgetH(QAccessible_queryAccessibleInterface(FAxWidget));
20127   QLCLAccessibleWidget_override_child(AxInterface, @childOverride);
20128   QLCLAccessibleWidget_override_childCount(AxInterface, @childCountOverride);
20129 end;
20130 
20131 procedure TQtAccessibleTree.childOverride(index: integer; out child:  QAccessibleInterfaceH); cdecl;
20132 var
20133   ChildIndex: Integer;
20134   LCLAxChild: TLazAccessibleObject;
20135   RowAxObject: TQtAccessibleTreeRow;
20136 begin
20137   child := QAccessibleInterfaceH(0);
20138   ChildIndex := 0;
20139   for LCLAxChild in FLazAxObject do begin
20140     RowAxObject := TQtAccessibleTreeRow(LCLAxChild.Handle);
20141     if RowAxObject.isVisible then begin
20142       if ChildIndex = index then begin
20143         child := QAccessible_queryAccessibleInterface(RowAxObject.FAxWidget);
20144         Exit;
20145       end;
20146       Inc(ChildIndex);
20147     end;
20148   end;
20149 end;
20150 
20151 procedure TQtAccessibleTree.childCountOverride(count: PInteger); cdecl;
20152 var
20153   Tree: TCustomTreeView;
20154   TreeNode: TTreeNode;
20155   ChildCount: Integer;
20156 begin
20157   Tree := TCustomTreeView(FLazAxObject.OwnerControl);
20158   ChildCount := 0;
20159   TreeNode := Tree.Items.GetFirstVisibleNode;
20160   while (TreeNode <> nil) do begin
20161     Inc(ChildCount);
20162     TreeNode := TreeNode.GetNextVisible;
20163   end;
20164   count^ := ChildCount;
20165 end;
20166 
20167 
20168 constructor TQtAccessibleTreeRow.Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
20169 var
20170   AxInterface: QLCLAccessibleWidgetH;
20171 begin
20172   inherited Create(ALazAxObject, AWidget);
20173 
20174   AxInterface := QLCLAccessibleWidgetH(QAccessible_queryAccessibleInterface(FAxWidget));
20175   QLCLAccessibleWidget_override_actionNames(AxInterface, @actionNamesOverride);
20176   QLCLAccessibleWidget_override_child(AxInterface, nil);
20177   QLCLAccessibleWidget_override_childAt(AxInterface, nil);
20178   QLCLAccessibleWidget_override_childCount(AxInterface, @childCountOverride);
20179   QLCLAccessibleWidget_override_doAction(AxInterface, @doActionOverride);
20180   QLCLAccessibleWidget_override_parent(AxInterface, @parentOVerride);
20181   QLCLAccessibleWidget_override_rect(AxInterface, @rectOverride);
20182   QLCLAccessibleWidget_override_role(AxInterface, @roleOverride);
20183   QLCLAccessibleWidget_override_text(AxInterface, @textOverride);
20184 end;
20185 
20186 procedure TQtAccessibleTreeRow.actionNamesOverride(names: PWideString)cdecl;
20187 begin
20188   names^ := GetUtf8String(axActionNamePress); // Takes a comma separated string of actions
20189 end;
20190 
20191 procedure TQtAccessibleTreeRow.doActionOverride(name: PWideString)cdecl;
20192 var s: string;
20193   TreeNode: TTreeNode;
20194 begin
20195   s := UTF16ToUTF8(name^);
20196   if s = axActionNamePress then begin
20197     TreeNode := TTreeNode(FLazAxObject.DataObject);
20198     TreeNode.TreeView.Select(TreeNode);
20199   end;
20200 end;
20201 
20202 procedure TQtAccessibleTreeRow.childCountOverride(count: PInteger)cdecl;
20203 begin
20204   count^ := 0;
20205 end;
20206 
20207 procedure TQtAccessibleTreeRow.parentOverride(out parent: QAccessibleInterfaceH)cdecl;
20208 begin
20209   parent := QLCLAccessibleWidgetH(QAccessible_queryAccessibleInterface(
20210      TQtAccessibleObject(FLazAxObject.Parent.Handle).FAxWidget));
20211 end;
20212 
20213 procedure TQtAccessibleTreeRow.rectOverride(left, top, width, height: PInteger)cdecl;
20214 var
20215   TreeNode: TTreeNode;
20216   NodeR: TRect;
20217   R: TRect;
20218 begin
20219   TreeNode := TTreeNode(FLazAxObject.DataObject);
20220   NodeR := TreeNode.DisplayRect(False);
20221   R := LCLControlRectToQtScreenRect(NodeR, TreeNode.TreeView);
20222   left^ := R.Left;
20223   top^ := R.Top;
20224   width^ := R.Width;
20225   height^ := R.Height;
20226 end;
20227 
20228 procedure TQtAccessibleTreeRow.roleOverride(out role: QAccessibleRole)cdecl;
20229 begin
20230   role := QAccessibleTreeItem;
20231 end;
20232 
20233 procedure TQtAccessibleTreeRow.textOverride(text: QAccessibleText; retval: PWideString) cdecl;
20234 var
20235   TreeNode: TTreeNode;
20236 begin
20237   TreeNode := TTreeNode(FLazAxObject.DataObject);
20238   case text of
20239     QAccessibleName, QAccessibleDescription, QAccessibleValue:
20240       retval^ := GetUtf8String(TreeNode.Text);
20241     else
20242      retval^ := GetUtf8String('');
20243     end;
20244 end;
20245 
isVisiblenull20246 function TQtAccessibleTreeRow.isVisible:Boolean;
20247 var
20248   TreeNode: TTreeNode;
20249 begin
20250   TreeNode := TTreeNode(FLazAxObject.DataObject);
20251   Result := TreeNode.IsVisible;
20252 end;
20253 {$ENDIF}
20254 
20255 
20256 
20257 
20258 end.
20259