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   qt4,
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 Cut;
95     procedure Copy;
96     procedure Paste;
97     procedure Undo;
98   end;
99 
100   // classes
101 
102   { TQtWidget }
103 
104   TQtWidget = class(TQtObject, IUnknown)
105   private
106     FInResizeEvent: boolean;
107     FWidgetState: TQtWidgetStates;
108     FWidgetDefaultFont: TQtFont;
109     FWidgetLCLFont: TQtFont;
110     FWidgetNeedFontColorInitialization: Boolean;
111     FChildOfComplexWidget: TChildOfComplexWidget;
112     FOwnWidget: Boolean;
113     FProps: TStringList;
114     FPaintData: TPaintData;
115     FCentralWidget: QWidgetH;
116     FContext: HDC;
117     FParams: TCreateParams;
118     FDefaultCursor: QCursorH;
119     FKeysToEat: TByteSet;
120     FText: WideString;
121     FHasCaret: Boolean;
122     FLastCaretPos: TQtPoint;
123     FHasPaint: Boolean;
124     FOwner: TQtWidget;
125 
126     FWidgetColorRole: QPaletteColorRole;
127     FTextColorRole: QPaletteColorRole;
128     FPalette: TQtWidgetPalette;
129 
130     {TQtWidget.scroll() info}
131     FScrollX: Integer;
132     FScrollY: Integer;
133 
GetPalettenull134     function GetPalette: TQtWidgetPalette;
GetPropsnull135     function GetProps(const AnIndex: String): pointer;
getScrolledOffsetnull136     function getScrolledOffset: TPoint;
GetStyleSheetnull137     function GetStyleSheet: WideString;
GetWidgetnull138     function GetWidget: QWidgetH;
LCLKeyToQtKeynull139     function LCLKeyToQtKey(AKey: Word): Integer;
QtButtonsToLCLButtonsnull140     function QtButtonsToLCLButtons(AButtons: QtMouseButton): PtrInt;
QtKeyModifiersToKeyStatenull141     function QtKeyModifiersToKeyState(AModifiers: QtKeyboardModifiers;
142       const AIsKeyEvent: Boolean;
143       AEvent: QKeyEventH = nil): PtrInt;
QtKeyToLCLKeynull144     function QtKeyToLCLKey(AKey: Integer; AText: WideString;
145       AEvent: QKeyEventH): Word;
146     procedure SetLastCaretPos(const AValue: TQtPoint);
147     procedure SetProps(const AnIndex: String; const AValue: pointer);
148     procedure SetStyleSheet(const AValue: WideString);
149     procedure SetWidget(const AValue: QWidgetH);
ShiftStateToQtModifiersnull150     function ShiftStateToQtModifiers(Shift: TShiftState): QtModifier;
151   protected
152     // IUnknown implementation
QueryInterfacenull153     function QueryInterface(constref iid: TGuid; out obj): LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
_AddRefnull154     function _AddRef: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
_Releasenull155     function _Release: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
GetContextnull156     function GetContext: HDC; virtual;
CreateWidgetnull157     function CreateWidget(const Params: TCreateParams):QWidgetH; virtual;
158     procedure DestroyWidget; virtual;
159     procedure SetHasCaret(const AValue: Boolean);
ProcessArrowKeysnull160     function ProcessArrowKeys: Boolean; virtual;
161 
162     class procedure removeProperty(AObject: QObjectH; APropName: PAnsiChar);
163     class procedure setProperty(AObject: QObjectH; APropName: PAnsiChar; APropValue: Int64);
164   public
165     LCLObject: TWinControl;
166   public
167     constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); virtual; overload;
168     constructor CreateFrom(const AWinControl: TWinControl; AWidget: QWidgetH); virtual;
169     procedure InitializeWidget; virtual;
170     procedure DeInitializeWidget; virtual;
171     procedure RecreateWidget;
172     procedure DestroyNotify(AWidget: TQtWidget); virtual;
173 
174     destructor Destroy; override;
GetContainerWidgetnull175     function GetContainerWidget: QWidgetH; virtual;
176     procedure Release; override;
177     procedure Destroyed; cdecl; override;
178   public
WinIDNeedednull179     function WinIDNeeded: boolean; virtual;
CanAdjustClientRectOnResizenull180     function CanAdjustClientRectOnResize: Boolean; virtual;
CanChangeFontColornull181     function CanChangeFontColor: Boolean; virtual;
CanSendLCLMessagenull182     function CanSendLCLMessage: Boolean;
CanPaintBackgroundnull183     function CanPaintBackground: Boolean; virtual;
184     {delays resize event of complex widgets or when LCLObject have caspComputingBounds in AutoSizePhases}
185     procedure DelayResizeEvent(AWidget: QWidgetH; ANewSize: TSize);
DeliverMessagenull186     function DeliverMessage(var Msg; const AIsInputEvent: Boolean = False): LRESULT; virtual;
EventFilternull187     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
getAcceptDropFilesnull188     function getAcceptDropFiles: Boolean; virtual;
189     {precise measure of text with widget''s current font when canvas.handle isn''t available}
measureTextnull190     function measureText(AText: WideString; AFlags: cardinal): TRect;
191     procedure SetNoMousePropagation(Sender: QWidgetH; const ANoMousePropagation: Boolean); virtual;
192     procedure SetLCLFont(AFont: TQtFont);
193     procedure SlotShow(vShow: Boolean); cdecl;
SlotClosenull194     function SlotClose: Boolean; cdecl; virtual;
195     procedure SlotDestroy; cdecl;
slotDropFilesnull196     function slotDropFiles(Sender: QObjectH; Event: QEventH): Boolean;
SlotHovernull197     function SlotHover(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotKeynull198     function SlotKey(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotInputMethodnull199     function SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotMousenull200     function SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; virtual; cdecl;
201     procedure SlotNCMouse(Sender: QObjectH; Event: QEventH); cdecl;
SlotMouseEnternull202     function SlotMouseEnter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotMouseMovenull203     function SlotMouseMove(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotMouseWheelnull204     function SlotMouseWheel(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
205     procedure SlotMove(Event: QEventH); cdecl;
206     procedure SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl; virtual;
207     procedure SlotPaint(Sender: QObjectH; Event: QEventH); cdecl;
208     procedure SlotResize(Event: QEventH); cdecl;
SlotContextMenunull209     function SlotContextMenu(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
210     procedure SlotWhatsThis(Sender: QObjectH; Event: QEventH); cdecl;
211     procedure SlotLCLMessage(Sender: QObjectH; Event: QEventH); cdecl;
212   public
213     procedure Activate; virtual;
214     procedure BringToFront;
215     procedure clearMask;
216     procedure OffsetMousePos(APoint: PQtPoint); virtual;
217     procedure Update(ARect: PRect = nil); virtual;
218     procedure UpdateRegion(ARgn: QRegionH); virtual;
219     procedure Repaint(ARect: PRect = nil); virtual;
220     procedure setWindowTitle(Str: PWideString);
221     procedure WindowTitle(Str: PWideString);
222     procedure Hide;
223     procedure Show;
224     procedure ShowNormal;
225     procedure ShowMinimized;
226     procedure ShowMaximized;
227     procedure ShowFullScreen;
getActionByIndexnull228     function getActionByIndex(AIndex: Integer): QActionH;
getAutoFillBackgroundnull229     function getAutoFillBackground: Boolean;
getClientBoundsnull230     function getClientBounds: TRect; virtual;
getClientOffsetnull231     function getClientOffset: TPoint; virtual;
getEnablednull232     function getEnabled: Boolean;
getFontnull233     function getFont: QFontH;
getFocusPolicynull234     function getFocusPolicy: QtFocusPolicy;
getFrameGeometrynull235     function getFrameGeometry: TRect; virtual;
getGeometrynull236     function getGeometry: TRect; virtual;
getLayoutDirectionnull237     function getLayoutDirection: QtLayoutDirection;
getVisiblenull238     function getVisible: Boolean; virtual;
getVisibleTonull239     function getVisibleTo(AWidget: QWidgetH): Boolean; virtual;
getOwnernull240     function getOwner: TQtWidget;
getParentnull241     function getParent: QWidgetH;
getPosnull242     function getPos: TQtPoint;
getFrameSizenull243     function getFrameSize: TSize; virtual;
getSizenull244     function getSize: TSize;
getTextnull245     function getText: WideString; virtual;
getTextStaticnull246     function getTextStatic: Boolean; virtual;
getHeightnull247     function getHeight: Integer;
getUpdatesEnablednull248     function getUpdatesEnabled: Boolean;
getWidthnull249     function getWidth: Integer;
getWindownull250     function getWindow: TQtWidget;
getWindowStatenull251     function getWindowState: QtWindowStates; {$IFDEF QTSCROLLABLEFORMS}virtual;{$ENDIF}
252     procedure grabMouse; virtual;
hasFocusnull253     function hasFocus: Boolean; virtual;
IsActiveWindownull254     function IsActiveWindow: Boolean;
isMinimizednull255     function isMinimized: Boolean;
isMaximizednull256     function isMaximized: Boolean;
IsFramedWidgetnull257     function IsFramedWidget: boolean; virtual;
isFullScreennull258     function isFullScreen: Boolean;
IsWindownull259     function IsWindow: Boolean;
260     procedure lowerWidget; virtual;
MapToGlobalnull261     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; virtual;
MapFromGlobalnull262     function MapFromGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; virtual;
263     procedure move(ANewLeft, ANewTop: Integer); virtual;
264     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); virtual;
265     procedure raiseWidget; virtual;
266     procedure stackUnder(AWidget: QWidgetH); virtual;
267     procedure frame_resize(ANewWidth, ANewHeight: Integer);
268     procedure Resize(ANewWidth, ANewHeight: Integer); virtual;
269     procedure releaseMouse;
270     procedure scroll(dx, dy: integer; ARect: PRect = nil); virtual;
271     procedure setAutoFillBackground(const AValue: Boolean);
272     procedure setAttribute(const Attr: QtWidgetAttribute; const TurnOn: Boolean = True);
273     procedure setBackgroundRole(const ARole: QPaletteColorRole);
274     procedure setDefaultColor(const DefaultColorType: TDefaultColorType);
275     procedure setColor(const Value: PQColor); virtual;
getContextMenuPolicynull276     function getContextMenuPolicy: QtContextMenuPolicy; virtual;
277     procedure setContextMenuPolicy(const AValue: QtContextMenuPolicy); virtual;
278     procedure setCursor(const ACursor: QCursorH); virtual;
279     procedure setDefaultColorRoles; virtual;
280     procedure setEnabled(p1: Boolean);
281     procedure setFocus;
282     procedure setFocusPolicy(const APolicy: QtFocusPolicy); virtual;
283     procedure setFocusProxy(const AWidget: QWidgetH);
284     procedure setFont(AFont: QFontH);
285     procedure setGeometry(ARect: TRect); virtual;
286     procedure setInitialFontColor(AControl: TWinControl); virtual;
287     procedure setLayoutDirection(ADirection: QtLayoutDirection);
288     procedure setMaximumSize(AWidth, AHeight: Integer);
289     procedure setMask(AMask: QBitmapH); overload;
290     procedure setMask(AMask: QRegionH); overload;
291     procedure setMinimumSize(AWidth, AHeight: Integer);
292     procedure setParent(parent: QWidgetH); virtual;
293     procedure setText(const W: WideString); virtual;
294     procedure setTextColor(const Value: PQColor); virtual;
295     procedure setVisible(AVisible: Boolean); virtual;
296     procedure setWindowFlags(_type: QtWindowFlags);
297     procedure setWindowIcon(AIcon: QIconH);
298     procedure setWindowModality(windowModality: QtWindowModality);
299     procedure setWindowOpacity(opacity: double);
300     procedure setWidth(p1: Integer);
301     procedure setHeight(p1: Integer);
302     procedure setUpdatesEnabled(const AEnabled: Boolean);
303     procedure setWindowState(AState: QtWindowStates);
304     procedure sizeHint(size: PSize);
testAttributenull305     function testAttribute(const AAttribute: QtWidgetAttribute): boolean;
windowFlagsnull306     function windowFlags: QtWindowFlags;
windowModalitynull307     function windowModality: QtWindowModality;
308     property ChildOfComplexWidget: TChildOfComplexWidget read FChildOfComplexWidget write FChildOfComplexWidget;
309     property Context: HDC read GetContext;
310     property HasCaret: Boolean read FHasCaret write SetHasCaret;
311     property HasPaint: Boolean read FHasPaint write FHasPaint;
312     property InResizeEvent: boolean read FInResizeEvent write FInResizeEvent;
313     property KeysToEat: TByteSet read FKeysToEat write FKeysToEat;
314     property LastCaretPos: TQtPoint read FLastCaretPos write SetLastCaretPos;
315     property ScrolledOffset: TPoint read getScrolledOffset;
316     property StyleSheet: WideString read GetStyleSheet write SetStyleSheet;
317     property PaintData: TPaintData read FPaintData write FPaintData;
318     property Palette: TQtWidgetPalette read GetPalette;
319     property Props[AnIndex:String]:pointer read GetProps write SetProps;
320     property TextColorRole: QPaletteColorRole read FTextColorRole write FTextColorRole;
321     property Widget: QWidgetH read GetWidget write SetWidget;
322     property WidgetColorRole: QPaletteColorRole read FWidgetColorRole write FWidgetColorRole;
323     property WidgetState: TQtWidgetStates read FWidgetState write FWidgetState;
324   end;
325 
326   { TQtAbstractSlider , inherited by TQtScrollBar, TQtTrackBar }
327 
328   TQtAbstractSlider = class(TQtWidget)
329   private
330     FSliderPressed: Boolean;
331     FSliderReleased: Boolean;
332     FRangeChangedHook: QAbstractSlider_hookH;
333     FSliderMovedHook:  QAbstractSlider_hookH;
334     FSliderPressedHook: QAbstractSlider_hookH;
335     FSliderReleasedHook: QAbstractSlider_hookH;
336     FValueChangedHook: QAbstractSlider_hookH;
337     FActionTriggeredHook: QAbstractSlider_hookH;
338   protected
CreateWidgetnull339     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
340   public
341     procedure AttachEvents; override;
342     procedure DetachEvents; override;
343 
344     procedure SlotSliderMoved(p1: Integer); cdecl; virtual;
345     procedure SlotValueChanged(p1: Integer); cdecl; virtual;
346     procedure SlotActionTriggered(action: Integer); cdecl; virtual;
347     procedure SlotRangeChanged(minimum: Integer; maximum: Integer); cdecl; virtual;
348     procedure SlotSliderPressed; cdecl;
349     procedure SlotSliderReleased; cdecl; virtual;
350   public
CanChangeFontColornull351     function CanChangeFontColor: Boolean; override;
getInvertedAppereancenull352     function getInvertedAppereance: Boolean;
getInvertedControlsnull353     function getInvertedControls: Boolean;
getOrientationnull354     function getOrientation: QtOrientation;
getValuenull355     function getValue: Integer;
getPageStepnull356     function getPageStep: Integer;
getMinnull357     function getMin: Integer;
getMaxnull358     function getMax: Integer;
getSingleStepnull359     function getSingleStep: Integer;
getSliderDownnull360     function getSliderDown: Boolean;
getSliderPositionnull361     function getSliderPosition: Integer;
getTrackingnull362     function getTracking: Boolean;
363 
364     procedure setInvertedAppereance(p1: Boolean); virtual;
365     procedure setInvertedControls(p1: Boolean); virtual;
366 
367     procedure setMaximum(p1: Integer); virtual;
368     procedure setMinimum(p1: Integer); virtual;
369 
370     procedure setOrientation(p1: QtOrientation); virtual;
371     procedure setPageStep(p1: Integer); virtual;
372     procedure setRange(minimum: Integer; maximum: Integer); virtual;
373     procedure setSingleStep(p1: Integer); virtual;
374     procedure setSliderDown(p1: Boolean); virtual;
375     procedure setSliderPosition(p1: Integer); virtual;
376     procedure setTracking(p1: Boolean); virtual;
377     procedure setValue(p1: Integer); virtual;
378     property SliderPressed: Boolean read FSliderPressed;
379     property SliderReleased: Boolean read FSliderReleased;
380   end;
381 
382   { TQtScrollBar }
383 
384   TQtScrollBar = class(TQtAbstractSlider)
385   private
386     FTrackPos: Integer;
387   protected
CreateWidgetnull388     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
389   public
390     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
391     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
392     procedure SlotSliderReleased; cdecl; override;
EventFilternull393     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
394     procedure AttachEvents; override;
395     property TrackPos: Integer read FTrackPos write FTrackPos;
396   end;
397 
398   { TQtFrame }
399 
400   TQtFrame = class(TQtWidget)
401   private
402   protected
CreateWidgetnull403     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
404   public
CanPaintBackgroundnull405     function CanPaintBackground: Boolean; override;
406     procedure SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl; override;
407     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
408     procedure setFrameStyle(p1: Integer);
409     procedure setFrameShape(p1: QFrameShape);
410     procedure setFrameShadow(p1: QFrameShadow);
411   end;
412 
413   { TQtAbstractScrollArea }
414 
415   TQtAbstractScrollArea = class(TQtFrame)
416   private
getScrollBarsPolicynull417     function getScrollBarsPolicy(AIndex: Boolean): QtScrollBarPolicy;
418   protected
419     FHScrollbar: TQtScrollBar;
420     FVScrollbar: TQtScrollbar;
421     procedure setScrollBarPolicy(AIndex: Boolean;
422       const AValue: QtScrollBarPolicy);
423   public
EventFilternull424     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
425     procedure grabMouse; override;
GetContainerWidgetnull426     function GetContainerWidget: QWidgetH; override;
getClientOffsetnull427     function getClientOffset: TPoint; override;
getClientBoundsnull428     function getClientBounds: TRect; override;
getScrollFrameOffsetnull429     function getScrollFrameOffset: Integer;
getViewOriginnull430     function getViewOrigin: TPoint;
viewportWidgetnull431     function viewportWidget: QWidgetH;
horizontalScrollBarnull432     function horizontalScrollBar: TQtScrollBar;
verticalScrollBarnull433     function verticalScrollBar: TQtScrollBar;
434     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
435     procedure setHorizontalScrollBar(AScrollBar: TQtScrollBar);
436     procedure setVerticalScrollBar(AScrollBar: TQtScrollBar);
437     procedure setScrollStyle(AScrollStyle: TScrollStyle);
438     procedure SetNoMousePropagation(Sender: QWidgetH; const ANoMousePropagation: Boolean); override;
439     procedure DestroyNotify(AWidget: TQtWidget); override;
440     destructor Destroy; override;
441     procedure Update(ARect: PRect = nil); override;
442     procedure UpdateRegion(ARgn: QRegionH); override;
443     procedure Repaint(ARect: PRect = nil); override;
444     property ScrollBarPolicy[AIndex: Boolean]: QtScrollBarPolicy read getScrollBarsPolicy write setScrollBarPolicy;
445   end;
446 
447   { TQtCustomControl }
448 
449   TQtCustomControl = class(TQtAbstractScrollArea)
450   private
451     FCornerWidget: TQtWidget;
452     FViewPortWidget: TQtViewPort;
453   protected
CreateWidgetnull454     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
ProcessArrowKeysnull455     function ProcessArrowKeys: Boolean; override;
456   public
457     destructor Destroy; override;
EventFilternull458     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
459     procedure ViewPortEventFilter(event: QEventH; retval: PBoolean); cdecl;
460 
461     procedure DestroyNotify(AWidget: TQtWidget); override;
462   public
CanAdjustClientRectOnResizenull463     function CanAdjustClientRectOnResize: Boolean; override;
cornerWidgetnull464     function cornerWidget: TQtWidget;
MapToGlobalnull465     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
MapFromGlobalnull466     function MapFromGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
viewportnull467     function viewport: TQtViewPort;
468     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); override;
469     procedure setCornerWidget(AWidget: TQtWidget);
470     procedure setCursor(const ACursor: QCursorH); override;
471     procedure setViewport(const AViewPort: QWidgetH);
472     procedure setVisible(AVisible: Boolean); override;
473     procedure viewportNeeded; virtual;
474     procedure viewportDelete; virtual;
475   end;
476 
477   { TQtViewPort }
478 
479   TQtViewPort = class(TQtWidget)
480   private
481     {when our viewport is invisible then we must keep track of scrolling. issue #29239}
482     FInvisibleX: integer;
483     FInvisibleY: integer;
484   public
CanPaintBackgroundnull485     function CanPaintBackground: Boolean; override;
EventFilternull486     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
487     procedure InitializeWidget; override;
488     procedure scroll(dx, dy: integer; ARect: PRect = nil); override;
489     procedure stackUnder(AWidget: QWidgetH); override;
490   end;
491 
492   { TQtGraphicView }
493 
494   TQtGraphicsView = class(TQtAbstractScrollArea)
495   protected
CreateWidgetnull496     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
497   end;
498 
499   { TQtArrow }
500 
501   TQtArrow = class(TQtFrame)
502   protected
CreateWidgetnull503     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
504   public
505     ArrowType: Integer;
506   end;
507 
508   { TQtAbstractButton }
509 
510   TQtAbstractButton = class(TQtWidget)
511   protected
ProcessArrowKeysnull512     function ProcessArrowKeys: Boolean; override;
513   public
CanPaintBackgroundnull514     function CanPaintBackground: Boolean; override;
getIconSizenull515     function getIconSize: TSize; virtual;
getTextnull516     function getText: WideString; override;
517     procedure setIcon(AIcon: QIconH); virtual;
518     procedure setIconSize(Size: PSize); virtual;
519     procedure setShortcut(AShortCutK1, AShortCutK2: TShortcut);
520     procedure setText(const W: WideString); override;
521     procedure Toggle;
isCheckednull522     function isChecked: Boolean;
isDownnull523     function isDown: Boolean;
524     procedure setCheckable(p1: Boolean);
525     procedure setChecked(p1: Boolean);
526     procedure setDefaultColorRoles; override;
527     procedure setDown(p1: Boolean);
528     procedure SignalPressed; cdecl;
529     procedure SignalReleased; cdecl;
530     procedure SignalClicked({%H-}Checked: Boolean = False); cdecl;
531     procedure SignalClicked2; cdecl;
532   end;
533 
534   { TQtPushButton }
535 
536   TQtPushButton = class(TQtAbstractButton)
537   private
538     FClickedHook: QAbstractButton_hookH;
539     FToggledHook: QAbstractButton_hookH;
540   protected
CreateWidgetnull541     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
542   public
543     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
544   public
545     procedure SetDefault(const ADefault: Boolean);
546     procedure AttachEvents; override;
547     procedure DetachEvents; override;
548     procedure SlotClicked; cdecl; virtual;
549     procedure SlotToggled({%H-}AChecked: Boolean); cdecl; virtual;
550   end;
551 
552   { TQtBitBtn }
553 
554   TQtBitBtn = class(TQtPushButton)
555   private
556     FGlyphLayout: Integer;
557     FIcon: QIconH;
558     FIconSize: TSize;
559   protected
CreateWidgetnull560     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
561   public
562     destructor Destroy; override;
EventFilternull563     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
564     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
565 
getIconSizenull566     function getIconSize: TSize; override;
getTextnull567     function getText: WideString; override;
568     procedure setIcon(AIcon: QIconH); override;
569     procedure setIconSize(Size: PSize); override;
570     procedure setText(const W: WideString); override;
571 
572     property GlyphLayout: Integer read FGlyphLayout write FGlyphLayout;
573   end;
574 
575   { TQtToggleBox }
576 
577   TQtToggleBox = class(TQtPushButton)
578   public
579     procedure SlotClicked; cdecl; override;
580     procedure SlotToggled({%H-}AChecked: Boolean); cdecl; override;
581   end;
582 
583   { TQtMainWindow }
584 
585   TQtMenuBar = class;
586   TQtToolBar = class;
587   TQtStatusBar = class;
588 
589   { TQtMDIArea }
590 
591   TQtMDIArea = class(TQtAbstractScrollArea)
592   private
593     FViewPortEventHook: QObject_hookH;
594     FSubWindowActivationHook: QMdiArea_hookH;
595     procedure SubWindowActivated(AWindow: QMDISubWindowH); cdecl;
596   protected
ScrollViewEventFilternull597     function ScrollViewEventFilter(Sender: QObjectH; Event: QEventH): boolean; cdecl;
598   public
599     constructor Create(const AParent: QWidgetH); overload;
600     destructor Destroy; override;
getClientOffsetnull601     function getClientOffset: TPoint; override;
EventFilternull602     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
603     procedure AttachEvents; override;
604     procedure DetachEvents; override;
ActiveSubWindownull605     function ActiveSubWindow: QMdiSubWindowH;
606     procedure ActivateSubWindow(AMdiWindow: QMdiSubWindowH);
607   end;
608 
609   {$IFDEF QTSCROLLABLEFORMS}
610   { TQtWindowArea }
611 
612   {Scrollbars on qt forms}
613   TQtWindowArea = class(TQtAbstractScrollArea)
614   private
615     FViewPortEventHook: QObject_hookH;
616   public
617     procedure AttachEvents; override;
CanAdjustClientRectOnResizenull618     function CanAdjustClientRectOnResize: Boolean; override;
619     procedure DetachEvents; override;
MapToGlobalnull620     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
621     procedure scroll(dx, dy: integer; ARect: PRect = nil); override;
622     {abstractscrollarea events}
EventFilternull623     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
624     {viewport events}
ScrollViewEventFilternull625     function ScrollViewEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
getWindowStatenull626     function getWindowState: QtWindowStates; override;
627   end;
628   {$ENDIF}
629 
630   TQtMainWindow = class(TQtWidget)
631   private
632     FBlocked: Boolean;
633     FFirstPaintEvent: boolean;
634     FIsFrameWindow: Boolean;
635     LayoutWidget: QBoxLayoutH;
636     FCWEventHook: QObject_hookH;
637     FShowOnTaskBar: Boolean;
638     FPopupParent: QWidgetH;
639     FMDIStateHook: QMdiSubWindow_hookH;
640   protected
CreateWidgetnull641     function CreateWidget(const {%H-}AParams: TCreateParams):QWidgetH; override;
642     procedure ChangeParent(NewParent: QWidgetH);
643     procedure UpdateParent;
644   public
645     QtFormBorderStyle: Integer;
646     QtFormStyle: Integer;
647     IsMainForm: Boolean;
648     MDIAreaHandle: TQtMDIArea; // valid only if we are fsMDIForm
649     MDIChildArea: TQtMDIArea; // valid only if we are fsMDIChild
650     MenuBar: TQtMenuBar;
651     ToolBar: TQtToolBar;
652     {$IFDEF QTSCROLLABLEFORMS}
653     ScrollArea: TQtWindowArea;
654     {$ENDIF}
655     destructor Destroy; override;
656 
657     procedure BeginUpdate; override;
658     procedure EndUpdate; override;
659 
660     procedure Activate; override;
CanAdjustClientRectOnResizenull661     function CanAdjustClientRectOnResize: Boolean; override;
getAcceptDropFilesnull662     function getAcceptDropFiles: Boolean; override;
GetContainerWidgetnull663     function GetContainerWidget: QWidgetH; override;
664     procedure grabMouse; override;
getClientBoundsnull665     function getClientBounds: TRect; override;
getClientOffsetnull666     function getClientOffset: TPoint; override;
667 
getTextnull668     function getText: WideString; override;
getTextStaticnull669     function getTextStatic: Boolean; override;
670 
MapToGlobalnull671     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
672 
673     procedure Update(ARect: PRect = nil); override;
674     procedure UpdateRegion(ARgn: QRegionH); override;
675     procedure Repaint(ARect: PRect = nil); override;
676 
677     procedure Resize(ANewWidth, ANewHeight: Integer); override;
678     procedure setText(const W: WideString); override;
679     procedure setMenuBar(AMenuBar: QMenuBarH);
EventFilternull680     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
681     procedure MDIChildWindowStateChanged(AOldState: QtWindowStates; ANewState: QtWindowStates); cdecl;
IsMdiChildnull682     function IsMdiChild: Boolean;
IsModalnull683     function IsModal: Boolean;
MdiChildCountnull684     function MdiChildCount: integer;
685     procedure OffsetMousePos(APoint: PQtPoint); override;
686     procedure setAcceptDropFiles(AValue: Boolean);
687     procedure setColor(const Value: PQColor); override;
688     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
689     procedure SlotActivateWindow(vActivate: Boolean); cdecl;
690     procedure slotWindowStateChange; cdecl;
691     procedure setShowInTaskBar(AValue: Boolean);
692     procedure setRealPopupParent(NewParent: QWidgetH);
693     property Blocked: Boolean read FBlocked write FBlocked;
694     property IsFrameWindow: Boolean read FIsFrameWindow write FIsFrameWindow; {check if our LCLObject is TCustomFrame}
695     property FirstPaintEvent: boolean read FFirstPaintEvent write FFirstPaintEvent; {only for x11 - if firstpaintevent arrived we are 100% sure that frame is 100% accurate}
696     property ShowOnTaskBar: Boolean read FShowOnTaskBar;
697   public
WinIDNeedednull698     function WinIDNeeded: boolean; override;
699     procedure AttachEvents; override;
700     procedure DetachEvents; override;
CWEventFilternull701     function CWEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
702   end;
703 
704   { TQtHintWindow }
705 
706   TQtHintWindow = class(TQtMainWindow)
707   private
708     FNeedRestoreVisible: Boolean;
709   protected
CreateWidgetnull710     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
711   public
WinIDNeedednull712     function WinIDNeeded: boolean; override;
713     procedure InitializeWidget; override;
714     procedure DeInitializeWidget; override;
CanPaintBackgroundnull715     function CanPaintBackground: Boolean; override;
716     procedure SetDefaultColorRoles; override;
717     procedure setVisible(AVisible: Boolean); override;
718     property NeedRestoreVisible: Boolean read FNeedRestoreVisible write FNeedRestoreVisible;
719   end;
720 
721   { TQtStaticText }
722 
723   TQtStaticText = class(TQtFrame)
724   private
GetWordWrapnull725     function GetWordWrap: Boolean;
726     procedure SetWordWrap(AValue: Boolean);
727   protected
CreateWidgetnull728     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
729   public
CanPaintBackgroundnull730     function CanPaintBackground: Boolean; override;
getTextnull731     function getText: WideString; override;
732     procedure setText(const W: WideString); override;
733     procedure setAlignment(const AAlignment: QtAlignment);
734     property WordWrap: Boolean read GetWordWrap write SetWordWrap;
735   end;
736 
737   { TQtCheckBox }
738 
739   TQtCheckBox = class(TQtAbstractButton)
740   private
741     FStateChangedHook : QCheckBox_hookH;
742   protected
CreateWidgetnull743     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
744   public
CheckStatenull745     function CheckState: QtCheckState;
746     procedure setCheckState(state: QtCheckState);
747     procedure setTriState(AAllowGrayed: Boolean);
748   public
749     procedure AttachEvents; override;
750     procedure DetachEvents; override;
751     procedure signalStateChanged(p1: Integer); cdecl;
752   end;
753 
754   { TQtRadioButton }
755 
756   TQtRadioButton = class(TQtAbstractButton)
757   private
758     FToggledHook: QAbstractButton_hookH;
759   protected
CreateWidgetnull760     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
761   public
762     procedure AttachEvents; override;
763     procedure DetachEvents; override;
764     procedure SignalToggled(Checked: Boolean); cdecl;
EventFilternull765     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
766   end;
767 
768   { TQtGroupBox }
769 
770   TQtGroupBox = class(TQtWidget)
771   private
772     FGroupBoxType: TQtGroupBoxType;
773     FCWEventHook: QObject_hookH;
GetCheckBoxStatenull774     function GetCheckBoxState: boolean;
GetCheckBoxVisiblenull775     function GetCheckBoxVisible: boolean;
776     procedure SetCheckBoxState(AValue: boolean);
777     procedure SetCheckBoxVisible(AValue: boolean);
778     procedure setLayoutThemeMargins(ALayout: QLayoutH; AWidget: QWidgetH);
779   protected
CreateWidgetnull780     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
781   public
782     procedure AttachEvents; override;
783     procedure DetachEvents; override;
CanPaintBackgroundnull784     function CanPaintBackground: Boolean; override;
EventFilternull785     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
getClientBoundsnull786     function getClientBounds: TRect; override;
getClientOffsetnull787     function getClientOffset: TPoint; override;
getTextnull788     function getText: WideString; override;
789     procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
790       {%H-}WithThemeSpace: Boolean); override;
791     procedure setText(const W: WideString); override;
792     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
793     procedure Update(ARect: PRect = nil); override;
794     procedure UpdateRegion(ARgn: QRegionH); override;
795     procedure Repaint(ARect: PRect = nil); override;
796 
797     property GroupBoxType: TQtGroupBoxType read FGroupBoxType write FGroupBoxType;
798     property CheckBoxState: boolean read GetCheckBoxState write SetCheckBoxState;
799     property CheckBoxVisible: boolean read GetCheckBoxVisible write SetCheckBoxVisible;
800   end;
801 
802   { TQtToolBar }
803 
804   TQtToolBar = class(TQtWidget)
805   private
806   protected
CreateWidgetnull807     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
808   end;
809 
810   { TQtToolButton }
811 
812   TQtToolButton = class(TQtAbstractButton)
813   private
814   protected
CreateWidgetnull815     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
816   end;
817 
818   { TQtTrackBar }
819 
820   TQtTrackBar = class(TQtAbstractSlider)
821   protected
CreateWidgetnull822     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
823   public
getTickIntervalnull824     function getTickInterval: Integer;
825     procedure setTickPosition(Value: QSliderTickPosition);
826     procedure setTickInterval(Value: Integer);
827   public
828     procedure AttachEvents; override;
829 
830     procedure SlotSliderMoved(p1: Integer); cdecl; override;
831     procedure SlotValueChanged(p1: Integer); cdecl; override;
832   end;
833 
834   { TQtLineEdit }
835 
836   TQtLineEdit = class(TQtWidget, IQtEdit)
837   private
838     FCachedSelectionLen: integer;
839     FCachedSelectionStart: integer;
840     FNumbersOnly: boolean;
841     FIntValidator: QIntValidatorH;
842     FTextChanged: QLineEdit_hookH;
getTextMarginsnull843     function getTextMargins: TRect;
844     procedure SetNumbersOnly(AValue: boolean);
845     procedure setTextMargins(ARect: TRect);
846   protected
CreateWidgetnull847     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
848   public
getAlignmentnull849     function getAlignment: QtAlignment;
getCursorPositionnull850     function getCursorPosition: TPoint;
getMaxLengthnull851     function getMaxLength: Integer;
getSelectedTextnull852     function getSelectedText: WideString;
getSelectionStartnull853     function getSelectionStart: Integer;
getSelectionLengthnull854     function getSelectionLength: Integer;
getTextnull855     function getText: WideString; override;
getTextStaticnull856     function getTextStatic: Boolean; override;
isUndoAvailablenull857     function isUndoAvailable: Boolean;
hasSelectedTextnull858     function hasSelectedText: Boolean;
859     procedure selectAll;
860     procedure setAlignment(const AAlignment: QtAlignment);
861     procedure setBorder(const ABorder: Boolean);
862     procedure setCursorPosition(const ACursorPosition: Integer);
863     procedure setDefaultColorRoles; override;
864     procedure setEchoMode(const AMode: QLineEditEchoMode);
865     procedure setInputMask(const AMask: WideString);
866     procedure setMaxLength(const ALength: Integer);
867     procedure setReadOnly(const AReadOnly: Boolean);
868     procedure setSelection(const AStart, ALength: Integer);
869     procedure setText(const AText: WideString); override;
870     procedure Cut;
871     procedure Copy;
872     procedure Paste;
873     procedure Undo;
874   public
875     destructor Destroy; override;
876     procedure AttachEvents; override;
877     procedure DetachEvents; override;
EventFilternull878     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
879     procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
880       {%H-}WithThemeSpace: Boolean); override;
881     procedure SignalTextChanged(p1: PWideString); cdecl;
882     property CachedSelectionStart: integer read FCachedSelectionStart write FCachedSelectionStart;
883     property CachedSelectionLen: integer read FCachedSelectionLen write FCachedSelectionLen;
884     property NumbersOnly: boolean read FNumbersOnly write SetNumbersOnly;
885     property TextMargins: TRect read GetTextMargins write SetTextMargins;
886   end;
887 
888   { TQtTextEdit }
889 
890   TQtTextEdit = class(TQtAbstractScrollArea, IQtEdit)
891   private
892     FViewportEventHook: QObject_hookH;
893     FUndoAvailableHook: QTextEdit_hookH;
894     FTextChangedHook: QTextEdit_hookH;
895     FUndoAvailable: Boolean;
GetAcceptRichTextnull896     function GetAcceptRichText: Boolean;
897     procedure SetAcceptRichText(AValue: Boolean);
898   protected
CreateWidgetnull899     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
900   public
901     FList: TStrings;
902     procedure Append(const AStr: WideString);
903     procedure ClearText;
getAlignmentnull904     function getAlignment: QtAlignment;
getBlockCountnull905     function getBlockCount: Integer;
getCursorPositionnull906     function getCursorPosition: TPoint;
getMaxLengthnull907     function getMaxLength: Integer;
getTextnull908     function getText: WideString; override;
getTextStaticnull909     function getTextStatic: Boolean; override;
getSelectionStartnull910     function getSelectionStart: Integer;
getSelectionEndnull911     function getSelectionEnd: Integer;
getSelectionLengthnull912     function getSelectionLength: Integer;
913     procedure appendLine(AText: WideString);
914     procedure insertLine(const AIndex: integer; AText: WideString);
isUndoAvailablenull915     function isUndoAvailable: Boolean;
916     procedure removeLine(const AIndex: integer);
917     procedure setAlignment(const AAlignment: QtAlignment);
918     procedure setBorder(const ABorder: Boolean);
919     procedure setCursorPosition(const ACursorPosition: Integer);
920     procedure setDefaultColorRoles; override;
921     procedure setEchoMode(const AMode: QLineEditEchoMode);
922     procedure setLineWrapMode(const AMode: QTextEditLineWrapMode);
923     procedure setMaxLength(const ALength: Integer);
924     procedure setLineText(const AIndex: integer; AText: WideString);
925     procedure setText(const AText: WideString); override;
926     procedure setReadOnly(const AReadOnly: Boolean);
927     procedure setSelection(const AStart, ALength: Integer);
928     procedure setTabChangesFocus(const AValue: Boolean);
929     procedure Cut;
930     procedure Copy;
931     procedure Paste;
932     procedure Undo;
933   public
934     procedure AttachEvents; override;
935     procedure DetachEvents; override;
viewportEventFilternull936     function viewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
getContextMenuPolicynull937     function getContextMenuPolicy: QtContextMenuPolicy; override;
938     procedure setContextMenuPolicy(const AValue: QtContextMenuPolicy); override;
939     procedure SignalUndoAvailable(b: Boolean); cdecl;
940     procedure SignalTextChanged(); cdecl;
941     property AcceptRichText: Boolean read GetAcceptRichText write SetAcceptRichText;
942   end;
943 
944   { TQtTabBar }
945   TQtTabBar = class(TQtWidget)
946   private
947     FSavedIndexOnPageChanging: Integer; // used to handle OnPageChanging AllowChange param
948     FTabBarChangedHook: QTabBar_hookH;
949     FTabBarMovedHook: QTabBar_hookH;
950   public
951     procedure AttachEvents; override;
952     procedure DetachEvents; override;
GetTabRectnull953     function GetTabRect(const AIndex: integer): TRect;
954     // under some themes tabs doesn't start at 0,0 (eg. MacOSX)
955     function TabBarOffset: TPoint;
956     procedure SignalTabBarMoved(fromIndex: integer; toIndex: Integer); cdecl;
957     procedure SignalTabBarCurrentChanged(Index: Integer); cdecl;
958     function SlotTabBarMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
959     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
960     procedure SetTabFontColor(AIndex: Integer; AColor: TQColor);
961   end;
962 
963   { TQtTabWidget }
964 
965   TQtTabWidget = class(TQtWidget)
966   private
967     FCurrentChangedHook: QTabWidget_hookH;
968     FCloseRequestedHook: QTabWidget_hookH;
969     FStackedWidgetHook: QObject_hookH;
970     FSwitchTabsByKeyboard: boolean;
971     FTabBar: TQtTabBar;
972     FStackWidget: QWidgetH;
973     function getShowTabs: Boolean;
974     function getStackWidget: QWidgetH;
975     function getTabBar: TQtTabBar;
976     procedure setShowTabs(const AValue: Boolean);
977   protected
978     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
979   public
980     destructor Destroy; override;
981     procedure DestroyNotify(AWidget: TQtWidget); override;
982     procedure AttachEvents; override;
983     procedure DetachEvents; override;
984 
985     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
986     procedure SignalCurrentChanged(Index: Integer); cdecl;
987     procedure SignalCloseRequested(Index: Integer); cdecl;
988   public
989     function indexOf(const AWidget: QWidgetH): integer;
990     function insertTab(index: Integer; page: QWidgetH; p2: WideString): Integer; overload;
991     function insertTab(index: Integer; page: QWidgetH; icon: QIconH; p2: WideString): Integer; overload;
992     function getCount: Integer;
993     function getClientBounds: TRect; override;
994     function getCurrentIndex: Integer;
995     function GetLCLPageIndex(AIndex: Integer): Integer;
996     function getTabPosition: QTabWidgetTabPosition;
997     procedure removeTab(AIndex: Integer);
998     procedure setCurrentIndex(AIndex: Integer);
999     procedure setCurrentWidget(APage: TQtWidget; const AIsMoved: Boolean);
1000     procedure setTabPosition(ATabPosition: QTabWidgetTabPosition);
1001     procedure setTabIcon(index: Integer; icon: QIconH);
1002     procedure setTabText(index: Integer; p2: WideString);
1003     procedure setTabsClosable(AValue: Boolean);
1004     function tabAt(APoint: TPoint): Integer;
1005 
1006     property ShowTabs: Boolean read getShowTabs write setShowTabs;
1007     property TabBar: TQtTabBar read getTabBar;
1008     property StackWidget: QWidgetH read getStackWidget;
1009     property SwitchTabsByKeyboard: boolean read FSwitchTabsByKeyboard write FSwitchTabsByKeyboard;
1010   end;
1011 
1012   { TQtComboBox }
1013 
1014   TQtComboBox = class(TQtWidget, IQtEdit)
1015   private
1016     FKeyEnterFix: boolean; {issue #31574}
1017     FMouseFixPos: TQtPoint;
1018     // hooks
1019     FChangeHook: QComboBox_hookH;
1020     FActivateHook: QComboBox_hookH;
1021     FOwnerDrawn: Boolean;
1022     FSelectHook: QComboBox_hookH;
1023     FDropListEventHook: QObject_hookH;
1024     // parts
1025     FLineEdit: TQtLineEdit;
1026     FDropList: TQtListWidget;
1027     FDropListVisibleInternal: Boolean;
1028     function GetDropList: TQtListWidget;
1029     function GetLineEdit: TQtLineEdit;
1030     procedure InternalIntfGetItems; // calls TCustomComboBox(LCLObject).IntfGetItems
1031     procedure SetOwnerDrawn(const AValue: Boolean);
1032     procedure slotPaintCombo(Sender: QObjectH; Event: QEventH); cdecl;
1033   protected
1034     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1035     // IQtEdit implementation
1036     function getCursorPosition: TPoint;
1037     function getMaxLength: Integer;
1038     function getSelectionStart: Integer;
1039     function getSelectionLength: Integer;
1040     function isUndoAvailable: Boolean;
1041     procedure setEchoMode(const AMode: QLineEditEchoMode);
1042     procedure setMaxLength(const ALength: Integer);
1043     procedure setReadOnly(const AReadOnly: Boolean);
1044     procedure setSelection(const AStart, ALength: Integer);
1045     procedure setCursorPosition(const ACursorPosition: Integer);
1046     procedure Cut;
1047     procedure Copy;
1048     procedure Paste;
1049     procedure Undo;
1050   public
1051     FList: TStrings;
1052     destructor Destroy; override;
1053     procedure DestroyNotify(AWidget: TQtWidget); override;
1054     procedure ClearItems;
1055     procedure setBorder(const ABorder: Boolean);
1056     function currentIndex: Integer;
1057     function findText(AText: WideString): Integer;
1058     function getDroppedDown: Boolean;
1059     function getEditable: Boolean;
1060     function getItemText(AIndex: Integer): WideString;
1061     function getMaxVisibleItems: Integer;
1062     function getText: WideString; override;
1063     function getTextStatic: Boolean; override;
1064     procedure insertItem(AIndex: Integer; AText: String); overload;
1065     procedure insertItem(AIndex: Integer; AText: PWideString); overload;
1066     procedure setCurrentIndex(index: Integer);
1067     procedure setDefaultColorRoles; override;
1068     procedure setDroppedDown(const ADroppedDown: Boolean);
1069     procedure setMaxVisibleItems(ACount: Integer);
1070     procedure setEditable(const AValue: Boolean);
1071     procedure setItemText(AIndex: Integer; AText: String);
1072     procedure setText(const W: WideString); override;
1073     procedure removeItem(AIndex: Integer);
1074 
1075     property DropList: TQtListWidget read GetDropList;
1076     property LineEdit: TQtLineEdit read GetLineEdit;
1077     property OwnerDrawn: Boolean read FOwnerDrawn write SetOwnerDrawn;
1078   public
1079     procedure AttachEvents; override;
1080     procedure DetachEvents; override;
1081     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1082     procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
1083       {%H-}WithThemeSpace: Boolean); override;
1084 
1085     procedure SlotActivate(index: Integer); cdecl;
1086     procedure SlotChange(p1: PWideString); cdecl;
1087     procedure SlotSelect(index: Integer); cdecl;
1088     procedure SlotDropListVisibility(AVisible: Boolean); cdecl;
1089     procedure FixMouseUp; // qt eats MouseRelease event when popup is shown, so we'll fix it
1090   end;
1091 
1092   { TQtAbstractSpinBox}
1093 
1094   TQtAbstractSpinBox = class(TQtWidget, IQtEdit)
1095   private
1096     {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
1097     FParentShowPassed: PtrInt;
1098     {$ENDIF}
1099     FEditingFinishedHook: QAbstractSpinBox_hookH;
1100     FLineEditHook: QObject_hookH;
1101     FTextChangedHook: QLineEdit_hookH;
1102     // parts
1103     FLineEdit: QLineEditH;
1104     FTextChangedByValueChanged: Boolean;
GetLineEditnull1105     function GetLineEdit: QLineEditH;
LineEditEventFilternull1106     function LineEditEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
1107   protected
CreateWidgetnull1108     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1109     // IQtEdit implementation
getCursorPositionnull1110     function getCursorPosition: TPoint;
getMaxLengthnull1111     function getMaxLength: Integer;
getSelectionStartnull1112     function getSelectionStart: Integer;
getSelectionLengthnull1113     function getSelectionLength: Integer;
isUndoAvailablenull1114     function isUndoAvailable: Boolean;
1115     procedure setEchoMode(const AMode: QLineEditEchoMode);
1116     procedure setMaxLength(const ALength: Integer);
1117     procedure setSelection(const AStart, ALength: Integer);
1118     procedure setCursorPosition(const ACursorPosition: Integer);
1119     procedure SignalLineEditTextChanged(AnonParam1: PWideString); virtual; cdecl;
1120     procedure Cut;
1121     procedure Copy;
1122     procedure Paste;
1123     procedure Undo;
1124     property TextChangedByValueChanged: Boolean read FTextChangedByValueChanged write FTextChangedByValueChanged;
1125   public
getValuenull1126     function getValue: Double; virtual; abstract;
getReadOnlynull1127     function getReadOnly: Boolean;
getTextnull1128     function getText: WideString; override;
getTextStaticnull1129     function getTextStatic: Boolean; override;
1130     procedure setAlignment(const AAlignment: QtAlignment);
1131     procedure setBorder(const ABorder: Boolean);
1132     procedure setDefaultColorRoles; override;
1133     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
1134     procedure setMinimum(const v: Double); virtual; abstract;
1135     procedure setMaximum(const v: Double); virtual; abstract;
1136     procedure setSingleStep(const v: Double); virtual; abstract;
1137     procedure setReadOnly(const r: Boolean);
1138     procedure setValue(const v: Double); virtual; abstract;
1139     procedure setText(const W: WideString); override;
1140 
1141     property LineEdit: QLineEditH read GetLineEdit;
1142   public
1143     procedure AttachEvents; override;
1144     procedure DetachEvents; override;
EventFilternull1145     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1146 
1147     procedure SignalEditingFinished; cdecl;
1148   end;
1149 
1150   { TQtFloatSpinBox }
1151 
1152   TQtFloatSpinBox = class(TQtAbstractSpinBox)
1153   private
1154     FValue: Double;
1155     FValueChangedHook: QDoubleSpinBox_hookH;
1156   protected
CreateWidgetnull1157     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1158   public
getValuenull1159     function getValue: Double; override;
1160     procedure setDecimals(const v: integer);
1161     procedure setMinimum(const v: Double); override;
1162     procedure setMaximum(const v: Double); override;
1163     procedure setSingleStep(const v: Double); override;
1164     procedure setValue(const v: Double); override;
1165   public
1166     procedure AttachEvents; override;
1167     procedure DetachEvents; override;
1168     procedure SignalValueChanged(p1: Double); cdecl;
1169   end;
1170 
1171   { TQtSpinBox }
1172 
1173   TQtSpinBox = class(TQtAbstractSpinBox)
1174   private
1175     FValue: Integer;
1176     FValueChangedHook: QSpinBox_hookH;
1177   protected
CreateWidgetnull1178     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1179   public
getValuenull1180     function getValue: Double; override;
1181     procedure setMinimum(const v: Double); override;
1182     procedure setMaximum(const v: Double); override;
1183     procedure setSingleStep(const v: Double); override;
1184     procedure setValue(const v: Double); override;
1185   public
1186     procedure AttachEvents; override;
1187     procedure DetachEvents; override;
1188 
1189     procedure SignalValueChanged(p1: Integer); cdecl;
1190   end;
1191 
1192   { TQtAbstractItemView }
1193 
1194   TQtAbstractItemView = class(TQtAbstractScrollArea)
1195   private
1196     FAllowGrayed: boolean;
1197     FSavedEvent: QMouseEventH;
1198     FSavedEventTimer: QTimerH;
1199     FSavedEventTimerHook: QTimer_hookH;
1200     FCheckable: boolean;
1201     FHideSelection: Boolean;
1202     FOldDelegate: QAbstractItemDelegateH;
1203     FNewDelegate: QLCLItemDelegateH;
1204     FOwnerData: Boolean;
1205     FSignalActivated: QAbstractItemView_hookH;
1206     FSignalClicked: QAbstractItemView_hookH;
1207     FSignalDoubleClicked: QAbstractItemView_hookH;
1208     FSignalEntered: QAbstractItemView_hookH;
1209     FSignalPressed: QAbstractItemView_hookH;
1210     FSignalViewportEntered: QAbstractItemView_hookH;
1211     FAbstractItemViewportEventHook: QObject_hookH;
1212     FSyncingItems: Boolean;
1213     FViewStyle: Integer;
getIconSizenull1214     function getIconSize: TSize;
GetOwnerDrawnnull1215     function GetOwnerDrawn: Boolean;
1216     procedure setIconSize(const AValue: TSize);
1217     procedure SetOwnerDrawn(const AValue: Boolean);
1218   protected
GetItemFlagsnull1219     function GetItemFlags(AIndex: Integer): QtItemFlags; virtual;
1220     procedure SetItemFlags(AIndex: Integer; AValue: QtItemFlags); virtual;
1221     procedure OwnerDataNeeded(ARect: TRect); virtual;
1222     procedure PostponedMouseRelease(AEvent: QEventH); virtual;
1223     procedure PostponedMouseReleaseTimerEvent(); cdecl; virtual;
1224   public
1225     constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); override;
1226     destructor Destroy; override;
1227     procedure signalActivated(index: QModelIndexH); cdecl; virtual;
1228     procedure signalClicked(index: QModelIndexH); cdecl; virtual;
1229     procedure signalDoubleClicked(index: QModelIndexH); cdecl; virtual;
1230     procedure signalEntered(index: QModelIndexH); cdecl; virtual;
1231     procedure signalPressed(index: QModelIndexH); cdecl; virtual;
1232     procedure signalViewportEntered; cdecl; virtual;
1233     procedure AttachEvents; override;
1234     procedure DetachEvents; override;
1235 
itemViewViewportEventFilternull1236     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; virtual;
1237     procedure setDefaultColorRoles; override;
1238   public
1239     procedure clearSelection; virtual;
getModelnull1240     function getModel: QAbstractItemModelH;
getRowHeightnull1241     function getRowHeight(ARowIndex: integer): integer;
getSelectionModenull1242     function getSelectionMode: QAbstractItemViewSelectionMode;
getTopItemnull1243     function getTopItem: integer; virtual;
getVisibleRowCountnull1244     function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; virtual;
1245 
1246     procedure modelIndex(retval: QModelIndexH; row, column: Integer; parent: QModelIndexH = nil);
visualRectnull1247     function visualRect(Index: QModelIndexH): TRect;
1248     procedure setEditTriggers(ATriggers: QAbstractItemViewEditTriggers);
1249     procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); virtual;
1250     procedure setSelectionBehavior(ABehavior: QAbstractItemViewSelectionBehavior);
1251     procedure setWordWrap(const AValue: Boolean); virtual;
1252     property AllowGrayed: boolean read FAllowGrayed write FAllowGrayed;
1253     property Checkable: boolean read FCheckable write FCheckable;
1254     property HideSelection: Boolean read FHideSelection write FHideSelection;
1255     property IconSize: TSize read getIconSize write setIconSize;
1256     property ItemFlags[AIndex: Integer]: QtItemFlags read GetItemFlags write SetItemFlags;
1257     property OwnerDrawn: Boolean read GetOwnerDrawn write SetOwnerDrawn;
1258     property OwnerData: Boolean read FOwnerData write FOwnerData;
1259     property SyncingItems: Boolean read FSyncingItems write FSyncingItems;
1260     property ViewStyle: Integer read FViewStyle write FViewStyle;
1261   public
1262     procedure ItemDelegateSizeHint(option: QStyleOptionViewItemH; index: QModelIndexH; Size: PSize); cdecl; virtual;
1263     procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; virtual;
1264   end;
1265 
1266   { TQtListView }
1267 
1268   TQtListView = class(TQtAbstractItemView)
1269   private
getBatchSizenull1270     function getBatchSize: integer;
getGridSizenull1271     function getGridSize: TSize;
getSpacingnull1272     function getSpacing: Integer;
1273     procedure setBatchSize(const AValue: integer);
1274     procedure setSpacing(const AValue: integer);
1275     procedure setGridSize(const AValue: TSize);
1276   public
1277     procedure setLayoutMode(const ALayoutMode: QListViewLayoutMode);
1278     procedure setMovement(const AMovement: QListViewMovement);
1279     procedure setResizeMode(const AResizeMode: QListViewResizeMode);
1280     procedure setUniformItemSizes(const AEnable: Boolean);
1281     procedure setViewFlow(const AFlow: QListViewFlow);
1282     procedure setViewMode(const AMode: QListViewViewMode);
1283     procedure setWordWrap(const AValue: Boolean); override;
1284     procedure setWrapping(const AWrapping: Boolean);
1285     procedure LayoutItems;
1286     property BatchSize: integer read getBatchSize write setBatchSize;
1287     property GridSize: TSize read getGridSize write setGridSize;
1288     property Spacing: Integer read getSpacing write setSpacing;
1289   end;
1290 
1291   { TQtListWidget }
1292 
1293   TQtListWidget = class(TQtListView)
1294   private
1295     FCheckBoxClicked: Boolean;
1296     FSavedSelection: TPtrIntArray;
1297     FCurrentItemChangedHook: QListWidget_hookH;
1298     FSelectionChangeHook: QListWidget_hookH;
1299     FItemClickedHook: QListWidget_hookH;
1300     FItemTextChangedHook: QListWidget_hookH;
1301     FDelayedCheckItem: QListWidgetItemH;
1302     FDontPassSelChange: Boolean;
1303     procedure HandleCheckChangedEvent(const AMousePos: TQtPoint;
1304         AItem: QListWidgetItemH; AEvent: QEventH);
GetItemCheckednull1305     function GetItemChecked(AIndex: Integer): Boolean;
getItemCountnull1306     function getItemCount: Integer;
GetItemEnablednull1307     function GetItemEnabled(AIndex: Integer): Boolean;
GetSelectednull1308     function GetSelected(AIndex: Integer): Boolean;
1309     procedure SetItemChecked(AIndex: Integer; AValue: Boolean);
1310     procedure setItemCount(const AValue: Integer);
1311     procedure SetItemEnabled(AIndex: Integer; AValue: Boolean);
1312     procedure SetSelected(AIndex: Integer; AValue: Boolean);
1313   protected
CreateWidgetnull1314     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1315     procedure OwnerDataNeeded(ARect: TRect); override;
GetItemFlagsnull1316     function GetItemFlags(AIndex: Integer): QtItemFlags; override;
1317     procedure SetItemFlags(AIndex: Integer; AValue: QtItemFlags); override;
1318     procedure SetItemLastCheckState(AItem: QListWidgetItemH);
1319     procedure SetItemLastCheckStateInternal(AItem: QListWidgetItemH; AState: QtCheckState);
1320     procedure SetNextStateMap(AItem: QListWidgetItemH); virtual;
1321   public
1322     FList: TStrings;
1323   public
1324     procedure AttachEvents; override;
1325     procedure DetachEvents; override;
1326     procedure InitializeWidget; override;
EventFilternull1327     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1328     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1329 
1330     procedure signalCurrentItemChanged(current: QListWidgetItemH; previous: QListWidgetItemH); cdecl; virtual;
1331     procedure signalItemTextChanged(ANewText: PWideString); cdecl; virtual;
1332     procedure signalItemClicked(item: QListWidgetItemH); cdecl; virtual;
1333     procedure signalSelectionChanged(); cdecl; virtual;
1334     procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; override;
1335   public
1336     procedure clearSelection; override;
1337     procedure ClearItems;
currentRownull1338     function currentRow: Integer;
currentItemnull1339     function currentItem: QListWidgetItemH;
GetItemLastCheckStatenull1340     function GetItemLastCheckState(AItem: QListWidgetItemH): QtCheckState;
IndexAtnull1341     function IndexAt(APoint: PQtPoint): Integer;
1342     procedure insertItem(AIndex: Integer; AText: String); overload;
1343     procedure insertItem(AIndex: Integer; AText: PWideString); overload;
itemAtnull1344     function itemAt(APoint: TPoint): QListWidgetItemH; overload;
itemAtnull1345     function itemAt(x: Integer; y: Integer): QListWidgetItemH; overload;
getItemnull1346     function getItem(AIndex: Integer): QListWidgetItemH;
getItemSelectednull1347     function getItemSelected(AItem: QListWidgetItemH): Boolean;
getItemVisiblenull1348     function getItemVisible(AItem: QListWidgetItemH): Boolean;
getRownull1349     function getRow(AItem: QListWidgetItemH): integer;
getSelCountnull1350     function getSelCount: Integer;
getTopItemnull1351     function getTopItem: integer; override;
getVisibleRowCountnull1352     function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; override;
getVisualItemRectnull1353     function getVisualItemRect(AItem: QListWidgetItemH): TRect;
selectedItemsnull1354     function selectedItems: TPtrIntArray;
1355     procedure setCurrentRow(row: Integer);
1356     procedure setCurrentItem(AItem: QListWidgetItemH; const AIsSet: Boolean = True);
1357     procedure setItemText(AIndex: Integer; AText: String); overload;
1358     procedure setItemText(AIndex: Integer; AText: String; AAlignment: Integer); overload;
1359     procedure setItemSelected(AItem: QListWidgetItemH; const ASelect: Boolean);
1360     procedure setItemVisible(AItem: QListWidgetItemH; const AVisible: Boolean);
1361     procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); override;
1362     procedure scrollToItem(row: integer; hint: QAbstractItemViewScrollHint);
1363     procedure removeItem(AIndex: Integer);
rowCountnull1364     function rowCount: integer;
1365     procedure ExchangeItems(const AIndex1, AIndex2: Integer);
1366     procedure MoveItem(const AFromIndex, AToIndex: Integer);
1367     property ItemCount: Integer read getItemCount write setItemCount;
1368     property ItemChecked[AIndex: Integer]: Boolean read GetItemChecked write SetItemChecked;
1369     property Enabled[AIndex: Integer]: Boolean read GetItemEnabled write SetItemEnabled;
1370     property Selected[AIndex: Integer]: Boolean read GetSelected write SetSelected;
1371   end;
1372 
1373   { TQtCheckListBox }
1374 
1375   TQtCheckListBox = class (TQtListWidget)
1376   private
1377     FItemChangedHook: QListWidget_hookH;
GetItemCheckStatenull1378     function GetItemCheckState(AIndex: Integer): QtCheckState;
1379     procedure SetItemCheckState(AIndex: Integer; AValue: QtCheckState);
1380   protected
CreateWidgetnull1381     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1382     procedure SetNextStateMap(AItem: QListWidgetItemH); override;
1383   public
1384     procedure AttachEvents; override;
1385     procedure DetachEvents; override;
1386 
EventFilternull1387     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1388     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1389 
1390     procedure signalCurrentItemChanged(current: QListWidgetItemH; previous: QListWidgetItemH); cdecl; override;
1391     procedure signalItemClicked(item: QListWidgetItemH); cdecl; override;
1392     procedure signalSelectionChanged(); cdecl; override;
1393     procedure signalItemChanged(item: QListWidgetItemH); cdecl;
1394     property ItemCheckState[AIndex: Integer]: QtCheckState read GetItemCheckState write SetItemCheckState;
1395   end;
1396 
1397   { TQtHeaderView }
1398 
1399   TQtHeaderView = class (TQtAbstractItemView)
1400   private
1401     FSectionClicked: QHeaderView_hookH;
getClickablenull1402     function getClickable: Boolean;
getMinSectionSizenull1403     function getMinSectionSize: Integer;
1404     procedure setClickable(const AValue: Boolean);
1405     procedure setMinSectionSize(const AValue: Integer);
1406   protected
CreateWidgetnull1407     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1408   public
1409     procedure AttachEvents; override;
1410     procedure DetachEvents; override;
EventFilternull1411     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1412     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1413     procedure SignalSectionClicked(logicalIndex: Integer); cdecl;
getResizeModenull1414     function getResizeMode(AIndex: Integer): QHeaderViewResizeMode;
1415     procedure setResizeMode(AResizeMode: QHeaderViewResizeMode); overload;
1416     procedure setResizeMode(AIndex: Integer; AResizeMode: QHeaderViewResizeMode); overload;
sectionSizenull1417     function sectionSize(AIndex: Integer): Integer;
sectionSizeHintnull1418     function sectionSizeHint(AIndex: Integer): Integer;
1419     procedure moveSection(AFromIndex: Integer; AToIndex: Integer);
1420     procedure resizeSection(ASection: Integer; ASize: Integer);
1421     procedure setHighlightSections(AValue: Boolean);
1422     procedure setDefaultSectionSize(AValue: Integer);
SortIndicatorOrdernull1423     function SortIndicatorOrder: QtSortOrder;
1424     procedure SetSortIndicator(const AColumn: Integer; const AOrder: QtSortOrder);
1425     procedure SetSortIndicatorVisible(AVisible: Boolean);
1426     procedure setStretchLastSection(AValue: Boolean);
1427     property Clickable: Boolean read getClickable write setClickable;
1428     property MinSectionSize: Integer read getMinSectionSize write setMinSectionSize;
1429   end;
1430 
1431   { TQtTreeView }
1432 
1433   TQtTreeView = class (TQtAbstractItemView)
1434   private
getColVisiblenull1435     function getColVisible(AIndex: Integer): Boolean;
getColWidthnull1436     function getColWidth(AIndex: Integer): Integer;
GetUniformRowHeightsnull1437     function GetUniformRowHeights: Boolean;
1438     procedure setColVisible(AIndex: Integer; const AValue: Boolean);
1439     procedure setColWidth(AIndex: Integer; const AValue: Integer);
1440     procedure SetUniformRowHeights(const AValue: Boolean);
1441   protected
CreateWidgetnull1442     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1443   public
1444     procedure setAllColumnsShowFocus(AValue: Boolean);
1445     procedure setWordWrap(const AValue: Boolean); override;
1446     procedure setRootIsDecorated(AValue: Boolean);
1447     property ColWidth[AIndex: Integer]: Integer read getColWidth write setColWidth;
1448     property ColVisible[AIndex: Integer]: Boolean read getColVisible write setColVisible;
1449     property UniformRowHeights: Boolean read GetUniformRowHeights write SetUniformRowHeights;
1450   end;
1451 
1452   { TQtTreeWidget }
1453 
1454   TQtTreeWidget = class(TQtTreeView)
1455   private
1456     FSelection: TFPList;
1457     FHeader: TQtHeaderView;
1458     {$IFDEF TEST_QT_SORTING}
1459     FCanSort: Boolean; // it can sort items only when LCL says so !
1460     FSorting: Boolean;
1461     FSortChanged: QHeaderView_hookH;
1462     {$ENDIF}
1463     FItemActivatedHook: QTreeWidget_hookH;
1464     FItemEnteredHook: QTreeWidget_hookH;
1465     FSelectionChangedHook: QTreeWidget_hookH;
1466     FDelayedCheckItem: QTreeWidgetItemH;
1467 
1468     procedure HandleCheckChangedEvent(const AMousePos: TQtPoint;
1469         AItem: QTreeWidgetItemH; AEvent: QEventH);
1470 
GetItemLastCheckStateInternalnull1471     function GetItemLastCheckStateInternal(AItem: QTreeWidgetItemH): QtCheckState;
1472     procedure SetItemLastCheckStateInternal(AItem: QTreeWidgetItemH; AState: QtCheckState);
1473 
getColCountnull1474     function getColCount: Integer;
getHeadernull1475     function getHeader: TQtHeaderView;
GetItemCheckednull1476     function GetItemChecked(AIndex: Integer): Boolean;
getItemCountnull1477     function getItemCount: Integer;
getMaxColSizenull1478     function getMaxColSize(ACol: Integer): Integer;
getMinColSizenull1479     function getMinColSize(ACol: Integer): Integer;
getSortEnablednull1480     function getSortEnabled: Boolean;
1481     procedure setColCount(const AValue: Integer);
1482     procedure SetItemChecked(AIndex: Integer; AValue: Boolean);
1483     procedure setItemCount(const AValue: Integer);
1484     procedure setMaxColSize(ACol: Integer; const AValue: Integer);
1485     procedure setMinColSize(ACol: Integer; const AValue: Integer);
1486     procedure setSortEnabled(const AValue: Boolean);
1487   protected
CreateWidgetnull1488     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1489     procedure OwnerDataNeeded(ARect: TRect); override;
1490   public
1491     destructor Destroy; override;
1492     procedure DestroyNotify(AWidget: TQtWidget); override;
EventFilternull1493     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1494     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1495     procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; override;
1496     procedure ClearItems;
1497     procedure clearSelection; override;
1498     procedure DeleteItem(const AIndex: integer);
currentRownull1499     function currentRow: Integer;
1500     procedure setCurrentRow(row: Integer);
currentItemnull1501     function currentItem: QTreeWidgetItemH;
1502     procedure setCurrentItem(AItem: QTreeWidgetItemH);
1503 
getRownull1504     function getRow(AItem: QTreeWidgetItemH): integer;
headerItemnull1505     function headerItem: QTreeWidgetItemH;
itemAtnull1506     function itemAt(APoint: TPoint): QTreeWidgetItemH; overload;
itemAtnull1507     function itemAt(x: Integer; y: Integer): QTreeWidgetItemH; overload;
1508     procedure insertTopLevelItem(AIndex: Integer; AItem: QTreeWidgetItemH);
takeTopLevelItemnull1509     function takeTopLevelItem(AIndex: Integer): QTreeWidgetItemH;
topLevelItemnull1510     function topLevelItem(AIndex: Integer): QTreeWidgetItemH;
visualItemRectnull1511     function visualItemRect(AItem: QTreeWidgetItemH): TRect;
getHeaderHeightnull1512     function getHeaderHeight(out AOrientation: QtOrientation): Integer;
getItemVisiblenull1513     function getItemVisible(AItem: QTreeWidgetItemH): Boolean;
getTopItemnull1514     function getTopItem: integer; override;
getVisibleRowCountnull1515     function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; override;
1516     procedure setItemVisible(AItem: QTreeWidgetItemH; Const AVisible: Boolean);
1517     procedure setItemText(AItem: QTreeWidgetItemH; const AColumn: Integer;
1518       const AText: WideString; const AAlignment: QtAlignment);
1519     procedure setItemData(AItem: QTreeWidgetItemH; const AColumn: Integer;
1520        Data: Pointer; const ARole: Integer = Ord(QtUserRole));
selCountnull1521     function selCount: Integer;
selectedItemsnull1522     function selectedItems: TPtrIntArray;
1523     procedure setHeaderVisible(AVisible: Boolean);
1524     procedure setItemSelected(AItem: QTreeWidgetItemH; ASelect: Boolean);
1525     procedure setStretchLastSection(AValue: Boolean);
1526     procedure scrollToItem(Item: QTreeWidgetItemH; hint: QAbstractItemViewScrollHint);
1527     {$IFDEF TEST_QT_SORTING}
1528     // direct Qt sorting via QtUserData ptr = our TListItem, crashes sometimes - qt bug.
1529     procedure sortItems(Acolumn: Integer; AOrder: QtSortOrder);
1530     {$ENDIF}
1531   public
1532     procedure AttachEvents; override;
1533     procedure DetachEvents; override;
1534     procedure ExchangeItems(const AIndex1, AIndex2: Integer);
1535     procedure MoveItem(const AFromIndex, AToIndex: Integer);
getClientBoundsnull1536     function getClientBounds: TRect; override;
getClientOffsetnull1537     function getClientOffset: TPoint; override;
1538 
1539     procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); override;
1540     procedure SignalItemActivated(item: QTreeWidgetItemH; column: Integer); cdecl;
1541     procedure SignalItemEntered(item: QTreeWidgetItemH; column: Integer); cdecl;
1542     procedure SignalCurrentItemChanged(current: QTreeWidgetItemH; previous: QTreeWidgetItemH); cdecl;
1543     procedure SignalSelectionChanged(); cdecl;
1544     {$IFDEF TEST_QT_SORTING}
1545     procedure SignalSortIndicatorChanged(ALogicalIndex: Integer; AOrder: QtSortOrder); cdecl;
1546     property CanSort: Boolean read FCanSort write FCanSort;
1547     {$ENDIF}
1548     property ColCount: Integer read getColCount write setColCount;
1549     property Header: TQtHeaderView read getHeader;
1550     property ItemChecked[AIndex: Integer]: Boolean read GetItemChecked write SetItemChecked;
1551     property ItemCount: Integer read getItemCount write setItemCount;
1552     property MaxColSize[ACol: Integer]: Integer read getMaxColSize write setMaxColSize;
1553     property MinColSize[ACol: Integer]: Integer read getMinColSize write setMinColSize;
1554     property SortEnabled: Boolean read getSortEnabled write setSortEnabled;
1555     {$IFDEF TEST_QT_SORTING}
1556     property Sorting: Boolean read FSorting write FSorting;
1557     {$ENDIF}
1558   end;
1559 
1560   {TQtTableView}
1561 
1562   TQtTableView = class(TQtAbstractItemView)
1563   private
1564     FVerticalHeader: TQtHeaderView;
1565     FHorizontalHeader: TQtHeaderView;
1566   public
verticalHeadernull1567     function verticalHeader: TQtHeaderView;
horizontalHeadernull1568     function horizontalHeader: TQtHeaderView;
CreateWidgetnull1569     function CreateWidget(const Params: TCreateParams): QWidgetH; override;
getViewPortnull1570     function getViewPort: QWidgetH;
getClientBoundsnull1571     function getClientBounds: TRect; override;
1572     procedure grabMouse; override;
1573     procedure setVisible(AVisible: Boolean); override;
getGridStylenull1574     function getGridStyle: QtPenStyle;
1575     procedure setGridStyle(ANewStyle: QtPenStyle);
1576   public
1577     destructor Destroy; override;
1578   end;
1579 
1580   { TQtMenu }
1581 
1582   TQtMenu = class(TQtWidget)
1583   private
1584     FLastTick: QWord; // issue #22872
1585     FActions: TFPList;
1586     FIcon: QIconH;
1587     FTriggeredHook: QAction_hookH;
1588     FHoveredHook: QAction_hookH;
1589     FAboutToShowHook: QMenu_hookH;
1590     FAboutToHideHook: QMenu_hookH;
1591     FActionEventFilter: QObject_hookH;
1592     FActionHandle: QActionH;
1593     FMenuItem: TMenuItem;
1594     FTrackButton: QtMouseButtons;
1595     procedure setActionGroups(AItem: TMenuItem);
1596   protected
CreateWidgetnull1597     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1598     procedure DoPopupClose;
1599   public
1600     constructor Create(const AMenuItem: TMenuItem); overload;
1601     destructor Destroy; override;
1602     procedure InitializeWidget; override;
1603   public
1604     procedure AttachEvents; override;
1605     procedure DetachEvents; override;
1606 
1607     procedure SlotHovered; cdecl;
1608     procedure SlotAboutToShow; cdecl;
1609     procedure SlotAboutToHide; cdecl;
1610     procedure SlotDestroy; cdecl;
1611     procedure SlotTriggered(checked: Boolean = False); cdecl;
ActionEventFilternull1612     function ActionEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
EventFilternull1613     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1614   public
actionHandlenull1615     function actionHandle: QActionH;
addMenunull1616     function addMenu(AMenu: QMenuH): QActionH;
insertMenunull1617     function insertMenu(AIndex: Integer; AMenu: QMenuH; AItem: TMenuItem): QActionH;
getHasSubMenunull1618     function getHasSubMenu: boolean;
getTextnull1619     function getText: WideString; override;
getVisiblenull1620     function getVisible: Boolean; override;
MenuItemEnablednull1621     function MenuItemEnabled: boolean;
1622     procedure PopUp(pos: PQtPoint; at: QActionH = nil);
1623     procedure Exec(pos: PQtPoint; at: QActionH = nil);
1624     procedure removeActionGroup;
1625     procedure setChecked(p1: Boolean);
1626     procedure setCheckable(p1: Boolean);
1627     procedure setHasSubmenu(AValue: Boolean);
1628     procedure setIcon(AIcon: QIconH);
1629     procedure setImage(AImage: TQtImage);
1630     procedure setSeparator(AValue: Boolean);
1631     procedure setShortcut(AShortCutK1, AShortCutK2: TShortcut);
1632     procedure setText(const W: WideString); override;
1633     procedure setVisible(AVisible: Boolean); override;
1634     property trackButton: QtMouseButton read FTrackButton write FTrackButton;
1635   end;
1636 
1637   { TQtMenuBar }
1638 
1639   TQtMenuBar = class(TQtWidget)
1640   private
1641     {$IFNDEF DARWIN}
1642     FCatchNextResizeEvent: Boolean; {needed during design time}
1643     FNumOfActions: PtrInt;
1644     {$ENDIF}
1645     FVisible: Boolean;
1646     FHeight: Integer;
1647     FIsApplicationMainMenu: Boolean;
1648   public
1649     constructor Create(const AParent: QWidgetH); overload;
1650   public
1651     {$IFNDEF DARWIN}
IsDesigningnull1652     function IsDesigning: Boolean;
1653     {$ENDIF}
EventFilternull1654     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
addMenunull1655     function addMenu(AMenu: QMenuH): QActionH;
insertMenunull1656     function insertMenu(AIndex: Integer; AMenu: QMenuH): QActionH;
getGeometrynull1657     function getGeometry: TRect; override;
1658   end;
1659 
1660   { TQtProgressBar }
1661 
1662   TQtProgressBar = class(TQtWidget)
1663   private
1664     FValueChangedHook: QProgressBar_hookH;
1665   protected
CreateWidgetnull1666     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1667   public
1668     procedure AttachEvents; override;
1669     procedure DetachEvents; override;
1670     procedure SignalValueChanged(Value: Integer); cdecl;
1671     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
1672   public
1673     procedure reset;
1674     procedure setRange(minimum: Integer; maximum: Integer);
1675     procedure setTextVisible(visible: Boolean);
1676     procedure setAlignment(const AAlignment: QtAlignment);
1677     procedure setTextDirection(textDirection: QProgressBarDirection);
1678     procedure setValue(value: Integer);
1679     procedure setOrientation(p1: QtOrientation);
1680     procedure setInvertedAppearance(invert: Boolean);
1681   end;
1682 
1683   { TQtStatusBarPanel }
1684 
1685   TQtStatusBarPanel = class(TQtFrame)
1686   private
1687     FId: Integer;
1688     procedure DrawItem(Sender: QObjectH; Event: QEventH);
1689   protected
CreateWidgetnull1690     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1691   public
EventFilternull1692     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1693     property ID: Integer read FId write FId;
1694   end;
1695 
1696   { TQtStatusBar }
1697 
1698   TQtStatusBar = class(TQtWidget)
1699   protected
CreateWidgetnull1700     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1701   public
1702     Panels: array of TQtStatusBarPanel;
1703     procedure setColor(const Value: PQColor); override;
1704     procedure showMessage(text: PWideString; timeout: Integer = 0);
1705     procedure addWidget(AWidget: QWidgetH; AStretch: Integer = 0);
1706     procedure removeWidget(AWidget: QWidgetH);
isSizeGripEnablednull1707     function isSizeGripEnabled: Boolean;
1708     procedure setSizeGripEnabled(const Value: Boolean);
SlotMousenull1709     function SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; override; cdecl;
1710   end;
1711 
1712   { TQtDialog }
1713 
1714   TQtDialog = class(TQtWidget)
1715   private
1716     FDialogEventHook: QObject_hookH;
1717   protected
1718     FDialog: TCommonDialog;
CreateWidgetnull1719     function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; virtual; overload;
1720   public
1721     constructor Create(ADialog: TCommonDialog; parent: QWidgetH = nil; f: QtWindowFlags = 0); overload;
1722     procedure AttachEvents; override;
1723     procedure DetachEvents; override;
DeliverMessagenull1724     function DeliverMessage(var Msg; const AIsInputEvent: Boolean = False): LRESULT; override;
SlotClosenull1725     function SlotClose: Boolean; cdecl; override;
1726   public
EventFilternull1727     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
execnull1728     function exec: Integer;
1729     procedure setSizeGripEnabled(const AEnabled: Boolean);
1730   end;
1731 
1732   { TQtFileDialog }
1733 
1734   TQtFileDialog = class(TQtDialog)
1735   private
1736     {$ifndef QT_NATIVE_DIALOGS}
1737     FBackBtn: QWidgetH;
1738     FForwardBtn: QWidgetH;
1739     FUpBtn: QWidgetH;
1740     FFileNameEdit: QWidgetH;
1741     FComboType: QWidgetH;
1742     FComboHistory: QWidgetH;
1743     FSideView: QWidgetH;
1744     FTreeView: QWidgetH;
1745     FListView: QWidgetH;
1746     FTreeViewEventFilter: QObject_hookH;
1747     FListViewEventFilter: QObject_hookH;
1748     FSideViewEventFilter: QObject_hookH;
1749     FFileNameEditEventFilter: QObject_hookH;
1750     FComboTypeEventFilter: QObject_hookH;
1751     FComboHistoryEventFilter: QObject_hookH;
1752     {$endif}
1753     FCurrentChangedHook: QFileDialog_hookH;
1754     FDirecotyEnteredHook: QFileDialog_hookH;
1755     FFilterSelectedHook: QFileDialog_hookH;
1756   protected
CreateWidgetnull1757     function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; override;
1758   public
1759     procedure AttachEvents; override;
1760     procedure DetachEvents; override;
1761     {$ifndef QT_NATIVE_DIALOGS}
EventFilternull1762     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1763     {$endif}
1764     procedure CurrentChangedEvent(path: PWideString); cdecl; virtual;
1765     procedure FilterSelectedEvent(filter: PWideString); cdecl;
1766     procedure DirectoryEnteredEvent(directory: PWideString); cdecl;
1767   public
1768     procedure getFilters(const retval: QStringListH);
selectFilenull1769     function selectFile: WideString;
1770     procedure selectedFiles(retval: QStringListH);
1771     procedure setAcceptMode(const AMode: QFileDialogAcceptMode);
1772     procedure setConfirmOverwrite(const AValue: Boolean);
1773     procedure setDirectory(const ADirectory: WideString);
1774     procedure setHistory(AList: TStrings);
1775     procedure setFileMode(const AMode: QFileDialogFileMode);
1776     procedure setFilter(const AFilter: WideString);
1777     procedure setLabelText(const ALabel: QFileDialogDialogLabel; const AText: WideString);
1778     procedure setReadOnly(const AReadOnly: Boolean);
1779     procedure setSelectedFilter(const ASelFilter: WideString);
1780     procedure setViewMode(const AMode: QFileDialogViewMode);
1781     {$ifndef QT_NATIVE_DIALOGS}
1782     procedure setShortcuts(const AIsOpenDialog: Boolean);
1783     {$endif}
1784   end;
1785 
1786   { TQtFilePreviewDialog }
1787 
1788   TQtFilePreviewDialog = class(TQtFileDialog)
1789   private
1790     {$ifndef QT_NATIVE_DIALOGS}
1791     FTextWidget: QLabelH;
1792     FPreviewWidget: QLabelH;
1793     {$ENDIF}
1794   protected
CreateWidgetnull1795     function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; override;
1796   public
1797     {$ifndef QT_NATIVE_DIALOGS}
1798     procedure initializePreview(const APreviewControl: TWinControl);
1799     procedure CurrentChangedEvent(path: PWideString); cdecl; override;
1800     property PreviewWidget: QLabelH read FPreviewWidget;
1801     property TextWidget: QLabelH read FTextWidget;
1802     {$ENDIF}
1803   end;
1804 
1805   { TQtMessageBox }
1806 
1807   TQtMessageBox = class(TQtWidget)
1808   private
1809     FMBEventHook: QObject_hookH;
1810     FTitle: WideString;
getDetailTextnull1811     function getDetailText: WideString;
getMessageStrnull1812     function getMessageStr: WideString;
getMsgBoxTypenull1813     function getMsgBoxType: QMessageBoxIcon;
GetTextFormatnull1814     function GetTextFormat: QtTextFormat;
1815     procedure setDetailText(const AValue: WideString);
1816     procedure setMessageStr(const AValue: WideString);
1817     procedure setMsgBoxType(const AValue: QMessageBoxIcon);
1818     procedure SetTextFormat(AValue: QtTextFormat);
1819     procedure setTitle(const AValue: WideString);
1820   protected
CreateWidgetnull1821     function CreateWidget(AParent: QWidgetH):QWidgetH; overload;
1822   public
1823     constructor Create(AParent: QWidgetH); overload;
1824     procedure AttachEvents; override;
1825     procedure DetachEvents; override;
EventFilternull1826     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1827   public
AddButtonnull1828     function AddButton(ACaption: WideString; ABtnType: QMessageBoxStandardButton; AResult: Int64;
1829       const ADefaultBtn: Boolean; const AEscapeBtn: Boolean = False): QPushButtonH; overload;
AddButtonnull1830     function AddButton(ACaption: WideString; AResult: Int64;
1831       const ADefaultBtn: Boolean; const AEscapeBtn: Boolean = False): QPushButtonH;
1832     procedure SetButtonProps(ABtn: QPushButtonH; AResult: Int64; const ADefaultBtn: Boolean;
1833       const AEscapeBtn: Boolean);
execnull1834     function exec: Int64;
1835     property DetailText: WideString read getDetailText write setDetailText;
1836     property MessageStr: WideString read getMessageStr write setMessageStr;
1837     property MsgBoxType:QMessageBoxIcon read getMsgBoxType write setMsgBoxType;
1838     property Title: WideString read FTitle write setTitle;
1839     property TextFormat: QtTextFormat read GetTextFormat write SetTextFormat;
1840   end;
1841 
1842   { TQtCalendar }
1843 
1844   TQtCalendar = class(TQtWidget)
1845   private
1846     FMouseDoubleClicked: Boolean;
1847     FCalViewportEventHook: QObject_hookH;
1848     FCalViewAreaEventHook: QObject_hookH;
1849     FClickedHook: QCalendarWidget_hookH;
1850     FActivatedHook: QCalendarWidget_hookH;
1851     FSelectionChangedHook: QCalendarWidget_hookH;
1852     FCurrentPageChangedHook: QCalendarWidget_hookH;
DeliverDayChangednull1853     function DeliverDayChanged(ADate: QDateH): boolean;
GetDateTimenull1854     function GetDateTime: TDateTime;
1855     procedure SetDateTime(const AValue: TDateTime);
1856     procedure SetSelectedDate(const AValue: QDateH);
1857   protected
CreateWidgetnull1858     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1859   public
1860     AYear, AMonth, ADay: Word;
1861     procedure AttachEvents; override;
1862     procedure DetachEvents; override;
EventFilternull1863     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
AreaViewEventFilternull1864     function AreaViewEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
calViewportEventFilternull1865     function calViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
HitTestnull1866     function HitTest(const APoint: TPoint): byte;
1867     procedure SetDisplaySettings(
1868       const AHHdrFmt: QCalendarWidgetHorizontalHeaderFormat;
1869       const AVHdrFmt: QCalendarWidgetVerticalHeaderFormat;
1870       const ASelMode: QCalendarWidgetSelectionMode;
1871       const ANavBarVisible: Boolean; const AGridVisible: Boolean);
1872     procedure SetFirstDayOfWeek(const ADayOfWeek: QtDayOfWeek);
1873     procedure SignalActivated(ADate: QDateH); cdecl;
1874     procedure SignalClicked(ADate: QDateH); cdecl;
1875     procedure SignalSelectionChanged; cdecl;
1876     procedure SignalCurrentPageChanged(p1, p2: Integer); cdecl;
1877     property DateTime: TDateTime read GetDateTime write SetDateTime;
1878   end;
1879 
1880   // for page control / notebook
1881 
1882   { TQtPage }
1883 
1884   TQtPage = class(TQtWidget)
1885   protected
1886     FIcon: QIconH;
CreateWidgetnull1887     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1888   public
EventFilternull1889     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
getIconnull1890     function getIcon: QIconH;
getIndexnull1891     function getIndex(const ATextChanging: Boolean = False): Integer;
getTabWidgetnull1892     function getTabWidget: QTabWidgetH;
1893     procedure setIcon(const AIcon: QIconH);
1894     procedure setText(const W: WideString); override;
1895   end;
1896 
1897   { TQtRubberBand }
1898 
1899   TQtRubberBand = class(TQtWidget)
1900   private
1901     FShape: QRubberBandShape;
1902   protected
CreateWidgetnull1903     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1904   public
1905     constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); override;
1906 
1907     // QRubberBand have it's own move,resize and setGeometry
1908     procedure move(ANewLeft, ANewTop: Integer); override;
1909     procedure Resize(ANewWidth, ANewHeight: Integer); override;
1910     procedure setGeometry(ARect: TRect); override;
1911 
1912     function getShape: QRubberBandShape;
1913     procedure setShape(AShape: QRubberBandShape);
1914   end;
1915 
1916   { TQtDesignWidget }
1917 
1918   TQtDesignWidget = class(TQtMainWindow)
1919   protected
1920     FDesignControlEventHook: QObject_hookH;
1921     FDesignControl: QWidgetH;
1922     FDesignContext: HDC;
1923     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1924     procedure DestroyWidget; override;
1925     procedure SlotDesignControlPaint(Sender: QObjectH; Event: QEventH); cdecl;
1926     procedure BringDesignerToFront;
1927     procedure ResizeDesigner;
1928     function GetContext: HDC; override;
1929   public
1930     function DesignControlEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
1931     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1932 
1933     procedure AttachEvents; override;
1934     procedure DetachEvents; override;
1935 
1936     procedure lowerWidget; override;
1937     procedure raiseWidget; override;
1938   public
1939     property DesignContext: HDC read FDesignContext;
1940   end;
1941 
1942 const
1943   AlignmentMap: array[TAlignment] of QtAlignment =
1944   (
1945 {taLeftJustify } QtAlignLeft,
1946 {taRightJustify} QtAlignRight,
1947 {taCenter      } QtAlignHCenter
1948   );
1949 
1950   QtCheckStateRole = Ord(QtUserRole) + 1;
1951   QtListViewOwnerDataRole = Ord(QtUserRole) + 2;
1952 implementation
1953 
1954 uses
1955   Buttons,
1956   math,
1957   qtCaret,
1958   qtproc,
1959   qtprivate,
1960   WSControls
1961   {$IFDEF HASX11}
1962   ,keysym
1963   {$ENDIF}
1964   ;
1965 
1966 const
1967   Forbid_TCN_SELCHANGE = -3;
1968   Allow_TCN_SELCHANGE = -2;
1969 
1970 type
1971   TWinControlAccess = class(TWinControl)
1972   end;
1973   TCustomListViewAccess = class(TCustomListView);
1974 
1975 var
1976   LastMouse: TLastMouseInfo;
1977 
1978 { TQtWidget }
1979 
1980 {------------------------------------------------------------------------------
1981   Function: TQtWidget.Create
1982   Params:  None
1983   Returns: Nothing
1984  ------------------------------------------------------------------------------}
1985 constructor TQtWidget.Create(const AWinControl: TWinControl; const AParams: TCreateParams);
1986 begin
1987   inherited Create;
1988   FOwner := nil;
1989   FCentralWidget := nil;
1990   FOwnWidget := True;
1991   // Initializes the properties
1992   FProps := nil;
1993   LCLObject := AWinControl;
1994   FKeysToEat := [VK_TAB, VK_RETURN, VK_ESCAPE];
1995   FHasPaint := False;
1996 
1997   FParams := AParams;
1998   InitializeWidget;
1999 end;
2000 
2001 constructor TQtWidget.CreateFrom(const AWinControl: TWinControl;
2002   AWidget: QWidgetH);
2003 begin
2004   inherited Create;
2005 
2006   FOwner := nil;
2007   FOwnWidget := False;
2008   FCentralWidget := nil;
2009   // Initializes the properties
2010   FProps := niL;
2011   LCLObject := AWinControl;
2012   FKeysToEat := [VK_TAB, VK_RETURN, VK_ESCAPE];
2013 
2014   // Creates the widget
2015   Widget := AWidget;
2016 
2017   FDefaultCursor := QCursor_create();
2018   QWidget_cursor(Widget, FDefaultCursor);
2019   FWidgetLCLFont := nil;
2020   FWidgetDefaultFont := TQtFont.Create(QWidget_font(AWidget));
2021 
2022   // set Handle->QWidget map
2023   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
2024   FillChar(FPaintData, sizeOf(FPaintData), 0);
2025 
2026   QtWidgetSet.AddHandle(Self);
2027   // set focus policy
2028   if (LCLObject <> nil) and not (Self is TQtMainWindow) then
2029     setFocusPolicy(QtClickFocus);
2030 
2031   // Set mouse move messages policy
2032   QWidget_setMouseTracking(Widget, True);
2033 end;
2034 
2035 procedure TQtWidget.InitializeWidget;
2036 begin
2037   FInResizeEvent := False;
2038   // default states
2039   FWidgetState := [];
2040   // default color roles
2041   FWidgetNeedFontColorInitialization := False;
2042   SetDefaultColorRoles;
2043   FPalette := nil;
2044   FHasCaret := False;
2045   FLastCaretPos := QtPoint(-1, -1);
2046   ChildOfComplexWidget := ccwNone;
2047   // creates the widget
2048   Widget := CreateWidget(FParams);
2049 
2050   // retrieve default cursor on create
2051   FDefaultCursor := QCursor_create();
2052   QWidget_cursor(Widget, FDefaultCursor);
2053 
2054   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
2055   FWidgetLCLFont := nil;
2056 
2057 
2058   // apply initial position and size
2059   move(FParams.X, FParams.Y);
2060   if GetContainerWidget <> Widget then
2061     QWidget_resize(GetContainerWidget, FParams.Width, FParams.Height);
2062 
2063   Resize(FParams.Width, FParams.Height);
2064 
2065   FScrollX := 0;
2066   FScrollY := 0;
2067 
2068   {$ifdef VerboseQt}
2069   DebugLn('TQtWidget.InitializeWidget: Self:%x Widget:%x was created for control %s',
2070     [PtrUInt(Self), PtrUInt(Widget), LCLObject.Name]);
2071   {$endif}
2072 
2073   // set Handle->QWidget map
2074   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
2075   QtWidgetSet.AddHandle(Self);
2076 
2077   FillChar(FPaintData, sizeOf(FPaintData), 0);
2078 
2079   // Sets it's initial properties
2080 
2081   // set focus policy
2082   if Assigned(LCLObject) then
2083   begin
2084     if (Self is TQtMainWindow) and
2085       (
2086       TQtMainWindow(Self).IsMDIChild or
2087       Assigned(TQtMainWindow(Self).MDIAreaHandle) or
2088        (csNoFocus in LCLObject.ControlStyle)
2089       ) then
2090     begin
2091       if TQtMainWindow(Self).IsMDIChild or
2092         Assigned(TQtMainWindow(Self).MDIAreaHandle) then
2093       begin
2094         QWidget_setFocusPolicy(FCentralWidget, QtNoFocus);
2095       end else
2096       begin
2097         if LCLObject.TabStop then
2098           setFocusPolicy(QtWheelFocus)
2099         else
2100           setFocusPolicy(QtNoFocus);
2101       end;
2102     end else
2103     begin
2104       if (Self is TQtMainWindow) then
2105         setFocusPolicy(QtTabFocus) // issue #28880
2106       else
2107       if (csNoFocus in LCLObject.ControlStyle) then
2108       begin
2109         if LCLObject.TabStop then
2110           setFocusPolicy(QtTabFocus)
2111         else
2112           setFocusPolicy(QtNoFocus);
2113       end else
2114       if (Self is TQtTabWidget) then
2115         setFocusPolicy(QtTabFocus)
2116       else
2117         setFocusPolicy(QtClickFocus);
2118     end;
2119     if LCLObject.Perform(LM_NCHITTEST, 0, 0)=HTTRANSPARENT then
2120       setAttribute(QtWA_TransparentForMouseEvents);
2121 
2122 
2123     if (csDesigning in LCLObject.ComponentState) and not
2124        (Self is TQtMainWindow) and
2125        HasPaint and
2126        getAutoFillBackground or
2127        ((csDesigning in LCLObject.ComponentState) and
2128         (ClassType = TQtTabWidget)) then
2129       setAutoFillBackground(False);
2130   end;
2131 
2132   // Set mouse move messages policy
2133   QWidget_setMouseTracking(Widget, True);
2134 
2135   if Assigned(LCLObject) and FWidgetNeedFontColorInitialization then
2136     setInitialFontColor(LCLObject);
2137   if (FParams.Style and WS_VISIBLE) = 0 then
2138     QWidget_hide(Widget)
2139   else
2140     QWidget_show(Widget);
2141 end;
2142 
2143 procedure TQtWidget.DeInitializeWidget;
2144 begin
2145   QtWidgetSet.RemoveHandle(Self);
2146   DetachEvents;
2147 
2148   if Widget <> nil then
2149     removeProperty(Widget, 'lclwidget');
2150 
2151   QCursor_destroy(FDefaultCursor);
2152 
2153   if HasCaret then
2154     DestroyCaret;
2155 
2156   if Assigned(FWidgetDefaultFont) then
2157     FreeThenNil(FWidgetDefaultFont);
2158   if Assigned(FWidgetLCLFont) then
2159     FreeThenNil(FWidgetLCLFont);
2160 
2161   if FPalette <> nil then
2162   begin
2163     FPalette.Free;
2164     FPalette := nil;
2165   end;
2166 
2167   DestroyWidget;
2168 end;
2169 
2170 procedure TQtWidget.RecreateWidget;
2171 var
2172   Parent: QWidgetH;
2173 begin
2174   // update createparams
2175   with getPos do
2176   begin
2177     FParams.X := X;
2178     FParams.Y := Y;
2179   end;
2180   with getSize do
2181   begin
2182     FParams.Width := cx;
2183     FParams.Height := cy;
2184   end;
2185 
2186   if Widget <> nil then
2187     Parent := QWidget_parentWidget(Widget)
2188   else
2189     Parent := nil;
2190   FParams.WndParent := HwndFromWidgetH(Parent);
2191   DeinitializeWidget;
2192   InitializeWidget;
2193 end;
2194 
2195 procedure TQtWidget.DestroyNotify(AWidget: TQtWidget);
2196 begin
2197   if AWidget = FOwner then
2198     FOwner := nil;
2199 end;
2200 
2201 {------------------------------------------------------------------------------
2202   Function: TQtWidget.Destroy
2203   Params:  None
2204   Returns: Nothing
2205  ------------------------------------------------------------------------------}
2206 destructor TQtWidget.Destroy;
2207 begin
2208   DeinitializeWidget;
2209 
2210   if FProps <> nil then
2211   begin
2212     FProps.Free;
2213     FProps:=nil;
2214   end;
2215 
2216   if FPaintData.ClipRegion <> nil then
2217   begin
2218     QRegion_Destroy(FPaintData.ClipRegion);
2219     FPaintData.ClipRegion:=nil;
2220   end;
2221 
2222   if FOwner <> nil then
2223     FOwner.DestroyNotify(Self);
2224 
2225   inherited Destroy;
2226 end;
2227 
2228 {------------------------------------------------------------------------------
2229   Function: TQtWidget.GetContainerWidget
2230   Params:  None
2231   Returns: The widget of the control on top of which other controls
2232            should be placed
2233  ------------------------------------------------------------------------------}
GetContainerWidgetnull2234 function TQtWidget.GetContainerWidget: QWidgetH;
2235 begin
2236   if FCentralWidget <> nil then
2237     Result := FCentralWidget
2238   else
2239     Result := Widget;
2240 end;
2241 
2242 procedure TQtWidget.Release;
2243 begin
2244   LCLObject := nil;
2245   {always hide widget since we use QObject_deleteLater(). issue #27781}
2246   if (Widget <> nil) then
2247     Hide;
2248   inherited Release;
2249 end;
2250 
2251 procedure TQtWidget.Destroyed; cdecl;
2252 begin
2253   Widget := nil;
2254   Release;
2255 end;
2256 
TQtWidget.WinIDNeedednull2257 function TQtWidget.WinIDNeeded: boolean;
2258 begin
2259   Result := False;
2260 end;
2261 
2262 {------------------------------------------------------------------------------
2263   Function: TQtWidget.CanAdjustClientRectOnResize
2264   Params:  None
2265   Returns: Boolean
2266   Checks if our control can call LCLObject.DoAdjustClientRect from SlotResize.
2267   This avoids deadlocks with autosizing.
2268  ------------------------------------------------------------------------------}
CanAdjustClientRectOnResizenull2269 function TQtWidget.CanAdjustClientRectOnResize: Boolean;
2270 begin
2271   Result := True;
2272 end;
2273 
CanChangeFontColornull2274 function TQtWidget.CanChangeFontColor: Boolean;
2275 begin
2276   Result := True;
2277 end;
2278 
2279 {------------------------------------------------------------------------------
2280   Function: TQtWidget.CanSendLCLMessage
2281   Params:  None
2282   Returns: Boolean
2283   If returns FALSE then we should not send any message to LCL since our
2284   LCLObject is probably being destroyed or it has csDestroying flag on.
2285   This is very important to know before calling NotifyApplicationUserInput,
2286   which is often called from mouse & keyboard events.
2287  ------------------------------------------------------------------------------}
CanSendLCLMessagenull2288 function TQtWidget.CanSendLCLMessage: Boolean;
2289 begin
2290   Result := (LCLObject <> nil) and (Widget <> nil) and getVisible and
2291     not ((csDestroying in LCLObject.ComponentState) or
2292          (csDestroyingHandle in LCLObject.ControlState));
2293 end;
2294 
2295 {------------------------------------------------------------------------------
2296   Function: TQtWidget.CanPaintBackground
2297   Params:  None
2298   Returns: Boolean
2299   Makes decision if control background need to be painted.
2300   Look at SlotPaintBg().
2301  ------------------------------------------------------------------------------}
TQtWidget.CanPaintBackgroundnull2302 function TQtWidget.CanPaintBackground: Boolean;
2303 begin
2304   {TODO: we must override this function for some classes
2305    until clDefault is implemented in LCL.Then we can easy
2306    ask EqualTQColor() for diff between
2307    Palette.DefaultColor and current LCLObject.Color}
2308   Result := False;
2309 end;
2310 
2311 procedure TQtWidget.DelayResizeEvent(AWidget: QWidgetH; ANewSize: TSize);
2312 var
2313   ALCLResizeEvent: QLCLMessageEventH;
2314 begin
2315   ALCLResizeEvent := QLCLMessageEvent_create(LCLQt_DelayResizeEvent, 0, PtrUInt(ANewSize.cx), PtrUInt(ANewSize.cy), 0);
2316   QCoreApplication_postEvent(AWidget, ALCLResizeEvent);
2317 end;
2318 
2319 {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtKeys)}
EventTypeToStrnull2320 function EventTypeToStr(Event:QEventH):string;
2321 // Qt 3 events
2322 const
2323   QEventChildInsertedRequest = 67;
2324   QEventChildInserted = 70;
2325   QEventLayoutHint = 72;
2326 begin
2327   case QEvent_type(Event) of
2328     QEventNone: result:='QEventNone';
2329     QEventTimer: result:='QEventTimer';
2330     QEventMouseButtonPress: result:='QEventMouseButtonPress';
2331     QEventMouseButtonRelease: result:='QEventMouseButtonRelease';
2332     QEventMouseButtonDblClick: result:='QEventMouseButtonDblClick';
2333     QEventMouseMove: result:='QEventMouseMove';
2334     QEventKeyPress: result:='QEventKeyPress';
2335     QEventKeyRelease: result:='QEventKeyRelease';
2336     QEventFocusIn: result:='QEventFocusIn';
2337     QEventFocusOut: result:='QEventFocusOut';
2338     QEventEnter: result:='QEventEnter';
2339     QEventLeave: result:='QEventLeave';
2340     QEventPaint: result:='QEventPaint';
2341     QEventMove: result:='QEventMove';
2342     QEventResize: result:='QEventResize';
2343     QEventCreate: result:='QEventCreate';
2344     QEventDestroy: result:='QEventDestroy';
2345     QEventShow: result:='QEventShow';
2346     QEventHide: result:='QEventHide';
2347     QEventClose: result:='QEventClose';
2348     QEventQuit: result:='QEventQuit';
2349     QEventParentChange: result:='QEventParentChange';
2350     QEventThreadChange: result:='QEventThreadChange';
2351     QEventWindowActivate: result:='QEventWindowActivate';
2352     QEventWindowDeactivate: result:='QEventWindowDeactivate';
2353     QEventShowToParent: result:='QEventShowToParent';
2354     QEventHideToParent: result:='QEventHideToParent';
2355     QEventWheel: result:='QEventWheel';
2356     QEventWindowTitleChange: result:='QEventWindowTitleChange';
2357     QEventWindowIconChange: result:='QEventWindowIconChange';
2358     QEventApplicationWindowIconChange: result:='QEventApplicationWindowIconChange';
2359     QEventApplicationFontChange: result:='QEventApplicationFontChange';
2360     QEventApplicationLayoutDirectionChange: result:='QEventApplicationLayoutDirectionChange';
2361     QEventApplicationPaletteChange: result:='QEventApplicationPaletteChange';
2362     QEventPaletteChange: result:='QEventPaletteChange';
2363     QEventClipboard: result:='QEventClipboard';
2364     QEventSpeech: result:='QEventSpeech';
2365     QEventMetaCall: result:='QEventMetaCall';
2366     QEventSockAct: result:='QEventSockAct';
2367     QEventShortcutOverride: result:='QEventShortcutOverride';
2368     QEventDeferredDelete: result:='QEventDeferredDelete';
2369     QEventDragEnter: result:='QEventDragEnter';
2370     QEventDragMove: result:='QEventDragMove';
2371     QEventDragLeave: result:='QEventDragLeave';
2372     QEventDrop: result:='QEventDrop';
2373     QEventDragResponse: result:='QEventDragResponse';
2374     //    QEventChildInsertedRequest: result:='(Qt3) QEventChildAdded'; //qt3
2375     QEventChildAdded: result:='QEventChildAdded';
2376     QEventChildPolished: result:='QEventChildPolished';
2377     //    QEventChildInserted: result:='(Qt3) QEventChildAdded'; // qt3
2378     //    QEventLayoutHint: result:='(Qt3) QEventChildAdded'; // qt3
2379     QEventChildRemoved: result:='QEventChildRemoved';
2380     QEventShowWindowRequest: result:='QEventShowWindowRequest';
2381     QEventPolishRequest: result:='QEventPolishRequest';
2382     QEventPolish: result:='QEventPolish';
2383     QEventLayoutRequest: result:='QEventLayoutRequest';
2384     QEventUpdateRequest: result:='QEventUpdateRequest';
2385     QEventUpdateLater: result:='QEventUpdateLater';
2386     QEventEmbeddingControl: result:='QEventEmbeddingControl';
2387     QEventActivateControl: result:='QEventActivateControl';
2388     QEventDeactivateControl: result:='QEventDeactivateControl';
2389     QEventContextMenu: result:='QEventContextMenu';
2390     QEventInputMethod: result:='QEventInputMethod';
2391     QEventAccessibilityPrepare: result:='QEventAccessibilityPrepare';
2392     QEventTabletMove: result:='QEventTabletMove';
2393     QEventLocaleChange: result:='QEventLocaleChange';
2394     QEventLanguageChange: result:='QEventLanguageChange';
2395     QEventLayoutDirectionChange: result:='QEventLayoutDirectionChange';
2396     QEventStyle: result:='QEventStyle';
2397     QEventTabletPress: result:='QEventTabletPress';
2398     QEventTabletRelease: result:='QEventTabletRelease';
2399     QEventOkRequest: result:='QEventOkRequest';
2400     QEventHelpRequest: result:='QEventHelpRequest';
2401     QEventIconDrag: result:='QEventIconDrag';
2402     QEventFontChange: result:='QEventFontChange';
2403     QEventEnabledChange: result:='QEventEnabledChange';
2404     QEventActivationChange: result:='QEventActivationChange';
2405     QEventStyleChange: result:='QEventStyleChange';
2406     QEventIconTextChange: result:='QEventIconTextChange';
2407     QEventModifiedChange: result:='QEventModifiedChange';
2408     QEventWindowBlocked: result:='QEventWindowBlocked';
2409     QEventWindowUnblocked: result:='QEventWindowUnblocked';
2410     QEventWindowStateChange: result:='QEventWindowStateChange';
2411     QEventMouseTrackingChange: result:='QEventMouseTrackingChange';
2412     QEventToolTip: result:='QEventToolTip';
2413     QEventWhatsThis: result:='QEventWhatsThis';
2414     QEventStatusTip: result:='QEventStatusTip';
2415     QEventActionChanged: result:='QEventActionChanged';
2416     QEventActionAdded: result:='QEventActionAdded';
2417     QEventActionRemoved: result:='QEventActionRemoved';
2418     QEventFileOpen: result:='QEventFileOpen';
2419     QEventShortcut: result:='QEventShortcut';
2420     QEventWhatsThisClicked: result:='QEventWhatsThisClicked';
2421     QEventAccessibilityHelp: result:='QEventAccessibilityHelp';
2422     QEventToolBarChange: result:='QEventToolBarChange';
2423     QEventApplicationActivated: result:='QEventApplicationActivated';
2424     QEventApplicationDeactivated: result:='QEventApplicationDeactivated';
2425     QEventQueryWhatsThis: result:='QEventQueryWhatsThis';
2426     QEventEnterWhatsThisMode: result:='QEventEnterWhatsThisMode';
2427     QEventLeaveWhatsThisMode: result:='QEventLeaveWhatsThisMode';
2428     QEventZOrderChange: result:='QEventZOrderChange';
2429     QEventHoverEnter: result:='QEventHoverEnter';
2430     QEventHoverLeave: result:='QEventHoverLeave';
2431     QEventHoverMove: result:='QEventHoverMove';
2432     QEventAccessibilityDescription: result:='QEventAccessibilityDescription';
2433     QEventParentAboutToChange: result:='QEventParentAboutToChange';
2434     QEventWinEventAct: result:='QEventWinEventAct';
2435     QEventAcceptDropsChange: result:='QEventAcceptDropsChange';
2436     QEventMenubarUpdated: result:='QEventMenubarUpdated';
2437     QEventZeroTimerEvent: result:='QEventZeroTimerEvent';
2438     QEventNonClientAreaMouseMove: result:='QEventNonClientAreaMouseMove';
2439     QEventNonClientAreaMouseButtonPress: result:='QEventNonClientAreaMouseButtonPress';
2440     QEventNonClientAreaMouseButtonRelease: result:='QEventNonClientAreaMouseButtonRelease';
2441     QEventNonClientAreaMouseButtonDblClick: result:='QEventNonClientAreaMouseButtonDblClick';
2442     QEventMacSizeChange: result := 'QEventMacSizeChange';
2443     QEventContentsRectChange: result := 'QEventContentsRectChange';
2444     QEventMacGLWindowChange: result := 'QEventMacGLWindowChange';
2445     QEventFutureCallOut: result := 'QEventFutureCallOut';
2446     QEventGraphicsSceneResize: result := 'QEventGraphicsSceneResize';
2447     QEventGraphicsSceneMove: result := 'QEventGraphicsSceneMove';
2448     QEventCursorChange: result := 'QEventCursorChange';
2449     QEventToolTipChange: result := 'QEventToolTipChange';
2450     QEventNetworkReplyUpdated: result := 'QEventNetworkReplyUpdated';
2451     QEventGrabMouse: result := 'QEventGrabMouse';
2452     QEventUngrabMouse: result := 'QEventUngrabMouse';
2453     QEventGrabKeyboard: result := 'QEventGrabKeyboard';
2454     QEventUngrabKeyboard: result := 'QEventUngrabKeyboard';
2455     QEventCocoaRequestModal: result := 'QEventCocoaRequestModal';
2456     QEventUser: result:='QEventUser';
2457     QEventMaxUser: result:='QEventMaxUser';
2458     200: Result := 'QEventCloseSoftwareInputPanel';
2459     QEventWinIdChange: Result := 'QEventWinIdChange';
2460   else
2461     Result := Format('Unknown event: %d', [QEvent_type(Event)]);
2462   end;
2463 end;
2464 {$ENDIF}
2465 
2466 {------------------------------------------------------------------------------
2467   Function: TQtWidget.EventFilter
2468   Params:  None
2469   Returns: Nothing
2470  ------------------------------------------------------------------------------}
TQtWidget.EventFilternull2471 function TQtWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
2472 var
2473   {$IFDEF MSWINDOWS}
2474   AContextEvent: QContextMenuEventH;
2475   {$ENDIF}
2476   QColor, OldColor: TQColor;
2477   ColorRef: TColorRef;
2478   QtEdit: IQtEdit;
2479   R: TRect;
2480   Pt: TQtPoint;
2481   ANewSize: TSize;
2482   AResizeEvent: QResizeEventH;
2483 begin
2484   Result := False;
2485   QEvent_accept(Event);
2486 
2487   BeginEventProcessing;
2488   try
2489     {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
2490     WriteLn('TQtWidget.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
2491       ' LCLObject=', dbgsName(LCLObject),
2492       ' Event=', EventTypeToStr(Event),' inUpdate=',InUpdate);
2493     {$endif}
2494 
2495     if LCLObject <> nil then
2496     begin
2497       case QEvent_type(Event) of
2498         LCLQt_DelayResizeEvent:
2499         begin
2500           ANewSize.cx := LongInt(QLCLMessageEvent_getWParam(QLCLMessageEventH(Event)));
2501           ANewSize.cy := LongInt(QLCLMessageEvent_getLParam(QLCLMessageEventH(Event)));
2502           AResizeEvent := QResizeEvent_create(@ANewSize, @ANewSize);
2503           try
2504             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2505             DebugLn('>LCLQt_DelayResizeEvent: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
2506             {$ENDIF}
2507             SlotResize(AResizeEvent);
2508             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2509             DebugLn('<LCLQt_DelayResizeEvent: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
2510             {$ENDIF}
2511           finally
2512             QResizeEvent_destroy(AResizeEvent);
2513           end;
2514           Result := True;
2515         end;
2516         QEventFontChange:
2517           begin
2518             //explanation for this event usage: issue #19695
2519             if not (qtwsFontUpdating in WidgetState) and
2520               not LCLObject.IsParentFont then
2521             begin
2522               if Assigned(FWidgetLCLFont) then
2523                 AssignQtFont(FWidgetLCLFont.FHandle, QWidget_font(QWidgetH(Sender)))
2524               else
2525                 AssignQtFont(FWidgetDefaultFont.FHandle, QWidget_font(QWidgetH(Sender)));
2526             end;
2527           end;
2528         QEventEnabledChange:
2529           begin
2530             // if we are disabled, imediatelly invalidate widgetAt cache
2531             if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
2532               QtWidgetSet.InvalidateWidgetAtCache
2533             else
2534             if QtWidgetSet.IsValidWidgetAtCachePointer then
2535             begin
2536               Pt := QtPoint(0, 0);
2537               QWidget_mapToGlobal(Widget, @Pt, @Pt);
2538               QWidget_geometry(Widget, @R);
2539               R := Rect(Pt.X, Pt.Y, Pt.X + (R.Right - R.Left), Pt.Y + (R.Bottom - R.Top));
2540               if PtInRect(R, QtWidgetSet.GetWidgetAtCachePoint) then
2541                 QtWidgetSet.InvalidateWidgetAtCache;
2542             end;
2543             // issue #25922
2544             if Assigned(FPalette) and Assigned(LCLObject) then
2545             begin
2546               // DebugLn('QEventEnabledChange: ',dbgsName(LCLObject),' enabled ',dbgs(getEnabled));
2547               if not getEnabled then
2548                 Palette.setTextColor(@Palette.DisabledTextColor)
2549               else
2550                 setInitialFontColor(LCLObject);
2551             end;
2552           end;
2553         QEventShow:
2554           begin
2555             SlotShow(True);
2556             {$IFDEF MSWINDOWS}
2557             if (qtwsInsideRightMouseButtonPressEvent in FWidgetState) and
2558                (qtwsHiddenInsideRightMouseButtonPressEvent in FWidgetState) then
2559             begin
2560               Exclude(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
2561               Exclude(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
2562               if (LastMouse.WinControl = LCLObject) and
2563                 (QApplication_mouseButtons and QtRightButton <> 0) then
2564               begin
2565                 Pt := QtPoint(LastMouse.MousePos.X, LastMouse.MousePos.Y);
2566                 AContextEvent := QContextMenuEvent_create(QContextMenuEventMouse, @Pt);
2567                 QCoreApplication_postEvent(Sender, AContextEvent);
2568                 LastMouse.MousePos := Point(Pt.X, Pt.Y);
2569               end;
2570             end;
2571             {$ENDIF}
2572           end;
2573         QEventHide:
2574           begin
2575             if QWidget_mouseGrabber() = Widget then
2576               ReleaseCapture;
2577             SlotShow(False);
2578             {$IFDEF MSWINDOWS}
2579             if qtwsInsideRightMouseButtonPressEvent in FWidgetState then
2580               Include(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
2581             {$ENDIF}
2582           end;
2583         QEventClose:
2584           if not SlotClose then
2585           begin
2586             QEvent_ignore(Event);
2587             Result := True;
2588           end;
2589         QEventDestroy: SlotDestroy;
2590         QEventEnter,
2591         QEventLeave: Result := SlotMouseEnter(Sender, Event);
2592 
2593         QEventHoverEnter,
2594         QEventHoverLeave,
2595         QEventHoverMove: Result := SlotHover(Sender, Event);
2596 
2597         QEventDrop,
2598         QEventDragMove,
2599         QEventDragEnter:
2600         begin
2601           Result := getAcceptDropFiles;
2602           if (Result) and (QEvent_type(Event) = QEventDrop) then
2603             Result := slotDropFiles(Sender, Event);
2604         end;
2605 
2606         QEventKeyPress,
2607         QEventKeyRelease:
2608           begin
2609             {non-spontaneous key events are garbage in Qt >= 4.4 for non edits}
2610             Result := QEvent_spontaneous(Event) or Supports(Self, IQtEdit, QtEdit);
2611             if Result then
2612               Result := SlotKey(Sender, Event) or (LCLObject is TCustomControl);
2613           end;
2614 
2615         //Dead keys (used to compose chars like "ó" by pressing 'o)  do not trigger EventKeyPress
2616         //and therefore no KeyDown,Utf8KeyPress,KeyPress
2617         QEventInputMethod:
2618           begin
2619             Result := SlotInputMethod(Sender, Event);
2620           end;
2621 
2622         QEventMouseButtonPress,
2623         QEventMouseButtonRelease,
2624         QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
2625         QEventMouseMove: Result := SlotMouseMove(Sender, Event);
2626         QEventWheel:
2627           begin
2628             if not getEnabled then
2629             begin
2630               QEvent_ignore(Event);
2631               QWidget_setAttribute(QWidgetH(Sender), QtWA_NoMousePropagation, False);
2632             end else
2633               Result := SlotMouseWheel(Sender, Event);
2634           end;
2635         QEventMove: SlotMove(Event);
2636         QEventResize: SlotResize(Event);
2637         QEventContentsRectChange:
2638         begin
2639           if ChildOfComplexWidget = ccwScrollingWinControl then
2640           begin
2641             // Result := (caspComputingBounds in LCLObject.AutoSizePhases);
2642             QEvent_ignore(Event);
2643           end;
2644           if LCLObject.ClientRectNeedsInterfaceUpdate then
2645           begin
2646             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
2647             if ChildOfComplexWidget = ccwScrollingWinControl then
2648             begin
2649               if Self is TQtViewport then
2650                 QWidget_rect(Widget, @R)
2651               else
2652                 QWidget_rect(TQtAbstractScrollArea(Self).viewportWidget, @R);
2653               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)));
2654             end else
2655               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));
2656             {$ENDIF}
2657             if not (caspComputingBounds in LCLObject.AutoSizePhases) then
2658             begin
2659               {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2660               DebugLn('  QEventContentsRectChange(',dbgsName(LCLObject),' call DoAdjustClientRectChange !');
2661               {$ENDIF}
2662               if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
2663               else
2664                 LCLObject.DoAdjustClientRectChange(True);
2665             end else
2666             begin
2667               {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2668               DebugLn('  QEventContentsRectChange(',dbgsName(LCLObject),' call InvalidatePrefferedSize !');
2669               {$ENDIF}
2670               if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
2671               else
2672                 LCLObject.InvalidatePreferredSize;
2673             end;
2674           end;
2675         end;
2676         QEventPaint:
2677           begin
2678             if canPaintBackground and (LCLObject.Color <> clDefault) then
2679               SlotPaintBg(Sender, Event);
2680             if FHasPaint then
2681               SlotPaint(Sender, Event);
2682           end;
2683         QEventContextMenu:
2684             Result := SlotContextMenu(Sender, Event);
2685         QEventNonClientAreaMouseButtonPress:
2686           begin
2687             SlotNCMouse(Sender, Event);
2688           end;
2689         QEventPaletteChange,
2690         QEventStyleChange:
2691           begin
2692             if (FPalette <> nil) and not InUpdate and not Palette.InReload then
2693             begin
2694               OldColor := Palette.CurrentColor;
2695               // now set our fpalette ColorRef from LCL
2696               if LCLObject.Color <> clDefault then
2697               begin
2698                 ColorRef := ColorToRGB(LCLObject.Color);
2699                 QColor_fromRgb(@QColor,Red(ColorRef),Green(ColorRef),Blue(ColorRef));
2700               end else
2701                 QColor := Palette.DefaultColor;
2702               if not EqualTQColor(OldColor, QColor) then
2703               begin
2704                 Palette.ReloadPaletteBegin;
2705                 try
2706                   SetColor(@QColor);
2707                   Result := True;
2708                   QEvent_accept(Event);
2709                 finally
2710                   Palette.ReloadPaletteEnd;
2711                 end;
2712               end;
2713             end;
2714           end;
2715         QEventQueryWhatsThis: Result := True;
2716         QEventWhatsThis:
2717           begin
2718             SlotWhatsThis(Sender, Event);
2719             // TODO: we need to stop event by Result := True; but then we also need
2720             // to ask qt to leave Whats This mode. Currently we have no means to do so
2721           end;
2722         QEventLCLMessage:
2723           begin
2724             SlotLCLMessage(Sender, Event);
2725             Result := True;
2726           end;
2727       else
2728         QEvent_ignore(Event);
2729       end;
2730     end
2731     else
2732       QEvent_ignore(Event);
2733 
2734     {fixes #14544 and others when we loose our LCLObject
2735      after delivering message to LCL.}
2736     if (LCLObject = nil) and
2737        ((QEvent_type(Event) = QEventMouseButtonPress) or
2738        (QEvent_type(Event) = QEventMouseButtonRelease) or
2739        (QEvent_type(Event) = QEventMouseButtonDblClick) or
2740        (QEvent_type(Event) = QEventMouseMove) or
2741        (QEvent_type(Event) = QEventHoverEnter) or
2742        (QEvent_type(Event) = QEventHoverLeave) or
2743        (QEvent_type(Event) = QEventHoverMove) or
2744        (QEvent_type(Event) = QEventKeyPress) or
2745        (QEvent_type(Event) = QEventKeyRelease)) then
2746       Result := True;
2747   finally
2748     EndEventProcessing;
2749   end;
2750 end;
2751 
getAcceptDropFilesnull2752 function TQtWidget.getAcceptDropFiles: Boolean;
2753 var
2754   Form: TCustomForm;
2755 begin
2756   Result := False;
2757   Form := GetParentForm(LCLObject);
2758   if Assigned(Form) and (Form.HandleAllocated) then
2759     Result := TQtMainWindow(Form.Handle).getAcceptDropFiles;
2760 end;
2761 
measureTextnull2762 function TQtWidget.measureText(AText: WideString; AFlags: cardinal): TRect;
2763 var
2764   AMetrics: QFontMetricsH;
2765   AFont: QFontH;
2766 begin
2767   Result := Rect(0, 0, 0, 0);
2768   if Assigned(LCLObject) and Assigned(LCLObject.Font) and
2769     LCLObject.Font.HandleAllocated then
2770       AFont := TQtFont(LCLObject.Font.Reference.Handle).FHandle
2771   else
2772     AFont := QWidget_font(Widget);
2773   AMetrics := QFontMetrics_create(AFont);
2774   try
2775     QFontMetrics_boundingRect(AMetrics, @Result, @AText);
2776   finally
2777     QFontMetrics_destroy(AMetrics);
2778   end;
2779 end;
2780 
2781 procedure TQtWidget.SetNoMousePropagation(Sender: QWidgetH;
2782   const ANoMousePropagation: Boolean);
2783 begin
2784   QWidget_setAttribute(Sender, QtWA_NoMousePropagation, ANoMousePropagation);
2785 end;
2786 
2787 {------------------------------------------------------------------------------
2788   Function: TQtWidget.SetLCLFont
2789   Params:  None
2790   Returns: Nothing
2791   Sets FWidgetLCLFont , font which is different from FWidgetDefaultFont
2792   so we can keep track over it inside QEventFontChange.
2793   This routine does nothing if called outside of TQtWSControl.SetFont,
2794   since qtwdFontUpdating must be in WidgetState
2795  ------------------------------------------------------------------------------}
2796 procedure TQtWidget.SetLCLFont(AFont: TQtFont);
2797 begin
2798   if not (qtwsFontUpdating in FWidgetState) then
2799     exit;
2800   if Assigned(FWidgetLCLFont) then
2801     FreeThenNil(FWidgetLCLFont);
2802   if not IsFontEqual(FWidgetDefaultFont, AFont) and (AFont.FHandle <> nil) then
2803     FWidgetLCLFont := TQtFont.Create(AFont.FHandle);
2804 end;
2805 
2806 {------------------------------------------------------------------------------
2807   Function: TQtWidget.SlotShow
2808   Params:  None
2809   Returns: Nothing
2810  ------------------------------------------------------------------------------}
2811 procedure TQtWidget.SlotShow(vShow: Boolean); cdecl;
2812 var
2813   Msg: TLMShowWindow;
2814 begin
2815   {$ifdef VerboseQt}
2816     WriteLn('TQtWidget.SlotShow Name', LCLObject.Name, ' vShow: ', dbgs(vShow));
2817   {$endif}
2818 
2819   {do not pass message to LCL if LCL setted up control visibility}
2820   if inUpdate then
2821     exit;
2822 
2823   FillChar(Msg{%H-}, SizeOf(Msg), #0);
2824 
2825   Msg.Msg := LM_SHOWWINDOW;
2826   Msg.Show := vShow;
2827 
2828   DeliverMessage(Msg);
2829 end;
2830 
2831 {------------------------------------------------------------------------------
2832   Function: TQtWidget.Close
2833   Params:  None
2834   Returns: Nothing
2835 
2836   Note: LCL uses LM_CLOSEQUERY to set the form visibility and if we don�t send this
2837  message, you won�t be able to show a form twice.
2838  ------------------------------------------------------------------------------}
SlotClosenull2839 function TQtWidget.SlotClose: Boolean; cdecl;
2840 var
2841   Msg : TLMessage;
2842 begin
2843   {$ifdef VerboseQt}
2844     WriteLn('TQtWidget.SlotClose');
2845   {$endif}
2846   FillChar(Msg{%H-}, SizeOf(Msg), 0);
2847 
2848   Msg.Msg := LM_CLOSEQUERY;
2849 
2850   DeliverMessage(Msg);
2851 
2852   Result := False;
2853 end;
2854 
2855 {------------------------------------------------------------------------------
2856   Function: TQtWidget.SlotDestroy
2857   Params:  None
2858   Returns: Nothing
2859 
2860   Currently commented because it was raising exception on software exit
2861  ------------------------------------------------------------------------------}
2862 procedure TQtWidget.SlotDestroy; cdecl;
2863 var
2864   Msg: TLMessage;
2865 begin
2866   {$ifdef VerboseQt}
2867     WriteLn('TQtWidget.SlotDestroy');
2868   {$endif}
2869 
2870   FillChar(Msg{%H-}, SizeOf(Msg), #0);
2871   Msg.Msg := LM_DESTROY;
2872   DeliverMessage(Msg);
2873   Release;
2874 end;
2875 
slotDropFilesnull2876 function TQtWidget.slotDropFiles(Sender: QObjectH; Event: QEventH): Boolean;
2877 var
2878   MimeData: QMimeDataH;
2879   QStrList: QStringListH;
2880   ByteArr: QByteArrayH;
2881   i: Integer;
2882   WStr: WideString;
2883   GotFiles: Boolean;
2884   FilesList: TStrings;
2885   Files: Array of String;
2886   ParentForm: TCustomForm;
2887   Url: QUrlH;
2888 begin
2889   Result := False;
2890   GotFiles := False;
2891   MimeData := QDropEvent_mimeData(QDropEventH(Event));
2892   QStrList := QStringList_create();
2893   try
2894     QMimeData_formats(MimeData, QStrList);
2895     for i := QStringList_size(QStrList) - 1 downto 0 do
2896     begin
2897       QStringList_at(QStrList, @WStr, i);
2898       GotFiles := (WStr = 'text/plain') or (WStr = 'text/uri-list');
2899       if GotFiles then
2900         break;
2901     end;
2902   finally
2903     QStringList_destroy(QStrList);
2904   end;
2905   if not GotFiles then
2906     exit;
2907   ByteArr := QByteArray_create();
2908   try
2909     QMimeData_data(MimeData, ByteArr, @WStr);
2910     if not QByteArray_isNull(ByteArr) then
2911     begin
2912       WStr := QByteArray_constData(ByteArr);
2913       FilesList := TStringList.Create;
2914       try
2915         FilesList.Text := WStr{%H-};
2916 
2917         if (FilesList.Count > 0) and
2918           ( (FilesList[FilesList.Count-1] = #0)
2919             or
2920             (FilesList[FilesList.Count-1] = '') ) then
2921           SetLength(Files, FilesList.Count - 1)
2922         else
2923           SetLength(Files, FilesList.Count);
2924         for i := 0 to High(Files) do
2925         begin
2926           WStr := FilesList{%H-}.Strings[i];
2927           Url := QUrl_create(@WStr);
2928           QUrl_toLocalFile(Url, @WStr);
2929           Files[i] := {%H-}WStr;
2930           QUrl_destroy(Url);
2931         end;
2932       finally
2933         FilesList.Free;
2934       end;
2935       QDropEvent_setDropAction(QDropEventH(Event), QtCopyAction);
2936       QDropEvent_acceptProposedAction(QDropEventH(Event));
2937 
2938       Application.IntfDropFiles(Files);
2939       if ClassType = TQtMainWindow then
2940         TCustomForm(LCLObject).IntfDropFiles(Files)
2941       else
2942       begin
2943         ParentForm := TCustomForm(LCLObject.IntfGetDropFilesTarget);
2944         if ParentForm is TCustomForm then
2945           ParentForm.IntfDropFiles(Files);
2946       end;
2947 
2948       Result := True;
2949     end;
2950   finally
2951     QByteArray_destroy(ByteArr);
2952   end;
2953 end;
2954 
SlotHovernull2955 function TQtWidget.SlotHover(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
2956 var
2957   Msg: TLMessage;
2958   MouseMsg: TLMMouseMove absolute Msg;
2959   MousePos: TQtPoint;
2960 begin
2961   Result := False;
2962   if not CanSendLCLMessage then
2963     Exit(True);
2964 
2965   if (QApplication_mouseButtons() = 0) and
2966      not QWidget_hasMouseTracking(QWidgetH(Sender)) then // in other case MouseMove will be hooked
2967   begin
2968     FillChar(Msg{%H-}, SizeOf(Msg), #0);
2969 
2970     MousePos := QHoverEvent_pos(QHoverEventH(Event))^;
2971     OffsetMousePos(@MousePos);
2972 
2973     case QEvent_type(Event) of
2974       QEventHoverEnter: Msg.Msg := LM_MOUSEENTER;
2975       QEventHoverLeave: Msg.Msg := LM_MOUSELEAVE;
2976       QEventHoverMove:
2977         begin
2978           MouseMsg.Msg := LM_MOUSEMOVE;
2979           MouseMsg.XPos := SmallInt(MousePos.X);
2980           MouseMsg.YPos := SmallInt(MousePos.Y);
2981         end;
2982     end;
2983     NotifyApplicationUserInput(LCLObject, Msg.Msg);
2984     if not CanSendLCLMessage then
2985       exit(True);
2986     DeliverMessage(Msg);
2987     SetNoMousePropagation(QWidgetH(Sender), True);
2988   end;
2989 end;
2990 
2991 {------------------------------------------------------------------------------
2992   Function: TQtWidget.SlotKey
2993   Params:  None
2994   Returns: Nothing
2995  ------------------------------------------------------------------------------}
SlotKeynull2996 function TQtWidget.SlotKey(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
2997 const
2998   CN_KeyDownMsgs: array[Boolean] of UINT = (CN_KEYDOWN, CN_SYSKEYDOWN);
2999   CN_KeyUpMsgs: array[Boolean] of UINT = (CN_KEYUP, CN_SYSKEYUP);
3000   LM_KeyDownMsgs: array[Boolean] of UINT = (LM_KEYDOWN, LM_SYSKEYDOWN);
3001   LM_KeyUpMsgs: array[Boolean] of UINT = (LM_KEYUP, LM_SYSKEYUP);
3002   CN_CharMsg: array[Boolean] of UINT = (CN_CHAR, CN_SYSCHAR);
3003   LM_CharMsg: array[Boolean] of UINT = (LM_CHAR, LM_SYSCHAR);
3004 var
3005   KeyMsg: TLMKey;
3006   CharMsg: TLMChar;
3007   Modifiers: QtKeyboardModifiers;
3008   IsSysKey: Boolean;
3009   Text: WideString;
3010   UTF8Text: String; // use to prevent 3 time convertion from WideString to utf8 string
3011   UTF8Char: TUTF8Char;
3012   ACharCode: Word;
3013   AKeyCode: Word;
3014   LCLModifiers: Word;
3015   {$IFDEF UNIX}
3016   ScanCode: LongWord;
3017   {$ENDIF}
3018   AChar: Char;
3019   AKeyEvent: QKeyEventH;
3020   GlobalAction: Integer;
3021   {$IFDEF VerboseQtKeys}
3022   s: String;
3023   s1: String;
3024   NativeModifiers: LongWord;
3025   {$ENDIF}
3026 
3027   function IsControlKey: Boolean;
3028   var
3029     AQtKey: Cardinal;
3030   begin
3031     // do not send UTF8KeyPress for control keys
3032     AQtKey := QKeyEvent_key(QKeyEventH(Event));
3033 
3034     // Enter, Return and Backspace should be sent to LCL in UTF8KeyPress,
3035     // so skip them here
3036 
3037     Result := (AQtKey = QtKey_Backtab) or // issue #35448
3038       // ((AQtKey >= QtKey_Escape) and (AQtKey <= QtKey_Backtab)) or
3039       ((AQtKey >= QtKey_Insert) and (AQtKey <= QtKey_Clear)) or
3040       ((AQtKey >= QtKey_Home) and (AQtKey <= QtKey_PageDown)) or
3041       ((AQtKey >= QtKey_F1) and (AQtKey <= QtKey_Direction_L)) or
3042       (AQtKey = QtKey_Direction_R);
3043   end;
3044 
3045   function EatArrowKeys: Boolean;
3046   var
3047     AQtKey: Cardinal;
3048   begin
3049     AQtKey := QKeyEvent_key(QKeyEventH(Event));
3050     Result := not ProcessArrowKeys and ((AQtKey = QtKey_Left) or (AQtKey = QtKey_Right)
3051       or (AQtKey = QtKey_Up) or (AQtKey = QtKey_Down));
3052   end;
3053 
3054   function SendChangedKey: boolean;
3055   begin
3056     if UTF8Char <> UTF8Text then
3057       Text := UTF8ToUTF16(Utf8Char)
3058     else
3059     if Word(AChar) <> CharMsg.CharCode then
3060       Text := Char(CharMsg.CharCode);
3061 
3062     AKeyEvent := QKeyEvent_createExtendedKeyEvent(
3063       QEvent_type(Event),
3064       LCLKeyToQtKey(KeyMsg.CharCode),
3065       Modifiers,
3066       0,
3067       KeyMsg.CharCode,
3068       0,
3069       @Text,
3070       QKeyEvent_isAutoRepeat(QKeyEventH(Event)),
3071       QKeyEvent_count(QKeyEventH(Event))
3072       );
3073     try
3074       Result := QObject_event(Sender, AKeyEvent);
3075     finally
3076       QKeyEvent_destroy(AKeyEvent);
3077     end;
3078 
3079   end;
3080 
3081 begin
3082   {$ifdef VerboseQt}
3083     DebugLn('TQtWidget.SlotKey ', dbgsname(LCLObject));
3084   {$endif}
3085 
3086   Result := True;
3087 
3088   if not CanSendLCLMessage then
3089     exit;
3090 
3091   FillChar(KeyMsg{%H-}, SizeOf(KeyMsg), #0);
3092   FillChar(CharMsg{%H-}, SizeOf(CharMsg), #0);
3093   UTF8Text := '';
3094   UTF8Char := '';
3095   AChar := #0;
3096 
3097   // Detects special keys (shift, alt, control, etc)
3098   Modifiers := QKeyEvent_modifiers(QKeyEventH(Event));
3099   {$IFDEF HASX11}
3100   //qt reports WRONG combination under X11 sometimes when Shift + LeftAlt
3101   //are pressed, so we must fix modifiers, ssMeta will be reported in keys.
3102   if (QtShiftModifier and Modifiers <> 0) and (QtMetaModifier and Modifiers <> 0) then
3103   begin
3104     if (QtAltModifier and Modifiers = 0) and
3105       (QKeyEvent_nativeVirtualKey(QKeyEventH(Event)) = XK_Meta_L) then
3106         Modifiers := (Modifiers and not QtMetaModifier) or QtAltModifier;
3107   end;
3108   {$ENDIF}
3109   IsSysKey := (QtAltModifier and Modifiers) <> $0;
3110 
3111   AKeyCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
3112 
3113   LCLModifiers := QtKeyModifiersToKeyState(Modifiers, True, QKeyEventH(Event));
3114 
3115   if QKeyEvent_isAutoRepeat(QKeyEventH(Event)) then
3116     LCLModifiers := LCLModifiers or KF_REPEAT;
3117 
3118   if QEvent_type(Event) = QEventKeyRelease then
3119     LCLModifiers := LCLModifiers or KF_UP;
3120 
3121   {$ifdef windows}
3122   ACharCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
3123   KeyMsg.CharCode := ACharCode;
3124   if (Modifiers = QtAltModifier or QtControlModifier) then
3125   begin
3126     if (QtWidgetSet.GetWinKeyState(VK_RMENU) < 0) and
3127       (QtWidgetSet.GetWinKeyState(VK_LCONTROL) < 0) then
3128     begin
3129       IsSysKey := False;
3130       LCLModifiers := 0;
3131       Modifiers := QtGroupSwitchModifier;
3132 
3133       if QKeyEvent_isAutoRepeat(QKeyEventH(Event)) then
3134         LCLModifiers := LCLModifiers or KF_REPEAT;
3135 
3136       if QEvent_type(Event) = QEventKeyRelease then
3137         LCLModifiers := LCLModifiers or KF_UP;
3138     end;
3139   end;
3140   {$endif}
3141   KeyMsg.KeyData := PtrInt((AKeyCode shl 16) or (LCLModifiers shl 16) or $0001);
3142 
3143   // Loads the UTF-8 character associated with the keypress, if any
3144   QKeyEvent_text(QKeyEventH(Event), @Text);
3145 
3146   {$IFDEF DARWIN}
3147   // qt on mac passes #3 instead of #13 when QtKey_Enter (numpad) is pressed
3148   // so our keypress get wrong about key. issue #20896
3149   if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Enter) and (length(Text) = 1) then
3150     Text := #13;
3151 
3152   ScanCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
3153   {$IFDEF VerboseQtKeys}
3154   // ScanCode := QKeyEvent_key(QKeyEventH(Event));
3155   writeln('!!!**** NATIVEVIRTUALKEY=',ScanCode,' lenText=',length(Text),' Modifiers ',Modifiers,' AKEYCODE=',AKeyCode);
3156   {$ENDIF}
3157 
3158   // set groupswitch for Shift+Option.
3159   if (length(Text) = 1) and
3160     ((Modifiers = QtAltModifier or QtShiftModifier) or ((Modifiers = QtAltModifier) and (ScanCode > 0))) then
3161   begin
3162     ScanCode := QKeyEvent_key(QKeyEventH(Event));
3163     // Arrow keys are reserved by macOSX keyboard commands
3164     // http://support.apple.com/kb/ht1343
3165     if (ScanCode <> QtKey_Left) and (ScanCode <> QtKey_Up) and
3166       (ScanCode <> QtKey_Right) and (ScanCode <> QtKey_Down) then
3167     begin
3168       Modifiers := QtGroupSwitchModifier;
3169       LCLModifiers := QtKeyModifiersToKeyState(Modifiers, True, QKeyEventH(Event));
3170       KeyMsg.KeyData := PtrInt((LCLModifiers shl 16) or $0001);
3171       IsSysKey := False; // was true above
3172     end;
3173     ScanCode := 0;
3174   end;
3175   {$ENDIF}
3176 
3177   {$IFDEF VerboseQtKeys}
3178   writeln('> TQtWidget.SlotKey dump begin event=',EventTypeToStr(Event),' IsSysKey ',IsSysKey);
3179 
3180   S := '';
3181   if Modifiers and QtShiftModifier <> 0 then
3182     S := 'SHIFT,';
3183   if Modifiers and QtControlModifier <> 0 then
3184     S := S + 'CONTROL,';
3185 
3186   if Modifiers and QtAltModifier <> 0 then
3187     S := S + 'ALT,';
3188 
3189   if Modifiers and QtMetaModifier <> 0 then
3190     S := S + 'META,';
3191 
3192   if Modifiers and QtKeypadModifier <> 0 then
3193     S := S + 'KEYPAD,';
3194 
3195   if Modifiers and QtGroupSwitchModifier <> 0 then
3196     S := S + 'GROUPSWITCH,';
3197 
3198   if Modifiers and QtKeyboardModifierMask <> 0 then
3199     S := S + 'KEYBOARDMODIFIERMASK,';
3200 
3201   if S <> '' then
3202     Delete(S, length(S), 1)
3203   else
3204     S := 'NONE';
3205 
3206 
3207   NativeModifiers := QKeyEvent_NativeModifiers(QKeyEventH(Event));
3208   S1 := '';
3209 
3210   if NativeModifiers and QtShiftModifier <> 0 then
3211     S1 := 'SHIFT,';
3212   if NativeModifiers and QtControlModifier <> 0 then
3213     S1 := S1 + 'CONTROL,';
3214 
3215   if NativeModifiers and QtAltModifier <> 0 then
3216     S1 := S1 + 'ALT,';
3217 
3218   if NativeModifiers and QtMetaModifier <> 0 then
3219     S1 := S1 + 'META,';
3220 
3221   if NativeModifiers and QtKeypadModifier <> 0 then
3222     S1 := S1 + 'KEYPAD,';
3223 
3224   if NativeModifiers and QtGroupSwitchModifier <> 0 then
3225     S1 := S1 + 'GROUPSWITCH,';
3226 
3227   if NativeModifiers and QtKeyboardModifierMask <> 0 then
3228     S1 := S1 + 'KEYBOARDMODIFIERMASK,';
3229 
3230   if S1 <> '' then
3231     Delete(S1, length(S1), 1)
3232   else
3233     S1 := 'NONE';
3234 
3235   writeln(' KEY=',QKeyEvent_key(QKeyEventH(Event)),' COUNT=',
3236     QKeyEvent_count(QKeyEventH(Event)),' TEXT=',Text);
3237   writeln(' LCLKEY=',QtKeyToLCLKey(QKeyEvent_key(QKeyEventH(Event)), Text,
3238     QKeyEventH(Event)),' SPONTANEOUS ', QEvent_spontaneous(Event));
3239   writeln(' MODIFIERS: ',S,' NATIVEMODIFIERS: ',S1);
3240   writeln(' HASEXTENDEDINFO: ',QKeyEvent_hasExtendedInfo(QKeyEventH(Event)),
3241     ' ISAUTOREPEAT: ',QKeyEvent_isAutoRepeat(QKeyEventH(Event)));
3242   writeln(' NATIVESCANCODE: ',QKeyEvent_nativeScanCode(QKeyEventH(Event)),
3243     ' NATIVEVIRTUALKEY: ',QKeyEvent_nativeVirtualKey(QKeyEventH(Event)));
3244 
3245   writeln('Key compression ? ',
3246     QWidget_testAttribute(QWidgetH(Sender), QtWA_KeyCompression));
3247   writeln('< TQtWidget.SlotKey dump end event=',EventTypeToStr(Event));
3248   {$ENDIF}
3249 
3250   {we must intercept modifiers for main form menu (if any). issue #18709}
3251   if (Modifiers = QtAltModifier) then
3252   begin
3253     if (QApplication_activeModalWidget() = nil) and
3254       (QEvent_type(Event) <> QEventKeyRelease) and
3255       QtWidgetSet.ShortcutInGlobalActions('Alt+'+Text, GlobalAction) then
3256     begin
3257       QtWidgetSet.TriggerGlobalAction(GlobalAction);
3258       exit;
3259     end;
3260   end;
3261 
3262   {$note TQtWidget.SlotKey: this is workaround for Qt bug which reports
3263    wrong keys with Shift+Ctrl pressed. Fixes #13470.
3264    LAST REVISION: Qt-4.7.4 20111023 fc14. zeljko}
3265   {$IFDEF UNIX}
3266   {$IFDEF DARWIN}
3267   // under darwin we must use nativeVirtualKey since nativeScanCode
3268   // isn't returned under carbon and cocoa.
3269   if (QtVersionMajor = 4) and (QtVersionMinor >= 6) and
3270     (Modifiers = QtShiftModifier or QtControlModifier) then
3271   begin
3272     ScanCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
3273     if (length(Text) = 1) and (ScanCode in [10,18..23,25,26,28,29]) then
3274     begin
3275       if ScanCode = 10 then
3276         ScanCode := VK_UNDEFINED
3277       else
3278       if ScanCode in [18..21] then
3279         ScanCode := ScanCode + 31
3280       else
3281       if ScanCode = 23 then
3282         ScanCode := 53
3283       else
3284       if ScanCode = 22 then
3285         ScanCode := 54
3286       else
3287       if ScanCode = 26 then
3288         ScanCode := 55
3289       else
3290       if ScanCode = 28 then
3291         ScanCode := 56
3292       else
3293       if ScanCode = 25 then
3294         ScanCode := 57
3295       else
3296       if ScanCode = 29 then
3297         ScanCode := 48;
3298 
3299       KeyMsg.CharCode := Word(ScanCode);
3300       if (Modifiers = QtShiftModifier or QtControlModifier) then
3301         Text := '';
3302     end;
3303   end;
3304   {$ELSE}
3305   if (Modifiers = QtShiftModifier or QtControlModifier) or
3306     (Modifiers = QtShiftModifier) then
3307   begin
3308     ScanCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
3309     if (length(Text) = 1) and (ScanCode in [10..19]) then
3310     begin
3311       if ScanCode = 19 then
3312         ScanCode := 48
3313       else
3314         ScanCode := ScanCode + 39;
3315       KeyMsg.CharCode := Word(ScanCode);
3316       if (Modifiers = QtShiftModifier or QtControlModifier) then
3317         Text := '';
3318     end;
3319   end else
3320   if (Modifiers = QtShiftModifier or QtAltModifier) then
3321   begin
3322     ScanCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
3323     if (length(Text) = 1) and (ScanCode in [10..19]) then
3324     begin
3325       if ScanCode = 19 then
3326         ScanCode := 48
3327       else
3328         ScanCode := ScanCode + 39;
3329       KeyMsg.CharCode := Word(ScanCode);
3330       if (Modifiers = QtShiftModifier or QtAltModifier) then
3331         Text := '';
3332     end;
3333   end;
3334   {$ENDIF}
3335   {$ENDIF}
3336 
3337   // Translates a Qt4 Key to a LCL VK_* key
3338   if KeyMsg.CharCode = 0 then
3339   begin
3340     ACharCode := QtKeyToLCLKey(QKeyEvent_key(QKeyEventH(Event)), Text, QKeyEventH(Event));
3341     KeyMsg.CharCode := ACharCode;
3342   end;
3343 
3344   {------------------------------------------------------------------------------
3345    Sends the adequate key messages
3346    ------------------------------------------------------------------------------}
3347   case QEvent_type(Event) of
3348     QEventKeyPress: KeyMsg.Msg := CN_KeyDownMsgs[IsSysKey];
3349     QEventKeyRelease: KeyMsg.Msg := CN_KeyUpMsgs[IsSysKey];
3350   end;
3351 
3352   {$ifdef VerboseQt}
3353   WriteLn(' message CN_Keys: ', KeyMsg.Msg);
3354   {$endif}
3355   if KeyMsg.CharCode <> VK_UNKNOWN then
3356   begin
3357     NotifyApplicationUserInput(LCLObject, KeyMsg.Msg);
3358 
3359     if not CanSendLCLMessage or (Sender = nil) then
3360       exit;
3361 
3362     if (DeliverMessage(KeyMsg, True) <> 0) or (KeyMsg.CharCode=VK_UNKNOWN) then
3363     begin
3364   {$ifdef VerboseQt}
3365       WriteLn('handled CN_Keys');
3366   {$endif}
3367       Exit;
3368     end;
3369 
3370     if not CanSendLCLMessage or (Sender = nil) then
3371       exit;
3372 
3373     // here we should let widgetset to handle key
3374     //...
3375     case QEvent_type(Event) of
3376       QEventKeyPress: KeyMsg.Msg := LM_KeyDownMsgs[IsSysKey];
3377       QEventKeyRelease: KeyMsg.Msg := LM_KeyUpMsgs[IsSysKey];
3378     end;
3379     {$ifdef VerboseQt}
3380     WriteLn(' message LM_Keys: ', KeyMsg.Msg);
3381     {$endif}
3382     if not EatArrowKeys then
3383     begin
3384       NotifyApplicationUserInput(LCLObject, KeyMsg.Msg);
3385 
3386       if not CanSendLCLMessage or (Sender = nil) then
3387         exit;
3388 
3389       if (DeliverMessage(KeyMsg, True) <> 0) or (KeyMsg.CharCode=VK_UNKNOWN) then
3390       begin
3391         // the LCL handled the key
3392         {$ifdef VerboseQt}
3393         WriteLn('handled LM_Keys');
3394         {$endif}
3395         Result := KeyMsg.CharCode=VK_UNKNOWN;
3396         Exit;
3397       end;
3398     end;
3399   end;
3400 
3401   { if our LCLObject dissappeared in the meantime just exit, otherwise
3402     we'll run into problems.}
3403   if not CanSendLCLMessage or (Sender = nil) then
3404     exit;
3405 
3406 
3407   { Also sends a utf-8 key event for key down }
3408   if (QEvent_type(Event) = QEventKeyPress) and (Length(Text) <> 0) then
3409   begin
3410     UTF8Text := {%H-}Text;
3411     UTF8Char := UTF8Text;
3412     {$ifdef VerboseQt}
3413     WriteLn('sending char ', UTF8Char);
3414     {$endif}
3415     if not IsControlKey and LCLObject.IntfUTF8KeyPress(UTF8Char, 1, IsSysKey) then
3416     begin
3417       // the LCL has handled the key
3418       {$ifdef VerboseQt}
3419       WriteLn('handled!');
3420       {$endif}
3421       Exit;
3422     end;
3423 
3424     if not CanSendLCLMessage or (Sender = nil) then
3425       exit;
3426 
3427     if (UTF8Char <> UTF8Text) then
3428     begin
3429       // process changed key and exit.
3430       // issue #26103
3431       SendChangedKey;
3432       exit;
3433     end;
3434 
3435     // create the CN_CHAR / CN_SYSCHAR message
3436     FillChar(CharMsg, SizeOf(CharMsg), 0);
3437     CharMsg.Msg := CN_CharMsg[IsSysKey];
3438     CharMsg.KeyData := KeyMsg.KeyData;
3439     AChar := Text[1];
3440     CharMsg.CharCode := Word(AChar);
3441 
3442     //Send message to LCL
3443     {$ifdef VerboseQt}
3444     WriteLn(' message: ', CharMsg.Msg);
3445     {$endif}
3446     NotifyApplicationUserInput(LCLObject, CharMsg.Msg);
3447 
3448     if not CanSendLCLMessage or (Sender = nil) then
3449       exit;
3450 
3451     if (DeliverMessage(CharMsg, True) <> 0) or (CharMsg.CharCode = VK_UNKNOWN) then
3452     begin
3453       // the LCL has handled the key
3454       {$ifdef VerboseQt}
3455       WriteLn('handled!');
3456       {$endif}
3457       Exit;
3458     end;
3459 
3460     //Here is where we (interface) can do something with the key
3461     //...
3462 
3463     //Send a LM_(SYS)CHAR
3464     CharMsg.Msg := LM_CharMsg[IsSysKey];
3465 
3466     {$ifdef VerboseQt}
3467     WriteLn(' message: ', CharMsg.Msg);
3468     {$endif}
3469     if not CanSendLCLMessage or (Sender = nil) then
3470       exit;
3471 
3472     NotifyApplicationUserInput(LCLObject, CharMsg.Msg);
3473 
3474     if not CanSendLCLMessage or (Sender = nil) then
3475       exit;
3476 
3477     DeliverMessage(CharMsg, True);
3478     if not CanSendLCLMessage or (Sender = nil) then
3479       exit;
3480   end;
3481 
3482   // check if data was changed during key handling
3483   if CanSendLCLMessage and (Sender <> nil) and
3484     ((KeyMsg.CharCode <> ACharCode) or (UTF8Char <> UTF8Text) or
3485       (Word(AChar) <> CharMsg.CharCode)) then
3486   begin
3487     // data was changed
3488     // moved to nested proc because of issue #26103
3489     SendChangedKey;
3490   end else
3491   begin
3492     Result := KeyMsg.CharCode in KeysToEat;
3493   end;
3494 end;
3495 
TQtWidget.SlotInputMethodnull3496 function TQtWidget.SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3497 var
3498   InputEvent: QInputMethodEventH;
3499   WStr: WideString;
3500   UnicodeChar: Cardinal;
3501   UnicodeOutLen: integer;
3502   KeyEvent: QKeyEventH;
3503 begin
3504   Result := True;
3505   if not (QEvent_type(Event) = QEventInputMethod) then Exit;
3506   {$ifdef VerboseQt}
3507     DebugLn('TQtWidget.SlotInputMethod ', dbgsname(LCLObject));
3508   {$endif}
3509   InputEvent := QInputMethodEventH(Event);
3510   QInputMethodEvent_commitString(InputEvent, @WStr);
3511   UnicodeChar := UTF8CodepointToUnicode(PChar(WStr), UnicodeOutLen);
3512   {$IFDEF VerboseQtKeys}
3513   writeln('> TQtWidget.SlotInputMethod ',dbgsname(LCLObject),' event=QEventInputMethod:');
3514   writeln('   commmitString ',WStr,' len ',length(WStr),' UnicodeChar ',UnicodeChar,
3515     ' UnicodeLen ',UnicodeOutLen);
3516   writeln('   sending QEventKeyPress');
3517   {$ENDIF}
3518 
3519   KeyEvent := QKeyEvent_create(QEventKeyPress, Integer(UnicodeChar), QApplication_keyboardModifiers, @WStr, False, 1);
3520   try
3521     // do not send it to queue, just pass it to SlotKey
3522     Result := SlotKey(Sender, KeyEvent);
3523   finally
3524     QKeyEvent_destroy(KeyEvent);
3525   end;
3526   {$IFDEF VerboseQtKeys}
3527   writeln('< TQtWidget.SlotInputMethod End: ',dbgsname(LCLObject),' event=QEventInputMethod, sent QEventKeyPress');
3528   {$ENDIF}
3529 end;
3530 
3531 {------------------------------------------------------------------------------
3532   Function: TQtWidget.SlotMouse
3533   Params:  None
3534   Returns: Nothing
3535  ------------------------------------------------------------------------------}
TQtWidget.SlotMousenull3536 function TQtWidget.SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3537 var
3538   Msg: TLMMouse;
3539   MousePos: TQtPoint;
3540   MButton: QTMouseButton;
3541   Modifiers: QtKeyboardModifiers;
3542   SaveWidget: QWidgetH;
3543   LazButton: Byte;
3544   LazPos: TPoint;
3545 
isTransparentForMousenull3546   function isTransparentForMouse: boolean;
3547   begin
3548     Result := testAttribute(QtWA_TransparentForMouseEvents) and
3549       (Self is TQtMainWindow) and not TQtMainWindow(Self).IsMdiChild;
3550   end;
3551 
HandleTransparentForMousenull3552   function HandleTransparentForMouse: boolean;
3553   var
3554     AWidgetAt: QWidgetH;
3555     AMouseEvent, ANewEvent: QMouseEventH;
3556     AWnd: HWND;
3557     AContextEvent: QContextMenuEventH;
3558     AMousePos, APos: TQtPoint;
3559     AEventOk: boolean;
3560   begin
3561     Result := False;
3562     {issue #30232}
3563     if isTransparentForMouse then
3564     begin
3565       Result := True;
3566       AMouseEvent := QMouseEventH(Event);
3567       AMousePos := QMouseEvent_globalPos(AMouseEvent)^;
3568       AWidgetAt := QApplication_widgetAt(@AMousePos);
3569       {TODO: check what happens if pure form is transparent for mouse events.}
3570       if AWidgetAt = nil then
3571         AWidgetAt := QApplication_activeModalWidget;
3572       if AWidgetAt = nil then
3573         AWidgetAt := QApplication_activeWindow;
3574 
3575       APos := QMouseEvent_pos(AMouseEvent)^;
3576 
3577       if AWidgetAt <> nil then
3578         QWidget_mapFromGlobal(AWidgetAt, @APos, @AMousePos);
3579 
3580       ANewEvent := QMouseEvent_create(QEvent_type(Event), @APos,
3581         QMouseEvent_globalPos(AMouseEvent), QMouseEvent_button(AMouseEvent),
3582           QMouseEvent_buttons(AMouseEvent), QInputEvent_modifiers(QInputEventH(Event)));
3583       QEvent_accept(Event);
3584       AEventOk := QCoreApplication_sendEvent(AWidgetAt, ANewEvent);
3585       QEvent_destroy(ANewEvent);
3586 
3587       if AEventOk and Assigned(AWidgetAt) then
3588       begin
3589         if (QWidget_focusPolicy(AWidgetAt) > QtNoFocus) and QWidget_isVisible(AWidgetAt) and
3590           QWidget_isEnabled(AWidgetAt) then
3591             QWidget_setFocus(AWidgetAt, QtMouseFocusReason);
3592         AWnd := HwndFromWidgetH(AWidgetAt);
3593         if (AWnd <> 0) and Assigned(TQtWidget(AWnd).LCLObject) and
3594           (QEvent_type(Event) <> QEventMouseButtonRelease) then
3595         begin
3596           if (QMouseEvent_button(QMouseEventH(Event)) = QtRightButton) then
3597           begin
3598             AContextEvent := QContextMenuEvent_create(QContextMenuEventMouse, @APos, QMouseEvent_globalPos(AMouseEvent),
3599               QInputEvent_modifiers(QInputEventH(Event)));
3600             QCoreApplication_sendEvent(AWidgetAt, AContextEvent);
3601             QEvent_destroy(AContextEvent);
3602           end;
3603           if ((Sender <> nil) and not QWidget_isVisible(QWidgetH(Sender))) or (Sender = nil) then
3604           begin
3605             ANewEvent := QMouseEvent_create(QEventMouseButtonRelease, @APos,
3606               QMouseEvent_globalPos(AMouseEvent), QMouseEvent_button(AMouseEvent),
3607                 QMouseEvent_buttons(AMouseEvent), QInputEvent_modifiers(QInputEventH(Event)));
3608             QEvent_accept(Event);
3609             QCoreApplication_sendEvent(AWidgetAt, ANewEvent);
3610             QEvent_destroy(ANewEvent);
3611           end;
3612         end;
3613       end;
3614       exit;
3615     end;
3616   end;
3617 
3618 begin
3619   {$ifdef VerboseQt}
3620     WriteLn('TQtWidget.SlotMouse');
3621   {$endif}
3622 
3623   Result := False; // allow qt to handle message
3624 
3625   if not CanSendLCLMessage then
3626     exit(True);
3627 
3628   if (LCLObject <> nil) and
3629     (not (csDesigning in LCLObject.ComponentState) and not getEnabled) then
3630     Exit;
3631 
3632   // idea of multi click implementation is taken from gtk
3633 
3634   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3635 
3636   MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
3637   OffsetMousePos(@MousePos);
3638 
3639   Modifiers := QInputEvent_modifiers(QInputEventH(Event));
3640   Msg.Keys := QtKeyModifiersToKeyState(Modifiers, False, nil);
3641 
3642   Msg.XPos := SmallInt(MousePos.X);
3643   Msg.YPos := SmallInt(MousePos.Y);
3644 
3645   MButton := QMouseEvent_Button(QMouseEventH(Event));
3646   LazPos := Point(MousePos.X, MousePos.Y);
3647   case MButton of
3648     QtLeftButton: LazButton := 1;
3649     QtRightButton: LazButton := 2;
3650     QtMidButton: LazButton := 3;
3651     QtXButton1, QtXButton2: LazButton := 4;
3652     else Exit; // Sometimes mouse wheel triggers an invalid button value. Ignore it.
3653   end;
3654   // do not pass mouse button into keys (TShiftState). issue #20916
3655   if (QEvent_type(Event) <> QEventMouseButtonRelease)
3656   or (((MButton and QtLeftButton) = 0) and ((MButton and QtRightButton) = 0) and
3657       ((MButton and QtMidButton) = 0))
3658   then
3659     Msg.Keys := Msg.Keys or QtButtonsToLCLButtons(MButton);
3660   Msg.Msg := CheckMouseButtonDownUp(TLCLIntfHandle(Self), LCLObject, LastMouse, LazPos, LazButton,
3661     QEvent_type(Event) in [QEventMouseButtonPress, QEventMouseButtonDblClick]);
3662   case LastMouse.ClickCount of
3663     2: Msg.Keys := Msg.Keys or MK_DOUBLECLICK;
3664     3: Msg.Keys := Msg.Keys or MK_TRIPLECLICK;
3665     4: Msg.Keys := Msg.Keys or MK_QUADCLICK;
3666   end;
3667 
3668   case QEvent_type(Event) of
3669     QEventMouseButtonPress, QEventMouseButtonDblClick:
3670     begin
3671       {$IFDEF MSWINDOWS}
3672       if (QEvent_type(Event) = QEventMouseButtonPress) and
3673           (MButton = QtRightButton) then
3674         Include(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
3675       try
3676       {$ENDIF}
3677       NotifyApplicationUserInput(LCLObject, Msg.Msg);
3678 
3679       if not CanSendLCLMessage or (Sender = nil) then
3680         exit(True);
3681 
3682       DeliverMessage(Msg, True);
3683 
3684       {$IFDEF MSWINDOWS}
3685       finally
3686         if (QEvent_type(Event) = QEventMouseButtonPress) and
3687           (MButton = QtRightButton) then
3688         begin
3689           Exclude(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
3690           Exclude(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
3691         end;
3692       end;
3693       {$ENDIF}
3694 
3695       // Check if our objects exists since LCL can destroy object during
3696       // mouse events...
3697       if CanSendLCLMessage and (Sender <> nil) then
3698       begin
3699         if isTransparentForMouse then
3700         begin
3701           SetNoMousePropagation(QWidgetH(Sender), False);
3702           Result := HandleTransparentForMouse;
3703         end else
3704           SetNoMousePropagation(QWidgetH(Sender), True)
3705       end else
3706         exit(True);
3707     end;
3708     QEventMouseButtonRelease:
3709     begin
3710       SaveWidget := nil;
3711       if (FChildOfComplexWidget = ccwCustomControl) and (FOwner <> nil) then
3712         SaveWidget := Widget;
3713 
3714       NotifyApplicationUserInput(LCLObject, Msg.Msg);
3715 
3716       if (SaveWidget <> nil) and (SaveWidget <> Widget) then
3717         exit(True);
3718 
3719       if not CanSendLCLMessage or (Sender = nil) then
3720         exit(True);
3721 
3722       DeliverMessage(Msg, True);
3723       if (SaveWidget <> nil) and (SaveWidget <> Widget) then
3724         exit(True);
3725 
3726       // Check if our objects exists since LCL can destroy object during
3727       // mouse events...
3728       if CanSendLCLMessage and (Sender <> nil) then
3729       begin
3730         if isTransparentForMouse then
3731         begin
3732           HandleTransparentForMouse;
3733           SetNoMousePropagation(QWidgetH(Sender), False);
3734         end else
3735           SetNoMousePropagation(QWidgetH(Sender), True);
3736       end else
3737         exit(True);
3738 
3739       { Clicking on buttons operates differently, because QEventMouseButtonRelease
3740         is sent if you click a control, drag the mouse out of it and release, but
3741         buttons should not be clicked on this case. }
3742       if CanSendLCLMessage and (Sender <> nil) and
3743         not (LCLObject is TCustomButton) then
3744       begin
3745         Msg.Msg := LM_CLICKED;
3746         DeliverMessage(Msg, True);
3747       end;
3748     end;
3749   end;
3750 end;
3751 
3752 procedure TQtWidget.SlotNCMouse(Sender: QObjectH; Event: QEventH); cdecl;
3753 var
3754   AHeader: TRect;
3755   APoint: TQtPoint;
3756 begin
3757   //Drag&Dock support TCustomForm => Start BeginDrag()
3758   if (LCLObject is TCustomForm) and
3759      not (csDesigning in LCLObject.ComponentState) and
3760      (TWinControlAccess(LCLObject).DragKind = dkDock) and
3761      (TWinControlAccess(LCLObject).DragMode = dmAutomatic) and
3762      (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
3763   begin
3764     APoint := QMouseEvent_globalPos(QMouseEventH(Event))^;
3765     AHeader := getGeometry;
3766     with getFrameGeometry do
3767       AHeader.Top := Top;
3768 
3769     // remove various buttons from header (how to request their pos cross platform?):
3770     Inc(AHeader.Left, 20);  // system menu
3771     Dec(AHeader.Right, 80); // close, min, max buttons
3772     if AHeader.Right < AHeader.Left then
3773       AHeader.Right := AHeader.Left + 1;
3774 
3775     // we can skip translation of coords to global since we already working with window
3776     // check for title
3777     if PtInRect(AHeader, Point(APoint.x, APoint.y)) then
3778       LCLObject.BeginDrag(true);
3779   end;
3780 end;
3781 
SlotMouseEnternull3782 function TQtWidget.SlotMouseEnter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3783 var
3784   Msg: TLMessage;
3785 begin
3786   Result := False;
3787   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3788   case QEvent_type(Event) of
3789     QEventEnter: Msg.Msg := LM_MOUSEENTER;
3790     QEventLeave: Msg.Msg := LM_MOUSELEAVE;
3791   end;
3792   DeliverMessage(Msg);
3793 end;
3794 
TQtWidget.QtButtonsToLCLButtonsnull3795 function TQtWidget.QtButtonsToLCLButtons(AButtons: QtMouseButton): PtrInt;
3796 begin
3797   Result := 0;
3798   if (QtLeftButton and AButtons) <> 0 then
3799     Result := Result or MK_LBUTTON;
3800 
3801   if (QtRightButton and AButtons) <> 0 then
3802     Result := Result or MK_RBUTTON;
3803 
3804   if (QtMidButton and AButtons) <> 0 then
3805     Result := Result or MK_MBUTTON;
3806 
3807   if (QtXButton1 and AButtons) <> 0 then
3808     Result := Result or MK_XBUTTON1;
3809 
3810   if (QtXButton2 and AButtons) <> 0 then
3811     Result := Result or MK_XBUTTON2;
3812 end;
3813 
QtKeyModifiersToKeyStatenull3814 function TQtWidget.QtKeyModifiersToKeyState(AModifiers: QtKeyboardModifiers;
3815   const AIsKeyEvent: Boolean; AEvent: QKeyEventH = nil): PtrInt;
3816 begin
3817 // TODO: remove AIsKeyEvent later
3818   Result := 0;
3819   if AModifiers and QtShiftModifier <> 0 then
3820     Result := Result or MK_SHIFT;
3821   if AModifiers and QtControlModifier <> 0 then
3822     Result := Result or MK_CONTROL;
3823   if AModifiers and QtAltModifier <> 0 then
3824   begin
3825     if AIsKeyEvent then
3826       Result := Result or KF_ALTDOWN
3827     else
3828       Result := Result or MK_ALT;
3829   end;
3830     // $20000000;
3831   { TODO: add support for ALT, META and NUMKEYPAD }
3832 end;
3833 
3834 {------------------------------------------------------------------------------
3835   Function: TQtWidget.SlotMouseMove
3836   Params:  None
3837   Returns: Nothing
3838  ------------------------------------------------------------------------------}
SlotMouseMovenull3839 function TQtWidget.SlotMouseMove(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3840 var
3841   Msg: TLMMouseMove;
3842   MousePos: TQtPoint;
3843   GlobPos: TQtPoint;
3844   R: TRect;
3845   P: TPoint;
3846   NewEvent: QEventH;
3847   W: QWidgetH;
3848   FrameBorder: Integer;
3849   TitleBarHeight: Integer;
3850   SenderWidget: QWidgetH;
3851   SavedLCLObject: PtrUint;
3852 begin
3853   Result := False;
3854   if not CanSendLCLMessage or (Sender = nil) or
3855     not QObject_isWidgetType(Sender) then
3856     Exit(True);
3857 
3858   SenderWidget := QWidgetH(Sender);
3859 
3860   if not (csCaptureMouse in LCLObject.ControlStyle) and
3861     not QWidget_isWindow(SenderWidget) and
3862     not DragManager.IsDragging then
3863   begin
3864     MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
3865     GlobPos := QMouseEvent_globalPos(QMouseEventH(Event))^;
3866 
3867     // get parent form, so check if mouse is out of parent form first.
3868     W := QWidget_window(SenderWidget);
3869 
3870     if W <> nil then
3871     begin
3872       QWidget_frameGeometry(W, @R);
3873 
3874       // exclude borders from frame
3875       FrameBorder := GetPixelMetric(QStylePM_DefaultFrameWidth, nil, W);
3876       TitleBarHeight := GetPixelMetric(QStylePM_TitleBarHeight, nil, W);
3877 
3878       inc(R.Left, FrameBorder);
3879       inc(R.Top, TitleBarHeight);
3880       dec(R.Right, FrameBorder);
3881       dec(R.Bottom, FrameBorder);
3882 
3883       P := Point(GlobPos.X, GlobPos.Y);
3884       if not PtInRect(R, P) then
3885         MousePos := QtPoint(-1, -1);
3886 
3887       if not QWidget_underMouse(SenderWidget) then
3888       begin
3889         if (MousePos.X >= 0) and (MousePos.Y >= 0) then
3890         begin
3891           QWidget_setAttribute(SenderWidget, QtWA_UnderMouse, True);
3892           NewEvent := QEvent_create(QEventEnter);
3893           QCoreApplication_postEvent(SenderWidget, NewEvent, 100);
3894         end;
3895       end;
3896     end;
3897 
3898     if not (csCaptureMouse in LCLObject.ControlStyle) and
3899       (QApplication_mouseButtons() <> QtNoButton) and
3900       (((MousePos.X < 0) or (MousePos.Y < 0)) or
3901       ((MousePos.X > getWidth) or (MousePos.Y > getHeight))) then
3902     begin
3903       if not QWidget_underMouse(SenderWidget) then
3904         exit;
3905       setCursor(FDefaultCursor);
3906       NewEvent := QEvent_create(QEventLeave);
3907       QCoreApplication_postEvent(SenderWidget, NewEvent, 100);
3908       exit;
3909     end;
3910   end;
3911 
3912   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3913 
3914   MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
3915   OffsetMousePos(@MousePos);
3916 
3917   Msg.XPos := SmallInt(MousePos.X);
3918   Msg.YPos := SmallInt(MousePos.Y);
3919 
3920   Msg.Keys := QtButtonsToLCLButtons(QMouseEvent_Buttons(QMouseEventH(Event)))
3921     or QtKeyModifiersToKeyState(QInputEvent_modifiers(QInputEventH(Event)), False, nil);
3922 
3923   Msg.Msg := LM_MOUSEMOVE;
3924 
3925   SetNoMousePropagation(SenderWidget, True);
3926   SavedLCLObject := PtrUInt(LCLObject);
3927 
3928   NotifyApplicationUserInput(LCLObject, Msg.Msg);
3929 
3930   if (SavedLCLObject <> PtrUInt(LCLObject)) or not CanSendLCLMessage then
3931     exit(True);
3932 
3933   DeliverMessage(Msg, True);
3934 
3935   if (SavedLCLObject <> PtrUInt(LCLObject)) or not CanSendLCLMessage then
3936     exit(True);
3937 end;
3938 
3939 {------------------------------------------------------------------------------
3940   Function: TQtWidget.SlotMouseWheel
3941   Params:  None
3942   Returns: Nothing
3943 
3944   Qt stores the delta in 1/8 of a degree
3945   Most mouses scroll 15 degrees each time
3946 
3947   Msg.WheelDelta: -1 for up, 1 for down
3948  ------------------------------------------------------------------------------}
SlotMouseWheelnull3949 function TQtWidget.SlotMouseWheel(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3950 var
3951   Msg: TLMMouseEvent;
3952   MousePos: TQtPoint;
3953   Modifiers: QtKeyboardModifiers;
3954   ModifierState: PtrInt;
3955   {$IFDEF DARWIN}
3956   CCtl: TQtAbstractScrollArea;
3957   {$ENDIF}
3958 begin
3959   Result := False;
3960   if not CanSendLCLMessage then
3961     exit;
3962 
3963   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3964 
3965   MousePos := QWheelEvent_Pos(QWheelEventH(Event))^;
3966   OffsetMousePos(@MousePos);
3967 
3968   Modifiers := QInputEvent_modifiers(QInputEventH(Event));
3969   Msg.State := [];
3970   ModifierState := QtKeyModifiersToKeyState(Modifiers, False, nil);
3971   if (ModifierState and MK_SHIFT) <> 0 then
3972     Msg.State := [ssShift];
3973   if (ModifierState and MK_CONTROL) <> 0 then
3974     Msg.State := [ssCtrl] + Msg.State;
3975   if (ModifierState and MK_ALT) <> 0 then
3976     Msg.State := [ssAlt] + Msg.State;
3977 
3978   LastMouse.WinControl := LCLObject;
3979   LastMouse.WinHandle := TLCLIntfHandle(Self);
3980   LastMouse.MousePos := Point(MousePos.X, MousePos.Y);
3981 
3982   Msg.X := SmallInt(MousePos.X);
3983   Msg.Y := SmallInt(MousePos.Y);
3984 
3985   Msg.WheelDelta := SmallInt(QWheelEvent_delta(QWheelEventH(Event)));
3986 
3987   Msg.Msg := LM_MOUSEWHEEL;
3988   if QWheelEvent_orientation(QWheelEventH(Event)) = QtHorizontal then
3989   begin
3990     Msg.Msg := LM_MOUSEHWHEEL;
3991     Msg.WheelDelta := -Msg.WheelDelta;
3992   end;
3993 
3994   {$IFDEF DARWIN}
3995   // LCL expects delta +-120, we must fix it. issue #20888
3996   if (ChildOfComplexWidget in [ccwCustomControl, ccwAbstractScrollArea,
3997       ccwScrollingWinControl]) then
3998   begin
3999     if (Msg.WheelDelta > 0) then
4000       Msg.WheelDelta := 1
4001     else
4002       Msg.WheelDelta := -1;
4003     Msg.WheelDelta := (120 * Msg.WheelDelta) div Mouse.WheelScrollLines;
4004     if FOwner <> nil then
4005     begin
4006       {$IFDEF QTSCROLLABLEFORMS}
4007       if (FOwner is TQtMainWindow) then
4008         CCtl := TQtMainWindow(FOwner).ScrollArea
4009       else
4010       {$ENDIF}
4011         CCtl := TQtAbstractScrollArea(FOwner);
4012     end else
4013       CCtl := TQtAbstractScrollArea(Self);
4014     //now fix ugly behaviour.
4015     if (Msg.WheelDelta > 0) and (CCtl.FVScrollbar.getVisible) and
4016         ((CCtl.FVScrollBar = Self) or
4017          (Assigned(CCtl.FVScrollbar) and (Self <> CCtl.FHScrollbar))) then
4018     begin
4019       if CCtl.FVScrollbar.getSliderPosition <= 1 then
4020         Msg.WheelDelta := 120;
4021     end;
4022   end;
4023   {$ENDIF}
4024 
4025   NotifyApplicationUserInput(LCLObject, Msg.Msg);
4026 
4027   if not CanSendLCLMessage then
4028     exit(True);
4029 
4030   Result := DeliverMessage(Msg, True) <> 0;
4031 
4032   if not CanSendLCLMessage then
4033     exit(True);
4034 
4035   SetNoMousePropagation(QWidgetH(Sender), False);
4036 
4037   {propagate mousewheel to parent if our sender is TPanel,
4038    fixes problem with mousewheel scroll with lazreport}
4039   if (LCLObject <> nil) and
4040     not (csDesigning in LCLObject.ComponentState) and
4041     (LCLObject is TPanel) and
4042     Assigned(LCLObject.Parent) then
4043       Result := TQtWidget(LCLObject.Parent.Handle).DeliverMessage(Msg) <> 0;
4044 end;
4045 
4046 procedure TQtWidget.SlotMove(Event: QEventH); cdecl;
4047 var
4048   Msg: TLMMove;
4049   APos: TQtPoint;
4050   {$IFDEF HASX11}
4051   ACurrPos: TQtPoint;
4052   {$ENDIF}
4053   FrameRect, WindowRect: TRect;
4054   ForceSendMove: boolean;
4055 begin
4056   {$ifdef VerboseQt}
4057     WriteLn('TQtWidget.SlotMove');
4058   {$endif}
4059 
4060   if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
4061     QtWidgetSet.InvalidateWidgetAtCache;
4062   // do not loop with LCL
4063   if InUpdate then
4064     exit;
4065 
4066   ForceSendMove := False; {mantis #34589}
4067   if not QEvent_spontaneous(Event) and Assigned(LCLObject) and Assigned(LCLObject.Parent) then
4068     // only children of 1st level should move.
4069     ForceSendMove := qtwsForceSendMove in TQtWidget(LCLObject.Parent.Handle).WidgetState;
4070 
4071   if ForceSendMove then
4072     // send message mantis #34589
4073   else
4074   if not QEvent_spontaneous(Event) or
4075     (not QEvent_spontaneous(Event) and
4076     ((Self is TQtMainWindow) and not
4077     TQtMainWindow(Self).IsMdiChild)) then
4078     Exit;
4079 
4080   FillChar(Msg{%H-}, SizeOf(Msg), #0);
4081 
4082   Msg.Msg := LM_MOVE;
4083 
4084   Msg.MoveType := Msg.MoveType or Move_SourceIsInterface;
4085 
4086   APos := QMoveEvent_pos(QMoveEventH(Event))^;
4087   FrameRect := getFrameGeometry;
4088   WindowRect := getGeometry;
4089 
4090   // here is explanation why frameGeometry sometimes
4091   // doesn't return correct results under X11
4092   // http://doc.qt.nokia.com/4.7/application-windows.html#window-geometry
4093   // issue #18658
4094   {$IFDEF HASX11}
4095   if (LCLObject is TCustomForm) and EqualRect(FrameRect, WindowRect) and
4096     (TCustomForm(LCLObject).BorderStyle <> bsNone) and
4097     (not (TCustomForm(LCLObject).FormStyle in [fsMDIChild,fsSplash]) or
4098       (csDesigning in LCLObject.ComponentState)) then
4099   begin
4100     ACurrPos := getPos;
4101     // do not send garbage to LCL. This window isn't decorated yet by WM.
4102     if (ACurrPos.X = WindowRect.Left) and (ACurrPos.Y = WindowRect.Top) then
4103       exit;
4104   end;
4105   {$ENDIF}
4106 
4107   Msg.XPos := SmallInt(APos.x - (WindowRect.Left - FrameRect.Left));
4108   Msg.YPos := SmallInt(APos.y - (WindowRect.Top - FrameRect.Top));
4109 
4110   DeliverMessage(Msg);
4111 end;
4112 
4113 {------------------------------------------------------------------------------
4114   Function: TQtWidget.SlotPaintBg
4115   Params:  None
4116   Returns: Nothing.
4117 
4118   Paints widget background.
4119   Only for classes which have HasPaint=False and AutoFillBackground=False
4120   and solid color different to default one (eg. clBtnFace for buttons).
4121   Current allowed classes are: All TQtCheckBox,TQtRadioButton,
4122   TQtPushButton (X11 only), TQtStaticText and TQtGroupBox.
4123  ------------------------------------------------------------------------------}
4124 procedure TQtWidget.SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl;
4125 var
4126   Painter: QPainterH;
4127   Brush: QBrushH;
4128   Color: TQColor;
4129   R: TRect;
4130 begin
4131   if CanSendLCLMessage and (LCLObject is TWinControl) then
4132   begin
4133     if LCLObject.Color = clDefault then
4134       Color := Palette.DefaultColor
4135     else
4136       ColorRefToTQColor(ColorToRGB(LCLObject.Color), Color);
4137     Painter := QPainter_create(QWidget_to_QPaintDevice(QWidgetH(Sender)));
4138     Brush := QBrush_create(@Color, QtSolidPattern);
4139     try
4140       QPaintEvent_rect(QPaintEventH(Event), @R);
4141       QPainter_fillRect(Painter, @R, Brush);
4142       QPainter_end(Painter);
4143     finally
4144       QBrush_destroy(Brush);
4145       QPainter_destroy(Painter);
4146     end;
4147   end;
4148 end;
4149 
4150 {------------------------------------------------------------------------------
4151   Function: TQtWidget.SlotPaint
4152   Params:  None
4153   Returns: Nothing
4154 
4155   Sends a LM_PAINT message to the LCL. This is for windowed controls only
4156  ------------------------------------------------------------------------------}
4157 procedure TQtWidget.SlotPaint(Sender: QObjectH; Event: QEventH); cdecl;
4158 var
4159   Msg: TLMPaint;
4160   AStruct: PPaintStruct;
4161   P: TPoint;
4162   B: Boolean;
4163 begin
4164   {$ifdef VerboseQt}
4165     WriteLn('TQtWidget.SlotPaint ', dbgsName(LCLObject));
4166   {$endif}
4167   if CanSendLCLMessage and (LCLObject is TWinControl) then
4168   begin
4169     FillChar(Msg{%H-}, SizeOf(Msg), #0);
4170 
4171     Msg.Msg := LM_PAINT;
4172     New(AStruct);
4173     FillChar(AStruct^, SizeOf(TPaintStruct), 0);
4174     Msg.PaintStruct := AStruct;
4175 
4176     with PaintData do
4177     begin
4178       PaintWidget := QWidgetH(Sender);
4179       ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
4180       if ClipRect = nil then
4181         New(ClipRect);
4182       QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
4183     end;
4184 
4185     Msg.DC := BeginPaint(THandle(Self), AStruct^);
4186     FContext := Msg.DC;
4187 
4188     Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
4189     Msg.PaintStruct^.hdc := FContext;
4190 
4191     P := getClientOffset;
4192     inc(P.X, FScrollX);
4193     inc(P.Y, FScrollY);
4194     TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
4195 
4196     // send paint message
4197     try
4198       // Saving clip rect and clip region
4199       try
4200         LCLObject.WindowProc(TLMessage(Msg));
4201         if HasCaret then
4202         begin
4203           if GlobalCaretDirty then
4204             QtCaret.ShowCaret(Self);
4205           QtCaret.DrawCaret;
4206         end;
4207       finally
4208         Dispose(PaintData.ClipRect);
4209         Fillchar(FPaintData, SizeOf(FPaintData), 0);
4210         FContext := 0;
4211         EndPaint(THandle(Self), AStruct^);
4212         Dispose(AStruct);
4213       end;
4214     except
4215       // prevent recursive repainting !
4216       B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
4217       if B then
4218         QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
4219       try
4220         Application.HandleException(nil);
4221       finally
4222         if B and Assigned(Application) and not Application.Terminated then
4223           QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
4224       end;
4225     end;
4226   end;
4227 end;
4228 
4229 {------------------------------------------------------------------------------
4230   Function: TQtWidget.SlotResize
4231   Params:  None
4232   Returns: Nothing
4233 
4234   Sends a LM_SIZE message to the LCL.
4235  ------------------------------------------------------------------------------}
4236 procedure TQtWidget.SlotResize(Event: QEventH); cdecl;
4237 var
4238   Msg: TLMSize;
4239   NewSize: TSize;
4240   {$IFDEF VerboseQtResizeError}
4241   R: TRect;
4242   {$ENDIF}
4243   B: Boolean;
4244   AQtClientRect: TRect;
4245 begin
4246   {$ifdef VerboseQt}
4247     WriteLn('TQtWidget.SlotResize');
4248   {$endif}
4249 
4250   if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
4251     QtWidgetSet.InvalidateWidgetAtCache;
4252 
4253   // return size w/o frame
4254   NewSize := QResizeEvent_size(QResizeEventH(Event))^;
4255 
4256   if not Assigned(LCLObject) then exit;
4257 
4258   if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
4259   begin
4260     {$IFDEF VerboseQtResizeError}
4261     if not InUpdate then
4262     begin
4263       DebugLn('============================================================================');
4264       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 !');
4265       DebugLn(dbgsName(LCLObject),' self=',dbgsName(Self),' already in SlotResize needClientRectAdjust',dbgs(LCLObject.ClientRectNeedsInterfaceUpdate),
4266       ' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
4267       R := getClientBounds;
4268       DebugLn('LCL CACHED CLIENT WxH=',dbgs(LCLObject.CachedClientWidth),'x',dbgs(LCLObject.CachedClientHeight),
4269       ' QtClient=',dbgs(R));
4270       DebugLn('============================================================================');
4271     end;
4272     {$ENDIF}
4273     exit;
4274   end;
4275   if Assigned(FOwner) then
4276     FOwner.InResizeEvent := True;
4277   InResizeEvent := True;
4278   try
4279     // do not loop with LCL but do not apply it to TQtMainWindow !
4280     if not (csDesigning in LCLObject.ComponentState) and
4281       not ((ClassType = TQtMainWindow) or (ClassType = TQtWindowArea)) and InUpdate then
4282     begin
4283       AQtClientRect := Rect(0, 0, 0, 0);
4284       if FOwner <> nil then
4285         B := GetClientRect(HWND(Self.FOwner), AQtClientRect)
4286       else
4287         B := GetClientRect(HWND(Self), AQtClientRect);
4288       if B and EqualRect(LCLObject.ClientRect, AQtClientRect) then
4289       begin
4290         {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
4291         DebugLn('==========',dbgsName(LCLObject),'.SlotResize inUpdate.LCLObject.ClientRect is ok,do not send LMSize');
4292         {$ENDIF}
4293         exit;
4294       end else
4295       begin
4296         {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
4297         DebugLn('====***====',dbgsName(LCLObject),'.SlotResize inUpdate but LCL.ClientRect isn''t adjusted. CanAdjust=',dbgs(CanAdjustClientRectOnResize),' CAPS=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' NeedUpd ',dbgs(LCLObject.ClientRectNeedsInterfaceUpdate));
4298         {$ENDIF}
4299         if LCLObject.ClientRectNeedsInterfaceUpdate and
4300           not (caspComputingBounds in LCLObject.AutoSizePhases) then
4301         begin
4302           LCLObject.DoAdjustClientRectChange(True);
4303           exit;
4304         end;
4305       end;
4306     end;
4307 
4308     {keep LCL value while designing pageControl}
4309     if (csDesigning in LCLObject.ComponentState) and InUpdate and
4310       ((Self is TQtPage) or (Self is TQtTabWidget)) then
4311         exit;
4312 
4313     if CanAdjustClientRectOnResize and
4314       LCLObject.ClientRectNeedsInterfaceUpdate then
4315     begin
4316       // postpone resize event if we are computingbounds otherwise
4317       // we can run into infinite size loop.
4318       if (caspComputingBounds in LCLObject.AutoSizePhases) then
4319       begin
4320         {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
4321         DebugLn('WARNING: *TQtWidget.SlotResize caspComputingBounds=true* ! ',dbgsname(LCLObject),':',dbgsName(Self),' inUpdate=',dbgs(inUpdate),' Time: ',dbgs(GetTickCount));
4322         {$ENDIF}
4323         if ChildOfComplexWidget <> ccwScrollingWinControl then
4324           DelayResizeEvent(Widget, NewSize);
4325         exit;
4326       end else
4327       begin
4328         LCLObject.DoAdjustClientRectChange;
4329       end;
4330     end;
4331 
4332     FillChar(Msg{%H-}, SizeOf(Msg), #0);
4333 
4334     Msg.Msg := LM_SIZE;
4335 
4336     case getWindowState of
4337       QtWindowMinimized: Msg.SizeType := SIZE_MINIMIZED;
4338       QtWindowMaximized: Msg.SizeType := SIZE_MAXIMIZED;
4339       QtWindowFullScreen: Msg.SizeType := SIZE_FULLSCREEN;
4340     else
4341       Msg.SizeType := SIZE_RESTORED;
4342     end;
4343 
4344     Msg.SizeType := Msg.SizeType or Size_SourceIsInterface;
4345 
4346     Msg.Width := Word(NewSize.cx);
4347     Msg.Height := Word(NewSize.cy);
4348 
4349     DeliverMessage(Msg);
4350   finally
4351     if ASsigned(FOwner) then
4352       FOwner.InResizeEvent := False;
4353     InResizeEvent := False;
4354   end;
4355 end;
4356 
TQtWidget.SlotContextMenunull4357 function TQtWidget.SlotContextMenu(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
4358 var
4359   Msg: TLMContextMenu;
4360   MousePos: TQtPoint;
4361 
4362   procedure SendMouseReleaseEventToSelf;
4363   var
4364     AEvent: QEventH;
4365     Modifiers: QtKeyboardModifiers;
4366   begin
4367     Modifiers := QInputEvent_modifiers(QInputEventH(Event));
4368     AEvent := QMouseEvent_create(QEventMouseButtonRelease,
4369       QContextMenuEvent_pos(QContextMenuEventH(Event)),
4370       QContextMenuEvent_globalPos(QContextMenuEventH(Event)),
4371       QtRightButton,
4372       QtRightButton,
4373       Modifiers);
4374     QCoreApplication_postEvent(Widget, AEvent, 1);
4375   end;
4376 
4377 begin
4378   if not CanSendLCLMessage then
4379     Exit(False);
4380 
4381   FillChar(Msg{%H-}, SizeOf(Msg), #0);
4382   MousePos := QContextMenuEvent_globalPos(QContextMenuEventH(Event))^;
4383 
4384   Msg.Msg := LM_CONTEXTMENU;
4385   if FOwner <> nil then
4386     Msg.hWnd := HWND(FOwner)
4387   else
4388     Msg.hWnd := HWND(Self);
4389   if QContextMenuEvent_reason(QContextMenuEventH(Event)) = QContextMenuEventKeyboard then
4390   begin
4391     Msg.XPos := -1;
4392     Msg.YPos := -1;
4393   end
4394   else
4395   begin
4396     Msg.XPos := SmallInt(MousePos.X);
4397     Msg.YPos := SmallInt(MousePos.Y);
4398   end;
4399 
4400   Result := DeliverMessage(Msg) <> 0;
4401 
4402   if Result then
4403     QEvent_accept(Event)
4404   else
4405   begin
4406     if Assigned(LCLObject.PopupMenu) then
4407       QEvent_ignore(Event);
4408     SetNoMousePropagation(QWidgetH(Sender), False);
4409     if (FOwner <> nil) and
4410       ((FChildOfComplexWidget = ccwCustomControl) or
4411       (FChildOfComplexWidget = ccwScrollingWinControl)) then
4412       SetNoMousePropagation(FOwner.Widget, False);
4413   end;
4414 
4415   if Result and (csDesigning in LCLObject.ComponentState) then
4416     SendMouseReleaseEventToSelf;
4417 end;
4418 
4419 procedure TQtWidget.SlotWhatsThis(Sender: QObjectH; Event: QEventH); cdecl;
4420 var
4421   Data: THelpInfo;
4422 begin
4423   if not CanSendLCLMessage then
4424     exit;
4425   Data.cbSize := SizeOf(Data);
4426   Data.iContextType := HELPINFO_WINDOW;
4427   Data.iCtrlId := 0;
4428   Data.hItemHandle := THandle(Sender);
4429   Data.dwContextId := 0;
4430   with QHelpEvent_globalPos(QHelpEventH(Event))^ do
4431     Data.MousePos := Point(X, Y);
4432   Application.HelpCommand(0, {%H-}PtrInt(@Data));
4433 end;
4434 
4435 procedure TQtWidget.SlotLCLMessage(Sender: QObjectH; Event: QEventH); cdecl;
4436 var
4437   MessageEvent: QLCLMessageEventH absolute Event;
4438   Msg: TLMessage;
4439 begin
4440   Msg.msg := Cardinal(QLCLMessageEvent_getMsg(MessageEvent));
4441   Msg.wParam := PtrInt(QLCLMessageEvent_getWParam(MessageEvent));
4442   Msg.lParam := PtrInt(QLCLMessageEvent_getLParam(MessageEvent));
4443   Msg.Result := 0;
4444   QLCLMessageEvent_setMsgResult(MessageEvent, PtrUInt(DeliverMessage(Msg)));
4445 end;
4446 
4447 procedure TQtWidget.Activate;
4448 begin
4449   QWidget_activateWindow(Widget);
4450 end;
4451 
4452 procedure TQtWidget.BringToFront;
4453 begin
4454   Activate;
4455   raiseWidget;
4456 end;
4457 
4458 procedure TQtWidget.clearMask;
4459 begin
4460   QWidget_clearMask(Widget);
4461 end;
4462 
4463 procedure TQtWidget.OffsetMousePos(APoint: PQtPoint);
4464 begin
4465   with getClientOffset do
4466   begin
4467     dec(APoint^.x, x);
4468     dec(APoint^.y, y);
4469   end;
4470 end;
4471 
4472 {------------------------------------------------------------------------------
4473   Function: TQtWidget.SetColor
4474   Params:  QColorH
4475   Returns: Nothing
4476 
4477   Changes the color of a widget
4478  ------------------------------------------------------------------------------}
4479 procedure TQtWidget.setColor(const Value: PQColor);
4480 begin
4481   Palette.setColor(Value);
4482 end;
4483 
getContextMenuPolicynull4484 function TQtWidget.getContextMenuPolicy: QtContextMenuPolicy;
4485 begin
4486   Result := QWidget_contextMenuPolicy(Widget);
4487 end;
4488 
4489 procedure TQtWidget.setContextMenuPolicy(const AValue: QtContextMenuPolicy);
4490 begin
4491   QWidget_setContextMenuPolicy(Widget, AValue);
4492 end;
4493 
4494 {------------------------------------------------------------------------------
4495   Function: TQtWidget.SetTextColor
4496   Params:  QColorH
4497   Returns: Nothing
4498 
4499   Changes the text color of a widget
4500  ------------------------------------------------------------------------------}
4501 procedure TQtWidget.setTextColor(const Value: PQColor);
4502 begin
4503   Palette.setTextColor(Value);
4504 end;
4505 
4506 procedure TQtWidget.setCursor(const ACursor: QCursorH);
4507 begin
4508   {$IFDEF DARWIN}
4509   if not QWidget_isVisible(Widget) then
4510     exit;
4511   {$ENDIF}
4512   if ACursor <> nil then
4513     QWidget_setCursor(Widget, ACursor)
4514   else
4515     QWidget_setCursor(Widget, FDefaultCursor);
4516 end;
4517 
4518 procedure TQtWidget.setDefaultColorRoles;
4519 begin
4520   FWidgetColorRole := QPaletteWindow;
4521   FTextColorRole := QPaletteWindowText;
4522 end;
4523 
4524 {------------------------------------------------------------------------------
4525   Function: TQtWidget.Update
4526   Params:  None
4527   Returns: Nothing
4528 
4529   Schedules a paint event for processing when Qt returns to the main event loop
4530  ------------------------------------------------------------------------------}
4531 procedure TQtWidget.Update(ARect: PRect = nil);
4532 begin
4533   if ARect <> nil then
4534     QWidget_update(Widget, ARect)
4535   else
4536     QWidget_update(Widget);
4537 end;
4538 
4539 procedure TQtWidget.UpdateRegion(ARgn: QRegionH);
4540 begin
4541   if ARgn <> nil then
4542     QWidget_update(Widget, ARgn)
4543   else
4544     QWidget_update(Widget);
4545 end;
4546 
4547 {------------------------------------------------------------------------------
4548   Function: TQtWidget.Repaint
4549   Params:  None
4550   Returns: Nothing
4551 
4552   Repaints the control imediately
4553  ------------------------------------------------------------------------------}
4554 procedure TQtWidget.Repaint(ARect: PRect = nil);
4555 begin
4556   if ARect <> nil then
4557     QWidget_repaint(Widget, ARect)
4558   else
4559     QWidget_repaint(Widget);
4560 end;
4561 
4562 procedure TQtWidget.setWindowTitle(Str: PWideString);
4563 begin
4564   QWidget_setWindowTitle(Widget, Str);
4565 end;
4566 
4567 procedure TQtWidget.WindowTitle(Str: PWideString);
4568 begin
4569   QWidget_WindowTitle(Widget, Str);
4570 end;
4571 
4572 procedure TQtWidget.Hide;
4573 begin
4574   QWidget_hide(Widget);
4575 end;
4576 
4577 procedure TQtWidget.Show;
4578 begin
4579   QWidget_show(Widget);
4580 end;
4581 
4582 procedure TQtWidget.ShowNormal;
4583 begin
4584   QWidget_showNormal(Widget);
4585 end;
4586 
4587 procedure TQtWidget.ShowMinimized;
4588 begin
4589   QWidget_showMinimized(Widget);
4590 end;
4591 
4592 procedure TQtWidget.ShowMaximized;
4593 begin
4594   QWidget_showMaximized(Widget);
4595 end;
4596 
4597 procedure TQtWidget.ShowFullScreen;
4598 begin
4599   QWidget_showFullScreen(Widget);
4600 end;
4601 
TQtWidget.getActionByIndexnull4602 function TQtWidget.getActionByIndex(AIndex: Integer): QActionH;
4603 var
4604   ActionList: TPtrIntArray;
4605 begin
4606   QWidget_actions(Widget, @ActionList);
4607   if (AIndex >= 0) and (AIndex < Length(ActionList)) then
4608     Result := QActionH(ActionList[AIndex])
4609   else
4610     Result := nil;
4611 end;
4612 
getAutoFillBackgroundnull4613 function TQtWidget.getAutoFillBackground: Boolean;
4614 begin
4615   Result := QWidget_autoFillBackground(Widget);
4616 end;
4617 
getEnablednull4618 function TQtWidget.getEnabled: Boolean;
4619 begin
4620   if Widget = nil then
4621     exit(False);
4622   Result := QWidget_isEnabled(Widget);
4623 end;
4624 
TQtWidget.getFontnull4625 function TQtWidget.getFont: QFontH;
4626 begin
4627   Result := QWidget_font(Widget);
4628 end;
4629 
TQtWidget.getFocusPolicynull4630 function TQtWidget.getFocusPolicy: QtFocusPolicy;
4631 begin
4632   Result := QWidget_focusPolicy(Widget);
4633 end;
4634 
getFrameGeometrynull4635 function TQtWidget.getFrameGeometry: TRect;
4636 begin
4637   QWidget_frameGeometry(Widget, @Result);
4638 end;
4639 
getGeometrynull4640 function TQtWidget.getGeometry: TRect;
4641 begin
4642   QWidget_geometry(Widget, @Result);
4643 end;
4644 
getLayoutDirectionnull4645 function TQtWidget.getLayoutDirection: QtLayoutDirection;
4646 begin
4647   Result := QWidget_layoutDirection(Widget);
4648 end;
4649 
getVisiblenull4650 function TQtWidget.getVisible: Boolean;
4651 begin
4652   if Widget = nil then
4653     exit(False);
4654   Result := QWidget_isVisible(Widget);
4655 end;
4656 
getVisibleTonull4657 function TQtWidget.getVisibleTo(AWidget: QWidgetH): Boolean;
4658 begin
4659   if Widget = nil then
4660     exit(False);
4661   Result := QWidget_isVisibleTo(Widget, AWidget);
4662 end;
4663 
TQtWidget.getOwnernull4664 function TQtWidget.getOwner: TQtWidget;
4665 begin
4666   Result := FOwner;
4667 end;
4668 
getParentnull4669 function TQtWidget.getParent: QWidgetH;
4670 begin
4671   Result := QWidget_parentWidget(Widget);
4672 end;
4673 
getPosnull4674 function TQtWidget.getPos: TQtPoint;
4675 begin
4676   QWidget_pos(Widget, @Result);
4677 end;
4678 
TQtWidget.getFrameSizenull4679 function TQtWidget.getFrameSize: TSize;
4680 begin
4681   QWidget_frameSize(Widget, @Result);
4682 end;
4683 
getSizenull4684 function TQtWidget.getSize: TSize;
4685 begin
4686   QWidget_size(Widget, @Result);
4687 end;
4688 
getTextnull4689 function TQtWidget.getText: WideString;
4690 begin
4691   Result := FText;
4692 end;
4693 
TQtWidget.getTextStaticnull4694 function TQtWidget.getTextStatic: Boolean;
4695 begin
4696   Result := True;
4697 end;
4698 
getHeightnull4699 function TQtWidget.getHeight: Integer;
4700 begin
4701   Result := QWidget_height(Widget);
4702 end;
4703 
getUpdatesEnablednull4704 function TQtWidget.getUpdatesEnabled: Boolean;
4705 begin
4706   Result := QWidget_updatesEnabled(Widget);
4707 end;
4708 
TQtWidget.getWidthnull4709 function TQtWidget.getWidth: Integer;
4710 begin
4711   Result := QWidget_width(Widget);
4712 end;
4713 
TQtWidget.getWindownull4714 function TQtWidget.getWindow: TQtWidget;
4715 var
4716   W: QWidgetH;
4717 begin
4718   Result := nil;
4719   W := QWidget_window(Widget);
4720   if W <> nil then
4721     Result := TQtWidget(HwndFromWidgetH(W));
4722 end;
4723 
getWindowStatenull4724 function TQtWidget.getWindowState: QtWindowStates;
4725 begin
4726   Result := QWidget_windowState(Widget);
4727 end;
4728 
getClientBoundsnull4729 function TQtWidget.getClientBounds: TRect;
4730 {$IFDEF VerboseQtResizeError}
4731 var
4732   R: TRect;
4733 {$ENDIF}
4734 begin
4735   QWidget_contentsRect(getContainerWidget, @Result);
4736   {only when FOwner implements it's own getClientBounds !
4737    Valid for FOwner: TQtTabWidget, TQtAbstractScrollArea and it's successors}
4738   if (FOwner <> nil) and
4739     not (ChildOfComplexWidget in [ccwComboBox]) then
4740   begin
4741     {$IFDEF VerboseQtResizeError}
4742     R := FOwner.getClientBounds;
4743     if not EqualRect(R, Result) then
4744       DebugLn('WARNING: Providing wrong clientRect ',dbgs(Result),' for ',dbgsName(LCLObject),' from ',dbgsName(Self),' FOwner ',dbgsName(FOwner),' ==>',dbgs(R));
4745     Result := R;
4746     {$ELSE}
4747     Result := FOwner.getClientBounds;
4748     {$ENDIF}
4749   end;
4750 end;
4751 
TQtWidget.getClientOffsetnull4752 function TQtWidget.getClientOffset: TPoint;
4753 var
4754   P: TQtPoint;
4755   R: TRect;
4756   {$IFDEF VerboseQtResizeError}
4757   Pt: TPoint;
4758   {$ENDIF}
4759 begin
4760   // we need an offset of container inside widget, but if container = widget then
4761   // offset = 0
4762   {$IFDEF VerboseQtResizeError}
4763   if Widget <> GetContainerWidget then
4764     QWidget_pos(GetContainerWidget, @P)
4765   else
4766     P := QtPoint(0, 0);
4767   R := getClientBounds;
4768   Result := Point(P.x + R.Left, P.y + R.Top);
4769   if (FOwner <> nil) and
4770     not (ChildOfComplexWidget in [ccwComboBox]) then
4771   begin
4772     Pt := FOwner.getClientOffset;
4773     if (Pt.x <> Result.x) or (Pt.y <> Result.y) then
4774       DebugLn('WARNING: Providing wrong clientOffset ',dbgs(Result),' for ',dbgsName(LCLObject),' from ',dbgsName(Self),' FOwner ',dbgsName(FOwner),' ==>',dbgs(Pt));
4775     Result := Pt;
4776   end;
4777   {$ELSE}
4778   if (FOwner <> nil) and
4779     not (ChildOfComplexWidget in [ccwComboBox]) then
4780   begin
4781     Result := FOwner.getClientOffset;
4782   end else
4783   begin
4784     if Widget <> GetContainerWidget then
4785       QWidget_pos(GetContainerWidget, @P)
4786     else
4787       P := QtPoint(0, 0);
4788     R := getClientBounds;
4789     Result := Point(P.x + R.Left, P.y + R.Top);
4790   end;
4791   {$ENDIF}
4792 end;
4793 
4794 procedure TQtWidget.grabMouse;
4795 begin
4796   //DumpStack;
4797   //DebugLn(['current grab is: ', dbgs(QWidget_mouseGrabber())]);
4798   //DebugLn(['grab mouse for: ', dbgsName(LCLObject), ' : ', dbgs(Widget)]);
4799   QWidget_grabMouse(Widget);
4800 end;
4801 
TQtWidget.hasFocusnull4802 function TQtWidget.hasFocus: Boolean;
4803 begin
4804   Result := QWidget_hasFocus(Widget);
4805 end;
4806 
IsActiveWindownull4807 function TQtWidget.IsActiveWindow: Boolean;
4808 begin
4809   Result := QWidget_isActiveWindow(Widget);
4810 end;
4811 
TQtWidget.isMinimizednull4812 function TQtWidget.isMinimized: Boolean;
4813 begin
4814   Result := QWidget_isMinimized(Widget);
4815 end;
4816 
isMaximizednull4817 function TQtWidget.isMaximized: Boolean;
4818 begin
4819   Result := QWidget_isMaximized(Widget);
4820 end;
4821 
TQtWidget.IsFramedWidgetnull4822 function TQtWidget.IsFramedWidget: boolean;
4823 begin
4824   Result := False;
4825 end;
4826 
TQtWidget.isFullScreennull4827 function TQtWidget.isFullScreen: Boolean;
4828 begin
4829   Result := QWidget_isFullScreen(Widget);
4830 end;
4831 
IsWindownull4832 function TQtWidget.IsWindow: Boolean;
4833 begin
4834   Result := QWidget_isWindow(Widget);
4835 end;
4836 
4837 procedure TQtWidget.lowerWidget;
4838 begin
4839   QWidget_lower(Widget);
4840 end;
4841 
MapToGlobalnull4842 function TQtWidget.MapToGlobal(APt: TPoint;
4843   const AWithScrollOffset: Boolean = False): TPoint;
4844 var
4845   Pt: TQtPoint;
4846   NewPt: TQtPoint;
4847 begin
4848   Pt := QtPoint(APt.X, APt.Y);
4849   NewPt := QtPoint(0, 0);
4850   QWidget_mapToGlobal(GetContainerWidget, @NewPt, @Pt);
4851   Result := Point(NewPt.x, NewPt.y);
4852 end;
4853 
MapFromGlobalnull4854 function TQtWidget.MapFromGlobal(APt: TPoint;
4855   const AWithScrollOffset: Boolean = False): TPoint;
4856 var
4857   Pt: TQtPoint;
4858   NewPt: TQtPoint;
4859 begin
4860   Pt := QtPoint(APt.X, APt.Y);
4861   NewPt := QtPoint(0, 0);
4862   QWidget_mapFromGlobal(GetContainerWidget, @NewPt, @Pt);
4863   Result := Point(NewPt.x, NewPt.y);
4864 end;
4865 
4866 procedure TQtWidget.move(ANewLeft, ANewTop: Integer);
4867 begin
4868   QWidget_move(Widget, ANewLeft, ANewTop);
4869 end;
4870 
4871 procedure TQtWidget.preferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean);
4872 var
4873   PrefSize: TSize;
4874 begin
4875   sizeHint(@PrefSize);
4876   if (PrefSize.cx >= 0) and (PrefSize.cy >=0) then
4877   begin
4878     PreferredWidth := PrefSize.cx;
4879     PreferredHeight := PrefSize.cy;
4880   end;
4881 end;
4882 
4883 procedure TQtWidget.raiseWidget;
4884 begin
4885   QWidget_raise(Widget);
4886 end;
4887 
4888 procedure TQtWidget.stackUnder(AWidget: QWidgetH);
4889 begin
4890   QWidget_stackUnder(Widget, AWidget);
4891 end;
4892 
4893 procedure TQtWidget.frame_resize(ANewWidth, ANewHeight: Integer);
4894 var
4895   R1, R2: TRect;
4896   dw, dh: integer;
4897 begin
4898   R1 := getGeometry;
4899   R2 := getFrameGeometry;
4900   dw := (R1.Left - R2.Left) + (R2.Right - R1.Right);
4901   dh := (R1.Top - R2.Top) + (R2.Bottom - R1.Bottom);
4902   QWidget_resize(Widget, ANewWidth - dw, ANewHeight - dh);
4903 end;
4904 
4905 procedure TQtWidget.Resize(ANewWidth, ANewHeight: Integer);
4906 begin
4907   QWidget_resize(Widget, ANewWidth, ANewHeight);
4908 end;
4909 
4910 procedure TQtWidget.releaseMouse;
4911 var
4912   AGrabWidget: QWidgetH;
4913 begin
4914   // capture widget can be one of children of Widget if Widget is complex control
4915   // so better to look for current Capture widget to release it
4916   // instead of pass Widget as argument
4917   AGrabWidget := QWidget_mouseGrabber();
4918   //DebugLn(['releasing current grab: ', dbgs(AGrabWidget)]);
4919   if AGrabWidget <> nil then
4920     QWidget_releaseMouse(AGrabWidget);
4921 end;
4922 
4923 procedure TQtWidget.scroll(dx, dy: integer; ARect: PRect = nil);
4924 begin
4925   if ARect = nil then
4926     QWidget_scroll(getContainerWidget, dx, dy)
4927   else
4928     QWidget_scroll(getContainerWidget, dx, dy, ARect);
4929 end;
4930 
4931 procedure TQtWidget.setAutoFillBackground(const AValue: Boolean);
4932 begin
4933   QWidget_setAutoFillBackground(Widget, AValue);
4934 end;
4935 
4936 procedure TQtWidget.setAttribute(const Attr: QtWidgetAttribute;
4937   const TurnOn: Boolean);
4938 begin
4939   QWidget_setAttribute(Widget, Attr, TurnOn);
4940 end;
4941 
4942 procedure TQtWidget.setBackgroundRole(const ARole: QPaletteColorRole);
4943 begin
4944   QWidget_setBackgroundRole(Widget, ARole);
4945 end;
4946 
4947 procedure TQtWidget.setDefaultColor(const DefaultColorType: TDefaultColorType);
4948 begin
4949   case DefaultColorType of
4950     dctBrush: setColor(@Palette.DefaultColor);
4951     dctFont: setTextColor(@Palette.DefaultTextColor);
4952   end;
4953 end;
4954 
4955 procedure TQtWidget.setEnabled(p1: Boolean);
4956 begin
4957   if not p1 and (HWND(Self) = GetCapture) then
4958     ReleaseCapture;
4959   QWidget_setEnabled(Widget, p1);
4960 end;
4961 
4962 procedure TQtWidget.setFocus;
4963 begin
4964   if getFocusPolicy <> QtNoFocus then
4965     QWidget_setFocus(Widget, QtTabFocusReason)
4966   else
4967     QWidget_setFocus(Widget);
4968 end;
4969 
4970 procedure TQtWidget.setFocusPolicy(const APolicy: QtFocusPolicy);
4971 begin
4972   QWidget_setFocusPolicy(Widget, APolicy);
4973 end;
4974 
4975 procedure TQtWidget.setFocusProxy(const AWidget: QWidgetH);
4976 begin
4977   QWidget_setFocusProxy(Widget, AWidget);
4978 end;
4979 
4980 procedure TQtWidget.setFont(AFont: QFontH);
4981 begin
4982   QWidget_setFont(Widget, AFont);
4983 end;
4984 
4985 procedure TQtWidget.setGeometry(ARect: TRect);
4986 begin
4987   QWidget_setGeometry(Widget, @ARect);
4988 end;
4989 
4990 procedure TQtWidget.setInitialFontColor(AControl: TWinControl);
4991 var
4992   QColor: TQColor;
4993   ColorRef: TColorRef;
4994 begin
4995   if AControl.Font.Color = clDefault then
4996   begin
4997     BeginUpdate;
4998     Palette.ForceColor := True;
4999     SetDefaultColor(dctFont);
5000     Palette.ForceColor := False;
5001     EndUpdate;
5002   end
5003   else
5004   begin
5005     ColorRef := ColorToRGB(AControl.Font.Color);
5006     QColor_fromRgb(@QColor,Red(ColorRef),Green(ColorRef),Blue(ColorRef));
5007     BeginUpdate;
5008     Palette.ForceColor := True;
5009     SetTextColor(@QColor);
5010     Palette.ForceColor := False;
5011     EndUpdate;
5012   end;
5013 end;
5014 
5015 procedure TQtWidget.setLayoutDirection(ADirection: QtLayoutDirection);
5016 begin
5017   QWidget_setLayoutDirection(Widget, ADirection);
5018 end;
5019 
5020 procedure TQtWidget.setMaximumSize(AWidth, AHeight: Integer);
5021 begin
5022   QWidget_setMaximumSize(Widget, AWidth, AHeight);
5023 end;
5024 
5025 procedure TQtWidget.setMask(AMask: QBitmapH);
5026 begin
5027   QWidget_setMask(Widget, AMask);
5028 end;
5029 
5030 procedure TQtWidget.setMask(AMask: QRegionH);
5031 begin
5032   QWidget_setMask(Widget, AMask);
5033 end;
5034 
5035 procedure TQtWidget.setMinimumSize(AWidth, AHeight: Integer);
5036 begin
5037   QWidget_setMinimumSize(Widget, AWidth, AHeight);
5038 end;
5039 
5040 procedure TQtWidget.setVisible(AVisible: Boolean);
5041 begin
5042   QWidget_setVisible(Widget, AVisible);
5043 end;
5044 
windowModalitynull5045 function TQtWidget.windowModality: QtWindowModality;
5046 begin
5047   Result := QWidget_windowModality(Widget);
5048 end;
5049 
5050 procedure TQtWidget.setWindowModality(windowModality: QtWindowModality);
5051 begin
5052   QWidget_setWindowModality(Widget, windowModality);
5053 end;
5054 
5055 procedure TQtWidget.setWindowOpacity(opacity: double);
5056 begin
5057   QWidget_setWindowOpacity(Widget, opacity);
5058 end;
5059 
5060 procedure TQtWidget.setParent(parent: QWidgetH);
5061 begin
5062   QWidget_setParent(Widget, parent);
5063 end;
5064 
5065 procedure TQtWidget.setText(const W: WideString);
5066 begin
5067   FText := W;
5068 end;
5069 
5070 procedure TQtWidget.setWindowFlags(_type: QtWindowFlags);
5071 begin
5072   QWidget_setWindowFlags(Widget, _type);
5073 end;
5074 
5075 procedure TQtWidget.setWindowIcon(AIcon: QIconH);
5076 var
5077   DestroyIcon: Boolean;
5078 begin
5079   DestroyIcon := AIcon = nil;
5080   if DestroyIcon then
5081     AIcon := QIcon_create();
5082   QWidget_setWindowIcon(Widget, AIcon);
5083   if DestroyIcon then
5084     QIcon_destroy(AIcon);
5085 end;
5086 
TQtWidget.windowFlagsnull5087 function TQtWidget.windowFlags: QtWindowFlags;
5088 begin
5089   Result := QWidget_windowFlags(Widget);
5090 end;
5091 
5092 procedure TQtWidget.setWidth(p1: Integer);
5093 var
5094   R: TRect;
5095 begin
5096   R := getGeometry;
5097   R.Right := R.Left + p1;
5098   setGeometry(R);
5099 end;
5100 
5101 procedure TQtWidget.setHeight(p1: Integer);
5102 var
5103   R: TRect;
5104 begin
5105   R := getGeometry;
5106   R.Bottom := R.Top + p1;
5107   setGeometry(R);
5108 end;
5109 
5110 procedure TQtWidget.setUpdatesEnabled(const AEnabled: Boolean);
5111 begin
5112   QWidget_setUpdatesEnabled(Widget, AEnabled);
5113 end;
5114 
5115 procedure TQtWidget.setWindowState(AState: QtWindowStates);
5116 begin
5117   QWidget_setWindowState(Widget, AState);
5118 end;
5119 
5120 procedure TQtWidget.sizeHint(size: PSize);
5121 begin
5122   QWidget_sizeHint(Widget, size);
5123 end;
5124 
TQtWidget.testAttributenull5125 function TQtWidget.testAttribute(const AAttribute: QtWidgetAttribute): boolean;
5126 begin
5127   Result := QWidget_testAttribute(Widget, AAttribute);
5128 end;
5129 
5130 {------------------------------------------------------------------------------
5131   Function: TQtWidget.QtKeyToLCLKey
5132   Params:  None
5133   Returns: Nothing
5134  ------------------------------------------------------------------------------}
QtKeyToLCLKeynull5135 function TQtWidget.QtKeyToLCLKey(AKey: Integer; AText: WideString;
5136   AEvent: QKeyEventH): Word;
5137 begin
5138   // The big problem here with unicode keys
5139   // Example: for Russian letter A qt returns AKey = $0410 and this is
5140   // absolutely correct: 0400 - 04FF - is russian unicode space and
5141   // 0410 is defined as "CYRILLIC CAPITAL LETTER A"
5142 
5143   Result := VK_UNKNOWN;
5144   case AKey of
5145     QtKey_0..QtKey_9: Result := VK_0 + (AKey - QtKey_0);
5146     QtKey_At: Result := VK_2; // some bug, but Ctrl + Shit + 2 produce QtKey_At
5147     QtKey_Escape: Result := VK_ESCAPE;
5148     QtKey_Tab: Result := VK_TAB;
5149     QtKey_Backtab: Result := VK_TAB; // ???
5150     QtKey_Backspace: Result := VK_BACK;
5151     QtKey_Return: Result := VK_RETURN;
5152     QtKey_Enter: Result := VK_RETURN;
5153     QtKey_Insert: Result := VK_INSERT;
5154     QtKey_Delete: Result := VK_DELETE;
5155     QtKey_Pause: Result := VK_PAUSE;
5156     QtKey_Print: Result := VK_PRINT;
5157     QtKey_SysReq: Result := VK_UNKNOWN; // ???
5158     QtKey_Clear: Result := VK_CLEAR;
5159     QtKey_Home: Result := VK_HOME;
5160     QtKey_End: Result := VK_END;
5161     QtKey_Left: Result := VK_LEFT;
5162     QtKey_Up: Result := VK_UP;
5163     QtKey_Right: Result := VK_RIGHT;
5164     QtKey_Down: Result := VK_DOWN;
5165     QtKey_PageUp: Result := VK_PRIOR;
5166     QtKey_PageDown: Result := VK_NEXT;
5167     QtKey_Shift: Result := VK_SHIFT;     // There is also RSHIFT
5168     QtKey_Control: Result := VK_CONTROL; // There is also RCONTROL
5169     QtKey_Meta:
5170     begin
5171       //TODO: Qt sends meta key, but info about left & right is in nativeScanCode
5172       {$IFDEF HASX11}
5173       if QKeyEvent_nativeVirtualKey(AEvent) = XK_Super_L then
5174         Result := VK_LWIN
5175       else
5176       if QKeyEvent_nativeVirtualKey(AEvent) = XK_Super_R then
5177         Result := VK_RWIN
5178       else
5179         Result := VK_MENU;
5180       {$ELSE}
5181       Result := VK_LWIN;
5182       {$ENDIF}
5183     end;
5184     QtKey_Alt: Result := VK_MENU;
5185     QtKey_AltGr: Result := VK_RMENU;
5186     QtKey_CapsLock: Result := VK_CAPITAL;
5187     QtKey_NumLock: Result := VK_NUMLOCK;
5188     QtKey_ScrollLock: Result := VK_SCROLL;
5189     QtKey_F1..QtKey_F24: Result := VK_F1 + (AKey - QtKey_F1);
5190     QtKey_F25..
5191     QtKey_F35: Result := VK_UNKNOWN;
5192     QtKey_Super_L: Result := VK_LWIN;
5193     QtKey_Super_R: Result := VK_RWIN;
5194     QtKey_Menu: Result := VK_APPS;
5195     QtKey_Hyper_L,
5196     QtKey_Hyper_R: Result := VK_UNKNOWN;
5197     QtKey_Help: Result := VK_HELP;
5198     QtKey_Direction_L,
5199     QtKey_Direction_R,
5200     QtKey_Exclam,QtKey_NumberSign..
5201     QtKey_AmperSand,
5202     QtKey_ParenLeft,
5203     QtKey_ParenRight: Result := VK_UNKNOWN;
5204     QtKey_Asterisk: Result := VK_MULTIPLY;
5205     QtKey_Plus: Result := VK_ADD;
5206     QtKey_Comma: Result := VK_SEPARATOR;
5207     QtKey_Minus: Result := VK_SUBTRACT;
5208     QtKey_Period: Result := VK_DECIMAL;
5209     QtKey_Slash: Result := VK_DIVIDE;
5210     QtKey_Equal: Result := VK_OEM_PLUS;
5211 
5212     QtKey_Colon,
5213     QtKey_Semicolon: Result := VK_OEM_1;
5214     QtKey_AsciiTilde: Result := VK_OEM_3;
5215     QtKey_BraceLeft,
5216     QtKey_BracketLeft: Result := VK_OEM_4;
5217     QtKey_BackSlash: Result := VK_OEM_5;
5218     QtKey_BraceRight,
5219     QtKey_BracketRight: Result := VK_OEM_6;
5220     QtKey_QuoteDbl,
5221     QtKey_Apostrophe: Result := VK_OEM_7;
5222     QtKey_Less: Result := VK_OEM_COMMA;
5223     QtKey_Greater: Result := VK_OEM_PERIOD;
5224 
5225     QtKey_ydiaeresis,
5226     QtKey_Multi_key..
5227     QtKey_No: Result := VK_UNKNOWN;
5228     QtKey_Cancel: Result := VK_CANCEL;
5229     QtKey_Printer: Result := VK_PRINT;
5230     QtKey_Execute: Result := VK_EXECUTE;
5231     QtKey_Sleep: Result := VK_SLEEP;
5232     QtKey_Play: Result := VK_PLAY;
5233     QtKey_Zoom: Result := VK_ZOOM;
5234     QtKey_Context1..
5235     QtKey_Flip,
5236     QtKey_unknown: Result := VK_UNKNOWN;
5237   else
5238     if AKey in [0..255] then // Qt:AKey = VK_KEY in many cases
5239       Result := AKey
5240     else
5241     if AText <> '' then
5242     begin
5243       // use QChar to understand whether we have unicode letter or number here or no
5244       // then try to map that char to VK_ code
5245     end;
5246   end;
5247 end;
5248 
5249 procedure TQtWidget.SetLastCaretPos(const AValue: TQtPoint);
5250 begin
5251   FLastCaretPos := AValue;
5252 end;
5253 
5254 procedure TQtWidget.SetHasCaret(const AValue: Boolean);
5255 begin
5256   FHasCaret := AValue;
5257 end;
5258 
ProcessArrowKeysnull5259 function TQtWidget.ProcessArrowKeys: Boolean;
5260 begin
5261   Result := False;
5262 end;
5263 
5264 class procedure TQtWidget.removeProperty(AObject: QObjectH; APropName: PAnsiChar);
5265 var
5266   AVariant: QVariantH;
5267 begin
5268   AVariant := QVariant_create;
5269   QObject_setProperty(AObject, APropName, AVariant);
5270   QVariant_destroy(AVariant);
5271 end;
5272 
5273 class procedure TQtWidget.setProperty(AObject: QObjectH; APropName: PAnsiChar; APropValue: Int64);
5274 var
5275   AVariant: QVariantH;
5276 begin
5277   AVariant := QVariant_create(APropValue);
5278   QObject_setProperty(AObject, APropName, AVariant);
5279   QVariant_destroy(AVariant);
5280 end;
5281 
LCLKeyToQtKeynull5282 function TQtWidget.LCLKeyToQtKey(AKey: Word): Integer;
5283 const
5284   VKKeyToQtKeyMap: array[0..255] of Integer = // Keyboard mapping table
5285    (
5286     QtKey_unknown,
5287     QtKey_unknown,
5288     QtKey_unknown,
5289     QtKey_Cancel,
5290     QtKey_unknown,
5291     QtKey_unknown,
5292     QtKey_unknown,
5293     QtKey_unknown,
5294     QtKey_Backspace,
5295     QtKey_Tab,
5296     QtKey_unknown,
5297     QtKey_unknown,
5298     QtKey_Clear,
5299     QtKey_Return,
5300     QtKey_unknown,
5301     QtKey_unknown,
5302     QtKey_Shift,
5303     QtKey_Control,
5304     QtKey_Alt,
5305     QtKey_Pause,
5306     QtKey_CapsLock,
5307     QtKey_unknown,
5308     QtKey_unknown,
5309     QtKey_unknown,
5310     QtKey_unknown,
5311     QtKey_unknown,
5312     QtKey_unknown,
5313     QtKey_Escape,
5314     QtKey_unknown,
5315     QtKey_unknown,
5316     QtKey_unknown,
5317     QtKey_Mode_switch,
5318     QtKey_Space,
5319     QtKey_PageUp,
5320     QtKey_PageDown,
5321     QtKey_End,
5322     QtKey_Home,
5323     QtKey_Left,
5324     QtKey_Up,
5325     QtKey_Right,
5326     QtKey_Down,
5327     QtKey_Select,
5328     QtKey_Printer,
5329     QtKey_Execute,
5330     QtKey_Print,
5331     QtKey_Insert,
5332     QtKey_Delete,
5333     QtKey_Help,
5334     QtKey_0,
5335     QtKey_1,
5336     QtKey_2,
5337     QtKey_3,
5338     QtKey_4,
5339     QtKey_5,
5340     QtKey_6,
5341     QtKey_7,
5342     QtKey_8,
5343     QtKey_9,
5344     QtKey_unknown,
5345     QtKey_unknown,
5346     QtKey_unknown,
5347     QtKey_unknown,
5348     QtKey_unknown,
5349     QtKey_unknown,
5350     QtKey_unknown,
5351     QtKey_A,
5352     QtKey_B,
5353     QtKey_C,
5354     QtKey_D,
5355     QtKey_E,
5356     QtKey_F,
5357     QtKey_G,
5358     QtKey_H,
5359     QtKey_I,
5360     QtKey_J,
5361     QtKey_K,
5362     QtKey_L,
5363     QtKey_M,
5364     QtKey_N,
5365     QtKey_O,
5366     QtKey_P,
5367     QtKey_Q,
5368     QtKey_R,
5369     QtKey_S,
5370     QtKey_T,
5371     QtKey_U,
5372     QtKey_V,
5373     QtKey_W,
5374     QtKey_X,
5375     QtKey_Y,
5376     QtKey_Z,
5377     QtKey_Meta,
5378     QtKey_Meta,
5379     QtKey_Menu,
5380     QtKey_unknown,
5381     QtKey_Sleep,
5382     QtKey_0,
5383     QtKey_1,
5384     QtKey_2,
5385     QtKey_3,
5386     QtKey_4,
5387     QtKey_5,
5388     QtKey_6,
5389     QtKey_7,
5390     QtKey_8,
5391     QtKey_9,
5392     QtKey_Asterisk,
5393     QtKey_Plus,
5394     QtKey_Comma,
5395     QtKey_Minus,
5396     QtKey_Period,
5397     QtKey_Slash,
5398     QtKey_F1,
5399     QtKey_F2,
5400     QtKey_F3,
5401     QtKey_F4,
5402     QtKey_F5,
5403     QtKey_F6,
5404     QtKey_F7,
5405     QtKey_F8,
5406     QtKey_F9,
5407     QtKey_F10,
5408     QtKey_F11,
5409     QtKey_F12,
5410     QtKey_F13,
5411     QtKey_F14,
5412     QtKey_F15,
5413     QtKey_F16,
5414     QtKey_F17,
5415     QtKey_F18,
5416     QtKey_F19,
5417     QtKey_F20,
5418     QtKey_F21,
5419     QtKey_F22,
5420     QtKey_F23,
5421     QtKey_F24,
5422     QtKey_unknown,
5423     QtKey_unknown,
5424     QtKey_unknown,
5425     QtKey_unknown,
5426     QtKey_unknown,
5427     QtKey_unknown,
5428     QtKey_unknown,
5429     QtKey_unknown,
5430     QtKey_NumLock,
5431     QtKey_ScrollLock,
5432     QtKey_unknown,
5433     QtKey_Massyo,
5434     QtKey_Touroku,
5435     QtKey_unknown,
5436     QtKey_unknown,
5437     QtKey_unknown,
5438     QtKey_unknown,
5439     QtKey_unknown,
5440     QtKey_unknown,
5441     QtKey_unknown,
5442     QtKey_unknown,
5443     QtKey_unknown,
5444     QtKey_unknown,
5445     QtKey_unknown,
5446     QtKey_Shift,
5447     QtKey_Shift,
5448     QtKey_Control,
5449     QtKey_Control,
5450     QtKey_Alt,
5451     QtKey_Alt,
5452     QtKey_Back,
5453     QtKey_Forward,
5454     QtKey_Refresh,
5455     QtKey_Stop,
5456     QtKey_Search,
5457     QtKey_Favorites,
5458     QtKey_HomePage,
5459     QtKey_VolumeMute,
5460     QtKey_VolumeDown,
5461     QtKey_VolumeUp,
5462     QtKey_MediaNext,
5463     QtKey_MediaPrevious,
5464     QtKey_MediaStop,
5465     QtKey_MediaPlay,
5466     QtKey_LaunchMail,
5467     QtKey_LaunchMedia,
5468     QtKey_Launch0,
5469     QtKey_Launch1,
5470     QtKey_unknown,
5471     QtKey_unknown,
5472     QtKey_1,
5473     QtKey_Plus,
5474     QtKey_Comma,
5475     QtKey_Minus,
5476     QtKey_Period,
5477     QtKey_2,
5478     QtKey_3,
5479     QtKey_unknown,
5480     QtKey_unknown,
5481     QtKey_unknown,
5482     QtKey_unknown,
5483     QtKey_unknown,
5484     QtKey_unknown,
5485     QtKey_unknown,
5486     QtKey_unknown,
5487     QtKey_unknown,
5488     QtKey_unknown,
5489     QtKey_unknown,
5490     QtKey_unknown,
5491     QtKey_unknown,
5492     QtKey_unknown,
5493     QtKey_unknown,
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_unknown,
5503     QtKey_unknown,
5504     QtKey_unknown,
5505     QtKey_4,
5506     QtKey_5,
5507     QtKey_6,
5508     QtKey_7,
5509     QtKey_8,
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_unknown,
5519     QtKey_unknown,
5520     QtKey_unknown,
5521     QtKey_unknown,
5522     QtKey_unknown,
5523     QtKey_unknown,
5524     QtKey_unknown,
5525     QtKey_unknown,
5526     QtKey_unknown,
5527     QtKey_unknown,
5528     QtKey_unknown,
5529     QtKey_unknown,
5530     QtKey_unknown,
5531     QtKey_unknown,
5532     QtKey_unknown,
5533     QtKey_unknown,
5534     QtKey_unknown,
5535     QtKey_unknown,
5536     QtKey_Play,
5537     QtKey_Zoom,
5538     QtKey_unknown,
5539     QtKey_unknown,
5540     QtKey_Clear,
5541     QtKey_unknown
5542    );
5543 begin
5544   if AKey > 255 then
5545     Result := QtKey_unknown
5546   else
5547     Result := VKKeyToQtKeyMap[AKey];
5548 end;
5549 
TQtWidget.ShiftStateToQtModifiersnull5550 function TQtWidget.ShiftStateToQtModifiers(Shift: TShiftState): QtModifier;
5551 begin
5552   Result := 0;
5553   if ssCtrl  in Shift then inc(Result, QtCTRL);
5554   if ssShift in Shift then Inc(Result, QtSHIFT);
5555   if ssMeta  in Shift then Inc(Result, QtMETA);
5556   if ssAlt   in Shift then Inc(Result, QtALT);
5557 end;
5558 
TQtWidget.QueryInterfacenull5559 function TQtWidget.QueryInterface(constref iid: TGuid; out obj): LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
5560 begin
5561   if GetInterface(iid, obj) then
5562     Result := 0
5563   else
5564     Result := E_NOINTERFACE;
5565 end;
5566 
_AddRefnull5567 function TQtWidget._AddRef: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
5568 begin
5569   Result := -1; // no ref counting
5570 end;
5571 
_Releasenull5572 function TQtWidget._Release: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
5573 begin
5574   Result := -1;
5575 end;
5576 
TQtWidget.GetPropsnull5577 function TQtWidget.GetProps(const AnIndex: String): pointer;
5578 var
5579   i: Integer;
5580 begin
5581   if (Fprops<>nil) then
5582   begin
5583     i:=Fprops.IndexOf(AnIndex);
5584     if i>=0 then
5585     begin
5586       result:=Fprops.Objects[i];
5587       exit;
5588     end;
5589   end;
5590   result := nil;
5591 end;
5592 
TQtWidget.getScrolledOffsetnull5593 function TQtWidget.getScrolledOffset: TPoint;
5594 begin
5595   Result := Point(-FScrollX, -FScrollY);
5596 end;
5597 
TQtWidget.GetStyleSheetnull5598 function TQtWidget.GetStyleSheet: WideString;
5599 var
5600   WStr: WideString;
5601 begin
5602   QWidget_styleSheet(Widget, @WStr);
5603   Result := WStr;
5604 end;
5605 
5606 {------------------------------------------------------------------------------
5607   Function: TQtWidget.GetPalette
5608   Params:  Nothing
5609   Returns: TQtWidgetPalette
5610 
5611   Assigns default widget palette, also takes care of widget colors changing.
5612  ------------------------------------------------------------------------------}
GetPalettenull5613 function TQtWidget.GetPalette: TQtWidgetPalette;
5614 begin
5615   if not Assigned(FPalette) then
5616   begin
5617     if (ClassType = TQtCustomControl) then
5618       FPalette := TQtWidgetPalette.Create(WidgetColorRole, TextColorRole,
5619         TQtCustomControl(Self).viewport.Widget)
5620     else
5621       FPalette := TQtWidgetPalette.Create(WidgetColorRole, TextColorRole, Widget);
5622   end;
5623   Result := FPalette;
5624 end;
5625 
TQtWidget.GetContextnull5626 function TQtWidget.GetContext: HDC;
5627 begin
5628   Result := FContext;
5629 end;
5630 
TQtWidget.GetWidgetnull5631 function TQtWidget.GetWidget: QWidgetH;
5632 begin
5633   Result := QWidgetH(TheObject);
5634 end;
5635 
TQtWidget.DeliverMessagenull5636 function TQtWidget.DeliverMessage(var Msg;
5637   const AIsInputEvent: Boolean = False): LRESULT;
5638 var
5639   AEvent: Cardinal;
5640 begin
5641   Result := LRESULT(AIsInputEvent);
5642   if LCLObject = nil then
5643     Exit;
5644   AEvent := TLMessage(Msg).Msg;
5645   try
5646     if LCLObject.HandleAllocated then
5647     begin
5648       LCLObject.WindowProc(TLMessage(Msg));
5649       Result := TLMessage(Msg).Result;
5650     end;
5651   except
5652     Result := 1;
5653     if AIsInputEvent and (LCLObject = nil) and (PtrUInt(Widget) = 0) and
5654       QtWidgetSet.IsValidHandle(HWND(Self)) then
5655     begin
5656       DebugLn(Format('WARNING: %s has been destroyed while processing input event %u result %u',
5657         [ClassName, AEvent, Result]));
5658     end else
5659       Application.HandleException(nil);
5660   end;
5661 end;
5662 
5663 procedure TQtWidget.SetProps(const AnIndex: String; const AValue: pointer);
5664 var
5665   i: Integer;
5666 begin
5667   if FProps=nil then
5668   begin
5669     FProps:=TStringList.Create;
5670     //FProps.CaseSensitive:=false;
5671     FProps.Sorted:=true;
5672   end;
5673   i := Fprops.IndexOf(AnIndex);
5674   if i < 0 then
5675     i := FProps.Add(AnIndex);
5676   Fprops.Objects[i] := TObject(AValue);
5677 end;
5678 
5679 procedure TQtWidget.SetStyleSheet(const AValue: WideString);
5680 var
5681   WStr: WideString;
5682 begin
5683   WStr := AValue;
5684   QWidget_setStyleSheet(Widget, @WStr);
5685 end;
5686 
5687 procedure TQtWidget.SetWidget(const AValue: QWidgetH);
5688 begin
5689   TheObject := AValue;
5690 end;
5691 
TQtWidget.CreateWidgetnull5692 function TQtWidget.CreateWidget(const Params: TCreateParams): QWidgetH;
5693 var
5694   Parent: QWidgetH;
5695 begin
5696   FHasPaint := True;
5697 
5698   if Params.WndParent <> 0 then
5699     Parent := TQtWidget(Params.WndParent).GetContainerWidget
5700   else
5701     Parent := nil;
5702 
5703   Widget := QWidget_create(Parent);
5704   Result := Widget;
5705 end;
5706 
5707 procedure TQtWidget.DestroyWidget;
5708 begin
5709   if (Widget <> nil) and FOwnWidget then
5710     QObject_deleteLater(Widget);
5711   Widget := nil;
5712 end;
5713 
5714 { TQtAbstractButton }
5715 
5716 procedure TQtAbstractButton.setIcon(AIcon: QIconH);
5717 begin
5718   QAbstractButton_setIcon(QAbstractButtonH(Widget), AIcon);
5719 end;
5720 
5721 procedure TQtAbstractButton.setIconSize(Size: PSize);
5722 begin
5723   QAbstractButton_setIconSize(QAbstractButtonH(Widget), Size);
5724 end;
5725 
5726 procedure TQtAbstractButton.setShortcut(AShortCutK1, AShortCutK2: TShortcut);
5727 var
5728   Key: Word;
5729   Shift: TShiftState;
5730   QtK1, QtK2: integer;
5731   KeySequence: QKeySequenceH;
5732 begin
5733   QtK1 := 0;
5734   QtK2 := 0;
5735   if AShortCutK1 <> 0 then
5736   begin
5737     ShortCutToKey(AShortCutK1, Key, Shift);
5738     QtK1 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
5739     if AShortCutK2 <> 0 then
5740     begin
5741       ShortCutToKey(AShortCutK2, Key, Shift);
5742       QtK2 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
5743     end;
5744   end;
5745   KeySequence := QKeySequence_create(QtK1, QtK2);
5746   QAbstractButton_setShortcut(QAbstractButtonH(Widget), KeySequence);
5747   QKeySequence_destroy(KeySequence);
5748 end;
5749 
5750 {------------------------------------------------------------------------------
5751   Function: TQtAbstractButton.SetText
5752   Params:  None
5753   Returns: Nothing
5754  ------------------------------------------------------------------------------}
5755 procedure TQtAbstractButton.SetText(const W: WideString);
5756 begin
5757   QAbstractButton_setText(QAbstractButtonH(Widget), @W);
5758 end;
5759 
TQtAbstractButton.ProcessArrowKeysnull5760 function TQtAbstractButton.ProcessArrowKeys: Boolean;
5761 begin
5762   Result := True;
5763 end;
5764 
TQtAbstractButton.CanPaintBackgroundnull5765 function TQtAbstractButton.CanPaintBackground: Boolean;
5766 begin
5767   Result := CanSendLCLMessage and getEnabled and
5768     (LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
5769     // DO NOT REMOVE ! QCheckBox,QRadioButton default = clBackground  !
5770 end;
5771 
TQtAbstractButton.getIconSizenull5772 function TQtAbstractButton.getIconSize: TSize;
5773 begin
5774   QAbstractButton_iconSize(QAbstractButtonH(Widget), @Result);
5775 end;
5776 
5777 {------------------------------------------------------------------------------
5778   Function: TQtAbstractButton.Text
5779   Params:  None
5780   Returns: Nothing
5781  ------------------------------------------------------------------------------}
getTextnull5782 function TQtAbstractButton.getText: WideString;
5783 begin
5784   QAbstractButton_text(QAbstractButtonH(Widget), @Result);
5785 end;
5786 
5787 procedure TQtAbstractButton.Toggle;
5788 begin
5789   QAbstractButton_toggle(QAbstractButtonH(Widget));
5790 end;
5791 
5792 {------------------------------------------------------------------------------
5793   Function: TQtAbstractButton.isChecked
5794   Params:  None
5795   Returns: Nothing
5796  ------------------------------------------------------------------------------}
TQtAbstractButton.isCheckednull5797 function TQtAbstractButton.isChecked: Boolean;
5798 begin
5799   Result := QAbstractButton_isChecked(QAbstractButtonH(Widget));
5800 end;
5801 
TQtAbstractButton.isDownnull5802 function TQtAbstractButton.isDown: Boolean;
5803 begin
5804   Result := QAbstractButton_isDown(QAbstractButtonH(Widget));
5805 end;
5806 
5807 procedure TQtAbstractButton.setCheckable(p1: Boolean);
5808 begin
5809   QAbstractButton_setCheckable(QAbstractButtonH(Widget), p1);
5810 end;
5811 
5812 {------------------------------------------------------------------------------
5813   Function: TQtAbstractButton.setChecked
5814   Params:  None
5815   Returns: Nothing
5816  ------------------------------------------------------------------------------}
5817 procedure TQtAbstractButton.setChecked(p1: Boolean);
5818 begin
5819   QAbstractButton_setChecked(QAbstractButtonH(Widget), p1);
5820 end;
5821 
5822 procedure TQtAbstractButton.setDefaultColorRoles;
5823 begin
5824   WidgetColorRole := QPaletteButton;
5825   TextColorRole := QPaletteButtonText;
5826 end;
5827 
5828 procedure TQtAbstractButton.setDown(p1: Boolean);
5829 begin
5830   QAbstractButton_setDown(QAbstractButtonH(Widget), p1);
5831 end;
5832 
5833 {------------------------------------------------------------------------------
5834   Function: TQtAbstractButton.SignalPressed
5835   Params:  None
5836   Returns: Nothing
5837  ------------------------------------------------------------------------------}
5838 procedure TQtAbstractButton.SignalPressed; cdecl;
5839 var
5840   Msg: TLMessage;
5841 begin
5842   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5843   Msg.Msg := LM_KEYDOWN;
5844   DeliverMessage(Msg);
5845 end;
5846 
5847 {------------------------------------------------------------------------------
5848   Function: TQtAbstractButton.SignalReleased
5849   Params:  None
5850   Returns: Nothing
5851  ------------------------------------------------------------------------------}
5852 procedure TQtAbstractButton.SignalReleased; cdecl;
5853 var
5854   Msg: TLMessage;
5855 begin
5856   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5857   Msg.Msg := LM_KEYUP;
5858   DeliverMessage(Msg);
5859 end;
5860 
5861 {------------------------------------------------------------------------------
5862   Function: TQtAbstractButton.SignalClicked
5863   Params:  None
5864   Returns: Nothing
5865  ------------------------------------------------------------------------------}
5866 procedure TQtAbstractButton.SignalClicked(Checked: Boolean = False); cdecl;
5867 var
5868   Msg: TLMessage;
5869 begin
5870   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5871   Msg.Msg := LM_CHANGED;
5872   DeliverMessage(Msg);
5873 end;
5874 
5875 {------------------------------------------------------------------------------
5876   Function: TQtAbstractButton.SignalClicked2
5877   Params:  None
5878   Returns: Nothing
5879  ------------------------------------------------------------------------------}
5880 procedure TQtAbstractButton.SignalClicked2; cdecl;
5881 var
5882   Msg: TLMessage;
5883 begin
5884   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5885   Msg.Msg := LM_CLICKED;
5886   DeliverMessage(Msg);
5887 end;
5888 
5889 { TQtPushButton }
5890 
TQtPushButton.CreateWidgetnull5891 function TQtPushButton.CreateWidget(const AParams: TCreateParams): QWidgetH;
5892 var
5893   Parent: QWidgetH;
5894 begin
5895   if AParams.WndParent <> 0 then
5896     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
5897   else
5898     Parent := nil;
5899   Result := QPushButton_create(Parent);
5900 end;
5901 
5902 procedure TQtPushButton.preferredSize(var PreferredWidth,
5903   PreferredHeight: integer; WithThemeSpace: Boolean);
5904 var
5905   Size: TSize;
5906 
AutoSizeButtonFromStylenull5907   function AutoSizeButtonFromStyle(const ASize: TSize): TSize;
5908   var
5909     AOpt: QStyleOptionButtonH;
5910     AText: WideString;
5911     AMetrics: QFontMetricsH;
5912     BtnWidth: Integer;
5913     BtnHeight: Integer;
5914     AIcon: QIconH;
5915     IconSize: TSize;
5916     {style pixel metrics}
5917     BtnMargin, FocusH, FocusV, ShiftH, ShiftV: Integer;
5918   begin
5919     Result := ASize;
5920     AOpt := QStyleOptionButton_create();
5921     QStyleOption_initFrom(AOpt, Widget);
5922     AText := getText;
5923     QStyleOptionButton_setText(AOpt, @AText);
5924     AMetrics := QFontMetrics_create(QWidget_font(Widget));
5925     try
5926       QStyleOption_fontMetrics(AOpt, AMetrics);
5927       BtnWidth := QFontMetrics_width(AMetrics, PWideString(@AText));
5928       BtnHeight := QFontMetrics_height(AMetrics);
5929       Result.cx := BtnWidth;
5930       Result.cy := BtnHeight;
5931 
5932       BtnMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
5933       FocusV := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
5934       FocusH := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
5935       ShiftH := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
5936       ShiftV := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
5937 
5938       if ShiftH = 0 then
5939         ShiftH := FocusH;
5940 
5941       //writeln('ButtonSizeFromStyle:  Metrics W=',BtnWidth,' H=',BtnHeight,
5942       //  ' BtnMargin ',BtnMargin,' FocusV ',FocusV,' FocusH ',FocusH,
5943       //  ' ShiftH ',ShiftH,' ShiftV ',ShiftV);
5944 
5945       Result.cx := Result.cx + BtnMargin + (FocusH * 2) + (ShiftH * 2);
5946       Result.cy := Result.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2);
5947 
5948       // now check if we have icon
5949       AIcon := QIcon_create();
5950       try
5951         QAbstractButton_icon(QPushButtonH(Widget), AIcon);
5952         if not QIcon_isNull(AIcon) then
5953         begin
5954           QAbstractButton_iconSize(QPushButtonH(Widget), @IconSize);
5955           Result.cx := Result.cx + IconSize.cx + (FocusH * 2) + (ShiftH * 2);
5956           if IconSize.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2) > Result.cy then
5957             Result.cy := IconSize.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2);
5958         end;
5959       finally
5960         QIcon_destroy(AIcon);
5961       end;
5962 
5963     finally
5964       QStyleOptionButton_destroy(AOpt);
5965       QFontMetrics_destroy(AMetrics);
5966     end;
5967   end;
5968 begin
5969   // qt doesn't return proper autosize for us.QSizePolicy class is missing.
5970   QPushButton_sizeHint(QPushButtonH(Widget), @Size);
5971   {qtlcl implementation of buttons autosizing, replace if/when we
5972    get QSizePolicy class into bindings}
5973   if Assigned(LCLObject) and LCLObject.AutoSize then
5974     Size := AutoSizeButtonFromStyle(Size);
5975   PreferredWidth := Size.cx;
5976   PreferredHeight := Size.cy;
5977 end;
5978 
5979 procedure TQtPushButton.SetDefault(const ADefault: Boolean);
5980 begin
5981   QPushButton_setDefault(QPushButtonH(Widget), ADefault);
5982 end;
5983 
5984 procedure TQtPushButton.AttachEvents;
5985 begin
5986   inherited AttachEvents;
5987 
5988   FClickedHook := QAbstractButton_hook_create(Widget);
5989   QAbstractButton_hook_hook_clicked2(FClickedHook, @SlotClicked);
5990 
5991   FToggledHook := QAbstractButton_hook_create(Widget);
5992   QAbstractButton_hook_hook_toggled(FToggledHook, @SlotToggled);
5993 end;
5994 
5995 procedure TQtPushButton.DetachEvents;
5996 begin
5997   if FClickedHook <> nil then
5998   begin
5999     QAbstractButton_hook_destroy(FClickedHook);
6000     FClickedHook := nil;
6001   end;
6002   if FToggledHook <> nil then
6003   begin
6004     QAbstractButton_hook_destroy(FToggledHook);
6005     FToggledHook := nil;
6006   end;
6007   inherited DetachEvents;
6008 end;
6009 
6010 {------------------------------------------------------------------------------
6011   Function: TQtPushButton.SlotClicked
6012   Params:  None
6013   Returns: Nothing
6014  ------------------------------------------------------------------------------}
6015 procedure TQtPushButton.SlotClicked; cdecl;
6016 var
6017   Msg: TLMessage;
6018 begin
6019   FillChar(Msg{%H-}, SizeOf(Msg), 0);
6020   Msg.Msg := LM_CLICKED;
6021   DeliverMessage(Msg);
6022 end;
6023 
6024 procedure TQtPushButton.SlotToggled(AChecked: Boolean); cdecl;
6025 begin
6026   // override later (eg. TQtToggleBox)
6027 end;
6028 
6029 { TQtBitBtn }
6030 
CreateWidgetnull6031 function TQtBitBtn.CreateWidget(const AParams: TCreateParams): QWidgetH;
6032 var
6033   Parent: QWidgetH;
6034 begin
6035   HasPaint := True;
6036   FGlyphLayout := 0;
6037   FText := '';
6038   FIcon := nil;
6039   FIconSize.cx := 0;
6040   FIconSize.cy := 0;
6041   if AParams.WndParent <> 0 then
6042     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
6043   else
6044     Parent := nil;
6045   Result := QPushButton_create(Parent);
6046 end;
6047 
6048 destructor TQtBitBtn.Destroy;
6049 begin
6050   if Assigned(FIcon) then
6051     QIcon_destroy(FIcon);
6052   inherited Destroy;
6053 end;
6054 
EventFilternull6055 function TQtBitBtn.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
6056   cdecl;
6057 
6058   function IconValid: boolean;
6059   begin
6060     Result := Assigned(FIcon) and not QIcon_isNull(FIcon) and
6061       (FIconSize.cx > 0) and (FIconSize.cy > 0);
6062   end;
6063 
6064   function PaintBtn: Boolean;
6065   var
6066     APainter: QPainterH;
6067     R: TRect;
6068     R2: TRect;
6069     R3: TRect;
6070     BMargin, HMargin, VMargin, SHorz, SVert: Integer;
6071     IconMode: QIconMode;
6072     IconAlign: QtAlignment;
6073     CenterOffset, W {, H}: Integer;
6074     AFontMetrics: QFontMetricsH;
6075     AText: WideString;
6076     DTFLAGS: DWord;
6077     ContentSize: TSize;
6078     IconDistance: Integer;
6079     IconMargin: Integer;
6080   begin
6081     Result := False;
6082     if (FIcon = nil) then
6083       exit;
6084 
6085     // paint button
6086     QObject_event(Widget, Event);
6087 
6088     IconDistance := TCustomBitBtn(LCLObject).Spacing;
6089     if IconDistance < 0 then
6090       IconDistance := 4; {qt default}
6091 
6092     IconMargin := TCustomBitBtn(LCLObject).Margin;
6093 
6094     // now we paint icon & text
6095     APainter := QPainter_create(QWidget_to_QPaintDevice(Widget));
6096     AText := FText;
6097     try
6098       QPainter_setBackgroundMode(APainter, QtTransparentMode);
6099       QWidget_rect(Widget, @R);
6100 
6101       BMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
6102       VMargin := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
6103       HMargin := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
6104       SHorz := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
6105       SVert := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
6106 
6107       if SHorz = 0 then
6108         SHorz := HMargin;
6109 
6110       if not getEnabled then
6111         IconMode := QIconDisabled
6112       else
6113       if QWidget_underMouse(Widget) then
6114         IconMode := QIconActive
6115       else
6116         IconMode := QIconNormal;
6117 
6118       inc(R.Left, HMargin + SHorz);
6119       inc(R.Top, VMargin + SVert);
6120       dec(R.Right, HMargin + SHorz);
6121       dec(R.Bottom, VMargin + SVert);
6122 
6123       W := R.Right - R.Left;
6124       // H := R.Bottom - R.Top;
6125 
6126       ContentSize.CX := 0;
6127       ContentSize.CY := 0;
6128       R3 := Rect(0, 0, 0, 0);
6129 
6130       DTFlags := DT_CENTER or DT_VCENTER;
6131       if IconValid then
6132       begin
6133         R2 := R;
6134         AFontMetrics := QFontMetrics_create(QPainter_font(APainter));
6135         QPainter_fontMetrics(APainter, AFontMetrics);
6136 
6137         // QtTextShowMnemonic = $0800
6138         if FText = '' then
6139           R3 := Rect(0, 0, 0, 0)
6140         else
6141           QFontMetrics_boundingRect(AFontMetrics, PRect(@R3), 0, 0,
6142             QWidget_width(Widget), QWidget_height(Widget), QtAlignLeft or $0800, @AText);
6143 
6144         QFontMetrics_destroy(AFontMetrics);
6145 
6146         ContentSize.cx := (R3.Right - R3.Left) + FIconSize.cx + IconDistance;
6147         ContentSize.cy := FIconSize.cy + IconDistance + (R3.Bottom - R3.Top);
6148 
6149         if FText = '' then
6150           IconAlign := QtAlignHCenter or QtAlignVCenter
6151         else
6152         case GlyphLayout of
6153           1: // right
6154           begin
6155             DTFLAGS := DT_RIGHT or DT_VCENTER;
6156             dec(R2.Right, BMargin div 2);
6157             IconAlign := QtAlignRight or QtAlignVCenter;
6158             dec(R2.Right, FIconSize.cx);
6159           end;
6160           2: // top
6161           begin
6162             inc(R2.Top, BMargin div 2);
6163             IconAlign := QtAlignTop or QtAlignHCenter;
6164             inc(R2.Top, FIconSize.cy);
6165           end;
6166           3: // bottom
6167           begin
6168             dec(R2.Bottom, BMargin div 2);
6169             IconAlign := QtAlignBottom or QtAlignHCenter;
6170             dec(R2.Bottom, FIconSize.cy);
6171           end;
6172           else
6173           begin // left
6174             DTFLAGS := DT_LEFT or DT_VCENTER;
6175             inc(R2.Left, BMargin div 2);
6176             IconAlign := QtAlignLeft or QtAlignVCenter;
6177             inc(R2.Left, FIconSize.cx);
6178           end;
6179         end;
6180       end;
6181 
6182       if IconValid then
6183       begin
6184         if FGlyphLayout in [0, 1] then
6185         begin
6186           CenterOffset := ((R.Right - R.Left) div 2) - (ContentSize.cx div 2);
6187           if W - ContentSize.cx - CenterOffset < 0 then
6188             CenterOffset := 0;
6189         end else
6190           CenterOffset := ((R.Bottom - R.Top) div 2) - (ContentSize.cy div 2);
6191 
6192         if IconMargin >= 0 then
6193           CenterOffset := IconMargin;
6194 
6195         if FText <> '' then
6196         begin
6197           if FGlyphLayout = 0 then
6198             inc(R.Left, CenterOffset)
6199           else
6200           if FGlyphLayout = 1 then
6201             dec(R.Right, CenterOffset)
6202           else
6203           if FGlyphLayout = 2 then
6204             inc(R.Top, CenterOffset)
6205           else
6206           if FGlyphLayout = 3 then
6207             dec(R.Bottom, CenterOffset);
6208         end;
6209 
6210         QIcon_paint(FIcon, APainter, @R, IconAlign, IconMode);
6211 
6212         R := R2;
6213         if FGlyphLayout = 0 then
6214           inc(R.Left, CenterOffset + IconDistance)
6215         else
6216         if FGlyphLayout = 1 then
6217           dec(R.Right, CenterOffset + IconDistance)
6218         else
6219         if FGlyphLayout = 2 then
6220           inc(R.Top, CenterOffset + IconDistance)
6221         else
6222         if FGlyphLayout = 3 then
6223           dec(R.Bottom, CenterOffset + IconDistance);
6224       end;
6225 
6226       if AText <> '' then
6227         QPainter_drawText(APainter, R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
6228           DTFlagsToQtFlags(DTFLAGS), @AText);
6229 
6230       QPainter_end(APainter);
6231       Result := True;
6232     finally
6233       QPainter_destroy(APainter);
6234     end;
6235   end;
6236 begin
6237   Result := False;
6238   if (LCLObject <> nil) and (QEvent_type(Event) = QEventPaint) then
6239     Result := PaintBtn
6240   else
6241     Result:=inherited EventFilter(Sender, Event);
6242 end;
6243 
6244 procedure TQtBitBtn.preferredSize(var PreferredWidth, PreferredHeight: integer;
6245   WithThemeSpace: Boolean);
6246 const
6247   IconDistance = 4; // hardcoded in qt libs
6248 var
6249   AOpt: QStyleOptionButtonH;
6250   AText: WideString;
6251   AMetrics: QFontMetricsH;
6252   TextSize: TSize;
6253   {style pixel metrics}
6254   BtnMargin, FocusH, FocusV, ShiftH, ShiftV, fsh, fsvm: Integer;
6255 begin
6256   AOpt := QStyleOptionButton_create();
6257   QStyleOption_initFrom(AOpt, Widget);
6258   AText := getText;
6259   QStyleOptionButton_setText(AOpt, @AText);
6260   AMetrics := QFontMetrics_create(QWidget_font(Widget));
6261   try
6262     QStyleOption_fontMetrics(AOpt, AMetrics);
6263 
6264     // QtTextShowMnemonic = $0800
6265     if AText <> '' then
6266       QFontMetrics_size(AMetrics, PSize(@TextSize),
6267         QtAlignLeft or $0800, PWideString(@AText))
6268     else
6269       TextSize := Size(0, 0);
6270     BtnMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
6271     FocusV := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
6272     FocusH := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
6273     ShiftH := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
6274     ShiftV := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
6275     if ShiftH = 0 then
6276       ShiftH := FocusH;
6277     fsh  := (FocusH * 2) + (ShiftH * 2);
6278     fsvm := (FocusV * 2) + (ShiftV * 2) + BtnMargin;
6279     PreferredWidth  := TextSize.cx + fsh + BtnMargin;
6280     PreferredHeight := TextSize.cy + fsvm;
6281 
6282     // now check if we have icon
6283     if Assigned(FIcon) and not QIcon_isNull(FIcon) then
6284     begin
6285       Inc(PreferredWidth, FIconSize.cx + fsh);
6286       if FIconSize.cy + fsvm > PreferredHeight then
6287         PreferredHeight := FIconSize.cy + fsvm;
6288       if FText <> '' then
6289       begin
6290         if FGlyphLayout in [2, 3] then
6291           Inc(PreferredHeight, TextSize.cy + IconDistance)
6292         else
6293           Inc(PreferredWidth, IconDistance);
6294       end;
6295     end;
6296 
6297     if ShiftV = 0 then
6298       Inc(PreferredHeight, 1);
6299   finally
6300     QStyleOptionButton_destroy(AOpt);
6301     QFontMetrics_destroy(AMetrics);
6302   end;
6303 end;
6304 
getIconSizenull6305 function TQtBitBtn.getIconSize: TSize;
6306 begin
6307   Result := FIconSize;
6308 end;
6309 
getTextnull6310 function TQtBitBtn.getText: WideString;
6311 begin
6312   Result := FText;
6313 end;
6314 
6315 procedure TQtBitBtn.setIcon(AIcon: QIconH);
6316 begin
6317   if Assigned(FIcon) then
6318   begin
6319     QIcon_destroy(FIcon);
6320     FIcon := nil;
6321   end;
6322   FIcon := QIcon_create(AIcon);
6323   if getVisible then
6324     Update(nil);
6325 end;
6326 
6327 procedure TQtBitBtn.setIconSize(Size: PSize);
6328 begin
6329   FIconSize.cx := 0;
6330   FIconSize.cy := 0;
6331   if Size <> nil then
6332     FIconSize := Size^;
6333   if getVisible then
6334     Update(nil);
6335 end;
6336 
6337 procedure TQtBitBtn.setText(const W: WideString);
6338 begin
6339   FText := W;
6340   if getVisible then
6341     Update(nil);
6342 end;
6343 
6344 { TQtToggleBox }
6345 
6346 procedure TQtToggleBox.SlotClicked; cdecl;
6347 begin
6348   // do nothing with ToggleBox
6349 end;
6350 
6351 procedure TQtToggleBox.SlotToggled(AChecked: Boolean); cdecl;
6352 var
6353   Msg: TLMessage;
6354 begin
6355   if InUpdate then
6356     exit;
6357 
6358   FillChar(Msg{%H-}, SizeOf(Msg), #0);
6359   Msg.Msg := LM_CHANGED;
6360   DeliverMessage(Msg);
6361 end;
6362 
6363 
6364 { TQtMDIArea }
6365 
6366 procedure TQtMDIArea.SubWindowActivated(AWindow: QMDISubWindowH); cdecl;
6367 var
6368   ActiveChild: TQtMainWindow;
6369   H: HWND;
6370   W: QWidgetH;
6371   WW: TQtWidget;
6372 begin
6373   {we must fix qt bugs here. QWidget_focusWidget() is lost when
6374    activating mdichild via BringToFront (eg from menu)}
6375   if AWindow <> nil then
6376   begin
6377     H := HwndFromWidgetH(AWindow);
6378     if H <> 0 then
6379       ActiveChild := TQtMainWindow(H)
6380     else
6381       ActiveChild := nil;
6382 
6383     if ActiveChild = nil then
6384       exit;
6385 
6386     W := QWidget_focusWidget(AWindow);
6387     if (W <> nil) and (W <> AWindow) then
6388     begin
6389       H := HwndFromWidgetH(W);
6390       if H <> 0 then
6391       begin
6392         WW := TQtWidget(H);
6393         {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
6394         writeln('TQtMDIArea.SubWindowActivated: *=* Current focus widget ',dbgsName(WW.LCLObject));
6395         {$ENDIF}
6396         {trigger QMDIArea to update it's focusWidget (it could be nil) }
6397         QWidget_setFocus(WW.Widget, QtActiveWindowFocusReason);
6398       end;
6399     end else
6400     begin
6401       // fallback when qt completely looses it's mind about focusWidget() inside
6402       // mdi form.
6403       {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
6404       writeln('TQtMDIArea.SubWindowActivated: fallback - ask TCustomForm.ActiveControl ',
6405         dbgsName(TCustomForm(ActiveChild.LCLObject).ActiveControl));
6406       {$ENDIF}
6407       if Assigned(ActiveChild.LCLObject) and
6408         Assigned(TCustomForm(ActiveChild.LCLObject).ActiveControl) and
6409         TCustomForm(ActiveChild.LCLObject).ActiveControl.HandleAllocated then
6410       begin
6411         WW := TQtWidget(TCustomForm(ActiveChild.LCLObject).ActiveControl.Handle);
6412         {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
6413         writeln('**** SUCCESSFULLY ACTIVATED FOCUS PATCH ****');
6414         {$ENDIF}
6415         QWidget_setFocus(WW.Widget, QtActiveWindowFocusReason);
6416       end;
6417     end;
6418   end;
6419 end;
6420 
6421 constructor TQtMDIArea.Create(const AParent: QWidgetH);
6422 begin
6423   Create;
6424   Widget := QMdiArea_create(AParent);
6425   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
6426   FWidgetLCLFont := nil;
6427   Palette.ForceColor := True;
6428   setDefaultColor(dctFont);
6429   Palette.ForceColor := False;
6430   FSubWindowActivationHook := QMdiArea_hook_create(Widget);
6431   QMdiArea_hook_hook_subWindowActivated(FSubWindowActivationHook, @SubWindowActivated);
6432   QWidget_setMouseTracking(Widget, True);
6433   FillChar(FPaintData, sizeOf(FPaintData), 0);
6434   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
6435   setProperty(viewportWidget, 'lclwidget', Int64(PtrUInt(Self)));
6436   QtWidgetSet.AddHandle(Self);
6437 end;
6438 
6439 destructor TQtMDIArea.Destroy;
6440 begin
6441   if FSubWindowActivationHook <> nil then
6442   begin
6443     QMdiArea_hook_destroy(FSubWindowActivationHook);
6444     FSubWindowActivationHook := nil;
6445   end;
6446   inherited Destroy;
6447 end;
6448 
getClientOffsetnull6449 function TQtMDIArea.getClientOffset: TPoint;
6450 begin
6451   if Assigned(FOwner) then
6452     Result := FOwner.getClientOffset
6453   else
6454     Result := inherited getClientOffset;
6455 end;
6456 
6457 procedure TQtMDIArea.AttachEvents;
6458 begin
6459   inherited AttachEvents;
6460   FViewPortEventHook := QObject_hook_create(QAbstractScrollArea_viewport(QAbstractScrollAreaH(Widget)));
6461   QObject_hook_hook_events(FViewPortEventHook, @ScrollViewEventFilter);
6462 end;
6463 
6464 procedure TQtMDIArea.DetachEvents;
6465 begin
6466   if Assigned(FViewPortEventHook) then
6467   begin
6468     QObject_hook_destroy(FViewPortEventHook);
6469     FViewPortEventHook := nil;
6470   end;
6471   inherited DetachEvents;
6472 end;
6473 
EventFilternull6474 function TQtMDIArea.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
6475   cdecl;
6476 begin
6477   Result := False;
6478   QEvent_accept(Event);
6479   case QEvent_type(Event) of
6480     QEventPaint: ;
6481     QEventMouseButtonPress, QEventMouseButtonRelease,
6482     QEventMouseButtonDblClick: ;
6483     QEventMouseMove, QEventWheel: ;
6484     QEventEnter,
6485     QEventLeave: Result := SlotMouseEnter(Sender, Event);
6486     else
6487       Result:=inherited EventFilter(Sender, Event);
6488   end;
6489 end;
6490 
ScrollViewEventFilternull6491 function TQtMDIArea.ScrollViewEventFilter(Sender: QObjectH; Event: QEventH
6492   ): boolean; cdecl;
6493 var
6494   R: TRect;
6495   Brush: QBrushH;
6496   Color: TQColor;
6497   Painter: QPainterH;
6498   APoint, APos, AOldPos, ANewPos: TQtPoint;
6499   AEvent: QEventH;
6500   APaintEvent: QPaintEventH;
6501 begin
6502   Result := False;
6503   QEvent_accept(Event);
6504   case QEvent_type(Event) of
6505     QEventMouseButtonPress, QEventMouseButtonRelease,
6506     QEventMouseButtonDblClick:
6507     begin
6508       // new event with parent coordinates
6509       APos := QMouseEvent_pos(QMouseEventH(Event))^;
6510       QWidget_mapToParent(Widget, @APoint, @APos);
6511       AEvent := QMouseEvent_create(QEvent_type(Event), @APoint, QMouseEvent_globalPos(QMouseEventH(Event)),
6512         QMouseEvent_button(QMouseEventH(Event)), QMouseEvent_buttons(QMouseEventH(Event)), QInputEvent_modifiers(QInputEventH(Event)));
6513       try
6514         Result := SlotMouse(Sender, AEvent);
6515       finally
6516         QEvent_destroy(AEvent);
6517       end;
6518     end;
6519     QEventMouseMove:
6520     begin
6521       AOldPos := QMouseEvent_globalPos(QMouseEventH(Event))^;
6522       APos := QMouseEvent_pos(QMouseEventH(Event))^;
6523       QWidget_mapToParent(Widget, @APoint, @APos);
6524       AEvent := QMouseEvent_create(QEvent_type(Event), @APoint, QMouseEvent_globalPos(QMouseEventH(Event)),
6525         QMouseEvent_button(QMouseEventH(Event)), QMouseEvent_buttons(QMouseEventH(Event)), QInputEvent_modifiers(QInputEventH(Event)));
6526       try
6527         Result := SlotMouseMove(Sender, AEvent);
6528       finally
6529         QEvent_destroy(AEvent);
6530       end;
6531     end;
6532 
6533     QEventWheel:
6534     begin
6535       APos := QWheelEvent_pos(QWheelEventH(Event))^;
6536       QWidget_mapToParent(Widget, @APoint, @APos);
6537       AEvent := QWheelEvent_create(@APoint, QWheelEvent_delta(QWheelEventH(Event)), QWheelEvent_buttons(QWheelEventH(Event)),
6538         QInputEvent_modifiers(QInputEventH(Event)), QWheelEvent_orientation(QWheelEventH(Event)));
6539       try
6540         Result := SlotMouseWheel(Sender, AEvent);
6541       finally
6542         QEvent_destroy(AEvent);
6543       end;
6544     end;
6545 
6546     QEventEnter,
6547     QEventLeave: Result := SlotMouseEnter(Sender, Event);
6548     QEventHoverEnter,
6549     QEventHoverLeave,
6550     QEventHoverMove:
6551     begin
6552       APos := QHoverEvent_pos(QHoverEventH(Event))^;
6553       AOldPos := QHoverEvent_oldPos(QHoverEventH(Event))^;
6554       QWidget_mapToParent(Widget, @APoint, @APos);
6555       QWidget_mapToParent(Widget, @ANewPos, @AOldPos);
6556       QHoverEvent_create(QEvent_type(Event), @APoint, @ANewPos);
6557       try
6558         Result := SlotHover(Sender, AEvent);
6559       finally
6560         QEvent_destroy(AEvent);
6561       end;
6562     end;
6563     QEventPaint:
6564     begin
6565       QPaintEvent_rect(QPaintEventH(Event), @R);
6566       if CanSendLCLMessage and (LCLObject is TWinControl) then
6567       begin
6568         Brush := QBrush_create;
6569         QMdiArea_background(QMDIAreaH(Widget), Brush);
6570         Color := QBrush_color(Brush)^;
6571         QBrush_destroy(Brush);
6572         Painter := QPainter_create(QWidget_to_QPaintDevice(QWidgetH(Sender)));
6573         Brush := QBrush_create(@Color, QtSolidPattern);
6574         try
6575           QPaintEvent_rect(QPaintEventH(Event), @R);
6576           QPainter_fillRect(Painter, @R, Brush);
6577           QPainter_end(Painter);
6578         finally
6579           QBrush_destroy(Brush);
6580           QPainter_destroy(Painter);
6581         end;
6582         APos.X := 0;
6583         APos.Y := 0;
6584         QWidget_mapToParent(Widget, @APoint, @APos);
6585         FScrollX := -APoint.x;
6586         FScrollY := -APoint.Y;
6587         APaintEvent := QPaintEvent_create(PRect(@R));
6588         try
6589           SlotPaint(Sender, Event);
6590         finally
6591           FScrollX := 0;
6592           FScrollY := 0;
6593           QPaintEvent_destroy(APaintEvent);
6594         end;
6595         Result := True; // do not paint MDIArea again
6596       end;
6597     end;
6598   end;
6599 end;
6600 
ActiveSubWindownull6601 function TQtMDIArea.ActiveSubWindow: QMdiSubWindowH;
6602 begin
6603   Result := QMdiArea_activeSubWindow(QMdiAreaH(Widget));
6604 end;
6605 
6606 procedure TQtMDIArea.ActivateSubWindow(AMdiWindow: QMdiSubWindowH);
6607 begin
6608   if AMdiWindow <> nil then
6609     QMdiArea_setActiveSubWindow(QMdiAreaH(Widget), AMdiWindow);
6610 end;
6611 
6612 {$IFDEF QTSCROLLABLEFORMS}
6613 
6614 { TQtWindowArea }
6615 
6616 procedure TQtWindowArea.AttachEvents;
6617 begin
6618   inherited AttachEvents;
6619   FViewPortEventHook := QObject_hook_create(viewportWidget);
6620   QObject_hook_hook_events(FViewPortEventHook, @ScrollViewEventFilter);
6621 end;
6622 
CanAdjustClientRectOnResizenull6623 function TQtWindowArea.CanAdjustClientRectOnResize: Boolean;
6624 begin
6625   Result := True;
6626 end;
6627 
6628 procedure TQtWindowArea.DetachEvents;
6629 begin
6630   if Assigned(FViewPortEventHook) then
6631   begin
6632     QObject_hook_destroy(FViewPortEventHook);
6633     FViewPortEventHook := nil;
6634   end;
6635   inherited DetachEvents;
6636 end;
6637 
MapToGlobalnull6638 function TQtWindowArea.MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean
6639   ): TPoint;
6640 var
6641   Pt: TPoint;
6642   ARet, AParam: TQtPoint;
6643   R: TRect;
6644 begin
6645   Result := inherited MapToGlobal(APt);
6646 
6647   if ((Result.X < 0) or (Result.Y < 0)) and Assigned(FOwner) and (FOwner is TQtMainWindow) and
6648     not TQtMainWindow(FOwner).IsMDIChild and
6649     not (csDesigning in TQtMainWindow(FOwner).LCLObject.ComponentState)  then
6650   begin
6651     QWidget_geometry(Widget, @R);
6652     if (R.Left >=0) and (R.Top >=0) then {this is valid geometry}
6653       exit;
6654     {all we know is when mapToGlobal returns wrong result is that geometry is wrong}
6655     if Assigned(FOwner) and (FOwner is TQtMainWindow) and not TQtMainWindow(FOwner).IsMdiChild then
6656     begin
6657       ARet.X := 0;
6658       ARet.Y := 0;
6659       AParam.X := APt.X;
6660       AParam.Y := APt.Y;
6661       if Assigned(TQtMainWindow(FOwner).MenuBar) and TQtMainWindow(FOwner).MenuBar.getVisible then
6662       begin
6663         QWidget_mapToGlobal(TQtMainWindow(FOwner).MenuBar.Widget, @ARet, @AParam);
6664         inc(ARet.Y, QWidget_height(TQtMainWindow(FOwner).MenuBar.Widget));
6665         Result.X := ARet.X;
6666         Result.Y := ARet.Y;
6667       end else
6668       begin
6669         QWidget_mapToGlobal(TQtMainWindow(FOwner).Widget, @ARet, @AParam);
6670         Result.X := ARet.X;
6671         Result.Y := ARet.Y;
6672       end;
6673     end;
6674   end;
6675 
6676   if AWithScrollOffset then
6677   begin
6678     Pt := ScrolledOffset;
6679     dec(Result.X, Pt.X);
6680     dec(Result.Y, Pt.Y);
6681   end;
6682 end;
6683 
6684 procedure TQtWindowArea.scroll(dx, dy: integer; ARect: PRect);
6685 begin
6686   inherited scroll(dx, dy, ARect);
6687   FScrollX := FScrollX + dx;
6688   FScrollY := FScrollY + dy;
6689 end;
6690 
EventFilternull6691 function TQtWindowArea.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
6692   cdecl;
6693 begin
6694   Result := False;
6695   if (LCLObject = nil) then
6696     exit;
6697   if (QEvent_Type(Event) in [QEventMouseButtonPress, QEventMouseButtonRelease,
6698     QEventMouseButtonDblClick, QEventMouseMove, QEventWheel, QEventPaint,
6699     QEventHoverEnter, QEventHoverMove, QEventHoverLeave, QEventResize]) then
6700     exit;
6701   Result := inherited EventFilter(Sender, Event);
6702 end;
6703 
ScrollViewEventFilternull6704 function TQtWindowArea.ScrollViewEventFilter(Sender: QObjectH; Event: QEventH
6705   ): Boolean; cdecl;
6706 var
6707   ASize: TSize;
6708   AResizeEvent: QResizeEventH;
6709   ScrollBar: QScrollBarH;
6710 begin
6711   Result := False;
6712   if LCLObject = nil then
6713     exit;
6714   BeginEventProcessing;
6715   try
6716     if (QEvent_Type(Event) in [QEventContextMenu, QEventHoverEnter, QEventPaint,
6717                                QEventHoverMove, QEventHoverLeave, QEventHide,
6718                                {must be added, see issue #29159}
6719                                QEventMouseMove]) then
6720     begin
6721       if (FOwner is TQtMainWindow) and not TQtMainWindow(FOwner).IsFrameWindow and
6722         (TCustomForm(LCLObject).FormStyle = fsMDIForm) and
6723         (TQtMainWindow(FOwner).MDIAreaHandle <> nil) then
6724         // paint via MDIAreaHandle viewport hook
6725       else
6726         Result := inherited EventFilter(Sender, Event);
6727     end else
6728     case QEvent_type(Event) of
6729       QEventResize:
6730       begin
6731         if FOwner <> nil then
6732         begin
6733           {TQtMainWindow does not send resize event if ScrollArea is assigned,
6734            it is done here when viewport geometry is finally updated by Qt.}
6735           ASize := FOwner.getSize;
6736           AResizeEvent := QResizeEvent_create(@ASize, @ASize);
6737           try
6738             // issue #28596 and others of TCustomControl clientrect related
6739             if CanAdjustClientRectOnResize and
6740               LCLObject.ClientRectNeedsInterfaceUpdate then
6741             begin
6742               {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
6743               DebugLn('TQtWindowArea.ScrollViewEventFilter invalidatingClientRectCache ',dbgsName(Self),' LCL=',dbgsName(LCLObject));
6744               {$ENDIF}
6745               LCLObject.InvalidateClientRectCache(False);
6746             end;
6747             SlotResize(AResizeEvent);
6748           finally
6749             QEvent_destroy(AResizeEvent);
6750           end;
6751         end else
6752           LCLObject.DoAdjustClientRectChange;
6753       end;
6754       QEventWheel:
6755         if not getEnabled then
6756           inherited EventFilter(Sender, Event)
6757         else
6758         if (QtVersionMajor = 4) and (QtVersionMinor < 7) then
6759         begin
6760           Result := SlotMouseWheel(Sender, Event);
6761           if not Result then
6762           case QWheelEvent_orientation(QWheelEventH(Event)) of
6763             QtVertical:
6764               begin
6765                 if verticalScrollBar.getVisible then
6766                 begin
6767                   ScrollBar := QScrollBarH(verticalScrollBar.Widget);
6768                   QScrollBar_event(ScrollBar, Event);
6769                 end else
6770                   Result := inherited EventFilter(Sender, Event);
6771               end;
6772             QtHorizontal:
6773             begin
6774               if horizontalScrollBar.getVisible then
6775               begin
6776                 ScrollBar := QScrollBarH(horizontalScrollBar.Widget);
6777                 QScrollBar_event(ScrollBar, Event);
6778               end else
6779                 Result := inherited EventFilter(Sender, Event);
6780             end;
6781           end;
6782           Result := True;
6783           QEvent_ignore(Event);
6784         end;
6785 
6786       QEventLayoutRequest:
6787       begin
6788         if FOwner <> nil then
6789         begin
6790           if LCLObject.ClientRectNeedsInterfaceUpdate then
6791           begin
6792             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
6793             DebugLn('TQtWindowArea.Viewport: ',dbgsName(LCLObject),' QEventLayoutRequest calling DoAdjustClientRectChange CASP=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' ***** !!!! ');
6794             {$ENDIF}
6795             Self.LCLObject.DoAdjustClientRectChange(True);
6796           end;
6797         end;
6798       end;
6799     end;
6800   finally
6801     EndEventProcessing;
6802   end;
6803 end;
6804 
getWindowStatenull6805 function TQtWindowArea.getWindowState: QtWindowStates;
6806 begin
6807   Result := inherited getWindowState;
6808   if Assigned(LCLObject) then
6809     Result := TQtMainWindow(LCLObject.Handle).getWindowState;
6810 end;
6811 
6812 {$ENDIF}
6813 
6814 
6815 { TQtMainWindow }
6816 
CreateWidgetnull6817 function TQtMainWindow.CreateWidget(const AParams: TCreateParams): QWidgetH;
6818   {$IFDEF QTSCROLLABLEFORMS}
6819   procedure SetScrollAreaRules;
6820   begin
6821     FCentralWidget := ScrollArea.Widget;
6822     ScrollArea.ChildOfComplexWidget := ccwAbstractScrollArea;
6823     ScrollArea.LCLObject := LCLObject;
6824 
6825     QFrame_setFrameShape(QAbstractScrollAreaH(ScrollArea.Widget), QFrameNoFrame);
6826     QWidget_setBackgroundRole(ScrollArea.viewportWidget, QPaletteNoRole);
6827     QWidget_setAutoFillBackground(ScrollArea.viewportWidget, False);
6828 
6829     // we must set minimum heigth / width to 1 otherwise we'll have strange
6830     // effect eg. with main ide bar window (small size and cannot resize).
6831     //QWidget_setMinimumHeight(FCentralWidget, 1);
6832     //QWidget_setMinimumWidth(FCentralWidget, 1);
6833     QWidget_setSizePolicy(FCentralWidget, QSizePolicyIgnored, QSizePolicyIgnored);
6834 
6835     ScrollArea.setScrollBarPolicy(True, QtScrollBarAlwaysOff);
6836     ScrollArea.setScrollBarPolicy(False, QtScrollBarAlwaysOff);
6837     ScrollArea.HasPaint := True;
6838     ScrollArea.FOwner := Self;
6839   end;
6840   {$ENDIF}
6841 var
6842   p: QPaletteH;
6843 begin
6844   // Creates the widget
6845   {$ifdef VerboseQt}
6846     WriteLn('TQtMainWindow.CreateWidget Name: ', LCLObject.Name);
6847   {$endif}
6848 
6849   FFirstPaintEvent := False;
6850   FBlocked := False;
6851   FShowOnTaskBar := False;
6852   QtFormBorderStyle := Ord(bsSizeable);
6853   QtFormStyle := Ord(fsNormal);
6854   FHasPaint := True;
6855   FPopupParent := nil;
6856   MDIAreaHandle := nil;
6857   MDIChildArea := nil;
6858   FMDIStateHook := nil;
6859   {$IFDEF QTSCROLLABLEFORMS}
6860   ScrollArea := nil;
6861   {$ENDIF}
6862 
6863   IsMainForm := (LCLObject <> nil) and (LCLObject = Application.MainForm);
6864 
6865   IsFrameWindow := not IsMainForm and (LCLObject is TCustomFrame);
6866   if IsFrameWindow then
6867     QtFormBorderStyle := Ord(bsNone);
6868 
6869   if IsMainForm then
6870   begin
6871 
6872     Result := QMainWindow_create(nil, QtWindow);
6873 
6874     MenuBar := TQtMenuBar.Create(Result);
6875 
6876     if not (csDesigning in LCLObject.ComponentState) then
6877       MenuBar.FIsApplicationMainMenu := True
6878     else
6879       {$IFNDEF DARWIN}
6880       MenuBar.setProperty(MenuBar.Widget,'lcldesignmenubar',1)
6881       {$ENDIF}
6882       ;
6883 
6884     if (Application.MainForm <> nil) and
6885        (Application.MainForm.FormStyle = fsMDIForm) and
6886        not (csDesigning in LCLObject.ComponentState) then
6887     begin
6888       FCentralWidget := QWidget_create(Result);
6889       MDIAreaHandle := TQtMDIArea.Create(Result);
6890       MDIAreaHandle.FOwner := Self;
6891       MDIAreaHandle.LCLObject := LCLObject;
6892       MDIAreaHandle.AttachEvents;
6893       p := QWidget_palette(FCentralWidget);
6894       if p <> nil then
6895         QMdiArea_setBackground(QMdiAreaH(MdiAreaHandle.Widget), QPalette_background(P));
6896       QWidget_setParent(MdiAreaHandle.Widget, FCentralWidget);
6897       QMdiArea_setActivationOrder(QMdiAreaH(MdiAreaHandle.Widget), QMdiAreaActivationHistoryOrder);
6898       QMdiArea_setOption(QMdiAreaH(MdiAreaHandle.Widget),
6899         QMdiAreaDontMaximizeSubWindowOnActivation, True);
6900     end
6901     else
6902     begin
6903       {$IFDEF QTSCROLLABLEFORMS}
6904       ScrollArea := TQtWindowArea.CreateFrom(LCLObject, QAbstractScrollArea_create(Result));
6905       SetScrollAreaRules;
6906       {$ELSE}
6907       FCentralWidget := QWidget_create(Result);
6908       {$ENDIF}
6909       MDIAreaHandle := nil;
6910     end;
6911 
6912     if FCentralWidget <> nil then
6913     begin
6914       QMainWindow_setCentralWidget(QMainWindowH(Result), FCentralWidget);
6915       QWidget_setMouseTracking(FCentralWidget, True);
6916     end;
6917 
6918     if not (csDesigning in LCLObject.ComponentState) then
6919       QMainWindow_setDockOptions(QMainWindowH(Result), QMainWindowAnimatedDocks);
6920   end else
6921   begin
6922     if IsMdiChild then
6923     begin
6924 
6925       if TQtMainWindow(Application.MainForm.Handle).MDIAreaHandle = nil then
6926         raise Exception.Create('MDIChild can be added to MDIForm only !');
6927 
6928       FFirstPaintEvent := True;
6929 
6930       Result := QMdiSubWindow_create(nil, QtWindow);
6931 
6932       // QMdiSubWindow already have an layout
6933 
6934       LayoutWidget := QBoxLayoutH(QWidget_layout(Result));
6935       if LayoutWidget <> nil then
6936         QBoxLayout_destroy(LayoutWidget);
6937     end else
6938     begin
6939       if not IsFrameWindow and (TCustomForm(LCLObject).FormStyle = fsSplash) and
6940         not (csDesigning in LCLObject.ComponentState) then
6941       begin
6942         FFirstPaintEvent := True;
6943         Result := QWidget_create(nil, QtSplashScreen);
6944       end else
6945         Result := QWidget_create(nil, QtWindow);
6946 
6947       QWidget_setAttribute(Result, QtWA_Hover);
6948       QWidget_setMouseTracking(Result, True);
6949     end;
6950 
6951     // Main menu bar
6952     {$IFDEF DARWIN}
6953     MenuBar := TQtMenuBar.Create(nil);
6954     {$ELSE}
6955     MenuBar := TQtMenuBar.Create(Result);
6956     if (csDesigning in LCLObject.ComponentState) then
6957       MenuBar.setProperty(MenuBar.Widget,'lcldesignmenubar',1);
6958     {$ENDIF}
6959 
6960     {$IFDEF QTSCROLLABLEFORMS}
6961     if QWidget_windowType(Result) = QtSplashScreen then
6962       FCentralWidget := QWidget_create(Result)
6963     else
6964     begin
6965       ScrollArea := TQtWindowArea.CreateFrom(LCLObject, QAbstractScrollArea_create(Result));
6966       SetScrollAreaRules;
6967     end;
6968     {$ELSE}
6969     FCentralWidget := QWidget_create(Result);
6970     {$ENDIF}
6971     QWidget_setMouseTracking(FCentralWidget, True);
6972 
6973     LayoutWidget := QBoxLayout_create(QBoxLayoutTopToBottom, Result);
6974 
6975     QBoxLayout_setSpacing(LayoutWidget, 0);
6976     QLayout_setContentsMargins(LayoutWidget, 0, 0, 0, 0);
6977 
6978     // we must fix mouse events in QMDISubWindow by
6979     // adding FCentralWidget as it''s widget
6980     if IsMdiChild then
6981       QMdiSubWindow_setWidget(QMdiSubWindowH(Result), FCentralWidget);
6982 
6983     QLayout_addWidget(LayoutWidget, FCentralWidget);
6984     QWidget_setLayout(Result, QLayoutH(LayoutWidget));
6985     QWidget_setAttribute(Result, QtWA_DeleteOnClose);
6986   end;
6987 end;
6988 
6989 procedure TQtMainWindow.ChangeParent(NewParent: QWidgetH);
6990 var
6991   Flags: QtWindowFlags;
6992   Visible: Boolean;
6993 begin
6994   if NewParent <> Widget then
6995   begin
6996     Visible := getVisible;
6997     Flags := windowFlags;
6998     setParent(NewParent);
6999     setWindowFlags(Flags);
7000     setVisible(Visible);
7001   end;
7002 end;
7003 
7004 procedure TQtMainWindow.UpdateParent;
7005 begin
7006   ChangeParent(FPopupParent);
7007 end;
7008 
7009 {------------------------------------------------------------------------------
7010   Function: TQtMainWindow.Destroy
7011   Params:  None
7012   Returns: Nothing
7013  ------------------------------------------------------------------------------}
7014 destructor TQtMainWindow.Destroy;
7015 begin
7016   // The main window takes care of the menubar handle
7017   {handle validator is added since we added events to
7018    menubar in r33309 (because of font changes).
7019    Events are attached in TQtWSCustomForm.CreateHandle
7020    Sometimes in various combinations we can
7021    crash here because MenuBar <> nil but not valid handle.
7022    Now it's totally safe.}
7023   if QtWidgetSet.IsValidHandle(HWND(MenuBar)) then
7024   begin
7025     MenuBar.DetachEvents;
7026     if FOwnWidget and (MenuBar.Widget <> nil) then
7027       QObject_deleteLater(MenuBar.Widget);
7028     MenuBar.Widget := nil;
7029     FreeThenNil(MenuBar);
7030   end;
7031 
7032   if MDIAreaHandle <> nil then
7033   begin
7034     MDIAreaHandle.DetachEvents;
7035     MDIAreaHandle.Widget := nil;
7036     FreeThenNil(MDIAreaHandle);
7037   end;
7038   {$IFDEF QTSCROLLABLEFORMS}
7039   if QtWidgetSet.IsValidHandle(HWND(ScrollArea)) then
7040   begin
7041     ScrollArea.DetachEvents;
7042     ScrollArea.Widget := nil;
7043     FreeAndNil(ScrollArea);
7044   end;
7045   {$ENDIF}
7046 
7047   inherited Destroy;
7048 end;
7049 
7050 procedure TQtMainWindow.BeginUpdate;
7051 begin
7052   inherited BeginUpdate;
7053   if Assigned(ScrollArea) then
7054     ScrollArea.BeginUpdate;
7055 end;
7056 
7057 procedure TQtMainWindow.EndUpdate;
7058 begin
7059   if Assigned(ScrollArea) then
7060     ScrollArea.EndUpdate;
7061   inherited EndUpdate;
7062 end;
7063 
7064 procedure TQtMainWindow.Activate;
7065 begin
7066   if IsMDIChild then
7067     QMdiArea_setActiveSubWindow(QMdiSubWindow_mdiArea(QMdiSubWindowH(Widget)),
7068       QMdiSubWindowH(Widget))
7069   else
7070     inherited Activate;
7071   {$IFDEF HASX11}
7072   if (QtWidgetSet.WindowManagerName = 'xfwm4') and not IsMDIChild and
7073     QWidget_isModal(Widget) then
7074   begin
7075     if X11GetActivewindow <> Widget then
7076       X11Raise(QWidget_winID(Widget));
7077   end else
7078   if not QWidget_isModal(Widget) then
7079   begin
7080     if (QtWidgetSet.WindowManagerName = 'metacity') and not IsMDIChild then
7081         X11Raise(QWidget_winID(Widget))
7082     else
7083       QWidget_raise(Widget);
7084   end;
7085   {$ENDIF}
7086 end;
7087 
CanAdjustClientRectOnResizenull7088 function TQtMainWindow.CanAdjustClientRectOnResize: Boolean;
7089 begin
7090   {$IFDEF QTSCROLLABLEFORMS}
7091   Result := not Assigned(ScrollArea);
7092   {$ELSE}
7093   Result:=inherited CanAdjustClientRectOnResize;
7094   {$ENDIF}
7095 end;
7096 
TQtMainWindow.getAcceptDropFilesnull7097 function TQtMainWindow.getAcceptDropFiles: Boolean;
7098 begin
7099   Result := QWidget_acceptDrops(Widget);
7100 end;
7101 
GetContainerWidgetnull7102 function TQtMainWindow.GetContainerWidget: QWidgetH;
7103 begin
7104   {$IFDEF QTSCROLLABLEFORMS}
7105   if IsFrameWindow then
7106     Result := ScrollArea.GetContainerWidget
7107   else
7108   if not Assigned(ScrollArea) or (QWidget_windowType(Widget) = QtToolTip) or
7109     (QWidget_windowType(Widget) = QtSplashScreen) or
7110     (TCustomForm(LCLObject).FormStyle = fsMdiForm) then
7111     Result := inherited GetContainerWidget
7112   else
7113     Result := ScrollArea.GetContainerWidget;
7114   {$ELSE}
7115   Result := inherited GetContainerWidget;
7116   {$ENDIF}
7117 end;
7118 
7119 procedure TQtMainWindow.grabMouse;
7120 begin
7121   {$IFDEF QTSCROLLABLEFORMS}
7122   if not Assigned(ScrollArea) then
7123     inherited grabMouse
7124   else
7125     ScrollArea.grabMouse;
7126   {$ELSE}
7127   inherited grabMouse;
7128   {$ENDIF}
7129 end;
7130 
getClientBoundsnull7131 function TQtMainWindow.getClientBounds: TRect;
7132 begin
7133   {$IFDEF QTSCROLLABLEFORMS}
7134   if Assigned(ScrollArea) then
7135   begin
7136     if not ScrollArea.testAttribute(QtWA_PendingResizeEvent) then
7137       Result := ScrollArea.getClientBounds
7138     else
7139       Result := inherited GetClientBounds;
7140   end else
7141   {$ENDIF}
7142   Result:=inherited getClientBounds;
7143 end;
7144 
getClientOffsetnull7145 function TQtMainWindow.getClientOffset: TPoint;
7146 begin
7147   {$IFDEF QTSCROLLABLEFORMS}
7148   if Assigned(ScrollArea) then
7149     Result := ScrollArea.getClientOffset
7150   else
7151     Result := inherited getClientOffset;
7152   if Assigned(ScrollArea) and Assigned(MenuBar) and
7153     (MenuBar.getVisible) then
7154       inc(Result.Y, MenuBar.getHeight);
7155   {$ELSE}
7156   Result:=inherited getClientOffset;
7157   {$ENDIF}
7158 end;
7159 
getTextnull7160 function TQtMainWindow.getText: WideString;
7161 begin
7162   WindowTitle(@Result);
7163 end;
7164 
TQtMainWindow.getTextStaticnull7165 function TQtMainWindow.getTextStatic: Boolean;
7166 begin
7167   Result := False;
7168 end;
7169 
TQtMainWindow.MapToGlobalnull7170 function TQtMainWindow.MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean
7171   ): TPoint;
7172 begin
7173   {$IFDEF QTSCROLLABLEFORMS}
7174   if Assigned(ScrollArea) then
7175     Result := ScrollArea.MapToGlobal(APt, AWithScrollOffset)
7176   else
7177     Result := inherited MapToGlobal(APt, AWithScrollOffset);
7178   {$ELSE}
7179   Result := inherited MapToGlobal(APt, AWithScrollOffset);
7180   {$ENDIF}
7181 end;
7182 
7183 procedure TQtMainWindow.Update(ARect: PRect);
7184 var
7185   R,R1: TRect;
7186 begin
7187   if Assigned(MDIAreaHandle) and not IsMDIChild then
7188   begin
7189     if ARect = nil then
7190       QWidget_update(MDIAreaHandle.viewportWidget)
7191     else
7192     begin
7193       R1 := ARect^;
7194       QWidget_geometry(MDIAreaHandle.Widget, @R);
7195       OffsetRect(R1, -R.Left, -R.Top);
7196       QWidget_update(MDIAreaHandle.viewportWidget, @R1);
7197     end;
7198   end else
7199     inherited Update(ARect);
7200 end;
7201 
7202 procedure TQtMainWindow.UpdateRegion(ARgn: QRegionH);
7203 var
7204   R1, R: TRect;
7205   ANewRgn: QRegionH;
7206 begin
7207   if Assigned(MDIAreaHandle) and not IsMDIChild then
7208   begin
7209     if ARgn = nil then
7210       QWidget_update(MDIAreaHandle.viewportWidget)
7211     else
7212     begin
7213       QRegion_boundingRect(ARgn, @R1);
7214       QWidget_geometry(MDIAreaHandle.Widget, @R);
7215       OffsetRect(R1, -R.Left, -R.Top);
7216       ANewRgn := QRegion_create(PRect(@R1));
7217       QWidget_update(MDIAreaHandle.viewportWidget, ANewRgn);
7218       QRegion_destroy(ANewRgn);
7219     end;
7220   end else
7221     inherited UpdateRegion(ARgn);
7222 end;
7223 
7224 procedure TQtMainWindow.Repaint(ARect: PRect);
7225 var
7226   R, R1: TRect;
7227 begin
7228   if Assigned(MDIAreaHandle) and not IsMDIChild then
7229   begin
7230     if ARect = nil then
7231       QWidget_repaint(MDIAreaHandle.viewportWidget)
7232     else
7233     begin
7234       R1 := ARect^;
7235       QWidget_geometry(MDIAreaHandle.Widget, @R);
7236       OffsetRect(R1, -R.Left, -R.Top);
7237       QWidget_repaint(MDIAreaHandle.viewportWidget, @R1);
7238     end;
7239   end else
7240     inherited Repaint(ARect);
7241 end;
7242 
7243 procedure TQtMainWindow.Resize(ANewWidth, ANewHeight: Integer);
7244 begin
7245   if not IsMDIChild and not IsFrameWindow and
7246     (TCustomForm(LCLObject).BorderStyle in [bsDialog, bsNone, bsSingle]) and
7247      not (csDesigning in LCLObject.ComponentState) then
7248     QWidget_setFixedSize(Widget, ANewWidth, ANewHeight)
7249   else
7250     inherited Resize(ANewWidth, ANewHeight);
7251 end;
7252 
7253 procedure TQtMainWindow.setText(const W: WideString);
7254 begin
7255   setWindowTitle(@W);
7256 end;
7257 
7258 procedure TQtMainWindow.setMenuBar(AMenuBar: QMenuBarH);
7259 begin
7260   if IsMainForm then
7261     QMainWindow_setMenuBar(QMainWindowH(Widget), AMenuBar)
7262   else
7263     QLayout_setMenuBar(LayoutWidget, AMenuBar);
7264 end;
7265 
7266 {------------------------------------------------------------------------------
7267   Function: TQtMainWindow.EventFilter
7268   Params:  None
7269   Returns: Nothing
7270  ------------------------------------------------------------------------------}
TQtMainWindow.EventFilternull7271 function TQtMainWindow.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
7272   cdecl;
7273 var
7274   AStateEvent: QWindowStateChangeEventH;
7275   AState: QtWindowStates;
7276   AOldState: QtWindowStates;
7277   CanSendEvent: Boolean;
7278   {$IFDEF MSWINDOWS}
7279   i: Integer;
7280   AForm: TCustomForm;
7281   w: QWidgetH;
7282   {$ENDIF}
7283   {$IFDEF HASX11}
7284   IsMinimizeEvent: Boolean;
7285   {$ENDIF}
7286 begin
7287   Result := False;
7288   QEvent_accept(Event);
7289   if LCLObject = nil then
7290     exit;
7291 
7292   {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
7293   if (QEvent_type(Event)=QEventWindowActivate) or
7294     (QEvent_type(Event)=QEventWindowDeactivate) or
7295     (QEvent_type(Event)=QEventShowToParent) or
7296     (QEvent_type(Event)=QEventWindowStateChange) then
7297       WriteLn('TQtMainWindow.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
7298       ' LCLObject=', dbgsName(LCLObject),
7299       ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
7300   {$endif}
7301 
7302   {$IFDEF MSWINDOWS}
7303   if (QEvent_type(Event) = QEventWinIDChange) and not FFirstPaintEvent then
7304      FFirstPaintEvent := True;
7305   {$ENDIF}
7306 
7307   {$IFDEF HASX11}
7308   if (QEvent_type(Event) = QEventPaint) and not FFirstPaintEvent then
7309     FFirstPaintEvent := True;
7310   {$ENDIF}
7311 
7312   {$IFDEF QTSCROLLABLEFORMS}
7313   if Assigned(ScrollArea) and not IsMDIChild then
7314   begin
7315     if QEvent_type(Event) in
7316       [QEventPaint, QEventContextMenu, QEventWheel] then
7317       exit;
7318   end;
7319   {$ENDIF}
7320 
7321   BeginEventProcessing;
7322   try
7323     case QEvent_type(Event) of
7324       QEventHide:
7325       begin
7326         Result := inherited EventFilter(Sender, Event);
7327         {as of r46623 (issue #26893) we use QObject_deleteLater
7328          instead of QWidget_destroy.
7329          QMDIArea does not respond after that, so we must activate next mdichild
7330          according to mdi standards.Looks like Qt4 bug.}
7331         if not Application.Terminated and IsMDIChild then
7332         begin
7333           if Assigned(MDIChildArea) then
7334           begin
7335             if (MDIChildArea.ActiveSubWindow = nil) or
7336               (MDIChildArea.ActiveSubWindow = Widget) then
7337             begin
7338               if not QWidget_isVisibleTo(Widget, MDIChildArea.Widget) then
7339                 QMdiArea_activatePreviousSubWindow(QMDIAreaH(MDIChildArea.Widget));
7340             end;
7341           end;
7342         end;
7343       end;
7344       {$IFDEF QTSCROLLABLEFORMS}
7345       QEventMouseMove: // issue #29159
7346       begin
7347         if (Self is TQtHintWindow) or (IsMdiChild or
7348           (Assigned(LCLObject) and (csDesigning in LCLObject.ComponentState))) then
7349           Result := inherited EventFilter(Sender, Event)
7350         else
7351           Result := False;
7352       end;
7353       {$ENDIF}
7354       QEventMouseButtonPress,
7355       QEventMouseButtonRelease,
7356       QEventMouseButtonDblClick:
7357       begin
7358         if IsMdiChild then
7359         begin
7360           if QMouseEvent_y(QMouseEventH(Event)) <= GetPixelMetric(
7361             QStylePM_TitleBarHeight, nil, Widget) then
7362             QEvent_ignore(Event)
7363           else
7364             Result := SlotMouse(Sender, Event);
7365         end else
7366           Result := SlotMouse(Sender, Event);
7367       end;
7368       QEventWindowUnblocked: Blocked := False;
7369       QEventWindowBlocked: Blocked := True;
7370       QEventWindowActivate:
7371       begin
7372         if not IsMDIChild then
7373         begin
7374           {$IFDEF MSWINDOWS}
7375           // issues #26463, #29744, must restore app if we activate non modal window from taskbar
7376           if (Application.ModalLevel > 0) and
7377             (QApplication_activeModalWidget <> nil) and QWidget_isMinimized(QApplication_activeModalWidget) then
7378           begin
7379             W := QApplication_activeModalWidget;
7380             // back to tray
7381             BeginUpdate;
7382             ShowMinimized;
7383             EndUpdate;
7384             AState := QWidget_windowState(W);
7385             AState := AState and not QtWindowMinimized;
7386             QWidget_setWindowState(W, AState);
7387           end else
7388           {$ENDIF}
7389           SlotActivateWindow(True);
7390         end;
7391       end;
7392       QEventWindowDeactivate: if not IsMDIChild then SlotActivateWindow(False);
7393       QEventShowToParent: ; // do nothing for TQtMainWindow, but leave it unhandled
7394       QEventWindowStateChange:
7395       begin
7396         if IsMDIChild then
7397         begin
7398           //do not process QEventWindowStateChange for MDI children !
7399           //we are doing that job in MDIChildWindowStateChanged slot.
7400           exit;
7401         end;
7402 
7403         CanSendEvent := True;
7404         {$IFDEF HASX11}
7405         // for X11 we must ask state of each modified window.
7406         AState := getWindowState;
7407 
7408         IsMinimizeEvent := AState and QtWindowMinimized <> 0;
7409         if IsMinimizeEvent then
7410         begin
7411           CanSendEvent := IsCurrentDesktop(Widget);
7412           QtWidgetSet.FMinimizedByPager := not CanSendEvent;
7413           if IsMainForm and QtWidgetSet.FMinimizedByPager then
7414             QtWidgetSet.HideAllHints;
7415         end;
7416         {$ENDIF}
7417         if IsMainForm and CanSendEvent then
7418         begin
7419           {$IFNDEF HASX11}
7420           AState := getWindowState;
7421           {$ENDIF}
7422           AStateEvent := QWindowStateChangeEventH(Event);
7423           AOldState := QWindowStateChangeEvent_oldState(AStateEvent);
7424           if AState and QtWindowMinimized <> 0 then
7425           begin
7426             {$IFDEF MSWINDOWS}
7427             for i := 0 to Screen.CustomFormZOrderCount - 1 do
7428             begin
7429               AForm := Screen.CustomFormsZOrdered[i];
7430               if (AForm <> Application.MainForm) and
7431                 // (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and
7432                 AForm.HandleAllocated and AForm.Visible then
7433               begin
7434                 W := TQtWidget(AForm.Handle).Widget;
7435                 if not QWidget_isMinimized(W) then
7436                 begin
7437                   TQtWidget(AForm.Handle).BeginUpdate;
7438                   try
7439                     QWidget_showMinimized(W);
7440                   finally
7441                     TQtWidget(AForm.Handle).EndUpdate;
7442                   end;
7443                 end;
7444               end;
7445             end;
7446             {$ENDIF}
7447             Application.IntfAppMinimize;
7448           end
7449           else
7450           if (AOldState and QtWindowMinimized <> 0) or
7451             (AOldState and QtWindowMaximized <> 0) or
7452             (AOldState and QtWindowFullScreen <> 0) then
7453           begin
7454             {$IFDEF MSWINDOWS}
7455             for i := 0 to Screen.CustomFormZOrderCount - 1 do
7456             begin
7457               AForm := Screen.CustomFormsZOrdered[i];
7458               if (AForm <> Application.MainForm) and
7459                 // (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and
7460                 AForm.HandleAllocated and AForm.Visible then
7461               begin
7462                 W := TQtWidget(AForm.Handle).Widget;
7463                 if QWidget_isMinimized(W) then
7464                 begin
7465                   TQtWidget(AForm.Handle).BeginUpdate;
7466                   try
7467                     QWidget_showNormal(W);
7468                   finally
7469                     TQtWidget(AForm.Handle).EndUpdate;
7470                   end;
7471                 end;
7472               end;
7473             end;
7474             Application.IntfAppRestore;
7475             {$ELSE}
7476 
7477             {$IFDEF HASX11}
7478             // do not activate lazarus app if it wasn't active during
7479             // pager switch !
7480             if (AOldState and QtWindowMinimized <> 0) and
7481               QtWidgetSet.FMinimizedByPager then
7482             begin
7483               QtWidgetSet.FMinimizedByPager := False;
7484               QtWidgetSet.RestoreAllHints;
7485             end else
7486             {$ENDIF}
7487               Application.IntfAppRestore;
7488             {$ENDIF}
7489           end;
7490         end;
7491         if CanSendEvent and not IsFrameWindow then
7492         begin
7493           {$IFDEF MSWINDOWS}
7494           AForm := TCustomForm(LCLObject);
7495           if (fsModal in AForm.FormState) then
7496           begin
7497             AOldState := QWindowStateChangeEvent_oldState(QWindowStateChangeEventH(Event));
7498             AState := GetWindowState;
7499             SlotWindowStateChange;
7500             if (AState and QtWindowMinimized = QtWindowMinimized) and (AOldState and QtWindowMinimized = 0) then
7501               Application.Minimize
7502             else
7503             if (AOldState and QtWindowMinimized = QtWindowMinimized) and (AState and QtWindowMinimized = 0) then
7504               Application.Restore;
7505           end else
7506           if (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and InUpdate then
7507             // do not trigger LCL
7508           else
7509           {$ENDIF}
7510           SlotWindowStateChange;
7511         end;
7512       end;
7513       QEventDrop,
7514       QEventDragMove,
7515       QEventDragEnter:
7516       begin
7517         Result := getAcceptDropFiles;
7518         if (Result) and (QEvent_type(Event) = QEventDrop) then
7519           Result := slotDropFiles(Sender, Event);
7520       end;
7521       QEventResize:
7522       begin
7523         {$IFDEF QTSCROLLABLEFORMS}
7524         if not Assigned(ScrollArea) then
7525         {$ENDIF}
7526           Result := inherited EventFilter(Sender, Event);
7527       end;
7528       QEventPaint:
7529       begin
7530         {do not send paint or resize event to LCL if we are pure TCustomForm,
7531          CWEvent or ScrollArea.EventFilter will process it.
7532          So call SlotPaint only if we are eg TQtHintWindow.}
7533         if (FCentralWidget = nil) or (FCentralWidget = Widget) then
7534           Result := inherited EventFilter(Sender, Event);
7535       end;
7536     else
7537       Result := inherited EventFilter(Sender, Event);
7538     end;
7539   finally
7540     EndEventProcessing;
7541   end;
7542 end;
7543 
7544 procedure TQtMainWindow.MDIChildWindowStateChanged(AOldState: QtWindowStates;
7545   ANewState: QtWindowStates); cdecl;
7546 var
7547   AOld, ANew: QtWindowStates;
7548   Arr: TPtrIntArray;
7549   i: Integer;
7550   W: QMDISubWindowH;
7551   B: Boolean;
7552   FoundWin: Boolean;
7553 begin
7554   // check if state is same without active flag, in that case don't inform lcl.
7555   AOld := AOldState and not QtWindowActive;
7556   ANew := ANewState and not QtWindowActive;
7557   if AOld = ANew then
7558     exit;
7559 
7560   {inform LCL about change}
7561   SlotWindowStateChange;
7562 
7563   if (AOldState and QtWindowMinimized <> 0) and (ANewState and QtWindowMinimized = 0) and
7564     (ANewState and QtWindowMaximized = 0) and LCLObject.ClientRectNeedsInterfaceUpdate then
7565     LCLObject.DoAdjustClientRectChange(True);
7566 
7567   {activate next mdi in chain if we are minimized}
7568   if Assigned(MDIChildArea) and
7569     (ANewState and QtWindowMinimized = QtWindowMinimized) and
7570     (ANewState and QtWindowActive = QtWindowActive) then
7571   begin
7572     QMdiArea_subWindowList(QMdiAreaH(MDIChildArea.Widget), @Arr);
7573     // activate only if MDIChild is not minimized !
7574     // we are using *history activation order*,
7575     // so we must take into account index of
7576     // current minimized win.
7577     B := False;
7578     FoundWin := False;
7579     for i := High(Arr) downto 0 do
7580     begin
7581       W := QMdiSubWindowH(Arr[i]);
7582       AOld := QWidget_windowState(W);
7583       B := W = Widget;
7584       if B and (W <> Widget) and (AOld and QtWindowMinimized = 0) then
7585       begin
7586         FoundWin := True;
7587         MDIChildArea.ActivateSubWindow(W);
7588         break;
7589       end;
7590     end;
7591     // not found lower index window, search for higher one
7592     if not FoundWin then
7593     begin
7594       for i := High(Arr) downto 0 do
7595       begin
7596         W := QMdiSubWindowH(Arr[i]);
7597         AOld := QWidget_windowState(W);
7598         if (W <> Widget) and (AOld and QtWindowMinimized = 0) then
7599         begin
7600           MDIChildArea.ActivateSubWindow(W);
7601           break;
7602         end;
7603       end;
7604     end;
7605 
7606   end;
7607 end;
7608 
IsMdiChildnull7609 function TQtMainWindow.IsMdiChild: Boolean;
7610 begin
7611   Result := (LCLObject <> nil) and not IsFrameWindow and not
7612     (csDesigning in LCLObject.ComponentState) and
7613     (TCustomForm(LCLObject).FormStyle = fsMDIChild) and not IsFormDesign(LCLObject);
7614 end;
7615 
IsModalnull7616 function TQtMainWindow.IsModal: Boolean;
7617 begin
7618   Result := QWidget_isModal(Widget);
7619 end;
7620 
MdiChildCountnull7621 function TQtMainWindow.MdiChildCount: integer;
7622 var
7623   Arr: TPtrIntArray;
7624   Area: QMdiAreaH;
7625 begin
7626   Result := 0;
7627   if IsMdiChild then
7628     Area := QMdiSubWindow_mdiArea(QMdiSubWindowH(Widget))
7629   else
7630     Area := QMDIAreaH(MDIAreaHandle.Widget);
7631   if Area <> nil then
7632   begin
7633     QMdiArea_subWindowList(Area, @Arr);
7634     Result := High(Arr);
7635   end;
7636 end;
7637 
7638 procedure TQtMainWindow.OffsetMousePos(APoint: PQtPoint);
7639 begin
7640   if not IsMdiChild then
7641     inherited OffsetMousePos(APoint);
7642 end;
7643 
7644 procedure TQtMainWindow.setAcceptDropFiles(AValue: Boolean);
7645 begin
7646   QWidget_setAcceptDrops(Widget, AValue);
7647 end;
7648 
7649 procedure TQtMainWindow.setColor(const Value: PQColor);
7650 var
7651   p: QPaletteH;
7652 begin
7653   inherited setColor(Value);
7654   if Assigned(MDIAreaHandle) and Assigned(FCentralWidget) then
7655   begin
7656     p := QWidget_palette(FCentralWidget);
7657     if p <> nil then
7658       QMdiArea_setBackground(QMdiAreaH(MdiAreaHandle.Widget), QPalette_background(P));
7659   end;
7660 end;
7661 
7662 procedure TQtMainWindow.setFocusPolicy(const APolicy: QtFocusPolicy);
7663 begin
7664   {$IFDEF QTSCROLLABLEFORMS}
7665   if Assigned(ScrollArea) then
7666     ScrollArea.setFocusPolicy(APolicy)
7667   else
7668     inherited setFocusPolicy(APolicy);
7669   {$ELSE}
7670   inherited setFocusPolicy(APolicy);
7671   {$ENDIF}
7672 end;
7673 
7674 procedure TQtMainWindow.SlotActivateWindow(vActivate: Boolean); cdecl;
7675 var
7676   Msg: TLMActivate;
7677   FIsActivated: Boolean;
7678 begin
7679   {$ifdef VerboseQt}
7680   WriteLn('TQtWidget.SlotActivateWindow Name', LCLObject.Name, ' vActivate: ', dbgs(vActivate));
7681   {$endif}
7682 
7683   if IsFrameWindow then
7684     exit;
7685 
7686   FillChar(Msg{%H-}, SizeOf(Msg), #0);
7687 
7688   FIsActivated := TCustomForm(LCLObject).Active;
7689   {do not send activate if form is already activated,
7690    also do not send activate if TCustomForm.Parent is assigned
7691    since it's form embedded into another control or form}
7692   if (vActivate = FIsActivated) or (LCLObject.Parent <> nil) then
7693     exit;
7694 
7695   Msg.Msg := LM_ACTIVATE;
7696   if vActivate then
7697     Msg.Active := WA_ACTIVE
7698   else
7699     Msg.Active := WA_INACTIVE;
7700   Msg.ActiveWindow := LCLObject.Handle;
7701 
7702   DeliverMessage(Msg);
7703 end;
7704 
7705 {------------------------------------------------------------------------------
7706   Function: TQtMainWindow.SlotWindowStateChange
7707   Params:  None
7708   Returns: Nothing
7709  ------------------------------------------------------------------------------}
7710 procedure TQtMainWindow.slotWindowStateChange; cdecl;
7711 var
7712   Msg: TLMSize;
7713 begin
7714   {$ifdef VerboseQt}
7715     WriteLn('TQtMainWindow.SlotWindowStateChange');
7716   {$endif}
7717 
7718   FillChar(Msg{%H-}, SizeOf(Msg), #0);
7719 
7720   Msg.Msg := LM_SIZE;
7721   Msg.SizeType := SIZE_RESTORED;
7722 
7723   if getWindowState and QtWindowMinimized <> 0 then
7724     Msg.SizeType := SIZE_MINIMIZED
7725   else
7726   if (getWindowState and QtWindowFullScreen <> 0) then
7727     Msg.SizeType := SIZE_FULLSCREEN
7728   else
7729   if (getWindowState and QtWindowMaximized <> 0) then
7730     Msg.SizeType := SIZE_MAXIMIZED;
7731 
7732   Msg.SizeType := Msg.SizeType or Size_SourceIsInterface;
7733 
7734   {Mdichild sends size of minimized title, and that's bad, after restore client
7735    rect is mismatched and provokes OnResize events.We are sending
7736    to the LCL Width and Height of LCLObject so resize event won't trigger.
7737    issue #27518}
7738   if IsMDIChild and Assigned(LCLObject) and
7739     (getWindowState and QtWindowMinimized <> 0) then
7740   begin
7741     Msg.Width := Word(LCLObject.Width);
7742     Msg.Height := Word(LCLObject.Height);
7743   end else
7744   begin
7745     Msg.Width := Word(getWidth);
7746     Msg.Height := Word(getHeight);
7747   end;
7748   DeliverMessage(Msg);
7749 end;
7750 
7751 procedure TQtMainWindow.setShowInTaskBar(AValue: Boolean);
7752 begin
7753   FShowOnTaskBar := AValue;
7754   {$IFNDEF HASX11}
7755   if not QWidget_isModal(Widget) then
7756     UpdateParent;
7757   {$ENDIF}
7758 end;
7759 
7760 procedure TQtMainWindow.setRealPopupParent(NewParent: QWidgetH);
7761 begin
7762   FPopupParent := NewParent;
7763   UpdateParent;
7764 end;
7765 
TQtMainWindow.WinIDNeedednull7766 function TQtMainWindow.WinIDNeeded: boolean;
7767 begin
7768   Result := False;
7769   {$IFDEF HASX11}
7770   if Assigned(LCLObject) and not IsFormDesign(LCLObject) and
7771     not IsMdiChild and (LCLObject.Parent = nil) and not testAttribute(QtWA_Mapped) and
7772     QWidget_isTopLevel(Widget) then
7773     Result := True;
7774   {$ENDIF}
7775 end;
7776 
7777 procedure TQtMainWindow.AttachEvents;
7778 begin
7779   inherited AttachEvents;
7780   {$IFDEF QTSCROLLABLEFORMS}
7781   FCWEventHook := nil;
7782   {$ENDIF}
7783   if (FCentralWidget <> nil)
7784     {$IFDEF QTSCROLLABLEFORMS} and not Assigned(ScrollArea){$ENDIF} then
7785   begin
7786     FCWEventHook := QObject_hook_create(FCentralWidget);
7787     QObject_hook_hook_events(FCWEventHook, @CWEventFilter);
7788   end;
7789   if IsMDIChild then
7790   begin
7791     FMDIStateHook := QMdiSubWindow_hook_create(Widget);
7792     QMdiSubWindow_hook_hook_windowStateChanged(FMDIStateHook,
7793       @MDIChildWindowStateChanged);
7794   end;
7795 end;
7796 
7797 procedure TQtMainWindow.DetachEvents;
7798 begin
7799   if FCWEventHook <> nil then
7800   begin
7801     QObject_hook_destroy(FCWEventHook);
7802     FCWEventHook := nil;
7803   end;
7804 
7805   if FMDIStateHook <> nil then
7806   begin
7807     QMdiSubWindow_hook_destroy(FMDIStateHook);
7808     FMDIStateHook := nil;
7809   end;
7810 
7811   inherited DetachEvents;
7812 end;
7813 
TQtMainWindow.CWEventFilternull7814 function TQtMainWindow.CWEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
7815 var
7816   R: TRect;
7817   R2: TRect;
7818   i: Integer;
7819 begin
7820   Result := False;
7821 
7822   if LCLObject <> nil then
7823   begin
7824     case QEvent_type(Event) of
7825       QEventPaint: Result := inherited EventFilter(Sender, Event);
7826       QEventResize:
7827         begin
7828           {mdi area part begins}
7829           if MdiAreaHandle <> nil then
7830           begin
7831             {first must get contents rect - all except main menu}
7832             QWidget_contentsRect(FCentralWidget, @R);
7833             {TODO: find better way to find out which controls are top,left,right & bottom aligned ...}
7834             for i := 0 to LCLObject.ControlCount - 1 do
7835             begin
7836               if (LCLObject.Controls[i] is TWinControl) and
7837                 (TWinControl(LCLObject.Controls[i]).Align in [alTop, alLeft, alRight, alBottom]) then
7838               begin
7839                 R2 := TWinControl(LCLObject.Controls[i]).BoundsRect;
7840                 case TWinControl(LCLObject.Controls[i]).Align of
7841                   alLeft: R.Left := R.Left + (R2.Right - R2.Left);
7842                   alTop: R.Top := R.Top + (R2.Bottom - R2.Top);
7843                   alRight: R.Right := R.Right - (R2.Right - R2.Left);
7844                   alBottom: R.Bottom := R.Bottom - (R2.Bottom - R2.Top);
7845                 end;
7846               end;
7847             end; {components loop}
7848             QWidget_setGeometry(MDIAreaHandle.Widget, @R);
7849           end;
7850           {mdi area part end}
7851         end;
7852     end;
7853   end;
7854 end;
7855 
7856 { TQtStaticText }
7857 
TQtStaticText.GetWordWrapnull7858 function TQtStaticText.GetWordWrap: Boolean;
7859 begin
7860   Result := QLabel_wordWrap(QLabelH(Widget));
7861 end;
7862 
7863 procedure TQtStaticText.SetWordWrap(AValue: Boolean);
7864 begin
7865   QLabel_setWordWrap(QLabelH(Widget), AValue);
7866 end;
7867 
CreateWidgetnull7868 function TQtStaticText.CreateWidget(const AParams: TCreateParams): QWidgetH;
7869 var
7870   Parent: QWidgetH;
7871 begin
7872   // Creates the widget
7873   {$ifdef VerboseQt}
7874     WriteLn('TQtStaticText.Create');
7875   {$endif}
7876   FWidgetNeedFontColorInitialization := True;
7877   if AParams.WndParent <> 0 then
7878     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
7879   else
7880     Parent := nil;
7881   Result := QLabel_create(Parent);
7882 end;
7883 
TQtStaticText.CanPaintBackgroundnull7884 function TQtStaticText.CanPaintBackground: Boolean;
7885 begin
7886   Result := CanSendLCLMessage and getEnabled and
7887     (LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
7888 end;
7889 
7890 {------------------------------------------------------------------------------
7891   Function: TQtStaticText.SetText
7892   Params:  None
7893   Returns: Nothing
7894  ------------------------------------------------------------------------------}
7895 procedure TQtStaticText.SetText(const W: WideString);
7896 var
7897   AmpersandPos: Integer;
7898   LocalW: WideString;
7899 begin
7900   LocalW := W;
7901   if TCustomStaticText(LCLObject).ShowAccelChar then
7902   begin
7903     // replace '&' by underline
7904     AmpersandPos := Pos('&', W);
7905     if AmpersandPos > 0 then
7906     begin
7907       LocalW := Copy(W, 1, AmpersandPos - 1) + '<u>';
7908       if AmpersandPos < Length(W) then
7909         LocalW := LocalW + W[AmpersandPos + 1];
7910       LocalW := LocalW + '</u>' + Copy(W, AmpersandPos + 2, Length(W));
7911     end;
7912   end;
7913   QLabel_setText(QLabelH(Widget), @LocalW);
7914 end;
7915 
7916 procedure TQtStaticText.setAlignment(const AAlignment: QtAlignment);
7917 begin
7918   QLabel_setAlignment(QLabelH(Widget), AAlignment);
7919 end;
7920 
7921 {------------------------------------------------------------------------------
7922   Function: TQtStaticText.Text
7923   Params:  None
7924   Returns: Nothing
7925  ------------------------------------------------------------------------------}
TQtStaticText.getTextnull7926 function TQtStaticText.getText: WideString;
7927 begin
7928   QLabel_text(QLabelH(Widget), @Result);
7929 end;
7930 
7931 { TQtCheckBox }
7932 
CreateWidgetnull7933 function TQtCheckBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
7934 var
7935   Parent: QWidgetH;
7936 begin
7937   // Creates the widget
7938   {$ifdef VerboseQt}
7939     WriteLn('TQtCheckBox.Create');
7940   {$endif}
7941   TextColorRole := QPaletteWindowText;
7942   FWidgetNeedFontColorInitialization := True;
7943   if AParams.WndParent <> 0 then
7944     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
7945   else
7946     Parent := nil;
7947 
7948   Result := QCheckBox_create(Parent);
7949 end;
7950 
7951 {------------------------------------------------------------------------------
7952   Function: TQtCheckBox.CheckState
7953   Params:  None
7954   Returns: Nothing
7955  ------------------------------------------------------------------------------}
TQtCheckBox.CheckStatenull7956 function TQtCheckBox.CheckState: QtCheckState;
7957 begin
7958   Result := QCheckBox_checkState(QCheckBoxH(Widget));
7959 end;
7960 
7961 {------------------------------------------------------------------------------
7962   Function: TQtCheckBox.setCheckState
7963   Params:  None
7964   Returns: Nothing
7965  ------------------------------------------------------------------------------}
7966 procedure TQtCheckBox.setCheckState(state: QtCheckState);
7967 begin
7968   QCheckBox_setCheckState(QCheckBoxH(Widget), state);
7969 end;
7970 
7971 procedure TQtCheckBox.setTriState(AAllowGrayed: Boolean);
7972 begin
7973   QCheckBox_setTristate(QCheckBoxH(Widget), AAllowGrayed);
7974 end;
7975 
7976 procedure TQtCheckBox.AttachEvents;
7977 begin
7978   inherited AttachEvents;
7979   FStateChangedHook := QCheckBox_hook_create(Widget);
7980   QCheckBox_hook_hook_stateChanged(FStateChangedHook, @SignalStateChanged);
7981 end;
7982 
7983 procedure TQtCheckBox.DetachEvents;
7984 begin
7985   if FStateChangedHook <> nil then
7986   begin
7987     QCheckBox_hook_destroy(FStateChangedHook);
7988     FStateChangedHook := nil;
7989   end;
7990   inherited DetachEvents;
7991 end;
7992 
7993 {------------------------------------------------------------------------------
7994   Function: TQtCheckBox.signalStateChanged
7995   Params:  None
7996   Returns: Nothing
7997  ------------------------------------------------------------------------------}
7998 procedure TQtCheckBox.signalStateChanged(p1: Integer); cdecl;
7999 var
8000   Msg: TLMessage;
8001 begin
8002   if not InUpdate then
8003   begin
8004     FillChar(Msg{%H-}, SizeOf(Msg), #0);
8005     Msg.Msg := LM_CHANGED;
8006     DeliverMessage(Msg);
8007   end;
8008 end;
8009 
8010 { TQtRadioButton }
8011 
TQtRadioButton.CreateWidgetnull8012 function TQtRadioButton.CreateWidget(const AParams: TCreateParams): QWidgetH;
8013 var
8014   Parent: QWidgetH;
8015 begin
8016   // Creates the widget
8017   {$ifdef VerboseQt}
8018     WriteLn('TQtRadioButton.Create');
8019   {$endif}
8020   TextColorRole := QPaletteWindowText;
8021   FWidgetNeedFontColorInitialization := True;
8022   if AParams.WndParent <> 0 then
8023     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8024   else
8025     Parent := nil;
8026   Result := QRadioButton_create(Parent);
8027   // hide widget by default
8028   QWidget_hide(Result);
8029 end;
8030 
8031 procedure TQtRadioButton.AttachEvents;
8032 begin
8033   inherited AttachEvents;
8034   FToggledHook := QAbstractButton_hook_create(Widget);
8035   QAbstractButton_hook_hook_toggled(FToggledHook, @SignalToggled);
8036 end;
8037 
8038 procedure TQtRadioButton.DetachEvents;
8039 begin
8040   if FToggledHook <> nil then
8041   begin
8042     QAbstractButton_hook_destroy(FToggledHook);
8043     FToggledHook := nil;
8044   end;
8045   inherited DetachEvents;
8046 end;
8047 
8048 procedure TQtRadioButton.SignalToggled(Checked: Boolean); cdecl;
8049 var
8050   Msg: TLMessage;
8051 begin
8052   if not InUpdate then
8053   begin
8054     FillChar(Msg{%H-}, SizeOf(Msg), #0);
8055     Msg.Msg := LM_CHANGED;
8056     DeliverMessage(Msg);
8057   end;
8058 end;
8059 
TQtRadioButton.EventFilternull8060 function TQtRadioButton.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
8061 begin
8062   Result := inherited EventFilter(Sender, Event);
8063   if (LCLObject <> nil) and
8064     ((QEvent_type(Event) in [QEventMouseButtonPress, QEventMouseButtonRelease])
8065     or
8066     ((QEvent_type(Event) in [QEventKeyPress, QEventKeyRelease]) and
8067      (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
8068      isChecked))
8069   then
8070     Result := False;
8071 end;
8072 
8073 { TQtGroupBox }
8074 
8075 procedure TQtGroupBox.setLayoutThemeMargins(ALayout: QLayoutH; AWidget: QWidgetH);
8076 var
8077   LeftMargin: Integer;
8078   TopMargin: Integer;
8079   RightMargin: Integer;
8080   BottomMargin: Integer;
8081   {$IFDEF HASX11}
8082   Font: QFontH;
8083   FontMetrics: QFontMetricsH;
8084   FontHeight: Integer;
8085   {$ENDIF}
8086 begin
8087   if ALayout = nil then
8088     exit;
8089   QWidget_getContentsMargins(AWidget,@LeftMargin, @TopMargin, @RightMargin, @BottomMargin);
8090 
8091   {if contentsMargins TopMargin is huge then we must rethink about TopMargin
8092    size (eg.oxygen theme have 32 top margin while plastique have 19
8093    with same font height) }
8094   {$IFDEF HASX11}
8095   Font := QWidget_font(AWidget);
8096   FontMetrics := QFontMetrics_create(Font);
8097   try
8098     FontHeight := QFontMetrics_height(FontMetrics);
8099   finally
8100     QFontMetrics_destroy(FontMetrics);
8101   end;
8102   {currently applies only to wrong TopMargin calculation (eg.gtk style).}
8103   if (TopMargin - FontHeight < 2) then
8104     TopMargin := FontHeight + 2 // top & bottom +1px
8105   else {currently applies only to oxygen & nitrogen theme.}
8106   if ((TopMargin - BottomMargin - 2) > FontHeight) then
8107   begin
8108     {do not touch fusion style !}
8109     if QtWidgetSet.StyleName <> 'fusion' then
8110     begin
8111       TopMargin := TopMargin - BottomMargin - 3;
8112       BottomMargin := 0;
8113     end;
8114   end;
8115   {$ENDIF}
8116   {if there's no text set margin to bottom margin size. issue #23642}
8117   if getText = '' then
8118     TopMargin := BottomMargin;
8119 
8120   QLayout_setContentsMargins(ALayout, LeftMargin, TopMargin, RightMargin, BottomMargin);
8121   QLayout_invalidate(ALayout);
8122 
8123   if (LCLObject <> nil) and testAttribute(QtWA_Mapped) then
8124   begin
8125     {$IFDEF VerboseQtResize}
8126     DebugLn('TQtGroupBox.setLayoutThemeMargins: ',dbgsName(LCLObject),' casp: ',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' mapped ',dbgs(testAttribute(QtWA_Mapped)));
8127     {$ENDIF}
8128     LCLObject.DoAdjustClientRectChange(False);
8129     LCLObject.InvalidateClientRectCache(True);
8130   end;
8131 end;
8132 
TQtGroupBox.GetCheckBoxVisiblenull8133 function TQtGroupBox.GetCheckBoxVisible: boolean;
8134 begin
8135   Result := QGroupBox_isCheckable(QGroupBoxH(Widget));
8136 end;
8137 
GetCheckBoxStatenull8138 function TQtGroupBox.GetCheckBoxState: boolean;
8139 begin
8140   Result := CheckBoxVisible and QGroupBox_isChecked(QGroupBoxH(Widget));
8141 end;
8142 
8143 procedure TQtGroupBox.SetCheckBoxState(AValue: boolean);
8144 begin
8145   if CheckBoxVisible then
8146     QGroupBox_setChecked(QGroupBoxH(Widget), AValue);
8147 end;
8148 
8149 procedure TQtGroupBox.SetCheckBoxVisible(AValue: boolean);
8150 begin
8151   QGroupBox_setCheckable(QGroupBoxH(Widget), AValue);
8152 end;
8153 
TQtGroupBox.CreateWidgetnull8154 function TQtGroupBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
8155 var
8156   Layout: QBoxLayoutH;
8157   Parent: QWidgetH;
8158 begin
8159   // Creates the widget
8160   {$ifdef VerboseQt}
8161     WriteLn('TQtGroupBox.Create ');
8162   {$endif}
8163   FGroupBoxType := tgbtNormal;
8164   FHasPaint := True;
8165   if AParams.WndParent <> 0 then
8166     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8167   else
8168     Parent := nil;
8169   Result := QGroupBox_create(Parent);
8170   FCentralWidget := QStackedWidget_create(Result);
8171   QWidget_setMouseTracking(FCentralWidget, True);
8172   {we set QtNoFocus by default, since we don't want
8173   FCentralWidget grabs focus on mouse click}
8174   QWidget_setFocusPolicy(FCentralWidget, QtNoFocus);
8175 
8176   Layout := QVBoxLayout_create(Result);
8177   QLayout_addWidget(Layout, FCentralWidget);
8178   QWidget_setLayout(Result, QLayoutH(Layout));
8179   QWidget_setAttribute(Result, QtWA_LayoutOnEntireRect, True);
8180 end;
8181 
8182 procedure TQtGroupBox.AttachEvents;
8183 begin
8184   inherited AttachEvents;
8185   if FCentralWidget <> nil then
8186   begin
8187     FCWEventHook := QObject_hook_create(FCentralWidget);
8188     QObject_hook_hook_events(FCWEventHook, @EventFilter);
8189   end;
8190 end;
8191 
8192 procedure TQtGroupBox.DetachEvents;
8193 begin
8194   if FCWEventHook <> nil then
8195   begin
8196     QObject_hook_destroy(FCWEventHook);
8197     FCWEventHook := nil;
8198   end;
8199   inherited DetachEvents;
8200 end;
8201 
TQtGroupBox.CanPaintBackgroundnull8202 function TQtGroupBox.CanPaintBackground: Boolean;
8203 begin
8204   Result := CanSendLCLMessage and getEnabled and
8205     (LCLObject.Color <> clDefault);
8206 end;
8207 
TQtGroupBox.EventFilternull8208 function TQtGroupBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
8209   cdecl;
8210 var
8211   ResizeEvent: QResizeEventH;
8212   NewSize, OldSize: TSize;
8213   R: TRect;
8214   APos, AGlobalPos: TQtPoint;
8215   ANewMouseEvent: QMouseEventH;
8216 begin
8217   Result := False;
8218   QEvent_accept(Event);
8219   if LCLObject = nil then
8220     exit;
8221 
8222   if (Sender = FCentralWidget) then
8223   begin
8224     case QEvent_type(Event) of
8225       QEventPaint: Result := inherited EventFilter(Sender, Event);
8226     end;
8227     exit;
8228   end;
8229   {about issue #29572: we must use main widget for mouse
8230    events, since using it in FCentralWidget above freezes
8231    application for some reason. Offsetting pos fixes problem.}
8232   case QEvent_type(Event) of
8233     QEventWheel: // issue #29572
8234     begin
8235       APos := QMouseEvent_pos(QMouseEventH(Event))^;
8236       AGlobalPos := QMouseEvent_globalPos(QMouseEventH(Event))^;
8237       QWidget_geometry(FCentralWidget, @R);
8238       inc(APos.X, -R.Left);
8239       inc(APos.Y, -R.Top);
8240       ANewMouseEvent := QMouseEvent_create(QEvent_type(Event), @APos, @AGlobalPos, QMouseEvent_button(QMouseEventH(Event)),
8241         QMouseEvent_buttons(QMouseEventH(Event)), QInputEvent_modifiers(QInputEventH(Event)));
8242       try
8243         Result := SlotMouseWheel(Sender, ANewMouseEvent);
8244       finally
8245         QMouseEvent_destroy(ANewMouseEvent);
8246       end;
8247     end;
8248     QEventMouseMove: // issue #29572
8249     begin
8250       APos := QMouseEvent_pos(QMouseEventH(Event))^;
8251       AGlobalPos := QMouseEvent_globalPos(QMouseEventH(Event))^;
8252       QWidget_geometry(FCentralWidget, @R);
8253       inc(APos.X, -R.Left);
8254       inc(APos.Y, -R.Top);
8255       ANewMouseEvent := QMouseEvent_create(QEvent_type(Event), @APos, @AGlobalPos, QMouseEvent_button(QMouseEventH(Event)),
8256         QMouseEvent_buttons(QMouseEventH(Event)), QInputEvent_modifiers(QInputEventH(Event)));
8257       try
8258         Result := SlotMouseMove(Sender, ANewMouseEvent);
8259       finally
8260         QMouseEvent_destroy(ANewMouseEvent);
8261       end;
8262     end;
8263     QEventMouseButtonPress,
8264     QEventMouseButtonRelease,
8265     QEventMouseButtonDblClick: // issue #29572
8266     begin
8267       APos := QMouseEvent_pos(QMouseEventH(Event))^;
8268       AGlobalPos := QMouseEvent_globalPos(QMouseEventH(Event))^;
8269       QWidget_geometry(FCentralWidget, @R);
8270       inc(APos.X, -R.Left);
8271       inc(APos.Y, -R.Top);
8272       ANewMouseEvent := QMouseEvent_create(QEvent_type(Event), @APos, @AGlobalPos, QMouseEvent_button(QMouseEventH(Event)),
8273         QMouseEvent_buttons(QMouseEventH(Event)), QInputEvent_modifiers(QInputEventH(Event)));
8274       try
8275         Result := SlotMouse(Sender, ANewMouseEvent);
8276       finally
8277         QMouseEvent_destroy(ANewMouseEvent);
8278       end;
8279     end;
8280     QEventPaint:
8281       begin
8282         Result := False;
8283         // paint complete background, like gtk2 does
8284         if CanPaintBackground then
8285           SlotPaintBg(Sender, Event);
8286         // issue #28155, we are painting our FCentralWidget, not QGroupBox
8287         // Result := inherited EventFilter(Sender, Event);
8288       end;
8289     QEventFontChange:
8290       begin
8291         Result := inherited EventFilter(Sender, Event);
8292         setLayoutThemeMargins(QWidget_layout(Widget), Widget);
8293       end;
8294     QEventStyleChange: setLayoutThemeMargins(QWidget_layout(Widget), Widget);
8295     QEventContentsRectChange:
8296       begin
8297         if testAttribute(QtWA_Mapped) then
8298           Result := inherited EventFilter(Sender, Event);
8299       end;
8300     QEventShow:
8301       begin
8302         {$IFDEF VerboseQtResize}
8303         DebugLn('TQtGroupBox.QEventShow: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' mapped=',dbgs(testAttribute(QtWA_Mapped)));
8304         {$ENDIF}
8305         LCLObject.DoAdjustClientRectChange(False);
8306         SlotShow(True);
8307         {send dummy LM_SIZE to LCL}
8308         if (FGroupBoxType <> tgbtNormal) and
8309           LCLObject.ClientRectNeedsInterfaceUpdate then
8310         begin
8311           OldSize.cx := LCLObject.Height;
8312           OldSize.cy := LCLObject.Width;
8313           NewSize := OldSize;
8314           inc(OldSize.cx);
8315           inc(OldSize.cy);
8316           ResizeEvent := QResizeEvent_create(@NewSize, @OldSize);
8317           QCoreApplication_postEvent(Widget, ResizeEvent, -1);
8318         end;
8319       end;
8320     else
8321       Result := inherited EventFilter(Sender, Event);
8322   end;
8323 end;
8324 
TQtGroupBox.getClientOffsetnull8325 function TQtGroupBox.getClientOffset: TPoint;
8326 begin
8327   Result:=inherited getClientOffset;
8328   // issue #28155
8329   // there's no client offset since FCentralWidget is at it's position 0,0
8330   if testAttribute(QtWA_Mapped) and QWidget_testAttribute(FCentralWidget, QtWA_Mapped) then
8331     Result := Point(0, 0);
8332 end;
8333 
getClientBoundsnull8334 function TQtGroupBox.getClientBounds: TRect;
8335 var
8336   R, R1: TRect;
8337   L: Integer;
8338   T: Integer;
8339   aRight: Integer;
8340   B: Integer;
8341   AStyleOption: QStyleOptionGroupBoxH;
8342   APixelMetric: Integer;
8343 begin
8344   QWidget_contentsRect(Widget, @R);
8345   if Assigned(FCentralWidget) then
8346     QWidget_rect(FCentralWidget, @R1)
8347   else
8348     R1 := Rect(0, 0, 0, 0);
8349   Result := R;
8350   OffsetRect(Result, -Result.Left, -Result.Top);
8351   {$IFNDEF HASX11}
8352   if testAttribute(QtWA_Mapped) and QWidget_testAttribute(FCentralWidget, QtWA_Mapped) then
8353     QWidget_rect(FCentralWidget, @Result)
8354   else
8355   {$ENDIF}
8356   begin
8357     if Assigned(FCentralWidget) and not IsRectEmpty(R1) then
8358     begin
8359       R := R1;
8360       R1.Left := 0;
8361       R1.Top := 0;
8362       R1.Right := R1.Right - R.Left;
8363       R1.Bottom := R1.Bottom - R.Top;
8364       QWidget_getContentsMargins(Widget,@L, @T, @aRight, @B);
8365       AStyleOption := QStyleOptionGroupBox_create;
8366       APixelMetric := QStyle_pixelMetric(QApplication_style(), QStylePM_DefaultChildMargin, AStyleOption, Widget);
8367       if APixelMetric = 4 then
8368         APixelMetric := 9
8369       else
8370         APixelMetric := 0;
8371       QStyleOptionGroupBox_destroy(AStyleOption);
8372       inc(Result.Bottom, APixelMetric);
8373       {$IFDEF VerboseQtResize}
8374       DebugLn('>>>>>>>>>>> TQtGroupBox.getClientBounds(',dbgsName(LCLObject),') setting clientBounds was ',dbgs(R),' changed to ',dbgs(R1),' from result ',dbgs(Result));
8375       DebugLn('    MARGINS ARE ',Format('l %d t %d r %d b %d',[L, T, ARight, B]),' APixelMetric=',dbgs(APixelMetric));
8376       {$ENDIF}
8377       exit;
8378     end;
8379   end;
8380   {$IFDEF VerboseQtResize}
8381   DebugLn('TQtGroupBox.getClientBounds(',dbgsName(LCLObject),') R=',dbgs(R),' Result=',dbgs(Result),' CENTRALWIDGET=',dbgs(R1),' mapped ',dbgs(testAttribute(QtWA_Mapped)));
8382   {$ENDIF}
8383 end;
8384 
getTextnull8385 function TQtGroupBox.getText: WideString;
8386 begin
8387   QGroupBox_title(QGroupBoxH(Widget), @Result);
8388 end;
8389 
8390 procedure TQtGroupBox.preferredSize(var PreferredWidth,
8391   PreferredHeight: integer; WithThemeSpace: Boolean);
8392 var
8393   L, T, R, B: Integer;
8394   ASize: TSize;
8395 begin
8396   QWidget_getContentsMargins(Widget,@L, @T, @R, @B);
8397   QGroupBox_minimumSizeHint(QGroupBoxH(Widget), @ASize);
8398   PreferredWidth := ASize.cx + L + R;
8399   PreferredHeight := ASize.cy + B + T;
8400   {$IFDEF VerboseQtResize}
8401   DebugLn('TQtGroupBox.preferredSize(',dbgsName(LCLObject),' PrefW=',dbgs(PreferredWidth),
8402     ' PrefH=',dbgs(PreferredHeight),' Mapped ? ',dbgs(testAttribute(QtWA_Mapped)),
8403     ' SizeHint ',dbgs(ASize),' casp ',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
8404   {$ENDIF}
8405 end;
8406 
8407 procedure TQtGroupBox.setText(const W: WideString);
8408 begin
8409   QGroupBox_setTitle(QGroupBoxH(Widget), @W);
8410   setLayoutThemeMargins(QWidget_Layout(Widget), Widget);
8411 end;
8412 
8413 procedure TQtGroupBox.setFocusPolicy(const APolicy: QtFocusPolicy);
8414 begin
8415   if Assigned(LCLObject) and not LCLObject.TabStop then
8416     inherited setFocusPolicy(QtNoFocus)
8417   else
8418     inherited setFocusPolicy(APolicy);
8419 end;
8420 
8421 procedure TQtGroupBox.Update(ARect: PRect);
8422 begin
8423   if Assigned(FCentralWidget) then
8424   begin
8425     if ARect <> nil then
8426       QWidget_update(FCentralWidget, ARect)
8427     else
8428       QWidget_update(FCentralWidget);
8429   end else
8430     inherited Update(ARect);
8431 end;
8432 
8433 procedure TQtGroupBox.UpdateRegion(ARgn: QRegionH);
8434 begin
8435   if Assigned(FCentralWidget) then
8436   begin
8437     if ARgn <> nil then
8438       QWidget_update(FCentralWidget, ARgn)
8439     else
8440       QWidget_update(FCentralWidget);
8441   end else
8442     inherited UpdateRegion(ARgn);
8443 end;
8444 
8445 procedure TQtGroupBox.Repaint(ARect: PRect);
8446 begin
8447   if Assigned(FCentralWidget) then
8448   begin
8449     if ARect <> nil then
8450       QWidget_repaint(FCentralWidget, ARect)
8451     else
8452       QWidget_repaint(FCentralWidget);
8453   end else
8454   inherited Repaint(ARect);
8455 end;
8456 
8457 { TQtFrame }
8458 
CreateWidgetnull8459 function TQtFrame.CreateWidget(const AParams: TCreateParams): QWidgetH;
8460 var
8461   Parent: QWidgetH;
8462 begin
8463   // Creates the widget
8464   {$ifdef VerboseQt}
8465     WriteLn('TQtFrame.Create');
8466   {$endif}
8467   FHasPaint := True;
8468   if AParams.WndParent <> 0 then
8469     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8470   else
8471     Parent := nil;
8472   Result := QFrame_create(Parent);
8473   if (QtVersionMajor = 4) and (QtVersionMinor < 6) then
8474     QWidget_setAutoFillBackground(Result, True);
8475 end;
8476 
TQtFrame.CanPaintBackgroundnull8477 function TQtFrame.CanPaintBackground: Boolean;
8478 begin
8479   Result := CanSendLCLMessage and getEnabled and
8480     (LCLObject.Color <> clBackground) and (LCLObject.Color <> clDefault);
8481 end;
8482 
8483 procedure TQtFrame.SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl;
8484 var
8485   Painter: QPainterH;
8486   Brush: QBrushH;
8487   Color: TQColor;
8488   R: TRect;
8489 begin
8490   if CanSendLCLMessage and (LCLObject is TWinControl) then
8491   begin
8492     if LCLObject.Color = clDefault then
8493       Color := Palette.DefaultColor
8494     else
8495       ColorRefToTQColor(ColorToRGB(LCLObject.Color), Color);
8496     Painter := QPainter_create(QWidget_to_QPaintDevice(QWidgetH(Sender)));
8497     Brush := QBrush_create(@Color, QtSolidPattern);
8498     try
8499       QPaintEvent_rect(QPaintEventH(Event), @R);
8500       QPainter_fillRect(Painter, @R, Brush);
8501       if (LCLObject is TCustomPanel) and (TCustomPanel(LCLObject).BorderStyle <> bsNone) then
8502         q_DrawShadePanel(Painter, PRect(@R), Palette.Handle, True, 2);
8503       QPainter_end(Painter);
8504     finally
8505       QBrush_destroy(Brush);
8506       QPainter_destroy(Painter);
8507     end;
8508   end;
8509 end;
8510 
8511 procedure TQtFrame.setFocusPolicy(const APolicy: QtFocusPolicy);
8512 begin
8513   if Assigned(LCLObject) and not LCLObject.TabStop then
8514     inherited setFocusPolicy(QtNoFocus)
8515   else
8516     inherited setFocusPolicy(APolicy);
8517 end;
8518 
8519 {------------------------------------------------------------------------------
8520   Function: TQtFrame.setFrameStyle
8521   Params:  None
8522   Returns: Nothing
8523  ------------------------------------------------------------------------------}
8524 procedure TQtFrame.setFrameStyle(p1: Integer);
8525 begin
8526   QFrame_setFrameStyle(QFrameH(Widget), p1);
8527 end;
8528 
8529 {------------------------------------------------------------------------------
8530   Function: TQtFrame.setFrameShape
8531   Params:  None
8532   Returns: Nothing
8533  ------------------------------------------------------------------------------}
8534 procedure TQtFrame.setFrameShape(p1: QFrameShape);
8535 begin
8536   QFrame_setFrameShape(QFrameH(Widget), p1);
8537 end;
8538 
8539 {------------------------------------------------------------------------------
8540   Function: TQtFrame.setFrameShadow
8541   Params:  None
8542   Returns: Nothing
8543  ------------------------------------------------------------------------------}
8544 procedure TQtFrame.setFrameShadow(p1: QFrameShadow);
8545 begin
8546   QFrame_setFrameShadow(QFrameH(Widget), p1);
8547 end;
8548 
8549 {------------------------------------------------------------------------------
8550   Function: TQtArrow.CreateWidget
8551   Params:  None
8552   Returns: Nothing
8553  ------------------------------------------------------------------------------}
TQtArrow.CreateWidgetnull8554 function TQtArrow.CreateWidget(const AParams: TCreateParams):QWidgetH;
8555 var
8556   Parent: QWidgetH;
8557 begin
8558   // Creates the widget
8559   {$ifdef VerboseQt}
8560     WriteLn('TQtArrow.Create');
8561   {$endif}
8562   FHasPaint := True;
8563   if AParams.WndParent <> 0 then
8564     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8565   else
8566     Parent := nil;
8567   Result := QFrame_create(Parent);
8568 end;
8569 
CreateWidgetnull8570 function TQtAbstractSlider.CreateWidget(const AParams: TCreateParams): QWidgetH;
8571 var
8572   Parent: QWidgetH;
8573 begin
8574   // Creates the widget
8575   {$ifdef VerboseQt}
8576     WriteLn('TQtAbstractSlider.Create');
8577   {$endif}
8578 
8579   FSliderPressed := False;
8580   FSliderReleased:= False;
8581 
8582   if AParams.WndParent <> 0 then
8583     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8584   else
8585     Parent := nil;
8586   Result := QAbstractSlider_create(Parent);
8587 end;
8588 
8589 procedure TQtAbstractSlider.AttachEvents;
8590 begin
8591   inherited AttachEvents;
8592   FRangeChangedHook := QAbstractSlider_hook_create(Widget);
8593   FSliderMovedHook :=  QAbstractSlider_hook_create(Widget);
8594   FSliderPressedHook := QAbstractSlider_hook_create(Widget);
8595   FSliderReleasedHook := QAbstractSlider_hook_create(Widget);
8596   FValueChangedHook := QAbstractSlider_hook_create(Widget);
8597   FActionTriggeredHook := QAbstractSlider_hook_create(Widget);
8598 end;
8599 
8600 procedure TQtAbstractSlider.DetachEvents;
8601 begin
8602   if FRangeChangedHook <> nil then
8603   begin
8604     QAbstractSlider_hook_destroy(FRangeChangedHook);
8605     FRangeChangedHook := nil;
8606   end;
8607   if FSliderMovedHook <> nil then
8608   begin
8609     QAbstractSlider_hook_destroy(FSliderMovedHook);
8610     FSliderMovedHook := nil;
8611   end;
8612   if FSliderPressedHook <> nil then
8613   begin
8614     QAbstractSlider_hook_destroy(FSliderPressedHook);
8615     FSliderPressedHook := nil;
8616   end;
8617   if FSliderReleasedHook <> nil then
8618   begin
8619     QAbstractSlider_hook_destroy(FSliderReleasedHook);
8620     FSliderReleasedHook := nil;
8621   end;
8622   if FValueChangedHook <> nil then
8623   begin
8624     QAbstractSlider_hook_destroy(FValueChangedHook);
8625     FValueChangedHook := nil;
8626   end;
8627   if FActionTriggeredHook <> nil then
8628   begin
8629     QAbstractSlider_hook_destroy(FActionTriggeredHook);
8630     FActionTriggeredHook := nil;
8631   end;
8632   inherited DetachEvents;
8633 end;
8634 
getValuenull8635 function TQtAbstractSlider.getValue: Integer;
8636 begin
8637   Result := QAbstractSlider_value(QAbstractSliderH(Widget));
8638 end;
8639 
getPageStepnull8640 function TQtAbstractSlider.getPageStep: Integer;
8641 begin
8642   Result := QAbstractSlider_pageStep(QAbstractSliderH(Widget));
8643 end;
8644 
getMinnull8645 function TQtAbstractSlider.getMin: Integer;
8646 begin
8647   Result := QAbstractSlider_minimum(QAbstractSliderH(Widget));
8648 end;
8649 
TQtAbstractSlider.getMaxnull8650 function TQtAbstractSlider.getMax: Integer;
8651 begin
8652   Result := QAbstractSlider_maximum(QAbstractSliderH(Widget));
8653 end;
8654 
TQtAbstractSlider.getSingleStepnull8655 function TQtAbstractSlider.getSingleStep: Integer;
8656 begin
8657   Result := QAbstractSlider_singleStep(QAbstractSliderH(Widget));
8658 end;
8659 
getSliderDownnull8660 function TQtAbstractSlider.getSliderDown: Boolean;
8661 begin
8662   Result := QAbstractSlider_isSliderDown(QAbstractSliderH(Widget));
8663 end;
8664 
getSliderPositionnull8665 function TQtAbstractSlider.getSliderPosition: Integer;
8666 begin
8667   Result := QAbstractSlider_sliderPosition(QAbstractSliderH(Widget));
8668 end;
8669 
getTrackingnull8670 function TQtAbstractSlider.getTracking: Boolean;
8671 begin
8672   Result := QAbstractSlider_hasTracking(QAbstractSliderH(Widget));
8673 end;
8674 
8675 {------------------------------------------------------------------------------
8676   Function: TQtAbstractSlider.rangeChanged
8677   Params:  minimum,maximum: Integer
8678   Returns: Nothing
8679  ------------------------------------------------------------------------------}
8680 procedure TQtAbstractSlider.SlotRangeChanged(minimum: Integer; maximum: Integer); cdecl;
8681 begin
8682   { TODO: find out what needs to be done on rangeChanged event
8683     Possibilities: repaint or recount pageSize() }
8684   {$ifdef VerboseQt}
8685   writeln('TQtAbstractSlider.rangeChanged() to min=',minimum,' max=',maximum);
8686   {$endif}
8687 end;
8688 
8689 {------------------------------------------------------------------------------
8690   Function: TQtAbstractSlider.setInvertedAppereance
8691   Params:  p1: Boolean
8692   Returns: Nothing
8693  ------------------------------------------------------------------------------}
8694 procedure TQtAbstractSlider.setInvertedAppereance(p1: Boolean);
8695 begin
8696   QAbstractSlider_setInvertedAppearance(QAbstractSliderH(Widget), p1);
8697 end;
8698 
8699 {------------------------------------------------------------------------------
8700   Function: TQtAbstractSlider.setInvertedControls
8701   Params:  p1: Boolean
8702   Returns: Nothing
8703  ------------------------------------------------------------------------------}
8704 procedure TQtAbstractSlider.setInvertedControls(p1: Boolean);
8705 begin
8706   QAbstractSlider_setInvertedControls(QAbstractSliderH(Widget), p1);
8707 end;
8708 
8709 {------------------------------------------------------------------------------
8710   Function: TQtAbstractSlider.setMaximum
8711   Params:  p1: Integer
8712   Returns: Nothing
8713  ------------------------------------------------------------------------------}
8714 procedure TQtAbstractSlider.setMaximum(p1: Integer);
8715 begin
8716   QAbstractSlider_setMaximum(QAbstractSliderH(Widget), p1);
8717 end;
8718 
8719 {------------------------------------------------------------------------------
8720   Function: TQtAbstractSlider.setMinimum
8721   Params:  p1: Integer
8722   Returns: Nothing
8723  ------------------------------------------------------------------------------}
8724 procedure TQtAbstractSlider.setMinimum(p1: Integer);
8725 begin
8726   QAbstractSlider_setMinimum(QAbstractSliderH(Widget), p1);
8727 end;
8728 
8729 {------------------------------------------------------------------------------
8730   Function: TQtAbstractSlider.setOrientation
8731   Params:  p1: QtOrientation (QtHorizontal or QtVertical)
8732   Returns: Nothing
8733  ------------------------------------------------------------------------------}
8734 procedure TQtAbstractSlider.setOrientation(p1: QtOrientation);
8735 begin
8736   QAbstractSlider_setOrientation(QAbstractSliderH(Widget), p1);
8737 end;
8738 
8739 {------------------------------------------------------------------------------
8740   Function: TQtAbstractSlider.setPageStep
8741   Params:  p1: Integer
8742   Returns: Nothing
8743  ------------------------------------------------------------------------------}
8744 procedure TQtAbstractSlider.setPageStep(p1: Integer);
8745 begin
8746   QAbstractSlider_setPageStep(QAbstractSliderH(Widget), p1);
8747 end;
8748 
8749 {------------------------------------------------------------------------------
8750   Function: TQtAbstractSlider.setRange
8751   Params:  minimum,maximum: Integer
8752   Returns: Nothing
8753  ------------------------------------------------------------------------------}
8754 procedure TQtAbstractSlider.setRange(minimum: Integer; maximum: Integer);
8755 begin
8756   QAbstractSlider_setRange(QAbstractSliderH(Widget), minimum, maximum);
8757 end;
8758 
8759 {------------------------------------------------------------------------------
8760   Function: TQtAbstractSlider.setSingleStep
8761   Params:  p1: Integer
8762   Returns: Nothing
8763  ------------------------------------------------------------------------------}
8764 procedure TQtAbstractSlider.setSingleStep(p1: Integer);
8765 begin
8766   QAbstractSlider_setSingleStep(QAbstractSliderH(Widget), p1);
8767 end;
8768 
8769 {------------------------------------------------------------------------------
8770   Function: TQtAbstractSlider.setSliderDown
8771   Params:  p1: Boolean
8772   Returns: Nothing
8773  ------------------------------------------------------------------------------}
8774 procedure TQtAbstractSlider.setSliderDown(p1: Boolean);
8775 begin
8776   QAbstractSlider_setSliderDown(QAbstractSliderH(Widget), p1);
8777 end;
8778 
8779 
8780 {------------------------------------------------------------------------------
8781   Function: TQtAbstractSlider.setSliderPosition
8782   Params:  p1: Integer
8783   Returns: Nothing
8784  ------------------------------------------------------------------------------}
8785 procedure TQtAbstractSlider.setSliderPosition(p1: Integer);
8786 begin
8787   QAbstractSlider_setSliderPosition(QAbstractSliderH(Widget), p1);
8788 end;
8789 
8790 {------------------------------------------------------------------------------
8791   Function: TQtAbstractSlider.setTracking
8792   Params:  p1: Boolean
8793   Returns: Nothing
8794  ------------------------------------------------------------------------------}
8795 procedure TQtAbstractSlider.setTracking(p1: Boolean);
8796 begin
8797   QAbstractSlider_setTracking(QAbstractSliderH(Widget), p1);
8798 end;
8799 
8800 {-----------------------------------------------------------------------------
8801   Function: TQtAbstractSlider.setValue
8802   Params:  p1: Integer
8803   Returns: Nothing
8804  ------------------------------------------------------------------------------}
8805 procedure TQtAbstractSlider.setValue(p1: Integer);
8806 begin
8807   QAbstractSlider_setValue(QAbstractSliderH(Widget), p1);
8808 end;
8809 
8810 procedure TQtAbstractSlider.SlotSliderMoved(p1: Integer); cdecl;
8811 begin
8812  {$ifdef VerboseQt}
8813   writeln('TQtAbstractSlider.sliderMoved() to pos=',p1);
8814  {$endif}
8815 
8816  // there's no need to deliver this message
8817  // since ValueChanged does it's job correct, also for tracking on/off
8818  // this signal must stay empty because of ttrackbar !
8819 end;
8820 
8821 procedure TQtAbstractSlider.SlotSliderPressed; cdecl;
8822 begin
8823   {$ifdef VerboseQt}
8824    writeln('TQtAbstractSlider.sliderPressed()');
8825   {$endif}
8826   FSliderPressed := True;
8827   FSliderReleased := False;
8828 end;
8829 
8830 procedure TQtAbstractSlider.SlotSliderReleased; cdecl;
8831 begin
8832   {$ifdef VerboseQt}
8833    writeln('TQtAbstractSlider.sliderReleased()');
8834   {$endif}
8835   FSliderPressed := False;
8836   FSliderReleased := True;
8837 end;
8838 
CanChangeFontColornull8839 function TQtAbstractSlider.CanChangeFontColor: Boolean;
8840 begin
8841   Result := False;
8842 end;
8843 
getInvertedAppereancenull8844 function TQtAbstractSlider.getInvertedAppereance: Boolean;
8845 begin
8846   Result := QAbstractSlider_invertedAppearance(QAbstractSliderH(Widget));
8847 end;
8848 
getInvertedControlsnull8849 function TQtAbstractSlider.getInvertedControls: Boolean;
8850 begin
8851   Result := QAbstractSlider_invertedControls(QAbstractSliderH(Widget));
8852 end;
8853 
getOrientationnull8854 function TQtAbstractSlider.getOrientation: QtOrientation;
8855 begin
8856   Result := QAbstractSlider_orientation(QAbstractSliderH(Widget));
8857 end;
8858 
8859 procedure TQtAbstractSlider.SlotValueChanged(p1: Integer); cdecl;
8860 var
8861   LMScroll: TLMScroll;
8862   b: Boolean;
8863 begin
8864   {$ifdef VerboseQt}
8865   writeln('TQtAbstractSlider.SlotValueChanged() to value ',p1,' inUpdate ',inUpdate,' maxIs ',getMax,
8866   ' FChildOfComplexWidget ',FChildOfComplexWidget);
8867   {$endif}
8868 
8869   FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
8870 
8871   LMScroll.ScrollBar := PtrUInt(Self);
8872 
8873   if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
8874     LMScroll.Msg := LM_HSCROLL
8875   else
8876     LMScroll.Msg := LM_VSCROLL;
8877 
8878   LMScroll.Pos := p1;
8879   LMScroll.ScrollCode := SIF_POS;
8880 
8881   if not InUpdate then
8882     DeliverMessage(LMScroll);
8883 
8884   b := p1 = getMax;
8885 
8886   if not InUpdate or (getVisible and ((p1=getMin) or b)) then
8887   begin
8888     if b and (FChildOfComplexWidget = ccwAbstractScrollArea) and
8889       not InUpdate and getVisible then
8890         QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
8891           QAbstractSliderSliderToMaximum);
8892   end;
8893 end;
8894 
8895 procedure TQtAbstractSlider.SlotActionTriggered(action: Integer); cdecl;
8896 const
8897   SliderActions: Array[0..7] of QAbstractSliderSliderAction = (
8898     QAbstractSliderSliderNoAction, QAbstractSliderSliderSingleStepAdd,
8899     QAbstractSliderSliderSingleStepSub, QAbstractSliderSliderPageStepAdd,
8900     QAbstractSliderSliderPageStepSub, QAbstractSliderSliderToMinimum,
8901     QAbstractSliderSliderToMaximum, QAbstractSliderSliderMove );
8902 var
8903   LMScroll: TLMScroll;
8904   SliderAction: QAbstractSliderSliderAction;
8905 begin
8906 
8907   if InUpdate then
8908     exit;
8909 
8910   {$ifdef VerboseQt}
8911   writeln('TQtAbstractSlider.SlotActionTriggered() action = ',action,' inUpdate ',inUpdate);
8912   {$endif}
8913 
8914   FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
8915 
8916   LMScroll.ScrollBar := PtrUInt(Self);
8917 
8918   if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
8919     LMScroll.Msg := LM_HSCROLL
8920   else
8921     LMScroll.Msg := LM_VSCROLL;
8922 
8923   if SliderPressed then
8924     LMScroll.Pos := getSliderPosition
8925   else
8926     LMScroll.Pos := getValue;
8927 
8928   SliderAction := SliderActions[Action];
8929 
8930   case SliderAction of
8931     QAbstractSliderSliderNoAction:
8932     begin
8933       // this is called from mouse release while qt still thinks that
8934       // slider is pressed, we must update position.issue #14728, #21610
8935       if getSliderDown then
8936       begin
8937         LMScroll.ScrollCode := SB_THUMBPOSITION;
8938         DeliverMessage(LMScroll);
8939       end;
8940       LMScroll.ScrollCode := SB_ENDSCROLL;
8941     end;
8942     QAbstractSliderSliderSingleStepAdd:
8943       begin
8944         if LMScroll.Msg = LM_HSCROLL then
8945           LMScroll.ScrollCode := SB_LINERIGHT
8946         else
8947           LMScroll.ScrollCode := SB_LINEDOWN;
8948       end;
8949     QAbstractSliderSliderSingleStepSub:
8950       begin
8951         if LMScroll.Msg = LM_HSCROLL then
8952           LMScroll.ScrollCode := SB_LINELEFT
8953         else
8954           LMScroll.ScrollCode := SB_LINEUP;
8955       end;
8956     QAbstractSliderSliderPageStepAdd:
8957       begin
8958         if LMScroll.Msg = LM_HSCROLL then
8959           LMScroll.ScrollCode := SB_PAGERIGHT
8960         else
8961           LMScroll.ScrollCode := SB_PAGEDOWN;
8962       end;
8963     QAbstractSliderSliderPageStepSub:
8964       begin
8965         if LMScroll.Msg = LM_HSCROLL then
8966           LMScroll.ScrollCode := SB_PAGELEFT
8967         else
8968           LMScroll.ScrollCode := SB_PAGEUP;
8969       end;
8970     QAbstractSliderSliderToMinimum:
8971       begin
8972         if LMScroll.Msg = LM_HSCROLL then
8973           LMScroll.ScrollCode := SB_LEFT
8974         else
8975           LMScroll.ScrollCode := SB_TOP;
8976       end;
8977     QAbstractSliderSliderToMaximum:
8978       begin
8979         // issue #21610
8980         // if we are reaching maximum with eg. mouse wheel
8981         // and our parent is TScrollingWinControl then update thumbposition.
8982         if not getSliderDown then
8983         begin
8984           LMScroll.ScrollCode := SB_THUMBPOSITION;
8985           DeliverMessage(LMScroll);
8986         end;
8987 
8988         if LMScroll.Msg = LM_HSCROLL then
8989           LMScroll.ScrollCode := SB_RIGHT
8990         else
8991           LMScroll.ScrollCode := SB_BOTTOM;
8992       end;
8993     QAbstractSliderSliderMove:
8994       begin
8995         if getTracking then
8996           LMScroll.ScrollCode := SB_THUMBTRACK
8997         else
8998         if not getSliderDown then
8999           LMScroll.ScrollCode := SB_THUMBPOSITION;
9000       end;
9001   end;
9002 
9003   DeliverMessage(LMScroll);
9004 end;
9005 
9006 { TQtScrollBar }
9007 
TQtScrollBar.CreateWidgetnull9008 function TQtScrollBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
9009 var
9010   Parent: QWidgetH;
9011 begin
9012   // Creates the widget
9013   {$ifdef VerboseQt}
9014     WriteLn('TQtScrollBar.Create');
9015   {$endif}
9016   if AParams.WndParent <> 0 then
9017     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9018   else
9019     Parent := nil;
9020   FTrackPos := 0;
9021   Result := QScrollBar_create(Parent);
9022   QWidget_setFocusPolicy(Result, QtNoFocus);
9023   if (QtVersionMajor = 4) and (QtVersionMinor < 6) then
9024     QWidget_setAutoFillBackground(Result, True);
9025   FHasPaint := True;
9026 end;
9027 
9028 procedure TQtScrollBar.preferredSize(var PreferredWidth,
9029   PreferredHeight: integer; WithThemeSpace: Boolean);
9030 var
9031   Size: TSize;
9032 begin
9033   QScrollBar_sizeHint(QScrollBarH(Widget), @Size);
9034   PreferredWidth := Size.cx;
9035   PreferredHeight := Size.cy;
9036 end;
9037 
9038 procedure TQtScrollBar.setFocusPolicy(const APolicy: QtFocusPolicy);
9039 begin
9040   if FOwnWidget and Assigned(LCLObject) and not LCLObject.TabStop then
9041     inherited setFocusPolicy(QtNoFocus)
9042   else
9043     inherited setFocusPolicy(APolicy);
9044 end;
9045 
9046 procedure TQtScrollBar.SlotSliderReleased; cdecl;
9047 var
9048   AValue: Integer;
9049   LMScroll: TLMScroll;
9050 begin
9051   inherited SlotSliderReleased;
9052   if
9053   {$IFDEF QTSCROLLABLEFORMS}
9054    ((ChildOfComplexWidget = ccwAbstractScrollArea) and (FOwner <> nil) and
9055     (FOwner is TQtWindowArea)) or
9056   {$ENDIF}
9057    ((ChildOfComplexWidget = ccwAbstractScrollArea) and (FOwner <> nil) and
9058     (FOwner.ChildOfComplexWidget in [ccwCustomControl])) then
9059   begin
9060     AValue := getValue;
9061     if AValue <= getMin then
9062       QAbstractSlider_triggerAction(QAbstractSliderH(Widget), QAbstractSliderSliderToMinimum)
9063     else
9064     if AValue >= getMax then
9065       QAbstractSlider_triggerAction(QAbstractSliderH(Widget), QAbstractSliderSliderToMaximum)
9066     else
9067     begin
9068       FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
9069 
9070       LMScroll.ScrollBar := PtrUInt(Self);
9071 
9072       if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
9073         LMScroll.Msg := LM_HSCROLL
9074       else
9075         LMScroll.Msg := LM_VSCROLL;
9076 
9077       LMScroll.Pos := getSliderPosition;
9078       if not GetTracking then
9079         LMScroll.ScrollCode := SB_THUMBPOSITION
9080       else
9081         LMScroll.ScrollCode := SB_THUMBTRACK;
9082       DeliverMessage(LMScroll);
9083     end;
9084   end;
9085 end;
9086 
EventFilternull9087 function TQtScrollBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
9088   cdecl;
9089 begin
9090   Result := False;
9091   QEvent_accept(Event);
9092 
9093   if LCLObject = nil then
9094     exit;
9095 
9096   case QEvent_type(Event) of
9097     {if any of those events returs TRUE our scrollbar becomes invisible.}
9098     QEventMouseMove,
9099     QEventWheel,
9100     QEventPaint,
9101     QEventKeyPress,
9102     QEventKeyRelease:
9103     begin
9104       if FOwnWidget and (FOwner = nil) and
9105         ((QEvent_type(Event) = QEventKeyPress) or
9106         (QEvent_type(Event) = QEventKeyRelease)) then
9107         Result := inherited EventFilter(Sender, Event)
9108       else
9109       if (QEvent_type(Event) = QEventWheel) and Assigned(FOwner) and
9110         (
9111         (FOwner is TQtAbstractScrollArea)
9112         ) then
9113       begin
9114 
9115         // issue #25992
9116         if not getVisible then
9117           Result := FOwner.SlotMouseWheel(FOwner.Widget, Event)
9118         else
9119         begin
9120           // issue #27675.Do not send wheel event from cbox when dropped down.
9121           // LCL thinks that combobox sent that event so we have undesirable effects.
9122           if (FOwner.ChildOfComplexWidget = ccwComboBox) and getEnabled then
9123             Result := False
9124           else
9125             Result := inherited EventFilter(Sender, Event);
9126         end;
9127         // do not scroll when disabled or issue #25992
9128         if not getEnabled then
9129           Result := True
9130         else
9131         if not getVisible then
9132         begin
9133           if {$IFDEF QTSCROLLABLEFORMS}(FOwner is TQtWindowArea) or {$ENDIF}
9134            (FOwner.ChildOfComplexWidget in
9135            [ccwScrollingWinControl, ccwScrollingWindow]) then
9136             Result := True;
9137         end;
9138       end else
9139         Result := False;
9140       if (QEvent_type(Event) = QEventKeyRelease) and not
9141         (QKeyEvent_isAutoRepeat(QKeyEventH(event))) then
9142         begin
9143           case QKeyEvent_key(QKeyEventH(Event)) of
9144             QtKey_Left, QtKey_Up, QtKey_Right, QtKey_Down,
9145             QtKey_PageUp, QtKey_PageDown, QtKey_Home, QtKey_End:
9146               QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
9147                        QAbstractSliderSliderNoAction);
9148           end;
9149         end;
9150     end;
9151 
9152     QEventMouseButtonRelease:
9153       QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
9154                         QAbstractSliderSliderNoAction);
9155   else
9156     if FOwnWidget then
9157       Result := inherited EventFilter(Sender, Event);
9158   end;
9159 end;
9160 
9161 procedure TQtScrollBar.AttachEvents;
9162 begin
9163   inherited AttachEvents;
9164   QAbstractSlider_hook_hook_rangeChanged(FRangeChangedHook, @SlotRangeChanged);
9165 
9166   QAbstractSlider_hook_hook_sliderMoved(FSliderMovedHook, @SlotSliderMoved);
9167 
9168   QAbstractSlider_hook_hook_sliderPressed(FSliderPressedHook, @SlotSliderPressed);
9169 
9170   QAbstractSlider_hook_hook_sliderReleased(FSliderReleasedHook, @SlotSliderReleased);
9171 
9172   QAbstractSlider_hook_hook_valueChanged(FValueChangedHook, @SlotValueChanged);
9173 
9174   QAbstractSlider_hook_hook_actionTriggered(FActionTriggeredHook, @SlotActionTriggered);
9175 end;
9176 
9177 { TQtToolBar }
9178 
TQtToolBar.CreateWidgetnull9179 function TQtToolBar.CreateWidget(const AParams: TCreateParams):QWidgetH;
9180 var
9181   Parent: QWidgetH;
9182 begin
9183   // Creates the widget
9184   {$ifdef VerboseQt}
9185     WriteLn('TQtToolBar.Create');
9186   {$endif}
9187   if AParams.WndParent <> 0 then
9188     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9189   else
9190     Parent := nil;
9191   Result := QToolBar_create(Parent);
9192 end;
9193 
9194 { TQtToolButton }
9195 
CreateWidgetnull9196 function TQtToolButton.CreateWidget(const AParams: TCreateParams):QWidgetH;
9197 var
9198   Parent: QWidgetH;
9199 begin
9200   // Creates the widget
9201   {$ifdef VerboseQt}
9202     WriteLn('TQtToolButton.Create');
9203   {$endif}
9204   if AParams.WndParent <> 0 then
9205     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9206   else
9207     Parent := nil;
9208   Result := QToolButton_create(Parent);
9209 end;
9210 
9211 { TQtTrackBar }
9212 
TQtTrackBar.CreateWidgetnull9213 function TQtTrackBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
9214 var
9215   Parent: QWidgetH;
9216 begin
9217   // Creates the widget
9218   {$ifdef VerboseQt}
9219     WriteLn('TQtTrackBar.Create');
9220   {$endif}
9221   if AParams.WndParent <> 0 then
9222     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9223   else
9224     Parent := nil;
9225   Result := QSlider_create(Parent);
9226 end;
9227 
TQtTrackBar.getTickIntervalnull9228 function TQtTrackBar.getTickInterval: Integer;
9229 begin
9230   Result := QSlider_tickInterval(QSliderH(Widget));
9231 end;
9232 
9233 {------------------------------------------------------------------------------
9234   Function: TQtTrackBar.setTickPosition
9235   Params:  Value: QSliderTickPosition
9236   Returns: Nothing
9237  ------------------------------------------------------------------------------ }
9238 procedure TQtTrackBar.setTickPosition(Value: QSliderTickPosition);
9239 begin
9240   QSlider_setTickPosition(QSliderH(Widget), Value);
9241 end;
9242 
9243 {------------------------------------------------------------------------------
9244   Function: TQtTrackBar.setTickInterval
9245   Params:  Value: Integer
9246   Returns: Nothing
9247  ------------------------------------------------------------------------------ }
9248 procedure TQtTrackBar.SetTickInterval(Value: Integer);
9249 begin
9250   QSlider_setTickInterval(QSliderH(Widget), Value);
9251 end;
9252 
9253 procedure TQtTrackBar.AttachEvents;
9254 begin
9255   inherited AttachEvents;
9256 
9257   QAbstractSlider_hook_hook_sliderMoved(FSliderMovedHook, @SlotSliderMoved);
9258 
9259   QAbstractSlider_hook_hook_sliderPressed(FSliderPressedHook, @SlotSliderPressed);
9260 
9261   QAbstractSlider_hook_hook_sliderReleased(FSliderReleasedHook, @SlotSliderReleased);
9262 
9263   QAbstractSlider_hook_hook_valueChanged(FValueChangedHook, @SlotValueChanged);
9264 end;
9265 
9266 procedure TQtTrackBar.SlotSliderMoved(p1: Integer); cdecl;
9267 var
9268   Msg: TLMessage;
9269 begin
9270  {$ifdef VerboseQt}
9271   writeln('TQtTrackBar.SlotSliderMoved() p1=',p1);
9272  {$endif}
9273   if SliderPressed and not InUpdate then
9274   begin
9275     Msg.Msg := 0; // shutup compiler
9276     FillChar(Msg, SizeOf(Msg), #0);
9277     Msg.Msg := LM_CHANGED;
9278     DeliverMessage(Msg);
9279   end;
9280 end;
9281 
9282 procedure TQtTrackBar.SlotValueChanged(p1: Integer); cdecl;
9283 var
9284   Msg: TLMessage;
9285 begin
9286  {$ifdef VerboseQt}
9287   writeln('TQtTrackBar.SlotValueChanged() p1=',p1);
9288  {$endif}
9289 
9290   if not SliderPressed and not InUpdate then
9291   begin
9292     FillChar(Msg{%H-}, SizeOf(Msg), #0);
9293     Msg.Msg := LM_CHANGED;
9294     DeliverMessage(Msg);
9295   end;
9296 end;
9297 
9298 { TQtLineEdit }
9299 
TQtLineEdit.CreateWidgetnull9300 function TQtLineEdit.CreateWidget(const AParams: TCreateParams): QWidgetH;
9301 var
9302   Parent: QWidgetH;
9303 begin
9304   FCachedSelectionStart := -1;
9305   FCachedSelectionLen := -1;
9306   FIntValidator := nil;
9307   FNumbersOnly := False;
9308   if AParams.WndParent <> 0 then
9309     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9310   else
9311     Parent := nil;
9312   Result := QLineEdit_create(Parent);
9313 end;
9314 
getAlignmentnull9315 function TQtLineEdit.getAlignment: QtAlignment;
9316 begin
9317   Result := QLineEdit_alignment(QLineEditH(Widget));
9318 end;
9319 
getCursorPositionnull9320 function TQtLineEdit.getCursorPosition: TPoint;
9321 begin
9322   Result.Y := 0;
9323   Result.X := QLineEdit_cursorPosition(QLineEditH(Widget));
9324 end;
9325 
TQtLineEdit.getMaxLengthnull9326 function TQtLineEdit.getMaxLength: Integer;
9327 begin
9328   Result := QLineEdit_maxLength(QLineEditH(Widget));
9329 end;
9330 
getSelectedTextnull9331 function TQtLineEdit.getSelectedText: WideString;
9332 begin
9333   Result := '';
9334   QLineEdit_selectedText(QLineEditH(Widget), @Result);
9335 end;
9336 
getSelectionStartnull9337 function TQtLineEdit.getSelectionStart: Integer;
9338 begin
9339   if hasSelectedText then
9340     Result := QLineEdit_selectionStart(QLineEditH(Widget))
9341   else
9342   begin
9343     if (CachedSelectionStart <> -1) and not hasFocus then
9344       Result := CachedSelectionStart
9345     else
9346       Result := getCursorPosition.X;
9347   end;
9348 end;
9349 
getSelectionLengthnull9350 function TQtLineEdit.getSelectionLength: Integer;
9351 var
9352   W: WideString;
9353 begin
9354   if hasSelectedText then
9355   begin
9356     W := getSelectedText;
9357     Result := UTF16Length(W);
9358   end else
9359   begin
9360     if (CachedSelectionStart <> -1) and (CachedSelectionLen <> -1) then
9361       Result := CachedSelectionLen
9362     else
9363       Result := 0;
9364   end;
9365 end;
9366 
TQtLineEdit.getTextnull9367 function TQtLineEdit.getText: WideString;
9368 begin
9369   Result := '';
9370   QLineEdit_text(QLineEditH(Widget), @Result);
9371 end;
9372 
getTextMarginsnull9373 function TQtLineEdit.getTextMargins: TRect;
9374 var
9375   L, T, R, B: Integer;
9376 begin
9377   QLineEdit_getTextMargins(QLineEditH(Widget), @L, @T, @R, @B);
9378   Result := Rect(L, T, R, B);
9379 end;
9380 
9381 procedure TQtLineEdit.SetNumbersOnly(AValue: boolean);
9382 begin
9383   if FNumbersOnly=AValue then Exit;
9384   FNumbersOnly:=AValue;
9385   if Assigned(FIntValidator) then
9386   begin
9387     QLineEdit_setValidator(QLineEditH(Widget), nil);
9388     QIntValidator_destroy(FIntValidator);
9389     FIntValidator := nil;
9390   end;
9391   if FNumbersOnly then
9392   begin
9393     FIntValidator := QIntValidator_create(0, MAXINT, Widget);
9394     QLineEdit_setValidator(QLineEditH(Widget), FIntValidator);
9395   end;
9396 end;
9397 
getTextStaticnull9398 function TQtLineEdit.getTextStatic: Boolean;
9399 begin
9400   Result := False;
9401 end;
9402 
TQtLineEdit.isUndoAvailablenull9403 function TQtLineEdit.isUndoAvailable: Boolean;
9404 begin
9405   Result := QLineEdit_isUndoAvailable(QLineEditH(Widget));
9406 end;
9407 
hasSelectedTextnull9408 function TQtLineEdit.hasSelectedText: Boolean;
9409 begin
9410   Result := QLineEdit_hasSelectedText(QLineEditH(Widget));
9411 end;
9412 
9413 procedure TQtLineEdit.selectAll;
9414 begin
9415   QLineEdit_selectAll(QLineEditH(Widget));
9416 end;
9417 
9418 procedure TQtLineEdit.setAlignment(const AAlignment: QtAlignment);
9419 begin
9420   QLineEdit_setAlignment(QLineEditH(Widget), AAlignment);
9421 end;
9422 
9423 procedure TQtLineEdit.setBorder(const ABorder: Boolean);
9424 begin
9425   QLineEdit_setFrame(QLineEditH(Widget), ABorder);
9426 end;
9427 
9428 procedure TQtLineEdit.AttachEvents;
9429 begin
9430   inherited AttachEvents;
9431 
9432   FTextChanged := QLineEdit_hook_create(Widget);
9433   QLineEdit_hook_hook_textChanged(FTextChanged, @SignalTextChanged);
9434 end;
9435 
9436 procedure TQtLineEdit.DetachEvents;
9437 begin
9438   if FTextChanged <> nil then
9439   begin
9440     QLineEdit_hook_destroy(FTextChanged);
9441     FTextChanged := nil;
9442   end;
9443   inherited DetachEvents;
9444 end;
9445 
TQtLineEdit.EventFilternull9446 function TQtLineEdit.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
9447 begin
9448   Result := False;
9449   QEvent_accept(Event);
9450   if LCLObject = nil then
9451     exit;
9452 
9453   if (QEvent_type(Event) = QEventFocusOut) then
9454   begin
9455     CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(Widget));
9456     CachedSelectionLen := UTF16Length(getSelectedText);
9457   end else
9458   if (QEvent_type(Event) = QEventFocusIn) then
9459   begin
9460     CachedSelectionStart := -1;
9461     CachedSelectionLen := -1;
9462   end;
9463 
9464   if (ChildOfComplexWidget = ccwComboBox) and (QEvent_type(Event) = QEventMove) then
9465     exit;
9466 
9467   if (ChildOfComplexWidget = ccwComboBox) and
9468     ((QEvent_type(Event) = QEventPaint) or (QEvent_type(Event) = QEventResize))
9469     and (LCLObject.HandleAllocated) then
9470   begin
9471     Result := TQtComboBox(LCLObject.Handle).InUpdate or
9472       (csDesigning in LCLObject.ComponentState);
9473     if (QEvent_type(Event) = QEventPaint) and (csDesigning in LCLObject.ComponentState) then
9474       QObject_event(Sender, Event);
9475     if Result then
9476       QEvent_ignore(Event)
9477     else
9478     begin
9479       // issue #26040
9480       if (QEvent_type(Event) = QEventResize) then
9481         LCLObject.DoAdjustClientRectChange
9482       else
9483         Result:=inherited EventFilter(Sender, Event);
9484     end;
9485   end else
9486     Result:=inherited EventFilter(Sender, Event);
9487 end;
9488 
9489 procedure TQtLineEdit.preferredSize(var PreferredWidth,
9490   PreferredHeight: integer; WithThemeSpace: Boolean);
9491 var
9492   Size: TSize;
9493 begin
9494   QLineEdit_sizeHint(QLineEditH(Widget), @Size);
9495   PreferredHeight := Size.cy;
9496   PreferredWidth := Size.cx;
9497 end;
9498 
9499 procedure TQtLineEdit.setCursorPosition(const ACursorPosition: Integer);
9500 begin
9501   QLineEdit_setCursorPosition(QLineEditH(Widget), ACursorPosition);
9502 end;
9503 
9504 procedure TQtLineEdit.setDefaultColorRoles;
9505 begin
9506   WidgetColorRole := QPaletteBase;
9507   TextColorRole := QPaletteText;
9508 end;
9509 
9510 procedure TQtLineEdit.setEchoMode(const AMode: QLineEditEchoMode);
9511 begin
9512   QLineEdit_setEchoMode(QLineEditH(Widget), AMode);
9513 end;
9514 
9515 procedure TQtLineEdit.setInputMask(const AMask: WideString);
9516 begin
9517   QLineEdit_setInputMask(QLineEditH(Widget), @AMask);
9518 end;
9519 
9520 procedure TQtLineEdit.setMaxLength(const ALength: Integer);
9521 begin
9522   QLineEdit_setMaxLength(QLineEditH(Widget), ALength);
9523 end;
9524 
9525 procedure TQtLineEdit.setReadOnly(const AReadOnly: Boolean);
9526 begin
9527   QLineEdit_setReadOnly(QLineEditH(Widget), AReadOnly);
9528 end;
9529 
9530 procedure TQtLineEdit.setSelection(const AStart, ALength: Integer);
9531 begin
9532   if AStart >= 0 then
9533   begin
9534     if ALength > 0 then
9535       QLineEdit_setSelection(QLineEditH(Widget), AStart, ALength)
9536     else
9537       setCursorPosition(AStart);
9538   end;
9539 end;
9540 
9541 procedure TQtLineEdit.setText(const AText: WideString);
9542 begin
9543   QLineEdit_setText(QLineEditH(Widget), @AText);
9544   if not getEnabled then
9545     setSelection(0, 0);
9546 end;
9547 
9548 procedure TQtLineEdit.setTextMargins(ARect: TRect);
9549 begin
9550   with ARect do
9551     QLineEdit_setTextMargins(QLineEditH(Widget), Left, Top, Right, Bottom);
9552 end;
9553 
9554 procedure TQtLineEdit.Cut;
9555 begin
9556   QLineEdit_cut(QLineEditH(Widget));
9557 end;
9558 
9559 procedure TQtLineEdit.Copy;
9560 begin
9561   QLineEdit_copy(QLineEditH(Widget));
9562 end;
9563 
9564 procedure TQtLineEdit.Paste;
9565 begin
9566   QLineEdit_paste(QLineEditH(Widget));
9567 end;
9568 
9569 procedure TQtLineEdit.Undo;
9570 begin
9571   QLineEdit_undo(QLineEditH(Widget));
9572 end;
9573 
9574 destructor TQtLineEdit.Destroy;
9575 begin
9576   if Assigned(FIntValidator) then
9577   begin
9578     QIntValidator_destroy(FIntValidator);
9579     FIntValidator := nil;
9580   end;
9581   inherited Destroy;
9582 end;
9583 
9584 {------------------------------------------------------------------------------
9585   Function: TQtLineEdit.SignalTextChanged
9586   Params:  PWideString
9587   Returns: Nothing
9588 
9589   Fires OnChange() event of TCustomEdit
9590  ------------------------------------------------------------------------------}
9591 procedure TQtLineEdit.SignalTextChanged(p1: PWideString); cdecl;
9592 var
9593   Msg: TLMessage;
9594 begin
9595   FillChar(Msg{%H-}, SizeOf(Msg), #0);
9596   Msg.Msg := CM_TEXTCHANGED;
9597   DeliverMessage(Msg);
9598 end;
9599 
9600 { TQtTextEdit }
9601 
GetAcceptRichTextnull9602 function TQtTextEdit.GetAcceptRichText: Boolean;
9603 begin
9604   Result := QTextEdit_acceptRichText(QTextEditH(Widget));
9605 end;
9606 
9607 procedure TQtTextEdit.SetAcceptRichText(AValue: Boolean);
9608 begin
9609   QTextEdit_setAcceptRichText(QTextEditH(Widget), AValue);
9610 end;
9611 
TQtTextEdit.CreateWidgetnull9612 function TQtTextEdit.CreateWidget(const AParams: TCreateParams): QWidgetH;
9613 var
9614   Parent: QWidgetH;
9615 begin
9616   // Creates the widget
9617   {$ifdef VerboseQt}
9618     WriteLn('TQtTextEdit.Create');
9619   {$endif}
9620   if AParams.WndParent <> 0 then
9621     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9622   else
9623     Parent := nil;
9624   Result := QTextEdit_create(Parent);
9625   FKeysToEat := [];
9626   FUndoAvailable := False;
9627   {drops are handled by slotDropFiles()}
9628   QWidget_setAcceptDrops(Result, False);
9629 end;
9630 
9631 procedure TQtTextEdit.Append(const AStr: WideString);
9632 begin
9633   QTextEdit_append(QTextEditH(Widget), @AStr);
9634 end;
9635 
9636 procedure TQtTextEdit.ClearText;
9637 begin
9638   QTextEdit_clear(QTextEditH(Widget));
9639 end;
9640 
getAlignmentnull9641 function TQtTextEdit.getAlignment: QtAlignment;
9642 begin
9643   Result := QTextEdit_alignment(QTextEditH(Widget));
9644 end;
9645 
getBlockCountnull9646 function TQtTextEdit.getBlockCount: Integer;
9647 begin
9648   Result := QTextDocument_blockCount(QTextEdit_document(QTextEditH(Widget)));
9649 end;
9650 
getCursorPositionnull9651 function TQtTextEdit.getCursorPosition: TPoint;
9652 var
9653   TextCursor: QTextCursorH;
9654 begin
9655   TextCursor := QTextCursor_create();
9656   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9657   if QTextCursor_isNull(TextCursor) then
9658     Result := Point(0, 0)
9659   else
9660   begin
9661     Result.X := QTextCursor_position(TextCursor);
9662     Result.Y := QTextCursor_blockNumber(TextCursor);
9663   end;
9664   QTextCursor_destroy(TextCursor);
9665 end;
9666 
getMaxLengthnull9667 function TQtTextEdit.getMaxLength: Integer;
9668 begin
9669   {$note implement TQtTextEdit.getMaxLength}
9670   Result := 0;
9671 end;
9672 
TQtTextEdit.getTextnull9673 function TQtTextEdit.getText: WideString;
9674 begin
9675   Result := '';
9676   QTextEdit_toPlainText(QTextEditH(Widget), @Result);
9677 end;
9678 
getTextStaticnull9679 function TQtTextEdit.getTextStatic: Boolean;
9680 begin
9681   Result := False;
9682 end;
9683 
getSelectionStartnull9684 function TQtTextEdit.getSelectionStart: Integer;
9685 var
9686   TextCursor: QTextCursorH;
9687 begin
9688   TextCursor := QTextCursor_create();
9689   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9690   Result := QTextCursor_selectionStart(TextCursor);
9691   QTextCursor_destroy(TextCursor);
9692 end;
9693 
TQtTextEdit.getSelectionEndnull9694 function TQtTextEdit.getSelectionEnd: Integer;
9695 var
9696   TextCursor: QTextCursorH;
9697 begin
9698   TextCursor := QTextCursor_create();
9699   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9700   Result := QTextCursor_selectionEnd(TextCursor);
9701   QTextCursor_destroy(TextCursor);
9702 end;
9703 
getSelectionLengthnull9704 function TQtTextEdit.getSelectionLength: Integer;
9705 begin
9706   Result := getSelectionEnd - getSelectionStart;
9707 end;
9708 
TQtTextEdit.isUndoAvailablenull9709 function TQtTextEdit.isUndoAvailable: Boolean;
9710 begin
9711   Result := QTextEdit_isUndoRedoEnabled(QTextEditH(Widget)) and FUndoAvailable;
9712 end;
9713 
9714 procedure TQtTextEdit.setEchoMode(const AMode: QLineEditEchoMode);
9715 begin
9716   {$note implement TQtTextEdit.setEchoMode}
9717 end;
9718 
9719 procedure TQtTextEdit.setLineWrapMode(const AMode: QTextEditLineWrapMode);
9720 begin
9721   QTextEdit_setLineWrapMode(QTextEditH(Widget), AMode);
9722 end;
9723 
9724 procedure TQtTextEdit.setMaxLength(const ALength: Integer);
9725 begin
9726   {$note implement TQtTextEdit.setMaxLength}
9727 end;
9728 
9729 procedure TQtTextEdit.appendLine(AText: WideString);
9730 var
9731   QtCursor: QTextCursorH;
9732   WrapMode: QTextEditLineWrapMode;
9733 begin
9734   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
9735   {we must remove wrapping to get correct line !}
9736   setLineWrapMode(QTextEditNoWrap);
9737   QtCursor := QTextCursor_create();
9738   try
9739     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
9740     QTextCursor_beginEditBlock(QtCursor);
9741     QTextCursor_movePosition(QtCursor, QTextCursorEnd,
9742         QTextCursorMoveAnchor, 1);
9743     QTextCursor_insertBlock(QtCursor);
9744     QTextCursor_insertText(QtCursor, @AText);
9745     QTextCursor_endEditBlock(QtCursor);
9746   finally
9747     QTextCursor_destroy(QtCursor);
9748     setLineWrapMode(WrapMode);
9749   end;
9750 end;
9751 
9752 procedure TQtTextEdit.insertLine(const AIndex: integer; AText: WideString);
9753 var
9754   QtCursor: QTextCursorH;
9755   WrapMode: QTextEditLineWrapMode;
9756 begin
9757   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
9758   {we must remove wrapping to get correct line !}
9759   setLineWrapMode(QTextEditNoWrap);
9760   QtCursor := QTextCursor_create();
9761   try
9762     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
9763     QTextCursor_beginEditBlock(QtCursor);
9764     // QTextCursor slowness
9765     // https://bugreports.qt-project.org/browse/QTBUG-3554
9766     // differentiate append vs. insert issue #22715
9767     // added check for AIndex. issue #29670
9768     if (AIndex > 0) and (AIndex >= FList.Count - 1) then
9769     begin
9770       QTextCursor_movePosition(QtCursor, QTextCursorEnd,
9771         QTextCursorMoveAnchor, 1);
9772       QTextCursor_insertBlock(QtCursor);
9773     end else
9774     begin
9775       QTextCursor_movePosition(QtCursor, QTextCursorStart,
9776         QTextCursorMoveAnchor, 1);
9777       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
9778         QTextCursorMoveAnchor, 1);
9779     end;
9780 
9781     QTextCursor_movePosition(QtCursor, QTextCursorDown,
9782       QTextCursorMoveAnchor, AIndex);
9783     // QTextCursor slowness
9784     // https://bugreports.qt-project.org/browse/QTBUG-3554
9785     // differentiate append vs. insert issue #22715
9786     if AIndex < FList.Count - 1 then
9787     begin
9788       QTextCursor_insertBlock(QtCursor);
9789       QTextCursor_movePosition(QtCursor, QTextCursorUp,
9790         QTextCursorMoveAnchor, 1);
9791     end;
9792     QTextCursor_insertText(QtCursor, @AText);
9793     QTextCursor_endEditBlock(QtCursor);
9794   finally
9795     QTextCursor_destroy(QtCursor);
9796     setLineWrapMode(WrapMode);
9797   end;
9798 end;
9799 
9800 procedure TQtTextEdit.removeLine(const AIndex: integer);
9801 var
9802   QtCursor: QTextCursorH;
9803   B: Boolean;
9804   WrapMode: QTextEditLineWrapMode;
9805   Diff: Integer;
9806 begin
9807   Diff := getBlockCount - AIndex;
9808   {we must remove wrapping to get correct line !}
9809   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
9810   setLineWrapMode(QTextEditNoWrap);
9811   QtCursor := QTextCursor_create();
9812   try
9813     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
9814     QTextCursor_beginEditBlock(QtCursor);
9815     // small optimization if we delete from end of list
9816     if Diff <= 2 then
9817     begin
9818       QTextCursor_movePosition(QtCursor, QTextCursorEnd,
9819         QTextCursorMoveAnchor, 1);
9820       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
9821         QTextCursorMoveAnchor, 1);
9822       QTextCursor_movePosition(QtCursor, QTextCursorUp,
9823         QTextCursorMoveAnchor, Diff - 1);
9824     end else
9825     begin
9826       QTextCursor_movePosition(QtCursor, QTextCursorStart,
9827         QTextCursorMoveAnchor, 1);
9828       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
9829         QTextCursorMoveAnchor, 1);
9830       QTextCursor_movePosition(QtCursor, QTextCursorDown,
9831         QTextCursorMoveAnchor, AIndex);
9832       QTextCursor_movePosition(QtCursor, QTextCursorEndOfLine,
9833         QTextCursorMoveAnchor, 1);
9834     end;
9835 
9836     QTextCursor_select(QtCursor, QTextCursorLineUnderCursor);
9837     B := QTextCursor_hasSelection(QtCursor);
9838     if not B then
9839       QTextCursor_deleteChar(QtCursor)
9840     else
9841       QTextCursor_deletePreviousChar(QtCursor);
9842 
9843     if (AIndex = 0) then
9844     begin
9845       QTextCursor_movePosition(QtCursor, QTextCursorStart,
9846         QTextCursorMoveAnchor, 1);
9847       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
9848         QTextCursorMoveAnchor, 1);
9849       QTextCursor_movePosition(QtCursor, QTextCursorDown,
9850         QTextCursorMoveAnchor, 1);
9851     end;
9852     if B then
9853       QTextCursor_deletePreviousChar(QtCursor);
9854     QTextCursor_endEditBlock(QtCursor);
9855   finally
9856     QTextCursor_destroy(QtCursor);
9857     setLineWrapMode(WrapMode);
9858   end;
9859 end;
9860 
9861 procedure TQtTextEdit.setLineText(const AIndex: integer; AText: WideString);
9862 var
9863   QtCursor: QTextCursorH;
9864   WrapMode: QTextEditLineWrapMode;
9865 begin
9866   {we must remove wrapping to get correct line !}
9867   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
9868   setLineWrapMode(QTextEditNoWrap);
9869   QtCursor := QTextCursor_create();
9870   try
9871     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
9872     QTextCursor_beginEditBlock(QtCursor);
9873     QTextCursor_movePosition(QtCursor, QTextCursorStart,
9874       QTextCursorMoveAnchor, 1);
9875     QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
9876       QTextCursorMoveAnchor, 1);
9877     QTextCursor_movePosition(QtCursor, QTextCursorDown,
9878       QTextCursorMoveAnchor, AIndex);
9879     QTextCursor_select(QtCursor, QTextCursorLineUnderCursor);
9880     QTextCursor_removeSelectedText(QtCursor);
9881     QTextCursor_insertText(QtCursor, @AText);
9882     QTextCursor_movePosition(QtCursor, QTextCursorEndOfLine,
9883       QTextCursorMoveAnchor, 1);
9884     QTextCursor_endEditBlock(QtCursor);
9885   finally
9886     QTextCursor_destroy(QtCursor);
9887     setLineWrapMode(WrapMode);
9888   end;
9889 end;
9890 
9891 procedure TQtTextEdit.setText(const AText: WideString);
9892 begin
9893   QTextEdit_setPlainText(QTextEditH(Widget), @AText);
9894 end;
9895 
9896 procedure TQtTextEdit.setReadOnly(const AReadOnly: Boolean);
9897 begin
9898   QTextEdit_setReadOnly(QTextEditH(Widget), AReadOnly);
9899 end;
9900 
9901 procedure TQtTextEdit.setSelection(const AStart, ALength: Integer);
9902 var
9903   TextCursor: QTextCursorH;
9904 begin
9905   if AStart >= 0 then
9906   begin
9907     TextCursor := QTextCursor_create();
9908     QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9909     QTextCursor_clearSelection(TextCursor);
9910     QTextCursor_setPosition(TextCursor, AStart);
9911     QTextCursor_setPosition(TextCursor, AStart + ALength, QTextCursorKeepAnchor);
9912     QTextEdit_setTextCursor(QTextEditH(Widget), TextCursor);
9913     QTextCursor_destroy(TextCursor);
9914   end;
9915 end;
9916 
9917 procedure TQtTextEdit.setTabChangesFocus(const AValue: Boolean);
9918 begin
9919   QTextEdit_setTabChangesFocus(QTextEditH(Widget), AValue);
9920 end;
9921 
9922 procedure TQtTextEdit.Cut;
9923 begin
9924   QTextEdit_cut(QTextEditH(Widget));
9925 end;
9926 
9927 procedure TQtTextEdit.Copy;
9928 begin
9929   QTextEdit_copy(QTextEditH(Widget));
9930 end;
9931 
9932 procedure TQtTextEdit.Paste;
9933 begin
9934   QTextEdit_paste(QTextEditH(Widget));
9935 end;
9936 
9937 procedure TQtTextEdit.Undo;
9938 begin
9939   QTextEdit_undo(QTextEditH(Widget));
9940 end;
9941 
9942 procedure TQtTextEdit.setAlignment(const AAlignment: QtAlignment);
9943 var
9944   TextCursor: QTextCursorH;
9945 begin
9946   // QTextEdit supports alignment for every paragraph. We need to align all text.
9947   // So, we should select all text, set format, and clear selection
9948 
9949   // 1. Select all text
9950   QTextEdit_selectAll(QTextEditH(Widget));
9951 
9952   // 2. Set format
9953   QTextEdit_setAlignment(QTextEditH(Widget), AAlignment);
9954 
9955   // 3. Clear selection. To unselect all document we must create new text cursor,
9956   // get format from Text Edit, clear selection in cursor and set it back to Text Edit
9957   TextCursor := QTextCursor_create();
9958   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9959   QTextCursor_clearSelection(TextCursor);
9960   QTextEdit_setTextCursor(QTextEditH(Widget), TextCursor);
9961   QTextCursor_destroy(TextCursor);
9962 end;
9963 
9964 procedure TQtTextEdit.setBorder(const ABorder: Boolean);
9965 begin
9966   if ABorder then
9967     QFrame_setFrameShape(QFrameH(Widget), QFrameStyledPanel)
9968   else
9969     QFrame_setFrameShape(QFrameH(Widget), QFrameNoFrame);
9970 end;
9971 
9972 procedure TQtTextEdit.setCursorPosition(const ACursorPosition: Integer);
9973 var
9974   TextCursor: QTextCursorH;
9975 begin
9976   TextCursor := QTextCursor_create();
9977   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9978   if not QTextCursor_isNull(TextCursor) then
9979     QTextCursor_setPosition(TextCursor, ACursorPosition);
9980   QTextCursor_destroy(TextCursor);
9981 end;
9982 
9983 procedure TQtTextEdit.setDefaultColorRoles;
9984 begin
9985   WidgetColorRole := QPaletteBase;
9986   TextColorRole := QPaletteText;
9987 end;
9988 
9989 procedure TQtTextEdit.AttachEvents;
9990 begin
9991   inherited AttachEvents;
9992 
9993   FUndoAvailableHook := QTextEdit_hook_create(Widget);
9994   QTextEdit_hook_hook_undoAvailable(FUndoAvailableHook, @SignalUndoAvailable);
9995 
9996   FTextChangedHook := QTextEdit_hook_create(Widget);
9997   QTextEdit_hook_hook_textChanged(FTextChangedHook, @SignalTextChanged);
9998 
9999   FViewportEventHook := QObject_hook_create(viewportWidget);
10000   QObject_hook_hook_events(FViewportEventHook, @viewportEventFilter);
10001   // initialize scrollbars
10002   verticalScrollBar;
10003   horizontalScrollBar;
10004 end;
10005 
10006 procedure TQtTextEdit.DetachEvents;
10007 begin
10008   if FUndoAvailableHook <> nil then
10009   begin
10010     QTextEdit_hook_destroy(FUndoAvailableHook);
10011     FUndoAvailableHook := nil;
10012   end;
10013 
10014   if FTextChangedHook <> nil then
10015   begin
10016     QTextEdit_hook_destroy(FTextChangedHook);
10017     FTextChangedHook := nil;
10018   end;
10019 
10020   if FViewportEventHook <> nil then
10021   begin
10022     QObject_hook_destroy(FViewportEventHook);
10023     FViewportEventHook := nil;
10024   end;
10025   inherited DetachEvents;
10026 end;
10027 
TQtTextEdit.viewportEventFilternull10028 function TQtTextEdit.viewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
10029 begin
10030   Result := False;
10031   QEvent_accept(Event);
10032   case QEvent_type(Event) of
10033     QEventContextMenu: Result := SlotContextMenu(Sender, Event);
10034     QEventMouseButtonPress,
10035     QEventMouseButtonRelease,
10036     QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
10037     QEventMouseMove: Result := SlotMouseMove(Sender, Event);
10038   end;
10039 end;
10040 
getContextMenuPolicynull10041 function TQtTextEdit.getContextMenuPolicy: QtContextMenuPolicy;
10042 begin
10043   Result := QWidget_contextMenuPolicy(viewPortWidget);
10044 end;
10045 
10046 procedure TQtTextEdit.setContextMenuPolicy(const AValue: QtContextMenuPolicy);
10047 begin
10048   QWidget_setContextMenuPolicy(viewportWidget, AValue);
10049 end;
10050 
10051 procedure TQtTextEdit.SignalUndoAvailable(b: Boolean); cdecl;
10052 begin
10053   FUndoAvailable := b;
10054 end;
10055 
10056 procedure TQtTextEdit.SignalTextChanged(); cdecl;
10057 var
10058   Mess: TLMessage;
10059 begin
10060   if (LCLObject = nil) or not GetVisible then
10061     exit;
10062   if Assigned(FList) then
10063     TQtMemoStrings(FList).TextChanged := True;
10064   if not InUpdate then
10065   begin
10066     FillChar(Mess{%H-}, SizeOf(Mess), #0);
10067     Mess.Msg := CM_TEXTCHANGED;
10068     DeliverMessage(Mess);
10069   end;
10070 end;
10071 
10072 { TQtTabBar }
10073 
10074 procedure TQtTabBar.AttachEvents;
10075 begin
10076   inherited AttachEvents;
10077   FTabBarChangedHook := QTabBar_hook_create(QTabBarH(Widget));
10078   FTabBarMovedHook := QTabBar_hook_create(QTabBarH(Widget));
10079   QTabBar_hook_hook_currentChanged(FTabBarChangedHook, @SignalTabBarCurrentChanged);
10080   QTabBar_hook_hook_tabMoved(FTabBarMovedHook, @SignalTabBarMoved);
10081 end;
10082 
10083 procedure TQtTabBar.DetachEvents;
10084 begin
10085   if FTabBarMovedHook <> nil then
10086   begin
10087     QTabBar_hook_destroy(FTabBarMovedHook);
10088     FTabBarMovedHook := nil;
10089   end;
10090   if FTabBarChangedHook <> nil then
10091   begin
10092     QTabBar_hook_destroy(FTabBarChangedHook);
10093     FTabBarChangedHook := nil;
10094   end;
10095   inherited DetachEvents;
10096 end;
10097 
GetTabRectnull10098 function TQtTabBar.GetTabRect(const AIndex: integer): TRect;
10099 var
10100   Pt: TPoint;
10101 begin
10102   QTabBar_tabRect(QTabBarH(Widget), @Result, AIndex);
10103   if Assigned(FOwner) then
10104   begin
10105     Pt := TabBarOffset;
10106     OffsetRect(Result, Pt.X, Pt.Y);
10107   end;
10108 end;
10109 
TabBarOffsetnull10110 function TQtTabBar.TabBarOffset: TPoint;
10111 var
10112   R: TRect;
10113 begin
10114   Result := Point(0, 0);
10115   if Assigned(FOwner) then
10116   begin
10117     QWidget_geometry(Widget, @R);
10118     case TQtTabWidget(FOwner).getTabPosition of
10119       QTabWidgetNorth,
10120       QTabWidgetSouth:
10121         begin
10122           if R.Left < 0 then
10123             R.Left := 0;
10124           // issue #28591
10125           if QWidget_layoutDirection(Widget) = QtRightToLeft then
10126             Result.X := 0
10127           else
10128             Result.X := R.Left;
10129         end;
10130       QTabWidgetEast,
10131       QTabWidgetWest:
10132         begin
10133           if R.Top < 0 then
10134             R.Top := 0;
10135           Result.Y := R.Top;
10136         end;
10137     end;
10138   end;
10139 end;
10140 
10141 procedure TQtTabBar.SignalTabBarMoved(fromIndex: integer; toIndex: Integer);
10142   cdecl;
10143 var
10144   ANewIndex: Integer;
10145 begin
10146   if LCLObject = nil then
10147     Exit;
10148   // DebugLn('TQtTabBar.SignalTabBarMoved From=',dbgs(fromIndex),' to ',dbgs(toIndex),' FSavedIndexOnPageChanging=',dbgs(FSavedIndexOnPageChanging));
10149   if Assigned(FOwner) and not (FOwner.ChildOfComplexWidget = ccwTTabControl) then
10150   begin
10151     ANewIndex := TQtTabWidget(FOwner).GetLCLPageIndex(toIndex);
10152     TQtTabWidget(FOwner).setCurrentWidget(TQtWidget(TCustomTabControl(LCLObject).Page[ANewIndex].Handle), True);
10153   end;
10154 end;
10155 
10156 procedure TQtTabBar.SignalTabBarCurrentChanged(Index: Integer); cdecl;
10157 var
10158   Msg: TLMNotify;
10159   Hdr: TNmHdr;
10160 begin
10161   if LCLObject = nil then
10162     Exit;
10163 
10164   if TQtTabWidget(LCLObject.Handle).InUpdate then
10165     exit;
10166   FillChar(Msg{%H-}, SizeOf(Msg), 0);
10167   Msg.Msg := LM_NOTIFY;
10168   FillChar(Hdr{%H-}, SizeOf(Hdr), 0);
10169 
10170   Hdr.hwndFrom := LCLObject.Handle;
10171   Hdr.Code := TCN_SELCHANGE;
10172   Hdr.idFrom := PtrUInt(TQtTabWidget(LCLObject.Handle).GetLCLPageIndex(Index));
10173   Msg.NMHdr := @Hdr;
10174   Msg.Result := 0;
10175   if FSavedIndexOnPageChanging = Forbid_TCN_SELCHANGE then
10176     FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE
10177   else
10178     DeliverMessage(Msg);
10179 end;
10180 
SlotTabBarMousenull10181 function TQtTabBar.SlotTabBarMouse(Sender: QObjectH; Event: QEventH): Boolean;
10182   cdecl;
10183 var
10184   MousePos: TQtPoint;
10185   NewEvent: QMouseEventH;
10186   R: TRect;
10187   R1: TRect;
10188   BaseHeight: Integer;
10189   ForcedMouseGrab: Boolean;
10190 begin
10191   Result := False;
10192 
10193   if not CanSendLCLMessage then
10194     exit;
10195 
10196   MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
10197 
10198   if Assigned(FOwner) then
10199   begin
10200     R := TQtTabWidget(FOwner).getGeometry;
10201     R1 := getGeometry;
10202     BaseHeight := GetPixelMetric(QStylePM_TabBarBaseHeight, nil, nil);
10203 
10204     case TQtTabWidget(FOwner).getTabPosition of
10205       QTabWidgetNorth:
10206         begin
10207           MousePos.Y := R.Top - (R1.Bottom - MousePos.Y);
10208           MousePos.X := MousePos.X - BaseHeight;
10209         end;
10210       QTabWidgetWest:
10211         begin
10212           MousePos.x := R.Left - (R1.Right - MousePos.X);
10213           MousePos.y := MousePos.Y - BaseHeight;
10214         end;
10215       QTabWidgetEast:
10216         begin
10217           MousePos.X := R1.Left + MousePos.X - BaseHeight;
10218           MousePos.y := MousePos.Y - BaseHeight;
10219         end;
10220       QTabWidgetSouth:
10221         begin
10222           MousePos.Y := R1.Top + MousePos.Y - BaseHeight;
10223           MousePos.X := MousePos.X - BaseHeight;
10224         end;
10225     end;
10226 
10227     NewEvent := QMouseEvent_create(QEvent_type(Event), @MousePos,
10228         QMouseEvent_globalPos(QMouseEventH(Event)),
10229         QMouseEvent_button(QMouseEventH(Event)),
10230         QMouseEvent_buttons(QMouseEventH(Event)),
10231         QInputEvent_modifiers(QInputEventH(Event))
10232       );
10233 
10234     ForcedMouseGrab := False;
10235     if QEvent_type(Event) = QEventMouseButtonPress then
10236       ForcedMouseGrab := not ((QWidget_mouseGrabber = Widget) or
10237         (Assigned(FOwner) and (QWidget_mouseGrabber = FOwner.Widget)));
10238 
10239     SlotMouse(Sender, NewEvent);
10240     QMouseEvent_destroy(NewEvent);
10241 
10242     ForcedMouseGrab := ForcedMouseGrab and
10243         (Assigned(FOwner) and (QWidget_mouseGrabber = FOwner.Widget));
10244 
10245     if ForcedMouseGrab then
10246       QWidget_grabMouse(Widget);
10247 
10248   end else
10249     SlotMouse(Sender, Event);
10250 end;
10251 
TQtTabBar.EventFilternull10252 function TQtTabBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
10253 
StopShortcutEventnull10254   function StopShortcutEvent: boolean;
10255   begin
10256     Result := Assigned(FOwner) and (FOwner.ChildOfComplexWidget <> ccwTTabControl) and
10257       not TQtTabWidget(FOwner).FSwitchTabsByKeyboard and (QKeyEvent_matches(QKeyEventH(Event), QKeySequenceNextChild) or
10258       QKeyEvent_matches(QKeyEventH(Event), QKeySequencePreviousChild));
10259   end;
10260 
10261 {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10262 var
10263   R: TRect;
10264 {$ENDIF}
10265 begin
10266   Result := False;
10267   QEvent_accept(Event);
10268   if LCLObject = nil then
10269     exit;
10270   {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
10271   WriteLn('TQtTabBar.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
10272     ' LCLObject=', dbgsName(LCLObject),
10273     ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
10274   {$endif}
10275 
10276   BeginEventProcessing;
10277   try
10278     case QEvent_type(Event) of
10279       {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10280       QEventPaint:
10281         begin
10282           QPaintEvent_rect(QPaintEventH(Event), @R);
10283           // qt paints tab
10284           QObject_event(Sender, Event);
10285           // LCL can do whatever now
10286           SlotPaint(Sender, Event);
10287           Result := True;
10288           QEvent_ignore(Event);
10289         end;
10290       {$ENDIF}
10291       QEventShortcutOverride: Result := StopShortcutEvent;
10292       QEventKeyPress,
10293       QEventKeyRelease:
10294       begin
10295         if (QEvent_type(Event) = QEventKeyPress) then
10296           FSavedIndexOnPageChanging := QTabBar_currentIndex(QTabBarH(Widget));
10297         SlotKey(Sender, Event);
10298         if (LCLObject = nil) or
10299           ((LCLObject <> nil) and not LCLObject.HandleAllocated) then
10300           Result := True;
10301         if not Result then
10302           Result := StopShortcutEvent;
10303       end;
10304       QEventMouseButtonPress,
10305       QEventMouseButtonRelease,
10306       QEventMouseButtonDblClick:
10307         begin
10308           if QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton then
10309           begin
10310             if (QEvent_type(Event) = QEventMouseButtonPress) then
10311               FSavedIndexOnPageChanging := QTabBar_currentIndex(QTabBarH(Widget));
10312             Result := SlotTabBarMouse(Sender, Event);
10313             if (LCLObject = nil) or
10314               ((LCLObject <> nil) and not LCLObject.HandleAllocated) then
10315               Result := True
10316             else
10317               SetNoMousePropagation(QWidgetH(Sender), False);
10318           end;
10319         end;
10320     else
10321       QEvent_ignore(Event);
10322     end;
10323   finally
10324     EndEventProcessing;
10325   end;
10326 end;
10327 
10328 procedure TQtTabBar.SetTabFontColor(AIndex: Integer; AColor: TQColor);
10329 begin
10330   QTabBar_setTabTextColor(QTabBarH(Widget), AIndex, @AColor);
10331 end;
10332 
10333 { TQtTabWidget }
10334 
getTabBarnull10335 function TQtTabWidget.getTabBar: TQtTabBar;
10336 begin
10337   if FTabBar = nil then
10338   begin
10339     {$note TQtTabWidget.getTabBar: we can remove QLCLTabWidget, and get it like StackWidget,
10340      objectName is qt_tabwidget_tabbar.}
10341     FTabBar := TQtTabBar.CreateFrom(LCLObject, QLCLTabWidget_tabBarHandle(QTabWidgetH(Widget)));
10342     {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10343     FTabBar.HasPaint := True;
10344     {$ENDIF}
10345     FTabBar.FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE;
10346     FTabBar.FOwner := Self;
10347     FTabBar.AttachEvents;
10348   end;
10349   Result := FTabBar;
10350 end;
10351 
getShowTabsnull10352 function TQtTabWidget.getShowTabs: Boolean;
10353 begin
10354   Result := TabBar.getVisible;
10355 end;
10356 
getStackWidgetnull10357 function TQtTabWidget.getStackWidget: QWidgetH;
10358 var
10359   List: TPtrIntArray;
10360   Obj: QObjectH;
10361   i: Integer;
10362   WStr: WideString;
10363 begin
10364   if FStackWidget = nil then
10365   begin
10366     QObject_children(Widget, @List);
10367     for i := 0 to High(List) do
10368     begin
10369       Obj := QObjectH(List[i]);
10370       QObject_objectName(Obj, @WStr);
10371       {do not localize !}
10372       if WStr = 'qt_tabwidget_stackedwidget' then
10373       begin
10374         FStackWidget := QWidgetH(List[i]);
10375         break;
10376       end;
10377     end;
10378     FCentralWidget := FStackWidget;
10379   end;
10380   Result := FStackWidget;
10381 end;
10382 
10383 procedure TQtTabWidget.setShowTabs(const AValue: Boolean);
10384 begin
10385   TabBar.setVisible(AValue);
10386 end;
10387 
CreateWidgetnull10388 function TQtTabWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
10389 var
10390   Parent: QWidgetH;
10391 begin
10392   // Creates the widget
10393   {$ifdef VerboseQt}
10394     WriteLn('TQtTabWidget.Create');
10395   {$endif}
10396   FSwitchTabsByKeyboard := False; {shortcuts are enabled by default under qt, but not under LCL}
10397   FWidgetNeedFontColorInitialization := True;
10398   if AParams.WndParent <> 0 then
10399     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
10400   else
10401     Parent := nil;
10402   Result := QTabWidget_create(Parent);
10403 
10404   {note: for some reason tabbar scroll buttons are not enabled as default option
10405   under mac - but under linux & win are. Qt docs says that this options is enabled
10406   as default ... possible qt bug}
10407   {$ifdef darwin}
10408   QTabWidget_setUsesScrollButtons(QTabWidgetH(Result), True);
10409   {$endif}
10410   if (QtVersionMajor = 4) and (QtVersionMinor < 6) then
10411     QWidget_setAutoFillBackground(Result, True);
10412 end;
10413 
10414 destructor TQtTabWidget.Destroy;
10415 begin
10416   FTabBar.Free;
10417   inherited Destroy;
10418 end;
10419 
10420 procedure TQtTabWidget.DestroyNotify(AWidget: TQtWidget);
10421 begin
10422   if AWidget = FTabBar then
10423     FTabBar := nil;
10424   inherited DestroyNotify(AWidget);
10425 end;
10426 
GetLCLPageIndexnull10427 function TQtTabWidget.GetLCLPageIndex(AIndex: Integer): Integer;
10428 var
10429   I: Integer;
10430 begin
10431   Result := AIndex;
10432   if (LCLObject = nil) or
10433      (csDesigning in LCLObject.ComponentState) or
10434      not (LCLObject is TCustomTabControl) then
10435     Exit;
10436   I := 0;
10437   while (I < TCustomTabControl(LCLObject).PageCount) and (I <= Result) do
10438   begin
10439     if not TCustomTabControl(LCLObject).Page[I].TabVisible then
10440       Inc(Result);
10441     Inc(I);
10442   end;
10443 end;
10444 
10445 procedure TQtTabWidget.AttachEvents;
10446 begin
10447   inherited AttachEvents;
10448 
10449   {initialize our tabbar}
10450   TabBar;
10451 
10452   FCurrentChangedHook := QTabWidget_hook_create(Widget);
10453   QTabWidget_hook_hook_currentChanged(FCurrentChangedHook, @SignalCurrentChanged);
10454 
10455   FCloseRequestedHook := QTabWidget_hook_create(Widget);
10456   QTabWidget_hook_hook_tabCloseRequested(FCloseRequestedHook, @SignalCloseRequested);
10457 
10458   FStackedWidgetHook := QObject_hook_create(StackWidget);
10459   QObject_hook_hook_events(FStackedWidgetHook, @EventFilter);
10460 
10461 end;
10462 
10463 procedure TQtTabWidget.DetachEvents;
10464 begin
10465 
10466   if FStackedWidgetHook <> nil then
10467   begin
10468     QObject_hook_destroy(FStackedWidgetHook);
10469     FStackedWidgetHook := nil;
10470   end;
10471   if FCurrentChangedHook <> nil then
10472   begin
10473     QTabWidget_hook_destroy(FCurrentChangedHook);
10474     FCurrentChangedHook := nil;
10475   end;
10476   if FCloseRequestedHook <> nil then
10477   begin
10478     QTabWidget_hook_destroy(FCloseRequestedHook);
10479     FCloseRequestedHook := nil;
10480   end;
10481   inherited DetachEvents;
10482 end;
10483 
TQtTabWidget.EventFilternull10484 function TQtTabWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
10485   cdecl;
10486 var
10487 {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10488   R: TRect;
10489   TabGeom: TRect;
10490   Pt: TPoint;
10491 {$ENDIF}
10492   ALCLEvent: QLCLMessageEventH;
10493   ANewSize: TSize;
10494 begin
10495 
10496   Result := False;
10497   QEvent_accept(Event);
10498   if LCLObject = nil then
10499     exit;
10500 
10501   if (Sender = FStackWidget) then
10502   begin
10503     {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
10504     WriteLn('TQtTabWidget.EventFilter: STACKWIDGET Sender=', IntToHex(PtrUInt(Sender),8),
10505       ' LCLObject=', dbgsName(LCLObject),
10506       ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
10507     {$endif}
10508     {leave this for debugging purposes}
10509     exit;
10510   end;
10511 
10512   BeginEventProcessing;
10513   try
10514     case QEvent_type(Event) of
10515       QEventResize:
10516       begin
10517         ANewSize := QResizeEvent_size(QResizeEventH(Event))^;
10518         DelayResizeEvent(QWidgetH(Sender), ANewSize); // delay resize event since we are complex widget
10519       end;
10520       {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10521       QEventPaint:
10522         begin
10523           {this paint event comes after tabbar paint event,
10524            so we have to exclude our tabs from painting}
10525           QPaintEvent_rect(QPaintEventH(Event), @R);
10526           QWidget_geometry(TabBar.Widget, @TabGeom);
10527           Pt.X := R.Left;
10528           Pt.Y := R.Top;
10529           Result := PtInRect(TabGeom, Pt) and
10530             (R.Bottom - R.Top = TabGeom.Bottom - TabGeom.Top) and
10531             (TabAt(Pt) >= 0);
10532           if Result then
10533             QEvent_ignore(Event);
10534         end;
10535       {$ENDIF}
10536       LCLQt_DelayLayoutRequest:
10537       begin
10538         if LCLObject.ClientRectNeedsInterfaceUpdate then
10539         begin
10540           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
10541           DebugLn('<*><*> TQtTabWidget calling DoAdjustClientRectChange() from LCLQt_DelayLayoutRequest ...');
10542           {$ENDIF}
10543           LCLObject.DoAdjustClientRectChange(True);
10544         end;
10545         Result := True;
10546       end;
10547       QEventLayoutRequest:
10548       begin
10549         //behaviour is changed because of issue #21805.
10550         //we send delayed event so LCL can read clientRect at the right time.
10551         ALCLEvent := QLCLMessageEvent_create(LCLQt_DelayLayoutRequest, 0, 0, 0, 0);
10552         QCoreApplication_postEvent(Sender, ALCLEvent);
10553       end;
10554       QEventKeyPress,
10555       QEventKeyRelease: QEvent_ignore(Event);
10556       QEventWheel:
10557         begin
10558           if not getEnabled then
10559             inherited EventFilter(Sender, Event)
10560           else
10561             QEvent_ignore(Event);
10562         end;
10563       else
10564         Result := inherited EventFilter(Sender, Event);
10565     end;
10566   finally
10567     EndEventProcessing;
10568   end;
10569 end;
10570 
10571 {------------------------------------------------------------------------------
10572   Function: TQtTabWidget.insertTab
10573   Params:  index: Integer; page: QWidgetH; p2: PWideString
10574   Returns: Nothing
10575  ------------------------------------------------------------------------------}
insertTabnull10576 function TQtTabWidget.insertTab(index: Integer; page: QWidgetH; p2: WideString): Integer; overload;
10577 begin
10578   Result := insertTab(index, page, nil, p2);
10579 end;
10580 
10581 {------------------------------------------------------------------------------
10582   Function: TQtTabWidget.insertTab
10583   Params:  index: Integer; page: QWidgetH; icon: QIconH; p2: PWideString
10584   Returns: Nothing
10585  ------------------------------------------------------------------------------}
insertTabnull10586 function TQtTabWidget.insertTab(index: Integer; page: QWidgetH; icon: QIconH; p2: WideString): Integer; overload;
10587 var
10588   UseAdd: Boolean;
10589 begin
10590   UseAdd := Index > getCount - 1;
10591   if icon <> nil then
10592   begin
10593     if UseAdd then
10594       Result := QTabWidget_addTab(QTabWidgetH(Widget), page, icon, @p2)
10595     else
10596       Result := QTabWidget_insertTab(QTabWidgetH(Widget), index, page, icon, @p2)
10597   end else
10598   begin
10599     if UseAdd then
10600       Result := QTabWidget_addTab(QTabWidgetH(Widget), page, @p2)
10601     else
10602       Result := QTabWidget_insertTab(QTabWidgetH(Widget), index, page, @p2);
10603   end;
10604 end;
10605 
TQtTabWidget.getCountnull10606 function TQtTabWidget.getCount: Integer;
10607 begin
10608   Result := QTabWidget_count(QTabWidgetH(Widget));
10609 end;
10610 
getClientBoundsnull10611 function TQtTabWidget.getClientBounds: TRect;
10612 begin
10613   QWidget_contentsRect(StackWidget, @Result);
10614 end;
10615 
getCurrentIndexnull10616 function TQtTabWidget.getCurrentIndex: Integer;
10617 begin
10618   Result := QTabWidget_currentIndex(QTabWidgetH(Widget));
10619 end;
10620 
getTabPositionnull10621 function TQtTabWidget.getTabPosition: QTabWidgetTabPosition;
10622 begin
10623   Result := QTabWidget_tabPosition(QTabWidgetH(Widget));
10624 end;
10625 
10626 procedure TQtTabWidget.removeTab(AIndex: Integer);
10627 begin
10628   QTabWidget_removeTab(QTabWidgetH(Widget), AIndex);
10629 end;
10630 
10631 procedure TQtTabWidget.setCurrentIndex(AIndex: Integer);
10632 begin
10633   QTabWidget_setCurrentIndex(QTabWidgetH(Widget), AIndex);
10634 end;
10635 
10636 procedure TQtTabWidget.setCurrentWidget(APage: TQtWidget; const AIsMoved: Boolean);
10637 begin
10638   QTabWidget_setCurrentWidget(QTabWidgetH(Widget), APage.Widget);
10639   if AIsMoved and (Assigned(LCLObject) and not (csDesigning in LCLObject.ComponentState)) then
10640     APage.setFocus;
10641 end;
10642 
10643 {------------------------------------------------------------------------------
10644   Function: TQtTabWidget.setTabPosition
10645   Params:  None
10646   Returns: Nothing
10647  ------------------------------------------------------------------------------}
10648 procedure TQtTabWidget.setTabPosition(ATabPosition: QTabWidgetTabPosition);
10649 begin
10650   QTabWidget_setTabPosition(QTabWidgetH(Widget), ATabPosition);
10651 end;
10652 
10653 procedure TQtTabWidget.setTabIcon(index: Integer; icon: QIconH);
10654 begin
10655   QTabWidget_setTabIcon(QTabWidgetH(Widget), index, icon);
10656 end;
10657 
10658 {------------------------------------------------------------------------------
10659   Function: TQtTabWidget.SignalCurrentChanged
10660   Params:  None
10661   Returns: Nothing
10662            Changes ActivePage of TPageControl
10663  ------------------------------------------------------------------------------}
10664 procedure TQtTabWidget.SignalCurrentChanged(Index: Integer); cdecl;
10665 var
10666   Msg: TLMNotify;
10667   Hdr: TNmHdr;
10668   i: Integer;
10669 begin
10670   if (LCLObject = nil) or InUpdate or not GetVisible then
10671   begin
10672     if TabBar.FSavedIndexOnPageChanging <> Forbid_TCN_SELCHANGE then
10673       TabBar.FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE;
10674     exit;
10675   end;
10676 
10677   FillChar(Msg{%H-}, SizeOf(Msg), 0);
10678   Msg.Msg := LM_NOTIFY;
10679   FillChar(Hdr{%H-}, SizeOf(Hdr), 0);
10680 
10681   Hdr.hwndFrom := LCLObject.Handle;
10682   Hdr.Code := TCN_SELCHANGING;
10683   Hdr.idFrom := PtrUInt(GetLCLPageIndex(Index));
10684   Msg.NMHdr := @Hdr;
10685   Msg.Result := 0;
10686   if (DeliverMessage(Msg) <> 0) and (Index >= 0) and
10687     (TabBar.FSavedIndexOnPageChanging >= 0) then
10688   begin
10689     BeginUpdate;
10690     try
10691       i := TabBar.FSavedIndexOnPageChanging;
10692       FTabBar.FSavedIndexOnPageChanging := Forbid_TCN_SELCHANGE;
10693       setCurrentIndex(i);
10694     finally
10695       EndUpdate;
10696     end;
10697   end;
10698 end;
10699 
10700 procedure TQtTabWidget.SignalCloseRequested(Index: Integer); cdecl;
10701 var
10702   APage: TCustomPage;
10703 begin
10704   APage := TCustomTabControl(LCLObject).Page[GetLCLPageIndex(Index)];
10705   if not APage.HandleAllocated then
10706     Exit;
10707   TCustomTabControl(LCLObject).DoCloseTabClicked(APage);
10708 end;
10709 
TQtTabWidget.indexOfnull10710 function TQtTabWidget.indexOf(const AWidget: QWidgetH): integer;
10711 begin
10712   Result := QTabWidget_indexOf(QTabWidgetH(Widget), AWidget);
10713 end;
10714 
10715 procedure TQtTabWidget.setTabText(index: Integer; p2: WideString);
10716 begin
10717   QTabWidget_setTabText(QTabWidgetH(Widget), index, @p2);
10718 end;
10719 
10720 procedure TQtTabWidget.setTabsClosable(AValue: Boolean);
10721 begin
10722   QTabWidget_setTabsClosable(QTabWidgetH(Widget), AValue);
10723 end;
10724 
tabAtnull10725 function TQtTabWidget.tabAt(APoint: TPoint): Integer;
10726 var
10727   AQtPoint: TQtPoint;
10728   R: TRect;
10729 begin
10730   if (APoint.Y < 0) or (APoint.X < 0) then
10731   begin
10732     {some themes (eg. MacOSX) moves tab buttons
10733      into the middle of parent, so we must
10734      take it's geometry into account.}
10735     R := TabBar.getGeometry;
10736     QWidget_pos(getStackWidget, @AQtPoint);
10737     AQtPoint.x := AQtPoint.x + APoint.x;
10738     AQtPoint.y := AQtPoint.y + APoint.y;
10739 
10740     if R.Left <> 0 then
10741       dec(AQtPoint.x, R.Left);
10742     if R.Top <> 0 then
10743       dec(AQtPoint.y, R.Top);
10744   end else
10745     AQtPoint := QtPoint(APoint.x, APoint.y);
10746   Result := QTabBar_tabAt(QTabBarH(TabBar.Widget), @AQtPoint);
10747 end;
10748 
10749 { TQtComboBox }
10750 
GetLineEditnull10751 function TQtComboBox.GetLineEdit: TQtLineEdit;
10752 begin
10753   if not getEditable then
10754   begin
10755     FLineEdit := nil
10756   end
10757   else
10758   begin
10759     if FLineEdit = nil then
10760     begin
10761       FLineEdit := TQtLineEdit.CreateFrom(LCLObject, QComboBox_lineEdit(QComboBoxH(Widget)));
10762       FLineEdit.FOwner := Self;
10763       QObject_disconnect(FLineEdit.Widget, '2returnPressed()', Widget, '1_q_returnPressed()');
10764       FLineEdit.ChildOfComplexWidget := ccwComboBox;
10765       FLineEdit.AttachEvents;
10766     end;
10767   end;
10768   Result := FLineEdit;
10769 end;
10770 
10771 procedure TQtComboBox.SetOwnerDrawn(const AValue: Boolean);
10772 begin
10773   FOwnerDrawn := AValue;
10774   if FDropList <> nil then
10775     FDropList.OwnerDrawn := FOwnerDrawn;
10776 end;
10777 
TQtComboBox.GetDropListnull10778 function TQtComboBox.GetDropList: TQtListWidget;
10779 begin
10780   if FDropList = nil then
10781   begin
10782     FDropList := TQtListWidget.CreateFrom(LCLObject, QListWidget_create());
10783     FDropList.FOwner := Self;
10784     FDropList.setAttribute(QtWA_NoMousePropagation, False);
10785     FDropList.OwnerDrawn := OwnerDrawn;
10786     FDropList.ChildOfComplexWidget := ccwComboBox;
10787     QComboBox_setModel(QComboBoxH(Widget), FDropList.getModel);
10788     QComboBox_setView(QComboBoxH(Widget), QListWidgetH(FDropList.Widget));
10789     FDropList.AttachEvents;
10790   end;
10791   Result := FDropList;
10792 end;
10793 
CreateWidgetnull10794 function TQtComboBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
10795 var
10796   Parent: QWidgetH;
10797 begin
10798   // Creates the widget
10799   {$ifdef VerboseQt}
10800     WriteLn('TQtComboBox.Create');
10801   {$endif}
10802   FKeyEnterFix := False; {issue #31574}
10803   FMouseFixPos := QtPoint(-1, -1);
10804   FDropListVisibleInternal := False;
10805   if AParams.WndParent <> 0 then
10806     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
10807   else
10808     Parent := nil;
10809   Result := QComboBox_create(Parent);
10810   // disable AutoCompletion. LCL has its own
10811   QComboBox_setAutoCompletion(QComboboxH(Result), False);
10812   FLineEdit := nil;
10813   FOwnerDrawn := False;
10814 end;
10815 
getCursorPositionnull10816 function TQtComboBox.getCursorPosition: TPoint;
10817 begin
10818   Result := Point(0, 0);
10819   if LineEdit <> nil then
10820     Result.X := LineEdit.getCursorPosition.X;
10821 end;
10822 
TQtComboBox.getMaxLengthnull10823 function TQtComboBox.getMaxLength: Integer;
10824 begin
10825   if LineEdit <> nil then
10826     Result := LineEdit.getMaxLength
10827   else
10828     Result := 0;
10829 end;
10830 
getSelectionStartnull10831 function TQtComboBox.getSelectionStart: Integer;
10832 begin
10833   if (LineEdit <> nil) then
10834     Result := LineEdit.getSelectionStart
10835   else
10836     Result := 0;
10837 end;
10838 
getSelectionLengthnull10839 function TQtComboBox.getSelectionLength: Integer;
10840 begin
10841   if (LineEdit <> nil) then
10842     Result := LineEdit.getSelectionLength
10843   else
10844     Result := 0;
10845 end;
10846 
TQtComboBox.isUndoAvailablenull10847 function TQtComboBox.isUndoAvailable: Boolean;
10848 begin
10849   if LineEdit <> nil then
10850     Result := LineEdit.isUndoAvailable
10851   else
10852     Result := False;
10853 end;
10854 
10855 procedure TQtComboBox.setBorder(const ABorder: Boolean);
10856 begin
10857   QComboBox_setFrame(QComboBoxH(Widget), ABorder);
10858 end;
10859 
10860 procedure TQtComboBox.setEchoMode(const AMode: QLineEditEchoMode);
10861 begin
10862   if LineEdit <> nil then
10863     LineEdit.setEchoMode(AMode);
10864 end;
10865 
10866 procedure TQtComboBox.setMaxLength(const ALength: Integer);
10867 begin
10868   if LineEdit <> nil then
10869     LineEdit.setMaxLength(ALength);
10870 end;
10871 
10872 procedure TQtComboBox.setReadOnly(const AReadOnly: Boolean);
10873 begin
10874   setEditable(not AReadOnly);
10875 end;
10876 
10877 procedure TQtComboBox.setSelection(const AStart, ALength: Integer);
10878 begin
10879   if LineEdit <> nil then
10880     LineEdit.setSelection(AStart, ALength);
10881 end;
10882 
10883 procedure TQtComboBox.setCursorPosition(const ACursorPosition: Integer);
10884 begin
10885   if LineEdit <> nil then
10886     LineEdit.setCursorPosition(ACursorPosition);
10887 end;
10888 
10889 procedure TQtComboBox.Cut;
10890 begin
10891   if LineEdit <> nil then
10892     LineEdit.Cut;
10893 end;
10894 
10895 procedure TQtComboBox.Copy;
10896 begin
10897   if LineEdit <> nil then
10898     LineEdit.Copy;
10899 end;
10900 
10901 procedure TQtComboBox.Paste;
10902 begin
10903   if LineEdit <> nil then
10904     LineEdit.Paste;
10905 end;
10906 
10907 procedure TQtComboBox.Undo;
10908 begin
10909   if LineEdit <> nil then
10910     LineEdit.Undo;
10911 end;
10912 
10913 {------------------------------------------------------------------------------
10914   Function: TQtComboBox.Destroy
10915   Params:  None
10916   Returns: Nothing
10917  ------------------------------------------------------------------------------}
10918 destructor TQtComboBox.Destroy;
10919 begin
10920   FDropList.Free;
10921   FLineEdit.Free;
10922   inherited Destroy;
10923 end;
10924 
10925 procedure TQtComboBox.DestroyNotify(AWidget: TQtWidget);
10926 begin
10927   if AWidget = FLineEdit then
10928     FLineEdit := nil;
10929   if AWidget = FDropList then
10930     FDropList := nil;
10931 
10932   if Assigned(FList) then
10933     FList := nil;
10934 
10935   inherited DestroyNotify(AWidget);
10936 end;
10937 
10938 procedure TQtComboBox.InternalIntfGetItems;
10939 begin
10940   TCustomComboBox(LCLObject).IntfGetItems;
10941   // because of issue #25032 we must call it here
10942   if getEnabled then
10943     SlotDropListVisibility(True);
10944 end;
10945 
10946 procedure TQtComboBox.ClearItems;
10947 begin
10948   QComboBox_clear(QComboBoxH(Widget));
10949 end;
10950 
10951 {------------------------------------------------------------------------------
10952   Function: TQtComboBox.currentIndex
10953   Params:  None
10954   Returns: Nothing
10955  ------------------------------------------------------------------------------}
TQtComboBox.currentIndexnull10956 function TQtComboBox.currentIndex: Integer;
10957 begin
10958   Result := QComboBox_currentIndex(QComboBoxH(Widget));
10959 end;
10960 
findTextnull10961 function TQtComboBox.findText(AText: WideString): Integer;
10962 begin
10963   Result := QComboBox_findText(QComboBoxH(Widget), @AText);
10964 end;
10965 
TQtComboBox.getDroppedDownnull10966 function TQtComboBox.getDroppedDown: Boolean;
10967 begin
10968   Result := QWidget_isVisible(QComboBox_view(QComboBoxH(Widget)));
10969 end;
10970 
TQtComboBox.getEditablenull10971 function TQtComboBox.getEditable: Boolean;
10972 begin
10973   Result := QComboBox_isEditable(QComboBoxH(Widget));
10974 end;
10975 
TQtComboBox.getItemTextnull10976 function TQtComboBox.getItemText(AIndex: Integer): WideString;
10977 begin
10978   Result := '';
10979   QComboBox_itemText(QComboBoxH(Widget), @Result, AIndex);
10980 end;
10981 
TQtComboBox.getMaxVisibleItemsnull10982 function TQtComboBox.getMaxVisibleItems: Integer;
10983 begin
10984   Result := QComboBox_maxVisibleItems(QComboboxH(Widget));
10985 end;
10986 
getTextnull10987 function TQtComboBox.getText: WideString;
10988 begin
10989   Result := '';
10990   QComboBox_currentText(QComboBoxH(Widget), @Result);
10991   if FOwnerDrawn and (FLineEdit = nil) and (Result = '') and (Result <> FText) then
10992     Result := FText;
10993 end;
10994 
TQtComboBox.getTextStaticnull10995 function TQtComboBox.getTextStatic: Boolean;
10996 begin
10997   Result := False;
10998 end;
10999 
11000 procedure TQtComboBox.insertItem(AIndex: Integer; AText: String);
11001 var
11002   Str: WideString;
11003 begin
11004   Str := {%H-}AText;
11005   insertItem(AIndex, @Str);
11006 end;
11007 
11008 procedure TQtComboBox.insertItem(AIndex: Integer; AText: PWideString);
11009 begin
11010   QComboBox_insertItem(QComboBoxH(WIdget), AIndex, AText, QVariant_create());
11011 end;
11012 
11013 {------------------------------------------------------------------------------
11014   Function: TQtComboBox.Destroy
11015   Params:  None
11016   Returns: Nothing
11017  ------------------------------------------------------------------------------}
11018 procedure TQtComboBox.setCurrentIndex(index: Integer);
11019 begin
11020   // don't fire any events when we are changing it from the LCL side
11021   BeginUpdate;
11022   QComboBox_setCurrentIndex(QComboBoxH(Widget), index);
11023   EndUpdate;
11024 end;
11025 
11026 procedure TQtComboBox.setDefaultColorRoles;
11027 begin
11028   WidgetColorRole := QPaletteBase;
11029   TextColorRole := QPaletteText;
11030 end;
11031 
11032 procedure TQtComboBox.setDroppedDown(const ADroppedDown: Boolean);
11033 begin
11034   if ADroppedDown <> QWidget_isVisible(QComboBox_view(QComboBoxH(Widget))) then
11035   begin
11036     if ADroppedDown then
11037     begin
11038       InternalIntfGetItems;
11039       QComboBox_showPopup(QComboBoxH(Widget));
11040     end else
11041       QComboBox_hidePopup(QComboBoxH(Widget));
11042   end;
11043 end;
11044 
11045 procedure TQtComboBox.setMaxVisibleItems(ACount: Integer);
11046 begin
11047   QComboBox_setMaxVisibleItems(QComboboxH(Widget), ACount);
11048 end;
11049 
11050 procedure TQtComboBox.setEditable(const AValue: Boolean);
11051 begin
11052   QComboBox_setEditable(QComboBoxH(Widget), AValue);
11053   if not AValue then
11054     FreeAndNil(FLineEdit)
11055   else
11056   begin
11057     LineEdit.setFocusPolicy(getFocusPolicy);
11058     setText(FText);
11059   end;
11060 end;
11061 
11062 procedure TQtComboBox.setItemText(AIndex: Integer; AText: String);
11063 var
11064   Str: WideString;
11065   item: QListWidgetItemH;
11066   R: TRect;
11067 begin
11068   if (AIndex >= 0) and (AIndex < QComboBox_count(QComboBoxH(Widget))) then
11069   begin
11070     Str := {%H-}AText;
11071     QComboBox_setItemText(QComboBoxH(Widget), AIndex, @Str);
11072     {we must update our custom delegate}
11073     if (FDropList <> nil) and
11074        (FDropList.getVisible) and
11075        (FDropList.OwnerDrawn) then
11076     begin
11077       Item := FDropList.getItem(AIndex);
11078       if Item <> nil then
11079       begin
11080         R := FDropList.getVisualItemRect(Item);
11081         FDropList.Update(@R);
11082       end;
11083     end;
11084   end else
11085     insertItem(AIndex, AText);
11086 end;
11087 
11088 procedure TQtComboBox.setText(const W: WideString);
11089 begin
11090   if FLineEdit = nil then
11091     FText := W
11092   else
11093     QComboBox_setEditText(QComboBoxH(Widget), @W);
11094 end;
11095 
11096 procedure TQtComboBox.removeItem(AIndex: Integer);
11097 begin
11098   QComboBox_removeItem(QComboBoxH(Widget), AIndex);
11099 end;
11100 
11101 procedure TQtComboBox.AttachEvents;
11102 begin
11103   inherited AttachEvents;
11104 
11105   FActivateHook := QComboBox_hook_create(Widget);
11106   FChangeHook := QComboBox_hook_create(Widget);
11107   FSelectHook := QComboBox_hook_create(Widget);
11108 
11109   // OnChange event if itemindex changed by mouse or kbd
11110   QComboBox_hook_hook_activated(FActivateHook, @SlotActivate);
11111 
11112   // OnChange event -> fires only when text changed
11113   QComboBox_hook_hook_editTextChanged(FChangeHook, @SlotChange);
11114   // OnSelect event
11115   QComboBox_hook_hook_currentIndexChanged(FSelectHook, @SlotSelect);
11116 
11117   // DropList events
11118   FDropListEventHook := QObject_hook_create(DropList.Widget);
11119   QObject_hook_hook_events(FDropListEventHook, @EventFilter);
11120 end;
11121 
11122 procedure TQtComboBox.DetachEvents;
11123 begin
11124   if FDropListEventHook <> nil then
11125   begin
11126     QObject_hook_destroy(FDropListEventHook);
11127     FDropListEventHook := nil;
11128   end;
11129   if FActivateHook <> nil then
11130   begin
11131     QComboBox_hook_destroy(FActivateHook);
11132     FActivateHook := nil;
11133   end;
11134   if FChangeHook <> nil then
11135   begin
11136     QComboBox_hook_destroy(FChangeHook);
11137     FChangeHook := nil;
11138   end;
11139   if FSelectHook <> nil then
11140   begin
11141     QComboBox_hook_destroy(FSelectHook);
11142     FSelectHook := nil;
11143   end;
11144 
11145   inherited DetachEvents;
11146 end;
11147 
11148 procedure TQtComboBox.slotPaintCombo(Sender: QObjectH; Event: QEventH); cdecl;
11149 var
11150   Msg: TLMPaint;
11151   AStruct: PPaintStruct;
11152   MsgItem: TLMDrawListItem;
11153   DrawStruct: TDrawListItemStruct;
11154   P: TPoint;
11155   Opt: QStyleOptionComboBoxH;
11156   R: TRect;
11157   State: QStyleState;
11158   CurrIndex: Integer;
11159 begin
11160   {$ifdef VerboseQt}
11161     WriteLn('TQtComboBox.SlotPaintCombo ', dbgsName(LCLObject));
11162   {$endif}
11163   CurrIndex := currentIndex;
11164   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11165 
11166   Msg.Msg := LM_PAINT;
11167   New(AStruct);
11168   FillChar(AStruct^, SizeOf(TPaintStruct), 0);
11169   Msg.PaintStruct := AStruct;
11170 
11171   with PaintData do
11172   begin
11173     PaintWidget := Widget;
11174     ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
11175     if ClipRect = nil then
11176       New(ClipRect);
11177     QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
11178   end;
11179 
11180   Msg.DC := BeginPaint(THandle(Self), AStruct^);
11181   FContext := Msg.DC;
11182 
11183   Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
11184   Msg.PaintStruct^.hdc := FContext;
11185 
11186   P := getClientOffset;
11187   inc(P.X, FScrollX);
11188   inc(P.Y, FScrollY);
11189   TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
11190 
11191   TQtDeviceContext(Msg.DC).save;
11192   try
11193     Opt := QStyleOptionComboBox_create();
11194     QStyleOption_initFrom(Opt, Widget);
11195     State := QStyleOption_state(opt);
11196     QStyleOption_rect(Opt, @R);
11197     QPainter_setClipRect(TQtDeviceContext(Msg.DC).Widget, @R);
11198 
11199     QStyle_drawComplexControl(QApplication_style(), QStyleCC_ComboBox, Opt,
11200       TQtDeviceContext(Msg.DC).Widget, Widget);
11201     QStyle_subControlRect(QApplication_style(), @R, QStyleCC_ComboBox, Opt,
11202       QStyleSC_ComboBoxEditField , Widget);
11203     if CurrIndex < 0 then
11204     begin
11205       QStyleOptionComboBox_setCurrentText(Opt, @FText);
11206       QStyle_drawControl(QApplication_style(), QStyleCE_ComboBoxLabel, opt,
11207         TQtDeviceContext(Msg.DC).Widget, Widget);
11208     end;
11209 
11210   finally
11211     QStyleOptionComboBox_destroy(Opt);
11212     TQtDeviceContext(Msg.DC).restore;
11213   end;
11214 
11215   inc(R.Top);
11216   dec(R.Bottom);
11217   QPainter_setClipRect(TQTDeviceContext(Msg.DC).Widget, @R);
11218 
11219   DrawStruct.ItemID := UINT(CurrIndex);
11220   DrawStruct.Area := R;
11221   DrawStruct.DC := Msg.DC;
11222 
11223   DrawStruct.ItemState := [];
11224 
11225   // selected
11226   if (State and QStyleState_Selected) <> 0 then
11227     Include(DrawStruct.ItemState, odSelected);
11228   // disabled
11229   if (State and QStyleState_Enabled) = 0 then
11230     Include(DrawStruct.ItemState, odDisabled);
11231   // focused (QStyleState_FocusAtBorder?)
11232   if ((State and QStyleState_HasFocus) <> 0) or
11233     ((State and QStyleState_FocusAtBorder) <> 0) then
11234     Include(DrawStruct.ItemState, odFocused);
11235   // hotlight
11236   if (State and QStyleState_MouseOver) <> 0 then
11237     Include(DrawStruct.ItemState, odHotLight);
11238 
11239   MsgItem.Msg := LM_DRAWLISTITEM;
11240   MsgItem.DrawListItemStruct := @DrawStruct;
11241 
11242   try
11243     if CurrIndex >= 0 then
11244       DeliverMessage(MsgItem);
11245   finally
11246     Dispose(PaintData.ClipRect);
11247     Fillchar(FPaintData, SizeOf(FPaintData), 0);
11248     FContext := 0;
11249     EndPaint(THandle(Self), AStruct^);
11250     Dispose(AStruct);
11251   end;
11252 end;
11253 
11254 {this routine is called ONLY from dropdown list viewport event filter
11255  when QEventShow occurs.It sends MouseRelease event to LCL !
11256  Should not be used in any other case.}
11257 procedure TQtComboBox.FixMouseUp;
11258 var
11259   MouseEvent: QMouseEventH;
11260 begin
11261   if (FMouseFixPos.x = -1) and (FMouseFixPos.y = -1) then
11262     exit;
11263   if QApplication_mouseButtons = QtLeftButton then
11264   begin
11265     MouseEvent := QMouseEvent_create(QEventMouseButtonRelease, @FMouseFixPos, QtLeftButton,
11266       QtLeftButton, QApplication_keyboardModifiers());
11267     QCoreApplication_postEvent(Widget, MouseEvent);
11268   end;
11269 end;
11270 
EventFilternull11271 function TQtComboBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
11272 var
11273   R, R1: TRect;
11274   ButtonRect: TRect;
11275   P: TQtPoint;
11276   Pt: TPoint;
11277   Opt: QStyleOptionComboBoxH;
11278 begin
11279 
11280   Result := False;
11281   QEvent_accept(Event);
11282 
11283   if LCLObject = nil then
11284     exit;
11285 
11286   if (FDropList <> nil) and (Sender = FDropList.Widget) then
11287   begin
11288     if (Byte(QEvent_type(Event)) in [QEventKeyPress, QEventKeyRelease,QEventFontChange]) then
11289     begin
11290       Result := inherited EventFilter(Sender, Event);
11291       if Result and (QEvent_type(Event) = QEventKeyPress) then
11292         FKeyEnterFix := True; {issue #31574}
11293     end;
11294     QEvent_ignore(Event);
11295     exit;
11296   end;
11297 
11298   BeginEventProcessing;
11299   try
11300 
11301     if FKeyEnterFix and (Byte(QEvent_type(Event)) in [QEventMouseButtonPress, QEventMouseButtonDblClick,
11302       QEventMouseButtonRelease, QEventKeyPress, QEventHide, QEventShow]) then
11303         FKeyEnterFix := False; {issue #31574}
11304 
11305     case QEvent_type(Event) of
11306       QEventFocusOut:
11307       begin
11308         if Assigned(FLineEdit) and FLineEdit.getVisible then
11309         begin
11310           FLineEdit.CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(FLineEdit.Widget));
11311           FLineEdit.CachedSelectionLen := UTF16Length(FLineEdit.getSelectedText);
11312         end;
11313         Result := inherited EventFilter(Sender, Event);
11314       end;
11315       QEventFocusIn:
11316       begin
11317         if Assigned(FLineEdit) and FLineEdit.getVisible then
11318         begin
11319           FLineEdit.CachedSelectionStart := -1;
11320           FLineEdit.CachedSelectionLen := -1;
11321         end;
11322         Result := inherited EventFilter(Sender, Event);
11323       end;
11324       QEventHide:
11325       begin
11326         if getVisible then
11327           SlotShow(False);
11328       end;
11329       QEventPaint:
11330       begin
11331         if FOwnerDrawn and not getEditable then
11332         begin
11333           SlotPaintCombo(Widget, Event);
11334           Result := True;
11335           QEvent_accept(Event);
11336         end;
11337       end;
11338       QEventMouseButtonRelease:
11339       begin
11340         FMouseFixPos := QtPoint(-1, -1);
11341         Result := inherited EventFilter(Sender, Event);
11342       end;
11343       QEventMouseButtonPress:
11344       begin
11345         if not FDropListVisibleInternal and
11346           (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
11347         begin
11348           // some themes have empty space around combo button !
11349 
11350           P := QMouseEvent_pos(QMouseEventH(Event))^;
11351           FMouseFixPos := P;
11352 
11353           // our combo geometry
11354           R := getGeometry;
11355 
11356           Pt := Point(P.X, P.Y);
11357 
11358           // our combo arrow position when we are editable combobox
11359           if getEditable then
11360           begin
11361             opt := QStyleOptionComboBox_create();
11362             QStyle_subControlRect(QApplication_style(), @R1, QStyleCC_ComboBox,
11363               opt, QStyleSC_ComboBoxArrow, QComboBoxH(Widget));
11364             QStyleOptionComboBox_destroy(opt);
11365             R := Rect(0, 0, R.Right - R.Left, R.Bottom - R.Top);
11366             ButtonRect := Rect(R.Right + R1.Left, R.Top,
11367               R.Right - R1.Right, R.Bottom);
11368           end else
11369           begin
11370             ButtonRect := R;
11371             OffsetRect(ButtonRect, -R.Left, -R.Top);
11372           end;
11373 
11374           if PtInRect(ButtonRect, Pt) then
11375             InternalIntfGetItems;
11376         end;
11377         Result := inherited EventFilter(Sender, Event);
11378       end;
11379 
11380       QEventMouseButtonDblClick:
11381       begin
11382         // avoid crash on unfocused combobox raised from
11383         // eg. TStringGrid as picklist.
11384         // crash happens when combo is hidden in cell, and then we
11385         // dbl click on position of combo button. Control raises combo
11386         // and propagate dbl click to combobox which must grab focus in
11387         // that case.
11388         if CanSendLCLMessage and getEnabled and not hasFocus then
11389           setFocus;
11390         Result := inherited EventFilter(Sender, Event);
11391       end;
11392 
11393       QEventKeyPress:
11394       begin
11395         if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_F4) or
11396           ((QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
11397             not getEditable) then
11398         begin
11399           if not FDropListVisibleInternal then
11400             InternalIntfGetItems
11401           else
11402             Result := inherited EventFilter(Sender, Event);
11403         end else
11404           Result := inherited EventFilter(Sender, Event);
11405       end;
11406       QEventKeyRelease:
11407       begin
11408         {issue #31574}
11409         if not FKeyEnterFix then
11410           Result := inherited EventFilter(Sender, Event);
11411         FKeyEnterFix := False;
11412       end;
11413       else
11414         Result := inherited EventFilter(Sender, Event);
11415     end;
11416   finally
11417     EndEventProcessing;
11418   end;
11419 end;
11420 
11421 procedure TQtComboBox.preferredSize(var PreferredWidth,
11422   PreferredHeight: integer; WithThemeSpace: Boolean);
11423 var
11424   Size: TSize;
11425 begin
11426   QComboBox_sizeHint(QComboBoxH(Widget), @Size);
11427   PreferredWidth := Size.cx;
11428   PreferredHeight := Size.cy;
11429 end;
11430 
11431 procedure TQtComboBox.SlotActivate(index: Integer); cdecl;
11432 var
11433   Msg: TLMessage;
11434 begin
11435   if InUpdate then
11436     Exit;
11437 
11438   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11439   Msg.Msg := LM_ACTIVATE;
11440   DeliverMessage(Msg);
11441 end;
11442 
11443 procedure TQtComboBox.SlotChange(p1: PWideString); cdecl;
11444 var
11445   Msg: TLMessage;
11446 begin
11447   if InUpdate then
11448     Exit;
11449 
11450   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11451 
11452   Msg.Msg := LM_CHANGED;
11453 
11454   DeliverMessage(Msg);
11455 end;
11456 
11457 procedure TQtComboBox.SlotSelect(index: Integer); cdecl;
11458 var
11459   Msg: TLMessage;
11460 begin
11461   if InUpdate then
11462     exit;
11463 
11464   {we must fire OnChange() if it isn''t editable
11465    since SlotChange() fires only for editable
11466    comboboxes }
11467   if not getEditable then
11468   begin
11469     FillChar(Msg{%H-}, SizeOf(Msg), #0);
11470     Msg.Msg := LM_CHANGED;
11471     DeliverMessage(Msg);
11472   end;
11473 
11474   FillChar(Msg, SizeOf(Msg), #0);
11475 
11476   Msg.Msg := LM_SELCHANGE;
11477 
11478   DeliverMessage(Msg);
11479 end;
11480 
11481 procedure TQtComboBox.SlotDropListVisibility(AVisible: Boolean); cdecl;
11482 const
11483   VisibilityToCodeMap: array[Boolean] of Word =
11484   (
11485     CBN_CLOSEUP,
11486     CBN_DROPDOWN
11487   );
11488 var
11489   Msg : TLMCommand;
11490 begin
11491   if InUpdate then
11492     Exit;
11493 
11494   FillChar(Msg{%H-}, SizeOf(Msg), 0);
11495   Msg.Msg := CN_COMMAND;
11496   Msg.NotifyCode := VisibilityToCodeMap[AVisible];
11497 
11498   DeliverMessage(Msg);
11499   FDropListVisibleInternal := AVisible;
11500 end;
11501 
11502 { TQtAbstractSpinBox }
11503 
GetLineEditnull11504 function TQtAbstractSpinBox.GetLineEdit: QLineEditH;
11505 begin
11506   if FLineEdit = nil then
11507     FLineEdit := QLCLAbstractSpinBox_lineEditHandle(QAbstractSpinBoxH(Widget));
11508   if Assigned(FLineEdit) and not Assigned(FLineEditHook) then
11509   begin
11510     FLineEditHook := QObject_hook_create(FLineEdit);
11511     QObject_hook_hook_events(FLineEditHook, @LineEditEventFilter);
11512     FTextChangedHook := QLineEdit_hook_create(FLineEdit);
11513     QLineEdit_hook_hook_textChanged(FTextChangedHook, @SignalLineEditTextChanged);
11514   end;
11515   Result := FLineEdit;
11516 end;
11517 
LineEditEventFilternull11518 function TQtAbstractSpinBox.LineEditEventFilter(Sender: QObjectH; Event: QEventH
11519   ): Boolean; cdecl;
11520 begin
11521   Result := False;
11522   QEvent_accept(Event);
11523   if QEvent_type(Event) = QEventFontChange then
11524     Result := EventFilter(QWidgetH(Sender), Event);
11525 end;
11526 
11527 procedure TQtAbstractSpinBox.SignalLineEditTextChanged(AnonParam1: PWideString); cdecl;
11528 var
11529   Msg: TLMessage;
11530 begin
11531   if FTextChangedByValueChanged then
11532   begin
11533     FTextChangedByValueChanged := False;
11534     Exit;
11535   end;
11536   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11537   Msg.Msg := CM_TEXTCHANGED;
11538   if not InUpdate then
11539     DeliverMessage(Msg);
11540 end;
11541 
CreateWidgetnull11542 function TQtAbstractSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
11543 var
11544   Parent: QWidgetH;
11545 begin
11546   // Creates the widget
11547   {$ifdef VerboseQt}
11548     WriteLn('TQtAbstractSpinBox.Create');
11549   {$endif}
11550   FLineEditHook := nil;
11551   if AParams.WndParent <> 0 then
11552     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
11553   else
11554     Parent := nil;
11555   FTextChangedByValueChanged := False;
11556   Result := QAbstractSpinBox_create(Parent);
11557 end;
11558 
getMaxLengthnull11559 function TQtAbstractSpinBox.getMaxLength: Integer;
11560 begin
11561   if LineEdit <> nil then
11562     Result := QLineEdit_maxLength(LineEdit)
11563   else
11564     Result := 0;
11565 end;
11566 
getSelectionStartnull11567 function TQtAbstractSpinBox.getSelectionStart: Integer;
11568 begin
11569   if (LineEdit <> nil) then
11570   begin
11571     if QLineEdit_hasSelectedText(LineEdit) then
11572       Result := QLineEdit_selectionStart(LineEdit)
11573     else
11574       Result := QLineEdit_cursorPosition(LineEdit);
11575   end
11576   else
11577     Result := 0;
11578 end;
11579 
getSelectionLengthnull11580 function TQtAbstractSpinBox.getSelectionLength: Integer;
11581 var
11582   W: WideString;
11583 begin
11584   if (LineEdit <> nil) and QLineEdit_hasSelectedText(LineEdit) then
11585   begin
11586     QLineEdit_selectedText(LineEdit, @W);
11587     Result := UTF16Length(W);
11588   end
11589   else
11590     Result := 0;
11591 end;
11592 
isUndoAvailablenull11593 function TQtAbstractSpinBox.isUndoAvailable: Boolean;
11594 begin
11595   if LineEdit <> nil then
11596     Result := QLineEdit_isUndoAvailable(LineEdit)
11597   else
11598     Result := False;
11599 end;
11600 
11601 procedure TQtAbstractSpinBox.setBorder(const ABorder: Boolean);
11602 begin
11603   QAbstractSpinBox_setFrame(QAbstractSpinBoxH(Widget), ABorder);
11604 end;
11605 
11606 procedure TQtAbstractSpinBox.setCursorPosition(const ACursorPosition: Integer);
11607 begin
11608   if LineEdit <> nil then
11609     QLineEdit_setCursorPosition(LineEdit, ACursorPosition);
11610 end;
11611 
11612 procedure TQtAbstractSpinBox.setDefaultColorRoles;
11613 begin
11614   WidgetColorRole := QPaletteBase;
11615   TextColorRole := QPaletteText;
11616 end;
11617 
11618 procedure TQtAbstractSpinBox.setEchoMode(const AMode: QLineEditEchoMode);
11619 begin
11620   if LineEdit <> nil then
11621     QLineEdit_setEchoMode(LineEdit, AMode);
11622 end;
11623 
11624 procedure TQtAbstractSpinBox.setMaxLength(const ALength: Integer);
11625 begin
11626   if LineEdit <> nil then
11627     QLineEdit_setMaxLength(LineEdit, ALength);
11628 end;
11629 
11630 procedure TQtAbstractSpinBox.setSelection(const AStart, ALength: Integer);
11631 begin
11632   if (LineEdit <> nil) and (AStart >= 0) then
11633   begin
11634     if ALength > 0 then
11635       QLineEdit_setSelection(LineEdit, AStart, ALength)
11636     else
11637       QLineEdit_setCursorPosition(LineEdit, AStart);
11638   end;
11639 end;
11640 
11641 procedure TQtAbstractSpinBox.Cut;
11642 begin
11643   if LineEdit <> nil then
11644     QLineEdit_cut(LineEdit);
11645 end;
11646 
11647 procedure TQtAbstractSpinBox.Copy;
11648 begin
11649   if LineEdit <> nil then
11650     QLineEdit_copy(LineEdit);
11651 end;
11652 
11653 procedure TQtAbstractSpinBox.Paste;
11654 begin
11655   if LineEdit <> nil then
11656     QLineEdit_paste(LineEdit);
11657 end;
11658 
11659 procedure TQtAbstractSpinBox.Undo;
11660 begin
11661   if LineEdit <> nil then
11662     QLineEdit_undo(LineEdit);
11663 end;
11664 
getCursorPositionnull11665 function TQtAbstractSpinBox.getCursorPosition: TPoint;
11666 begin
11667   Result := Point(0, 0);
11668   if LineEdit <> nil then
11669     Result.X := QLineEdit_cursorPosition(LineEdit);
11670 end;
11671 
getReadOnlynull11672 function TQtAbstractSpinBox.getReadOnly: Boolean;
11673 begin
11674   {$ifdef VerboseQt}
11675     WriteLn('TQtAbstractSpinBox.IsReadOnly');
11676   {$endif}
11677   Result := QAbstractSpinBox_isReadOnly(QAbstractSpinBoxH(Widget));
11678 end;
11679 
getTextnull11680 function TQtAbstractSpinBox.getText: WideString;
11681 begin
11682   if LineEdit <> nil then
11683     QLineEdit_text(LineEdit, @Result)
11684   else
11685     Result := '';
11686   {$ifdef VerboseQt}
11687   WriteLn('TQtAbstractSpinBox.GetText Result=',Result);
11688   {$endif}
11689 end;
11690 
getTextStaticnull11691 function TQtAbstractSpinBox.getTextStatic: Boolean;
11692 begin
11693   Result := False;
11694 end;
11695 
11696 procedure TQtAbstractSpinBox.setAlignment(const AAlignment: QtAlignment);
11697 begin
11698   QAbstractSpinBox_setAlignment(QSpinBoxH(Widget), AAlignment);
11699 end;
11700 
11701 procedure TQtAbstractSpinBox.setFocusPolicy(const APolicy: QtFocusPolicy);
11702 begin
11703   inherited setFocusPolicy(APolicy);
11704   QWidget_setFocusPolicy(LineEdit, APolicy);
11705 end;
11706 
11707 procedure TQtAbstractSpinBox.setReadOnly(const r: Boolean);
11708 begin
11709   QAbstractSpinBox_setReadOnly(QAbstractSpinBoxH(Widget), r);
11710 end;
11711 
11712 procedure TQtAbstractSpinBox.setText(const W: WideString);
11713 begin
11714   {$ifdef VerboseQt}
11715   WriteLn('TQtAbstractSpinBox.SetText W=',w);
11716   {$endif}
11717   if (LineEdit <> nil) then
11718     QLineEdit_setText(LineEdit, @W)
11719 end;
11720 
11721 procedure TQtAbstractSpinBox.AttachEvents;
11722 begin
11723   inherited AttachEvents;
11724 
11725   FEditingFinishedHook := QAbstractSpinBox_hook_create(Widget);
11726   {TODO: find out which TLMessage should be sended }
11727   QAbstractSpinBox_hook_hook_editingFinished(FEditingFinishedHook, @SignalEditingFinished);
11728 end;
11729 
11730 procedure TQtAbstractSpinBox.DetachEvents;
11731 begin
11732   if FEditingFinishedHook <> nil then
11733   begin
11734     QAbstractSpinBox_hook_destroy(FEditingFinishedHook);
11735     FEditingFinishedHook := nil;
11736   end;
11737 
11738   if FLineEditHook <> nil then
11739   begin
11740     QObject_hook_destroy(FLineEditHook);
11741     FLineEditHook := nil;
11742   end;
11743 
11744   if FTextChangedHook <> nil then
11745   begin
11746     QLineEdit_hook_destroy(FTextChangedHook);
11747     FTextChangedHook := nil;
11748   end;
11749 
11750   inherited DetachEvents;
11751 end;
11752 
EventFilternull11753 function TQtAbstractSpinBox.EventFilter(Sender: QObjectH; Event: QEventH
11754   ): Boolean; cdecl;
11755 var
11756   IsDeleteKey: Boolean;
11757 begin
11758   if (QEvent_type(Event) = QEventKeyPress) or
11759      (QEvent_type(Event) = QEventKeyRelease) then
11760     IsDeleteKey := (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Delete) and
11761       (QKeyEvent_modifiers(QKeyEventH(Event)) = QtNoModifier)
11762   else
11763     IsDeleteKey := False;
11764   Result := inherited EventFilter(Sender, Event);
11765   {we must pass delete key to qt, qabstractspinbox doesn't like what we do}
11766   if IsDeleteKey then
11767     Result := False;
11768   {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
11769   if (FParentShowPassed = 1) then
11770   begin
11771     if QEvent_type(Event) <> QEventPaint then
11772     begin
11773       inc(FParentShowPassed);
11774       BeginUpdate;
11775       setValue(getValue);
11776       EndUpdate;
11777     end;
11778   end;
11779 
11780   if (QEvent_type(Event) = QEventShowToParent) and
11781     (FParentShowPassed = 0) then
11782     inc(FParentShowPassed);
11783   {$ENDIF}
11784 
11785 end;
11786 
11787 procedure TQtAbstractSpinBox.SignalEditingFinished; cdecl;
11788 var
11789   Msg: TLMessage;
11790 begin
11791   {$ifdef VerboseQt}
11792     WriteLn('TQtAbstractSpinBox.SignalEditingFinished');
11793   {$endif}
11794   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11795   { TODO: Find out which message should be sended here
11796     problem:
11797      everything is fine when we work with mouse, or
11798      press TabKey to select next control, but if we
11799      connect OnKeyDown and say eg. VK_RETURN: SelectNext(ActiveControl, true, true)
11800      then spinedit text is always selected, nothing important but looks ugly.}
11801   //  Msg.Msg := LM_EXIT;
11802   //  DeliverMessage(Msg);
11803 end;
11804 
11805 { TQtFloatSpinBox }
11806 
TQtFloatSpinBox.CreateWidgetnull11807 function TQtFloatSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
11808 var
11809   Parent: QWidgetH;
11810 begin
11811   // Creates the widget
11812   {$ifdef VerboseQt}
11813     WriteLn('TQtFloatSpinBox.Create');
11814   {$endif}
11815   {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
11816   FParentShowPassed := 0;
11817   {$ENDIF}
11818   FValue := 0;
11819   FLineEditHook := nil;
11820   if AParams.WndParent <> 0 then
11821     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
11822   else
11823     Parent := nil;
11824   Result := QDoubleSpinBox_create(Parent);
11825 end;
11826 
getValuenull11827 function TQtFloatSpinBox.getValue: Double;
11828 begin
11829   Result := FValue;
11830 end;
11831 
11832 procedure TQtFloatSpinBox.setDecimals(const v: integer);
11833 begin
11834   QDoubleSpinBox_setDecimals(QDoubleSpinBoxH(Widget), v);
11835 end;
11836 
11837 procedure TQtFloatSpinBox.setMinimum(const v: Double);
11838 begin
11839   QDoubleSpinBox_setMinimum(QDoubleSpinBoxH(Widget), v);
11840 end;
11841 
11842 procedure TQtFloatSpinBox.setMaximum(const v: Double);
11843 begin
11844   QDoubleSpinBox_setMaximum(QDoubleSpinBoxH(Widget), v);
11845 end;
11846 
11847 procedure TQtFloatSpinBox.setSingleStep(const v: Double);
11848 begin
11849   QDoubleSpinBox_setSingleStep(QDoubleSpinBoxH(Widget), v);
11850 end;
11851 
11852 procedure TQtFloatSpinBox.setValue(const v: Double);
11853 begin
11854   FValue := v;
11855   QDoubleSpinBox_setValue(QDoubleSpinBoxH(Widget), FValue);
11856 end;
11857 
11858 procedure TQtFloatSpinBox.AttachEvents;
11859 begin
11860   inherited AttachEvents;
11861   FValueChangedHook := QDoubleSpinBox_hook_create(Widget);
11862   QDoubleSpinBox_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
11863 end;
11864 
11865 procedure TQtFloatSpinBox.DetachEvents;
11866 begin
11867   if FValueChangedHook <> nil then
11868   begin
11869     QDoubleSpinBox_hook_destroy(FValueChangedHook);
11870     FValueChangedHook := nil;
11871   end;
11872   inherited DetachEvents;
11873 end;
11874 
11875 procedure TQtFloatSpinBox.SignalValueChanged(p1: Double); cdecl;
11876 var
11877   Msg: TLMessage;
11878 begin
11879   FValue := p1;
11880   FTextChangedByValueChanged := True;
11881   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11882   Msg.Msg := CM_TEXTCHANGED;
11883   if not InUpdate then
11884     DeliverMessage(Msg);
11885 end;
11886 
11887 { TQtSpinBox }
11888 
CreateWidgetnull11889 function TQtSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
11890 var
11891   Parent: QWidgetH;
11892 begin
11893   // Creates the widget
11894   {$ifdef VerboseQt}
11895     WriteLn('TQtSpinBox.Create');
11896   {$endif}
11897   {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
11898   FParentShowPassed := 0;
11899   {$ENDIF}
11900   FLineEditHook := nil;
11901   if AParams.WndParent <> 0 then
11902     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
11903   else
11904     Parent := nil;
11905   Result := QSpinBox_create(Parent);
11906 end;
11907 
getValuenull11908 function TQtSpinBox.getValue: Double;
11909 begin
11910   Result := FValue;
11911 end;
11912 
11913 procedure TQtSpinBox.setMinimum(const v: Double);
11914 begin
11915   QSpinBox_setMinimum(QSpinBoxH(Widget), round(v));
11916 end;
11917 
11918 procedure TQtSpinBox.setMaximum(const v: Double);
11919 begin
11920   QSpinBox_setMaximum(QSpinBoxH(Widget), round(v));
11921 end;
11922 
11923 procedure TQtSpinBox.setSingleStep(const v: Double);
11924 begin
11925   QSpinBox_setSingleStep(QSpinBoxH(Widget), round(v));
11926 end;
11927 
11928 procedure TQtSpinBox.setValue(const v: Double);
11929 begin
11930   FValue := Round(v);
11931   QSpinBox_setValue(QSpinBoxH(Widget), round(v));
11932 end;
11933 
11934 procedure TQtSpinBox.AttachEvents;
11935 begin
11936   inherited AttachEvents;
11937   FValueChangedHook := QSpinBox_hook_create(Widget);
11938   QSpinBox_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
11939 end;
11940 
11941 procedure TQtSpinBox.DetachEvents;
11942 begin
11943   if FValueChangedHook <> nil then
11944   begin
11945     QSpinBox_hook_destroy(FValueChangedHook);
11946     FValueChangedHook := nil;
11947   end;
11948   inherited DetachEvents;
11949 end;
11950 
11951 procedure TQtSpinBox.SignalValueChanged(p1: Integer); cdecl;
11952 var
11953   Msg: TLMessage;
11954 begin
11955   FValue := p1;
11956   FTextChangedByValueChanged := True;
11957   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11958   Msg.Msg := CM_TEXTCHANGED;
11959   if not InUpdate then
11960    DeliverMessage(Msg);
11961 end;
11962 
11963 { TQtListView }
11964 
getBatchSizenull11965 function TQtListView.getBatchSize: integer;
11966 begin
11967   Result := QListView_batchSize(QListViewH(Widget));
11968 end;
11969 
getGridSizenull11970 function TQtListView.getGridSize: TSize;
11971 begin
11972   QListView_gridSize(QListViewH(Widget), @Result);
11973 end;
11974 
getSpacingnull11975 function TQtListView.getSpacing: Integer;
11976 begin
11977   Result := QListView_spacing(QListViewH(Widget));
11978 end;
11979 
11980 procedure TQtListView.setBatchSize(const AValue: integer);
11981 begin
11982   QListView_setBatchSize(QListViewH(Widget), AValue);
11983 end;
11984 
11985 procedure TQtListView.setGridSize(const AValue: TSize);
11986 begin
11987   QListView_setGridSize(QListViewH(Widget), @AValue);
11988 end;
11989 
11990 procedure TQtListView.setLayoutMode(const ALayoutMode: QListViewLayoutMode);
11991 begin
11992   QListView_setLayoutMode(QListViewH(Widget), ALayoutMode);
11993 end;
11994 
11995 procedure TQtListView.setMovement(const AMovement: QListViewMovement);
11996 begin
11997   QListView_setMovement(QListViewH(Widget), AMovement);
11998 end;
11999 
12000 procedure TQtListView.setResizeMode(const AResizeMode: QListViewResizeMode);
12001 begin
12002   QListView_setResizeMode(QListViewH(Widget), AResizeMode);
12003 end;
12004 
12005 procedure TQtListView.setSpacing(const AValue: integer);
12006 begin
12007   QListView_setSpacing(QListViewH(Widget), AValue);
12008 end;
12009 
12010 procedure TQtListView.setUniformItemSizes(const AEnable: Boolean);
12011 begin
12012   QListView_setUniformItemSizes(QListViewH(Widget), AEnable);
12013 end;
12014 
12015 procedure TQtListView.setViewFlow(const AFlow: QListViewFlow);
12016 begin
12017   QListView_setFlow(QListViewH(Widget), AFlow);
12018 end;
12019 
12020 procedure TQtListView.setViewMode(const AMode: QListViewViewMode);
12021 begin
12022   QListView_setViewMode(QListViewH(Widget), AMode);
12023 end;
12024 
12025 procedure TQtListView.setWordWrap(const AValue: Boolean);
12026 begin
12027   QListView_setWordWrap(QListViewH(Widget), AValue);
12028 end;
12029 
12030 procedure TQtListView.setWrapping(const AWrapping: Boolean);
12031 begin
12032   QListView_setWrapping(QListViewH(Widget), AWrapping);
12033 end;
12034 
12035 procedure TQtListView.LayoutItems;
12036 begin
12037   QListView_doItemsLayout(QListViewH(Widget));
12038 end;
12039 
12040 { TQtListWidget }
12041 
TQtListWidget.getItemCountnull12042 function TQtListWidget.getItemCount: Integer;
12043 begin
12044   Result := QListWidget_count(QListWidgetH(Widget));
12045 end;
12046 
TQtListWidget.GetItemCheckednull12047 function TQtListWidget.GetItemChecked(AIndex: Integer): Boolean;
12048 var
12049   AItem: QListWidgetItemH;
12050 begin
12051   Result := False;
12052   AItem := getItem(AIndex);
12053   if Assigned(AItem) then
12054     Result := QListWidgetItem_checkState(AItem) = QtChecked;
12055 end;
12056 
GetItemEnablednull12057 function TQtListWidget.GetItemEnabled(AIndex: Integer): Boolean;
12058 var
12059   AItem: QListWidgetItemH;
12060 begin
12061   Result := False;
12062   AItem := getItem(AIndex);
12063   if Assigned(AItem) then
12064     Result := QListWidgetItem_flags(AItem) and QtItemIsEnabled <> 0;
12065 end;
12066 
TQtListWidget.GetSelectednull12067 function TQtListWidget.GetSelected(AIndex: Integer): Boolean;
12068 var
12069   AItem: QListWidgetItemH;
12070 begin
12071   Result := False;
12072   AItem := getItem(AIndex);
12073   if Assigned(AItem) then
12074     Result := getItemSelected(AItem);
12075 end;
12076 
12077 procedure TQtListWidget.SetItemChecked(AIndex: Integer; AValue: Boolean);
12078 var
12079   AItem: QListWidgetItemH;
12080 begin
12081   AItem := getItem(AIndex);
12082   if Assigned(AItem) then
12083   begin
12084     if AValue then
12085       QListWidgetItem_setCheckState(AItem, QtChecked)
12086     else
12087       QListWidgetItem_setCheckState(AItem, QtUnChecked);
12088     SetItemLastCheckState(AItem);
12089   end;
12090 end;
12091 
12092 procedure TQtListWidget.setItemCount(const AValue: Integer);
12093 var
12094   i: Integer;
12095   AList: QStringListH;
12096   WStr: WideString;
12097 begin
12098   if AValue = ItemCount then
12099     exit;
12100   BeginUpdate;
12101   try
12102     ClearItems;
12103     AList := QStringList_create();
12104     WStr := '';
12105     for i := 1 to AValue do
12106       QStringList_append(AList, @WStr);
12107     QListWidget_addItems(QListWidgetH(Widget), AList);
12108     QStringList_destroy(AList);
12109   finally
12110     EndUpdate;
12111   end;
12112 end;
12113 
12114 procedure TQtListWidget.SetItemEnabled(AIndex: Integer; AValue: Boolean);
12115 var
12116   AItem: QListWidgetItemH;
12117   Flags: QtItemFlags;
12118 begin
12119   AItem := getItem(AIndex);
12120   if Assigned(AItem) then
12121   begin
12122     Flags := QListWidgetItem_flags(AItem);
12123     if AValue then
12124       Flags := Flags or QtItemIsEnabled
12125     else
12126       Flags := Flags and not QtItemIsEnabled;
12127     QListWidgetItem_setFlags(AItem, Flags);
12128   end;
12129 end;
12130 
12131 procedure TQtListWidget.SetSelected(AIndex: Integer; AValue: Boolean);
12132 begin
12133   if (AIndex >= 0) and (AIndex < RowCount) then
12134     setItemSelected(getItem(AIndex), AValue);
12135 end;
12136 
GetItemLastCheckStatenull12137 function TQtListWidget.GetItemLastCheckState(AItem: QListWidgetItemH
12138   ): QtCheckState;
12139 var
12140   v: QVariantH;
12141   ok: Boolean;
12142 begin
12143   Result := QtUnChecked;
12144   if AItem = nil then
12145     exit;
12146   v := QVariant_create();
12147   QListWidgetItem_data(AItem, v,  QtCheckStateRole);
12148   ok := False;
12149   if QVariant_isValid(v) then
12150     Result := QtCheckState(QVariant_toInt(v, @Ok));
12151   QVariant_destroy(v);
12152 end;
12153 
12154 procedure TQtListWidget.SetItemLastCheckState(AItem: QListWidgetItemH);
12155 var
12156   AState: QtCheckState;
12157 begin
12158   if AItem = nil then
12159     exit;
12160   AState := QListWidgetItem_checkState(AItem);
12161   SetItemLastCheckStateInternal(AItem, AState);
12162 end;
12163 
12164 procedure TQtListWidget.SetItemLastCheckStateInternal(AItem: QListWidgetItemH;
12165   AState: QtCheckState);
12166 var
12167   v: QVariantH;
12168 begin
12169   v := QVariant_create(Ord(AState));
12170   QListWidgetItem_setData(AItem, QtCheckStateRole, v);
12171   QVariant_destroy(v);
12172 end;
12173 
12174 procedure TQtListWidget.SetNextStateMap(AItem: QListWidgetItemH);
12175 begin
12176   // does the job only for TQtCheckListBox
12177 end;
12178 
TQtListWidget.CreateWidgetnull12179 function TQtListWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
12180 var
12181   Parent: QWidgetH;
12182 begin
12183   FCheckBoxClicked := False;
12184   FDelayedCheckItem := nil;
12185   SetLength(FSavedSelection, 0);
12186   AllowGrayed := False;
12187   FSavedEvent := nil;
12188   FSavedEventTimer := nil;
12189   FSavedEventTimerHook := nil;
12190 
12191   FViewStyle := -1;
12192   FSyncingItems := False;
12193   FCheckable := False;
12194   FDontPassSelChange := False;
12195   FOwnerData := False;
12196   if AParams.WndParent <> 0 then
12197     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
12198   else
12199     Parent := nil;
12200   Result := QListWidget_create(Parent);
12201 end;
12202 
12203 type
12204   TCustomListViewHack = class(TCustomListView);
12205 
12206 procedure TQtListWidget.OwnerDataNeeded(ARect: TRect);
12207 var
12208   R: TRect;
12209   TopItem: Integer;
12210   i: Integer;
12211   VHeight: Integer; // viewport height
12212   RowHeight, AImagesWidth: Integer;
12213   item: QListWidgetItemH;
12214   v, v2, v3: QVariantH;
12215   WStr, DataStr: WideString;
12216   ImgList: TCustomImageList;
12217   AImageIndex: TImageIndex;
12218   Bmp: TBitmap;
12219   AIcon: QIconH;
12220   AOk, AStateImages: Boolean;
12221   ASize: TSize;
12222   ImgListRes: TScaledImageListResolution;
12223 begin
12224 
12225   {do not set items during design time}
12226   if (csDesigning in LCLObject.ComponentState) then
12227     exit;
12228 
12229   if ItemCount < 1 then
12230     exit;
12231 
12232   {TODO: add QtDecorationRole (icon) etc ... }
12233   QWidget_contentsRect(viewportWidget, @R);
12234   VHeight := R.Bottom - R.Top;
12235 
12236   item := itemAt(0, 1);
12237   if item <> nil then
12238   begin
12239     TopItem := getRow(Item);
12240     RowHeight := getRowHeight(TopItem);
12241 
12242     if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
12243       exit;
12244 
12245     i := 0;
12246 
12247     while (i < (VHeight + RowHeight)) do
12248     begin
12249       item := itemAt(0, i + 1);
12250       if (item <> nil) then
12251       begin
12252         TopItem := getRow(Item);
12253         RowHeight := getRowHeight(TopItem);
12254 
12255         if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
12256           break;
12257 
12258         AStateImages := False;
12259         ImgList := TCustomListViewHack(LCLObject).SmallImages;
12260         if Assigned(ImgList) then
12261           AImagesWidth := TCustomListViewHack(LCLObject).SmallImagesWidth
12262         else
12263         begin
12264           ImgList := TCustomListViewHack(LCLObject).StateImages;
12265           if Assigned(ImgList) then
12266             AImagesWidth := TCustomListViewHack(LCLObject).StateImagesWidth;
12267           AStateImages := True;
12268         end;
12269         if Assigned(ImgList) then
12270         begin
12271           ImgListRes := ImgList.ResolutionForPPI[
12272             AImagesWidth,
12273             TCustomListViewHack(LCLObject).Font.PixelsPerInch,
12274             TCustomListViewHack(LCLObject).GetCanvasScaleFactor];
12275           QListWidgetItem_sizeHint(item, @ASize);
12276           if (ASize.cx <> ImgListRes.Width) or (ASize.cx <> ImgListRes.Height) then
12277           begin
12278             ASize.cx := ImgListRes.Width;
12279             ASize.cy := ImgListRes.Height;
12280             QListWidgetItem_setSizeHint(item, @ASize);
12281           end;
12282           if AStateImages then
12283             AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].StateIndex
12284           else
12285             AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].ImageIndex;
12286           if (ImgListRes.Count > 0) and
12287             ((AImageIndex >= 0) and (AImageIndex < ImgListRes.Count)) then
12288           begin
12289             Bmp := TBitmap.Create;
12290             try
12291               ImgListRes.GetBitmap(AImageIndex, Bmp);
12292               v2 := QVariant_create;
12293               QListWidgetItem_data(item, v2, QtListViewOwnerDataRole);
12294               if not QVariant_isNull(v2) then
12295               begin
12296                 AOk := True;
12297                 if QVariant_toInt(v2, @AOk) <> AImageIndex then
12298                 begin
12299                   v2 := QVariant_create(AImageIndex);
12300                   QListWidgetItem_setData(item, QtListViewOwnerDataRole, v2);
12301                   QVariant_destroy(v2);
12302                   QListWidgetItem_setIcon(item, TQtImage(Bmp.Handle).AsIcon)
12303                 end;
12304                 // else we are imageIndex and that''s fine.
12305               end else
12306               begin
12307                 v2 := QVariant_create(AImageIndex);
12308                 QListWidgetItem_setData(item, QtListViewOwnerDataRole, v2);
12309                 QVariant_destroy(v2);
12310                 QListWidgetItem_setIcon(item, TQtImage(Bmp.Handle).AsIcon);
12311               end;
12312             finally
12313               Bmp.Free;
12314             end;
12315           end else
12316           if (AImageIndex < 0) then
12317           begin
12318             v2 := QVariant_create;
12319             AIcon := QIcon_create;
12320             try
12321               QListWidgetItem_data(item, v2, QtListViewOwnerDataRole);
12322               if not QVariant_isNull(v2) then
12323               begin
12324                 v3 := QVariant_create;
12325                 try
12326                   QListWidgetItem_setData(item, QtListViewOwnerDataRole, v3);
12327                 finally
12328                   QVariant_destroy(v3);
12329                 end;
12330               end;
12331               QListWidgetItem_icon(item, AIcon);
12332               if not QIcon_isNull(AIcon) then
12333                 QListWidgetItem_setIcon(item, nil);
12334             finally
12335               QVariant_destroy(v2);
12336               QIcon_destroy(AIcon);
12337             end;
12338           end;
12339         end;
12340 
12341         WStr := TCustomListViewHack(LCLObject){%H-}.Items[TopItem].Caption;
12342 
12343         // reduce paint overhead by checking text
12344         v := QVariant_create();
12345         QListWidgetItem_data(item, v, Ord(QtDisplayRole));
12346         if QVariant_isValid(v) then
12347           QVariant_toString(v, @DataStr)
12348         else
12349           DataStr := '';
12350         QVariant_destroy(v);
12351 
12352         // ASelected := not TCustomListViewHack(LCLObject).Items[TopItem].Selected;
12353 
12354         if (DataStr <> WStr) then
12355         begin
12356           v := QVariant_create(PWideString(@WStr));
12357           try
12358             QListWidgetItem_setData(item, Ord(QtDisplayRole), v);
12359           finally
12360             QVariant_destroy(v);
12361           end;
12362         end;
12363 
12364         // if (QListWidgetItem_isSelected(Item) <> ASelected) then
12365         //  QListWidgetItem_setSelected(Item, ASelected);
12366 
12367       end else
12368         break;
12369 
12370       inc(i, RowHeight);
12371     end;
12372   end;
12373 end;
12374 
TQtListWidget.GetItemFlagsnull12375 function TQtListWidget.GetItemFlags(AIndex: Integer): QtItemFlags;
12376 var
12377   AItem: QListWidgetItemH;
12378 begin
12379   Result := inherited GetItemFlags(AIndex);
12380   AItem := getItem(AIndex);
12381   if Assigned(AItem) then
12382     Result := QListWidgetItem_flags(AItem);
12383 end;
12384 
12385 procedure TQtListWidget.SetItemFlags(AIndex: Integer; AValue: QtItemFlags);
12386 var
12387   AItem: QListWidgetItemH;
12388 begin
12389   inherited SetItemFlags(AIndex, AValue);
12390   AItem := getItem(AIndex);
12391   if Assigned(AItem) then
12392     QListWidgetItem_setFlags(AItem, AValue);
12393 end;
12394 
12395 procedure TQtListWidget.AttachEvents;
12396 begin
12397   inherited AttachEvents;
12398 
12399   FCurrentItemChangedHook := QListWidget_hook_create(Widget);
12400   FSelectionChangeHook := QListWidget_hook_create(Widget);
12401   FItemClickedHook := QListWidget_hook_create(Widget);
12402   FItemTextChangedHook := QListWidget_hook_create(Widget);
12403 
12404   // used only when we are handle of TListView
12405   QListWidget_hook_hook_currentItemChanged(FCurrentItemChangedHook,
12406     @signalCurrentItemChanged);
12407 
12408   // OnSelectionChange event (listbox)
12409   QListWidget_hook_hook_itemSelectionChanged(FSelectionChangeHook, @signalSelectionChanged);
12410   QListWidget_hook_hook_itemClicked(FItemClickedHook, @signalItemClicked);
12411   QListWidget_hook_hook_currentTextChanged(FItemTextChangedHook, @signalItemTextChanged);
12412 end;
12413 
12414 procedure TQtListWidget.DetachEvents;
12415 begin
12416   if FCurrentItemChangedHook <> nil then
12417   begin
12418     QListWidget_hook_destroy(FCurrentItemChangedHook);
12419     FCurrentItemChangedHook := nil;
12420   end;
12421   if FSelectionChangeHook <> nil then
12422   begin
12423     QListWidget_hook_destroy(FSelectionChangeHook);
12424     FSelectionChangeHook := nil;
12425   end;
12426   if FItemClickedHook <> nil then
12427   begin
12428     QListWidget_hook_destroy(FItemClickedHook);
12429     FItemClickedHook := nil;
12430   end;
12431   if FItemTextChangedHook <> nil then
12432   begin
12433     QListWidget_hook_destroy(FItemTextChangedHook);
12434     FItemTextChangedHook := nil;
12435   end;
12436 
12437   inherited DetachEvents;
12438 end;
12439 
12440 procedure TQtListWidget.InitializeWidget;
12441 begin
12442   inherited InitializeWidget;
12443   // by default horz scrollbars is off. it is set by SetScrollWidth
12444   setScrollBarPolicy(False, QtScrollBarAlwaysOff);
12445 end;
12446 
TQtListWidget.EventFilternull12447 function TQtListWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
12448 var
12449   ev: QEventH;
12450 begin
12451   Result := False;
12452   QEvent_accept(Event);
12453   if LCLObject = nil then
12454     exit;
12455 
12456   if (FChildOfComplexWidget = ccwComboBox) and (FOwner <> nil) then
12457   begin
12458     case QEvent_type(Event) of
12459       QEventHide:
12460       begin
12461         {we must delay SlotDropDownVisiblity according to #9574
12462          so order is OnChange(if editable)->OnSelect->OnCloseUp }
12463         ev := QEvent_create(QEventHideToParent);
12464         QCoreApplication_postEvent(Sender, ev);
12465       end;
12466       QEventHideToParent: TQtComboBox(FOwner).SlotDropListVisibility(False);
12467     end;
12468   end else
12469   begin
12470     if (QEvent_type(Event) = QEventResize) then
12471       // let the viewport send resize
12472     else
12473     if (QEvent_type(Event) = QEventMouseButtonPress) or
12474       (QEvent_type(Event) = QEventMouseButtonRelease) then
12475       {eat mouse button events when we are TListView class.
12476        Such events are handled by itemViewportEventFilter.
12477        With Qt TListBox and TCheckListBox are also affected. issue #21318}
12478     else
12479     begin
12480       Result:=inherited EventFilter(Sender, Event);
12481       if Checkable and
12482         (QEvent_type(Event) = QEventKeyPress) and
12483         (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) then
12484       begin
12485         if CurrentItem <> nil then
12486         begin
12487           HandleCheckChangedEvent(QtPoint(0, 0), currentItem, Event);
12488           if OwnerDrawn and not (Self is TQtCheckListBox) then
12489           begin
12490             if QListWidgetItem_checkState(currentItem) = QtUnChecked then
12491               QListWidgetItem_setCheckState(currentItem, QtChecked)
12492             else
12493               QListWidgetItem_setCheckState(currentItem, QtUnchecked);
12494           end;
12495         end;
12496       end;
12497     end;
12498   end;
12499 end;
12500 
12501 procedure TQtListWidget.HandleCheckChangedEvent(const AMousePos: TQtPoint;
12502   AItem: QListWidgetItemH; AEvent: QEventH);
12503 var
12504   xx: Integer;
12505   B: Boolean;
12506 
12507   procedure SendMessage(AnItem: QListWidgetItemH);
12508   var
12509     Msg: TLMNotify;
12510     NMLV: TNMListView;
12511   begin
12512     FillChar(Msg{%H-}, SizeOf(Msg), #0);
12513     FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
12514 
12515     Msg.Msg := CN_NOTIFY;
12516 
12517     NMLV.hdr.hwndfrom := HWND(Self);
12518     NMLV.hdr.code := LVN_ITEMCHANGED;
12519 
12520     NMLV.iItem := QListWidget_row(QListWidgetH(Widget), AnItem);
12521 
12522     NMLV.uNewState := UINT(B);
12523     NMLV.uChanged := LVIF_STATE;
12524 
12525     Msg.NMHdr := @NMLV.hdr;
12526 
12527     // DebugLn('HandleCheckableMouseDown sending LVN_ITEMCHANGED ...');
12528     DeliverMessage(Msg);
12529   end;
12530 begin
12531   if not Checkable or (AItem = nil) or (ViewStyle < 0) then
12532     exit;
12533 
12534   if ((QEvent_type(AEvent) = QEventMouseButtonPress) or
12535     (QEvent_type(AEvent) = QEventMouseButtonDblClick)) and
12536   (QMouseEvent_button(QMouseEventH(AEvent)) = QtLeftButton) then
12537   begin
12538     if (QListWidgetItem_flags(AItem) and QtItemIsUserCheckable) <> 0 then
12539     begin
12540       xx := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
12541       if ((AMousePos.X > 2) and (AMousePos.X <= (xx + 2))) then
12542       begin
12543         B := QListWidgetItem_checkState(AItem) = QtUnChecked;
12544         if B then
12545           SetItemLastCheckStateInternal(AItem, QtChecked)
12546         else
12547           SetItemLastCheckStateInternal(AItem, QtUnChecked);
12548 
12549         // if AItem is deleted in mouse event FDelayedCheckItem becomes nil and that's fine. issue #32869
12550         FDelayedCheckItem := AItem;
12551         SendMessage(AItem);
12552       end;
12553     end;
12554   end else
12555   if QEvent_type(AEvent) = LCLQt_ItemViewAfterMouseRelease then
12556   begin
12557     if (FDelayedCheckItem <> nil) and (FDelayedCheckItem <> AItem) then
12558     begin
12559       SetItemLastCheckStateInternal(FDelayedCheckItem, QListWidgetItem_checkState(FDelayedCheckItem));
12560       SendMessage(FDelayedCheckItem);
12561     end;
12562     if FDelayedCheckItem = nil then // issue #32869
12563       exit;
12564     FDelayedCheckItem := nil;
12565     SetItemLastCheckStateInternal(AItem, QListWidgetItem_checkState(AItem));
12566     SendMessage(AItem);
12567   end else
12568   if (QEvent_type(AEvent) = QEventKeyPress) and
12569     (QKeyEvent_key(QKeyEventH(AEvent)) = QtKey_Space) then
12570   begin
12571     FDelayedCheckItem := nil;
12572     B := QListWidgetItem_checkState(AItem) = QtUnChecked;
12573     if B then
12574       SetItemLastCheckStateInternal(AItem, QtChecked)
12575     else
12576       SetItemLastCheckStateInternal(AItem, QtUnChecked);
12577 
12578     SendMessage(AItem);
12579   end;
12580 end;
12581 
itemViewViewportEventFilternull12582 function TQtListWidget.itemViewViewportEventFilter(Sender: QObjectH;
12583   Event: QEventH): Boolean; cdecl;
12584 var
12585   Item, CurrItem: QListWidgetItemH;
12586   MousePos: TQtPoint;
12587   X: Integer;
12588   Arr: TPtrIntArray;
12589   Modifiers: QtKeyboardModifiers;
12590   ItemRow, CurrItemRow: Integer;
12591   ALCLEvent: QLCLMessageEventH;
12592   R: TRect;
12593   DC: TQtDeviceContext;
12594   AMsgData: PtrUInt;
12595 
12596   procedure SendEventToParent;
12597   begin
12598     //issue #21318
12599     SlotMouse(Widget, Event);
12600   end;
12601 
12602 begin
12603   Result := False;
12604   QEvent_accept(Event);
12605 
12606   if (FChildOfComplexWidget = ccwComboBox) and (FOwner <> nil) then
12607   begin
12608     if QEvent_type(Event) = QEventShow then
12609       TQtComboBox(FOwner).FixMouseUp;
12610     exit;
12611   end;
12612 
12613   if (LCLObject <> nil) then
12614   begin
12615     if ViewStyle >= 0 then
12616     begin
12617       if (QEvent_type(Event) = QEventPaint) and (Sender = viewportWidget) then
12618       begin
12619         HasPaint := True;
12620         QPaintEvent_rect(QPaintEventH(Event), @R);
12621         if FOwnerData then
12622           OwnerDataNeeded(R);
12623         DC := TQtDeviceContext.Create(QWidgetH(Sender), True);
12624         try
12625           TCustomListViewAccess(LCLObject).Canvas.handle := HDC(DC);
12626           TCustomListViewAccess(LCLObject).IntfCustomDraw(dtControl, cdPrePaint, 0, 0, [], @R);
12627         finally
12628           TCustomListViewAccess(LCLObject).Canvas.handle := 0;
12629           DC.Free;
12630         end;
12631       end else
12632       if getEnabled and (QEvent_type(Event) = LCLQt_ItemViewAfterMouseRelease) then
12633       begin
12634         ALCLEvent := QLCLMessageEventH(Event);
12635         Item := QListWidgetItemH(QLCLMessageEvent_getLParam(ALCLEvent));
12636         // sync lcl with qt state. This is needed only when mouse is pressed
12637         // and moved out of item, or pressed on item and released over checkbox
12638         if (Item <> nil) and (GetItemLastCheckState(Item) <>
12639           QListWidgetItem_checkState(Item)) then
12640         begin
12641           MousePos := QtPoint(0, 0); // shutup compiler
12642           if QLCLMessageEvent_getMsg(ALCLEvent) > 0 then
12643             QListWidgetItem_setCheckState(Item, GetItemLastCheckState(Item));
12644           HandleCheckChangedEvent(MousePos, Item, Event);
12645         end;
12646       end else
12647       if getEnabled and (QEvent_type(Event) = QEventMouseButtonRelease) then
12648       begin
12649         if OwnerDrawn and Checkable then
12650         begin
12651           MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
12652           Item := itemAt(MousePos.x, MousePos.y);
12653 
12654           if (Item <> nil) and
12655             ((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
12656           begin
12657             x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
12658             if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
12659             begin
12660               if QListWidgetItem_checkState(Item) = QtUnchecked then
12661                 QListWidgetItem_setCheckState(Item, QtChecked)
12662               else
12663                 QListWidgetItem_setCheckState(Item, QtUnChecked);
12664             end;
12665           end;
12666           Result := SlotMouse(Sender, Event);
12667         end else
12668         begin
12669           PostponedMouseRelease(Event);
12670           if Checkable then
12671           begin
12672             MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
12673             Item := itemAt(MousePos.x, MousePos.y);
12674             if (Item <> nil) then
12675             begin
12676               if Assigned(LCLObject) and LCLObject.Dragging then
12677                 AMsgData := Ord(QListWidgetItem_checkState(Item)) + 1
12678               else
12679                 AMsgData := 0;
12680               ALCLEvent := QLCLMessageEvent_create(LCLQt_ItemViewAfterMouseRelease, AMsgData,
12681                 PtrUInt(Item), PtrUInt(Item), 0);
12682               QCoreApplication_postEvent(Sender, ALCLEvent);
12683             end;
12684           end;
12685         end;
12686       end else
12687       begin
12688         if getEnabled and (QEvent_type(Event) = QEventMouseButtonPress) then
12689         begin
12690           MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
12691           Item := itemAt(MousePos.x, MousePos.y);
12692           if Item = nil then
12693             FSavedSelection := selectedItems
12694           else
12695           begin
12696             // qt selection in QListWidget is ugly, and LCL needs that info
12697             // when mouse button is pressed, not after that, so we
12698             // trigger selectionChanged() here
12699             // Multiselection needs special handling to get proper
12700             // order of OnSelectItem.
12701             if (getSelectionMode > QAbstractItemViewSingleSelection) or FOwnerData then
12702             begin
12703               Modifiers := QInputEvent_modifiers(QInputEventH(Event));
12704               SlotMouse(Sender, Event);
12705 
12706               HandleCheckChangedEvent(MousePos, Item, Event);
12707 
12708               if not QListWidgetItem_isSelected(Item) then
12709               begin
12710                 if Modifiers = 0 then
12711                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
12712                     QItemSelectionModelClearAndSelect or QItemSelectionModelCurrent)
12713                 else
12714                 if (Modifiers and QtControlModifier <> 0) then
12715                 begin
12716                   X := getSelCount;
12717                   // DebugLn('**** Called SELECT IN 1 X=', dbgs(X),' is curr ? ',dbgs(CurrentItem = Item));
12718                   if CurrentItem = Item then
12719                     X := 0;
12720                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
12721                     QItemSelectionModelSelect);
12722                   if (X <= 1) then
12723                     signalCurrentItemChanged(Item, nil);
12724                 end else
12725                 if (Modifiers and QtShiftModifier <> 0) then
12726                 begin
12727                   // select this and all other's (calculate is it up or down)
12728                   X := getSelCount;
12729                   CurrItem := currentItem; //<-- doesn't smell good with QtShiftModifier
12730                   if CurrItem = nil then // <-- do not crash
12731                     CurrItem := Item;
12732                   ItemRow := getRow(Item);
12733                   CurrItemRow := getRow(CurrItem);
12734                   if (ItemRow < CurrItemRow) and (ItemRow >= 0) then
12735                   begin
12736                     for x := CurrItemRow + 1 to rowCount - 1 do
12737                     begin
12738                       CurrItem := getItem(x);
12739                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
12740                         QItemSelectionModelClear or QItemSelectionModelDeselect);
12741                     end;
12742                     for x := CurrItemRow downto ItemRow do
12743                     begin
12744                       CurrItem := getItem(x);
12745                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
12746                         QItemSelectionModelSelect);
12747                     end;
12748                   end else
12749                   if (ItemRow > CurrItemRow) then
12750                   begin
12751                     for x := 0 to CurrItemRow - 1 do
12752                     begin
12753                       CurrItem := getItem(x);
12754                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
12755                         QItemSelectionModelClear or QItemSelectionModelDeselect);
12756                     end;
12757                     for x := ItemRow downto CurrItemRow do
12758                     begin
12759                       CurrItem := getItem(x);
12760                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
12761                         QItemSelectionModelSelect);
12762                     end;
12763                   end;
12764                 end;
12765               end else
12766               begin
12767                 X := getSelCount;
12768                 if (Modifiers = 0) and (X > 1) then
12769                 begin
12770                   Arr := selectedItems;
12771                   for x := 0 to High(Arr) do
12772                   begin
12773                     if QListWidgetItemH(Arr[x]) <> Item then
12774                       QListWidget_setCurrentItem(QListWidgetH(Widget),
12775                         QListWidgetItemH(Arr[x]), QItemSelectionModelDeSelect);
12776                   end;
12777                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
12778                     QItemSelectionModelSelectCurrent);
12779                 end else
12780                 if (Modifiers and QtControlModifier <> 0) then
12781                 begin
12782                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
12783                     QItemSelectionModelDeSelect);
12784                   if (X = 1) or (currentItem = Item) then
12785                     signalCurrentItemChanged(nil, Item);
12786                 end;
12787               end;
12788               QEvent_ignore(Event);
12789               Result := True;
12790               exit;
12791             end else
12792             begin
12793               SlotMouse(Sender, Event);
12794               HandleCheckChangedEvent(MousePos, Item, Event);
12795               if not QListWidgetItem_isSelected(Item) then
12796                 QListWidget_setCurrentItem(QListWidgetH(Widget), Item, QItemSelectionModelClearAndSelect);
12797               QEvent_ignore(Event);
12798               Result := True;
12799               exit;
12800             end;
12801           end;
12802         end;
12803 
12804         if getEnabled and Checkable and (QEvent_type(Event) = QEventMouseButtonDblClick) then
12805         begin
12806           MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
12807           Item := itemAt(MousePos.x, MousePos.y);
12808           if Item <> nil then
12809             HandleCheckChangedEvent(MousePos, Item, Event);
12810         end;
12811 
12812         Result := inherited itemViewViewportEventFilter(Sender, Event);
12813       end;
12814     end else
12815     case QEvent_type(Event) of
12816       QEventMouseButtonPress,
12817       QEventMouseButtonRelease,
12818       QEventMouseButtonDblClick:
12819       begin
12820         if getEnabled and Checkable and
12821           (QEvent_type(Event) <> QEventMouseButtonDblClick) and
12822           (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
12823         begin
12824           MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
12825           Item := itemAt(MousePos.x, MousePos.y);
12826           if (Item <> nil) and
12827             ((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
12828           begin
12829             x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
12830             if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
12831             begin
12832               FCheckBoxClicked := True;
12833               SetItemLastCheckState(Item);
12834               {signalItemClicked() fires !}
12835             end else
12836               SendEventToParent;
12837           end else
12838             SendEventToParent;
12839         end else
12840           SendEventToParent;
12841       end;
12842     else
12843       Result := inherited itemViewViewportEventFilter(Sender, Event);
12844     end;
12845   end;
12846 end;
12847 
12848 procedure TQtListWidget.signalCurrentItemChanged(current: QListWidgetItemH;
12849   previous: QListWidgetItemH); cdecl;
12850 var
12851   Msg: TLMNotify;
12852   NMLV: TNMListView;
12853   ASubIndex: Integer;
12854   AIndex: Integer;
12855 begin
12856   // only when TQtListWidget is handle of TListView !
12857   if ViewStyle = -1 then
12858     exit;
12859 
12860   FillChar(Msg{%H-}, SizeOf(Msg), #0);
12861   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
12862 
12863   Msg.Msg := CN_NOTIFY;
12864 
12865   NMLV.hdr.hwndfrom := LCLObject.Handle;
12866   NMLV.hdr.code := LVN_ITEMCHANGING;
12867 
12868   if Current <> nil then
12869     AIndex := getRow(Current)
12870   else
12871     AIndex := -1;
12872 
12873   ASubIndex := 0;
12874 
12875   NMLV.iItem := AIndex;
12876   NMLV.iSubItem := ASubIndex;
12877   NMLV.uNewState := LVIS_SELECTED;
12878   NMLV.uChanged := LVIF_STATE;
12879 
12880   Msg.NMHdr := @NMLV.hdr;
12881   DeliverMessage(Msg);
12882 
12883   // if getSelectionMode > QAbstractItemViewSingleSelection then
12884   //  DebugLn('*** MultiSelect: SignalCurrentItemChanged Current ',dbgs(Current),' Previous ',dbgs(Previous));
12885 
12886   FSyncingItems := True;
12887   try
12888     if Current <> nil then
12889     begin
12890       FillChar(Msg, SizeOf(Msg), #0);
12891       FillChar(NMLV, SizeOf(NMLV), #0);
12892       Msg.Msg := CN_NOTIFY;
12893       NMLV.hdr.hwndfrom := LCLObject.Handle;
12894       NMLV.hdr.code := LVN_ITEMCHANGED;
12895       NMLV.iItem := AIndex;
12896       NMLV.iSubItem := ASubIndex;
12897       if QListWidget_isItemSelected(QListWidgetH(Widget), Current) then
12898         NMLV.uNewState := LVIS_SELECTED
12899       else
12900         NMLV.uOldState := LVIS_SELECTED;
12901       NMLV.uChanged := LVIF_STATE;
12902       Msg.NMHdr := @NMLV.hdr;
12903       DeliverMessage(Msg);
12904 
12905       // send focused msg
12906       NMLV.uOldState := 0;
12907       NMLV.uNewState := LVIS_FOCUSED;
12908       NMLV.uChanged := LVIF_STATE;
12909       Msg.NMHdr := @NMLV.hdr;
12910       DeliverMessage(Msg);
12911 
12912     end;
12913 
12914     if Previous <> nil then
12915     begin
12916       FillChar(Msg, SizeOf(Msg), #0);
12917       FillChar(NMLV, SizeOf(NMLV), #0);
12918       Msg.Msg := CN_NOTIFY;
12919       NMLV.hdr.hwndfrom := LCLObject.Handle;
12920       NMLV.hdr.code := LVN_ITEMCHANGED;
12921       NMLV.iItem := getRow(Previous);
12922       ASubIndex := 0;
12923       NMLV.iSubItem := ASubIndex;
12924       if QListWidget_isItemSelected(QListWidgetH(Widget), Previous) then
12925         NMLV.uNewState := LVIS_SELECTED
12926       else
12927         NMLV.uOldState := LVIS_SELECTED;
12928       NMLV.uChanged := LVIF_STATE;
12929       Msg.NMHdr := @NMLV.hdr;
12930       DeliverMessage(Msg);
12931     end;
12932   finally
12933     FSyncingItems := False;
12934   end;
12935 end;
12936 
12937 {------------------------------------------------------------------------------
12938   Function: TQtListWidget.SlotSelectionChange
12939   Params:  None
12940   Returns: Nothing
12941  ------------------------------------------------------------------------------}
12942 
12943 procedure TQtListWidget.signalSelectionChanged(); cdecl;
12944 var
12945   Msg: TLMessage;
12946   i: Integer;
12947   Item: QListWidgetItemH;
12948 begin
12949   {$ifdef VerboseQt}
12950     WriteLn('TQtListWidget.signalSelectionChange');
12951   {$endif}
12952 
12953   if FDontPassSelChange then
12954   begin
12955     FDontPassSelChange := False;
12956     Exit;
12957   end;
12958 
12959   if (ViewStyle >= 0) and (InUpdate or
12960     (not InUpdate and (length(FSavedSelection) = 0)) ) then
12961     exit;
12962 
12963   FillChar(Msg{%H-}, SizeOf(Msg), #0);
12964   Msg.Msg := LM_SELCHANGE;
12965   if (FChildOfComplexWidget <> ccwComboBox) then
12966   begin
12967     if (ViewStyle < 0) and (getSelCount > 0) then
12968       DeliverMessage(Msg)
12969     else
12970     if (ViewStyle >= 0) then
12971     begin
12972       if getSelCount = 0 then
12973       begin
12974         for i := 0 to High(FSavedSelection) do
12975         begin
12976           Item := QListWidgetItemH(FSavedSelection[i]);
12977           if (Item <> nil) then
12978             signalCurrentItemChanged(nil, Item);
12979         end;
12980       end;
12981       setLength(FSavedSelection, 0);
12982     end;
12983   end;
12984 end;
12985 
12986 procedure TQtListWidget.signalItemTextChanged(ANewText: PWideString); cdecl;
12987 var
12988   Msg: TLMessage;
12989 begin
12990   {$ifdef VerboseQt}
12991     WriteLn('TQtListWidget.signalItemTextChanged');
12992   {$endif}
12993   FillChar(Msg{%H-}, SizeOf(Msg), #0);
12994   Msg.Msg := CM_TEXTCHANGED;
12995   DeliverMessage(Msg);
12996 end;
12997 
12998 procedure TQtListWidget.signalItemClicked(item: QListWidgetItemH); cdecl;
12999 var
13000   Msg: TLMessage;
13001   ItemRow: Integer;
13002   MsgN: TLMNotify;
13003   NMLV: TNMListView;
13004   R: TRect;
13005   Pt: TPoint;
13006 begin
13007   {$ifdef VerboseQt}
13008     WriteLn('TQtListWidget.signalItemClicked');
13009   {$endif}
13010   if (ViewStyle >= 0) and (FChildOfComplexWidget <> ccwComboBox) then
13011   begin
13012     FillChar(MsgN{%H-}, SizeOf(MsgN), #0);
13013     FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
13014 
13015     MsgN.Msg := LM_CLICKED;
13016 
13017     NMLV.hdr.hwndfrom := LCLObject.Handle;
13018     NMLV.hdr.code := NM_CLICK;
13019 
13020     NMLV.iItem := getRow(Item);
13021 
13022     NMLV.iSubItem := 0;
13023     NMLV.uNewState := UINT(NM_CLICK);
13024     NMLV.uChanged :=  LVIS_SELECTED;
13025 
13026     QListWidget_visualItemRect(QListWidgetH(Widget), @R, Item);
13027 
13028     pt.X := R.Left;
13029     pt.Y := R.Top;
13030 
13031     NMLV.ptAction := pt;
13032 
13033     MsgN.NMHdr := @NMLV.hdr;
13034 
13035     DeliverMessage(MsgN);
13036   end;
13037 
13038   if Checkable then
13039   begin
13040     FillChar(Msg{%H-}, SizeOf(Msg), #0);
13041     Msg.Msg := LM_CHANGED;
13042     ItemRow := QListWidget_row(QListWidgetH(Widget), Item);
13043     Msg.WParam := ItemRow;
13044     DeliverMessage(Msg);
13045   end;
13046 
13047 end;
13048 
13049 procedure TQtListWidget.ItemDelegatePaint(painter: QPainterH;
13050   option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
13051 var
13052   Msg: TLMDrawListItem;
13053   DrawStruct: TDrawListItemStruct;
13054   State: QStyleState;
13055   R: TRect;
13056   ItemIndex, SubItemIndex: Integer;
13057   ACustomState: TCustomDrawState;
13058   ATarget: TCustomDrawTarget;
13059   TmpDC1, TmpDC2: HDC;
13060   SkipDefault: Boolean;
13061   Item: QListWidgetItemH;
13062   APaintResult: TCustomDrawResult;
13063 begin
13064   if (ViewStyle >= 0) and not (FChildOfComplexWidget = ccwComboBox) then
13065   begin
13066     State := QStyleOption_state(option);
13067     ACustomState := [cdsDefault];
13068     (*
13069     cdsSelected,
13070     cdsGrayed,
13071     cdsDisabled,
13072     cdsChecked,
13073     cdsFocused,
13074     cdsDefault,
13075     cdsHot,
13076     cdsMarked,
13077     cdsIndeterminate
13078     *)
13079 
13080     if (State and QStyleState_Selected) <> 0 then
13081       Include(ACustomState, cdsSelected);
13082     // disabled
13083     if (State and QStyleState_Enabled) = 0 then
13084       Include(ACustomState, cdsDisabled);
13085     // focused (QStyleState_FocusAtBorder?)
13086     if (State and QStyleState_HasFocus) <> 0 then
13087       Include(ACustomState, cdsFocused);
13088     // hotlight
13089     if (State and QStyleState_MouseOver) <> 0 then
13090       Include(ACustomState, cdsHot);
13091 
13092     ItemIndex := QModelIndex_row(index);
13093     SubItemIndex := QModelIndex_column(index);
13094 
13095     // checked does not work under qt for some reason ?!?
13096     if Checkable then
13097     begin
13098       // if (State and QStyleState_On <> 0) then
13099       //  Include(ACustomState, cdsChecked);
13100       Item := getItem(ItemIndex);
13101       if Assigned(Item) and (QListWidgetItem_checkState(Item) = QtChecked) then
13102         Include(ACustomState, cdsChecked);
13103     end;
13104 
13105     QStyle_drawControl(QApplication_style, QStyleCE_ItemViewItem, Option, painter, viewportWidget);
13106 
13107     // NOW WE ARE DRAWING ITEMS ...
13108     QPainter_save(painter);
13109     if TCustomListView(LCLObject).Canvas.HandleAllocated then
13110       TmpDC2 := TCustomListView(LCLObject).Canvas.GetUpdatedHandle([csHandleValid])
13111     else
13112       TmpDC2 := 0;
13113     TmpDC1 := HDC(TQtDeviceContext.CreateFromPainter(painter));
13114     TCustomListView(LCLObject).Canvas.Handle := TmpDC1;
13115     try
13116       R := visualRect(index);
13117 
13118       if SubItemIndex <= 0 then
13119         ATarget := dtItem
13120       else
13121         ATarget := dtSubItem;
13122 
13123       // here we do only OnCustomDrawItem and OnCustomDrawSubItem
13124       // OnCustomDraw is done inside itemViewportEventFilter.
13125 
13126       APaintResult := TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPrePaint, ItemIndex, SubItemIndex, ACustomState, @R);
13127       SkipDefault := cdrSkipDefault in APaintResult;
13128 
13129       if not SkipDefault then // do default paint by unknown magic
13130         QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
13131 
13132       // issue #27315
13133       if cdrNotifyPostpaint in APaintResult then
13134         TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPostPaint, ItemIndex, SubItemIndex, ACustomState, @R);
13135 
13136     finally
13137       TCustomListView(LCLObject).Canvas.Handle := TmpDC2;
13138       TQtDeviceContext(TmpDC1).Free;
13139       QPainter_restore(painter);
13140     end;
13141   end else
13142   begin
13143     QPainter_save(painter);
13144     State := QStyleOption_state(option);
13145     DrawStruct.ItemID := UINT(QModelIndex_row(index));
13146 
13147     DrawStruct.Area := visualRect(index);
13148     DrawStruct.DC := HDC(TQtDeviceContext.CreateFromPainter(painter));
13149 
13150     DrawStruct.ItemState := [];
13151     // selected
13152     if (State and QStyleState_Selected) <> 0 then
13153       Include(DrawStruct.ItemState, odSelected);
13154     // disabled
13155     if (State and QStyleState_Enabled) = 0 then
13156       Include(DrawStruct.ItemState, odDisabled);
13157     // focused (QStyleState_FocusAtBorder?)
13158     if (State and QStyleState_HasFocus) <> 0 then
13159       Include(DrawStruct.ItemState, odFocused);
13160     // hotlight
13161     if (State and QStyleState_MouseOver) <> 0 then
13162       Include(DrawStruct.ItemState, odHotLight);
13163     // checked
13164     if Checkable then
13165     begin
13166       // if (State and QStyleState_On <> 0) then
13167       //  Include(ACustomState, cdsChecked);
13168       Item := getItem(QModelIndex_row(index));
13169       if Assigned(Item) and (QListWidgetItem_checkState(Item) = QtChecked) then
13170         Include(DrawStruct.ItemState, odChecked);
13171     end;
13172 
13173     { todo: over states:
13174 
13175       odGrayed, odChecked,
13176       odDefault, odInactive, odNoAccel,
13177       odNoFocusRect, odReserved1, odReserved2, odComboBoxEdit
13178     }
13179     Msg.Msg := LM_DRAWLISTITEM;
13180     Msg.DrawListItemStruct := @DrawStruct;
13181     DeliverMessage(Msg);
13182 
13183     QPainter_restore(painter);
13184 
13185     TQtDeviceContext(DrawStruct.DC).Free;
13186   end;
13187 end;
13188 
13189 procedure TQtListWidget.clearSelection;
13190 begin
13191   inherited clearSelection;
13192   SetLength(FSavedSelection, 0);
13193 end;
13194 
13195 procedure TQtListWidget.ClearItems;
13196 begin
13197   SetLength(FSavedSelection, 0);
13198   QListWidget_clear(QListWidgetH(Widget));
13199 end;
13200 
13201 {------------------------------------------------------------------------------
13202   Function: TQtListWidget.currentRow
13203   Params:  None
13204   Returns: Nothing
13205  ------------------------------------------------------------------------------}
currentRownull13206 function TQtListWidget.currentRow: Integer;
13207 begin
13208   Result := QListWidget_currentRow(QListWidgetH(Widget));
13209 end;
13210 
currentItemnull13211 function TQtListWidget.currentItem: QListWidgetItemH;
13212 begin
13213   Result := QListWidget_currentItem(QListWidgetH(Widget));
13214 end;
13215 
IndexAtnull13216 function TQtListWidget.IndexAt(APoint: PQtPoint): Integer;
13217 var
13218   AModelIndex: QModelIndexH;
13219 begin
13220   AModelIndex := QModelIndex_create();
13221   QListView_indexAt(QListWidgetH(Widget), AModelIndex, APoint);
13222   Result := QModelIndex_row(AModelIndex);
13223   QModelIndex_destroy(AModelIndex);
13224 end;
13225 
13226 procedure TQtListWidget.insertItem(AIndex: Integer; AText: String);
13227 var
13228   Str: WideString;
13229 begin
13230   Str := {%H-}AText;
13231   insertItem(AIndex, @Str);
13232 end;
13233 
13234 procedure TQtListWidget.insertItem(AIndex: Integer; AText: PWideString);
13235 var
13236   Item: QListWidgetItemH;
13237 begin
13238   Item := QListWidgetItem_create(AText, nil, QListWidgetItemType);
13239   if Checkable then
13240     QListWidgetItem_setCheckState(Item, QtUnChecked)
13241   else
13242   if (ViewStyle = Ord(vsIcon)) and not (FChildOfComplexWidget = ccwComboBox) then
13243     QListWidgetItem_setTextAlignment(Item, QtAlignHCenter);
13244   QListWidget_insertItem(QListWidgetH(Widget), AIndex, Item);
13245 end;
13246 
itemAtnull13247 function TQtListWidget.itemAt(APoint: TPoint): QListWidgetItemH;
13248 begin
13249   Result := ItemAt(APoint.X, APoint.Y);
13250 end;
13251 
itemAtnull13252 function TQtListWidget.itemAt(x: Integer; y: Integer): QListWidgetItemH;
13253 begin
13254   Result := QListWidget_itemAt(QListWidgetH(Widget), x, y);
13255 end;
13256 
getItemnull13257 function TQtListWidget.getItem(AIndex: Integer): QListWidgetItemH;
13258 begin
13259   if (AIndex >= 0) and (AIndex < rowCount) then
13260     Result := QListWidget_item(QListWidgetH(Widget), AIndex)
13261   else
13262     Result := nil;
13263 end;
13264 
getItemSelectednull13265 function TQtListWidget.getItemSelected(AItem: QListWidgetItemH): Boolean;
13266 begin
13267   if AItem <> nil then
13268     Result := QListWidget_isItemSelected(QListWidgetH(Widget), AItem)
13269   else
13270     Result := False;
13271 end;
13272 
getItemVisiblenull13273 function TQtListWidget.getItemVisible(AItem: QListWidgetItemH): Boolean;
13274 begin
13275   if AItem = nil then
13276     Result := False
13277   else
13278     Result := not QListWidget_isItemHidden(QListWidgetH(Widget), AItem);
13279 end;
13280 
getRownull13281 function TQtListWidget.getRow(AItem: QListWidgetItemH): integer;
13282 begin
13283   if AItem = nil then
13284     Result := -1
13285   else
13286     Result := QListWidget_row(QListWidgetH(Widget), AItem);
13287 end;
13288 
getSelCountnull13289 function TQtListWidget.getSelCount: Integer;
13290 begin
13291   Result := length(selectedItems);
13292 end;
13293 
getTopItemnull13294 function TQtListWidget.getTopItem: integer;
13295 begin
13296   Result := getVisibleRowCount(True);
13297 end;
13298 
13299 {------------------------------------------------------------------------------
13300   Function: TQtListWidget.getVisibleRowCount
13301   Params:  Boolean
13302   Returns: if AFirstVisibleOnly = False (default) then it returns number
13303   of visible rows, or 0 if there's no visible rows.
13304   When AFirstVisibleOnly = True then it returns index of first visible row,
13305   otherwise result is -1.
13306  ------------------------------------------------------------------------------}
getVisibleRowCountnull13307 function TQtListWidget.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
13308 var
13309   R: TRect;
13310   i: integer;
13311   item: QListWidgetItemH;
13312   RowIndex: integer;
13313   RowHeight: integer;
13314 begin
13315   if AFirstVisibleOnly then
13316     Result := -1
13317   else
13318     Result := 0;
13319   QWidget_contentsRect(viewportWidget, @R);
13320   i := 0;
13321   repeat
13322     item := itemAt(0, i);
13323     if item <> nil then
13324     begin
13325       RowIndex := getRow(Item);
13326       if AFirstVisibleOnly then
13327       begin
13328         Result := RowIndex;
13329         break;
13330       end;
13331       RowHeight := getRowHeight(RowIndex);
13332       inc(Result);
13333       if RowHeight <= 0 then
13334         RowHeight := 1;
13335       inc(i, RowHeight);
13336     end else
13337       inc(i, 1);
13338   until i >= R.Bottom;
13339 end;
13340 
getVisualItemRectnull13341 function TQtListWidget.getVisualItemRect(AItem: QListWidgetItemH): TRect;
13342 begin
13343   Result := Rect(0, 0, 0, 0);
13344   if AItem <> nil then
13345     QListWidget_visualItemRect(QListWidgetH(Widget), @Result, AItem);
13346 end;
13347 
TQtListWidget.selectedItemsnull13348 function TQtListWidget.selectedItems: TPtrIntArray;
13349 begin
13350   QListWidget_selectedItems(QListWidgetH(Widget), @Result);
13351 end;
13352 
13353 {------------------------------------------------------------------------------
13354   Function: TQtListWidget.setCurrentRow
13355   Params:  None
13356   Returns: Nothing
13357  ------------------------------------------------------------------------------}
13358 procedure TQtListWidget.setCurrentRow(row: Integer);
13359 begin
13360   if (getSelectionMode <> QAbstractItemViewSingleSelection) and (row < 0) then
13361     row := 0;
13362 
13363   if currentRow <> row then
13364   begin
13365     FDontPassSelChange := True;
13366     QListWidget_setCurrentRow(QListWidgetH(Widget), row);
13367   end;
13368 end;
13369 
13370 procedure TQtListWidget.setCurrentItem(AItem: QListWidgetItemH;
13371   const AIsSet: Boolean = True);
13372 begin
13373   if AIsSet then
13374     QListWidget_setCurrentItem(QListWidgetH(Widget), AItem);
13375 end;
13376 
13377 procedure TQtListWidget.setItemText(AIndex: Integer; AText: String);
13378 var
13379   Item: QListWidgetItemH;
13380   Str: WideString;
13381   R: TRect;
13382 begin
13383   Str := {%H-}AText;
13384   if (AIndex >= 0) and (AIndex < rowCount) then
13385   begin
13386     Item := getItem(AIndex);
13387     QListWidgetItem_setText(Item, @Str);
13388     {we must update our custom delegate}
13389     if OwnerDrawn then
13390     begin
13391       R := getVisualItemRect(Item);
13392       Update(@R);
13393     end;
13394   end else
13395     insertItem(AIndex, @Str);
13396 end;
13397 
13398 procedure TQtListWidget.setItemText(AIndex: Integer; AText: String;
13399   AAlignment: Integer);
13400 var
13401   Item: QListWidgetItemH;
13402   Str: WideString;
13403   R: TRect;
13404 begin
13405   Str := {%H-}AText;
13406   if (AIndex >= 0) and (AIndex < rowCount) then
13407   begin
13408     Item := getItem(AIndex);
13409     QListWidgetItem_setText(Item, @Str);
13410     QListWidgetItem_setTextAlignment(Item, AAlignment);
13411     {we must update our custom delegate}
13412     if OwnerDrawn then
13413     begin
13414       R := getVisualItemRect(Item);
13415       Update(@R);
13416     end;
13417   end else
13418     insertItem(AIndex, @Str);
13419 end;
13420 
13421 procedure TQtListWidget.setItemSelected(AItem: QListWidgetItemH;
13422   const ASelect: Boolean);
13423 begin
13424   if AItem <> nil then
13425     QListWidget_setItemSelected(QListWidgetH(Widget), AItem, ASelect);
13426 end;
13427 
13428 procedure TQtListWidget.setItemVisible(AItem: QListWidgetItemH;
13429   const AVisible: Boolean);
13430 begin
13431   if AItem <> nil then
13432     QListWidget_setItemHidden(QListWidgetH(Widget), AItem, not AVisible);
13433 end;
13434 
13435 procedure TQtListWidget.setSelectionMode(AMode: QAbstractItemViewSelectionMode);
13436 var
13437   SavedItem: QListWidgetItemH;
13438   Arr: TPtrIntArray;
13439   i: Integer;
13440 begin
13441   SavedItem := nil;
13442   // this code is here due to Qt bug with QListView/QListWidget ..
13443   // QTreeWidget works correct .. clearSelection does not trigger signals
13444   // so we must do that manually.
13445   if (ViewStyle > 0) and (AMode < QAbstractItemViewMultiSelection) and
13446     (getSelectionMode > QAbstractItemViewSingleSelection) then
13447   begin
13448     SavedItem := CurrentItem;
13449     Arr := selectedItems;
13450     if not ((SavedItem <> nil) and (QListWidgetItem_isSelected(SavedItem))) then
13451     begin
13452       SavedItem := nil;
13453       if length(Arr) > 0 then
13454         SavedItem := QListWidgetItemH(Arr[0]);
13455     end;
13456     for i := 0 to High(Arr) do
13457     begin
13458       if QListWidgetItemH(Arr[i]) <> SavedItem then
13459       begin
13460         QListWidgetItem_setSelected(QListWidgetItemH(Arr[i]), False);
13461         signalCurrentItemChanged(nil, QListWidgetItemH(Arr[i]));
13462       end;
13463     end;
13464     clearSelection;
13465   end;
13466   inherited setSelectionMode(AMode);
13467   if SavedItem <> nil then
13468     setItemSelected(SavedItem, True);
13469 end;
13470 
13471 procedure TQtListWidget.scrollToItem(row: integer;
13472   hint: QAbstractItemViewScrollHint);
13473 var
13474   Item: QListWidgetItemH;
13475 begin
13476   Item := getItem(Row);
13477   QListWidget_scrollToItem(QListWidgetH(Widget), Item, hint);
13478 end;
13479 
13480 procedure TQtListWidget.removeItem(AIndex: Integer);
13481 var
13482   Item: QListWidgetItemH;
13483 begin
13484   if (currentRow = AIndex) then
13485     if (getSelectionMode = QAbstractItemViewSingleSelection) then
13486       setCurrentRow(-1);
13487   Item := QListWidget_takeitem(QListWidgetH(Widget), AIndex);
13488   if FDelayedCheckItem = Item then
13489     FDelayedCheckItem := nil;
13490   QListWidgetItem_destroy(Item);
13491 end;
13492 
TQtListWidget.rowCountnull13493 function TQtListWidget.rowCount: integer;
13494 begin
13495   Result := QListWidget_count(QListWidgetH(Widget));
13496 end;
13497 
13498 procedure TQtListWidget.ExchangeItems(const AIndex1, AIndex2: Integer);
13499 var
13500   ItemTo, ItemFrom: QListWidgetItemH;
13501   R: TRect;
13502 begin
13503   if AIndex1 = AIndex2 then
13504     exit;
13505 
13506   if AIndex1 < AIndex2 then
13507   begin
13508     ItemTo := QListWidget_takeItem(QListWidgetH(Widget), AIndex2);
13509     ItemFrom := QListWidget_takeItem(QListWidgetH(Widget), AIndex1);
13510     QListWidget_insertItem(QListWidgetH(Widget), AIndex1, ItemTo);
13511     QListWidget_insertItem(QListWidgetH(Widget), AIndex2, ItemFrom);
13512   end else
13513   begin
13514     ItemFrom := QListWidget_takeItem(QListWidgetH(Widget), AIndex1);
13515     ItemTo := QListWidget_takeItem(QListWidgetH(Widget), AIndex2);
13516     QListWidget_insertItem(QListWidgetH(Widget), AIndex2, ItemFrom);
13517     QListWidget_insertItem(QListWidgetH(Widget), AIndex1, ItemTo);
13518   end;
13519 
13520   if OwnerDrawn then
13521   begin
13522     R := getVisualItemRect(ItemTo);
13523     Update(@R);
13524     R := getVisualItemRect(ItemFrom);
13525     Update(@R);
13526   end;
13527 end;
13528 
13529 procedure TQtListWidget.MoveItem(const AFromIndex, AToIndex: Integer);
13530 var
13531   Item: QListWidgetItemH;
13532   R: TRect;
13533 begin
13534   Item := QListWidget_takeItem(QListWidgetH(Widget), AFromIndex);
13535   QListWidget_insertItem(QListWidgetH(Widget), AToIndex, Item);
13536   if OwnerDrawn then
13537   begin
13538     R := getVisualItemRect(Item);
13539     Update(@R);
13540   end;
13541 end;
13542 
13543 { TQtCheckListBox }
13544 
CreateWidgetnull13545 function TQtCheckListBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
13546 var
13547   Parent: QWidgetH;
13548 begin
13549   FCheckBoxClicked := False;
13550   FDelayedCheckItem := nil;
13551   FSavedEvent := nil;
13552   FSavedEventTimer := nil;
13553   FSavedEventTimerHook := nil;
13554 
13555   FViewStyle := -1;
13556   FSyncingItems := False;
13557   FDontPassSelChange := False;
13558   FOwnerData := False;
13559 
13560   FCheckable := True;
13561   if AParams.WndParent <> 0 then
13562     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
13563   else
13564     Parent := nil;
13565   Result := QListWidget_create(Parent);
13566 end;
13567 
13568 procedure TQtCheckListBox.SetNextStateMap(AItem: QListWidgetItemH);
13569 var
13570   ACurrState: QtCheckState;
13571 begin
13572   inherited SetNextStateMap(AItem);
13573   if (AItem = nil) or not AllowGrayed then
13574     exit;
13575   ACurrState := GetItemLastCheckState(AItem);
13576 
13577   case ACurrState of
13578     QtUnchecked: ItemCheckState[GetRow(AItem)] := QtPartiallyChecked;
13579     QtPartiallyChecked: ItemCheckState[GetRow(AItem)] := QtChecked;
13580     QtChecked: ItemCheckState[GetRow(AItem)] := QtUnChecked;
13581   end;
13582 end;
13583 
13584 procedure TQtCheckListBox.AttachEvents;
13585 begin
13586   inherited AttachEvents;
13587   FItemChangedHook := QListWidget_hook_create(Widget);
13588   QListWidget_hook_hook_itemChanged(FItemChangedHook, @signalItemChanged);
13589 end;
13590 
13591 procedure TQtCheckListBox.DetachEvents;
13592 begin
13593   if FItemChangedHook <> nil then
13594   begin
13595     QListWidget_hook_destroy(FItemChangedHook);
13596     FItemChangedHook := nil;
13597   end;
13598   inherited DetachEvents;
13599 end;
13600 
TQtCheckListBox.EventFilternull13601 function TQtCheckListBox.EventFilter(Sender: QObjectH; Event: QEventH
13602   ): Boolean; cdecl;
13603 begin
13604   Result := False;
13605   if (QEvent_type(Event) = QEventKeyPress) and
13606     (QtVersionMajor = 4) and (QtVersionMinor >= 8) and
13607      ((QKeyEvent_key(QKeyEventH(Event)) = QtKey_Up) or
13608      (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Down)) then
13609   begin
13610     {issue #31697}
13611     Result:=inherited EventFilter(Sender, Event);
13612     if ItemCount > 0 then
13613     begin
13614       if (getSelCount = 0) then
13615       begin
13616         Selected[0] := True;
13617         Result := True;
13618       end;
13619       inherited signalSelectionChanged();
13620     end;
13621   end else
13622   if (QEvent_type(Event) = QEventMouseButtonDblClick) then
13623     // issue #25089
13624   else
13625     Result:=inherited EventFilter(Sender, Event);
13626 end;
13627 
TQtCheckListBox.itemViewViewportEventFilternull13628 function TQtCheckListBox.itemViewViewportEventFilter(Sender: QObjectH;
13629   Event: QEventH): Boolean; cdecl;
13630 var
13631   MousePos: TQtPoint;
13632   Item: QListWidgetItemH;
13633   x: Integer;
13634 begin
13635   Result := False;
13636   QEvent_accept(Event);
13637   if (LCLObject <> nil) then
13638   begin
13639     case QEvent_type(Event) of
13640       QEventMouseButtonRelease,
13641       QEventMouseButtonPress,
13642       QEventMouseButtonDblClick:
13643         begin
13644           // issue #21318
13645           MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
13646           Item := itemAt(MousePos.x, MousePos.y);
13647 
13648           if QEvent_Type(Event) = QEventMouseButtonDblClick then
13649           begin
13650             SlotMouse(Widget, Event);
13651             QEvent_ignore(Event);
13652             // qt capture locks for some reason under qt-4.7.4 ?!?
13653             // when we dbl click on viewport without checkable items
13654             if (Item = nil) and (Sender = QWidget_mouseGrabber) then
13655               QWidget_releaseMouse(QWidgetH(Sender));
13656           end else
13657           begin
13658             Result := SlotMouse(Sender, Event);
13659             if (Item <> nil) and (OwnerDrawn) and
13660               (QEvent_type(Event) = QEventMouseButtonRelease) and
13661               ((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
13662             begin
13663               x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
13664               if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
13665               begin
13666                 if QListWidgetItem_checkState(Item) = QtUnchecked then
13667                   QListWidgetItem_setCheckState(Item, QtChecked)
13668                 else
13669                   QListWidgetItem_setCheckState(Item, QtUnChecked);
13670               end;
13671             end;
13672           end;
13673           if (QtVersionMajor = 4) and (QtVersionMinor >= 8) and
13674             (QEvent_Type(Event) = QEventMouseButtonPress) then
13675           begin
13676             // change current row , this works fine with qt < 4.8
13677             if Assigned(Item) and
13678               ((currentItem <> Item) or not QListWidgetItem_isSelected(Item)) then
13679             begin
13680               // DebugLn('TQtCheckListBox forced item change');
13681               // Self.setCurrentItem(Item, True);
13682               {issue #31697}
13683               QListWidget_setCurrentItem(QListWidgetH(Widget), Item, QItemSelectionModelSelectCurrent);
13684               inherited signalSelectionChanged();
13685             end;
13686           end;
13687         end;
13688       else
13689       begin
13690         {do not change selection if mousepressed and mouse moved}
13691         Result := (QEvent_type(Event) = QEventMouseMove) and
13692           hasFocus and (QApplication_mouseButtons() > 0);
13693          QEvent_ignore(Event);
13694       end;
13695     end;
13696   end;
13697 end;
13698 
13699 procedure TQtCheckListBox.signalCurrentItemChanged(current: QListWidgetItemH;
13700   previous: QListWidgetItemH); cdecl;
13701 begin
13702   // Do nothing
13703   // inherited signalCurrentItemChanged(current, previous);
13704 end;
13705 
13706 procedure TQtCheckListBox.signalItemClicked(item: QListWidgetItemH); cdecl;
13707 begin
13708 
13709   if InUpdate or not GetVisible then
13710     exit;
13711   {$note seem that we have qtbug with tristate listwidget items, so
13712    we must handle statemap somehow}
13713 
13714   //TODO try to fix nextstatemap
13715   if FCheckBoxClicked then
13716   begin
13717     FCheckBoxClicked := False;
13718     SetNextStateMap(item);
13719   end;
13720 end;
13721 
13722 procedure TQtCheckListBox.signalSelectionChanged(); cdecl;
13723 begin
13724   // DO NOTHING
13725   // inherited signalSelectionChanged;
13726 end;
13727 
13728 procedure TQtCheckListBox.signalItemChanged(item: QListWidgetItemH); cdecl;
13729 var
13730   Msg: TLMessage;
13731 begin
13732   if InUpdate or not GetVisible then
13733     exit;
13734   FillChar(Msg{%H-}, SizeOf(Msg), #0);
13735   Msg.Msg := LM_CHANGED;
13736   Msg.WParam := PtrInt(QListWidget_row(QListWidgetH(Widget), Item));
13737   DeliverMessage(Msg);
13738 end;
13739 
TQtCheckListBox.GetItemCheckStatenull13740 function TQtCheckListBox.GetItemCheckState(AIndex: Integer): QtCheckState;
13741 var
13742   AItem: QListWidgetItemH;
13743 begin
13744   Result := QtUnChecked;
13745   if (AIndex >= 0) and (AIndex < rowCount) then
13746   begin
13747     AItem := QListWidget_item(QListWidgetH(Widget), AIndex);
13748     if AItem <> nil then
13749       Result := QListWidgetItem_checkState(AItem);
13750   end;
13751 end;
13752 
13753 procedure TQtCheckListBox.SetItemCheckState(AIndex: Integer;
13754   AValue: QtCheckState);
13755 var
13756   AItem: QListWidgetItemH;
13757 begin
13758   if (AIndex >= 0) and (AIndex < rowCount) then
13759   begin
13760     AItem := QListWidget_item(QListWidgetH(Widget), AIndex);
13761     if AItem <> nil then
13762     begin
13763       QListWidgetItem_setCheckState(AItem, AValue);
13764       SetItemLastCheckState(AItem);
13765     end;
13766   end;
13767 end;
13768 
13769 { TQtHeaderView }
13770 
TQtHeaderView.getClickablenull13771 function TQtHeaderView.getClickable: Boolean;
13772 begin
13773   Result := QHeaderView_isClickable(QHeaderViewH(Widget));
13774 end;
13775 
getMinSectionSizenull13776 function TQtHeaderView.getMinSectionSize: Integer;
13777 begin
13778   Result := QHeaderView_minimumSectionSize(QHeaderViewH(Widget));
13779 end;
13780 
TQtHeaderView.SortIndicatorOrdernull13781 function TQtHeaderView.SortIndicatorOrder: QtSortOrder;
13782 begin
13783   Result := QHeaderView_sortIndicatorOrder(QHeaderViewH(Widget));
13784 end;
13785 
13786 procedure TQtHeaderView.setClickable(const AValue: Boolean);
13787 begin
13788   QHeaderView_setClickable(QHeaderViewH(Widget), AValue);
13789 end;
13790 
13791 procedure TQtHeaderView.setMinSectionSize(const AValue: Integer);
13792 begin
13793   QHeaderView_setMinimumSectionSize(QHeaderViewH(Widget), AValue);
13794 end;
13795 
13796 procedure TQtHeaderView.SetSortIndicator(const AColumn: Integer;
13797   const AOrder: QtSortOrder);
13798 begin
13799   QHeaderView_setSortIndicator(QHeaderViewH(Widget), AColumn, AOrder);
13800 end;
13801 
13802 procedure TQtHeaderView.SetSortIndicatorVisible(AVisible: Boolean);
13803 begin
13804   QHeaderView_setSortIndicatorShown(QHeaderViewH(Widget), AVisible);
13805 end;
13806 
13807 {------------------------------------------------------------------------------
13808   Function: TQtHeaderView.CreateWidget
13809   Params:  None
13810   Returns: Widget (QHeaderViewH)
13811  ------------------------------------------------------------------------------}
CreateWidgetnull13812 function TQtHeaderView.CreateWidget(const AParams: TCreateParams):QWidgetH;
13813 var
13814   Parent: QWidgetH;
13815 begin
13816   // Creates the widget
13817   {$ifdef VerboseQt}
13818     WriteLn('TQtHeaderView.Create');
13819   {$endif}
13820   if AParams.WndParent <> 0 then
13821     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
13822   else
13823     Parent := nil;
13824 
13825   Result := QHeaderView_create(QtHorizontal, Parent);
13826 end;
13827 
13828 procedure TQtHeaderView.AttachEvents;
13829 begin
13830   inherited AttachEvents;
13831   FSectionClicked := QHeaderView_hook_create(Widget);
13832   QHeaderView_hook_hook_sectionClicked(FSectionClicked, @SignalSectionClicked);
13833 end;
13834 
13835 procedure TQtHeaderView.DetachEvents;
13836 begin
13837   if FSectionClicked <> nil then
13838   begin
13839     QHeaderView_hook_destroy(FSectionClicked);
13840     FSectionClicked := nil;
13841   end;
13842   inherited DetachEvents;
13843 end;
13844 
TQtHeaderView.EventFilternull13845 function TQtHeaderView.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
13846   cdecl;
13847 begin
13848   Result := False;
13849   QEvent_accept(Event);
13850   if (FOwner <> nil) and (LCLObject <> nil) then
13851   begin
13852     if (FChildOfComplexWidget = ccwTreeWidget) and
13853       (QEvent_type(Event) = QEventFocusIn) then
13854     begin
13855       Result := True;
13856       QEvent_ignore(Event);
13857       QWidget_setFocus(FOwner.Widget);
13858     end;
13859   end;
13860 end;
13861 
itemViewViewportEventFilternull13862 function TQtHeaderView.itemViewViewportEventFilter(Sender: QObjectH;
13863   Event: QEventH): Boolean; cdecl;
13864 begin
13865   Result := False;
13866   QEvent_accept(Event);
13867   case QEvent_type(Event) of
13868     QEventMouseButtonPress,
13869     QEventMouseButtonRelease,
13870     QEventMouseButtonDblClick: ; {do nothing here - signal is fired}
13871     else
13872       Result := inherited itemViewViewportEventFilter(Sender, Event);
13873   end;
13874 end;
13875 
13876 {------------------------------------------------------------------------------
13877   Function: TQtHeaderView.SignalSectionClicked
13878   Params:  None
13879   Returns: Nothing
13880  ------------------------------------------------------------------------------}
13881 procedure TQtHeaderView.SignalSectionClicked(logicalIndex: Integer); cdecl;
13882 var
13883   Msg: TLMNotify;
13884   NMLV: TNMListView;
13885 begin
13886   {$ifdef VerboseQt}
13887   writeln('TQtHeaderView.signalSectionClicked index ',logicalIndex);
13888   {$endif}
13889 
13890   FillChar(Msg{%H-}, SizeOf(Msg), #0);
13891   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
13892 
13893   Msg.Msg := CN_NOTIFY;
13894   NMLV.hdr.hwndfrom := LCLObject.Handle;
13895   NMLV.hdr.code := LVN_COLUMNCLICK;
13896   NMLV.iItem := -1;
13897   NMLV.iSubItem := logicalIndex;
13898 
13899   Msg.NMHdr := @NMLV.hdr;
13900 
13901   DeliverMessage(Msg);
13902 
13903 end;
13904 
getResizeModenull13905 function TQtHeaderView.getResizeMode(AIndex: Integer): QHeaderViewResizeMode;
13906 begin
13907   Result := QHeaderView_resizeMode(QHeaderViewH(Widget), AIndex);
13908 end;
13909 
13910 procedure TQtHeaderView.setResizeMode(AResizeMode: QHeaderViewResizeMode);
13911 begin
13912   QHeaderView_setResizeMode(QHeaderViewH(Widget), AResizeMode);
13913 end;
13914 
13915 procedure TQtHeaderView.setResizeMode(AIndex: Integer;
13916   AResizeMode: QHeaderViewResizeMode);
13917 begin
13918   QHeaderView_setResizeMode(QHeaderViewH(Widget), AIndex, AResizeMode);
13919 end;
13920 
sectionSizenull13921 function TQtHeaderView.sectionSize(AIndex: Integer): Integer;
13922 begin
13923   Result := QHeaderView_sectionSize(QHeaderViewH(Widget), AIndex);
13924 end;
13925 
sectionSizeHintnull13926 function TQtHeaderView.sectionSizeHint(AIndex: Integer): Integer;
13927 begin
13928   Result := QHeaderView_sectionSizeHint(QHeaderViewH(Widget), AIndex);
13929 end;
13930 
13931 procedure TQtHeaderView.moveSection(AFromIndex: Integer; AToIndex: Integer);
13932 begin
13933   QHeaderView_moveSection(QHeaderViewH(Widget), AFromIndex, AToIndex);
13934 end;
13935 
13936 procedure TQtHeaderView.resizeSection(ASection: Integer; ASize: Integer);
13937 begin
13938   QHeaderView_resizeSection(QHeaderViewH(Widget), ASection, ASize);
13939 end;
13940 
13941 procedure TQtHeaderView.setHighlightSections(AValue: Boolean);
13942 begin
13943   QHeaderView_setHighlightSections(QHeaderViewH(Widget), AValue);
13944 end;
13945 
13946 procedure TQtHeaderView.setDefaultSectionSize(AValue: Integer);
13947 begin
13948   QHeaderView_setDefaultSectionSize(QHeaderViewH(Widget), AValue);
13949 end;
13950 
13951 procedure TQtHeaderView.setStretchLastSection(AValue: Boolean);
13952 begin
13953   QHeaderView_setStretchLastSection(QHeaderViewH(Widget), AValue);
13954 end;
13955 
13956   { TQtTreeView }
13957 
getColVisiblenull13958 function TQtTreeView.getColVisible(AIndex: Integer): Boolean;
13959 begin
13960   Result := not QTreeView_isColumnHidden(QTreeViewH(Widget), AIndex);
13961 end;
13962 
getColWidthnull13963 function TQtTreeView.getColWidth(AIndex: Integer): Integer;
13964 begin
13965   Result := QTreeView_columnWidth(QTreeViewH(Widget), AIndex);
13966 end;
13967 
GetUniformRowHeightsnull13968 function TQtTreeView.GetUniformRowHeights: Boolean;
13969 begin
13970   Result := QTreeView_uniformRowHeights(QTreeViewH(Widget));
13971 end;
13972 
13973 procedure TQtTreeView.setColVisible(AIndex: Integer; const AValue: Boolean);
13974 begin
13975   QTreeView_setColumnHidden(QTreeViewH(Widget), AIndex, not AValue);
13976 end;
13977 
13978 procedure TQtTreeView.setColWidth(AIndex: Integer; const AValue: Integer);
13979 begin
13980   QTreeView_setColumnWidth(QTreeViewH(Widget), AIndex, AValue);
13981 end;
13982 
13983 procedure TQtTreeView.SetUniformRowHeights(const AValue: Boolean);
13984 begin
13985   QTreeView_setUniformRowHeights(QTreeViewH(Widget), AValue);
13986 end;
13987 
13988 procedure TQtTreeView.setWordWrap(const AValue: Boolean);
13989 begin
13990   QTreeView_setWordWrap(QTreeViewH(Widget), AValue);
13991 end;
13992 
13993 procedure TQtTreeView.setRootIsDecorated(AValue: Boolean);
13994 begin
13995   QTreeView_setRootIsDecorated(QTreeViewH(Widget), AValue);
13996 end;
13997 
13998 procedure TQtTreeView.setAllColumnsShowFocus(AValue: Boolean);
13999 begin
14000   QTreeView_setAllColumnsShowFocus(QTreeViewH(Widget), AValue);
14001 end;
14002 
14003 {------------------------------------------------------------------------------
14004   Function: TQtTreeView.CreateWidget
14005   Params:  None
14006   Returns: Widget (QTreeViewH)
14007  ------------------------------------------------------------------------------}
TQtTreeView.CreateWidgetnull14008 function TQtTreeView.CreateWidget(const AParams: TCreateParams):QWidgetH;
14009 var
14010   Parent: QWidgetH;
14011 begin
14012   // Creates the widget
14013   {$ifdef VerboseQt}
14014     WriteLn('TQtTreeView.Create');
14015   {$endif}
14016   if AParams.WndParent <> 0 then
14017     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
14018   else
14019     Parent := nil;
14020   Result := QTreeView_create(Parent);
14021 end;
14022 
14023   { TQtTreeWidget }
14024 
14025 {------------------------------------------------------------------------------
14026   Function: TQtTreeWidget.CreateWidget
14027   Params:  None
14028   Returns: Widget (QTreeWidgetH)
14029  ------------------------------------------------------------------------------}
CreateWidgetnull14030 function TQtTreeWidget.CreateWidget(const AParams: TCreateParams):QWidgetH;
14031 var
14032   Parent: QWidgetH;
14033 begin
14034   {$ifdef VerboseQt}
14035     WriteLn('TQtTreeWidget.Create');
14036   {$endif}
14037   FDelayedCheckItem := nil;
14038   AllowGrayed := False;
14039   FSelection := TFPList.Create;
14040   FSavedEvent := nil;
14041   FSavedEventTimer := nil;
14042   FSavedEventTimerHook := nil;
14043   FViewStyle := -1;
14044   FCheckable := False;
14045   FHideSelection := False;
14046   FOwnerData := False;
14047   FSyncingItems := False;
14048   {$IFDEF TEST_QT_SORTING}
14049   FCanSort := False;
14050   FSorting := False;
14051   {$ENDIF}
14052   if AParams.WndParent <> 0 then
14053     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
14054   else
14055     Parent := nil;
14056   Result := QTreeWidget_create(Parent);
14057   FHeader := nil;
14058 end;
14059 
14060 {------------------------------------------------------------------------------
14061   Function: TQtTreeWidget.Destroy
14062   Params:  None
14063   Returns: Nothing
14064  ------------------------------------------------------------------------------}
14065 destructor TQtTreeWidget.Destroy;
14066 begin
14067   {$ifdef VerboseQt}
14068     WriteLn('TQtTreeWidget.Destroy');
14069   {$endif}
14070   FSelection.Free;
14071   if Assigned(FHeader) then
14072     FHeader.Free;
14073 
14074   inherited Destroy;
14075 end;
14076 
14077 procedure TQtTreeWidget.DestroyNotify(AWidget: TQtWidget);
14078 begin
14079   if AWidget = FHeader then
14080     FHeader := nil;
14081   inherited DestroyNotify(AWidget);
14082 end;
14083 
TQtTreeWidget.EventFilternull14084 function TQtTreeWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
14085   cdecl;
14086 var
14087   item: QTreeWidgetItemH;
14088 begin
14089   Result := False;
14090   QEvent_accept(Event);
14091   if LCLObject = nil then
14092     exit;
14093   if QEvent_Type(Event) = QEventResize then
14094     // let the viewport send resize
14095   else
14096   if Checkable then
14097   begin
14098     if (QEvent_type(Event) = QEventKeyPress) and
14099       (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
14100       (QKeyEvent_modifiers(QKeyEventH(Event)) and QtControlModifier = 0) then
14101     begin
14102       Result:=inherited EventFilter(Sender, Event);
14103       if not Result then
14104       begin
14105         Item := currentItem;
14106         if Item <> nil then
14107         begin
14108           Item := topLevelItem(getRow(Item));
14109           if (Item <> nil) and
14110             ((QTreeWidget_currentColumn(QTreeWidgetH(Widget)) = 0) or
14111             TCustomListView(LCLObject).RowSelect) then
14112           HandleCheckChangedEvent(QtPoint(0, 0), Item, Event);
14113           if OwnerDrawn then
14114           begin
14115             if QTreeWidgetItem_checkState(Item, 0) = QtUnChecked then
14116               QTreeWidgetItem_setCheckState(Item, 0, QtChecked)
14117             else
14118               QTreeWidgetItem_setCheckState(Item, 0, QtUnchecked);
14119           end;
14120         end;
14121       end else
14122         QEvent_ignore(Event);
14123     end else
14124       Result:=inherited EventFilter(Sender, Event);
14125   end else
14126   if ((QEvent_type(Event) = QEventMouseButtonPress) or
14127     (QEvent_type(Event) = QEventMouseButtonRelease))
14128     and (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
14129     {eat mouse button events -> signalItemClicked is fired}
14130   else
14131     Result:=inherited EventFilter(Sender, Event);
14132 end;
14133 
14134 procedure TQtTreeWidget.SetItemLastCheckStateInternal(AItem: QTreeWidgetItemH;
14135   AState: QtCheckState);
14136 var
14137   v: QVariantH;
14138 begin
14139   v := QVariant_create(Ord(AState));
14140   QTreeWidgetItem_setData(AItem, 0, QtCheckStateRole, v);
14141   QVariant_destroy(v);
14142 end;
14143 
14144 procedure TQtTreeWidget.HandleCheckChangedEvent(const AMousePos: TQtPoint;
14145   AItem: QTreeWidgetItemH; AEvent: QEventH);
14146 var
14147   xx: Integer;
14148   B: Boolean;
14149   R: TRect;
14150 
14151   procedure SendMessage(AnItem: QTreeWidgetItemH);
14152   var
14153     Msg: TLMNotify;
14154     NMLV: TNMListView;
14155   begin
14156 
14157     FillChar(Msg{%H-}, SizeOf(Msg), #0);
14158     FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
14159 
14160     Msg.Msg := CN_NOTIFY;
14161 
14162     NMLV.hdr.hwndfrom := LCLObject.Handle;
14163     NMLV.hdr.code := LVN_ITEMCHANGED;
14164 
14165 
14166     NMLV.iItem := GetRow(AnItem);
14167 
14168     NMLV.uOldState := UINT(Ord(not B));
14169     NMLV.uNewState := UINT(Ord(B));
14170     NMLV.uChanged := LVIF_STATE;
14171 
14172     Msg.NMHdr := @NMLV.hdr;
14173     {$IFDEF QT_DEBUGTQTTREEWIDGET}
14174     DebugLn('TQtTreeWidget.HandleCheckableMouseDown sending LVN_ITEMCHANGED Checked ',dbgs(B));
14175     {$ENDIF}
14176     DeliverMessage(Msg);
14177   end;
14178 
14179 begin
14180   if not Checkable or (AItem = nil) or (ViewStyle < 0) then
14181     exit;
14182 
14183   if ((QEvent_type(AEvent) = QEventMouseButtonPress) or
14184     (QEvent_type(AEvent) = QEventMouseButtonDblClick)) and
14185   (QMouseEvent_button(QMouseEventH(AEvent)) = QtLeftButton) then
14186   begin
14187     if (QTreeWidgetItem_flags(AItem) and QtItemIsUserCheckable) <> 0 then
14188     begin
14189       xx := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
14190       R := visualItemRect(AItem);
14191       if ((AMousePos.X > 2) and (AMousePos.X <= (xx + 2)))
14192         and (AMousePos.Y > R.Top + 1) and (AMousePos.Y < (R.Bottom - 2))  then
14193       begin
14194         B := QTreeWidgetItem_checkState(AItem, 0) = QtUnChecked;
14195         if B then
14196           SetItemLastCheckStateInternal(AItem, QtChecked)
14197         else
14198           SetItemLastCheckStateInternal(AItem, QtUnChecked);
14199 
14200         // if AItem is deleted in mouse event FDelayedCheckItem becomes nil and that's fine. issue #32869
14201         FDelayedCheckItem := AItem;
14202         SendMessage(AItem);
14203       end;
14204     end;
14205   end else
14206   if (QEvent_type(AEvent) = LCLQt_ItemViewAfterMouseRelease) then
14207   begin
14208     if (FDelayedCheckItem <> nil) and (FDelayedCheckItem <> AItem) then
14209     begin
14210       SetItemLastCheckStateInternal(FDelayedCheckItem, QTreeWidgetItem_checkState(FDelayedCheckItem, 0));
14211       SendMessage(FDelayedCheckItem);
14212     end;
14213     if FDelayedCheckItem = nil then // issue #32869
14214       exit;
14215     FDelayedCheckItem := nil;
14216     SetItemLastCheckStateInternal(AItem, QTreeWidgetItem_checkState(AItem, 0));
14217     SendMessage(AItem);
14218   end else
14219   if (QEvent_type(AEvent) = QEventKeyPress) and
14220     (QKeyEvent_key(QKeyEventH(AEvent)) = QtKey_Space) then
14221   begin
14222     FDelayedCheckItem := nil;
14223     B := QTreeWidgetItem_checkState(AItem, 0) = QtUnChecked;
14224     if B then
14225       SetItemLastCheckStateInternal(AItem, QtChecked)
14226     else
14227       SetItemLastCheckStateInternal(AItem, QtUnChecked);
14228 
14229     SendMessage(AItem);
14230   end;
14231 end;
14232 
GetItemLastCheckStateInternalnull14233 function TQtTreeWidget.GetItemLastCheckStateInternal(AItem: QTreeWidgetItemH
14234   ): QtCheckState;
14235 var
14236   v: QVariantH;
14237   ok: Boolean;
14238 begin
14239   Result := QtUnChecked;
14240   if AItem = nil then
14241     exit;
14242   v := QVariant_create();
14243   QTreeWidgetItem_data(AItem, v,  0, QtCheckStateRole);
14244   ok := False;
14245   if QVariant_isValid(v) then
14246     Result := QtCheckState(QVariant_toInt(v, @Ok));
14247   QVariant_destroy(v);
14248 end;
14249 
itemViewViewportEventFilternull14250 function TQtTreeWidget.itemViewViewportEventFilter(Sender: QObjectH;
14251   Event: QEventH): Boolean; cdecl;
14252 var
14253   MousePos: TQtPoint;
14254   Item: QTreeWidgetItemH;
14255   ALCLEvent: QLCLMessageEventH;
14256   AMsgData: PtrUInt;
14257   W: QHeaderViewH;
14258   R: TRect;
14259   DC: TQtDeviceContext;
14260   x: Integer;
14261 begin
14262   Result := False;
14263   QEvent_accept(Event);
14264   if LCLObject = nil then
14265     exit;
14266   BeginEventProcessing;
14267   try
14268     if (QEvent_type(Event) = QEventPaint) and
14269       not Self.FOwnerData and (Sender = viewportWidget) then
14270     begin
14271       HasPaint := True;
14272       QPaintEvent_rect(QPaintEventH(Event), @R);
14273       DC := TQtDeviceContext.Create(QWidgetH(Sender), True);
14274       try
14275         TCustomListViewAccess(LCLObject).Canvas.handle := HDC(DC);
14276         TCustomListViewAccess(LCLObject).IntfCustomDraw(dtControl, cdPrePaint, 0, 0, [], @R);
14277       finally
14278         TCustomListViewAccess(LCLObject).Canvas.handle := 0;
14279         DC.Free;
14280       end;
14281     end else
14282     if (ViewStyle = Ord(vsReport)) and Checkable and getEnabled then
14283     begin
14284       if QEvent_type(Event) = LCLQt_ItemViewAfterMouseRelease then
14285       begin
14286         ALCLEvent := QLCLMessageEventH(Event);
14287         Item := QTreeWidgetItemH(QLCLMessageEvent_getLParam(ALCLEvent));
14288         // sync lcl with qt state. This is needed only when mouse is pressed
14289         // and moved out of item, or pressed on item and released over checkbox
14290         if (Item <> nil) and (GetItemLastCheckStateInternal(Item) <>
14291           QTreeWidgetItem_checkState(Item, 0)) then
14292         begin
14293           MousePos := QtPoint(0, 0); // shutup compiler
14294           if QLCLMessageEvent_getMsg(ALCLEvent) > 0 then
14295             QTreeWidgetItem_setCheckState(Item, 0, GetItemLastCheckStateInternal(Item));
14296 
14297           HandleCheckChangedEvent(MousePos, Item, Event);
14298         end;
14299       end else
14300       if ((QEvent_type(Event) = QEventMouseButtonPress) or
14301       (QEvent_type(Event) = QEventMouseButtonDblClick)) then
14302       begin
14303         MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
14304         Item := itemAt(MousePos.x, MousePos.y);
14305         Result := inherited itemViewViewportEventFilter(Sender, Event);
14306 
14307         if Item <> nil then
14308           HandleCheckChangedEvent(MousePos, Item, Event);
14309       end else
14310       if (QEvent_type(Event) = QEventMouseButtonRelease) then
14311       begin
14312         if OwnerDrawn and Checkable then
14313         begin
14314           MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
14315           Item := itemAt(MousePos.x, MousePos.y);
14316           if (Item <> nil) and
14317             ((QTreeWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
14318           begin
14319             x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
14320             if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
14321             begin
14322               if QTreeWidgetItem_checkState(Item, 0) = QtUnchecked then
14323                 QTreeWidgetItem_setCheckState(Item, 0, QtChecked)
14324               else
14325                 QTreeWidgetItem_setCheckState(Item, 0, QtUnChecked);
14326             end;
14327           end;
14328           Result := SlotMouse(Sender, Event);
14329         end else
14330         begin
14331           if Checkable then
14332           begin
14333             MousePos := QMouseEvent_pos(QMouseEventH(Event))^;
14334             Item := itemAt(MousePos.x, MousePos.y);
14335             if Item <> nil then
14336             begin
14337               Item := topLevelItem(GetRow(Item));
14338               if Assigned(LCLObject) and LCLObject.Dragging then
14339                 AMsgData := Ord(QTreeWidgetItem_checkState(Item, 0)) + 1
14340               else
14341                 AMsgData := 0;
14342               ALCLEvent := QLCLMessageEvent_create(LCLQt_ItemViewAfterMouseRelease, AMsgData,
14343                 PtrUInt(Item), PtrUInt(Item), 0);
14344               QCoreApplication_postEvent(Sender, ALCLEvent);
14345             end;
14346           end;
14347           Result := inherited itemViewViewportEventFilter(Sender, Event);
14348         end;
14349       end else
14350       if (QEvent_type(Event) = QEventMouseMove) and (LCLObject <> nil) then
14351       begin
14352         W := QTreeView_header(QTreeViewH(Widget));
14353         if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
14354         begin
14355           BeginEventProcessing;
14356           try
14357             Result := SlotMouseMove(Sender, Event);
14358             // allow dnd inside listview (vsReport and vsList only).
14359             if not Result and Assigned(LCLObject) and LCLObject.Dragging then
14360               Result := True;
14361           finally
14362             EndEventProcessing;
14363           end;
14364         end else
14365           Result := inherited itemViewViewportEventFilter(Sender, Event);
14366       end;
14367     end else
14368     begin
14369       if (QEvent_type(Event) = QEventMouseMove) and (LCLObject <> nil) then
14370       begin
14371         W := QTreeView_header(QTreeViewH(Widget));
14372         if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
14373         begin
14374           BeginEventProcessing;
14375           try
14376             Result := SlotMouseMove(Sender, Event);
14377             // allow dnd inside listview (vsReport and vsList only).
14378             if not Result and Assigned(LCLObject) and LCLObject.Dragging then
14379               Result := True;
14380           finally
14381             EndEventProcessing;
14382           end;
14383         end else
14384           Result := inherited itemViewViewportEventFilter(Sender, Event);
14385       end else
14386         Result := inherited itemViewViewportEventFilter(Sender, Event);
14387     end;
14388   finally
14389     EndEventProcessing;
14390   end;
14391 end;
14392 
14393 procedure TQtTreeWidget.OwnerDataNeeded(ARect: TRect);
14394 var
14395   R: TRect;
14396   TopItem: Integer;
14397   i: Integer;
14398   j: Integer;
14399   ChildCount: Integer;
14400   VHeight: Integer; // viewport height
14401   RowHeight, AImagesWidth: Integer;
14402   item: QTreeWidgetItemH;
14403   itemChild: QTreeWidgetItemH;
14404   v,v2,v3: QVariantH;
14405   WStr, TempStr: WideString;
14406   ASelected: Boolean;
14407   ImgList: TCustomImageList;
14408   AImageIndex: TImageIndex;
14409   Bmp: TBitmap;
14410   AOk, AStateImages: Boolean;
14411   AIcon: QIconH;
14412   ASize: TSize;
14413   ImgListRes: TScaledImageListResolution;
14414 begin
14415   {do not set items during design time}
14416   if csDesigning in LCLObject.ComponentState then
14417     exit;
14418 
14419   if QTreeWidget_topLevelItemCount(QTreeWidgetH(Widget)) < 1 then
14420     exit;
14421 
14422   {TODO: add QtDecorationRole (icon) etc ... }
14423   QWidget_contentsRect(viewportWidget, @R);
14424   VHeight := R.Bottom - R.Top;
14425 
14426   item := QTreeWidget_itemAt(QTreeWidgetH(Widget), 0, 1);
14427   if item <> nil then
14428   begin
14429 
14430     TopItem := getRow(item);
14431     RowHeight := getRowHeight(TopItem);
14432 
14433     if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
14434       exit;
14435 
14436     i := 0;
14437     while (i < (VHeight + RowHeight)) do
14438     begin
14439       item := QTreeWidget_itemAt(QTreeWidgetH(Widget), 0, i + 1);
14440       if item <> nil then
14441       begin
14442 
14443         TopItem := getRow(item);
14444         RowHeight := getRowHeight(TopItem);
14445         if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
14446           continue;
14447 
14448         WStr := TCustomListViewHack(LCLObject){%H-}.Items[TopItem].Caption;
14449         ASelected := TCustomListViewHack(LCLObject).Items[TopItem].Selected;
14450 
14451         v := QVariant_create(PWideString(@WStr));
14452         try
14453           v2 := QVariant_create;
14454           try
14455             TempStr := '';
14456             QTreeWidgetItem_data(item, v2, 0, Ord(QtDisplayRole));
14457             if not QVariant_isNull(v2) then
14458               QVariant_toString(v2, @TempStr);
14459             if TempStr <> WStr then
14460               QTreeWidgetItem_setData(item, 0, Ord(QtDisplayRole), v);
14461           finally
14462             QVariant_destroy(v2);
14463           end;
14464 
14465           AStateImages := False;
14466           // set imageindex, part of comment in issue #27233
14467           ImgList := TCustomListViewHack(LCLObject).SmallImages;
14468           if Assigned(ImgList) then
14469             AImagesWidth := TCustomListViewHack(LCLObject).SmallImagesWidth
14470           else
14471           begin
14472             ImgList := TCustomListViewHack(LCLObject).StateImages;
14473             if Assigned(ImgList) then
14474               AImagesWidth := TCustomListViewHack(LCLObject).StateImagesWidth;
14475             AStateImages := True;
14476           end;
14477           if Assigned(ImgList) then
14478           begin
14479             ImgListRes := ImgList.ResolutionForPPI[
14480               AImagesWidth,
14481               TCustomListViewHack(LCLObject).Font.PixelsPerInch,
14482               TCustomListViewHack(LCLObject).GetCanvasScaleFactor];
14483             QTreeWidgetItem_sizeHint(item, @ASize, 0);
14484             if (ASize.cx <> ImgListRes.Width) or (ASize.cx <> ImgListRes.Height) then
14485             begin
14486               ASize.cx := ImgListRes.Width;
14487               ASize.cy := ImgListRes.Height;
14488               QTreeWidgetItem_setSizeHint(item, 0, @ASize);
14489             end;
14490             if AStateImages then
14491               AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].StateIndex
14492             else
14493               AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].ImageIndex;
14494             if (ImgListRes.Count > 0) and
14495               ((AImageIndex >= 0) and (AImageIndex < ImgListRes.Count)) then
14496             begin
14497               Bmp := TBitmap.Create;
14498               try
14499                 ImgListRes.GetBitmap(AImageIndex, Bmp);
14500                 v2 := QVariant_create;
14501                 QTreeWidgetItem_data(item, v2, 0, QtListViewOwnerDataRole);
14502                 if not QVariant_isNull(v2) then
14503                 begin
14504                   AOk := True;
14505                   if QVariant_toInt(v2, @AOk) <> AImageIndex then
14506                   begin
14507                     v2 := QVariant_create(AImageIndex);
14508                     QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v2);
14509                     QVariant_destroy(v2);
14510                     QTreeWidgetItem_setIcon(item, 0, TQtImage(Bmp.Handle).AsIcon)
14511                   end;
14512                   // else we are imageIndex and that''s fine.
14513                 end else
14514                 begin
14515                   v2 := QVariant_create(AImageIndex);
14516                   QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v2);
14517                   QVariant_destroy(v2);
14518                   QTreeWidgetItem_setIcon(item, 0, TQtImage(Bmp.Handle).AsIcon);
14519                 end;
14520               finally
14521                 Bmp.Free;
14522               end;
14523             end else
14524             if (AImageIndex < 0) then
14525             begin
14526               v2 := QVariant_create;
14527               AIcon := QIcon_create;
14528               try
14529                 QTreeWidgetItem_data(item, v2, 0, QtListViewOwnerDataRole);
14530                 if not QVariant_isNull(v2) then
14531                 begin
14532                   v3 := QVariant_create;
14533                   try
14534                     QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v3);
14535                   finally
14536                     QVariant_destroy(v3);
14537                   end;
14538                 end;
14539                 QTreeWidgetItem_icon(item, AIcon, 0);
14540                 if not QIcon_isNull(AIcon) then
14541                   QTreeWidgetItem_setIcon(item, 0, nil);
14542               finally
14543                 QVariant_destroy(v2);
14544                 QIcon_destroy(AIcon);
14545               end;
14546             end;
14547           end;
14548 
14549           // set alignment, issue #27233
14550           if TCustomListViewHack(LCLObject).Columns.Count > 0 then
14551           begin
14552             case TCustomListViewHack(LCLObject).Column[0].Alignment of
14553               taRightJustify: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignRight);
14554               taCenter: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignCenter);
14555               taLeftJustify: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignLeft);
14556             end;
14557           end;
14558         finally
14559           QVariant_destroy(v);
14560         end;
14561 
14562         ChildCount := QTreeWidgetItem_childCount(Item);
14563         if ChildCount = TCustomListViewHack(LCLObject).Items[TopItem].SubItems.Count then
14564         begin
14565           for j := 0 to ChildCount - 1 do
14566           begin
14567             itemChild := QTreeWidgetItem_child(item, j);
14568             if itemChild <> nil then
14569             begin
14570               WStr := TCustomListViewHack(LCLObject){%H-}.Items[TopItem].SubItems[j];
14571               v := QVariant_create(PWideString(@WStr));
14572               v2 := QVariant_create;
14573               try
14574                 TempStr := '';
14575                 QTreeWidgetItem_data(itemChild, v2, j, Ord(QtDisplayRole));
14576                 if not QVariant_isNull(v2) then
14577                   QVariant_toString(v2, @TempStr);
14578                 if TempStr <> WStr then
14579                   QTreeWidgetItem_setData(itemChild, j, Ord(QtDisplayRole), v);
14580               finally
14581                 QVariant_destroy(v2);
14582                 QVariant_destroy(v);
14583               end;
14584             end;
14585           end;
14586         end else
14587         begin
14588           for j := 0 to TCustomListViewHack(LCLObject).Items[TopItem].SubItems.Count - 1 do
14589           begin
14590             WStr := TCustomListViewHack(LCLObject){%H-}.Items[TopItem].SubItems[j];
14591             v := QVariant_create(PWideString(@WStr));
14592             QTreeWidgetItem_setData(item, j + 1, Ord(QtDisplayRole), v);
14593 
14594             // set alignment, issue #27233
14595             if (TCustomListViewHack(LCLObject).Columns.Count > 0) then
14596             begin
14597               case TCustomListViewHack(LCLObject).Column[j + 1].Alignment of
14598                 taRightJustify: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignRight);
14599                 taCenter: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignCenter);
14600                 taLeftJustify: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignLeft);
14601               end;
14602             end;
14603             QVariant_destroy(v);
14604           end;
14605         end;
14606         if QTreeWidgetItem_isSelected(Item) <> ASelected then
14607           QTreeWidgetItem_setSelected(Item, ASelected);
14608       end;
14609 
14610       inc(i, RowHeight);
14611     end;
14612   end;
14613 end;
14614 
14615 procedure TQtTreeWidget.ItemDelegatePaint(painter: QPainterH;
14616   option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
14617 var
14618   Msg: TLMDrawListItem;
14619   DrawStruct: TDrawListItemStruct;
14620   State: QStyleState;
14621   R: TRect;
14622   ItemIndex, SubItemIndex: Integer;
14623   ACustomState: TCustomDrawState;
14624   ATarget: TCustomDrawTarget;
14625   TmpDC1, TmpDC2: HDC;
14626   SkipDefault: Boolean;
14627   APaintResult: TCustomDrawResult;
14628 
14629   function IsItemEmpty: boolean;
14630   var
14631     AText: WideString;
14632     AIcon: QIconH;
14633   begin
14634     QTreeWidgetItem_text(topLevelItem(ItemIndex), @AText, SubItemIndex);
14635     AIcon := QIcon_create;
14636     QTreeWidgetItem_icon(topLevelItem(ItemIndex), AIcon, SubItemIndex);
14637     Result := (AText = '') and QIcon_isNull(AIcon);
14638     QIcon_destroy(AIcon);
14639   end;
14640 
14641 begin
14642   if TCustomListViewAccess(LCLObject).OwnerDraw and (ViewStyle = Ord(vsReport)) then
14643   begin
14644     QPainter_save(painter);
14645     State := QStyleOption_state(option);
14646     DrawStruct.ItemID := UINT(QModelIndex_row(index));
14647 
14648     DrawStruct.Area := visualRect(index);
14649     DrawStruct.DC := HDC(TQtDeviceContext.CreateFromPainter(painter));
14650 
14651     DrawStruct.ItemState := [];
14652     // selected
14653     if (State and QStyleState_Selected) <> 0 then
14654       Include(DrawStruct.ItemState, odSelected);
14655     // disabled
14656     if (State and QStyleState_Enabled) = 0 then
14657       Include(DrawStruct.ItemState, odDisabled);
14658     // focused (QStyleState_FocusAtBorder?)
14659     if (State and QStyleState_HasFocus) <> 0 then
14660       Include(DrawStruct.ItemState, odFocused);
14661     // hotlight
14662     if (State and QStyleState_MouseOver) <> 0 then
14663       Include(DrawStruct.ItemState, odHotLight);
14664 
14665     // checked does not work as we expected.
14666     if Checkable and (QModelIndex_column(index) <= 0) then
14667     begin
14668       // if (State and QStyleState_On <> 0) and (ATarget = dtItem) then
14669       //  Include(ACustomState, cdsChecked);
14670       if  QTreeWidgetItem_checkState(topLevelItem(QModelIndex_row(index)), 0) <> QtUnchecked then
14671         Include(DrawStruct.ItemState, odChecked);
14672     end;
14673 
14674     { todo: over states:
14675 
14676       odGrayed, odChecked,
14677       odDefault, odInactive, odNoAccel,
14678       odNoFocusRect, odReserved1, odReserved2, odComboBoxEdit
14679     }
14680     Msg.Msg := CN_DRAWITEM;
14681     Msg.DrawListItemStruct := @DrawStruct;
14682     DeliverMessage(Msg);
14683 
14684     QPainter_restore(painter);
14685 
14686     TQtDeviceContext(DrawStruct.DC).Free;
14687   end else
14688   begin
14689     State := QStyleOption_state(option);
14690     ACustomState := [cdsDefault];
14691 
14692     if (State and QStyleState_Selected) <> 0 then
14693       Include(ACustomState, cdsSelected);
14694     // disabled
14695     if (State and QStyleState_Enabled) = 0 then
14696       Include(ACustomState, cdsDisabled);
14697     // focused (QStyleState_FocusAtBorder?)
14698     if (State and QStyleState_HasFocus) <> 0 then
14699       Include(ACustomState, cdsFocused);
14700     // hotlight
14701     if (State and QStyleState_MouseOver) <> 0 then
14702       Include(ACustomState, cdsHot);
14703 
14704     ItemIndex := QModelIndex_row(index);
14705     SubItemIndex := QModelIndex_column(index);
14706 
14707     if SubItemIndex <= 0 then
14708       ATarget := dtItem
14709     else
14710       ATarget := dtSubItem;
14711 
14712     // checked does not work as we expected.
14713     if Checkable and (ATarget = dtItem) then
14714     begin
14715       // if (State and QStyleState_On <> 0) and (ATarget = dtItem) then
14716       //  Include(ACustomState, cdsChecked);
14717       if  QTreeWidgetItem_checkState(topLevelItem(ItemIndex), 0) <> QtUnchecked then
14718         Include(ACustomState, cdsChecked);
14719     end;
14720 
14721     QStyle_drawControl(QApplication_style, QStyleCE_ItemViewItem, Option, painter, viewportWidget);
14722 
14723     // NOW WE ARE DRAWING ITEMS ...
14724     QPainter_save(painter);
14725     if TCustomListView(LCLObject).Canvas.HandleAllocated then
14726       TmpDC2 := TCustomListView(LCLObject).Canvas.GetUpdatedHandle([csHandleValid])
14727     else
14728       TmpDC2 := 0;
14729     TmpDC1 := HDC(TQtDeviceContext.CreateFromPainter(painter));
14730     TCustomListView(LCLObject).Canvas.Handle := TmpDC1;
14731     try
14732       R := visualRect(index);
14733       // here we do only OnCustomDrawItem and OnCustomDrawSubItem
14734       // OnCustomDraw is done inside itemViewportEventFilter.
14735       if IsItemEmpty then
14736         QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
14737 
14738       APaintResult := TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPrePaint, ItemIndex, SubItemIndex, ACustomState, @R);
14739       SkipDefault := cdrSkipDefault in APaintResult;
14740 
14741       if not SkipDefault then // do default paint by unknown magic
14742       begin
14743         if not IsItemEmpty then
14744           QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
14745       end;
14746       // issue #27315
14747       if cdrNotifyPostpaint in APaintResult then
14748         TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPostPaint, ItemIndex, SubItemIndex, ACustomState, @R);
14749     finally
14750       TCustomListView(LCLObject).Canvas.Handle := TmpDC2;
14751       TQtDeviceContext(TmpDC1).Free;
14752       QPainter_restore(painter);
14753     end;
14754   end;
14755 end;
14756 
14757 procedure TQtTreeWidget.ClearItems;
14758 begin
14759   FSelection.Clear;
14760   QTreeWidget_clear(QTreeWidgetH(Widget));
14761 end;
14762 
14763 procedure TQtTreeWidget.clearSelection;
14764 begin
14765   inherited clearSelection;
14766   FSelection.Clear;
14767 end;
14768 
14769 procedure TQtTreeWidget.DeleteItem(const AIndex: integer);
14770 var
14771   Item: QTreeWidgetItemH;
14772   Index: Integer;
14773 begin
14774   Item := topLevelItem(AIndex);
14775   if Item <> nil then
14776     Index := FSelection.IndexOf(Item)
14777   else
14778     Index := -1;
14779   if Index <> -1 then
14780     FSelection.Remove(Item);
14781   if FDelayedCheckItem = Item then
14782     FDelayedCheckItem := nil;
14783   Item := takeTopLevelItem(AIndex);
14784   if Item <> nil then
14785     QTreeWidgetItem_destroy(Item);
14786 end;
14787 
getHeadernull14788 function TQtTreeWidget.getHeader: TQtHeaderView;
14789 begin
14790   {while designing TQtHeaderView is a no-no}
14791   if not (csDesigning in LCLObject.ComponentState) and (FHeader = nil) then
14792   begin
14793     FHeader := TQtHeaderView.CreateFrom(LCLObject, QTreeView_header(QTreeViewH(Widget)));
14794     FHeader.FOwner := Self;
14795     FHeader.FChildOfComplexWidget := ccwTreeWidget;
14796     QHeaderView_setMovable(QHeaderViewH(FHeader.Widget), False);
14797     {$IFDEF TEST_QT_SORTING}
14798     FSortChanged := QHeaderView_hook_create(FHeader.Widget);
14799     QHeaderView_hook_hook_sortIndicatorChanged(FSortChanged,
14800       @SignalSortIndicatorChanged);
14801     {$ENDIF}
14802     FHeader.AttachEvents;
14803   end;
14804   Result := FHeader;
14805 end;
14806 
GetItemCheckednull14807 function TQtTreeWidget.GetItemChecked(AIndex: Integer): Boolean;
14808 var
14809   AItem: QTreeWidgetItemH;
14810 begin
14811   Result := False;
14812   AItem := topLevelItem(AIndex);
14813   if AItem <> nil then
14814     Result := GetItemLastCheckStateInternal(AItem) = QtChecked;
14815    // Result := QTreeWidgetItem_checkState(AItem, 0) = QtChecked;
14816 end;
14817 
getItemCountnull14818 function TQtTreeWidget.getItemCount: Integer;
14819 begin
14820   Result := QTreeWidget_topLevelItemCount(QTreeWidgetH(Widget));
14821 end;
14822 
getMaxColSizenull14823 function TQtTreeWidget.getMaxColSize(ACol: Integer): Integer;
14824 begin
14825   {$note QSizeH implementation missing for TQtTreeWidget.getMaxColSize}
14826   Result := MAXINT -1;
14827 end;
14828 
getMinColSizenull14829 function TQtTreeWidget.getMinColSize(ACol: Integer): Integer;
14830 begin
14831   {$note QSizeH implementation missing for TQtTreeWidget.getMinColSize}
14832   Result := 0;
14833 end;
14834 
getSortEnablednull14835 function TQtTreeWidget.getSortEnabled: Boolean;
14836 begin
14837   Result := QTreeWidget_isSortingEnabled(QTreeWidgetH(Widget));
14838 end;
14839 
getColCountnull14840 function TQtTreeWidget.getColCount: Integer;
14841 begin
14842   Result := QTreeWidget_columnCount(QTreeWidgetH(Widget));
14843 end;
14844 
14845 procedure TQtTreeWidget.setColCount(const AValue: Integer);
14846 begin
14847   QTreeWidget_setColumnCount(QTreeWidgetH(Widget), AValue);
14848 end;
14849 
14850 procedure TQtTreeWidget.SetItemChecked(AIndex: Integer; AValue: Boolean);
14851 var
14852   AItem: QTreeWidgetItemH;
14853   AState: QtCheckState;
14854 begin
14855   AItem := topLevelItem(AIndex);
14856   if AItem <> nil then
14857   begin
14858     if AValue then
14859       AState := QtChecked
14860     else
14861       AState := QtUnChecked;
14862 
14863     QTreeWidgetItem_setCheckState(AItem, 0, AState);
14864     SetItemLastCheckStateInternal(AItem, AState);
14865   end;
14866 end;
14867 
14868 procedure TQtTreeWidget.setItemCount(const AValue: Integer);
14869 var
14870   i: Integer;
14871   j: Integer;
14872   Items: TPtrIntArray;
14873   Item: QTreeWidgetItemH;
14874   ItemChild: QTreeWidgetItemH;
14875 begin
14876   if AValue = ItemCount then
14877     exit;
14878   BeginUpdate;
14879   try
14880     ClearItems;
14881     SetLength(Items, AValue);
14882     for i := 0 to High(Items) do
14883     begin
14884       Item := QTreeWidgetItem_create(QTreeWidgetH(Widget), QTreeWidgetItemType);
14885       for j := 0 to ColCount - 1 do
14886       begin
14887         ItemChild := QTreeWidgetItem_create(item, QTreeWidgetItemType);
14888         QTreeWidgetItem_addChild(item, ItemChild);
14889       end;
14890       Items[i] := PtrUInt(Item);
14891     end;
14892     if length(Items) > 0 then
14893       QTreeWidget_addTopLevelItems(QTreeWidgetH(Widget), @Items);
14894   finally
14895     EndUpdate;
14896   end;
14897 end;
14898 
14899 procedure TQtTreeWidget.setMaxColSize(ACol: Integer; const AValue: Integer);
14900 begin
14901   {$note QSizeH implementation missing for TQtTreeWidget.setMaxColSize}
14902 end;
14903 
14904 procedure TQtTreeWidget.setMinColSize(ACol: Integer; const AValue: Integer);
14905 begin
14906   QHeaderView_setMinimumSectionSize(QTreeView_header(QTreeViewH(Widget)), AValue);
14907 end;
14908 
14909 {------------------------------------------------------------------------------
14910   Function: TQtTreeWidget.setSortEnabled
14911   Params:  Boolean
14912   Returns: Nothing
14913   Enables sorting of items.
14914  ------------------------------------------------------------------------------}
14915 procedure TQtTreeWidget.setSortEnabled(const AValue: Boolean);
14916 begin
14917   QTreeWidget_setSortingEnabled(QTreeWidgetH(Widget), AValue);
14918 end;
14919 
14920 {------------------------------------------------------------------------------
14921   Function: TQtTreeWidget.CurrentRow
14922   Params:  None
14923   Returns: Integer
14924  ------------------------------------------------------------------------------}
currentRownull14925 function TQtTreeWidget.currentRow: Integer;
14926 var
14927   TWI: QTreeWidgetItemH;
14928 begin
14929   TWI := QTreeWidget_currentItem(QTreeWidgetH(Widget));
14930   Result := getRow(TWI);
14931 end;
14932 
14933 {------------------------------------------------------------------------------
14934   Function: TQtTreeWidget.setCurrentRow
14935   Params:  Integer
14936   Returns: Nothing
14937  ------------------------------------------------------------------------------}
14938 procedure TQtTreeWidget.setCurrentRow(row: Integer);
14939 var
14940   TWI: QTreeWidgetItemH;
14941 begin
14942   TWI := QTreeWidget_topLevelItem(QTreeWidgetH(Widget), Row);
14943   QTreeWidget_setCurrentItem(QTreeWidgetH(Widget), TWI);
14944 end;
14945 
currentItemnull14946 function TQtTreeWidget.currentItem: QTreeWidgetItemH;
14947 begin
14948   Result := QTreeWidget_currentItem(QTreeWidgetH(Widget));
14949 end;
14950 
14951 procedure TQtTreeWidget.setCurrentItem(AItem: QTreeWidgetItemH);
14952 begin
14953   QTreeWidget_setCurrentItem(QTreeWidgetH(Widget), AItem);
14954 end;
14955 
getRownull14956 function TQtTreeWidget.getRow(AItem: QTreeWidgetItemH): integer;
14957 begin
14958   Result := QTreeWidget_indexOfTopLevelItem(QTreeWidgetH(Widget), AItem);
14959 end;
14960 
headerItemnull14961 function TQtTreeWidget.headerItem: QTreeWidgetItemH;
14962 begin
14963   Result := QTreeWidget_headerItem(QTreeWidgetH(Widget));
14964 end;
14965 
itemAtnull14966 function TQtTreeWidget.itemAt(APoint: TPoint): QTreeWidgetItemH;
14967 begin
14968   Result := itemAt(APoint.X, APoint.Y);
14969 end;
14970 
itemAtnull14971 function TQtTreeWidget.itemAt(x: Integer; y: Integer): QTreeWidgetItemH;
14972 begin
14973   Result := QTreeWidget_itemAt(QTreeWidgetH(Widget), x, y);
14974 end;
14975 
14976 procedure TQtTreeWidget.insertTopLevelItem(AIndex: Integer;
14977   AItem: QTreeWidgetItemH);
14978 begin
14979   QTreeWidget_insertTopLevelItem(QTreeWidgetH(Widget), AIndex, AItem);
14980 end;
14981 
takeTopLevelItemnull14982 function TQtTreeWidget.takeTopLevelItem(AIndex: Integer): QTreeWidgetItemH;
14983 begin
14984   Result := QTreeWidget_takeTopLevelItem(QTreeWidgetH(Widget), AIndex);
14985 end;
14986 
topLevelItemnull14987 function TQtTreeWidget.topLevelItem(AIndex: Integer): QTreeWidgetItemH;
14988 begin
14989   Result := QTreeWidget_topLevelItem(QTreeWidgetH(Widget), AIndex);
14990 end;
14991 
visualItemRectnull14992 function TQtTreeWidget.visualItemRect(AItem: QTreeWidgetItemH): TRect;
14993 var
14994   ItemRect: TRect;
14995 begin
14996   QTreeWidget_visualItemRect(QTreeWidgetH(Widget), @ItemRect, AItem);
14997   Result := ItemRect;
14998 end;
14999 
getHeaderHeightnull15000 function TQtTreeWidget.getHeaderHeight(out AOrientation: QtOrientation): Integer;
15001 var
15002   W: QHeaderViewH;
15003 begin
15004   Result := 0;
15005   AOrientation := QtHorizontal;
15006   W := QTreeView_header(QTreeViewH(Widget));
15007   if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
15008   begin
15009     AOrientation := QHeaderView_orientation(W);
15010     if AOrientation = QtHorizontal then
15011       Result := QWidget_height(W)
15012     else
15013       Result := QWidget_width(W);
15014   end;
15015 end;
15016 
getItemVisiblenull15017 function TQtTreeWidget.getItemVisible(AItem: QTreeWidgetItemH): Boolean;
15018 begin
15019   Result := not QTreeWidget_isItemHidden(QTreeWidgetH(Widget), AItem);
15020 end;
15021 
getTopItemnull15022 function TQtTreeWidget.getTopItem: integer;
15023 begin
15024   Result := getVisibleRowCount(True);
15025 end;
15026 
15027 {------------------------------------------------------------------------------
15028   Function: TQtTreeWidget.getVisibleRowCount
15029   Params:  Boolean
15030   Returns: if AFirstVisibleOnly = False (default) then it returns number
15031   of visible rows, or 0 if there's no visible rows.
15032   When AFirstVisibleOnly = True then it returns index of first visible row,
15033   otherwise result is -1.
15034  ------------------------------------------------------------------------------}
getVisibleRowCountnull15035 function TQtTreeWidget.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
15036 var
15037   R: TRect;
15038   i: integer;
15039   item: QTreeWidgetItemH;
15040   RowIndex: integer;
15041   RowHeight: integer;
15042 begin
15043   if AFirstVisibleOnly then
15044     Result := -1
15045   else
15046     Result := 0;
15047   QWidget_contentsRect(viewportWidget, @R);
15048   i := 0;
15049   repeat
15050     item := itemAt(0, i);
15051     if item <> nil then
15052     begin
15053       RowIndex := getRow(Item);
15054       if AFirstVisibleOnly then
15055       begin
15056         Result := RowIndex;
15057         break;
15058       end;
15059       RowHeight := getRowHeight(RowIndex);
15060       if RowHeight <= 0 then
15061         RowHeight := 1;
15062       inc(Result);
15063       inc(i, RowHeight);
15064     end else
15065       inc(i, 1);
15066   until i >= R.Bottom;
15067 end;
15068 
15069 procedure TQtTreeWidget.setItemVisible(AItem: QTreeWidgetItemH;
15070   const AVisible: Boolean);
15071 begin
15072   QTreeWidget_setItemHidden(QTreeWidgetH(Widget), AItem, not AVisible);
15073 end;
15074 
15075 procedure TQtTreeWidget.setItemText(AItem: QTreeWidgetItemH;
15076   const AColumn: Integer; const AText: WideString; const AAlignment: QtAlignment);
15077 begin
15078   QTreeWidgetItem_setText(AItem, AColumn, @AText);
15079   QTreeWidgetItem_setTextAlignment(AItem, AColumn, AAlignment);
15080 end;
15081 
15082 procedure TQtTreeWidget.setItemData(AItem: QTreeWidgetItemH;
15083   const AColumn: Integer; Data: Pointer; const ARole: Integer = Ord(QtUserRole));
15084 var
15085   v: QVariantH;
15086 begin
15087   if Data = nil then
15088     v := QVariant_create
15089   else
15090     v := QVariant_create(Int64({%H-}PtrUInt(Data)));
15091   QTreeWidgetItem_setData(AItem, AColumn, ARole, v);
15092   QVariant_destroy(v);
15093 end;
15094 
selCountnull15095 function TQtTreeWidget.selCount: Integer;
15096 begin
15097   Result := length(selectedItems);
15098 end;
15099 
TQtTreeWidget.selectedItemsnull15100 function TQtTreeWidget.selectedItems: TPtrIntArray;
15101 begin
15102   QTreeWidget_selectedItems(QTreeWidgetH(Widget), @Result);
15103 end;
15104 
15105 procedure TQtTreeWidget.setHeaderVisible(AVisible: Boolean);
15106 begin
15107   if (csDesigning in LCLObject.ComponentState) then
15108     QTreeView_setHeaderHidden(QTreeViewH(Widget), not AVisible)
15109   else
15110     Header.setVisible(AVisible);
15111 end;
15112 
15113 procedure TQtTreeWidget.setItemSelected(AItem: QTreeWidgetItemH;
15114   ASelect: Boolean);
15115 var
15116   Msg: TLMNotify;
15117   NMLV: TNMListView;
15118   AParent: QTreeWidgetItemH;
15119   AIndex: Integer;
15120   ASubIndex: Integer;
15121 begin
15122 
15123   if not InUpdate and
15124     (((FSelection.Count > 0) and (FSelection.IndexOf(AItem) <> -1)) or
15125     (QTreeWidget_isItemSelected(QTreeWidgetH(Widget), AItem) = ASelect)) then
15126     exit;
15127 
15128   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15129   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
15130   Msg.Msg := CN_NOTIFY;
15131 
15132   NMLV.hdr.hwndfrom := LCLObject.Handle;
15133   NMLV.hdr.code := LVN_ITEMCHANGED;
15134 
15135   AIndex := getRow(AItem);
15136 
15137   if AIndex = -1 then
15138     exit;
15139 
15140   AParent := QTreeWidgetItem_parent(AItem);
15141 
15142   if AParent <> nil then
15143     ASubIndex := QTreeWidgetItem_indexOfChild(AParent, AItem)
15144   else
15145     ASubIndex := 0;
15146 
15147 
15148   NMLV.iItem := AIndex;
15149   NMLV.iSubItem := ASubIndex;
15150   if not ASelect then
15151     NMLV.uOldState := LVIS_SELECTED
15152   else
15153     NMLV.uNewState := LVIS_SELECTED;
15154   NMLV.uChanged := LVIF_STATE;
15155   Msg.NMHdr := @NMLV.hdr;
15156 
15157   QTreeWidget_setItemSelected(QTreeWidgetH(Widget), AItem, ASelect);
15158   if not FSyncingItems then
15159   begin
15160     {$IFDEF QT_DEBUGTQTTREEWIDGET}
15161     DebugLn('TQtTreeWidget.setItemSelected() delivering ASelect ',dbgs(ASelect));
15162     {$ENDIF}
15163     DeliverMessage(Msg);
15164   end;
15165 end;
15166 
15167 procedure TQtTreeWidget.setStretchLastSection(AValue: Boolean);
15168 begin
15169   if (csDesigning in LCLObject.ComponentState) then
15170     QHeaderView_setStretchLastSection(QTreeView_header(QTreeViewH(Widget)),
15171       AValue)
15172   else
15173     Header.setStretchLastSection(AValue);
15174 end;
15175 
15176 procedure TQtTreeWidget.scrollToItem(Item: QTreeWidgetItemH;
15177   hint: QAbstractItemViewScrollHint);
15178 begin
15179   QTreeWidget_scrollToItem(QTreeWidgetH(Widget), Item, hint);
15180 end;
15181 
15182 {$IFDEF TEST_QT_SORTING}
15183 procedure TQtTreeWidget.sortItems(Acolumn: Integer; AOrder: QtSortOrder);
15184 var
15185   StdModel: QStandardItemModelH;
15186 begin
15187   // there's bug with QStandardItemModel persistent index update, we
15188   // use InternalUpdate in QtWSComCtrls !
15189   if not FCanSort then
15190     exit;
15191   try
15192     if ItemCount = 0 then
15193       exit;
15194     StdModel := QStandardItemModelH(getModel);
15195     // writeln('Sorting called ...SortRole=',QStandardItemModel_sortRole(StdModel));
15196     if QStandardItemModel_sortRole(StdModel) <> Ord(QtUserRole) then
15197       QStandardItemModel_setSortRole(StdModel, Ord(QtUserRole));
15198     setUpdatesEnabled(False);
15199     QStandardItemModel_sort(StdModel, AColumn, AOrder);
15200     setUpdatesEnabled(True);
15201   finally
15202     FCanSort := False;
15203   end;
15204 end;
15205 {$ENDIF}
15206 
15207 procedure TQtTreeWidget.AttachEvents;
15208 begin
15209   inherited AttachEvents;
15210 
15211   FItemActivatedHook := QTreeWidget_hook_create(Widget);
15212   FItemEnteredHook := QTreeWidget_hook_create(Widget);
15213   FSelectionChangedHook := QTreeWidget_hook_create(Widget);
15214   QTreeWidget_hook_hook_ItemActivated(FItemActivatedHook, @SignalItemActivated);
15215   QTreeWidget_hook_hook_ItemEntered(FItemEnteredHook, @SignalItemEntered);
15216   QTreeWidget_hook_hook_itemSelectionChanged(FSelectionChangedHook, @SignalSelectionChanged);
15217 end;
15218 
15219 procedure TQtTreeWidget.DetachEvents;
15220 begin
15221   if FItemActivatedHook <> nil then
15222   begin
15223     QTreeWidget_hook_destroy(FItemActivatedHook);
15224     FItemActivatedHook := nil;
15225   end;
15226 
15227   if FItemEnteredHook <> nil then
15228   begin
15229     QTreeWidget_hook_destroy(FItemEnteredHook);
15230     FItemEnteredHook := nil;
15231   end;
15232   if FSelectionChangedHook <> nil then
15233   begin
15234     QTreeWidget_hook_destroy(FSelectionChangedHook);
15235     FSelectionChangedHook := nil;
15236   end;
15237 
15238   {$IFDEF TEST_QT_SORTING}
15239   if FSortChanged <> nil then
15240   begin
15241     QHeaderView_hook_destroy(FSortChanged);
15242     FSortChanged := nil;
15243   end;
15244   {$ENDIF}
15245 
15246   inherited DetachEvents;
15247 end;
15248 
15249 procedure TQtTreeWidget.ExchangeItems(const AIndex1, AIndex2: Integer);
15250 var
15251   ItemFrom: QTreeWidgetItemH;
15252   ItemTo: QTreeWidgetItemH;
15253   R: TRect;
15254 begin
15255 
15256   if AIndex1 = AIndex2 then
15257     exit;
15258 
15259   if AIndex1 < AIndex2 then
15260   begin
15261     ItemTo := takeTopLevelItem(AIndex2);
15262     ItemFrom := takeTopLevelItem(AIndex1);
15263     insertTopLevelItem(AIndex1, ItemTo);
15264     insertTopLevelItem(AIndex2, ItemFrom);
15265   end else
15266   begin
15267     ItemFrom := takeTopLevelItem(AIndex1);
15268     ItemTo := takeTopLevelItem(AIndex2);
15269     insertTopLevelItem(AIndex2, ItemFrom);
15270     insertTopLevelItem(AIndex1, ItemTo);
15271   end;
15272 
15273   if OwnerDrawn then
15274   begin
15275     R := VisualItemRect(ItemFrom);
15276     Update(@R);
15277     R := VisualItemRect(ItemTo);
15278     Update(@R);
15279   end;
15280 end;
15281 
15282 procedure TQtTreeWidget.MoveItem(const AFromIndex, AToIndex: Integer);
15283 var
15284   Item: QTreeWidgetItemH;
15285   R: TRect;
15286 begin
15287   Item := takeTopLevelItem(AFromIndex);
15288   insertTopLevelItem(AToIndex, Item);
15289   if OwnerDrawn then
15290   begin
15291     R := VisualItemRect(Item);
15292     Update(@R);
15293   end;
15294 end;
15295 
getClientBoundsnull15296 function TQtTreeWidget.getClientBounds: TRect;
15297 begin
15298   Result := inherited getClientBounds;
15299 end;
15300 
getClientOffsetnull15301 function TQtTreeWidget.getClientOffset: TPoint;
15302 var
15303   Offset: Integer;
15304   AOrientation: QtOrientation;
15305 begin
15306   Offset := getHeaderHeight(AOrientation);
15307   if Offset > 0 then
15308     Result := Point(0, 0)
15309   else
15310     Result := inherited getClientOffset;
15311 end;
15312 
15313 procedure TQtTreeWidget.setSelectionMode(AMode: QAbstractItemViewSelectionMode);
15314 var
15315   SavedItem: QTreeWidgetItemH;
15316   i: Integer;
15317   Arr: TPtrIntArray;
15318 begin
15319   SavedItem := nil;
15320   if (ViewStyle > 0) and (AMode < QAbstractItemViewMultiSelection) and
15321     (getSelectionMode > QAbstractItemViewSingleSelection) then
15322   begin
15323     SavedItem := CurrentItem;
15324     Arr := selectedItems;
15325     if not ((SavedItem <> nil) and (QTreeWidgetItem_isSelected(SavedItem))) then
15326     begin
15327       SavedItem := nil;
15328       if length(Arr) > 0 then
15329         SavedItem := QTreeWidgetItemH(Arr[0]);
15330     end;
15331     for i := 0 to High(Arr) do
15332     begin
15333       if QTreeWidgetItemH(Arr[i]) <> SavedItem then
15334       begin
15335         QTreeWidgetItem_setSelected(QTreeWidgetItemH(Arr[i]), False);
15336         signalCurrentItemChanged(nil, QTreeWidgetItemH(Arr[i]));
15337       end;
15338     end;
15339     clearSelection;
15340   end;
15341   inherited setSelectionMode(AMode);
15342   if SavedItem <> nil then
15343     setItemSelected(SavedItem, True);
15344 end;
15345 
15346 {------------------------------------------------------------------------------
15347   Function: TQtTreeWidget.SignalItemActivated
15348   Params:  Integer
15349   Returns: Nothing
15350  ------------------------------------------------------------------------------}
15351 procedure TQtTreeWidget.SignalItemActivated(item: QTreeWidgetItemH;
15352   column: Integer); cdecl;
15353 var
15354   Msg: TLMNotify;
15355   NMLV: TNMListView;
15356 begin
15357   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15358   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
15359 
15360   Msg.Msg := CN_NOTIFY;
15361 
15362   NMLV.hdr.hwndfrom := LCLObject.Handle;
15363   NMLV.hdr.code := LVN_ITEMCHANGED;
15364 
15365   NMLV.iItem := getRow(Item);
15366 
15367   NMLV.iSubItem := Column;
15368   NMLV.uOldState := 0;
15369   NMLV.uNewState := LVIS_FOCUSED;
15370   NMLV.uChanged := LVIF_STATE;
15371 
15372   Msg.NMHdr := @NMLV.hdr;
15373   DeliverMessage( Msg);
15374 end;
15375 
15376 {------------------------------------------------------------------------------
15377   Function: TQtTreeWidget.SignalItemEntered
15378   Params:  Integer
15379   Returns: Nothing
15380  ------------------------------------------------------------------------------}
15381 procedure TQtTreeWidget.SignalItemEntered(item: QTreeWidgetItemH;
15382   column: Integer); cdecl;
15383 var
15384   Msg: TLMessage;
15385 begin
15386   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15387   Msg.Msg := LM_ENTER;
15388   DeliverMessage(Msg);
15389 end;
15390 
15391 {------------------------------------------------------------------------------
15392   Function: TQtTreeWidget.SignalCurrentItemChanged
15393   Params:  Integer
15394   Returns: Nothing
15395  ------------------------------------------------------------------------------}
15396 procedure TQtTreeWidget.SignalCurrentItemChanged(current: QTreeWidgetItemH;
15397   previous: QTreeWidgetItemH); cdecl;
15398 var
15399   Msg: TLMNotify;
15400   NMLV: TNMListView;
15401   AParent: QTreeWidgetItemH;
15402   ASubIndex: Integer;
15403   AIndex: Integer;
15404   ListItem: TListItem;
15405   B: Boolean;
15406   Item: QTreeWidgetItemH;
15407 begin
15408   if Current = nil then
15409     Item := Previous
15410   else
15411     Item := Current;
15412   {$IFDEF QT_DEBUGTQTTREEWIDGET}
15413   writeln('SignalCurrentItemChangedNG CUR=',dbgHex(PtrUInt(Current)),
15414     ' PREV=',dbgHex(PtrUInt(Previous)),
15415     ' InUpdate ',InUpdate,' Curr=PREVIOUS ? ',Current = Previous);
15416   {$ENDIF}
15417 
15418   if (Item <> nil) and (Current = Previous) then
15419     exit;
15420 
15421   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15422   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
15423 
15424   Msg.Msg := CN_NOTIFY;
15425 
15426   NMLV.hdr.hwndfrom := LCLObject.Handle;
15427   NMLV.hdr.code := LVN_ITEMCHANGING;
15428 
15429   AIndex := getRow(Item);
15430   AParent := nil;
15431   if Item <> nil then
15432     AParent := QTreeWidgetItem_parent(Item);
15433 
15434   if AParent <> nil then
15435     ASubIndex := QTreeWidgetItem_indexOfChild(AParent, Item)
15436   else
15437     ASubIndex := 0;
15438 
15439   NMLV.iItem := AIndex;
15440   NMLV.iSubItem := ASubIndex;
15441   if (Item <> nil) and (Item = Previous) then
15442     NMLV.uOldState := LVIS_SELECTED
15443   else
15444     NMLV.uNewState := LVIS_SELECTED;
15445   NMLV.uChanged := LVIF_STATE;
15446 
15447   Msg.NMHdr := @NMLV.hdr;
15448   DeliverMessage(Msg);
15449 
15450   FSyncingItems := True;
15451   try
15452     if Current <> nil then
15453     begin
15454       ListItem := nil;
15455       B := False;
15456       if (ViewStyle = Ord(vsReport)) and (Previous <> nil) then
15457       begin
15458         ListItem := TCustomListViewHack(LCLObject).Selected;
15459         if ListItem <> nil then
15460           B := ListItem.Index = AIndex;
15461       end;
15462       FillChar(Msg, SizeOf(Msg), #0);
15463       FillChar(NMLV, SizeOf(NMLV), #0);
15464       Msg.Msg := CN_NOTIFY;
15465       NMLV.hdr.hwndfrom := LCLObject.Handle;
15466       NMLV.hdr.code := LVN_ITEMCHANGED;
15467       NMLV.iItem := AIndex;
15468       NMLV.iSubItem := ASubIndex;
15469       if (FSelection.Count > 0) and (FSelection.IndexOf(Current) <> -1) then
15470         NMLV.uNewState := LVIS_SELECTED
15471       else
15472         NMLV.uOldState := LVIS_SELECTED;
15473       NMLV.uChanged := LVIF_STATE;
15474       Msg.NMHdr := @NMLV.hdr;
15475       if not B then
15476         DeliverMessage(Msg);
15477 
15478 
15479       // send focused msg
15480       NMLV.uNewState := 0;
15481       NMLV.uOldState := 0;
15482       NMLV.iSubItem := -1;
15483       if (FSelection.Count > 0) and (FSelection.IndexOf(Current) <> -1) then
15484         NMLV.uNewState := LVIS_FOCUSED
15485       else
15486         NMLV.uOldState := LVIS_FOCUSED;
15487       NMLV.uChanged := LVIF_STATE;
15488       Msg.NMHdr := @NMLV.hdr;
15489       if not B then
15490         DeliverMessage(Msg);
15491 
15492     end;
15493 
15494     if (Previous <> nil) then
15495     begin
15496       AIndex := getRow(Previous);
15497       ListItem := nil;
15498       B := False;
15499       // From Qt docs:
15500       // This signal is emitted when the current item changes.
15501       // The current item is specified by current, and this replaces
15502       // the previous current item.
15503       // So, if Current = nil, do not ask TListView anything ! issue #18701
15504       if (ViewStyle = Ord(vsReport)) and (Current <> nil) and
15505         (Current <> Previous) then
15506       begin
15507         ListItem := TCustomListViewHack(LCLObject).Selected;
15508         if ListItem <> nil then
15509           B := ListItem.Index = AIndex;
15510       end;
15511 
15512       FillChar(Msg, SizeOf(Msg), #0);
15513       FillChar(NMLV, SizeOf(NMLV), #0);
15514       Msg.Msg := CN_NOTIFY;
15515       NMLV.hdr.hwndfrom := LCLObject.Handle;
15516       NMLV.hdr.code := LVN_ITEMCHANGED;
15517       NMLV.iItem := AIndex;
15518       AParent := QTreeWidgetItem_parent(Previous);
15519       if AParent <> nil then
15520         ASubIndex := QTreeWidgetItem_indexOfChild(AParent, Previous)
15521       else
15522         ASubIndex := 0;
15523       NMLV.iSubItem := ASubIndex;
15524 
15525       if QTreeWidget_isItemSelected(QTreeWidgetH(Widget), Previous) then
15526         NMLV.uNewState := LVIS_SELECTED
15527       else
15528         NMLV.uOldState := LVIS_SELECTED;
15529 
15530       NMLV.uChanged := LVIF_STATE;
15531       Msg.NMHdr := @NMLV.hdr;
15532       if not B then
15533         DeliverMessage(Msg);
15534     end;
15535   finally
15536     FSyncingItems := False;
15537   end;
15538 end;
15539 
15540 procedure TQtTreeWidget.SignalSelectionChanged(); cdecl;
15541 var
15542   Arr: TPtrIntArray;
15543   ItemsList: TFPList;
15544   i: Integer;
15545   j: Integer;
15546 
15547   procedure RemoveUnselectedItems;
15548   var
15549     x: Integer;
15550     Index: Integer;
15551     AnItem: QTreeWidgetItemH;
15552   begin
15553     // we are removing only items which are not in selection, to avoid
15554     // duplicated triggering of TListView.OnSelectItem
15555     for x := ItemsList.Count - 1 downto 0 do
15556     begin
15557       Index := FSelection.IndexOf(ItemsList.Items[x]);
15558       if Index = -1 then
15559       begin
15560         AnItem := QTreeWidgetItemH(ItemsList.Items[x]);
15561         SignalCurrentItemChanged(nil, AnItem);
15562         ItemsList.Remove(AnItem);
15563       end;
15564     end;
15565     ItemsList.Clear;
15566   end;
15567 begin
15568   ItemsList := TFPList.Create;
15569   try
15570     if FSelection.Count > 0 then
15571       ItemsList.Assign(FSelection);
15572     FSelection.Clear;
15573     Arr := selectedItems;
15574 
15575     {$IFDEF QT_DEBUGTQTTREEWIDGET}
15576     writeln('TQtTreeWidget.SignalSelectionChanged NewSel count ',length(Arr),
15577       ' InUpdate ',InUpdate,
15578       ' OldSel count ',ItemsList.Count);
15579     {$ENDIF}
15580 
15581     for i := 0 to High(Arr) do
15582       FSelection.Add(QTreeWidgetItemH(Arr[i]));
15583 
15584     if not InUpdate then
15585     begin
15586       if FSelection.Count = 0 then
15587         RemoveUnSelectedItems
15588       else
15589       if (getSelectionMode in [QAbstractItemViewMultiSelection,
15590                                QAbstractItemViewExtendedSelection]) and
15591         (ItemsList.Count >= 1) then // and (FSelection.Count <> ItemsList.Count) then
15592       begin
15593         RemoveUnSelectedItems;
15594         for i := 0 to FSelection.Count - 1 do
15595           SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]), nil);
15596       end else
15597       for i := 0 to FSelection.Count - 1 do
15598       begin
15599         if ItemsList.Count > 0 then
15600         begin
15601           for j := 0 to ItemsList.Count - 1 do
15602             SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]),
15603               QTreeWidgetItemH(ItemsList.Items[j]));
15604         end else
15605           SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]), nil);
15606       end;
15607     end;
15608   finally
15609     ItemsList.Free;
15610   end;
15611 end;
15612 
15613 {$IFDEF TEST_QT_SORTING}
15614 procedure TQtTreeWidget.SignalSortIndicatorChanged(ALogicalIndex: Integer;
15615   AOrder: QtSortOrder); cdecl;
15616 begin
15617   if FSorting or not Assigned(LCLObject) or not
15618     QHeaderView_isSortIndicatorShown(QHeaderViewH(Header.Widget)) then
15619     exit;
15620   if not FCanSort then
15621     exit;
15622   FSorting := True;
15623   try
15624     if ALogicalIndex >= 0 then
15625       sortItems(ALogicalIndex, AOrder);
15626   finally
15627     FSorting := False;
15628   end;
15629 end;
15630 {$ENDIF}
15631 
15632 {TQtTableView}
15633 
CreateWidgetnull15634 function TQtTableView.CreateWidget(const Params: TCreateParams): QWidgetH;
15635 var
15636   Parent: QWidgetH;
15637 begin
15638   {$ifdef VerboseQt}
15639     WriteLn('TQtTableView.CreateWidget');
15640   {$endif}
15641   HasPaint := False;
15642   if Params.WndParent <> 0 then
15643     Parent := TQtWidget(Params.WndParent).GetContainerWidget
15644   else
15645     Parent := nil;
15646   Result := QTableView_create(Parent);
15647   if (QtVersionMajor = 4) and (QtVersionMinor < 6) then
15648     QWidget_setAutoFillBackground(Result, True);
15649 end;
15650 
verticalHeadernull15651 function TQtTableView.verticalHeader: TQtHeaderView;
15652 begin
15653   {$ifdef VerboseQt}
15654     WriteLn('TQtTableView.verticalHeader');
15655   {$endif}
15656   if FVerticalHeader = nil then
15657     FVerticalHeader := TQtHeaderView.CreateFrom(LCLObject, QTableView_verticalHeader(QTableViewH(Widget)));
15658   Result := FVerticalHeader;
15659 end;
15660 
horizontalHeadernull15661 function TQtTableView.horizontalHeader: TQtHeaderView;
15662 begin
15663   {$ifdef VerboseQt}
15664     WriteLn('TQtTableView.horizontalHeader');
15665   {$endif}
15666   if FHorizontalHeader = nil then
15667     FHorizontalHeader := TQtHeaderView.CreateFrom(LCLObject, QTableView_horizontalHeader(QTableViewH(Widget)));
15668   Result := FHorizontalHeader;
15669 end;
15670 
15671 procedure TQtTableView.setVisible(AVisible: Boolean);
15672 begin
15673   QWidget_setVisible(Widget, AVisible);
15674 end;
15675 
getGridStylenull15676 function TQtTableView.getGridStyle: QtPenStyle;
15677 begin
15678   Result := QTableView_gridStyle(QTableViewH(Widget));
15679 end;
15680 
15681 procedure TQtTableView.setGridStyle(ANewStyle: QtPenStyle);
15682 begin
15683   QTableView_setGridStyle(QTableViewH(Widget), ANewStyle);
15684 end;
15685 
15686 destructor TQtTableView.Destroy;
15687 begin
15688   if FVerticalHeader <> nil then
15689     FVerticalHeader.Free;
15690   if FHorizontalHeader <> nil then
15691     FHorizontalHeader.Free;
15692   inherited Destroy;
15693 end;
15694 
getViewPortnull15695 function TQtTableView.getViewPort: QWidgetH;
15696 begin
15697   Result := viewportWidget;
15698 end;
15699 
getClientBoundsnull15700 function TQtTableView.getClientBounds: TRect;
15701 begin
15702   QWidget_contentsRect(Widget, @Result);
15703 end;
15704 
15705 procedure TQtTableView.grabMouse;
15706 begin
15707   QWidget_grabMouse(Widget);
15708 end;
15709 
15710 { TQtMenu }
15711 
CreateWidgetnull15712 function TQtMenu.CreateWidget(const AParams: TCreateParams): QWidgetH;
15713 var
15714   AGroup: TQtActionGroup;
15715   Parent: QWidgetH;
15716 begin
15717   FTrackButton := QtNoButton;
15718   FLastTick := 0;
15719   FIcon := nil;
15720   if AParams.WndParent <> 0 then
15721     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
15722   else
15723     Parent := nil;
15724   Result := QMenu_create(Parent);
15725   FDeleteLater := True;
15726   FActionHandle := nil;
15727   FActions := TFPList.Create;
15728   AGroup := TQtActionGroup.Create(Result);
15729   if FMenuItem <> nil then
15730     AGroup.GroupIndex := FMenuItem.GroupIndex
15731   else
15732     AGroup.GroupIndex := -1;
15733   AGroup.Exclusive := False;
15734   FActions.Add(AGroup);
15735 end;
15736 
15737 procedure TQtMenu.InitializeWidget;
15738 begin
15739   FWidgetState := [];
15740   ChildOfComplexWidget := ccwNone;
15741   WidgetColorRole := QPaletteWindow;
15742   TextColorRole := QPaletteText;
15743   Widget := CreateWidget(FParams);
15744   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
15745   QtWidgetSet.AddHandle(Self);
15746   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
15747   FWidgetLCLFont := nil;
15748 end;
15749 
15750 constructor TQtMenu.Create(const AMenuItem: TMenuItem);
15751 var
15752   AParams: TCreateParams;
15753 begin
15754   FillChar(AParams{%H-}, SizeOf(AParams), #0);
15755   FMenuItem := AMenuItem;
15756   inherited Create(nil, AParams);
15757 end;
15758 
15759 destructor TQtMenu.Destroy;
15760 var
15761   i: integer;
15762 begin
15763   if FIcon <> nil then
15764     QIcon_destroy(FIcon);
15765 
15766   if Assigned(FActions) then
15767   begin
15768     for i := 0 to FActions.Count - 1 do
15769       TQtActionGroup(FActions.Items[i]).Free;
15770 
15771     FActions.Free;
15772   end;
15773 
15774   inherited Destroy;
15775 end;
15776 
15777 procedure TQtMenu.AttachEvents;
15778 begin
15779   FTriggeredHook := QAction_hook_create(ActionHandle);
15780   FHoveredHook := QAction_hook_create(ActionHandle);
15781   FAboutToShowHook := QMenu_hook_create(Widget);
15782   FAboutToHideHook := QMenu_hook_create(Widget);
15783   FEventHook := QObject_hook_create(Widget);
15784 
15785   QAction_hook_hook_triggered(FTriggeredHook, @SlotTriggered);
15786 
15787   QAction_hook_hook_hovered(FHoveredHook, @SlotHovered);
15788 
15789   QMenu_hook_hook_aboutToShow(FAboutToShowHook, @SlotAboutToShow);
15790 
15791   QMenu_hook_hook_aboutToHide(FAboutToHideHook, @SlotAboutToHide);
15792 
15793   QObject_hook_hook_events(FEventHook, @EventFilter);
15794 end;
15795 
15796 procedure TQtMenu.DetachEvents;
15797 begin
15798   if FActionEventFilter <> nil then
15799   begin
15800     QObject_hook_destroy(FActionEventFilter);
15801     FActionEventFilter := nil;
15802   end;
15803 
15804   if FTriggeredHook <> nil then
15805   begin
15806     QAction_hook_destroy(FTriggeredHook);
15807     FTriggeredHook := nil;
15808   end;
15809 
15810   if FHoveredHook <> nil then
15811   begin
15812     QAction_hook_destroy(FHoveredHook);
15813     FHoveredHook := nil;
15814   end;
15815 
15816   if FAboutToShowHook <> nil then
15817   begin
15818     QMenu_hook_destroy(FAboutToShowHook);
15819     FAboutToShowHook := nil;
15820   end;
15821 
15822   if FAboutToHideHook <> nil then
15823   begin
15824     QMenu_hook_destroy(FAboutToHideHook);
15825     FAboutToHideHook := nil;
15826   end;
15827   inherited DetachEvents;
15828 end;
15829 
15830 procedure TQtMenu.SlotHovered; cdecl;
15831 begin
15832   FMenuItem.IntfDoSelect;
15833 end;
15834 
15835 procedure TQtMenu.SlotAboutToShow; cdecl;
15836 var
15837   Msg: TLMessage;
15838 begin
15839   //issues #22872 (flickering), #24979 (actions)
15840   if Assigned(FMenuItem) and
15841     not (FMenuItem.Menu is TPopupMenu) then
15842   begin
15843     // DebugLn('TQtMenu.SlotAboutToShow ',dbgsName(FMenuItem));
15844     if GetTickCount64 - FLastTick > 10 then
15845     begin
15846       FLastTick := GetTickCount64;
15847       FillChar(Msg{%H-}, SizeOf(Msg), 0);
15848       Msg.msg := LM_ACTIVATE;
15849       if Assigned(FMenuItem) then
15850         FMenuItem.Dispatch(Msg);
15851       FLastTick := GetTickCount64;
15852     end;
15853   end;
15854 end;
15855 
15856 procedure TQtMenu.SlotAboutToHide; cdecl;
15857 var
15858   Event: QLCLMessageEventH;
15859 begin
15860   if FMenuItem.Menu is TPopupMenu then
15861   begin
15862     Event := QLCLMessageEvent_create(LCLQt_PopupMenuClose);
15863     QCoreApplication_postEvent(Widget, Event);
15864   end;
15865   // DebugLn('TQtMenu.SlotAboutToHide ',dbgsName(FMenuItem));
15866   FLastTick := GetTickCount64; // issue #22872, #24979
15867 end;
15868 
15869 procedure TQtMenu.DoPopupClose;
15870 begin
15871   if FMenuItem.Menu is TPopupMenu then
15872     TPopupMenu(FMenuItem.Menu).Close;
15873 end;
15874 
15875 procedure TQtMenu.SlotDestroy; cdecl;
15876 begin
15877   Widget := nil;
15878 end;
15879 
15880 procedure TQtMenu.PopUp(pos: PQtPoint; at: QActionH);
15881 begin
15882   QMenu_popup(QMenuH(Widget), pos, at);
15883 end;
15884 
15885 procedure TQtMenu.Exec(pos: PQtPoint; at: QActionH);
15886 begin
15887   QMenu_exec(QMenuH(Widget), pos, at);
15888 end;
15889 
actionHandlenull15890 function TQtMenu.actionHandle: QActionH;
15891 begin
15892   if FActionHandle = nil then
15893   begin
15894     if FActionEventFilter <> nil then
15895     begin
15896       QObject_hook_destroy(FActionEventFilter);
15897       FActionEventFilter := nil;
15898     end;
15899     FActionHandle := QMenu_menuAction(QMenuH(Widget));
15900     FActionEventFilter := QObject_hook_create(FActionHandle);
15901     QObject_hook_hook_events(FActionEventFilter, @ActionEventFilter);
15902   end;
15903   Result := FActionHandle;
15904 end;
15905 
addMenunull15906 function TQtMenu.addMenu(AMenu: QMenuH): QActionH;
15907 begin
15908   setHasSubmenu(True);
15909   Result := QMenu_addMenu(QMenuH(Widget), AMenu);
15910 end;
15911 
15912 procedure TQtMenu.removeActionGroup;
15913 var
15914   Action: QActionGroupH;
15915 begin
15916   Action := QAction_actionGroup(ActionHandle);
15917   if Action <> nil then
15918     QActionGroup_removeAction(Action, ActionHandle);
15919 end;
15920 
15921 procedure TQtMenu.setActionGroups(AItem: TMenuItem);
15922 var
15923   i: integer;
15924   b: Boolean = True;
15925   Group: TQtActionGroup;
15926 begin
15927   for i := 0 to FActions.Count - 1 do
15928   begin
15929     Group := TQtActionGroup(FActions.Items[i]);
15930     if Group.GroupIndex = AItem.GroupIndex then
15931     begin
15932       QAction_setEnabled(TQtMenu(AItem.Handle).actionHandle, AItem.Enabled);
15933       QAction_setVisible(TQtMenu(AItem.Handle).actionHandle, AItem.Visible);
15934       Group.addAction(TQtMenu(AItem.Handle).actionHandle);
15935       Group.Exclusive := AItem.RadioItem;
15936       Group.Visible := True;
15937       Group.Enabled := True;
15938       b := False;
15939       break;
15940     end;
15941   end;
15942   if b then
15943   begin
15944     Group := TQtActionGroup.Create(Widget);
15945     Group.Exclusive := AItem.RadioItem;
15946     Group.GroupIndex := AItem.GroupIndex;
15947     QAction_setEnabled(TQtMenu(AItem.Handle).actionHandle, AItem.Enabled);
15948     QAction_setVisible(TQtMenu(AItem.Handle).actionHandle, AItem.Visible);
15949     Group.addAction(TQtMenu(AItem.Handle).actionHandle);
15950     Group.Visible := True;
15951     Group.Enabled := True;
15952     FActions.Add(Group);
15953   end;
15954 end;
15955 
insertMenunull15956 function TQtMenu.insertMenu(AIndex: Integer; AMenu: QMenuH; AItem: TMenuItem): QActionH;
15957 var
15958   actionBefore: QActionH;
15959 begin
15960 
15961   setHasSubmenu(True);
15962 
15963   if (AItem <> nil) and not AItem.IsLine then
15964     setActionGroups(AItem);
15965 
15966   actionBefore := getActionByIndex(AIndex);
15967 
15968   if actionBefore <> nil then
15969     Result := QMenu_insertMenu(QMenuH(Widget), actionBefore, AMenu)
15970   else
15971     Result := QMenu_addMenu(QMenuH(Widget), AMenu);
15972 end;
15973 
getHasSubMenunull15974 function TQtMenu.getHasSubMenu: boolean;
15975 begin
15976   Result := QAction_menu(ActionHandle) <> nil;
15977 end;
15978 
getVisiblenull15979 function TQtMenu.getVisible: Boolean;
15980 begin
15981   if ActionHandle = nil then
15982     exit(False);
15983   Result := QAction_isVisible(ActionHandle);
15984 end;
15985 
getTextnull15986 function TQtMenu.getText: WideString;
15987 begin
15988   QAction_text(ActionHandle, @Result);
15989 end;
15990 
15991 procedure TQtMenu.setText(const W: WideString);
15992 begin
15993   QAction_setText(ActionHandle, @W);
15994 end;
15995 
15996 procedure TQtMenu.setVisible(AVisible: Boolean);
15997 begin
15998   QAction_setVisible(ActionHandle, AVisible);
15999 end;
16000 
16001 procedure TQtMenu.setChecked(p1: Boolean);
16002 begin
16003   setCheckable(p1);
16004   QAction_setChecked(ActionHandle, p1);
16005 end;
16006 
16007 procedure TQtMenu.setCheckable(p1: Boolean);
16008 begin
16009   if FMenuItem.RadioItem or FMenuItem.ShowAlwaysCheckable then
16010     QAction_setCheckable(ActionHandle, True)
16011   else
16012     QAction_setCheckable(ActionHandle, p1);
16013 end;
16014 
16015 procedure TQtMenu.setHasSubmenu(AValue: Boolean);
16016 begin
16017   if AValue then
16018     QAction_setMenu(ActionHandle, QMenuH(Widget))
16019   else
16020     QAction_setMenu(ActionHandle, nil);
16021 end;
16022 
16023 procedure TQtMenu.setIcon(AIcon: QIconH);
16024 begin
16025   QMenu_setIcon(QMenuH(Widget), AIcon);
16026 end;
16027 
16028 procedure TQtMenu.setImage(AImage: TQtImage);
16029 begin
16030   if FIcon <> nil then
16031   begin
16032     QIcon_destroy(FIcon);
16033     FIcon := nil;
16034   end;
16035 
16036   if AImage <> nil then
16037     FIcon := AImage.AsIcon()
16038   else
16039     FIcon := QIcon_create();
16040 
16041   setIcon(FIcon);
16042 end;
16043 
16044 procedure TQtMenu.setSeparator(AValue: Boolean);
16045 begin
16046   QAction_setSeparator(ActionHandle, AValue);
16047 end;
16048 
16049 procedure TQtMenu.setShortcut(AShortCutK1, AShortCutK2: TShortcut);
16050 var
16051   Key: Word;
16052   Shift: TShiftState;
16053   QtK1, QtK2: integer;
16054   KeySequence: QKeySequenceH;
16055 begin
16056   QtK1 := 0;
16057   QtK2 := 0;
16058   if AShortCutK1 <> 0 then
16059   begin
16060     ShortCutToKey(AShortCutK1, Key, Shift);
16061     QtK1 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
16062     if AShortCutK2 <> 0 then
16063     begin
16064       ShortCutToKey(AShortCutK2, Key, Shift);
16065       QtK2 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
16066     end;
16067   end;
16068   // there is no need in destroying QKeySequnce
16069   KeySequence := QKeySequence_create(QtK1, QtK2);
16070   QAction_setShortcut(ActionHandle, KeySequence);
16071   QKeySequence_destroy(KeySequence);
16072 end;
16073 
16074 {------------------------------------------------------------------------------
16075   Method: TQtMenu.SlotTriggered
16076 
16077   Callback for menu item click
16078  ------------------------------------------------------------------------------}
16079 procedure TQtMenu.SlotTriggered(checked: Boolean); cdecl;
16080 var
16081   Event: QLCLMessageEventH;
16082 begin
16083   Event := QLCLMessageEvent_create(LCLQt_PopupMenuTriggered);
16084   QCoreApplication_postEvent(Widget, Event, 1 {high priority});
16085 end;
16086 
ActionEventFilternull16087 function TQtMenu.ActionEventFilter(Sender: QObjectH; Event: QEventH): Boolean;
16088   cdecl;
16089 var
16090   TempAction: QActionH;
16091   Group: QActionGroupH;
16092 begin
16093   Result := False;
16094   QEvent_accept(Event);
16095   if Assigned(FMenuItem) and (QEvent_type(Event) = QEventActionChanged) then
16096   begin
16097     {qt shouldn't change checkables in any case, LCL should do that !}
16098     TempAction := QActionEvent_action(QActionEventH(Event));
16099     if (TempAction <> nil) and
16100       QAction_isCheckable(TempAction) and
16101       (QAction_isChecked(TempAction) <> FMenuItem.Checked) then
16102     begin
16103       Group := QAction_actionGroup(TempAction);
16104       if Group <> nil then
16105       begin
16106         if QActionGroup_isExclusive(Group) then
16107           QObject_blockSignals(Group, True)
16108         else
16109           QObject_blockSignals(TempAction, True);
16110       end else
16111         QObject_blockSignals(TempAction, True);
16112 
16113       QAction_setChecked(TempAction, FMenuItem.Checked);
16114 
16115       if QObject_signalsBlocked(TempAction) then
16116       begin
16117         QObject_blockSignals(TempAction, False);
16118         Result := True;
16119         QEvent_ignore(Event);
16120       end;
16121     end;
16122   end;
16123 end;
16124 
TQtMenu.MenuItemEnablednull16125 function TQtMenu.MenuItemEnabled: boolean;
16126 var
16127   AParentMenu: TMenuItem;
16128 begin
16129   if not Assigned(FMenuItem) then
16130   begin
16131     Result := getEnabled;
16132     exit;
16133   end;
16134 
16135   Result := FMenuItem.Enabled;
16136   AParentMenu := FMenuItem.Parent;
16137   while AParentMenu <> nil do
16138   begin
16139     Result := AParentMenu.Enabled;
16140     if not Result then
16141       break;
16142     AParentMenu := AParentMenu.Parent;
16143   end;
16144 end;
16145 
EventFilternull16146 function TQtMenu.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
16147 var
16148   Msg: TLMessage;
16149   TempAction: QActionH;
16150 begin
16151   Result := False;
16152   QEvent_accept(Event);
16153 
16154   case QEvent_type(Event) of
16155     LCLQt_PopupMenuTriggered:
16156       begin
16157         {$IFDEF HASX11}
16158         // make interface snappy after menuitem triggers
16159         if Assigned(Application) and not Application.Terminated then
16160         begin
16161           if QApplication_activePopupWidget = nil then
16162           begin
16163             if QApplication_activeModalWidget <> nil then
16164               QWidget_repaint(QApplication_activeModalWidget)
16165             else
16166             if QApplication_activeWindow <> nil then
16167               QWidget_repaint(QApplication_activeWindow);
16168             QCoreApplication_processEvents(QEventLoopAllEvents);
16169           end;
16170         end;
16171         {$ENDIF}
16172         FillChar(Msg{%H-}, SizeOf(Msg), 0);
16173         Msg.msg := LM_ACTIVATE;
16174         if MenuItemEnabled then
16175           FMenuItem.Dispatch(Msg);
16176         Result := True;
16177       end;
16178     LCLQt_PopupMenuClose:
16179       begin
16180         DoPopupClose;
16181         Result := True;
16182       end;
16183     QEventDestroy: SlotDestroy;
16184     QEventMouseButtonPress,
16185     QEventMouseButtonRelease:
16186       begin
16187         Result := (FTrackButton = QtLeftButton) and
16188           (QMouseEvent_button(QMouseEventH(Event)) <> FTrackButton);
16189         if Assigned(FMenuItem) and not (FMenuItem.Menu is TPopupMenu) then
16190         begin
16191           TempAction := QMenu_actionAt(QMenuH(Widget),
16192             QMouseEvent_pos(QMouseEventH(Event)));
16193           {trigger LCL if root of menu have OnClick() connected,
16194            since qt won't do that for us.}
16195           if (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) and
16196             Assigned(FMenuItem.OnClick) and
16197             (TempAction = nil) and not (FMenuItem.IsInMenuBar) then
16198             SlotTriggered();
16199         end;
16200       end;
16201   end;
16202 end;
16203 
16204 { TQtMenuBar }
16205 
16206 constructor TQtMenuBar.Create(const AParent: QWidgetH);
16207 begin
16208   Create;
16209   Widget := QMenuBar_create(AParent);
16210   {$IFNDEF DARWIN}
16211   FCatchNextResizeEvent := False;
16212   FNumOfActions := 0;
16213   {$ENDIF}
16214   FOwnWidget := AParent = nil;
16215   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
16216   FWidgetLCLFont := nil;
16217   FHeight := getHeight;
16218   FVisible := False;
16219   FIsApplicationMainMenu := False;
16220   Palette.ForceColor := True;
16221   setDefaultColor(dctFont);
16222   Palette.ForceColor := False;
16223   setVisible(FVisible);
16224   QtWidgetSet.AddHandle(Self);
16225 end;
16226 
16227 {$IFNDEF DARWIN}
IsDesigningnull16228 function TQtMenuBar.IsDesigning: Boolean;
16229 var
16230   V: QVariantH;
16231   B: Boolean;
16232 begin
16233   Result := (Widget <> nil);
16234   if not Result then
16235     exit(False);
16236 
16237   Result := False;
16238   v := QVariant_create();
16239   try
16240     B := False;
16241     QObject_property(Widget, v, 'lcldesignmenubar');
16242     if QVariant_isValid(v) and not QVariant_isNull(v) then
16243       Result := QVariant_toInt(V, @B) = 1;
16244   finally
16245     QVariant_destroy(v);
16246   end;
16247 end;
16248 {$ENDIF}
16249 
TQtMenuBar.EventFilternull16250 function TQtMenuBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
16251   cdecl;
16252   {$IFNDEF DARWIN}
16253   procedure UpdateDesignerClientRect;
16254   var
16255     WParent: QWidgetH;
16256     Window: HWND;
16257     ACtl: TWinControl;
16258   begin
16259     WParent := getParent;
16260     if (WParent <> nil) then
16261     begin
16262       Window := HwndFromWidgetH(WParent);
16263       if (Window <> 0) and (TQtWidget(Window) is TQtDesignWidget) and
16264         (TQtWidget(Window).getVisible) then
16265       begin
16266         ACtl := TQtMainWindow(Window).LCLObject;
16267         if Assigned(ACtl) and not (csDestroying in ACtl.ComponentState) then
16268         begin
16269           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
16270           DebugLn('TQtMenuBar.EventFilter: before DoAdjustClientRecChange=',
16271             dbgs(ACtl.ClientRect));
16272           {$ENDIF}
16273           ACtl.DoAdjustClientRectChange(True);
16274           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
16275           DebugLn('TQtMenuBar.EventFilter: after  DoAdjustClientRecChange=',
16276             dbgs(ACtl.ClientRect));
16277           {$ENDIF}
16278         end;
16279       end;
16280     end;
16281   end;
16282   {$ENDIF}
16283 begin
16284   Result := False;
16285   QEvent_accept(Event);
16286   if (QEvent_type(Event) = QEventFontChange) then
16287     AssignQtFont(FWidgetDefaultFont.FHandle, QWidget_font(QWidgetH(Sender)));
16288 
16289   {$IFNDEF DARWIN}
16290   if (QEvent_type(Event) = QEventResize) then
16291   begin
16292     // adjusts client rect of designer form.
16293     if FCatchNextResizeEvent then
16294     begin
16295       FCatchNextResizeEvent := False;
16296       if IsDesigning then
16297         UpdateDesignerClientRect;
16298     end;
16299   end else
16300   if (QEvent_type(Event) = QEventActionAdded) then
16301   begin
16302     if IsDesigning then
16303     begin
16304       inc(FNumOfActions);
16305       FCatchNextResizeEvent := FNumOfActions = 1;
16306       {$IFDEF VerboseQtEvents}
16307       DebugLn(Format('TQtMenuBar: Added new action now have %d actions ',
16308         [FNumOfActions]));
16309       {$ENDIF}
16310     end;
16311   end else
16312   if (QEvent_type(Event) = QEventActionRemoved) then
16313   begin
16314     if IsDesigning then
16315     begin
16316       dec(FNumOfActions);
16317       {$IFDEF VerboseQtEvents}
16318       DebugLn(Format('TQtMenuBar: Removed action still have %d actions ',
16319         [FNumOfActions]));
16320       {$ENDIF}
16321       FCatchNextResizeEvent := FNumOfActions = 0;
16322     end;
16323   end;
16324   {$ENDIF}
16325 end;
16326 
addMenunull16327 function TQtMenuBar.addMenu(AMenu: QMenuH): QActionH;
16328 begin
16329   if not FVisible then
16330   begin
16331     FVisible := True;
16332     setVisible(FVisible);
16333   end;
16334   Result := QMenuBar_addMenu(QMenuBarH(Widget), AMenu);
16335 end;
16336 
TQtMenuBar.insertMenunull16337 function TQtMenuBar.insertMenu(AIndex: Integer; AMenu: QMenuH): QActionH;
16338 var
16339   actionBefore: QActionH;
16340   Actions: TPtrIntArray;
16341   Action: QActionH;
16342   i: Integer;
16343   seq: QKeySequenceH;
16344   WStr: WideString;
16345 begin
16346   if not FVisible then
16347   begin
16348     FVisible := True;
16349     setVisible(FVisible);
16350   end;
16351   actionBefore := getActionByIndex(AIndex);
16352   if actionBefore <> nil then
16353     Result := QMenuBar_insertMenu(QMenuBarH(Widget), actionBefore, AMenu)
16354   else
16355     Result := QMenuBar_addMenu(QMenuBarH(Widget), AMenu);
16356   if FIsApplicationMainMenu then
16357   begin
16358     QWidget_actions(Widget, @Actions);
16359     QtWidgetSet.ClearGlobalActions;
16360     for i := 0 to High(Actions) do
16361     begin
16362       Action := QActionH(Actions[i]);
16363       seq := QKeySequence_create();
16364       try
16365         if QKeySequence_isEmpty(seq) then
16366         begin
16367           QAction_shortcut(Action, seq);
16368           WStr := '';
16369           QAction_text(Action, @WStr);
16370           QKeySequence_destroy(seq);
16371           seq := nil;
16372           seq := QKeySequence_create();
16373           QKeySequence_mnemonic(seq, @WStr);
16374           if not QKeySequence_isEmpty(seq) then
16375           begin
16376             QAction_setShortcutContext(Action, QtApplicationShortcut);
16377             QtWidgetSet.AddGlobalAction(Action);
16378           end;
16379         end;
16380       finally
16381         QKeySequence_destroy(seq);
16382       end;
16383     end;
16384   end;
16385 end;
16386 
TQtMenuBar.getGeometrynull16387 function TQtMenuBar.getGeometry: TRect;
16388 begin
16389   Result := inherited getGeometry;
16390 
16391   // workaround since after attaching menu it takes 0 height
16392   if Result.Bottom = 0 then
16393     Result.Bottom := FHeight;
16394 end;
16395 
16396 { TQtProgressBar }
16397 
TQtProgressBar.CreateWidgetnull16398 function TQtProgressBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
16399 var
16400   Parent: QWidgetH;
16401 begin
16402   // Creates the widget
16403   {$ifdef VerboseQt}
16404     WriteLn('TQProgressBar.Create');
16405   {$endif}
16406   if AParams.WndParent <> 0 then
16407     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
16408   else
16409     Parent := nil;
16410   Result := QProgressBar_create(Parent);
16411 end;
16412 
16413 procedure TQtProgressBar.AttachEvents;
16414 begin
16415   inherited AttachEvents;
16416 
16417   FValueChangedHook := QProgressBar_hook_create(Widget);
16418   QProgressBar_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
16419 end;
16420 
16421 procedure TQtProgressBar.DetachEvents;
16422 begin
16423   if FValueChangedHook <> nil then
16424   begin
16425     QProgressBar_hook_destroy(FValueChangedHook);
16426     FValueChangedHook := nil;
16427   end;
16428   inherited DetachEvents;
16429 end;
16430 
16431 procedure TQtProgressBar.setRange(minimum: Integer; maximum: Integer);
16432 begin
16433   QProgressBar_setRange(QProgressBarH(Widget), minimum, maximum);
16434 end;
16435 
16436 procedure TQtProgressBar.setTextVisible(visible: Boolean);
16437 begin
16438   QProgressBar_setTextVisible(QProgressBarH(Widget), visible);
16439 end;
16440 
16441 procedure TQtProgressBar.setAlignment(const AAlignment: QtAlignment);
16442 begin
16443   QProgressBar_setAlignment(QProgressBarH(Widget), AAlignment);
16444 end;
16445 
16446 procedure TQtProgressBar.setTextDirection(textDirection: QProgressBarDirection);
16447 begin
16448   QProgressBar_setTextDirection(QProgressBarH(Widget), textDirection);
16449 end;
16450 
16451 procedure TQtProgressBar.setValue(value: Integer);
16452 begin
16453   QProgressBar_setValue(QProgressBarH(Widget), value);
16454 end;
16455 
16456 procedure TQtProgressBar.setOrientation(p1: QtOrientation);
16457 begin
16458   QProgressBar_setOrientation(QProgressBarH(Widget), p1);
16459 end;
16460 
16461 procedure TQtProgressBar.setInvertedAppearance(invert: Boolean);
16462 begin
16463   QProgressBar_setInvertedAppearance(QProgressBarH(Widget), invert);
16464 end;
16465 
16466 procedure TQtProgressBar.SignalValueChanged(Value: Integer); cdecl;
16467 var
16468   Msg: TLMessage;
16469 begin
16470   FillChar(Msg{%H-}, SizeOf(Msg), #0);
16471   Msg.Msg := LM_CHANGED;
16472   if not InUpdate then
16473     DeliverMessage(Msg);
16474 end;
16475 
16476 procedure TQtProgressBar.setFocusPolicy(const APolicy: QtFocusPolicy);
16477 begin
16478   if APolicy = QtNoFocus then
16479     QWidget_setFocusPolicy(Widget, APolicy)
16480   else
16481     QWidget_setFocusPolicy(Widget, QtTabFocus);
16482 end;
16483 
16484 procedure TQtProgressBar.reset;
16485 begin
16486   QProgressBar_reset(QProgressBarH(Widget));
16487 end;
16488 
16489 { TQtStatusBarPanel }
16490 
CreateWidgetnull16491 function TQtStatusBarPanel.CreateWidget(const AParams: TCreateParams
16492   ): QWidgetH;
16493 var
16494   Parent: QWidgetH;
16495 begin
16496   // Creates the widget
16497   {$ifdef VerboseQt}
16498     WriteLn('TQtStatusBarPanel.Create');
16499   {$endif}
16500 
16501   if AParams.WndParent <> 0 then
16502     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
16503   else
16504     Parent := nil;
16505   Result := QLabel_create(Parent);
16506 end;
16507 
16508 procedure TQtStatusBarPanel.DrawItem(Sender: QObjectH; Event: QEventH);
16509 var
16510   Msg: TLMDrawItems;
16511   AStruct: TPaintStruct;
16512   ItemStruct: PDrawItemStruct;
16513   P: TPoint;
16514   B: Boolean;
16515 begin
16516   {$ifdef VerboseQt}
16517     WriteLn('TQtWidget.DrawItem ', dbgsName(LCLObject));
16518   {$endif}
16519   if CanSendLCLMessage and (LCLObject is TWinControl) then
16520   begin
16521     FillChar(Msg{%H-}, SizeOf(Msg), #0);
16522 
16523     Msg.Msg := LM_DRAWITEM;
16524     FillChar(AStruct{%H-}, SizeOf(TPaintStruct), 0);
16525     FillChar(ItemStruct{%H-}, SizeOf(TDrawItemStruct), 0);
16526     New(ItemStruct);
16527 
16528     with PaintData do
16529     begin
16530       PaintWidget := QWidgetH(Sender);
16531       ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
16532       if ClipRect = nil then
16533         New(ClipRect);
16534       QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
16535     end;
16536 
16537     ItemStruct^.itemID := UINT(ID);
16538     ItemStruct^._hDC := BeginPaint(THandle(Self), AStruct);
16539     FContext := ItemStruct^._hDC;
16540     ItemStruct^.rcItem := PaintData.ClipRect^;
16541     ItemStruct^.hwndItem := HWND(Self);
16542     Msg.Ctl := LCLObject.Handle;
16543     Msg.DrawItemStruct := ItemStruct;
16544 
16545     P := getClientOffset;
16546     inc(P.X, FScrollX);
16547     inc(P.Y, FScrollY);
16548     TQtDeviceContext(FContext).translate(P.X, P.Y);
16549 
16550     // send paint message
16551     try
16552       try
16553         LCLObject.WindowProc(TLMessage(Msg));
16554       finally
16555         Dispose(PaintData.ClipRect);
16556         Fillchar(FPaintData, SizeOf(FPaintData), 0);
16557         FContext := 0;
16558         EndPaint(THandle(Self), AStruct);
16559         Dispose(ItemStruct);
16560       end;
16561     except
16562       // prevent recursive repainting !
16563       B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
16564       if B then
16565         QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
16566       try
16567         Application.HandleException(nil);
16568       finally
16569         if B and Assigned(Application) and not Application.Terminated then
16570           QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
16571       end;
16572     end;
16573   end;
16574 end;
16575 
TQtStatusBarPanel.EventFilternull16576 function TQtStatusBarPanel.EventFilter(Sender: QObjectH; Event: QEventH
16577   ): Boolean; cdecl;
16578 begin
16579   Result := False;
16580   QEvent_accept(Event);
16581   if LCLObject = nil then
16582     exit;
16583   if HasPaint and (QEvent_type(Event) = QEventPaint) then
16584   begin
16585     DrawItem(Sender, Event);
16586     Result := True;
16587   end;
16588 end;
16589 
16590 { TQtStatusBar }
16591 
TQtStatusBar.CreateWidgetnull16592 function TQtStatusBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
16593 var
16594   Parent: QWidgetH;
16595 begin
16596   SetLength(Panels, 0);
16597   if AParams.WndParent <> 0 then
16598     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
16599   else
16600     Parent := nil;
16601   Result := QStatusBar_create(Parent);
16602   if (QtVersionMajor = 4) and (QtVersionMinor < 6) then
16603     QWidget_setAutoFillBackground(Result, True);
16604   Widget := Result;
16605 end;
16606 
16607 procedure TQtStatusBar.setColor(const Value: PQColor);
16608 var
16609   I: Integer;
16610   P: QPaletteH;
16611   WP: QPaletteH;
16612 begin
16613   inherited setColor(Value);
16614   QWidget_setAutoFillBackground(Widget, not EqualTQColor(Palette.CurrentColor, Palette.DefaultColor));
16615   for i := 0 to High(self.Panels) do
16616   begin
16617     P := QWidget_palette(getContainerWidget);
16618     WP := QWidget_palette(Panels[i].Widget);
16619     QWidget_setAutoFillBackground(Panels[i].Widget, not EqualTQColor(Palette.CurrentColor, Palette.DefaultColor));
16620     QPalette_setBrush(WP, QPaletteWindow, QPalette_background(P));
16621   end;
16622 end;
16623 
16624 procedure TQtStatusBar.showMessage(text: PWideString; timeout: Integer);
16625 begin
16626   QStatusBar_showMessage(QStatusBarH(Widget), text, timeout);
16627 end;
16628 
16629 procedure TQtStatusBar.addWidget(AWidget: QWidgetH; AStretch: Integer = 0);
16630 begin
16631   QStatusBar_addWidget(QStatusBarH(Widget), AWidget, AStretch);
16632 end;
16633 
16634 procedure TQtStatusBar.removeWidget(AWidget: QWidgetH);
16635 begin
16636   QStatusBar_removeWidget(QStatusBarH(Widget), AWidget);
16637 end;
16638 
isSizeGripEnablednull16639 function TQtStatusBar.isSizeGripEnabled: Boolean;
16640 begin
16641   Result := QStatusBar_isSizeGripEnabled(QStatusBarH(Widget));
16642 end;
16643 
16644 procedure TQtStatusBar.setSizeGripEnabled(const Value: Boolean);
16645 begin
16646   QStatusBar_setSizeGripEnabled(QStatusBarH(Widget), Value);
16647 end;
16648 
SlotMousenull16649 function TQtStatusBar.SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
16650 begin
16651   inherited SlotMouse(Sender, Event);
16652   Result := True; // cancel event propagation
16653 end;
16654 
16655 { TQtDialog }
16656 
TQtDialog.CreateWidgetnull16657 function TQtDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags): QWidgetH;
16658 begin
16659   Result := QDialog_create(parent, f);
16660 end;
16661 
16662 constructor TQtDialog.Create(ADialog: TCommonDialog; parent: QWidgetH; f: QtWindowFlags);
16663 begin
16664   WidgetColorRole := QPaletteWindow;
16665   TextColorRole := QPaletteWindowText;
16666   FOwner := nil;
16667   FCentralWidget := nil;
16668   FOwnWidget := True;
16669   FProps := nil;
16670   LCLObject := nil;
16671   FKeysToEat := [];
16672   FHasPaint := False;
16673   FDialog := ADialog;
16674   Widget := CreateWidget(parent, f);
16675   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
16676   QtWidgetSet.AddHandle(Self);
16677 end;
16678 
16679 procedure TQtDialog.AttachEvents;
16680 begin
16681   inherited AttachEvents;
16682   FDialogEventHook := QObject_hook_create(Widget);
16683   QObject_hook_hook_events(FDialogEventHook, @EventFilter);
16684 end;
16685 
16686 procedure TQtDialog.DetachEvents;
16687 begin
16688   if FDialogEventHook <> nil then
16689   begin
16690     QObject_hook_destroy(FDialogEventHook);
16691     FDialogEventHook := nil;
16692   end;
16693   inherited DetachEvents;
16694 end;
16695 
TQtDialog.DeliverMessagenull16696 function TQtDialog.DeliverMessage(var Msg;
16697   const AIsInputEvent: Boolean = False): LRESULT;
16698 begin
16699   try
16700     if FDialog.HandleAllocated then
16701     begin
16702       FDialog.Dispatch(TLMessage(Msg));
16703       Result := TLMessage(Msg).Result;
16704     end else
16705       Result := 0;
16706   except
16707     Application.HandleException(nil);
16708   end;
16709 end;
16710 
TQtDialog.SlotClosenull16711 function TQtDialog.SlotClose: Boolean; cdecl;
16712 begin
16713   Result := True;
16714   FDialog.DoCanClose(Result);
16715 end;
16716 
TQtDialog.EventFilternull16717 function TQtDialog.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
16718   cdecl;
16719 begin
16720   {we'll need it later. QDialog uses it's own eventLoop !}
16721   Result := False;
16722   QEvent_accept(Event);
16723   if LCLObject <> nil then
16724     Result := inherited EventFilter(Sender, Event);
16725 end;
16726 
TQtDialog.execnull16727 function TQtDialog.exec: Integer;
16728 {$IFDEF HASX11}
16729 var
16730   AWND: HWND;
16731 {$ENDIF}
16732 begin
16733   {$IF DEFINED(DARWIN) OR DEFINED(QT_DIALOGS_USE_QT_LOOP)}
16734   Result := QDialog_exec(QDialogH(Widget));
16735   {$ELSE}
16736   if QWidget_testAttribute(Widget, QtWA_DeleteOnClose) then
16737     Result := QDialog_exec(QDialogH(Widget))
16738   else
16739   begin
16740     QWidget_setWindowModality(Widget ,QtApplicationModal);
16741     QWidget_show(Widget);
16742     repeat
16743       QCoreApplication_processEvents();
16744       Application.Idle(true);
16745     until not QWidget_isVisible(Widget) or Application.Terminated;
16746     Result := QDialog_result(QDialogH(Widget));
16747   end;
16748   {$ENDIF}
16749   {$IFDEF HASX11}
16750   if (QtWidgetSet.WindowManagerName = 'xfwm4') and (QApplication_activeModalWidget() <> nil) then
16751   begin
16752     AWND := HwndFromWidgetH(QApplication_activeModalWidget());
16753     if (AWND <> 0) and (X11GetActivewindow <> TQtWidget(AWND).Widget) then
16754       X11Raise(QWidget_winID(TQtWidget(AWND).Widget));
16755   end;
16756   {$ENDIF}
16757 end;
16758 
16759 procedure TQtDialog.setSizeGripEnabled(const AEnabled: Boolean);
16760 begin
16761   QDialog_setSizeGripEnabled(QDialogH(Widget), AEnabled);
16762 end;
16763 
16764 { TQtViewPort }
16765 
TQtViewPort.CanPaintBackgroundnull16766 function TQtViewPort.CanPaintBackground: Boolean;
16767 begin
16768   Result := CanSendLCLMessage and getEnabled and
16769     (FChildOfComplexWidget in [ccwCustomControl, ccwScrollingWinControl]) and
16770     (LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
16771 end;
16772 
TQtViewPort.EventFilternull16773 function TQtViewPort.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
16774 var
16775   ScrollBar: QScrollBarH;
16776   ASize: TSize;
16777   AResizeEvent: QResizeEventH;
16778 begin
16779   Result := False;
16780   {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
16781   if (QEvent_type(Event) = QEventResize) or
16782     (QEvent_type(Event) = QEventLayoutRequest) or
16783     (QEvent_type(Event) = QEventWheel) then
16784     WriteLn('TQtViewPort.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
16785       ' LCLObject=', dbgsName(LCLObject),
16786       ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
16787   {$endif}
16788   case QEvent_type(Event) of
16789     QEventShow,
16790     QEventShowToParent:
16791     begin
16792       {Qt does not track scrolled offset of widget when it''s not visible.issue #29239}
16793       if (FInvisibleX <> 0) or (FInvisibleY <> 0) then
16794       begin
16795         QWidget_scroll(Widget, FInvisibleX, FInvisibleY);
16796         FInvisibleX := 0;
16797         FInvisibleY := 0;
16798       end;
16799       Result := inherited EventFilter(Sender, Event);
16800     end;
16801     QEventMove: ; // do not flood LCL with viewport position
16802     QEventResize:
16803     begin
16804       // immediate update clientRect !
16805       if FOwner <> nil then
16806       begin
16807         {TQtCustomControl does not send resize event, it is done here
16808          when viewport geometry is finally updated by Qt.}
16809         ASize := FOwner.getSize;
16810         AResizeEvent := QResizeEvent_create(@ASize, @ASize);
16811         try
16812           // issue #28596 and others of TCustomControl clientrect related
16813           if CanAdjustClientRectOnResize and
16814             LCLObject.ClientRectNeedsInterfaceUpdate then
16815           begin
16816             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
16817             DebugLn('TQtViewPort.EventFilter invalidatingClientRectCache ',dbgsName(Self),' LCL=',dbgsName(LCLObject));
16818             {$ENDIF}
16819             LCLObject.InvalidateClientRectCache(False);
16820           end;
16821           FOwner.SlotResize(AResizeEvent);
16822         finally
16823           QEvent_destroy(AResizeEvent);
16824         end;
16825       end else
16826       begin
16827         {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
16828         DebugLn('TQtViewport: QEventResize wrong call....possible ERROR');
16829         {$ENDIF}
16830         LCLObject.DoAdjustClientRectChange;
16831       end;
16832     end;
16833     QEventWheel:
16834       if not getEnabled then
16835         inherited EventFilter(Sender, Event)
16836       else
16837       if (QtVersionMajor = 4) and (QtVersionMinor < 7) then
16838       begin
16839         Result := SlotMouseWheel(Sender, Event);
16840         if not Result then
16841         case QWheelEvent_orientation(QWheelEventH(Event)) of
16842           QtVertical:
16843             begin
16844               if TQtCustomControl(FOwner).verticalScrollBar.getVisible then
16845               begin
16846                 ScrollBar := QScrollBarH(TQtCustomControl(FOwner).verticalScrollBar.Widget);
16847                 QScrollBar_event(ScrollBar, Event);
16848               end else
16849                 Result := inherited EventFilter(Sender, Event);
16850             end;
16851           QtHorizontal:
16852           begin
16853             if TQtCustomControl(FOwner).horizontalScrollBar.getVisible then
16854             begin
16855               ScrollBar := QScrollBarH(TQtCustomControl(FOwner).horizontalScrollBar.Widget);
16856               QScrollBar_event(ScrollBar, Event);
16857             end else
16858               Result := inherited EventFilter(Sender, Event);
16859           end;
16860         end;
16861         Result := True;
16862         QEvent_ignore(Event);
16863       end;
16864 
16865     QEventLayoutRequest:
16866     begin
16867       if FOwner <> nil then
16868       begin
16869         if LCLObject.ClientRectNeedsInterfaceUpdate then
16870         begin
16871           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize) OR DEFINED(VerboseSizeMsg)}
16872           if caspComputingBounds in LCLObject.AutoSizePhases then
16873             DebugLn('TQtViewport of ',dbgsName(LCLObject),' QEventLayoutRequest calling DoAdjustClientRectChange. CASP=TRUE *** !!!!');
16874           {$ENDIF}
16875           LCLObject.DoAdjustClientRectChange(True);
16876         end;
16877       end;
16878     end;
16879   else
16880     Result := inherited EventFilter(Sender, Event);
16881   end;
16882 end;
16883 
16884 procedure TQtViewPort.InitializeWidget;
16885 begin
16886   FInvisibleX := 0;
16887   FInvisibleY := 0;
16888   inherited InitializeWidget;
16889 end;
16890 
16891 procedure TQtViewPort.scroll(dx, dy: integer; ARect: PRect = nil);
16892 begin
16893   if not getVisible then
16894   begin
16895     FInvisibleX += dx;
16896     FInvisibleY += dy;
16897   end else
16898     inherited scroll(dx, dy, ARect);
16899   FScrollX := FScrollX + dx;
16900   FScrollY := FScrollY + dy;
16901 end;
16902 
16903 procedure TQtViewPort.stackUnder(AWidget: QWidgetH);
16904 begin
16905   // do nothing for TQtViewPort
16906   // inherited stackUnder(AWidget);
16907 end;
16908 
16909 {------------------------------------------------------------------------------
16910   Function: TQtAbstractScrollArea.horizontalScrollbar
16911   Params:  None
16912   Returns: Nothing
16913  ------------------------------------------------------------------------------}
16914 
16915 procedure TQtAbstractScrollArea.setScrollBarPolicy(AIndex: Boolean;
16916   const AValue: QtScrollBarPolicy);
16917 var
16918   Area: QAbstractScrollAreaH;
16919 begin
16920   Area := QAbstractScrollAreaH(Widget);
16921   if getScrollBarsPolicy(AIndex) <> AValue then
16922   begin
16923     if AIndex then
16924       QAbstractScrollArea_setVerticalScrollBarPolicy(Area, AValue)
16925     else
16926       QAbstractScrollArea_setHorizontalScrollBarPolicy(Area, AValue);
16927 
16928     if Assigned(LCLObject) and LCLObject.ClientRectNeedsInterfaceUpdate then
16929     begin
16930       if not (caspComputingBounds in LCLObject.AutoSizePhases) then
16931         LCLObject.DoAdjustClientRectChange(True);
16932     end;
16933   end;
16934 end;
16935 
EventFilternull16936 function TQtAbstractScrollArea.EventFilter(Sender: QObjectH; Event: QEventH
16937   ): Boolean; cdecl;
16938 var
16939   w: QWidgetH;
16940 begin
16941   Result := False;
16942 
16943   if (QEvent_type(Event) = QEventHide) then
16944   begin
16945     // issue #28880
16946     w := QWidget_mouseGrabber;
16947     if w <> nil then
16948     begin
16949       if w = Widget then
16950         ReleaseCapture
16951       else
16952       if w = viewportWidget then
16953         ReleaseCapture;
16954     end;
16955   end else
16956   if (QEvent_type(Event) = QEventResize) then
16957     // DebugLn('***TQtAbstractScrollArea.EventFilter QEventResize(',dbgsName(LCLObject),') EAT !')
16958   else
16959   if (QEvent_type(Event) = QEventWheel) and
16960     not (FChildOfComplexWidget in
16961       [ccwCustomControl, ccwScrollingWinControl, ccwScrollingWindow]) then
16962     // issue #25992.Do not propagate wheel event to lcl, it is done via TQtScrollBar.EventFilter.
16963   else
16964     Result:=inherited EventFilter(Sender, Event);
16965 end;
16966 
16967 procedure TQtAbstractScrollArea.grabMouse;
16968 var
16969   W: QWidgetH;
16970 begin
16971   W := viewportWidget;
16972   if (W <> nil) and QWidget_isVisible(W) and QWidget_isEnabled(W) then
16973     QWidget_grabMouse(W)
16974   else
16975     inherited grabMouse;
16976 end;
16977 
GetContainerWidgetnull16978 function TQtAbstractScrollArea.GetContainerWidget: QWidgetH;
16979 begin
16980   Result := viewportWidget;
16981 end;
16982 
getClientOffsetnull16983 function TQtAbstractScrollArea.getClientOffset: TPoint;
16984 begin
16985   with getClientBounds do
16986     Result := Point(Left, Top);
16987 end;
16988 
TQtAbstractScrollArea.getScrollFrameOffsetnull16989 function TQtAbstractScrollArea.getScrollFrameOffset: Integer;
16990 begin
16991   Result := 0;
16992   if (QStyle_styleHint(QApplication_style(),
16993     QStyleSH_ScrollView_FrameOnlyAroundContents) <> 0) then
16994       Result := QStyle_pixelMetric(QApplication_style(), QStylePM_ScrollView_ScrollBarSpacing, nil, Widget);
16995 end;
16996 
TQtAbstractScrollArea.getClientBoundsnull16997 function TQtAbstractScrollArea.getClientBounds: TRect;
16998 var
16999   HaveBar: Boolean;
17000   ASize: TSize;
17001 begin
17002   if not QWidget_testAttribute(viewportWidget, QtWA_Mapped) then
17003   begin
17004     ASize := getSize;
17005     QWidget_contentsRect(Widget, @Result);
17006     if (ASize.cx > 0) and (ASize.cy > 0) and (QStyle_styleHint(QApplication_style(),
17007           QStyleSH_ScrollView_FrameOnlyAroundContents) <= 0) then
17008     begin
17009       HaveBar := Assigned(FVScrollbar);
17010       if HaveBar and (verticalScrollBar.getVisibleTo(Widget)) then
17011         dec(Result.Right, verticalScrollBar.getWidth);
17012 
17013       HaveBar := Assigned(FHScrollbar);
17014       if HaveBar and (horizontalScrollBar.getVisibleTo(Widget)) then
17015         dec(Result.Bottom, horizontalScrollBar.getHeight);
17016     end;
17017     OffsetRect(Result, -Result.Left, -Result.Top);
17018     {$IF DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
17019     DebugLn('TQtAbstractScrollArea.GetClientBounds(not mapped): ',dbgsName(LCLObject),':',dbgsName(Self),' ',dbgs(Result),' ChildComplex=',dbgs(Ord(ChildOfComplexWidget)));
17020     {$ENDIF}
17021   end else
17022   begin
17023     QWidget_rect(viewportWidget, @Result);
17024     {$IF DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
17025     DebugLn('TQtAbstractScrollArea.GetClientBounds: ',dbgsName(LCLObject),':',dbgsName(Self),' ',dbgs(Result),' ChildComplex=',dbgs(Ord(ChildOfComplexWidget)));
17026     {$ENDIF}
17027   end;
17028 end;
17029 
getViewOriginnull17030 function TQtAbstractScrollArea.getViewOrigin: TPoint;
17031 var
17032   R: TRect;
17033 begin
17034   QWidget_rect(viewportWidget, @R);
17035   // current bindings (2.1) does not assign TopLeft so it's always 0,0
17036   Result := R.TopLeft;
17037 end;
17038 
viewportWidgetnull17039 function TQtAbstractScrollArea.viewportWidget: QWidgetH;
17040 begin
17041   Result := QAbstractScrollArea_viewport(QAbstractScrollAreaH(Widget));
17042 end;
17043 
getScrollBarsPolicynull17044 function TQtAbstractScrollArea.getScrollBarsPolicy(AIndex: Boolean
17045   ): QtScrollBarPolicy;
17046 var
17047   Area: QAbstractScrollAreaH;
17048 begin
17049   Area := QAbstractScrollAreaH(Widget);
17050   if AIndex then
17051     Result := QAbstractScrollArea_verticalScrollBarPolicy(Area)
17052   else
17053     Result := QAbstractScrollArea_horizontalScrollBarPolicy(Area);
17054 end;
17055 
horizontalScrollBarnull17056 function TQtAbstractScrollArea.horizontalScrollBar: TQtScrollBar;
17057 begin
17058   {$ifdef VerboseQt}
17059     WriteLn('TQAbstractScrollArea.horizontalScrollBar');
17060   {$endif}
17061   if FHScrollBar = nil then
17062   begin
17063     FHScrollBar := TQtScrollBar.CreateFrom(LCLObject,
17064       QAbstractScrollArea_horizontalScrollBar(QAbstractScrollAreaH(Widget)));
17065 
17066     if FHScrollBar.getTracking then
17067       FHScrollBar.TrackPos := SB_POLICY_CONTINUOUS
17068     else
17069       FHScrollBar.TrackPos := SB_POLICY_DISCONTINUOUS;
17070 
17071     FHScrollBar.ChildOfComplexWidget := ccwAbstractScrollArea;
17072     FHScrollBar.FOwner := Self;
17073     FHScrollBar.setFocusPolicy(QtNoFocus);
17074 
17075     if not FHScrollBar.CanChangeFontColor then
17076     begin
17077       with FHScrollBar do
17078       begin
17079         Palette.ForceColor := True;
17080         setDefaultColor(dctFont);
17081         Palette.ForceColor := False;
17082       end;
17083     end;
17084     FHScrollBar.AttachEvents;
17085   end;
17086   Result := FHScrollBar;
17087 end;
17088 
17089 {------------------------------------------------------------------------------
17090   Function: TQtAbstractScrollArea.verticalScrollbar
17091   Params:  None
17092   Returns: Nothing
17093  ------------------------------------------------------------------------------}
verticalScrollBarnull17094 function TQtAbstractScrollArea.verticalScrollBar: TQtScrollBar;
17095 begin
17096   {$ifdef VerboseQt}
17097     WriteLn('TQAbstractScrollArea.verticalScrollBar');
17098   {$endif}
17099   if FVScrollBar = nil then
17100   begin
17101     FVScrollbar := TQtScrollBar.CreateFrom(LCLObject,
17102       QAbstractScrollArea_verticalScrollBar(QAbstractScrollAreaH(Widget)));;
17103     if FVScrollBar.getTracking then
17104       FVScrollBar.TrackPos := SB_POLICY_CONTINUOUS
17105     else
17106       FVScrollBar.TrackPos := SB_POLICY_DISCONTINUOUS;
17107     FVScrollBar.ChildOfComplexWidget := ccwAbstractScrollArea;
17108     FVScrollBar.FOwner := Self;
17109     FVScrollBar.setFocusPolicy(QtNoFocus);
17110     if not FVScrollBar.CanChangeFontColor then
17111     begin
17112       with FVScrollBar do
17113       begin
17114         Palette.ForceColor := True;
17115         setDefaultColor(dctFont);
17116         Palette.ForceColor := False;
17117       end;
17118     end;
17119     FVScrollbar.AttachEvents;
17120   end;
17121   Result := FVScrollBar;
17122 end;
17123 
17124 procedure TQtAbstractScrollArea.setFocusPolicy(const APolicy: QtFocusPolicy);
17125 begin
17126   QWidget_setFocusPolicy(Widget, APolicy);
17127 end;
17128 
17129 {------------------------------------------------------------------------------
17130   Function: TQtAbstractScrollArea.setHorizontalScrollbar
17131   Params:  None
17132   Returns: Nothing
17133  ------------------------------------------------------------------------------}
17134 procedure TQtAbstractScrollArea.setHorizontalScrollBar(AScrollBar: TQtScrollBar);
17135 begin
17136   {$ifdef VerboseQt}
17137     WriteLn('TQAbstractScrollArea.setHorizontalScrollBar');
17138   {$endif}
17139   FHScrollbar := AScrollBar;
17140   if Assigned(FHScrollBar) then
17141     QAbstractScrollArea_setHorizontalScrollBar(QAbstractScrollAreaH(Widget), QScrollBarH(FHScrollBar.Widget));
17142 end;
17143 
17144 {------------------------------------------------------------------------------
17145   Function: TQtAbstractScrollArea.setVerticalScrollbar
17146   Params:  None
17147   Returns: Nothing
17148  ------------------------------------------------------------------------------}
17149 procedure TQtAbstractScrollArea.setVerticalScrollBar(AScrollBar: TQtScrollBar);
17150 begin
17151   {$ifdef VerboseQt}
17152     WriteLn('TQAbstractScrollArea.setVerticalScrollBar');
17153   {$endif}
17154   FVScrollBar := AScrollBar;
17155   if Assigned(FVScrollBar) then
17156     QAbstractScrollArea_setVerticalScrollBar(QAbstractScrollAreaH(Widget), QScrollBarH(FVScrollBar.Widget));
17157 end;
17158 
17159 {------------------------------------------------------------------------------
17160   Function: TQtAbstractScrollArea.setScrollStyle
17161   Params:  None
17162   Returns: Nothing
17163            Setting scrollbar''s policy (LCL TScrollStyle)
17164  -----------------------------------------------------------------------------}
17165 procedure TQtAbstractScrollArea.setScrollStyle(AScrollStyle: TScrollStyle);
17166 begin
17167   {$ifdef VerboseQt}
17168     WriteLn('TQAbstractScrollArea.setScrollStyle');
17169   {$endif}
17170   case AScrollStyle of
17171     ssNone:
17172     begin
17173       ScrollBarPolicy[True] := QtScrollBarAlwaysOff;
17174       ScrollBarPolicy[False] := QtScrollBarAlwaysOff;
17175     end;
17176     ssHorizontal, ssVertical:
17177     begin
17178       ScrollBarPolicy[AScrollStyle = ssVertical] := QtScrollBarAlwaysOn;
17179     end;
17180     ssBoth:
17181     begin
17182       ScrollBarPolicy[True] := QtScrollBarAlwaysOn;
17183       ScrollBarPolicy[False] := QtScrollBarAlwaysOn;
17184     end;
17185     ssAutoHorizontal, ssAutoVertical:
17186     begin
17187       ScrollBarPolicy[AScrollStyle = ssAutoVertical] := QtScrollBarAsNeeded;
17188     end;
17189     ssAutoBoth:
17190     begin
17191       ScrollBarPolicy[True] := QtScrollBarAsNeeded;
17192       ScrollBarPolicy[False] := QtScrollBarAsNeeded;
17193     end;
17194   end;
17195 
17196 end;
17197 
17198 procedure TQtAbstractScrollArea.SetNoMousePropagation(Sender: QWidgetH;
17199   const ANoMousePropagation: Boolean);
17200 begin
17201   // keep it so because sender can be dangling pointer from qt inside
17202   // mouse event of viewportWidget ! issue #26466
17203   if Sender = viewportWidget then
17204     inherited SetNoMousePropagation(Sender, False)
17205   else
17206     inherited SetNoMousePropagation(Sender, ANoMousePropagation);
17207 end;
17208 
17209 procedure TQtAbstractScrollArea.DestroyNotify(AWidget: TQtWidget);
17210 begin
17211   if AWidget = FHScrollbar then
17212     FHScrollbar := nil;
17213 
17214   if AWidget = FVScrollbar then
17215     FVScrollbar := nil;
17216 
17217   inherited DestroyNotify(AWidget);
17218 end;
17219 
17220 destructor TQtAbstractScrollArea.Destroy;
17221 begin
17222   FreeAndNil(FHScrollBar);
17223   FreeAndNil(FVScrollBar);
17224   inherited Destroy;
17225 end;
17226 
17227 procedure TQtAbstractScrollArea.Update(ARect: PRect);
17228 var
17229   P: TPoint;
17230 begin
17231   if ARect <> nil then
17232   begin
17233     P := getClientOffset;
17234     OffsetRect(ARect^, -P.X , -P.Y);
17235     QWidget_update(viewportWidget, ARect);
17236   end else
17237     QWidget_update(viewportWidget);
17238 end;
17239 
17240 procedure TQtAbstractScrollArea.UpdateRegion(ARgn: QRegionH);
17241 begin
17242   if ARgn <> nil then
17243     QWidget_update(viewportWidget, ARgn)
17244   else
17245     QWidget_update(viewportWidget);
17246 end;
17247 
17248 procedure TQtAbstractScrollArea.Repaint(ARect: PRect);
17249 var
17250   P: TPoint;
17251 begin
17252   if ARect <> nil then
17253   begin
17254     P := getClientOffset;
17255     OffsetRect(ARect^, -P.X , -P.Y);
17256     QWidget_repaint(viewportWidget, ARect);
17257   end else
17258     QWidget_repaint(viewportWidget);
17259 end;
17260 
17261 { TQtCustomControl }
17262 
17263 {------------------------------------------------------------------------------
17264   Function: TQtCustomControl.CreateWidget
17265   Params:  None
17266   Returns: Nothing
17267  ------------------------------------------------------------------------------}
CreateWidgetnull17268 function TQtCustomControl.CreateWidget(const AParams: TCreateParams):QWidgetH;
17269 var
17270   Parent: QWidgetH;
17271 begin
17272   // Creates the widget
17273   {$ifdef VerboseQt}
17274     WriteLn('TQtCustomControl.CreateWidget');
17275   {$endif}
17276   FHasPaint := True;
17277   FViewPortWidget := nil;
17278   if AParams.WndParent <> 0 then
17279     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
17280   else
17281     Parent := nil;
17282   Result := QLCLAbstractScrollArea_create(Parent);
17283 
17284   FChildOfComplexWidget := ccwCustomControl;
17285 
17286   if (LCLObject is TScrollingWinControl) then
17287   begin
17288     if (QtVersionMajor = 4) and (QtVersionMinor < 6) and
17289       not (csDesigning in LCLObject.ComponentState) then
17290       QWidget_setAutoFillBackground(Result, True);
17291     FChildOfComplexWidget := ccwScrollingWinControl;
17292   end else
17293     QWidget_setAutoFillBackground(Result, False);
17294 
17295   QWidget_setAttribute(Result, QtWA_InputMethodEnabled);
17296 end;
17297 
ProcessArrowKeysnull17298 function TQtCustomControl.ProcessArrowKeys: Boolean;
17299 begin
17300   Result := True;
17301 end;
17302 
17303 {------------------------------------------------------------------------------
17304   Function: TQtCustomControl.Destroy
17305   Params:  None
17306   Returns: Nothing
17307  ------------------------------------------------------------------------------}
17308 destructor TQtCustomControl.Destroy;
17309 begin
17310   {$ifdef VerboseQt}
17311     WriteLn('TQtCustomControl.Destroy');
17312   {$endif}
17313   viewportDelete;
17314   inherited Destroy;
17315 end;
17316 
EventFilternull17317 function TQtCustomControl.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
17318 begin
17319   Result := False;
17320   QEvent_accept(Event);
17321   if (LCLObject = nil) then
17322     exit;
17323 
17324   if (QEvent_type(Event) in [
17325                             QEventPaint,
17326                             QEventResize, // TQtViewport.EventFilter sends resize !
17327                             QEventMouseButtonPress,
17328                             QEventMouseButtonRelease,
17329                             QEventMouseButtonDblClick,
17330                             QEventContextMenu
17331                            ]) and
17332      (ClassType = TQtCustomControl) then
17333     Result := False
17334   else
17335   if QEvent_type(Event) = QEventWheel then
17336   begin
17337     if not getEnabled then
17338      inherited EventFilter(Sender, Event)
17339     else
17340     if not horizontalScrollBar.getVisible and
17341       not verticalScrollBar.getVisible then
17342       Result := inherited EventFilter(Sender, Event)
17343     else
17344       Result := False;
17345   end else
17346   {$IFDEF MSWINDOWS}
17347   {sometimes our IDE completely freezes, after screensaver activated
17348    or OS sleep state / hibernation under Win32 (if cursor stays
17349    inside SourceEditor), so if application is deactivated by OS
17350    we must release mouse grab. }
17351   if QEvent_type(Event) = QEventApplicationDeactivate then
17352   begin
17353     if HWND(Self) = GetCapture then
17354       ReleaseCapture;
17355     Result := inherited EventFilter(Sender, Event);
17356   end else
17357   {$ENDIF}
17358     Result := inherited EventFilter(Sender, Event);
17359 end;
17360 
17361 procedure TQtCustomControl.ViewPortEventFilter(event: QEventH; retval: PBoolean); cdecl;
17362 var
17363   MouseEventTyp: Boolean;
17364 begin
17365   {$ifdef VerboseViewPortEventFilter}
17366     WriteLn('ViewPortEventFilter ',QEvent_type(Event));
17367   {$endif}
17368 
17369   QEvent_accept(Event);
17370 
17371   case QEvent_type(Event) of
17372     QEventResize,
17373     QEventMouseButtonPress,
17374     QEventMouseButtonRelease,
17375     QEventMouseButtonDblClick,
17376     QEventMouseMove,
17377     QEventWheel,
17378     QEventContextMenu,
17379     QEventPaint:
17380     begin
17381       MouseEventTyp := (QEvent_type(Event) = QEventMouseButtonPress) or
17382         (QEvent_type(Event) = QEventMouseButtonRelease) or
17383         (QEvent_type(Event) = QEventMouseButtonDblClick) or
17384         (QEvent_type(Event) = QEventWheel) or
17385         (QEvent_type(Event) = QEventMouseMove);
17386 
17387       if (QEvent_type(Event) = QEventWheel) and
17388         (QtVersionMajor = 4) and (QtVersionMinor > 6) then
17389         QLCLAbstractScrollArea_InheritedViewportEvent(QLCLAbstractScrollAreaH(Widget), event);
17390 
17391       retval^ := True;
17392 
17393       if FViewPortWidget <> nil then
17394         Viewport.EventFilter(ViewPortWidget, Event);
17395 
17396       // do not allow qt to call notifications on user input events (mouse)
17397       // otherwise we can crash since our object maybe does not exist
17398       // after mouse clicks
17399       if not MouseEventTyp then
17400         QEvent_ignore(Event);
17401     end;
17402   else
17403     retval^ := QLCLAbstractScrollArea_InheritedViewportEvent(QLCLAbstractScrollAreaH(Widget), event);
17404   end;
17405 end;
17406 
17407 procedure TQtCustomControl.DestroyNotify(AWidget: TQtWidget);
17408 begin
17409   if AWidget = FCornerWidget then
17410     FCornerWidget := nil;
17411 
17412   if AWidget = FViewPortWidget then
17413     FViewPortWidget := nil;
17414 
17415   inherited DestroyNotify(AWidget);
17416 end;
17417 
CanAdjustClientRectOnResizenull17418 function TQtCustomControl.CanAdjustClientRectOnResize: Boolean;
17419 begin
17420   // DoAdjustClientRectChange(); is called from TQtViewport resize event !
17421   Result := True;
17422 end;
17423 
17424 {------------------------------------------------------------------------------
17425   Function: TQtCustomControl.cornerWidget
17426   Params:  None
17427   Returns: Nothing
17428  ------------------------------------------------------------------------------}
cornerWidgetnull17429 function TQtCustomControl.cornerWidget: TQtWidget;
17430 begin
17431   {$ifdef VerboseQt}
17432     WriteLn('TQAbstractScrollArea.cornerWidget');
17433   {$endif}
17434   Result := FCornerWidget;
17435 end;
17436 
MapToGlobalnull17437 function TQtCustomControl.MapToGlobal(APt: TPoint;
17438   const AWithScrollOffset: Boolean = False): TPoint;
17439 var
17440   Pt: TPoint;
17441 begin
17442   Result := inherited MapToGlobal(APt);
17443   if AWithScrollOffset and (ChildOfComplexWidget = ccwScrollingWinControl) then
17444   begin
17445     Pt := viewport.ScrolledOffset;
17446     dec(Result.X, Pt.X);
17447     dec(Result.Y, Pt.Y);
17448   end;
17449 end;
17450 
MapFromGlobalnull17451 function TQtCustomControl.MapFromGlobal(APt: TPoint;
17452   const AWithScrollOffset: Boolean = False): TPoint;
17453 begin
17454   //TODO: see what to do with ccwScrollingWinControl
17455   Result := inherited MapFromGlobal(APt);
17456 end;
17457 
17458 {------------------------------------------------------------------------------
17459   Function: TQtCustomControl.setCornerWidget
17460   Params:  TQtWidget
17461   Returns: Nothing
17462  ------------------------------------------------------------------------------}
17463 procedure TQtCustomControl.setCornerWidget(AWidget: TQtWidget);
17464 begin
17465   {$ifdef VerboseQt}
17466     WriteLn('TQAbstractScrollArea.setCornerWidget');
17467   {$endif}
17468   FCornerWidget := AWidget;
17469   if Assigned(FCornerWidget) then
17470     QAbstractScrollArea_setCornerWidget(QAbstractScrollAreaH(Widget), FCornerWidget.Widget)
17471   else
17472     QAbstractScrollArea_setCornerWidget(QAbstractScrollAreaH(Widget), NiL);
17473 end;
17474 
17475 procedure TQtCustomControl.setCursor(const ACursor: QCursorH);
17476 begin
17477   if (LCLObject is TCustomControl) and HasPaint then
17478     viewport.setCursor(ACursor)
17479   else
17480     inherited setCursor(ACursor);
17481 end;
17482 
17483 procedure TQtCustomControl.setViewport(const AViewPort: QWidgetH);
17484 begin
17485   QAbstractScrollArea_setViewport(QAbstractScrollAreaH(Widget), AViewPort);
17486 end;
17487 
17488 procedure TQtCustomControl.setVisible(AVisible: Boolean);
17489 begin
17490   inherited setVisible(AVisible);
17491   if FViewPortWidget <> nil then
17492     FViewPortWidget.setVisible(AVisible);
17493 end;
17494 
17495 {------------------------------------------------------------------------------
17496   Function: TQtCustomControl.viewport
17497   Params:  None
17498   Returns: viewport widget of QAbstractScrollArea
17499  ------------------------------------------------------------------------------}
viewportnull17500 function TQtCustomControl.viewport: TQtViewPort;
17501 begin
17502   viewportNeeded;
17503   Result := FViewPortWidget;
17504 end;
17505 
17506 procedure TQtCustomControl.preferredSize(var PreferredWidth,
17507   PreferredHeight: integer; WithThemeSpace: Boolean);
17508 begin
17509   if LCLObject is TCustomControl then
17510   begin
17511     PreferredWidth := 0;
17512     PreferredHeight := 0;
17513   end else
17514     inherited preferredSize(PreferredWidth, PreferredHeight, WithThemeSpace);
17515 end;
17516 
17517 {------------------------------------------------------------------------------
17518   Function: TQtCustomControl.viewportNeeded
17519   Params:  None
17520   Returns: Nothing
17521            Creates viewport widget for QAbstractScrollArea
17522  ------------------------------------------------------------------------------}
17523 procedure TQtCustomControl.viewportNeeded;
17524 var
17525   AParams: TCreateParams;
17526 begin
17527   if FViewPortWidget <> niL then
17528     exit;
17529   FillChar(AParams{%H-}, SizeOf(AParams), #0);
17530   FViewPortWidget := TQtViewPort.Create(LCLObject, AParams);
17531   FViewPortWidget.setFocusProxy(Widget);
17532   FViewPortWidget.setBackgroundRole(QPaletteNoRole);
17533   FViewPortWidget.setAutoFillBackground(False);
17534   FViewPortWidget.FOwner := Self;
17535   FViewPortWidget.FChildOfComplexWidget := FChildOfComplexWidget;
17536 
17537   // some events will be redirected to scroll area
17538   FViewPortWidget.AttachEvents;
17539 
17540   QLCLAbstractScrollArea_override_viewportEvent(QLCLAbstractScrollAreaH(Widget),
17541     @ViewPortEventFilter);
17542 
17543   setViewport(FViewPortWidget.Widget);
17544 end;
17545 
17546 procedure TQtCustomControl.viewportDelete;
17547 begin
17548   if Assigned(FViewPortWidget) then
17549   begin
17550     QLCLAbstractScrollArea_override_viewportEvent(QLCLAbstractScrollAreaH(Widget),
17551       QLCLAbstractScrollArea_viewportEvent_Override(NilMethod));
17552     FViewPortWidget.FOwner := nil;
17553     FViewPortWidget.Release;
17554     FViewPortWidget := nil;
17555   end;
17556 end;
17557 
17558   { TQtCalendar }
17559 
GetDateTimenull17560 function TQtCalendar.GetDateTime: TDateTime;
17561 var
17562   Date: QDateH;
17563 begin
17564   Date := QDate_create();
17565   QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), Date);
17566   AYear := QDate_year(Date);
17567   AMonth := QDate_month(Date);
17568   ADay := QDate_day(Date);
17569   QDate_destroy(Date);
17570   Result := EncodeDate(AYear, AMonth, ADay);
17571 end;
17572 
17573 procedure TQtCalendar.SetDateTime(const AValue: TDateTime);
17574 var
17575   Date: QDateH;
17576 begin
17577   DecodeDate(AValue, AYear, AMonth, ADay);
17578   Date := QDate_create(AYear, AMonth, ADay);
17579   QCalendarWidget_setCurrentPage(QCalendarWidgetH(Widget),
17580     AYear, AMonth);
17581   SetSelectedDate(Date);
17582   QDate_destroy(Date);
17583 end;
17584 
17585 procedure TQtCalendar.SetSelectedDate(const AValue: QDateH);
17586 begin
17587   QCalendarWidget_setSelectedDate(QCalendarWidgetH(Widget), AValue);
17588 end;
17589 
17590 {------------------------------------------------------------------------------
17591   Function: TQtCalendar.CreateWidget
17592   Params:  None
17593   Returns: Nothing
17594  ------------------------------------------------------------------------------}
CreateWidgetnull17595 function TQtCalendar.CreateWidget(const AParams: TCreateParams):QWidgetH;
17596 var
17597   Parent: QWidgetH;
17598 begin
17599   // Creates the widget
17600   {$ifdef VerboseQt}
17601     WriteLn('TQtCalendar.Create');
17602   {$endif}
17603   FMouseDoubleClicked := False;
17604   if AParams.WndParent <> 0 then
17605     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
17606   else
17607     Parent := nil;
17608   Result := QCalendarWidget_create(Parent);
17609 end;
17610 
17611 procedure TQtCalendar.AttachEvents;
17612 var
17613   i: integer;
17614   Children: TPtrIntArray;
17615   AnObject: QObjectH;
17616   WP: QWidgetH;
17617 begin
17618   inherited AttachEvents;
17619 
17620   FClickedHook := QCalendarWidget_hook_create(Widget);
17621   FActivatedHook := QCalendarWidget_hook_create(Widget);
17622   FSelectionChangedHook := QCalendarWidget_hook_create(Widget);
17623   FCurrentPageChangedHook := QCalendarWidget_hook_create(Widget);
17624 
17625   QCalendarWidget_hook_hook_clicked(FClickedHook, @SignalClicked);
17626 
17627   QCalendarWidget_hook_hook_activated(FActivatedHook, @SignalActivated);
17628 
17629   QCalendarWidget_hook_hook_selectionChanged(FSelectionChangedHook, @SignalSelectionChanged);
17630 
17631   QCalendarWidget_hook_hook_currentPageChanged(FCurrentPageChangedHook, @SignalCurrentPageChanged);
17632 
17633   QObject_children(Widget, @Children);
17634   for i := 0 to High(Children) do
17635   begin
17636     AnObject := QObjectH(Children[i]);
17637     if QObject_isWidgetType(AnObject) then
17638     begin
17639       {do not localize !!}
17640       if QObject_inherits(AnObject,'QAbstractScrollArea') then
17641       begin
17642         WP := QAbstractScrollArea_viewport(QAbstractScrollAreaH(AnObject));
17643         QWidget_setMouseTracking(WP, True);
17644         FCalViewportEventHook := QObject_hook_create(WP);
17645         QObject_hook_hook_events(FCalViewportEventHook, @calViewportEventFilter);
17646         setProperty(QWidgetH(AnObject), 'lclwidget', Int64(PtrUInt(Self)));
17647         FCalViewAreaEventHook := QObject_hook_create(QWidgetH(AnObject));
17648         QObject_hook_hook_events(FCalViewAreaEventHook, @AreaViewEventFilter);
17649       end;
17650     end;
17651   end;
17652 end;
17653 
17654 procedure TQtCalendar.DetachEvents;
17655 begin
17656   if FCalViewAreaEventHook <> nil then
17657   begin
17658     QObject_hook_destroy(FCalViewAreaEventHook);
17659     FCalViewAreaEventHook := nil;
17660   end;
17661   if FCalViewportEventHook <> nil then
17662   begin
17663     QObject_hook_destroy(FCalViewportEventHook);
17664     FCalViewportEventHook := nil;
17665   end;
17666   if FClickedHook <> nil then
17667   begin
17668     QCalendarWidget_hook_destroy(FClickedHook);
17669     FClickedHook := nil;
17670   end;
17671   if FActivatedHook <> nil then
17672   begin
17673     QCalendarWidget_hook_destroy(FActivatedHook);
17674     FActivatedHook := nil;
17675   end;
17676   if FSelectionChangedHook <> nil then
17677   begin
17678     QCalendarWidget_hook_destroy(FSelectionChangedHook);
17679     FSelectionChangedHook := nil;
17680   end;
17681   if FCurrentPageChangedHook <> nil then
17682   begin
17683     QCalendarWidget_hook_destroy(FCurrentPageChangedHook);
17684     FCurrentPageChangedHook := nil;
17685   end;
17686   inherited DetachEvents;
17687 end;
17688 
EventFilternull17689 function TQtCalendar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
17690   cdecl;
17691 begin
17692   Result := False;
17693   if (QEvent_Type(Event) = QEventKeyPress) or (QEvent_Type(Event) = QEventKeyRelease) then
17694     exit;
17695   Result := inherited EventFilter(Sender, Event);
17696 end;
17697 
AreaViewEventFilternull17698 function TQtCalendar.AreaViewEventFilter(Sender: QObjectH; Event: QEventH
17699   ): Boolean; cdecl;
17700 var
17701   ADate: QDateH;
17702   AKey: Integer;
17703 begin
17704   Result := False;
17705   if (LCLObject <> nil) and ((QEvent_type(Event) = QEventKeyPress) or
17706     (QEvent_type(Event) = QEventKeyRelease)) then
17707   begin
17708     AKey := QKeyEvent_key(QKeyEventH(Event));
17709     Result := SlotKey(Widget, Event);
17710     if (QEvent_type(Event) = QEventKeyRelease) and
17711       ( (AKey = QtKey_Up) or (AKey = QtKey_Left) or
17712         (AKey = QtKey_Right) or (AKey = QtKey_Down) ) then
17713     begin
17714       ADate := QDate_create();
17715       QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), ADate);
17716       DeliverDayChanged(ADate);
17717       QDate_destroy(ADate);
17718     end;
17719   end;
17720 end;
17721 
calViewportEventFilternull17722 function TQtCalendar.calViewportEventFilter(Sender: QObjectH; Event: QEventH
17723   ): Boolean; cdecl;
17724 begin
17725   {we install only mouse dblclick event on QCalendar viewport,
17726    since inside signalActivated we don't know is it signalled from
17727    dblclick or by pressing return key.}
17728   Result := False;
17729   QEvent_accept(Event);
17730   if (LCLObject <> nil) then
17731   begin
17732     case QEvent_type(Event) of
17733       QEventMouseMove: Result := SlotMouseMove(Sender, Event);
17734       QEventEnter,
17735       QEventLeave: Result := SlotMouseEnter(Sender, Event);
17736       QEventMouseButtonDblClick: FMouseDoubleClicked := True;
17737       QEventWheel:
17738         begin
17739           if not getEnabled then
17740           begin
17741             QEvent_ignore(Event);
17742             QWidget_setAttribute(QWidgetH(Sender), QtWA_NoMousePropagation, False);
17743           end;
17744         end;
17745     end;
17746   end;
17747 end;
17748 
HitTestnull17749 function TQtCalendar.HitTest(const APoint: TPoint): byte;
17750 var
17751   Layout: QLayoutH;
17752   CalendarBody: QWidgetH;
17753   HeaderRect, BodyRect: TRect;
17754   AQtPoint: TQtPoint;
17755   Index: QModelIndexH;
17756 begin
17757   Result := 0;
17758   Layout := QWidget_layout(Widget);
17759   // layout must have 2 items:
17760   // 1 - navigation bar
17761   // 2 - calendar model
17762   if QLayout_count(Layout) <> 2 then
17763     Exit;
17764   QLayoutItem_geometry(QLayout_itemAt(Layout, 0), @HeaderRect);
17765   QLayoutItem_geometry(QLayout_itemAt(Layout, 1), @BodyRect);
17766   if PtInRect(HeaderRect, APoint) then
17767   begin
17768     // we are in the header
17769     Result := 3;
17770     // todo: detail result more - button / month / year
17771   end
17772   else
17773   if PtInRect(BodyRect, APoint) then
17774   begin
17775     CalendarBody := QLayoutItem_widget(QLayout_itemAt(Layout, 1));
17776     AQtPoint := QtPoint(APoint.X, APoint.Y);
17777     QWidget_mapFrom(CalendarBody, @AQtPoint, Widget, @AQtPoint);
17778     Index := QModelIndex_create();
17779     try
17780       QTableView_indexAt(QTableWidgetH(CalendarBody), Index, @AQtPoint);
17781       if (QCalendarWidget_horizontalHeaderFormat(QCalendarWidgetH(Widget)) = QCalendarWidgetNoHorizontalHeader) or
17782          (QModelIndex_row(Index) > 0) then
17783       begin
17784         if (QCalendarWidget_verticalHeaderFormat(QCalendarWidgetH(Widget)) = QCalendarWidgetNoVerticalHeader) or
17785            (QModelIndex_column(Index) > 0) then
17786           Result := 1
17787         else
17788           Result := 2;
17789       end;
17790     finally
17791       QModelIndex_destroy(Index);
17792     end;
17793   end;
17794 end;
17795 
17796 procedure TQtCalendar.SetDisplaySettings(
17797       const AHHdrFmt: QCalendarWidgetHorizontalHeaderFormat;
17798       const AVHdrFmt: QCalendarWidgetVerticalHeaderFormat;
17799       const ASelMode: QCalendarWidgetSelectionMode;
17800       const ANavBarVisible: Boolean; const AGridVisible: Boolean);
17801 //      const AStartMonday: Boolean);
17802 begin
17803   QCalendarWidget_setHorizontalHeaderFormat(QCalendarWidgetH(Widget), AHHdrFmt);
17804   QCalendarWidget_setNavigationBarVisible(QCalendarWidgetH(Widget), ANavBarVisible);
17805   QCalendarWidget_setVerticalHeaderFormat(QCalendarWidgetH(Widget), AVHdrFmt);
17806   QCalendarWidget_setGridVisible(QCalendarWidgetH(Widget), AGridVisible);
17807   QCalendarWidget_setSelectionMode(QCalendarWidgetH(Widget), ASelMode);
17808 end;
17809 
17810 procedure TQtCalendar.SetFirstDayOfWeek(const ADayOfWeek: QtDayOfWeek);
17811 begin
17812   QCalendarWidget_setFirstDayOfWeek(QCalendarWidgetH(Widget), ADayOfWeek);
17813 end;
17814 
TQtCalendar.DeliverDayChangednull17815 function TQtCalendar.DeliverDayChanged(ADate: QDateH): boolean;
17816 var
17817   y,m,d: Integer;
17818   Msg: TLMessage;
17819 begin
17820   Result := False;
17821   FillChar(Msg{%H-}, SizeOf(Msg), #0);
17822   Msg.Msg := LM_DAYCHANGED;
17823   y := QDate_year(ADate);
17824   m := QDate_month(ADate);
17825   d := QDate_day(ADate);
17826   Result := (y <> aYear) or (m <> aMonth) or (d <> aDay);
17827   if Result then
17828     DeliverMessage(Msg);
17829   aYear := y;
17830   aMonth := m;
17831   aDay := d;
17832 end;
17833 
17834 {------------------------------------------------------------------------------
17835   Function: TQtCalendar.SignalActivated
17836   Params:  None
17837   Returns: Nothing
17838            Sends signal when RETURN pressed on selected date.
17839  ------------------------------------------------------------------------------}
17840 procedure TQtCalendar.SignalActivated(ADate: QDateH); cdecl;
17841 var
17842   AKeyEvent: QKeyEventH;
17843   AMouseEvent: QMouseEventH;
17844   APos: TQtPoint;
17845   AGlobalPos: TQtPoint;
17846 begin
17847   {$IFDEF VerboseQt}
17848   writeln('TQtCalendar.signalActivated ');
17849   {$ENDIF}
17850 
17851   DeliverDayChanged(ADate);
17852 
17853   {avoid OnAcceptDate() to trigger twice if doubleclicked
17854    via FMouseDoubleClicked, also send dummy Key events to LCL when item
17855    activated (only QtKey_Return activates)}
17856   if not FMouseDoubleClicked then
17857   begin
17858     AKeyEvent := QKeyEvent_create(QEventKeyPress, QtKey_Return, QtNoModifier);
17859     SlotKey(Widget, AKeyEvent);
17860     QEvent_destroy(AKeyEvent);
17861     AKeyEvent := QKeyEvent_create(QEventKeyRelease, QtKey_Return, QtNoModifier);
17862     SlotKey(Widget, AKeyEvent);
17863     QEvent_destroy(AKeyEvent);
17864   end else
17865   begin
17866     FMouseDoubleClicked := False;
17867     if QWidget_underMouse(Widget) then
17868     begin
17869       QCursor_pos(@AGlobalPos);
17870       QWidget_mapFromGlobal(Widget, @APos, @AGlobalPos);
17871       AMouseEvent := QMouseEvent_create(QEventMouseButtonDblClick, @APos,
17872         @AGlobalPos, QtLeftButton, QtLeftButton,
17873         QApplication_keyboardModifiers());
17874       SlotMouse(Widget, AMouseEvent);
17875       QMouseEvent_destroy(AMouseEvent);
17876     end;
17877   end;
17878 end;
17879 
17880 {------------------------------------------------------------------------------
17881   Function: TQtCalendar.SignalClicked
17882   Params:  None
17883   Returns: Nothing
17884            Sends msg LM_DAYCHANGED when OldDate<>NewDate
17885  ------------------------------------------------------------------------------}
17886 procedure TQtCalendar.SignalClicked(ADate: QDateH); cdecl;
17887 var
17888   AEvent: QMouseEventH;
17889   APos: TQtPoint;
17890   AGlobalPos: TQtPoint;
17891 begin
17892   {$IFDEF VerboseQt}
17893   writeln('TQtCalendar.signalClicked');
17894   {$ENDIF}
17895   DeliverDayChanged(ADate);
17896 
17897   if QWidget_underMouse(Widget) then
17898   begin
17899     {we create dummy event for LCL, and call directly SlotMouse() - no need
17900     to send it via event loop}
17901     QCursor_pos(@AGlobalPos);
17902     QWidget_mapFromGlobal(Widget, @APos, @AGlobalPos);
17903     AEvent := QMouseEvent_create(QEventMouseButtonPress, @APos, @AGlobalPos,
17904       QtLeftButton, QtLeftButton, QApplication_keyboardModifiers());
17905     SlotMouse(Widget, AEvent);
17906     QMouseEvent_destroy(AEvent);
17907     AEvent := QMouseEvent_create(QEventMouseButtonRelease, @APos, @AGlobalPos,
17908       QtLeftButton, QtLeftButton, QApplication_keyboardModifiers());
17909     SlotMouse(Widget, AEvent);
17910     QMouseEvent_destroy(AEvent);
17911   end;
17912 end;
17913 
17914 {------------------------------------------------------------------------------
17915   Function: TQtCalendar.SignalSelectionChanged
17916   Params:  None
17917   Returns: Nothing
17918 
17919   Notes: no event for date changed by keyboard ?!?
17920    always triggers even if selection isn't changed ...
17921    this is not Qt4 bug ... tested with pure Qt C++ app
17922  ------------------------------------------------------------------------------}
17923 procedure TQtCalendar.SignalSelectionChanged; cdecl;
17924 var
17925   Msg: TLMessage;
17926 begin
17927   {$IFDEF VerboseQt}
17928   writeln('TQtCalendar.SignalSelectionChanged');
17929   {$ENDIF}
17930   if InUpdate then
17931     exit;
17932   FillChar(Msg{%H-}, SizeOf(Msg), #0);
17933   Msg.Msg := LM_SELCHANGE;
17934   DeliverMessage(Msg);
17935 end;
17936 
17937 {------------------------------------------------------------------------------
17938   Function: TQtCalendar.SignalCurrentPageChanged
17939   Params:  None
17940   Returns: Nothing
17941 
17942   Notes: fixme what's wrong with those values ?!?
17943    with pure Qt C++ app this works ok, but via bindings get
17944    impossible year & month values ...
17945  ------------------------------------------------------------------------------}
17946 procedure TQtCalendar.signalCurrentPageChanged(p1, p2: Integer); cdecl;
17947 var
17948   Msg: TLMessage;
17949   ADate: QDateH;
17950   HasChanges: Boolean;
17951   TempYear, TempMonth: Integer;
17952 begin
17953   {$IFDEF VerboseQt}
17954   writeln('TQtCalendar.SignalCurrentPageChanged p1=',p1,' p2=',p2,' AMonth=',AMonth,' AYear=',AYear);
17955   {$ENDIF}
17956   if InUpdate then
17957     exit;
17958   TempYear := AYear;
17959   TempMonth := AMonth;
17960   FillChar(Msg{%H-}, SizeOf(Msg), #0);
17961   HasChanges := (TempYear <> p1) or (TempMonth <> p2);
17962 
17963   if HasChanges then
17964   begin
17965     ADate := QDate_create();
17966     try
17967       QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), ADate);
17968       QDate_setYMD(ADate, p1, p2, QDate_day(ADate));
17969       SetSelectedDate(ADate);
17970     finally
17971       QDate_destroy(ADate);
17972     end;
17973   end;
17974 
17975   if TempYear <> p1 then
17976   begin
17977     Msg.Msg := LM_YEARCHANGED;
17978     DeliverMessage(Msg);
17979   end;
17980 
17981   if TempMonth <> p2 then
17982   begin
17983     Msg.Msg := LM_MONTHCHANGED;
17984     DeliverMessage(Msg);
17985   end;
17986 
17987   if HasChanges then
17988   begin
17989     Msg.Msg := LM_CHANGED;
17990     DeliverMessage(Msg);
17991   end;
17992 end;
17993 
17994 { TQtHintWindow }
17995 
CreateWidgetnull17996 function TQtHintWindow.CreateWidget(const AParams: TCreateParams): QWidgetH;
17997 var
17998   Parent: QWidgetH;
17999 begin
18000   FFirstPaintEvent := True;
18001   FHasPaint := True;
18002   FNeedRestoreVisible := False;
18003   if AParams.WndParent <> 0 then
18004     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
18005   else
18006   if QApplication_activeModalWidget <> nil then
18007     Parent := QApplication_activeModalWidget
18008   else
18009     Parent := nil;
18010   Result := QWidget_create(Parent, QtToolTip);
18011   FDeleteLater := True;
18012   MenuBar := nil;
18013   {$IFDEF QTSCROLLABLEFORMS}
18014   ScrollArea := nil;
18015   {$ENDIF}
18016 end;
18017 
TQtHintWindow.WinIDNeedednull18018 function TQtHintWindow.WinIDNeeded: boolean;
18019 begin
18020   Result := False;
18021 end;
18022 
18023 procedure TQtHintWindow.InitializeWidget;
18024 begin
18025   inherited InitializeWidget;
18026   {$IFDEF HASX11}
18027   QtWidgetSet.AddHintHandle(Self);
18028   {$ENDIF}
18029 end;
18030 
18031 procedure TQtHintWindow.DeInitializeWidget;
18032 begin
18033   {$IFDEF HASX11}
18034   QtWidgetSet.RemoveHintHandle(Self);
18035   {$ENDIF}
18036   inherited DeInitializeWidget;
18037 end;
18038 
CanPaintBackgroundnull18039 function TQtHintWindow.CanPaintBackground: Boolean;
18040 begin
18041   Result := CanSendLCLMessage and getEnabled and
18042     (LCLObject.Color <> clDefault);
18043 end;
18044 
18045 procedure TQtHintWindow.SetDefaultColorRoles;
18046 begin
18047   WidgetColorRole := QPaletteToolTipBase;
18048   TextColorRole := QPaletteToolTipText;
18049 end;
18050 
18051 procedure TQtHintWindow.setVisible(AVisible: Boolean);
18052 var
18053   D: TRect;
18054   R: TRect;
18055   Pt: TQtPoint;
18056   ScreenNumber: integer;
18057 begin
18058   // must use ClassType comparision here since qt is buggy about hints.#16551
18059   if AVisible and
18060     ((LCLObject.ClassType = THintWindow) or
18061       (LCLObject.InheritsFrom(THintWindow))) then
18062   begin
18063     R := getGeometry;
18064 
18065     if QDesktopWidget_isVirtualDesktop(QApplication_desktop()) then
18066     begin
18067       Pt.x := R.Left;
18068       Pt.y := R.Top;
18069       ScreenNumber := QDesktopWidget_screenNumber(QApplication_desktop(), @Pt);
18070     end
18071     else
18072     begin
18073       if Widget <> nil then
18074         ScreenNumber := QDesktopWidget_screenNumber(QApplication_desktop(), Widget)
18075       else
18076         ScreenNumber := 0;
18077     end;
18078     {$IFDEF DARWIN}
18079     QDesktopWidget_availableGeometry(QApplication_desktop() ,@D, ScreenNumber);
18080     {$ELSE}
18081     QDesktopWidget_screenGeometry(QApplication_desktop() ,@D, ScreenNumber);
18082     {$ENDIF}
18083 
18084     // place hint window within monitor rect
18085     if R.Right-R.Left > D.Right-D.Left then // check width
18086       R.Right := R.Left + D.Right-D.Left;
18087     if R.Bottom-R.Top > D.Bottom-D.Top then // check height
18088       R.Bottom := R.Top + D.Bottom-D.Top;
18089     if R.Left < D.Left then
18090       OffsetRect(R, D.Left-R.Left, 0);
18091     if R.Top < D.Top then
18092       OffsetRect(R, 0, D.Top-R.Top);
18093     if (R.Right > D.Right) then
18094       OffsetRect(R, D.Right-R.Right, 0);
18095     if (R.Bottom > D.Bottom) then
18096       OffsetRect(R, 0, D.Bottom-R.Bottom);
18097 
18098     move(R.Left, R.Top);
18099   end;
18100   inherited setVisible(AVisible);
18101 end;
18102 
18103 { TQtPage }
18104 
CreateWidgetnull18105 function TQtPage.CreateWidget(const AParams: TCreateParams): QWidgetH;
18106 var
18107   Parent: QWidgetH;
18108 begin
18109   FHasPaint := True;
18110   if AParams.WndParent <> 0 then
18111     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
18112   else
18113     Parent := nil;
18114   Result := QWidget_create(Parent);
18115   if (QtVersionMajor = 4) and (QtVersionMinor < 6) then
18116     QWidget_setAutoFillBackground(Result, True);
18117 end;
18118 
TQtPage.EventFilternull18119 function TQtPage.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
18120 var
18121   ASize: TSize;
18122   ACapture: HWND;
18123   B: Boolean;
18124 begin
18125   Result := False;
18126   if LCLObject = nil then
18127     exit;
18128   if (QEvent_type(Event) = QEventResize) then
18129   begin
18130     if (csDestroying in LCLObject.ComponentState) or
18131       (csDestroyingHandle in LCLObject.ControlState) then
18132         exit;
18133     if not testAttribute(QtWA_Mapped) then
18134     begin
18135       ASize := QResizeEvent_size(QResizeEventH(Event))^;
18136       {$IFDEF VerboseQtResize}
18137       DebugLn('TQtPage.EventFilter widget is not mapped, resize event size=',dbgs(ASize));
18138       {$ENDIF}
18139       if (ASize.cx = 0) and (ASize.cy = 0) then
18140       begin
18141         ASize.cx := LCLObject.Width;
18142         ASize.cy := LCLObject.Height;
18143         {$IFDEF VerboseQtResize}
18144         DebugLn('TQtPage.EventFilter sending LCL size as size=',dbgs(ASize),' since our size is still 0x0');
18145         {$ENDIF}
18146       end;
18147       DelayResizeEvent(QWidgetH(Sender), ASize);
18148       exit;
18149     end;
18150   end else
18151   if (QEvent_type(Event) = QEventShow) and Assigned(LCLObject) and
18152     not (csDesigning in LCLObject.ComponentState) then
18153   begin
18154     if Assigned(DragManager) and DragManager.IsDragging then
18155       ACapture := GetCapture
18156     else
18157       ACapture := 0;
18158     B := (ACapture <> 0) and (ACapture <> HWND(Self));
18159     Result := inherited EventFilter(Sender, Event);
18160     if B then
18161     begin
18162       QtWidgetSet.InvalidateWidgetAtCache;
18163       SetCapture(0);
18164       SetCapture(HWND(Self));
18165     end;
18166   end else
18167   Result := inherited EventFilter(Sender, Event);
18168 end;
18169 
TQtPage.getIconnull18170 function TQtPage.getIcon: QIconH;
18171 begin
18172   Result := FIcon;
18173 end;
18174 
getIndexnull18175 function TQtPage.getIndex(const ATextChanging: Boolean = False): Integer;
18176 var
18177   AParent: QTabWidgetH;
18178 
CanReturnIndexnull18179   function CanReturnIndex: Boolean;
18180   begin
18181     Result := AParent <> nil;
18182     if Result then
18183       Result := QWidget_isVisible(AParent) or
18184         ( (QtVersionMajor >= 4) and (QtVersionMinor >= 6)
18185          and LCLObject.HandleObjectShouldBeVisible );
18186   end;
18187 
18188 begin
18189   AParent := getTabWidget;
18190   if CanReturnIndex or ATextChanging then
18191     Result := QTabWidget_indexOf(AParent, Widget)
18192   else
18193   if not QObject_inherits(QWidget_parentWidget(Widget),'QStackedWidget') then
18194     Result := 0
18195   else
18196     Result := -1;
18197 end;
18198 
getTabWidgetnull18199 function TQtPage.getTabWidget: QTabWidgetH;
18200 var
18201   AParent: QWidgetH;
18202 begin
18203   // it is placed to the stack widget and stack widget into tab widget
18204   AParent := QWidget_parentWidget(Widget);
18205   // do not localize !
18206   if (AParent <> nil) and QObject_inherits(AParent,'QStackedWidget') then
18207     Result := QTabWidgetH(QWidget_parentWidget(AParent))
18208   else
18209     Result := nil;
18210 end;
18211 
18212 procedure TQtPage.setIcon(const AIcon: QIconH);
18213 var
18214   AParent: QTabWidgetH;
18215   TabWidget: TQtTabWidget;
18216 begin
18217   FIcon := AIcon;
18218   AParent := getTabWidget;
18219   if AParent <> nil then
18220   begin
18221     if ChildOfComplexWidget = ccwTabWidget then
18222     begin
18223       TabWidget := TQtTabWidget(LCLObject.Parent.Handle);
18224       TabWidget.setTabIcon(TabWidget.indexOf(Widget), AIcon);
18225     end else
18226       QTabWidget_setTabIcon(AParent, getIndex, AIcon);
18227   end;
18228 end;
18229 
18230 procedure TQtPage.setText(const W: WideString);
18231 var
18232   AParent: QTabWidgetH;
18233   Index: integer;
18234 begin
18235   inherited setText(W);
18236   AParent := getTabWidget;
18237   if (AParent <> nil) then
18238   begin
18239     Index := getIndex(True);
18240     if Index <> -1 then
18241       QTabWidget_setTabText(AParent, Index, @W);
18242   end;
18243 end;
18244 
18245 { TQtAbstractItemView }
18246 
TQtAbstractItemView.GetOwnerDrawnnull18247 function TQtAbstractItemView.GetOwnerDrawn: Boolean;
18248 begin
18249   Result := FNewDelegate <> nil;
18250 end;
18251 
TQtAbstractItemView.getIconSizenull18252 function TQtAbstractItemView.getIconSize: TSize;
18253 begin
18254   QAbstractItemView_iconSize(QAbstractItemViewH(Widget), @Result);
18255 end;
18256 
TQtAbstractItemView.GetItemFlagsnull18257 function TQtAbstractItemView.GetItemFlags(AIndex: Integer): QtItemFlags;
18258 begin
18259   Result := QtNoItemFlags;
18260 end;
18261 
18262 procedure TQtAbstractItemView.setIconSize(const AValue: TSize);
18263 begin
18264   QAbstractItemView_setIconSize(QAbstractItemViewH(Widget), @AValue);
18265 end;
18266 
18267 procedure TQtAbstractItemView.SetItemFlags(AIndex: Integer; AValue: QtItemFlags
18268   );
18269 begin
18270   // must be overrided !
18271 end;
18272 
18273 procedure TQtAbstractItemView.SetOwnerDrawn(const AValue: Boolean);
18274 begin
18275   if AValue and (FNewDelegate = nil) then
18276   begin
18277     FNewDelegate := QLCLItemDelegate_create(Widget);
18278 
18279     QLCLItemDelegate_override_sizeHint(FNewDelegate, @ItemDelegateSizeHint);
18280 
18281     QLCLItemDelegate_override_Paint(FNewDelegate, @ItemDelegatePaint);
18282 
18283     FOldDelegate := QAbstractItemView_itemDelegate(QAbstractItemViewH(Widget));
18284     QAbstractItemView_setItemDelegate(QAbstractItemViewH(Widget), FNewDelegate);
18285   end
18286   else
18287   if ((not AValue) and (FNewDelegate <> nil)) then
18288   begin
18289     {TQtAbstractItemView.SetOwnerDrawn: this call avoid sporadic AVs with
18290      QLCLItemDelegate_destroy(FNewDelegate).
18291      howto reproduce: comment next code line, recompile laz, and then in oi click
18292      in first field eg. Action (TForm), now push kbd down arrow let it pass all properties,
18293      you'll have crash at Constraints property.}
18294     FNewDelegate := QLCLItemDelegateH(QAbstractItemView_itemDelegate(QAbstractItemViewH(Widget)));
18295     QAbstractItemView_setItemDelegate(QAbstractItemViewH(Widget), FOldDelegate);
18296     QLCLItemDelegate_destroy(FNewDelegate);
18297     FNewDelegate := nil;
18298   end;
18299 end;
18300 
18301 procedure TQtAbstractItemView.OwnerDataNeeded(ARect: TRect);
18302 begin
18303   // override
18304 end;
18305 
18306 procedure TQtAbstractItemView.PostponedMouseRelease(AEvent: QEventH);
18307  // postpone mouse release for LCL
18308 var
18309   ev: QMouseEventH;
18310 begin
18311   if QEvent_type(AEvent) = QEventMouseButtonRelease then
18312   begin
18313     ev := QMouseEventH(AEvent);
18314     FSavedEvent := QMouseEvent_create(QEventMouseButtonRelease,
18315       QMouseEvent_pos(ev), QMouseEvent_globalPos(ev),
18316       QMouseEvent_button(ev), QMouseEvent_buttons(ev),
18317       QInputEvent_modifiers(QInputEventH(AEvent)));
18318     FSavedEventTimer := QTimer_create(Widget);
18319     FSavedEventTimerHook := QTimer_hook_create(FSavedEventTimer);
18320     QTimer_hook_hook_timeout(FSavedEventTimerHook,
18321       @PostponedMouseReleaseTimerEvent);
18322     QTimer_setInterval(FSavedEventTimer, 5);
18323     QTimer_setSingleShot(FSavedEventTimer, True);
18324     QTimer_start(FSavedEventTimer);
18325   end;
18326 end;
18327 
18328 procedure TQtAbstractItemView.PostponedMouseReleaseTimerEvent(); cdecl;
18329 begin
18330   if FSavedEvent <> nil then
18331   begin
18332     SlotMouse(Widget, FSavedEvent);
18333     QMouseEvent_destroy(FSavedEvent);
18334     FSavedEvent := nil;
18335     QTimer_hook_destroy(FSavedEventTimerHook);
18336     QTimer_destroy(FSavedEventTimer);
18337     FSavedEventTimer := nil;
18338     FSavedEventTimerHook := nil;
18339   end;
18340 end;
18341 
18342 constructor TQtAbstractItemView.Create(const AWinControl: TWinControl;
18343   const AParams: TCreateParams);
18344 begin
18345   inherited Create(AWinControl, AParams);
18346   FOldDelegate := nil;
18347   FNewDelegate := nil;
18348 end;
18349 
18350 destructor TQtAbstractItemView.Destroy;
18351 begin
18352   if FNewDelegate <> nil then
18353     SetOwnerDrawn(False);
18354   inherited Destroy;
18355 end;
18356 
18357 procedure TQtAbstractItemView.signalActivated(index: QModelIndexH); cdecl;
18358 var
18359   Msg: TLMessage;
18360 begin
18361   // writeln('SIGNAL: TQtAbstractItemView.signalActivated');
18362   FillChar(Msg{%H-}, SizeOf(Msg), 0);
18363   Msg.Msg := LM_ACTIVATE;
18364   DeliverMessage( Msg );
18365 end;
18366 
18367 procedure TQtAbstractItemView.signalClicked(index: QModelIndexH); cdecl;
18368 begin
18369   {use to be overriden by descedants, don''t implement it here,
18370    or U get in trouble with TQtListView && TQtListWidget items.}
18371 end;
18372 
18373 procedure TQtAbstractItemView.signalDoubleClicked(index: QModelIndexH); cdecl;
18374 begin
18375   {use to be overriden by descedants, don''t implement it here,
18376    or U get in trouble with TQtListView && TQtListWidget items.}
18377 end;
18378 
18379 procedure TQtAbstractItemView.signalEntered(index: QModelIndexH); cdecl;
18380 var
18381   Msg: TLMessage;
18382 begin
18383   FillChar(Msg{%H-}, SizeOf(Msg), 0);
18384   Msg.Msg := LM_ENTER;
18385   DeliverMessage( Msg );
18386 end;
18387 
18388 procedure TQtAbstractItemView.signalPressed(index: QModelIndexH); cdecl;
18389 begin
18390   {should be overriden by descedants}
18391 end;
18392 
18393 procedure TQtAbstractItemView.signalViewportEntered; cdecl;
18394 begin
18395   {should be overriden by descedants}
18396 end;
18397 
18398 procedure TQtAbstractItemView.AttachEvents;
18399 begin
18400   inherited AttachEvents;
18401   FSignalActivated := QAbstractItemView_hook_create(Widget);
18402   FSignalClicked := QAbstractItemView_hook_create(Widget);
18403   FSignalDoubleClicked := QAbstractItemView_hook_create(Widget);
18404   FSignalEntered := QAbstractItemView_hook_create(Widget);
18405   FSignalPressed := QAbstractItemView_hook_create(Widget);
18406   FSignalViewportEntered := QAbstractItemView_hook_create(Widget);
18407 
18408   QAbstractItemView_hook_hook_activated(FSignalActivated, @SignalActivated);
18409 
18410   QAbstractItemView_hook_hook_clicked(FSignalClicked, @SignalClicked);
18411 
18412   QAbstractItemView_hook_hook_doubleClicked(FSignalDoubleClicked, @SignalDoubleClicked);
18413 
18414   QAbstractItemView_hook_hook_entered(FSignalEntered, @SignalEntered);
18415 
18416   QAbstractItemView_hook_hook_pressed(FSignalPressed, @SignalPressed);
18417 
18418   QAbstractItemView_hook_hook_viewportEntered(FSignalViewportEntered, @SignalViewportEntered);
18419 
18420   FAbstractItemViewportEventHook := QObject_hook_create(viewportWidget);
18421   QObject_hook_hook_events(FAbstractItemViewportEventHook, @itemViewViewportEventFilter);
18422 
18423   // initialize scrollbars
18424   verticalScrollBar;
18425   horizontalScrollBar;
18426 
18427 end;
18428 
18429 procedure TQtAbstractItemView.DetachEvents;
18430 begin
18431   if FSignalActivated <> nil then
18432   begin
18433     QAbstractItemView_hook_destroy(FSignalActivated);
18434     FSignalActivated := nil;
18435   end;
18436   if FSignalClicked <> nil then
18437   begin
18438     QAbstractItemView_hook_destroy(FSignalClicked);
18439     FSignalClicked := nil;
18440   end;
18441   if FSignalDoubleClicked <> nil then
18442   begin
18443     QAbstractItemView_hook_destroy(FSignalDoubleClicked);
18444     FSignalDoubleClicked := nil;
18445   end;
18446   if FSignalEntered <> nil then
18447   begin
18448     QAbstractItemView_hook_destroy(FSignalEntered);
18449     FSignalEntered := nil;
18450   end;
18451   if FSignalPressed <> nil then
18452   begin
18453     QAbstractItemView_hook_destroy(FSignalPressed);
18454     FSignalPressed := nil;
18455   end;
18456   if FSignalViewportEntered <> nil then
18457   begin
18458     QAbstractItemView_hook_destroy(FSignalViewportEntered);
18459     FSignalViewportEntered := nil;
18460   end;
18461   if FAbstractItemViewportEventHook <> nil then
18462   begin
18463     QObject_hook_destroy(FAbstractItemViewportEventHook);
18464     FAbstractItemViewportEventHook := nil;
18465   end;
18466   inherited DetachEvents;
18467 end;
18468 
TQtAbstractItemView.itemViewViewportEventFilternull18469 function TQtAbstractItemView.itemViewViewportEventFilter(Sender: QObjectH;
18470   Event: QEventH): Boolean; cdecl;
18471 var
18472   R: TRect;
18473   ASize: TSize;
18474   AResizeEvent: QResizeEventH;
18475 begin
18476   {we install only mouse events on QAbstractItemView viewport}
18477   Result := False;
18478   QEvent_accept(Event);
18479 
18480   if (LCLObject = nil) then
18481     exit;
18482 
18483   BeginEventProcessing;
18484   try
18485     {ownerdata is needed only before qt paint's data}
18486     if (ViewStyle >= 0) and FOwnerData and
18487       (QEvent_type(Event) = QEventPaint) then
18488     begin
18489       QPaintEvent_rect(QPaintEventH(Event), @R);
18490       OwnerDataNeeded(R);
18491     end;
18492 
18493     case QEvent_type(Event) of
18494       QEventResize:
18495       begin
18496         if Assigned(FOwner) then
18497           ASize := FOwner.getSize
18498         else
18499           ASize := getSize;
18500         AResizeEvent := QResizeEvent_create(@ASize, @ASize);
18501         try
18502           SlotResize(AResizeEvent);
18503         finally
18504           QEvent_destroy(AResizeEvent);
18505         end;
18506       end;
18507       QEventHide:
18508         if QWidget_mouseGrabber() = QWidgetH(Sender) then
18509           ReleaseCapture;
18510       QEventMouseButtonPress,
18511       QEventMouseButtonRelease,
18512       QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
18513       QEventContextMenu: Result := SlotContextMenu(Sender, Event);
18514       else
18515       begin
18516         if not (ViewStyle in [Ord(vsIcon), Ord(vsSmallIcon)]) then
18517         begin
18518           {do not change selection if mousepressed and mouse moved}
18519           Result := (QEvent_type(Event) = QEventMouseMove) and
18520             hasFocus and (QApplication_mouseButtons() > 0);
18521           QEvent_ignore(Event);
18522         end;
18523       end;
18524     end;
18525   finally
18526     EndEventProcessing;
18527   end;
18528 end;
18529 
18530 procedure TQtAbstractItemView.setDefaultColorRoles;
18531 begin
18532   WidgetColorRole := QPaletteBase;
18533   TextColorRole := QPaletteText;
18534 end;
18535 
18536 procedure TQtAbstractItemView.clearSelection;
18537 begin
18538   QAbstractItemView_clearSelection(QAbstractItemViewH(Widget));
18539 end;
18540 
getModelnull18541 function TQtAbstractItemView.getModel: QAbstractItemModelH;
18542 begin
18543   Result := QAbstractItemView_model(QAbstractItemViewH(Widget));
18544 end;
18545 
TQtAbstractItemView.getRowHeightnull18546 function TQtAbstractItemView.getRowHeight(ARowIndex: integer): integer;
18547 begin
18548   Result := QAbstractItemView_sizeHintForRow(QAbstractItemViewH(Widget),
18549     ARowIndex);
18550 end;
18551 
TQtAbstractItemView.getSelectionModenull18552 function TQtAbstractItemView.getSelectionMode: QAbstractItemViewSelectionMode;
18553 begin
18554   Result := QAbstractItemView_SelectionMode(QAbstractItemViewH(Widget));
18555 end;
18556 
getTopItemnull18557 function TQtAbstractItemView.getTopItem: integer;
18558 begin
18559   Result := -1;
18560 end;
18561 
18562 {------------------------------------------------------------------------------
18563   Function: TQtAbstractItemView.getVisibleRowCount
18564   Params:  Boolean
18565   Returns: if AFirstVisibleOnly = False (default) then it returns number
18566   of visible rows, or 0 if there's no visible rows.
18567   When AFirstVisibleOnly = True then it returns index of first visible row,
18568   otherwise result is -1.
18569   This function is used by TQtTreeWidget and TQtListWidget.
18570  ------------------------------------------------------------------------------}
getVisibleRowCountnull18571 function TQtAbstractItemView.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
18572 begin
18573   Result := 0;
18574 end;
18575 
18576 procedure TQtAbstractItemView.modelIndex(retval: QModelIndexH; row, column: Integer; parent: QModelIndexH = nil);
18577 begin
18578   QAbstractItemModel_index(getModel, retval, row, column, parent);
18579 end;
18580 
TQtAbstractItemView.visualRectnull18581 function TQtAbstractItemView.visualRect(Index: QModelIndexH): TRect;
18582 begin
18583   QAbstractItemView_visualRect(QAbstractItemViewH(Widget), @Result, Index);
18584 end;
18585 
18586 procedure TQtAbstractItemView.setEditTriggers(
18587   ATriggers: QAbstractItemViewEditTriggers);
18588 begin
18589   QAbstractItemView_setEditTriggers(QAbstractItemViewH(Widget), ATriggers);
18590 end;
18591 
18592 procedure TQtAbstractItemView.setSelectionMode(
18593   AMode: QAbstractItemViewSelectionMode);
18594 begin
18595   QAbstractItemView_setSelectionMode(QAbstractItemViewH(Widget), AMode);
18596 end;
18597 
18598 procedure TQtAbstractItemView.setSelectionBehavior(
18599   ABehavior: QAbstractItemViewSelectionBehavior);
18600 begin
18601   QAbstractItemView_setSelectionBehavior(QAbstractItemViewH(Widget), ABehavior);
18602 end;
18603 
18604 procedure TQtAbstractItemView.setWordWrap(const AValue: Boolean);
18605 begin
18606   // override
18607 end;
18608 
18609 procedure TQtAbstractItemView.ItemDelegateSizeHint(
18610   option: QStyleOptionViewItemH; index: QModelIndexH; Size: PSize); cdecl;
18611 var
18612   Msg: TLMMeasureItem;
18613   MeasureItemStruct: TMeasureItemStruct;
18614   decorationSize: TSize;
18615   Metric: Integer;
18616 begin
18617   QStyleOptionViewItem_decorationSize(option, @decorationSize);
18618   Metric := QStyle_pixelMetric(QApplication_style(), QStylePM_FocusFrameVMargin, nil, nil) * 2;
18619   MeasureItemStruct.itemID := UINT(QModelIndex_row(index));
18620   MeasureItemStruct.itemWidth := UINT(Size^.cx);
18621   MeasureItemStruct.itemHeight := UINT(Max(Size^.cy, (decorationSize.cy + Metric)));
18622   Msg.Msg := LM_MEASUREITEM;
18623   Msg.MeasureItemStruct := @MeasureItemStruct;
18624   DeliverMessage(Msg);
18625   Size^.cx := Longint(MeasureItemStruct.itemWidth);
18626   Size^.cy := Longint(MeasureItemStruct.itemHeight);
18627 end;
18628 
18629 procedure TQtAbstractItemView.ItemDelegatePaint(painter: QPainterH;
18630   option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
18631 begin
18632   // should be overrided
18633 end;
18634 
18635 { TQtRubberBand }
18636 
CreateWidgetnull18637 function TQtRubberBand.CreateWidget(const AParams: TCreateParams): QWidgetH;
18638 var
18639   Parent: QWidgetH;
18640 begin
18641   if AParams.WndParent <> 0 then
18642     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
18643   else
18644     Parent := nil;
18645   Result := QRubberBand_create(FShape, Parent);
18646 end;
18647 
18648 constructor TQtRubberBand.Create(const AWinControl: TWinControl;
18649   const AParams: TCreateParams);
18650 begin
18651   FShape := QRubberBandLine;
18652   inherited Create(AWinControl, AParams);
18653 end;
18654 
18655 procedure TQtRubberBand.move(ANewLeft, ANewTop: Integer);
18656 begin
18657   QRubberBand_move(QRubberBandH(Widget), ANewLeft, ANewTop);
18658 end;
18659 
18660 procedure TQtRubberBand.Resize(ANewWidth, ANewHeight: Integer);
18661 begin
18662   QRubberBand_resize(QRubberBandH(Widget), ANewWidth, ANewHeight);
18663 end;
18664 
18665 procedure TQtRubberBand.setGeometry(ARect: TRect);
18666 begin
18667   QRubberBand_setGeometry(QRubberBandH(Widget), @ARect);
18668 end;
18669 
TQtRubberBand.getShapenull18670 function TQtRubberBand.getShape: QRubberBandShape;
18671 begin
18672   Result := QRubberBand_shape(QRubberBandH(Widget));
18673 end;
18674 
18675 procedure TQtRubberBand.setShape(AShape: QRubberBandShape);
18676 begin
18677   if getShape <> AShape then
18678   begin
18679     // recreate widget
18680     FShape := AShape;
18681     RecreateWidget;
18682     AttachEvents;
18683   end;
18684 end;
18685 
18686 { TQtFileDialog }
18687 
TQtFileDialog.CreateWidgetnull18688 function TQtFileDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags): QWidgetH;
18689 begin
18690   Result := QFileDialog_create(parent, f);
18691   {$ifndef QT_NATIVE_DIALOGS}
18692   FBackBtn := nil;
18693   FForwardBtn := nil;
18694   FUpBtn := nil;
18695   FFileNameEdit := nil;
18696   FComboType := nil;
18697   FComboHistory := nil;
18698   FSideView := nil;;
18699   FTreeView := nil;
18700   FListView := nil;
18701 
18702   FTreeViewEventFilter := nil; // detailed view
18703   FListViewEventFilter := nil; // small icons
18704   FSideViewEventFilter := nil; // sidebar
18705   FFileNameEditEventFilter := nil; // filename editor
18706   FComboTypeEventFilter := nil;
18707   FComboHistoryEventFilter := nil;
18708   {$endif}
18709 end;
18710 
18711 procedure TQtFileDialog.AttachEvents;
18712 begin
18713   inherited AttachEvents;
18714 
18715   FCurrentChangedHook := QFileDialog_hook_create(Widget);
18716   FDirecotyEnteredHook := QFileDialog_hook_create(Widget);
18717   FFilterSelectedHook := QFileDialog_hook_create(Widget);
18718 
18719   QFileDialog_hook_hook_filterSelected(FFilterSelectedHook, @FilterSelectedEvent);
18720 
18721   QFileDialog_hook_hook_currentChanged(FCurrentChangedHook, @CurrentChangedEvent);
18722 
18723   QFileDialog_hook_hook_directoryEntered(FDirecotyEnteredHook, @DirectoryEnteredEvent);
18724 end;
18725 
18726 procedure TQtFileDialog.DetachEvents;
18727 begin
18728   if FCurrentChangedHook <> nil then
18729   begin
18730     QFileDialog_hook_destroy(FCurrentChangedHook);
18731     FCurrentChangedHook := nil;
18732   end;
18733   if FFilterSelectedHook <> nil then
18734   begin
18735     QFileDialog_hook_destroy(FFilterSelectedHook);
18736     FFilterSelectedHook := nil;
18737   end;
18738   if FDirecotyEnteredHook <> nil then
18739   begin
18740     QFileDialog_hook_destroy(FDirecotyEnteredHook);
18741     FDirecotyEnteredHook := nil;
18742   end;
18743   {$ifndef QT_NATIVE_DIALOGS}
18744   if FTreeViewEventFilter <> nil then
18745   begin
18746     QObject_hook_destroy(FTreeViewEventFilter);
18747     FTreeViewEventFilter := nil;
18748   end;
18749   if FListViewEventFilter <> nil then
18750   begin
18751     QObject_hook_destroy(FListViewEventFilter);
18752     FListViewEventFilter := nil;
18753   end;
18754   if FSideViewEventFilter <> nil then
18755   begin
18756     QObject_hook_destroy(FSideViewEventFilter);
18757     FSideViewEventFilter := nil;
18758   end;
18759   if FFileNameEditEventFilter <> nil then
18760   begin
18761     QObject_hook_destroy(FFileNameEditEventFilter);
18762     FFileNameEditEventFilter := nil;
18763   end;
18764   if FComboTypeEventFilter <> nil then
18765   begin
18766     QObject_hook_destroy(FComboTypeEventFilter);
18767     FComboTypeEventFilter := nil;
18768   end;
18769   if FComboHistoryEventFilter <> nil then
18770   begin
18771     QObject_hook_destroy(FComboHistoryEventFilter);
18772     FComboHistoryEventFilter := nil;
18773   end;
18774   {$endif}
18775   inherited DetachEvents;
18776 end;
18777 
18778 {$ifndef QT_NATIVE_DIALOGS}
TQtFileDialog.EventFilternull18779 function TQtFileDialog.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
18780   cdecl;
18781 begin
18782   Result := False;
18783   if Sender <> Widget then
18784   begin
18785     // TODO: Ctrl + Letter for Open/Save button trigger
18786     // ALT + Left, Up, Right to navigate (Backward, Up parent, Forward) in list.
18787     // ALT + E to focus fileedit
18788     // ALT + H to focus lookInCombo (history combo)
18789     // ALT + L to focus view
18790     // ALT + N to create new folder (TODO)
18791     // ALT + S to select sidebar
18792     // ALT + T to focus file type combo
18793     // ALT + V to change view style (TODO)
18794     case QEvent_type(Event) of
18795       QEventKeyPress:
18796         begin
18797           if (QKeyEvent_modifiers(QKeyEventH(Event)) and QtAltModifier <> 0) then
18798           begin
18799             case QKeyEvent_key(QKeyEventH(Event)) of
18800               QtKey_Left:
18801                 begin
18802                   if Assigned(FBackBtn) and QWidget_isVisible(FBackBtn) and
18803                     QWidget_isEnabled(FBackBtn) then
18804                     QAbstractButton_click(QAbstractButtonH(FBackBtn));
18805                   Result := True;
18806                 end;
18807               QtKey_Right:
18808                 begin
18809                   if Assigned(FForwardBtn) and QWidget_isVisible(FForwardBtn) and
18810                     QWidget_isEnabled(FForwardBtn) then
18811                     QAbstractButton_click(QAbstractButtonH(FForwardBtn));
18812                   Result := True;
18813                 end;
18814               QtKey_Up:
18815                 begin
18816                   if Assigned(FUpBtn) and QWidget_isVisible(FUpBtn) and
18817                     QWidget_isEnabled(FUpBtn) then
18818                     QAbstractButton_click(QAbstractButtonH(FUpBtn));
18819                   Result := True;
18820                 end;
18821               QtKey_E:
18822                 begin
18823                   if Assigned(FFileNameEdit) and
18824                     QWidget_isVisible(FFileNameEdit) and
18825                     QWidget_isEnabled(FFileNameEdit) and
18826                     not QWidget_hasFocus(FFileNameEdit) then
18827                     QWidget_setFocus(FFileNameEdit);
18828                   Result := True;
18829                 end;
18830               QtKey_H:
18831                 begin
18832                   if Assigned(FComboHistory) and
18833                     QWidget_isVisible(FComboHistory) and
18834                     QWidget_isEnabled(FComboHistory) and
18835                     not QWidget_hasFocus(FComboHistory) then
18836                       QWidget_setFocus(FComboHistory);
18837                   Result := True;
18838                 end;
18839               QtKey_L:
18840                 begin
18841                   if Assigned(FTreeView) and
18842                     QWidget_isVisible(FTreeView) and
18843                     QWidget_isEnabled(FTreeView) and
18844                     not QWidget_hasFocus(FTreeView) then
18845                     QWidget_setFocus(FTreeView)
18846                   else
18847                   if Assigned(FListView) and
18848                     QWidget_isVisible(FListView) and
18849                     QWidget_isEnabled(FListView) and
18850                     not QWidget_hasFocus(FListView) then
18851                     QWidget_setFocus(FListView);
18852                   Result := True;
18853                 end;
18854               QtKey_N:
18855                 begin
18856                   //TODO: create newfolder
18857                   Result := True;
18858                 end;
18859               QtKey_S:
18860                 begin
18861                   // select sidebar
18862                   if Assigned(FSideView) and
18863                     QWidget_isVisible(FSideView) and
18864                     QWidget_isEnabled(FSideView) and
18865                     not QWidget_hasFocus(FSideView) then
18866                     QWidget_setFocus(FSideView);
18867                   Result := True;
18868                 end;
18869               QtKey_T:
18870                 begin
18871                   // focus combo filetype
18872                   if Assigned(FComboType) and
18873                     QWidget_isVisible(FComboType) and
18874                     QWidget_isEnabled(FComboType) and
18875                     not QWidget_hasFocus(FComboType) then
18876                       QWidget_setFocus(FComboType);
18877                   Result := True;
18878                 end;
18879               QtKey_V:
18880                 begin
18881                   //TODO: change viewStyle
18882                   Result := True;
18883                 end;
18884             end;
18885           end;
18886         end;
18887     end;
18888   end else
18889     Result := inherited EventFilter(Sender, Event);
18890 end;
18891 {$endif}
18892 
TQtFileDialog.selectFilenull18893 function TQtFileDialog.selectFile: WideString;
18894 begin
18895   QFileDialog_selectFile(QFileDialogH(Widget), @Result);
18896 end;
18897 
18898 procedure TQtFileDialog.selectedFiles(retval: QStringListH);
18899 begin
18900   QFileDialog_selectedFiles(QFileDialogH(Widget), retval);
18901 end;
18902 
18903 procedure TQtFileDialog.setAcceptMode(const AMode: QFileDialogAcceptMode);
18904 begin
18905   QFileDialog_setAcceptMode(QFileDialogH(Widget), AMode)
18906 end;
18907 
18908 procedure TQtFileDialog.setConfirmOverwrite(const AValue: Boolean);
18909 begin
18910   QFileDialog_setConfirmOverwrite(QFileDialogH(Widget), AValue);
18911 end;
18912 
18913 procedure TQtFileDialog.setDirectory(const ADirectory: WideString);
18914 begin
18915   QFileDialog_setDirectory(QFileDialogH(Widget), @ADirectory);
18916 end;
18917 
18918 procedure TQtFileDialog.setHistory(AList: TStrings);
18919 var
18920   List: QStringListH;
18921   i: Integer;
18922   WStr: WideString;
18923 begin
18924   List := QStringList_create();
18925   try
18926     for i := 0 to AList.Count - 1 do
18927     begin
18928       WStr := AList{%H-}.Strings[i];
18929       QStringList_append(List, @WStr);
18930     end;
18931     QFileDialog_setHistory(QFileDialogH(Widget), List);
18932   finally
18933     QStringList_destroy(List);
18934   end;
18935 end;
18936 
18937 procedure TQtFileDialog.setFileMode(const AMode: QFileDialogFileMode);
18938 begin
18939   QFileDialog_setFileMode(QFileDialogH(Widget), AMode);
18940 end;
18941 
18942 procedure TQtFileDialog.setFilter(const AFilter: WideString);
18943 begin
18944   QFileDialog_setNameFilter(QFileDialogH(Widget), @AFilter);
18945 end;
18946 
18947 procedure TQtFileDialog.setLabelText(const ALabel: QFileDialogDialogLabel;
18948   const AText: WideString);
18949 begin
18950   QFileDialog_setLabelText(QFileDialogH(Widget), ALabel, @AText);
18951 end;
18952 
18953 procedure TQtFileDialog.setReadOnly(const AReadOnly: Boolean);
18954 begin
18955   QFileDialog_setReadOnly(QFileDialogH(Widget), AReadOnly);
18956 end;
18957 
18958 procedure TQtFileDialog.setSelectedFilter(const ASelFilter: WideString);
18959 begin
18960   QFileDialog_selectNameFilter(QFileDialogH(Widget), @ASelFilter);
18961 end;
18962 
18963 procedure TQtFileDialog.setViewMode(const AMode: QFileDialogViewMode);
18964 begin
18965   QFileDialog_setViewMode(QFileDialogH(Widget), AMode);
18966 end;
18967 
18968 {------------------------------------------------------------------------------
18969   Function: TQtFileDialog.setShortcuts
18970   Params:  None
18971   Returns: Nothing
18972   Qt non-native dialogs doesn't set keyboard shortcuts, so we must do that.
18973   This functions hooks eventFilter of all widgets on QFileDialog.
18974  ------------------------------------------------------------------------------}
18975 {$ifndef QT_NATIVE_DIALOGS}
18976 procedure TQtFileDialog.setShortcuts(const AIsOpenDialog: Boolean);
18977 var
18978   AnIter: TQtObjectDump;
18979   i: Integer;
18980   Obj: QObjectH;
18981   WStr, ToolTip: WideString;
18982 begin
18983   // if there's auto recognition enabled then don''t set shortcuts
18984   // cause we are maybe native dialog and then boomer.
18985   if not QFileDialog_testOption(QFileDialogH(Widget),
18986     QFileDialogDontUseNativeDialog) then
18987     exit;
18988   FForwardBtn := nil;
18989   FBackBtn := nil;
18990   FUpBtn := nil;
18991 
18992   AnIter := TQtObjectDump.Create(Widget);
18993   try
18994     AnIter.DumpObject;
18995 
18996     for i := 0 to AnIter.ObjList.Count - 1 do
18997     begin
18998       Obj := QObjectH(AnIter.Objlist.Items[i]);
18999       if AnIter.IsWidget(Obj) then
19000       begin
19001         WStr := AnIter.GetObjectName(Obj);
19002         if (WStr = 'treeView') or (WStr = 'listView') or (WStr = 'sidebar') then
19003         begin
19004           if FForwardBtn = nil then
19005           begin
19006             FForwardBtn := AnIter.FindWidgetByName('forwardButton');
19007             if FForwardBtn <> nil then
19008             begin
19009               ToolTip := 'Forward (Alt + Right)';
19010               QWidget_setToolTip(FForwardBtn, @ToolTip);
19011             end;
19012           end;
19013           if FBackBtn = nil then
19014           begin
19015             FBackBtn := AnIter.FindWidgetByName('backButton');
19016             if FBackBtn <> nil then
19017             begin
19018               ToolTip := 'Back (Alt + Left)';
19019               QWidget_setToolTip(FBackBtn, @ToolTip);
19020             end;
19021           end;
19022           if FUpBtn = nil then
19023           begin
19024             FUpBtn := AnIter.FindWidgetByName('toParentButton');
19025             if FUpBtn <> nil then
19026             begin
19027               ToolTip := 'To parent directory (Alt + Up)';
19028               QWidget_setToolTip(FUpBtn, @ToolTip);
19029             end;
19030           end;
19031 
19032           if FForwardBtn <> nil then
19033           begin
19034             if WStr = 'treeView' then
19035             begin
19036               FTreeView := QWidgetH(Obj);
19037               FTreeViewEventFilter := QObject_hook_create(Obj);
19038               QObject_hook_hook_events(FTreeViewEventFilter, @EventFilter);
19039               ToolTip := 'Alt + L to focus this widget';
19040               QWidget_setToolTip(FTreeView, @ToolTip);
19041             end else
19042             if WStr = 'listView' then
19043             begin
19044               FListView := QWidgetH(Obj);
19045               FListViewEventFilter := QObject_hook_create(Obj);
19046               QObject_hook_hook_events(FListViewEventFilter, @EventFilter);
19047               ToolTip := 'Alt + L to focus this widget';
19048               QWidget_setToolTip(FListView, @ToolTip);
19049             end else
19050             if WStr = 'sidebar' then
19051             begin
19052               FSideView := QWidgetH(Obj);
19053               FSideViewEventFilter := QObject_hook_create(Obj);
19054               QObject_hook_hook_events(FSideViewEventFilter, @EventFilter);
19055               ToolTip := 'Alt + S to focus this widget';
19056               QWidget_setToolTip(FSideView, @ToolTip);
19057             end;
19058 
19059           end;
19060         end else
19061         if WStr = 'fileNameEdit' then
19062         begin
19063           FFileNameEdit := QWidgetH(Obj);
19064           FFileNameEditEventFilter := QObject_hook_create(Obj);
19065           QObject_hook_hook_events(FFileNameEditEventFilter, @EventFilter);
19066           ToolTip := 'Alt + E to focus this widget';
19067           QWidget_setToolTip(FFileNameEdit, @ToolTip);
19068         end else
19069         if WStr = 'fileTypeCombo' then
19070         begin
19071           FComboType := QWidgetH(Obj);
19072           FComboTypeEventFilter := QObject_hook_create(Obj);
19073           QObject_hook_hook_events(FComboTypeEventFilter, @EventFilter);
19074           ToolTip := 'Alt + T to focus this widget';
19075           QWidget_setToolTip(FComboType, @ToolTip);
19076         end else
19077         if WStr = 'lookInCombo' then
19078         begin
19079           FComboHistory := QWidgetH(Obj);
19080           FComboHistoryEventFilter := QObject_hook_create(Obj);
19081           QObject_hook_hook_events(FComboHistoryEventFilter, @EventFilter);
19082           ToolTip := 'Alt + H to focus this widget';
19083           QWidget_setToolTip(FComboHistory, @ToolTip);
19084         end;
19085       end;
19086     end;
19087 
19088   finally
19089     AnIter.Free;
19090   end;
19091 end;
19092 {$endif}
19093 
19094 procedure TQtFileDialog.FilterSelectedEvent(filter: PWideString); cdecl;
19095 var
19096   List: TQtStringList;
19097   index: Integer;
19098 begin
19099   if filter <> nil then
19100   begin
19101     List := TQtStringList.Create;
19102     getFilters(List.Handle);
19103     index := List.IndexOf(UTF16ToUTF8(filter^));
19104     if index <> -1 then
19105       TFileDialog(FDialog).IntfFileTypeChanged(index + 1);
19106     List.Free;
19107   end;
19108 end;
19109 
19110 procedure TQtFileDialog.CurrentChangedEvent(path: PWideString); cdecl;
19111 begin
19112   if FDialog is TOpenDialog then
19113   begin
19114     TOpenDialog(FDialog).FileName := UTF16ToUTF8(path^);
19115     TOpenDialog(FDialog).DoSelectionChange;
19116   end;
19117 end;
19118 
19119 procedure TQtFileDialog.DirectoryEnteredEvent(directory: PWideString); cdecl;
19120 begin
19121   if FDialog is TOpenDialog then
19122     TOpenDialog(FDialog).DoFolderChange;
19123 end;
19124 
19125 procedure TQtFileDialog.getFilters(const retval: QStringListH);
19126 begin
19127   QFileDialog_nameFilters(QFileDialogH(Widget), retval);
19128 end;
19129 
19130 { TQtFilePreviewDialog }
19131 
CreateWidgetnull19132 function TQtFilePreviewDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags
19133   ): QWidgetH;
19134 begin
19135   {$ifndef QT_NATIVE_DIALOGS}
19136   FPreviewWidget := nil;
19137   FTextWidget := nil;
19138   {$endif}
19139   Result := inherited CreateWidget(parent, f);
19140 end;
19141 
19142 {$ifndef QT_NATIVE_DIALOGS}
19143 
19144 procedure TQtFilePreviewDialog.initializePreview(const APreviewControl: TWinControl);
19145 var
19146   ALayout: QGridLayoutH;
19147   ATitle: WideString;
19148   W, H: Integer;
19149 begin
19150   ALayout := QGridLayoutH(QWidget_layout(Widget));
19151   ATitle := 'No image';
19152   FTextWidget := QLabel_create(@ATitle, Widget);
19153   QFrame_setFrameShape(FTextWidget, QFrameStyledPanel);
19154   QLabel_setWordWrap(FTextWidget, True);
19155   QLabel_setScaledContents(FTextWidget, True);
19156   QLabel_setAlignment(FTextWidget, QtAlignCenter);
19157   ATitle := '';
19158   FPreviewWidget := QLabel_create(@ATitle, Widget);
19159   QLabel_setAlignment(FPreviewWidget, QtAlignCenter);
19160 
19161   W := QWidget_width(Widget) div 5;
19162   H := W;
19163 
19164   if Assigned(APreviewControl) then
19165   begin
19166     APreviewControl.Width := W;
19167     APreviewControl.Height := H;
19168   end;
19169 
19170   QWidget_setGeometry(FTextWidget, 0, 0, W, 32);
19171   QWidget_setMaximumHeight(FTextWidget, 32);
19172   QWidget_setMaximumWidth(FTextWidget, W);
19173   QWidget_setMinimumWidth(FTextWidget, W);
19174 
19175   QWidget_setGeometry(FPreviewWidget, 0, 0, W, H);
19176   QWidget_setMaximumHeight(FPreviewWidget, H);
19177   QWidget_setMaximumWidth(FPreviewWidget, W);
19178   QLabel_setScaledContents(FPreviewWidget, True);
19179   (*
19180   do not use layout, Qt asserts with message that another layout already exists.
19181   ABox := QVBoxLayout_create(Widget);
19182   QBoxLayout_addWidget(ABox, FTextWidget, 0, QtAlignTop);
19183   // QBoxLayout_addWidget();
19184   QBoxLayout_addWidget(ABox, FPreviewWidget, 0, QtAlignCenter);
19185   QBoxLayout_addStretch(ABox);
19186   *)
19187   QGridLayout_addWidget(ALayout, FTextWidget, 1, 3, 3, 1, QtAlignTop);
19188   QGridLayout_addWidget(ALayout, FPreviewWidget, 1, 3, 3, 1, QtAlignCenter);
19189   QGridLayout_columnStretch(ALayout, 3);
19190 end;
19191 
19192 procedure TQtFilePreviewDialog.CurrentChangedEvent(path: PWideString); cdecl;
19193 var
19194   APixmap: QPixmapH;
19195   ATitle: WideString;
19196   ASize: TSize;
19197   ANewPixmap: QPixmapH;
19198 begin
19199   if Assigned(FPreviewWidget) then
19200   begin
19201     APixmap := QPixmap_create(path);
19202     if QPixmap_isNull(APixmap) then
19203     begin
19204       ATitle := 'Not an image';
19205       QLabel_setText(FTextWidget, @ATitle);
19206       ATitle := ' ';
19207       QLabel_setText(FPreviewWidget, @ATitle);
19208       QWidget_setToolTip(FTextWidget, @ATitle);
19209       QWidget_setToolTip(FPreviewWidget, @ATitle);
19210       QPixmap_destroy(APixmap);
19211     end else
19212     begin
19213       QPixmap_size(APixmap, @ASize);
19214       if path <> nil then
19215         ATitle := '' // ExtractFileName(path^)
19216       else
19217         ATitle := 'error file';
19218       if path <> nil then
19219         ATitle := {%H-}Format('%d x %d x %d',[ASize.cx, ASize.cy, QPixmap_depth(APixmap)]);
19220       QLabel_setText(FTextWidget, @ATitle);
19221       ATitle := ExtractFileName(path^);
19222       QWidget_setToolTip(FTextWidget, @ATitle);
19223       ATitle := ATitle + LineEnding + {%H-}Format('w %d x h %d x %d',[ASize.cx, ASize.cy, QPixmap_depth(APixmap)]);
19224       QWidget_setToolTip(FPreviewWidget, @ATitle);
19225       ANewPixmap := QPixmap_create;
19226       // QPixmap_scaled(APixmap, ANewPixmap,
19227       //  128, 128, QtKeepAspectRatio, QtSmoothTransformation);
19228       QLabel_setPixmap(FPreviewWidget, APixmap);
19229       QPixmap_destroy(APixmap);
19230       QPixmap_destroy(ANewPixmap);
19231     end;
19232 
19233   end;
19234   TOpenDialog(FDialog).FileName := UTF16ToUTF8(path^);
19235   TOpenDialog(FDialog).DoSelectionChange;
19236 end;
19237 {$ENDIF}
19238 
19239 { TQtGraphicView }
19240 
CreateWidgetnull19241 function TQtGraphicsView.CreateWidget(const AParams: TCreateParams): QWidgetH;
19242 var
19243   Parent: QWidgetH;
19244 begin
19245   FHasPaint := True;
19246   if AParams.WndParent <> 0 then
19247     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
19248   else
19249     Parent := nil;
19250   Result := QGraphicsView_create(Parent);
19251 end;
19252 
19253 { TQtDesignWidget }
19254 
CreateWidgetnull19255 function TQtDesignWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
19256 begin
19257   Result := inherited CreateWidget(AParams);
19258   FDesignControl := QWidget_create(Result);
19259   QWidget_setMouseTracking(FDesignControl, True);
19260   setProperty(FDesignControl, 'lclwidget', Int64(PtrUInt(Self)));
19261   QtWidgetSet.AddHandle(Self);
19262   BringDesignerToFront;
19263 end;
19264 
19265 procedure TQtDesignWidget.DestroyWidget;
19266 begin
19267   inherited DestroyWidget;
19268   FDesignControl := nil;
19269 end;
19270 
19271 procedure TQtDesignWidget.SlotDesignControlPaint(Sender: QObjectH; Event: QEventH); cdecl;
19272 var
19273   Msg: TLMPaint;
19274   AStruct: PPaintStruct;
19275   P: TPoint;
19276   B: Boolean;
19277 begin
19278   {$ifdef VerboseQt}
19279     WriteLn('TQtDesignWidget.SlotDesignControlPaint ', dbgsName(LCLObject));
19280   {$endif}
19281 
19282   if (LCLObject is TWinControl) then
19283   begin
19284     FillChar(Msg{%H-}, SizeOf(Msg), #0);
19285 
19286     Msg.Msg := LM_PAINT;
19287     New(AStruct);
19288     FillChar(AStruct^, SizeOf(TPaintStruct), 0);
19289     Msg.PaintStruct := AStruct;
19290 
19291     with PaintData do
19292     begin
19293       PaintWidget := FDesignControl;
19294       ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
19295       if ClipRect = nil then
19296         New(ClipRect);
19297       QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
19298     end;
19299 
19300     Msg.DC := BeginPaint(THandle(Self), AStruct^);
19301     FDesignContext := Msg.DC;
19302 
19303     Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
19304     Msg.PaintStruct^.hdc := FDesignContext;
19305 
19306     P := getClientOffset;
19307     inc(P.X, FScrollX);
19308     inc(P.Y, FScrollY);
19309     TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
19310 
19311     // send paint message
19312     try
19313       // Saving clip rect and clip region
19314       try
19315         LCLObject.WindowProc(TLMessage(Msg));
19316       finally
19317         Dispose(PaintData.ClipRect);
19318         Fillchar(FPaintData, SizeOf(FPaintData), 0);
19319         FDesignContext := 0;
19320         EndPaint(THandle(Self), AStruct^);
19321         Dispose(AStruct);
19322       end;
19323     except
19324       // prevent recursive repainting !
19325       B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
19326       if B then
19327         QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
19328       try
19329         Application.HandleException(nil);
19330       finally
19331         if B and Assigned(Application) and not Application.Terminated then
19332           QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
19333       end;
19334     end;
19335   end;
19336 end;
19337 
19338 procedure TQtDesignWidget.BringDesignerToFront;
19339 begin
19340   if FDesignControl <> nil then
19341     QWidget_raise(FDesignControl);
19342 end;
19343 
19344 procedure TQtDesignWidget.ResizeDesigner;
19345 var
19346   R: TRect;
19347 begin
19348   if FDesignControl = nil then
19349     Exit;
19350   // FDesignControl must be same as form area,
19351   // since we use QWidget, not QMainWindow in design time.
19352   QWidget_contentsRect(Widget, @R);
19353   with R do
19354   begin
19355     QWidget_move(FDesignControl, Left, Top);
19356     QWidget_resize(FDesignControl, Right - Left, Bottom - Top);
19357   end;
19358 end;
19359 
GetContextnull19360 function TQtDesignWidget.GetContext: HDC;
19361 begin
19362   if FDesignContext <> 0 then
19363     Result := FDesignContext
19364   else
19365     Result := FContext;
19366 end;
19367 
DesignControlEventFilternull19368 function TQtDesignWidget.DesignControlEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
19369 var
19370   p: TQtPoint;
19371   pt: TPoint;
19372   R: TRect;
19373   Control: TControl;
19374   MouseEvent: QMouseEventH;
19375   WidgetToNotify: QWidgetH;
19376   WSQtWidget: TWSWinControlClass;
19377   Action: QActionH;
19378   AWidget: TQtWidget;
19379   ATabWidget: TQtTabWidget;
19380   ATabIndex: Integer;
19381 begin
19382   Result := False;
19383   QEvent_Accept(Event);
19384   if LCLObject = nil then
19385     exit;
19386   if QEvent_type(Event) = QEventDestroy then
19387   begin
19388     {FDesignControl is always destroyed by it's parent,
19389      only thing we need is to remove dynamic property.}
19390     RemoveProperty(FDesignControl,'lclwidget');
19391     exit;
19392   end;
19393   BeginEventProcessing;
19394   try
19395     case QEvent_type(Event) of
19396       QEventMouseButtonPress,
19397       QEventMouseButtonRelease:
19398       begin
19399         p := QMouseEvent_pos(QMouseEventH(Event))^;
19400         OffsetMousePos(@p);
19401         pt := Point(p.x, p.y);
19402         Control := LCLObject.ControlAtPos(pt, [capfRecursive, capfAllowWinControls]);
19403 
19404         if Control is TWinControl then
19405         begin
19406           AWidget := TQtWidget(TWinControl(Control).Handle);
19407           if (Control is TCustomTabControl) and
19408             (AWidget.ChildOfComplexWidget <> ccwTTabControl) then
19409             WidgetToNotify := TQtTabWidget(TWinControl(Control).Handle).TabBar.Widget
19410           else
19411             WidgetToNotify := TQtWidget(TWinControl(Control).Handle).Widget;
19412 
19413           p := QMouseEvent_pos(QMouseEventH(Event))^;
19414           QWidget_mapFrom(WidgetToNotify, @p, Widget, @p);
19415           Pt := Point(p.x, p.y);
19416 
19417           WSQtWidget := TWSWinControlClass(TWinControl(Control).WidgetSetClass);
19418 
19419           if WSQtWidget.GetDesignInteractive(TWinControl(Control), Pt) then
19420           begin
19421             if (Control is TCustomTabControl) and
19422               (AWidget.ChildOfComplexWidget <> ccwTTabControl) then
19423             begin
19424               ATabWidget := TQtTabWidget(TWinControl(Control).Handle);
19425               ATabIndex := ATabWidget.tabAt(Pt);
19426               if ATabIndex >= 0 then
19427                 ATabWidget.setCurrentIndex(ATabIndex);
19428             end else
19429             begin
19430               MouseEvent := QMouseEvent_create(QEvent_type(Event), @p,
19431                 QMouseEvent_globalpos(QMouseEventH(Event)),
19432                 QMouseEvent_button(QMouseEventH(Event)),
19433                 QMouseEvent_buttons(QMouseEventH(Event)),
19434                 QInputEvent_modifiers(QInputEventH(Event))
19435                 );
19436               QCoreApplication_postEvent(WidgetToNotify, MouseEvent, 1);
19437             end;
19438           end;
19439         end else
19440         begin
19441           p := QMouseEvent_globalPos(QMouseEventH(Event))^;
19442           WidgetToNotify := QApplication_widgetAt(@p);
19443           if (WidgetToNotify <> nil) then
19444           begin
19445             if TQtMainWindow(Self).MenuBar.Widget <> nil then
19446             begin
19447               p := QMouseEvent_Pos(QMouseEventH(Event))^;
19448               QWidget_geometry(TQtMainWindow(Self).MenuBar.Widget, @R);
19449               pt := Point(P.X, P.Y);
19450               if LCLIntf.PtInRect(R, pt) then
19451               begin
19452                 Action := QMenuBar_actionAt(QMenuBarH(TQtMainWindow(Self).MenuBar.Widget), @p);
19453                 if Action <> nil then
19454                 begin
19455                   QCoreApplication_notify(QCoreApplication_instance(), TQtMainWindow(Self).MenuBar.Widget, Event);
19456                   QEvent_accept(Event);
19457                   Result := True;
19458                 end;
19459               end;
19460             end;
19461           end;
19462         end;
19463       end;
19464       QEventPaint: SlotDesignControlPaint(Sender, Event);
19465     end;
19466   finally
19467     EndEventProcessing;
19468   end;
19469 end;
19470 
TQtDesignWidget.EventFilternull19471 function TQtDesignWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
19472 begin
19473   Result := False;
19474   QEvent_accept(Event);
19475   if LCLObject = nil then
19476     exit;
19477 
19478   BeginEventProcessing;
19479   try
19480     case QEvent_type(Event) of
19481       QEventWindowActivate:
19482       begin
19483         Result := inherited EventFilter(Sender, Event);
19484         setFocus;
19485         BringDesignerToFront;
19486       end;
19487       QEventChildAdded,
19488       QEventChildRemoved: BringDesignerToFront;
19489       QEventResize:
19490         begin
19491           Result := inherited EventFilter(Sender, Event);
19492           ResizeDesigner;
19493         end;
19494       else
19495         Result := inherited EventFilter(Sender, Event);
19496     end;
19497   finally
19498     EndEventProcessing;
19499   end;
19500 end;
19501 
19502 procedure TQtDesignWidget.AttachEvents;
19503 begin
19504   inherited AttachEvents;
19505   if FDesignControl <> nil then
19506   begin
19507     FDesignControlEventHook := QObject_hook_create(FDesignControl);
19508     QObject_hook_hook_events(FDesignControlEventHook, @DesignControlEventFilter);
19509   end;
19510 end;
19511 
19512 procedure TQtDesignWidget.DetachEvents;
19513 begin
19514   if FDesignControlEventHook <> nil then
19515   begin
19516     QObject_hook_destroy(FDesignControlEventHook);
19517     FDesignControlEventHook := nil;
19518   end;
19519   inherited DetachEvents;
19520 end;
19521 
19522 procedure TQtDesignWidget.lowerWidget;
19523 begin
19524   inherited lowerWidget;
19525   BringDesignerToFront;
19526 end;
19527 
19528 procedure TQtDesignWidget.raiseWidget;
19529 begin
19530   inherited raiseWidget;
19531   BringDesignerToFront;
19532 end;
19533 
19534 { TQtMessageBox }
19535 
TQtMessageBox.getMsgBoxTypenull19536 function TQtMessageBox.getMsgBoxType: QMessageBoxIcon;
19537 begin
19538   Result := QMessageBox_icon(QMessageBoxH(Widget));
19539 end;
19540 
GetTextFormatnull19541 function TQtMessageBox.GetTextFormat: QtTextFormat;
19542 begin
19543   Result := QMessageBox_textFormat(QMessageBoxH(Widget));
19544 end;
19545 
19546 procedure TQtMessageBox.setDetailText(const AValue: WideString);
19547 var
19548   Str: WideString;
19549 begin
19550   Str := AValue;
19551   QMessageBox_setDetailedText(QMessageBoxH(Widget), @Str);
19552 end;
19553 
TQtMessageBox.getMessageStrnull19554 function TQtMessageBox.getMessageStr: WideString;
19555 var
19556   Str: WideString;
19557 begin
19558   QMessageBox_text(QMessageBoxH(Widget), @Str);
19559   Result := Str;
19560 end;
19561 
TQtMessageBox.getDetailTextnull19562 function TQtMessageBox.getDetailText: WideString;
19563 var
19564   Str: WideString;
19565 begin
19566   QMessageBox_detailedText(QMessageBoxH(Widget), @Str);
19567   Result := Str;
19568 end;
19569 
19570 procedure TQtMessageBox.setMessageStr(const AValue: WideString);
19571 var
19572   Str: WideString;
19573 begin
19574   Str := AValue;
19575   QMessageBox_setText(QMessageBoxH(Widget), @Str);
19576 end;
19577 
19578 procedure TQtMessageBox.setMsgBoxType(const AValue: QMessageBoxIcon);
19579 begin
19580   QMessageBox_setIcon(QMessageBoxH(Widget), AValue);
19581 end;
19582 
19583 procedure TQtMessageBox.SetTextFormat(AValue: QtTextFormat);
19584 begin
19585   QMessageBox_setTextFormat(QMessageBoxH(Widget), AValue);
19586 end;
19587 
19588 procedure TQtMessageBox.setTitle(const AValue: WideString);
19589 begin
19590   if AValue <> FTitle then
19591   begin
19592     FTitle := AValue;
19593     QMessageBox_setWindowTitle(QMessageBoxH(Widget), @FTitle);
19594   end;
19595 end;
19596 
TQtMessageBox.CreateWidgetnull19597 function TQtMessageBox.CreateWidget(AParent: QWidgetH): QWidgetH;
19598 begin
19599   FHasPaint := False;
19600   Result := QMessageBox_create(AParent);
19601   QMessageBox_setWindowModality(QMessageBoxH(Result), QtApplicationModal);
19602 end;
19603 
19604 constructor TQtMessageBox.Create(AParent: QWidgetH);
19605 begin
19606   WidgetColorRole := QPaletteWindow;
19607   TextColorRole := QPaletteWindowText;
19608   FOwner := nil;
19609   FCentralWidget := nil;
19610   FOwnWidget := True;
19611   FProps := nil;
19612   LCLObject := nil;
19613   FKeysToEat := [];
19614   FHasPaint := False;
19615   {$IFDEF TQTMESSAGEBOXUSEPARENT}
19616   if AParent = nil then
19617     AParent := QApplication_activeWindow;
19618   {$ENDIF}
19619   Widget := CreateWidget(AParent);
19620   {$IFNDEF QTDIALOGSUSEHTMLTEXT}
19621   TextFormat := QtPlainText;
19622   {$ENDIF}
19623   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
19624   QtWidgetSet.AddHandle(Self);
19625 end;
19626 
19627 procedure TQtMessageBox.AttachEvents;
19628 begin
19629   inherited AttachEvents;
19630   FMBEventHook := QObject_hook_create(Widget);
19631   QObject_hook_hook_events(FMBEventHook, @EventFilter);
19632 end;
19633 
19634 procedure TQtMessageBox.DetachEvents;
19635 begin
19636   if FMBEventHook <> nil then
19637   begin
19638     QObject_hook_destroy(FMBEventHook);
19639     FMBEventHook := nil;
19640   end;
19641   inherited DetachEvents;
19642 end;
19643 
TQtMessageBox.EventFilternull19644 function TQtMessageBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
19645 begin
19646   {we'll need it later. QMessageBox uses it's own eventLoop !}
19647   Result := False;
19648   QEvent_accept(Event);
19649   if LCLObject <> nil then
19650     Result := inherited EventFilter(Sender, Event)
19651   else
19652   begin
19653     case QEvent_type(Event) of
19654       QEventKeyPress:
19655       begin
19656         if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Escape) and
19657           (QMessageBox_escapeButton(QMessageBoxH(Sender)) = nil) then
19658         begin
19659           QDialog_done(QDialogH(Sender), Ord(QDialogRejected));
19660           Result := True;
19661         end;
19662       end;
19663       QEventClose:
19664       begin
19665         if QMessageBox_escapeButton(QMessageBoxH(Sender)) = nil then
19666         begin
19667           QDialog_done(QDialogH(Sender), Ord(QDialogRejected));
19668           Result := True;
19669         end;
19670       end;
19671     end;
19672   end;
19673 end;
19674 
19675 procedure TQtMessageBox.SetButtonProps(ABtn: QPushButtonH; AResult: Int64; const ADefaultBtn: Boolean; const AEscapeBtn: Boolean);
19676 var
19677   v: QVariantH;
19678 begin
19679   if ADefaultBtn then
19680     QMessageBox_setDefaultButton(QMessageBoxH(Widget), ABtn);
19681 
19682   if AEscapeBtn then
19683     QMessageBox_setEscapeButton(QMessageBoxH(Widget), ABtn);
19684 
19685   v := QVariant_create(AResult);
19686   try
19687     QObject_setProperty(ABtn, 'lclmsgboxbutton', v);
19688   finally
19689     QVariant_destroy(v);
19690   end;
19691 end;
19692 
TQtMessageBox.AddButtonnull19693 function TQtMessageBox.AddButton(ACaption: WideString; ABtnType: QMessageBoxStandardButton;
19694    AResult: Int64; const ADefaultBtn: Boolean; const AEscapeBtn: Boolean): QPushButtonH;
19695 var
19696   Str: WideString;
19697 begin
19698   Result := QMessageBox_addButton(QMessageBoxH(Widget), ABtnType);
19699   Str := ACaption;
19700   QAbstractButton_setText(Result, @Str);
19701   SetButtonProps(Result, AResult, ADefaultBtn, AEscapeBtn);
19702 end;
19703 
TQtMessageBox.AddButtonnull19704 function TQtMessageBox.AddButton(ACaption: WideString; AResult: Int64; const ADefaultBtn: Boolean;
19705   const AEscapeBtn: Boolean): QPushButtonH;
19706 var
19707   Str: WideString;
19708 begin
19709   Str := ACaption;
19710   Result := QMessageBox_addButton(QMessageBoxH(Widget), @Str, QMessageBoxActionRole);
19711   SetButtonProps(Result, AResult, ADefaultBtn, AEscapeBtn);
19712 end;
19713 
TQtMessageBox.execnull19714 function TQtMessageBox.exec: Int64;
19715 var
19716   ABtn: QPushButtonH;
19717   v: QVariantH;
19718   ok: Boolean;
19719   QResult: Int64;
19720 begin
19721   Result := mrCancel;
19722   {$IFDEF QTDIALOGS_USES_QT_LOOP}
19723   QDialog_exec(QMessageBoxH(Widget));
19724   {$ELSE}
19725   QMessageBox_setWindowModality(QMessageBoxH(Widget), QtApplicationModal);
19726   QWidget_show(Widget);
19727 
19728   {$IFDEF HASX11}
19729   if (QtWidgetSet.WindowManagerName = 'metacity') then
19730       X11Raise(QWidget_winID(Widget));
19731   {$ENDIF}
19732   {$IFDEF TQTMESSAGEBOXUSEPARENT}
19733   QWidget_activateWindow(Widget);
19734   QWidget_raise(Widget);
19735   {$ENDIF}
19736 
19737   repeat
19738     QCoreApplication_processEvents();
19739     Application.Idle(true);
19740   until not QWidget_isVisible(Widget) or Application.Terminated;
19741   {$ENDIF}
19742   ABtn := QPushButtonH(QMessageBox_clickedButton(QMessageBoxH(Widget)));
19743   if ABtn <> nil then
19744   begin
19745     v := QVariant_create();
19746     try
19747       QObject_property(ABtn, v, 'lclmsgboxbutton');
19748       if QVariant_isValid(v) then
19749       begin
19750         QResult := QVariant_toLongLong(v, @Ok);
19751         if Ok then
19752           Result := QResult;
19753       end;
19754     finally
19755       QVariant_destroy(v);
19756     end;
19757   end;
19758   {$IFDEF HASX11}
19759   // make qt interface snappy.
19760   if Assigned(Application) and not Application.Terminated then
19761     QCoreApplication_processEvents(QEventLoopAllEvents);
19762   {$ENDIF}
19763 end;
19764 
19765 end.
19766