1 {
2  *****************************************************************************
3  *                              QtWidgets.pas                                *
4  *                              --------------                               *
5  *                                                                           *
6  *                                                                           *
7  *****************************************************************************
8 
9  *****************************************************************************
10   This file is part of the Lazarus Component Library (LCL)
11 
12   See the file COPYING.modifiedLGPL.txt, included in this distribution,
13   for details about the license.
14  *****************************************************************************
15 }
16 unit qtwidgets;
17 
18 {$mode objfpc}{$H+}
19 
20 interface
21 
22 {$I qtdefines.inc}
23 
24 uses
25   // Bindings
26   qt5,
27   qtobjects, qtint,
28   // Free Pascal
29   Classes, SysUtils, Types,
30   // LCL
31   LCLType, LCLProc, LazUTF8, LCLIntf, LMessages, Graphics, Forms, Controls,
32   ComCtrls, ExtCtrls, StdCtrls, Menus, Dialogs, ImgList;
33 
34 type
35   // forward declarations
36   TQtListWidget = class;
37   TQtViewPort = class;
38 
39   TByteSet = set of byte;
40 
41   {Used to know if our widget is part of some complex widget.
42    Only for TQtWidgets created by CreateFrom & attach it's events.
43    For now only combobox added for it's lineedit but not for droplist
44    which doesn't attach it's event filter.
45    We'll need it later for TQtScrollBar and probably TQtTabWidget}
46   TChildOfComplexWidget = (ccwNone,
47                           ccwComboBox,
48                           ccwTreeWidget,
49                           ccwAbstractScrollArea,
50                           ccwCustomControl,
51                           ccwScrollingWinControl,
52                           ccwScrollingWindow,
53                           ccwTabWidget,
54                           ccwTTabControl);
55 
56   TQtGroupBoxType = (tgbtNormal,
57                    tgbtCheckGroup,
58                    tgbtRadioGroup);
59 
60   {state is setted up only when LCL is doing changes.}
61   TQtWidgetState = (qtwsColorUpdating, qtwsFontUpdating, qtwsSizeUpdating,
62     qtwsPositionUpdating, qtwsInsideRightMouseButtonPressEvent,
63     qtwsHiddenInsideRightMouseButtonPressEvent,
64     qtwsForceSendMove {mantis #34589 , LM_MOVE from ScrollWindowEx(SW_SCROLLCHILDREN)});
65 
66   TQtWidgetStates = set of TQtWidgetState;
67 
68   // records
69   TPaintData = record
70     PaintWidget: QWidgetH;
71     ClipRect: Prect;
72     ClipRegion: QRegionH;
73   end;
74 
75   // interfaces
76 
77   { IQtTextEdit }
78 
79   { IQtEdit }
80 
81   IQtEdit = interface
82     ['{035CA259-4442-4E82-9E70-96A114DD3BC6}']
getCursorPositionnull83     function getCursorPosition: TPoint;
getMaxLengthnull84     function getMaxLength: Integer;
getSelectionStartnull85     function getSelectionStart: Integer;
getSelectionLengthnull86     function getSelectionLength: Integer;
isUndoAvailablenull87     function isUndoAvailable: Boolean;
88     procedure setEchoMode(const AMode: QLineEditEchoMode);
89     procedure setMaxLength(const ALength: Integer);
90     procedure setReadOnly(const AReadOnly: Boolean);
91     procedure setSelection(const AStart, ALength: Integer);
92     procedure setBorder(const ABorder: Boolean);
93     procedure setCursorPosition(const ACursorPosition: Integer);
94     procedure setTextHint(const ATextHint: string);
95     procedure Cut;
96     procedure Copy;
97     procedure Paste;
98     procedure Undo;
99   end;
100 
101   // classes
102 
103   { TQtWidget }
104 
105   TQtWidget = class(TQtObject, IUnknown)
106   private
107     {$IFDEF QtUseAccurateFrame}
108     FFrameMargins: TRect;
109     {$ENDIF}
110     FInResizeEvent: boolean;
111     FWidgetState: TQtWidgetStates;
112     FWidgetDefaultFont: TQtFont;
113     FWidgetLCLFont: TQtFont;
114     FWidgetNeedFontColorInitialization: Boolean;
115     FChildOfComplexWidget: TChildOfComplexWidget;
116     FOwnWidget: Boolean;
117     FProps: TStringList;
118     FPaintData: TPaintData;
119     FCentralWidget: QWidgetH;
120     FContext: HDC;
121     FParams: TCreateParams;
122     FDefaultCursor: QCursorH;
123     FKeysToEat: TByteSet;
124     FText: WideString;
125     FHasCaret: Boolean;
126     FLastCaretPos: TQtPoint;
127     FHasPaint: Boolean;
128     FOwner: TQtWidget;
129 
130     FWidgetColorRole: QPaletteColorRole;
131     FTextColorRole: QPaletteColorRole;
132     FPalette: TQtWidgetPalette;
133 
134     {TQtWidget.scroll() info}
135     FScrollX: Integer;
136     FScrollY: Integer;
137 
GetPalettenull138     function GetPalette: TQtWidgetPalette;
GetPropsnull139     function GetProps(const AnIndex: String): pointer;
getScrolledOffsetnull140     function getScrolledOffset: TPoint;
GetStyleSheetnull141     function GetStyleSheet: WideString;
GetWidgetnull142     function GetWidget: QWidgetH;
LCLKeyToQtKeynull143     function LCLKeyToQtKey(AKey: Word): Integer;
QtButtonsToLCLButtonsnull144     function QtButtonsToLCLButtons(AButtons: QtMouseButton): PtrInt;
QtKeyModifiersToKeyStatenull145     function QtKeyModifiersToKeyState(AModifiers: QtKeyboardModifiers;
146       const AIsKeyEvent: Boolean;
147       AEvent: QKeyEventH = nil): PtrInt;
QtKeyToLCLKeynull148     function QtKeyToLCLKey(AKey: Integer; AText: WideString;
149       AEvent: QKeyEventH): Word;
150     procedure SetLastCaretPos(const AValue: TQtPoint);
151     procedure SetProps(const AnIndex: String; const AValue: pointer);
152     procedure SetStyleSheet(const AValue: WideString);
153     procedure SetWidget(const AValue: QWidgetH);
ShiftStateToQtModifiersnull154     function ShiftStateToQtModifiers(Shift: TShiftState): QtModifier;
155   protected
156     // IUnknown implementation
QueryInterfacenull157     function QueryInterface(constref iid: TGuid; out obj): LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
_AddRefnull158     function _AddRef: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
_Releasenull159     function _Release: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
GetContextnull160     function GetContext: HDC; virtual;
CreateWidgetnull161     function CreateWidget(const Params: TCreateParams):QWidgetH; virtual;
162     procedure DestroyWidget; virtual;
163     procedure SetHasCaret(const AValue: Boolean);
ProcessArrowKeysnull164     function ProcessArrowKeys: Boolean; virtual;
165 
166     class procedure removeProperty(AObject: QObjectH; APropName: PAnsiChar);
167     class procedure setProperty(AObject: QObjectH; APropName: PAnsiChar; APropValue: Int64);
168   public
169     LCLObject: TWinControl;
170   public
171     constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); virtual; overload;
172     constructor CreateFrom(const AWinControl: TWinControl; AWidget: QWidgetH); virtual;
173     procedure InitializeWidget; virtual;
174     procedure DeInitializeWidget; virtual;
175     procedure RecreateWidget;
176     procedure DestroyNotify(AWidget: TQtWidget); virtual;
177 
178     destructor Destroy; override;
GetContainerWidgetnull179     function GetContainerWidget: QWidgetH; virtual;
180     procedure Release; override;
181     procedure Destroyed; cdecl; override;
182   public
CanAdjustClientRectOnResizenull183     function CanAdjustClientRectOnResize: Boolean; virtual;
CanChangeFontColornull184     function CanChangeFontColor: Boolean; virtual;
CanSendLCLMessagenull185     function CanSendLCLMessage: Boolean;
CanPaintBackgroundnull186     function CanPaintBackground: Boolean; virtual;
187     {delays resize event of complex widgets or when LCLObject have caspComputingBounds in AutoSizePhases}
188     procedure DelayResizeEvent(AWidget: QWidgetH; ANewSize: TSize);
DeliverMessagenull189     function DeliverMessage(var Msg; const AIsInputEvent: Boolean = False): LRESULT; virtual;
EventFilternull190     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
getAcceptDropFilesnull191     function getAcceptDropFiles: Boolean; virtual;
192     {precise measure of text with widget''s current font when canvas.handle isn''t available}
measureTextnull193     function measureText(AText: WideString; AFlags: cardinal): TRect;
194     procedure SetNoMousePropagation(Sender: QWidgetH; const ANoMousePropagation: Boolean); virtual;
195     procedure SetLCLFont(AFont: TQtFont);
196     procedure SlotShow(vShow: Boolean); cdecl;
SlotClosenull197     function SlotClose: Boolean; cdecl; virtual;
198     procedure SlotDestroy; cdecl;
slotDropFilesnull199     function slotDropFiles(Sender: QObjectH; Event: QEventH): Boolean;
SlotHovernull200     function SlotHover(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotKeynull201     function SlotKey(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotInputMethodnull202     function SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotMousenull203     function SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; virtual; cdecl;
204     procedure SlotNCMouse(Sender: QObjectH; Event: QEventH); cdecl;
SlotMouseEnternull205     function SlotMouseEnter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotMouseMovenull206     function SlotMouseMove(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
SlotMouseWheelnull207     function SlotMouseWheel(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
208     procedure SlotMove(Event: QEventH); cdecl;
209     procedure SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl;
210     procedure SlotPaint(Sender: QObjectH; Event: QEventH); cdecl;
211     procedure SlotResize(Event: QEventH); cdecl;
SlotContextMenunull212     function SlotContextMenu(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
213     procedure SlotWhatsThis(Sender: QObjectH; Event: QEventH); cdecl;
214     procedure SlotLCLMessage(Sender: QObjectH; Event: QEventH); cdecl;
215   public
216     procedure Activate; virtual;
217     procedure BringToFront;
218     procedure clearMask;
219     procedure OffsetMousePos(APoint: PQtPoint); virtual;
220     procedure Update(ARect: PRect = nil); virtual;
221     procedure UpdateRegion(ARgn: QRegionH); virtual;
222     procedure Repaint(ARect: PRect = nil); virtual;
223     procedure setWindowTitle(Str: PWideString);
224     procedure WindowTitle(Str: PWideString);
225     procedure Hide;
226     procedure Show;
227     procedure ShowNormal;
228     procedure ShowMinimized;
229     procedure ShowMaximized;
230     procedure ShowFullScreen;
getActionByIndexnull231     function getActionByIndex(AIndex: Integer): QActionH;
getAutoFillBackgroundnull232     function getAutoFillBackground: Boolean;
getClientBoundsnull233     function getClientBounds: TRect; virtual;
getClientOffsetnull234     function getClientOffset: TPoint; virtual;
getEnablednull235     function getEnabled: Boolean;
getFontnull236     function getFont: QFontH;
getFocusPolicynull237     function getFocusPolicy: QtFocusPolicy;
getFrameGeometrynull238     function getFrameGeometry: TRect; virtual;
getGeometrynull239     function getGeometry: TRect; virtual;
getLayoutDirectionnull240     function getLayoutDirection: QtLayoutDirection;
getVisiblenull241     function getVisible: Boolean; virtual;
getVisibleTonull242     function getVisibleTo(AWidget: QWidgetH): Boolean; virtual;
getOwnernull243     function getOwner: TQtWidget;
getParentnull244     function getParent: QWidgetH;
getPosnull245     function getPos: TQtPoint;
getFrameSizenull246     function getFrameSize: TSize; virtual;
getSizenull247     function getSize: TSize;
getTextnull248     function getText: WideString; virtual;
getTextStaticnull249     function getTextStatic: Boolean; virtual;
getHeightnull250     function getHeight: Integer;
getUpdatesEnablednull251     function getUpdatesEnabled: Boolean;
getWidthnull252     function getWidth: Integer;
getWindownull253     function getWindow: TQtWidget;
getWindowStatenull254     function getWindowState: QtWindowStates; {$IFDEF QTSCROLLABLEFORMS}virtual;{$ENDIF}
255     procedure grabMouse; virtual;
hasFocusnull256     function hasFocus: Boolean; virtual;
IsActiveWindownull257     function IsActiveWindow: Boolean;
isMinimizednull258     function isMinimized: Boolean;
isMaximizednull259     function isMaximized: Boolean;
IsFramedWidgetnull260     function IsFramedWidget: boolean; virtual;
isFullScreennull261     function isFullScreen: Boolean;
IsWindownull262     function IsWindow: Boolean;
263     procedure lowerWidget; virtual;
MapToGlobalnull264     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; virtual;
MapFromGlobalnull265     function MapFromGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; virtual;
266     procedure move(ANewLeft, ANewTop: Integer); virtual;
267     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); virtual;
268     procedure raiseWidget; virtual;
269     procedure stackUnder(AWidget: QWidgetH); virtual;
270     procedure frame_resize(ANewWidth, ANewHeight: Integer);
271     procedure Resize(ANewWidth, ANewHeight: Integer); virtual;
272     procedure releaseMouse;
273     procedure scroll(dx, dy: integer; ARect: PRect = nil); virtual;
274     procedure setAutoFillBackground(const AValue: Boolean);
275     procedure setAttribute(const Attr: QtWidgetAttribute; const TurnOn: Boolean = True);
276     procedure setBackgroundRole(const ARole: QPaletteColorRole);
277     procedure setDefaultColor(const DefaultColorType: TDefaultColorType);
278     procedure setColor(const Value: PQColor); virtual;
getContextMenuPolicynull279     function getContextMenuPolicy: QtContextMenuPolicy; virtual;
280     procedure setContextMenuPolicy(const AValue: QtContextMenuPolicy); virtual;
281     procedure setCursor(const ACursor: QCursorH); virtual;
282     procedure setDefaultColorRoles; virtual;
283     procedure setEnabled(p1: Boolean);
284     procedure setFocus;
285     procedure setFocusPolicy(const APolicy: QtFocusPolicy); virtual;
286     procedure setFocusProxy(const AWidget: QWidgetH);
287     procedure setFont(AFont: QFontH);
288     procedure setGeometry(ARect: TRect); virtual;
289     procedure setInitialFontColor(AControl: TWinControl); virtual;
290     procedure setLayoutDirection(ADirection: QtLayoutDirection);
291     procedure setMaximumSize(AWidth, AHeight: Integer);
292     procedure setMask(AMask: QBitmapH); overload;
293     procedure setMask(AMask: QRegionH); overload;
294     procedure setMinimumSize(AWidth, AHeight: Integer);
295     procedure setParent(parent: QWidgetH); virtual;
296     procedure setText(const W: WideString); virtual;
297     procedure setTextColor(const Value: PQColor); virtual;
298     procedure setVisible(AVisible: Boolean); virtual;
299     procedure setWindowFlags(_type: QtWindowFlags);
300     procedure setWindowIcon(AIcon: QIconH);
301     procedure setWindowModality(windowModality: QtWindowModality);
302     procedure setWindowOpacity(opacity: double);
303     procedure setWidth(p1: Integer);
304     procedure setHeight(p1: Integer);
305     procedure setUpdatesEnabled(const AEnabled: Boolean);
306     procedure setWindowState(AState: QtWindowStates);
307     procedure sizeHint(size: PSize);
testAttributenull308     function testAttribute(const AAttribute: QtWidgetAttribute): boolean;
windowFlagsnull309     function windowFlags: QtWindowFlags;
windowModalitynull310     function windowModality: QtWindowModality;
311     property ChildOfComplexWidget: TChildOfComplexWidget read FChildOfComplexWidget write FChildOfComplexWidget;
312     property Context: HDC read GetContext;
313     {$IFDEF QtUseAccurateFrame}
314     property FrameMargins: TRect read FFrameMargins write FFrameMargins;
315     {$ENDIF}
316     property HasCaret: Boolean read FHasCaret write SetHasCaret;
317     property HasPaint: Boolean read FHasPaint write FHasPaint;
318     property InResizeEvent: boolean read FInResizeEvent write FInResizeEvent;
319     property KeysToEat: TByteSet read FKeysToEat write FKeysToEat;
320     property LastCaretPos: TQtPoint read FLastCaretPos write SetLastCaretPos;
321     property ScrolledOffset: TPoint read getScrolledOffset;
322     property StyleSheet: WideString read GetStyleSheet write SetStyleSheet;
323     property PaintData: TPaintData read FPaintData write FPaintData;
324     property Palette: TQtWidgetPalette read GetPalette;
325     property Props[AnIndex:String]:pointer read GetProps write SetProps;
326     property TextColorRole: QPaletteColorRole read FTextColorRole write FTextColorRole;
327     property Widget: QWidgetH read GetWidget write SetWidget;
328     property WidgetColorRole: QPaletteColorRole read FWidgetColorRole write FWidgetColorRole;
329     property WidgetState: TQtWidgetStates read FWidgetState write FWidgetState;
330   end;
331 
332   { TQtAbstractSlider , inherited by TQtScrollBar, TQtTrackBar }
333 
334   TQtAbstractSlider = class(TQtWidget)
335   private
336     FSliderPressed: Boolean;
337     FSliderReleased: Boolean;
338     FRangeChangedHook: QAbstractSlider_hookH;
339     FSliderMovedHook:  QAbstractSlider_hookH;
340     FSliderPressedHook: QAbstractSlider_hookH;
341     FSliderReleasedHook: QAbstractSlider_hookH;
342     FValueChangedHook: QAbstractSlider_hookH;
343     FActionTriggeredHook: QAbstractSlider_hookH;
344   protected
CreateWidgetnull345     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
346   public
347     procedure AttachEvents; override;
348     procedure DetachEvents; override;
349 
350     procedure SlotSliderMoved(p1: Integer); cdecl; virtual;
351     procedure SlotValueChanged(p1: Integer); cdecl; virtual;
352     procedure SlotActionTriggered(action: Integer); cdecl; virtual;
353     procedure SlotRangeChanged(minimum: Integer; maximum: Integer); cdecl; virtual;
354     procedure SlotSliderPressed; cdecl;
355     procedure SlotSliderReleased; cdecl; virtual;
356   public
CanChangeFontColornull357     function CanChangeFontColor: Boolean; override;
getInvertedAppereancenull358     function getInvertedAppereance: Boolean;
getInvertedControlsnull359     function getInvertedControls: Boolean;
getOrientationnull360     function getOrientation: QtOrientation;
getValuenull361     function getValue: Integer;
getPageStepnull362     function getPageStep: Integer;
getMinnull363     function getMin: Integer;
getMaxnull364     function getMax: Integer;
getSingleStepnull365     function getSingleStep: Integer;
getSliderDownnull366     function getSliderDown: Boolean;
getSliderPositionnull367     function getSliderPosition: Integer;
getTrackingnull368     function getTracking: Boolean;
369 
370     procedure setInvertedAppereance(p1: Boolean); virtual;
371     procedure setInvertedControls(p1: Boolean); virtual;
372 
373     procedure setMaximum(p1: Integer); virtual;
374     procedure setMinimum(p1: Integer); virtual;
375 
376     procedure setOrientation(p1: QtOrientation); virtual;
377     procedure setPageStep(p1: Integer); virtual;
378     procedure setRange(minimum: Integer; maximum: Integer); virtual;
379     procedure setSingleStep(p1: Integer); virtual;
380     procedure setSliderDown(p1: Boolean); virtual;
381     procedure setSliderPosition(p1: Integer); virtual;
382     procedure setTracking(p1: Boolean); virtual;
383     procedure setValue(p1: Integer); virtual;
384     property SliderPressed: Boolean read FSliderPressed;
385     property SliderReleased: Boolean read FSliderReleased;
386   end;
387 
388   { TQtScrollBar }
389 
390   TQtScrollBar = class(TQtAbstractSlider)
391   private
392     FTrackPos: Integer;
393   protected
CreateWidgetnull394     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
395   public
396     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
397     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
398     procedure SlotSliderReleased; cdecl; override;
EventFilternull399     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
400     procedure AttachEvents; override;
401     property TrackPos: Integer read FTrackPos write FTrackPos;
402   end;
403 
404   { TQtFrame }
405 
406   TQtFrame = class(TQtWidget)
407   private
408   protected
CreateWidgetnull409     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
410   public
CanPaintBackgroundnull411     function CanPaintBackground: Boolean; override;
412     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
413     procedure setFrameStyle(p1: Integer);
414     procedure setFrameShape(p1: QFrameShape);
415     procedure setFrameShadow(p1: QFrameShadow);
416   end;
417 
418   { TQtAbstractScrollArea }
419 
420   TQtAbstractScrollArea = class(TQtFrame)
421   private
getScrollBarsPolicynull422     function getScrollBarsPolicy(AIndex: Boolean): QtScrollBarPolicy;
423   protected
424     FHScrollbar: TQtScrollBar;
425     FVScrollbar: TQtScrollbar;
426     procedure setScrollBarPolicy(AIndex: Boolean;
427       const AValue: QtScrollBarPolicy);
428   public
EventFilternull429     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
430     procedure grabMouse; override;
GetContainerWidgetnull431     function GetContainerWidget: QWidgetH; override;
getClientOffsetnull432     function getClientOffset: TPoint; override;
getClientBoundsnull433     function getClientBounds: TRect; override;
getScrollFrameOffsetnull434     function getScrollFrameOffset: Integer;
getViewOriginnull435     function getViewOrigin: TPoint;
viewportWidgetnull436     function viewportWidget: QWidgetH;
horizontalScrollBarnull437     function horizontalScrollBar: TQtScrollBar;
verticalScrollBarnull438     function verticalScrollBar: TQtScrollBar;
439     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
440     procedure setHorizontalScrollBar(AScrollBar: TQtScrollBar);
441     procedure setVerticalScrollBar(AScrollBar: TQtScrollBar);
442     procedure setScrollStyle(AScrollStyle: TScrollStyle);
443     procedure SetNoMousePropagation(Sender: QWidgetH; const ANoMousePropagation: Boolean); override;
444     procedure DestroyNotify(AWidget: TQtWidget); override;
445     destructor Destroy; override;
446     procedure Update(ARect: PRect = nil); override;
447     procedure UpdateRegion(ARgn: QRegionH); override;
448     procedure Repaint(ARect: PRect = nil); override;
449     property ScrollBarPolicy[AIndex: Boolean]: QtScrollBarPolicy read getScrollBarsPolicy write setScrollBarPolicy;
450   end;
451 
452   { TQtCustomControl }
453 
454   TQtCustomControl = class(TQtAbstractScrollArea)
455   private
456     FCornerWidget: TQtWidget;
457     FViewPortWidget: TQtViewPort;
458   protected
CreateWidgetnull459     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
ProcessArrowKeysnull460     function ProcessArrowKeys: Boolean; override;
461   public
462     destructor Destroy; override;
EventFilternull463     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
464     procedure ViewPortEventFilter(event: QEventH; retval: PBoolean); cdecl;
465 
466     procedure DestroyNotify(AWidget: TQtWidget); override;
467   public
CanAdjustClientRectOnResizenull468     function CanAdjustClientRectOnResize: Boolean; override;
cornerWidgetnull469     function cornerWidget: TQtWidget;
MapToGlobalnull470     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
MapFromGlobalnull471     function MapFromGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
viewportnull472     function viewport: TQtViewPort;
473     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); override;
474     procedure setCornerWidget(AWidget: TQtWidget);
475     procedure setCursor(const ACursor: QCursorH); override;
476     procedure setViewport(const AViewPort: QWidgetH);
477     procedure setVisible(AVisible: Boolean); override;
478     procedure viewportNeeded; virtual;
479     procedure viewportDelete; virtual;
480   end;
481 
482   { TQtViewPort }
483 
484   TQtViewPort = class(TQtWidget)
485   private
486     {when our viewport is invisible then we must keep track of scrolling. issue #29239}
487     FInvisibleX: integer;
488     FInvisibleY: integer;
489   public
CanPaintBackgroundnull490     function CanPaintBackground: Boolean; override;
EventFilternull491     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
492     procedure InitializeWidget; override;
493     procedure scroll(dx, dy: integer; ARect: PRect = nil); override;
494     procedure stackUnder(AWidget: QWidgetH); override;
495   end;
496 
497   { TQtGraphicView }
498 
499   TQtGraphicsView = class(TQtAbstractScrollArea)
500   protected
CreateWidgetnull501     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
502   end;
503 
504   { TQtArrow }
505 
506   TQtArrow = class(TQtFrame)
507   protected
CreateWidgetnull508     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
509   public
510     ArrowType: Integer;
511   end;
512 
513   { TQtAbstractButton }
514 
515   TQtAbstractButton = class(TQtWidget)
516   protected
ProcessArrowKeysnull517     function ProcessArrowKeys: Boolean; override;
518   public
CanPaintBackgroundnull519     function CanPaintBackground: Boolean; override;
getIconSizenull520     function getIconSize: TSize; virtual;
getTextnull521     function getText: WideString; override;
522     procedure setIcon(AIcon: QIconH); virtual;
523     procedure setIconSize(Size: PSize); virtual;
524     procedure setShortcut(AShortCutK1, AShortCutK2: TShortcut);
525     procedure setText(const W: WideString); override;
526     procedure Toggle;
isCheckednull527     function isChecked: Boolean;
isDownnull528     function isDown: Boolean;
529     procedure setCheckable(p1: Boolean);
530     procedure setChecked(p1: Boolean);
531     procedure setDefaultColorRoles; override;
532     procedure setDown(p1: Boolean);
533     procedure SignalPressed; cdecl;
534     procedure SignalReleased; cdecl;
535     procedure SignalClicked({%H-}Checked: Boolean = False); cdecl;
536     procedure SignalClicked2; cdecl;
537   end;
538 
539   { TQtPushButton }
540 
541   TQtPushButton = class(TQtAbstractButton)
542   private
543     FClickedHook: QAbstractButton_hookH;
544     FToggledHook: QAbstractButton_hookH;
545   protected
CreateWidgetnull546     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
547   public
548     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
549   public
550     procedure SetDefault(const ADefault: Boolean);
551     procedure AttachEvents; override;
552     procedure DetachEvents; override;
553     procedure SlotClicked; cdecl; virtual;
554     procedure SlotToggled({%H-}AChecked: Boolean); cdecl; virtual;
555   end;
556 
557   { TQtBitBtn }
558 
559   TQtBitBtn = class(TQtPushButton)
560   private
561     FGlyphLayout: Integer;
562     FIcon: QIconH;
563     FIconSize: TSize;
564   protected
CreateWidgetnull565     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
566   public
567     destructor Destroy; override;
EventFilternull568     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
569     procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
570 
getIconSizenull571     function getIconSize: TSize; override;
getTextnull572     function getText: WideString; override;
573     procedure setIcon(AIcon: QIconH); override;
574     procedure setIconSize(Size: PSize); override;
575     procedure setText(const W: WideString); override;
576 
577     property GlyphLayout: Integer read FGlyphLayout write FGlyphLayout;
578   end;
579 
580   { TQtToggleBox }
581 
582   TQtToggleBox = class(TQtPushButton)
583   public
584     procedure SlotClicked; cdecl; override;
585     procedure SlotToggled({%H-}AChecked: Boolean); cdecl; override;
586   end;
587 
588   { TQtMainWindow }
589 
590   TQtMenuBar = class;
591   TQtToolBar = class;
592   TQtStatusBar = class;
593 
594   { TQtMDIArea }
595 
596   TQtMDIArea = class(TQtAbstractScrollArea)
597   private
598     FViewPortEventHook: QObject_hookH;
599     FSubWindowActivationHook: QMdiArea_hookH;
600     procedure SubWindowActivated(AWindow: QMDISubWindowH); cdecl;
601   protected
ScrollViewEventFilternull602     function ScrollViewEventFilter(Sender: QObjectH; Event: QEventH): boolean; cdecl;
603   public
604     constructor Create(const AParent: QWidgetH); overload;
605     destructor Destroy; override;
getClientOffsetnull606     function getClientOffset: TPoint; override;
EventFilternull607     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
608     procedure AttachEvents; override;
609     procedure DetachEvents; override;
ActiveSubWindownull610     function ActiveSubWindow: QMdiSubWindowH;
611     procedure ActivateSubWindow(AMdiWindow: QMdiSubWindowH);
612   end;
613 
614   {$IFDEF QTSCROLLABLEFORMS}
615   { TQtWindowArea }
616 
617   {Scrollbars on qt forms}
618   TQtWindowArea = class(TQtAbstractScrollArea)
619   private
620     FViewPortEventHook: QObject_hookH;
621   public
622     procedure AttachEvents; override;
CanAdjustClientRectOnResizenull623     function CanAdjustClientRectOnResize: Boolean; override;
624     procedure DetachEvents; override;
MapToGlobalnull625     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
626     procedure scroll(dx, dy: integer; ARect: PRect = nil); override;
627     {abstractscrollarea events}
EventFilternull628     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
629     {viewport events}
ScrollViewEventFilternull630     function ScrollViewEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
getWindowStatenull631     function getWindowState: QtWindowStates; override;
632   end;
633   {$ENDIF}
634 
635   TQtMainWindow = class(TQtWidget)
636   private
637     FBlocked: Boolean;
638     FIsFrameWindow: Boolean;
639     LayoutWidget: QBoxLayoutH;
640     FCWEventHook: QObject_hookH;
641     FShowOnTaskBar: Boolean;
642     FPopupParent: QWidgetH;
643     FMDIStateHook: QMdiSubWindow_hookH;
644     {$IFDEF QtUseAccurateFrame}
645     FFormHasInvalidPosition: boolean;
646     {$ENDIF}
647   protected
CreateWidgetnull648     function CreateWidget(const {%H-}AParams: TCreateParams):QWidgetH; override;
649     procedure ChangeParent(NewParent: QWidgetH);
650     procedure UpdateParent;
651   public
652     QtFormBorderStyle: Integer;
653     QtFormStyle: Integer;
654     IsMainForm: Boolean;
655     MDIAreaHandle: TQtMDIArea; // valid only if we are fsMDIForm
656     MDIChildArea: TQtMDIArea; // valid only if we are fsMDIChild
657     MenuBar: TQtMenuBar;
658     ToolBar: TQtToolBar;
659     {$IFDEF QTSCROLLABLEFORMS}
660     ScrollArea: TQtWindowArea;
661     {$ENDIF}
662     destructor Destroy; override;
663     procedure Activate; override;
CanAdjustClientRectOnResizenull664     function CanAdjustClientRectOnResize: Boolean; override;
getAcceptDropFilesnull665     function getAcceptDropFiles: Boolean; override;
GetContainerWidgetnull666     function GetContainerWidget: QWidgetH; override;
667     procedure grabMouse; override;
getClientBoundsnull668     function getClientBounds: TRect; override;
getClientOffsetnull669     function getClientOffset: TPoint; override;
670 
getFrameSizenull671     function getFrameSize: TSize; override;
getFrameGeometrynull672     function getFrameGeometry: TRect; override;
getTextnull673     function getText: WideString; override;
getTextStaticnull674     function getTextStatic: Boolean; override;
675 
MapToGlobalnull676     function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
677 
678     procedure Update(ARect: PRect = nil); override;
679     procedure UpdateRegion(ARgn: QRegionH); override;
680     procedure Repaint(ARect: PRect = nil); override;
681 
682     procedure Resize(ANewWidth, ANewHeight: Integer); override;
683     procedure setText(const W: WideString); override;
684     procedure setMenuBar(AMenuBar: QMenuBarH);
EventFilternull685     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
686     procedure MDIChildWindowStateChanged(AOldState: QtWindowStates; ANewState: QtWindowStates); cdecl;
IsFramedWidgetnull687     function IsFramedWidget: boolean; override;
IsMdiChildnull688     function IsMdiChild: Boolean;
IsModalnull689     function IsModal: Boolean;
MdiChildCountnull690     function MdiChildCount: integer;
691     procedure OffsetMousePos(APoint: PQtPoint); override;
692     procedure setAcceptDropFiles(AValue: Boolean);
693     procedure setColor(const Value: PQColor); override;
694     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
695     procedure SlotActivateWindow(vActivate: Boolean); cdecl;
696     procedure slotWindowStateChange; cdecl;
697     procedure setShowInTaskBar(AValue: Boolean);
698     procedure setRealPopupParent(NewParent: QWidgetH);
699     property Blocked: Boolean read FBlocked write FBlocked;
700     property IsFrameWindow: Boolean read FIsFrameWindow write FIsFrameWindow; {check if our LCLObject is TCustomFrame}
701     property ShowOnTaskBar: Boolean read FShowOnTaskBar;
702   public
703     procedure AttachEvents; override;
704     procedure DetachEvents; override;
CWEventFilternull705     function CWEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
706   end;
707 
708   { TQtHintWindow }
709 
710   TQtHintWindow = class(TQtMainWindow)
711   private
712     FNeedRestoreVisible: Boolean;
713   protected
CreateWidgetnull714     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
715   public
716     procedure InitializeWidget; override;
717     procedure DeInitializeWidget; override;
CanPaintBackgroundnull718     function CanPaintBackground: Boolean; override;
719     procedure SetDefaultColorRoles; override;
720     procedure setVisible(AVisible: Boolean); override;
721     property NeedRestoreVisible: Boolean read FNeedRestoreVisible write FNeedRestoreVisible;
722   end;
723 
724   { TQtStaticText }
725 
726   TQtStaticText = class(TQtFrame)
727   private
GetWordWrapnull728     function GetWordWrap: Boolean;
729     procedure SetWordWrap(AValue: Boolean);
730   protected
CreateWidgetnull731     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
732   public
CanPaintBackgroundnull733     function CanPaintBackground: Boolean; override;
getTextnull734     function getText: WideString; override;
735     procedure setText(const W: WideString); override;
736     procedure setAlignment(const AAlignment: QtAlignment);
737     property WordWrap: Boolean read GetWordWrap write SetWordWrap;
738   end;
739 
740   { TQtCheckBox }
741 
742   TQtCheckBox = class(TQtAbstractButton)
743   private
744     FStateChangedHook : QCheckBox_hookH;
745   protected
CreateWidgetnull746     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
747   public
CheckStatenull748     function CheckState: QtCheckState;
749     procedure setCheckState(state: QtCheckState);
750     procedure setTriState(AAllowGrayed: Boolean);
751   public
752     procedure AttachEvents; override;
753     procedure DetachEvents; override;
754     procedure signalStateChanged(p1: Integer); cdecl;
755   end;
756 
757   { TQtRadioButton }
758 
759   TQtRadioButton = class(TQtAbstractButton)
760   private
761     FToggledHook: QAbstractButton_hookH;
762   protected
CreateWidgetnull763     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
764   public
765     procedure AttachEvents; override;
766     procedure DetachEvents; override;
767     procedure SignalToggled(Checked: Boolean); cdecl;
EventFilternull768     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
769   end;
770 
771   { TQtGroupBox }
772 
773   TQtGroupBox = class(TQtWidget)
774   private
775     FGroupBoxType: TQtGroupBoxType;
776     FCWEventHook: QObject_hookH;
GetCheckBoxStatenull777     function GetCheckBoxState: boolean;
GetCheckBoxVisiblenull778     function GetCheckBoxVisible: boolean;
779     procedure SetCheckBoxState(AValue: boolean);
780     procedure SetCheckBoxVisible(AValue: boolean);
781     procedure setLayoutThemeMargins(ALayout: QLayoutH; AWidget: QWidgetH);
782   protected
CreateWidgetnull783     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
784   public
785     procedure AttachEvents; override;
786     procedure DetachEvents; override;
CanPaintBackgroundnull787     function CanPaintBackground: Boolean; override;
EventFilternull788     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
getClientBoundsnull789     function getClientBounds: TRect; override;
getClientOffsetnull790     function getClientOffset: TPoint; override;
getTextnull791     function getText: WideString; override;
792     procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
793       {%H-}WithThemeSpace: Boolean); override;
794     procedure setText(const W: WideString); override;
795     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
796     procedure Update(ARect: PRect = nil); override;
797     procedure UpdateRegion(ARgn: QRegionH); override;
798     procedure Repaint(ARect: PRect = nil); override;
799 
800     property GroupBoxType: TQtGroupBoxType read FGroupBoxType write FGroupBoxType;
801     property CheckBoxState: boolean read GetCheckBoxState write SetCheckBoxState;
802     property CheckBoxVisible: boolean read GetCheckBoxVisible write SetCheckBoxVisible;
803   end;
804 
805   { TQtToolBar }
806 
807   TQtToolBar = class(TQtWidget)
808   private
809   protected
CreateWidgetnull810     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
811   end;
812 
813   { TQtToolButton }
814 
815   TQtToolButton = class(TQtAbstractButton)
816   private
817   protected
CreateWidgetnull818     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
819   end;
820 
821   { TQtTrackBar }
822 
823   TQtTrackBar = class(TQtAbstractSlider)
824   protected
CreateWidgetnull825     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
826   public
getTickIntervalnull827     function getTickInterval: Integer;
828     procedure setTickPosition(Value: QSliderTickPosition);
829     procedure setTickInterval(Value: Integer);
830   public
831     procedure AttachEvents; override;
832 
833     procedure SlotSliderMoved(p1: Integer); cdecl; override;
834     procedure SlotValueChanged(p1: Integer); cdecl; override;
835   end;
836 
837   { TQtLineEdit }
838 
839   TQtLineEdit = class(TQtWidget, IQtEdit)
840   private
841     FCachedSelectionLen: integer;
842     FCachedSelectionStart: integer;
843     FNumbersOnly: boolean;
844     FIntValidator: QIntValidatorH;
845     FTextChanged: QLineEdit_hookH;
getTextMarginsnull846     function getTextMargins: TRect;
847     procedure SetNumbersOnly(AValue: boolean);
848     procedure setTextMargins(ARect: TRect);
849   protected
CreateWidgetnull850     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
851     procedure setTextHint(const ATextHint: string);
852   public
getAlignmentnull853     function getAlignment: QtAlignment;
getCursorPositionnull854     function getCursorPosition: TPoint;
getMaxLengthnull855     function getMaxLength: Integer;
getSelectedTextnull856     function getSelectedText: WideString;
getSelectionStartnull857     function getSelectionStart: Integer;
getSelectionLengthnull858     function getSelectionLength: Integer;
getTextnull859     function getText: WideString; override;
getTextStaticnull860     function getTextStatic: Boolean; override;
isUndoAvailablenull861     function isUndoAvailable: Boolean;
hasSelectedTextnull862     function hasSelectedText: Boolean;
863     procedure selectAll;
864     procedure setAlignment(const AAlignment: QtAlignment);
865     procedure setBorder(const ABorder: Boolean);
866     procedure setCursorPosition(const ACursorPosition: Integer);
867     procedure setDefaultColorRoles; override;
868     procedure setEchoMode(const AMode: QLineEditEchoMode);
869     procedure setInputMask(const AMask: WideString);
870     procedure setMaxLength(const ALength: Integer);
871     procedure setReadOnly(const AReadOnly: Boolean);
872     procedure setSelection(const AStart, ALength: Integer);
873     procedure setText(const AText: WideString); override;
874     procedure Cut;
875     procedure Copy;
876     procedure Paste;
877     procedure Undo;
878   public
879     destructor Destroy; override;
880     procedure AttachEvents; override;
881     procedure DetachEvents; override;
EventFilternull882     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
883     procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
884       {%H-}WithThemeSpace: Boolean); override;
885     procedure SignalTextChanged(p1: PWideString); cdecl;
886     property CachedSelectionStart: integer read FCachedSelectionStart write FCachedSelectionStart;
887     property CachedSelectionLen: integer read FCachedSelectionLen write FCachedSelectionLen;
888     property NumbersOnly: boolean read FNumbersOnly write SetNumbersOnly;
889     property TextMargins: TRect read GetTextMargins write SetTextMargins;
890   end;
891 
892   { TQtTextEdit }
893 
894   TQtTextEdit = class(TQtAbstractScrollArea, IQtEdit)
895   private
896     FViewportEventHook: QObject_hookH;
897     FUndoAvailableHook: QTextEdit_hookH;
898     FTextChangedHook: QTextEdit_hookH;
899     FUndoAvailable: Boolean;
GetAcceptRichTextnull900     function GetAcceptRichText: Boolean;
901     procedure SetAcceptRichText(AValue: Boolean);
902   protected
CreateWidgetnull903     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
904     procedure setTextHint(const ATextHint: string);
905   public
906     FList: TStrings;
907     procedure Append(const AStr: WideString);
908     procedure ClearText;
getAlignmentnull909     function getAlignment: QtAlignment;
getBlockCountnull910     function getBlockCount: Integer;
getCursorPositionnull911     function getCursorPosition: TPoint;
getMaxLengthnull912     function getMaxLength: Integer;
getTextnull913     function getText: WideString; override;
getTextStaticnull914     function getTextStatic: Boolean; override;
getSelectionStartnull915     function getSelectionStart: Integer;
getSelectionEndnull916     function getSelectionEnd: Integer;
getSelectionLengthnull917     function getSelectionLength: Integer;
918     procedure appendLine(AText: WideString);
919     procedure insertLine(const AIndex: integer; AText: WideString);
isUndoAvailablenull920     function isUndoAvailable: Boolean;
921     procedure removeLine(const AIndex: integer);
922     procedure setAlignment(const AAlignment: QtAlignment);
923     procedure setBorder(const ABorder: Boolean);
924     procedure setCursorPosition(const ACursorPosition: Integer);
925     procedure setDefaultColorRoles; override;
926     procedure setEchoMode(const AMode: QLineEditEchoMode);
927     procedure setLineWrapMode(const AMode: QTextEditLineWrapMode);
928     procedure setMaxLength(const ALength: Integer);
929     procedure setLineText(const AIndex: integer; AText: WideString);
930     procedure setText(const AText: WideString); override;
931     procedure setReadOnly(const AReadOnly: Boolean);
932     procedure setSelection(const AStart, ALength: Integer);
933     procedure setTabChangesFocus(const AValue: Boolean);
934     procedure Cut;
935     procedure Copy;
936     procedure Paste;
937     procedure Undo;
938   public
939     procedure AttachEvents; override;
940     procedure DetachEvents; override;
viewportEventFilternull941     function viewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
getContextMenuPolicynull942     function getContextMenuPolicy: QtContextMenuPolicy; override;
943     procedure setContextMenuPolicy(const AValue: QtContextMenuPolicy); override;
944     procedure SignalUndoAvailable(b: Boolean); cdecl;
945     procedure SignalTextChanged(); cdecl;
946     property AcceptRichText: Boolean read GetAcceptRichText write SetAcceptRichText;
947   end;
948 
949   { TQtTabBar }
950   TQtTabBar = class(TQtWidget)
951   private
952     FSavedIndexOnPageChanging: Integer; // used to handle OnPageChanging AllowChange param
953     FTabBarChangedHook: QTabBar_hookH;
954     FTabBarMovedHook: QTabBar_hookH;
955   public
956     procedure AttachEvents; override;
957     procedure DetachEvents; override;
GetTabRectnull958     function GetTabRect(const AIndex: integer): TRect;
959     // under some themes tabs doesn't start at 0,0 (eg. MacOSX)
960     function TabBarOffset: TPoint;
961     procedure SignalTabBarMoved(fromIndex: integer; toIndex: Integer); cdecl;
962     procedure SignalTabBarCurrentChanged(Index: Integer); cdecl;
963     function SlotTabBarMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
964     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
965     procedure SetTabFontColor(AIndex: Integer; AColor: TQColor);
966   end;
967 
968   { TQtTabWidget }
969 
970   TQtTabWidget = class(TQtWidget)
971   private
972     FCurrentChangedHook: QTabWidget_hookH;
973     FCloseRequestedHook: QTabWidget_hookH;
974     FStackedWidgetHook: QObject_hookH;
975     FSwitchTabsByKeyboard: boolean;
976     FTabBar: TQtTabBar;
977     FStackWidget: QWidgetH;
978     function getShowTabs: Boolean;
979     function getStackWidget: QWidgetH;
980     function getTabBar: TQtTabBar;
981     procedure setShowTabs(const AValue: Boolean);
982   protected
983     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
984   public
985     destructor Destroy; override;
986     procedure DestroyNotify(AWidget: TQtWidget); override;
987     procedure AttachEvents; override;
988     procedure DetachEvents; override;
989 
990     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
991     procedure SignalCurrentChanged(Index: Integer); cdecl;
992     procedure SignalCloseRequested(Index: Integer); cdecl;
993   public
994     function indexOf(const AWidget: QWidgetH): integer;
995     function insertTab(index: Integer; page: QWidgetH; p2: WideString): Integer; overload;
996     function insertTab(index: Integer; page: QWidgetH; icon: QIconH; p2: WideString): Integer; overload;
997     function getCount: Integer;
998     function getClientBounds: TRect; override;
999     function getCurrentIndex: Integer;
1000     function GetLCLPageIndex(AIndex: Integer): Integer;
1001     function getTabPosition: QTabWidgetTabPosition;
1002     procedure removeTab(AIndex: Integer);
1003     procedure setCurrentIndex(AIndex: Integer);
1004     procedure setCurrentWidget(APage: TQtWidget; const AIsMoved: Boolean);
1005     procedure setTabPosition(ATabPosition: QTabWidgetTabPosition);
1006     procedure setTabIcon(index: Integer; icon: QIconH);
1007     procedure setTabText(index: Integer; p2: WideString);
1008     procedure setTabsClosable(AValue: Boolean);
1009     function tabAt(APoint: TPoint): Integer;
1010 
1011     property ShowTabs: Boolean read getShowTabs write setShowTabs;
1012     property TabBar: TQtTabBar read getTabBar;
1013     property StackWidget: QWidgetH read getStackWidget;
1014     property SwitchTabsByKeyboard: boolean read FSwitchTabsByKeyboard write FSwitchTabsByKeyboard;
1015   end;
1016 
1017   { TQtComboBox }
1018 
1019   TQtComboBox = class(TQtWidget, IQtEdit)
1020   private
1021     FKeyEnterFix: boolean; {issue #31574}
1022     FMouseFixPos: TQtPoint;
1023     // hooks
1024     FChangeHook: QComboBox_hookH;
1025     FActivateHook: QComboBox_hookH;
1026     FOwnerDrawn: Boolean;
1027     FSelectHook: QComboBox_hookH;
1028     FDropListEventHook: QObject_hookH;
1029     // parts
1030     FLineEdit: TQtLineEdit;
1031     FDropList: TQtListWidget;
1032     FDropListVisibleInternal: Boolean;
1033     function GetDropList: TQtListWidget;
1034     function GetLineEdit: TQtLineEdit;
1035     procedure InternalIntfGetItems; // calls TCustomComboBox(LCLObject).IntfGetItems
1036     procedure SetOwnerDrawn(const AValue: Boolean);
1037     procedure slotPaintCombo(Sender: QObjectH; Event: QEventH); cdecl;
1038   protected
1039     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1040     // IQtEdit implementation
1041     function getCursorPosition: TPoint;
1042     function getMaxLength: Integer;
1043     function getSelectionStart: Integer;
1044     function getSelectionLength: Integer;
1045     function isUndoAvailable: Boolean;
1046     procedure setEchoMode(const AMode: QLineEditEchoMode);
1047     procedure setMaxLength(const ALength: Integer);
1048     procedure setReadOnly(const AReadOnly: Boolean);
1049     procedure setSelection(const AStart, ALength: Integer);
1050     procedure setCursorPosition(const ACursorPosition: Integer);
1051     procedure setTextHint(const ATextHint: string);
1052     procedure Cut;
1053     procedure Copy;
1054     procedure Paste;
1055     procedure Undo;
1056   public
1057     FList: TStrings;
1058     destructor Destroy; override;
1059     procedure DestroyNotify(AWidget: TQtWidget); override;
1060     procedure ClearItems;
1061     procedure setBorder(const ABorder: Boolean);
1062     function currentIndex: Integer;
1063     function findText(AText: WideString): Integer;
1064     function getDroppedDown: Boolean;
1065     function getEditable: Boolean;
1066     function getItemText(AIndex: Integer): WideString;
1067     function getMaxVisibleItems: Integer;
1068     function getText: WideString; override;
1069     function getTextStatic: Boolean; override;
1070     procedure insertItem(AIndex: Integer; AText: String); overload;
1071     procedure insertItem(AIndex: Integer; AText: PWideString); overload;
1072     procedure setCurrentIndex(index: Integer);
1073     procedure setDefaultColorRoles; override;
1074     procedure setDroppedDown(const ADroppedDown: Boolean);
1075     procedure setMaxVisibleItems(ACount: Integer);
1076     procedure setEditable(const AValue: Boolean);
1077     procedure setItemText(AIndex: Integer; AText: String);
1078     procedure setText(const W: WideString); override;
1079     procedure removeItem(AIndex: Integer);
1080 
1081     property DropList: TQtListWidget read GetDropList;
1082     property LineEdit: TQtLineEdit read GetLineEdit;
1083     property OwnerDrawn: Boolean read FOwnerDrawn write SetOwnerDrawn;
1084   public
1085     procedure AttachEvents; override;
1086     procedure DetachEvents; override;
1087     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1088     procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
1089       {%H-}WithThemeSpace: Boolean); override;
1090 
1091     procedure SlotActivate(index: Integer); cdecl;
1092     procedure SlotChange(p1: PWideString); cdecl;
1093     procedure SlotSelect(index: Integer); cdecl;
1094     procedure SlotDropListVisibility(AVisible: Boolean); cdecl;
1095     procedure FixMouseUp; // qt eats MouseRelease event when popup is shown, so we'll fix it
1096   end;
1097 
1098   { TQtAbstractSpinBox}
1099 
1100   TQtAbstractSpinBox = class(TQtWidget, IQtEdit)
1101   private
1102     {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
1103     FParentShowPassed: PtrInt;
1104     {$ENDIF}
1105     FEditingFinishedHook: QAbstractSpinBox_hookH;
1106     FLineEditHook: QObject_hookH;
1107     FTextChangedHook: QLineEdit_hookH;
1108     // parts
1109     FLineEdit: QLineEditH;
1110     FTextChangedByValueChanged: Boolean;
GetLineEditnull1111     function GetLineEdit: QLineEditH;
LineEditEventFilternull1112     function LineEditEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
1113   protected
CreateWidgetnull1114     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1115     // IQtEdit implementation
getCursorPositionnull1116     function getCursorPosition: TPoint;
getMaxLengthnull1117     function getMaxLength: Integer;
getSelectionStartnull1118     function getSelectionStart: Integer;
getSelectionLengthnull1119     function getSelectionLength: Integer;
isUndoAvailablenull1120     function isUndoAvailable: Boolean;
1121     procedure setEchoMode(const AMode: QLineEditEchoMode);
1122     procedure setMaxLength(const ALength: Integer);
1123     procedure setSelection(const AStart, ALength: Integer);
1124     procedure setCursorPosition(const ACursorPosition: Integer);
1125     procedure SignalLineEditTextChanged(AnonParam1: PWideString); virtual; cdecl;
1126     procedure setTextHint(const ATextHint: string);
1127     procedure Cut;
1128     procedure Copy;
1129     procedure Paste;
1130     procedure Undo;
1131     property TextChangedByValueChanged: Boolean read FTextChangedByValueChanged write FTextChangedByValueChanged;
1132   public
getValuenull1133     function getValue: Double; virtual; abstract;
getReadOnlynull1134     function getReadOnly: Boolean;
getTextnull1135     function getText: WideString; override;
getTextStaticnull1136     function getTextStatic: Boolean; override;
1137     procedure setAlignment(const AAlignment: QtAlignment);
1138     procedure setBorder(const ABorder: Boolean);
1139     procedure setDefaultColorRoles; override;
1140     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
1141     procedure setMinimum(const v: Double); virtual; abstract;
1142     procedure setMaximum(const v: Double); virtual; abstract;
1143     procedure setSingleStep(const v: Double); virtual; abstract;
1144     procedure setReadOnly(const r: Boolean);
1145     procedure setValue(const v: Double); virtual; abstract;
1146     procedure setText(const W: WideString); override;
1147 
1148     property LineEdit: QLineEditH read GetLineEdit;
1149   public
1150     procedure AttachEvents; override;
1151     procedure DetachEvents; override;
EventFilternull1152     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1153 
1154     procedure SignalEditingFinished; cdecl;
1155   end;
1156 
1157   { TQtFloatSpinBox }
1158 
1159   TQtFloatSpinBox = class(TQtAbstractSpinBox)
1160   private
1161     FValue: Double;
1162     FValueChangedHook: QDoubleSpinBox_hookH;
1163   protected
CreateWidgetnull1164     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1165   public
getValuenull1166     function getValue: Double; override;
1167     procedure setDecimals(const v: integer);
1168     procedure setMinimum(const v: Double); override;
1169     procedure setMaximum(const v: Double); override;
1170     procedure setSingleStep(const v: Double); override;
1171     procedure setValue(const v: Double); override;
1172   public
1173     procedure AttachEvents; override;
1174     procedure DetachEvents; override;
1175     procedure SignalValueChanged(p1: Double); cdecl;
1176   end;
1177 
1178   { TQtSpinBox }
1179 
1180   TQtSpinBox = class(TQtAbstractSpinBox)
1181   private
1182     FValue: Integer;
1183     FValueChangedHook: QSpinBox_hookH;
1184   protected
CreateWidgetnull1185     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1186   public
getValuenull1187     function getValue: Double; override;
1188     procedure setMinimum(const v: Double); override;
1189     procedure setMaximum(const v: Double); override;
1190     procedure setSingleStep(const v: Double); override;
1191     procedure setValue(const v: Double); override;
1192   public
1193     procedure AttachEvents; override;
1194     procedure DetachEvents; override;
1195 
1196     procedure SignalValueChanged(p1: Integer); cdecl;
1197   end;
1198 
1199   { TQtAbstractItemView }
1200 
1201   TQtAbstractItemView = class(TQtAbstractScrollArea)
1202   private
1203     FAllowGrayed: boolean;
1204     FSavedEvent: QMouseEventH;
1205     FSavedEventTimer: QTimerH;
1206     FSavedEventTimerHook: QTimer_hookH;
1207     FCheckable: boolean;
1208     FHideSelection: Boolean;
1209     FOldDelegate: QAbstractItemDelegateH;
1210     FNewDelegate: QLCLItemDelegateH;
1211     FOwnerData: Boolean;
1212     FSignalActivated: QAbstractItemView_hookH;
1213     FSignalClicked: QAbstractItemView_hookH;
1214     FSignalDoubleClicked: QAbstractItemView_hookH;
1215     FSignalEntered: QAbstractItemView_hookH;
1216     FSignalPressed: QAbstractItemView_hookH;
1217     FSignalViewportEntered: QAbstractItemView_hookH;
1218     FAbstractItemViewportEventHook: QObject_hookH;
1219     FSyncingItems: Boolean;
1220     FViewStyle: Integer;
getIconSizenull1221     function getIconSize: TSize;
GetOwnerDrawnnull1222     function GetOwnerDrawn: Boolean;
1223     procedure setIconSize(const AValue: TSize);
1224     procedure SetOwnerDrawn(const AValue: Boolean);
1225   protected
GetItemFlagsnull1226     function GetItemFlags(AIndex: Integer): QtItemFlags; virtual;
1227     procedure SetItemFlags(AIndex: Integer; AValue: QtItemFlags); virtual;
1228     procedure OwnerDataNeeded(ARect: TRect); virtual;
1229     procedure PostponedMouseRelease(AEvent: QEventH); virtual;
1230     procedure PostponedMouseReleaseTimerEvent(); cdecl; virtual;
1231   public
1232     constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); override;
1233     destructor Destroy; override;
1234     procedure signalActivated(index: QModelIndexH); cdecl; virtual;
1235     procedure signalClicked(index: QModelIndexH); cdecl; virtual;
1236     procedure signalDoubleClicked(index: QModelIndexH); cdecl; virtual;
1237     procedure signalEntered(index: QModelIndexH); cdecl; virtual;
1238     procedure signalPressed(index: QModelIndexH); cdecl; virtual;
1239     procedure signalViewportEntered; cdecl; virtual;
1240     procedure AttachEvents; override;
1241     procedure DetachEvents; override;
1242 
itemViewViewportEventFilternull1243     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; virtual;
1244     procedure setDefaultColorRoles; override;
1245   public
1246     procedure clearSelection; virtual;
getModelnull1247     function getModel: QAbstractItemModelH;
getRowHeightnull1248     function getRowHeight(ARowIndex: integer): integer;
getSelectionModenull1249     function getSelectionMode: QAbstractItemViewSelectionMode;
getTopItemnull1250     function getTopItem: integer; virtual;
getVisibleRowCountnull1251     function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; virtual;
1252 
1253     procedure modelIndex(retval: QModelIndexH; row, column: Integer; parent: QModelIndexH = nil);
visualRectnull1254     function visualRect(Index: QModelIndexH): TRect;
1255     procedure setEditTriggers(ATriggers: QAbstractItemViewEditTriggers);
1256     procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); virtual;
1257     procedure setSelectionBehavior(ABehavior: QAbstractItemViewSelectionBehavior);
1258     procedure setWordWrap(const AValue: Boolean); virtual;
1259     property AllowGrayed: boolean read FAllowGrayed write FAllowGrayed;
1260     property Checkable: boolean read FCheckable write FCheckable;
1261     property HideSelection: Boolean read FHideSelection write FHideSelection;
1262     property IconSize: TSize read getIconSize write setIconSize;
1263     property ItemFlags[AIndex: Integer]: QtItemFlags read GetItemFlags write SetItemFlags;
1264     property OwnerDrawn: Boolean read GetOwnerDrawn write SetOwnerDrawn;
1265     property OwnerData: Boolean read FOwnerData write FOwnerData;
1266     property SyncingItems: Boolean read FSyncingItems write FSyncingItems;
1267     property ViewStyle: Integer read FViewStyle write FViewStyle;
1268   public
1269     procedure ItemDelegateSizeHint(option: QStyleOptionViewItemH; index: QModelIndexH; Size: PSize); cdecl; virtual;
1270     procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; virtual;
1271   end;
1272 
1273   { TQtListView }
1274 
1275   TQtListView = class(TQtAbstractItemView)
1276   private
getBatchSizenull1277     function getBatchSize: integer;
getGridSizenull1278     function getGridSize: TSize;
getSpacingnull1279     function getSpacing: Integer;
1280     procedure setBatchSize(const AValue: integer);
1281     procedure setSpacing(const AValue: integer);
1282     procedure setGridSize(const AValue: TSize);
1283   public
1284     procedure setLayoutMode(const ALayoutMode: QListViewLayoutMode);
1285     procedure setMovement(const AMovement: QListViewMovement);
1286     procedure setResizeMode(const AResizeMode: QListViewResizeMode);
1287     procedure setUniformItemSizes(const AEnable: Boolean);
1288     procedure setViewFlow(const AFlow: QListViewFlow);
1289     procedure setViewMode(const AMode: QListViewViewMode);
1290     procedure setWordWrap(const AValue: Boolean); override;
1291     procedure setWrapping(const AWrapping: Boolean);
1292     procedure LayoutItems;
1293     property BatchSize: integer read getBatchSize write setBatchSize;
1294     property GridSize: TSize read getGridSize write setGridSize;
1295     property Spacing: Integer read getSpacing write setSpacing;
1296   end;
1297 
1298   { TQtListWidget }
1299 
1300   TQtListWidget = class(TQtListView)
1301   private
1302     FCheckBoxClicked: Boolean;
1303     FSavedSelection: TPtrIntArray;
1304     FCurrentItemChangedHook: QListWidget_hookH;
1305     FSelectionChangeHook: QListWidget_hookH;
1306     FItemClickedHook: QListWidget_hookH;
1307     FItemTextChangedHook: QListWidget_hookH;
1308     FDelayedCheckItem: QListWidgetItemH;
1309     FDontPassSelChange: Boolean;
1310     procedure HandleCheckChangedEvent(const AMousePos: TQtPoint;
1311         AItem: QListWidgetItemH; AEvent: QEventH);
GetItemCheckednull1312     function GetItemChecked(AIndex: Integer): Boolean;
getItemCountnull1313     function getItemCount: Integer;
GetItemEnablednull1314     function GetItemEnabled(AIndex: Integer): Boolean;
GetSelectednull1315     function GetSelected(AIndex: Integer): Boolean;
1316     procedure SetItemChecked(AIndex: Integer; AValue: Boolean);
1317     procedure setItemCount(const AValue: Integer);
1318     procedure SetItemEnabled(AIndex: Integer; AValue: Boolean);
1319     procedure SetSelected(AIndex: Integer; AValue: Boolean);
1320   protected
CreateWidgetnull1321     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1322     procedure OwnerDataNeeded(ARect: TRect); override;
GetItemFlagsnull1323     function GetItemFlags(AIndex: Integer): QtItemFlags; override;
1324     procedure SetItemFlags(AIndex: Integer; AValue: QtItemFlags); override;
1325     procedure SetItemLastCheckState(AItem: QListWidgetItemH);
1326     procedure SetItemLastCheckStateInternal(AItem: QListWidgetItemH; AState: QtCheckState);
1327     procedure SetNextStateMap(AItem: QListWidgetItemH); virtual;
1328   public
1329     FList: TStrings;
1330   public
1331     procedure AttachEvents; override;
1332     procedure DetachEvents; override;
1333     procedure InitializeWidget; override;
EventFilternull1334     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1335     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1336 
1337     procedure signalCurrentItemChanged(current: QListWidgetItemH; previous: QListWidgetItemH); cdecl; virtual;
1338     procedure signalItemTextChanged(ANewText: PWideString); cdecl; virtual;
1339     procedure signalItemClicked(item: QListWidgetItemH); cdecl; virtual;
1340     procedure signalSelectionChanged(); cdecl; virtual;
1341     procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; override;
1342   public
1343     procedure clearSelection; override;
1344     procedure ClearItems;
currentRownull1345     function currentRow: Integer;
currentItemnull1346     function currentItem: QListWidgetItemH;
GetItemLastCheckStatenull1347     function GetItemLastCheckState(AItem: QListWidgetItemH): QtCheckState;
IndexAtnull1348     function IndexAt(APoint: PQtPoint): Integer;
1349     procedure insertItem(AIndex: Integer; AText: String); overload;
1350     procedure insertItem(AIndex: Integer; AText: PWideString); overload;
itemAtnull1351     function itemAt(APoint: TPoint): QListWidgetItemH; overload;
itemAtnull1352     function itemAt(x: Integer; y: Integer): QListWidgetItemH; overload;
getItemnull1353     function getItem(AIndex: Integer): QListWidgetItemH;
getItemSelectednull1354     function getItemSelected(AItem: QListWidgetItemH): Boolean;
getItemVisiblenull1355     function getItemVisible(AItem: QListWidgetItemH): Boolean;
getRownull1356     function getRow(AItem: QListWidgetItemH): integer;
getSelCountnull1357     function getSelCount: Integer;
getTopItemnull1358     function getTopItem: integer; override;
getVisibleRowCountnull1359     function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; override;
getVisualItemRectnull1360     function getVisualItemRect(AItem: QListWidgetItemH): TRect;
selectedItemsnull1361     function selectedItems: TPtrIntArray;
1362     procedure setCurrentRow(row: Integer);
1363     procedure setCurrentItem(AItem: QListWidgetItemH; const AIsSet: Boolean = True);
1364     procedure setItemText(AIndex: Integer; AText: String); overload;
1365     procedure setItemText(AIndex: Integer; AText: String; AAlignment: Integer); overload;
1366     procedure setItemSelected(AItem: QListWidgetItemH; const ASelect: Boolean);
1367     procedure setItemVisible(AItem: QListWidgetItemH; const AVisible: Boolean);
1368     procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); override;
1369     procedure scrollToItem(row: integer; hint: QAbstractItemViewScrollHint);
1370     procedure removeItem(AIndex: Integer);
rowCountnull1371     function rowCount: integer;
1372     procedure ExchangeItems(const AIndex1, AIndex2: Integer);
1373     procedure MoveItem(const AFromIndex, AToIndex: Integer);
1374     property ItemCount: Integer read getItemCount write setItemCount;
1375     property ItemChecked[AIndex: Integer]: Boolean read GetItemChecked write SetItemChecked;
1376     property Enabled[AIndex: Integer]: Boolean read GetItemEnabled write SetItemEnabled;
1377     property Selected[AIndex: Integer]: Boolean read GetSelected write SetSelected;
1378   end;
1379 
1380   { TQtCheckListBox }
1381 
1382   TQtCheckListBox = class (TQtListWidget)
1383   private
1384     FItemChangedHook: QListWidget_hookH;
GetItemCheckStatenull1385     function GetItemCheckState(AIndex: Integer): QtCheckState;
1386     procedure SetItemCheckState(AIndex: Integer; AValue: QtCheckState);
1387   protected
CreateWidgetnull1388     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1389     procedure SetNextStateMap(AItem: QListWidgetItemH); override;
1390   public
1391     procedure AttachEvents; override;
1392     procedure DetachEvents; override;
1393 
EventFilternull1394     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1395     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1396 
1397     procedure signalCurrentItemChanged(current: QListWidgetItemH; previous: QListWidgetItemH); cdecl; override;
1398     procedure signalItemClicked(item: QListWidgetItemH); cdecl; override;
1399     procedure signalSelectionChanged(); cdecl; override;
1400     procedure signalItemChanged(item: QListWidgetItemH); cdecl;
1401     property ItemCheckState[AIndex: Integer]: QtCheckState read GetItemCheckState write SetItemCheckState;
1402   end;
1403 
1404   { TQtHeaderView }
1405 
1406   TQtHeaderView = class (TQtAbstractItemView)
1407   private
1408     FSectionClicked: QHeaderView_hookH;
getClickablenull1409     function getClickable: Boolean;
getMinSectionSizenull1410     function getMinSectionSize: Integer;
1411     procedure setClickable(const AValue: Boolean);
1412     procedure setMinSectionSize(const AValue: Integer);
1413   protected
CreateWidgetnull1414     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1415   public
1416     procedure AttachEvents; override;
1417     procedure DetachEvents; override;
EventFilternull1418     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1419     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1420     procedure SignalSectionClicked(logicalIndex: Integer); cdecl;
getResizeModenull1421     function getResizeMode(AIndex: Integer): QHeaderViewResizeMode;
1422     procedure setResizeMode(AResizeMode: QHeaderViewResizeMode); overload;
1423     procedure setResizeMode(AIndex: Integer; AResizeMode: QHeaderViewResizeMode); overload;
sectionSizenull1424     function sectionSize(AIndex: Integer): Integer;
sectionSizeHintnull1425     function sectionSizeHint(AIndex: Integer): Integer;
1426     procedure moveSection(AFromIndex: Integer; AToIndex: Integer);
1427     procedure resizeSection(ASection: Integer; ASize: Integer);
1428     procedure setHighlightSections(AValue: Boolean);
1429     procedure setDefaultSectionSize(AValue: Integer);
SortIndicatorOrdernull1430     function SortIndicatorOrder: QtSortOrder;
1431     procedure SetSortIndicator(const AColumn: Integer; const AOrder: QtSortOrder);
1432     procedure SetSortIndicatorVisible(AVisible: Boolean);
1433     procedure setStretchLastSection(AValue: Boolean);
1434     property Clickable: Boolean read getClickable write setClickable;
1435     property MinSectionSize: Integer read getMinSectionSize write setMinSectionSize;
1436   end;
1437 
1438   { TQtTreeView }
1439 
1440   TQtTreeView = class (TQtAbstractItemView)
1441   private
getColVisiblenull1442     function getColVisible(AIndex: Integer): Boolean;
getColWidthnull1443     function getColWidth(AIndex: Integer): Integer;
GetUniformRowHeightsnull1444     function GetUniformRowHeights: Boolean;
1445     procedure setColVisible(AIndex: Integer; const AValue: Boolean);
1446     procedure setColWidth(AIndex: Integer; const AValue: Integer);
1447     procedure SetUniformRowHeights(const AValue: Boolean);
1448   protected
CreateWidgetnull1449     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1450   public
1451     procedure setAllColumnsShowFocus(AValue: Boolean);
1452     procedure setWordWrap(const AValue: Boolean); override;
1453     procedure setRootIsDecorated(AValue: Boolean);
1454     property ColWidth[AIndex: Integer]: Integer read getColWidth write setColWidth;
1455     property ColVisible[AIndex: Integer]: Boolean read getColVisible write setColVisible;
1456     property UniformRowHeights: Boolean read GetUniformRowHeights write SetUniformRowHeights;
1457   end;
1458 
1459   { TQtTreeWidget }
1460 
1461   TQtTreeWidget = class(TQtTreeView)
1462   private
1463     FSelection: TFPList;
1464     FHeader: TQtHeaderView;
1465     {$IFDEF TEST_QT_SORTING}
1466     FCanSort: Boolean; // it can sort items only when LCL says so !
1467     FSorting: Boolean;
1468     FSortChanged: QHeaderView_hookH;
1469     {$ENDIF}
1470     FItemActivatedHook: QTreeWidget_hookH;
1471     FItemEnteredHook: QTreeWidget_hookH;
1472     FSelectionChangedHook: QTreeWidget_hookH;
1473     FDelayedCheckItem: QTreeWidgetItemH;
1474 
1475     procedure HandleCheckChangedEvent(const AMousePos: TQtPoint;
1476         AItem: QTreeWidgetItemH; AEvent: QEventH);
1477 
GetItemLastCheckStateInternalnull1478     function GetItemLastCheckStateInternal(AItem: QTreeWidgetItemH): QtCheckState;
1479     procedure SetItemLastCheckStateInternal(AItem: QTreeWidgetItemH; AState: QtCheckState);
1480 
getColCountnull1481     function getColCount: Integer;
getHeadernull1482     function getHeader: TQtHeaderView;
GetItemCheckednull1483     function GetItemChecked(AIndex: Integer): Boolean;
getItemCountnull1484     function getItemCount: Integer;
getMaxColSizenull1485     function getMaxColSize(ACol: Integer): Integer;
getMinColSizenull1486     function getMinColSize(ACol: Integer): Integer;
getSortEnablednull1487     function getSortEnabled: Boolean;
1488     procedure setColCount(const AValue: Integer);
1489     procedure SetItemChecked(AIndex: Integer; AValue: Boolean);
1490     procedure setItemCount(const AValue: Integer);
1491     procedure setMaxColSize(ACol: Integer; const AValue: Integer);
1492     procedure setMinColSize(ACol: Integer; const AValue: Integer);
1493     procedure setSortEnabled(const AValue: Boolean);
1494   protected
CreateWidgetnull1495     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1496     procedure OwnerDataNeeded(ARect: TRect); override;
1497   public
1498     destructor Destroy; override;
1499     procedure DestroyNotify(AWidget: TQtWidget); override;
EventFilternull1500     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
itemViewViewportEventFilternull1501     function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1502     procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; override;
1503     procedure ClearItems;
1504     procedure clearSelection; override;
1505     procedure DeleteItem(const AIndex: integer);
currentRownull1506     function currentRow: Integer;
1507     procedure setCurrentRow(row: Integer);
currentItemnull1508     function currentItem: QTreeWidgetItemH;
1509     procedure setCurrentItem(AItem: QTreeWidgetItemH);
1510 
getRownull1511     function getRow(AItem: QTreeWidgetItemH): integer;
headerItemnull1512     function headerItem: QTreeWidgetItemH;
itemAtnull1513     function itemAt(APoint: TPoint): QTreeWidgetItemH; overload;
itemAtnull1514     function itemAt(x: Integer; y: Integer): QTreeWidgetItemH; overload;
1515     procedure insertTopLevelItem(AIndex: Integer; AItem: QTreeWidgetItemH);
takeTopLevelItemnull1516     function takeTopLevelItem(AIndex: Integer): QTreeWidgetItemH;
topLevelItemnull1517     function topLevelItem(AIndex: Integer): QTreeWidgetItemH;
visualItemRectnull1518     function visualItemRect(AItem: QTreeWidgetItemH): TRect;
getHeaderHeightnull1519     function getHeaderHeight(out AOrientation: QtOrientation): Integer;
getItemVisiblenull1520     function getItemVisible(AItem: QTreeWidgetItemH): Boolean;
getTopItemnull1521     function getTopItem: integer; override;
getVisibleRowCountnull1522     function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; override;
1523     procedure setItemVisible(AItem: QTreeWidgetItemH; Const AVisible: Boolean);
1524     procedure setItemText(AItem: QTreeWidgetItemH; const AColumn: Integer;
1525       const AText: WideString; const AAlignment: QtAlignment);
1526     procedure setItemData(AItem: QTreeWidgetItemH; const AColumn: Integer;
1527        Data: Pointer; const ARole: Integer = Ord(QtUserRole));
selCountnull1528     function selCount: Integer;
selectedItemsnull1529     function selectedItems: TPtrIntArray;
1530     procedure setHeaderVisible(AVisible: Boolean);
1531     procedure setItemSelected(AItem: QTreeWidgetItemH; ASelect: Boolean);
1532     procedure setStretchLastSection(AValue: Boolean);
1533     procedure scrollToItem(Item: QTreeWidgetItemH; hint: QAbstractItemViewScrollHint);
1534     {$IFDEF TEST_QT_SORTING}
1535     // direct Qt sorting via QtUserData ptr = our TListItem, crashes sometimes - qt bug.
1536     procedure sortItems(Acolumn: Integer; AOrder: QtSortOrder);
1537     {$ENDIF}
1538   public
1539     procedure AttachEvents; override;
1540     procedure DetachEvents; override;
1541     procedure ExchangeItems(const AIndex1, AIndex2: Integer);
1542     procedure MoveItem(const AFromIndex, AToIndex: Integer);
getClientBoundsnull1543     function getClientBounds: TRect; override;
getClientOffsetnull1544     function getClientOffset: TPoint; override;
1545 
1546     procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); override;
1547     procedure SignalItemActivated(item: QTreeWidgetItemH; column: Integer); cdecl;
1548     procedure SignalItemEntered(item: QTreeWidgetItemH; column: Integer); cdecl;
1549     procedure SignalCurrentItemChanged(current: QTreeWidgetItemH; previous: QTreeWidgetItemH); cdecl;
1550     procedure SignalSelectionChanged(); cdecl;
1551     {$IFDEF TEST_QT_SORTING}
1552     procedure SignalSortIndicatorChanged(ALogicalIndex: Integer; AOrder: QtSortOrder); cdecl;
1553     property CanSort: Boolean read FCanSort write FCanSort;
1554     {$ENDIF}
1555     property ColCount: Integer read getColCount write setColCount;
1556     property Header: TQtHeaderView read getHeader;
1557     property ItemChecked[AIndex: Integer]: Boolean read GetItemChecked write SetItemChecked;
1558     property ItemCount: Integer read getItemCount write setItemCount;
1559     property MaxColSize[ACol: Integer]: Integer read getMaxColSize write setMaxColSize;
1560     property MinColSize[ACol: Integer]: Integer read getMinColSize write setMinColSize;
1561     property SortEnabled: Boolean read getSortEnabled write setSortEnabled;
1562     {$IFDEF TEST_QT_SORTING}
1563     property Sorting: Boolean read FSorting write FSorting;
1564     {$ENDIF}
1565   end;
1566 
1567   {TQtTableView}
1568 
1569   TQtTableView = class(TQtAbstractItemView)
1570   private
1571     FVerticalHeader: TQtHeaderView;
1572     FHorizontalHeader: TQtHeaderView;
1573   public
verticalHeadernull1574     function verticalHeader: TQtHeaderView;
horizontalHeadernull1575     function horizontalHeader: TQtHeaderView;
CreateWidgetnull1576     function CreateWidget(const Params: TCreateParams): QWidgetH; override;
getViewPortnull1577     function getViewPort: QWidgetH;
getClientBoundsnull1578     function getClientBounds: TRect; override;
1579     procedure grabMouse; override;
1580     procedure setVisible(AVisible: Boolean); override;
getGridStylenull1581     function getGridStyle: QtPenStyle;
1582     procedure setGridStyle(ANewStyle: QtPenStyle);
1583   public
1584     destructor Destroy; override;
1585   end;
1586 
1587   { TQtMenu }
1588 
1589   TQtMenu = class(TQtWidget)
1590   private
1591     FLastTick: QWord; // issue #22872
1592     FActions: TFPList;
1593     FIcon: QIconH;
1594     FTriggeredHook: QAction_hookH;
1595     FHoveredHook: QAction_hookH;
1596     FAboutToShowHook: QMenu_hookH;
1597     FAboutToHideHook: QMenu_hookH;
1598     FActionEventFilter: QObject_hookH;
1599     FActionHandle: QActionH;
1600     FMenuItem: TMenuItem;
1601     FTrackButton: QtMouseButtons;
1602     procedure setActionGroups(AItem: TMenuItem);
1603   protected
CreateWidgetnull1604     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1605     procedure DoPopupClose;
1606   public
1607     constructor Create(const AMenuItem: TMenuItem); overload;
1608     destructor Destroy; override;
1609     procedure InitializeWidget; override;
1610   public
1611     procedure AttachEvents; override;
1612     procedure DetachEvents; override;
1613 
1614     procedure SlotHovered; cdecl;
1615     procedure SlotAboutToShow; cdecl;
1616     procedure SlotAboutToHide; cdecl;
1617     procedure SlotDestroy; cdecl;
1618     procedure SlotTriggered(checked: Boolean = False); cdecl;
ActionEventFilternull1619     function ActionEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
EventFilternull1620     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1621   public
actionHandlenull1622     function actionHandle: QActionH;
addMenunull1623     function addMenu(AMenu: QMenuH): QActionH;
insertMenunull1624     function insertMenu(AIndex: Integer; AMenu: QMenuH; AItem: TMenuItem): QActionH;
getHasSubMenunull1625     function getHasSubMenu: boolean;
getTextnull1626     function getText: WideString; override;
getVisiblenull1627     function getVisible: Boolean; override;
MenuItemEnablednull1628     function MenuItemEnabled: boolean;
1629     procedure PopUp(pos: PQtPoint; at: QActionH = nil);
1630     procedure Exec(pos: PQtPoint; at: QActionH = nil);
1631     procedure removeActionGroup;
1632     procedure setChecked(p1: Boolean);
1633     procedure setCheckable(p1: Boolean);
1634     procedure setHasSubmenu(AValue: Boolean);
1635     procedure setIcon(AIcon: QIconH);
1636     procedure setImage(AImage: TQtImage);
1637     procedure setSeparator(AValue: Boolean);
1638     procedure setShortcut(AShortCutK1, AShortCutK2: TShortcut);
1639     procedure setText(const W: WideString); override;
1640     procedure setVisible(AVisible: Boolean); override;
1641     property trackButton: QtMouseButton read FTrackButton write FTrackButton;
1642   end;
1643 
1644   { TQtMenuBar }
1645 
1646   TQtMenuBar = class(TQtWidget)
1647   private
1648     {$IFNDEF DARWIN}
1649     FCatchNextResizeEvent: Boolean; {needed during design time}
1650     FNumOfActions: PtrInt;
1651     {$ENDIF}
1652     FVisible: Boolean;
1653     FHeight: Integer;
1654     FIsApplicationMainMenu: Boolean;
1655   public
1656     constructor Create(const AParent: QWidgetH); overload;
1657   public
1658     {$IFNDEF DARWIN}
IsDesigningnull1659     function IsDesigning: Boolean;
1660     {$ENDIF}
EventFilternull1661     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
addMenunull1662     function addMenu(AMenu: QMenuH): QActionH;
insertMenunull1663     function insertMenu(AIndex: Integer; AMenu: QMenuH): QActionH;
getGeometrynull1664     function getGeometry: TRect; override;
1665   end;
1666 
1667   { TQtProgressBar }
1668 
1669   TQtProgressBar = class(TQtWidget)
1670   private
1671     FValueChangedHook: QProgressBar_hookH;
1672   protected
CreateWidgetnull1673     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1674   public
1675     procedure AttachEvents; override;
1676     procedure DetachEvents; override;
1677     procedure SignalValueChanged(Value: Integer); cdecl;
1678     procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
1679   public
1680     procedure reset;
1681     procedure setRange(minimum: Integer; maximum: Integer);
1682     procedure setTextVisible(visible: Boolean);
1683     procedure setAlignment(const AAlignment: QtAlignment);
1684     procedure setTextDirection(textDirection: QProgressBarDirection);
1685     procedure setValue(value: Integer);
1686     procedure setOrientation(p1: QtOrientation);
1687     procedure setInvertedAppearance(invert: Boolean);
1688   end;
1689 
1690   { TQtStatusBarPanel }
1691 
1692   TQtStatusBarPanel = class(TQtFrame)
1693   private
1694     FId: Integer;
1695     procedure DrawItem(Sender: QObjectH; Event: QEventH);
1696   protected
CreateWidgetnull1697     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1698   public
EventFilternull1699     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1700     property ID: Integer read FId write FId;
1701   end;
1702 
1703   { TQtStatusBar }
1704 
1705   TQtStatusBar = class(TQtWidget)
1706   protected
CreateWidgetnull1707     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1708   public
1709     Panels: array of TQtStatusBarPanel;
1710     procedure setColor(const Value: PQColor); override;
1711     procedure showMessage(text: PWideString; timeout: Integer = 0);
1712     procedure addWidget(AWidget: QWidgetH; AStretch: Integer = 0);
1713     procedure removeWidget(AWidget: QWidgetH);
isSizeGripEnablednull1714     function isSizeGripEnabled: Boolean;
1715     procedure setSizeGripEnabled(const Value: Boolean);
SlotMousenull1716     function SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; override; cdecl;
1717   end;
1718 
1719   { TQtDialog }
1720 
1721   TQtDialog = class(TQtWidget)
1722   private
1723     FDialogEventHook: QObject_hookH;
1724   protected
1725     FDialog: TCommonDialog;
CreateWidgetnull1726     function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; virtual; overload;
1727   public
1728     constructor Create(ADialog: TCommonDialog; parent: QWidgetH = nil; f: QtWindowFlags = 0); overload;
1729     procedure AttachEvents; override;
1730     procedure DetachEvents; override;
DeliverMessagenull1731     function DeliverMessage(var Msg; const AIsInputEvent: Boolean = False): LRESULT; override;
SlotClosenull1732     function SlotClose: Boolean; cdecl; override;
1733   public
EventFilternull1734     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
execnull1735     function exec: Integer;
1736     procedure setSizeGripEnabled(const AEnabled: Boolean);
1737   end;
1738 
1739   { TQtFileDialog }
1740 
1741   TQtFileDialog = class(TQtDialog)
1742   private
1743     {$ifndef QT_NATIVE_DIALOGS}
1744     FBackBtn: QWidgetH;
1745     FForwardBtn: QWidgetH;
1746     FUpBtn: QWidgetH;
1747     FFileNameEdit: QWidgetH;
1748     FComboType: QWidgetH;
1749     FComboHistory: QWidgetH;
1750     FSideView: QWidgetH;
1751     FTreeView: QWidgetH;
1752     FListView: QWidgetH;
1753     FTreeViewEventFilter: QObject_hookH;
1754     FListViewEventFilter: QObject_hookH;
1755     FSideViewEventFilter: QObject_hookH;
1756     FFileNameEditEventFilter: QObject_hookH;
1757     FComboTypeEventFilter: QObject_hookH;
1758     FComboHistoryEventFilter: QObject_hookH;
1759     {$endif}
1760     FCurrentChangedHook: QFileDialog_hookH;
1761     FDirecotyEnteredHook: QFileDialog_hookH;
1762     FFilterSelectedHook: QFileDialog_hookH;
1763   protected
CreateWidgetnull1764     function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; override;
1765   public
1766     procedure AttachEvents; override;
1767     procedure DetachEvents; override;
1768     {$ifndef QT_NATIVE_DIALOGS}
EventFilternull1769     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1770     {$endif}
1771     procedure CurrentChangedEvent(path: PWideString); cdecl; virtual;
1772     procedure FilterSelectedEvent(filter: PWideString); cdecl;
1773     procedure DirectoryEnteredEvent(directory: PWideString); cdecl;
1774   public
1775     procedure getFilters(const retval: QStringListH);
selectFilenull1776     function selectFile: WideString;
1777     procedure selectedFiles(retval: QStringListH);
1778     procedure setAcceptMode(const AMode: QFileDialogAcceptMode);
1779     procedure setConfirmOverwrite(const AValue: Boolean);
1780     procedure setDirectory(const ADirectory: WideString);
1781     procedure setHistory(AList: TStrings);
1782     procedure setFileMode(const AMode: QFileDialogFileMode);
1783     procedure setFilter(const AFilter: WideString);
1784     procedure setLabelText(const ALabel: QFileDialogDialogLabel; const AText: WideString);
1785     procedure setReadOnly(const AReadOnly: Boolean);
1786     procedure setSelectedFilter(const ASelFilter: WideString);
1787     procedure setViewMode(const AMode: QFileDialogViewMode);
1788     {$ifndef QT_NATIVE_DIALOGS}
1789     procedure setShortcuts(const AIsOpenDialog: Boolean);
1790     {$endif}
1791   end;
1792 
1793   { TQtFilePreviewDialog }
1794 
1795   TQtFilePreviewDialog = class(TQtFileDialog)
1796   private
1797     {$ifndef QT_NATIVE_DIALOGS}
1798     FTextWidget: QLabelH;
1799     FPreviewWidget: QLabelH;
1800     {$ENDIF}
1801   protected
CreateWidgetnull1802     function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; override;
1803   public
1804     {$ifndef QT_NATIVE_DIALOGS}
1805     procedure initializePreview(const APreviewControl: TWinControl);
1806     procedure CurrentChangedEvent(path: PWideString); cdecl; override;
1807     property PreviewWidget: QLabelH read FPreviewWidget;
1808     property TextWidget: QLabelH read FTextWidget;
1809     {$ENDIF}
1810   end;
1811 
1812   { TQtMessageBox }
1813 
1814   TQtMessageBox = class(TQtWidget)
1815   private
1816     FMBEventHook: QObject_hookH;
1817     FTitle: WideString;
getDetailTextnull1818     function getDetailText: WideString;
getMessageStrnull1819     function getMessageStr: WideString;
getMsgBoxTypenull1820     function getMsgBoxType: QMessageBoxIcon;
1821     procedure setDetailText(const AValue: WideString);
1822     procedure setMessageStr(const AValue: WideString);
1823     procedure setMsgBoxType(const AValue: QMessageBoxIcon);
1824     procedure setTitle(const AValue: WideString);
1825   protected
CreateWidgetnull1826     function CreateWidget(AParent: QWidgetH):QWidgetH; overload;
1827   public
1828     constructor Create(AParent: QWidgetH); overload;
1829     procedure AttachEvents; override;
1830     procedure DetachEvents; override;
EventFilternull1831     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1832   public
AddButtonnull1833     function AddButton(ACaption: WideString; ABtnType: QMessageBoxStandardButton; AResult: Int64;
1834       const ADefaultBtn: Boolean; const AEscapeBtn: Boolean = False): QPushButtonH; overload;
AddButtonnull1835     function AddButton(ACaption: WideString; AResult: Int64;
1836       const ADefaultBtn: Boolean; const AEscapeBtn: Boolean = False): QPushButtonH;
1837     procedure SetButtonProps(ABtn: QPushButtonH; AResult: Int64; const ADefaultBtn: Boolean;
1838       const AEscapeBtn: Boolean);
execnull1839     function exec: Int64;
1840     property DetailText: WideString read getDetailText write setDetailText;
1841     property MessageStr: WideString read getMessageStr write setMessageStr;
1842     property MsgBoxType:QMessageBoxIcon read getMsgBoxType write setMsgBoxType;
1843     property Title: WideString read FTitle write setTitle;
1844   end;
1845 
1846   { TQtCalendar }
1847 
1848   TQtCalendar = class(TQtWidget)
1849   private
1850     FMouseDoubleClicked: Boolean;
1851     FCalViewportEventHook: QObject_hookH;
1852     FCalViewAreaEventHook: QObject_hookH;
1853     FClickedHook: QCalendarWidget_hookH;
1854     FActivatedHook: QCalendarWidget_hookH;
1855     FSelectionChangedHook: QCalendarWidget_hookH;
1856     FCurrentPageChangedHook: QCalendarWidget_hookH;
DeliverDayChangednull1857     function DeliverDayChanged(ADate: QDateH): boolean;
GetDateTimenull1858     function GetDateTime: TDateTime;
1859     procedure SetDateTime(const AValue: TDateTime);
1860     procedure SetSelectedDate(const AValue: QDateH);
1861   protected
CreateWidgetnull1862     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1863   public
1864     AYear, AMonth, ADay: Word;
1865     procedure AttachEvents; override;
1866     procedure DetachEvents; override;
EventFilternull1867     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
AreaViewEventFilternull1868     function AreaViewEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
calViewportEventFilternull1869     function calViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
HitTestnull1870     function HitTest(const APoint: TPoint): byte;
1871     procedure SetDisplaySettings(
1872       const AHHdrFmt: QCalendarWidgetHorizontalHeaderFormat;
1873       const AVHdrFmt: QCalendarWidgetVerticalHeaderFormat;
1874       const ASelMode: QCalendarWidgetSelectionMode;
1875       const ANavBarVisible: Boolean; const AGridVisible: Boolean;
1876       const AStartMonday: Boolean
1877       );
1878     procedure SignalActivated(ADate: QDateH); cdecl;
1879     procedure SignalClicked(ADate: QDateH); cdecl;
1880     procedure SignalSelectionChanged; cdecl;
1881     procedure SignalCurrentPageChanged(p1, p2: Integer); cdecl;
1882     property DateTime: TDateTime read GetDateTime write SetDateTime;
1883   end;
1884 
1885   // for page control / notebook
1886 
1887   { TQtPage }
1888 
1889   TQtPage = class(TQtWidget)
1890   protected
1891     FIcon: QIconH;
CreateWidgetnull1892     function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
1893   public
EventFilternull1894     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
getIconnull1895     function getIcon: QIconH;
getIndexnull1896     function getIndex(const ATextChanging: Boolean = False): Integer;
getTabWidgetnull1897     function getTabWidget: QTabWidgetH;
1898     procedure setIcon(const AIcon: QIconH);
1899     procedure setText(const W: WideString); override;
1900   end;
1901 
1902   { TQtRubberBand }
1903 
1904   TQtRubberBand = class(TQtWidget)
1905   private
1906     FShape: QRubberBandShape;
1907   protected
CreateWidgetnull1908     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1909   public
1910     constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); override;
1911 
1912     // QRubberBand have it's own move,resize and setGeometry
1913     procedure move(ANewLeft, ANewTop: Integer); override;
1914     procedure Resize(ANewWidth, ANewHeight: Integer); override;
1915     procedure setGeometry(ARect: TRect); override;
1916 
1917     function getShape: QRubberBandShape;
1918     procedure setShape(AShape: QRubberBandShape);
1919   end;
1920 
1921   { TQtDesignWidget }
1922 
1923   TQtDesignWidget = class(TQtMainWindow)
1924   protected
1925     FDesignControlEventHook: QObject_hookH;
1926     FDesignControl: QWidgetH;
1927     FDesignContext: HDC;
1928     function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
1929     procedure DestroyWidget; override;
1930     procedure SlotDesignControlPaint(Sender: QObjectH; Event: QEventH); cdecl;
1931     procedure BringDesignerToFront;
1932     procedure ResizeDesigner;
1933     function GetContext: HDC; override;
1934   public
1935     function DesignControlEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
1936     function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
1937 
1938     procedure AttachEvents; override;
1939     procedure DetachEvents; override;
1940 
1941     procedure lowerWidget; override;
1942     procedure raiseWidget; override;
1943   public
1944     property DesignContext: HDC read FDesignContext;
1945   end;
1946 
1947 const
1948   AlignmentMap: array[TAlignment] of QtAlignment =
1949   (
1950 {taLeftJustify } QtAlignLeft,
1951 {taRightJustify} QtAlignRight,
1952 {taCenter      } QtAlignHCenter
1953   );
1954 
1955   QtCheckStateRole = Ord(QtUserRole) + 1;
1956   QtListViewOwnerDataRole = Ord(QtUserRole) + 2;
1957 implementation
1958 
1959 uses
1960   Buttons,
1961   math,
1962   qtCaret,
1963   qtproc,
1964   qtprivate,
1965   WSControls
1966   {$IFDEF HASX11}
1967   ,keysym
1968   {$ENDIF}
1969   ;
1970 
1971 const
1972   Forbid_TCN_SELCHANGE = -3;
1973   Allow_TCN_SELCHANGE = -2;
1974 
1975 type
1976   TWinControlAccess = class(TWinControl)
1977   end;
1978   TCustomListViewAccess = class(TCustomListView);
1979 
1980 var
1981   LastMouse: TLastMouseInfo;
1982 
1983 { TQtWidget }
1984 
1985 {------------------------------------------------------------------------------
1986   Function: TQtWidget.Create
1987   Params:  None
1988   Returns: Nothing
1989  ------------------------------------------------------------------------------}
1990 constructor TQtWidget.Create(const AWinControl: TWinControl; const AParams: TCreateParams);
1991 begin
1992   inherited Create;
1993   FOwner := nil;
1994   FCentralWidget := nil;
1995   FOwnWidget := True;
1996   // Initializes the properties
1997   FProps := nil;
1998   LCLObject := AWinControl;
1999   FKeysToEat := [VK_TAB, VK_RETURN, VK_ESCAPE];
2000   FHasPaint := False;
2001 
2002   FParams := AParams;
2003   InitializeWidget;
2004 end;
2005 
2006 constructor TQtWidget.CreateFrom(const AWinControl: TWinControl;
2007   AWidget: QWidgetH);
2008 begin
2009   inherited Create;
2010 
2011   FOwner := nil;
2012   FOwnWidget := False;
2013   FCentralWidget := nil;
2014   // Initializes the properties
2015   FProps := niL;
2016   LCLObject := AWinControl;
2017   FKeysToEat := [VK_TAB, VK_RETURN, VK_ESCAPE];
2018 
2019   // Creates the widget
2020   Widget := AWidget;
2021 
2022   FDefaultCursor := QCursor_create();
2023   QWidget_cursor(Widget, FDefaultCursor);
2024   FWidgetLCLFont := nil;
2025   FWidgetDefaultFont := TQtFont.Create(QWidget_font(AWidget));
2026 
2027   // set Handle->QWidget map
2028   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
2029   FillChar(FPaintData, sizeOf(FPaintData), 0);
2030 
2031   QtWidgetSet.AddHandle(Self);
2032   // set focus policy
2033   if (LCLObject <> nil) and not (Self is TQtMainWindow) then
2034     setFocusPolicy(QtClickFocus);
2035 
2036   // Set mouse move messages policy
2037   QWidget_setMouseTracking(Widget, True);
2038 end;
2039 
2040 procedure TQtWidget.InitializeWidget;
2041 begin
2042   {$IFDEF QtUseAccurateFrame}
2043   FFrameMargins := Rect(0, 0, 0, 0);
2044   {$ENDIF}
2045   FInResizeEvent := False;
2046   // default states
2047   FWidgetState := [];
2048   // default color roles
2049   FWidgetNeedFontColorInitialization := False;
2050   SetDefaultColorRoles;
2051   FPalette := nil;
2052   FHasCaret := False;
2053   FLastCaretPos := QtPoint(-1, -1);
2054   ChildOfComplexWidget := ccwNone;
2055   // creates the widget
2056   Widget := CreateWidget(FParams);
2057 
2058   // retrieve default cursor on create
2059   FDefaultCursor := QCursor_create();
2060   QWidget_cursor(Widget, FDefaultCursor);
2061 
2062   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
2063   FWidgetLCLFont := nil;
2064 
2065 
2066   // apply initial position and size
2067   move(FParams.X, FParams.Y);
2068   if GetContainerWidget <> Widget then
2069     QWidget_resize(GetContainerWidget, FParams.Width, FParams.Height);
2070 
2071   {$IFDEF QTUSEACCURATEFRAME}
2072   if IsFramedWidget then
2073   begin
2074     {$IFDEF DEBUGQTUSEACCURATEFRAME}
2075     DebugLn(Format('TQtWidget.InitializeWidget: proposed width %d height %d',[FParams.Width, FParams.Height]),' WSFrame=',dbgs(QtWidgetSet.WSFrameMargins),' FFrame=',dbgs(FFrameMargins));
2076     {$ENDIF}
2077     if (QtWidgetSet.WSFrameMargins.Top > 0) then
2078       FFrameMargins := QtWidgetSet.WSFrameMargins;
2079   end;
2080   {$ENDIF}
2081   Resize(FParams.Width, FParams.Height);
2082 
2083   FScrollX := 0;
2084   FScrollY := 0;
2085 
2086   {$ifdef VerboseQt}
2087   DebugLn('TQtWidget.InitializeWidget: Self:%x Widget:%x was created for control %s',
2088     [PtrUInt(Self), PtrUInt(Widget), LCLObject.Name]);
2089   {$endif}
2090 
2091   // set Handle->QWidget map
2092   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
2093   QtWidgetSet.AddHandle(Self);
2094 
2095   FillChar(FPaintData, sizeOf(FPaintData), 0);
2096 
2097   // Sets it's initial properties
2098 
2099   // set focus policy
2100   if Assigned(LCLObject) then
2101   begin
2102     if (Self is TQtMainWindow) and
2103       (
2104       TQtMainWindow(Self).IsMDIChild or
2105       Assigned(TQtMainWindow(Self).MDIAreaHandle) or
2106        (csNoFocus in LCLObject.ControlStyle)
2107       ) then
2108     begin
2109       if TQtMainWindow(Self).IsMDIChild or
2110         Assigned(TQtMainWindow(Self).MDIAreaHandle) then
2111       begin
2112         QWidget_setFocusPolicy(FCentralWidget, QtNoFocus);
2113       end else
2114       begin
2115         if LCLObject.TabStop then
2116           setFocusPolicy(QtWheelFocus)
2117         else
2118           setFocusPolicy(QtNoFocus);
2119       end;
2120     end else
2121     begin
2122       if (Self is TQtMainWindow) then
2123         setFocusPolicy(QtTabFocus) // issue #28880
2124       else
2125       if (csNoFocus in LCLObject.ControlStyle) then
2126       begin
2127         if LCLObject.TabStop then
2128           setFocusPolicy(QtTabFocus)
2129         else
2130           setFocusPolicy(QtNoFocus);
2131       end else
2132       if (Self is TQtTabWidget) then
2133         setFocusPolicy(QtTabFocus)
2134       else
2135         setFocusPolicy(QtClickFocus);
2136     end;
2137 
2138     if LCLObject.Perform(LM_NCHITTEST, 0, 0)=HTTRANSPARENT then
2139     begin
2140       setAttribute(QtWA_TransparentForMouseEvents);
2141       setWindowFlags(windowFlags or QtWindowTransparentForInput);
2142     end;
2143 
2144     if (csDesigning in LCLObject.ComponentState) and not
2145        (Self is TQtMainWindow) and
2146        HasPaint and
2147        getAutoFillBackground or
2148        ((csDesigning in LCLObject.ComponentState) and
2149         (ClassType = TQtTabWidget)) then
2150       setAutoFillBackground(False);
2151   end;
2152 
2153 
2154   // Set mouse move messages policy
2155   QWidget_setMouseTracking(Widget, True);
2156 
2157   if Assigned(LCLObject) and FWidgetNeedFontColorInitialization then
2158     setInitialFontColor(LCLObject);
2159   if (FParams.Style and WS_VISIBLE) = 0 then
2160     QWidget_hide(Widget)
2161   else
2162     QWidget_show(Widget);
2163 end;
2164 
2165 procedure TQtWidget.DeInitializeWidget;
2166 begin
2167   QtWidgetSet.RemoveHandle(Self);
2168   DetachEvents;
2169 
2170   if Widget <> nil then
2171     removeProperty(Widget, 'lclwidget');
2172 
2173   QCursor_destroy(FDefaultCursor);
2174 
2175   if HasCaret then
2176     DestroyCaret;
2177 
2178   if Assigned(FWidgetDefaultFont) then
2179     FreeThenNil(FWidgetDefaultFont);
2180   if Assigned(FWidgetLCLFont) then
2181     FreeThenNil(FWidgetLCLFont);
2182 
2183   if FPalette <> nil then
2184   begin
2185     FPalette.Free;
2186     FPalette := nil;
2187   end;
2188 
2189   DestroyWidget;
2190 end;
2191 
2192 procedure TQtWidget.RecreateWidget;
2193 var
2194   Parent: QWidgetH;
2195 begin
2196   // update createparams
2197   with getPos do
2198   begin
2199     FParams.X := X;
2200     FParams.Y := Y;
2201   end;
2202   with getSize do
2203   begin
2204     FParams.Width := cx;
2205     FParams.Height := cy;
2206   end;
2207 
2208   if Widget <> nil then
2209     Parent := QWidget_parentWidget(Widget)
2210   else
2211     Parent := nil;
2212   FParams.WndParent := HwndFromWidgetH(Parent);
2213   DeinitializeWidget;
2214   InitializeWidget;
2215 end;
2216 
2217 procedure TQtWidget.DestroyNotify(AWidget: TQtWidget);
2218 begin
2219   if AWidget = FOwner then
2220     FOwner := nil;
2221 end;
2222 
2223 {------------------------------------------------------------------------------
2224   Function: TQtWidget.Destroy
2225   Params:  None
2226   Returns: Nothing
2227  ------------------------------------------------------------------------------}
2228 destructor TQtWidget.Destroy;
2229 begin
2230   DeinitializeWidget;
2231 
2232   if FProps <> nil then
2233   begin
2234     FProps.Free;
2235     FProps:=nil;
2236   end;
2237 
2238   if FPaintData.ClipRegion <> nil then
2239   begin
2240     QRegion_Destroy(FPaintData.ClipRegion);
2241     FPaintData.ClipRegion:=nil;
2242   end;
2243 
2244   if FOwner <> nil then
2245     FOwner.DestroyNotify(Self);
2246 
2247   inherited Destroy;
2248 end;
2249 
2250 {------------------------------------------------------------------------------
2251   Function: TQtWidget.GetContainerWidget
2252   Params:  None
2253   Returns: The widget of the control on top of which other controls
2254            should be placed
2255  ------------------------------------------------------------------------------}
GetContainerWidgetnull2256 function TQtWidget.GetContainerWidget: QWidgetH;
2257 begin
2258   if FCentralWidget <> nil then
2259     Result := FCentralWidget
2260   else
2261     Result := Widget;
2262 end;
2263 
2264 procedure TQtWidget.Release;
2265 begin
2266   LCLObject := nil;
2267   {always hide widget since we use QObject_deleteLater(). issue #27781}
2268   if (Widget <> nil) then
2269     Hide;
2270   inherited Release;
2271 end;
2272 
2273 procedure TQtWidget.Destroyed; cdecl;
2274 begin
2275   Widget := nil;
2276   Release;
2277 end;
2278 
2279 {------------------------------------------------------------------------------
2280   Function: TQtWidget.CanAdjustClientRectOnResize
2281   Params:  None
2282   Returns: Boolean
2283   Checks if our control can call LCLObject.DoAdjustClientRect from SlotResize.
2284   This avoids deadlocks with autosizing.
2285  ------------------------------------------------------------------------------}
CanAdjustClientRectOnResizenull2286 function TQtWidget.CanAdjustClientRectOnResize: Boolean;
2287 begin
2288   Result := True;
2289 end;
2290 
CanChangeFontColornull2291 function TQtWidget.CanChangeFontColor: Boolean;
2292 begin
2293   Result := True;
2294 end;
2295 
2296 {------------------------------------------------------------------------------
2297   Function: TQtWidget.CanSendLCLMessage
2298   Params:  None
2299   Returns: Boolean
2300   If returns FALSE then we should not send any message to LCL since our
2301   LCLObject is probably being destroyed or it has csDestroying flag on.
2302   This is very important to know before calling NotifyApplicationUserInput,
2303   which is often called from mouse & keyboard events.
2304  ------------------------------------------------------------------------------}
CanSendLCLMessagenull2305 function TQtWidget.CanSendLCLMessage: Boolean;
2306 begin
2307   Result := (LCLObject <> nil) and (Widget <> nil) and getVisible and
2308     not ((csDestroying in LCLObject.ComponentState) or
2309          (csDestroyingHandle in LCLObject.ControlState));
2310 end;
2311 
2312 {------------------------------------------------------------------------------
2313   Function: TQtWidget.CanPaintBackground
2314   Params:  None
2315   Returns: Boolean
2316   Makes decision if control background need to be painted.
2317   Look at SlotPaintBg().
2318  ------------------------------------------------------------------------------}
TQtWidget.CanPaintBackgroundnull2319 function TQtWidget.CanPaintBackground: Boolean;
2320 begin
2321   {TODO: we must override this function for some classes
2322    until clDefault is implemented in LCL.Then we can easy
2323    ask EqualTQColor() for diff between
2324    Palette.DefaultColor and current LCLObject.Color}
2325   Result := False;
2326 end;
2327 
2328 procedure TQtWidget.DelayResizeEvent(AWidget: QWidgetH; ANewSize: TSize);
2329 var
2330   ALCLResizeEvent: QLCLMessageEventH;
2331 begin
2332   ALCLResizeEvent := QLCLMessageEvent_create(LCLQt_DelayResizeEvent, 0, PtrUInt(ANewSize.cx), PtrUInt(ANewSize.cy), 0);
2333   QCoreApplication_postEvent(AWidget, ALCLResizeEvent);
2334 end;
2335 
2336 {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtKeys)}
EventTypeToStrnull2337 function EventTypeToStr(Event:QEventH):string;
2338 // Qt 3 events
2339 const
2340   QEventChildInsertedRequest = 67;
2341   QEventChildInserted = 70;
2342   QEventLayoutHint = 72;
2343 begin
2344   case QEvent_type(Event) of
2345     QEventNone: result:='QEventNone';
2346     QEventTimer: result:='QEventTimer';
2347     QEventMouseButtonPress: result:='QEventMouseButtonPress';
2348     QEventMouseButtonRelease: result:='QEventMouseButtonRelease';
2349     QEventMouseButtonDblClick: result:='QEventMouseButtonDblClick';
2350     QEventMouseMove: result:='QEventMouseMove';
2351     QEventKeyPress: result:='QEventKeyPress';
2352     QEventKeyRelease: result:='QEventKeyRelease';
2353     QEventFocusIn: result:='QEventFocusIn';
2354     QEventFocusOut: result:='QEventFocusOut';
2355     QEventEnter: result:='QEventEnter';
2356     QEventLeave: result:='QEventLeave';
2357     QEventPaint: result:='QEventPaint';
2358     QEventMove: result:='QEventMove';
2359     QEventResize: result:='QEventResize';
2360     QEventCreate: result:='QEventCreate';
2361     QEventDestroy: result:='QEventDestroy';
2362     QEventShow: result:='QEventShow';
2363     QEventHide: result:='QEventHide';
2364     QEventClose: result:='QEventClose';
2365     QEventQuit: result:='QEventQuit';
2366     QEventParentChange: result:='QEventParentChange';
2367     QEventThreadChange: result:='QEventThreadChange';
2368     QEventWindowActivate: result:='QEventWindowActivate';
2369     QEventWindowDeactivate: result:='QEventWindowDeactivate';
2370     QEventShowToParent: result:='QEventShowToParent';
2371     QEventHideToParent: result:='QEventHideToParent';
2372     QEventWheel: result:='QEventWheel';
2373     QEventWindowTitleChange: result:='QEventWindowTitleChange';
2374     QEventWindowIconChange: result:='QEventWindowIconChange';
2375     QEventApplicationWindowIconChange: result:='QEventApplicationWindowIconChange';
2376     QEventApplicationFontChange: result:='QEventApplicationFontChange';
2377     QEventApplicationLayoutDirectionChange: result:='QEventApplicationLayoutDirectionChange';
2378     QEventApplicationPaletteChange: result:='QEventApplicationPaletteChange';
2379     QEventPaletteChange: result:='QEventPaletteChange';
2380     QEventClipboard: result:='QEventClipboard';
2381     QEventSpeech: result:='QEventSpeech';
2382     QEventMetaCall: result:='QEventMetaCall';
2383     QEventSockAct: result:='QEventSockAct';
2384     QEventShortcutOverride: result:='QEventShortcutOverride';
2385     QEventDeferredDelete: result:='QEventDeferredDelete';
2386     QEventDragEnter: result:='QEventDragEnter';
2387     QEventDragMove: result:='QEventDragMove';
2388     QEventDragLeave: result:='QEventDragLeave';
2389     QEventDrop: result:='QEventDrop';
2390     QEventDragResponse: result:='QEventDragResponse';
2391     //    QEventChildInsertedRequest: result:='(Qt3) QEventChildAdded'; //qt3
2392     QEventChildAdded: result:='QEventChildAdded';
2393     QEventChildPolished: result:='QEventChildPolished';
2394     //    QEventChildInserted: result:='(Qt3) QEventChildAdded'; // qt3
2395     //    QEventLayoutHint: result:='(Qt3) QEventChildAdded'; // qt3
2396     QEventChildRemoved: result:='QEventChildRemoved';
2397     QEventShowWindowRequest: result:='QEventShowWindowRequest';
2398     QEventPolishRequest: result:='QEventPolishRequest';
2399     QEventPolish: result:='QEventPolish';
2400     QEventLayoutRequest: result:='QEventLayoutRequest';
2401     QEventUpdateRequest: result:='QEventUpdateRequest';
2402     QEventUpdateLater: result:='QEventUpdateLater';
2403     QEventEmbeddingControl: result:='QEventEmbeddingControl';
2404     QEventActivateControl: result:='QEventActivateControl';
2405     QEventDeactivateControl: result:='QEventDeactivateControl';
2406     QEventContextMenu: result:='QEventContextMenu';
2407     QEventInputMethod: result:='QEventInputMethod';
2408     QEventAccessibilityPrepare: result:='QEventAccessibilityPrepare';
2409     QEventTabletMove: result:='QEventTabletMove';
2410     QEventLocaleChange: result:='QEventLocaleChange';
2411     QEventLanguageChange: result:='QEventLanguageChange';
2412     QEventLayoutDirectionChange: result:='QEventLayoutDirectionChange';
2413     QEventStyle: result:='QEventStyle';
2414     QEventTabletPress: result:='QEventTabletPress';
2415     QEventTabletRelease: result:='QEventTabletRelease';
2416     QEventOkRequest: result:='QEventOkRequest';
2417     QEventHelpRequest: result:='QEventHelpRequest';
2418     QEventIconDrag: result:='QEventIconDrag';
2419     QEventFontChange: result:='QEventFontChange';
2420     QEventEnabledChange: result:='QEventEnabledChange';
2421     QEventActivationChange: result:='QEventActivationChange';
2422     QEventStyleChange: result:='QEventStyleChange';
2423     QEventIconTextChange: result:='QEventIconTextChange';
2424     QEventModifiedChange: result:='QEventModifiedChange';
2425     QEventWindowBlocked: result:='QEventWindowBlocked';
2426     QEventWindowUnblocked: result:='QEventWindowUnblocked';
2427     QEventWindowStateChange: result:='QEventWindowStateChange';
2428     QEventMouseTrackingChange: result:='QEventMouseTrackingChange';
2429     QEventToolTip: result:='QEventToolTip';
2430     QEventWhatsThis: result:='QEventWhatsThis';
2431     QEventStatusTip: result:='QEventStatusTip';
2432     QEventActionChanged: result:='QEventActionChanged';
2433     QEventActionAdded: result:='QEventActionAdded';
2434     QEventActionRemoved: result:='QEventActionRemoved';
2435     QEventFileOpen: result:='QEventFileOpen';
2436     QEventShortcut: result:='QEventShortcut';
2437     QEventWhatsThisClicked: result:='QEventWhatsThisClicked';
2438     QEventAccessibilityHelp: result:='QEventAccessibilityHelp';
2439     QEventToolBarChange: result:='QEventToolBarChange';
2440     QEventApplicationActivated: result:='QEventApplicationActivated';
2441     QEventApplicationDeactivated: result:='QEventApplicationDeactivated';
2442     QEventQueryWhatsThis: result:='QEventQueryWhatsThis';
2443     QEventEnterWhatsThisMode: result:='QEventEnterWhatsThisMode';
2444     QEventLeaveWhatsThisMode: result:='QEventLeaveWhatsThisMode';
2445     QEventZOrderChange: result:='QEventZOrderChange';
2446     QEventHoverEnter: result:='QEventHoverEnter';
2447     QEventHoverLeave: result:='QEventHoverLeave';
2448     QEventHoverMove: result:='QEventHoverMove';
2449     QEventAccessibilityDescription: result:='QEventAccessibilityDescription';
2450     QEventParentAboutToChange: result:='QEventParentAboutToChange';
2451     QEventWinEventAct: result:='QEventWinEventAct';
2452     QEventAcceptDropsChange: result:='QEventAcceptDropsChange';
2453     QEventMenubarUpdated: result:='QEventMenubarUpdated';
2454     QEventZeroTimerEvent: result:='QEventZeroTimerEvent';
2455     QEventNonClientAreaMouseMove: result:='QEventNonClientAreaMouseMove';
2456     QEventNonClientAreaMouseButtonPress: result:='QEventNonClientAreaMouseButtonPress';
2457     QEventNonClientAreaMouseButtonRelease: result:='QEventNonClientAreaMouseButtonRelease';
2458     QEventNonClientAreaMouseButtonDblClick: result:='QEventNonClientAreaMouseButtonDblClick';
2459     QEventMacSizeChange: result := 'QEventMacSizeChange';
2460     QEventContentsRectChange: result := 'QEventContentsRectChange';
2461     QEventMacGLWindowChange: result := 'QEventMacGLWindowChange';
2462     QEventFutureCallOut: result := 'QEventFutureCallOut';
2463     QEventGraphicsSceneResize: result := 'QEventGraphicsSceneResize';
2464     QEventGraphicsSceneMove: result := 'QEventGraphicsSceneMove';
2465     QEventCursorChange: result := 'QEventCursorChange';
2466     QEventToolTipChange: result := 'QEventToolTipChange';
2467     QEventNetworkReplyUpdated: result := 'QEventNetworkReplyUpdated';
2468     QEventGrabMouse: result := 'QEventGrabMouse';
2469     QEventUngrabMouse: result := 'QEventUngrabMouse';
2470     QEventGrabKeyboard: result := 'QEventGrabKeyboard';
2471     QEventUngrabKeyboard: result := 'QEventUngrabKeyboard';
2472     QEventCocoaRequestModal: result := 'QEventCocoaRequestModal';
2473     QEventUser: result:='QEventUser';
2474     QEventMaxUser: result:='QEventMaxUser';
2475     200: Result := 'QEventCloseSoftwareInputPanel';
2476     203: Result := 'QEventWinIdChange';
2477   else
2478     Result := Format('Unknown event: %d', [QEvent_type(Event)]);
2479   end;
2480 end;
2481 {$ENDIF}
2482 
2483 {------------------------------------------------------------------------------
2484   Function: TQtWidget.EventFilter
2485   Params:  None
2486   Returns: Nothing
2487  ------------------------------------------------------------------------------}
TQtWidget.EventFilternull2488 function TQtWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
2489 var
2490   {$IFDEF MSWINDOWS}
2491   AContextEvent: QContextMenuEventH;
2492   {$ENDIF}
2493   QColor, OldColor: TQColor;
2494   ColorRef: TColorRef;
2495   QtEdit: IQtEdit;
2496   R: TRect;
2497   Pt: TQtPoint;
2498   ANewSize: TSize;
2499   AResizeEvent: QResizeEventH;
2500 begin
2501   Result := False;
2502   QEvent_accept(Event);
2503 
2504   BeginEventProcessing;
2505   try
2506     {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
2507     WriteLn('TQtWidget.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
2508       ' LCLObject=', dbgsName(LCLObject),
2509       ' Event=', EventTypeToStr(Event),' inUpdate=',InUpdate);
2510     {$endif}
2511 
2512     if LCLObject <> nil then
2513     begin
2514       case QEvent_type(Event) of
2515         LCLQt_DelayResizeEvent:
2516         begin
2517           ANewSize.cx := LongInt(QLCLMessageEvent_getWParam(QLCLMessageEventH(Event)));
2518           ANewSize.cy := LongInt(QLCLMessageEvent_getLParam(QLCLMessageEventH(Event)));
2519           AResizeEvent := QResizeEvent_create(@ANewSize, @ANewSize);
2520           try
2521             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2522             DebugLn('>LCLQt_DelayResizeEvent: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
2523             {$ENDIF}
2524             SlotResize(AResizeEvent);
2525             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2526             DebugLn('<LCLQt_DelayResizeEvent: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
2527             {$ENDIF}
2528           finally
2529             QResizeEvent_destroy(AResizeEvent);
2530           end;
2531           Result := True;
2532         end;
2533         QEventFontChange:
2534           begin
2535             //explanation for this event usage: issue #19695
2536             if not (qtwsFontUpdating in WidgetState) and
2537               not LCLObject.IsParentFont then
2538             begin
2539               if Assigned(FWidgetLCLFont) then
2540                 AssignQtFont(FWidgetLCLFont.FHandle, QWidget_font(QWidgetH(Sender)))
2541               else
2542                 AssignQtFont(FWidgetDefaultFont.FHandle, QWidget_font(QWidgetH(Sender)));
2543             end;
2544           end;
2545         QEventEnabledChange:
2546           begin
2547             // if we are disabled, imediatelly invalidate widgetAt cache
2548             if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
2549               QtWidgetSet.InvalidateWidgetAtCache
2550             else
2551             if QtWidgetSet.IsValidWidgetAtCachePointer then
2552             begin
2553               Pt := QtPoint(0, 0);
2554               QWidget_mapToGlobal(Widget, @Pt, @Pt);
2555               QWidget_geometry(Widget, @R);
2556               R := Rect(Pt.X, Pt.Y, Pt.X + (R.Right - R.Left), Pt.Y + (R.Bottom - R.Top));
2557               if PtInRect(R, QtWidgetSet.GetWidgetAtCachePoint) then
2558                 QtWidgetSet.InvalidateWidgetAtCache;
2559             end;
2560             // issue #25922
2561             if Assigned(FPalette) and Assigned(LCLObject) then
2562             begin
2563               // DebugLn('QEventEnabledChange: ',dbgsName(LCLObject),' enabled ',dbgs(getEnabled));
2564               if not getEnabled then
2565                 Palette.setTextColor(@Palette.DisabledTextColor)
2566               else
2567                 setInitialFontColor(LCLObject);
2568             end;
2569           end;
2570         QEventShow:
2571           begin
2572             SlotShow(True);
2573             {$IFDEF MSWINDOWS}
2574             if (qtwsInsideRightMouseButtonPressEvent in FWidgetState) and
2575                (qtwsHiddenInsideRightMouseButtonPressEvent in FWidgetState) then
2576             begin
2577               Exclude(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
2578               Exclude(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
2579               if (LastMouse.WinControl = LCLObject) and
2580                 (QGUIApplication_mouseButtons and QtRightButton <> 0) then
2581               begin
2582                 Pt := QtPoint(LastMouse.MousePos.X, LastMouse.MousePos.Y);
2583                 AContextEvent := QContextMenuEvent_create(QContextMenuEventMouse, @Pt);
2584                 QCoreApplication_postEvent(Sender, AContextEvent);
2585                 LastMouse.MousePos := Point(Pt.X, Pt.Y);
2586               end;
2587             end;
2588             {$ENDIF}
2589           end;
2590         QEventHide:
2591           begin
2592             if QWidget_mouseGrabber() = Widget then
2593               ReleaseCapture;
2594             SlotShow(False);
2595             {$IFDEF MSWINDOWS}
2596             if qtwsInsideRightMouseButtonPressEvent in FWidgetState then
2597               Include(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
2598             {$ENDIF}
2599           end;
2600         QEventClose:
2601           if not SlotClose then
2602           begin
2603             QEvent_ignore(Event);
2604             Result := True;
2605           end;
2606         QEventDestroy: SlotDestroy;
2607         QEventEnter,
2608         QEventLeave: Result := SlotMouseEnter(Sender, Event);
2609 
2610         QEventHoverEnter,
2611         QEventHoverLeave,
2612         QEventHoverMove: Result := SlotHover(Sender, Event);
2613 
2614         QEventDrop,
2615         QEventDragMove,
2616         QEventDragEnter:
2617         begin
2618           Result := getAcceptDropFiles;
2619           if (Result) and (QEvent_type(Event) = QEventDrop) then
2620             Result := slotDropFiles(Sender, Event);
2621         end;
2622 
2623         QEventKeyPress,
2624         QEventKeyRelease:
2625           begin
2626             {non-spontaneous key events are garbage in Qt >= 4.4 for non edits}
2627             Result := QEvent_spontaneous(Event) or Supports(Self, IQtEdit, QtEdit);
2628             if Result then
2629               Result := SlotKey(Sender, Event) or
2630                 ((LCLObject <> nil) and (LCLObject is TCustomControl));
2631           end;
2632 
2633         //Dead keys (used to compose chars like "ó" by pressing 'o)  do not trigger EventKeyPress
2634         //and therefore no KeyDown,Utf8KeyPress,KeyPress
2635         QEventInputMethod:
2636           begin
2637             Result := SlotInputMethod(Sender, Event);
2638           end;
2639 
2640         QEventMouseButtonPress,
2641         QEventMouseButtonRelease,
2642         QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
2643         QEventMouseMove: Result := SlotMouseMove(Sender, Event);
2644         QEventWheel:
2645           begin
2646             if not getEnabled then
2647             begin
2648               QEvent_ignore(Event);
2649               QWidget_setAttribute(QWidgetH(Sender), QtWA_NoMousePropagation, False);
2650             end else
2651               Result := SlotMouseWheel(Sender, Event);
2652           end;
2653         QEventMove: SlotMove(Event);
2654         QEventResize: SlotResize(Event);
2655         QEventContentsRectChange:
2656         begin
2657           if ChildOfComplexWidget = ccwScrollingWinControl then
2658           begin
2659             // Result := (caspComputingBounds in LCLObject.AutoSizePhases);
2660             QEvent_ignore(Event);
2661           end;
2662           if LCLObject.ClientRectNeedsInterfaceUpdate then
2663           begin
2664             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
2665             if ChildOfComplexWidget = ccwScrollingWinControl then
2666             begin
2667               if Self is TQtViewport then
2668                 QWidget_rect(Widget, @R)
2669               else
2670                 QWidget_rect(TQtAbstractScrollArea(Self).viewportWidget, @R);
2671               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)));
2672             end else
2673               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));
2674             {$ENDIF}
2675             if not (caspComputingBounds in LCLObject.AutoSizePhases) then
2676             begin
2677               {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2678               DebugLn('  QEventContentsRectChange(',dbgsName(LCLObject),' call DoAdjustClientRectChange !');
2679               {$ENDIF}
2680               if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
2681               else
2682                 LCLObject.DoAdjustClientRectChange(True);
2683             end else
2684             begin
2685               {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
2686               DebugLn('  QEventContentsRectChange(',dbgsName(LCLObject),' call InvalidatePrefferedSize !');
2687               {$ENDIF}
2688               if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
2689               else
2690                 LCLObject.InvalidatePreferredSize;
2691             end;
2692           end;
2693         end;
2694         QEventPaint:
2695           begin
2696             if canPaintBackground and (LCLObject.Color <> clDefault) then
2697               SlotPaintBg(Sender, Event);
2698             if FHasPaint then
2699               SlotPaint(Sender, Event);
2700           end;
2701         QEventContextMenu:
2702             Result := SlotContextMenu(Sender, Event);
2703         QEventNonClientAreaMouseButtonPress:
2704           begin
2705             SlotNCMouse(Sender, Event);
2706           end;
2707         QEventPaletteChange,
2708         QEventStyleChange:
2709           begin
2710             if (FPalette <> nil) and not InUpdate and not Palette.InReload then
2711             begin
2712               OldColor := Palette.CurrentColor;
2713               // now set our fpalette ColorRef from LCL
2714               if LCLObject.Color <> clDefault then
2715               begin
2716                 ColorRef := ColorToRGB(LCLObject.Color);
2717                 QColor_fromRgb(@QColor,Red(ColorRef),Green(ColorRef),Blue(ColorRef));
2718               end else
2719                 QColor := Palette.DefaultColor;
2720               if not EqualTQColor(OldColor, QColor) then
2721               begin
2722                 Palette.ReloadPaletteBegin;
2723                 try
2724                   SetColor(@QColor);
2725                   Result := True;
2726                   QEvent_accept(Event);
2727                 finally
2728                   Palette.ReloadPaletteEnd;
2729                 end;
2730               end;
2731             end;
2732           end;
2733         QEventQueryWhatsThis: Result := True;
2734         QEventWhatsThis:
2735           begin
2736             SlotWhatsThis(Sender, Event);
2737             // TODO: we need to stop event by Result := True; but then we also need
2738             // to ask qt to leave Whats This mode. Currently we have no means to do so
2739           end;
2740         QEventLCLMessage:
2741           begin
2742             SlotLCLMessage(Sender, Event);
2743             Result := True;
2744           end;
2745       else
2746         QEvent_ignore(Event);
2747       end;
2748     end
2749     else
2750       QEvent_ignore(Event);
2751 
2752     {fixes #14544 and others when we loose our LCLObject
2753      after delivering message to LCL.}
2754     if (LCLObject = nil) and
2755        ((QEvent_type(Event) = QEventMouseButtonPress) or
2756        (QEvent_type(Event) = QEventMouseButtonRelease) or
2757        (QEvent_type(Event) = QEventMouseButtonDblClick) or
2758        (QEvent_type(Event) = QEventMouseMove) or
2759        (QEvent_type(Event) = QEventHoverEnter) or
2760        (QEvent_type(Event) = QEventHoverLeave) or
2761        (QEvent_type(Event) = QEventHoverMove) or
2762        (QEvent_type(Event) = QEventKeyPress) or
2763        (QEvent_type(Event) = QEventKeyRelease)) then
2764       Result := True;
2765   finally
2766     EndEventProcessing;
2767   end;
2768 end;
2769 
getAcceptDropFilesnull2770 function TQtWidget.getAcceptDropFiles: Boolean;
2771 var
2772   Form: TCustomForm;
2773 begin
2774   Result := False;
2775   Form := GetParentForm(LCLObject);
2776   if Assigned(Form) and (Form.HandleAllocated) then
2777     Result := TQtMainWindow(Form.Handle).getAcceptDropFiles;
2778 end;
2779 
measureTextnull2780 function TQtWidget.measureText(AText: WideString; AFlags: cardinal): TRect;
2781 var
2782   AMetrics: QFontMetricsH;
2783   AFont: QFontH;
2784 begin
2785   Result := Rect(0, 0, 0, 0);
2786   if Assigned(LCLObject) and Assigned(LCLObject.Font) and
2787     LCLObject.Font.HandleAllocated then
2788       AFont := TQtFont(LCLObject.Font.Reference.Handle).FHandle
2789   else
2790     AFont := QWidget_font(Widget);
2791   AMetrics := QFontMetrics_create(AFont);
2792   try
2793     QFontMetrics_boundingRect(AMetrics, @Result, @AText);
2794   finally
2795     QFontMetrics_destroy(AMetrics);
2796   end;
2797 end;
2798 
2799 procedure TQtWidget.SetNoMousePropagation(Sender: QWidgetH;
2800   const ANoMousePropagation: Boolean);
2801 begin
2802   QWidget_setAttribute(Sender, QtWA_NoMousePropagation, ANoMousePropagation);
2803 end;
2804 
2805 {------------------------------------------------------------------------------
2806   Function: TQtWidget.SetLCLFont
2807   Params:  None
2808   Returns: Nothing
2809   Sets FWidgetLCLFont , font which is different from FWidgetDefaultFont
2810   so we can keep track over it inside QEventFontChange.
2811   This routine does nothing if called outside of TQtWSControl.SetFont,
2812   since qtwdFontUpdating must be in WidgetState
2813  ------------------------------------------------------------------------------}
2814 procedure TQtWidget.SetLCLFont(AFont: TQtFont);
2815 begin
2816   if not (qtwsFontUpdating in FWidgetState) then
2817     exit;
2818   if Assigned(FWidgetLCLFont) then
2819     FreeThenNil(FWidgetLCLFont);
2820   if not IsFontEqual(FWidgetDefaultFont, AFont) and (AFont.FHandle <> nil) then
2821     FWidgetLCLFont := TQtFont.Create(AFont.FHandle);
2822 end;
2823 
2824 {------------------------------------------------------------------------------
2825   Function: TQtWidget.SlotShow
2826   Params:  None
2827   Returns: Nothing
2828  ------------------------------------------------------------------------------}
2829 procedure TQtWidget.SlotShow(vShow: Boolean); cdecl;
2830 var
2831   Msg: TLMShowWindow;
2832 begin
2833   {$ifdef VerboseQt}
2834     WriteLn('TQtWidget.SlotShow Name', LCLObject.Name, ' vShow: ', dbgs(vShow));
2835   {$endif}
2836 
2837   {do not pass message to LCL if LCL setted up control visibility}
2838   if inUpdate then
2839     exit;
2840 
2841   FillChar(Msg{%H-}, SizeOf(Msg), #0);
2842 
2843   Msg.Msg := LM_SHOWWINDOW;
2844   Msg.Show := vShow;
2845 
2846   DeliverMessage(Msg);
2847 end;
2848 
2849 {------------------------------------------------------------------------------
2850   Function: TQtWidget.Close
2851   Params:  None
2852   Returns: Nothing
2853 
2854   Note: LCL uses LM_CLOSEQUERY to set the form visibility and if we don�t send this
2855  message, you won�t be able to show a form twice.
2856  ------------------------------------------------------------------------------}
SlotClosenull2857 function TQtWidget.SlotClose: Boolean; cdecl;
2858 var
2859   Msg : TLMessage;
2860 begin
2861   {$ifdef VerboseQt}
2862     WriteLn('TQtWidget.SlotClose');
2863   {$endif}
2864   FillChar(Msg{%H-}, SizeOf(Msg), 0);
2865 
2866   Msg.Msg := LM_CLOSEQUERY;
2867 
2868   DeliverMessage(Msg);
2869 
2870   Result := False;
2871 end;
2872 
2873 {------------------------------------------------------------------------------
2874   Function: TQtWidget.SlotDestroy
2875   Params:  None
2876   Returns: Nothing
2877 
2878   Currently commented because it was raising exception on software exit
2879  ------------------------------------------------------------------------------}
2880 procedure TQtWidget.SlotDestroy; cdecl;
2881 var
2882   Msg: TLMessage;
2883 begin
2884   {$ifdef VerboseQt}
2885     WriteLn('TQtWidget.SlotDestroy');
2886   {$endif}
2887 
2888   FillChar(Msg{%H-}, SizeOf(Msg), #0);
2889   Msg.Msg := LM_DESTROY;
2890   DeliverMessage(Msg);
2891   Release;
2892 end;
2893 
slotDropFilesnull2894 function TQtWidget.slotDropFiles(Sender: QObjectH; Event: QEventH): Boolean;
2895 var
2896   MimeData: QMimeDataH;
2897   QStrList: QStringListH;
2898   ByteArr: QByteArrayH;
2899   i: Integer;
2900   WStr: WideString;
2901   GotFiles: Boolean;
2902   FilesList: TStrings;
2903   Files: Array of String;
2904   ParentForm: TCustomForm;
2905   Url: QUrlH;
2906 begin
2907   Result := False;
2908   GotFiles := False;
2909   MimeData := QDropEvent_mimeData(QDropEventH(Event));
2910   QStrList := QStringList_create();
2911   try
2912     QMimeData_formats(MimeData, QStrList);
2913     for i := QStringList_size(QStrList) - 1 downto 0 do
2914     begin
2915       QStringList_at(QStrList, @WStr, i);
2916       GotFiles := (WStr = 'text/plain') or (WStr = 'text/uri-list');
2917       if GotFiles then
2918         break;
2919     end;
2920   finally
2921     QStringList_destroy(QStrList);
2922   end;
2923   if not GotFiles then
2924     exit;
2925   ByteArr := QByteArray_create();
2926   try
2927     QMimeData_data(MimeData, ByteArr, @WStr);
2928     if not QByteArray_isNull(ByteArr) then
2929     begin
2930       WStr := QByteArray_constData(ByteArr);
2931       FilesList := TStringList.Create;
2932       try
2933         FilesList.Text := UTF16ToUTF8(WStr);
2934 
2935         if (FilesList.Count > 0) and
2936           ( (FilesList[FilesList.Count-1] = #0)
2937             or
2938             (FilesList[FilesList.Count-1] = '') ) then
2939           SetLength(Files, FilesList.Count - 1)
2940         else
2941           SetLength(Files, FilesList.Count);
2942         for i := 0 to High(Files) do
2943         begin
2944           WStr := GetUTF8String(FilesList.Strings[i]);
2945           Url := QUrl_create(@WStr);
2946           QUrl_toLocalFile(Url, @WStr);
2947           Files[i] := UTF16ToUTF8(WStr);
2948           QUrl_destroy(Url);
2949         end;
2950       finally
2951         FilesList.Free;
2952       end;
2953       QDropEvent_setDropAction(QDropEventH(Event), QtCopyAction);
2954       QDropEvent_acceptProposedAction(QDropEventH(Event));
2955 
2956       Application.IntfDropFiles(Files);
2957       if ClassType = TQtMainWindow then
2958         TCustomForm(LCLObject).IntfDropFiles(Files)
2959       else
2960       begin
2961         ParentForm := TCustomForm(LCLObject.IntfGetDropFilesTarget);
2962         if ParentForm is TCustomForm then
2963           ParentForm.IntfDropFiles(Files);
2964       end;
2965 
2966       Result := True;
2967     end;
2968   finally
2969     QByteArray_destroy(ByteArr);
2970   end;
2971 end;
2972 
SlotHovernull2973 function TQtWidget.SlotHover(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
2974 var
2975   Msg: TLMessage;
2976   MouseMsg: TLMMouseMove absolute Msg;
2977   MousePos: TQtPoint;
2978 begin
2979   Result := False;
2980   if not CanSendLCLMessage then
2981     Exit(True);
2982 
2983   if (QGUIApplication_mouseButtons() = 0) and
2984      not QWidget_hasMouseTracking(QWidgetH(Sender)) then // in other case MouseMove will be hooked
2985   begin
2986     FillChar(Msg{%H-}, SizeOf(Msg), #0);
2987 
2988     // MousePos :=
2989     QHoverEvent_pos(QHoverEventH(Event), @MousePos);
2990     OffsetMousePos(@MousePos);
2991 
2992     case QEvent_type(Event) of
2993       QEventHoverEnter: Msg.Msg := LM_MOUSEENTER;
2994       QEventHoverLeave: Msg.Msg := LM_MOUSELEAVE;
2995       QEventHoverMove:
2996         begin
2997           MouseMsg.Msg := LM_MOUSEMOVE;
2998           MouseMsg.XPos := SmallInt(MousePos.X);
2999           MouseMsg.YPos := SmallInt(MousePos.Y);
3000         end;
3001     end;
3002     NotifyApplicationUserInput(LCLObject, Msg.Msg);
3003     if not CanSendLCLMessage then
3004       exit(True);
3005     DeliverMessage(Msg);
3006     SetNoMousePropagation(QWidgetH(Sender), True);
3007   end;
3008 end;
3009 
3010 {------------------------------------------------------------------------------
3011   Function: TQtWidget.SlotKey
3012   Params:  None
3013   Returns: Nothing
3014  ------------------------------------------------------------------------------}
SlotKeynull3015 function TQtWidget.SlotKey(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3016 const
3017   CN_KeyDownMsgs: array[Boolean] of UINT = (CN_KEYDOWN, CN_SYSKEYDOWN);
3018   CN_KeyUpMsgs: array[Boolean] of UINT = (CN_KEYUP, CN_SYSKEYUP);
3019   LM_KeyDownMsgs: array[Boolean] of UINT = (LM_KEYDOWN, LM_SYSKEYDOWN);
3020   LM_KeyUpMsgs: array[Boolean] of UINT = (LM_KEYUP, LM_SYSKEYUP);
3021   CN_CharMsg: array[Boolean] of UINT = (CN_CHAR, CN_SYSCHAR);
3022   LM_CharMsg: array[Boolean] of UINT = (LM_CHAR, LM_SYSCHAR);
3023 var
3024   KeyMsg: TLMKey;
3025   CharMsg: TLMChar;
3026   Modifiers: QtKeyboardModifiers;
3027   IsSysKey: Boolean;
3028   Text: WideString;
3029   UTF8Text: String; // use to prevent 3 time convertion from WideString to utf8 string
3030   UTF8Char: TUTF8Char;
3031   ACharCode: Word;
3032   AKeyCode: Word;
3033   LCLModifiers: Word;
3034   {$IFDEF UNIX}
3035   ScanCode: LongWord;
3036   {$ENDIF}
3037   AChar: Char;
3038   AKeyEvent: QKeyEventH;
3039   GlobalAction: Integer;
3040   {$IFDEF VerboseQtKeys}
3041   s: String;
3042   s1: String;
3043   NativeModifiers: LongWord;
3044   {$ENDIF}
3045 
3046   function IsControlKey: Boolean;
3047   var
3048     AQtKey: Cardinal;
3049   begin
3050     // do not send UTF8KeyPress for control keys
3051     AQtKey := QKeyEvent_key(QKeyEventH(Event));
3052 
3053     // Enter, Return and Backspace should be sent to LCL in UTF8KeyPress,
3054     // so skip them here
3055 
3056     Result :=
3057       ((AQtKey >= QtKey_Escape) and (AQtKey <= QtKey_Backtab)) or
3058       ((AQtKey >= QtKey_Insert) and (AQtKey <= QtKey_Clear)) or
3059       ((AQtKey >= QtKey_Home) and (AQtKey <= QtKey_PageDown)) or
3060       ((AQtKey >= QtKey_F1) and (AQtKey <= QtKey_Direction_L)) or
3061       (AQtKey = QtKey_Direction_R);
3062   end;
3063 
3064   function EatArrowKeys: Boolean;
3065   var
3066     AQtKey: Cardinal;
3067   begin
3068     AQtKey := QKeyEvent_key(QKeyEventH(Event));
3069     Result := not ProcessArrowKeys and ((AQtKey = QtKey_Left) or (AQtKey = QtKey_Right)
3070       or (AQtKey = QtKey_Up) or (AQtKey = QtKey_Down));
3071   end;
3072 
3073   function SendChangedKey: boolean;
3074   begin
3075     if UTF8Char <> UTF8Text then
3076       Text := UTF8ToUTF16(Utf8Char)
3077     else
3078     if Word(AChar) <> CharMsg.CharCode then
3079       Text := Char(CharMsg.CharCode);
3080 
3081     AKeyEvent := QKeyEvent_create( {ExtendedKeyEvent(}
3082       QEvent_type(Event),
3083       LCLKeyToQtKey(KeyMsg.CharCode),
3084       Modifiers,
3085       0,
3086       KeyMsg.CharCode,
3087       0,
3088       @Text,
3089       QKeyEvent_isAutoRepeat(QKeyEventH(Event)),
3090       QKeyEvent_count(QKeyEventH(Event))
3091       );
3092     try
3093       Result := QObject_event(Sender, AKeyEvent);
3094     finally
3095       QKeyEvent_destroy(AKeyEvent);
3096     end;
3097 
3098   end;
3099 
3100 begin
3101   {$ifdef VerboseQt}
3102     DebugLn('TQtWidget.SlotKey ', dbgsname(LCLObject));
3103   {$endif}
3104 
3105   Result := True;
3106 
3107   if not CanSendLCLMessage then
3108     exit;
3109 
3110   FillChar(KeyMsg{%H-}, SizeOf(KeyMsg), #0);
3111   FillChar(CharMsg{%H-}, SizeOf(CharMsg), #0);
3112   UTF8Text := '';
3113   UTF8Char := '';
3114   AChar := #0;
3115 
3116   // Detects special keys (shift, alt, control, etc)
3117   Modifiers := QKeyEvent_modifiers(QKeyEventH(Event));
3118   {$IFDEF HASX11}
3119   //qt reports WRONG combination under X11 sometimes when Shift + LeftAlt
3120   //are pressed, so we must fix modifiers, ssMeta will be reported in keys.
3121   if (QtShiftModifier and Modifiers <> 0) and (QtMetaModifier and Modifiers <> 0) then
3122   begin
3123     if (QtAltModifier and Modifiers = 0) and
3124       (QKeyEvent_nativeVirtualKey(QKeyEventH(Event)) = XK_Meta_L) then
3125         Modifiers := (Modifiers and not QtMetaModifier) or QtAltModifier;
3126   end;
3127   {$ENDIF}
3128   IsSysKey := (QtAltModifier and Modifiers) <> $0;
3129 
3130   AKeyCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
3131 
3132   LCLModifiers := QtKeyModifiersToKeyState(Modifiers, True, QKeyEventH(Event));
3133 
3134   if QKeyEvent_isAutoRepeat(QKeyEventH(Event)) then
3135     LCLModifiers := LCLModifiers or KF_REPEAT;
3136 
3137   if QEvent_type(Event) = QEventKeyRelease then
3138     LCLModifiers := LCLModifiers or KF_UP;
3139 
3140   {$ifdef windows}
3141   ACharCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
3142   KeyMsg.CharCode := ACharCode;
3143   if (Modifiers = QtAltModifier or QtControlModifier) then
3144   begin
3145     if (QtWidgetSet.GetWinKeyState(VK_RMENU) < 0) and
3146       (QtWidgetSet.GetWinKeyState(VK_LCONTROL) < 0) then
3147     begin
3148       IsSysKey := False;
3149       LCLModifiers := 0;
3150       Modifiers := QtGroupSwitchModifier;
3151 
3152       if QKeyEvent_isAutoRepeat(QKeyEventH(Event)) then
3153         LCLModifiers := LCLModifiers or KF_REPEAT;
3154 
3155       if QEvent_type(Event) = QEventKeyRelease then
3156         LCLModifiers := LCLModifiers or KF_UP;
3157     end;
3158   end;
3159   {$endif}
3160   KeyMsg.KeyData := PtrInt((AKeyCode shl 16) or (LCLModifiers shl 16) or $0001);
3161 
3162   // Loads the UTF-8 character associated with the keypress, if any
3163   QKeyEvent_text(QKeyEventH(Event), @Text);
3164 
3165   {$IFDEF DARWIN}
3166   // qt on mac passes #3 instead of #13 when QtKey_Enter (numpad) is pressed
3167   // so our keypress get wrong about key. issue #20896
3168   if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Enter) and (length(Text) = 1) then
3169     Text := #13;
3170 
3171   ScanCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
3172   {$IFDEF VerboseQtKeys}
3173   // ScanCode := QKeyEvent_key(QKeyEventH(Event));
3174   writeln('!!!**** NATIVEVIRTUALKEY=',ScanCode,' lenText=',length(Text),' Modifiers ',Modifiers,' AKEYCODE=',AKeyCode);
3175   {$ENDIF}
3176 
3177   // set groupswitch for Shift+Option.
3178   if (length(Text) = 1) and
3179     ((Modifiers = QtAltModifier or QtShiftModifier) or ((Modifiers = QtAltModifier) and (ScanCode > 0))) then
3180   begin
3181     ScanCode := QKeyEvent_key(QKeyEventH(Event));
3182     // Arrow keys are reserved by macOSX keyboard commands
3183     // http://support.apple.com/kb/ht1343
3184     if (ScanCode <> QtKey_Left) and (ScanCode <> QtKey_Up) and
3185       (ScanCode <> QtKey_Right) and (ScanCode <> QtKey_Down) then
3186     begin
3187       Modifiers := QtGroupSwitchModifier;
3188       LCLModifiers := QtKeyModifiersToKeyState(Modifiers, True, QKeyEventH(Event));
3189       KeyMsg.KeyData := PtrInt((LCLModifiers shl 16) or $0001);
3190       IsSysKey := False; // was true above
3191     end;
3192     ScanCode := 0;
3193   end;
3194   {$ENDIF}
3195 
3196   {$IFDEF VerboseQtKeys}
3197   writeln('> TQtWidget.SlotKey dump begin event=',EventTypeToStr(Event),' IsSysKey ',IsSysKey);
3198 
3199   S := '';
3200   if Modifiers and QtShiftModifier <> 0 then
3201     S := 'SHIFT,';
3202   if Modifiers and QtControlModifier <> 0 then
3203     S := S + 'CONTROL,';
3204 
3205   if Modifiers and QtAltModifier <> 0 then
3206     S := S + 'ALT,';
3207 
3208   if Modifiers and QtMetaModifier <> 0 then
3209     S := S + 'META,';
3210 
3211   if Modifiers and QtKeypadModifier <> 0 then
3212     S := S + 'KEYPAD,';
3213 
3214   if Modifiers and QtGroupSwitchModifier <> 0 then
3215     S := S + 'GROUPSWITCH,';
3216 
3217   if Modifiers and QtKeyboardModifierMask <> 0 then
3218     S := S + 'KEYBOARDMODIFIERMASK,';
3219 
3220   if S <> '' then
3221     Delete(S, length(S), 1)
3222   else
3223     S := 'NONE';
3224 
3225 
3226   NativeModifiers := QKeyEvent_NativeModifiers(QKeyEventH(Event));
3227   S1 := '';
3228 
3229   if NativeModifiers and QtShiftModifier <> 0 then
3230     S1 := 'SHIFT,';
3231   if NativeModifiers and QtControlModifier <> 0 then
3232     S1 := S1 + 'CONTROL,';
3233 
3234   if NativeModifiers and QtAltModifier <> 0 then
3235     S1 := S1 + 'ALT,';
3236 
3237   if NativeModifiers and QtMetaModifier <> 0 then
3238     S1 := S1 + 'META,';
3239 
3240   if NativeModifiers and QtKeypadModifier <> 0 then
3241     S1 := S1 + 'KEYPAD,';
3242 
3243   if NativeModifiers and QtGroupSwitchModifier <> 0 then
3244     S1 := S1 + 'GROUPSWITCH,';
3245 
3246   if NativeModifiers and QtKeyboardModifierMask <> 0 then
3247     S1 := S1 + 'KEYBOARDMODIFIERMASK,';
3248 
3249   if S1 <> '' then
3250     Delete(S1, length(S1), 1)
3251   else
3252     S1 := 'NONE';
3253 
3254   writeln(' KEY=',QKeyEvent_key(QKeyEventH(Event)),' COUNT=',
3255     QKeyEvent_count(QKeyEventH(Event)),' TEXT=',Text);
3256   writeln(' LCLKEY=',QtKeyToLCLKey(QKeyEvent_key(QKeyEventH(Event)), Text,
3257     QKeyEventH(Event)),' SPONTANEOUS ', QEvent_spontaneous(Event));
3258   writeln(' MODIFIERS: ',S,' NATIVEMODIFIERS: ',S1);
3259   writeln(' HASEXTENDEDINFO: ',QKeyEvent_hasExtendedInfo(QKeyEventH(Event)),
3260     ' ISAUTOREPEAT: ',QKeyEvent_isAutoRepeat(QKeyEventH(Event)));
3261   writeln(' NATIVESCANCODE: ',QKeyEvent_nativeScanCode(QKeyEventH(Event)),
3262     ' NATIVEVIRTUALKEY: ',QKeyEvent_nativeVirtualKey(QKeyEventH(Event)));
3263 
3264   writeln('Key compression ? ',
3265     QWidget_testAttribute(QWidgetH(Sender), QtWA_KeyCompression));
3266   writeln('< TQtWidget.SlotKey dump end event=',EventTypeToStr(Event));
3267   {$ENDIF}
3268 
3269   {we must intercept modifiers for main form menu (if any). issue #18709}
3270   if (Modifiers = QtAltModifier) then
3271   begin
3272     if (QApplication_activeModalWidget() = nil) and
3273       (QEvent_type(Event) <> QEventKeyRelease) and
3274       QtWidgetSet.ShortcutInGlobalActions('Alt+'+Text, GlobalAction) then
3275     begin
3276       QtWidgetSet.TriggerGlobalAction(GlobalAction);
3277       exit;
3278     end;
3279   end;
3280 
3281   {$note TQtWidget.SlotKey: this is workaround for Qt bug which reports
3282    wrong keys with Shift+Ctrl pressed. Fixes #13470.
3283    LAST REVISION: Qt-4.7.4 20111023 fc14. zeljko}
3284   {$IFDEF UNIX}
3285   {$IFDEF DARWIN}
3286   // under darwin we must use nativeVirtualKey since nativeScanCode
3287   // isn't returned under carbon and cocoa.
3288   if (QtVersionMajor = 5) and (QtVersionMinor >= 2) and
3289     (Modifiers = QtShiftModifier or QtControlModifier) then
3290   begin
3291     ScanCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
3292     if (length(Text) = 1) and (ScanCode in [10,18..23,25,26,28,29]) then
3293     begin
3294       if ScanCode = 10 then
3295         ScanCode := VK_UNDEFINED
3296       else
3297       if ScanCode in [18..21] then
3298         ScanCode := ScanCode + 31
3299       else
3300       if ScanCode = 23 then
3301         ScanCode := 53
3302       else
3303       if ScanCode = 22 then
3304         ScanCode := 54
3305       else
3306       if ScanCode = 26 then
3307         ScanCode := 55
3308       else
3309       if ScanCode = 28 then
3310         ScanCode := 56
3311       else
3312       if ScanCode = 25 then
3313         ScanCode := 57
3314       else
3315       if ScanCode = 29 then
3316         ScanCode := 48;
3317 
3318       KeyMsg.CharCode := Word(ScanCode);
3319       if (Modifiers = QtShiftModifier or QtControlModifier) then
3320         Text := '';
3321     end;
3322   end;
3323   {$ELSE}
3324   if (Modifiers = QtShiftModifier or QtControlModifier) or
3325     (Modifiers = QtShiftModifier) then
3326   begin
3327     ScanCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
3328     if (length(Text) = 1) and (ScanCode in [10..19]) then
3329     begin
3330       if ScanCode = 19 then
3331         ScanCode := 48
3332       else
3333         ScanCode := ScanCode + 39;
3334       KeyMsg.CharCode := Word(ScanCode);
3335       if (Modifiers = QtShiftModifier or QtControlModifier) then
3336         Text := '';
3337     end;
3338   end else
3339   if (Modifiers = QtShiftModifier or QtAltModifier) then
3340   begin
3341     ScanCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
3342     if (length(Text) = 1) and (ScanCode in [10..19]) then
3343     begin
3344       if ScanCode = 19 then
3345         ScanCode := 48
3346       else
3347         ScanCode := ScanCode + 39;
3348       KeyMsg.CharCode := Word(ScanCode);
3349       if (Modifiers = QtShiftModifier or QtAltModifier) then
3350         Text := '';
3351     end;
3352   end;
3353   {$ENDIF}
3354   {$ENDIF}
3355 
3356   // Translates a Qt4 Key to a LCL VK_* key
3357   if KeyMsg.CharCode = 0 then
3358   begin
3359     ACharCode := QtKeyToLCLKey(QKeyEvent_key(QKeyEventH(Event)), Text, QKeyEventH(Event));
3360     KeyMsg.CharCode := ACharCode;
3361   end;
3362 
3363   {------------------------------------------------------------------------------
3364    Sends the adequate key messages
3365    ------------------------------------------------------------------------------}
3366   case QEvent_type(Event) of
3367     QEventKeyPress: KeyMsg.Msg := CN_KeyDownMsgs[IsSysKey];
3368     QEventKeyRelease: KeyMsg.Msg := CN_KeyUpMsgs[IsSysKey];
3369   end;
3370 
3371   {$ifdef VerboseQt}
3372   WriteLn(' message CN_Keys: ', KeyMsg.Msg);
3373   {$endif}
3374   if KeyMsg.CharCode <> VK_UNKNOWN then
3375   begin
3376     NotifyApplicationUserInput(LCLObject, KeyMsg.Msg);
3377 
3378     if not CanSendLCLMessage or (Sender = nil) then
3379       exit;
3380 
3381     if (DeliverMessage(KeyMsg, True) <> 0) or (KeyMsg.CharCode=VK_UNKNOWN) then
3382     begin
3383   {$ifdef VerboseQt}
3384       WriteLn('handled CN_Keys');
3385   {$endif}
3386       Exit;
3387     end;
3388 
3389     if not CanSendLCLMessage or (Sender = nil) then
3390       exit;
3391 
3392     // here we should let widgetset to handle key
3393     //...
3394     case QEvent_type(Event) of
3395       QEventKeyPress: KeyMsg.Msg := LM_KeyDownMsgs[IsSysKey];
3396       QEventKeyRelease: KeyMsg.Msg := LM_KeyUpMsgs[IsSysKey];
3397     end;
3398     {$ifdef VerboseQt}
3399     WriteLn(' message LM_Keys: ', KeyMsg.Msg);
3400     {$endif}
3401     if not EatArrowKeys then
3402     begin
3403       NotifyApplicationUserInput(LCLObject, KeyMsg.Msg);
3404 
3405       if not CanSendLCLMessage or (Sender = nil) then
3406         exit;
3407 
3408       if (DeliverMessage(KeyMsg, True) <> 0) or (KeyMsg.CharCode=VK_UNKNOWN) then
3409       begin
3410         // the LCL handled the key
3411         {$ifdef VerboseQt}
3412         WriteLn('handled LM_Keys');
3413         {$endif}
3414         Result := KeyMsg.CharCode=VK_UNKNOWN;
3415         Exit;
3416       end;
3417     end;
3418   end;
3419 
3420   { if our LCLObject dissappeared in the meantime just exit, otherwise
3421     we'll run into problems.}
3422   if not CanSendLCLMessage or (Sender = nil) then
3423     exit;
3424 
3425 
3426   { Also sends a utf-8 key event for key down }
3427   if (QEvent_type(Event) = QEventKeyPress) and (Length(Text) <> 0) then
3428   begin
3429     UTF8Text := UTF16ToUTF8(Text);
3430     UTF8Char := UTF8Text;
3431     {$ifdef VerboseQt}
3432     WriteLn('sending char ', UTF8Char);
3433     {$endif}
3434     if not IsControlKey and LCLObject.IntfUTF8KeyPress(UTF8Char, 1, IsSysKey) then
3435     begin
3436       // the LCL has handled the key
3437       {$ifdef VerboseQt}
3438       WriteLn('handled!');
3439       {$endif}
3440       Exit;
3441     end;
3442 
3443     if not CanSendLCLMessage or (Sender = nil) then
3444       exit;
3445 
3446     if (UTF8Char <> UTF8Text) then
3447     begin
3448       // process changed key and exit.
3449       // issue #26103
3450       SendChangedKey;
3451       exit;
3452     end;
3453 
3454     // create the CN_CHAR / CN_SYSCHAR message
3455     FillChar(CharMsg, SizeOf(CharMsg), 0);
3456     CharMsg.Msg := CN_CharMsg[IsSysKey];
3457     CharMsg.KeyData := KeyMsg.KeyData;
3458     AChar := Text[1];
3459     CharMsg.CharCode := Word(AChar);
3460 
3461     //Send message to LCL
3462     {$ifdef VerboseQt}
3463     WriteLn(' message: ', CharMsg.Msg);
3464     {$endif}
3465     NotifyApplicationUserInput(LCLObject, CharMsg.Msg);
3466 
3467     if not CanSendLCLMessage or (Sender = nil) then
3468       exit;
3469 
3470     if (DeliverMessage(CharMsg, True) <> 0) or (CharMsg.CharCode = VK_UNKNOWN) then
3471     begin
3472       // the LCL has handled the key
3473       {$ifdef VerboseQt}
3474       WriteLn('handled!');
3475       {$endif}
3476       Exit;
3477     end;
3478 
3479     //Here is where we (interface) can do something with the key
3480     //...
3481 
3482     //Send a LM_(SYS)CHAR
3483     CharMsg.Msg := LM_CharMsg[IsSysKey];
3484 
3485     {$ifdef VerboseQt}
3486     WriteLn(' message: ', CharMsg.Msg);
3487     {$endif}
3488     if not CanSendLCLMessage or (Sender = nil) then
3489       exit;
3490 
3491     NotifyApplicationUserInput(LCLObject, CharMsg.Msg);
3492 
3493     if not CanSendLCLMessage or (Sender = nil) then
3494       exit;
3495 
3496     DeliverMessage(CharMsg, True);
3497     if not CanSendLCLMessage or (Sender = nil) then
3498       exit;
3499   end;
3500 
3501   // check if data was changed during key handling
3502   if CanSendLCLMessage and (Sender <> nil) and
3503     ((KeyMsg.CharCode <> ACharCode) or (UTF8Char <> UTF8Text) or
3504       (Word(AChar) <> CharMsg.CharCode)) then
3505   begin
3506     // data was changed
3507     // moved to nested proc because of issue #26103
3508     SendChangedKey;
3509   end else
3510   begin
3511     Result := KeyMsg.CharCode in KeysToEat;
3512   end;
3513 end;
3514 
TQtWidget.SlotInputMethodnull3515 function TQtWidget.SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3516 var
3517   InputEvent: QInputMethodEventH;
3518   WStr: WideString;
3519   UnicodeChar: Cardinal;
3520   UnicodeOutLen: integer;
3521   KeyEvent: QKeyEventH;
3522 begin
3523   Result := True;
3524   if not (QEvent_type(Event) = QEventInputMethod) then Exit;
3525   {$ifdef VerboseQt}
3526     DebugLn('TQtWidget.SlotInputMethod ', dbgsname(LCLObject));
3527   {$endif}
3528   InputEvent := QInputMethodEventH(Event);
3529   QInputMethodEvent_commitString(InputEvent, @WStr);
3530   UnicodeChar := UTF8CodepointToUnicode(PChar(WStr), UnicodeOutLen);
3531   {$IFDEF VerboseQtKeys}
3532   writeln('> TQtWidget.SlotInputMethod ',dbgsname(LCLObject),' event=QEventInputMethod:');
3533   writeln('   commmitString ',WStr,' len ',length(WStr),' UnicodeChar ',UnicodeChar,
3534     ' UnicodeLen ',UnicodeOutLen);
3535   writeln('   sending QEventKeyPress');
3536   {$ENDIF}
3537 
3538   KeyEvent := QKeyEvent_create(QEventKeyPress, PtrInt(UnicodeChar), QGUIApplication_keyboardModifiers, @WStr, False, 1);
3539   try
3540     // do not send it to queue, just pass it to SlotKey
3541     Result := SlotKey(Sender, KeyEvent);
3542   finally
3543     QKeyEvent_destroy(KeyEvent);
3544   end;
3545   {$IFDEF VerboseQtKeys}
3546   writeln('< TQtWidget.SlotInputMethod End: ',dbgsname(LCLObject),' event=QEventInputMethod, sent QEventKeyPress');
3547   {$ENDIF}
3548 end;
3549 
3550 {------------------------------------------------------------------------------
3551   Function: TQtWidget.SlotMouse
3552   Params:  None
3553   Returns: Nothing
3554  ------------------------------------------------------------------------------}
TQtWidget.SlotMousenull3555 function TQtWidget.SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3556 var
3557   Msg: TLMMouse;
3558   MousePos: TQtPoint;
3559   MButton: QTMouseButton;
3560   Modifiers: QtKeyboardModifiers;
3561   SaveWidget: QWidgetH;
3562   LazButton: Byte;
3563   LazPos: TPoint;
3564 begin
3565   {$ifdef VerboseQt}
3566   WriteLn('TQtWidget.SlotMouse ',DbgSName(Self));
3567   {$endif}
3568 
3569   Result := False; // allow qt to handle message
3570 
3571   if not CanSendLCLMessage then
3572     exit(True);
3573 
3574   if (LCLObject <> nil) and
3575     (not (csDesigning in LCLObject.ComponentState) and not getEnabled) then
3576     Exit;
3577 
3578   // idea of multi click implementation is taken from gtk
3579 
3580   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3581 
3582   // MousePos :=
3583   QMouseEvent_pos(QMouseEventH(Event), @MousePos);
3584   OffsetMousePos(@MousePos);
3585 
3586   Modifiers := QInputEvent_modifiers(QInputEventH(Event));
3587   Msg.Keys := QtKeyModifiersToKeyState(Modifiers, False, nil);
3588 
3589   Msg.XPos := SmallInt(MousePos.X);
3590   Msg.YPos := SmallInt(MousePos.Y);
3591 
3592   MButton := QMouseEvent_Button(QMouseEventH(Event));
3593   LazPos := Point(MousePos.X, MousePos.Y);
3594   case MButton of
3595     QtLeftButton: LazButton := 1;
3596     QtRightButton: LazButton := 2;
3597     QtMidButton: LazButton := 3;
3598     QtXButton1, QtXButton2: LazButton := 4;
3599     else Exit; // Sometimes mouse wheel triggers an invalid button value. Ignore it.
3600   end;
3601   // do not pass mouse button into keys (TShiftState). issue #20916
3602   if (QEvent_type(Event) <> QEventMouseButtonRelease)
3603   or (((MButton and QtLeftButton) = 0) and ((MButton and QtRightButton) = 0) and
3604       ((MButton and QtMidButton) = 0))
3605   then
3606     Msg.Keys := Msg.Keys or QtButtonsToLCLButtons(MButton);
3607   Msg.Msg := CheckMouseButtonDownUp(TLCLIntfHandle(Self), LCLObject, LastMouse, LazPos, LazButton,
3608     QEvent_type(Event) in [QEventMouseButtonPress, QEventMouseButtonDblClick]);
3609   case LastMouse.ClickCount of
3610     2: Msg.Keys := Msg.Keys or MK_DOUBLECLICK;
3611     3: Msg.Keys := Msg.Keys or MK_TRIPLECLICK;
3612     4: Msg.Keys := Msg.Keys or MK_QUADCLICK;
3613   end;
3614 
3615   case QEvent_type(Event) of
3616     QEventMouseButtonPress, QEventMouseButtonDblClick:
3617     begin
3618       {$IFDEF MSWINDOWS}
3619       if (QEvent_type(Event) = QEventMouseButtonPress) and
3620           (MButton = QtRightButton) then
3621         Include(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
3622       try
3623       {$ENDIF}
3624 
3625       NotifyApplicationUserInput(LCLObject, Msg.Msg);
3626 
3627       if not CanSendLCLMessage or (Sender = nil) then
3628         exit(True);
3629 
3630       DeliverMessage(Msg, True);
3631 
3632       {$IFDEF MSWINDOWS}
3633       finally
3634         if (QEvent_type(Event) = QEventMouseButtonPress) and
3635           (MButton = QtRightButton) then
3636         begin
3637           Exclude(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
3638           Exclude(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
3639         end;
3640       end;
3641       {$ENDIF}
3642 
3643       // Check if our objects exists since LCL can destroy object during
3644       // mouse events...
3645       if CanSendLCLMessage and (Sender <> nil) then
3646         SetNoMousePropagation(QWidgetH(Sender), True)
3647       else
3648         exit(True);
3649     end;
3650     QEventMouseButtonRelease:
3651     begin
3652       SaveWidget := nil;
3653       if (FChildOfComplexWidget = ccwCustomControl) and (FOwner <> nil) then
3654         SaveWidget := Widget;
3655 
3656       NotifyApplicationUserInput(LCLObject, Msg.Msg);
3657 
3658       if (SaveWidget <> nil) and (SaveWidget <> Widget) then
3659         exit(True);
3660 
3661       if not CanSendLCLMessage or (Sender = nil) then
3662         exit(True);
3663 
3664       DeliverMessage(Msg, True);
3665       if (SaveWidget <> nil) and (SaveWidget <> Widget) then
3666         exit(True);
3667 
3668       // Check if our objects exists since LCL can destroy object during
3669       // mouse events...
3670       if CanSendLCLMessage and (Sender <> nil) then
3671         SetNoMousePropagation(QWidgetH(Sender), True)
3672       else
3673         exit(True);
3674 
3675       { Clicking on buttons operates differently, because QEventMouseButtonRelease
3676         is sent if you click a control, drag the mouse out of it and release, but
3677         buttons should not be clicked on this case. }
3678       if CanSendLCLMessage and (Sender <> nil) and
3679         not (LCLObject is TCustomButton) then
3680       begin
3681         Msg.Msg := LM_CLICKED;
3682         DeliverMessage(Msg, True);
3683       end;
3684     end;
3685   end;
3686 end;
3687 
3688 procedure TQtWidget.SlotNCMouse(Sender: QObjectH; Event: QEventH); cdecl;
3689 var
3690   AHeader: TRect;
3691   APoint: TQtPoint;
3692 begin
3693   //Drag&Dock support TCustomForm => Start BeginDrag()
3694   if (LCLObject is TCustomForm) and
3695      not (csDesigning in LCLObject.ComponentState) and
3696      (TWinControlAccess(LCLObject).DragKind = dkDock) and
3697      (TWinControlAccess(LCLObject).DragMode = dmAutomatic) and
3698      (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
3699   begin
3700     QMouseEvent_globalPos(QMouseEventH(Event), @APoint);
3701     AHeader := getGeometry;
3702     with getFrameGeometry do
3703       AHeader.Top := Top;
3704 
3705     // remove various buttons from header (how to request their pos cross platform?):
3706     Inc(AHeader.Left, 20);  // system menu
3707     Dec(AHeader.Right, 80); // close, min, max buttons
3708     if AHeader.Right < AHeader.Left then
3709       AHeader.Right := AHeader.Left + 1;
3710 
3711     // we can skip translation of coords to global since we already working with window
3712     // check for title
3713     if PtInRect(AHeader, Point(APoint.x, APoint.y)) then
3714       LCLObject.BeginDrag(true);
3715   end;
3716 end;
3717 
SlotMouseEnternull3718 function TQtWidget.SlotMouseEnter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3719 var
3720   Msg: TLMessage;
3721 begin
3722   Result := False;
3723   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3724   case QEvent_type(Event) of
3725     QEventEnter: Msg.Msg := LM_MOUSEENTER;
3726     QEventLeave: Msg.Msg := LM_MOUSELEAVE;
3727   end;
3728   DeliverMessage(Msg);
3729 end;
3730 
TQtWidget.QtButtonsToLCLButtonsnull3731 function TQtWidget.QtButtonsToLCLButtons(AButtons: QtMouseButton): PtrInt;
3732 begin
3733   Result := 0;
3734   if (QtLeftButton and AButtons) <> 0 then
3735     Result := Result or MK_LBUTTON;
3736 
3737   if (QtRightButton and AButtons) <> 0 then
3738     Result := Result or MK_RBUTTON;
3739 
3740   if (QtMidButton and AButtons) <> 0 then
3741     Result := Result or MK_MBUTTON;
3742 
3743   if (QtXButton1 and AButtons) <> 0 then
3744     Result := Result or MK_XBUTTON1;
3745 
3746   if (QtXButton2 and AButtons) <> 0 then
3747     Result := Result or MK_XBUTTON2;
3748 end;
3749 
QtKeyModifiersToKeyStatenull3750 function TQtWidget.QtKeyModifiersToKeyState(AModifiers: QtKeyboardModifiers;
3751   const AIsKeyEvent: Boolean; AEvent: QKeyEventH = nil): PtrInt;
3752 begin
3753 // TODO: remove AIsKeyEvent later
3754   Result := 0;
3755   if AModifiers and QtShiftModifier <> 0 then
3756     Result := Result or MK_SHIFT;
3757   if AModifiers and QtControlModifier <> 0 then
3758     Result := Result or MK_CONTROL;
3759   if AModifiers and QtAltModifier <> 0 then
3760   begin
3761     if AIsKeyEvent then
3762       Result := Result or KF_ALTDOWN
3763     else
3764       Result := Result or MK_ALT;
3765   end;
3766     // $20000000;
3767   { TODO: add support for ALT, META and NUMKEYPAD }
3768 end;
3769 
3770 {------------------------------------------------------------------------------
3771   Function: TQtWidget.SlotMouseMove
3772   Params:  None
3773   Returns: Nothing
3774  ------------------------------------------------------------------------------}
SlotMouseMovenull3775 function TQtWidget.SlotMouseMove(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3776 var
3777   Msg: TLMMouseMove;
3778   MousePos: TQtPoint;
3779   GlobPos: TQtPoint;
3780   R: TRect;
3781   P: TPoint;
3782   NewEvent: QEventH;
3783   W: QWidgetH;
3784   FrameBorder: Integer;
3785   TitleBarHeight: Integer;
3786   SenderWidget: QWidgetH;
3787   SavedLCLObject: PtrUint;
3788 begin
3789   Result := False;
3790   if not CanSendLCLMessage or (Sender = nil) or
3791     not QObject_isWidgetType(Sender) then
3792     Exit(True);
3793 
3794   SenderWidget := QWidgetH(Sender);
3795 
3796   if not (csCaptureMouse in LCLObject.ControlStyle) and
3797     not QWidget_isWindow(SenderWidget) and
3798     not DragManager.IsDragging then
3799   begin
3800     QMouseEvent_pos(QMouseEventH(Event), @MousePos);
3801     QMouseEvent_globalPos(QMouseEventH(Event), @GlobPos);
3802 
3803     // get parent form, so check if mouse is out of parent form first.
3804     W := QWidget_window(SenderWidget);
3805 
3806     if W <> nil then
3807     begin
3808       QWidget_frameGeometry(W, @R);
3809 
3810       // exclude borders from frame
3811       FrameBorder := GetPixelMetric(QStylePM_DefaultFrameWidth, nil, W);
3812       TitleBarHeight := GetPixelMetric(QStylePM_TitleBarHeight, nil, W);
3813 
3814       inc(R.Left, FrameBorder);
3815       inc(R.Top, TitleBarHeight);
3816       dec(R.Right, FrameBorder);
3817       dec(R.Bottom, FrameBorder);
3818 
3819       P := Point(GlobPos.X, GlobPos.Y);
3820       if not PtInRect(R, P) then
3821         MousePos := QtPoint(-1, -1);
3822 
3823       if not QWidget_underMouse(SenderWidget) then
3824       begin
3825         if (MousePos.X >= 0) and (MousePos.Y >= 0) then
3826         begin
3827           QWidget_setAttribute(SenderWidget, QtWA_UnderMouse, True);
3828           NewEvent := QEvent_create(QEventEnter);
3829           QCoreApplication_postEvent(SenderWidget, NewEvent, 100);
3830         end;
3831       end;
3832     end;
3833 
3834     if not (csCaptureMouse in LCLObject.ControlStyle) and
3835       (QGUIApplication_mouseButtons() <> QtNoButton) and
3836       (((MousePos.X < 0) or (MousePos.Y < 0)) or
3837       ((MousePos.X > getWidth) or (MousePos.Y > getHeight))) then
3838     begin
3839       if not QWidget_underMouse(SenderWidget) then
3840         exit;
3841       setCursor(FDefaultCursor);
3842       NewEvent := QEvent_create(QEventLeave);
3843       QCoreApplication_postEvent(SenderWidget, NewEvent, 100);
3844       exit;
3845     end;
3846   end;
3847 
3848   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3849 
3850   // MousePos :=
3851   QMouseEvent_pos(QMouseEventH(Event), @MousePos);
3852   OffsetMousePos(@MousePos);
3853 
3854   Msg.XPos := SmallInt(MousePos.X);
3855   Msg.YPos := SmallInt(MousePos.Y);
3856 
3857   Msg.Keys := QtButtonsToLCLButtons(QMouseEvent_Buttons(QMouseEventH(Event)))
3858     or QtKeyModifiersToKeyState(QInputEvent_modifiers(QInputEventH(Event)), False, nil);
3859 
3860   Msg.Msg := LM_MOUSEMOVE;
3861 
3862   SetNoMousePropagation(SenderWidget, True);
3863   SavedLCLObject := PtrUInt(LCLObject);
3864 
3865   NotifyApplicationUserInput(LCLObject, Msg.Msg);
3866 
3867   if (SavedLCLObject <> PtrUInt(LCLObject)) or not CanSendLCLMessage then
3868     exit(True);
3869 
3870   DeliverMessage(Msg, True);
3871 
3872   if (SavedLCLObject <> PtrUInt(LCLObject)) or not CanSendLCLMessage then
3873     exit(True);
3874 end;
3875 
3876 {------------------------------------------------------------------------------
3877   Function: TQtWidget.SlotMouseWheel
3878   Params:  None
3879   Returns: Nothing
3880 
3881   Qt stores the delta in 1/8 of a degree
3882   Most mouses scroll 15 degrees each time
3883 
3884   Msg.WheelDelta: -1 for up, 1 for down
3885  ------------------------------------------------------------------------------}
SlotMouseWheelnull3886 function TQtWidget.SlotMouseWheel(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
3887 var
3888   Msg: TLMMouseEvent;
3889   MousePos: TQtPoint;
3890   Modifiers: QtKeyboardModifiers;
3891   ModifierState: PtrInt;
3892   {$IFDEF DARWIN}
3893   CCtl: TQtAbstractScrollArea;
3894   {$ENDIF}
3895 begin
3896   Result := False;
3897   if not CanSendLCLMessage then
3898     exit;
3899 
3900   FillChar(Msg{%H-}, SizeOf(Msg), #0);
3901 
3902   QWheelEvent_Pos(QWheelEventH(Event), @MousePos);
3903   OffsetMousePos(@MousePos);
3904 
3905   Modifiers := QInputEvent_modifiers(QInputEventH(Event));
3906   Msg.State := [];
3907   ModifierState := QtKeyModifiersToKeyState(Modifiers, False, nil);
3908   if (ModifierState and MK_SHIFT) <> 0 then
3909     Msg.State := [ssShift];
3910   if (ModifierState and MK_CONTROL) <> 0 then
3911     Msg.State := [ssCtrl] + Msg.State;
3912   if (ModifierState and MK_ALT) <> 0 then
3913     Msg.State := [ssAlt] + Msg.State;
3914 
3915   LastMouse.WinControl := LCLObject;
3916   LastMouse.WinHandle := TLCLIntfHandle(Self);
3917   LastMouse.MousePos := Point(MousePos.X, MousePos.Y);
3918 
3919   Msg.X := SmallInt(MousePos.X);
3920   Msg.Y := SmallInt(MousePos.Y);
3921 
3922   Msg.WheelDelta := SmallInt(QWheelEvent_delta(QWheelEventH(Event)));
3923 
3924   Msg.Msg := LM_MOUSEWHEEL;
3925   if QWheelEvent_orientation(QWheelEventH(Event)) = QtHorizontal then
3926   begin
3927     Msg.Msg := LM_MOUSEHWHEEL;
3928     Msg.WheelDelta := -Msg.WheelDelta;
3929   end;
3930 
3931   {$IFDEF DARWIN}
3932   // LCL expects delta +-120, we must fix it. issue #20888
3933   if (ChildOfComplexWidget in [ccwCustomControl, ccwAbstractScrollArea,
3934       ccwScrollingWinControl]) then
3935   begin
3936     if (Msg.WheelDelta > 0) then
3937       Msg.WheelDelta := 1
3938     else
3939       Msg.WheelDelta := -1;
3940     Msg.WheelDelta := (120 * Msg.WheelDelta) div Mouse.WheelScrollLines;
3941     if FOwner <> nil then
3942     begin
3943       {$IFDEF QTSCROLLABLEFORMS}
3944       if (FOwner is TQtMainWindow) then
3945         CCtl := TQtMainWindow(FOwner).ScrollArea
3946       else
3947       {$ENDIF}
3948         CCtl := TQtAbstractScrollArea(FOwner);
3949     end else
3950       CCtl := TQtAbstractScrollArea(Self);
3951     //now fix ugly behaviour.
3952     if (Msg.WheelDelta > 0) and (CCtl.FVScrollbar.getVisible) and
3953         ((CCtl.FVScrollBar = Self) or
3954          (Assigned(CCtl.FVScrollbar) and (Self <> CCtl.FHScrollbar))) then
3955     begin
3956       if CCtl.FVScrollbar.getSliderPosition <= 1 then
3957         Msg.WheelDelta := 120;
3958     end;
3959   end;
3960   {$ENDIF}
3961 
3962   NotifyApplicationUserInput(LCLObject, Msg.Msg);
3963 
3964   if not CanSendLCLMessage then
3965     exit(True);
3966 
3967   Result := DeliverMessage(Msg, True) <> 0;
3968 
3969   if not CanSendLCLMessage then
3970     exit(True);
3971 
3972   SetNoMousePropagation(QWidgetH(Sender), False);
3973 
3974   {propagate mousewheel to parent if our sender is TPanel,
3975    fixes problem with mousewheel scroll with lazreport}
3976   if (LCLObject <> nil) and
3977     not (csDesigning in LCLObject.ComponentState) and
3978     (LCLObject is TPanel) and
3979     Assigned(LCLObject.Parent) then
3980       Result := TQtWidget(LCLObject.Parent.Handle).DeliverMessage(Msg) <> 0;
3981 end;
3982 
3983 procedure TQtWidget.SlotMove(Event: QEventH); cdecl;
3984 var
3985   Msg: TLMMove;
3986   APos: TQtPoint;
3987   {$IFDEF HASX11}
3988   ACurrPos: TQtPoint;
3989   {$IFDEF QtUseAccurateFrame}
3990   X11Pos: TQtPoint;
3991   ALeft, ATop, ABorder, AWidth, AHeight: integer;
3992   {$ENDIF}
3993   {$ENDIF}
3994   FrameRect, WindowRect: TRect;
3995   ForceSendMove: boolean;
3996 begin
3997   {$ifdef VerboseQt}
3998     WriteLn('TQtWidget.SlotMove');
3999   {$endif}
4000 
4001   if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
4002     QtWidgetSet.InvalidateWidgetAtCache;
4003   // do not loop with LCL
4004   if InUpdate {$ifdef darwin} and not (qtwsForceSendMove in WidgetState){$endif} then
4005     exit;
4006 
4007   ForceSendMove := False; {mantis #34589}
4008   if not QEvent_spontaneous(Event) and Assigned(LCLObject) and Assigned(LCLObject.Parent) then
4009     // only children of 1st level should move.
4010     ForceSendMove := qtwsForceSendMove in TQtWidget(LCLObject.Parent.Handle).WidgetState;
4011 
4012   {$ifdef darwin}
4013   // issue #34698
4014   if not ForceSendMove and not QEvent_spontaneous(Event) and Assigned(LCLObject) and
4015     (Self is TQtMainWindow) and not TQtMainWindow(Self).IsMdiChild then
4016   begin
4017     ForceSendMove := qtwsForceSendMove in WidgetState;
4018     Exclude(FWidgetState, qtwsForceSendMove);
4019   end;
4020   {$endif}
4021 
4022   if ForceSendMove then
4023     // send message mantis #34589
4024   else
4025   if not QEvent_spontaneous(Event) or
4026     (not QEvent_spontaneous(Event) and
4027     ((Self is TQtMainWindow) and not
4028     TQtMainWindow(Self).IsMdiChild)) then
4029     Exit;
4030 
4031   FillChar(Msg{%H-}, SizeOf(Msg), #0);
4032 
4033   Msg.Msg := LM_MOVE;
4034 
4035   Msg.MoveType := Msg.MoveType or Move_SourceIsInterface;
4036 
4037   APos := QMoveEvent_pos(QMoveEventH(Event))^;
4038   FrameRect := getFrameGeometry;
4039   WindowRect := getGeometry;
4040 
4041   // here is explanation why frameGeometry sometimes
4042   // doesn't return correct results under X11
4043   // http://doc.qt.nokia.com/4.7/application-windows.html#window-geometry
4044   // issue #18658
4045   {$IFDEF HASX11}
4046   if (LCLObject is TCustomForm) and EqualRect(FrameRect, WindowRect) and
4047     (TCustomForm(LCLObject).BorderStyle <> bsNone) and
4048     (not (TCustomForm(LCLObject).FormStyle in [fsMDIChild,fsSplash]) or
4049       (csDesigning in LCLObject.ComponentState)) then
4050   begin
4051     ACurrPos := getPos;
4052     // do not send garbage to LCL. This window isn't decorated yet by WM.
4053     if (ACurrPos.X = WindowRect.Left) and (ACurrPos.Y = WindowRect.Top) then
4054       exit;
4055   end;
4056   {$ENDIF}
4057 
4058   Msg.XPos := SmallInt(APos.x - (WindowRect.Left - FrameRect.Left));
4059   Msg.YPos := SmallInt(APos.y - (WindowRect.Top - FrameRect.Top));
4060 
4061   {$IFDEF QtUseAccurateFrame}
4062   // Qt is sometimes mismatched with X11
4063   {$IFDEF HASX11}
4064   if IsFramedWidget and PointsEqual(FrameRect.TopLeft, WindowRect.TopLeft) then
4065   begin
4066     // checking code above means that we have mismatch somewhere
4067     // in between Qt and X11. Question is who is correct in this case X or Qt.
4068     // SlotMove is triggered always after form activation
4069     if (getWindowState and QtWindowFullScreen = QtWindowFullScreen) or
4070       (getWindowState and QtWindowMaximized = QtWindowMaximized) then
4071     begin
4072       {$IF DEFINED(DEBUGQTUSEACCURATEFRAME) OR DEFINED(DEBUGQTCHECKMOVESIZE)}
4073       DebugLn('WARNING: SlotMove(',dbgsName(LCLObject),') FULLSCREEN CALCULATED X=',dbgs(Msg.XPos),' Y=',dbgs(Msg.YPos));
4074       {$ENDIF}
4075     end else
4076     if GetX11WindowRealized(QWidget_winID(Widget)) then
4077     begin
4078       {$IF DEFINED(DEBUGQTUSEACCURATEFRAME) OR DEFINED(DEBUGQTCHECKMOVESIZE)}
4079       DebugLn('WARNING: SlotMove(',dbgsName(LCLObject),') frame and geometry have same values geom=',dbgs(WindowRect),' frame=',dbgs(FrameRect),' MARGINS=',dbgs(FrameMargins),' WS=',dbgs(QtWidgetSet.WSFrameMargins),' InvPos=',dbgs(TQtMainWindow(Self).FFormHasInvalidPosition));
4080       {$ENDIF}
4081       {TODO: KWin4 is find with FFormHasInvalidPosition := True, but gtk based wm's like
4082        xfce,gnome-shell and cinnamon and kwin5 aren''t, so we must use code below.}
4083       if (GetKdeSessionVersion = 3) then
4084         TQtMainWindow(Self).FFormHasInvalidPosition := True
4085       else
4086       begin
4087         GetX11WindowPos(QWidget_winId(Widget),  X11Pos.x, X11Pos.y);
4088 
4089         if GetX11WindowAttributes(QWidget_winID(Widget), ALeft, ATop, AWidth, AHeight, ABorder) then
4090         begin
4091           if ALeft = 0 then
4092             X11Pos.x -= FFrameMargins.Left;
4093           if ATop = 0 then
4094             X11Pos.y -= FFrameMargins.Top;
4095         end else
4096         begin
4097           X11Pos.x -= FFrameMargins.Left;
4098           X11Pos.y -= FFrameMargins.Top;
4099         end;
4100         if ((GetKdeSessionVersion = 5) or ((X11Pos.x = LCLObject.Left) and (X11Pos.y = LCLObject.Top))) and
4101           ((QWidget_x(Widget) <> X11Pos.x) or (QWidget_y(Widget) <> X11Pos.y)) then
4102         begin
4103           {$IF DEFINED(DEBUGQTUSEACCURATEFRAME) OR DEFINED(DEBUGQTCHECKMOVESIZE)}
4104           DebugLn('1.*error: *** SlotMove(',dbgsName(LCLObject),Format(' calculated pos x %d y %d',[Msg.XPos, Msg.YPos]),' realized=',dbgs(GetX11WindowRealized(QWidget_winId(Widget))));
4105           DebugLn(' > ',Format('current LCL x %d y %d Qt x %d y %d X11 x %d y %d CALC x %d y %d',[LCLObject.Left, LCLObject.Top, QWidget_x(Widget), QWidget_y(Widget), X11Pos.x, X11Pos.y, Msg.XPos, Msg.YPos]));
4106           DebugLn(' > FrameRect=',dbgs(FrameRect),' WindowRect=',dbgs(WindowRect),' Margins=',dbgs(FFrameMargins));
4107           DebugLn('< sending valid values to Qt and LCL ',Format('x %d y %d compositor %s ',[X11Pos.X, X11Pos.y,dbgs(QX11Info_isCompositingManagerRunning)]));
4108           {$ENDIF}
4109           QWidget_move(Widget, X11Pos.x, X11Pos.y);
4110           exit;
4111         end;
4112       end;
4113     end;
4114   end;
4115   {$ENDIF}
4116   {$ENDIF}
4117   DeliverMessage(Msg);
4118 end;
4119 
4120 {------------------------------------------------------------------------------
4121   Function: TQtWidget.SlotPaintBg
4122   Params:  None
4123   Returns: Nothing.
4124 
4125   Paints widget background.
4126   Only for classes which have HasPaint=False and AutoFillBackground=False
4127   and solid color different to default one (eg. clBtnFace for buttons).
4128   Current allowed classes are: All TQtCheckBox,TQtRadioButton,
4129   TQtPushButton (X11 only), TQtStaticText and TQtGroupBox.
4130  ------------------------------------------------------------------------------}
4131 procedure TQtWidget.SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl;
4132 var
4133   Painter: QPainterH;
4134   Brush: QBrushH;
4135   Color: TQColor;
4136   R: TRect;
4137 begin
4138   if CanSendLCLMessage and (LCLObject is TWinControl) then
4139   begin
4140     if LCLObject.Color = clDefault then
4141       Color := Palette.DefaultColor
4142     else
4143       ColorRefToTQColor(ColorToRGB(LCLObject.Color), Color);
4144     Painter := QPainter_create(QWidget_to_QPaintDevice(QWidgetH(Sender)));
4145     {$IFDEF USEQT4COMPATIBILEPAINTER}
4146     QPainter_setRenderHint(Painter, QPainterQt4CompatiblePainting);
4147     {$ENDIF}
4148     Brush := QBrush_create(@Color, QtSolidPattern);
4149     try
4150       QPaintEvent_rect(QPaintEventH(Event), @R);
4151       QPainter_fillRect(Painter, @R, Brush);
4152       QPainter_end(Painter);
4153     finally
4154       QBrush_destroy(Brush);
4155       QPainter_destroy(Painter);
4156     end;
4157   end;
4158 end;
4159 
4160 {------------------------------------------------------------------------------
4161   Function: TQtWidget.SlotPaint
4162   Params:  None
4163   Returns: Nothing
4164 
4165   Sends a LM_PAINT message to the LCL. This is for windowed controls only
4166  ------------------------------------------------------------------------------}
4167 procedure TQtWidget.SlotPaint(Sender: QObjectH; Event: QEventH); cdecl;
4168 var
4169   Msg: TLMPaint;
4170   AStruct: PPaintStruct;
4171   P: TPoint;
4172   B: Boolean;
4173 begin
4174   {$ifdef VerboseQt}
4175     WriteLn('TQtWidget.SlotPaint ', dbgsName(LCLObject));
4176   {$endif}
4177   if CanSendLCLMessage and (LCLObject is TWinControl) then
4178   begin
4179     FillChar(Msg{%H-}, SizeOf(Msg), #0);
4180 
4181     Msg.Msg := LM_PAINT;
4182     New(AStruct);
4183     FillChar(AStruct^, SizeOf(TPaintStruct), 0);
4184     Msg.PaintStruct := AStruct;
4185 
4186     with PaintData do
4187     begin
4188       PaintWidget := QWidgetH(Sender);
4189       ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
4190       if ClipRect = nil then
4191         New(ClipRect);
4192       QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
4193     end;
4194 
4195     Msg.DC := BeginPaint(THandle(Self), AStruct^);
4196     FContext := Msg.DC;
4197 
4198     Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
4199     Msg.PaintStruct^.hdc := FContext;
4200 
4201     P := getClientOffset;
4202 
4203     if (Self is TQtGroupBox) and (QWidgetH(Sender) = FCentralWidget) then
4204     begin
4205       P.X := 0;
4206       P.Y := 0;
4207     end;
4208     inc(P.X, FScrollX);
4209     inc(P.Y, FScrollY);
4210     TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
4211 
4212     // send paint message
4213     try
4214       // Saving clip rect and clip region
4215       try
4216         LCLObject.WindowProc(TLMessage(Msg));
4217         if HasCaret then
4218         begin
4219           if GlobalCaretDirty then
4220             QtCaret.ShowCaret(Self);
4221           QtCaret.DrawCaret;
4222         end;
4223       finally
4224         Dispose(PaintData.ClipRect);
4225         Fillchar(FPaintData, SizeOf(FPaintData), 0);
4226         FContext := 0;
4227         EndPaint(THandle(Self), AStruct^);
4228         Dispose(AStruct);
4229       end;
4230     except
4231       // prevent recursive repainting !
4232       B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
4233       if B then
4234         QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
4235       try
4236         Application.HandleException(nil);
4237       finally
4238         if B and Assigned(Application) and not Application.Terminated then
4239           QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
4240       end;
4241     end;
4242   end;
4243 end;
4244 
4245 {------------------------------------------------------------------------------
4246   Function: TQtWidget.SlotResize
4247   Params:  None
4248   Returns: Nothing
4249 
4250   Sends a LM_SIZE message to the LCL.
4251  ------------------------------------------------------------------------------}
4252 procedure TQtWidget.SlotResize(Event: QEventH); cdecl;
4253 var
4254   Msg: TLMSize;
4255   NewSize: TSize;
4256   {$IFDEF VerboseQtResizeError}
4257   R: TRect;
4258   {$ENDIF}
4259   B: Boolean;
4260   AQtClientRect: TRect;
4261 begin
4262   {$ifdef VerboseQt}
4263     WriteLn('TQtWidget.SlotResize');
4264   {$endif}
4265 
4266   if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
4267     QtWidgetSet.InvalidateWidgetAtCache;
4268 
4269   // return size w/o frame
4270   NewSize := QResizeEvent_size(QResizeEventH(Event))^;
4271 
4272   if not Assigned(LCLObject) then exit;
4273 
4274   if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
4275   begin
4276     {$IFDEF VerboseQtResizeError}
4277     if not InUpdate then
4278     begin
4279       DebugLn('============================================================================');
4280       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 !');
4281       DebugLn(dbgsName(LCLObject),' self=',dbgsName(Self),' already in SlotResize needClientRectAdjust',dbgs(LCLObject.ClientRectNeedsInterfaceUpdate),
4282       ' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
4283       R := getClientBounds;
4284       DebugLn('LCL CACHED CLIENT WxH=',dbgs(LCLObject.CachedClientWidth),'x',dbgs(LCLObject.CachedClientHeight),
4285       ' QtClient=',dbgs(R));
4286       DebugLn('============================================================================');
4287     end;
4288     {$ENDIF}
4289     exit;
4290   end;
4291   if Assigned(FOwner) then
4292     FOwner.InResizeEvent := True;
4293   InResizeEvent := True;
4294   try
4295     // do not loop with LCL but do not apply it to TQtMainWindow !
4296     if not (csDesigning in LCLObject.ComponentState) then
4297       if not (ClassType = TQtMainWindow) and InUpdate then
4298     begin
4299       AQtClientRect := Rect(0, 0, 0, 0);
4300       if FOwner <> nil then
4301         B := GetClientRect(HWND(Self.FOwner), AQtClientRect)
4302       else
4303         B := GetClientRect(HWND(Self), AQtClientRect);
4304       if B and EqualRect(LCLObject.ClientRect, AQtClientRect) then
4305       begin
4306         {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
4307         DebugLn('==========',dbgsName(LCLObject),'.SlotResize inUpdate.LCLObject.ClientRect is ok,do not send LMSize');
4308         {$ENDIF}
4309         exit;
4310       end else
4311       begin
4312         {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
4313         DebugLn('====***====',dbgsName(LCLObject),'.SlotResize inUpdate but LCL.ClientRect isn''t adjusted. CanAdjust=',dbgs(CanAdjustClientRectOnResize),' CAPS=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' NeedUpd ',dbgs(LCLObject.ClientRectNeedsInterfaceUpdate));
4314         {$ENDIF}
4315         if LCLObject.ClientRectNeedsInterfaceUpdate and
4316           not (caspComputingBounds in LCLObject.AutoSizePhases) then
4317         begin
4318           LCLObject.DoAdjustClientRectChange(True);
4319           exit;
4320         end;
4321       end;
4322     end;
4323 
4324     {keep LCL value while designing pageControl}
4325     if (csDesigning in LCLObject.ComponentState) and InUpdate and
4326       ((Self is TQtPage) or (Self is TQtTabWidget)) then
4327         exit;
4328 
4329     if CanAdjustClientRectOnResize and
4330       LCLObject.ClientRectNeedsInterfaceUpdate then
4331     begin
4332       // postpone resize event if we are computingbounds otherwise
4333       // we can run into infinite size loop.
4334       if (caspComputingBounds in LCLObject.AutoSizePhases) then
4335       begin
4336         {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
4337         DebugLn('WARNING: *TQtWidget.SlotResize caspComputingBounds=true* ! ',dbgsname(LCLObject),':',dbgsName(Self),' inUpdate=',dbgs(inUpdate),' Time: ',dbgs(GetTickCount));
4338         {$ENDIF}
4339         if ChildOfComplexWidget <> ccwScrollingWinControl then
4340           DelayResizeEvent(Widget, NewSize);
4341         exit;
4342       end else
4343       begin
4344         LCLObject.DoAdjustClientRectChange;
4345       end;
4346     end;
4347 
4348     FillChar(Msg{%H-}, SizeOf(Msg), #0);
4349 
4350     Msg.Msg := LM_SIZE;
4351 
4352     case getWindowState of
4353       QtWindowMinimized: Msg.SizeType := SIZE_MINIMIZED;
4354       QtWindowMaximized: Msg.SizeType := SIZE_MAXIMIZED;
4355       QtWindowFullScreen: Msg.SizeType := SIZE_FULLSCREEN;
4356     else
4357       Msg.SizeType := SIZE_RESTORED;
4358     end;
4359 
4360     Msg.SizeType := Msg.SizeType or Size_SourceIsInterface;
4361 
4362     Msg.Width := Word(NewSize.cx);
4363     Msg.Height := Word(NewSize.cy);
4364 
4365     DeliverMessage(Msg);
4366   finally
4367     if ASsigned(FOwner) then
4368       FOwner.InResizeEvent := False;
4369     InResizeEvent := False;
4370   end;
4371 end;
4372 
TQtWidget.SlotContextMenunull4373 function TQtWidget.SlotContextMenu(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
4374 var
4375   Msg: TLMContextMenu;
4376   MousePos: TQtPoint;
4377 
4378   procedure SendMouseReleaseEventToSelf;
4379   var
4380     AEvent: QEventH;
4381     Modifiers: QtKeyboardModifiers;
4382     APos, AGlobalPos: TQtPoint;
4383     APosF, AGlobalPosF: TQtPointF;
4384   begin
4385     APos := QContextMenuEvent_pos(QContextMenuEventH(Event))^;
4386     AGlobalPos := QContextMenuEvent_globalPos(QContextMenuEventH(Event))^;
4387     APosF.X := APos.X;
4388     APosF.Y := APos.Y;
4389     AGlobalPosF.X := AGlobalPos.x;
4390     AGlobalPosF.Y := AGlobalPos.y;
4391     Modifiers := QInputEvent_modifiers(QInputEventH(Event));
4392     AEvent := QMouseEvent_create(QEventMouseButtonRelease,
4393       @APosF,
4394       @AGlobalPosF,
4395       QtRightButton,
4396       QtRightButton,
4397       Modifiers);
4398     QCoreApplication_postEvent(Widget, AEvent, 1);
4399   end;
4400 
4401 begin
4402   if not CanSendLCLMessage then
4403     Exit(False);
4404 
4405   FillChar(Msg{%H-}, SizeOf(Msg), #0);
4406   MousePos := QContextMenuEvent_globalPos(QContextMenuEventH(Event))^;
4407 
4408   Msg.Msg := LM_CONTEXTMENU;
4409   if FOwner <> nil then
4410     Msg.hWnd := HWND(FOwner)
4411   else
4412     Msg.hWnd := HWND(Self);
4413   if QContextMenuEvent_reason(QContextMenuEventH(Event)) = QContextMenuEventKeyboard then
4414   begin
4415     Msg.XPos := -1;
4416     Msg.YPos := -1;
4417   end
4418   else
4419   begin
4420     Msg.XPos := SmallInt(MousePos.X);
4421     Msg.YPos := SmallInt(MousePos.Y);
4422   end;
4423 
4424   Result := DeliverMessage(Msg) <> 0;
4425 
4426   if Result then
4427     QEvent_accept(Event)
4428   else
4429   begin
4430     if Assigned(LCLObject.PopupMenu) then
4431       QEvent_ignore(Event);
4432     SetNoMousePropagation(QWidgetH(Sender), False);
4433     if (FOwner <> nil) and
4434       ((FChildOfComplexWidget = ccwCustomControl) or
4435       (FChildOfComplexWidget = ccwScrollingWinControl)) then
4436       SetNoMousePropagation(FOwner.Widget, False);
4437   end;
4438 
4439   if Result and (csDesigning in LCLObject.ComponentState) then
4440     SendMouseReleaseEventToSelf;
4441 end;
4442 
4443 procedure TQtWidget.SlotWhatsThis(Sender: QObjectH; Event: QEventH); cdecl;
4444 var
4445   Data: THelpInfo;
4446 begin
4447   if not CanSendLCLMessage then
4448     exit;
4449   Data.cbSize := SizeOf(Data);
4450   Data.iContextType := HELPINFO_WINDOW;
4451   Data.iCtrlId := 0;
4452   Data.hItemHandle := THandle(Sender);
4453   Data.dwContextId := 0;
4454   with QHelpEvent_globalPos(QHelpEventH(Event))^ do
4455     Data.MousePos := Point(X, Y);
4456   Application.HelpCommand(0, {%H-}PtrInt(@Data));
4457 end;
4458 
4459 procedure TQtWidget.SlotLCLMessage(Sender: QObjectH; Event: QEventH); cdecl;
4460 var
4461   MessageEvent: QLCLMessageEventH absolute Event;
4462   Msg: TLMessage;
4463 begin
4464   Msg.msg := Cardinal(QLCLMessageEvent_getMsg(MessageEvent));
4465   Msg.wParam := PtrInt(QLCLMessageEvent_getWParam(MessageEvent));
4466   Msg.lParam := PtrInt(QLCLMessageEvent_getLParam(MessageEvent));
4467   Msg.Result := 0;
4468   QLCLMessageEvent_setMsgResult(MessageEvent, PtrUInt(DeliverMessage(Msg)));
4469 end;
4470 
4471 procedure TQtWidget.Activate;
4472 begin
4473   QWidget_activateWindow(Widget);
4474 end;
4475 
4476 procedure TQtWidget.BringToFront;
4477 begin
4478   Activate;
4479   raiseWidget;
4480 end;
4481 
4482 procedure TQtWidget.clearMask;
4483 begin
4484   QWidget_clearMask(Widget);
4485 end;
4486 
4487 procedure TQtWidget.OffsetMousePos(APoint: PQtPoint);
4488 begin
4489   with getClientOffset do
4490   begin
4491     dec(APoint^.x, x);
4492     dec(APoint^.y, y);
4493   end;
4494 end;
4495 
4496 {------------------------------------------------------------------------------
4497   Function: TQtWidget.SetColor
4498   Params:  QColorH
4499   Returns: Nothing
4500 
4501   Changes the color of a widget
4502  ------------------------------------------------------------------------------}
4503 procedure TQtWidget.SetColor(const Value: PQColor);
4504 begin
4505   Palette.setColor(Value);
4506 end;
4507 
getContextMenuPolicynull4508 function TQtWidget.getContextMenuPolicy: QtContextMenuPolicy;
4509 begin
4510   Result := QWidget_contextMenuPolicy(Widget);
4511 end;
4512 
4513 procedure TQtWidget.setContextMenuPolicy(const AValue: QtContextMenuPolicy);
4514 begin
4515   QWidget_setContextMenuPolicy(Widget, AValue);
4516 end;
4517 
4518 {------------------------------------------------------------------------------
4519   Function: TQtWidget.SetTextColor
4520   Params:  QColorH
4521   Returns: Nothing
4522 
4523   Changes the text color of a widget
4524  ------------------------------------------------------------------------------}
4525 procedure TQtWidget.SetTextColor(const Value: PQColor);
4526 begin
4527   Palette.setTextColor(Value);
4528 end;
4529 
4530 procedure TQtWidget.SetCursor(const ACursor: QCursorH);
4531 begin
4532   {$IFDEF DARWIN}
4533   if not QWidget_isVisible(Widget) then
4534     exit;
4535   {$ENDIF}
4536   if ACursor <> nil then
4537     QWidget_setCursor(Widget, ACursor)
4538   else
4539     QWidget_setCursor(Widget, FDefaultCursor);
4540 end;
4541 
4542 procedure TQtWidget.setDefaultColorRoles;
4543 begin
4544   FWidgetColorRole := QPaletteWindow;
4545   FTextColorRole := QPaletteWindowText;
4546 end;
4547 
4548 {------------------------------------------------------------------------------
4549   Function: TQtWidget.Update
4550   Params:  None
4551   Returns: Nothing
4552 
4553   Schedules a paint event for processing when Qt returns to the main event loop
4554  ------------------------------------------------------------------------------}
4555 procedure TQtWidget.Update(ARect: PRect = nil);
4556 begin
4557   if ARect <> nil then
4558     QWidget_update(Widget, ARect)
4559   else
4560     QWidget_update(Widget);
4561 end;
4562 
4563 procedure TQtWidget.UpdateRegion(ARgn: QRegionH);
4564 begin
4565   if ARgn <> nil then
4566     QWidget_update(Widget, ARgn)
4567   else
4568     QWidget_update(Widget);
4569 end;
4570 
4571 {------------------------------------------------------------------------------
4572   Function: TQtWidget.Repaint
4573   Params:  None
4574   Returns: Nothing
4575 
4576   Repaints the control imediately
4577  ------------------------------------------------------------------------------}
4578 procedure TQtWidget.Repaint(ARect: PRect = nil);
4579 begin
4580   if ARect <> nil then
4581     QWidget_repaint(Widget, ARect)
4582   else
4583     QWidget_repaint(Widget);
4584 end;
4585 
4586 procedure TQtWidget.setWindowTitle(Str: PWideString);
4587 begin
4588   QWidget_setWindowTitle(Widget, Str);
4589 end;
4590 
4591 procedure TQtWidget.WindowTitle(Str: PWideString);
4592 begin
4593   QWidget_WindowTitle(Widget, Str);
4594 end;
4595 
4596 procedure TQtWidget.Hide;
4597 begin
4598   QWidget_hide(Widget);
4599 end;
4600 
4601 procedure TQtWidget.Show;
4602 begin
4603   QWidget_show(Widget);
4604 end;
4605 
4606 procedure TQtWidget.ShowNormal;
4607 begin
4608   QWidget_showNormal(Widget);
4609 end;
4610 
4611 procedure TQtWidget.ShowMinimized;
4612 begin
4613   QWidget_showMinimized(Widget);
4614 end;
4615 
4616 procedure TQtWidget.ShowMaximized;
4617 begin
4618   QWidget_showMaximized(Widget);
4619 end;
4620 
4621 procedure TQtWidget.ShowFullScreen;
4622 begin
4623   QWidget_showFullScreen(Widget);
4624 end;
4625 
TQtWidget.getActionByIndexnull4626 function TQtWidget.getActionByIndex(AIndex: Integer): QActionH;
4627 var
4628   ActionList: TPtrIntArray;
4629 begin
4630   QWidget_actions(Widget, @ActionList);
4631   if (AIndex >= 0) and (AIndex < Length(ActionList)) then
4632     Result := QActionH(ActionList[AIndex])
4633   else
4634     Result := nil;
4635 end;
4636 
getAutoFillBackgroundnull4637 function TQtWidget.getAutoFillBackground: Boolean;
4638 begin
4639   Result := QWidget_autoFillBackground(Widget);
4640 end;
4641 
getEnablednull4642 function TQtWidget.getEnabled: Boolean;
4643 begin
4644   if Widget = nil then
4645     exit(False);
4646   Result := QWidget_isEnabled(Widget);
4647 end;
4648 
TQtWidget.getFontnull4649 function TQtWidget.getFont: QFontH;
4650 begin
4651   Result := QWidget_font(Widget);
4652 end;
4653 
TQtWidget.getFocusPolicynull4654 function TQtWidget.getFocusPolicy: QtFocusPolicy;
4655 begin
4656   Result := QWidget_focusPolicy(Widget);
4657 end;
4658 
getFrameGeometrynull4659 function TQtWidget.getFrameGeometry: TRect;
4660 begin
4661   QWidget_frameGeometry(Widget, @Result);
4662 end;
4663 
getGeometrynull4664 function TQtWidget.getGeometry: TRect;
4665 begin
4666   QWidget_geometry(Widget, @Result);
4667 end;
4668 
getLayoutDirectionnull4669 function TQtWidget.getLayoutDirection: QtLayoutDirection;
4670 begin
4671   Result := QWidget_layoutDirection(Widget);
4672 end;
4673 
getVisiblenull4674 function TQtWidget.getVisible: boolean;
4675 begin
4676   if Widget = nil then
4677     exit(False);
4678   Result := QWidget_isVisible(Widget);
4679 end;
4680 
getVisibleTonull4681 function TQtWidget.getVisibleTo(AWidget: QWidgetH): Boolean;
4682 begin
4683   if Widget = nil then
4684     exit(False);
4685   Result := QWidget_isVisibleTo(Widget, AWidget);
4686 end;
4687 
TQtWidget.getOwnernull4688 function TQtWidget.getOwner: TQtWidget;
4689 begin
4690   Result := FOwner;
4691 end;
4692 
getParentnull4693 function TQtWidget.getParent: QWidgetH;
4694 begin
4695   Result := QWidget_parentWidget(Widget);
4696 end;
4697 
getPosnull4698 function TQtWidget.getPos: TQtPoint;
4699 begin
4700   QWidget_pos(Widget, @Result);
4701 end;
4702 
TQtWidget.getFrameSizenull4703 function TQtWidget.getFrameSize: TSize;
4704 begin
4705   QWidget_frameSize(Widget, @Result);
4706 end;
4707 
getSizenull4708 function TQtWidget.getSize: TSize;
4709 begin
4710   QWidget_size(Widget, @Result);
4711 end;
4712 
getTextnull4713 function TQtWidget.getText: WideString;
4714 begin
4715   Result := FText;
4716 end;
4717 
TQtWidget.getTextStaticnull4718 function TQtWidget.getTextStatic: Boolean;
4719 begin
4720   Result := True;
4721 end;
4722 
getHeightnull4723 function TQtWidget.getHeight: Integer;
4724 {$IFDEF QtUseAccurateFrame}
4725 var
4726   ASize: TSize;
4727 {$ENDIF}
4728 begin
4729   {$IFDEF QtUseAccurateFrame}
4730   if IsFramedWidget then
4731   begin
4732     ASize := getFrameSize;
4733     Result := ASize.cy;
4734   end else
4735   {$ENDIF}
4736   Result := QWidget_height(Widget);
4737 end;
4738 
getUpdatesEnablednull4739 function TQtWidget.getUpdatesEnabled: Boolean;
4740 begin
4741   Result := QWidget_updatesEnabled(Widget);
4742 end;
4743 
TQtWidget.getWidthnull4744 function TQtWidget.getWidth: Integer;
4745 {$IFDEF QtUseAccurateFrame}
4746 var
4747   ASize: TSize;
4748 {$ENDIF}
4749 begin
4750   {$IFDEF QtUseAccurateFrame}
4751   if IsFramedWidget then
4752   begin
4753     ASize := getFrameSize;
4754     Result := ASize.cx;
4755   end else
4756   {$ENDIF}
4757     Result := QWidget_width(Widget);
4758 end;
4759 
TQtWidget.getWindownull4760 function TQtWidget.getWindow: TQtWidget;
4761 var
4762   W: QWidgetH;
4763 begin
4764   Result := nil;
4765   W := QWidget_window(Widget);
4766   if W <> nil then
4767     Result := TQtWidget(HwndFromWidgetH(W));
4768 end;
4769 
getWindowStatenull4770 function TQtWidget.getWindowState: QtWindowStates;
4771 begin
4772   Result := QWidget_windowState(Widget);
4773 end;
4774 
getClientBoundsnull4775 function TQtWidget.getClientBounds: TRect;
4776 {$IFDEF VerboseQtResizeError}
4777 var
4778   R: TRect;
4779 {$ENDIF}
4780 begin
4781   QWidget_contentsRect(getContainerWidget, @Result);
4782   {only when FOwner implements it's own getClientBounds !
4783    Valid for FOwner: TQtTabWidget, TQtAbstractScrollArea and it's successors}
4784   if (FOwner <> nil) and
4785     not (ChildOfComplexWidget in [ccwComboBox]) then
4786   begin
4787     {$IFDEF VerboseQtResizeError}
4788     R := FOwner.getClientBounds;
4789     if not EqualRect(R, Result) then
4790       DebugLn('WARNING: Providing wrong clientRect ',dbgs(Result),' for ',dbgsName(LCLObject),' from ',dbgsName(Self),' FOwner ',dbgsName(FOwner),' ==>',dbgs(R));
4791     Result := R;
4792     {$ELSE}
4793     Result := FOwner.getClientBounds;
4794     {$ENDIF}
4795   end;
4796 end;
4797 
TQtWidget.getClientOffsetnull4798 function TQtWidget.getClientOffset: TPoint;
4799 var
4800   P: TQtPoint;
4801   R: TRect;
4802   {$IFDEF VerboseQtResizeError}
4803   Pt: TPoint;
4804   {$ENDIF}
4805 begin
4806   // we need an offset of container inside widget, but if container = widget then
4807   // offset = 0
4808   {$IFDEF VerboseQtResizeError}
4809   if Widget <> GetContainerWidget then
4810     QWidget_pos(GetContainerWidget, @P)
4811   else
4812     P := QtPoint(0, 0);
4813   R := getClientBounds;
4814   Result := Point(P.x + R.Left, P.y + R.Top);
4815   if (FOwner <> nil) and
4816     not (ChildOfComplexWidget in [ccwComboBox]) then
4817   begin
4818     Pt := FOwner.getClientOffset;
4819     if (Pt.x <> Result.x) or (Pt.y <> Result.y) then
4820       DebugLn('WARNING: Providing wrong clientOffset ',dbgs(Result),' for ',dbgsName(LCLObject),' from ',dbgsName(Self),' FOwner ',dbgsName(FOwner),' ==>',dbgs(Pt));
4821     Result := Pt;
4822   end;
4823   {$ELSE}
4824   if (FOwner <> nil) and
4825     not (ChildOfComplexWidget in [ccwComboBox]) then
4826   begin
4827     Result := FOwner.getClientOffset;
4828   end else
4829   begin
4830     if Widget <> GetContainerWidget then
4831       QWidget_pos(GetContainerWidget, @P)
4832     else
4833       P := QtPoint(0, 0);
4834     R := getClientBounds;
4835     Result := Point(P.x + R.Left, P.y + R.Top);
4836   end;
4837   {$ENDIF}
4838 end;
4839 
4840 procedure TQtWidget.grabMouse;
4841 begin
4842   //DumpStack;
4843   //DebugLn(['current grab is: ', dbgs(QWidget_mouseGrabber())]);
4844   //DebugLn(['grab mouse for: ', dbgsName(LCLObject), ' : ', dbgs(Widget)]);
4845   QWidget_grabMouse(Widget);
4846 end;
4847 
TQtWidget.hasFocusnull4848 function TQtWidget.hasFocus: Boolean;
4849 begin
4850   Result := QWidget_hasFocus(Widget);
4851 end;
4852 
IsActiveWindownull4853 function TQtWidget.IsActiveWindow: Boolean;
4854 begin
4855   Result := QWidget_isActiveWindow(Widget);
4856 end;
4857 
TQtWidget.isMinimizednull4858 function TQtWidget.isMinimized: Boolean;
4859 begin
4860   Result := QWidget_isMinimized(Widget);
4861 end;
4862 
isMaximizednull4863 function TQtWidget.isMaximized: Boolean;
4864 begin
4865   Result := QWidget_isMaximized(Widget);
4866 end;
4867 
TQtWidget.IsFramedWidgetnull4868 function TQtWidget.IsFramedWidget: boolean;
4869 begin
4870   Result := False;
4871 end;
4872 
TQtWidget.isFullScreennull4873 function TQtWidget.isFullScreen: Boolean;
4874 begin
4875   Result := QWidget_isFullScreen(Widget);
4876 end;
4877 
IsWindownull4878 function TQtWidget.IsWindow: Boolean;
4879 begin
4880   Result := QWidget_isWindow(Widget);
4881 end;
4882 
4883 procedure TQtWidget.lowerWidget;
4884 begin
4885   QWidget_lower(Widget);
4886 end;
4887 
MapToGlobalnull4888 function TQtWidget.MapToGlobal(APt: TPoint;
4889   const AWithScrollOffset: Boolean = False): TPoint;
4890 var
4891   Pt: TQtPoint;
4892   NewPt: TQtPoint;
4893 begin
4894   Pt := QtPoint(APt.X, APt.Y);
4895   NewPt := QtPoint(0, 0);
4896   QWidget_mapToGlobal(GetContainerWidget, @NewPt, @Pt);
4897   Result := Point(NewPt.x, NewPt.y);
4898 end;
4899 
MapFromGlobalnull4900 function TQtWidget.MapFromGlobal(APt: TPoint;
4901   const AWithScrollOffset: Boolean = False): TPoint;
4902 var
4903   Pt: TQtPoint;
4904   NewPt: TQtPoint;
4905 begin
4906   Pt := QtPoint(APt.X, APt.Y);
4907   NewPt := QtPoint(0, 0);
4908   QWidget_mapFromGlobal(GetContainerWidget, @NewPt, @Pt);
4909   Result := Point(NewPt.x, NewPt.y);
4910 end;
4911 
4912 procedure TQtWidget.move(ANewLeft, ANewTop: Integer);
4913 begin
4914   QWidget_move(Widget, ANewLeft, ANewTop);
4915 end;
4916 
4917 procedure TQtWidget.preferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean);
4918 var
4919   PrefSize: TSize;
4920 begin
4921   sizeHint(@PrefSize);
4922   if (PrefSize.cx >= 0) and (PrefSize.cy >=0) then
4923   begin
4924     PreferredWidth := PrefSize.cx;
4925     PreferredHeight := PrefSize.cy;
4926   end;
4927 end;
4928 
4929 procedure TQtWidget.raiseWidget;
4930 begin
4931   QWidget_raise(Widget);
4932 end;
4933 
4934 procedure TQtWidget.stackUnder(AWidget: QWidgetH);
4935 begin
4936   QWidget_stackUnder(Widget, AWidget);
4937 end;
4938 
4939 procedure TQtWidget.frame_resize(ANewWidth, ANewHeight: Integer);
4940 var
4941   R1, R2: TRect;
4942   dw, dh: integer;
4943 begin
4944   {$IFDEF QTUSEACCURATEFRAME}
4945   QWidget_resize(Widget, ANewWidth - (FFrameMargins.Right + FFrameMargins.Left),
4946     ANewHeight - (FFrameMargins.Bottom + FFrameMargins.Top));
4947   {$ELSE}
4948   R1 := getGeometry;
4949   R2 := getFrameGeometry;
4950   dw := (R1.Left - R2.Left) + (R2.Right - R1.Right);
4951   dh := (R1.Top - R2.Top) + (R2.Bottom - R1.Bottom);
4952   QWidget_resize(Widget, ANewWidth - dw, ANewHeight - dh);
4953   {$ENDIF}
4954 end;
4955 
4956 procedure TQtWidget.Resize(ANewWidth, ANewHeight: Integer);
4957 begin
4958   {$IFDEF QTUSEACCURATEFRAME}
4959   if IsFramedWidget then
4960     frame_resize(ANewWidth, ANewHeight)
4961   else
4962   {$ENDIF}
4963     QWidget_resize(Widget, ANewWidth, ANewHeight);
4964 end;
4965 
4966 procedure TQtWidget.releaseMouse;
4967 var
4968   AGrabWidget: QWidgetH;
4969 begin
4970   // capture widget can be one of children of Widget if Widget is complex control
4971   // so better to look for current Capture widget to release it
4972   // instead of pass Widget as argument
4973   AGrabWidget := QWidget_mouseGrabber();
4974   //DebugLn(['releasing current grab: ', dbgs(AGrabWidget)]);
4975   if AGrabWidget <> nil then
4976     QWidget_releaseMouse(AGrabWidget);
4977 end;
4978 
4979 procedure TQtWidget.scroll(dx, dy: integer; ARect: PRect = nil);
4980 begin
4981   if ARect = nil then
4982     QWidget_scroll(getContainerWidget, dx, dy)
4983   else
4984     QWidget_scroll(getContainerWidget, dx, dy, ARect);
4985 end;
4986 
4987 procedure TQtWidget.setAutoFillBackground(const AValue: Boolean);
4988 begin
4989   QWidget_setAutoFillBackground(Widget, AValue);
4990 end;
4991 
4992 procedure TQtWidget.setAttribute(const Attr: QtWidgetAttribute;
4993   const TurnOn: Boolean);
4994 begin
4995   QWidget_setAttribute(Widget, Attr, TurnOn);
4996 end;
4997 
4998 procedure TQtWidget.setBackgroundRole(const ARole: QPaletteColorRole);
4999 begin
5000   QWidget_setBackgroundRole(Widget, ARole);
5001 end;
5002 
5003 procedure TQtWidget.setDefaultColor(const DefaultColorType: TDefaultColorType);
5004 begin
5005   case DefaultColorType of
5006     dctBrush: setColor(@Palette.DefaultColor);
5007     dctFont: setTextColor(@Palette.DefaultTextColor);
5008   end;
5009 end;
5010 
5011 procedure TQtWidget.setEnabled(p1: Boolean);
5012 begin
5013   if not p1 and (HWND(Self) = GetCapture) then
5014     ReleaseCapture;
5015   QWidget_setEnabled(Widget, p1);
5016 end;
5017 
5018 procedure TQtWidget.setFocus;
5019 begin
5020   if getFocusPolicy <> QtNoFocus then
5021     QWidget_setFocus(Widget, QtTabFocusReason)
5022   else
5023     QWidget_setFocus(Widget);
5024 end;
5025 
5026 procedure TQtWidget.setFocusPolicy(const APolicy: QtFocusPolicy);
5027 begin
5028   QWidget_setFocusPolicy(Widget, APolicy);
5029 end;
5030 
5031 procedure TQtWidget.setFocusProxy(const AWidget: QWidgetH);
5032 begin
5033   QWidget_setFocusProxy(Widget, AWidget);
5034 end;
5035 
5036 procedure TQtWidget.setFont(AFont: QFontH);
5037 begin
5038   QWidget_setFont(Widget, AFont);
5039 end;
5040 
5041 procedure TQtWidget.setGeometry(ARect: TRect);
5042 begin
5043   QWidget_setGeometry(Widget, @ARect);
5044 end;
5045 
5046 procedure TQtWidget.setInitialFontColor(AControl: TWinControl);
5047 var
5048   QColor: TQColor;
5049   ColorRef: TColorRef;
5050 begin
5051   if AControl.Font.Color = clDefault then
5052   begin
5053     BeginUpdate;
5054     Palette.ForceColor := True;
5055     SetDefaultColor(dctFont);
5056     Palette.ForceColor := False;
5057     EndUpdate;
5058   end
5059   else
5060   begin
5061     ColorRef := ColorToRGB(AControl.Font.Color);
5062     QColor_fromRgb(@QColor,Red(ColorRef),Green(ColorRef),Blue(ColorRef));
5063     BeginUpdate;
5064     Palette.ForceColor := True;
5065     SetTextColor(@QColor);
5066     Palette.ForceColor := False;
5067     EndUpdate;
5068   end;
5069 end;
5070 
5071 procedure TQtWidget.setLayoutDirection(ADirection: QtLayoutDirection);
5072 begin
5073   QWidget_setLayoutDirection(Widget, ADirection);
5074 end;
5075 
5076 procedure TQtWidget.setMaximumSize(AWidth, AHeight: Integer);
5077 begin
5078   {$IFDEF QTUSEACCURATEFRAME}
5079   if IsFramedWidget then
5080     QWidget_setMaximumSize(Widget, AWidth - (FFrameMargins.Right + FFrameMargins.Left),
5081       AHeight - (FFrameMargins.Bottom + FFrameMargins.Top))
5082   else
5083   {$ENDIF}
5084   QWidget_setMaximumSize(Widget, AWidth, AHeight);
5085 end;
5086 
5087 procedure TQtWidget.setMask(AMask: QBitmapH);
5088 begin
5089   QWidget_setMask(Widget, AMask);
5090 end;
5091 
5092 procedure TQtWidget.setMask(AMask: QRegionH);
5093 begin
5094   QWidget_setMask(Widget, AMask);
5095 end;
5096 
5097 procedure TQtWidget.setMinimumSize(AWidth, AHeight: Integer);
5098 begin
5099   {$IFDEF QTUSEACCURATEFRAME}
5100   if IsFramedWidget then
5101     QWidget_setMinimumSize(Widget, Max(0, AWidth - (FFrameMargins.Right + FFrameMargins.Left)),
5102       Max(0, AHeight - (FFrameMargins.Bottom + FFrameMargins.Top)))
5103   else
5104   {$ENDIF}
5105   QWidget_setMinimumSize(Widget, AWidth, AHeight);
5106 end;
5107 
5108 procedure TQtWidget.setVisible(AVisible: Boolean);
5109 begin
5110   QWidget_setVisible(Widget, AVisible);
5111 end;
5112 
windowModalitynull5113 function TQtWidget.windowModality: QtWindowModality;
5114 begin
5115   Result := QWidget_windowModality(Widget);
5116 end;
5117 
5118 procedure TQtWidget.setWindowModality(windowModality: QtWindowModality);
5119 begin
5120   QWidget_setWindowModality(Widget, windowModality);
5121 end;
5122 
5123 procedure TQtWidget.setWindowOpacity(opacity: double);
5124 begin
5125   QWidget_setWindowOpacity(Widget, opacity);
5126 end;
5127 
5128 procedure TQtWidget.setParent(parent: QWidgetH);
5129 begin
5130   QWidget_setParent(Widget, parent);
5131 end;
5132 
5133 procedure TQtWidget.setText(const W: WideString);
5134 begin
5135   FText := W;
5136 end;
5137 
5138 procedure TQtWidget.setWindowFlags(_type: QtWindowFlags);
5139 begin
5140   QWidget_setWindowFlags(Widget, _type);
5141 end;
5142 
5143 procedure TQtWidget.setWindowIcon(AIcon: QIconH);
5144 var
5145   DestroyIcon: Boolean;
5146 begin
5147   DestroyIcon := AIcon = nil;
5148   if DestroyIcon then
5149     AIcon := QIcon_create();
5150   QWidget_setWindowIcon(Widget, AIcon);
5151   if DestroyIcon then
5152     QIcon_destroy(AIcon);
5153 end;
5154 
TQtWidget.windowFlagsnull5155 function TQtWidget.windowFlags: QtWindowFlags;
5156 begin
5157   Result := QWidget_windowFlags(Widget);
5158 end;
5159 
5160 procedure TQtWidget.setWidth(p1: Integer);
5161 var
5162   R: TRect;
5163 begin
5164   R := getGeometry;
5165   R.Right := R.Left + p1;
5166   setGeometry(R);
5167 end;
5168 
5169 procedure TQtWidget.setHeight(p1: Integer);
5170 var
5171   R: TRect;
5172 begin
5173   R := getGeometry;
5174   R.Bottom := R.Top + p1;
5175   setGeometry(R);
5176 end;
5177 
5178 procedure TQtWidget.setUpdatesEnabled(const AEnabled: Boolean);
5179 begin
5180   QWidget_setUpdatesEnabled(Widget, AEnabled);
5181 end;
5182 
5183 procedure TQtWidget.setWindowState(AState: QtWindowStates);
5184 begin
5185   QWidget_setWindowState(Widget, AState);
5186 end;
5187 
5188 procedure TQtWidget.sizeHint(size: PSize);
5189 begin
5190   QWidget_sizeHint(Widget, size);
5191 end;
5192 
TQtWidget.testAttributenull5193 function TQtWidget.testAttribute(const AAttribute: QtWidgetAttribute): boolean;
5194 begin
5195   Result := QWidget_testAttribute(Widget, AAttribute);
5196 end;
5197 
5198 {------------------------------------------------------------------------------
5199   Function: TQtWidget.QtKeyToLCLKey
5200   Params:  None
5201   Returns: Nothing
5202  ------------------------------------------------------------------------------}
QtKeyToLCLKeynull5203 function TQtWidget.QtKeyToLCLKey(AKey: Integer; AText: WideString;
5204   AEvent: QKeyEventH): Word;
5205 begin
5206   // The big problem here with unicode keys
5207   // Example: for Russian letter A qt returns AKey = $0410 and this is
5208   // absolutely correct: 0400 - 04FF - is russian unicode space and
5209   // 0410 is defined as "CYRILLIC CAPITAL LETTER A"
5210 
5211   Result := VK_UNKNOWN;
5212   case AKey of
5213     QtKey_0..QtKey_9: Result := VK_0 + (AKey - QtKey_0);
5214     QtKey_At: Result := VK_2; // some bug, but Ctrl + Shit + 2 produce QtKey_At
5215     QtKey_Escape: Result := VK_ESCAPE;
5216     QtKey_Tab: Result := VK_TAB;
5217     QtKey_Backtab: Result := VK_TAB; // ???
5218     QtKey_Backspace: Result := VK_BACK;
5219     QtKey_Return: Result := VK_RETURN;
5220     QtKey_Enter: Result := VK_RETURN;
5221     QtKey_Insert: Result := VK_INSERT;
5222     QtKey_Delete: Result := VK_DELETE;
5223     QtKey_Pause: Result := VK_PAUSE;
5224     QtKey_Print: Result := VK_PRINT;
5225     QtKey_SysReq: Result := VK_UNKNOWN; // ???
5226     QtKey_Clear: Result := VK_CLEAR;
5227     QtKey_Home: Result := VK_HOME;
5228     QtKey_End: Result := VK_END;
5229     QtKey_Left: Result := VK_LEFT;
5230     QtKey_Up: Result := VK_UP;
5231     QtKey_Right: Result := VK_RIGHT;
5232     QtKey_Down: Result := VK_DOWN;
5233     QtKey_PageUp: Result := VK_PRIOR;
5234     QtKey_PageDown: Result := VK_NEXT;
5235     QtKey_Shift: Result := VK_SHIFT;     // There is also RSHIFT
5236     QtKey_Control: Result := VK_CONTROL; // There is also RCONTROL
5237     QtKey_Meta:
5238     begin
5239       //TODO: Qt sends meta key, but info about left & right is in nativeScanCode
5240       {$IFDEF HASX11}
5241       if QKeyEvent_nativeVirtualKey(AEvent) = XK_Super_L then
5242         Result := VK_LWIN
5243       else
5244       if QKeyEvent_nativeVirtualKey(AEvent) = XK_Super_R then
5245         Result := VK_RWIN
5246       else
5247         Result := VK_MENU;
5248       {$ELSE}
5249       Result := VK_LWIN;
5250       {$ENDIF}
5251     end;
5252     QtKey_Alt: Result := VK_MENU;
5253     QtKey_AltGr: Result := VK_RMENU;
5254     QtKey_CapsLock: Result := VK_CAPITAL;
5255     QtKey_NumLock: Result := VK_NUMLOCK;
5256     QtKey_ScrollLock: Result := VK_SCROLL;
5257     QtKey_F1..QtKey_F24: Result := VK_F1 + (AKey - QtKey_F1);
5258     QtKey_F25..
5259     QtKey_F35: Result := VK_UNKNOWN;
5260     QtKey_Super_L: Result := VK_LWIN;
5261     QtKey_Super_R: Result := VK_RWIN;
5262     QtKey_Menu: Result := VK_APPS;
5263     QtKey_Hyper_L,
5264     QtKey_Hyper_R: Result := VK_UNKNOWN;
5265     QtKey_Help: Result := VK_HELP;
5266     QtKey_Direction_L,
5267     QtKey_Direction_R,
5268     QtKey_Exclam,QtKey_NumberSign..
5269     QtKey_AmperSand,
5270     QtKey_ParenLeft,
5271     QtKey_ParenRight: Result := VK_UNKNOWN;
5272     QtKey_Asterisk: Result := VK_MULTIPLY;
5273     QtKey_Plus: Result := VK_ADD;
5274     QtKey_Comma: Result := VK_SEPARATOR;
5275     QtKey_Minus: Result := VK_SUBTRACT;
5276     QtKey_Period: Result := VK_DECIMAL;
5277     QtKey_Slash: Result := VK_DIVIDE;
5278     QtKey_Equal: Result := VK_OEM_PLUS;
5279 
5280     QtKey_Colon,
5281     QtKey_Semicolon: Result := VK_OEM_1;
5282     QtKey_AsciiTilde: Result := VK_OEM_3;
5283     QtKey_BraceLeft,
5284     QtKey_BracketLeft: Result := VK_OEM_4;
5285     QtKey_BackSlash: Result := VK_OEM_5;
5286     QtKey_BraceRight,
5287     QtKey_BracketRight: Result := VK_OEM_6;
5288     QtKey_QuoteDbl,
5289     QtKey_Apostrophe: Result := VK_OEM_7;
5290     QtKey_Less: Result := VK_OEM_COMMA;
5291     QtKey_Greater: Result := VK_OEM_PERIOD;
5292 
5293     QtKey_ydiaeresis,
5294     QtKey_Multi_key..
5295     QtKey_No: Result := VK_UNKNOWN;
5296     QtKey_Cancel: Result := VK_CANCEL;
5297     QtKey_Printer: Result := VK_PRINT;
5298     QtKey_Execute: Result := VK_EXECUTE;
5299     QtKey_Sleep: Result := VK_SLEEP;
5300     QtKey_Play: Result := VK_PLAY;
5301     QtKey_Zoom: Result := VK_ZOOM;
5302     QtKey_Context1..
5303     QtKey_Flip,
5304     QtKey_unknown: Result := VK_UNKNOWN;
5305   else
5306     if AKey in [0..255] then // Qt:AKey = VK_KEY in many cases
5307       Result := AKey
5308     else
5309     if AText <> '' then
5310     begin
5311       // use QChar to understand whether we have unicode letter or number here or no
5312       // then try to map that char to VK_ code
5313     end;
5314   end;
5315 end;
5316 
5317 procedure TQtWidget.SetLastCaretPos(const AValue: TQtPoint);
5318 begin
5319   FLastCaretPos := AValue;
5320 end;
5321 
5322 procedure TQtWidget.SetHasCaret(const AValue: Boolean);
5323 begin
5324   FHasCaret := AValue;
5325 end;
5326 
ProcessArrowKeysnull5327 function TQtWidget.ProcessArrowKeys: Boolean;
5328 begin
5329   Result := False;
5330 end;
5331 
5332 class procedure TQtWidget.removeProperty(AObject: QObjectH; APropName: PAnsiChar);
5333 var
5334   AVariant: QVariantH;
5335 begin
5336   AVariant := QVariant_create;
5337   QObject_setProperty(AObject, APropName, AVariant);
5338   QVariant_destroy(AVariant);
5339 end;
5340 
5341 class procedure TQtWidget.setProperty(AObject: QObjectH; APropName: PAnsiChar; APropValue: Int64);
5342 var
5343   AVariant: QVariantH;
5344 begin
5345   AVariant := QVariant_create(APropValue);
5346   QObject_setProperty(AObject, APropName, AVariant);
5347   QVariant_destroy(AVariant);
5348 end;
5349 
LCLKeyToQtKeynull5350 function TQtWidget.LCLKeyToQtKey(AKey: Word): Integer;
5351 const
5352   VKKeyToQtKeyMap: array[0..255] of Integer = // Keyboard mapping table
5353    (
5354     QtKey_unknown,
5355     QtKey_unknown,
5356     QtKey_unknown,
5357     QtKey_Cancel,
5358     QtKey_unknown,
5359     QtKey_unknown,
5360     QtKey_unknown,
5361     QtKey_unknown,
5362     QtKey_Backspace,
5363     QtKey_Tab,
5364     QtKey_unknown,
5365     QtKey_unknown,
5366     QtKey_Clear,
5367     QtKey_Return,
5368     QtKey_unknown,
5369     QtKey_unknown,
5370     QtKey_Shift,
5371     QtKey_Control,
5372     QtKey_Alt,
5373     QtKey_Pause,
5374     QtKey_CapsLock,
5375     QtKey_unknown,
5376     QtKey_unknown,
5377     QtKey_unknown,
5378     QtKey_unknown,
5379     QtKey_unknown,
5380     QtKey_unknown,
5381     QtKey_Escape,
5382     QtKey_unknown,
5383     QtKey_unknown,
5384     QtKey_unknown,
5385     QtKey_Mode_switch,
5386     QtKey_Space,
5387     QtKey_PageUp,
5388     QtKey_PageDown,
5389     QtKey_End,
5390     QtKey_Home,
5391     QtKey_Left,
5392     QtKey_Up,
5393     QtKey_Right,
5394     QtKey_Down,
5395     QtKey_Select,
5396     QtKey_Printer,
5397     QtKey_Execute,
5398     QtKey_Print,
5399     QtKey_Insert,
5400     QtKey_Delete,
5401     QtKey_Help,
5402     QtKey_0,
5403     QtKey_1,
5404     QtKey_2,
5405     QtKey_3,
5406     QtKey_4,
5407     QtKey_5,
5408     QtKey_6,
5409     QtKey_7,
5410     QtKey_8,
5411     QtKey_9,
5412     QtKey_unknown,
5413     QtKey_unknown,
5414     QtKey_unknown,
5415     QtKey_unknown,
5416     QtKey_unknown,
5417     QtKey_unknown,
5418     QtKey_unknown,
5419     QtKey_A,
5420     QtKey_B,
5421     QtKey_C,
5422     QtKey_D,
5423     QtKey_E,
5424     QtKey_F,
5425     QtKey_G,
5426     QtKey_H,
5427     QtKey_I,
5428     QtKey_J,
5429     QtKey_K,
5430     QtKey_L,
5431     QtKey_M,
5432     QtKey_N,
5433     QtKey_O,
5434     QtKey_P,
5435     QtKey_Q,
5436     QtKey_R,
5437     QtKey_S,
5438     QtKey_T,
5439     QtKey_U,
5440     QtKey_V,
5441     QtKey_W,
5442     QtKey_X,
5443     QtKey_Y,
5444     QtKey_Z,
5445     QtKey_Meta,
5446     QtKey_Meta,
5447     QtKey_Menu,
5448     QtKey_unknown,
5449     QtKey_Sleep,
5450     QtKey_0,
5451     QtKey_1,
5452     QtKey_2,
5453     QtKey_3,
5454     QtKey_4,
5455     QtKey_5,
5456     QtKey_6,
5457     QtKey_7,
5458     QtKey_8,
5459     QtKey_9,
5460     QtKey_Asterisk,
5461     QtKey_Plus,
5462     QtKey_Comma,
5463     QtKey_Minus,
5464     QtKey_Period,
5465     QtKey_Slash,
5466     QtKey_F1,
5467     QtKey_F2,
5468     QtKey_F3,
5469     QtKey_F4,
5470     QtKey_F5,
5471     QtKey_F6,
5472     QtKey_F7,
5473     QtKey_F8,
5474     QtKey_F9,
5475     QtKey_F10,
5476     QtKey_F11,
5477     QtKey_F12,
5478     QtKey_F13,
5479     QtKey_F14,
5480     QtKey_F15,
5481     QtKey_F16,
5482     QtKey_F17,
5483     QtKey_F18,
5484     QtKey_F19,
5485     QtKey_F20,
5486     QtKey_F21,
5487     QtKey_F22,
5488     QtKey_F23,
5489     QtKey_F24,
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_NumLock,
5499     QtKey_ScrollLock,
5500     QtKey_unknown,
5501     QtKey_Massyo,
5502     QtKey_Touroku,
5503     QtKey_unknown,
5504     QtKey_unknown,
5505     QtKey_unknown,
5506     QtKey_unknown,
5507     QtKey_unknown,
5508     QtKey_unknown,
5509     QtKey_unknown,
5510     QtKey_unknown,
5511     QtKey_unknown,
5512     QtKey_unknown,
5513     QtKey_unknown,
5514     QtKey_Shift,
5515     QtKey_Shift,
5516     QtKey_Control,
5517     QtKey_Control,
5518     QtKey_Alt,
5519     QtKey_Alt,
5520     QtKey_Back,
5521     QtKey_Forward,
5522     QtKey_Refresh,
5523     QtKey_Stop,
5524     QtKey_Search,
5525     QtKey_Favorites,
5526     QtKey_HomePage,
5527     QtKey_VolumeMute,
5528     QtKey_VolumeDown,
5529     QtKey_VolumeUp,
5530     QtKey_MediaNext,
5531     QtKey_MediaPrevious,
5532     QtKey_MediaStop,
5533     QtKey_MediaPlay,
5534     QtKey_LaunchMail,
5535     QtKey_LaunchMedia,
5536     QtKey_Launch0,
5537     QtKey_Launch1,
5538     QtKey_unknown,
5539     QtKey_unknown,
5540     QtKey_1,
5541     QtKey_Plus,
5542     QtKey_Comma,
5543     QtKey_Minus,
5544     QtKey_Period,
5545     QtKey_2,
5546     QtKey_3,
5547     QtKey_unknown,
5548     QtKey_unknown,
5549     QtKey_unknown,
5550     QtKey_unknown,
5551     QtKey_unknown,
5552     QtKey_unknown,
5553     QtKey_unknown,
5554     QtKey_unknown,
5555     QtKey_unknown,
5556     QtKey_unknown,
5557     QtKey_unknown,
5558     QtKey_unknown,
5559     QtKey_unknown,
5560     QtKey_unknown,
5561     QtKey_unknown,
5562     QtKey_unknown,
5563     QtKey_unknown,
5564     QtKey_unknown,
5565     QtKey_unknown,
5566     QtKey_unknown,
5567     QtKey_unknown,
5568     QtKey_unknown,
5569     QtKey_unknown,
5570     QtKey_unknown,
5571     QtKey_unknown,
5572     QtKey_unknown,
5573     QtKey_4,
5574     QtKey_5,
5575     QtKey_6,
5576     QtKey_7,
5577     QtKey_8,
5578     QtKey_unknown,
5579     QtKey_unknown,
5580     QtKey_unknown,
5581     QtKey_unknown,
5582     QtKey_unknown,
5583     QtKey_unknown,
5584     QtKey_unknown,
5585     QtKey_unknown,
5586     QtKey_unknown,
5587     QtKey_unknown,
5588     QtKey_unknown,
5589     QtKey_unknown,
5590     QtKey_unknown,
5591     QtKey_unknown,
5592     QtKey_unknown,
5593     QtKey_unknown,
5594     QtKey_unknown,
5595     QtKey_unknown,
5596     QtKey_unknown,
5597     QtKey_unknown,
5598     QtKey_unknown,
5599     QtKey_unknown,
5600     QtKey_unknown,
5601     QtKey_unknown,
5602     QtKey_unknown,
5603     QtKey_unknown,
5604     QtKey_Play,
5605     QtKey_Zoom,
5606     QtKey_unknown,
5607     QtKey_unknown,
5608     QtKey_Clear,
5609     QtKey_unknown
5610    );
5611 begin
5612   if AKey > 255 then
5613     Result := QtKey_unknown
5614   else
5615     Result := VKKeyToQtKeyMap[AKey];
5616 end;
5617 
TQtWidget.ShiftStateToQtModifiersnull5618 function TQtWidget.ShiftStateToQtModifiers(Shift: TShiftState): QtModifier;
5619 begin
5620   Result := 0;
5621   if ssCtrl  in Shift then inc(Result, QtCTRL);
5622   if ssShift in Shift then Inc(Result, QtSHIFT);
5623   if ssMeta  in Shift then Inc(Result, QtMETA);
5624   if ssAlt   in Shift then Inc(Result, QtALT);
5625 end;
5626 
TQtWidget.QueryInterfacenull5627 function TQtWidget.QueryInterface(constref iid: TGuid; out obj): LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
5628 begin
5629   if GetInterface(iid, obj) then
5630     Result := 0
5631   else
5632     Result := E_NOINTERFACE;
5633 end;
5634 
_AddRefnull5635 function TQtWidget._AddRef: longint; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
5636 begin
5637   Result := -1; // no ref counting
5638 end;
5639 
_Releasenull5640 function TQtWidget._Release: longint; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
5641 begin
5642   Result := -1;
5643 end;
5644 
TQtWidget.GetPropsnull5645 function TQtWidget.GetProps(const AnIndex: String): pointer;
5646 var
5647   i: Integer;
5648 begin
5649   if (Fprops<>nil) then
5650   begin
5651     i:=Fprops.IndexOf(AnIndex);
5652     if i>=0 then
5653     begin
5654       result:=Fprops.Objects[i];
5655       exit;
5656     end;
5657   end;
5658   result := nil;
5659 end;
5660 
TQtWidget.getScrolledOffsetnull5661 function TQtWidget.getScrolledOffset: TPoint;
5662 begin
5663   Result := Point(-FScrollX, -FScrollY);
5664 end;
5665 
TQtWidget.GetStyleSheetnull5666 function TQtWidget.GetStyleSheet: WideString;
5667 var
5668   WStr: WideString;
5669 begin
5670   QWidget_styleSheet(Widget, @WStr);
5671   Result := UTF16ToUTF8(WStr);
5672 end;
5673 
5674 {------------------------------------------------------------------------------
5675   Function: TQtWidget.GetPalette
5676   Params:  Nothing
5677   Returns: TQtWidgetPalette
5678 
5679   Assigns default widget palette, also takes care of widget colors changing.
5680  ------------------------------------------------------------------------------}
GetPalettenull5681 function TQtWidget.GetPalette: TQtWidgetPalette;
5682 begin
5683   if not Assigned(FPalette) then
5684   begin
5685     if (ClassType = TQtCustomControl) then
5686       FPalette := TQtWidgetPalette.Create(WidgetColorRole, TextColorRole,
5687         TQtCustomControl(Self).viewport.Widget)
5688     else
5689       FPalette := TQtWidgetPalette.Create(WidgetColorRole, TextColorRole, Widget);
5690   end;
5691   Result := FPalette;
5692 end;
5693 
TQtWidget.GetContextnull5694 function TQtWidget.GetContext: HDC;
5695 begin
5696   Result := FContext;
5697 end;
5698 
TQtWidget.GetWidgetnull5699 function TQtWidget.GetWidget: QWidgetH;
5700 begin
5701   Result := QWidgetH(TheObject);
5702 end;
5703 
TQtWidget.DeliverMessagenull5704 function TQtWidget.DeliverMessage(var Msg;
5705   const AIsInputEvent: Boolean = False): LRESULT;
5706 var
5707   AEvent: Cardinal;
5708 begin
5709   Result := LRESULT(AIsInputEvent);
5710   if LCLObject = nil then
5711     Exit;
5712   AEvent := TLMessage(Msg).Msg;
5713   try
5714     if LCLObject.HandleAllocated then
5715     begin
5716       LCLObject.WindowProc(TLMessage(Msg));
5717       Result := TLMessage(Msg).Result;
5718     end;
5719   except
5720     Result := 1;
5721     if AIsInputEvent and (LCLObject = nil) and (PtrUInt(Widget) = 0) and
5722       QtWidgetSet.IsValidHandle(HWND(Self)) then
5723     begin
5724       DebugLn(Format('WARNING: %s has been destroyed while processing input event %u result %u',
5725         [ClassName, AEvent, Result]));
5726     end else
5727       Application.HandleException(nil);
5728   end;
5729 end;
5730 
5731 procedure TQtWidget.SetProps(const AnIndex: String; const AValue: pointer);
5732 var
5733   i: Integer;
5734 begin
5735   if FProps=nil then
5736   begin
5737     FProps:=TStringList.Create;
5738     //FProps.CaseSensitive:=false;
5739     FProps.Sorted:=true;
5740   end;
5741   i := Fprops.IndexOf(AnIndex);
5742   if i < 0 then
5743     i := FProps.Add(AnIndex);
5744   Fprops.Objects[i] := TObject(AValue);
5745 end;
5746 
5747 procedure TQtWidget.SetStyleSheet(const AValue: WideString);
5748 var
5749   WStr: WideString;
5750 begin
5751   WStr := GetUTF8String(AValue);
5752   QWidget_setStyleSheet(Widget, @WStr);
5753 end;
5754 
5755 procedure TQtWidget.SetWidget(const AValue: QWidgetH);
5756 begin
5757   TheObject := AValue;
5758 end;
5759 
TQtWidget.CreateWidgetnull5760 function TQtWidget.CreateWidget(const Params: TCreateParams): QWidgetH;
5761 var
5762   Parent: QWidgetH;
5763 begin
5764   FHasPaint := True;
5765 
5766   if Params.WndParent <> 0 then
5767     Parent := TQtWidget(Params.WndParent).GetContainerWidget
5768   else
5769     Parent := nil;
5770 
5771   Widget := QWidget_create(Parent);
5772   Result := Widget;
5773 end;
5774 
5775 procedure TQtWidget.DestroyWidget;
5776 begin
5777   if (Widget <> nil) and FOwnWidget then
5778     QObject_deleteLater(Widget);
5779   Widget := nil;
5780 end;
5781 
5782 { TQtAbstractButton }
5783 
5784 procedure TQtAbstractButton.setIcon(AIcon: QIconH);
5785 begin
5786   QAbstractButton_setIcon(QAbstractButtonH(Widget), AIcon);
5787 end;
5788 
5789 procedure TQtAbstractButton.setIconSize(Size: PSize);
5790 begin
5791   QAbstractButton_setIconSize(QAbstractButtonH(Widget), Size);
5792 end;
5793 
5794 procedure TQtAbstractButton.setShortcut(AShortCutK1, AShortCutK2: TShortcut);
5795 var
5796   Key: Word;
5797   Shift: TShiftState;
5798   QtK1, QtK2: integer;
5799   KeySequence: QKeySequenceH;
5800 begin
5801   QtK1 := 0;
5802   QtK2 := 0;
5803   if AShortCutK1 <> 0 then
5804   begin
5805     ShortCutToKey(AShortCutK1, Key, Shift);
5806     QtK1 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
5807     if AShortCutK2 <> 0 then
5808     begin
5809       ShortCutToKey(AShortCutK2, Key, Shift);
5810       QtK2 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
5811     end;
5812   end;
5813   KeySequence := QKeySequence_create(QtK1, QtK2);
5814   QAbstractButton_setShortcut(QAbstractButtonH(Widget), KeySequence);
5815   QKeySequence_destroy(KeySequence);
5816 end;
5817 
5818 {------------------------------------------------------------------------------
5819   Function: TQtAbstractButton.SetText
5820   Params:  None
5821   Returns: Nothing
5822  ------------------------------------------------------------------------------}
5823 procedure TQtAbstractButton.SetText(const W: WideString);
5824 begin
5825   QAbstractButton_setText(QAbstractButtonH(Widget), @W);
5826 end;
5827 
TQtAbstractButton.ProcessArrowKeysnull5828 function TQtAbstractButton.ProcessArrowKeys: Boolean;
5829 begin
5830   Result := True;
5831 end;
5832 
TQtAbstractButton.CanPaintBackgroundnull5833 function TQtAbstractButton.CanPaintBackground: Boolean;
5834 begin
5835   Result := CanSendLCLMessage and getEnabled and
5836     (LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
5837     // DO NOT REMOVE ! QCheckBox,QRadioButton default = clBackground  !
5838 end;
5839 
TQtAbstractButton.getIconSizenull5840 function TQtAbstractButton.getIconSize: TSize;
5841 begin
5842   QAbstractButton_iconSize(QAbstractButtonH(Widget), @Result);
5843 end;
5844 
5845 {------------------------------------------------------------------------------
5846   Function: TQtAbstractButton.Text
5847   Params:  None
5848   Returns: Nothing
5849  ------------------------------------------------------------------------------}
getTextnull5850 function TQtAbstractButton.getText: WideString;
5851 begin
5852   QAbstractButton_text(QAbstractButtonH(Widget), @Result);
5853 end;
5854 
5855 procedure TQtAbstractButton.Toggle;
5856 begin
5857   QAbstractButton_toggle(QAbstractButtonH(Widget));
5858 end;
5859 
5860 {------------------------------------------------------------------------------
5861   Function: TQtAbstractButton.isChecked
5862   Params:  None
5863   Returns: Nothing
5864  ------------------------------------------------------------------------------}
TQtAbstractButton.isCheckednull5865 function TQtAbstractButton.isChecked: Boolean;
5866 begin
5867   Result := QAbstractButton_isChecked(QAbstractButtonH(Widget));
5868 end;
5869 
TQtAbstractButton.isDownnull5870 function TQtAbstractButton.isDown: Boolean;
5871 begin
5872   Result := QAbstractButton_isDown(QAbstractButtonH(Widget));
5873 end;
5874 
5875 procedure TQtAbstractButton.setCheckable(p1: Boolean);
5876 begin
5877   QAbstractButton_setCheckable(QAbstractButtonH(Widget), p1);
5878 end;
5879 
5880 {------------------------------------------------------------------------------
5881   Function: TQtAbstractButton.setChecked
5882   Params:  None
5883   Returns: Nothing
5884  ------------------------------------------------------------------------------}
5885 procedure TQtAbstractButton.setChecked(p1: Boolean);
5886 begin
5887   QAbstractButton_setChecked(QAbstractButtonH(Widget), p1);
5888 end;
5889 
5890 procedure TQtAbstractButton.setDefaultColorRoles;
5891 begin
5892   WidgetColorRole := QPaletteButton;
5893   TextColorRole := QPaletteButtonText;
5894 end;
5895 
5896 procedure TQtAbstractButton.setDown(p1: Boolean);
5897 begin
5898   QAbstractButton_setDown(QAbstractButtonH(Widget), p1);
5899 end;
5900 
5901 {------------------------------------------------------------------------------
5902   Function: TQtAbstractButton.SignalPressed
5903   Params:  None
5904   Returns: Nothing
5905  ------------------------------------------------------------------------------}
5906 procedure TQtAbstractButton.SignalPressed; cdecl;
5907 var
5908   Msg: TLMessage;
5909 begin
5910   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5911   Msg.Msg := LM_KEYDOWN;
5912   DeliverMessage(Msg);
5913 end;
5914 
5915 {------------------------------------------------------------------------------
5916   Function: TQtAbstractButton.SignalReleased
5917   Params:  None
5918   Returns: Nothing
5919  ------------------------------------------------------------------------------}
5920 procedure TQtAbstractButton.SignalReleased; cdecl;
5921 var
5922   Msg: TLMessage;
5923 begin
5924   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5925   Msg.Msg := LM_KEYUP;
5926   DeliverMessage(Msg);
5927 end;
5928 
5929 {------------------------------------------------------------------------------
5930   Function: TQtAbstractButton.SignalClicked
5931   Params:  None
5932   Returns: Nothing
5933  ------------------------------------------------------------------------------}
5934 procedure TQtAbstractButton.SignalClicked(Checked: Boolean = False); cdecl;
5935 var
5936   Msg: TLMessage;
5937 begin
5938   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5939   Msg.Msg := LM_CHANGED;
5940   DeliverMessage(Msg);
5941 end;
5942 
5943 {------------------------------------------------------------------------------
5944   Function: TQtAbstractButton.SignalClicked2
5945   Params:  None
5946   Returns: Nothing
5947  ------------------------------------------------------------------------------}
5948 procedure TQtAbstractButton.SignalClicked2; cdecl;
5949 var
5950   Msg: TLMessage;
5951 begin
5952   FillChar(Msg{%H-}, SizeOf(Msg), #0);
5953   Msg.Msg := LM_CLICKED;
5954   DeliverMessage(Msg);
5955 end;
5956 
5957 { TQtPushButton }
5958 
TQtPushButton.CreateWidgetnull5959 function TQtPushButton.CreateWidget(const AParams: TCreateParams): QWidgetH;
5960 var
5961   Parent: QWidgetH;
5962 begin
5963   if AParams.WndParent <> 0 then
5964     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
5965   else
5966     Parent := nil;
5967   Result := QPushButton_create(Parent);
5968 end;
5969 
5970 procedure TQtPushButton.preferredSize(var PreferredWidth,
5971   PreferredHeight: integer; WithThemeSpace: Boolean);
5972 var
5973   Size: TSize;
5974 
AutoSizeButtonFromStylenull5975   function AutoSizeButtonFromStyle(const ASize: TSize): TSize;
5976   var
5977     AOpt: QStyleOptionButtonH;
5978     AText: WideString;
5979     AMetrics: QFontMetricsH;
5980     BtnWidth: Integer;
5981     BtnHeight: Integer;
5982     AIcon: QIconH;
5983     IconSize: TSize;
5984     {style pixel metrics}
5985     BtnMargin, FocusH, FocusV, ShiftH, ShiftV: Integer;
5986   begin
5987     Result := ASize;
5988     AOpt := QStyleOptionButton_create();
5989     QStyleOption_initFrom(AOpt, Widget);
5990     AText := getText;
5991     QStyleOptionButton_setText(AOpt, @AText);
5992     AMetrics := QFontMetrics_create(QWidget_font(Widget));
5993     try
5994       QStyleOption_fontMetrics(AOpt, AMetrics);
5995       BtnWidth := QFontMetrics_width(AMetrics, PWideString(@AText));
5996       BtnHeight := QFontMetrics_height(AMetrics);
5997       Result.cx := BtnWidth;
5998       Result.cy := BtnHeight;
5999 
6000       BtnMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
6001       FocusV := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
6002       FocusH := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
6003       ShiftH := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
6004       ShiftV := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
6005 
6006       if ShiftH = 0 then
6007         ShiftH := FocusH;
6008 
6009       //writeln('ButtonSizeFromStyle:  Metrics W=',BtnWidth,' H=',BtnHeight,
6010       //  ' BtnMargin ',BtnMargin,' FocusV ',FocusV,' FocusH ',FocusH,
6011       //  ' ShiftH ',ShiftH,' ShiftV ',ShiftV);
6012 
6013       Result.cx := Result.cx + BtnMargin + (FocusH * 2) + (ShiftH * 2);
6014       Result.cy := Result.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2);
6015 
6016       // now check if we have icon
6017       AIcon := QIcon_create();
6018       try
6019         QAbstractButton_icon(QPushButtonH(Widget), AIcon);
6020         if not QIcon_isNull(AIcon) then
6021         begin
6022           QAbstractButton_iconSize(QPushButtonH(Widget), @IconSize);
6023           Result.cx := Result.cx + IconSize.cx + (FocusH * 2) + (ShiftH * 2);
6024           if IconSize.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2) > Result.cy then
6025             Result.cy := IconSize.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2);
6026         end;
6027       finally
6028         QIcon_destroy(AIcon);
6029       end;
6030 
6031     finally
6032       QStyleOptionButton_destroy(AOpt);
6033       QFontMetrics_destroy(AMetrics);
6034     end;
6035   end;
6036 begin
6037   // qt doesn't return proper autosize for us.QSizePolicy class is missing.
6038   QPushButton_sizeHint(QPushButtonH(Widget), @Size);
6039   {qtlcl implementation of buttons autosizing, replace if/when we
6040    get QSizePolicy class into bindings}
6041   if Assigned(LCLObject) and LCLObject.AutoSize then
6042     Size := AutoSizeButtonFromStyle(Size);
6043   PreferredWidth := Size.cx;
6044   PreferredHeight := Size.cy;
6045 end;
6046 
6047 procedure TQtPushButton.SetDefault(const ADefault: Boolean);
6048 begin
6049   QPushButton_setDefault(QPushButtonH(Widget), ADefault);
6050 end;
6051 
6052 procedure TQtPushButton.AttachEvents;
6053 begin
6054   inherited AttachEvents;
6055 
6056   FClickedHook := QAbstractButton_hook_create(Widget);
6057   QAbstractButton_hook_hook_clicked2(FClickedHook, @SlotClicked);
6058 
6059   FToggledHook := QAbstractButton_hook_create(Widget);
6060   QAbstractButton_hook_hook_toggled(FToggledHook, @SlotToggled);
6061 end;
6062 
6063 procedure TQtPushButton.DetachEvents;
6064 begin
6065   if FClickedHook <> nil then
6066   begin
6067     QAbstractButton_hook_destroy(FClickedHook);
6068     FClickedHook := nil;
6069   end;
6070   if FToggledHook <> nil then
6071   begin
6072     QAbstractButton_hook_destroy(FToggledHook);
6073     FToggledHook := nil;
6074   end;
6075   inherited DetachEvents;
6076 end;
6077 
6078 {------------------------------------------------------------------------------
6079   Function: TQtPushButton.SlotClicked
6080   Params:  None
6081   Returns: Nothing
6082  ------------------------------------------------------------------------------}
6083 procedure TQtPushButton.SlotClicked; cdecl;
6084 var
6085   Msg: TLMessage;
6086 begin
6087   FillChar(Msg{%H-}, SizeOf(Msg), 0);
6088   Msg.Msg := LM_CLICKED;
6089   DeliverMessage(Msg);
6090 end;
6091 
6092 procedure TQtPushButton.SlotToggled(AChecked: Boolean); cdecl;
6093 begin
6094   // override later (eg. TQtToggleBox)
6095 end;
6096 
6097 { TQtBitBtn }
6098 
CreateWidgetnull6099 function TQtBitBtn.CreateWidget(const AParams: TCreateParams): QWidgetH;
6100 var
6101   Parent: QWidgetH;
6102 begin
6103   HasPaint := True;
6104   FGlyphLayout := 0;
6105   FText := '';
6106   FIcon := nil;
6107   FIconSize.cx := 0;
6108   FIconSize.cy := 0;
6109   if AParams.WndParent <> 0 then
6110     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
6111   else
6112     Parent := nil;
6113   Result := QPushButton_create(Parent);
6114 end;
6115 
6116 destructor TQtBitBtn.Destroy;
6117 begin
6118   if Assigned(FIcon) then
6119     QIcon_destroy(FIcon);
6120   inherited Destroy;
6121 end;
6122 
EventFilternull6123 function TQtBitBtn.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
6124   cdecl;
6125 
6126   function IconValid: boolean;
6127   begin
6128     Result := Assigned(FIcon) and not QIcon_isNull(FIcon) and
6129       (FIconSize.cx > 0) and (FIconSize.cy > 0);
6130   end;
6131 
6132   function PaintBtn: Boolean;
6133   var
6134     APainter: QPainterH;
6135     R: TRect;
6136     R2: TRect;
6137     R3: TRect;
6138     BMargin, HMargin, VMargin, SHorz, SVert: Integer;
6139     IconMode: QIconMode;
6140     IconAlign: QtAlignment;
6141     CenterOffset, W {, H}: Integer;
6142     AFontMetrics: QFontMetricsH;
6143     AText: WideString;
6144     DTFLAGS: DWord;
6145     ContentSize: TSize;
6146     IconDistance: Integer;
6147     IconMargin: Integer;
6148   begin
6149     Result := False;
6150     if (FIcon = nil) then
6151       exit;
6152 
6153     // paint button
6154     QObject_event(Widget, Event);
6155 
6156     IconDistance := TCustomBitBtn(LCLObject).Spacing;
6157     if IconDistance < 0 then
6158       IconDistance := 4; {qt default}
6159 
6160     IconMargin := TCustomBitBtn(LCLObject).Margin;
6161 
6162     // now we paint icon & text
6163     APainter := QPainter_create(QWidget_to_QPaintDevice(Widget));
6164     {$IFDEF USEQT4COMPATIBILEPAINTER}
6165     QPainter_setRenderHint(APainter, QPainterQt4CompatiblePainting);
6166     {$ENDIF}
6167     AText := FText;
6168     try
6169       QPainter_setBackgroundMode(APainter, QtTransparentMode);
6170       QWidget_rect(Widget, @R);
6171 
6172       BMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
6173       VMargin := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
6174       HMargin := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
6175       SHorz := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
6176       SVert := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
6177 
6178       if SHorz = 0 then
6179         SHorz := HMargin;
6180 
6181       if not getEnabled then
6182         IconMode := QIconDisabled
6183       else
6184       if QWidget_underMouse(Widget) then
6185         IconMode := QIconActive
6186       else
6187         IconMode := QIconNormal;
6188 
6189       inc(R.Left, HMargin + SHorz);
6190       inc(R.Top, VMargin + SVert);
6191       dec(R.Right, HMargin + SHorz);
6192       dec(R.Bottom, VMargin + SVert);
6193 
6194       W := R.Right - R.Left;
6195       // H := R.Bottom - R.Top;
6196 
6197       ContentSize.CX := 0;
6198       ContentSize.CY := 0;
6199       R3 := Rect(0, 0, 0, 0);
6200 
6201       DTFlags := DT_CENTER or DT_VCENTER;
6202       if IconValid then
6203       begin
6204         R2 := R;
6205         AFontMetrics := QFontMetrics_create(QPainter_font(APainter));
6206         QPainter_fontMetrics(APainter, AFontMetrics);
6207 
6208         // QtTextShowMnemonic = $0800
6209         if FText = '' then
6210           R3 := Rect(0, 0, 0, 0)
6211         else
6212           QFontMetrics_boundingRect(AFontMetrics, PRect(@R3), 0, 0,
6213             QWidget_width(Widget), QWidget_height(Widget), QtAlignLeft or $0800,
6214             PWideString(@AText));
6215 
6216         QFontMetrics_destroy(AFontMetrics);
6217 
6218         ContentSize.cx := (R3.Right - R3.Left) + FIconSize.cx + IconDistance;
6219         ContentSize.cy := FIconSize.cy + IconDistance + (R3.Bottom - R3.Top);
6220 
6221         if FText = '' then
6222           IconAlign := QtAlignHCenter or QtAlignVCenter
6223         else
6224         case GlyphLayout of
6225           1: // right
6226           begin
6227             DTFLAGS := DT_RIGHT or DT_VCENTER;
6228             dec(R2.Right, BMargin div 2);
6229             IconAlign := QtAlignRight or QtAlignVCenter;
6230             dec(R2.Right, FIconSize.cx);
6231           end;
6232           2: // top
6233           begin
6234             inc(R2.Top, BMargin div 2);
6235             IconAlign := QtAlignTop or QtAlignHCenter;
6236             inc(R2.Top, FIconSize.cy);
6237           end;
6238           3: // bottom
6239           begin
6240             dec(R2.Bottom, BMargin div 2);
6241             IconAlign := QtAlignBottom or QtAlignHCenter;
6242             dec(R2.Bottom, FIconSize.cy);
6243           end;
6244           else
6245           begin // left
6246             DTFLAGS := DT_LEFT or DT_VCENTER;
6247             inc(R2.Left, BMargin div 2);
6248             IconAlign := QtAlignLeft or QtAlignVCenter;
6249             inc(R2.Left, FIconSize.cx);
6250           end;
6251         end;
6252       end;
6253 
6254       if IconValid then
6255       begin
6256         if FGlyphLayout in [0, 1] then
6257         begin
6258           CenterOffset := ((R.Right - R.Left) div 2) - (ContentSize.cx div 2);
6259           if W - ContentSize.cx - CenterOffset < 0 then
6260             CenterOffset := 0;
6261         end else
6262           CenterOffset := ((R.Bottom - R.Top) div 2) - (ContentSize.cy div 2);
6263 
6264         if IconMargin >= 0 then
6265           CenterOffset := IconMargin;
6266 
6267         if FText <> '' then
6268         begin
6269           if FGlyphLayout = 0 then
6270             inc(R.Left, CenterOffset)
6271           else
6272           if FGlyphLayout = 1 then
6273             dec(R.Right, CenterOffset)
6274           else
6275           if FGlyphLayout = 2 then
6276             inc(R.Top, CenterOffset)
6277           else
6278           if FGlyphLayout = 3 then
6279             dec(R.Bottom, CenterOffset);
6280         end;
6281 
6282         QIcon_paint(FIcon, APainter, @R, IconAlign, IconMode);
6283 
6284         R := R2;
6285         if FGlyphLayout = 0 then
6286           inc(R.Left, CenterOffset + IconDistance)
6287         else
6288         if FGlyphLayout = 1 then
6289           dec(R.Right, CenterOffset + IconDistance)
6290         else
6291         if FGlyphLayout = 2 then
6292           inc(R.Top, CenterOffset + IconDistance)
6293         else
6294         if FGlyphLayout = 3 then
6295           dec(R.Bottom, CenterOffset + IconDistance);
6296       end;
6297 
6298       if AText <> '' then
6299         QPainter_drawText(APainter, R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
6300           DTFlagsToQtFlags(DTFLAGS), @AText);
6301 
6302       QPainter_end(APainter);
6303       Result := True;
6304     finally
6305       QPainter_destroy(APainter);
6306     end;
6307   end;
6308 begin
6309   Result := False;
6310   if (LCLObject <> nil) and (QEvent_type(Event) = QEventPaint) then
6311     Result := PaintBtn
6312   else
6313     Result:=inherited EventFilter(Sender, Event);
6314 end;
6315 
6316 procedure TQtBitBtn.preferredSize(var PreferredWidth, PreferredHeight: integer;
6317   WithThemeSpace: Boolean);
6318 const
6319   IconDistance = 4; // hardcoded in qt libs
6320 var
6321   AOpt: QStyleOptionButtonH;
6322   AText: WideString;
6323   AMetrics: QFontMetricsH;
6324   TextSize: TSize;
6325   {style pixel metrics}
6326   BtnMargin, FocusH, FocusV, ShiftH, ShiftV, fsh, fsvm: Integer;
6327 begin
6328   AOpt := QStyleOptionButton_create();
6329   QStyleOption_initFrom(AOpt, Widget);
6330   AText := getText;
6331   QStyleOptionButton_setText(AOpt, @AText);
6332   AMetrics := QFontMetrics_create(QWidget_font(Widget));
6333   try
6334     QStyleOption_fontMetrics(AOpt, AMetrics);
6335 
6336     // QtTextShowMnemonic = $0800
6337     if AText <> '' then
6338       QFontMetrics_size(AMetrics, PSize(@TextSize),
6339         QtAlignLeft or $0800, PWideString(@AText))
6340     else
6341       TextSize := Size(0, 0);
6342     BtnMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
6343     FocusV := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
6344     FocusH := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
6345     ShiftH := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
6346     ShiftV := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
6347     if ShiftH = 0 then
6348       ShiftH := FocusH;
6349     fsh  := (FocusH * 2) + (ShiftH * 2);
6350     fsvm := (FocusV * 2) + (ShiftV * 2) + BtnMargin;
6351     PreferredWidth  := TextSize.cx + fsh + BtnMargin;
6352     PreferredHeight := TextSize.cy + fsvm;
6353 
6354     // now check if we have icon
6355     if Assigned(FIcon) and not QIcon_isNull(FIcon) then
6356     begin
6357       Inc(PreferredWidth, FIconSize.cx + fsh);
6358       if FIconSize.cy + fsvm > PreferredHeight then
6359         PreferredHeight := FIconSize.cy + fsvm;
6360       if FText <> '' then
6361       begin
6362         if FGlyphLayout in [2, 3] then
6363           Inc(PreferredHeight, TextSize.cy + IconDistance)
6364         else
6365           Inc(PreferredWidth, IconDistance);
6366       end;
6367     end;
6368 
6369     if ShiftV = 0 then
6370       Inc(PreferredHeight, 1);
6371   finally
6372     QStyleOptionButton_destroy(AOpt);
6373     QFontMetrics_destroy(AMetrics);
6374   end;
6375 end;
6376 
getIconSizenull6377 function TQtBitBtn.getIconSize: TSize;
6378 begin
6379   Result := FIconSize;
6380 end;
6381 
getTextnull6382 function TQtBitBtn.getText: WideString;
6383 begin
6384   Result := FText;
6385 end;
6386 
6387 procedure TQtBitBtn.setIcon(AIcon: QIconH);
6388 begin
6389   if Assigned(FIcon) then
6390   begin
6391     QIcon_destroy(FIcon);
6392     FIcon := nil;
6393   end;
6394   FIcon := QIcon_create(AIcon);
6395   if getVisible then
6396     Update(nil);
6397 end;
6398 
6399 procedure TQtBitBtn.setIconSize(Size: PSize);
6400 begin
6401   FIconSize.cx := 0;
6402   FIconSize.cy := 0;
6403   if Size <> nil then
6404     FIconSize := Size^;
6405   if getVisible then
6406     Update(nil);
6407 end;
6408 
6409 procedure TQtBitBtn.setText(const W: WideString);
6410 begin
6411   FText := W;
6412   if getVisible then
6413     Update(nil);
6414 end;
6415 
6416 { TQtToggleBox }
6417 
6418 procedure TQtToggleBox.SlotClicked; cdecl;
6419 begin
6420   // do nothing with ToggleBox
6421 end;
6422 
6423 procedure TQtToggleBox.SlotToggled(AChecked: Boolean); cdecl;
6424 var
6425   Msg: TLMessage;
6426 begin
6427   if InUpdate then
6428     exit;
6429 
6430   FillChar(Msg{%H-}, SizeOf(Msg), #0);
6431   Msg.Msg := LM_CHANGED;
6432   DeliverMessage(Msg);
6433 end;
6434 
6435 
6436 { TQtMDIArea }
6437 
6438 procedure TQtMDIArea.SubWindowActivated(AWindow: QMDISubWindowH); cdecl;
6439 var
6440   ActiveChild: TQtMainWindow;
6441   H: HWND;
6442   W: QWidgetH;
6443   WW: TQtWidget;
6444 begin
6445   {we must fix qt bugs here. QWidget_focusWidget() is lost when
6446    activating mdichild via BringToFront (eg from menu)}
6447   if AWindow <> nil then
6448   begin
6449     H := HwndFromWidgetH(AWindow);
6450     if H <> 0 then
6451       ActiveChild := TQtMainWindow(H)
6452     else
6453       ActiveChild := nil;
6454 
6455     if ActiveChild = nil then
6456       exit;
6457 
6458     W := QWidget_focusWidget(AWindow);
6459     if (W <> nil) and (W <> AWindow) then
6460     begin
6461       H := HwndFromWidgetH(W);
6462       if H <> 0 then
6463       begin
6464         WW := TQtWidget(H);
6465         {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
6466         writeln('TQtMDIArea.SubWindowActivated: *=* Current focus widget ',dbgsName(WW.LCLObject));
6467         {$ENDIF}
6468         {trigger QMDIArea to update it's focusWidget (it could be nil) }
6469         QWidget_setFocus(WW.Widget, QtActiveWindowFocusReason);
6470       end;
6471     end else
6472     begin
6473       // fallback when qt completely looses it's mind about focusWidget() inside
6474       // mdi form.
6475       {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
6476       writeln('TQtMDIArea.SubWindowActivated: fallback - ask TCustomForm.ActiveControl ',
6477         dbgsName(TCustomForm(ActiveChild.LCLObject).ActiveControl));
6478       {$ENDIF}
6479       if Assigned(ActiveChild.LCLObject) and
6480         Assigned(TCustomForm(ActiveChild.LCLObject).ActiveControl) and
6481         TCustomForm(ActiveChild.LCLObject).ActiveControl.HandleAllocated then
6482       begin
6483         WW := TQtWidget(TCustomForm(ActiveChild.LCLObject).ActiveControl.Handle);
6484         {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
6485         writeln('**** SUCCESSFULLY ACTIVATED FOCUS PATCH ****');
6486         {$ENDIF}
6487         QWidget_setFocus(WW.Widget, QtActiveWindowFocusReason);
6488       end;
6489     end;
6490   end;
6491 end;
6492 
6493 constructor TQtMDIArea.Create(const AParent: QWidgetH);
6494 begin
6495   Create;
6496   Widget := QMdiArea_create(AParent);
6497   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
6498   FWidgetLCLFont := nil;
6499   Palette.ForceColor := True;
6500   setDefaultColor(dctFont);
6501   Palette.ForceColor := False;
6502   FSubWindowActivationHook := QMdiArea_hook_create(Widget);
6503   QMdiArea_hook_hook_subWindowActivated(FSubWindowActivationHook, @SubWindowActivated);
6504   QWidget_setMouseTracking(Widget, True);
6505   FillChar(FPaintData, sizeOf(FPaintData), 0);
6506   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
6507   setProperty(viewportWidget, 'lclwidget', Int64(PtrUInt(Self)));
6508   QtWidgetSet.AddHandle(Self);
6509 end;
6510 
6511 destructor TQtMDIArea.Destroy;
6512 begin
6513   if FSubWindowActivationHook <> nil then
6514   begin
6515     QMdiArea_hook_destroy(FSubWindowActivationHook);
6516     FSubWindowActivationHook := nil;
6517   end;
6518   inherited Destroy;
6519 end;
6520 
getClientOffsetnull6521 function TQtMDIArea.getClientOffset: TPoint;
6522 begin
6523   if Assigned(FOwner) then
6524     Result := FOwner.getClientOffset
6525   else
6526     Result := inherited getClientOffset;
6527 end;
6528 
6529 procedure TQtMDIArea.AttachEvents;
6530 begin
6531   inherited AttachEvents;
6532   FViewPortEventHook := QObject_hook_create(QAbstractScrollArea_viewport(QAbstractScrollAreaH(Widget)));
6533   QObject_hook_hook_events(FViewPortEventHook, @ScrollViewEventFilter);
6534 end;
6535 
6536 procedure TQtMDIArea.DetachEvents;
6537 begin
6538   if Assigned(FViewPortEventHook) then
6539   begin
6540     QObject_hook_destroy(FViewPortEventHook);
6541     FViewPortEventHook := nil;
6542   end;
6543   inherited DetachEvents;
6544 end;
6545 
EventFilternull6546 function TQtMDIArea.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
6547   cdecl;
6548 begin
6549   Result := False;
6550   QEvent_accept(Event);
6551   case QEvent_type(Event) of
6552     QEventPaint: ;
6553     QEventMouseButtonPress, QEventMouseButtonRelease,
6554     QEventMouseButtonDblClick: ;
6555     QEventMouseMove, QEventWheel: ;
6556     QEventEnter,
6557     QEventLeave: Result := SlotMouseEnter(Sender, Event);
6558     else
6559       Result:=inherited EventFilter(Sender, Event);
6560   end;
6561 end;
6562 
ScrollViewEventFilternull6563 function TQtMDIArea.ScrollViewEventFilter(Sender: QObjectH; Event: QEventH
6564   ): boolean; cdecl;
6565 var
6566   R: TRect;
6567   Brush: QBrushH;
6568   Color: TQColor;
6569   Painter: QPainterH;
6570   APoint, APos, AOldPos, ANewPos, AGlobalPos: TQtPoint;
6571   APosF, AGlobalPosF: TQtPointF;
6572   AEvent: QEventH;
6573   APaintEvent: QPaintEventH;
6574 begin
6575   Result := False;
6576   QEvent_accept(Event);
6577   case QEvent_type(Event) of
6578     QEventMouseButtonPress, QEventMouseButtonRelease,
6579     QEventMouseButtonDblClick:
6580     begin
6581       // new event with parent coordinates
6582       QMouseEvent_pos(QMouseEventH(Event), @APos);
6583       QWidget_mapToParent(Widget, @APoint, @APos);
6584       APosF.x := APoint.X;
6585       APosF.y := APoint.y;
6586       QMouseEvent_globalPos(QMouseEventH(Event), @AGlobalPos);
6587       AGlobalPosF.X := AGlobalPos.X;
6588       AGlobalPosF.Y := AGlobalPos.Y;
6589       AEvent := QMouseEvent_create(QEvent_type(Event), @APosF, @AGlobalPosF,
6590         QMouseEvent_button(QMouseEventH(Event)), QMouseEvent_buttons(QMouseEventH(Event)), QInputEvent_modifiers(QInputEventH(Event)));
6591       try
6592         Result := SlotMouse(Sender, AEvent);
6593       finally
6594         QEvent_destroy(AEvent);
6595       end;
6596     end;
6597     QEventMouseMove:
6598     begin
6599       QMouseEvent_globalPos(QMouseEventH(Event), @AGlobalPos);
6600       QMouseEvent_pos(QMouseEventH(Event), @APos);
6601       QWidget_mapToParent(Widget, @APoint, @APos);
6602       APosF.x := APoint.X;
6603       APosF.y := APoint.y;
6604       AGlobalPosF.X := AGlobalPos.X;
6605       AGlobalPosF.Y := AGlobalPos.Y;
6606       AEvent := QMouseEvent_create(QEvent_type(Event), @APosF, @AGlobalPosF,
6607         QMouseEvent_button(QMouseEventH(Event)), QMouseEvent_buttons(QMouseEventH(Event)), QInputEvent_modifiers(QInputEventH(Event)));
6608       try
6609         Result := SlotMouseMove(Sender, AEvent);
6610       finally
6611         QEvent_destroy(AEvent);
6612       end;
6613     end;
6614 
6615     QEventWheel:
6616     begin
6617       // APos :=
6618       QWheelEvent_pos(QWheelEventH(Event), @APos);
6619       QWidget_mapToParent(Widget, @APoint, @APos);
6620       APosF.X := APoint.X;
6621       APosF.Y := APoint.Y;
6622       AEvent := QWheelEvent_create(@APosF, QWheelEvent_delta(QWheelEventH(Event)), QWheelEvent_buttons(QWheelEventH(Event)),
6623         QInputEvent_modifiers(QInputEventH(Event)), QWheelEvent_orientation(QWheelEventH(Event)));
6624       try
6625         Result := SlotMouseWheel(Sender, AEvent);
6626       finally
6627         QEvent_destroy(AEvent);
6628       end;
6629     end;
6630 
6631     QEventEnter,
6632     QEventLeave: Result := SlotMouseEnter(Sender, Event);
6633     QEventHoverEnter,
6634     QEventHoverLeave,
6635     QEventHoverMove:
6636     begin
6637       // APos :=
6638       QHoverEvent_pos(QHoverEventH(Event), @APos);
6639       QHoverEvent_oldPos(QHoverEventH(Event), @AOldPos);
6640       QWidget_mapToParent(Widget, @APoint, @APos);
6641       QWidget_mapToParent(Widget, @ANewPos, @AOldPos);
6642       APosF.X := APoint.X;
6643       APosF.Y := APoint.Y;
6644       AGlobalPosF.X := ANewPos.X;
6645       AGlobalPosF.Y := ANewPos.Y;
6646       QHoverEvent_create(QEvent_type(Event), @APosF, @AGlobalPosF);
6647       try
6648         Result := SlotHover(Sender, AEvent);
6649       finally
6650         QEvent_destroy(AEvent);
6651       end;
6652     end;
6653     QEventPaint:
6654     begin
6655       QPaintEvent_rect(QPaintEventH(Event), @R);
6656       if CanSendLCLMessage and (LCLObject is TWinControl) then
6657       begin
6658         Brush := QBrush_create;
6659         QMdiArea_background(QMDIAreaH(Widget), Brush);
6660         Color := QBrush_color(Brush)^;
6661         QBrush_destroy(Brush);
6662         Painter := QPainter_create(QWidget_to_QPaintDevice(QWidgetH(Sender)));
6663         {$IFDEF USEQT4COMPATIBILEPAINTER}
6664         QPainter_setRenderHint(Painter, QPainterQt4CompatiblePainting);
6665         {$ENDIF}
6666         Brush := QBrush_create(@Color, QtSolidPattern);
6667         try
6668           QPaintEvent_rect(QPaintEventH(Event), @R);
6669           QPainter_fillRect(Painter, @R, Brush);
6670           QPainter_end(Painter);
6671         finally
6672           QBrush_destroy(Brush);
6673           QPainter_destroy(Painter);
6674         end;
6675         APos.X := 0;
6676         APos.Y := 0;
6677         QWidget_mapToParent(Widget, @APoint, @APos);
6678         FScrollX := -APoint.x;
6679         FScrollY := -APoint.Y;
6680         APaintEvent := QPaintEvent_create(PRect(@R));
6681         try
6682           SlotPaint(Sender, Event);
6683         finally
6684           FScrollX := 0;
6685           FScrollY := 0;
6686           QPaintEvent_destroy(APaintEvent);
6687         end;
6688         Result := True; // do not paint MDIArea again
6689       end;
6690     end;
6691   end;
6692 end;
6693 
ActiveSubWindownull6694 function TQtMDIArea.ActiveSubWindow: QMdiSubWindowH;
6695 begin
6696   Result := QMdiArea_activeSubWindow(QMdiAreaH(Widget));
6697 end;
6698 
6699 procedure TQtMDIArea.ActivateSubWindow(AMdiWindow: QMdiSubWindowH);
6700 begin
6701   if AMdiWindow <> nil then
6702     QMdiArea_setActiveSubWindow(QMdiAreaH(Widget), AMdiWindow);
6703 end;
6704 
6705 {$IFDEF QTSCROLLABLEFORMS}
6706 
6707 { TQtWindowArea }
6708 
6709 procedure TQtWindowArea.AttachEvents;
6710 begin
6711   inherited AttachEvents;
6712   FViewPortEventHook := QObject_hook_create(viewportWidget);
6713   QObject_hook_hook_events(FViewPortEventHook, @ScrollViewEventFilter);
6714 end;
6715 
CanAdjustClientRectOnResizenull6716 function TQtWindowArea.CanAdjustClientRectOnResize: Boolean;
6717 begin
6718   Result := True;
6719 end;
6720 
6721 procedure TQtWindowArea.DetachEvents;
6722 begin
6723   if Assigned(FViewPortEventHook) then
6724   begin
6725     QObject_hook_destroy(FViewPortEventHook);
6726     FViewPortEventHook := nil;
6727   end;
6728   inherited DetachEvents;
6729 end;
6730 
MapToGlobalnull6731 function TQtWindowArea.MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean
6732   ): TPoint;
6733 var
6734   Pt: TPoint;
6735 begin
6736   Result := inherited MapToGlobal(APt);
6737   if AWithScrollOffset then
6738   begin
6739     Pt := ScrolledOffset;
6740     dec(Result.X, Pt.X);
6741     dec(Result.Y, Pt.Y);
6742   end;
6743 end;
6744 
6745 procedure TQtWindowArea.scroll(dx, dy: integer; ARect: PRect);
6746 begin
6747   inherited scroll(dx, dy, ARect);
6748   FScrollX := FScrollX + dx;
6749   FScrollY := FScrollY + dy;
6750 end;
6751 
EventFilternull6752 function TQtWindowArea.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
6753   cdecl;
6754 begin
6755   Result := False;
6756   if (LCLObject = nil) then
6757     exit;
6758   if (QEvent_Type(Event) in [QEventMouseButtonPress, QEventMouseButtonRelease,
6759     QEventMouseButtonDblClick, QEventMouseMove, QEventWheel, QEventPaint,
6760     QEventHoverEnter, QEventHoverMove, QEventHoverLeave, QEventResize]) then
6761     exit;
6762   Result := inherited EventFilter(Sender, Event);
6763 end;
6764 
ScrollViewEventFilternull6765 function TQtWindowArea.ScrollViewEventFilter(Sender: QObjectH; Event: QEventH
6766   ): Boolean; cdecl;
6767 var
6768   ASize: TSize;
6769   AResizeEvent: QResizeEventH;
6770   ScrollBar: QScrollBarH;
6771 begin
6772   Result := False;
6773   if LCLObject = nil then
6774     exit;
6775   BeginEventProcessing;
6776   try
6777     if (QEvent_Type(Event) in [QEventContextMenu, QEventHoverEnter, QEventPaint,
6778                                QEventHoverMove, QEventHoverLeave, QEventHide,
6779                                {must be added, see issue #29159}
6780                                QEventMouseMove]) then
6781     begin
6782       if (FOwner is TQtMainWindow) and not TQtMainWindow(FOwner).IsFrameWindow and
6783         (TCustomForm(LCLObject).FormStyle = fsMDIForm) and
6784         (TQtMainWindow(FOwner).MDIAreaHandle <> nil) then
6785         // paint via MDIAreaHandle viewport hook
6786       else
6787         Result := inherited EventFilter(Sender, Event);
6788     end else
6789     case QEvent_type(Event) of
6790       QEventResize:
6791       begin
6792         if FOwner <> nil then
6793         begin
6794           {TQtMainWindow does not send resize event if ScrollArea is assigned,
6795            it is done here when viewport geometry is finally updated by Qt.}
6796           {$IFDEF QTUSEACCURATEFRAME}
6797           if (FOwner.IsFramedWidget) then
6798             ASize := FOwner.getFrameSize
6799           else
6800           {$ENDIF}
6801             ASize := FOwner.getSize;
6802           AResizeEvent := QResizeEvent_create(@ASize, @ASize);
6803           try
6804             // issue #28596 and others of TCustomControl clientrect related
6805             if CanAdjustClientRectOnResize and
6806               LCLObject.ClientRectNeedsInterfaceUpdate then
6807             begin
6808               {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
6809               DebugLn('TQtWindowArea.ScrollViewEventFilter invalidatingClientRectCache ',dbgsName(Self),' LCL=',dbgsName(LCLObject));
6810               {$ENDIF}
6811               LCLObject.InvalidateClientRectCache(False);
6812             end;
6813             SlotResize(AResizeEvent);
6814           finally
6815             QEvent_destroy(AResizeEvent);
6816           end;
6817         end else
6818           LCLObject.DoAdjustClientRectChange;
6819       end;
6820       QEventWheel:
6821         if not getEnabled then
6822           inherited EventFilter(Sender, Event);
6823       QEventLayoutRequest:
6824       begin
6825         if FOwner <> nil then
6826         begin
6827           if LCLObject.ClientRectNeedsInterfaceUpdate then
6828           begin
6829             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
6830             DebugLn('TQtWindowArea.Viewport: ',dbgsName(LCLObject),' QEventLayoutRequest calling DoAdjustClientRectChange CASP=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' ***** !!!! ');
6831             {$ENDIF}
6832             Self.LCLObject.DoAdjustClientRectChange(True);
6833           end;
6834         end;
6835       end;
6836     end;
6837   finally
6838     EndEventProcessing;
6839   end;
6840 end;
6841 
getWindowStatenull6842 function TQtWindowArea.getWindowState: QtWindowStates;
6843 begin
6844   Result := inherited getWindowState;
6845   if Assigned(LCLObject) then
6846     Result := TQtMainWindow(LCLObject.Handle).getWindowState;
6847 end;
6848 
6849 {$ENDIF}
6850 
6851 
6852 { TQtMainWindow }
6853 
CreateWidgetnull6854 function TQtMainWindow.CreateWidget(const AParams: TCreateParams): QWidgetH;
6855   {$IFDEF QTSCROLLABLEFORMS}
6856   procedure SetScrollAreaRules;
6857   begin
6858     FCentralWidget := ScrollArea.Widget;
6859     ScrollArea.ChildOfComplexWidget := ccwAbstractScrollArea;
6860     ScrollArea.LCLObject := LCLObject;
6861 
6862     QFrame_setFrameShape(QAbstractScrollAreaH(ScrollArea.Widget), QFrameNoFrame);
6863     QWidget_setBackgroundRole(ScrollArea.viewportWidget, QPaletteNoRole);
6864     QWidget_setAutoFillBackground(ScrollArea.viewportWidget, False);
6865 
6866     // we must set minimum heigth / width to 1 otherwise we'll have strange
6867     // effect eg. with main ide bar window (small size and cannot resize).
6868     //QWidget_setMinimumHeight(FCentralWidget, 1);
6869     //QWidget_setMinimumWidth(FCentralWidget, 1);
6870     QWidget_setSizePolicy(FCentralWidget, QSizePolicyIgnored, QSizePolicyIgnored);
6871 
6872     ScrollArea.setScrollBarPolicy(True, QtScrollBarAlwaysOff);
6873     ScrollArea.setScrollBarPolicy(False, QtScrollBarAlwaysOff);
6874     ScrollArea.HasPaint := True;
6875     ScrollArea.FOwner := Self;
6876   end;
6877   {$ENDIF}
6878 var
6879   p: QPaletteH;
6880 begin
6881   // Creates the widget
6882   {$ifdef VerboseQt}
6883     WriteLn('TQtMainWindow.CreateWidget Name: ', LCLObject.Name);
6884   {$endif}
6885   {$IFDEF QtUseAccurateFrame}
6886   FFormHasInvalidPosition := False;
6887   {$ENDIF}
6888 
6889   FBlocked := False;
6890   FShowOnTaskBar := False;
6891   QtFormBorderStyle := Ord(bsSizeable);
6892   QtFormStyle := Ord(fsNormal);
6893   FHasPaint := True;
6894   FPopupParent := nil;
6895   MDIAreaHandle := nil;
6896   MDIChildArea := nil;
6897   FMDIStateHook := nil;
6898   {$IFDEF QTSCROLLABLEFORMS}
6899   ScrollArea := nil;
6900   {$ENDIF}
6901 
6902   IsMainForm := (LCLObject <> nil) and (LCLObject = Application.MainForm);
6903 
6904   IsFrameWindow := not IsMainForm and (LCLObject <> nil) and (LCLObject is TCustomFrame);
6905   if IsFrameWindow then
6906     QtFormBorderStyle := Ord(bsNone);
6907 
6908   if IsMainForm then
6909   begin
6910 
6911     Result := QMainWindow_create(nil, QtWindow);
6912 
6913     MenuBar := TQtMenuBar.Create(Result);
6914 
6915     if not (csDesigning in LCLObject.ComponentState) then
6916       MenuBar.FIsApplicationMainMenu := True
6917     else
6918       {$IFNDEF DARWIN}
6919       MenuBar.setProperty(MenuBar.Widget,'lcldesignmenubar',1)
6920       {$ENDIF}
6921       ;
6922 
6923     if (Application.MainForm <> nil) and
6924        (Application.MainForm.FormStyle = fsMDIForm) and
6925        not (csDesigning in LCLObject.ComponentState) then
6926     begin
6927       FCentralWidget := QWidget_create(Result);
6928       MDIAreaHandle := TQtMDIArea.Create(Result);
6929       MDIAreaHandle.FOwner := Self;
6930       MDIAreaHandle.LCLObject := LCLObject;
6931       MDIAreaHandle.AttachEvents;
6932       p := QWidget_palette(FCentralWidget);
6933       if p <> nil then
6934         QMdiArea_setBackground(QMdiAreaH(MdiAreaHandle.Widget), QPalette_background(P));
6935       QWidget_setParent(MdiAreaHandle.Widget, FCentralWidget);
6936       QMdiArea_setActivationOrder(QMdiAreaH(MdiAreaHandle.Widget), QMdiAreaActivationHistoryOrder);
6937       QMdiArea_setOption(QMdiAreaH(MdiAreaHandle.Widget),
6938         QMdiAreaDontMaximizeSubWindowOnActivation, True);
6939     end
6940     else
6941     begin
6942       {$IFDEF QTSCROLLABLEFORMS}
6943       ScrollArea := TQtWindowArea.CreateFrom(LCLObject, QAbstractScrollArea_create(Result));
6944       SetScrollAreaRules;
6945       {$ELSE}
6946       FCentralWidget := QWidget_create(Result);
6947       {$ENDIF}
6948       MDIAreaHandle := nil;
6949     end;
6950 
6951     if FCentralWidget <> nil then
6952     begin
6953       QMainWindow_setCentralWidget(QMainWindowH(Result), FCentralWidget);
6954       QWidget_setMouseTracking(FCentralWidget, True);
6955     end;
6956 
6957     if not (csDesigning in LCLObject.ComponentState) then
6958       QMainWindow_setDockOptions(QMainWindowH(Result), QMainWindowAnimatedDocks);
6959   end else
6960   begin
6961     if IsMdiChild then
6962     begin
6963 
6964       if TQtMainWindow(Application.MainForm.Handle).MDIAreaHandle = nil then
6965         raise Exception.Create('MDIChild can be added to MDIForm only !');
6966 
6967       Result := QMdiSubWindow_create(nil, QtWindow);
6968 
6969       // QMdiSubWindow already have an layout
6970 
6971       LayoutWidget := QBoxLayoutH(QWidget_layout(Result));
6972       if LayoutWidget <> nil then
6973         QBoxLayout_destroy(LayoutWidget);
6974     end else
6975     begin
6976       if not IsFrameWindow and (TCustomForm(LCLObject).FormStyle = fsSplash) and
6977         not (csDesigning in LCLObject.ComponentState) then
6978         Result := QWidget_create(nil, QtSplashScreen)
6979       else
6980         Result := QWidget_create(nil, QtWindow);
6981 
6982       QWidget_setAttribute(Result, QtWA_Hover);
6983       QWidget_setMouseTracking(Result, True);
6984     end;
6985 
6986     // Main menu bar
6987     {$IFDEF DARWIN}
6988     MenuBar := TQtMenuBar.Create(nil);
6989     {$ELSE}
6990     MenuBar := TQtMenuBar.Create(Result);
6991     if (csDesigning in LCLObject.ComponentState) then
6992       MenuBar.setProperty(MenuBar.Widget,'lcldesignmenubar',1);
6993     {$ENDIF}
6994 
6995     {$IFDEF QTSCROLLABLEFORMS}
6996     if QWidget_windowType(Result) = QtSplashScreen then
6997       FCentralWidget := QWidget_create(Result)
6998     else
6999     begin
7000       ScrollArea := TQtWindowArea.CreateFrom(LCLObject, QAbstractScrollArea_create(Result));
7001       SetScrollAreaRules;
7002     end;
7003     {$ELSE}
7004     FCentralWidget := QWidget_create(Result);
7005     {$ENDIF}
7006     QWidget_setMouseTracking(FCentralWidget, True);
7007 
7008     LayoutWidget := QBoxLayout_create(QBoxLayoutTopToBottom, Result);
7009 
7010     QBoxLayout_setSpacing(LayoutWidget, 0);
7011     QLayout_setContentsMargins(LayoutWidget, 0, 0, 0, 0);
7012 
7013     // we must fix mouse events in QMDISubWindow by
7014     // adding FCentralWidget as it''s widget
7015     if IsMdiChild then
7016       QMdiSubWindow_setWidget(QMdiSubWindowH(Result), FCentralWidget);
7017 
7018     QLayout_addWidget(LayoutWidget, FCentralWidget);
7019     QWidget_setLayout(Result, QLayoutH(LayoutWidget));
7020     QWidget_setAttribute(Result, QtWA_DeleteOnClose);
7021   end;
7022 end;
7023 
7024 procedure TQtMainWindow.ChangeParent(NewParent: QWidgetH);
7025 var
7026   Flags: QtWindowFlags;
7027   Visible: Boolean;
7028 begin
7029   if NewParent <> Widget then
7030   begin
7031     Visible := getVisible;
7032     Flags := windowFlags;
7033     setParent(NewParent);
7034     setWindowFlags(Flags);
7035     setVisible(Visible);
7036   end;
7037 end;
7038 
7039 procedure TQtMainWindow.UpdateParent;
7040 begin
7041   ChangeParent(FPopupParent);
7042 end;
7043 
7044 {------------------------------------------------------------------------------
7045   Function: TQtMainWindow.Destroy
7046   Params:  None
7047   Returns: Nothing
7048  ------------------------------------------------------------------------------}
7049 destructor TQtMainWindow.Destroy;
7050 begin
7051   // The main window takes care of the menubar handle
7052   {handle validator is added since we added events to
7053    menubar in r33309 (because of font changes).
7054    Events are attached in TQtWSCustomForm.CreateHandle
7055    Sometimes in various combinations we can
7056    crash here because MenuBar <> nil but not valid handle.
7057    Now it's totally safe.}
7058   if QtWidgetSet.IsValidHandle(HWND(MenuBar)) then
7059   begin
7060     MenuBar.DetachEvents;
7061     if FOwnWidget and (MenuBar.Widget <> nil) then
7062       QObject_deleteLater(MenuBar.Widget);
7063     MenuBar.Widget := nil;
7064     FreeThenNil(MenuBar);
7065   end;
7066 
7067   if MDIAreaHandle <> nil then
7068   begin
7069     MDIAreaHandle.DetachEvents;
7070     MDIAreaHandle.Widget := nil;
7071     FreeThenNil(MDIAreaHandle);
7072   end;
7073   {$IFDEF QTSCROLLABLEFORMS}
7074   if QtWidgetSet.IsValidHandle(HWND(ScrollArea)) then
7075   begin
7076     ScrollArea.DetachEvents;
7077     ScrollArea.Widget := nil;
7078     FreeAndNil(ScrollArea);
7079   end;
7080   {$ENDIF}
7081 
7082   inherited Destroy;
7083 end;
7084 
7085 procedure TQtMainWindow.Activate;
7086 begin
7087   if IsMDIChild then
7088     QMdiArea_setActiveSubWindow(QMdiSubWindow_mdiArea(QMdiSubWindowH(Widget)),
7089       QMdiSubWindowH(Widget))
7090   else
7091     inherited Activate;
7092   {$IFDEF DARWIN}
7093   QWidget_raise(Widget);
7094   {$ENDIF}
7095   {$IFDEF HASX11}
7096   if (QtWidgetSet.WindowManagerName = 'xfwm4') and not IsMDIChild and
7097     QWidget_isModal(Widget) then
7098   begin
7099     if X11GetActivewindow <> Widget then
7100       X11Raise(QWidget_winID(Widget));
7101   end else
7102   if not QWidget_isModal(Widget) then
7103   begin
7104     if (QtWidgetSet.WindowManagerName = 'metacity') and not IsMDIChild then
7105         X11Raise(QWidget_winID(Widget))
7106     else
7107       QWidget_raise(Widget);
7108   end;
7109   {$ENDIF}
7110 end;
7111 
CanAdjustClientRectOnResizenull7112 function TQtMainWindow.CanAdjustClientRectOnResize: Boolean;
7113 begin
7114   {$IFDEF QTSCROLLABLEFORMS}
7115   Result := not Assigned(ScrollArea);
7116   {$ELSE}
7117   Result:=inherited CanAdjustClientRectOnResize;
7118   {$ENDIF}
7119 end;
7120 
TQtMainWindow.getAcceptDropFilesnull7121 function TQtMainWindow.getAcceptDropFiles: Boolean;
7122 begin
7123   Result := QWidget_acceptDrops(Widget);
7124 end;
7125 
GetContainerWidgetnull7126 function TQtMainWindow.GetContainerWidget: QWidgetH;
7127 begin
7128   {$IFDEF QTSCROLLABLEFORMS}
7129   if IsFrameWindow then
7130     Result := ScrollArea.GetContainerWidget
7131   else
7132   if not Assigned(ScrollArea) or (QWidget_windowType(Widget) = QtToolTip) or
7133     (QWidget_windowType(Widget) = QtSplashScreen) or
7134     (TCustomForm(LCLObject).FormStyle = fsMdiForm) then
7135     Result := inherited GetContainerWidget
7136   else
7137     Result := ScrollArea.GetContainerWidget;
7138   {$ELSE}
7139   Result := inherited GetContainerWidget;
7140   {$ENDIF}
7141 end;
7142 
7143 procedure TQtMainWindow.grabMouse;
7144 begin
7145   {$IFDEF QTSCROLLABLEFORMS}
7146   if not Assigned(ScrollArea) then
7147     inherited grabMouse
7148   else
7149     ScrollArea.grabMouse;
7150   {$ELSE}
7151   inherited grabMouse;
7152   {$ENDIF}
7153 end;
7154 
getClientBoundsnull7155 function TQtMainWindow.getClientBounds: TRect;
7156 begin
7157   {$IFDEF QTSCROLLABLEFORMS}
7158   if Assigned(ScrollArea) then
7159   begin
7160     if not ScrollArea.testAttribute(QtWA_PendingResizeEvent) then
7161     begin
7162       Result := ScrollArea.getClientBounds;
7163       {$IF DEFINED(QTUSEACCURATEFRAME) AND DEFINED(DEBUGQTUSEACCURATEFRAME)}
7164       DebugLn('TQtMainWindow.getClientBounds(',dbgsName(LCLObject),'): ',dbgs(Result),' FFrame=',dbgs(FFrameMargins));
7165       {$ENDIF}
7166     end else
7167     begin
7168       Result := inherited GetClientBounds;
7169       {$IFDEF QTUSEACCURATEFRAME}
7170       if IsFramedWidget then
7171       begin
7172         {$IFDEF DEBUGQTUSEACCURATEFRAME}
7173         DebugLn('>TQtMainWindow.getClientBounds(',dbgsName(LCLObject),'): ***ERROR*** ',dbgs(Result),' FFrame=',dbgs(FFrameMargins),' Assigned ? ',BoolToStr(Assigned(ScrollArea)));
7174         {$ENDIF}
7175         dec(Result.Right, FFrameMargins.Right + FFrameMargins.Left);
7176         dec(Result.Bottom, FFrameMargins.Bottom + FFrameMargins.Top);
7177         {menubar is not yet allocated, so use SM_CYMENU}
7178         if Assigned(TCustomForm(LCLObject).Menu) then
7179           dec(Result.Bottom, QtWidgetSet.GetSystemMetrics(SM_CYMENU));
7180         {$IFDEF DEBUGQTUSEACCURATEFRAME}
7181         DebugLn('<TQtMainWindow.getClientBounds(',dbgsName(LCLObject),'): ***ERROR*** NEW RESULT=',dbgs(Result));
7182         {$ENDIF}
7183       end;
7184       {$ENDIF}
7185     end;
7186   end else
7187   {$ENDIF}
7188   Result:=inherited getClientBounds;
7189 end;
7190 
getClientOffsetnull7191 function TQtMainWindow.getClientOffset: TPoint;
7192 begin
7193   {$IFDEF QTSCROLLABLEFORMS}
7194   if Assigned(ScrollArea) then
7195     Result := ScrollArea.getClientOffset
7196   else
7197     Result := inherited getClientOffset;
7198   if Assigned(ScrollArea) and Assigned(MenuBar) and
7199     (MenuBar.getVisible) then
7200       inc(Result.Y, MenuBar.getHeight);
7201   {$ELSE}
7202   Result:=inherited getClientOffset;
7203   {$ENDIF}
7204 end;
7205 
getFrameSizenull7206 function TQtMainWindow.getFrameSize: TSize;
7207 {$IFDEF QtUseAccurateFrame}
7208 var
7209   ASize, AFrameSize: TSize;
7210 {$ENDIF}
7211 begin
7212   Result:=inherited getFrameSize;
7213   {$IFDEF QtUseAccurateFrame}
7214   if IsFramedWidget then
7215   begin
7216     ASize := GetSize;
7217     AFrameSize := Result;
7218     if (getWindowState and QtWindowMaximized = QtWindowMaximized) then
7219     begin
7220       Result.cx := ASize.cx;
7221       Result.cy := ASize.cy + FFrameMargins.Top + FFrameMargins.Bottom;
7222     end else
7223     if (ASize.cx = AFrameSize.cx) and (ASize.cy = AFrameSize.cy) then
7224     begin
7225       {$IFDEF DebugQtUseAccurateFrame}
7226       DebugLn('>TQtMainWindow.getFrameSize ',dbgs(Result),' must apply frameMargins=',dbgs(FFrameMargins));
7227       {$ENDIF}
7228       inc(Result.cx, FrameMargins.Left + FrameMargins.Right);
7229       inc(Result.cy, FrameMargins.Top + FrameMargins.Bottom);
7230       {$IFDEF DebugQtUseAccurateFrame}
7231       DebugLn('<TQtMainWindow.getFrameSize ',dbgs(Result),' must apply frameMargins=',dbgs(FFrameMargins));
7232       {$ENDIF}
7233     end;
7234   end;
7235   {$ENDIF}
7236 end;
7237 
TQtMainWindow.getFrameGeometrynull7238 function TQtMainWindow.getFrameGeometry: TRect;
7239 {$IFDEF QtUseAccurateFrame}
7240 var
7241   ASize, AFrameSize: TSize;
7242   {$IFDEF HASX11}
7243   X11X, X11Y, X, Y: integer;
7244   ALeft, ATop, AWidth, AHeight, ABorder: integer;
7245   {$ENDIF}
7246 {$ENDIF}
7247 begin
7248   Result:=inherited getFrameGeometry;
7249   {$IFDEF QtUseAccurateFrame}
7250   if IsFramedWidget then
7251   begin
7252     QWidget_size(Widget, @ASize);
7253     QWidget_frameSize(Widget, @AFrameSize);
7254 
7255     if (getWindowState and QtWindowFullScreen = QtWindowFullScreen) then
7256     begin
7257       Result.Left := 0;
7258       Result.Top := 0;
7259       Result.Right := Screen.Width;
7260       Result.Bottom := Screen.Height;
7261       FFormHasInvalidPosition := False;
7262     end else
7263     if (getWindowState and QtWindowMaximized = QtWindowMaximized) then
7264     begin
7265       Result.Left := 0;
7266       Result.Top := 0;
7267       Result.Right := ASize.cx;
7268       Result.Bottom := ASize.cy + FFrameMargins.Top + FFrameMargins.Bottom;
7269       FFormHasInvalidPosition := False;
7270     end else
7271     if (ASize.cx = AFrameSize.cx) and (ASize.cy = AFrameSize.cy) then
7272     begin
7273       {$IFDEF DebugQtUseAccurateFrame}
7274       DebugLn('>TQtMainWindow.getFrameGeometry ',dbgs(Result),' must apply frameMargins=',dbgs(FFrameMargins));
7275       if (FFrameMargins.Left = 0) and (FFrameMargins.Top = 0) and (FFrameMargins.Right = 0) and (FFrameMargins.Bottom = 0) then
7276         FFrameMargins := QtWidgetSet.WSFrameMargins;
7277       {$ENDIF}
7278       inc(Result.Right, FrameMargins.Left + FrameMargins.Right);
7279       inc(Result.Bottom, FrameMargins.Top + FrameMargins.Bottom);
7280       {$IFDEF DebugQtUseAccurateFrame}
7281       DebugLn('<TQtMainWindow.getFrameGeometry ',dbgs(Result),' WS W=',dbgs(Result.Right - Result.Left),' H=',dbgs(Result.Bottom - Result.Top),' SIZE=',dbgs(ASize));
7282       {$ENDIF}
7283     end;
7284     if FFormHasInvalidPosition then
7285     begin
7286       {$IFDEF HASX11}
7287       if GetX11WindowPos(QWidget_winID(Widget), X11X, X11Y) then
7288       begin
7289         if GetX11WindowAttributes(QWidget_winID(Widget), ALeft, ATop, AWidth, AHeight, ABorder) then
7290         begin
7291           if ALeft = 0 then
7292             X11X -= FFrameMargins.Left;
7293           if ATop = 0 then
7294             X11Y -= FFrameMargins.Top;
7295         end else
7296         begin
7297           X11X -= FFrameMargins.Left;
7298           X11Y -= FFrameMargins.Top;
7299         end;
7300 
7301         X := Result.Left;
7302         Y := Result.Top;
7303         if (X11X = x) and (X11Y = y) then
7304           FFormHasInvalidPosition := False
7305         else
7306           OffsetRect(Result, X11X - x, X11Y - y);
7307       end;
7308       {$ELSE}
7309       DebugLn('TQtMainWindow.getFrameGeometry currently implemented only on X11');
7310       {$ENDIF}
7311     end;
7312   end;
7313   {$ENDIF}
7314 end;
7315 
getTextnull7316 function TQtMainWindow.getText: WideString;
7317 begin
7318   WindowTitle(@Result);
7319 end;
7320 
TQtMainWindow.getTextStaticnull7321 function TQtMainWindow.getTextStatic: Boolean;
7322 begin
7323   Result := False;
7324 end;
7325 
TQtMainWindow.MapToGlobalnull7326 function TQtMainWindow.MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean
7327   ): TPoint;
7328 begin
7329   {$IFDEF QTSCROLLABLEFORMS}
7330   if Assigned(ScrollArea) then
7331     Result := ScrollArea.MapToGlobal(APt, AWithScrollOffset)
7332   else
7333     Result := inherited MapToGlobal(APt, AWithScrollOffset);
7334   {$ELSE}
7335   Result := inherited MapToGlobal(APt, AWithScrollOffset);
7336   {$ENDIF}
7337 end;
7338 
7339 procedure TQtMainWindow.Update(ARect: PRect);
7340 var
7341   R,R1: TRect;
7342 begin
7343   if Assigned(MDIAreaHandle) and not IsMDIChild then
7344   begin
7345     if ARect = nil then
7346       QWidget_update(MDIAreaHandle.viewportWidget)
7347     else
7348     begin
7349       R1 := ARect^;
7350       QWidget_geometry(MDIAreaHandle.Widget, @R);
7351       OffsetRect(R1, -R.Left, -R.Top);
7352       QWidget_update(MDIAreaHandle.viewportWidget, @R1);
7353     end;
7354   end else
7355     inherited Update(ARect);
7356 end;
7357 
7358 procedure TQtMainWindow.UpdateRegion(ARgn: QRegionH);
7359 var
7360   R1, R: TRect;
7361   ANewRgn: QRegionH;
7362 begin
7363   if Assigned(MDIAreaHandle) and not IsMDIChild then
7364   begin
7365     if ARgn = nil then
7366       QWidget_update(MDIAreaHandle.viewportWidget)
7367     else
7368     begin
7369       QRegion_boundingRect(ARgn, @R1);
7370       QWidget_geometry(MDIAreaHandle.Widget, @R);
7371       OffsetRect(R1, -R.Left, -R.Top);
7372       ANewRgn := QRegion_create(PRect(@R1));
7373       QWidget_update(MDIAreaHandle.viewportWidget, ANewRgn);
7374       QRegion_destroy(ANewRgn);
7375     end;
7376   end else
7377     inherited UpdateRegion(ARgn);
7378 end;
7379 
7380 procedure TQtMainWindow.Repaint(ARect: PRect);
7381 var
7382   R, R1: TRect;
7383 begin
7384   if Assigned(MDIAreaHandle) and not IsMDIChild then
7385   begin
7386     if ARect = nil then
7387       QWidget_repaint(MDIAreaHandle.viewportWidget)
7388     else
7389     begin
7390       R1 := ARect^;
7391       QWidget_geometry(MDIAreaHandle.Widget, @R);
7392       OffsetRect(R1, -R.Left, -R.Top);
7393       QWidget_repaint(MDIAreaHandle.viewportWidget, @R1);
7394     end;
7395   end else
7396     inherited Repaint(ARect);
7397 end;
7398 
7399 procedure TQtMainWindow.Resize(ANewWidth, ANewHeight: Integer);
7400 begin
7401   if not IsMDIChild and not IsFrameWindow and
7402     (TCustomForm(LCLObject).BorderStyle in [bsDialog, bsNone, bsSingle]) and
7403      not (csDesigning in LCLObject.ComponentState) then
7404   begin
7405     {$IFDEF QtUseAccurateFrame}
7406     if IsFramedWidget then
7407       QWidget_setFixedSize(Widget, ANewWidth - (FFrameMargins.Right + FFrameMargins.Left),
7408         ANewHeight - (FFrameMargins.Bottom + FFrameMargins.Top))
7409     else
7410     {$ENDIF}
7411     QWidget_setFixedSize(Widget, ANewWidth, ANewHeight);
7412   end else
7413     inherited Resize(ANewWidth, ANewHeight);
7414 end;
7415 
7416 procedure TQtMainWindow.setText(const W: WideString);
7417 begin
7418   setWindowTitle(@W);
7419 end;
7420 
7421 procedure TQtMainWindow.setMenuBar(AMenuBar: QMenuBarH);
7422 begin
7423   if IsMainForm then
7424     QMainWindow_setMenuBar(QMainWindowH(Widget), AMenuBar)
7425   else
7426     QLayout_setMenuBar(LayoutWidget, AMenuBar);
7427 end;
7428 
7429 {------------------------------------------------------------------------------
7430   Function: TQtMainWindow.EventFilter
7431   Params:  None
7432   Returns: Nothing
7433  ------------------------------------------------------------------------------}
TQtMainWindow.EventFilternull7434 function TQtMainWindow.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
7435   cdecl;
7436 var
7437   AStateEvent: QWindowStateChangeEventH;
7438   AState: QtWindowStates;
7439   AOldState: QtWindowStates;
7440   CanSendEvent: Boolean;
7441   {$IFDEF QtUseAccurateFrame}
7442   R: TRect;
7443   ASize, AFrameSize: TSize;
7444   {$IFDEF HASX11}
7445   ALeft, ATop, ABorder, AWidth, AHeight: integer;
7446   X11X, X11Y: integer;
7447   AMoveMsg: TLMMove;
7448   ASizeMsg: TLMSize;
7449   ATempFrame: TRect;
7450   {$ENDIF}
7451   {$ENDIF}
7452   {$IFDEF MSWINDOWS}
7453   i: Integer;
7454   AForm: TCustomForm;
7455   w: QWidgetH;
7456   {$ENDIF}
7457   {$IFDEF HASX11}
7458   IsMinimizeEvent: Boolean;
7459   {$ENDIF}
7460 begin
7461   Result := False;
7462   QEvent_accept(Event);
7463   if LCLObject = nil then
7464     exit;
7465 
7466   {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
7467   if (QEvent_type(Event)=QEventWindowActivate) or
7468     (QEvent_type(Event)=QEventWindowDeactivate) or
7469     (QEvent_type(Event)=QEventShowToParent) or
7470     (QEvent_type(Event)=QEventWindowStateChange) then
7471       WriteLn('TQtMainWindow.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
7472       ' LCLObject=', dbgsName(LCLObject),
7473       ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
7474   {$endif}
7475 
7476   {$IFDEF QTSCROLLABLEFORMS}
7477   if Assigned(ScrollArea) and not IsMDIChild then
7478   begin
7479     if QEvent_type(Event) in
7480       [QEventPaint, QEventContextMenu, QEventWheel] then
7481       exit;
7482   end;
7483   {$ENDIF}
7484 
7485   BeginEventProcessing;
7486   try
7487     case QEvent_type(Event) of
7488       QEventHide:
7489       begin
7490         Result := inherited EventFilter(Sender, Event);
7491         {as of r46623 (issue #26893) we use QObject_deleteLater
7492          instead of QWidget_destroy.
7493          QMDIArea does not respond after that, so we must activate next mdichild
7494          according to mdi standards.Looks like Qt4 bug.}
7495         if not Application.Terminated and IsMDIChild then
7496         begin
7497           if Assigned(MDIChildArea) then
7498           begin
7499             if (MDIChildArea.ActiveSubWindow = nil) or
7500               (MDIChildArea.ActiveSubWindow = Widget) then
7501             begin
7502               if not QWidget_isVisibleTo(Widget, MDIChildArea.Widget) then
7503                 QMdiArea_activatePreviousSubWindow(QMDIAreaH(MDIChildArea.Widget));
7504             end;
7505           end;
7506         end;
7507       end;
7508       {$IFDEF QTSCROLLABLEFORMS}
7509       QEventMouseMove: // issue #29159
7510       begin
7511         if (Self is TQtHintWindow) or (IsMdiChild or
7512           (Assigned(LCLObject) and (csDesigning in LCLObject.ComponentState))) then
7513           Result := inherited EventFilter(Sender, Event)
7514         else
7515           Result := False;
7516       end;
7517       {$ENDIF}
7518       QEventMouseButtonPress,
7519       QEventMouseButtonRelease,
7520       QEventMouseButtonDblClick:
7521       begin
7522         if IsMdiChild then
7523         begin
7524           if QMouseEvent_y(QMouseEventH(Event)) <= GetPixelMetric(
7525             QStylePM_TitleBarHeight, nil, Widget) then
7526             QEvent_ignore(Event)
7527           else
7528             Result := SlotMouse(Sender, Event);
7529         end else
7530           Result := SlotMouse(Sender, Event);
7531       end;
7532       QEventWindowUnblocked: Blocked := False;
7533       QEventWindowBlocked: Blocked := True;
7534       {$IF DEFINED(QtUseAccurateFrame) AND DEFINED(HASX11)}
7535       (*
7536       QEventActivationChange:
7537       begin
7538         // here we still have wrong x,y from qt
7539         if IsFramedWidget and not FFormHasInvalidPosition then
7540         begin
7541           {This is Qt bug, so we must take care of it}
7542           if GetX11WindowPos(QWidget_winID(Widget), R.Left, R.Top) then
7543           begin
7544             if (R.Left - QWidget_x(Widget) = FrameMargins.Left) and (R.Top - QWidget_y(Widget) = FrameMargins.Left) then
7545             begin
7546               DebugLn('WARNING: QEventActivationChange(FALSE) ',GetWindowManager,' wm strange position: ',Format('X11 x %d y %d Qt x %d y %d',[R.Left, R.Top, QWidget_x(Widget), QWidget_y(Widget)]));
7547             end else
7548             begin
7549               R.Left := R.Left - FFrameMargins.Left;
7550               R.Top := R.Top - FFrameMargins.Top;
7551               if (R.Left <> QWidget_x(Widget)) or (R.Top <> QWidget_y(Widget)) then
7552               begin
7553                 DebugLn('WARNING: QEventActivationChange(*TRUE*) ',GetWindowManager,' wm strange position: ',Format('X11 x %d y %d Qt x %d y %d',[R.Left, R.Top, QWidget_x(Widget), QWidget_y(Widget)]));
7554                 FFormHasInvalidPosition := True;
7555               end;
7556             end;
7557           end;
7558         end;
7559       end;
7560       *)
7561       {$ENDIF}
7562       QEventWindowActivate:
7563       begin
7564         if not IsMDIChild then
7565         begin
7566           {$IF DEFINED(QtUseAccurateFrame) AND DEFINED(HASX11)}
7567           if IsFramedWidget and not (getWindowState and QtWindowFullScreen = QtWindowFullScreen) then
7568           begin
7569             {This is Qt bug, so we must take care of it}
7570             if GetX11WindowPos(QWidget_winID(Widget), R.Left, R.Top) then
7571             begin
7572               // fluxbox
7573               if (R.Left - QWidget_x(Widget) = FrameMargins.Left) and (R.Top - QWidget_y(Widget) = FrameMargins.Left) then
7574               begin
7575                 GetX11WindowAttributes(QWidget_winID(Widget), ALeft, ATop, AWidth, AHeight, ABorder);
7576                 {$IF DEFINED(DEBUGQTUSEACCURATEFRAME) OR DEFINED(DEBUGQTCHECKMOVESIZE)}
7577                 DebugLn('WARNING: QEventWindowActivate(FALSE) ',dbgsName(LCLObject),' ',GetWindowManager,' wm strange position: ',Format('X11 x %d y %d Qt x %d y %d X11 attr x %d y %d',[R.Left, R.Top, QWidget_x(Widget), QWidget_y(Widget), ALeft, ATop]));
7578                 {$ENDIF}
7579               end else
7580               begin
7581                 if GetX11WindowAttributes(QWidget_winID(Widget), ALeft, ATop, AWidth, AHeight, ABorder) then
7582                 begin
7583                   if ALeft = 0 then
7584                     R.Left -= FFrameMargins.Left;
7585                   if ATop = 0 then
7586                     R.Top -= FFrameMargins.Top;
7587                 end else
7588                 begin
7589                   R.Left -= FFrameMargins.Left;
7590                   R.Top -= FFrameMargins.Top;
7591                 end;
7592                 if (R.Left <> QWidget_x(Widget)) or (R.Top <> QWidget_y(Widget)) then
7593                 begin
7594                   {$IF DEFINED(DEBUGQTUSEACCURATEFRAME) OR DEFINED(DEBUGQTCHECKMOVESIZE)}
7595                   GetX11RectForAtom(QWidget_winID(Widget), '_NET_FRAME_EXTENTS', ATempFrame);
7596                   DebugLn('WARNING: QEventWindowActivate(**',dbgsName(LCLObject),'**) ',
7597                     Format('%s wm invalid form position: X11 x %d y %d Qt x %d y %d realized %s LCL x %d y %d margins %s x11m %s',
7598                     [GetWindowManager, R.Left, R.Top, QWidget_x(Widget), QWidget_y(Widget), dbgs(GetX11WindowRealized(QWidget_winID(Widget))), LCLObject.Left, LCLObject.Top, dbgs(FrameMargins),dbgs(ATempFrame)]));
7599                   DebugLn('  Attributes ',Format('x %d y %d w %d h %d border %d x11wob x %d y %d',[ALeft, ATop, AWidth, AHeight, ABorder,R.Left, R.Top]));
7600                   {$ENDIF}
7601                   FFormHasInvalidPosition := True;
7602                   // KWin under KDE5 makes problem sometimes since
7603                   // Qt and X11 values are totally unsynced
7604                   if QX11Info_isCompositingManagerRunning and (GetKdeSessionVersion = 5) then
7605                   begin
7606                     {$IF DEFINED(DEBUGQTUSEACCURATEFRAME) OR DEFINED(DEBUGQTCHECKMOVESIZE)}
7607                     DebugLn(Format('**** DO NOT TOUCH QT POSITION UNDER KWin AND KDE v.%d, but we are trying coords x %d y %d',[GetKdeSessionVersion, R.Left, R.Top]));
7608                     {$ENDIF}
7609                   end else
7610                     QWidget_move(Widget, R.Left, R.Top);
7611                 end;
7612               end;
7613             end;
7614             R := QtWidgetSet.WSFrameMargins;
7615             if (R.Left = 0) and (R.Top = 0) and (R.Bottom = 0) and (R.Right = 0) then
7616             begin
7617               GetX11RectForAtom(QWidget_winID(Widget),'_NET_FRAME_EXTENTS', R);
7618               QtWidgetSet.WSFrameMargins := R;
7619               FrameMargins := R;
7620               DebugLn('WARNING: TQtMainWindow.EventFilter('+dbgsName(LCLObject)+') setting widgetset frame margins to '+dbgs(R)+' from form activation !');
7621             end else
7622             begin
7623               if QX11Info_isCompositingManagerRunning then
7624               begin
7625                 QWidget_size(Widget, @ASize);
7626                 QWidget_frameSize(Widget, @AFrameSize);
7627                 R.Left := (AFrameSize.cx - ASize.cx) div 2;
7628                 R.Right :=  R.Left;
7629                 R.Bottom := R.Left;
7630                 R.Top := (AFrameSize.cy - ASize.cy) - R.Bottom;
7631                 if (AFrameSize.cy > ASize.cy) and not EqualRect(FFrameMargins, R) then
7632                 begin
7633                   {$IF DEFINED(DEBUGQTUSEACCURATEFRAME) OR DEFINED(DEBUGQTCHECKMOVESIZE)}
7634                   DebugLn('***CHANGE FRAME MARGINS ',dbgsName(LCLObject),' OLD FFFRAME=',dbgs(FFrameMargins),' NEW FFRAME=',dbgs(R));
7635                   {$ENDIF}
7636                   // composite wm changes _NET_FRAME_EXTENTS to + or even - for shadows
7637                   // so update just this window FFrameMargins.
7638                   // eg. Gnome 3 shows modal window without title, so changes frame
7639                   // size eg from 4,27,4,4 to 1,3,1,1.
7640                   // Cinnamon have shadows eg _NET_FRAME_EXTENTS are 4,27,4,4
7641                   // but after shadowing we have 10,36,10,10. So keep them here !
7642                   // More problems comes from cinnamon since titlebar size depends
7643                   // if widget have constraints (min,max) or if widget is modal.
7644                   // All we can do is to inform LCL that handle bounds are changed.
7645                   FFrameMargins := R;
7646                   GetX11WindowPos(QWidget_winID(Widget), X11X, X11Y);
7647                   X11X -= R.Left;
7648                   X11Y -= R.Top;
7649                   {$IF DEFINED(DEBUGQTUSEACCURATEFRAME) OR DEFINED(DEBUGQTCHECKMOVESIZE)}
7650                   DebugLn(Format('  =>> X11 pos x %d y %d',[X11X, X11Y]));
7651                   {$ENDIF}
7652 
7653                   if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
7654                     QtWidgetSet.InvalidateWidgetAtCache;
7655 
7656                   FillChar(AMoveMsg{%H-}, SizeOf(AMoveMsg), #0);
7657                   AMoveMsg.Msg := LM_MOVE;
7658                   AMoveMsg.MoveType := AMoveMsg.MoveType or Move_SourceIsInterface;
7659                   AMoveMsg.XPos := SmallInt(X11X);
7660                   AMoveMsg.YPos := SmallInt(X11Y);
7661                   DeliverMessage(AMoveMsg);
7662 
7663                   FillChar(ASizeMsg{%H-}, SizeOf(ASizeMsg), #0);
7664 
7665                   ASizeMsg.Msg := LM_SIZE;
7666 
7667                   case getWindowState of
7668                     QtWindowMinimized: ASizeMsg.SizeType := SIZE_MINIMIZED;
7669                     QtWindowMaximized: ASizeMsg.SizeType := SIZE_MAXIMIZED;
7670                     QtWindowFullScreen: ASizeMsg.SizeType := SIZE_FULLSCREEN;
7671                   else
7672                     ASizeMsg.SizeType := SIZE_RESTORED;
7673                   end;
7674 
7675                   ASizeMsg.SizeType := ASizeMsg.SizeType or Size_SourceIsInterface;
7676 
7677                   AFrameSize := getFrameSize;
7678                   ASizeMsg.Width := Word(AFrameSize.cx);
7679                   ASizeMsg.Height := Word(AFrameSize.cy);
7680 
7681                   DeliverMessage(ASizeMsg);
7682 
7683 
7684                 end;
7685               end;
7686             end;
7687           end;
7688           {$ENDIF}
7689 
7690           {$IFDEF MSWINDOWS}
7691           // issues #26463, #29744, must restore app if we activate non modal window from taskbar
7692           if (Application.ModalLevel > 0) and
7693             (QApplication_activeModalWidget <> nil) and QWidget_isMinimized(QApplication_activeModalWidget) then
7694           begin
7695             W := QApplication_activeModalWidget;
7696             // back to tray
7697             BeginUpdate;
7698             ShowMinimized;
7699             EndUpdate;
7700             AState := QWidget_windowState(W);
7701             AState := AState and not QtWindowMinimized;
7702             QWidget_setWindowState(W, AState);
7703           end else
7704           {$ENDIF}
7705           SlotActivateWindow(True);
7706         end;
7707       end;
7708       QEventWindowDeactivate: if not IsMDIChild then SlotActivateWindow(False);
7709       QEventShowToParent: ; // do nothing for TQtMainWindow, but leave it unhandled
7710       QEventWindowStateChange:
7711       begin
7712         if IsMDIChild then
7713         begin
7714           //do not process QEventWindowStateChange for MDI children !
7715           //we are doing that job in MDIChildWindowStateChanged slot.
7716           exit;
7717         end;
7718 
7719         CanSendEvent := True;
7720         {$IFDEF HASX11}
7721         // for X11 we must ask state of each modified window.
7722         AState := getWindowState;
7723 
7724         IsMinimizeEvent := AState and QtWindowMinimized <> 0;
7725         if IsMinimizeEvent then
7726         begin
7727           CanSendEvent := IsCurrentDesktop(Widget);
7728           QtWidgetSet.FMinimizedByPager := not CanSendEvent;
7729           if IsMainForm and QtWidgetSet.FMinimizedByPager then
7730             QtWidgetSet.HideAllHints;
7731         end;
7732         {$ENDIF}
7733         if IsMainForm and CanSendEvent then
7734         begin
7735           {$IFNDEF HASX11}
7736           AState := getWindowState;
7737           {$ENDIF}
7738           AStateEvent := QWindowStateChangeEventH(Event);
7739           AOldState := QWindowStateChangeEvent_oldState(AStateEvent);
7740           if AState and QtWindowMinimized <> 0 then
7741           begin
7742             {$IFDEF MSWINDOWS}
7743             for i := 0 to Screen.CustomFormZOrderCount - 1 do
7744             begin
7745               AForm := Screen.CustomFormsZOrdered[i];
7746               if (AForm <> Application.MainForm) and
7747                 // (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and
7748                 AForm.HandleAllocated and AForm.Visible then
7749               begin
7750                 W := TQtWidget(AForm.Handle).Widget;
7751                 if not QWidget_isMinimized(W) then
7752                 begin
7753                   TQtWidget(AForm.Handle).BeginUpdate;
7754                   try
7755                     QWidget_showMinimized(W);
7756                   finally
7757                     TQtWidget(AForm.Handle).EndUpdate;
7758                   end;
7759                 end;
7760               end;
7761             end;
7762             {$ENDIF}
7763             Application.IntfAppMinimize;
7764           end
7765           else
7766           if (AOldState and QtWindowMinimized <> 0) or
7767             (AOldState and QtWindowMaximized <> 0) or
7768             (AOldState and QtWindowFullScreen <> 0) then
7769           begin
7770             {$IFDEF MSWINDOWS}
7771             for i := 0 to Screen.CustomFormZOrderCount - 1 do
7772             begin
7773               AForm := Screen.CustomFormsZOrdered[i];
7774               if (AForm <> Application.MainForm) and
7775                 // (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and
7776                 AForm.HandleAllocated and AForm.Visible then
7777               begin
7778                 W := TQtWidget(AForm.Handle).Widget;
7779                 if QWidget_isMinimized(W) then
7780                 begin
7781                   TQtWidget(AForm.Handle).BeginUpdate;
7782                   try
7783                     QWidget_showNormal(W);
7784                   finally
7785                     TQtWidget(AForm.Handle).EndUpdate;
7786                   end;
7787                 end;
7788               end;
7789             end;
7790             Application.IntfAppRestore;
7791             {$ELSE}
7792 
7793             {$IFDEF HASX11}
7794             // do not activate lazarus app if it wasn't active during
7795             // pager switch !
7796             if (AOldState and QtWindowMinimized <> 0) and
7797               QtWidgetSet.FMinimizedByPager then
7798             begin
7799               QtWidgetSet.FMinimizedByPager := False;
7800               QtWidgetSet.RestoreAllHints;
7801             end else
7802             {$ENDIF}
7803               Application.IntfAppRestore;
7804             {$ENDIF}
7805           end;
7806         end;
7807         if CanSendEvent and not IsFrameWindow then
7808         begin
7809           {$IFDEF MSWINDOWS}
7810           AForm := TCustomForm(LCLObject);
7811           if (fsModal in AForm.FormState) then
7812           begin
7813             AOldState := QWindowStateChangeEvent_oldState(QWindowStateChangeEventH(Event));
7814             AState := GetWindowState;
7815             SlotWindowStateChange;
7816             if (AState and QtWindowMinimized = QtWindowMinimized) and (AOldState and QtWindowMinimized = 0) then
7817               Application.Minimize
7818             else
7819             if (AOldState and QtWindowMinimized = QtWindowMinimized) and (AState and QtWindowMinimized = 0) then
7820               Application.Restore;
7821           end else
7822           if (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and InUpdate then
7823             // do not trigger LCL
7824           else
7825           {$ENDIF}
7826           SlotWindowStateChange;
7827         end;
7828       end;
7829       QEventDrop,
7830       QEventDragMove,
7831       QEventDragEnter:
7832       begin
7833         Result := getAcceptDropFiles;
7834         if (Result) and (QEvent_type(Event) = QEventDrop) then
7835           Result := slotDropFiles(Sender, Event);
7836       end;
7837       QEventResize:
7838       begin
7839         // issue #34698
7840         {$ifdef darwin}
7841         if (QResizeEvent_oldSize(QResizeEventH(Event))^.cx = -1) and (QResizeEvent_oldSize(QResizeEventH(Event))^.cy = -1) then
7842           include(FWidgetState, qtwsForceSendMove);
7843         {$endif}
7844         {$IFDEF QTSCROLLABLEFORMS}
7845         if not Assigned(ScrollArea) then
7846         {$ENDIF}
7847           Result := inherited EventFilter(Sender, Event);
7848       end;
7849       QEventPaint:
7850       begin
7851         {do not send paint or resize event to LCL if we are pure TCustomForm,
7852          CWEvent or ScrollArea.EventFilter will process it.
7853          So call SlotPaint only if we are eg TQtHintWindow.}
7854         if (FCentralWidget = nil) or (FCentralWidget = Widget) then
7855           Result := inherited EventFilter(Sender, Event);
7856       end;
7857     else
7858       Result := inherited EventFilter(Sender, Event);
7859     end;
7860   finally
7861     EndEventProcessing;
7862   end;
7863 end;
7864 
7865 procedure TQtMainWindow.MDIChildWindowStateChanged(AOldState: QtWindowStates;
7866   ANewState: QtWindowStates); cdecl;
7867 var
7868   AOld, ANew: QtWindowStates;
7869   Arr: TPtrIntArray;
7870   i: Integer;
7871   W: QMDISubWindowH;
7872   B: Boolean;
7873   FoundWin: Boolean;
7874 begin
7875   // check if state is same without active flag, in that case don't inform lcl.
7876   AOld := AOldState and not QtWindowActive;
7877   ANew := ANewState and not QtWindowActive;
7878   if AOld = ANew then
7879     exit;
7880 
7881   {inform LCL about change}
7882   SlotWindowStateChange;
7883 
7884   if (AOldState and QtWindowMinimized <> 0) and (ANewState and QtWindowMinimized = 0) and
7885     (ANewState and QtWindowMaximized = 0) and LCLObject.ClientRectNeedsInterfaceUpdate then
7886     LCLObject.DoAdjustClientRectChange(True);
7887 
7888   {activate next mdi in chain if we are minimized}
7889   if Assigned(MDIChildArea) and
7890     (ANewState and QtWindowMinimized = QtWindowMinimized) and
7891     (ANewState and QtWindowActive = QtWindowActive) then
7892   begin
7893     QMdiArea_subWindowList(QMdiAreaH(MDIChildArea.Widget), @Arr);
7894     // activate only if MDIChild is not minimized !
7895     // we are using *history activation order*,
7896     // so we must take into account index of
7897     // current minimized win.
7898     B := False;
7899     FoundWin := False;
7900     for i := High(Arr) downto 0 do
7901     begin
7902       W := QMdiSubWindowH(Arr[i]);
7903       AOld := QWidget_windowState(W);
7904       B := W = Widget;
7905       if B and (W <> Widget) and (AOld and QtWindowMinimized = 0) then
7906       begin
7907         FoundWin := True;
7908         MDIChildArea.ActivateSubWindow(W);
7909         break;
7910       end;
7911     end;
7912     // not found lower index window, search for higher one
7913     if not FoundWin then
7914     begin
7915       for i := High(Arr) downto 0 do
7916       begin
7917         W := QMdiSubWindowH(Arr[i]);
7918         AOld := QWidget_windowState(W);
7919         if (W <> Widget) and (AOld and QtWindowMinimized = 0) then
7920         begin
7921           MDIChildArea.ActivateSubWindow(W);
7922           break;
7923         end;
7924       end;
7925     end;
7926 
7927   end;
7928 end;
7929 
IsFramedWidgetnull7930 function TQtMainWindow.IsFramedWidget: boolean;
7931 begin
7932   Result:=inherited IsFramedWidget;
7933   {$IFDEF QtUseAccurateFrame}
7934   Result := not IsMDIChild and (LCLObject.Parent = nil) and
7935     (TCustomForm(LCLObject).BorderStyle <> bsNone) and
7936     (TCustomForm(LCLObject).FormStyle <> fsSplash);
7937   {$ENDIF}
7938 end;
7939 
IsMdiChildnull7940 function TQtMainWindow.IsMdiChild: Boolean;
7941 begin
7942   Result := (LCLObject <> nil) and not IsFrameWindow and not
7943     (csDesigning in LCLObject.ComponentState) and
7944     (TCustomForm(LCLObject).FormStyle = fsMDIChild) and not IsFormDesign(LCLObject);
7945 end;
7946 
IsModalnull7947 function TQtMainWindow.IsModal: Boolean;
7948 begin
7949   Result := QWidget_isModal(Widget);
7950 end;
7951 
MdiChildCountnull7952 function TQtMainWindow.MdiChildCount: integer;
7953 var
7954   Arr: TPtrIntArray;
7955   Area: QMdiAreaH;
7956 begin
7957   Result := 0;
7958   if IsMdiChild then
7959     Area := QMdiSubWindow_mdiArea(QMdiSubWindowH(Widget))
7960   else
7961     Area := QMDIAreaH(MDIAreaHandle.Widget);
7962   if Area <> nil then
7963   begin
7964     QMdiArea_subWindowList(Area, @Arr);
7965     Result := High(Arr);
7966   end;
7967 end;
7968 
7969 procedure TQtMainWindow.OffsetMousePos(APoint: PQtPoint);
7970 begin
7971   if not IsMdiChild then
7972     inherited OffsetMousePos(APoint);
7973 end;
7974 
7975 procedure TQtMainWindow.setAcceptDropFiles(AValue: Boolean);
7976 begin
7977   QWidget_setAcceptDrops(Widget, AValue);
7978 end;
7979 
7980 procedure TQtMainWindow.setColor(const Value: PQColor);
7981 var
7982   p: QPaletteH;
7983 begin
7984   inherited setColor(Value);
7985   if Assigned(MDIAreaHandle) and Assigned(FCentralWidget) then
7986   begin
7987     p := QWidget_palette(FCentralWidget);
7988     if p <> nil then
7989       QMdiArea_setBackground(QMdiAreaH(MdiAreaHandle.Widget), QPalette_background(P));
7990   end;
7991 end;
7992 
7993 procedure TQtMainWindow.setFocusPolicy(const APolicy: QtFocusPolicy);
7994 begin
7995   {$IFDEF QTSCROLLABLEFORMS}
7996   if Assigned(ScrollArea) then
7997     ScrollArea.setFocusPolicy(APolicy)
7998   else
7999     inherited setFocusPolicy(APolicy);
8000   {$ELSE}
8001   inherited setFocusPolicy(APolicy);
8002   {$ENDIF}
8003 end;
8004 
8005 procedure TQtMainWindow.SlotActivateWindow(vActivate: Boolean); cdecl;
8006 var
8007   Msg: TLMActivate;
8008   FIsActivated: Boolean;
8009 begin
8010   {$ifdef VerboseQt}
8011   WriteLn('TQtWidget.SlotActivateWindow Name', LCLObject.Name, ' vActivate: ', dbgs(vActivate));
8012   {$endif}
8013 
8014   if IsFrameWindow then
8015     exit;
8016 
8017   FillChar(Msg{%H-}, SizeOf(Msg), #0);
8018 
8019   FIsActivated := TCustomForm(LCLObject).Active;
8020   {do not send activate if form is already activated,
8021    also do not send activate if TCustomForm.Parent is assigned
8022    since it's form embedded into another control or form}
8023   if (vActivate = FIsActivated) or (LCLObject.Parent <> nil) then
8024     exit;
8025 
8026   Msg.Msg := LM_ACTIVATE;
8027   if vActivate then
8028     Msg.Active := WA_ACTIVE
8029   else
8030     Msg.Active := WA_INACTIVE;
8031   Msg.ActiveWindow := LCLObject.Handle;
8032 
8033   DeliverMessage(Msg);
8034 end;
8035 
8036 {------------------------------------------------------------------------------
8037   Function: TQtMainWindow.SlotWindowStateChange
8038   Params:  None
8039   Returns: Nothing
8040  ------------------------------------------------------------------------------}
8041 procedure TQtMainWindow.slotWindowStateChange; cdecl;
8042 var
8043   Msg: TLMSize;
8044 begin
8045   {$ifdef VerboseQt}
8046     WriteLn('TQtMainWindow.SlotWindowStateChange');
8047   {$endif}
8048 
8049   FillChar(Msg{%H-}, SizeOf(Msg), #0);
8050 
8051   Msg.Msg := LM_SIZE;
8052   Msg.SizeType := SIZE_RESTORED;
8053 
8054   if getWindowState and QtWindowMinimized <> 0 then
8055     Msg.SizeType := SIZE_MINIMIZED
8056   else
8057   if (getWindowState and QtWindowFullScreen <> 0) then
8058     Msg.SizeType := SIZE_FULLSCREEN
8059   else
8060   if (getWindowState and QtWindowMaximized <> 0) then
8061     Msg.SizeType := SIZE_MAXIMIZED;
8062 
8063   Msg.SizeType := Msg.SizeType or Size_SourceIsInterface;
8064 
8065   {Mdichild sends size of minimized title, and that's bad, after restore client
8066    rect is mismatched and provokes OnResize events.We are sending
8067    to the LCL Width and Height of LCLObject so resize event won't trigger.
8068    issue #27518}
8069   if IsMDIChild and Assigned(LCLObject) and
8070     (getWindowState and QtWindowMinimized <> 0) then
8071   begin
8072     Msg.Width := Word(LCLObject.Width);
8073     Msg.Height := Word(LCLObject.Height);
8074   end else
8075   begin
8076     Msg.Width := Word(getWidth);
8077     Msg.Height := Word(getHeight);
8078   end;
8079   DeliverMessage(Msg);
8080 end;
8081 
8082 procedure TQtMainWindow.setShowInTaskBar(AValue: Boolean);
8083 begin
8084   FShowOnTaskBar := AValue;
8085   {$IFNDEF HASX11}
8086   if not QWidget_isModal(Widget) then
8087     UpdateParent;
8088   {$ENDIF}
8089 end;
8090 
8091 procedure TQtMainWindow.setRealPopupParent(NewParent: QWidgetH);
8092 begin
8093   FPopupParent := NewParent;
8094   UpdateParent;
8095 end;
8096 
8097 procedure TQtMainWindow.AttachEvents;
8098 begin
8099   inherited AttachEvents;
8100   {$IFDEF QTSCROLLABLEFORMS}
8101   FCWEventHook := nil;
8102   {$ENDIF}
8103   if (FCentralWidget <> nil)
8104     {$IFDEF QTSCROLLABLEFORMS} and not Assigned(ScrollArea){$ENDIF} then
8105   begin
8106     FCWEventHook := QObject_hook_create(FCentralWidget);
8107     QObject_hook_hook_events(FCWEventHook, @CWEventFilter);
8108   end;
8109   if IsMDIChild then
8110   begin
8111     FMDIStateHook := QMdiSubWindow_hook_create(Widget);
8112     QMdiSubWindow_hook_hook_windowStateChanged(FMDIStateHook,
8113       @MDIChildWindowStateChanged);
8114   end;
8115 end;
8116 
8117 procedure TQtMainWindow.DetachEvents;
8118 begin
8119   if FCWEventHook <> nil then
8120   begin
8121     QObject_hook_destroy(FCWEventHook);
8122     FCWEventHook := nil;
8123   end;
8124 
8125   if FMDIStateHook <> nil then
8126   begin
8127     QMdiSubWindow_hook_destroy(FMDIStateHook);
8128     FMDIStateHook := nil;
8129   end;
8130 
8131   inherited DetachEvents;
8132 end;
8133 
TQtMainWindow.CWEventFilternull8134 function TQtMainWindow.CWEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
8135 var
8136   R: TRect;
8137   R2: TRect;
8138   i: Integer;
8139 begin
8140   Result := False;
8141 
8142   if LCLObject <> nil then
8143   begin
8144     case QEvent_type(Event) of
8145       QEventPaint: Result := inherited EventFilter(Sender, Event);
8146       QEventResize:
8147         begin
8148           {mdi area part begins}
8149           if MdiAreaHandle <> nil then
8150           begin
8151             {first must get contents rect - all except main menu}
8152             QWidget_contentsRect(FCentralWidget, @R);
8153             {TODO: find better way to find out which controls are top,left,right & bottom aligned ...}
8154             for i := 0 to LCLObject.ControlCount - 1 do
8155             begin
8156               if (LCLObject.Controls[i] is TWinControl) and
8157                 (TWinControl(LCLObject.Controls[i]).Align in [alTop, alLeft, alRight, alBottom]) then
8158               begin
8159                 R2 := TWinControl(LCLObject.Controls[i]).BoundsRect;
8160                 case TWinControl(LCLObject.Controls[i]).Align of
8161                   alLeft: R.Left := R.Left + (R2.Right - R2.Left);
8162                   alTop: R.Top := R.Top + (R2.Bottom - R2.Top);
8163                   alRight: R.Right := R.Right - (R2.Right - R2.Left);
8164                   alBottom: R.Bottom := R.Bottom - (R2.Bottom - R2.Top);
8165                 end;
8166               end;
8167             end; {components loop}
8168             QWidget_setGeometry(MDIAreaHandle.Widget, @R);
8169           end;
8170           {mdi area part end}
8171         end;
8172     end;
8173   end;
8174 end;
8175 
8176 { TQtStaticText }
8177 
TQtStaticText.GetWordWrapnull8178 function TQtStaticText.GetWordWrap: Boolean;
8179 begin
8180   Result := QLabel_wordWrap(QLabelH(Widget));
8181 end;
8182 
8183 procedure TQtStaticText.SetWordWrap(AValue: Boolean);
8184 begin
8185   QLabel_setWordWrap(QLabelH(Widget), AValue);
8186 end;
8187 
CreateWidgetnull8188 function TQtStaticText.CreateWidget(const AParams: TCreateParams): QWidgetH;
8189 var
8190   Parent: QWidgetH;
8191 begin
8192   // Creates the widget
8193   {$ifdef VerboseQt}
8194     WriteLn('TQtStaticText.Create');
8195   {$endif}
8196   FWidgetNeedFontColorInitialization := True;
8197   if AParams.WndParent <> 0 then
8198     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8199   else
8200     Parent := nil;
8201   Result := QLabel_create(Parent);
8202 end;
8203 
TQtStaticText.CanPaintBackgroundnull8204 function TQtStaticText.CanPaintBackground: Boolean;
8205 begin
8206   Result := CanSendLCLMessage and getEnabled and
8207     (LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
8208 end;
8209 
8210 {------------------------------------------------------------------------------
8211   Function: TQtStaticText.SetText
8212   Params:  None
8213   Returns: Nothing
8214  ------------------------------------------------------------------------------}
8215 procedure TQtStaticText.SetText(const W: WideString);
8216 var
8217   AmpersandPos: Integer;
8218   LocalW: WideString;
8219 begin
8220   LocalW := W;
8221   if TCustomStaticText(LCLObject).ShowAccelChar then
8222   begin
8223     // replace '&' by underline
8224     AmpersandPos := Pos('&', W);
8225     if AmpersandPos > 0 then
8226     begin
8227       LocalW := Copy(W, 1, AmpersandPos - 1) + '<u>';
8228       if AmpersandPos < Length(W) then
8229         LocalW := LocalW + W[AmpersandPos + 1];
8230       LocalW := LocalW + '</u>' + Copy(W, AmpersandPos + 2, Length(W));
8231     end;
8232   end;
8233   QLabel_setText(QLabelH(Widget), @LocalW);
8234 end;
8235 
8236 procedure TQtStaticText.setAlignment(const AAlignment: QtAlignment);
8237 begin
8238   QLabel_setAlignment(QLabelH(Widget), AAlignment);
8239 end;
8240 
8241 {------------------------------------------------------------------------------
8242   Function: TQtStaticText.Text
8243   Params:  None
8244   Returns: Nothing
8245  ------------------------------------------------------------------------------}
TQtStaticText.getTextnull8246 function TQtStaticText.getText: WideString;
8247 begin
8248   QLabel_text(QLabelH(Widget), @Result);
8249 end;
8250 
8251 { TQtCheckBox }
8252 
CreateWidgetnull8253 function TQtCheckBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
8254 var
8255   Parent: QWidgetH;
8256 begin
8257   // Creates the widget
8258   {$ifdef VerboseQt}
8259     WriteLn('TQtCheckBox.Create');
8260   {$endif}
8261   TextColorRole := QPaletteWindowText;
8262   FWidgetNeedFontColorInitialization := True;
8263   if AParams.WndParent <> 0 then
8264     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8265   else
8266     Parent := nil;
8267 
8268   Result := QCheckBox_create(Parent);
8269 end;
8270 
8271 {------------------------------------------------------------------------------
8272   Function: TQtCheckBox.CheckState
8273   Params:  None
8274   Returns: Nothing
8275  ------------------------------------------------------------------------------}
TQtCheckBox.CheckStatenull8276 function TQtCheckBox.CheckState: QtCheckState;
8277 begin
8278   Result := QCheckBox_checkState(QCheckBoxH(Widget));
8279 end;
8280 
8281 {------------------------------------------------------------------------------
8282   Function: TQtCheckBox.setCheckState
8283   Params:  None
8284   Returns: Nothing
8285  ------------------------------------------------------------------------------}
8286 procedure TQtCheckBox.setCheckState(state: QtCheckState);
8287 begin
8288   QCheckBox_setCheckState(QCheckBoxH(Widget), state);
8289 end;
8290 
8291 procedure TQtCheckBox.setTriState(AAllowGrayed: Boolean);
8292 begin
8293   QCheckBox_setTristate(QCheckBoxH(Widget), AAllowGrayed);
8294 end;
8295 
8296 procedure TQtCheckBox.AttachEvents;
8297 begin
8298   inherited AttachEvents;
8299   FStateChangedHook := QCheckBox_hook_create(Widget);
8300   QCheckBox_hook_hook_stateChanged(FStateChangedHook, @SignalStateChanged);
8301 end;
8302 
8303 procedure TQtCheckBox.DetachEvents;
8304 begin
8305   if FStateChangedHook <> nil then
8306   begin
8307     QCheckBox_hook_destroy(FStateChangedHook);
8308     FStateChangedHook := nil;
8309   end;
8310   inherited DetachEvents;
8311 end;
8312 
8313 {------------------------------------------------------------------------------
8314   Function: TQtCheckBox.signalStateChanged
8315   Params:  None
8316   Returns: Nothing
8317  ------------------------------------------------------------------------------}
8318 procedure TQtCheckBox.signalStateChanged(p1: Integer); cdecl;
8319 var
8320   Msg: TLMessage;
8321 begin
8322   if not InUpdate then
8323   begin
8324     FillChar(Msg{%H-}, SizeOf(Msg), #0);
8325     Msg.Msg := LM_CHANGED;
8326     DeliverMessage(Msg);
8327   end;
8328 end;
8329 
8330 { TQtRadioButton }
8331 
TQtRadioButton.CreateWidgetnull8332 function TQtRadioButton.CreateWidget(const AParams: TCreateParams): QWidgetH;
8333 var
8334   Parent: QWidgetH;
8335 begin
8336   // Creates the widget
8337   {$ifdef VerboseQt}
8338     WriteLn('TQtRadioButton.Create');
8339   {$endif}
8340   TextColorRole := QPaletteWindowText;
8341   FWidgetNeedFontColorInitialization := True;
8342   if AParams.WndParent <> 0 then
8343     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8344   else
8345     Parent := nil;
8346   Result := QRadioButton_create(Parent);
8347   // hide widget by default
8348   QWidget_hide(Result);
8349 end;
8350 
8351 procedure TQtRadioButton.AttachEvents;
8352 begin
8353   inherited AttachEvents;
8354   FToggledHook := QAbstractButton_hook_create(Widget);
8355   QAbstractButton_hook_hook_toggled(FToggledHook, @SignalToggled);
8356 end;
8357 
8358 procedure TQtRadioButton.DetachEvents;
8359 begin
8360   if FToggledHook <> nil then
8361   begin
8362     QAbstractButton_hook_destroy(FToggledHook);
8363     FToggledHook := nil;
8364   end;
8365   inherited DetachEvents;
8366 end;
8367 
8368 procedure TQtRadioButton.SignalToggled(Checked: Boolean); cdecl;
8369 var
8370   Msg: TLMessage;
8371 begin
8372   if not InUpdate then
8373   begin
8374     FillChar(Msg{%H-}, SizeOf(Msg), #0);
8375     Msg.Msg := LM_CHANGED;
8376     DeliverMessage(Msg);
8377   end;
8378 end;
8379 
TQtRadioButton.EventFilternull8380 function TQtRadioButton.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
8381 begin
8382   Result := inherited EventFilter(Sender, Event);
8383   if (LCLObject <> nil) and
8384     ((QEvent_type(Event) in [QEventMouseButtonPress, QEventMouseButtonRelease])
8385     or
8386     ((QEvent_type(Event) in [QEventKeyPress, QEventKeyRelease]) and
8387      (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
8388      isChecked))
8389   then
8390     Result := False;
8391 end;
8392 
8393 { TQtGroupBox }
8394 
8395 procedure TQtGroupBox.setLayoutThemeMargins(ALayout: QLayoutH; AWidget: QWidgetH);
8396 var
8397   LeftMargin: Integer;
8398   TopMargin: Integer;
8399   RightMargin: Integer;
8400   BottomMargin: Integer;
8401   {$IFDEF HASX11}
8402   Font: QFontH;
8403   FontMetrics: QFontMetricsH;
8404   FontHeight: Integer;
8405   {$ENDIF}
8406 begin
8407   if ALayout = nil then
8408     exit;
8409   QWidget_getContentsMargins(AWidget,@LeftMargin, @TopMargin, @RightMargin, @BottomMargin);
8410 
8411   {if contentsMargins TopMargin is huge then we must rethink about TopMargin
8412    size (eg.oxygen theme have 32 top margin while plastique have 19
8413    with same font height) }
8414   {$IFDEF HASX11}
8415   Font := QWidget_font(AWidget);
8416   FontMetrics := QFontMetrics_create(Font);
8417   try
8418     FontHeight := QFontMetrics_height(FontMetrics);
8419   finally
8420     QFontMetrics_destroy(FontMetrics);
8421   end;
8422   {currently applies only to wrong TopMargin calculation (eg.gtk style).}
8423   if (TopMargin - FontHeight < 2) then
8424     TopMargin := FontHeight + 2 // top & bottom +1px
8425   else {currently applies only to oxygen & nitrogen theme.}
8426   if ((TopMargin - BottomMargin - 2) > FontHeight) then
8427   begin
8428     {do not touch fusion style !}
8429     if QtWidgetSet.StyleName <> 'fusion' then
8430     begin
8431       TopMargin := TopMargin - BottomMargin - 3;
8432       BottomMargin := 0;
8433     end;
8434   end;
8435   {$ENDIF}
8436   {if there's no text set margin to bottom margin size. issue #23642}
8437   if getText = '' then
8438     TopMargin := BottomMargin;
8439   QLayout_setContentsMargins(ALayout, LeftMargin, TopMargin, RightMargin, BottomMargin);
8440   QLayout_invalidate(ALayout);
8441 
8442   if (LCLObject <> nil) and testAttribute(QtWA_Mapped) then
8443   begin
8444     {.$IFDEF VerboseQtResize}
8445     DebugLn('TQtGroupBox.setLayoutThemeMargins: ',dbgsName(LCLObject),' casp: ',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' mapped ',dbgs(testAttribute(QtWA_Mapped)));
8446     {.$ENDIF}
8447     LCLObject.DoAdjustClientRectChange(False);
8448     LCLObject.InvalidateClientRectCache(True);
8449   end;
8450 end;
8451 
TQtGroupBox.GetCheckBoxVisiblenull8452 function TQtGroupBox.GetCheckBoxVisible: boolean;
8453 begin
8454   Result := QGroupBox_isCheckable(QGroupBoxH(Widget));
8455 end;
8456 
GetCheckBoxStatenull8457 function TQtGroupBox.GetCheckBoxState: boolean;
8458 begin
8459   Result := CheckBoxVisible and QGroupBox_isChecked(QGroupBoxH(Widget));
8460 end;
8461 
8462 procedure TQtGroupBox.SetCheckBoxState(AValue: boolean);
8463 begin
8464   if CheckBoxVisible then
8465     QGroupBox_setChecked(QGroupBoxH(Widget), AValue);
8466 end;
8467 
8468 procedure TQtGroupBox.SetCheckBoxVisible(AValue: boolean);
8469 begin
8470   QGroupBox_setCheckable(QGroupBoxH(Widget), AValue);
8471 end;
8472 
TQtGroupBox.CreateWidgetnull8473 function TQtGroupBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
8474 var
8475   Layout: QBoxLayoutH;
8476   Parent: QWidgetH;
8477 begin
8478   // Creates the widget
8479   {$ifdef VerboseQt}
8480     WriteLn('TQtGroupBox.Create ');
8481   {$endif}
8482   FGroupBoxType := tgbtNormal;
8483   FHasPaint := True;
8484   if AParams.WndParent <> 0 then
8485     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8486   else
8487     Parent := nil;
8488   Result := QGroupBox_create(Parent);
8489   FCentralWidget := QStackedWidget_create(Result);
8490   QWidget_setMouseTracking(FCentralWidget, True);
8491   {we set QtNoFocus by default, since we don't want
8492   FCentralWidget grabs focus on mouse click}
8493   QWidget_setFocusPolicy(FCentralWidget, QtNoFocus);
8494 
8495   Layout := QVBoxLayout_create(Result);
8496   QLayout_addWidget(Layout, FCentralWidget);
8497   QWidget_setLayout(Result, QLayoutH(Layout));
8498   QWidget_setAttribute(Result, QtWA_LayoutOnEntireRect, True);
8499 end;
8500 
8501 procedure TQtGroupBox.AttachEvents;
8502 begin
8503   inherited AttachEvents;
8504   if FCentralWidget <> nil then
8505   begin
8506     FCWEventHook := QObject_hook_create(FCentralWidget);
8507     QObject_hook_hook_events(FCWEventHook, @EventFilter);
8508   end;
8509 end;
8510 
8511 procedure TQtGroupBox.DetachEvents;
8512 begin
8513   if FCWEventHook <> nil then
8514   begin
8515     QObject_hook_destroy(FCWEventHook);
8516     FCWEventHook := nil;
8517   end;
8518   inherited DetachEvents;
8519 end;
8520 
TQtGroupBox.CanPaintBackgroundnull8521 function TQtGroupBox.CanPaintBackground: Boolean;
8522 begin
8523   Result := CanSendLCLMessage and getEnabled and
8524     (LCLObject.Color <> clDefault);
8525 end;
8526 
TQtGroupBox.EventFilternull8527 function TQtGroupBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
8528   cdecl;
8529 var
8530   ResizeEvent: QResizeEventH;
8531   NewSize, OldSize: TSize;
8532 begin
8533   Result := False;
8534   QEvent_accept(Event);
8535   if LCLObject = nil then
8536     exit;
8537 
8538   if (Sender = FCentralWidget) then
8539   begin
8540     case QEvent_type(Event) of
8541       QEventPaint: Result := inherited EventFilter(Sender, Event);
8542     end;
8543     exit;
8544   end;
8545   {For possible problems with Mouse events check issue #29572 and #32186}
8546   case QEvent_type(Event) of
8547     QEventPaint:
8548       begin
8549         Result := False;
8550         // paint complete background, like gtk2 does
8551         if CanPaintBackground then
8552           SlotPaintBg(Sender, Event);
8553         // issue #28155, we are painting our FCentralWidget, not QGroupBox
8554         // Result := inherited EventFilter(Sender, Event);
8555       end;
8556     QEventFontChange:
8557       begin
8558         Result := inherited EventFilter(Sender, Event);
8559         setLayoutThemeMargins(QWidget_layout(Widget), Widget);
8560       end;
8561     QEventStyleChange: setLayoutThemeMargins(QWidget_layout(Widget), Widget);
8562     QEventContentsRectChange:
8563       begin
8564         if testAttribute(QtWA_Mapped) then
8565           Result := inherited EventFilter(Sender, Event);
8566       end;
8567     QEventShow:
8568       begin
8569         {$IFDEF VerboseQtResize}
8570         DebugLn('TQtGroupBox.QEventShow: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' mapped=',dbgs(testAttribute(QtWA_Mapped)));
8571         {$ENDIF}
8572         LCLObject.DoAdjustClientRectChange(False);
8573         SlotShow(True);
8574         {send dummy LM_SIZE to LCL}
8575         if (FGroupBoxType <> tgbtNormal) and
8576           LCLObject.ClientRectNeedsInterfaceUpdate then
8577         begin
8578           OldSize.cx := LCLObject.Height;
8579           OldSize.cy := LCLObject.Width;
8580           NewSize := OldSize;
8581           inc(OldSize.cx);
8582           inc(OldSize.cy);
8583           ResizeEvent := QResizeEvent_create(@NewSize, @OldSize);
8584           QCoreApplication_postEvent(Widget, ResizeEvent, -1);
8585         end;
8586       end;
8587     else
8588       Result := inherited EventFilter(Sender, Event);
8589   end;
8590 end;
8591 
TQtGroupBox.getClientOffsetnull8592 function TQtGroupBox.getClientOffset: TPoint;
8593 begin
8594   Result:=inherited getClientOffset;
8595   // issue #28155
8596   // there's no client offset since FCentralWidget is at it's position 0,0
8597   if testAttribute(QtWA_Mapped) and QWidget_testAttribute(FCentralWidget, QtWA_Mapped) then
8598     Result := Point(0, 0);
8599 end;
8600 
getClientBoundsnull8601 function TQtGroupBox.getClientBounds: TRect;
8602 var
8603   R, R1: TRect;
8604   L: Integer;
8605   T: Integer;
8606   aRight: Integer;
8607   B: Integer;
8608   AStyleOption: QStyleOptionGroupBoxH;
8609   APixelMetric: Integer;
8610 begin
8611   QWidget_contentsRect(Widget, @R);
8612   if Assigned(FCentralWidget) then
8613     QWidget_rect(FCentralWidget, @R1)
8614   else
8615     R1 := Rect(0, 0, 0, 0);
8616   Result := R;
8617   OffsetRect(Result, -Result.Left, -Result.Top);
8618   {$IFNDEF HASX11}
8619   if testAttribute(QtWA_Mapped) and QWidget_testAttribute(FCentralWidget, QtWA_Mapped) then
8620     QWidget_rect(FCentralWidget, @Result)
8621   else
8622   {$ENDIF}
8623   begin
8624     if Assigned(FCentralWidget) and not IsRectEmpty(R1) then
8625     begin
8626       R := R1;
8627       R1.Left := 0;
8628       R1.Top := 0;
8629       R1.Right := R1.Right - R.Left;
8630       R1.Bottom := R1.Bottom - R.Top;
8631       QWidget_getContentsMargins(Widget,@L, @T, @aRight, @B);
8632       AStyleOption := QStyleOptionGroupBox_create;
8633       APixelMetric := QStyle_pixelMetric(QApplication_style(), QStylePM_DefaultChildMargin, AStyleOption, Widget);
8634       if APixelMetric = 4 then
8635         APixelMetric := 9
8636       else
8637         APixelMetric := 0;
8638       QStyleOptionGroupBox_destroy(AStyleOption);
8639       inc(Result.Bottom, APixelMetric);
8640       {$IFDEF VerboseQtResize}
8641       DebugLn('>>>>>>>>>>> TQtGroupBox.getClientBounds(',dbgsName(LCLObject),') setting clientBounds was ',dbgs(R),' changed to ',dbgs(R1),' from result ',dbgs(Result));
8642       DebugLn('    MARGINS ARE ',Format('l %d t %d r %d b %d',[L, T, ARight, B]),' APixelMetric=',dbgs(APixelMetric));
8643       {$ENDIF}
8644       exit;
8645     end;
8646   end;
8647   {$IFDEF VerboseQtResize}
8648   DebugLn('TQtGroupBox.getClientBounds(',dbgsName(LCLObject),') R=',dbgs(R),' Result=',dbgs(Result),' CENTRALWIDGET=',dbgs(R1),' mapped ',dbgs(testAttribute(QtWA_Mapped)));
8649   {$ENDIF}
8650 end;
8651 
getTextnull8652 function TQtGroupBox.getText: WideString;
8653 begin
8654   QGroupBox_title(QGroupBoxH(Widget), @Result);
8655 end;
8656 
8657 procedure TQtGroupBox.preferredSize(var PreferredWidth,
8658   PreferredHeight: integer; WithThemeSpace: Boolean);
8659 var
8660   L, T, R, B: Integer;
8661   ASize: TSize;
8662 begin
8663   QWidget_getContentsMargins(Widget,@L, @T, @R, @B);
8664   QGroupBox_minimumSizeHint(QGroupBoxH(Widget), @ASize);
8665   PreferredWidth := ASize.cx + L + R;
8666   PreferredHeight := ASize.cy + B + T;
8667   {$IFDEF VerboseQtResize}
8668   DebugLn('TQtGroupBox.preferredSize(',dbgsName(LCLObject),' PrefW=',dbgs(PreferredWidth),
8669     ' PrefH=',dbgs(PreferredHeight),' Mapped ? ',dbgs(testAttribute(QtWA_Mapped)),
8670     ' SizeHint ',dbgs(ASize),' casp ',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
8671   {$ENDIF}
8672 end;
8673 
8674 procedure TQtGroupBox.setText(const W: WideString);
8675 begin
8676   QGroupBox_setTitle(QGroupBoxH(Widget), @W);
8677   setLayoutThemeMargins(QWidget_Layout(Widget), Widget);
8678 end;
8679 
8680 procedure TQtGroupBox.setFocusPolicy(const APolicy: QtFocusPolicy);
8681 begin
8682   if Assigned(LCLObject) and not LCLObject.TabStop then
8683     inherited setFocusPolicy(QtNoFocus)
8684   else
8685     inherited setFocusPolicy(APolicy);
8686 end;
8687 
8688 procedure TQtGroupBox.Update(ARect: PRect);
8689 var
8690   P: TPoint;
8691   R: TRect;
8692 begin
8693   if Assigned(FCentralWidget) then
8694   begin
8695     if ARect <> nil then
8696     begin
8697       P := getClientOffset;
8698       R := ARect^;
8699       OffsetRect(R, -P.X, -P.Y);
8700       QWidget_update(FCentralWidget, @R);
8701     end else
8702       QWidget_update(FCentralWidget);
8703   end else
8704     inherited Update(ARect);
8705 end;
8706 
8707 procedure TQtGroupBox.UpdateRegion(ARgn: QRegionH);
8708 var
8709   P: TPoint;
8710 begin
8711   if Assigned(FCentralWidget) then
8712   begin
8713     if ARgn <> nil then
8714     begin
8715       P := getClientOffset;
8716       QRegion_translate(ARgn, -P.X, -P.Y);
8717       QWidget_update(FCentralWidget, ARgn)
8718     end else
8719       QWidget_update(FCentralWidget);
8720   end else
8721     inherited UpdateRegion(ARgn);
8722 end;
8723 
8724 procedure TQtGroupBox.Repaint(ARect: PRect);
8725 var
8726   P: TPoint;
8727   R: TRect;
8728 begin
8729   if Assigned(FCentralWidget) then
8730   begin
8731     if ARect <> nil then
8732     begin
8733       P := getClientOffset;
8734       R := ARect^;
8735       OffsetRect(R, -P.X, -P.Y);
8736       QWidget_repaint(FCentralWidget, @R);
8737     end else
8738       QWidget_repaint(FCentralWidget);
8739   end else
8740   inherited Repaint(ARect);
8741 end;
8742 
8743 { TQtFrame }
8744 
CreateWidgetnull8745 function TQtFrame.CreateWidget(const AParams: TCreateParams): QWidgetH;
8746 var
8747   Parent: QWidgetH;
8748 begin
8749   // Creates the widget
8750   {$ifdef VerboseQt}
8751     WriteLn('TQtFrame.Create');
8752   {$endif}
8753   FHasPaint := True;
8754   if AParams.WndParent <> 0 then
8755     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8756   else
8757     Parent := nil;
8758   Result := QFrame_create(Parent);
8759 end;
8760 
TQtFrame.CanPaintBackgroundnull8761 function TQtFrame.CanPaintBackground: Boolean;
8762 begin
8763   Result := CanSendLCLMessage and getEnabled and
8764     (LCLObject.Color <> clBackground);
8765   if Result and (LCLObject is TCustomPanel) then
8766   begin
8767     Result := (TCustomPanel(LCLObject).BevelInner = bvNone) and
8768      (TCustomPanel(LCLObject).BevelOuter = bvNone);
8769   end;
8770 end;
8771 
8772 procedure TQtFrame.setFocusPolicy(const APolicy: QtFocusPolicy);
8773 begin
8774   if Assigned(LCLObject) and not LCLObject.TabStop then
8775     inherited setFocusPolicy(QtNoFocus)
8776   else
8777     inherited setFocusPolicy(APolicy);
8778 end;
8779 
8780 {------------------------------------------------------------------------------
8781   Function: TQtFrame.setFrameStyle
8782   Params:  None
8783   Returns: Nothing
8784  ------------------------------------------------------------------------------}
8785 procedure TQtFrame.setFrameStyle(p1: Integer);
8786 begin
8787   QFrame_setFrameStyle(QFrameH(Widget), p1);
8788 end;
8789 
8790 {------------------------------------------------------------------------------
8791   Function: TQtFrame.setFrameShape
8792   Params:  None
8793   Returns: Nothing
8794  ------------------------------------------------------------------------------}
8795 procedure TQtFrame.setFrameShape(p1: QFrameShape);
8796 begin
8797   QFrame_setFrameShape(QFrameH(Widget), p1);
8798 end;
8799 
8800 {------------------------------------------------------------------------------
8801   Function: TQtFrame.setFrameShadow
8802   Params:  None
8803   Returns: Nothing
8804  ------------------------------------------------------------------------------}
8805 procedure TQtFrame.setFrameShadow(p1: QFrameShadow);
8806 begin
8807   QFrame_setFrameShadow(QFrameH(Widget), p1);
8808 end;
8809 
8810 {------------------------------------------------------------------------------
8811   Function: TQtArrow.CreateWidget
8812   Params:  None
8813   Returns: Nothing
8814  ------------------------------------------------------------------------------}
TQtArrow.CreateWidgetnull8815 function TQtArrow.CreateWidget(const AParams: TCreateParams):QWidgetH;
8816 var
8817   Parent: QWidgetH;
8818 begin
8819   // Creates the widget
8820   {$ifdef VerboseQt}
8821     WriteLn('TQtArrow.Create');
8822   {$endif}
8823   FHasPaint := True;
8824   if AParams.WndParent <> 0 then
8825     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8826   else
8827     Parent := nil;
8828   Result := QFrame_create(Parent);
8829 end;
8830 
CreateWidgetnull8831 function TQtAbstractSlider.CreateWidget(const AParams: TCreateParams): QWidgetH;
8832 var
8833   Parent: QWidgetH;
8834 begin
8835   // Creates the widget
8836   {$ifdef VerboseQt}
8837     WriteLn('TQtAbstractSlider.Create');
8838   {$endif}
8839 
8840   FSliderPressed := False;
8841   FSliderReleased:= False;
8842 
8843   if AParams.WndParent <> 0 then
8844     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
8845   else
8846     Parent := nil;
8847   Result := QAbstractSlider_create(Parent);
8848 end;
8849 
8850 procedure TQtAbstractSlider.AttachEvents;
8851 begin
8852   inherited AttachEvents;
8853   FRangeChangedHook := QAbstractSlider_hook_create(Widget);
8854   FSliderMovedHook :=  QAbstractSlider_hook_create(Widget);
8855   FSliderPressedHook := QAbstractSlider_hook_create(Widget);
8856   FSliderReleasedHook := QAbstractSlider_hook_create(Widget);
8857   FValueChangedHook := QAbstractSlider_hook_create(Widget);
8858   FActionTriggeredHook := QAbstractSlider_hook_create(Widget);
8859 end;
8860 
8861 procedure TQtAbstractSlider.DetachEvents;
8862 begin
8863   if FRangeChangedHook <> nil then
8864   begin
8865     QAbstractSlider_hook_destroy(FRangeChangedHook);
8866     FRangeChangedHook := nil;
8867   end;
8868   if FSliderMovedHook <> nil then
8869   begin
8870     QAbstractSlider_hook_destroy(FSliderMovedHook);
8871     FSliderMovedHook := nil;
8872   end;
8873   if FSliderPressedHook <> nil then
8874   begin
8875     QAbstractSlider_hook_destroy(FSliderPressedHook);
8876     FSliderPressedHook := nil;
8877   end;
8878   if FSliderReleasedHook <> nil then
8879   begin
8880     QAbstractSlider_hook_destroy(FSliderReleasedHook);
8881     FSliderReleasedHook := nil;
8882   end;
8883   if FValueChangedHook <> nil then
8884   begin
8885     QAbstractSlider_hook_destroy(FValueChangedHook);
8886     FValueChangedHook := nil;
8887   end;
8888   if FActionTriggeredHook <> nil then
8889   begin
8890     QAbstractSlider_hook_destroy(FActionTriggeredHook);
8891     FActionTriggeredHook := nil;
8892   end;
8893   inherited DetachEvents;
8894 end;
8895 
getValuenull8896 function TQtAbstractSlider.getValue: Integer;
8897 begin
8898   Result := QAbstractSlider_value(QAbstractSliderH(Widget));
8899 end;
8900 
getPageStepnull8901 function TQtAbstractSlider.getPageStep: Integer;
8902 begin
8903   Result := QAbstractSlider_pageStep(QAbstractSliderH(Widget));
8904 end;
8905 
getMinnull8906 function TQtAbstractSlider.getMin: Integer;
8907 begin
8908   Result := QAbstractSlider_minimum(QAbstractSliderH(Widget));
8909 end;
8910 
TQtAbstractSlider.getMaxnull8911 function TQtAbstractSlider.getMax: Integer;
8912 begin
8913   Result := QAbstractSlider_maximum(QAbstractSliderH(Widget));
8914 end;
8915 
TQtAbstractSlider.getSingleStepnull8916 function TQtAbstractSlider.getSingleStep: Integer;
8917 begin
8918   Result := QAbstractSlider_singleStep(QAbstractSliderH(Widget));
8919 end;
8920 
getSliderDownnull8921 function TQtAbstractSlider.getSliderDown: Boolean;
8922 begin
8923   Result := QAbstractSlider_isSliderDown(QAbstractSliderH(Widget));
8924 end;
8925 
getSliderPositionnull8926 function TQtAbstractSlider.getSliderPosition: Integer;
8927 begin
8928   Result := QAbstractSlider_sliderPosition(QAbstractSliderH(Widget));
8929 end;
8930 
getTrackingnull8931 function TQtAbstractSlider.getTracking: Boolean;
8932 begin
8933   Result := QAbstractSlider_hasTracking(QAbstractSliderH(Widget));
8934 end;
8935 
8936 {------------------------------------------------------------------------------
8937   Function: TQtAbstractSlider.rangeChanged
8938   Params:  minimum,maximum: Integer
8939   Returns: Nothing
8940  ------------------------------------------------------------------------------}
8941 procedure TQtAbstractSlider.SlotRangeChanged(minimum: Integer; maximum: Integer); cdecl;
8942 begin
8943   { TODO: find out what needs to be done on rangeChanged event
8944     Possibilities: repaint or recount pageSize() }
8945   {$ifdef VerboseQt}
8946   writeln('TQtAbstractSlider.rangeChanged() to min=',minimum,' max=',maximum);
8947   {$endif}
8948 end;
8949 
8950 {------------------------------------------------------------------------------
8951   Function: TQtAbstractSlider.setInvertedAppereance
8952   Params:  p1: Boolean
8953   Returns: Nothing
8954  ------------------------------------------------------------------------------}
8955 procedure TQtAbstractSlider.setInvertedAppereance(p1: Boolean);
8956 begin
8957   QAbstractSlider_setInvertedAppearance(QAbstractSliderH(Widget), p1);
8958 end;
8959 
8960 {------------------------------------------------------------------------------
8961   Function: TQtAbstractSlider.setInvertedControls
8962   Params:  p1: Boolean
8963   Returns: Nothing
8964  ------------------------------------------------------------------------------}
8965 procedure TQtAbstractSlider.setInvertedControls(p1: Boolean);
8966 begin
8967   QAbstractSlider_setInvertedControls(QAbstractSliderH(Widget), p1);
8968 end;
8969 
8970 {------------------------------------------------------------------------------
8971   Function: TQtAbstractSlider.setMaximum
8972   Params:  p1: Integer
8973   Returns: Nothing
8974  ------------------------------------------------------------------------------}
8975 procedure TQtAbstractSlider.setMaximum(p1: Integer);
8976 begin
8977   QAbstractSlider_setMaximum(QAbstractSliderH(Widget), p1);
8978 end;
8979 
8980 {------------------------------------------------------------------------------
8981   Function: TQtAbstractSlider.setMinimum
8982   Params:  p1: Integer
8983   Returns: Nothing
8984  ------------------------------------------------------------------------------}
8985 procedure TQtAbstractSlider.setMinimum(p1: Integer);
8986 begin
8987   QAbstractSlider_setMinimum(QAbstractSliderH(Widget), p1);
8988 end;
8989 
8990 {------------------------------------------------------------------------------
8991   Function: TQtAbstractSlider.setOrientation
8992   Params:  p1: QtOrientation (QtHorizontal or QtVertical)
8993   Returns: Nothing
8994  ------------------------------------------------------------------------------}
8995 procedure TQtAbstractSlider.setOrientation(p1: QtOrientation);
8996 begin
8997   QAbstractSlider_setOrientation(QAbstractSliderH(Widget), p1);
8998 end;
8999 
9000 {------------------------------------------------------------------------------
9001   Function: TQtAbstractSlider.setPageStep
9002   Params:  p1: Integer
9003   Returns: Nothing
9004  ------------------------------------------------------------------------------}
9005 procedure TQtAbstractSlider.setPageStep(p1: Integer);
9006 begin
9007   QAbstractSlider_setPageStep(QAbstractSliderH(Widget), p1);
9008 end;
9009 
9010 {------------------------------------------------------------------------------
9011   Function: TQtAbstractSlider.setRange
9012   Params:  minimum,maximum: Integer
9013   Returns: Nothing
9014  ------------------------------------------------------------------------------}
9015 procedure TQtAbstractSlider.setRange(minimum: Integer; maximum: Integer);
9016 begin
9017   QAbstractSlider_setRange(QAbstractSliderH(Widget), minimum, maximum);
9018 end;
9019 
9020 {------------------------------------------------------------------------------
9021   Function: TQtAbstractSlider.setSingleStep
9022   Params:  p1: Integer
9023   Returns: Nothing
9024  ------------------------------------------------------------------------------}
9025 procedure TQtAbstractSlider.setSingleStep(p1: Integer);
9026 begin
9027   QAbstractSlider_setSingleStep(QAbstractSliderH(Widget), p1);
9028 end;
9029 
9030 {------------------------------------------------------------------------------
9031   Function: TQtAbstractSlider.setSliderDown
9032   Params:  p1: Boolean
9033   Returns: Nothing
9034  ------------------------------------------------------------------------------}
9035 procedure TQtAbstractSlider.setSliderDown(p1: Boolean);
9036 begin
9037   QAbstractSlider_setSliderDown(QAbstractSliderH(Widget), p1);
9038 end;
9039 
9040 
9041 {------------------------------------------------------------------------------
9042   Function: TQtAbstractSlider.setSliderPosition
9043   Params:  p1: Integer
9044   Returns: Nothing
9045  ------------------------------------------------------------------------------}
9046 procedure TQtAbstractSlider.setSliderPosition(p1: Integer);
9047 begin
9048   QAbstractSlider_setSliderPosition(QAbstractSliderH(Widget), p1);
9049 end;
9050 
9051 {------------------------------------------------------------------------------
9052   Function: TQtAbstractSlider.setTracking
9053   Params:  p1: Boolean
9054   Returns: Nothing
9055  ------------------------------------------------------------------------------}
9056 procedure TQtAbstractSlider.setTracking(p1: Boolean);
9057 begin
9058   QAbstractSlider_setTracking(QAbstractSliderH(Widget), p1);
9059 end;
9060 
9061 {-----------------------------------------------------------------------------
9062   Function: TQtAbstractSlider.setValue
9063   Params:  p1: Integer
9064   Returns: Nothing
9065  ------------------------------------------------------------------------------}
9066 procedure TQtAbstractSlider.setValue(p1: Integer);
9067 begin
9068   QAbstractSlider_setValue(QAbstractSliderH(Widget), p1);
9069 end;
9070 
9071 procedure TQtAbstractSlider.SlotSliderMoved(p1: Integer); cdecl;
9072 begin
9073  {$ifdef VerboseQt}
9074   writeln('TQtAbstractSlider.sliderMoved() to pos=',p1);
9075  {$endif}
9076 
9077  // there's no need to deliver this message
9078  // since ValueChanged does it's job correct, also for tracking on/off
9079  // this signal must stay empty because of ttrackbar !
9080 end;
9081 
9082 procedure TQtAbstractSlider.SlotSliderPressed; cdecl;
9083 begin
9084   {$ifdef VerboseQt}
9085    writeln('TQtAbstractSlider.sliderPressed()');
9086   {$endif}
9087   FSliderPressed := True;
9088   FSliderReleased := False;
9089 end;
9090 
9091 procedure TQtAbstractSlider.SlotSliderReleased; cdecl;
9092 begin
9093   {$ifdef VerboseQt}
9094    writeln('TQtAbstractSlider.sliderReleased()');
9095   {$endif}
9096   FSliderPressed := False;
9097   FSliderReleased := True;
9098 end;
9099 
CanChangeFontColornull9100 function TQtAbstractSlider.CanChangeFontColor: Boolean;
9101 begin
9102   Result := False;
9103 end;
9104 
getInvertedAppereancenull9105 function TQtAbstractSlider.getInvertedAppereance: Boolean;
9106 begin
9107   Result := QAbstractSlider_invertedAppearance(QAbstractSliderH(Widget));
9108 end;
9109 
getInvertedControlsnull9110 function TQtAbstractSlider.getInvertedControls: Boolean;
9111 begin
9112   Result := QAbstractSlider_invertedControls(QAbstractSliderH(Widget));
9113 end;
9114 
getOrientationnull9115 function TQtAbstractSlider.getOrientation: QtOrientation;
9116 begin
9117   Result := QAbstractSlider_orientation(QAbstractSliderH(Widget));
9118 end;
9119 
9120 procedure TQtAbstractSlider.SlotValueChanged(p1: Integer); cdecl;
9121 var
9122   LMScroll: TLMScroll;
9123   b: Boolean;
9124 begin
9125   {$ifdef VerboseQt}
9126   writeln('TQtAbstractSlider.SlotValueChanged() to value ',p1,' inUpdate ',inUpdate,' maxIs ',getMax,
9127   ' FChildOfComplexWidget ',FChildOfComplexWidget);
9128   {$endif}
9129 
9130   FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
9131 
9132   LMScroll.ScrollBar := PtrUInt(Self);
9133 
9134   if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
9135     LMScroll.Msg := LM_HSCROLL
9136   else
9137     LMScroll.Msg := LM_VSCROLL;
9138 
9139   LMScroll.Pos := p1;
9140   LMScroll.ScrollCode := SIF_POS;
9141 
9142   if not InUpdate then
9143     DeliverMessage(LMScroll);
9144 
9145   b := p1 = getMax;
9146 
9147   if not InUpdate or (getVisible and ((p1=getMin) or b)) then
9148   begin
9149     if b and (FChildOfComplexWidget = ccwAbstractScrollArea) and
9150       not InUpdate and getVisible then
9151         QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
9152           QAbstractSliderSliderToMaximum);
9153   end;
9154 end;
9155 
9156 procedure TQtAbstractSlider.SlotActionTriggered(action: Integer); cdecl;
9157 const
9158   SliderActions: Array[0..7] of QAbstractSliderSliderAction = (
9159     QAbstractSliderSliderNoAction, QAbstractSliderSliderSingleStepAdd,
9160     QAbstractSliderSliderSingleStepSub, QAbstractSliderSliderPageStepAdd,
9161     QAbstractSliderSliderPageStepSub, QAbstractSliderSliderToMinimum,
9162     QAbstractSliderSliderToMaximum, QAbstractSliderSliderMove );
9163 var
9164   LMScroll: TLMScroll;
9165   SliderAction: QAbstractSliderSliderAction;
9166 begin
9167 
9168   if InUpdate then
9169     exit;
9170 
9171   {$ifdef VerboseQt}
9172   writeln('TQtAbstractSlider.SlotActionTriggered() action = ',action,' inUpdate ',inUpdate);
9173   {$endif}
9174 
9175   FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
9176 
9177   LMScroll.ScrollBar := PtrUInt(Self);
9178 
9179   if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
9180     LMScroll.Msg := LM_HSCROLL
9181   else
9182     LMScroll.Msg := LM_VSCROLL;
9183 
9184   if SliderPressed then
9185     LMScroll.Pos := getSliderPosition
9186   else
9187     LMScroll.Pos := getValue;
9188 
9189   SliderAction := SliderActions[Action];
9190 
9191   case SliderAction of
9192     QAbstractSliderSliderNoAction:
9193     begin
9194       // this is called from mouse release while qt still thinks that
9195       // slider is pressed, we must update position.issue #14728, #21610
9196       if getSliderDown then
9197       begin
9198         LMScroll.ScrollCode := SB_THUMBPOSITION;
9199         DeliverMessage(LMScroll);
9200       end;
9201       LMScroll.ScrollCode := SB_ENDSCROLL;
9202     end;
9203     QAbstractSliderSliderSingleStepAdd:
9204       begin
9205         if LMScroll.Msg = LM_HSCROLL then
9206           LMScroll.ScrollCode := SB_LINERIGHT
9207         else
9208           LMScroll.ScrollCode := SB_LINEDOWN;
9209       end;
9210     QAbstractSliderSliderSingleStepSub:
9211       begin
9212         if LMScroll.Msg = LM_HSCROLL then
9213           LMScroll.ScrollCode := SB_LINELEFT
9214         else
9215           LMScroll.ScrollCode := SB_LINEUP;
9216       end;
9217     QAbstractSliderSliderPageStepAdd:
9218       begin
9219         if LMScroll.Msg = LM_HSCROLL then
9220           LMScroll.ScrollCode := SB_PAGERIGHT
9221         else
9222           LMScroll.ScrollCode := SB_PAGEDOWN;
9223       end;
9224     QAbstractSliderSliderPageStepSub:
9225       begin
9226         if LMScroll.Msg = LM_HSCROLL then
9227           LMScroll.ScrollCode := SB_PAGELEFT
9228         else
9229           LMScroll.ScrollCode := SB_PAGEUP;
9230       end;
9231     QAbstractSliderSliderToMinimum:
9232       begin
9233         if LMScroll.Msg = LM_HSCROLL then
9234           LMScroll.ScrollCode := SB_LEFT
9235         else
9236           LMScroll.ScrollCode := SB_TOP;
9237       end;
9238     QAbstractSliderSliderToMaximum:
9239       begin
9240         // issue #21610
9241         // if we are reaching maximum with eg. mouse wheel
9242         // and our parent is TScrollingWinControl then update thumbposition.
9243         if not getSliderDown then
9244         begin
9245           LMScroll.ScrollCode := SB_THUMBPOSITION;
9246           DeliverMessage(LMScroll);
9247         end;
9248 
9249         if LMScroll.Msg = LM_HSCROLL then
9250           LMScroll.ScrollCode := SB_RIGHT
9251         else
9252           LMScroll.ScrollCode := SB_BOTTOM;
9253       end;
9254     QAbstractSliderSliderMove:
9255       begin
9256         if getTracking then
9257           LMScroll.ScrollCode := SB_THUMBTRACK
9258         else
9259         if not getSliderDown then
9260           LMScroll.ScrollCode := SB_THUMBPOSITION;
9261       end;
9262   end;
9263 
9264   DeliverMessage(LMScroll);
9265 end;
9266 
9267 { TQtScrollBar }
9268 
TQtScrollBar.CreateWidgetnull9269 function TQtScrollBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
9270 var
9271   Parent: QWidgetH;
9272 begin
9273   // Creates the widget
9274   {$ifdef VerboseQt}
9275     WriteLn('TQtScrollBar.Create');
9276   {$endif}
9277   if AParams.WndParent <> 0 then
9278     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9279   else
9280     Parent := nil;
9281   FTrackPos := 0;
9282   Result := QScrollBar_create(Parent);
9283   QWidget_setFocusPolicy(Result, QtNoFocus);
9284   FHasPaint := True;
9285 end;
9286 
9287 procedure TQtScrollBar.preferredSize(var PreferredWidth,
9288   PreferredHeight: integer; WithThemeSpace: Boolean);
9289 var
9290   Size: TSize;
9291 begin
9292   QScrollBar_sizeHint(QScrollBarH(Widget), @Size);
9293   PreferredWidth := Size.cx;
9294   PreferredHeight := Size.cy;
9295 end;
9296 
9297 procedure TQtScrollBar.setFocusPolicy(const APolicy: QtFocusPolicy);
9298 begin
9299   if FOwnWidget and Assigned(LCLObject) and not LCLObject.TabStop then
9300     inherited setFocusPolicy(QtNoFocus)
9301   else
9302     inherited setFocusPolicy(APolicy);
9303 end;
9304 
9305 procedure TQtScrollBar.SlotSliderReleased; cdecl;
9306 var
9307   AValue: Integer;
9308   LMScroll: TLMScroll;
9309 begin
9310   inherited SlotSliderReleased;
9311   if
9312   {$IFDEF QTSCROLLABLEFORMS}
9313    ((ChildOfComplexWidget = ccwAbstractScrollArea) and (FOwner <> nil) and
9314     (FOwner is TQtWindowArea)) or
9315   {$ENDIF}
9316    ((ChildOfComplexWidget = ccwAbstractScrollArea) and (FOwner <> nil) and
9317     (FOwner.ChildOfComplexWidget in [ccwCustomControl])) then
9318   begin
9319     AValue := getValue;
9320     if AValue <= getMin then
9321       QAbstractSlider_triggerAction(QAbstractSliderH(Widget), QAbstractSliderSliderToMinimum)
9322     else
9323     if AValue >= getMax then
9324       QAbstractSlider_triggerAction(QAbstractSliderH(Widget), QAbstractSliderSliderToMaximum)
9325     else
9326     begin
9327       FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
9328 
9329       LMScroll.ScrollBar := PtrUInt(Self);
9330 
9331       if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
9332         LMScroll.Msg := LM_HSCROLL
9333       else
9334         LMScroll.Msg := LM_VSCROLL;
9335 
9336       LMScroll.Pos := getSliderPosition;
9337       if not GetTracking then
9338         LMScroll.ScrollCode := SB_THUMBPOSITION
9339       else
9340         LMScroll.ScrollCode := SB_THUMBTRACK;
9341       DeliverMessage(LMScroll);
9342     end;
9343   end;
9344 end;
9345 
EventFilternull9346 function TQtScrollBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
9347   cdecl;
9348 begin
9349   Result := False;
9350   QEvent_accept(Event);
9351 
9352   if LCLObject = nil then
9353     exit;
9354 
9355   case QEvent_type(Event) of
9356     {if any of those events returs TRUE our scrollbar becomes invisible.}
9357     QEventMouseMove,
9358     QEventWheel,
9359     QEventPaint,
9360     QEventKeyPress,
9361     QEventKeyRelease:
9362     begin
9363       if FOwnWidget and (FOwner = nil) and
9364         ((QEvent_type(Event) = QEventKeyPress) or
9365         (QEvent_type(Event) = QEventKeyRelease)) then
9366         Result := inherited EventFilter(Sender, Event)
9367       else
9368       if (QEvent_type(Event) = QEventWheel) and Assigned(FOwner) and
9369         (
9370         (FOwner is TQtAbstractScrollArea)
9371         ) then
9372       begin
9373 
9374         // issue #25992
9375         if not getVisible then
9376           Result := FOwner.SlotMouseWheel(FOwner.Widget, Event)
9377         else
9378         begin
9379           // issue #27675.Do not send wheel event from cbox when dropped down.
9380           // LCL thinks that combobox sent that event so we have undesirable effects.
9381           if (FOwner.ChildOfComplexWidget = ccwComboBox) and getEnabled then
9382             Result := False
9383           else
9384             Result := inherited EventFilter(Sender, Event);
9385         end;
9386         // do not scroll when disabled or issue #25992
9387         if not getEnabled then
9388           Result := True
9389         else
9390         if not getVisible then
9391         begin
9392           if {$IFDEF QTSCROLLABLEFORMS}(FOwner is TQtWindowArea) or {$ENDIF}
9393            (FOwner.ChildOfComplexWidget in
9394            [ccwScrollingWinControl, ccwScrollingWindow]) then
9395             Result := True;
9396         end;
9397       end else
9398         Result := False;
9399       if (QEvent_type(Event) = QEventKeyRelease) and not
9400         (QKeyEvent_isAutoRepeat(QKeyEventH(event))) then
9401         begin
9402           case QKeyEvent_key(QKeyEventH(Event)) of
9403             QtKey_Left, QtKey_Up, QtKey_Right, QtKey_Down,
9404             QtKey_PageUp, QtKey_PageDown, QtKey_Home, QtKey_End:
9405               QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
9406                        QAbstractSliderSliderNoAction);
9407           end;
9408         end;
9409     end;
9410 
9411     QEventMouseButtonRelease:
9412       QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
9413                         QAbstractSliderSliderNoAction);
9414   else
9415     if FOwnWidget then
9416       Result := inherited EventFilter(Sender, Event);
9417   end;
9418 end;
9419 
9420 procedure TQtScrollBar.AttachEvents;
9421 begin
9422   inherited AttachEvents;
9423   QAbstractSlider_hook_hook_rangeChanged(FRangeChangedHook, @SlotRangeChanged);
9424 
9425   QAbstractSlider_hook_hook_sliderMoved(FSliderMovedHook, @SlotSliderMoved);
9426 
9427   QAbstractSlider_hook_hook_sliderPressed(FSliderPressedHook, @SlotSliderPressed);
9428 
9429   QAbstractSlider_hook_hook_sliderReleased(FSliderReleasedHook, @SlotSliderReleased);
9430 
9431   QAbstractSlider_hook_hook_valueChanged(FValueChangedHook, @SlotValueChanged);
9432 
9433   QAbstractSlider_hook_hook_actionTriggered(FActionTriggeredHook, @SlotActionTriggered);
9434 end;
9435 
9436 { TQtToolBar }
9437 
TQtToolBar.CreateWidgetnull9438 function TQtToolBar.CreateWidget(const AParams: TCreateParams):QWidgetH;
9439 var
9440   Parent: QWidgetH;
9441 begin
9442   // Creates the widget
9443   {$ifdef VerboseQt}
9444     WriteLn('TQtToolBar.Create');
9445   {$endif}
9446   if AParams.WndParent <> 0 then
9447     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9448   else
9449     Parent := nil;
9450   Result := QToolBar_create(Parent);
9451 end;
9452 
9453 { TQtToolButton }
9454 
CreateWidgetnull9455 function TQtToolButton.CreateWidget(const AParams: TCreateParams):QWidgetH;
9456 var
9457   Parent: QWidgetH;
9458 begin
9459   // Creates the widget
9460   {$ifdef VerboseQt}
9461     WriteLn('TQtToolButton.Create');
9462   {$endif}
9463   if AParams.WndParent <> 0 then
9464     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9465   else
9466     Parent := nil;
9467   Result := QToolButton_create(Parent);
9468 end;
9469 
9470 { TQtTrackBar }
9471 
TQtTrackBar.CreateWidgetnull9472 function TQtTrackBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
9473 var
9474   Parent: QWidgetH;
9475 begin
9476   // Creates the widget
9477   {$ifdef VerboseQt}
9478     WriteLn('TQtTrackBar.Create');
9479   {$endif}
9480   if AParams.WndParent <> 0 then
9481     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9482   else
9483     Parent := nil;
9484   Result := QSlider_create(Parent);
9485 end;
9486 
TQtTrackBar.getTickIntervalnull9487 function TQtTrackBar.getTickInterval: Integer;
9488 begin
9489   Result := QSlider_tickInterval(QSliderH(Widget));
9490 end;
9491 
9492 {------------------------------------------------------------------------------
9493   Function: TQtTrackBar.setTickPosition
9494   Params:  Value: QSliderTickPosition
9495   Returns: Nothing
9496  ------------------------------------------------------------------------------ }
9497 procedure TQtTrackBar.setTickPosition(Value: QSliderTickPosition);
9498 begin
9499   QSlider_setTickPosition(QSliderH(Widget), Value);
9500 end;
9501 
9502 {------------------------------------------------------------------------------
9503   Function: TQtTrackBar.setTickInterval
9504   Params:  Value: Integer
9505   Returns: Nothing
9506  ------------------------------------------------------------------------------ }
9507 procedure TQtTrackBar.SetTickInterval(Value: Integer);
9508 begin
9509   QSlider_setTickInterval(QSliderH(Widget), Value);
9510 end;
9511 
9512 procedure TQtTrackBar.AttachEvents;
9513 begin
9514   inherited AttachEvents;
9515 
9516   QAbstractSlider_hook_hook_sliderMoved(FSliderMovedHook, @SlotSliderMoved);
9517 
9518   QAbstractSlider_hook_hook_sliderPressed(FSliderPressedHook, @SlotSliderPressed);
9519 
9520   QAbstractSlider_hook_hook_sliderReleased(FSliderReleasedHook, @SlotSliderReleased);
9521 
9522   QAbstractSlider_hook_hook_valueChanged(FValueChangedHook, @SlotValueChanged);
9523 end;
9524 
9525 procedure TQtTrackBar.SlotSliderMoved(p1: Integer); cdecl;
9526 var
9527   Msg: TLMessage;
9528 begin
9529  {$ifdef VerboseQt}
9530   writeln('TQtTrackBar.SlotSliderMoved() p1=',p1);
9531  {$endif}
9532   if SliderPressed and not InUpdate then
9533   begin
9534     Msg.Msg := 0; // shutup compiler
9535     FillChar(Msg, SizeOf(Msg), #0);
9536     Msg.Msg := LM_CHANGED;
9537     DeliverMessage(Msg);
9538   end;
9539 end;
9540 
9541 procedure TQtTrackBar.SlotValueChanged(p1: Integer); cdecl;
9542 var
9543   Msg: TLMessage;
9544 begin
9545  {$ifdef VerboseQt}
9546   writeln('TQtTrackBar.SlotValueChanged() p1=',p1);
9547  {$endif}
9548 
9549   if not SliderPressed and not InUpdate then
9550   begin
9551     FillChar(Msg{%H-}, SizeOf(Msg), #0);
9552     Msg.Msg := LM_CHANGED;
9553     DeliverMessage(Msg);
9554   end;
9555 end;
9556 
9557 { TQtLineEdit }
9558 
TQtLineEdit.CreateWidgetnull9559 function TQtLineEdit.CreateWidget(const AParams: TCreateParams): QWidgetH;
9560 var
9561   Parent: QWidgetH;
9562 begin
9563   FCachedSelectionStart := -1;
9564   FCachedSelectionLen := -1;
9565   FIntValidator := nil;
9566   FNumbersOnly := False;
9567   if AParams.WndParent <> 0 then
9568     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9569   else
9570     Parent := nil;
9571   Result := QLineEdit_create(Parent);
9572 end;
9573 
getAlignmentnull9574 function TQtLineEdit.getAlignment: QtAlignment;
9575 begin
9576   Result := QLineEdit_alignment(QLineEditH(Widget));
9577 end;
9578 
getCursorPositionnull9579 function TQtLineEdit.getCursorPosition: TPoint;
9580 begin
9581   Result.Y := 0;
9582   Result.X := QLineEdit_cursorPosition(QLineEditH(Widget));
9583 end;
9584 
TQtLineEdit.getMaxLengthnull9585 function TQtLineEdit.getMaxLength: Integer;
9586 begin
9587   Result := QLineEdit_maxLength(QLineEditH(Widget));
9588 end;
9589 
getSelectedTextnull9590 function TQtLineEdit.getSelectedText: WideString;
9591 begin
9592   Result := '';
9593   QLineEdit_selectedText(QLineEditH(Widget), @Result);
9594 end;
9595 
getSelectionStartnull9596 function TQtLineEdit.getSelectionStart: Integer;
9597 begin
9598   if hasSelectedText then
9599     Result := QLineEdit_selectionStart(QLineEditH(Widget))
9600   else
9601   begin
9602     if (CachedSelectionStart <> -1) and not hasFocus then
9603       Result := CachedSelectionStart
9604     else
9605       Result := getCursorPosition.X;
9606   end;
9607 end;
9608 
getSelectionLengthnull9609 function TQtLineEdit.getSelectionLength: Integer;
9610 var
9611   W: WideString;
9612 begin
9613   if hasSelectedText then
9614   begin
9615     W := getSelectedText;
9616     Result := UTF16Length(W);
9617   end else
9618   begin
9619     if (CachedSelectionStart <> -1) and (CachedSelectionLen <> -1) then
9620       Result := CachedSelectionLen
9621     else
9622       Result := 0;
9623   end;
9624 end;
9625 
TQtLineEdit.getTextnull9626 function TQtLineEdit.getText: WideString;
9627 begin
9628   Result := '';
9629   QLineEdit_text(QLineEditH(Widget), @Result);
9630 end;
9631 
getTextMarginsnull9632 function TQtLineEdit.getTextMargins: TRect;
9633 var
9634   L, T, R, B: Integer;
9635 begin
9636   QLineEdit_getTextMargins(QLineEditH(Widget), @L, @T, @R, @B);
9637   Result := Rect(L, T, R, B);
9638 end;
9639 
9640 procedure TQtLineEdit.SetNumbersOnly(AValue: boolean);
9641 begin
9642   if FNumbersOnly=AValue then Exit;
9643   FNumbersOnly:=AValue;
9644   if Assigned(FIntValidator) then
9645   begin
9646     QLineEdit_setValidator(QLineEditH(Widget), nil);
9647     QIntValidator_destroy(FIntValidator);
9648     FIntValidator := nil;
9649   end;
9650   if FNumbersOnly then
9651   begin
9652     FIntValidator := QIntValidator_create(0, MAXINT, Widget);
9653     QLineEdit_setValidator(QLineEditH(Widget), FIntValidator);
9654   end;
9655 end;
9656 
getTextStaticnull9657 function TQtLineEdit.getTextStatic: Boolean;
9658 begin
9659   Result := False;
9660 end;
9661 
TQtLineEdit.isUndoAvailablenull9662 function TQtLineEdit.isUndoAvailable: Boolean;
9663 begin
9664   Result := QLineEdit_isUndoAvailable(QLineEditH(Widget));
9665 end;
9666 
hasSelectedTextnull9667 function TQtLineEdit.hasSelectedText: Boolean;
9668 begin
9669   Result := QLineEdit_hasSelectedText(QLineEditH(Widget));
9670 end;
9671 
9672 procedure TQtLineEdit.selectAll;
9673 begin
9674   QLineEdit_selectAll(QLineEditH(Widget));
9675 end;
9676 
9677 procedure TQtLineEdit.setAlignment(const AAlignment: QtAlignment);
9678 begin
9679   QLineEdit_setAlignment(QLineEditH(Widget), AAlignment);
9680 end;
9681 
9682 procedure TQtLineEdit.setBorder(const ABorder: Boolean);
9683 begin
9684   QLineEdit_setFrame(QLineEditH(Widget), ABorder);
9685 end;
9686 
9687 procedure TQtLineEdit.AttachEvents;
9688 begin
9689   inherited AttachEvents;
9690 
9691   FTextChanged := QLineEdit_hook_create(Widget);
9692   QLineEdit_hook_hook_textChanged(FTextChanged, @SignalTextChanged);
9693 end;
9694 
9695 procedure TQtLineEdit.DetachEvents;
9696 begin
9697   if FTextChanged <> nil then
9698   begin
9699     QLineEdit_hook_destroy(FTextChanged);
9700     FTextChanged := nil;
9701   end;
9702   inherited DetachEvents;
9703 end;
9704 
TQtLineEdit.EventFilternull9705 function TQtLineEdit.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
9706   cdecl;
9707 begin
9708   Result := False;
9709   QEvent_accept(Event);
9710   if LCLObject = nil then
9711     exit;
9712 
9713   if (QEvent_type(Event) = QEventFocusOut) then
9714   begin
9715     CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(Widget));
9716     CachedSelectionLen := UTF16Length(getSelectedText);
9717   end else
9718   if (QEvent_type(Event) = QEventFocusIn) then
9719   begin
9720     CachedSelectionStart := -1;
9721     CachedSelectionLen := -1;
9722   end;
9723 
9724   if (ChildOfComplexWidget = ccwComboBox) and (QEvent_type(Event) = QEventMove) then
9725     exit;
9726 
9727   if (ChildOfComplexWidget = ccwComboBox) and
9728     ((QEvent_type(Event) = QEventPaint) or (QEvent_type(Event) = QEventResize))
9729     and (LCLObject.HandleAllocated) then
9730   begin
9731     Result := TQtComboBox(LCLObject.Handle).InUpdate or
9732       (csDesigning in LCLObject.ComponentState);
9733     if (QEvent_type(Event) = QEventPaint) and (csDesigning in LCLObject.ComponentState) then
9734       QObject_event(Sender, Event);
9735     if Result then
9736       QEvent_ignore(Event)
9737     else
9738     begin
9739       // issue #26040
9740       if (QEvent_type(Event) = QEventResize) then
9741         LCLObject.DoAdjustClientRectChange
9742       else
9743         Result:=inherited EventFilter(Sender, Event);
9744     end;
9745   end else
9746     Result:=inherited EventFilter(Sender, Event);
9747 end;
9748 
9749 procedure TQtLineEdit.preferredSize(var PreferredWidth,
9750   PreferredHeight: integer; WithThemeSpace: Boolean);
9751 var
9752   Size: TSize;
9753 begin
9754   QLineEdit_sizeHint(QLineEditH(Widget), @Size);
9755   PreferredHeight := Size.cy;
9756   PreferredWidth := Size.cx;
9757 end;
9758 
9759 procedure TQtLineEdit.setCursorPosition(const ACursorPosition: Integer);
9760 begin
9761   QLineEdit_setCursorPosition(QLineEditH(Widget), ACursorPosition);
9762 end;
9763 
9764 procedure TQtLineEdit.setDefaultColorRoles;
9765 begin
9766   WidgetColorRole := QPaletteBase;
9767   TextColorRole := QPaletteText;
9768 end;
9769 
9770 procedure TQtLineEdit.setEchoMode(const AMode: QLineEditEchoMode);
9771 begin
9772   QLineEdit_setEchoMode(QLineEditH(Widget), AMode);
9773 end;
9774 
9775 procedure TQtLineEdit.setInputMask(const AMask: WideString);
9776 begin
9777   QLineEdit_setInputMask(QLineEditH(Widget), @AMask);
9778 end;
9779 
9780 procedure TQtLineEdit.setMaxLength(const ALength: Integer);
9781 begin
9782   QLineEdit_setMaxLength(QLineEditH(Widget), ALength);
9783 end;
9784 
9785 procedure TQtLineEdit.setReadOnly(const AReadOnly: Boolean);
9786 begin
9787   QLineEdit_setReadOnly(QLineEditH(Widget), AReadOnly);
9788 end;
9789 
9790 procedure TQtLineEdit.setSelection(const AStart, ALength: Integer);
9791 begin
9792   if AStart >= 0 then
9793   begin
9794     if ALength > 0 then
9795       QLineEdit_setSelection(QLineEditH(Widget), AStart, ALength)
9796     else
9797       setCursorPosition(AStart);
9798   end;
9799 end;
9800 
9801 procedure TQtLineEdit.setText(const AText: WideString);
9802 begin
9803   QLineEdit_setText(QLineEditH(Widget), @AText);
9804 end;
9805 
9806 procedure TQtLineEdit.setTextHint(const ATextHint: string);
9807 var
9808   W: WideString;
9809 begin
9810   W := UTF8ToUTF16(ATextHint);
9811   QLineEdit_setPlaceholderText(QLineEditH(Widget), @W);
9812 end;
9813 
9814 procedure TQtLineEdit.setTextMargins(ARect: TRect);
9815 begin
9816   with ARect do
9817     QLineEdit_setTextMargins(QLineEditH(Widget), Left, Top, Right, Bottom);
9818 end;
9819 
9820 procedure TQtLineEdit.Cut;
9821 begin
9822   QLineEdit_cut(QLineEditH(Widget));
9823 end;
9824 
9825 procedure TQtLineEdit.Copy;
9826 begin
9827   QLineEdit_copy(QLineEditH(Widget));
9828 end;
9829 
9830 procedure TQtLineEdit.Paste;
9831 begin
9832   QLineEdit_paste(QLineEditH(Widget));
9833 end;
9834 
9835 procedure TQtLineEdit.Undo;
9836 begin
9837   QLineEdit_undo(QLineEditH(Widget));
9838 end;
9839 
9840 destructor TQtLineEdit.Destroy;
9841 begin
9842   if Assigned(FIntValidator) then
9843   begin
9844     QIntValidator_destroy(FIntValidator);
9845     FIntValidator := nil;
9846   end;
9847   inherited Destroy;
9848 end;
9849 
9850 {------------------------------------------------------------------------------
9851   Function: TQtLineEdit.SignalTextChanged
9852   Params:  PWideString
9853   Returns: Nothing
9854 
9855   Fires OnChange() event of TCustomEdit
9856  ------------------------------------------------------------------------------}
9857 procedure TQtLineEdit.SignalTextChanged(p1: PWideString); cdecl;
9858 var
9859   Msg: TLMessage;
9860 begin
9861   FillChar(Msg{%H-}, SizeOf(Msg), #0);
9862   Msg.Msg := CM_TEXTCHANGED;
9863   DeliverMessage(Msg);
9864 end;
9865 
9866 { TQtTextEdit }
9867 
GetAcceptRichTextnull9868 function TQtTextEdit.GetAcceptRichText: Boolean;
9869 begin
9870   Result := QTextEdit_acceptRichText(QTextEditH(Widget));
9871 end;
9872 
9873 procedure TQtTextEdit.SetAcceptRichText(AValue: Boolean);
9874 begin
9875   QTextEdit_setAcceptRichText(QTextEditH(Widget), AValue);
9876 end;
9877 
TQtTextEdit.CreateWidgetnull9878 function TQtTextEdit.CreateWidget(const AParams: TCreateParams): QWidgetH;
9879 var
9880   Parent: QWidgetH;
9881 begin
9882   // Creates the widget
9883   {$ifdef VerboseQt}
9884     WriteLn('TQtTextEdit.Create');
9885   {$endif}
9886   if AParams.WndParent <> 0 then
9887     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
9888   else
9889     Parent := nil;
9890   Result := QTextEdit_create(Parent);
9891   FKeysToEat := [];
9892   FUndoAvailable := False;
9893   {drops are handled by slotDropFiles()}
9894   QWidget_setAcceptDrops(Result, False);
9895 end;
9896 
9897 procedure TQtTextEdit.Append(const AStr: WideString);
9898 begin
9899   QTextEdit_append(QTextEditH(Widget), @AStr);
9900 end;
9901 
9902 procedure TQtTextEdit.ClearText;
9903 begin
9904   QTextEdit_clear(QTextEditH(Widget));
9905 end;
9906 
getAlignmentnull9907 function TQtTextEdit.getAlignment: QtAlignment;
9908 begin
9909   Result := QTextEdit_alignment(QTextEditH(Widget));
9910 end;
9911 
getBlockCountnull9912 function TQtTextEdit.getBlockCount: Integer;
9913 begin
9914   Result := QTextDocument_blockCount(QTextEdit_document(QTextEditH(Widget)));
9915 end;
9916 
getCursorPositionnull9917 function TQtTextEdit.getCursorPosition: TPoint;
9918 var
9919   TextCursor: QTextCursorH;
9920 begin
9921   TextCursor := QTextCursor_create();
9922   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9923   if QTextCursor_isNull(TextCursor) then
9924     Result := Point(0, 0)
9925   else
9926   begin
9927     Result.X := QTextCursor_position(TextCursor);
9928     Result.Y := QTextCursor_blockNumber(TextCursor);
9929   end;
9930   QTextCursor_destroy(TextCursor);
9931 end;
9932 
getMaxLengthnull9933 function TQtTextEdit.getMaxLength: Integer;
9934 begin
9935   {$note implement TQtTextEdit.getMaxLength}
9936   Result := 0;
9937 end;
9938 
TQtTextEdit.getTextnull9939 function TQtTextEdit.getText: WideString;
9940 begin
9941   Result := '';
9942   QTextEdit_toPlainText(QTextEditH(Widget), @Result);
9943 end;
9944 
getTextStaticnull9945 function TQtTextEdit.getTextStatic: Boolean;
9946 begin
9947   Result := False;
9948 end;
9949 
getSelectionStartnull9950 function TQtTextEdit.getSelectionStart: Integer;
9951 var
9952   TextCursor: QTextCursorH;
9953 begin
9954   TextCursor := QTextCursor_create();
9955   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9956   Result := QTextCursor_selectionStart(TextCursor);
9957   QTextCursor_destroy(TextCursor);
9958 end;
9959 
TQtTextEdit.getSelectionEndnull9960 function TQtTextEdit.getSelectionEnd: Integer;
9961 var
9962   TextCursor: QTextCursorH;
9963 begin
9964   TextCursor := QTextCursor_create();
9965   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
9966   Result := QTextCursor_selectionEnd(TextCursor);
9967   QTextCursor_destroy(TextCursor);
9968 end;
9969 
getSelectionLengthnull9970 function TQtTextEdit.getSelectionLength: Integer;
9971 begin
9972   Result := getSelectionEnd - getSelectionStart;
9973 end;
9974 
TQtTextEdit.isUndoAvailablenull9975 function TQtTextEdit.isUndoAvailable: Boolean;
9976 begin
9977   Result := QTextEdit_isUndoRedoEnabled(QTextEditH(Widget)) and FUndoAvailable;
9978 end;
9979 
9980 procedure TQtTextEdit.setEchoMode(const AMode: QLineEditEchoMode);
9981 begin
9982   {$note implement TQtTextEdit.setEchoMode}
9983 end;
9984 
9985 procedure TQtTextEdit.setLineWrapMode(const AMode: QTextEditLineWrapMode);
9986 begin
9987   QTextEdit_setLineWrapMode(QTextEditH(Widget), AMode);
9988 end;
9989 
9990 procedure TQtTextEdit.setMaxLength(const ALength: Integer);
9991 begin
9992   {$note implement TQtTextEdit.setMaxLength}
9993 end;
9994 
9995 procedure TQtTextEdit.appendLine(AText: WideString);
9996 var
9997   QtCursor: QTextCursorH;
9998   WrapMode: QTextEditLineWrapMode;
9999 begin
10000   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
10001   {we must remove wrapping to get correct line !}
10002   setLineWrapMode(QTextEditNoWrap);
10003   QtCursor := QTextCursor_create();
10004   try
10005     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
10006     QTextCursor_beginEditBlock(QtCursor);
10007     QTextCursor_movePosition(QtCursor, QTextCursorEnd,
10008         QTextCursorMoveAnchor, 1);
10009     QTextCursor_insertBlock(QtCursor);
10010     QTextCursor_insertText(QtCursor, @AText);
10011     QTextCursor_endEditBlock(QtCursor);
10012   finally
10013     QTextCursor_destroy(QtCursor);
10014     setLineWrapMode(WrapMode);
10015   end;
10016 end;
10017 
10018 procedure TQtTextEdit.insertLine(const AIndex: integer; AText: WideString);
10019 var
10020   QtCursor: QTextCursorH;
10021   WrapMode: QTextEditLineWrapMode;
10022 begin
10023   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
10024   {we must remove wrapping to get correct line !}
10025   setLineWrapMode(QTextEditNoWrap);
10026   QtCursor := QTextCursor_create();
10027   try
10028     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
10029     QTextCursor_beginEditBlock(QtCursor);
10030     // QTextCursor slowness
10031     // https://bugreports.qt-project.org/browse/QTBUG-3554
10032     // differentiate append vs. insert issue #22715
10033     // added check for AIndex. issue #29670
10034     if (AIndex > 0) and (AIndex >= FList.Count - 1) then
10035     begin
10036       QTextCursor_movePosition(QtCursor, QTextCursorEnd,
10037         QTextCursorMoveAnchor, 1);
10038       QTextCursor_insertBlock(QtCursor);
10039     end else
10040     begin
10041       QTextCursor_movePosition(QtCursor, QTextCursorStart,
10042         QTextCursorMoveAnchor, 1);
10043       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
10044         QTextCursorMoveAnchor, 1);
10045     end;
10046 
10047     QTextCursor_movePosition(QtCursor, QTextCursorDown,
10048       QTextCursorMoveAnchor, AIndex);
10049     // QTextCursor slowness
10050     // https://bugreports.qt-project.org/browse/QTBUG-3554
10051     // differentiate append vs. insert issue #22715
10052     if AIndex < FList.Count - 1 then
10053     begin
10054       QTextCursor_insertBlock(QtCursor);
10055       QTextCursor_movePosition(QtCursor, QTextCursorUp,
10056         QTextCursorMoveAnchor, 1);
10057     end;
10058     QTextCursor_insertText(QtCursor, @AText);
10059     QTextCursor_endEditBlock(QtCursor);
10060   finally
10061     QTextCursor_destroy(QtCursor);
10062     setLineWrapMode(WrapMode);
10063   end;
10064 end;
10065 
10066 procedure TQtTextEdit.removeLine(const AIndex: integer);
10067 var
10068   QtCursor: QTextCursorH;
10069   B: Boolean;
10070   WrapMode: QTextEditLineWrapMode;
10071   Diff: Integer;
10072 begin
10073   Diff := getBlockCount - AIndex;
10074   {we must remove wrapping to get correct line !}
10075   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
10076   setLineWrapMode(QTextEditNoWrap);
10077   QtCursor := QTextCursor_create();
10078   try
10079     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
10080     QTextCursor_beginEditBlock(QtCursor);
10081     // small optimization if we delete from end of list
10082     if Diff <= 2 then
10083     begin
10084       QTextCursor_movePosition(QtCursor, QTextCursorEnd,
10085         QTextCursorMoveAnchor, 1);
10086       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
10087         QTextCursorMoveAnchor, 1);
10088       QTextCursor_movePosition(QtCursor, QTextCursorUp,
10089         QTextCursorMoveAnchor, Diff - 1);
10090     end else
10091     begin
10092       QTextCursor_movePosition(QtCursor, QTextCursorStart,
10093         QTextCursorMoveAnchor, 1);
10094       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
10095         QTextCursorMoveAnchor, 1);
10096       QTextCursor_movePosition(QtCursor, QTextCursorDown,
10097         QTextCursorMoveAnchor, AIndex);
10098       QTextCursor_movePosition(QtCursor, QTextCursorEndOfLine,
10099         QTextCursorMoveAnchor, 1);
10100     end;
10101 
10102     QTextCursor_select(QtCursor, QTextCursorLineUnderCursor);
10103     B := QTextCursor_hasSelection(QtCursor);
10104     if not B then
10105       QTextCursor_deleteChar(QtCursor)
10106     else
10107       QTextCursor_deletePreviousChar(QtCursor);
10108 
10109     if (AIndex = 0) then
10110     begin
10111       QTextCursor_movePosition(QtCursor, QTextCursorStart,
10112         QTextCursorMoveAnchor, 1);
10113       QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
10114         QTextCursorMoveAnchor, 1);
10115       QTextCursor_movePosition(QtCursor, QTextCursorDown,
10116         QTextCursorMoveAnchor, 1);
10117     end;
10118     if B then
10119       QTextCursor_deletePreviousChar(QtCursor);
10120     QTextCursor_endEditBlock(QtCursor);
10121   finally
10122     QTextCursor_destroy(QtCursor);
10123     setLineWrapMode(WrapMode);
10124   end;
10125 end;
10126 
10127 procedure TQtTextEdit.setLineText(const AIndex: integer; AText: WideString);
10128 var
10129   QtCursor: QTextCursorH;
10130   WrapMode: QTextEditLineWrapMode;
10131 begin
10132   {we must remove wrapping to get correct line !}
10133   WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
10134   setLineWrapMode(QTextEditNoWrap);
10135   QtCursor := QTextCursor_create();
10136   try
10137     QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
10138     QTextCursor_beginEditBlock(QtCursor);
10139     QTextCursor_movePosition(QtCursor, QTextCursorStart,
10140       QTextCursorMoveAnchor, 1);
10141     QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
10142       QTextCursorMoveAnchor, 1);
10143     QTextCursor_movePosition(QtCursor, QTextCursorDown,
10144       QTextCursorMoveAnchor, AIndex);
10145     QTextCursor_select(QtCursor, QTextCursorLineUnderCursor);
10146     QTextCursor_removeSelectedText(QtCursor);
10147     QTextCursor_insertText(QtCursor, @AText);
10148     QTextCursor_movePosition(QtCursor, QTextCursorEndOfLine,
10149       QTextCursorMoveAnchor, 1);
10150     QTextCursor_endEditBlock(QtCursor);
10151   finally
10152     QTextCursor_destroy(QtCursor);
10153     setLineWrapMode(WrapMode);
10154   end;
10155 end;
10156 
10157 procedure TQtTextEdit.setText(const AText: WideString);
10158 begin
10159   QTextEdit_setPlainText(QTextEditH(Widget), @AText);
10160 end;
10161 
10162 procedure TQtTextEdit.setTextHint(const ATextHint: string);
10163 var
10164   W: WideString;
10165 begin
10166   W := UTF8ToUTF16(ATextHint);
10167   QTextEdit_setPlaceholderText(QTextEditH(Widget), @W);
10168 end;
10169 
10170 procedure TQtTextEdit.setReadOnly(const AReadOnly: Boolean);
10171 begin
10172   QTextEdit_setReadOnly(QTextEditH(Widget), AReadOnly);
10173 end;
10174 
10175 procedure TQtTextEdit.setSelection(const AStart, ALength: Integer);
10176 var
10177   TextCursor: QTextCursorH;
10178 begin
10179   if AStart >= 0 then
10180   begin
10181     TextCursor := QTextCursor_create();
10182     QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
10183     QTextCursor_clearSelection(TextCursor);
10184     QTextCursor_setPosition(TextCursor, AStart);
10185     QTextCursor_setPosition(TextCursor, AStart + ALength, QTextCursorKeepAnchor);
10186     QTextEdit_setTextCursor(QTextEditH(Widget), TextCursor);
10187     QTextCursor_destroy(TextCursor);
10188   end;
10189 end;
10190 
10191 procedure TQtTextEdit.setTabChangesFocus(const AValue: Boolean);
10192 begin
10193   QTextEdit_setTabChangesFocus(QTextEditH(Widget), AValue);
10194 end;
10195 
10196 procedure TQtTextEdit.Cut;
10197 begin
10198   QTextEdit_cut(QTextEditH(Widget));
10199 end;
10200 
10201 procedure TQtTextEdit.Copy;
10202 begin
10203   QTextEdit_copy(QTextEditH(Widget));
10204 end;
10205 
10206 procedure TQtTextEdit.Paste;
10207 begin
10208   QTextEdit_paste(QTextEditH(Widget));
10209 end;
10210 
10211 procedure TQtTextEdit.Undo;
10212 begin
10213   QTextEdit_undo(QTextEditH(Widget));
10214 end;
10215 
10216 procedure TQtTextEdit.setAlignment(const AAlignment: QtAlignment);
10217 var
10218   TextCursor: QTextCursorH;
10219 begin
10220   // QTextEdit supports alignment for every paragraph. We need to align all text.
10221   // So, we should select all text, set format, and clear selection
10222 
10223   // 1. Select all text
10224   QTextEdit_selectAll(QTextEditH(Widget));
10225 
10226   // 2. Set format
10227   QTextEdit_setAlignment(QTextEditH(Widget), AAlignment);
10228 
10229   // 3. Clear selection. To unselect all document we must create new text cursor,
10230   // get format from Text Edit, clear selection in cursor and set it back to Text Edit
10231   TextCursor := QTextCursor_create();
10232   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
10233   QTextCursor_clearSelection(TextCursor);
10234   QTextEdit_setTextCursor(QTextEditH(Widget), TextCursor);
10235   QTextCursor_destroy(TextCursor);
10236 end;
10237 
10238 procedure TQtTextEdit.setBorder(const ABorder: Boolean);
10239 begin
10240   if ABorder then
10241     QFrame_setFrameShape(QFrameH(Widget), QFrameStyledPanel)
10242   else
10243     QFrame_setFrameShape(QFrameH(Widget), QFrameNoFrame);
10244 end;
10245 
10246 procedure TQtTextEdit.setCursorPosition(const ACursorPosition: Integer);
10247 var
10248   TextCursor: QTextCursorH;
10249 begin
10250   TextCursor := QTextCursor_create();
10251   QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
10252   if not QTextCursor_isNull(TextCursor) then
10253     QTextCursor_setPosition(TextCursor, ACursorPosition);
10254   QTextCursor_destroy(TextCursor);
10255 end;
10256 
10257 procedure TQtTextEdit.setDefaultColorRoles;
10258 begin
10259   WidgetColorRole := QPaletteBase;
10260   TextColorRole := QPaletteText;
10261 end;
10262 
10263 procedure TQtTextEdit.AttachEvents;
10264 begin
10265   inherited AttachEvents;
10266 
10267   FUndoAvailableHook := QTextEdit_hook_create(Widget);
10268   QTextEdit_hook_hook_undoAvailable(FUndoAvailableHook, @SignalUndoAvailable);
10269 
10270   FTextChangedHook := QTextEdit_hook_create(Widget);
10271   QTextEdit_hook_hook_textChanged(FTextChangedHook, @SignalTextChanged);
10272 
10273   FViewportEventHook := QObject_hook_create(viewportWidget);
10274   QObject_hook_hook_events(FViewportEventHook, @viewportEventFilter);
10275   // initialize scrollbars
10276   verticalScrollBar;
10277   horizontalScrollBar;
10278 end;
10279 
10280 procedure TQtTextEdit.DetachEvents;
10281 begin
10282   if FUndoAvailableHook <> nil then
10283   begin
10284     QTextEdit_hook_destroy(FUndoAvailableHook);
10285     FUndoAvailableHook := nil;
10286   end;
10287 
10288   if FTextChangedHook <> nil then
10289   begin
10290     QTextEdit_hook_destroy(FTextChangedHook);
10291     FTextChangedHook := nil;
10292   end;
10293 
10294   if FViewportEventHook <> nil then
10295   begin
10296     QObject_hook_destroy(FViewportEventHook);
10297     FViewportEventHook := nil;
10298   end;
10299   inherited DetachEvents;
10300 end;
10301 
TQtTextEdit.viewportEventFilternull10302 function TQtTextEdit.viewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
10303 begin
10304   Result := False;
10305   QEvent_accept(Event);
10306   case QEvent_type(Event) of
10307     QEventContextMenu: Result := SlotContextMenu(Sender, Event);
10308     QEventMouseButtonPress,
10309     QEventMouseButtonRelease,
10310     QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
10311     QEventMouseMove: Result := SlotMouseMove(Sender, Event);
10312   end;
10313 end;
10314 
getContextMenuPolicynull10315 function TQtTextEdit.getContextMenuPolicy: QtContextMenuPolicy;
10316 begin
10317   Result := QWidget_contextMenuPolicy(viewPortWidget);
10318 end;
10319 
10320 procedure TQtTextEdit.setContextMenuPolicy(const AValue: QtContextMenuPolicy);
10321 begin
10322   QWidget_setContextMenuPolicy(viewportWidget, AValue);
10323 end;
10324 
10325 procedure TQtTextEdit.SignalUndoAvailable(b: Boolean); cdecl;
10326 begin
10327   FUndoAvailable := b;
10328 end;
10329 
10330 procedure TQtTextEdit.SignalTextChanged(); cdecl;
10331 var
10332   Mess: TLMessage;
10333 begin
10334   if (LCLObject = nil) or not GetVisible then
10335     exit;
10336   if Assigned(FList) then
10337     TQtMemoStrings(FList).TextChanged := True;
10338   if not InUpdate then
10339   begin
10340     FillChar(Mess{%H-}, SizeOf(Mess), #0);
10341     Mess.Msg := CM_TEXTCHANGED;
10342     DeliverMessage(Mess);
10343   end;
10344 end;
10345 
10346 { TQtTabBar }
10347 
10348 procedure TQtTabBar.AttachEvents;
10349 begin
10350   inherited AttachEvents;
10351   FTabBarChangedHook := QTabBar_hook_create(QTabBarH(Widget));
10352   FTabBarMovedHook := QTabBar_hook_create(QTabBarH(Widget));
10353   QTabBar_hook_hook_currentChanged(FTabBarChangedHook, @SignalTabBarCurrentChanged);
10354   QTabBar_hook_hook_tabMoved(FTabBarMovedHook, @SignalTabBarMoved);
10355 end;
10356 
10357 procedure TQtTabBar.DetachEvents;
10358 begin
10359   if FTabBarMovedHook <> nil then
10360   begin
10361     QTabBar_hook_destroy(FTabBarMovedHook);
10362     FTabBarMovedHook := nil;
10363   end;
10364   if FTabBarChangedHook <> nil then
10365   begin
10366     QTabBar_hook_destroy(FTabBarChangedHook);
10367     FTabBarChangedHook := nil;
10368   end;
10369   inherited DetachEvents;
10370 end;
10371 
GetTabRectnull10372 function TQtTabBar.GetTabRect(const AIndex: integer): TRect;
10373 var
10374   Pt: TPoint;
10375 begin
10376   QTabBar_tabRect(QTabBarH(Widget), @Result, AIndex);
10377   if Assigned(FOwner) then
10378   begin
10379     Pt := TabBarOffset;
10380     OffsetRect(Result, Pt.X, Pt.Y);
10381   end;
10382 end;
10383 
TabBarOffsetnull10384 function TQtTabBar.TabBarOffset: TPoint;
10385 var
10386   R: TRect;
10387 begin
10388   Result := Point(0, 0);
10389   if Assigned(FOwner) then
10390   begin
10391     QWidget_geometry(Widget, @R);
10392     case TQtTabWidget(FOwner).getTabPosition of
10393       QTabWidgetNorth,
10394       QTabWidgetSouth:
10395         begin
10396           if R.Left < 0 then
10397             R.Left := 0;
10398           // issue #28591
10399           if QWidget_layoutDirection(Widget) = QtRightToLeft then
10400             Result.X := 0
10401           else
10402             Result.X := R.Left;
10403         end;
10404       QTabWidgetEast,
10405       QTabWidgetWest:
10406         begin
10407           if R.Top < 0 then
10408             R.Top := 0;
10409           Result.Y := R.Top;
10410         end;
10411     end;
10412   end;
10413 end;
10414 
10415 procedure TQtTabBar.SignalTabBarMoved(fromIndex: integer; toIndex: Integer);
10416   cdecl;
10417 var
10418   ANewIndex: Integer;
10419 begin
10420   if LCLObject = nil then
10421     Exit;
10422   // DebugLn('TQtTabBar.SignalTabBarMoved From=',dbgs(fromIndex),' to ',dbgs(toIndex),' FSavedIndexOnPageChanging=',dbgs(FSavedIndexOnPageChanging));
10423   if Assigned(FOwner) and not (FOwner.ChildOfComplexWidget = ccwTTabControl) then
10424   begin
10425     ANewIndex := TQtTabWidget(FOwner).GetLCLPageIndex(toIndex);
10426     TQtTabWidget(FOwner).setCurrentWidget(TQtWidget(TCustomTabControl(LCLObject).Page[ANewIndex].Handle), True);
10427   end;
10428 end;
10429 
10430 procedure TQtTabBar.SignalTabBarCurrentChanged(Index: Integer); cdecl;
10431 var
10432   Msg: TLMNotify;
10433   Hdr: TNmHdr;
10434 begin
10435   if LCLObject = nil then
10436     Exit;
10437 
10438   if TQtTabWidget(LCLObject.Handle).InUpdate then
10439     exit;
10440   FillChar(Msg{%H-}, SizeOf(Msg), 0);
10441   Msg.Msg := LM_NOTIFY;
10442   FillChar(Hdr{%H-}, SizeOf(Hdr), 0);
10443 
10444   Hdr.hwndFrom := LCLObject.Handle;
10445   Hdr.Code := TCN_SELCHANGE;
10446   Hdr.idFrom := PtrUInt(TQtTabWidget(LCLObject.Handle).GetLCLPageIndex(Index));
10447   Msg.NMHdr := @Hdr;
10448   Msg.Result := 0;
10449   if FSavedIndexOnPageChanging = Forbid_TCN_SELCHANGE then
10450     FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE
10451   else
10452     DeliverMessage(Msg);
10453 end;
10454 
SlotTabBarMousenull10455 function TQtTabBar.SlotTabBarMouse(Sender: QObjectH; Event: QEventH): Boolean;
10456   cdecl;
10457 var
10458   MousePos, AGlobalPos: TQtPoint;
10459   APosF, AGlobalPosF: TQtPointF;
10460   NewEvent: QMouseEventH;
10461   R: TRect;
10462   R1: TRect;
10463   BaseHeight: Integer;
10464   ForcedMouseGrab: Boolean;
10465 begin
10466   Result := False;
10467 
10468   if not CanSendLCLMessage then
10469     exit;
10470 
10471   // MousePos :=
10472   QMouseEvent_pos(QMouseEventH(Event), @MousePos);
10473 
10474   if Assigned(FOwner) then
10475   begin
10476     R := TQtTabWidget(FOwner).getGeometry;
10477     R1 := getGeometry;
10478     BaseHeight := GetPixelMetric(QStylePM_TabBarBaseHeight, nil, nil);
10479 
10480     case TQtTabWidget(FOwner).getTabPosition of
10481       QTabWidgetNorth:
10482         begin
10483           MousePos.Y := R.Top - (R1.Bottom - MousePos.Y);
10484           MousePos.X := MousePos.X - BaseHeight;
10485         end;
10486       QTabWidgetWest:
10487         begin
10488           MousePos.x := R.Left - (R1.Right - MousePos.X);
10489           MousePos.y := MousePos.Y - BaseHeight;
10490         end;
10491       QTabWidgetEast:
10492         begin
10493           MousePos.X := R1.Left + MousePos.X - BaseHeight;
10494           MousePos.y := MousePos.Y - BaseHeight;
10495         end;
10496       QTabWidgetSouth:
10497         begin
10498           MousePos.Y := R1.Top + MousePos.Y - BaseHeight;
10499           MousePos.X := MousePos.X - BaseHeight;
10500         end;
10501     end;
10502     QMouseEvent_globalPos(QMouseEventH(Event), @AGlobalPos);
10503     APosF.X := MousePos.X;
10504     APosF.Y := MousePos.Y;
10505     AGlobalPosF.X := AGlobalPos.X;
10506     AGlobalPosF.Y := AGlobalPos.Y;
10507     NewEvent := QMouseEvent_create(QEvent_type(Event), @APosF,
10508         @AGlobalPosF,
10509         QMouseEvent_button(QMouseEventH(Event)),
10510         QMouseEvent_buttons(QMouseEventH(Event)),
10511         QInputEvent_modifiers(QInputEventH(Event))
10512       );
10513 
10514     ForcedMouseGrab := False;
10515     if QEvent_type(Event) = QEventMouseButtonPress then
10516       ForcedMouseGrab := not ((QWidget_mouseGrabber = Widget) or
10517         (Assigned(FOwner) and (QWidget_mouseGrabber = FOwner.Widget)));
10518 
10519     SlotMouse(Sender, NewEvent);
10520     QMouseEvent_destroy(NewEvent);
10521 
10522     ForcedMouseGrab := ForcedMouseGrab and
10523         (Assigned(FOwner) and (QWidget_mouseGrabber = FOwner.Widget));
10524 
10525     if ForcedMouseGrab then
10526       QWidget_grabMouse(Widget);
10527 
10528   end else
10529     SlotMouse(Sender, Event);
10530 end;
10531 
TQtTabBar.EventFilternull10532 function TQtTabBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
10533 
StopShortcutEventnull10534   function StopShortcutEvent: boolean;
10535   begin
10536     Result := Assigned(FOwner) and (FOwner.ChildOfComplexWidget <> ccwTTabControl) and
10537       not TQtTabWidget(FOwner).FSwitchTabsByKeyboard and (QKeyEvent_matches(QKeyEventH(Event), QKeySequenceNextChild) or
10538       QKeyEvent_matches(QKeyEventH(Event), QKeySequencePreviousChild));
10539   end;
10540 
10541 {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10542 var
10543   R: TRect;
10544 {$ENDIF}
10545 begin
10546   Result := False;
10547   QEvent_accept(Event);
10548   if LCLObject = nil then
10549     exit;
10550   {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
10551   WriteLn('TQtTabBar.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
10552     ' LCLObject=', dbgsName(LCLObject),
10553     ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
10554   {$endif}
10555 
10556   BeginEventProcessing;
10557   try
10558     case QEvent_type(Event) of
10559       {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10560       QEventPaint:
10561         begin
10562           QPaintEvent_rect(QPaintEventH(Event), @R);
10563           // qt paints tab
10564           QObject_event(Sender, Event);
10565           // LCL can do whatever now
10566           SlotPaint(Sender, Event);
10567           Result := True;
10568           QEvent_ignore(Event);
10569         end;
10570       {$ENDIF}
10571       QEventShortcutOverride: Result := StopShortcutEvent;
10572       QEventKeyPress,
10573       QEventKeyRelease:
10574       begin
10575         if (QEvent_type(Event) = QEventKeyPress) then
10576           FSavedIndexOnPageChanging := QTabBar_currentIndex(QTabBarH(Widget));
10577         SlotKey(Sender, Event);
10578         if (LCLObject = nil) or
10579           ((LCLObject <> nil) and not LCLObject.HandleAllocated) then
10580           Result := True;
10581         if not Result then
10582           Result := StopShortcutEvent;
10583       end;
10584       QEventMouseButtonPress,
10585       QEventMouseButtonRelease,
10586       QEventMouseButtonDblClick:
10587         begin
10588           if QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton then
10589           begin
10590             if (QEvent_type(Event) = QEventMouseButtonPress) then
10591               FSavedIndexOnPageChanging := QTabBar_currentIndex(QTabBarH(Widget));
10592             Result := SlotTabBarMouse(Sender, Event);
10593             if (LCLObject = nil) or
10594               ((LCLObject <> nil) and not LCLObject.HandleAllocated) then
10595               Result := True
10596             else
10597               SetNoMousePropagation(QWidgetH(Sender), False);
10598           end;
10599         end;
10600     else
10601       QEvent_ignore(Event);
10602     end;
10603   finally
10604     EndEventProcessing;
10605   end;
10606 end;
10607 
10608 procedure TQtTabBar.SetTabFontColor(AIndex: Integer; AColor: TQColor);
10609 begin
10610   QTabBar_setTabTextColor(QTabBarH(Widget), AIndex, @AColor);
10611 end;
10612 
10613 { TQtTabWidget }
10614 
getTabBarnull10615 function TQtTabWidget.getTabBar: TQtTabBar;
10616 begin
10617   if FTabBar = nil then
10618   begin
10619     {$note TQtTabWidget.getTabBar: we can remove QLCLTabWidget, and get it like StackWidget,
10620      objectName is qt_tabwidget_tabbar.}
10621     FTabBar := TQtTabBar.CreateFrom(LCLObject, QLCLTabWidget_tabBarHandle(QTabWidgetH(Widget)));
10622     {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10623     FTabBar.HasPaint := True;
10624     {$ENDIF}
10625     FTabBar.FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE;
10626     FTabBar.FOwner := Self;
10627     FTabBar.AttachEvents;
10628   end;
10629   Result := FTabBar;
10630 end;
10631 
getShowTabsnull10632 function TQtTabWidget.getShowTabs: Boolean;
10633 begin
10634   Result := TabBar.getVisible;
10635 end;
10636 
getStackWidgetnull10637 function TQtTabWidget.getStackWidget: QWidgetH;
10638 var
10639   List: TPtrIntArray;
10640   Obj: QObjectH;
10641   i: Integer;
10642   WStr: WideString;
10643 begin
10644   if FStackWidget = nil then
10645   begin
10646     QObject_children(Widget, @List);
10647     for i := 0 to High(List) do
10648     begin
10649       Obj := QObjectH(List[i]);
10650       QObject_objectName(Obj, @WStr);
10651       {do not localize !}
10652       if WStr = 'qt_tabwidget_stackedwidget' then
10653       begin
10654         FStackWidget := QWidgetH(List[i]);
10655         break;
10656       end;
10657     end;
10658     FCentralWidget := FStackWidget;
10659   end;
10660   Result := FStackWidget;
10661 end;
10662 
10663 procedure TQtTabWidget.setShowTabs(const AValue: Boolean);
10664 begin
10665   TabBar.setVisible(AValue);
10666 end;
10667 
CreateWidgetnull10668 function TQtTabWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
10669 var
10670   Parent: QWidgetH;
10671 begin
10672   // Creates the widget
10673   {$ifdef VerboseQt}
10674     WriteLn('TQtTabWidget.Create');
10675   {$endif}
10676   FSwitchTabsByKeyboard := False; {shortcuts are enabled by default under qt, but not under LCL}
10677   FWidgetNeedFontColorInitialization := True;
10678   if AParams.WndParent <> 0 then
10679     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
10680   else
10681     Parent := nil;
10682   Result := QTabWidget_create(Parent);
10683 
10684   {note: for some reason tabbar scroll buttons are not enabled as default option
10685   under mac - but under linux & win are. Qt docs says that this options is enabled
10686   as default ... possible qt bug}
10687   {$ifdef darwin}
10688   QTabWidget_setUsesScrollButtons(QTabWidgetH(Result), True);
10689   {$endif}
10690 end;
10691 
10692 destructor TQtTabWidget.Destroy;
10693 begin
10694   FTabBar.Free;
10695   inherited Destroy;
10696 end;
10697 
10698 procedure TQtTabWidget.DestroyNotify(AWidget: TQtWidget);
10699 begin
10700   if AWidget = FTabBar then
10701     FTabBar := nil;
10702   inherited DestroyNotify(AWidget);
10703 end;
10704 
GetLCLPageIndexnull10705 function TQtTabWidget.GetLCLPageIndex(AIndex: Integer): Integer;
10706 var
10707   I: Integer;
10708 begin
10709   Result := AIndex;
10710   if (LCLObject = nil) or
10711      (csDesigning in LCLObject.ComponentState) or
10712      not (LCLObject is TCustomTabControl) then
10713     Exit;
10714   I := 0;
10715   while (I < TCustomTabControl(LCLObject).PageCount) and (I <= Result) do
10716   begin
10717     if not TCustomTabControl(LCLObject).Page[I].TabVisible then
10718       Inc(Result);
10719     Inc(I);
10720   end;
10721 end;
10722 
10723 procedure TQtTabWidget.AttachEvents;
10724 begin
10725   inherited AttachEvents;
10726 
10727   {initialize our tabbar}
10728   TabBar;
10729 
10730   FCurrentChangedHook := QTabWidget_hook_create(Widget);
10731   QTabWidget_hook_hook_currentChanged(FCurrentChangedHook, @SignalCurrentChanged);
10732 
10733   FCloseRequestedHook := QTabWidget_hook_create(Widget);
10734   QTabWidget_hook_hook_tabCloseRequested(FCloseRequestedHook, @SignalCloseRequested);
10735 
10736   FStackedWidgetHook := QObject_hook_create(StackWidget);
10737   QObject_hook_hook_events(FStackedWidgetHook, @EventFilter);
10738 
10739 end;
10740 
10741 procedure TQtTabWidget.DetachEvents;
10742 begin
10743 
10744   if FStackedWidgetHook <> nil then
10745   begin
10746     QObject_hook_destroy(FStackedWidgetHook);
10747     FStackedWidgetHook := nil;
10748   end;
10749   if FCurrentChangedHook <> nil then
10750   begin
10751     QTabWidget_hook_destroy(FCurrentChangedHook);
10752     FCurrentChangedHook := nil;
10753   end;
10754   if FCloseRequestedHook <> nil then
10755   begin
10756     QTabWidget_hook_destroy(FCloseRequestedHook);
10757     FCloseRequestedHook := nil;
10758   end;
10759   inherited DetachEvents;
10760 end;
10761 
TQtTabWidget.EventFilternull10762 function TQtTabWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
10763   cdecl;
10764 var
10765 {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10766   R: TRect;
10767   TabGeom: TRect;
10768   Pt: TPoint;
10769 {$ENDIF}
10770   ALCLEvent: QLCLMessageEventH;
10771   ANewSize: TSize;
10772 begin
10773 
10774   Result := False;
10775   QEvent_accept(Event);
10776   if LCLObject = nil then
10777     exit;
10778 
10779   if (Sender = FStackWidget) then
10780   begin
10781     {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
10782     WriteLn('TQtTabWidget.EventFilter: STACKWIDGET Sender=', IntToHex(PtrUInt(Sender),8),
10783       ' LCLObject=', dbgsName(LCLObject),
10784       ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
10785     {$endif}
10786     {leave this for debugging purposes}
10787     exit;
10788   end;
10789 
10790   BeginEventProcessing;
10791   try
10792     case QEvent_type(Event) of
10793       QEventResize:
10794       begin
10795         ANewSize := QResizeEvent_size(QResizeEventH(Event))^;
10796         DelayResizeEvent(QWidgetH(Sender), ANewSize); // delay resize event since we are complex widget
10797       end;
10798       {$IFDEF QT_ENABLE_LCL_PAINT_TABS}
10799       QEventPaint:
10800         begin
10801           {this paint event comes after tabbar paint event,
10802            so we have to exclude our tabs from painting}
10803           QPaintEvent_rect(QPaintEventH(Event), @R);
10804           QWidget_geometry(TabBar.Widget, @TabGeom);
10805           Pt.X := R.Left;
10806           Pt.Y := R.Top;
10807           Result := PtInRect(TabGeom, Pt) and
10808             (R.Bottom - R.Top = TabGeom.Bottom - TabGeom.Top) and
10809             (TabAt(Pt) >= 0);
10810           if Result then
10811             QEvent_ignore(Event);
10812         end;
10813       {$ENDIF}
10814       LCLQt_DelayLayoutRequest:
10815       begin
10816         if LCLObject.ClientRectNeedsInterfaceUpdate then
10817         begin
10818           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
10819           DebugLn('<*><*> TQtTabWidget calling DoAdjustClientRectChange() from LCLQt_DelayLayoutRequest ...');
10820           {$ENDIF}
10821           LCLObject.DoAdjustClientRectChange(True);
10822         end;
10823         Result := True;
10824       end;
10825       QEventLayoutRequest:
10826       begin
10827         //behaviour is changed because of issue #21805.
10828         //we send delayed event so LCL can read clientRect at the right time.
10829         ALCLEvent := QLCLMessageEvent_create(LCLQt_DelayLayoutRequest, 0,
10830           0, 0, 0);
10831         QCoreApplication_postEvent(Sender, ALCLEvent);
10832       end;
10833       QEventKeyPress,
10834       QEventKeyRelease: QEvent_ignore(Event);
10835       QEventWheel:
10836         begin
10837           if not getEnabled then
10838             inherited EventFilter(Sender, Event)
10839           else
10840             QEvent_ignore(Event);
10841         end;
10842       else
10843         Result := inherited EventFilter(Sender, Event);
10844     end;
10845   finally
10846     EndEventProcessing;
10847   end;
10848 end;
10849 
10850 {------------------------------------------------------------------------------
10851   Function: TQtTabWidget.insertTab
10852   Params:  index: Integer; page: QWidgetH; p2: PWideString
10853   Returns: Nothing
10854  ------------------------------------------------------------------------------}
insertTabnull10855 function TQtTabWidget.insertTab(index: Integer; page: QWidgetH; p2: WideString): Integer; overload;
10856 begin
10857   Result := insertTab(index, page, nil, p2);
10858 end;
10859 
10860 {------------------------------------------------------------------------------
10861   Function: TQtTabWidget.insertTab
10862   Params:  index: Integer; page: QWidgetH; icon: QIconH; p2: PWideString
10863   Returns: Nothing
10864  ------------------------------------------------------------------------------}
insertTabnull10865 function TQtTabWidget.insertTab(index: Integer; page: QWidgetH; icon: QIconH; p2: WideString): Integer; overload;
10866 var
10867   UseAdd: Boolean;
10868 begin
10869   UseAdd := Index > getCount - 1;
10870   if icon <> nil then
10871   begin
10872     if UseAdd then
10873       Result := QTabWidget_addTab(QTabWidgetH(Widget), page, icon, @p2)
10874     else
10875       Result := QTabWidget_insertTab(QTabWidgetH(Widget), index, page, icon, @p2)
10876   end else
10877   begin
10878     if UseAdd then
10879       Result := QTabWidget_addTab(QTabWidgetH(Widget), page, @p2)
10880     else
10881       Result := QTabWidget_insertTab(QTabWidgetH(Widget), index, page, @p2);
10882   end;
10883 end;
10884 
TQtTabWidget.getCountnull10885 function TQtTabWidget.getCount: Integer;
10886 begin
10887   Result := QTabWidget_count(QTabWidgetH(Widget));
10888 end;
10889 
getClientBoundsnull10890 function TQtTabWidget.getClientBounds: TRect;
10891 begin
10892   QWidget_contentsRect(StackWidget, @Result);
10893 end;
10894 
getCurrentIndexnull10895 function TQtTabWidget.getCurrentIndex: Integer;
10896 begin
10897   Result := QTabWidget_currentIndex(QTabWidgetH(Widget));
10898 end;
10899 
getTabPositionnull10900 function TQtTabWidget.getTabPosition: QTabWidgetTabPosition;
10901 begin
10902   Result := QTabWidget_tabPosition(QTabWidgetH(Widget));
10903 end;
10904 
10905 procedure TQtTabWidget.removeTab(AIndex: Integer);
10906 begin
10907   QTabWidget_removeTab(QTabWidgetH(Widget), AIndex);
10908 end;
10909 
10910 procedure TQtTabWidget.setCurrentIndex(AIndex: Integer);
10911 begin
10912   QTabWidget_setCurrentIndex(QTabWidgetH(Widget), AIndex);
10913 end;
10914 
10915 procedure TQtTabWidget.setCurrentWidget(APage: TQtWidget; const AIsMoved: Boolean);
10916 begin
10917   QTabWidget_setCurrentWidget(QTabWidgetH(Widget), APage.Widget);
10918   if AisMoved then
10919     APage.setFocus;
10920 end;
10921 
10922 {------------------------------------------------------------------------------
10923   Function: TQtTabWidget.setTabPosition
10924   Params:  None
10925   Returns: Nothing
10926  ------------------------------------------------------------------------------}
10927 procedure TQtTabWidget.setTabPosition(ATabPosition: QTabWidgetTabPosition);
10928 begin
10929   QTabWidget_setTabPosition(QTabWidgetH(Widget), ATabPosition);
10930 end;
10931 
10932 procedure TQtTabWidget.setTabIcon(index: Integer; icon: QIconH);
10933 begin
10934   QTabWidget_setTabIcon(QTabWidgetH(Widget), index, icon);
10935 end;
10936 
10937 {------------------------------------------------------------------------------
10938   Function: TQtTabWidget.SignalCurrentChanged
10939   Params:  None
10940   Returns: Nothing
10941            Changes ActivePage of TPageControl
10942  ------------------------------------------------------------------------------}
10943 procedure TQtTabWidget.SignalCurrentChanged(Index: Integer); cdecl;
10944 var
10945   Msg: TLMNotify;
10946   Hdr: TNmHdr;
10947   i: Integer;
10948 begin
10949   if (LCLObject = nil) or InUpdate or not GetVisible then
10950   begin
10951     if TabBar.FSavedIndexOnPageChanging <> Forbid_TCN_SELCHANGE then
10952       TabBar.FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE;
10953     exit;
10954   end;
10955 
10956   FillChar(Msg{%H-}, SizeOf(Msg), 0);
10957   Msg.Msg := LM_NOTIFY;
10958   FillChar(Hdr{%H-}, SizeOf(Hdr), 0);
10959 
10960   Hdr.hwndFrom := LCLObject.Handle;
10961   Hdr.Code := TCN_SELCHANGING;
10962   Hdr.idFrom := PtrUInt(GetLCLPageIndex(Index));
10963   Msg.NMHdr := @Hdr;
10964   Msg.Result := 0;
10965   if (DeliverMessage(Msg) <> 0) and (Index >= 0) and
10966     (TabBar.FSavedIndexOnPageChanging >= 0) then
10967   begin
10968     BeginUpdate;
10969     try
10970       i := TabBar.FSavedIndexOnPageChanging;
10971       FTabBar.FSavedIndexOnPageChanging := Forbid_TCN_SELCHANGE;
10972       setCurrentIndex(i);
10973     finally
10974       EndUpdate;
10975     end;
10976   end;
10977 end;
10978 
10979 procedure TQtTabWidget.SignalCloseRequested(Index: Integer); cdecl;
10980 var
10981   APage: TCustomPage;
10982 begin
10983   APage := TCustomTabControl(LCLObject).Page[GetLCLPageIndex(Index)];
10984   if not APage.HandleAllocated then
10985     Exit;
10986   TCustomTabControl(LCLObject).DoCloseTabClicked(APage);
10987 end;
10988 
TQtTabWidget.indexOfnull10989 function TQtTabWidget.indexOf(const AWidget: QWidgetH): integer;
10990 begin
10991   Result := QTabWidget_indexOf(QTabWidgetH(Widget), AWidget);
10992 end;
10993 
10994 procedure TQtTabWidget.setTabText(index: Integer; p2: WideString);
10995 begin
10996   QTabWidget_setTabText(QTabWidgetH(Widget), index, @p2);
10997 end;
10998 
10999 procedure TQtTabWidget.setTabsClosable(AValue: Boolean);
11000 begin
11001   QTabWidget_setTabsClosable(QTabWidgetH(Widget), AValue);
11002 end;
11003 
tabAtnull11004 function TQtTabWidget.tabAt(APoint: TPoint): Integer;
11005 var
11006   AQtPoint: TQtPoint;
11007   R: TRect;
11008 begin
11009   if (APoint.Y < 0) or (APoint.X < 0) then
11010   begin
11011     {some themes (eg. MacOSX) moves tab buttons
11012      into the middle of parent, so we must
11013      take it's geometry into account.}
11014     R := TabBar.getGeometry;
11015     QWidget_pos(getStackWidget, @AQtPoint);
11016     AQtPoint.x := AQtPoint.x + APoint.x;
11017     AQtPoint.y := AQtPoint.y + APoint.y;
11018 
11019     if R.Left <> 0 then
11020       dec(AQtPoint.x, R.Left);
11021     if R.Top <> 0 then
11022       dec(AQtPoint.y, R.Top);
11023   end else
11024     AQtPoint := QtPoint(APoint.x, APoint.y);
11025   Result := QTabBar_tabAt(QTabBarH(TabBar.Widget), @AQtPoint);
11026 end;
11027 
11028 { TQtComboBox }
11029 
GetLineEditnull11030 function TQtComboBox.GetLineEdit: TQtLineEdit;
11031 begin
11032   if not getEditable then
11033   begin
11034     FLineEdit := nil
11035   end
11036   else
11037   begin
11038     if FLineEdit = nil then
11039     begin
11040       FLineEdit := TQtLineEdit.CreateFrom(LCLObject, QComboBox_lineEdit(QComboBoxH(Widget)));
11041       FLineEdit.FOwner := Self;
11042       QObject_disconnect(FLineEdit.Widget, '2returnPressed()', Widget, '1_q_returnPressed()');
11043       FLineEdit.ChildOfComplexWidget := ccwComboBox;
11044       FLineEdit.AttachEvents;
11045     end;
11046   end;
11047   Result := FLineEdit;
11048 end;
11049 
11050 procedure TQtComboBox.SetOwnerDrawn(const AValue: Boolean);
11051 begin
11052   FOwnerDrawn := AValue;
11053   if FDropList <> nil then
11054     FDropList.OwnerDrawn := FOwnerDrawn;
11055 end;
11056 
TQtComboBox.GetDropListnull11057 function TQtComboBox.GetDropList: TQtListWidget;
11058 begin
11059   if FDropList = nil then
11060   begin
11061     FDropList := TQtListWidget.CreateFrom(LCLObject, QListWidget_create());
11062     FDropList.FOwner := Self;
11063     FDropList.setAttribute(QtWA_NoMousePropagation, False);
11064     FDropList.OwnerDrawn := OwnerDrawn;
11065     FDropList.ChildOfComplexWidget := ccwComboBox;
11066     QComboBox_setModel(QComboBoxH(Widget), FDropList.getModel);
11067     QComboBox_setView(QComboBoxH(Widget), QListWidgetH(FDropList.Widget));
11068     FDropList.AttachEvents;
11069   end;
11070   Result := FDropList;
11071 end;
11072 
CreateWidgetnull11073 function TQtComboBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
11074 var
11075   Parent: QWidgetH;
11076 begin
11077   // Creates the widget
11078   {$ifdef VerboseQt}
11079     WriteLn('TQtComboBox.Create');
11080   {$endif}
11081   FKeyEnterFix := False; {issue #31574}
11082   FMouseFixPos := QtPoint(-1, -1);
11083   FDropListVisibleInternal := False;
11084   if AParams.WndParent <> 0 then
11085     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
11086   else
11087     Parent := nil;
11088   Result := QComboBox_create(Parent);
11089   // disable AutoCompletion. LCL has its own
11090   QComboBox_setAutoCompletion(QComboboxH(Result), False);
11091   FLineEdit := nil;
11092   FOwnerDrawn := False;
11093 end;
11094 
getCursorPositionnull11095 function TQtComboBox.getCursorPosition: TPoint;
11096 begin
11097   Result := Point(0, 0);
11098   if LineEdit <> nil then
11099     Result.X := LineEdit.getCursorPosition.X;
11100 end;
11101 
TQtComboBox.getMaxLengthnull11102 function TQtComboBox.getMaxLength: Integer;
11103 begin
11104   if LineEdit <> nil then
11105     Result := LineEdit.getMaxLength
11106   else
11107     Result := 0;
11108 end;
11109 
getSelectionStartnull11110 function TQtComboBox.getSelectionStart: Integer;
11111 begin
11112   if (LineEdit <> nil) then
11113     Result := LineEdit.getSelectionStart
11114   else
11115     Result := 0;
11116 end;
11117 
getSelectionLengthnull11118 function TQtComboBox.getSelectionLength: Integer;
11119 begin
11120   if (LineEdit <> nil) then
11121     Result := LineEdit.getSelectionLength
11122   else
11123     Result := 0;
11124 end;
11125 
TQtComboBox.isUndoAvailablenull11126 function TQtComboBox.isUndoAvailable: Boolean;
11127 begin
11128   if LineEdit <> nil then
11129     Result := LineEdit.isUndoAvailable
11130   else
11131     Result := False;
11132 end;
11133 
11134 procedure TQtComboBox.setBorder(const ABorder: Boolean);
11135 begin
11136   QComboBox_setFrame(QComboBoxH(Widget), ABorder);
11137 end;
11138 
11139 procedure TQtComboBox.setEchoMode(const AMode: QLineEditEchoMode);
11140 begin
11141   if LineEdit <> nil then
11142     LineEdit.setEchoMode(AMode);
11143 end;
11144 
11145 procedure TQtComboBox.setMaxLength(const ALength: Integer);
11146 begin
11147   if LineEdit <> nil then
11148     LineEdit.setMaxLength(ALength);
11149 end;
11150 
11151 procedure TQtComboBox.setReadOnly(const AReadOnly: Boolean);
11152 begin
11153   setEditable(not AReadOnly);
11154 end;
11155 
11156 procedure TQtComboBox.setSelection(const AStart, ALength: Integer);
11157 begin
11158   if LineEdit <> nil then
11159     LineEdit.setSelection(AStart, ALength);
11160 end;
11161 
11162 procedure TQtComboBox.setCursorPosition(const ACursorPosition: Integer);
11163 begin
11164   if LineEdit <> nil then
11165     LineEdit.setCursorPosition(ACursorPosition);
11166 end;
11167 
11168 procedure TQtComboBox.setTextHint(const ATextHint: string);
11169 begin
11170   if getEditable then
11171     LineEdit.setTextHint(ATextHint);
11172 end;
11173 
11174 procedure TQtComboBox.Cut;
11175 begin
11176   if LineEdit <> nil then
11177     LineEdit.Cut;
11178 end;
11179 
11180 procedure TQtComboBox.Copy;
11181 begin
11182   if LineEdit <> nil then
11183     LineEdit.Copy;
11184 end;
11185 
11186 procedure TQtComboBox.Paste;
11187 begin
11188   if LineEdit <> nil then
11189     LineEdit.Paste;
11190 end;
11191 
11192 procedure TQtComboBox.Undo;
11193 begin
11194   if LineEdit <> nil then
11195     LineEdit.Undo;
11196 end;
11197 
11198 {------------------------------------------------------------------------------
11199   Function: TQtComboBox.Destroy
11200   Params:  None
11201   Returns: Nothing
11202  ------------------------------------------------------------------------------}
11203 destructor TQtComboBox.Destroy;
11204 begin
11205   FDropList.Free;
11206   FLineEdit.Free;
11207   inherited Destroy;
11208 end;
11209 
11210 procedure TQtComboBox.DestroyNotify(AWidget: TQtWidget);
11211 begin
11212   if AWidget = FLineEdit then
11213     FLineEdit := nil;
11214   if AWidget = FDropList then
11215     FDropList := nil;
11216 
11217   if Assigned(FList) then
11218     FList := nil;
11219 
11220   inherited DestroyNotify(AWidget);
11221 end;
11222 
11223 procedure TQtComboBox.InternalIntfGetItems;
11224 begin
11225   TCustomComboBox(LCLObject).IntfGetItems;
11226   // because of issue #25032 we must call it here
11227   if getEnabled then
11228     SlotDropListVisibility(True);
11229 end;
11230 
11231 procedure TQtComboBox.ClearItems;
11232 begin
11233   QComboBox_clear(QComboBoxH(Widget));
11234 end;
11235 
11236 {------------------------------------------------------------------------------
11237   Function: TQtComboBox.currentIndex
11238   Params:  None
11239   Returns: Nothing
11240  ------------------------------------------------------------------------------}
TQtComboBox.currentIndexnull11241 function TQtComboBox.currentIndex: Integer;
11242 begin
11243   Result := QComboBox_currentIndex(QComboBoxH(Widget));
11244 end;
11245 
findTextnull11246 function TQtComboBox.findText(AText: WideString): Integer;
11247 begin
11248   Result := QComboBox_findText(QComboBoxH(Widget), @AText, QtMatchStartsWith);
11249 end;
11250 
TQtComboBox.getDroppedDownnull11251 function TQtComboBox.getDroppedDown: Boolean;
11252 begin
11253   Result := QWidget_isVisible(QComboBox_view(QComboBoxH(Widget)));
11254 end;
11255 
TQtComboBox.getEditablenull11256 function TQtComboBox.getEditable: Boolean;
11257 begin
11258   Result := QComboBox_isEditable(QComboBoxH(Widget));
11259 end;
11260 
TQtComboBox.getItemTextnull11261 function TQtComboBox.getItemText(AIndex: Integer): WideString;
11262 begin
11263   Result := '';
11264   QComboBox_itemText(QComboBoxH(Widget), @Result, AIndex);
11265 end;
11266 
TQtComboBox.getMaxVisibleItemsnull11267 function TQtComboBox.getMaxVisibleItems: Integer;
11268 begin
11269   Result := QComboBox_maxVisibleItems(QComboboxH(Widget));
11270 end;
11271 
getTextnull11272 function TQtComboBox.getText: WideString;
11273 begin
11274   Result := '';
11275   QComboBox_currentText(QComboBoxH(Widget), @Result);
11276   if FOwnerDrawn and (FLineEdit = nil) and
11277     (Result = '') and (Result <> FText) then
11278     Result := FText;
11279 end;
11280 
TQtComboBox.getTextStaticnull11281 function TQtComboBox.getTextStatic: Boolean;
11282 begin
11283   Result := False;
11284 end;
11285 
11286 procedure TQtComboBox.insertItem(AIndex: Integer; AText: String);
11287 var
11288   Str: WideString;
11289 begin
11290   Str := GetUtf8String(AText);
11291   insertItem(AIndex, @Str);
11292 end;
11293 
11294 procedure TQtComboBox.insertItem(AIndex: Integer; AText: PWideString);
11295 begin
11296   QComboBox_insertItem(QComboBoxH(WIdget), AIndex, AText, QVariant_create());
11297 end;
11298 
11299 {------------------------------------------------------------------------------
11300   Function: TQtComboBox.Destroy
11301   Params:  None
11302   Returns: Nothing
11303  ------------------------------------------------------------------------------}
11304 procedure TQtComboBox.setCurrentIndex(index: Integer);
11305 begin
11306   // don't fire any events when we are changing it from the LCL side
11307   BeginUpdate;
11308   QComboBox_setCurrentIndex(QComboBoxH(Widget), index);
11309   EndUpdate;
11310 end;
11311 
11312 procedure TQtComboBox.setDefaultColorRoles;
11313 begin
11314   WidgetColorRole := QPaletteBase;
11315   TextColorRole := QPaletteText;
11316 end;
11317 
11318 procedure TQtComboBox.setDroppedDown(const ADroppedDown: Boolean);
11319 begin
11320   if ADroppedDown <> QWidget_isVisible(QComboBox_view(QComboBoxH(Widget))) then
11321   begin
11322     if ADroppedDown then
11323     begin
11324       InternalIntfGetItems;
11325       QComboBox_showPopup(QComboBoxH(Widget));
11326     end else
11327       QComboBox_hidePopup(QComboBoxH(Widget));
11328   end;
11329 end;
11330 
11331 procedure TQtComboBox.setMaxVisibleItems(ACount: Integer);
11332 begin
11333   QComboBox_setMaxVisibleItems(QComboboxH(Widget), ACount);
11334 end;
11335 
11336 procedure TQtComboBox.setEditable(const AValue: Boolean);
11337 begin
11338   QComboBox_setEditable(QComboBoxH(Widget), AValue);
11339   if not AValue then
11340     FreeAndNil(FLineEdit)
11341   else
11342   begin
11343     LineEdit.setFocusPolicy(getFocusPolicy);
11344     setText(FText);
11345   end;
11346 end;
11347 
11348 procedure TQtComboBox.setItemText(AIndex: Integer; AText: String);
11349 var
11350   Str: WideString;
11351   item: QListWidgetItemH;
11352   R: TRect;
11353 begin
11354   if (AIndex >= 0) and (AIndex < QComboBox_count(QComboBoxH(Widget))) then
11355   begin
11356     Str := GetUTF8String(AText);
11357     QComboBox_setItemText(QComboBoxH(Widget), AIndex, @Str);
11358     {we must update our custom delegate}
11359     if (FDropList <> nil) and
11360        (FDropList.getVisible) and
11361        (FDropList.OwnerDrawn) then
11362     begin
11363       Item := FDropList.getItem(AIndex);
11364       if Item <> nil then
11365       begin
11366         R := FDropList.getVisualItemRect(Item);
11367         FDropList.Update(@R);
11368       end;
11369     end;
11370   end else
11371     insertItem(AIndex, AText);
11372 end;
11373 
11374 procedure TQtComboBox.setText(const W: WideString);
11375 begin
11376   if FLineEdit = nil then
11377     FText := W
11378   else
11379     QComboBox_setEditText(QComboBoxH(Widget), @W);
11380 end;
11381 
11382 procedure TQtComboBox.removeItem(AIndex: Integer);
11383 begin
11384   QComboBox_removeItem(QComboBoxH(Widget), AIndex);
11385 end;
11386 
11387 procedure TQtComboBox.AttachEvents;
11388 begin
11389   inherited AttachEvents;
11390 
11391   FActivateHook := QComboBox_hook_create(Widget);
11392   FChangeHook := QComboBox_hook_create(Widget);
11393   FSelectHook := QComboBox_hook_create(Widget);
11394 
11395   // OnChange event if itemindex changed by mouse or kbd
11396   QComboBox_hook_hook_activated(FActivateHook, @SlotActivate);
11397 
11398   // OnChange event -> fires only when text changed
11399   QComboBox_hook_hook_editTextChanged(FChangeHook, @SlotChange);
11400   // OnSelect event
11401   QComboBox_hook_hook_currentIndexChanged(FSelectHook, @SlotSelect);
11402 
11403   // DropList events
11404   FDropListEventHook := QObject_hook_create(DropList.Widget);
11405   QObject_hook_hook_events(FDropListEventHook, @EventFilter);
11406 end;
11407 
11408 procedure TQtComboBox.DetachEvents;
11409 begin
11410   if FDropListEventHook <> nil then
11411   begin
11412     QObject_hook_destroy(FDropListEventHook);
11413     FDropListEventHook := nil;
11414   end;
11415   if FActivateHook <> nil then
11416   begin
11417     QComboBox_hook_destroy(FActivateHook);
11418     FActivateHook := nil;
11419   end;
11420   if FChangeHook <> nil then
11421   begin
11422     QComboBox_hook_destroy(FChangeHook);
11423     FChangeHook := nil;
11424   end;
11425   if FSelectHook <> nil then
11426   begin
11427     QComboBox_hook_destroy(FSelectHook);
11428     FSelectHook := nil;
11429   end;
11430 
11431   inherited DetachEvents;
11432 end;
11433 
11434 procedure TQtComboBox.slotPaintCombo(Sender: QObjectH; Event: QEventH); cdecl;
11435 var
11436   Msg: TLMPaint;
11437   AStruct: PPaintStruct;
11438   MsgItem: TLMDrawListItem;
11439   DrawStruct: TDrawListItemStruct;
11440   P: TPoint;
11441   Opt: QStyleOptionComboBoxH;
11442   R: TRect;
11443   State: QStyleState;
11444   CurrIndex: Integer;
11445 begin
11446   {$ifdef VerboseQt}
11447     WriteLn('TQtComboBox.SlotPaintCombo ', dbgsName(LCLObject));
11448   {$endif}
11449   CurrIndex := currentIndex;
11450   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11451 
11452   Msg.Msg := LM_PAINT;
11453   New(AStruct);
11454   FillChar(AStruct^, SizeOf(TPaintStruct), 0);
11455   Msg.PaintStruct := AStruct;
11456 
11457   with PaintData do
11458   begin
11459     PaintWidget := Widget;
11460     ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
11461     if ClipRect = nil then
11462       New(ClipRect);
11463     QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
11464   end;
11465 
11466   Msg.DC := BeginPaint(THandle(Self), AStruct^);
11467   FContext := Msg.DC;
11468 
11469   Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
11470   Msg.PaintStruct^.hdc := FContext;
11471 
11472   P := getClientOffset;
11473   inc(P.X, FScrollX);
11474   inc(P.Y, FScrollY);
11475   TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
11476 
11477   TQtDeviceContext(Msg.DC).save;
11478   try
11479     Opt := QStyleOptionComboBox_create();
11480     QStyleOption_initFrom(Opt, Widget);
11481     State := QStyleOption_state(opt);
11482     QStyleOption_rect(Opt, @R);
11483     QPainter_setClipRect(TQtDeviceContext(Msg.DC).Widget, @R);
11484 
11485     QStyle_drawComplexControl(QApplication_style(), QStyleCC_ComboBox, Opt,
11486       TQtDeviceContext(Msg.DC).Widget, Widget);
11487     QStyle_subControlRect(QApplication_style(), @R, QStyleCC_ComboBox, Opt,
11488       QStyleSC_ComboBoxEditField , Widget);
11489     if CurrIndex < 0 then
11490     begin
11491       QStyleOptionComboBox_setCurrentText(Opt, @FText);
11492       QStyle_drawControl(QApplication_style(), QStyleCE_ComboBoxLabel, opt,
11493         TQtDeviceContext(Msg.DC).Widget, Widget);
11494     end;
11495 
11496   finally
11497     QStyleOptionComboBox_destroy(Opt);
11498     TQtDeviceContext(Msg.DC).restore;
11499   end;
11500 
11501   inc(R.Top);
11502   dec(R.Bottom);
11503   QPainter_setClipRect(TQTDeviceContext(Msg.DC).Widget, @R);
11504 
11505   DrawStruct.ItemID := UINT(CurrIndex);
11506   DrawStruct.Area := R;
11507   DrawStruct.DC := Msg.DC;
11508 
11509   DrawStruct.ItemState := [];
11510 
11511   // selected
11512   if (State and QStyleState_Selected) <> 0 then
11513     Include(DrawStruct.ItemState, odSelected);
11514   // disabled
11515   if (State and QStyleState_Enabled) = 0 then
11516     Include(DrawStruct.ItemState, odDisabled);
11517   // focused (QStyleState_FocusAtBorder?)
11518   if ((State and QStyleState_HasFocus) <> 0) or
11519     ((State and QStyleState_FocusAtBorder) <> 0) then
11520     Include(DrawStruct.ItemState, odFocused);
11521   // hotlight
11522   if (State and QStyleState_MouseOver) <> 0 then
11523     Include(DrawStruct.ItemState, odHotLight);
11524 
11525   MsgItem.Msg := LM_DRAWLISTITEM;
11526   MsgItem.DrawListItemStruct := @DrawStruct;
11527 
11528   try
11529     if CurrIndex >= 0 then
11530       DeliverMessage(MsgItem);
11531   finally
11532     Dispose(PaintData.ClipRect);
11533     Fillchar(FPaintData, SizeOf(FPaintData), 0);
11534     FContext := 0;
11535     EndPaint(THandle(Self), AStruct^);
11536     Dispose(AStruct);
11537   end;
11538 end;
11539 
11540 {this routine is called ONLY from dropdown list viewport event filter
11541  when QEventShow occurs.It sends MouseRelease event to LCL !
11542  Should not be used in any other case.}
11543 procedure TQtComboBox.FixMouseUp;
11544 var
11545   MouseEvent: QMouseEventH;
11546   AMouseFixPosF: TQtPointF;
11547 begin
11548   if (FMouseFixPos.x = -1) and (FMouseFixPos.y = -1) then
11549     exit;
11550   if QGUIApplication_mouseButtons = QtLeftButton then
11551   begin
11552     AMouseFixPosF.X := FMouseFixPos.X;
11553     AMouseFixPosF.Y := FMouseFixPos.Y;
11554     MouseEvent := QMouseEvent_create(QEventMouseButtonRelease, @AMouseFixPosF, QtLeftButton,
11555       QtLeftButton, QGUIApplication_keyboardModifiers());
11556     QCoreApplication_postEvent(Widget, MouseEvent);
11557   end;
11558 end;
11559 
EventFilternull11560 function TQtComboBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
11561 var
11562   R, R1: TRect;
11563   ButtonRect: TRect;
11564   P: TQtPoint;
11565   Pt: TPoint;
11566   Opt: QStyleOptionComboBoxH;
11567 begin
11568 
11569   Result := False;
11570   QEvent_accept(Event);
11571 
11572   if LCLObject = nil then
11573     exit;
11574 
11575   if (FDropList <> nil) and (Sender = FDropList.Widget) then
11576   begin
11577     if (Byte(QEvent_type(Event)) in [QEventKeyPress, QEventKeyRelease,QEventFontChange]) then
11578     begin
11579       Result := inherited EventFilter(Sender, Event);
11580       if Result and (QEvent_type(Event) = QEventKeyPress) then
11581         FKeyEnterFix := True; {issue #31574}
11582     end;
11583     QEvent_ignore(Event);
11584     exit;
11585   end;
11586 
11587   BeginEventProcessing;
11588   try
11589     if FKeyEnterFix and (Byte(QEvent_type(Event)) in [QEventMouseButtonPress, QEventMouseButtonDblClick,
11590       QEventMouseButtonRelease, QEventKeyPress, QEventHide, QEventShow]) then
11591         FKeyEnterFix := False; {issue #31574}
11592     case QEvent_type(Event) of
11593       QEventFocusOut:
11594       begin
11595         if Assigned(FLineEdit) and FLineEdit.getVisible then
11596         begin
11597           FLineEdit.CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(FLineEdit.Widget));
11598           FLineEdit.CachedSelectionLen := UTF16Length(FLineEdit.getSelectedText);
11599         end;
11600         Result := inherited EventFilter(Sender, Event);
11601       end;
11602       QEventFocusIn:
11603       begin
11604         if Assigned(FLineEdit) and FLineEdit.getVisible then
11605         begin
11606           FLineEdit.CachedSelectionStart := -1;
11607           FLineEdit.CachedSelectionLen := -1;
11608         end;
11609         Result := inherited EventFilter(Sender, Event);
11610       end;
11611       QEventHide:
11612       begin
11613         if getVisible then
11614           SlotShow(False);
11615       end;
11616       QEventPaint:
11617       begin
11618         if FOwnerDrawn and not getEditable then
11619         begin
11620           SlotPaintCombo(Widget, Event);
11621           Result := True;
11622           QEvent_accept(Event);
11623         end;
11624       end;
11625       QEventMouseButtonRelease:
11626       begin
11627         FMouseFixPos := QtPoint(-1, -1);
11628         Result := inherited EventFilter(Sender, Event);
11629       end;
11630       QEventMouseButtonPress:
11631       begin
11632         if not FDropListVisibleInternal and
11633           (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
11634         begin
11635           // some themes have empty space around combo button !
11636 
11637           QMouseEvent_pos(QMouseEventH(Event), @P);
11638           FMouseFixPos := P;
11639 
11640           // our combo geometry
11641           R := getGeometry;
11642 
11643           Pt := Point(P.X, P.Y);
11644 
11645           // our combo arrow position when we are editable combobox
11646           if getEditable then
11647           begin
11648             opt := QStyleOptionComboBox_create();
11649             QStyle_subControlRect(QApplication_style(), @R1, QStyleCC_ComboBox,
11650               opt, QStyleSC_ComboBoxArrow, QComboBoxH(Widget));
11651             QStyleOptionComboBox_destroy(opt);
11652             R := Rect(0, 0, R.Right - R.Left, R.Bottom - R.Top);
11653             ButtonRect := Rect(R.Right + R1.Left, R.Top,
11654               R.Right - R1.Right, R.Bottom);
11655           end else
11656           begin
11657             ButtonRect := R;
11658             OffsetRect(ButtonRect, -R.Left, -R.Top);
11659           end;
11660 
11661           if PtInRect(ButtonRect, Pt) then
11662             InternalIntfGetItems;
11663         end;
11664         Result := inherited EventFilter(Sender, Event);
11665       end;
11666 
11667       QEventMouseButtonDblClick:
11668       begin
11669         // avoid crash on unfocused combobox raised from
11670         // eg. TStringGrid as picklist.
11671         // crash happens when combo is hidden in cell, and then we
11672         // dbl click on position of combo button. Control raises combo
11673         // and propagate dbl click to combobox which must grab focus in
11674         // that case.
11675         if CanSendLCLMessage and getEnabled and not hasFocus then
11676           setFocus;
11677         Result := inherited EventFilter(Sender, Event);
11678       end;
11679 
11680       QEventKeyPress:
11681       begin
11682         if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_F4) or
11683           ((QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
11684             not getEditable) then
11685         begin
11686           if not FDropListVisibleInternal then
11687             InternalIntfGetItems
11688           else
11689             Result := inherited EventFilter(Sender, Event);
11690         end else
11691           Result := inherited EventFilter(Sender, Event);
11692       end;
11693       QEventKeyRelease:
11694       begin
11695         {issue #31574}
11696         if not FKeyEnterFix then
11697           Result := inherited EventFilter(Sender, Event);
11698         FKeyEnterFix := False;
11699       end;
11700       else
11701         Result := inherited EventFilter(Sender, Event);
11702     end;
11703   finally
11704     EndEventProcessing;
11705   end;
11706 end;
11707 
11708 procedure TQtComboBox.preferredSize(var PreferredWidth,
11709   PreferredHeight: integer; WithThemeSpace: Boolean);
11710 var
11711   Size: TSize;
11712 begin
11713   QComboBox_sizeHint(QComboBoxH(Widget), @Size);
11714   PreferredWidth := Size.cx;
11715   PreferredHeight := Size.cy;
11716 end;
11717 
11718 procedure TQtComboBox.SlotActivate(index: Integer); cdecl;
11719 var
11720   Msg: TLMessage;
11721 begin
11722   if InUpdate then
11723     Exit;
11724 
11725   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11726   Msg.Msg := LM_ACTIVATE;
11727   DeliverMessage(Msg);
11728 end;
11729 
11730 procedure TQtComboBox.SlotChange(p1: PWideString); cdecl;
11731 var
11732   Msg: TLMessage;
11733 begin
11734   if InUpdate then
11735     Exit;
11736 
11737   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11738 
11739   Msg.Msg := LM_CHANGED;
11740 
11741   DeliverMessage(Msg);
11742 end;
11743 
11744 procedure TQtComboBox.SlotSelect(index: Integer); cdecl;
11745 var
11746   Msg: TLMessage;
11747 begin
11748   if InUpdate then
11749     exit;
11750 
11751   {we must fire OnChange() if it isn''t editable
11752    since SlotChange() fires only for editable
11753    comboboxes }
11754   if not getEditable then
11755   begin
11756     FillChar(Msg{%H-}, SizeOf(Msg), #0);
11757     Msg.Msg := LM_CHANGED;
11758     DeliverMessage(Msg);
11759   end;
11760 
11761   FillChar(Msg, SizeOf(Msg), #0);
11762 
11763   Msg.Msg := LM_SELCHANGE;
11764 
11765   DeliverMessage(Msg);
11766 end;
11767 
11768 procedure TQtComboBox.SlotDropListVisibility(AVisible: Boolean); cdecl;
11769 const
11770   VisibilityToCodeMap: array[Boolean] of Word =
11771   (
11772     CBN_CLOSEUP,
11773     CBN_DROPDOWN
11774   );
11775 var
11776   Msg : TLMCommand;
11777 begin
11778   if InUpdate then
11779     Exit;
11780 
11781   FillChar(Msg{%H-}, SizeOf(Msg), 0);
11782   Msg.Msg := CN_COMMAND;
11783   Msg.NotifyCode := VisibilityToCodeMap[AVisible];
11784 
11785   DeliverMessage(Msg);
11786   FDropListVisibleInternal := AVisible;
11787 end;
11788 
11789 { TQtAbstractSpinBox }
11790 
GetLineEditnull11791 function TQtAbstractSpinBox.GetLineEdit: QLineEditH;
11792 begin
11793   if FLineEdit = nil then
11794     FLineEdit := QLCLAbstractSpinBox_lineEditHandle(QAbstractSpinBoxH(Widget));
11795   if Assigned(FLineEdit) and not Assigned(FLineEditHook) then
11796   begin
11797     FLineEditHook := QObject_hook_create(FLineEdit);
11798     QObject_hook_hook_events(FLineEditHook, @LineEditEventFilter);
11799     FTextChangedHook := QLineEdit_hook_create(FLineEdit);
11800     QLineEdit_hook_hook_textChanged(FTextChangedHook, @SignalLineEditTextChanged);
11801   end;
11802   Result := FLineEdit;
11803 end;
11804 
LineEditEventFilternull11805 function TQtAbstractSpinBox.LineEditEventFilter(Sender: QObjectH; Event: QEventH
11806   ): Boolean; cdecl;
11807 begin
11808   Result := False;
11809   QEvent_accept(Event);
11810   if QEvent_type(Event) = QEventFontChange then
11811     Result := EventFilter(QWidgetH(Sender), Event);
11812 end;
11813 
11814 procedure TQtAbstractSpinBox.SignalLineEditTextChanged(AnonParam1: PWideString); cdecl;
11815 var
11816   Msg: TLMessage;
11817 begin
11818   if FTextChangedByValueChanged then
11819   begin
11820     FTextChangedByValueChanged := False;
11821     Exit;
11822   end;
11823   FillChar(Msg{%H-}, SizeOf(Msg), #0);
11824   Msg.Msg := CM_TEXTCHANGED;
11825   if not InUpdate then
11826     DeliverMessage(Msg);
11827 end;
11828 
11829 procedure TQtAbstractSpinBox.setTextHint(const ATextHint: string);
11830 var
11831   W: WideString;
11832 begin
11833   if Assigned(FLineEdit) and not (csDesigning in LCLObject.ComponentState) then
11834   begin
11835     W := UTF8ToUTF16(ATextHint);
11836     QLineEdit_setPlaceholderText(FLineEdit, @W);
11837   end;
11838 end;
11839 
CreateWidgetnull11840 function TQtAbstractSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
11841 var
11842   Parent: QWidgetH;
11843 begin
11844   // Creates the widget
11845   {$ifdef VerboseQt}
11846     WriteLn('TQtAbstractSpinBox.Create');
11847   {$endif}
11848   FLineEditHook := nil;
11849   if AParams.WndParent <> 0 then
11850     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
11851   else
11852     Parent := nil;
11853   FTextChangedByValueChanged := False;
11854   Result := QAbstractSpinBox_create(Parent);
11855 end;
11856 
getMaxLengthnull11857 function TQtAbstractSpinBox.getMaxLength: Integer;
11858 begin
11859   if LineEdit <> nil then
11860     Result := QLineEdit_maxLength(LineEdit)
11861   else
11862     Result := 0;
11863 end;
11864 
getSelectionStartnull11865 function TQtAbstractSpinBox.getSelectionStart: Integer;
11866 begin
11867   if (LineEdit <> nil) then
11868   begin
11869     if QLineEdit_hasSelectedText(LineEdit) then
11870       Result := QLineEdit_selectionStart(LineEdit)
11871     else
11872       Result := QLineEdit_cursorPosition(LineEdit);
11873   end
11874   else
11875     Result := 0;
11876 end;
11877 
getSelectionLengthnull11878 function TQtAbstractSpinBox.getSelectionLength: Integer;
11879 var
11880   W: WideString;
11881 begin
11882   if (LineEdit <> nil) and QLineEdit_hasSelectedText(LineEdit) then
11883   begin
11884     QLineEdit_selectedText(LineEdit, @W);
11885     Result := UTF16Length(W);
11886   end
11887   else
11888     Result := 0;
11889 end;
11890 
isUndoAvailablenull11891 function TQtAbstractSpinBox.isUndoAvailable: Boolean;
11892 begin
11893   if LineEdit <> nil then
11894     Result := QLineEdit_isUndoAvailable(LineEdit)
11895   else
11896     Result := False;
11897 end;
11898 
11899 procedure TQtAbstractSpinBox.setBorder(const ABorder: Boolean);
11900 begin
11901   QAbstractSpinBox_setFrame(QAbstractSpinBoxH(Widget), ABorder);
11902 end;
11903 
11904 procedure TQtAbstractSpinBox.setCursorPosition(const ACursorPosition: Integer);
11905 begin
11906   if LineEdit <> nil then
11907     QLineEdit_setCursorPosition(LineEdit, ACursorPosition);
11908 end;
11909 
11910 procedure TQtAbstractSpinBox.setDefaultColorRoles;
11911 begin
11912   WidgetColorRole := QPaletteBase;
11913   TextColorRole := QPaletteText;
11914 end;
11915 
11916 procedure TQtAbstractSpinBox.setEchoMode(const AMode: QLineEditEchoMode);
11917 begin
11918   if LineEdit <> nil then
11919     QLineEdit_setEchoMode(LineEdit, AMode);
11920 end;
11921 
11922 procedure TQtAbstractSpinBox.setMaxLength(const ALength: Integer);
11923 begin
11924   if LineEdit <> nil then
11925     QLineEdit_setMaxLength(LineEdit, ALength);
11926 end;
11927 
11928 procedure TQtAbstractSpinBox.setSelection(const AStart, ALength: Integer);
11929 begin
11930   if (LineEdit <> nil) and (AStart >= 0) then
11931   begin
11932     if ALength > 0 then
11933       QLineEdit_setSelection(LineEdit, AStart, ALength)
11934     else
11935       QLineEdit_setCursorPosition(LineEdit, AStart);
11936   end;
11937 end;
11938 
11939 procedure TQtAbstractSpinBox.Cut;
11940 begin
11941   if LineEdit <> nil then
11942     QLineEdit_cut(LineEdit);
11943 end;
11944 
11945 procedure TQtAbstractSpinBox.Copy;
11946 begin
11947   if LineEdit <> nil then
11948     QLineEdit_copy(LineEdit);
11949 end;
11950 
11951 procedure TQtAbstractSpinBox.Paste;
11952 begin
11953   if LineEdit <> nil then
11954     QLineEdit_paste(LineEdit);
11955 end;
11956 
11957 procedure TQtAbstractSpinBox.Undo;
11958 begin
11959   if LineEdit <> nil then
11960     QLineEdit_undo(LineEdit);
11961 end;
11962 
getCursorPositionnull11963 function TQtAbstractSpinBox.getCursorPosition: TPoint;
11964 begin
11965   Result := Point(0, 0);
11966   if LineEdit <> nil then
11967     Result.X := QLineEdit_cursorPosition(LineEdit);
11968 end;
11969 
getReadOnlynull11970 function TQtAbstractSpinBox.getReadOnly: Boolean;
11971 begin
11972   {$ifdef VerboseQt}
11973     WriteLn('TQtAbstractSpinBox.IsReadOnly');
11974   {$endif}
11975   Result := QAbstractSpinBox_isReadOnly(QAbstractSpinBoxH(Widget));
11976 end;
11977 
getTextnull11978 function TQtAbstractSpinBox.getText: WideString;
11979 begin
11980   if LineEdit <> nil then
11981     QLineEdit_text(LineEdit, @Result)
11982   else
11983     Result := '';
11984   {$ifdef VerboseQt}
11985   WriteLn('TQtAbstractSpinBox.GetText Result=',Result);
11986   {$endif}
11987 end;
11988 
getTextStaticnull11989 function TQtAbstractSpinBox.getTextStatic: Boolean;
11990 begin
11991   Result := False;
11992 end;
11993 
11994 procedure TQtAbstractSpinBox.setAlignment(const AAlignment: QtAlignment);
11995 begin
11996   QAbstractSpinBox_setAlignment(QSpinBoxH(Widget), AAlignment);
11997 end;
11998 
11999 procedure TQtAbstractSpinBox.setFocusPolicy(const APolicy: QtFocusPolicy);
12000 begin
12001   inherited setFocusPolicy(APolicy);
12002   QWidget_setFocusPolicy(LineEdit, APolicy);
12003 end;
12004 
12005 procedure TQtAbstractSpinBox.setReadOnly(const r: Boolean);
12006 begin
12007   QAbstractSpinBox_setReadOnly(QAbstractSpinBoxH(Widget), r);
12008 end;
12009 
12010 procedure TQtAbstractSpinBox.setText(const W: WideString);
12011 begin
12012   {$ifdef VerboseQt}
12013   WriteLn('TQtAbstractSpinBox.SetText W=',w);
12014   {$endif}
12015   if (LineEdit <> nil) then
12016     QLineEdit_setText(LineEdit, @W)
12017 end;
12018 
12019 procedure TQtAbstractSpinBox.AttachEvents;
12020 begin
12021   inherited AttachEvents;
12022 
12023   FEditingFinishedHook := QAbstractSpinBox_hook_create(Widget);
12024   {TODO: find out which TLMessage should be sended }
12025   QAbstractSpinBox_hook_hook_editingFinished(FEditingFinishedHook, @SignalEditingFinished);
12026 end;
12027 
12028 procedure TQtAbstractSpinBox.DetachEvents;
12029 begin
12030   if FEditingFinishedHook <> nil then
12031   begin
12032     QAbstractSpinBox_hook_destroy(FEditingFinishedHook);
12033     FEditingFinishedHook := nil;
12034   end;
12035 
12036   if FLineEditHook <> nil then
12037   begin
12038     QObject_hook_destroy(FLineEditHook);
12039     FLineEditHook := nil;
12040   end;
12041 
12042   if FTextChangedHook <> nil then
12043   begin
12044     QLineEdit_hook_destroy(FTextChangedHook);
12045     FTextChangedHook := nil;
12046   end;
12047 
12048   inherited DetachEvents;
12049 end;
12050 
EventFilternull12051 function TQtAbstractSpinBox.EventFilter(Sender: QObjectH; Event: QEventH
12052   ): Boolean; cdecl;
12053 var
12054   IsDeleteKey: Boolean;
12055 begin
12056   if (QEvent_type(Event) = QEventKeyPress) or
12057      (QEvent_type(Event) = QEventKeyRelease) then
12058     IsDeleteKey := (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Delete) and
12059       (QKeyEvent_modifiers(QKeyEventH(Event)) = QtNoModifier)
12060   else
12061     IsDeleteKey := False;
12062   Result := inherited EventFilter(Sender, Event);
12063   {we must pass delete key to qt, qabstractspinbox doesn't like what we do}
12064   if IsDeleteKey then
12065     Result := False;
12066   {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
12067   if (FParentShowPassed = 1) then
12068   begin
12069     if QEvent_type(Event) <> QEventPaint then
12070     begin
12071       inc(FParentShowPassed);
12072       BeginUpdate;
12073       setValue(getValue);
12074       EndUpdate;
12075     end;
12076   end;
12077 
12078   if (QEvent_type(Event) = QEventShowToParent) and
12079     (FParentShowPassed = 0) then
12080     inc(FParentShowPassed);
12081   {$ENDIF}
12082 
12083 end;
12084 
12085 procedure TQtAbstractSpinBox.SignalEditingFinished; cdecl;
12086 var
12087   Msg: TLMessage;
12088 begin
12089   {$ifdef VerboseQt}
12090     WriteLn('TQtAbstractSpinBox.SignalEditingFinished');
12091   {$endif}
12092   FillChar(Msg{%H-}, SizeOf(Msg), #0);
12093   { TODO: Find out which message should be sended here
12094     problem:
12095      everything is fine when we work with mouse, or
12096      press TabKey to select next control, but if we
12097      connect OnKeyDown and say eg. VK_RETURN: SelectNext(ActiveControl, true, true)
12098      then spinedit text is always selected, nothing important but looks ugly.}
12099   //  Msg.Msg := LM_EXIT;
12100   //  DeliverMessage(Msg);
12101 end;
12102 
12103 { TQtFloatSpinBox }
12104 
TQtFloatSpinBox.CreateWidgetnull12105 function TQtFloatSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
12106 var
12107   Parent: QWidgetH;
12108 begin
12109   // Creates the widget
12110   {$ifdef VerboseQt}
12111     WriteLn('TQtFloatSpinBox.Create');
12112   {$endif}
12113   {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
12114   FParentShowPassed := 0;
12115   {$ENDIF}
12116   FValue := 0;
12117   FLineEditHook := nil;
12118   if AParams.WndParent <> 0 then
12119     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
12120   else
12121     Parent := nil;
12122   Result := QDoubleSpinBox_create(Parent);
12123 end;
12124 
getValuenull12125 function TQtFloatSpinBox.getValue: Double;
12126 begin
12127   Result := FValue;
12128 end;
12129 
12130 procedure TQtFloatSpinBox.setDecimals(const v: integer);
12131 begin
12132   QDoubleSpinBox_setDecimals(QDoubleSpinBoxH(Widget), v);
12133 end;
12134 
12135 procedure TQtFloatSpinBox.setMinimum(const v: Double);
12136 begin
12137   QDoubleSpinBox_setMinimum(QDoubleSpinBoxH(Widget), v);
12138 end;
12139 
12140 procedure TQtFloatSpinBox.setMaximum(const v: Double);
12141 begin
12142   QDoubleSpinBox_setMaximum(QDoubleSpinBoxH(Widget), v);
12143 end;
12144 
12145 procedure TQtFloatSpinBox.setSingleStep(const v: Double);
12146 begin
12147   QDoubleSpinBox_setSingleStep(QDoubleSpinBoxH(Widget), v);
12148 end;
12149 
12150 procedure TQtFloatSpinBox.setValue(const v: Double);
12151 begin
12152   FValue := v;
12153   QDoubleSpinBox_setValue(QDoubleSpinBoxH(Widget), FValue);
12154 end;
12155 
12156 procedure TQtFloatSpinBox.AttachEvents;
12157 begin
12158   inherited AttachEvents;
12159   FValueChangedHook := QDoubleSpinBox_hook_create(Widget);
12160   QDoubleSpinBox_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
12161 end;
12162 
12163 procedure TQtFloatSpinBox.DetachEvents;
12164 begin
12165   if FValueChangedHook <> nil then
12166   begin
12167     QDoubleSpinBox_hook_destroy(FValueChangedHook);
12168     FValueChangedHook := nil;
12169   end;
12170   inherited DetachEvents;
12171 end;
12172 
12173 procedure TQtFloatSpinBox.SignalValueChanged(p1: Double); cdecl;
12174 var
12175   Msg: TLMessage;
12176 begin
12177   FValue := p1;
12178   FTextChangedByValueChanged := True;
12179   FillChar(Msg{%H-}, SizeOf(Msg), #0);
12180   Msg.Msg := CM_TEXTCHANGED;
12181   if not InUpdate then
12182     DeliverMessage(Msg);
12183 end;
12184 
12185 { TQtSpinBox }
12186 
CreateWidgetnull12187 function TQtSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
12188 var
12189   Parent: QWidgetH;
12190 begin
12191   // Creates the widget
12192   {$ifdef VerboseQt}
12193     WriteLn('TQtSpinBox.Create');
12194   {$endif}
12195   {$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
12196   FParentShowPassed := 0;
12197   {$ENDIF}
12198   FLineEditHook := nil;
12199   if AParams.WndParent <> 0 then
12200     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
12201   else
12202     Parent := nil;
12203   Result := QSpinBox_create(Parent);
12204 end;
12205 
getValuenull12206 function TQtSpinBox.getValue: Double;
12207 begin
12208   Result := FValue;
12209 end;
12210 
12211 procedure TQtSpinBox.setMinimum(const v: Double);
12212 begin
12213   QSpinBox_setMinimum(QSpinBoxH(Widget), round(v));
12214 end;
12215 
12216 procedure TQtSpinBox.setMaximum(const v: Double);
12217 begin
12218   QSpinBox_setMaximum(QSpinBoxH(Widget), round(v));
12219 end;
12220 
12221 procedure TQtSpinBox.setSingleStep(const v: Double);
12222 begin
12223   QSpinBox_setSingleStep(QSpinBoxH(Widget), round(v));
12224 end;
12225 
12226 procedure TQtSpinBox.setValue(const v: Double);
12227 begin
12228   FValue := Round(v);
12229   QSpinBox_setValue(QSpinBoxH(Widget), round(v));
12230 end;
12231 
12232 procedure TQtSpinBox.AttachEvents;
12233 begin
12234   inherited AttachEvents;
12235   FValueChangedHook := QSpinBox_hook_create(Widget);
12236   QSpinBox_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
12237 end;
12238 
12239 procedure TQtSpinBox.DetachEvents;
12240 begin
12241   if FValueChangedHook <> nil then
12242   begin
12243     QSpinBox_hook_destroy(FValueChangedHook);
12244     FValueChangedHook := nil;
12245   end;
12246   inherited DetachEvents;
12247 end;
12248 
12249 procedure TQtSpinBox.SignalValueChanged(p1: Integer); cdecl;
12250 var
12251   Msg: TLMessage;
12252 begin
12253   FValue := p1;
12254   FTextChangedByValueChanged := True;
12255   FillChar(Msg{%H-}, SizeOf(Msg), #0);
12256   Msg.Msg := CM_TEXTCHANGED;
12257   if not InUpdate then
12258    DeliverMessage(Msg);
12259 end;
12260 
12261 { TQtListView }
12262 
getBatchSizenull12263 function TQtListView.getBatchSize: integer;
12264 begin
12265   Result := QListView_batchSize(QListViewH(Widget));
12266 end;
12267 
getGridSizenull12268 function TQtListView.getGridSize: TSize;
12269 begin
12270   QListView_gridSize(QListViewH(Widget), @Result);
12271 end;
12272 
getSpacingnull12273 function TQtListView.getSpacing: Integer;
12274 begin
12275   Result := QListView_spacing(QListViewH(Widget));
12276 end;
12277 
12278 procedure TQtListView.setBatchSize(const AValue: integer);
12279 begin
12280   QListView_setBatchSize(QListViewH(Widget), AValue);
12281 end;
12282 
12283 procedure TQtListView.setGridSize(const AValue: TSize);
12284 begin
12285   QListView_setGridSize(QListViewH(Widget), @AValue);
12286 end;
12287 
12288 procedure TQtListView.setLayoutMode(const ALayoutMode: QListViewLayoutMode);
12289 begin
12290   QListView_setLayoutMode(QListViewH(Widget), ALayoutMode);
12291 end;
12292 
12293 procedure TQtListView.setMovement(const AMovement: QListViewMovement);
12294 begin
12295   QListView_setMovement(QListViewH(Widget), AMovement);
12296 end;
12297 
12298 procedure TQtListView.setResizeMode(const AResizeMode: QListViewResizeMode);
12299 begin
12300   QListView_setResizeMode(QListViewH(Widget), AResizeMode);
12301 end;
12302 
12303 procedure TQtListView.setSpacing(const AValue: integer);
12304 begin
12305   QListView_setSpacing(QListViewH(Widget), AValue);
12306 end;
12307 
12308 procedure TQtListView.setUniformItemSizes(const AEnable: Boolean);
12309 begin
12310   QListView_setUniformItemSizes(QListViewH(Widget), AEnable);
12311 end;
12312 
12313 procedure TQtListView.setViewFlow(const AFlow: QListViewFlow);
12314 begin
12315   QListView_setFlow(QListViewH(Widget), AFlow);
12316 end;
12317 
12318 procedure TQtListView.setViewMode(const AMode: QListViewViewMode);
12319 begin
12320   QListView_setViewMode(QListViewH(Widget), AMode);
12321 end;
12322 
12323 procedure TQtListView.setWordWrap(const AValue: Boolean);
12324 begin
12325   QListView_setWordWrap(QListViewH(Widget), AValue);
12326 end;
12327 
12328 procedure TQtListView.setWrapping(const AWrapping: Boolean);
12329 begin
12330   QListView_setWrapping(QListViewH(Widget), AWrapping);
12331 end;
12332 
12333 procedure TQtListView.LayoutItems;
12334 begin
12335   QListView_doItemsLayout(QListViewH(Widget));
12336 end;
12337 
12338 { TQtListWidget }
12339 
TQtListWidget.getItemCountnull12340 function TQtListWidget.getItemCount: Integer;
12341 begin
12342   Result := QListWidget_count(QListWidgetH(Widget));
12343 end;
12344 
TQtListWidget.GetItemCheckednull12345 function TQtListWidget.GetItemChecked(AIndex: Integer): Boolean;
12346 var
12347   AItem: QListWidgetItemH;
12348 begin
12349   Result := False;
12350   AItem := getItem(AIndex);
12351   if Assigned(AItem) then
12352     Result := QListWidgetItem_checkState(AItem) = QtChecked;
12353 end;
12354 
GetItemEnablednull12355 function TQtListWidget.GetItemEnabled(AIndex: Integer): Boolean;
12356 var
12357   AItem: QListWidgetItemH;
12358 begin
12359   Result := False;
12360   AItem := getItem(AIndex);
12361   if Assigned(AItem) then
12362     Result := QListWidgetItem_flags(AItem) and QtItemIsEnabled <> 0;
12363 end;
12364 
TQtListWidget.GetSelectednull12365 function TQtListWidget.GetSelected(AIndex: Integer): Boolean;
12366 var
12367   AItem: QListWidgetItemH;
12368 begin
12369   Result := False;
12370   AItem := getItem(AIndex);
12371   if Assigned(AItem) then
12372     Result := getItemSelected(AItem);
12373 end;
12374 
12375 procedure TQtListWidget.SetItemChecked(AIndex: Integer; AValue: Boolean);
12376 var
12377   AItem: QListWidgetItemH;
12378 begin
12379   AItem := getItem(AIndex);
12380   if Assigned(AItem) then
12381   begin
12382     if AValue then
12383       QListWidgetItem_setCheckState(AItem, QtChecked)
12384     else
12385       QListWidgetItem_setCheckState(AItem, QtUnChecked);
12386     SetItemLastCheckState(AItem);
12387   end;
12388 end;
12389 
12390 procedure TQtListWidget.setItemCount(const AValue: Integer);
12391 var
12392   i: Integer;
12393   AList: QStringListH;
12394   WStr: WideString;
12395 begin
12396   if AValue = ItemCount then
12397     exit;
12398   BeginUpdate;
12399   try
12400     ClearItems;
12401     AList := QStringList_create();
12402     WStr := '';
12403     for i := 1 to AValue do
12404       QStringList_append(AList, @WStr);
12405     QListWidget_addItems(QListWidgetH(Widget), AList);
12406     QStringList_destroy(AList);
12407   finally
12408     EndUpdate;
12409   end;
12410 end;
12411 
12412 procedure TQtListWidget.SetItemEnabled(AIndex: Integer; AValue: Boolean);
12413 var
12414   AItem: QListWidgetItemH;
12415   Flags: QtItemFlags;
12416 begin
12417   AItem := getItem(AIndex);
12418   if Assigned(AItem) then
12419   begin
12420     Flags := QListWidgetItem_flags(AItem);
12421     if AValue then
12422       Flags := Flags or QtItemIsEnabled
12423     else
12424       Flags := Flags and not QtItemIsEnabled;
12425     QListWidgetItem_setFlags(AItem, Flags);
12426   end;
12427 end;
12428 
12429 procedure TQtListWidget.SetSelected(AIndex: Integer; AValue: Boolean);
12430 begin
12431   if (AIndex >= 0) and (AIndex < RowCount) then
12432     setItemSelected(getItem(AIndex), AValue);
12433 end;
12434 
GetItemLastCheckStatenull12435 function TQtListWidget.GetItemLastCheckState(AItem: QListWidgetItemH
12436   ): QtCheckState;
12437 var
12438   v: QVariantH;
12439   ok: Boolean;
12440 begin
12441   Result := QtUnChecked;
12442   if AItem = nil then
12443     exit;
12444   v := QVariant_create();
12445   QListWidgetItem_data(AItem, v,  QtCheckStateRole);
12446   ok := False;
12447   if QVariant_isValid(v) then
12448     Result := QtCheckState(QVariant_toInt(v, @Ok));
12449   QVariant_destroy(v);
12450 end;
12451 
12452 procedure TQtListWidget.SetItemLastCheckState(AItem: QListWidgetItemH);
12453 var
12454   AState: QtCheckState;
12455 begin
12456   if AItem = nil then
12457     exit;
12458   AState := QListWidgetItem_checkState(AItem);
12459   SetItemLastCheckStateInternal(AItem, AState);
12460 end;
12461 
12462 procedure TQtListWidget.SetItemLastCheckStateInternal(AItem: QListWidgetItemH;
12463   AState: QtCheckState);
12464 var
12465   v: QVariantH;
12466 begin
12467   v := QVariant_create(Ord(AState));
12468   QListWidgetItem_setData(AItem, QtCheckStateRole, v);
12469   QVariant_destroy(v);
12470 end;
12471 
12472 procedure TQtListWidget.SetNextStateMap(AItem: QListWidgetItemH);
12473 begin
12474   // does the job only for TQtCheckListBox
12475 end;
12476 
TQtListWidget.CreateWidgetnull12477 function TQtListWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
12478 var
12479   Parent: QWidgetH;
12480 begin
12481   FCheckBoxClicked := False;
12482   FDelayedCheckItem := nil;
12483   SetLength(FSavedSelection, 0);
12484   AllowGrayed := False;
12485   FSavedEvent := nil;
12486   FSavedEventTimer := nil;
12487   FSavedEventTimerHook := nil;
12488 
12489   FViewStyle := -1;
12490   FSyncingItems := False;
12491   FCheckable := False;
12492   FDontPassSelChange := False;
12493   FOwnerData := False;
12494   if AParams.WndParent <> 0 then
12495     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
12496   else
12497     Parent := nil;
12498   Result := QListWidget_create(Parent);
12499 end;
12500 
12501 type
12502   TCustomListViewHack = class(TCustomListView);
12503 
12504 procedure TQtListWidget.OwnerDataNeeded(ARect: TRect);
12505 var
12506   R: TRect;
12507   TopItem: Integer;
12508   i: Integer;
12509   VHeight: Integer; // viewport height
12510   RowHeight, AImagesWidth: Integer;
12511   item: QListWidgetItemH;
12512   v, v2, v3: QVariantH;
12513   WStr: WideString;
12514   DataStr: WideString;
12515   ImgList: TCustomImageList;
12516   AImageIndex: TImageIndex;
12517   Bmp: TBitmap;
12518   AIcon: QIconH;
12519   AOk, AStateImages: Boolean;
12520   ASize: TSize;
12521   ImgListRes: TScaledImageListResolution;
12522 begin
12523 
12524   {do not set items during design time}
12525   if (csDesigning in LCLObject.ComponentState) then
12526     exit;
12527 
12528   if ItemCount < 1 then
12529     exit;
12530 
12531   {TODO: add QtDecorationRole (icon) etc ... }
12532   QWidget_contentsRect(viewportWidget, @R);
12533   VHeight := R.Bottom - R.Top;
12534 
12535   item := itemAt(0, 1);
12536   if item <> nil then
12537   begin
12538     TopItem := getRow(Item);
12539     RowHeight := getRowHeight(TopItem);
12540 
12541     if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
12542       exit;
12543 
12544     i := 0;
12545 
12546     while (i < (VHeight + RowHeight)) do
12547     begin
12548       item := itemAt(0, i + 1);
12549       if (item <> nil) then
12550       begin
12551         TopItem := getRow(Item);
12552         RowHeight := getRowHeight(TopItem);
12553 
12554         if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
12555           break;
12556 
12557         AStateImages := False;
12558         ImgList := TCustomListViewHack(LCLObject).SmallImages;
12559         if Assigned(ImgList) then
12560           AImagesWidth := TCustomListViewHack(LCLObject).SmallImagesWidth
12561         else
12562         begin
12563           ImgList := TCustomListViewHack(LCLObject).StateImages;
12564           if Assigned(ImgList) then
12565             AImagesWidth := TCustomListViewHack(LCLObject).StateImagesWidth;
12566           AStateImages := True;
12567         end;
12568         if Assigned(ImgList) then
12569         begin
12570           ImgListRes := ImgList.ResolutionForPPI[
12571             AImagesWidth,
12572             TCustomListViewHack(LCLObject).Font.PixelsPerInch,
12573             TCustomListViewHack(LCLObject).GetCanvasScaleFactor];
12574           QListWidgetItem_sizeHint(item, @ASize);
12575           if (ASize.cx <> ImgListRes.Width) or (ASize.cx <> ImgListRes.Height) then
12576           begin
12577             ASize.cx := ImgListRes.Width;
12578             ASize.cy := ImgListRes.Height;
12579             QListWidgetItem_setSizeHint(item, @ASize);
12580           end;
12581           if AStateImages then
12582             AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].StateIndex
12583           else
12584             AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].ImageIndex;
12585           if (ImgListRes.Count > 0) and
12586             ((AImageIndex >= 0) and (AImageIndex < ImgListRes.Count)) then
12587           begin
12588             Bmp := TBitmap.Create;
12589             try
12590               ImgListRes.GetBitmap(AImageIndex, Bmp);
12591               v2 := QVariant_create;
12592               QListWidgetItem_data(item, v2, QtListViewOwnerDataRole);
12593               if not QVariant_isNull(v2) then
12594               begin
12595                 AOk := True;
12596                 if QVariant_toInt(v2, @AOk) <> AImageIndex then
12597                 begin
12598                   v2 := QVariant_create(AImageIndex);
12599                   QListWidgetItem_setData(item, QtListViewOwnerDataRole, v2);
12600                   QVariant_destroy(v2);
12601                   QListWidgetItem_setIcon(item, TQtImage(Bmp.Handle).AsIcon)
12602                 end;
12603                 // else we are imageIndex and that''s fine.
12604               end else
12605               begin
12606                 v2 := QVariant_create(AImageIndex);
12607                 QListWidgetItem_setData(item, QtListViewOwnerDataRole, v2);
12608                 QVariant_destroy(v2);
12609                 QListWidgetItem_setIcon(item, TQtImage(Bmp.Handle).AsIcon);
12610               end;
12611             finally
12612               Bmp.Free;
12613             end;
12614           end else
12615           if (AImageIndex < 0) then
12616           begin
12617             v2 := QVariant_create;
12618             AIcon := QIcon_create;
12619             try
12620               QListWidgetItem_data(item, v2, QtListViewOwnerDataRole);
12621               if not QVariant_isNull(v2) then
12622               begin
12623                 v3 := QVariant_create;
12624                 try
12625                   QListWidgetItem_setData(item, QtListViewOwnerDataRole, v3);
12626                 finally
12627                   QVariant_destroy(v3);
12628                 end;
12629               end;
12630               QListWidgetItem_icon(item, AIcon);
12631               if not QIcon_isNull(AIcon) then
12632                 QListWidgetItem_setIcon(item, nil);
12633             finally
12634               QVariant_destroy(v2);
12635               QIcon_destroy(AIcon);
12636             end;
12637           end;
12638         end;
12639 
12640         WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].Caption);
12641 
12642         // reduce paint overhead by checking text
12643         v := QVariant_create();
12644         QListWidgetItem_data(item, v, Ord(QtDisplayRole));
12645         if QVariant_isValid(v) then
12646           QVariant_toString(v, @DataStr)
12647         else
12648           DataStr := '';
12649         QVariant_destroy(v);
12650 
12651         // ASelected := not TCustomListViewHack(LCLObject).Items[TopItem].Selected;
12652 
12653         if (DataStr <> WStr) then
12654         begin
12655           v := QVariant_create(PWideString(@WStr));
12656           try
12657             QListWidgetItem_setData(item, Ord(QtDisplayRole), v);
12658           finally
12659             QVariant_destroy(v);
12660           end;
12661         end;
12662 
12663         // if (QListWidgetItem_isSelected(Item) <> ASelected) then
12664         //  QListWidgetItem_setSelected(Item, ASelected);
12665 
12666       end else
12667         break;
12668 
12669       inc(i, RowHeight);
12670     end;
12671   end;
12672 end;
12673 
TQtListWidget.GetItemFlagsnull12674 function TQtListWidget.GetItemFlags(AIndex: Integer): QtItemFlags;
12675 var
12676   AItem: QListWidgetItemH;
12677 begin
12678   Result := inherited GetItemFlags(AIndex);
12679   AItem := getItem(AIndex);
12680   if Assigned(AItem) then
12681     Result := QListWidgetItem_flags(AItem);
12682 end;
12683 
12684 procedure TQtListWidget.SetItemFlags(AIndex: Integer; AValue: QtItemFlags);
12685 var
12686   AItem: QListWidgetItemH;
12687 begin
12688   inherited SetItemFlags(AIndex, AValue);
12689   AItem := getItem(AIndex);
12690   if Assigned(AItem) then
12691     QListWidgetItem_setFlags(AItem, AValue);
12692 end;
12693 
12694 procedure TQtListWidget.AttachEvents;
12695 begin
12696   inherited AttachEvents;
12697 
12698   FCurrentItemChangedHook := QListWidget_hook_create(Widget);
12699   FSelectionChangeHook := QListWidget_hook_create(Widget);
12700   FItemClickedHook := QListWidget_hook_create(Widget);
12701   FItemTextChangedHook := QListWidget_hook_create(Widget);
12702 
12703   // used only when we are handle of TListView
12704   QListWidget_hook_hook_currentItemChanged(FCurrentItemChangedHook,
12705     @signalCurrentItemChanged);
12706 
12707   // OnSelectionChange event (listbox)
12708   QListWidget_hook_hook_itemSelectionChanged(FSelectionChangeHook, @signalSelectionChanged);
12709   QListWidget_hook_hook_itemClicked(FItemClickedHook, @signalItemClicked);
12710   QListWidget_hook_hook_currentTextChanged(FItemTextChangedHook, @signalItemTextChanged);
12711 end;
12712 
12713 procedure TQtListWidget.DetachEvents;
12714 begin
12715   if FCurrentItemChangedHook <> nil then
12716   begin
12717     QListWidget_hook_destroy(FCurrentItemChangedHook);
12718     FCurrentItemChangedHook := nil;
12719   end;
12720   if FSelectionChangeHook <> nil then
12721   begin
12722     QListWidget_hook_destroy(FSelectionChangeHook);
12723     FSelectionChangeHook := nil;
12724   end;
12725   if FItemClickedHook <> nil then
12726   begin
12727     QListWidget_hook_destroy(FItemClickedHook);
12728     FItemClickedHook := nil;
12729   end;
12730   if FItemTextChangedHook <> nil then
12731   begin
12732     QListWidget_hook_destroy(FItemTextChangedHook);
12733     FItemTextChangedHook := nil;
12734   end;
12735 
12736   inherited DetachEvents;
12737 end;
12738 
12739 procedure TQtListWidget.InitializeWidget;
12740 begin
12741   inherited InitializeWidget;
12742   // by default horz scrollbars is off. it is set by SetScrollWidth
12743   setScrollBarPolicy(False, QtScrollBarAlwaysOff);
12744 end;
12745 
TQtListWidget.EventFilternull12746 function TQtListWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
12747   cdecl;
12748 var
12749   ev: QEventH;
12750 begin
12751   Result := False;
12752   QEvent_accept(Event);
12753   if LCLObject = nil then
12754     exit;
12755 
12756   if (FChildOfComplexWidget = ccwComboBox) and (FOwner <> nil) then
12757   begin
12758     case QEvent_type(Event) of
12759       QEventHide:
12760       begin
12761         {we must delay SlotDropDownVisiblity according to #9574
12762          so order is OnChange(if editable)->OnSelect->OnCloseUp }
12763         ev := QEvent_create(QEventHideToParent);
12764         QCoreApplication_postEvent(Sender, ev);
12765       end;
12766       QEventHideToParent: TQtComboBox(FOwner).SlotDropListVisibility(False);
12767     end;
12768   end else
12769   begin
12770     if (QEvent_type(Event) = QEventResize) then
12771       // let the viewport send resize
12772     else
12773     if (QEvent_type(Event) = QEventMouseButtonPress) or
12774       (QEvent_type(Event) = QEventMouseButtonRelease) then
12775       {eat mouse button events when we are TListView class.
12776        Such events are handled by itemViewportEventFilter.
12777        With Qt TListBox and TCheckListBox are also affected. issue #21318}
12778     else
12779     begin
12780       Result:=inherited EventFilter(Sender, Event);
12781       if Checkable and
12782         (QEvent_type(Event) = QEventKeyPress) and
12783         (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) then
12784       begin
12785         if CurrentItem <> nil then
12786         begin
12787           HandleCheckChangedEvent(QtPoint(0, 0), currentItem, Event);
12788           if OwnerDrawn and not (Self is TQtCheckListBox) then
12789           begin
12790             if QListWidgetItem_checkState(currentItem) = QtUnChecked then
12791               QListWidgetItem_setCheckState(currentItem, QtChecked)
12792             else
12793               QListWidgetItem_setCheckState(currentItem, QtUnchecked);
12794           end;
12795         end;
12796       end;
12797     end;
12798   end;
12799 end;
12800 
12801 procedure TQtListWidget.HandleCheckChangedEvent(const AMousePos: TQtPoint;
12802   AItem: QListWidgetItemH; AEvent: QEventH);
12803 var
12804   xx: Integer;
12805   B: Boolean;
12806 
12807   procedure SendMessage(AnItem: QListWidgetItemH);
12808   var
12809     Msg: TLMNotify;
12810     NMLV: TNMListView;
12811   begin
12812     FillChar(Msg{%H-}, SizeOf(Msg), #0);
12813     FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
12814 
12815     Msg.Msg := CN_NOTIFY;
12816 
12817     NMLV.hdr.hwndfrom := HWND(Self);
12818     NMLV.hdr.code := LVN_ITEMCHANGED;
12819 
12820     NMLV.iItem := QListWidget_row(QListWidgetH(Widget), AnItem);
12821 
12822     NMLV.uNewState := UINT(B);
12823     NMLV.uChanged := LVIF_STATE;
12824 
12825     Msg.NMHdr := @NMLV.hdr;
12826 
12827     // DebugLn('HandleCheckableMouseDown sending LVN_ITEMCHANGED ...');
12828     DeliverMessage(Msg);
12829   end;
12830 begin
12831   if not Checkable or (AItem = nil) or (ViewStyle < 0) then
12832     exit;
12833 
12834   if ((QEvent_type(AEvent) = QEventMouseButtonPress) or
12835     (QEvent_type(AEvent) = QEventMouseButtonDblClick)) and
12836   (QMouseEvent_button(QMouseEventH(AEvent)) = QtLeftButton) then
12837   begin
12838     if (QListWidgetItem_flags(AItem) and QtItemIsUserCheckable) <> 0 then
12839     begin
12840       xx := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
12841       if ((AMousePos.X > 2) and (AMousePos.X <= (xx + 2))) then
12842       begin
12843         B := QListWidgetItem_checkState(AItem) = QtUnChecked;
12844         if B then
12845           SetItemLastCheckStateInternal(AItem, QtChecked)
12846         else
12847           SetItemLastCheckStateInternal(AItem, QtUnChecked);
12848 
12849         // if AItem is deleted in mouse event FDelayedCheckItem becomes nil and that's fine. issue #32869
12850         FDelayedCheckItem := AItem;
12851         SendMessage(AItem);
12852       end;
12853     end;
12854   end else
12855   if QEvent_type(AEvent) = LCLQt_ItemViewAfterMouseRelease then
12856   begin
12857     if (FDelayedCheckItem <> nil) and (FDelayedCheckItem <> AItem) then
12858     begin
12859       SetItemLastCheckStateInternal(FDelayedCheckItem, QListWidgetItem_checkState(FDelayedCheckItem));
12860       SendMessage(FDelayedCheckItem);
12861     end;
12862     FDelayedCheckItem := nil;
12863     SetItemLastCheckStateInternal(AItem, QListWidgetItem_checkState(AItem));
12864     SendMessage(AItem);
12865   end else
12866   if (QEvent_type(AEvent) = QEventKeyPress) and
12867     (QKeyEvent_key(QKeyEventH(AEvent)) = QtKey_Space) then
12868   begin
12869     FDelayedCheckItem := nil;
12870     B := QListWidgetItem_checkState(AItem) = QtUnChecked;
12871     if B then
12872       SetItemLastCheckStateInternal(AItem, QtChecked)
12873     else
12874       SetItemLastCheckStateInternal(AItem, QtUnChecked);
12875 
12876     SendMessage(AItem);
12877   end;
12878 end;
12879 
itemViewViewportEventFilternull12880 function TQtListWidget.itemViewViewportEventFilter(Sender: QObjectH;
12881   Event: QEventH): Boolean; cdecl;
12882 var
12883   Item, CurrItem: QListWidgetItemH;
12884   MousePos: TQtPoint;
12885   X: Integer;
12886   Arr: TPtrIntArray;
12887   Modifiers: QtKeyboardModifiers;
12888   ItemRow, CurrItemRow: Integer;
12889   ALCLEvent: QLCLMessageEventH;
12890   R: TRect;
12891   DC: TQtDeviceContext;
12892   AMsgData: PtrUInt;
12893 
12894   procedure SendEventToParent;
12895   begin
12896     //issue #21318
12897     SlotMouse(Widget, Event);
12898   end;
12899 
12900 begin
12901   Result := False;
12902   QEvent_accept(Event);
12903 
12904   if (FChildOfComplexWidget = ccwComboBox) and (FOwner <> nil) then
12905   begin
12906     if QEvent_type(Event) = QEventShow then
12907       TQtComboBox(FOwner).FixMouseUp;
12908     exit;
12909   end;
12910 
12911   if (LCLObject <> nil) then
12912   begin
12913     if ViewStyle >= 0 then
12914     begin
12915       if (QEvent_type(Event) = QEventPaint) and (Sender = viewportWidget) then
12916       begin
12917         HasPaint := True;
12918         QPaintEvent_rect(QPaintEventH(Event), @R);
12919         if FOwnerData then
12920           OwnerDataNeeded(R);
12921         DC := TQtDeviceContext.Create(QWidgetH(Sender), True);
12922         try
12923           TCustomListViewAccess(LCLObject).Canvas.handle := HDC(DC);
12924           TCustomListViewAccess(LCLObject).IntfCustomDraw(dtControl, cdPrePaint, 0, 0, [], @R);
12925         finally
12926           TCustomListViewAccess(LCLObject).Canvas.handle := 0;
12927           DC.Free;
12928         end;
12929       end else
12930       if getEnabled and (QEvent_type(Event) = LCLQt_ItemViewAfterMouseRelease) then
12931       begin
12932         ALCLEvent := QLCLMessageEventH(Event);
12933         Item := QListWidgetItemH(QLCLMessageEvent_getLParam(ALCLEvent));
12934         // sync lcl with qt state. This is needed only when mouse is pressed
12935         // and moved out of item, or pressed on item and released over checkbox
12936         if (Item <> nil) and (GetItemLastCheckState(Item) <>
12937           QListWidgetItem_checkState(Item)) then
12938         begin
12939           MousePos := QtPoint(0, 0); // shutup compiler
12940           if QLCLMessageEvent_getMsg(ALCLEvent) > 0 then
12941             QListWidgetItem_setCheckState(Item, GetItemLastCheckState(Item));
12942           HandleCheckChangedEvent(MousePos, Item, Event);
12943         end;
12944       end else
12945       if getEnabled and (QEvent_type(Event) = QEventMouseButtonRelease) then
12946       begin
12947         if OwnerDrawn and Checkable then
12948         begin
12949           // MousePos :=
12950           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
12951           Item := itemAt(MousePos.x, MousePos.y);
12952 
12953           if (Item <> nil) and
12954             ((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
12955           begin
12956             x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
12957             if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
12958             begin
12959               if QListWidgetItem_checkState(Item) = QtUnchecked then
12960                 QListWidgetItem_setCheckState(Item, QtChecked)
12961               else
12962                 QListWidgetItem_setCheckState(Item, QtUnChecked);
12963             end;
12964           end;
12965           Result := SlotMouse(Sender, Event);
12966         end else
12967         begin
12968           PostponedMouseRelease(Event);
12969           if Checkable then
12970           begin
12971             // MousePos :=
12972             QMouseEvent_pos(QMouseEventH(Event), @MousePos);
12973             Item := itemAt(MousePos.x, MousePos.y);
12974             if (Item <> nil) then
12975             begin
12976               if Assigned(LCLObject) and LCLObject.Dragging then
12977                 AMsgData := Ord(QListWidgetItem_checkState(Item)) + 1
12978               else
12979                 AMsgData := 0;
12980               ALCLEvent := QLCLMessageEvent_create(LCLQt_ItemViewAfterMouseRelease, AMsgData,
12981                 PtrUInt(Item), PtrUInt(Item), 0);
12982               QCoreApplication_postEvent(Sender, ALCLEvent);
12983             end;
12984           end;
12985         end;
12986       end else
12987       begin
12988         if getEnabled and (QEvent_type(Event) = QEventMouseButtonPress) then
12989         begin
12990           // MousePos :=
12991           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
12992           Item := itemAt(MousePos.x, MousePos.y);
12993           if Item = nil then
12994             FSavedSelection := selectedItems
12995           else
12996           begin
12997             // qt selection in QListWidget is ugly, and LCL needs that info
12998             // when mouse button is pressed, not after that, so we
12999             // trigger selectionChanged() here
13000             // Multiselection needs special handling to get proper
13001             // order of OnSelectItem.
13002             if (getSelectionMode > QAbstractItemViewSingleSelection) or FOwnerData then
13003             begin
13004               Modifiers := QInputEvent_modifiers(QInputEventH(Event));
13005               SlotMouse(Sender, Event);
13006 
13007               HandleCheckChangedEvent(MousePos, Item, Event);
13008 
13009               if not QListWidgetItem_isSelected(Item) then
13010               begin
13011                 if Modifiers = 0 then
13012                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
13013                     QItemSelectionModelClearAndSelect or QItemSelectionModelCurrent)
13014                 else
13015                 if (Modifiers and QtControlModifier <> 0) then
13016                 begin
13017                   X := getSelCount;
13018                   // DebugLn('**** Called SELECT IN 1 X=', dbgs(X),' is curr ? ',dbgs(CurrentItem = Item));
13019                   if CurrentItem = Item then
13020                     X := 0;
13021                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
13022                     QItemSelectionModelSelect);
13023                   if (X <= 1) then
13024                     signalCurrentItemChanged(Item, nil);
13025                 end else
13026                 if (Modifiers and QtShiftModifier <> 0) then
13027                 begin
13028                   // select this and all other's (calculate is it up or down)
13029                   X := getSelCount;
13030                   CurrItem := currentItem; //<-- doesn't smell good with QtShiftModifier
13031                   if CurrItem = nil then // <-- do not crash
13032                     CurrItem := Item;
13033                   ItemRow := getRow(Item);
13034                   CurrItemRow := getRow(CurrItem);
13035                   if (ItemRow < CurrItemRow) and (ItemRow >= 0) then
13036                   begin
13037                     for x := CurrItemRow + 1 to rowCount - 1 do
13038                     begin
13039                       CurrItem := getItem(x);
13040                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
13041                         QItemSelectionModelClear or QItemSelectionModelDeselect);
13042                     end;
13043                     for x := CurrItemRow downto ItemRow do
13044                     begin
13045                       CurrItem := getItem(x);
13046                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
13047                         QItemSelectionModelSelect);
13048                     end;
13049                   end else
13050                   if (ItemRow > CurrItemRow) then
13051                   begin
13052                     for x := 0 to CurrItemRow - 1 do
13053                     begin
13054                       CurrItem := getItem(x);
13055                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
13056                         QItemSelectionModelClear or QItemSelectionModelDeselect);
13057                     end;
13058                     for x := ItemRow downto CurrItemRow do
13059                     begin
13060                       CurrItem := getItem(x);
13061                       QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
13062                         QItemSelectionModelSelect);
13063                     end;
13064                   end;
13065                 end;
13066               end else
13067               begin
13068                 X := getSelCount;
13069                 if (Modifiers = 0) and (X > 1) then
13070                 begin
13071                   Arr := selectedItems;
13072                   for x := 0 to High(Arr) do
13073                   begin
13074                     if QListWidgetItemH(Arr[x]) <> Item then
13075                       QListWidget_setCurrentItem(QListWidgetH(Widget),
13076                         QListWidgetItemH(Arr[x]), QItemSelectionModelDeSelect);
13077                   end;
13078                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
13079                     QItemSelectionModelSelectCurrent);
13080                 end else
13081                 if (Modifiers and QtControlModifier <> 0) then
13082                 begin
13083                   QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
13084                     QItemSelectionModelDeSelect);
13085                   if (X = 1) or (currentItem = Item) then
13086                     signalCurrentItemChanged(nil, Item);
13087                 end;
13088               end;
13089               QEvent_ignore(Event);
13090               Result := True;
13091               exit;
13092             end else
13093             begin
13094               SlotMouse(Sender, Event);
13095               HandleCheckChangedEvent(MousePos, Item, Event);
13096               if not QListWidgetItem_isSelected(Item) then
13097                 QListWidget_setCurrentItem(QListWidgetH(Widget), Item, QItemSelectionModelClearAndSelect);
13098               QEvent_ignore(Event);
13099               Result := True;
13100               exit;
13101             end;
13102           end;
13103         end;
13104 
13105         if getEnabled and Checkable and (QEvent_type(Event) = QEventMouseButtonDblClick) then
13106         begin
13107           // MousePos :=
13108           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
13109           Item := itemAt(MousePos.x, MousePos.y);
13110           if Item <> nil then
13111             HandleCheckChangedEvent(MousePos, Item, Event);
13112         end;
13113 
13114         Result := inherited itemViewViewportEventFilter(Sender, Event);
13115       end;
13116     end else
13117     case QEvent_type(Event) of
13118       QEventMouseButtonPress,
13119       QEventMouseButtonRelease,
13120       QEventMouseButtonDblClick:
13121       begin
13122         if getEnabled and Checkable and
13123           (QEvent_type(Event) <> QEventMouseButtonDblClick) and
13124           (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
13125         begin
13126           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
13127           Item := itemAt(MousePos.x, MousePos.y);
13128           if (Item <> nil) and
13129             ((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
13130           begin
13131             x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
13132             if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
13133             begin
13134               FCheckBoxClicked := True;
13135               SetItemLastCheckState(Item);
13136               {signalItemClicked() fires !}
13137             end else
13138               SendEventToParent;
13139           end else
13140             SendEventToParent;
13141         end else
13142           SendEventToParent;
13143       end;
13144     else
13145       Result := inherited itemViewViewportEventFilter(Sender, Event);
13146     end;
13147   end;
13148 end;
13149 
13150 procedure TQtListWidget.signalCurrentItemChanged(current: QListWidgetItemH;
13151   previous: QListWidgetItemH); cdecl;
13152 var
13153   Msg: TLMNotify;
13154   NMLV: TNMListView;
13155   ASubIndex: Integer;
13156   AIndex: Integer;
13157 begin
13158   // only when TQtListWidget is handle of TListView !
13159   if ViewStyle = -1 then
13160     exit;
13161 
13162   FillChar(Msg{%H-}, SizeOf(Msg), #0);
13163   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
13164 
13165   Msg.Msg := CN_NOTIFY;
13166 
13167   NMLV.hdr.hwndfrom := LCLObject.Handle;
13168   NMLV.hdr.code := LVN_ITEMCHANGING;
13169 
13170   if Current <> nil then
13171     AIndex := getRow(Current)
13172   else
13173     AIndex := -1;
13174 
13175   ASubIndex := 0;
13176 
13177   NMLV.iItem := AIndex;
13178   NMLV.iSubItem := ASubIndex;
13179   NMLV.uNewState := LVIS_SELECTED;
13180   NMLV.uChanged := LVIF_STATE;
13181 
13182   Msg.NMHdr := @NMLV.hdr;
13183   DeliverMessage(Msg);
13184 
13185   // if getSelectionMode > QAbstractItemViewSingleSelection then
13186   //  DebugLn('*** MultiSelect: SignalCurrentItemChanged Current ',dbgs(Current),' Previous ',dbgs(Previous));
13187 
13188   FSyncingItems := True;
13189   try
13190     if Current <> nil then
13191     begin
13192       FillChar(Msg, SizeOf(Msg), #0);
13193       FillChar(NMLV, SizeOf(NMLV), #0);
13194       Msg.Msg := CN_NOTIFY;
13195       NMLV.hdr.hwndfrom := LCLObject.Handle;
13196       NMLV.hdr.code := LVN_ITEMCHANGED;
13197       NMLV.iItem := AIndex;
13198       NMLV.iSubItem := ASubIndex;
13199       if QListWidget_isItemSelected(QListWidgetH(Widget), Current) then
13200         NMLV.uNewState := LVIS_SELECTED
13201       else
13202         NMLV.uOldState := LVIS_SELECTED;
13203       NMLV.uChanged := LVIF_STATE;
13204       Msg.NMHdr := @NMLV.hdr;
13205       DeliverMessage(Msg);
13206 
13207       // send focused msg
13208       NMLV.uOldState := 0;
13209       NMLV.uNewState := LVIS_FOCUSED;
13210       NMLV.uChanged := LVIF_STATE;
13211       Msg.NMHdr := @NMLV.hdr;
13212       DeliverMessage(Msg);
13213 
13214     end;
13215 
13216     if Previous <> nil then
13217     begin
13218       FillChar(Msg, SizeOf(Msg), #0);
13219       FillChar(NMLV, SizeOf(NMLV), #0);
13220       Msg.Msg := CN_NOTIFY;
13221       NMLV.hdr.hwndfrom := LCLObject.Handle;
13222       NMLV.hdr.code := LVN_ITEMCHANGED;
13223       NMLV.iItem := getRow(Previous);
13224       ASubIndex := 0;
13225       NMLV.iSubItem := ASubIndex;
13226       if QListWidget_isItemSelected(QListWidgetH(Widget), Previous) then
13227         NMLV.uNewState := LVIS_SELECTED
13228       else
13229         NMLV.uOldState := LVIS_SELECTED;
13230       NMLV.uChanged := LVIF_STATE;
13231       Msg.NMHdr := @NMLV.hdr;
13232       DeliverMessage(Msg);
13233     end;
13234   finally
13235     FSyncingItems := False;
13236   end;
13237 end;
13238 
13239 {------------------------------------------------------------------------------
13240   Function: TQtListWidget.SlotSelectionChange
13241   Params:  None
13242   Returns: Nothing
13243  ------------------------------------------------------------------------------}
13244 
13245 procedure TQtListWidget.signalSelectionChanged(); cdecl;
13246 var
13247   Msg: TLMessage;
13248   i: Integer;
13249   Item: QListWidgetItemH;
13250 begin
13251   {$ifdef VerboseQt}
13252     WriteLn('TQtListWidget.signalSelectionChange');
13253   {$endif}
13254 
13255   if FDontPassSelChange then
13256   begin
13257     FDontPassSelChange := False;
13258     Exit;
13259   end;
13260 
13261   if (ViewStyle >= 0) and (InUpdate or
13262     (not InUpdate and (length(FSavedSelection) = 0)) ) then
13263     exit;
13264 
13265   FillChar(Msg{%H-}, SizeOf(Msg), #0);
13266   Msg.Msg := LM_SELCHANGE;
13267   if (FChildOfComplexWidget <> ccwComboBox) then
13268   begin
13269     if (ViewStyle < 0) and (getSelCount > 0) then
13270       DeliverMessage(Msg)
13271     else
13272     if (ViewStyle >= 0) then
13273     begin
13274       if getSelCount = 0 then
13275       begin
13276         for i := 0 to High(FSavedSelection) do
13277         begin
13278           Item := QListWidgetItemH(FSavedSelection[i]);
13279           if (Item <> nil) then
13280             signalCurrentItemChanged(nil, Item);
13281         end;
13282       end;
13283       setLength(FSavedSelection, 0);
13284     end;
13285   end;
13286 end;
13287 
13288 procedure TQtListWidget.signalItemTextChanged(ANewText: PWideString); cdecl;
13289 var
13290   Msg: TLMessage;
13291 begin
13292   {$ifdef VerboseQt}
13293     WriteLn('TQtListWidget.signalItemTextChanged');
13294   {$endif}
13295   FillChar(Msg{%H-}, SizeOf(Msg), #0);
13296   Msg.Msg := CM_TEXTCHANGED;
13297   DeliverMessage(Msg);
13298 end;
13299 
13300 procedure TQtListWidget.signalItemClicked(item: QListWidgetItemH); cdecl;
13301 var
13302   Msg: TLMessage;
13303   ItemRow: Integer;
13304   MsgN: TLMNotify;
13305   NMLV: TNMListView;
13306   R: TRect;
13307   Pt: TPoint;
13308 begin
13309   {$ifdef VerboseQt}
13310     WriteLn('TQtListWidget.signalItemClicked');
13311   {$endif}
13312   if (ViewStyle >= 0) and (FChildOfComplexWidget <> ccwComboBox) then
13313   begin
13314     FillChar(MsgN{%H-}, SizeOf(MsgN), #0);
13315     FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
13316 
13317     MsgN.Msg := LM_CLICKED;
13318 
13319     NMLV.hdr.hwndfrom := LCLObject.Handle;
13320     NMLV.hdr.code := NM_CLICK;
13321 
13322     NMLV.iItem := getRow(Item);
13323 
13324     NMLV.iSubItem := 0;
13325     NMLV.uNewState := UINT(NM_CLICK);
13326     NMLV.uChanged :=  LVIS_SELECTED;
13327 
13328     QListWidget_visualItemRect(QListWidgetH(Widget), @R, Item);
13329 
13330     pt.X := R.Left;
13331     pt.Y := R.Top;
13332 
13333     NMLV.ptAction := pt;
13334 
13335     MsgN.NMHdr := @NMLV.hdr;
13336 
13337     DeliverMessage(MsgN);
13338   end;
13339 
13340   if Checkable then
13341   begin
13342     FillChar(Msg{%H-}, SizeOf(Msg), #0);
13343     Msg.Msg := LM_CHANGED;
13344     ItemRow := QListWidget_row(QListWidgetH(Widget), Item);
13345     Msg.WParam := ItemRow;
13346     DeliverMessage(Msg);
13347   end;
13348 
13349 end;
13350 
13351 procedure TQtListWidget.ItemDelegatePaint(painter: QPainterH;
13352   option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
13353 var
13354   Msg: TLMDrawListItem;
13355   DrawStruct: TDrawListItemStruct;
13356   State: QStyleState;
13357   R: TRect;
13358   ItemIndex, SubItemIndex: Integer;
13359   ACustomState: TCustomDrawState;
13360   ATarget: TCustomDrawTarget;
13361   TmpDC1, TmpDC2: HDC;
13362   SkipDefault: Boolean;
13363   Item: QListWidgetItemH;
13364   APaintResult: TCustomDrawResult;
13365 begin
13366   if (ViewStyle >= 0) and not (FChildOfComplexWidget = ccwComboBox) then
13367   begin
13368     State := QStyleOption_state(option);
13369     ACustomState := [cdsDefault];
13370     (*
13371     cdsSelected,
13372     cdsGrayed,
13373     cdsDisabled,
13374     cdsChecked,
13375     cdsFocused,
13376     cdsDefault,
13377     cdsHot,
13378     cdsMarked,
13379     cdsIndeterminate
13380     *)
13381 
13382     if (State and QStyleState_Selected) <> 0 then
13383       Include(ACustomState, cdsSelected);
13384     // disabled
13385     if (State and QStyleState_Enabled) = 0 then
13386       Include(ACustomState, cdsDisabled);
13387     // focused (QStyleState_FocusAtBorder?)
13388     if (State and QStyleState_HasFocus) <> 0 then
13389       Include(ACustomState, cdsFocused);
13390     // hotlight
13391     if (State and QStyleState_MouseOver) <> 0 then
13392       Include(ACustomState, cdsHot);
13393 
13394     ItemIndex := QModelIndex_row(index);
13395     SubItemIndex := QModelIndex_column(index);
13396 
13397     // checked does not work under qt for some reason ?!?
13398     if Checkable then
13399     begin
13400       // if (State and QStyleState_On <> 0) then
13401       //  Include(ACustomState, cdsChecked);
13402       Item := getItem(ItemIndex);
13403       if Assigned(Item) and (QListWidgetItem_checkState(Item) = QtChecked) then
13404         Include(ACustomState, cdsChecked);
13405     end;
13406 
13407     QStyle_drawControl(QApplication_style, QStyleCE_ItemViewItem, Option, painter, viewportWidget);
13408 
13409     // NOW WE ARE DRAWING ITEMS ...
13410     QPainter_save(painter);
13411     if TCustomListView(LCLObject).Canvas.HandleAllocated then
13412       TmpDC2 := TCustomListView(LCLObject).Canvas.GetUpdatedHandle([csHandleValid])
13413     else
13414       TmpDC2 := 0;
13415     TmpDC1 := HDC(TQtDeviceContext.CreateFromPainter(painter));
13416     TCustomListView(LCLObject).Canvas.Handle := TmpDC1;
13417     try
13418       R := visualRect(index);
13419 
13420       if SubItemIndex <= 0 then
13421         ATarget := dtItem
13422       else
13423         ATarget := dtSubItem;
13424 
13425       // here we do only OnCustomDrawItem and OnCustomDrawSubItem
13426       // OnCustomDraw is done inside itemViewportEventFilter.
13427 
13428       APaintResult := TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPrePaint, ItemIndex, SubItemIndex, ACustomState, @R);
13429       SkipDefault := cdrSkipDefault in APaintResult;
13430 
13431       if not SkipDefault then // do default paint by unknown magic
13432         QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
13433 
13434       // issue #27315
13435       if cdrNotifyPostpaint in APaintResult then
13436         TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPostPaint, ItemIndex, SubItemIndex, ACustomState, @R);
13437 
13438     finally
13439       TCustomListView(LCLObject).Canvas.Handle := TmpDC2;
13440       TQtDeviceContext(TmpDC1).Free;
13441       QPainter_restore(painter);
13442     end;
13443   end else
13444   begin
13445     QPainter_save(painter);
13446     State := QStyleOption_state(option);
13447     DrawStruct.ItemID := UINT(QModelIndex_row(index));
13448 
13449     DrawStruct.Area := visualRect(index);
13450     DrawStruct.DC := HDC(TQtDeviceContext.CreateFromPainter(painter));
13451 
13452     DrawStruct.ItemState := [];
13453     // selected
13454     if (State and QStyleState_Selected) <> 0 then
13455       Include(DrawStruct.ItemState, odSelected);
13456     // disabled
13457     if (State and QStyleState_Enabled) = 0 then
13458       Include(DrawStruct.ItemState, odDisabled);
13459     // focused (QStyleState_FocusAtBorder?)
13460     if (State and QStyleState_HasFocus) <> 0 then
13461       Include(DrawStruct.ItemState, odFocused);
13462     // hotlight
13463     if (State and QStyleState_MouseOver) <> 0 then
13464       Include(DrawStruct.ItemState, odHotLight);
13465     // checked
13466     if Checkable then
13467     begin
13468       // if (State and QStyleState_On <> 0) then
13469       //  Include(ACustomState, cdsChecked);
13470       Item := getItem(QModelIndex_row(index));
13471       if Assigned(Item) and (QListWidgetItem_checkState(Item) = QtChecked) then
13472         Include(DrawStruct.ItemState, odChecked);
13473     end;
13474 
13475     { todo: over states:
13476 
13477       odGrayed, odChecked,
13478       odDefault, odInactive, odNoAccel,
13479       odNoFocusRect, odReserved1, odReserved2, odComboBoxEdit
13480     }
13481     Msg.Msg := LM_DRAWLISTITEM;
13482     Msg.DrawListItemStruct := @DrawStruct;
13483     DeliverMessage(Msg);
13484 
13485     QPainter_restore(painter);
13486 
13487     TQtDeviceContext(DrawStruct.DC).Free;
13488   end;
13489 end;
13490 
13491 procedure TQtListWidget.clearSelection;
13492 begin
13493   inherited clearSelection;
13494   SetLength(FSavedSelection, 0);
13495 end;
13496 
13497 procedure TQtListWidget.ClearItems;
13498 begin
13499   SetLength(FSavedSelection, 0);
13500   QListWidget_clear(QListWidgetH(Widget));
13501 end;
13502 
13503 {------------------------------------------------------------------------------
13504   Function: TQtListWidget.currentRow
13505   Params:  None
13506   Returns: Nothing
13507  ------------------------------------------------------------------------------}
currentRownull13508 function TQtListWidget.currentRow: Integer;
13509 begin
13510   Result := QListWidget_currentRow(QListWidgetH(Widget));
13511 end;
13512 
currentItemnull13513 function TQtListWidget.currentItem: QListWidgetItemH;
13514 begin
13515   Result := QListWidget_currentItem(QListWidgetH(Widget));
13516 end;
13517 
IndexAtnull13518 function TQtListWidget.IndexAt(APoint: PQtPoint): Integer;
13519 var
13520   AModelIndex: QModelIndexH;
13521 begin
13522   AModelIndex := QModelIndex_create();
13523   QListView_indexAt(QListWidgetH(Widget), AModelIndex, APoint);
13524   Result := QModelIndex_row(AModelIndex);
13525   QModelIndex_destroy(AModelIndex);
13526 end;
13527 
13528 procedure TQtListWidget.insertItem(AIndex: Integer; AText: String);
13529 var
13530   Str: WideString;
13531 begin
13532   Str := GetUtf8String(AText);
13533   insertItem(AIndex, @Str);
13534 end;
13535 
13536 procedure TQtListWidget.insertItem(AIndex: Integer; AText: PWideString);
13537 var
13538   Item: QListWidgetItemH;
13539 begin
13540   Item := QListWidgetItem_create(AText, nil, Ord(QListWidgetItemType));
13541   if Checkable then
13542     QListWidgetItem_setCheckState(Item, QtUnChecked)
13543   else
13544   if (ViewStyle = Ord(vsIcon)) and not (FChildOfComplexWidget = ccwComboBox) then
13545     QListWidgetItem_setTextAlignment(Item, QtAlignHCenter);
13546   QListWidget_insertItem(QListWidgetH(Widget), AIndex, Item);
13547 end;
13548 
itemAtnull13549 function TQtListWidget.itemAt(APoint: TPoint): QListWidgetItemH;
13550 begin
13551   Result := ItemAt(APoint.X, APoint.Y);
13552 end;
13553 
itemAtnull13554 function TQtListWidget.itemAt(x: Integer; y: Integer): QListWidgetItemH;
13555 begin
13556   Result := QListWidget_itemAt(QListWidgetH(Widget), x, y);
13557 end;
13558 
getItemnull13559 function TQtListWidget.getItem(AIndex: Integer): QListWidgetItemH;
13560 begin
13561   if (AIndex >= 0) and (AIndex < rowCount) then
13562     Result := QListWidget_item(QListWidgetH(Widget), AIndex)
13563   else
13564     Result := nil;
13565 end;
13566 
getItemSelectednull13567 function TQtListWidget.getItemSelected(AItem: QListWidgetItemH): Boolean;
13568 begin
13569   if AItem <> nil then
13570     Result := QListWidget_isItemSelected(QListWidgetH(Widget), AItem)
13571   else
13572     Result := False;
13573 end;
13574 
getItemVisiblenull13575 function TQtListWidget.getItemVisible(AItem: QListWidgetItemH): Boolean;
13576 begin
13577   if AItem = nil then
13578     Result := False
13579   else
13580     Result := not QListWidget_isItemHidden(QListWidgetH(Widget), AItem);
13581 end;
13582 
getRownull13583 function TQtListWidget.getRow(AItem: QListWidgetItemH): integer;
13584 begin
13585   if AItem = nil then
13586     Result := -1
13587   else
13588     Result := QListWidget_row(QListWidgetH(Widget), AItem);
13589 end;
13590 
getSelCountnull13591 function TQtListWidget.getSelCount: Integer;
13592 begin
13593   Result := length(selectedItems);
13594 end;
13595 
getTopItemnull13596 function TQtListWidget.getTopItem: integer;
13597 begin
13598   Result := getVisibleRowCount(True);
13599 end;
13600 
13601 {------------------------------------------------------------------------------
13602   Function: TQtListWidget.getVisibleRowCount
13603   Params:  Boolean
13604   Returns: if AFirstVisibleOnly = False (default) then it returns number
13605   of visible rows, or 0 if there's no visible rows.
13606   When AFirstVisibleOnly = True then it returns index of first visible row,
13607   otherwise result is -1.
13608  ------------------------------------------------------------------------------}
getVisibleRowCountnull13609 function TQtListWidget.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
13610 var
13611   R: TRect;
13612   i: integer;
13613   item: QListWidgetItemH;
13614   RowIndex: integer;
13615   RowHeight: integer;
13616 begin
13617   if AFirstVisibleOnly then
13618     Result := -1
13619   else
13620     Result := 0;
13621   QWidget_contentsRect(viewportWidget, @R);
13622   i := 0;
13623   repeat
13624     item := itemAt(0, i);
13625     if item <> nil then
13626     begin
13627       RowIndex := getRow(Item);
13628       if AFirstVisibleOnly then
13629       begin
13630         Result := RowIndex;
13631         break;
13632       end;
13633       RowHeight := getRowHeight(RowIndex);
13634       inc(Result);
13635       if RowHeight <= 0 then
13636         RowHeight := 1;
13637       inc(i, RowHeight);
13638     end else
13639       inc(i, 1);
13640   until i >= R.Bottom;
13641 end;
13642 
getVisualItemRectnull13643 function TQtListWidget.getVisualItemRect(AItem: QListWidgetItemH): TRect;
13644 begin
13645   Result := Rect(0, 0, 0, 0);
13646   if AItem <> nil then
13647     QListWidget_visualItemRect(QListWidgetH(Widget), @Result, AItem);
13648 end;
13649 
TQtListWidget.selectedItemsnull13650 function TQtListWidget.selectedItems: TPtrIntArray;
13651 begin
13652   QListWidget_selectedItems(QListWidgetH(Widget), @Result);
13653 end;
13654 
13655 {------------------------------------------------------------------------------
13656   Function: TQtListWidget.setCurrentRow
13657   Params:  None
13658   Returns: Nothing
13659  ------------------------------------------------------------------------------}
13660 procedure TQtListWidget.setCurrentRow(row: Integer);
13661 begin
13662   if (getSelectionMode <> QAbstractItemViewSingleSelection) and (row < 0) then
13663     row := 0;
13664 
13665   if currentRow <> row then
13666   begin
13667     FDontPassSelChange := True;
13668     QListWidget_setCurrentRow(QListWidgetH(Widget), row);
13669   end;
13670 end;
13671 
13672 procedure TQtListWidget.setCurrentItem(AItem: QListWidgetItemH;
13673   const AIsSet: Boolean = True);
13674 begin
13675   if AIsSet then
13676     QListWidget_setCurrentItem(QListWidgetH(Widget), AItem);
13677 end;
13678 
13679 procedure TQtListWidget.setItemText(AIndex: Integer; AText: String);
13680 var
13681   Item: QListWidgetItemH;
13682   Str: WideString;
13683   R: TRect;
13684 begin
13685   Str := GetUTF8String(AText);
13686   if (AIndex >= 0) and (AIndex < rowCount) then
13687   begin
13688     Item := getItem(AIndex);
13689     QListWidgetItem_setText(Item, @Str);
13690     {we must update our custom delegate}
13691     if OwnerDrawn then
13692     begin
13693       R := getVisualItemRect(Item);
13694       Update(@R);
13695     end;
13696   end else
13697     insertItem(AIndex, @Str);
13698 end;
13699 
13700 procedure TQtListWidget.setItemText(AIndex: Integer; AText: String;
13701   AAlignment: Integer);
13702 var
13703   Item: QListWidgetItemH;
13704   Str: WideString;
13705   R: TRect;
13706 begin
13707   Str := GetUTF8String(AText);
13708   if (AIndex >= 0) and (AIndex < rowCount) then
13709   begin
13710     Item := getItem(AIndex);
13711     QListWidgetItem_setText(Item, @Str);
13712     QListWidgetItem_setTextAlignment(Item, AAlignment);
13713     {we must update our custom delegate}
13714     if OwnerDrawn then
13715     begin
13716       R := getVisualItemRect(Item);
13717       Update(@R);
13718     end;
13719   end else
13720     insertItem(AIndex, @Str);
13721 end;
13722 
13723 procedure TQtListWidget.setItemSelected(AItem: QListWidgetItemH;
13724   const ASelect: Boolean);
13725 begin
13726   if AItem <> nil then
13727     QListWidget_setItemSelected(QListWidgetH(Widget), AItem, ASelect);
13728 end;
13729 
13730 procedure TQtListWidget.setItemVisible(AItem: QListWidgetItemH;
13731   const AVisible: Boolean);
13732 begin
13733   if AItem <> nil then
13734     QListWidget_setItemHidden(QListWidgetH(Widget), AItem, not AVisible);
13735 end;
13736 
13737 procedure TQtListWidget.setSelectionMode(AMode: QAbstractItemViewSelectionMode);
13738 var
13739   SavedItem: QListWidgetItemH;
13740   Arr: TPtrIntArray;
13741   i: Integer;
13742 begin
13743   SavedItem := nil;
13744   // this code is here due to Qt bug with QListView/QListWidget ..
13745   // QTreeWidget works correct .. clearSelection does not trigger signals
13746   // so we must do that manually.
13747   if (ViewStyle > 0) and (AMode < QAbstractItemViewMultiSelection) and
13748     (getSelectionMode > QAbstractItemViewSingleSelection) then
13749   begin
13750     SavedItem := CurrentItem;
13751     Arr := selectedItems;
13752     if not ((SavedItem <> nil) and (QListWidgetItem_isSelected(SavedItem))) then
13753     begin
13754       SavedItem := nil;
13755       if length(Arr) > 0 then
13756         SavedItem := QListWidgetItemH(Arr[0]);
13757     end;
13758     for i := 0 to High(Arr) do
13759     begin
13760       if QListWidgetItemH(Arr[i]) <> SavedItem then
13761       begin
13762         QListWidgetItem_setSelected(QListWidgetItemH(Arr[i]), False);
13763         signalCurrentItemChanged(nil, QListWidgetItemH(Arr[i]));
13764       end;
13765     end;
13766     clearSelection;
13767   end;
13768   inherited setSelectionMode(AMode);
13769   if SavedItem <> nil then
13770     setItemSelected(SavedItem, True);
13771 end;
13772 
13773 procedure TQtListWidget.scrollToItem(row: integer;
13774   hint: QAbstractItemViewScrollHint);
13775 var
13776   Item: QListWidgetItemH;
13777 begin
13778   Item := getItem(Row);
13779   QListWidget_scrollToItem(QListWidgetH(Widget), Item, hint);
13780 end;
13781 
13782 procedure TQtListWidget.removeItem(AIndex: Integer);
13783 var
13784   Item: QListWidgetItemH;
13785 begin
13786   if (currentRow = AIndex) then
13787     if (getSelectionMode = QAbstractItemViewSingleSelection) then
13788       setCurrentRow(-1);
13789   Item := QListWidget_takeitem(QListWidgetH(Widget), AIndex);
13790   if FDelayedCheckItem = Item then
13791     FDelayedCheckItem := nil;
13792   QListWidgetItem_destroy(Item);
13793 end;
13794 
TQtListWidget.rowCountnull13795 function TQtListWidget.rowCount: integer;
13796 begin
13797   Result := QListWidget_count(QListWidgetH(Widget));
13798 end;
13799 
13800 procedure TQtListWidget.ExchangeItems(const AIndex1, AIndex2: Integer);
13801 var
13802   ItemTo, ItemFrom: QListWidgetItemH;
13803   R: TRect;
13804 begin
13805   if AIndex1 = AIndex2 then
13806     exit;
13807 
13808   if AIndex1 < AIndex2 then
13809   begin
13810     ItemTo := QListWidget_takeItem(QListWidgetH(Widget), AIndex2);
13811     ItemFrom := QListWidget_takeItem(QListWidgetH(Widget), AIndex1);
13812     QListWidget_insertItem(QListWidgetH(Widget), AIndex1, ItemTo);
13813     QListWidget_insertItem(QListWidgetH(Widget), AIndex2, ItemFrom);
13814   end else
13815   begin
13816     ItemFrom := QListWidget_takeItem(QListWidgetH(Widget), AIndex1);
13817     ItemTo := QListWidget_takeItem(QListWidgetH(Widget), AIndex2);
13818     QListWidget_insertItem(QListWidgetH(Widget), AIndex2, ItemFrom);
13819     QListWidget_insertItem(QListWidgetH(Widget), AIndex1, ItemTo);
13820   end;
13821 
13822   if OwnerDrawn then
13823   begin
13824     R := getVisualItemRect(ItemTo);
13825     Update(@R);
13826     R := getVisualItemRect(ItemFrom);
13827     Update(@R);
13828   end;
13829 end;
13830 
13831 procedure TQtListWidget.MoveItem(const AFromIndex, AToIndex: Integer);
13832 var
13833   Item: QListWidgetItemH;
13834   R: TRect;
13835 begin
13836   Item := QListWidget_takeItem(QListWidgetH(Widget), AFromIndex);
13837   QListWidget_insertItem(QListWidgetH(Widget), AToIndex, Item);
13838   if OwnerDrawn then
13839   begin
13840     R := getVisualItemRect(Item);
13841     Update(@R);
13842   end;
13843 end;
13844 
13845 { TQtCheckListBox }
13846 
CreateWidgetnull13847 function TQtCheckListBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
13848 var
13849   Parent: QWidgetH;
13850 begin
13851   FCheckBoxClicked := False;
13852   FDelayedCheckItem := nil;
13853   FSavedEvent := nil;
13854   FSavedEventTimer := nil;
13855   FSavedEventTimerHook := nil;
13856 
13857   FViewStyle := -1;
13858   FSyncingItems := False;
13859   FDontPassSelChange := False;
13860   FOwnerData := False;
13861 
13862   FCheckable := True;
13863   if AParams.WndParent <> 0 then
13864     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
13865   else
13866     Parent := nil;
13867   Result := QListWidget_create(Parent);
13868 end;
13869 
13870 procedure TQtCheckListBox.SetNextStateMap(AItem: QListWidgetItemH);
13871 var
13872   ACurrState: QtCheckState;
13873 begin
13874   inherited SetNextStateMap(AItem);
13875   if (AItem = nil) or not AllowGrayed then
13876     exit;
13877   ACurrState := GetItemLastCheckState(AItem);
13878 
13879   case ACurrState of
13880     QtUnchecked: ItemCheckState[GetRow(AItem)] := QtPartiallyChecked;
13881     QtPartiallyChecked: ItemCheckState[GetRow(AItem)] := QtChecked;
13882     QtChecked: ItemCheckState[GetRow(AItem)] := QtUnChecked;
13883   end;
13884 end;
13885 
13886 procedure TQtCheckListBox.AttachEvents;
13887 begin
13888   inherited AttachEvents;
13889   FItemChangedHook := QListWidget_hook_create(Widget);
13890   QListWidget_hook_hook_itemChanged(FItemChangedHook, @signalItemChanged);
13891 end;
13892 
13893 procedure TQtCheckListBox.DetachEvents;
13894 begin
13895   if FItemChangedHook <> nil then
13896   begin
13897     QListWidget_hook_destroy(FItemChangedHook);
13898     FItemChangedHook := nil;
13899   end;
13900   inherited DetachEvents;
13901 end;
13902 
TQtCheckListBox.EventFilternull13903 function TQtCheckListBox.EventFilter(Sender: QObjectH; Event: QEventH
13904   ): Boolean; cdecl;
13905 begin
13906   Result := False;
13907   if (QEvent_type(Event) = QEventKeyPress) and
13908      ((QKeyEvent_key(QKeyEventH(Event)) = QtKey_Up) or
13909      (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Down)) then
13910   begin
13911     {issue #31697}
13912     Result:=inherited EventFilter(Sender, Event);
13913     if ItemCount > 0 then
13914     begin
13915       if (getSelCount = 0) then
13916       begin
13917         Selected[0] := True;
13918         Result := True;
13919       end;
13920       inherited signalSelectionChanged();
13921     end;
13922   end else
13923   if (QEvent_type(Event) = QEventMouseButtonDblClick) then
13924     // issue #25089
13925   else
13926     Result:=inherited EventFilter(Sender, Event);
13927 end;
13928 
TQtCheckListBox.itemViewViewportEventFilternull13929 function TQtCheckListBox.itemViewViewportEventFilter(Sender: QObjectH;
13930   Event: QEventH): Boolean; cdecl;
13931 var
13932   MousePos: TQtPoint;
13933   Item: QListWidgetItemH;
13934   x: Integer;
13935 begin
13936   Result := False;
13937   QEvent_accept(Event);
13938   if (LCLObject <> nil) then
13939   begin
13940     case QEvent_type(Event) of
13941       QEventMouseButtonRelease,
13942       QEventMouseButtonPress,
13943       QEventMouseButtonDblClick:
13944         begin
13945           // issue #21318
13946           // MousePos :=
13947           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
13948           Item := itemAt(MousePos.x, MousePos.y);
13949           if QEvent_Type(Event) = QEventMouseButtonDblClick then
13950           begin
13951             SlotMouse(Widget, Event);
13952             QEvent_ignore(Event);
13953             // qt capture locks for some reason under qt-4.7.4 ?!?
13954             // when we dbl click on viewport without checkable items
13955             if (Item = nil) and (Sender = QWidget_mouseGrabber) then
13956               QWidget_releaseMouse(QWidgetH(Sender));
13957           end else
13958           begin
13959             Result := SlotMouse(Sender, Event);
13960             if (Item <> nil) and (OwnerDrawn) and
13961               (QEvent_type(Event) = QEventMouseButtonRelease) and
13962               ((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
13963             begin
13964               x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
13965               if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
13966               begin
13967                 if QListWidgetItem_checkState(Item) = QtUnchecked then
13968                   QListWidgetItem_setCheckState(Item, QtChecked)
13969                 else
13970                   QListWidgetItem_setCheckState(Item, QtUnChecked);
13971               end;
13972             end;
13973           end;
13974 
13975           if (QEvent_Type(Event) = QEventMouseButtonPress) then
13976           begin
13977             // change current row , this works fine with qt < 4.8
13978             if Assigned(Item) and
13979               ((currentItem <> Item) or not QListWidgetItem_isSelected(Item)) then
13980             begin
13981               // DebugLn('TQtCheckListBox forced item change');
13982               {issue #31697}
13983               QListWidget_setCurrentItem(QListWidgetH(Widget), Item, QItemSelectionModelSelectCurrent);
13984               inherited signalSelectionChanged();
13985             end;
13986           end;
13987         end;
13988       else
13989       begin
13990         {do not change selection if mousepressed and mouse moved}
13991         Result := (QEvent_type(Event) = QEventMouseMove) and
13992           hasFocus and (QGUIApplication_mouseButtons() > 0);
13993          QEvent_ignore(Event);
13994       end;
13995     end;
13996   end;
13997 end;
13998 
13999 procedure TQtCheckListBox.signalCurrentItemChanged(current: QListWidgetItemH;
14000   previous: QListWidgetItemH); cdecl;
14001 begin
14002   // Do nothing
14003   // inherited signalCurrentItemChanged(current, previous);
14004 end;
14005 
14006 procedure TQtCheckListBox.signalItemClicked(item: QListWidgetItemH); cdecl;
14007 begin
14008 
14009   if InUpdate or not GetVisible then
14010     exit;
14011   {$note seem that we have qtbug with tristate listwidget items, so
14012    we must handle statemap somehow}
14013 
14014   //TODO try to fix nextstatemap
14015   if FCheckBoxClicked then
14016   begin
14017     FCheckBoxClicked := False;
14018     SetNextStateMap(item);
14019   end;
14020 end;
14021 
14022 procedure TQtCheckListBox.signalSelectionChanged(); cdecl;
14023 begin
14024   // DO NOTHING
14025   // inherited signalSelectionChanged;
14026 end;
14027 
14028 procedure TQtCheckListBox.signalItemChanged(item: QListWidgetItemH); cdecl;
14029 var
14030   Msg: TLMessage;
14031 begin
14032   if InUpdate or not GetVisible then
14033     exit;
14034   FillChar(Msg{%H-}, SizeOf(Msg), #0);
14035   Msg.Msg := LM_CHANGED;
14036   Msg.WParam := PtrInt(QListWidget_row(QListWidgetH(Widget), Item));
14037   DeliverMessage(Msg);
14038 end;
14039 
TQtCheckListBox.GetItemCheckStatenull14040 function TQtCheckListBox.GetItemCheckState(AIndex: Integer): QtCheckState;
14041 var
14042   AItem: QListWidgetItemH;
14043 begin
14044   Result := QtUnChecked;
14045   if (AIndex >= 0) and (AIndex < rowCount) then
14046   begin
14047     AItem := QListWidget_item(QListWidgetH(Widget), AIndex);
14048     if AItem <> nil then
14049       Result := QListWidgetItem_checkState(AItem);
14050   end;
14051 end;
14052 
14053 procedure TQtCheckListBox.SetItemCheckState(AIndex: Integer;
14054   AValue: QtCheckState);
14055 var
14056   AItem: QListWidgetItemH;
14057 begin
14058   if (AIndex >= 0) and (AIndex < rowCount) then
14059   begin
14060     AItem := QListWidget_item(QListWidgetH(Widget), AIndex);
14061     if AItem <> nil then
14062     begin
14063       QListWidgetItem_setCheckState(AItem, AValue);
14064       SetItemLastCheckState(AItem);
14065     end;
14066   end;
14067 end;
14068 
14069 { TQtHeaderView }
14070 
TQtHeaderView.getClickablenull14071 function TQtHeaderView.getClickable: Boolean;
14072 begin
14073   // QHeaderView_sectionsClickable();
14074   Result := QHeaderView_sectionsClickable(QHeaderViewH(Widget));
14075 end;
14076 
getMinSectionSizenull14077 function TQtHeaderView.getMinSectionSize: Integer;
14078 begin
14079   Result := QHeaderView_minimumSectionSize(QHeaderViewH(Widget));
14080 end;
14081 
TQtHeaderView.SortIndicatorOrdernull14082 function TQtHeaderView.SortIndicatorOrder: QtSortOrder;
14083 begin
14084   Result := QHeaderView_sortIndicatorOrder(QHeaderViewH(Widget));
14085 end;
14086 
14087 procedure TQtHeaderView.setClickable(const AValue: Boolean);
14088 begin
14089   QHeaderView_setSectionsClickable(QHeaderViewH(Widget), AValue);
14090   // QHeaderView_setClickable(QHeaderViewH(Widget), AValue);
14091 end;
14092 
14093 procedure TQtHeaderView.setMinSectionSize(const AValue: Integer);
14094 begin
14095   QHeaderView_setMinimumSectionSize(QHeaderViewH(Widget), AValue);
14096 end;
14097 
14098 procedure TQtHeaderView.SetSortIndicator(const AColumn: Integer;
14099   const AOrder: QtSortOrder);
14100 begin
14101   QHeaderView_setSortIndicator(QHeaderViewH(Widget), AColumn, AOrder);
14102 end;
14103 
14104 procedure TQtHeaderView.SetSortIndicatorVisible(AVisible: Boolean);
14105 begin
14106   QHeaderView_setSortIndicatorShown(QHeaderViewH(Widget), AVisible);
14107 end;
14108 
14109 {------------------------------------------------------------------------------
14110   Function: TQtHeaderView.CreateWidget
14111   Params:  None
14112   Returns: Widget (QHeaderViewH)
14113  ------------------------------------------------------------------------------}
CreateWidgetnull14114 function TQtHeaderView.CreateWidget(const AParams: TCreateParams):QWidgetH;
14115 var
14116   Parent: QWidgetH;
14117 begin
14118   // Creates the widget
14119   {$ifdef VerboseQt}
14120     WriteLn('TQtHeaderView.Create');
14121   {$endif}
14122   if AParams.WndParent <> 0 then
14123     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
14124   else
14125     Parent := nil;
14126 
14127   Result := QHeaderView_create(QtHorizontal, Parent);
14128 end;
14129 
14130 procedure TQtHeaderView.AttachEvents;
14131 begin
14132   inherited AttachEvents;
14133   FSectionClicked := QHeaderView_hook_create(Widget);
14134   QHeaderView_hook_hook_sectionClicked(FSectionClicked, @SignalSectionClicked);
14135 end;
14136 
14137 procedure TQtHeaderView.DetachEvents;
14138 begin
14139   if FSectionClicked <> nil then
14140   begin
14141     QHeaderView_hook_destroy(FSectionClicked);
14142     FSectionClicked := nil;
14143   end;
14144   inherited DetachEvents;
14145 end;
14146 
TQtHeaderView.EventFilternull14147 function TQtHeaderView.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
14148   cdecl;
14149 begin
14150   Result := False;
14151   QEvent_accept(Event);
14152   if (FOwner <> nil) and (LCLObject <> nil) then
14153   begin
14154     if (FChildOfComplexWidget = ccwTreeWidget) and
14155       (QEvent_type(Event) = QEventFocusIn) then
14156     begin
14157       Result := True;
14158       QEvent_ignore(Event);
14159       QWidget_setFocus(FOwner.Widget);
14160     end;
14161   end;
14162 end;
14163 
itemViewViewportEventFilternull14164 function TQtHeaderView.itemViewViewportEventFilter(Sender: QObjectH;
14165   Event: QEventH): Boolean; cdecl;
14166 begin
14167   Result := False;
14168   QEvent_accept(Event);
14169   case QEvent_type(Event) of
14170     QEventMouseButtonPress,
14171     QEventMouseButtonRelease,
14172     QEventMouseButtonDblClick: ; {do nothing here - signal is fired}
14173     else
14174       Result := inherited itemViewViewportEventFilter(Sender, Event);
14175   end;
14176 end;
14177 
14178 {------------------------------------------------------------------------------
14179   Function: TQtHeaderView.SignalSectionClicked
14180   Params:  None
14181   Returns: Nothing
14182  ------------------------------------------------------------------------------}
14183 procedure TQtHeaderView.SignalSectionClicked(logicalIndex: Integer); cdecl;
14184 var
14185   Msg: TLMNotify;
14186   NMLV: TNMListView;
14187 begin
14188   {$ifdef VerboseQt}
14189   writeln('TQtHeaderView.signalSectionClicked index ',logicalIndex);
14190   {$endif}
14191 
14192   FillChar(Msg{%H-}, SizeOf(Msg), #0);
14193   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
14194 
14195   Msg.Msg := CN_NOTIFY;
14196   NMLV.hdr.hwndfrom := LCLObject.Handle;
14197   NMLV.hdr.code := LVN_COLUMNCLICK;
14198   NMLV.iItem := -1;
14199   NMLV.iSubItem := logicalIndex;
14200 
14201   Msg.NMHdr := @NMLV.hdr;
14202 
14203   DeliverMessage(Msg);
14204 
14205 end;
14206 
getResizeModenull14207 function TQtHeaderView.getResizeMode(AIndex: Integer): QHeaderViewResizeMode;
14208 begin
14209   Result := QHeaderView_sectionResizeMode(QHeaderViewH(Widget), AIndex);
14210   // Result := QHeaderView_resizeMode(QHeaderViewH(Widget), AIndex);
14211 end;
14212 
14213 procedure TQtHeaderView.setResizeMode(AResizeMode: QHeaderViewResizeMode);
14214 begin
14215   QHeaderView_setSectionResizeMode(QHeaderViewH(Widget), AResizeMode);
14216   // QHeaderView_setResizeMode(QHeaderViewH(Widget), AResizeMode);
14217 end;
14218 
14219 procedure TQtHeaderView.setResizeMode(AIndex: Integer;
14220   AResizeMode: QHeaderViewResizeMode);
14221 begin
14222   QHeaderView_setSectionResizeMode(QHeaderViewH(Widget), AIndex, AResizeMode);
14223   // QHeaderView_setResizeMode(QHeaderViewH(Widget), AIndex, AResizeMode);
14224 end;
14225 
sectionSizenull14226 function TQtHeaderView.sectionSize(AIndex: Integer): Integer;
14227 begin
14228   Result := QHeaderView_sectionSize(QHeaderViewH(Widget), AIndex);
14229 end;
14230 
sectionSizeHintnull14231 function TQtHeaderView.sectionSizeHint(AIndex: Integer): Integer;
14232 begin
14233   Result := QHeaderView_sectionSizeHint(QHeaderViewH(Widget), AIndex);
14234 end;
14235 
14236 procedure TQtHeaderView.moveSection(AFromIndex: Integer; AToIndex: Integer);
14237 begin
14238   QHeaderView_moveSection(QHeaderViewH(Widget), AFromIndex, AToIndex);
14239 end;
14240 
14241 procedure TQtHeaderView.resizeSection(ASection: Integer; ASize: Integer);
14242 begin
14243   QHeaderView_resizeSection(QHeaderViewH(Widget), ASection, ASize);
14244 end;
14245 
14246 procedure TQtHeaderView.setHighlightSections(AValue: Boolean);
14247 begin
14248   QHeaderView_setHighlightSections(QHeaderViewH(Widget), AValue);
14249 end;
14250 
14251 procedure TQtHeaderView.setDefaultSectionSize(AValue: Integer);
14252 begin
14253   QHeaderView_setDefaultSectionSize(QHeaderViewH(Widget), AValue);
14254 end;
14255 
14256 procedure TQtHeaderView.setStretchLastSection(AValue: Boolean);
14257 begin
14258   QHeaderView_setStretchLastSection(QHeaderViewH(Widget), AValue);
14259 end;
14260 
14261   { TQtTreeView }
14262 
getColVisiblenull14263 function TQtTreeView.getColVisible(AIndex: Integer): Boolean;
14264 begin
14265   Result := not QTreeView_isColumnHidden(QTreeViewH(Widget), AIndex);
14266 end;
14267 
getColWidthnull14268 function TQtTreeView.getColWidth(AIndex: Integer): Integer;
14269 begin
14270   Result := QTreeView_columnWidth(QTreeViewH(Widget), AIndex);
14271 end;
14272 
GetUniformRowHeightsnull14273 function TQtTreeView.GetUniformRowHeights: Boolean;
14274 begin
14275   Result := QTreeView_uniformRowHeights(QTreeViewH(Widget));
14276 end;
14277 
14278 procedure TQtTreeView.setColVisible(AIndex: Integer; const AValue: Boolean);
14279 begin
14280   QTreeView_setColumnHidden(QTreeViewH(Widget), AIndex, not AValue);
14281 end;
14282 
14283 procedure TQtTreeView.setColWidth(AIndex: Integer; const AValue: Integer);
14284 begin
14285   QTreeView_setColumnWidth(QTreeViewH(Widget), AIndex, AValue);
14286 end;
14287 
14288 procedure TQtTreeView.SetUniformRowHeights(const AValue: Boolean);
14289 begin
14290   QTreeView_setUniformRowHeights(QTreeViewH(Widget), AValue);
14291 end;
14292 
14293 procedure TQtTreeView.setWordWrap(const AValue: Boolean);
14294 begin
14295   QTreeView_setWordWrap(QTreeViewH(Widget), AValue);
14296 end;
14297 
14298 procedure TQtTreeView.setRootIsDecorated(AValue: Boolean);
14299 begin
14300   QTreeView_setRootIsDecorated(QTreeViewH(Widget), AValue);
14301 end;
14302 
14303 procedure TQtTreeView.setAllColumnsShowFocus(AValue: Boolean);
14304 begin
14305   QTreeView_setAllColumnsShowFocus(QTreeViewH(Widget), AValue);
14306 end;
14307 
14308 {------------------------------------------------------------------------------
14309   Function: TQtTreeView.CreateWidget
14310   Params:  None
14311   Returns: Widget (QTreeViewH)
14312  ------------------------------------------------------------------------------}
TQtTreeView.CreateWidgetnull14313 function TQtTreeView.CreateWidget(const AParams: TCreateParams):QWidgetH;
14314 var
14315   Parent: QWidgetH;
14316 begin
14317   // Creates the widget
14318   {$ifdef VerboseQt}
14319     WriteLn('TQtTreeView.Create');
14320   {$endif}
14321   if AParams.WndParent <> 0 then
14322     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
14323   else
14324     Parent := nil;
14325   Result := QTreeView_create(Parent);
14326 end;
14327 
14328   { TQtTreeWidget }
14329 
14330 {------------------------------------------------------------------------------
14331   Function: TQtTreeWidget.CreateWidget
14332   Params:  None
14333   Returns: Widget (QTreeWidgetH)
14334  ------------------------------------------------------------------------------}
CreateWidgetnull14335 function TQtTreeWidget.CreateWidget(const AParams: TCreateParams):QWidgetH;
14336 var
14337   Parent: QWidgetH;
14338 begin
14339   {$ifdef VerboseQt}
14340     WriteLn('TQtTreeWidget.Create');
14341   {$endif}
14342   FDelayedCheckItem := nil;
14343   AllowGrayed := False;
14344   FSelection := TFPList.Create;
14345   FSavedEvent := nil;
14346   FSavedEventTimer := nil;
14347   FSavedEventTimerHook := nil;
14348   FViewStyle := -1;
14349   FCheckable := False;
14350   FHideSelection := False;
14351   FOwnerData := False;
14352   FSyncingItems := False;
14353   {$IFDEF TEST_QT_SORTING}
14354   FCanSort := False;
14355   FSorting := False;
14356   {$ENDIF}
14357   if AParams.WndParent <> 0 then
14358     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
14359   else
14360     Parent := nil;
14361   Result := QTreeWidget_create(Parent);
14362   FHeader := nil;
14363 end;
14364 
14365 {------------------------------------------------------------------------------
14366   Function: TQtTreeWidget.Destroy
14367   Params:  None
14368   Returns: Nothing
14369  ------------------------------------------------------------------------------}
14370 destructor TQtTreeWidget.Destroy;
14371 begin
14372   {$ifdef VerboseQt}
14373     WriteLn('TQtTreeWidget.Destroy');
14374   {$endif}
14375   FSelection.Free;
14376   if Assigned(FHeader) then
14377     FHeader.Free;
14378 
14379   inherited Destroy;
14380 end;
14381 
14382 procedure TQtTreeWidget.DestroyNotify(AWidget: TQtWidget);
14383 begin
14384   if AWidget = FHeader then
14385     FHeader := nil;
14386   inherited DestroyNotify(AWidget);
14387 end;
14388 
TQtTreeWidget.EventFilternull14389 function TQtTreeWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
14390   cdecl;
14391 var
14392   item: QTreeWidgetItemH;
14393 begin
14394   Result := False;
14395   QEvent_accept(Event);
14396   if LCLObject = nil then
14397     exit;
14398   if QEvent_Type(Event) = QEventResize then
14399     // let the viewport send resize
14400   else
14401   if Checkable then
14402   begin
14403     if (QEvent_type(Event) = QEventKeyPress) and
14404       (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
14405       (QKeyEvent_modifiers(QKeyEventH(Event)) and QtControlModifier = 0) then
14406     begin
14407       Result:=inherited EventFilter(Sender, Event);
14408       if not Result then
14409       begin
14410         Item := currentItem;
14411         if Item <> nil then
14412         begin
14413           Item := topLevelItem(getRow(Item));
14414           if (Item <> nil) and
14415             ((QTreeWidget_currentColumn(QTreeWidgetH(Widget)) = 0) or
14416             TCustomListView(LCLObject).RowSelect) then
14417           HandleCheckChangedEvent(QtPoint(0, 0), Item, Event);
14418           if OwnerDrawn then
14419           begin
14420             if QTreeWidgetItem_checkState(Item, 0) = QtUnChecked then
14421               QTreeWidgetItem_setCheckState(Item, 0, QtChecked)
14422             else
14423               QTreeWidgetItem_setCheckState(Item, 0, QtUnchecked);
14424           end;
14425         end;
14426       end else
14427         QEvent_ignore(Event);
14428     end else
14429       Result:=inherited EventFilter(Sender, Event);
14430   end else
14431   if ((QEvent_type(Event) = QEventMouseButtonPress) or
14432     (QEvent_type(Event) = QEventMouseButtonRelease))
14433     and (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
14434     {eat mouse button events -> signalItemClicked is fired}
14435   else
14436     Result:=inherited EventFilter(Sender, Event);
14437 end;
14438 
14439 procedure TQtTreeWidget.SetItemLastCheckStateInternal(AItem: QTreeWidgetItemH;
14440   AState: QtCheckState);
14441 var
14442   v: QVariantH;
14443 begin
14444   v := QVariant_create(Ord(AState));
14445   QTreeWidgetItem_setData(AItem, 0, QtCheckStateRole, v);
14446   QVariant_destroy(v);
14447 end;
14448 
14449 procedure TQtTreeWidget.HandleCheckChangedEvent(const AMousePos: TQtPoint;
14450   AItem: QTreeWidgetItemH; AEvent: QEventH);
14451 var
14452   xx: Integer;
14453   B: Boolean;
14454   R: TRect;
14455 
14456   procedure SendMessage(AnItem: QTreeWidgetItemH);
14457   var
14458     Msg: TLMNotify;
14459     NMLV: TNMListView;
14460   begin
14461 
14462     FillChar(Msg{%H-}, SizeOf(Msg), #0);
14463     FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
14464 
14465     Msg.Msg := CN_NOTIFY;
14466 
14467     NMLV.hdr.hwndfrom := LCLObject.Handle;
14468     NMLV.hdr.code := LVN_ITEMCHANGED;
14469 
14470 
14471     NMLV.iItem := GetRow(AnItem);
14472 
14473     NMLV.uOldState := UINT(Ord(not B));
14474     NMLV.uNewState := UINT(Ord(B));
14475     NMLV.uChanged := LVIF_STATE;
14476 
14477     Msg.NMHdr := @NMLV.hdr;
14478     {$IFDEF QT_DEBUGTQTTREEWIDGET}
14479     DebugLn('TQtTreeWidget.HandleCheckableMouseDown sending LVN_ITEMCHANGED Checked ',dbgs(B));
14480     {$ENDIF}
14481     DeliverMessage(Msg);
14482   end;
14483 
14484 begin
14485   if not Checkable or (AItem = nil) or (ViewStyle < 0) then
14486     exit;
14487 
14488   if ((QEvent_type(AEvent) = QEventMouseButtonPress) or
14489     (QEvent_type(AEvent) = QEventMouseButtonDblClick)) and
14490   (QMouseEvent_button(QMouseEventH(AEvent)) = QtLeftButton) then
14491   begin
14492     if (QTreeWidgetItem_flags(AItem) and QtItemIsUserCheckable) <> 0 then
14493     begin
14494       xx := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
14495       R := visualItemRect(AItem);
14496       if ((AMousePos.X > 2) and (AMousePos.X <= (xx + 2)))
14497         and (AMousePos.Y > R.Top + 1) and (AMousePos.Y < (R.Bottom - 2))  then
14498       begin
14499         B := QTreeWidgetItem_checkState(AItem, 0) = QtUnChecked;
14500         if B then
14501           SetItemLastCheckStateInternal(AItem, QtChecked)
14502         else
14503           SetItemLastCheckStateInternal(AItem, QtUnChecked);
14504 
14505         // if AItem is deleted in mouse event FDelayedCheckItem becomes nil and that's fine. issue #32869
14506         FDelayedCheckItem := AItem;
14507         SendMessage(AItem);
14508       end;
14509     end;
14510   end else
14511   if (QEvent_type(AEvent) = LCLQt_ItemViewAfterMouseRelease) then
14512   begin
14513     if (FDelayedCheckItem <> nil) and (FDelayedCheckItem <> AItem) then
14514     begin
14515       SetItemLastCheckStateInternal(FDelayedCheckItem, QTreeWidgetItem_checkState(FDelayedCheckItem, 0));
14516       SendMessage(FDelayedCheckItem);
14517     end;
14518     FDelayedCheckItem := nil;
14519     SetItemLastCheckStateInternal(AItem, QTreeWidgetItem_checkState(AItem, 0));
14520     SendMessage(AItem);
14521   end else
14522   if (QEvent_type(AEvent) = QEventKeyPress) and
14523     (QKeyEvent_key(QKeyEventH(AEvent)) = QtKey_Space) then
14524   begin
14525     FDelayedCheckItem := nil;
14526     B := QTreeWidgetItem_checkState(AItem, 0) = QtUnChecked;
14527     if B then
14528       SetItemLastCheckStateInternal(AItem, QtChecked)
14529     else
14530       SetItemLastCheckStateInternal(AItem, QtUnChecked);
14531 
14532     SendMessage(AItem);
14533   end;
14534 end;
14535 
GetItemLastCheckStateInternalnull14536 function TQtTreeWidget.GetItemLastCheckStateInternal(AItem: QTreeWidgetItemH
14537   ): QtCheckState;
14538 var
14539   v: QVariantH;
14540   ok: Boolean;
14541 begin
14542   Result := QtUnChecked;
14543   if AItem = nil then
14544     exit;
14545   v := QVariant_create();
14546   QTreeWidgetItem_data(AItem, v,  0, QtCheckStateRole);
14547   ok := False;
14548   if QVariant_isValid(v) then
14549     Result := QtCheckState(QVariant_toInt(v, @Ok));
14550   QVariant_destroy(v);
14551 end;
14552 
itemViewViewportEventFilternull14553 function TQtTreeWidget.itemViewViewportEventFilter(Sender: QObjectH;
14554   Event: QEventH): Boolean; cdecl;
14555 var
14556   MousePos: TQtPoint;
14557   Item: QTreeWidgetItemH;
14558   ALCLEvent: QLCLMessageEventH;
14559   W: QHeaderViewH;
14560   R: TRect;
14561   DC: TQtDeviceContext;
14562   x: Integer;
14563   AMsgData: PtrUInt;
14564 begin
14565   Result := False;
14566   QEvent_accept(Event);
14567   if LCLObject = nil then
14568     exit;
14569   BeginEventProcessing;
14570   try
14571     if (QEvent_type(Event) = QEventPaint) and
14572       not Self.FOwnerData and (Sender = viewportWidget) then
14573     begin
14574       HasPaint := True;
14575       QPaintEvent_rect(QPaintEventH(Event), @R);
14576       DC := TQtDeviceContext.Create(QWidgetH(Sender), True);
14577       try
14578         TCustomListViewAccess(LCLObject).Canvas.handle := HDC(DC);
14579         TCustomListViewAccess(LCLObject).IntfCustomDraw(dtControl, cdPrePaint, 0, 0, [], @R);
14580       finally
14581         TCustomListViewAccess(LCLObject).Canvas.handle := 0;
14582         DC.Free;
14583       end;
14584     end else
14585     if (ViewStyle = Ord(vsReport)) and Checkable and getEnabled then
14586     begin
14587       if QEvent_type(Event) = LCLQt_ItemViewAfterMouseRelease then
14588       begin
14589         ALCLEvent := QLCLMessageEventH(Event);
14590         Item := QTreeWidgetItemH(QLCLMessageEvent_getLParam(ALCLEvent));
14591         // sync lcl with qt state. This is needed only when mouse is pressed
14592         // and moved out of item, or pressed on item and released over checkbox
14593         if (Item <> nil) and (GetItemLastCheckStateInternal(Item) <>
14594           QTreeWidgetItem_checkState(Item, 0)) then
14595         begin
14596           MousePos := QtPoint(0, 0); // shutup compiler
14597           if QLCLMessageEvent_getMsg(ALCLEvent) > 0 then
14598             QTreeWidgetItem_setCheckState(Item, 0, GetItemLastCheckStateInternal(Item));
14599           HandleCheckChangedEvent(MousePos, Item, Event);
14600         end;
14601       end else
14602       if ((QEvent_type(Event) = QEventMouseButtonPress) or
14603       (QEvent_type(Event) = QEventMouseButtonDblClick)) then
14604       begin
14605         // MousePos :=
14606         QMouseEvent_pos(QMouseEventH(Event), @MousePos);
14607         Item := itemAt(MousePos.x, MousePos.y);
14608         Result := inherited itemViewViewportEventFilter(Sender, Event);
14609 
14610         if Item <> nil then
14611           HandleCheckChangedEvent(MousePos, Item, Event);
14612       end else
14613       if (QEvent_type(Event) = QEventMouseButtonRelease) then
14614       begin
14615         if OwnerDrawn and Checkable then
14616         begin
14617           // MousePos :=
14618           QMouseEvent_pos(QMouseEventH(Event), @MousePos);
14619           Item := itemAt(MousePos.x, MousePos.y);
14620           if (Item <> nil) and
14621             ((QTreeWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
14622           begin
14623             x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
14624             if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
14625             begin
14626               if QTreeWidgetItem_checkState(Item, 0) = QtUnchecked then
14627                 QTreeWidgetItem_setCheckState(Item, 0, QtChecked)
14628               else
14629                 QTreeWidgetItem_setCheckState(Item, 0, QtUnChecked);
14630             end;
14631           end;
14632           Result := SlotMouse(Sender, Event);
14633         end else
14634         begin
14635           if Checkable then
14636           begin
14637             // MousePos :=
14638             QMouseEvent_pos(QMouseEventH(Event), @MousePos);
14639             Item := itemAt(MousePos.x, MousePos.y);
14640             if Item <> nil then
14641             begin
14642               Item := topLevelItem(GetRow(Item));
14643               if Assigned(LCLObject) and LCLObject.Dragging then
14644                 AMsgData := Ord(QTreeWidgetItem_checkState(Item, 0)) + 1
14645               else
14646                 AMsgData := 0;
14647               ALCLEvent := QLCLMessageEvent_create(LCLQt_ItemViewAfterMouseRelease, AMsgData,
14648                 PtrUInt(Item), PtrUInt(Item), 0);
14649               QCoreApplication_postEvent(Sender, ALCLEvent);
14650             end;
14651           end;
14652           Result := inherited itemViewViewportEventFilter(Sender, Event);
14653         end;
14654       end else
14655       if (QEvent_type(Event) = QEventMouseMove) and (LCLObject <> nil) then
14656       begin
14657         W := QTreeView_header(QTreeViewH(Widget));
14658         if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
14659         begin
14660           BeginEventProcessing;
14661           try
14662             Result := SlotMouseMove(Sender, Event);
14663             // allow dnd inside listview (vsReport and vsList only).
14664             if not Result and Assigned(LCLObject) and LCLObject.Dragging then
14665               Result := True;
14666           finally
14667             EndEventProcessing;
14668           end;
14669         end else
14670           Result := inherited itemViewViewportEventFilter(Sender, Event);
14671       end;
14672     end else
14673     begin
14674       if (QEvent_type(Event) = QEventMouseMove) and (LCLObject <> nil) then
14675       begin
14676         W := QTreeView_header(QTreeViewH(Widget));
14677         if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
14678         begin
14679           BeginEventProcessing;
14680           try
14681             Result := SlotMouseMove(Sender, Event);
14682             // allow dnd inside listview (vsReport and vsList only).
14683             if not Result and Assigned(LCLObject) and LCLObject.Dragging then
14684               Result := True;
14685           finally
14686             EndEventProcessing;
14687           end;
14688         end else
14689           Result := inherited itemViewViewportEventFilter(Sender, Event);
14690       end else
14691         Result := inherited itemViewViewportEventFilter(Sender, Event);
14692     end;
14693   finally
14694     EndEventProcessing;
14695   end;
14696 end;
14697 
14698 procedure TQtTreeWidget.OwnerDataNeeded(ARect: TRect);
14699 var
14700   R: TRect;
14701   TopItem: Integer;
14702   i: Integer;
14703   j: Integer;
14704   ChildCount: Integer;
14705   VHeight: Integer; // viewport height
14706   RowHeight, AImagesWidth: Integer;
14707   item: QTreeWidgetItemH;
14708   itemChild: QTreeWidgetItemH;
14709   v,v2,v3: QVariantH;
14710   WStr, TempStr: WideString;
14711   ASelected: Boolean;
14712   ImgList: TCustomImageList;
14713   AImageIndex: TImageIndex;
14714   Bmp: TBitmap;
14715   AOk, AStateImages: Boolean;
14716   AIcon: QIconH;
14717   ASize: TSize;
14718   ImgListRes: TScaledImageListResolution;
14719 begin
14720   {do not set items during design time}
14721   if csDesigning in LCLObject.ComponentState then
14722     exit;
14723 
14724   if QTreeWidget_topLevelItemCount(QTreeWidgetH(Widget)) < 1 then
14725     exit;
14726 
14727   {TODO: add QtDecorationRole (icon) etc ... }
14728   QWidget_contentsRect(viewportWidget, @R);
14729   VHeight := R.Bottom - R.Top;
14730 
14731   item := QTreeWidget_itemAt(QTreeWidgetH(Widget), 0, 1);
14732   if item <> nil then
14733   begin
14734 
14735     TopItem := getRow(item);
14736     RowHeight := getRowHeight(TopItem);
14737 
14738     if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
14739       exit;
14740 
14741     i := 0;
14742     while (i < (VHeight + RowHeight)) do
14743     begin
14744       item := QTreeWidget_itemAt(QTreeWidgetH(Widget), 0, i + 1);
14745       if item <> nil then
14746       begin
14747 
14748         TopItem := getRow(item);
14749         RowHeight := getRowHeight(TopItem);
14750         if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
14751           continue;
14752 
14753         WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].Caption);
14754         ASelected := TCustomListViewHack(LCLObject).Items[TopItem].Selected;
14755 
14756         v := QVariant_create(PWideString(@WStr));
14757         try
14758           v2 := QVariant_create;
14759           try
14760             TempStr := '';
14761             QTreeWidgetItem_data(item, v2, 0, Ord(QtDisplayRole));
14762             if not QVariant_isNull(v2) then
14763               QVariant_toString(v2, @TempStr);
14764             if TempStr <> WStr then
14765               QTreeWidgetItem_setData(item, 0, Ord(QtDisplayRole), v);
14766           finally
14767             QVariant_destroy(v2);
14768           end;
14769 
14770           AStateImages := False;
14771           // set imageindex, part of comment in issue #27233
14772           ImgList := TCustomListViewHack(LCLObject).SmallImages;
14773           if Assigned(ImgList) then
14774             AImagesWidth := TCustomListViewHack(LCLObject).SmallImagesWidth
14775           else
14776           begin
14777             ImgList := TCustomListViewHack(LCLObject).StateImages;
14778             if Assigned(ImgList) then
14779               AImagesWidth := TCustomListViewHack(LCLObject).StateImagesWidth;
14780             AStateImages := True;
14781           end;
14782           if Assigned(ImgList) then
14783           begin
14784             ImgListRes := ImgList.ResolutionForPPI[
14785               AImagesWidth,
14786               TCustomListViewHack(LCLObject).Font.PixelsPerInch,
14787               TCustomListViewHack(LCLObject).GetCanvasScaleFactor];
14788             QTreeWidgetItem_sizeHint(item, @ASize, 0);
14789             if (ASize.cx <> ImgListRes.Width) or (ASize.cx <> ImgListRes.Height) then
14790             begin
14791               ASize.cx := ImgListRes.Width;
14792               ASize.cy := ImgListRes.Height;
14793               QTreeWidgetItem_setSizeHint(item, 0, @ASize);
14794             end;
14795             if AStateImages then
14796               AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].StateIndex
14797             else
14798               AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].ImageIndex;
14799             if (ImgListRes.Count > 0) and
14800               ((AImageIndex >= 0) and (AImageIndex < ImgListRes.Count)) then
14801             begin
14802               Bmp := TBitmap.Create;
14803               try
14804                 ImgListRes.GetBitmap(AImageIndex, Bmp);
14805                 v2 := QVariant_create;
14806                 QTreeWidgetItem_data(item, v2, 0, QtListViewOwnerDataRole);
14807                 if not QVariant_isNull(v2) then
14808                 begin
14809                   AOk := True;
14810                   if QVariant_toInt(v2, @AOk) <> AImageIndex then
14811                   begin
14812                     v2 := QVariant_create(AImageIndex);
14813                     QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v2);
14814                     QVariant_destroy(v2);
14815                     QTreeWidgetItem_setIcon(item, 0, TQtImage(Bmp.Handle).AsIcon)
14816                   end;
14817                   // else we are imageIndex and that''s fine.
14818                 end else
14819                 begin
14820                   v2 := QVariant_create(AImageIndex);
14821                   QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v2);
14822                   QVariant_destroy(v2);
14823                   QTreeWidgetItem_setIcon(item, 0, TQtImage(Bmp.Handle).AsIcon);
14824                 end;
14825               finally
14826                 Bmp.Free;
14827               end;
14828             end else
14829             if (AImageIndex < 0) then
14830             begin
14831               v2 := QVariant_create;
14832               AIcon := QIcon_create;
14833               try
14834                 QTreeWidgetItem_data(item, v2, 0, QtListViewOwnerDataRole);
14835                 if not QVariant_isNull(v2) then
14836                 begin
14837                   v3 := QVariant_create;
14838                   try
14839                     QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v3);
14840                   finally
14841                     QVariant_destroy(v3);
14842                   end;
14843                 end;
14844                 QTreeWidgetItem_icon(item, AIcon, 0);
14845                 if not QIcon_isNull(AIcon) then
14846                   QTreeWidgetItem_setIcon(item, 0, nil);
14847               finally
14848                 QVariant_destroy(v2);
14849                 QIcon_destroy(AIcon);
14850               end;
14851             end;
14852           end;
14853 
14854           // set alignment, issue #27233
14855           if TCustomListViewHack(LCLObject).Columns.Count > 0 then
14856           begin
14857             case TCustomListViewHack(LCLObject).Column[0].Alignment of
14858               taRightJustify: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignRight);
14859               taCenter: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignCenter);
14860               taLeftJustify: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignLeft);
14861             end;
14862           end;
14863         finally
14864           QVariant_destroy(v);
14865         end;
14866 
14867         ChildCount := QTreeWidgetItem_childCount(Item);
14868         if ChildCount = TCustomListViewHack(LCLObject).Items[TopItem].SubItems.Count then
14869         begin
14870           for j := 0 to ChildCount - 1 do
14871           begin
14872             itemChild := QTreeWidgetItem_child(item, j);
14873             if itemChild <> nil then
14874             begin
14875               WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].SubItems[j]);
14876               v := QVariant_create(PWideString(@WStr));
14877               v2 := QVariant_create;
14878               try
14879                 TempStr := '';
14880                 QTreeWidgetItem_data(itemChild, v2, j, Ord(QtDisplayRole));
14881                 if not QVariant_isNull(v2) then
14882                   QVariant_toString(v2, @TempStr);
14883                 if TempStr <> WStr then
14884                   QTreeWidgetItem_setData(itemChild, j, Ord(QtDisplayRole), v);
14885               finally
14886                 QVariant_destroy(v2);
14887                 QVariant_destroy(v);
14888               end;
14889             end;
14890           end;
14891         end else
14892         begin
14893           for j := 0 to TCustomListViewHack(LCLObject).Items[TopItem].SubItems.Count - 1 do
14894           begin
14895             WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].SubItems[j]);
14896             v := QVariant_create(PWideString(@WStr));
14897             QTreeWidgetItem_setData(item, j + 1, Ord(QtDisplayRole), v);
14898 
14899             // set alignment, issue #27233
14900             if (TCustomListViewHack(LCLObject).Columns.Count > 0) then
14901             begin
14902               case TCustomListViewHack(LCLObject).Column[j + 1].Alignment of
14903                 taRightJustify: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignRight);
14904                 taCenter: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignCenter);
14905                 taLeftJustify: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignLeft);
14906               end;
14907             end;
14908             QVariant_destroy(v);
14909           end;
14910         end;
14911         if QTreeWidgetItem_isSelected(Item) <> ASelected then
14912           QTreeWidgetItem_setSelected(Item, ASelected);
14913       end;
14914 
14915       inc(i, RowHeight);
14916     end;
14917   end;
14918 end;
14919 
14920 procedure TQtTreeWidget.ItemDelegatePaint(painter: QPainterH;
14921   option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
14922 var
14923   Msg: TLMDrawListItem;
14924   DrawStruct: TDrawListItemStruct;
14925   State: QStyleState;
14926   R: TRect;
14927   ItemIndex, SubItemIndex: Integer;
14928   ACustomState: TCustomDrawState;
14929   ATarget: TCustomDrawTarget;
14930   TmpDC1, TmpDC2: HDC;
14931   SkipDefault: Boolean;
14932   APaintResult: TCustomDrawResult;
14933 
14934   function IsItemEmpty: boolean;
14935   var
14936     AText: WideString;
14937     AIcon: QIconH;
14938   begin
14939     QTreeWidgetItem_text(topLevelItem(ItemIndex), @AText, SubItemIndex);
14940     AIcon := QIcon_create;
14941     QTreeWidgetItem_icon(topLevelItem(ItemIndex), AIcon, SubItemIndex);
14942     Result := (AText = '') and QIcon_isNull(AIcon);
14943     QIcon_destroy(AIcon);
14944   end;
14945 
14946 begin
14947   if TCustomListViewAccess(LCLObject).OwnerDraw and (ViewStyle = Ord(vsReport)) then
14948   begin
14949     QPainter_save(painter);
14950     State := QStyleOption_state(option);
14951     DrawStruct.ItemID := UINT(QModelIndex_row(index));
14952 
14953     DrawStruct.Area := visualRect(index);
14954     DrawStruct.DC := HDC(TQtDeviceContext.CreateFromPainter(painter));
14955 
14956     DrawStruct.ItemState := [];
14957     // selected
14958     if (State and QStyleState_Selected) <> 0 then
14959       Include(DrawStruct.ItemState, odSelected);
14960     // disabled
14961     if (State and QStyleState_Enabled) = 0 then
14962       Include(DrawStruct.ItemState, odDisabled);
14963     // focused (QStyleState_FocusAtBorder?)
14964     if (State and QStyleState_HasFocus) <> 0 then
14965       Include(DrawStruct.ItemState, odFocused);
14966     // hotlight
14967     if (State and QStyleState_MouseOver) <> 0 then
14968       Include(DrawStruct.ItemState, odHotLight);
14969 
14970     // checked does not work as we expected.
14971     if Checkable and (QModelIndex_column(index) <= 0) then
14972     begin
14973       // if (State and QStyleState_On <> 0) and (ATarget = dtItem) then
14974       //  Include(ACustomState, cdsChecked);
14975       if  QTreeWidgetItem_checkState(topLevelItem(QModelIndex_row(index)), 0) <> QtUnchecked then
14976         Include(DrawStruct.ItemState, odChecked);
14977     end;
14978 
14979     { todo: over states:
14980 
14981       odGrayed, odChecked,
14982       odDefault, odInactive, odNoAccel,
14983       odNoFocusRect, odReserved1, odReserved2, odComboBoxEdit
14984     }
14985     Msg.Msg := CN_DRAWITEM;
14986     Msg.DrawListItemStruct := @DrawStruct;
14987     DeliverMessage(Msg);
14988 
14989     QPainter_restore(painter);
14990 
14991     TQtDeviceContext(DrawStruct.DC).Free;
14992   end else
14993   begin
14994     State := QStyleOption_state(option);
14995     ACustomState := [cdsDefault];
14996 
14997     if (State and QStyleState_Selected) <> 0 then
14998       Include(ACustomState, cdsSelected);
14999     // disabled
15000     if (State and QStyleState_Enabled) = 0 then
15001       Include(ACustomState, cdsDisabled);
15002     // focused (QStyleState_FocusAtBorder?)
15003     if (State and QStyleState_HasFocus) <> 0 then
15004       Include(ACustomState, cdsFocused);
15005     // hotlight
15006     if (State and QStyleState_MouseOver) <> 0 then
15007       Include(ACustomState, cdsHot);
15008 
15009     ItemIndex := QModelIndex_row(index);
15010     SubItemIndex := QModelIndex_column(index);
15011 
15012     if SubItemIndex <= 0 then
15013       ATarget := dtItem
15014     else
15015       ATarget := dtSubItem;
15016 
15017     // checked does not work as we expected.
15018     if Checkable and (ATarget = dtItem) then
15019     begin
15020       // if (State and QStyleState_On <> 0) and (ATarget = dtItem) then
15021       //  Include(ACustomState, cdsChecked);
15022       if  QTreeWidgetItem_checkState(topLevelItem(ItemIndex), 0) <> QtUnchecked then
15023         Include(ACustomState, cdsChecked);
15024     end;
15025 
15026     QStyle_drawControl(QApplication_style, QStyleCE_ItemViewItem, Option, painter, viewportWidget);
15027 
15028     // NOW WE ARE DRAWING ITEMS ...
15029     QPainter_save(painter);
15030     if TCustomListView(LCLObject).Canvas.HandleAllocated then
15031       TmpDC2 := TCustomListView(LCLObject).Canvas.GetUpdatedHandle([csHandleValid])
15032     else
15033       TmpDC2 := 0;
15034     TmpDC1 := HDC(TQtDeviceContext.CreateFromPainter(painter));
15035     TCustomListView(LCLObject).Canvas.Handle := TmpDC1;
15036     try
15037       R := visualRect(index);
15038       // here we do only OnCustomDrawItem and OnCustomDrawSubItem
15039       // OnCustomDraw is done inside itemViewportEventFilter.
15040       if IsItemEmpty then
15041         QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
15042 
15043       APaintResult := TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPrePaint, ItemIndex, SubItemIndex, ACustomState, @R);
15044       SkipDefault := cdrSkipDefault in APaintResult;
15045 
15046       if not SkipDefault then // do default paint by unknown magic
15047       begin
15048         if not IsItemEmpty then
15049           QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
15050       end;
15051       // issue #27315
15052       if cdrNotifyPostpaint in APaintResult then
15053         TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPostPaint, ItemIndex, SubItemIndex, ACustomState, @R);
15054     finally
15055       TCustomListView(LCLObject).Canvas.Handle := TmpDC2;
15056       TQtDeviceContext(TmpDC1).Free;
15057       QPainter_restore(painter);
15058     end;
15059   end;
15060 end;
15061 
15062 procedure TQtTreeWidget.ClearItems;
15063 begin
15064   FSelection.Clear;
15065   QTreeWidget_clear(QTreeWidgetH(Widget));
15066 end;
15067 
15068 procedure TQtTreeWidget.clearSelection;
15069 begin
15070   inherited clearSelection;
15071   FSelection.Clear;
15072 end;
15073 
15074 procedure TQtTreeWidget.DeleteItem(const AIndex: integer);
15075 var
15076   Item: QTreeWidgetItemH;
15077   Index: Integer;
15078 begin
15079   Item := topLevelItem(AIndex);
15080   if Item <> nil then
15081     Index := FSelection.IndexOf(Item)
15082   else
15083     Index := -1;
15084   if Index <> -1 then
15085     FSelection.Remove(Item);
15086   if FDelayedCheckItem = Item then
15087     FDelayedCheckItem := nil;
15088   Item := takeTopLevelItem(AIndex);
15089   if Item <> nil then
15090     QTreeWidgetItem_destroy(Item);
15091 end;
15092 
getHeadernull15093 function TQtTreeWidget.getHeader: TQtHeaderView;
15094 begin
15095   {while designing TQtHeaderView is a no-no}
15096   if not (csDesigning in LCLObject.ComponentState) and (FHeader = nil) then
15097   begin
15098     FHeader := TQtHeaderView.CreateFrom(LCLObject, QTreeView_header(QTreeViewH(Widget)));
15099     FHeader.FOwner := Self;
15100     FHeader.FChildOfComplexWidget := ccwTreeWidget;
15101     QHeaderView_setSectionsMovable(QHeaderViewH(FHeader.Widget), False);
15102     {$IFDEF TEST_QT_SORTING}
15103     FSortChanged := QHeaderView_hook_create(FHeader.Widget);
15104     QHeaderView_hook_hook_sortIndicatorChanged(FSortChanged,
15105       @SignalSortIndicatorChanged);
15106     {$ENDIF}
15107     FHeader.AttachEvents;
15108   end;
15109   Result := FHeader;
15110 end;
15111 
GetItemCheckednull15112 function TQtTreeWidget.GetItemChecked(AIndex: Integer): Boolean;
15113 var
15114   AItem: QTreeWidgetItemH;
15115 begin
15116   Result := False;
15117   AItem := topLevelItem(AIndex);
15118   if AItem <> nil then
15119     Result := GetItemLastCheckStateInternal(AItem) = QtChecked;
15120    // Result := QTreeWidgetItem_checkState(AItem, 0) = QtChecked;
15121 end;
15122 
getItemCountnull15123 function TQtTreeWidget.getItemCount: Integer;
15124 begin
15125   Result := QTreeWidget_topLevelItemCount(QTreeWidgetH(Widget));
15126 end;
15127 
getMaxColSizenull15128 function TQtTreeWidget.getMaxColSize(ACol: Integer): Integer;
15129 begin
15130   {$note QSizeH implementation missing for TQtTreeWidget.getMaxColSize}
15131   Result := MAXINT -1;
15132 end;
15133 
getMinColSizenull15134 function TQtTreeWidget.getMinColSize(ACol: Integer): Integer;
15135 begin
15136   {$note QSizeH implementation missing for TQtTreeWidget.getMinColSize}
15137   Result := 0;
15138 end;
15139 
getSortEnablednull15140 function TQtTreeWidget.getSortEnabled: Boolean;
15141 begin
15142   Result := QTreeView_isSortingEnabled(QTreeViewH(Widget));
15143 end;
15144 
getColCountnull15145 function TQtTreeWidget.getColCount: Integer;
15146 begin
15147   Result := QTreeWidget_columnCount(QTreeWidgetH(Widget));
15148 end;
15149 
15150 procedure TQtTreeWidget.setColCount(const AValue: Integer);
15151 begin
15152   QTreeWidget_setColumnCount(QTreeWidgetH(Widget), AValue);
15153 end;
15154 
15155 procedure TQtTreeWidget.SetItemChecked(AIndex: Integer; AValue: Boolean);
15156 var
15157   AItem: QTreeWidgetItemH;
15158   AState: QtCheckState;
15159 begin
15160   AItem := topLevelItem(AIndex);
15161   if AItem <> nil then
15162   begin
15163     if AValue then
15164       AState := QtChecked
15165     else
15166       AState := QtUnChecked;
15167 
15168     QTreeWidgetItem_setCheckState(AItem, 0, AState);
15169     SetItemLastCheckStateInternal(AItem, AState);
15170   end;
15171 end;
15172 
15173 procedure TQtTreeWidget.setItemCount(const AValue: Integer);
15174 var
15175   i: Integer;
15176   j: Integer;
15177   Items: TPtrIntArray;
15178   Item: QTreeWidgetItemH;
15179   ItemChild: QTreeWidgetItemH;
15180 begin
15181   if AValue = ItemCount then
15182     exit;
15183   BeginUpdate;
15184   try
15185     ClearItems;
15186     SetLength(Items, AValue);
15187     for i := 0 to High(Items) do
15188     begin
15189       Item := QTreeWidgetItem_create(QTreeWidgetH(Widget), Ord(QTreeWidgetItemType));
15190       for j := 0 to ColCount - 1 do
15191       begin
15192         ItemChild := QTreeWidgetItem_create(item, Ord(QTreeWidgetItemType));
15193         QTreeWidgetItem_addChild(item, ItemChild);
15194       end;
15195       Items[i] := PtrUInt(Item);
15196     end;
15197     if length(Items) > 0 then
15198       QTreeWidget_addTopLevelItems(QTreeWidgetH(Widget), @Items);
15199   finally
15200     EndUpdate;
15201   end;
15202 end;
15203 
15204 procedure TQtTreeWidget.setMaxColSize(ACol: Integer; const AValue: Integer);
15205 begin
15206   {$note QSizeH implementation missing for TQtTreeWidget.setMaxColSize}
15207 end;
15208 
15209 procedure TQtTreeWidget.setMinColSize(ACol: Integer; const AValue: Integer);
15210 begin
15211   QHeaderView_setMinimumSectionSize(QTreeView_header(QTreeViewH(Widget)), AValue);
15212 end;
15213 
15214 {------------------------------------------------------------------------------
15215   Function: TQtTreeWidget.setSortEnabled
15216   Params:  Boolean
15217   Returns: Nothing
15218   Enables sorting of items.
15219  ------------------------------------------------------------------------------}
15220 procedure TQtTreeWidget.setSortEnabled(const AValue: Boolean);
15221 begin
15222   QTreeView_setSortingEnabled(QTreeWidgetH(Widget), AValue);
15223 end;
15224 
15225 {------------------------------------------------------------------------------
15226   Function: TQtTreeWidget.CurrentRow
15227   Params:  None
15228   Returns: Integer
15229  ------------------------------------------------------------------------------}
currentRownull15230 function TQtTreeWidget.currentRow: Integer;
15231 var
15232   TWI: QTreeWidgetItemH;
15233 begin
15234   TWI := QTreeWidget_currentItem(QTreeWidgetH(Widget));
15235   Result := getRow(TWI);
15236 end;
15237 
15238 {------------------------------------------------------------------------------
15239   Function: TQtTreeWidget.setCurrentRow
15240   Params:  Integer
15241   Returns: Nothing
15242  ------------------------------------------------------------------------------}
15243 procedure TQtTreeWidget.setCurrentRow(row: Integer);
15244 var
15245   TWI: QTreeWidgetItemH;
15246 begin
15247   TWI := QTreeWidget_topLevelItem(QTreeWidgetH(Widget), Row);
15248   QTreeWidget_setCurrentItem(QTreeWidgetH(Widget), TWI);
15249 end;
15250 
currentItemnull15251 function TQtTreeWidget.currentItem: QTreeWidgetItemH;
15252 begin
15253   Result := QTreeWidget_currentItem(QTreeWidgetH(Widget));
15254 end;
15255 
15256 procedure TQtTreeWidget.setCurrentItem(AItem: QTreeWidgetItemH);
15257 begin
15258   QTreeWidget_setCurrentItem(QTreeWidgetH(Widget), AItem);
15259 end;
15260 
getRownull15261 function TQtTreeWidget.getRow(AItem: QTreeWidgetItemH): integer;
15262 begin
15263   Result := QTreeWidget_indexOfTopLevelItem(QTreeWidgetH(Widget), AItem);
15264 end;
15265 
headerItemnull15266 function TQtTreeWidget.headerItem: QTreeWidgetItemH;
15267 begin
15268   Result := QTreeWidget_headerItem(QTreeWidgetH(Widget));
15269 end;
15270 
itemAtnull15271 function TQtTreeWidget.itemAt(APoint: TPoint): QTreeWidgetItemH;
15272 begin
15273   Result := itemAt(APoint.X, APoint.Y);
15274 end;
15275 
itemAtnull15276 function TQtTreeWidget.itemAt(x: Integer; y: Integer): QTreeWidgetItemH;
15277 begin
15278   Result := QTreeWidget_itemAt(QTreeWidgetH(Widget), x, y);
15279 end;
15280 
15281 procedure TQtTreeWidget.insertTopLevelItem(AIndex: Integer;
15282   AItem: QTreeWidgetItemH);
15283 begin
15284   QTreeWidget_insertTopLevelItem(QTreeWidgetH(Widget), AIndex, AItem);
15285 end;
15286 
takeTopLevelItemnull15287 function TQtTreeWidget.takeTopLevelItem(AIndex: Integer): QTreeWidgetItemH;
15288 begin
15289   Result := QTreeWidget_takeTopLevelItem(QTreeWidgetH(Widget), AIndex);
15290 end;
15291 
topLevelItemnull15292 function TQtTreeWidget.topLevelItem(AIndex: Integer): QTreeWidgetItemH;
15293 begin
15294   Result := QTreeWidget_topLevelItem(QTreeWidgetH(Widget), AIndex);
15295 end;
15296 
visualItemRectnull15297 function TQtTreeWidget.visualItemRect(AItem: QTreeWidgetItemH): TRect;
15298 var
15299   ItemRect: TRect;
15300 begin
15301   QTreeWidget_visualItemRect(QTreeWidgetH(Widget), @ItemRect, AItem);
15302   Result := ItemRect;
15303 end;
15304 
getHeaderHeightnull15305 function TQtTreeWidget.getHeaderHeight(out AOrientation: QtOrientation): Integer;
15306 var
15307   W: QHeaderViewH;
15308 begin
15309   Result := 0;
15310   AOrientation := QtHorizontal;
15311   W := QTreeView_header(QTreeViewH(Widget));
15312   if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
15313   begin
15314     AOrientation := QHeaderView_orientation(W);
15315     if AOrientation = QtHorizontal then
15316       Result := QWidget_height(W)
15317     else
15318       Result := QWidget_width(W);
15319   end;
15320 end;
15321 
getItemVisiblenull15322 function TQtTreeWidget.getItemVisible(AItem: QTreeWidgetItemH): Boolean;
15323 begin
15324   Result := not QTreeWidget_isItemHidden(QTreeWidgetH(Widget), AItem);
15325 end;
15326 
getTopItemnull15327 function TQtTreeWidget.getTopItem: integer;
15328 begin
15329   Result := getVisibleRowCount(True);
15330 end;
15331 
15332 {------------------------------------------------------------------------------
15333   Function: TQtTreeWidget.getVisibleRowCount
15334   Params:  Boolean
15335   Returns: if AFirstVisibleOnly = False (default) then it returns number
15336   of visible rows, or 0 if there's no visible rows.
15337   When AFirstVisibleOnly = True then it returns index of first visible row,
15338   otherwise result is -1.
15339  ------------------------------------------------------------------------------}
getVisibleRowCountnull15340 function TQtTreeWidget.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
15341 var
15342   R: TRect;
15343   i: integer;
15344   item: QTreeWidgetItemH;
15345   RowIndex: integer;
15346   RowHeight: integer;
15347 begin
15348   if AFirstVisibleOnly then
15349     Result := -1
15350   else
15351     Result := 0;
15352   QWidget_contentsRect(viewportWidget, @R);
15353   i := 0;
15354   repeat
15355     item := itemAt(0, i);
15356     if item <> nil then
15357     begin
15358       RowIndex := getRow(Item);
15359       if AFirstVisibleOnly then
15360       begin
15361         Result := RowIndex;
15362         break;
15363       end;
15364       RowHeight := getRowHeight(RowIndex);
15365       if RowHeight <= 0 then
15366         RowHeight := 1;
15367       inc(Result);
15368       inc(i, RowHeight);
15369     end else
15370       inc(i, 1);
15371   until i >= R.Bottom;
15372 end;
15373 
15374 procedure TQtTreeWidget.setItemVisible(AItem: QTreeWidgetItemH;
15375   const AVisible: Boolean);
15376 begin
15377   QTreeWidget_setItemHidden(QTreeWidgetH(Widget), AItem, not AVisible);
15378 end;
15379 
15380 procedure TQtTreeWidget.setItemText(AItem: QTreeWidgetItemH;
15381   const AColumn: Integer; const AText: WideString; const AAlignment: QtAlignment
15382   );
15383 begin
15384   QTreeWidgetItem_setText(AItem, AColumn, @AText);
15385   QTreeWidgetItem_setTextAlignment(AItem, AColumn, AAlignment);
15386 end;
15387 
15388 procedure TQtTreeWidget.setItemData(AItem: QTreeWidgetItemH;
15389   const AColumn: Integer; Data: Pointer; const ARole: Integer = Ord(QtUserRole));
15390 var
15391   v: QVariantH;
15392 begin
15393   if Data = nil then
15394     v := QVariant_create
15395   else
15396     v := QVariant_create(Int64({%H-}PtrUInt(Data)));
15397   QTreeWidgetItem_setData(AItem, AColumn, ARole, v);
15398   QVariant_destroy(v);
15399 end;
15400 
selCountnull15401 function TQtTreeWidget.selCount: Integer;
15402 begin
15403   Result := length(selectedItems);
15404 end;
15405 
TQtTreeWidget.selectedItemsnull15406 function TQtTreeWidget.selectedItems: TPtrIntArray;
15407 begin
15408   QTreeWidget_selectedItems(QTreeWidgetH(Widget), @Result);
15409 end;
15410 
15411 procedure TQtTreeWidget.setHeaderVisible(AVisible: Boolean);
15412 begin
15413   if (csDesigning in LCLObject.ComponentState) then
15414     QTreeView_setHeaderHidden(QTreeViewH(Widget), not AVisible)
15415   else
15416     Header.setVisible(AVisible);
15417 end;
15418 
15419 procedure TQtTreeWidget.setItemSelected(AItem: QTreeWidgetItemH;
15420   ASelect: Boolean);
15421 var
15422   Msg: TLMNotify;
15423   NMLV: TNMListView;
15424   AParent: QTreeWidgetItemH;
15425   AIndex: Integer;
15426   ASubIndex: Integer;
15427 begin
15428 
15429   if not InUpdate and
15430     (((FSelection.Count > 0) and (FSelection.IndexOf(AItem) <> -1)) or
15431     (QTreeWidget_isItemSelected(QTreeWidgetH(Widget), AItem) = ASelect)) then
15432     exit;
15433 
15434   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15435   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
15436   Msg.Msg := CN_NOTIFY;
15437 
15438   NMLV.hdr.hwndfrom := LCLObject.Handle;
15439   NMLV.hdr.code := LVN_ITEMCHANGED;
15440 
15441   AIndex := getRow(AItem);
15442 
15443   if AIndex = -1 then
15444     exit;
15445 
15446   AParent := QTreeWidgetItem_parent(AItem);
15447 
15448   if AParent <> nil then
15449     ASubIndex := QTreeWidgetItem_indexOfChild(AParent, AItem)
15450   else
15451     ASubIndex := 0;
15452 
15453 
15454   NMLV.iItem := AIndex;
15455   NMLV.iSubItem := ASubIndex;
15456   if not ASelect then
15457     NMLV.uOldState := LVIS_SELECTED
15458   else
15459     NMLV.uNewState := LVIS_SELECTED;
15460   NMLV.uChanged := LVIF_STATE;
15461   Msg.NMHdr := @NMLV.hdr;
15462 
15463   QTreeWidget_setItemSelected(QTreeWidgetH(Widget), AItem, ASelect);
15464   if not FSyncingItems then
15465   begin
15466     {$IFDEF QT_DEBUGTQTTREEWIDGET}
15467     DebugLn('TQtTreeWidget.setItemSelected() delivering ASelect ',dbgs(ASelect));
15468     {$ENDIF}
15469     DeliverMessage(Msg);
15470   end;
15471 end;
15472 
15473 procedure TQtTreeWidget.setStretchLastSection(AValue: Boolean);
15474 begin
15475   if (csDesigning in LCLObject.ComponentState) then
15476     QHeaderView_setStretchLastSection(QTreeView_header(QTreeViewH(Widget)),
15477       AValue)
15478   else
15479     Header.setStretchLastSection(AValue);
15480 end;
15481 
15482 procedure TQtTreeWidget.scrollToItem(Item: QTreeWidgetItemH;
15483   hint: QAbstractItemViewScrollHint);
15484 begin
15485   QTreeWidget_scrollToItem(QTreeWidgetH(Widget), Item, hint);
15486 end;
15487 
15488 {$IFDEF TEST_QT_SORTING}
15489 procedure TQtTreeWidget.sortItems(Acolumn: Integer; AOrder: QtSortOrder);
15490 var
15491   StdModel: QStandardItemModelH;
15492 begin
15493   // there's bug with QStandardItemModel persistent index update, we
15494   // use InternalUpdate in QtWSComCtrls !
15495   if not FCanSort then
15496     exit;
15497   try
15498     if ItemCount = 0 then
15499       exit;
15500     StdModel := QStandardItemModelH(getModel);
15501     // writeln('Sorting called ...SortRole=',QStandardItemModel_sortRole(StdModel));
15502     if QStandardItemModel_sortRole(StdModel) <> Ord(QtUserRole) then
15503       QStandardItemModel_setSortRole(StdModel, Ord(QtUserRole));
15504     setUpdatesEnabled(False);
15505     QStandardItemModel_sort(StdModel, AColumn, AOrder);
15506     setUpdatesEnabled(True);
15507   finally
15508     FCanSort := False;
15509   end;
15510 end;
15511 {$ENDIF}
15512 
15513 procedure TQtTreeWidget.AttachEvents;
15514 begin
15515   inherited AttachEvents;
15516 
15517   FItemActivatedHook := QTreeWidget_hook_create(Widget);
15518   FItemEnteredHook := QTreeWidget_hook_create(Widget);
15519   FSelectionChangedHook := QTreeWidget_hook_create(Widget);
15520   QTreeWidget_hook_hook_ItemActivated(FItemActivatedHook, @SignalItemActivated);
15521   QTreeWidget_hook_hook_ItemEntered(FItemEnteredHook, @SignalItemEntered);
15522   QTreeWidget_hook_hook_itemSelectionChanged(FSelectionChangedHook, @SignalSelectionChanged);
15523 end;
15524 
15525 procedure TQtTreeWidget.DetachEvents;
15526 begin
15527   if FItemActivatedHook <> nil then
15528   begin
15529     QTreeWidget_hook_destroy(FItemActivatedHook);
15530     FItemActivatedHook := nil;
15531   end;
15532 
15533   if FItemEnteredHook <> nil then
15534   begin
15535     QTreeWidget_hook_destroy(FItemEnteredHook);
15536     FItemEnteredHook := nil;
15537   end;
15538   if FSelectionChangedHook <> nil then
15539   begin
15540     QTreeWidget_hook_destroy(FSelectionChangedHook);
15541     FSelectionChangedHook := nil;
15542   end;
15543 
15544   {$IFDEF TEST_QT_SORTING}
15545   if FSortChanged <> nil then
15546   begin
15547     QHeaderView_hook_destroy(FSortChanged);
15548     FSortChanged := nil;
15549   end;
15550   {$ENDIF}
15551 
15552   inherited DetachEvents;
15553 end;
15554 
15555 procedure TQtTreeWidget.ExchangeItems(const AIndex1, AIndex2: Integer);
15556 var
15557   ItemFrom: QTreeWidgetItemH;
15558   ItemTo: QTreeWidgetItemH;
15559   R: TRect;
15560 begin
15561 
15562   if AIndex1 = AIndex2 then
15563     exit;
15564 
15565   if AIndex1 < AIndex2 then
15566   begin
15567     ItemTo := takeTopLevelItem(AIndex2);
15568     ItemFrom := takeTopLevelItem(AIndex1);
15569     insertTopLevelItem(AIndex1, ItemTo);
15570     insertTopLevelItem(AIndex2, ItemFrom);
15571   end else
15572   begin
15573     ItemFrom := takeTopLevelItem(AIndex1);
15574     ItemTo := takeTopLevelItem(AIndex2);
15575     insertTopLevelItem(AIndex2, ItemFrom);
15576     insertTopLevelItem(AIndex1, ItemTo);
15577   end;
15578 
15579   if OwnerDrawn then
15580   begin
15581     R := VisualItemRect(ItemFrom);
15582     Update(@R);
15583     R := VisualItemRect(ItemTo);
15584     Update(@R);
15585   end;
15586 end;
15587 
15588 procedure TQtTreeWidget.MoveItem(const AFromIndex, AToIndex: Integer);
15589 var
15590   Item: QTreeWidgetItemH;
15591   R: TRect;
15592 begin
15593   Item := takeTopLevelItem(AFromIndex);
15594   insertTopLevelItem(AToIndex, Item);
15595   if OwnerDrawn then
15596   begin
15597     R := VisualItemRect(Item);
15598     Update(@R);
15599   end;
15600 end;
15601 
getClientBoundsnull15602 function TQtTreeWidget.getClientBounds: TRect;
15603 begin
15604   Result := inherited getClientBounds;
15605 end;
15606 
getClientOffsetnull15607 function TQtTreeWidget.getClientOffset: TPoint;
15608 var
15609   Offset: Integer;
15610   AOrientation: QtOrientation;
15611 begin
15612   Offset := getHeaderHeight(AOrientation);
15613   if Offset > 0 then
15614     Result := Point(0, 0)
15615   else
15616     Result := inherited getClientOffset;
15617 end;
15618 
15619 procedure TQtTreeWidget.setSelectionMode(AMode: QAbstractItemViewSelectionMode);
15620 var
15621   SavedItem: QTreeWidgetItemH;
15622   i: Integer;
15623   Arr: TPtrIntArray;
15624 begin
15625   SavedItem := nil;
15626   if (ViewStyle > 0) and (AMode < QAbstractItemViewMultiSelection) and
15627     (getSelectionMode > QAbstractItemViewSingleSelection) then
15628   begin
15629     SavedItem := CurrentItem;
15630     Arr := selectedItems;
15631     if not ((SavedItem <> nil) and (QTreeWidgetItem_isSelected(SavedItem))) then
15632     begin
15633       SavedItem := nil;
15634       if length(Arr) > 0 then
15635         SavedItem := QTreeWidgetItemH(Arr[0]);
15636     end;
15637     for i := 0 to High(Arr) do
15638     begin
15639       if QTreeWidgetItemH(Arr[i]) <> SavedItem then
15640       begin
15641         QTreeWidgetItem_setSelected(QTreeWidgetItemH(Arr[i]), False);
15642         signalCurrentItemChanged(nil, QTreeWidgetItemH(Arr[i]));
15643       end;
15644     end;
15645     clearSelection;
15646   end;
15647   inherited setSelectionMode(AMode);
15648   if SavedItem <> nil then
15649     setItemSelected(SavedItem, True);
15650 end;
15651 
15652 {------------------------------------------------------------------------------
15653   Function: TQtTreeWidget.SignalItemActivated
15654   Params:  Integer
15655   Returns: Nothing
15656  ------------------------------------------------------------------------------}
15657 procedure TQtTreeWidget.SignalItemActivated(item: QTreeWidgetItemH;
15658   column: Integer); cdecl;
15659 var
15660   Msg: TLMNotify;
15661   NMLV: TNMListView;
15662 begin
15663   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15664   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
15665 
15666   Msg.Msg := CN_NOTIFY;
15667 
15668   NMLV.hdr.hwndfrom := LCLObject.Handle;
15669   NMLV.hdr.code := LVN_ITEMCHANGED;
15670 
15671   NMLV.iItem := getRow(Item);
15672 
15673   NMLV.iSubItem := Column;
15674   NMLV.uOldState := 0;
15675   NMLV.uNewState := LVIS_FOCUSED;
15676   NMLV.uChanged := LVIF_STATE;
15677 
15678   Msg.NMHdr := @NMLV.hdr;
15679   DeliverMessage( Msg);
15680 end;
15681 
15682 {------------------------------------------------------------------------------
15683   Function: TQtTreeWidget.SignalItemEntered
15684   Params:  Integer
15685   Returns: Nothing
15686  ------------------------------------------------------------------------------}
15687 procedure TQtTreeWidget.SignalItemEntered(item: QTreeWidgetItemH;
15688   column: Integer); cdecl;
15689 var
15690   Msg: TLMessage;
15691 begin
15692   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15693   Msg.Msg := LM_ENTER;
15694   DeliverMessage(Msg);
15695 end;
15696 
15697 {------------------------------------------------------------------------------
15698   Function: TQtTreeWidget.SignalCurrentItemChanged
15699   Params:  Integer
15700   Returns: Nothing
15701  ------------------------------------------------------------------------------}
15702 procedure TQtTreeWidget.SignalCurrentItemChanged(current: QTreeWidgetItemH;
15703   previous: QTreeWidgetItemH); cdecl;
15704 var
15705   Msg: TLMNotify;
15706   NMLV: TNMListView;
15707   AParent: QTreeWidgetItemH;
15708   ASubIndex: Integer;
15709   AIndex: Integer;
15710   ListItem: TListItem;
15711   B: Boolean;
15712   Item: QTreeWidgetItemH;
15713 begin
15714   if Current = nil then
15715     Item := Previous
15716   else
15717     Item := Current;
15718   {$IFDEF QT_DEBUGTQTTREEWIDGET}
15719   writeln('SignalCurrentItemChangedNG CUR=',dbgHex(PtrUInt(Current)),
15720     ' PREV=',dbgHex(PtrUInt(Previous)),
15721     ' InUpdate ',InUpdate,' Curr=PREVIOUS ? ',Current = Previous);
15722   {$ENDIF}
15723 
15724   if (Item <> nil) and (Current = Previous) then
15725     exit;
15726 
15727   FillChar(Msg{%H-}, SizeOf(Msg), #0);
15728   FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
15729 
15730   Msg.Msg := CN_NOTIFY;
15731 
15732   NMLV.hdr.hwndfrom := LCLObject.Handle;
15733   NMLV.hdr.code := LVN_ITEMCHANGING;
15734 
15735   AIndex := getRow(Item);
15736   AParent := nil;
15737   if Item <> nil then
15738     AParent := QTreeWidgetItem_parent(Item);
15739 
15740   if AParent <> nil then
15741     ASubIndex := QTreeWidgetItem_indexOfChild(AParent, Item)
15742   else
15743     ASubIndex := 0;
15744 
15745   NMLV.iItem := AIndex;
15746   NMLV.iSubItem := ASubIndex;
15747   if (Item <> nil) and (Item = Previous) then
15748     NMLV.uOldState := LVIS_SELECTED
15749   else
15750     NMLV.uNewState := LVIS_SELECTED;
15751   NMLV.uChanged := LVIF_STATE;
15752 
15753   Msg.NMHdr := @NMLV.hdr;
15754   DeliverMessage(Msg);
15755 
15756   FSyncingItems := True;
15757   try
15758     if Current <> nil then
15759     begin
15760       ListItem := nil;
15761       B := False;
15762       if (ViewStyle = Ord(vsReport)) and (Previous <> nil) then
15763       begin
15764         ListItem := TCustomListViewHack(LCLObject).Selected;
15765         if ListItem <> nil then
15766           B := ListItem.Index = AIndex;
15767       end;
15768       FillChar(Msg, SizeOf(Msg), #0);
15769       FillChar(NMLV, SizeOf(NMLV), #0);
15770       Msg.Msg := CN_NOTIFY;
15771       NMLV.hdr.hwndfrom := LCLObject.Handle;
15772       NMLV.hdr.code := LVN_ITEMCHANGED;
15773       NMLV.iItem := AIndex;
15774       NMLV.iSubItem := ASubIndex;
15775       if (FSelection.Count > 0) and (FSelection.IndexOf(Current) <> -1) then
15776         NMLV.uNewState := LVIS_SELECTED
15777       else
15778         NMLV.uOldState := LVIS_SELECTED;
15779       NMLV.uChanged := LVIF_STATE;
15780       Msg.NMHdr := @NMLV.hdr;
15781       if not B then
15782         DeliverMessage(Msg);
15783 
15784 
15785       // send focused msg
15786       NMLV.uNewState := 0;
15787       NMLV.uOldState := 0;
15788       NMLV.iSubItem := -1;
15789       if (FSelection.Count > 0) and (FSelection.IndexOf(Current) <> -1) then
15790         NMLV.uNewState := LVIS_FOCUSED
15791       else
15792         NMLV.uOldState := LVIS_FOCUSED;
15793       NMLV.uChanged := LVIF_STATE;
15794       Msg.NMHdr := @NMLV.hdr;
15795       if not B then
15796         DeliverMessage(Msg);
15797 
15798     end;
15799 
15800     if (Previous <> nil) then
15801     begin
15802       AIndex := getRow(Previous);
15803       ListItem := nil;
15804       B := False;
15805       // From Qt docs:
15806       // This signal is emitted when the current item changes.
15807       // The current item is specified by current, and this replaces
15808       // the previous current item.
15809       // So, if Current = nil, do not ask TListView anything ! issue #18701
15810       if (ViewStyle = Ord(vsReport)) and (Current <> nil) and
15811         (Current <> Previous) then
15812       begin
15813         ListItem := TCustomListViewHack(LCLObject).Selected;
15814         if ListItem <> nil then
15815           B := ListItem.Index = AIndex;
15816       end;
15817 
15818       FillChar(Msg, SizeOf(Msg), #0);
15819       FillChar(NMLV, SizeOf(NMLV), #0);
15820       Msg.Msg := CN_NOTIFY;
15821       NMLV.hdr.hwndfrom := LCLObject.Handle;
15822       NMLV.hdr.code := LVN_ITEMCHANGED;
15823       NMLV.iItem := AIndex;
15824       AParent := QTreeWidgetItem_parent(Previous);
15825       if AParent <> nil then
15826         ASubIndex := QTreeWidgetItem_indexOfChild(AParent, Previous)
15827       else
15828         ASubIndex := 0;
15829       NMLV.iSubItem := ASubIndex;
15830 
15831       if QTreeWidget_isItemSelected(QTreeWidgetH(Widget), Previous) then
15832         NMLV.uNewState := LVIS_SELECTED
15833       else
15834         NMLV.uOldState := LVIS_SELECTED;
15835 
15836       NMLV.uChanged := LVIF_STATE;
15837       Msg.NMHdr := @NMLV.hdr;
15838       if not B then
15839         DeliverMessage(Msg);
15840     end;
15841   finally
15842     FSyncingItems := False;
15843   end;
15844 end;
15845 
15846 procedure TQtTreeWidget.SignalSelectionChanged(); cdecl;
15847 var
15848   Arr: TPtrIntArray;
15849   ItemsList: TFPList;
15850   i: Integer;
15851   j: Integer;
15852 
15853   procedure RemoveUnselectedItems;
15854   var
15855     x: Integer;
15856     Index: Integer;
15857     AnItem: QTreeWidgetItemH;
15858   begin
15859     // we are removing only items which are not in selection, to avoid
15860     // duplicated triggering of TListView.OnSelectItem
15861     for x := ItemsList.Count - 1 downto 0 do
15862     begin
15863       Index := FSelection.IndexOf(ItemsList.Items[x]);
15864       if Index = -1 then
15865       begin
15866         AnItem := QTreeWidgetItemH(ItemsList.Items[x]);
15867         SignalCurrentItemChanged(nil, AnItem);
15868         ItemsList.Remove(AnItem);
15869       end;
15870     end;
15871     ItemsList.Clear;
15872   end;
15873 begin
15874   ItemsList := TFPList.Create;
15875   try
15876     if FSelection.Count > 0 then
15877       ItemsList.Assign(FSelection);
15878     FSelection.Clear;
15879     Arr := selectedItems;
15880 
15881     {$IFDEF QT_DEBUGTQTTREEWIDGET}
15882     writeln('TQtTreeWidget.SignalSelectionChanged NewSel count ',length(Arr),
15883       ' InUpdate ',InUpdate,
15884       ' OldSel count ',ItemsList.Count);
15885     {$ENDIF}
15886 
15887     for i := 0 to High(Arr) do
15888       FSelection.Add(QTreeWidgetItemH(Arr[i]));
15889 
15890     if not InUpdate then
15891     begin
15892       if FSelection.Count = 0 then
15893         RemoveUnSelectedItems
15894       else
15895       if (getSelectionMode in [QAbstractItemViewMultiSelection,
15896                                QAbstractItemViewExtendedSelection]) and
15897         (ItemsList.Count >= 1) then // and (FSelection.Count <> ItemsList.Count) then
15898       begin
15899         RemoveUnSelectedItems;
15900         for i := 0 to FSelection.Count - 1 do
15901           SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]), nil);
15902       end else
15903       for i := 0 to FSelection.Count - 1 do
15904       begin
15905         if ItemsList.Count > 0 then
15906         begin
15907           for j := 0 to ItemsList.Count - 1 do
15908             SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]),
15909               QTreeWidgetItemH(ItemsList.Items[j]));
15910         end else
15911           SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]), nil);
15912       end;
15913     end;
15914   finally
15915     ItemsList.Free;
15916   end;
15917 end;
15918 
15919 {$IFDEF TEST_QT_SORTING}
15920 procedure TQtTreeWidget.SignalSortIndicatorChanged(ALogicalIndex: Integer;
15921   AOrder: QtSortOrder); cdecl;
15922 begin
15923   if FSorting or not Assigned(LCLObject) or not
15924     QHeaderView_isSortIndicatorShown(QHeaderViewH(Header.Widget)) then
15925     exit;
15926   if not FCanSort then
15927     exit;
15928   FSorting := True;
15929   try
15930     if ALogicalIndex >= 0 then
15931       sortItems(ALogicalIndex, AOrder);
15932   finally
15933     FSorting := False;
15934   end;
15935 end;
15936 {$ENDIF}
15937 
15938 {TQtTableView}
15939 
CreateWidgetnull15940 function TQtTableView.CreateWidget(const Params: TCreateParams): QWidgetH;
15941 var
15942   Parent: QWidgetH;
15943 begin
15944   {$ifdef VerboseQt}
15945     WriteLn('TQtTableView.CreateWidget');
15946   {$endif}
15947   HasPaint := False;
15948   if Params.WndParent <> 0 then
15949     Parent := TQtWidget(Params.WndParent).GetContainerWidget
15950   else
15951     Parent := nil;
15952   Result := QTableView_create(Parent);
15953 end;
15954 
verticalHeadernull15955 function TQtTableView.verticalHeader: TQtHeaderView;
15956 begin
15957   {$ifdef VerboseQt}
15958     WriteLn('TQtTableView.verticalHeader');
15959   {$endif}
15960   if FVerticalHeader = nil then
15961     FVerticalHeader := TQtHeaderView.CreateFrom(LCLObject, QTableView_verticalHeader(QTableViewH(Widget)));
15962   Result := FVerticalHeader;
15963 end;
15964 
horizontalHeadernull15965 function TQtTableView.horizontalHeader: TQtHeaderView;
15966 begin
15967   {$ifdef VerboseQt}
15968     WriteLn('TQtTableView.horizontalHeader');
15969   {$endif}
15970   if FHorizontalHeader = nil then
15971     FHorizontalHeader := TQtHeaderView.CreateFrom(LCLObject, QTableView_horizontalHeader(QTableViewH(Widget)));
15972   Result := FHorizontalHeader;
15973 end;
15974 
15975 procedure TQtTableView.setVisible(AVisible: Boolean);
15976 begin
15977   QWidget_setVisible(Widget, AVisible);
15978 end;
15979 
getGridStylenull15980 function TQtTableView.getGridStyle: QtPenStyle;
15981 begin
15982   Result := QTableView_gridStyle(QTableViewH(Widget));
15983 end;
15984 
15985 procedure TQtTableView.setGridStyle(ANewStyle: QtPenStyle);
15986 begin
15987   QTableView_setGridStyle(QTableViewH(Widget), ANewStyle);
15988 end;
15989 
15990 destructor TQtTableView.Destroy;
15991 begin
15992   if FVerticalHeader <> nil then
15993     FVerticalHeader.Free;
15994   if FHorizontalHeader <> nil then
15995     FHorizontalHeader.Free;
15996   inherited Destroy;
15997 end;
15998 
getViewPortnull15999 function TQtTableView.getViewPort: QWidgetH;
16000 begin
16001   Result := viewportWidget;
16002 end;
16003 
getClientBoundsnull16004 function TQtTableView.getClientBounds: TRect;
16005 begin
16006   QWidget_contentsRect(Widget, @Result);
16007 end;
16008 
16009 procedure TQtTableView.grabMouse;
16010 begin
16011   QWidget_grabMouse(Widget);
16012 end;
16013 
16014 { TQtMenu }
16015 
CreateWidgetnull16016 function TQtMenu.CreateWidget(const AParams: TCreateParams): QWidgetH;
16017 var
16018   AGroup: TQtActionGroup;
16019   Parent: QWidgetH;
16020 begin
16021   FTrackButton := QtNoButton;
16022   FLastTick := 0;
16023   FIcon := nil;
16024   if AParams.WndParent <> 0 then
16025     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
16026   else
16027     Parent := nil;
16028   Result := QMenu_create(Parent);
16029   FDeleteLater := True;
16030   FActionHandle := nil;
16031   FActions := TFPList.Create;
16032   AGroup := TQtActionGroup.Create(Result);
16033   if FMenuItem <> nil then
16034     AGroup.GroupIndex := FMenuItem.GroupIndex
16035   else
16036     AGroup.GroupIndex := -1;
16037   AGroup.Exclusive := False;
16038   FActions.Add(AGroup);
16039 end;
16040 
16041 procedure TQtMenu.InitializeWidget;
16042 begin
16043   FWidgetState := [];
16044   ChildOfComplexWidget := ccwNone;
16045   WidgetColorRole := QPaletteWindow;
16046   TextColorRole := QPaletteText;
16047   Widget := CreateWidget(FParams);
16048   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
16049   QtWidgetSet.AddHandle(Self);
16050   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
16051   FWidgetLCLFont := nil;
16052 end;
16053 
16054 constructor TQtMenu.Create(const AMenuItem: TMenuItem);
16055 var
16056   AParams: TCreateParams;
16057 begin
16058   FillChar(AParams{%H-}, SizeOf(AParams), #0);
16059   FMenuItem := AMenuItem;
16060   inherited Create(nil, AParams);
16061 end;
16062 
16063 destructor TQtMenu.Destroy;
16064 var
16065   i: integer;
16066 begin
16067   if FIcon <> nil then
16068     QIcon_destroy(FIcon);
16069 
16070   if Assigned(FActions) then
16071   begin
16072     for i := 0 to FActions.Count - 1 do
16073       TQtActionGroup(FActions.Items[i]).Free;
16074 
16075     FActions.Free;
16076   end;
16077 
16078   inherited Destroy;
16079 end;
16080 
16081 procedure TQtMenu.AttachEvents;
16082 begin
16083   FTriggeredHook := QAction_hook_create(ActionHandle);
16084   FHoveredHook := QAction_hook_create(ActionHandle);
16085   FAboutToShowHook := QMenu_hook_create(Widget);
16086   FAboutToHideHook := QMenu_hook_create(Widget);
16087   FEventHook := QObject_hook_create(Widget);
16088 
16089   QAction_hook_hook_triggered(FTriggeredHook, @SlotTriggered);
16090 
16091   QAction_hook_hook_hovered(FHoveredHook, @SlotHovered);
16092 
16093   QMenu_hook_hook_aboutToShow(FAboutToShowHook, @SlotAboutToShow);
16094 
16095   QMenu_hook_hook_aboutToHide(FAboutToHideHook, @SlotAboutToHide);
16096 
16097   QObject_hook_hook_events(FEventHook, @EventFilter);
16098 end;
16099 
16100 procedure TQtMenu.DetachEvents;
16101 begin
16102   if FActionEventFilter <> nil then
16103   begin
16104     QObject_hook_destroy(FActionEventFilter);
16105     FActionEventFilter := nil;
16106   end;
16107 
16108   if FTriggeredHook <> nil then
16109   begin
16110     QAction_hook_destroy(FTriggeredHook);
16111     FTriggeredHook := nil;
16112   end;
16113 
16114   if FHoveredHook <> nil then
16115   begin
16116     QAction_hook_destroy(FHoveredHook);
16117     FHoveredHook := nil;
16118   end;
16119 
16120   if FAboutToShowHook <> nil then
16121   begin
16122     QMenu_hook_destroy(FAboutToShowHook);
16123     FAboutToShowHook := nil;
16124   end;
16125 
16126   if FAboutToHideHook <> nil then
16127   begin
16128     QMenu_hook_destroy(FAboutToHideHook);
16129     FAboutToHideHook := nil;
16130   end;
16131   inherited DetachEvents;
16132 end;
16133 
16134 procedure TQtMenu.SlotHovered; cdecl;
16135 begin
16136   FMenuItem.IntfDoSelect;
16137 end;
16138 
16139 procedure TQtMenu.SlotAboutToShow; cdecl;
16140 var
16141   Msg: TLMessage;
16142 begin
16143   //issues #22872 (flickering), #24979 (actions)
16144   if Assigned(FMenuItem) and
16145     not (FMenuItem.Menu is TPopupMenu) then
16146   begin
16147     // DebugLn('TQtMenu.SlotAboutToShow ',dbgsName(FMenuItem));
16148     if GetTickCount64 - FLastTick > 10 then
16149     begin
16150       FLastTick := GetTickCount64;
16151       FillChar(Msg{%H-}, SizeOf(Msg), 0);
16152       Msg.msg := LM_ACTIVATE;
16153       if Assigned(FMenuItem) then
16154         FMenuItem.Dispatch(Msg);
16155       FLastTick := GetTickCount64;
16156     end;
16157   end;
16158 end;
16159 
16160 procedure TQtMenu.SlotAboutToHide; cdecl;
16161 var
16162   Event: QLCLMessageEventH;
16163 begin
16164   if FMenuItem.Menu is TPopupMenu then
16165   begin
16166     Event := QLCLMessageEvent_create(LCLQt_PopupMenuClose);
16167     QCoreApplication_postEvent(Widget, Event);
16168   end;
16169   // DebugLn('TQtMenu.SlotAboutToHide ',dbgsName(FMenuItem));
16170   FLastTick := GetTickCount64; // issue #22872, #24979
16171 end;
16172 
16173 procedure TQtMenu.DoPopupClose;
16174 begin
16175   if FMenuItem.Menu is TPopupMenu then
16176     TPopupMenu(FMenuItem.Menu).Close;
16177 end;
16178 
16179 procedure TQtMenu.SlotDestroy; cdecl;
16180 begin
16181   Widget := nil;
16182 end;
16183 
16184 procedure TQtMenu.PopUp(pos: PQtPoint; at: QActionH);
16185 begin
16186   QMenu_popup(QMenuH(Widget), pos, at);
16187 end;
16188 
16189 procedure TQtMenu.Exec(pos: PQtPoint; at: QActionH);
16190 begin
16191   QMenu_exec(QMenuH(Widget), pos, at);
16192 end;
16193 
actionHandlenull16194 function TQtMenu.actionHandle: QActionH;
16195 begin
16196   if FActionHandle = nil then
16197   begin
16198     if FActionEventFilter <> nil then
16199     begin
16200       QObject_hook_destroy(FActionEventFilter);
16201       FActionEventFilter := nil;
16202     end;
16203     FActionHandle := QMenu_menuAction(QMenuH(Widget));
16204     FActionEventFilter := QObject_hook_create(FActionHandle);
16205     QObject_hook_hook_events(FActionEventFilter, @ActionEventFilter);
16206   end;
16207   Result := FActionHandle;
16208 end;
16209 
addMenunull16210 function TQtMenu.addMenu(AMenu: QMenuH): QActionH;
16211 begin
16212   setHasSubmenu(True);
16213   Result := QMenu_addMenu(QMenuH(Widget), AMenu);
16214 end;
16215 
16216 procedure TQtMenu.removeActionGroup;
16217 var
16218   Action: QActionGroupH;
16219 begin
16220   Action := QAction_actionGroup(ActionHandle);
16221   if Action <> nil then
16222     QActionGroup_removeAction(Action, ActionHandle);
16223 end;
16224 
16225 procedure TQtMenu.setActionGroups(AItem: TMenuItem);
16226 var
16227   i: integer;
16228   b: Boolean = True;
16229   Group: TQtActionGroup;
16230 begin
16231   for i := 0 to FActions.Count - 1 do
16232   begin
16233     Group := TQtActionGroup(FActions.Items[i]);
16234     if Group.GroupIndex = AItem.GroupIndex then
16235     begin
16236       QAction_setEnabled(TQtMenu(AItem.Handle).actionHandle, AItem.Enabled);
16237       QAction_setVisible(TQtMenu(AItem.Handle).actionHandle, AItem.Visible);
16238       Group.addAction(TQtMenu(AItem.Handle).actionHandle);
16239       Group.Exclusive := AItem.RadioItem;
16240       Group.Visible := True;
16241       Group.Enabled := True;
16242       b := False;
16243       break;
16244     end;
16245   end;
16246   if b then
16247   begin
16248     Group := TQtActionGroup.Create(Widget);
16249     Group.Exclusive := AItem.RadioItem;
16250     Group.GroupIndex := AItem.GroupIndex;
16251     QAction_setEnabled(TQtMenu(AItem.Handle).actionHandle, AItem.Enabled);
16252     QAction_setVisible(TQtMenu(AItem.Handle).actionHandle, AItem.Visible);
16253     Group.addAction(TQtMenu(AItem.Handle).actionHandle);
16254     Group.Visible := True;
16255     Group.Enabled := True;
16256     FActions.Add(Group);
16257   end;
16258 end;
16259 
insertMenunull16260 function TQtMenu.insertMenu(AIndex: Integer; AMenu: QMenuH; AItem: TMenuItem): QActionH;
16261 var
16262   actionBefore: QActionH;
16263 begin
16264 
16265   setHasSubmenu(True);
16266 
16267   if (AItem <> nil) and not AItem.IsLine then
16268     setActionGroups(AItem);
16269 
16270   actionBefore := getActionByIndex(AIndex);
16271 
16272   if actionBefore <> nil then
16273     Result := QMenu_insertMenu(QMenuH(Widget), actionBefore, AMenu)
16274   else
16275     Result := QMenu_addMenu(QMenuH(Widget), AMenu);
16276 end;
16277 
getHasSubMenunull16278 function TQtMenu.getHasSubMenu: boolean;
16279 begin
16280   Result := QAction_menu(ActionHandle) <> nil;
16281 end;
16282 
getVisiblenull16283 function TQtMenu.getVisible: Boolean;
16284 begin
16285   if ActionHandle = nil then
16286     exit(False);
16287   Result := QAction_isVisible(ActionHandle);
16288 end;
16289 
getTextnull16290 function TQtMenu.getText: WideString;
16291 begin
16292   QAction_text(ActionHandle, @Result);
16293 end;
16294 
16295 procedure TQtMenu.setText(const W: WideString);
16296 begin
16297   QAction_setText(ActionHandle, @W);
16298 end;
16299 
16300 procedure TQtMenu.setVisible(AVisible: Boolean);
16301 begin
16302   QAction_setVisible(ActionHandle, AVisible);
16303 end;
16304 
16305 procedure TQtMenu.setChecked(p1: Boolean);
16306 begin
16307   setCheckable(p1);
16308   QAction_setChecked(ActionHandle, p1);
16309 end;
16310 
16311 procedure TQtMenu.setCheckable(p1: Boolean);
16312 begin
16313   if FMenuItem.RadioItem or FMenuItem.ShowAlwaysCheckable then
16314     QAction_setCheckable(ActionHandle, True)
16315   else
16316     QAction_setCheckable(ActionHandle, p1);
16317 end;
16318 
16319 procedure TQtMenu.setHasSubmenu(AValue: Boolean);
16320 begin
16321   if AValue then
16322     QAction_setMenu(ActionHandle, QMenuH(Widget))
16323   else
16324     QAction_setMenu(ActionHandle, nil);
16325 end;
16326 
16327 procedure TQtMenu.setIcon(AIcon: QIconH);
16328 begin
16329   QMenu_setIcon(QMenuH(Widget), AIcon);
16330 end;
16331 
16332 procedure TQtMenu.setImage(AImage: TQtImage);
16333 begin
16334   if FIcon <> nil then
16335   begin
16336     QIcon_destroy(FIcon);
16337     FIcon := nil;
16338   end;
16339 
16340   if AImage <> nil then
16341     FIcon := AImage.AsIcon()
16342   else
16343     FIcon := QIcon_create();
16344 
16345   setIcon(FIcon);
16346 end;
16347 
16348 procedure TQtMenu.setSeparator(AValue: Boolean);
16349 begin
16350   QAction_setSeparator(ActionHandle, AValue);
16351 end;
16352 
16353 procedure TQtMenu.setShortcut(AShortCutK1, AShortCutK2: TShortcut);
16354 var
16355   Key: Word;
16356   Shift: TShiftState;
16357   QtK1, QtK2: integer;
16358   KeySequence: QKeySequenceH;
16359 begin
16360   QtK1 := 0;
16361   QtK2 := 0;
16362   if AShortCutK1 <> 0 then
16363   begin
16364     ShortCutToKey(AShortCutK1, Key, Shift);
16365     QtK1 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
16366     if AShortCutK2 <> 0 then
16367     begin
16368       ShortCutToKey(AShortCutK2, Key, Shift);
16369       QtK2 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
16370     end;
16371   end;
16372   // there is no need in destroying QKeySequnce
16373   KeySequence := QKeySequence_create(QtK1, QtK2);
16374   QAction_setShortcut(ActionHandle, KeySequence);
16375   QKeySequence_destroy(KeySequence);
16376 end;
16377 
16378 {------------------------------------------------------------------------------
16379   Method: TQtMenu.SlotTriggered
16380 
16381   Callback for menu item click
16382  ------------------------------------------------------------------------------}
16383 procedure TQtMenu.SlotTriggered(checked: Boolean); cdecl;
16384 var
16385   Event: QLCLMessageEventH;
16386 begin
16387   Event := QLCLMessageEvent_create(LCLQt_PopupMenuTriggered);
16388   QCoreApplication_postEvent(Widget, Event, 1 {high priority});
16389 end;
16390 
ActionEventFilternull16391 function TQtMenu.ActionEventFilter(Sender: QObjectH; Event: QEventH): Boolean;
16392   cdecl;
16393 var
16394   TempAction: QActionH;
16395   Group: QActionGroupH;
16396 begin
16397   Result := False;
16398   QEvent_accept(Event);
16399   if Assigned(FMenuItem) and (QEvent_type(Event) = QEventActionChanged) then
16400   begin
16401     {qt shouldn't change checkables in any case, LCL should do that !}
16402     TempAction := QActionEvent_action(QActionEventH(Event));
16403     if (TempAction <> nil) and
16404       QAction_isCheckable(TempAction) and
16405       (QAction_isChecked(TempAction) <> FMenuItem.Checked) then
16406     begin
16407       Group := QAction_actionGroup(TempAction);
16408       if Group <> nil then
16409       begin
16410         if QActionGroup_isExclusive(Group) then
16411           QObject_blockSignals(Group, True)
16412         else
16413           QObject_blockSignals(TempAction, True);
16414       end else
16415         QObject_blockSignals(TempAction, True);
16416 
16417       QAction_setChecked(TempAction, FMenuItem.Checked);
16418 
16419       if QObject_signalsBlocked(TempAction) then
16420       begin
16421         QObject_blockSignals(TempAction, False);
16422         Result := True;
16423         QEvent_ignore(Event);
16424       end;
16425     end;
16426   end;
16427 end;
16428 
TQtMenu.MenuItemEnablednull16429 function TQtMenu.MenuItemEnabled: boolean;
16430 var
16431   AParentMenu: TMenuItem;
16432 begin
16433   if not Assigned(FMenuItem) then
16434   begin
16435     Result := getEnabled;
16436     exit;
16437   end;
16438 
16439   Result := FMenuItem.Enabled;
16440   AParentMenu := FMenuItem.Parent;
16441   while AParentMenu <> nil do
16442   begin
16443     Result := AParentMenu.Enabled;
16444     if not Result then
16445       break;
16446     AParentMenu := AParentMenu.Parent;
16447   end;
16448 end;
16449 
EventFilternull16450 function TQtMenu.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
16451 var
16452   Msg: TLMessage;
16453   TempAction: QActionH;
16454   APos: TQtPoint;
16455 begin
16456   Result := False;
16457   QEvent_accept(Event);
16458 
16459   case QEvent_type(Event) of
16460     LCLQt_PopupMenuTriggered:
16461       begin
16462         {$IFDEF HASX11}
16463         // make interface snappy after menuitem triggers
16464         if Assigned(Application) and not Application.Terminated then
16465         begin
16466           if QApplication_activePopupWidget = nil then
16467           begin
16468             if QApplication_activeModalWidget <> nil then
16469               QWidget_repaint(QApplication_activeModalWidget)
16470             else
16471             if QApplication_activeWindow <> nil then
16472               QWidget_repaint(QApplication_activeWindow);
16473             QCoreApplication_processEvents(QEventLoopAllEvents);
16474           end;
16475         end;
16476         {$ENDIF}
16477         FillChar(Msg{%H-}, SizeOf(Msg), 0);
16478         Msg.msg := LM_ACTIVATE;
16479         if MenuItemEnabled then
16480           FMenuItem.Dispatch(Msg);
16481         Result := True;
16482       end;
16483     LCLQt_PopupMenuClose:
16484       begin
16485         DoPopupClose;
16486         Result := True;
16487       end;
16488     QEventDestroy: SlotDestroy;
16489     QEventMouseButtonPress,
16490     QEventMouseButtonRelease:
16491       begin
16492         Result := (FTrackButton = QtLeftButton) and
16493           (QMouseEvent_button(QMouseEventH(Event)) <> FTrackButton);
16494         if Assigned(FMenuItem) and not (FMenuItem.Menu is TPopupMenu) then
16495         begin
16496           QMouseEvent_pos(QMouseEventH(Event), @APos);
16497           TempAction := QMenu_actionAt(QMenuH(Widget),
16498             @APos);
16499           {trigger LCL if root of menu have OnClick() connected,
16500            since qt won't do that for us.}
16501           if (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) and
16502             Assigned(FMenuItem.OnClick) and
16503             (TempAction = nil) and not (FMenuItem.IsInMenuBar) then
16504             SlotTriggered();
16505         end;
16506       end;
16507   end;
16508 end;
16509 
16510 { TQtMenuBar }
16511 
16512 constructor TQtMenuBar.Create(const AParent: QWidgetH);
16513 begin
16514   Create;
16515   Widget := QMenuBar_create(AParent);
16516   {$IFNDEF DARWIN}
16517   FCatchNextResizeEvent := False;
16518   FNumOfActions := 0;
16519   {$ENDIF}
16520   FOwnWidget := AParent = nil;
16521   FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
16522   FWidgetLCLFont := nil;
16523   FHeight := getHeight;
16524   FVisible := False;
16525   FIsApplicationMainMenu := False;
16526   Palette.ForceColor := True;
16527   setDefaultColor(dctFont);
16528   Palette.ForceColor := False;
16529   setVisible(FVisible);
16530   QtWidgetSet.AddHandle(Self);
16531 end;
16532 
16533 {$IFNDEF DARWIN}
IsDesigningnull16534 function TQtMenuBar.IsDesigning: Boolean;
16535 var
16536   V: QVariantH;
16537   B: Boolean;
16538 begin
16539   Result := (Widget <> nil);
16540   if not Result then
16541     exit(False);
16542 
16543   Result := False;
16544   v := QVariant_create();
16545   try
16546     B := False;
16547     QObject_property(Widget, v, 'lcldesignmenubar');
16548     if QVariant_isValid(v) and not QVariant_isNull(v) then
16549       Result := QVariant_toInt(V, @B) = 1;
16550   finally
16551     QVariant_destroy(v);
16552   end;
16553 end;
16554 {$ENDIF}
16555 
TQtMenuBar.EventFilternull16556 function TQtMenuBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
16557   cdecl;
16558   {$IFNDEF DARWIN}
16559   procedure UpdateDesignerClientRect;
16560   var
16561     WParent: QWidgetH;
16562     Window: HWND;
16563     ACtl: TWinControl;
16564   begin
16565     WParent := getParent;
16566     if (WParent <> nil) then
16567     begin
16568       Window := HwndFromWidgetH(WParent);
16569       if (Window <> 0) and (TQtWidget(Window) is TQtDesignWidget) and
16570         (TQtWidget(Window).getVisible) then
16571       begin
16572         ACtl := TQtMainWindow(Window).LCLObject;
16573         if Assigned(ACtl) and not (csDestroying in ACtl.ComponentState) then
16574         begin
16575           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
16576           DebugLn('TQtMenuBar.EventFilter: before DoAdjustClientRecChange=',
16577             dbgs(ACtl.ClientRect));
16578           {$ENDIF}
16579           ACtl.DoAdjustClientRectChange(True);
16580           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
16581           DebugLn('TQtMenuBar.EventFilter: after  DoAdjustClientRecChange=',
16582             dbgs(ACtl.ClientRect));
16583           {$ENDIF}
16584         end;
16585       end;
16586     end;
16587   end;
16588   {$ENDIF}
16589 begin
16590   Result := False;
16591   QEvent_accept(Event);
16592   if (QEvent_type(Event) = QEventFontChange) then
16593     AssignQtFont(FWidgetDefaultFont.FHandle, QWidget_font(QWidgetH(Sender)));
16594 
16595   {$IFNDEF DARWIN}
16596   if (QEvent_type(Event) = QEventResize) then
16597   begin
16598     // adjusts client rect of designer form.
16599     if FCatchNextResizeEvent then
16600     begin
16601       FCatchNextResizeEvent := False;
16602       if IsDesigning then
16603         UpdateDesignerClientRect;
16604     end;
16605   end else
16606   if (QEvent_type(Event) = QEventActionAdded) then
16607   begin
16608     if IsDesigning then
16609     begin
16610       inc(FNumOfActions);
16611       FCatchNextResizeEvent := FNumOfActions = 1;
16612       {$IFDEF VerboseQtEvents}
16613       DebugLn(Format('TQtMenuBar: Added new action now have %d actions ',
16614         [FNumOfActions]));
16615       {$ENDIF}
16616     end;
16617   end else
16618   if (QEvent_type(Event) = QEventActionRemoved) then
16619   begin
16620     if IsDesigning then
16621     begin
16622       dec(FNumOfActions);
16623       {$IFDEF VerboseQtEvents}
16624       DebugLn(Format('TQtMenuBar: Removed action still have %d actions ',
16625         [FNumOfActions]));
16626       {$ENDIF}
16627       FCatchNextResizeEvent := FNumOfActions = 0;
16628     end;
16629   end;
16630   {$ENDIF}
16631 end;
16632 
addMenunull16633 function TQtMenuBar.addMenu(AMenu: QMenuH): QActionH;
16634 begin
16635   if not FVisible then
16636   begin
16637     FVisible := True;
16638     setVisible(FVisible);
16639   end;
16640   Result := QMenuBar_addMenu(QMenuBarH(Widget), AMenu);
16641 end;
16642 
TQtMenuBar.insertMenunull16643 function TQtMenuBar.insertMenu(AIndex: Integer; AMenu: QMenuH): QActionH;
16644 var
16645   actionBefore: QActionH;
16646   Actions: TPtrIntArray;
16647   Action: QActionH;
16648   i: Integer;
16649   seq: QKeySequenceH;
16650   WStr: WideString;
16651 begin
16652   if not FVisible then
16653   begin
16654     FVisible := True;
16655     setVisible(FVisible);
16656   end;
16657   actionBefore := getActionByIndex(AIndex);
16658   if actionBefore <> nil then
16659     Result := QMenuBar_insertMenu(QMenuBarH(Widget), actionBefore, AMenu)
16660   else
16661     Result := QMenuBar_addMenu(QMenuBarH(Widget), AMenu);
16662   if FIsApplicationMainMenu then
16663   begin
16664     QWidget_actions(Widget, @Actions);
16665     QtWidgetSet.ClearGlobalActions;
16666     for i := 0 to High(Actions) do
16667     begin
16668       Action := QActionH(Actions[i]);
16669       seq := QKeySequence_create();
16670       try
16671         if QKeySequence_isEmpty(seq) then
16672         begin
16673           QAction_shortcut(Action, seq);
16674           WStr := '';
16675           QAction_text(Action, @WStr);
16676           QKeySequence_destroy(seq);
16677           seq := nil;
16678           seq := QKeySequence_create();
16679           QKeySequence_mnemonic(seq, @WStr);
16680           if not QKeySequence_isEmpty(seq) then
16681           begin
16682             QAction_setShortcutContext(Action, QtApplicationShortcut);
16683             QtWidgetSet.AddGlobalAction(Action);
16684           end;
16685         end;
16686       finally
16687         QKeySequence_destroy(seq);
16688       end;
16689     end;
16690   end;
16691 end;
16692 
TQtMenuBar.getGeometrynull16693 function TQtMenuBar.getGeometry: TRect;
16694 begin
16695   Result := inherited getGeometry;
16696 
16697   // workaround since after attaching menu it takes 0 height
16698   if Result.Bottom = 0 then
16699     Result.Bottom := FHeight;
16700 end;
16701 
16702 { TQtProgressBar }
16703 
TQtProgressBar.CreateWidgetnull16704 function TQtProgressBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
16705 var
16706   Parent: QWidgetH;
16707 begin
16708   // Creates the widget
16709   {$ifdef VerboseQt}
16710     WriteLn('TQProgressBar.Create');
16711   {$endif}
16712   if AParams.WndParent <> 0 then
16713     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
16714   else
16715     Parent := nil;
16716   Result := QProgressBar_create(Parent);
16717 end;
16718 
16719 procedure TQtProgressBar.AttachEvents;
16720 begin
16721   inherited AttachEvents;
16722 
16723   FValueChangedHook := QProgressBar_hook_create(Widget);
16724   QProgressBar_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
16725 end;
16726 
16727 procedure TQtProgressBar.DetachEvents;
16728 begin
16729   if FValueChangedHook <> nil then
16730   begin
16731     QProgressBar_hook_destroy(FValueChangedHook);
16732     FValueChangedHook := nil;
16733   end;
16734   inherited DetachEvents;
16735 end;
16736 
16737 procedure TQtProgressBar.setRange(minimum: Integer; maximum: Integer);
16738 begin
16739   QProgressBar_setRange(QProgressBarH(Widget), minimum, maximum);
16740 end;
16741 
16742 procedure TQtProgressBar.setTextVisible(visible: Boolean);
16743 begin
16744   QProgressBar_setTextVisible(QProgressBarH(Widget), visible);
16745 end;
16746 
16747 procedure TQtProgressBar.setAlignment(const AAlignment: QtAlignment);
16748 begin
16749   QProgressBar_setAlignment(QProgressBarH(Widget), AAlignment);
16750 end;
16751 
16752 procedure TQtProgressBar.setTextDirection(textDirection: QProgressBarDirection);
16753 begin
16754   QProgressBar_setTextDirection(QProgressBarH(Widget), textDirection);
16755 end;
16756 
16757 procedure TQtProgressBar.setValue(value: Integer);
16758 begin
16759   QProgressBar_setValue(QProgressBarH(Widget), value);
16760 end;
16761 
16762 procedure TQtProgressBar.setOrientation(p1: QtOrientation);
16763 begin
16764   QProgressBar_setOrientation(QProgressBarH(Widget), p1);
16765 end;
16766 
16767 procedure TQtProgressBar.setInvertedAppearance(invert: Boolean);
16768 begin
16769   QProgressBar_setInvertedAppearance(QProgressBarH(Widget), invert);
16770 end;
16771 
16772 procedure TQtProgressBar.SignalValueChanged(Value: Integer); cdecl;
16773 var
16774   Msg: TLMessage;
16775 begin
16776   FillChar(Msg{%H-}, SizeOf(Msg), #0);
16777   Msg.Msg := LM_CHANGED;
16778   if not InUpdate then
16779     DeliverMessage(Msg);
16780 end;
16781 
16782 procedure TQtProgressBar.setFocusPolicy(const APolicy: QtFocusPolicy);
16783 begin
16784   if APolicy = QtNoFocus then
16785     QWidget_setFocusPolicy(Widget, APolicy)
16786   else
16787     QWidget_setFocusPolicy(Widget, QtTabFocus);
16788 end;
16789 
16790 procedure TQtProgressBar.reset;
16791 begin
16792   QProgressBar_reset(QProgressBarH(Widget));
16793 end;
16794 
16795 { TQtStatusBarPanel }
16796 
CreateWidgetnull16797 function TQtStatusBarPanel.CreateWidget(const AParams: TCreateParams
16798   ): QWidgetH;
16799 var
16800   Parent: QWidgetH;
16801 begin
16802   // Creates the widget
16803   {$ifdef VerboseQt}
16804     WriteLn('TQtStatusBarPanel.Create');
16805   {$endif}
16806 
16807   if AParams.WndParent <> 0 then
16808     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
16809   else
16810     Parent := nil;
16811   Result := QLabel_create(Parent);
16812 end;
16813 
16814 procedure TQtStatusBarPanel.DrawItem(Sender: QObjectH; Event: QEventH);
16815 var
16816   Msg: TLMDrawItems;
16817   AStruct: TPaintStruct;
16818   ItemStruct: PDrawItemStruct;
16819   P: TPoint;
16820   B: Boolean;
16821 begin
16822   {$ifdef VerboseQt}
16823     WriteLn('TQtWidget.DrawItem ', dbgsName(LCLObject));
16824   {$endif}
16825   if CanSendLCLMessage and (LCLObject is TWinControl) then
16826   begin
16827     FillChar(Msg{%H-}, SizeOf(Msg), #0);
16828 
16829     Msg.Msg := LM_DRAWITEM;
16830     FillChar(AStruct{%H-}, SizeOf(TPaintStruct), 0);
16831     FillChar(ItemStruct{%H-}, SizeOf(TDrawItemStruct), 0);
16832     New(ItemStruct);
16833 
16834     with PaintData do
16835     begin
16836       PaintWidget := QWidgetH(Sender);
16837       ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
16838       if ClipRect = nil then
16839         New(ClipRect);
16840       QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
16841     end;
16842 
16843     ItemStruct^.itemID := UINT(ID);
16844     ItemStruct^._hDC := BeginPaint(THandle(Self), AStruct);
16845     FContext := ItemStruct^._hDC;
16846     ItemStruct^.rcItem := PaintData.ClipRect^;
16847     ItemStruct^.hwndItem := HWND(Self);
16848     Msg.Ctl := LCLObject.Handle;
16849     Msg.DrawItemStruct := ItemStruct;
16850 
16851     P := getClientOffset;
16852     inc(P.X, FScrollX);
16853     inc(P.Y, FScrollY);
16854     TQtDeviceContext(FContext).translate(P.X, P.Y);
16855 
16856     // send paint message
16857     try
16858       try
16859         LCLObject.WindowProc(TLMessage(Msg));
16860       finally
16861         Dispose(PaintData.ClipRect);
16862         Fillchar(FPaintData, SizeOf(FPaintData), 0);
16863         FContext := 0;
16864         EndPaint(THandle(Self), AStruct);
16865         Dispose(ItemStruct);
16866       end;
16867     except
16868       // prevent recursive repainting !
16869       B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
16870       if B then
16871         QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
16872       try
16873         Application.HandleException(nil);
16874       finally
16875         if B and Assigned(Application) and not Application.Terminated then
16876           QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
16877       end;
16878     end;
16879   end;
16880 end;
16881 
TQtStatusBarPanel.EventFilternull16882 function TQtStatusBarPanel.EventFilter(Sender: QObjectH; Event: QEventH
16883   ): Boolean; cdecl;
16884 begin
16885   Result := False;
16886   QEvent_accept(Event);
16887   if LCLObject = nil then
16888     exit;
16889   if HasPaint and (QEvent_type(Event) = QEventPaint) then
16890   begin
16891     DrawItem(Sender, Event);
16892     Result := True;
16893   end;
16894 end;
16895 
16896 { TQtStatusBar }
16897 
TQtStatusBar.CreateWidgetnull16898 function TQtStatusBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
16899 var
16900   Parent: QWidgetH;
16901 begin
16902   SetLength(Panels, 0);
16903   if AParams.WndParent <> 0 then
16904     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
16905   else
16906     Parent := nil;
16907   Result := QStatusBar_create(Parent);
16908   Widget := Result;
16909 end;
16910 
16911 procedure TQtStatusBar.setColor(const Value: PQColor);
16912 var
16913   I: Integer;
16914   P: QPaletteH;
16915   WP: QPaletteH;
16916 begin
16917   inherited setColor(Value);
16918   QWidget_setAutoFillBackground(Widget, not EqualTQColor(Palette.CurrentColor, Palette.DefaultColor));
16919   for i := 0 to High(self.Panels) do
16920   begin
16921     P := QWidget_palette(getContainerWidget);
16922     WP := QWidget_palette(Panels[i].Widget);
16923     QWidget_setAutoFillBackground(Panels[i].Widget, not EqualTQColor(Palette.CurrentColor, Palette.DefaultColor));
16924     QPalette_setBrush(WP, QPaletteWindow, QPalette_background(P));
16925   end;
16926 end;
16927 
16928 procedure TQtStatusBar.showMessage(text: PWideString; timeout: Integer);
16929 begin
16930   QStatusBar_showMessage(QStatusBarH(Widget), text, timeout);
16931 end;
16932 
16933 procedure TQtStatusBar.addWidget(AWidget: QWidgetH; AStretch: Integer = 0);
16934 begin
16935   QStatusBar_addWidget(QStatusBarH(Widget), AWidget, AStretch);
16936 end;
16937 
16938 procedure TQtStatusBar.removeWidget(AWidget: QWidgetH);
16939 begin
16940   QStatusBar_removeWidget(QStatusBarH(Widget), AWidget);
16941 end;
16942 
isSizeGripEnablednull16943 function TQtStatusBar.isSizeGripEnabled: Boolean;
16944 begin
16945   Result := QStatusBar_isSizeGripEnabled(QStatusBarH(Widget));
16946 end;
16947 
16948 procedure TQtStatusBar.setSizeGripEnabled(const Value: Boolean);
16949 begin
16950   QStatusBar_setSizeGripEnabled(QStatusBarH(Widget), Value);
16951 end;
16952 
SlotMousenull16953 function TQtStatusBar.SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
16954 begin
16955   inherited SlotMouse(Sender, Event);
16956   Result := True; // cancel event propagation
16957 end;
16958 
16959 { TQtDialog }
16960 
TQtDialog.CreateWidgetnull16961 function TQtDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags): QWidgetH;
16962 begin
16963   Result := QDialog_create(parent, f);
16964 end;
16965 
16966 constructor TQtDialog.Create(ADialog: TCommonDialog; parent: QWidgetH; f: QtWindowFlags);
16967 begin
16968   WidgetColorRole := QPaletteWindow;
16969   TextColorRole := QPaletteWindowText;
16970   FOwner := nil;
16971   FCentralWidget := nil;
16972   FOwnWidget := True;
16973   FProps := nil;
16974   LCLObject := nil;
16975   FKeysToEat := [];
16976   FHasPaint := False;
16977   FDialog := ADialog;
16978   Widget := CreateWidget(parent, f);
16979   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
16980   QtWidgetSet.AddHandle(Self);
16981 end;
16982 
16983 procedure TQtDialog.AttachEvents;
16984 begin
16985   inherited AttachEvents;
16986   FDialogEventHook := QObject_hook_create(Widget);
16987   QObject_hook_hook_events(FDialogEventHook, @EventFilter);
16988 end;
16989 
16990 procedure TQtDialog.DetachEvents;
16991 begin
16992   if FDialogEventHook <> nil then
16993   begin
16994     QObject_hook_destroy(FDialogEventHook);
16995     FDialogEventHook := nil;
16996   end;
16997   inherited DetachEvents;
16998 end;
16999 
TQtDialog.DeliverMessagenull17000 function TQtDialog.DeliverMessage(var Msg;
17001   const AIsInputEvent: Boolean = False): LRESULT;
17002 begin
17003   try
17004     if FDialog.HandleAllocated then
17005     begin
17006       FDialog.Dispatch(TLMessage(Msg));
17007       Result := TLMessage(Msg).Result;
17008     end else
17009       Result := 0;
17010   except
17011     Application.HandleException(nil);
17012   end;
17013 end;
17014 
TQtDialog.SlotClosenull17015 function TQtDialog.SlotClose: Boolean; cdecl;
17016 begin
17017   Result := True;
17018   FDialog.DoCanClose(Result);
17019 end;
17020 
TQtDialog.EventFilternull17021 function TQtDialog.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
17022   cdecl;
17023 begin
17024   {we'll need it later. QDialog uses it's own eventLoop !}
17025   Result := False;
17026   QEvent_accept(Event);
17027   if LCLObject <> nil then
17028     Result := inherited EventFilter(Sender, Event);
17029 end;
17030 
TQtDialog.execnull17031 function TQtDialog.exec: Integer;
17032 {$IFDEF HASX11}
17033 var
17034   AWND: HWND;
17035 {$ENDIF}
17036 begin
17037   {$IF DEFINED(DARWIN) OR DEFINED(QT_DIALOGS_USE_QT_LOOP)}
17038   Result := QDialog_exec(QDialogH(Widget));
17039   {$ELSE}
17040   if QWidget_testAttribute(Widget, QtWA_DeleteOnClose) then
17041     Result := QDialog_exec(QDialogH(Widget))
17042   else
17043   begin
17044     QWidget_setWindowModality(Widget ,QtApplicationModal);
17045     QWidget_show(Widget);
17046     repeat
17047       QCoreApplication_processEvents();
17048       Application.Idle(true);
17049     until not QWidget_isVisible(Widget) or Application.Terminated;
17050     Result := QDialog_result(QDialogH(Widget));
17051   end;
17052   {$ENDIF}
17053   {$IFDEF HASX11}
17054   if (QtWidgetSet.WindowManagerName = 'xfwm4') and (QApplication_activeModalWidget() <> nil) then
17055   begin
17056     AWND := HwndFromWidgetH(QApplication_activeModalWidget());
17057     if (AWND <> 0) and (X11GetActivewindow <> TQtWidget(AWND).Widget) then
17058       X11Raise(QWidget_winID(TQtWidget(AWND).Widget));
17059   end;
17060   {$ENDIF}
17061 end;
17062 
17063 procedure TQtDialog.setSizeGripEnabled(const AEnabled: Boolean);
17064 begin
17065   QDialog_setSizeGripEnabled(QDialogH(Widget), AEnabled);
17066 end;
17067 
17068 { TQtViewPort }
17069 
TQtViewPort.CanPaintBackgroundnull17070 function TQtViewPort.CanPaintBackground: Boolean;
17071 begin
17072   Result := CanSendLCLMessage and getEnabled and
17073     (FChildOfComplexWidget in [ccwCustomControl, ccwScrollingWinControl]) and
17074     (LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
17075 end;
17076 
TQtViewPort.EventFilternull17077 function TQtViewPort.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
17078 var
17079   ScrollBar: QScrollBarH;
17080   ASize: TSize;
17081   AResizeEvent: QResizeEventH;
17082 begin
17083   Result := False;
17084   {$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
17085   if (QEvent_type(Event) = QEventResize) or
17086     (QEvent_type(Event) = QEventLayoutRequest) or
17087     (QEvent_type(Event) = QEventWheel) then
17088     WriteLn('TQtViewPort.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
17089       ' LCLObject=', dbgsName(LCLObject),
17090       ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
17091   {$endif}
17092   case QEvent_type(Event) of
17093     QEventShow,
17094     QEventShowToParent:
17095     begin
17096       {Qt does not track scrolled offset of widget when it''s not visible.issue #29239}
17097       if (FInvisibleX <> 0) or (FInvisibleY <> 0) then
17098       begin
17099         QWidget_scroll(Widget, FInvisibleX, FInvisibleY);
17100         FInvisibleX := 0;
17101         FInvisibleY := 0;
17102       end;
17103       Result := inherited EventFilter(Sender, Event);
17104     end;
17105     QEventMove: ; // do not flood LCL with viewport position
17106     QEventResize:
17107     begin
17108       // immediate update clientRect !
17109       if FOwner <> nil then
17110       begin
17111         {TQtCustomControl does not send resize event, it is done here
17112          when viewport geometry is finally updated by Qt.}
17113         ASize := FOwner.getSize;
17114         AResizeEvent := QResizeEvent_create(@ASize, @ASize);
17115         try
17116           // issue #28596 and others of TCustomControl clientrect related
17117           if CanAdjustClientRectOnResize and
17118             LCLObject.ClientRectNeedsInterfaceUpdate then
17119           begin
17120             {$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
17121             DebugLn('TQtViewPort.EventFilter invalidatingClientRectCache ',dbgsName(Self),' LCL=',dbgsName(LCLObject));
17122             {$ENDIF}
17123             LCLObject.InvalidateClientRectCache(False);
17124           end;
17125           FOwner.SlotResize(AResizeEvent);
17126         finally
17127           QEvent_destroy(AResizeEvent);
17128         end;
17129       end else
17130       begin
17131         {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
17132         DebugLn('TQtViewport: QEventResize wrong call....possible ERROR');
17133         {$ENDIF}
17134         LCLObject.DoAdjustClientRectChange;
17135       end;
17136     end;
17137     QEventWheel:
17138       if not getEnabled then
17139         inherited EventFilter(Sender, Event);
17140     QEventLayoutRequest:
17141     begin
17142       if FOwner <> nil then
17143       begin
17144         if LCLObject.ClientRectNeedsInterfaceUpdate then
17145         begin
17146           {$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize) OR DEFINED(VerboseSizeMsg)}
17147           if caspComputingBounds in LCLObject.AutoSizePhases then
17148             DebugLn('TQtViewport of ',dbgsName(LCLObject),' QEventLayoutRequest calling DoAdjustClientRectChange. CASP=TRUE *** !!!!');
17149           {$ENDIF}
17150           LCLObject.DoAdjustClientRectChange(True);
17151         end;
17152       end;
17153     end;
17154   else
17155     Result := inherited EventFilter(Sender, Event);
17156   end;
17157 end;
17158 
17159 procedure TQtViewPort.InitializeWidget;
17160 begin
17161   FInvisibleX := 0;
17162   FInvisibleY := 0;
17163   inherited InitializeWidget;
17164 end;
17165 
17166 procedure TQtViewPort.scroll(dx, dy: integer; ARect: PRect = nil);
17167 begin
17168   if not getVisible then
17169   begin
17170     FInvisibleX += dx;
17171     FInvisibleY += dy;
17172   end else
17173     inherited scroll(dx, dy, ARect);
17174   FScrollX := FScrollX + dx;
17175   FScrollY := FScrollY + dy;
17176 end;
17177 
17178 procedure TQtViewPort.stackUnder(AWidget: QWidgetH);
17179 begin
17180   // do nothing for TQtViewPort
17181   // inherited stackUnder(AWidget);
17182 end;
17183 
17184 {------------------------------------------------------------------------------
17185   Function: TQtAbstractScrollArea.horizontalScrollbar
17186   Params:  None
17187   Returns: Nothing
17188  ------------------------------------------------------------------------------}
17189 
17190 procedure TQtAbstractScrollArea.setScrollBarPolicy(AIndex: Boolean;
17191   const AValue: QtScrollBarPolicy);
17192 var
17193   Area: QAbstractScrollAreaH;
17194 begin
17195   Area := QAbstractScrollAreaH(Widget);
17196   if getScrollBarsPolicy(AIndex) <> AValue then
17197   begin
17198     if AIndex then
17199       QAbstractScrollArea_setVerticalScrollBarPolicy(Area, AValue)
17200     else
17201       QAbstractScrollArea_setHorizontalScrollBarPolicy(Area, AValue);
17202 
17203     if Assigned(LCLObject) and LCLObject.ClientRectNeedsInterfaceUpdate then
17204     begin
17205       if not (caspComputingBounds in LCLObject.AutoSizePhases) then
17206         LCLObject.DoAdjustClientRectChange(True);
17207     end;
17208   end;
17209 end;
17210 
EventFilternull17211 function TQtAbstractScrollArea.EventFilter(Sender: QObjectH; Event: QEventH
17212   ): Boolean; cdecl;
17213 var
17214   w: QWidgetH;
17215 begin
17216   Result := False;
17217 
17218   if (QEvent_type(Event) = QEventHide) then
17219   begin
17220     // issue #28880
17221     w := QWidget_mouseGrabber;
17222     if w <> nil then
17223     begin
17224       if w = Widget then
17225         ReleaseCapture
17226       else
17227       if w = viewportWidget then
17228         ReleaseCapture;
17229     end;
17230   end else
17231   if (QEvent_type(Event) = QEventResize) then
17232     // DebugLn('***TQtAbstractScrollArea.EventFilter QEventResize(',dbgsName(LCLObject),') EAT !')
17233   else
17234   if (QEvent_type(Event) = QEventWheel) and
17235     not (FChildOfComplexWidget in
17236       [ccwCustomControl, ccwScrollingWinControl, ccwScrollingWindow]) then
17237     // issue #25992.Do not propagate wheel event to lcl, it is done via TQtScrollBar.EventFilter.
17238   else
17239     Result:=inherited EventFilter(Sender, Event);
17240 end;
17241 
17242 procedure TQtAbstractScrollArea.grabMouse;
17243 var
17244   W: QWidgetH;
17245 begin
17246   W := viewportWidget;
17247   if (W <> nil) and QWidget_isVisible(W) and QWidget_isEnabled(W) then
17248     QWidget_grabMouse(W)
17249   else
17250     inherited grabMouse;
17251 end;
17252 
GetContainerWidgetnull17253 function TQtAbstractScrollArea.GetContainerWidget: QWidgetH;
17254 begin
17255   Result := viewportWidget;
17256 end;
17257 
getClientOffsetnull17258 function TQtAbstractScrollArea.getClientOffset: TPoint;
17259 begin
17260   with getClientBounds do
17261     Result := Point(Left, Top);
17262 end;
17263 
TQtAbstractScrollArea.getScrollFrameOffsetnull17264 function TQtAbstractScrollArea.getScrollFrameOffset: Integer;
17265 begin
17266   Result := 0;
17267   if (QStyle_styleHint(QApplication_style(),
17268     QStyleSH_ScrollView_FrameOnlyAroundContents) <> 0) then
17269       Result := QStyle_pixelMetric(QApplication_style(), QStylePM_ScrollView_ScrollBarSpacing, nil, Widget);
17270 end;
17271 
TQtAbstractScrollArea.getClientBoundsnull17272 function TQtAbstractScrollArea.getClientBounds: TRect;
17273 var
17274   HaveBar: Boolean;
17275   ASize: TSize;
17276 begin
17277   if not QWidget_testAttribute(viewportWidget, QtWA_Mapped) then
17278   begin
17279     ASize := getSize;
17280     QWidget_contentsRect(Widget, @Result);
17281     if (ASize.cx > 0) and (ASize.cy > 0) and (QStyle_styleHint(QApplication_style(),
17282           QStyleSH_ScrollView_FrameOnlyAroundContents) <= 0) then
17283     begin
17284       HaveBar := Assigned(FVScrollbar);
17285       if HaveBar and (verticalScrollBar.getVisibleTo(Widget)) then
17286         dec(Result.Right, verticalScrollBar.getWidth);
17287 
17288       HaveBar := Assigned(FHScrollbar);
17289       if HaveBar and (horizontalScrollBar.getVisibleTo(Widget)) then
17290         dec(Result.Bottom, horizontalScrollBar.getHeight);
17291     end;
17292     OffsetRect(Result, -Result.Left, -Result.Top);
17293     {$IF DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
17294     DebugLn('TQtAbstractScrollArea.GetClientBounds(not mapped): ',dbgsName(LCLObject),':',dbgsName(Self),' ',dbgs(Result),' ChildComplex=',dbgs(Ord(ChildOfComplexWidget)));
17295     {$ENDIF}
17296   end else
17297   begin
17298     QWidget_rect(viewportWidget, @Result);
17299     {$IF DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
17300     DebugLn('TQtAbstractScrollArea.GetClientBounds: ',dbgsName(LCLObject),':',dbgsName(Self),' ',dbgs(Result),' ChildComplex=',dbgs(Ord(ChildOfComplexWidget)));
17301     {$ENDIF}
17302   end;
17303 end;
17304 
getViewOriginnull17305 function TQtAbstractScrollArea.getViewOrigin: TPoint;
17306 var
17307   R: TRect;
17308 begin
17309   QWidget_rect(viewportWidget, @R);
17310   // current bindings (2.1) does not assign TopLeft so it's always 0,0
17311   Result := R.TopLeft;
17312 end;
17313 
viewportWidgetnull17314 function TQtAbstractScrollArea.viewportWidget: QWidgetH;
17315 begin
17316   Result := QAbstractScrollArea_viewport(QAbstractScrollAreaH(Widget));
17317 end;
17318 
getScrollBarsPolicynull17319 function TQtAbstractScrollArea.getScrollBarsPolicy(AIndex: Boolean
17320   ): QtScrollBarPolicy;
17321 var
17322   Area: QAbstractScrollAreaH;
17323 begin
17324   Area := QAbstractScrollAreaH(Widget);
17325   if AIndex then
17326     Result := QAbstractScrollArea_verticalScrollBarPolicy(Area)
17327   else
17328     Result := QAbstractScrollArea_horizontalScrollBarPolicy(Area);
17329 end;
17330 
horizontalScrollBarnull17331 function TQtAbstractScrollArea.horizontalScrollBar: TQtScrollBar;
17332 begin
17333   {$ifdef VerboseQt}
17334     WriteLn('TQAbstractScrollArea.horizontalScrollBar');
17335   {$endif}
17336   if FHScrollBar = nil then
17337   begin
17338     FHScrollBar := TQtScrollBar.CreateFrom(LCLObject,
17339       QAbstractScrollArea_horizontalScrollBar(QAbstractScrollAreaH(Widget)));
17340 
17341     if FHScrollBar.getTracking then
17342       FHScrollBar.TrackPos := SB_POLICY_CONTINUOUS
17343     else
17344       FHScrollBar.TrackPos := SB_POLICY_DISCONTINUOUS;
17345 
17346     FHScrollBar.ChildOfComplexWidget := ccwAbstractScrollArea;
17347     FHScrollBar.FOwner := Self;
17348     FHScrollBar.setFocusPolicy(QtNoFocus);
17349 
17350     if not FHScrollBar.CanChangeFontColor then
17351     begin
17352       with FHScrollBar do
17353       begin
17354         Palette.ForceColor := True;
17355         setDefaultColor(dctFont);
17356         Palette.ForceColor := False;
17357       end;
17358     end;
17359     FHScrollBar.AttachEvents;
17360   end;
17361   Result := FHScrollBar;
17362 end;
17363 
17364 {------------------------------------------------------------------------------
17365   Function: TQtAbstractScrollArea.verticalScrollbar
17366   Params:  None
17367   Returns: Nothing
17368  ------------------------------------------------------------------------------}
verticalScrollBarnull17369 function TQtAbstractScrollArea.verticalScrollBar: TQtScrollBar;
17370 begin
17371   {$ifdef VerboseQt}
17372     WriteLn('TQAbstractScrollArea.verticalScrollBar');
17373   {$endif}
17374   if FVScrollBar = nil then
17375   begin
17376     FVScrollbar := TQtScrollBar.CreateFrom(LCLObject,
17377       QAbstractScrollArea_verticalScrollBar(QAbstractScrollAreaH(Widget)));;
17378     if FVScrollBar.getTracking then
17379       FVScrollBar.TrackPos := SB_POLICY_CONTINUOUS
17380     else
17381       FVScrollBar.TrackPos := SB_POLICY_DISCONTINUOUS;
17382     FVScrollBar.ChildOfComplexWidget := ccwAbstractScrollArea;
17383     FVScrollBar.FOwner := Self;
17384     FVScrollBar.setFocusPolicy(QtNoFocus);
17385     if not FVScrollBar.CanChangeFontColor then
17386     begin
17387       with FVScrollBar do
17388       begin
17389         Palette.ForceColor := True;
17390         setDefaultColor(dctFont);
17391         Palette.ForceColor := False;
17392       end;
17393     end;
17394     FVScrollbar.AttachEvents;
17395   end;
17396   Result := FVScrollBar;
17397 end;
17398 
17399 procedure TQtAbstractScrollArea.setFocusPolicy(const APolicy: QtFocusPolicy);
17400 begin
17401   QWidget_setFocusPolicy(Widget, APolicy);
17402 end;
17403 
17404 {------------------------------------------------------------------------------
17405   Function: TQtAbstractScrollArea.setHorizontalScrollbar
17406   Params:  None
17407   Returns: Nothing
17408  ------------------------------------------------------------------------------}
17409 procedure TQtAbstractScrollArea.setHorizontalScrollBar(AScrollBar: TQtScrollBar);
17410 begin
17411   {$ifdef VerboseQt}
17412     WriteLn('TQAbstractScrollArea.setHorizontalScrollBar');
17413   {$endif}
17414   FHScrollbar := AScrollBar;
17415   if Assigned(FHScrollBar) then
17416     QAbstractScrollArea_setHorizontalScrollBar(QAbstractScrollAreaH(Widget), QScrollBarH(FHScrollBar.Widget));
17417 end;
17418 
17419 {------------------------------------------------------------------------------
17420   Function: TQtAbstractScrollArea.setVerticalScrollbar
17421   Params:  None
17422   Returns: Nothing
17423  ------------------------------------------------------------------------------}
17424 procedure TQtAbstractScrollArea.setVerticalScrollBar(AScrollBar: TQtScrollBar);
17425 begin
17426   {$ifdef VerboseQt}
17427     WriteLn('TQAbstractScrollArea.setVerticalScrollBar');
17428   {$endif}
17429   FVScrollBar := AScrollBar;
17430   if Assigned(FVScrollBar) then
17431     QAbstractScrollArea_setVerticalScrollBar(QAbstractScrollAreaH(Widget), QScrollBarH(FVScrollBar.Widget));
17432 end;
17433 
17434 {------------------------------------------------------------------------------
17435   Function: TQtAbstractScrollArea.setScrollStyle
17436   Params:  None
17437   Returns: Nothing
17438            Setting scrollbar''s policy (LCL TScrollStyle)
17439  -----------------------------------------------------------------------------}
17440 procedure TQtAbstractScrollArea.setScrollStyle(AScrollStyle: TScrollStyle);
17441 begin
17442   {$ifdef VerboseQt}
17443     WriteLn('TQAbstractScrollArea.setScrollStyle');
17444   {$endif}
17445   case AScrollStyle of
17446     ssNone:
17447     begin
17448       ScrollBarPolicy[True] := QtScrollBarAlwaysOff;
17449       ScrollBarPolicy[False] := QtScrollBarAlwaysOff;
17450     end;
17451     ssHorizontal, ssVertical:
17452     begin
17453       ScrollBarPolicy[AScrollStyle = ssVertical] := QtScrollBarAlwaysOn;
17454     end;
17455     ssBoth:
17456     begin
17457       ScrollBarPolicy[True] := QtScrollBarAlwaysOn;
17458       ScrollBarPolicy[False] := QtScrollBarAlwaysOn;
17459     end;
17460     ssAutoHorizontal, ssAutoVertical:
17461     begin
17462       ScrollBarPolicy[AScrollStyle = ssAutoVertical] := QtScrollBarAsNeeded;
17463     end;
17464     ssAutoBoth:
17465     begin
17466       ScrollBarPolicy[True] := QtScrollBarAsNeeded;
17467       ScrollBarPolicy[False] := QtScrollBarAsNeeded;
17468     end;
17469   end;
17470 
17471 end;
17472 
17473 procedure TQtAbstractScrollArea.SetNoMousePropagation(Sender: QWidgetH;
17474   const ANoMousePropagation: Boolean);
17475 begin
17476   // keep it so because sender can be dangling pointer from qt inside
17477   // mouse event of viewportWidget ! issue #26466
17478   if Sender = viewportWidget then
17479     inherited SetNoMousePropagation(Sender, False)
17480   else
17481     inherited SetNoMousePropagation(Sender, ANoMousePropagation);
17482 end;
17483 
17484 procedure TQtAbstractScrollArea.DestroyNotify(AWidget: TQtWidget);
17485 begin
17486   if AWidget = FHScrollbar then
17487     FHScrollbar := nil;
17488 
17489   if AWidget = FVScrollbar then
17490     FVScrollbar := nil;
17491 
17492   inherited DestroyNotify(AWidget);
17493 end;
17494 
17495 destructor TQtAbstractScrollArea.Destroy;
17496 begin
17497   FreeAndNil(FHScrollBar);
17498   FreeAndNil(FVScrollBar);
17499   inherited Destroy;
17500 end;
17501 
17502 procedure TQtAbstractScrollArea.Update(ARect: PRect);
17503 var
17504   P: TPoint;
17505 begin
17506   if ARect <> nil then
17507   begin
17508     P := getClientOffset;
17509     OffsetRect(ARect^, -P.X , -P.Y);
17510     QWidget_update(viewportWidget, ARect);
17511   end else
17512     QWidget_update(viewportWidget);
17513 end;
17514 
17515 procedure TQtAbstractScrollArea.UpdateRegion(ARgn: QRegionH);
17516 begin
17517   if ARgn <> nil then
17518     QWidget_update(viewportWidget, ARgn)
17519   else
17520     QWidget_update(viewportWidget);
17521 end;
17522 
17523 procedure TQtAbstractScrollArea.Repaint(ARect: PRect);
17524 var
17525   P: TPoint;
17526 begin
17527   if ARect <> nil then
17528   begin
17529     P := getClientOffset;
17530     OffsetRect(ARect^, -P.X , -P.Y);
17531     QWidget_repaint(viewportWidget, ARect);
17532   end else
17533     QWidget_repaint(viewportWidget);
17534 end;
17535 
17536 { TQtCustomControl }
17537 
17538 {------------------------------------------------------------------------------
17539   Function: TQtCustomControl.CreateWidget
17540   Params:  None
17541   Returns: Nothing
17542  ------------------------------------------------------------------------------}
CreateWidgetnull17543 function TQtCustomControl.CreateWidget(const AParams: TCreateParams):QWidgetH;
17544 var
17545   Parent: QWidgetH;
17546 begin
17547   // Creates the widget
17548   {$ifdef VerboseQt}
17549     WriteLn('TQtCustomControl.CreateWidget');
17550   {$endif}
17551   FHasPaint := True;
17552   FViewPortWidget := nil;
17553   if AParams.WndParent <> 0 then
17554     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
17555   else
17556     Parent := nil;
17557   Result := QLCLAbstractScrollArea_create(Parent);
17558 
17559   FChildOfComplexWidget := ccwCustomControl;
17560 
17561   if (LCLObject is TScrollingWinControl) then
17562     FChildOfComplexWidget := ccwScrollingWinControl
17563   else
17564     QWidget_setAutoFillBackground(Result, False);
17565 
17566   QWidget_setAttribute(Result, QtWA_InputMethodEnabled);
17567 end;
17568 
ProcessArrowKeysnull17569 function TQtCustomControl.ProcessArrowKeys: Boolean;
17570 begin
17571   Result := True;
17572 end;
17573 
17574 {------------------------------------------------------------------------------
17575   Function: TQtCustomControl.Destroy
17576   Params:  None
17577   Returns: Nothing
17578  ------------------------------------------------------------------------------}
17579 destructor TQtCustomControl.Destroy;
17580 begin
17581   {$ifdef VerboseQt}
17582     WriteLn('TQtCustomControl.Destroy');
17583   {$endif}
17584   viewportDelete;
17585   inherited Destroy;
17586 end;
17587 
EventFilternull17588 function TQtCustomControl.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
17589 begin
17590   Result := False;
17591   QEvent_accept(Event);
17592   if (LCLObject = nil) then
17593     exit;
17594 
17595   if (QEvent_type(Event) in [
17596                             QEventPaint,
17597                             QEventResize, // TQtViewport.EventFilter sends resize !
17598                             QEventMouseButtonPress,
17599                             QEventMouseButtonRelease,
17600                             QEventMouseButtonDblClick,
17601                             QEventContextMenu
17602                            ]) and
17603      (ClassType = TQtCustomControl) then
17604     Result := False
17605   else
17606   if QEvent_type(Event) = QEventWheel then
17607   begin
17608     if not getEnabled then
17609      inherited EventFilter(Sender, Event)
17610     else
17611     if not horizontalScrollBar.getVisible and
17612       not verticalScrollBar.getVisible then
17613       Result := inherited EventFilter(Sender, Event)
17614     else
17615       Result := False;
17616   end else
17617   {$IFDEF MSWINDOWS}
17618   {sometimes our IDE completely freezes, after screensaver activated
17619    or OS sleep state / hibernation under Win32 (if cursor stays
17620    inside SourceEditor), so if application is deactivated by OS
17621    we must release mouse grab. }
17622   if QEvent_type(Event) = QEventApplicationDeactivate then
17623   begin
17624     if HWND(Self) = GetCapture then
17625       ReleaseCapture;
17626     Result := inherited EventFilter(Sender, Event);
17627   end else
17628   {$ENDIF}
17629     Result := inherited EventFilter(Sender, Event);
17630 end;
17631 
17632 procedure TQtCustomControl.ViewPortEventFilter(event: QEventH; retval: PBoolean); cdecl;
17633 var
17634   MouseEventTyp: Boolean;
17635 begin
17636   {$ifdef VerboseViewPortEventFilter}
17637     WriteLn('ViewPortEventFilter ',QEvent_type(Event));
17638   {$endif}
17639 
17640   QEvent_accept(Event);
17641 
17642   case QEvent_type(Event) of
17643     QEventResize,
17644     QEventMouseButtonPress,
17645     QEventMouseButtonRelease,
17646     QEventMouseButtonDblClick,
17647     QEventMouseMove,
17648     QEventWheel,
17649     QEventContextMenu,
17650     QEventPaint:
17651     begin
17652       MouseEventTyp := (QEvent_type(Event) = QEventMouseButtonPress) or
17653         (QEvent_type(Event) = QEventMouseButtonRelease) or
17654         (QEvent_type(Event) = QEventMouseButtonDblClick) or
17655         (QEvent_type(Event) = QEventWheel) or
17656         (QEvent_type(Event) = QEventMouseMove);
17657 
17658       if (QEvent_type(Event) = QEventWheel) then
17659         QLCLAbstractScrollArea_InheritedViewportEvent(QLCLAbstractScrollAreaH(Widget), event);
17660 
17661       retval^ := True;
17662 
17663       if FViewPortWidget <> nil then
17664         Viewport.EventFilter(ViewPortWidget, Event);
17665 
17666       // do not allow qt to call notifications on user input events (mouse)
17667       // otherwise we can crash since our object maybe does not exist
17668       // after mouse clicks
17669       if not MouseEventTyp then
17670         QEvent_ignore(Event);
17671     end;
17672   else
17673     retval^ := QLCLAbstractScrollArea_InheritedViewportEvent(QLCLAbstractScrollAreaH(Widget), event);
17674   end;
17675 end;
17676 
17677 procedure TQtCustomControl.DestroyNotify(AWidget: TQtWidget);
17678 begin
17679   if AWidget = FCornerWidget then
17680     FCornerWidget := nil;
17681 
17682   if AWidget = FViewPortWidget then
17683     FViewPortWidget := nil;
17684 
17685   inherited DestroyNotify(AWidget);
17686 end;
17687 
CanAdjustClientRectOnResizenull17688 function TQtCustomControl.CanAdjustClientRectOnResize: Boolean;
17689 begin
17690   // DoAdjustClientRectChange(); is called from TQtViewport resize event !
17691   Result := True;
17692 end;
17693 
17694 {------------------------------------------------------------------------------
17695   Function: TQtCustomControl.cornerWidget
17696   Params:  None
17697   Returns: Nothing
17698  ------------------------------------------------------------------------------}
cornerWidgetnull17699 function TQtCustomControl.cornerWidget: TQtWidget;
17700 begin
17701   {$ifdef VerboseQt}
17702     WriteLn('TQAbstractScrollArea.cornerWidget');
17703   {$endif}
17704   Result := FCornerWidget;
17705 end;
17706 
MapToGlobalnull17707 function TQtCustomControl.MapToGlobal(APt: TPoint;
17708   const AWithScrollOffset: Boolean = False): TPoint;
17709 var
17710   Pt: TPoint;
17711 begin
17712   Result := inherited MapToGlobal(APt);
17713   if AWithScrollOffset and (ChildOfComplexWidget = ccwScrollingWinControl) then
17714   begin
17715     Pt := viewport.ScrolledOffset;
17716     dec(Result.X, Pt.X);
17717     dec(Result.Y, Pt.Y);
17718   end;
17719 end;
17720 
MapFromGlobalnull17721 function TQtCustomControl.MapFromGlobal(APt: TPoint;
17722   const AWithScrollOffset: Boolean = False): TPoint;
17723 begin
17724   //TODO: see what to do with ccwScrollingWinControl
17725   Result := inherited MapFromGlobal(APt);
17726 end;
17727 
17728 {------------------------------------------------------------------------------
17729   Function: TQtCustomControl.setCornerWidget
17730   Params:  TQtWidget
17731   Returns: Nothing
17732  ------------------------------------------------------------------------------}
17733 procedure TQtCustomControl.setCornerWidget(AWidget: TQtWidget);
17734 begin
17735   {$ifdef VerboseQt}
17736     WriteLn('TQAbstractScrollArea.setCornerWidget');
17737   {$endif}
17738   FCornerWidget := AWidget;
17739   if Assigned(FCornerWidget) then
17740     QAbstractScrollArea_setCornerWidget(QAbstractScrollAreaH(Widget), FCornerWidget.Widget)
17741   else
17742     QAbstractScrollArea_setCornerWidget(QAbstractScrollAreaH(Widget), NiL);
17743 end;
17744 
17745 procedure TQtCustomControl.setCursor(const ACursor: QCursorH);
17746 begin
17747   if (LCLObject is TCustomControl) and HasPaint then
17748     viewport.setCursor(ACursor)
17749   else
17750     inherited setCursor(ACursor);
17751 end;
17752 
17753 procedure TQtCustomControl.setViewport(const AViewPort: QWidgetH);
17754 begin
17755   QAbstractScrollArea_setViewport(QAbstractScrollAreaH(Widget), AViewPort);
17756 end;
17757 
17758 procedure TQtCustomControl.setVisible(AVisible: Boolean);
17759 begin
17760   inherited setVisible(AVisible);
17761   if FViewPortWidget <> nil then
17762     FViewPortWidget.setVisible(AVisible);
17763 end;
17764 
17765 {------------------------------------------------------------------------------
17766   Function: TQtCustomControl.viewport
17767   Params:  None
17768   Returns: viewport widget of QAbstractScrollArea
17769  ------------------------------------------------------------------------------}
viewportnull17770 function TQtCustomControl.viewport: TQtViewPort;
17771 begin
17772   viewportNeeded;
17773   Result := FViewPortWidget;
17774 end;
17775 
17776 procedure TQtCustomControl.preferredSize(var PreferredWidth,
17777   PreferredHeight: integer; WithThemeSpace: Boolean);
17778 begin
17779   if LCLObject is TCustomControl then
17780   begin
17781     PreferredWidth := 0;
17782     PreferredHeight := 0;
17783   end else
17784     inherited preferredSize(PreferredWidth, PreferredHeight, WithThemeSpace);
17785 end;
17786 
17787 {------------------------------------------------------------------------------
17788   Function: TQtCustomControl.viewportNeeded
17789   Params:  None
17790   Returns: Nothing
17791            Creates viewport widget for QAbstractScrollArea
17792  ------------------------------------------------------------------------------}
17793 procedure TQtCustomControl.viewportNeeded;
17794 var
17795   AParams: TCreateParams;
17796 begin
17797   if FViewPortWidget <> niL then
17798     exit;
17799   FillChar(AParams{%H-}, SizeOf(AParams), #0);
17800   FViewPortWidget := TQtViewPort.Create(LCLObject, AParams);
17801   FViewPortWidget.setFocusProxy(Widget);
17802   FViewPortWidget.setBackgroundRole(QPaletteNoRole);
17803   FViewPortWidget.setAutoFillBackground(False);
17804   FViewPortWidget.FOwner := Self;
17805   FViewPortWidget.FChildOfComplexWidget := FChildOfComplexWidget;
17806 
17807   // some events will be redirected to scroll area
17808   FViewPortWidget.AttachEvents;
17809 
17810   QLCLAbstractScrollArea_override_viewportEvent(QLCLAbstractScrollAreaH(Widget),
17811     @ViewPortEventFilter);
17812 
17813   setViewport(FViewPortWidget.Widget);
17814 end;
17815 
17816 procedure TQtCustomControl.viewportDelete;
17817 begin
17818   if Assigned(FViewPortWidget) then
17819   begin
17820     QLCLAbstractScrollArea_override_viewportEvent(QLCLAbstractScrollAreaH(Widget),
17821       QLCLAbstractScrollArea_viewportEvent_Override(NilMethod));
17822     FViewPortWidget.FOwner := nil;
17823     FViewPortWidget.Release;
17824     FViewPortWidget := nil;
17825   end;
17826 end;
17827 
17828   { TQtCalendar }
17829 
GetDateTimenull17830 function TQtCalendar.GetDateTime: TDateTime;
17831 var
17832   Date: QDateH;
17833 begin
17834   Date := QDate_create();
17835   QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), Date);
17836   AYear := QDate_year(Date);
17837   AMonth := QDate_month(Date);
17838   ADay := QDate_day(Date);
17839   QDate_destroy(Date);
17840   Result := EncodeDate(AYear, AMonth, ADay);
17841 end;
17842 
17843 procedure TQtCalendar.SetDateTime(const AValue: TDateTime);
17844 var
17845   Date: QDateH;
17846 begin
17847   DecodeDate(AValue, AYear, AMonth, ADay);
17848   Date := QDate_create(AYear, AMonth, ADay);
17849   QCalendarWidget_setCurrentPage(QCalendarWidgetH(Widget),
17850     AYear, AMonth);
17851   SetSelectedDate(Date);
17852   QDate_destroy(Date);
17853 end;
17854 
17855 procedure TQtCalendar.SetSelectedDate(const AValue: QDateH);
17856 begin
17857   QCalendarWidget_setSelectedDate(QCalendarWidgetH(Widget), AValue);
17858 end;
17859 
17860 {------------------------------------------------------------------------------
17861   Function: TQtCalendar.CreateWidget
17862   Params:  None
17863   Returns: Nothing
17864  ------------------------------------------------------------------------------}
CreateWidgetnull17865 function TQtCalendar.CreateWidget(const AParams: TCreateParams):QWidgetH;
17866 var
17867   Parent: QWidgetH;
17868 begin
17869   // Creates the widget
17870   {$ifdef VerboseQt}
17871     WriteLn('TQtCalendar.Create');
17872   {$endif}
17873   FMouseDoubleClicked := False;
17874   if AParams.WndParent <> 0 then
17875     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
17876   else
17877     Parent := nil;
17878   Result := QCalendarWidget_create(Parent);
17879 end;
17880 
17881 procedure TQtCalendar.AttachEvents;
17882 var
17883   i: integer;
17884   Children: TPtrIntArray;
17885   AnObject: QObjectH;
17886   WP: QWidgetH;
17887 begin
17888   inherited AttachEvents;
17889 
17890   FClickedHook := QCalendarWidget_hook_create(Widget);
17891   FActivatedHook := QCalendarWidget_hook_create(Widget);
17892   FSelectionChangedHook := QCalendarWidget_hook_create(Widget);
17893   FCurrentPageChangedHook := QCalendarWidget_hook_create(Widget);
17894 
17895   QCalendarWidget_hook_hook_clicked(FClickedHook, @SignalClicked);
17896 
17897   QCalendarWidget_hook_hook_activated(FActivatedHook, @SignalActivated);
17898 
17899   QCalendarWidget_hook_hook_selectionChanged(FSelectionChangedHook, @SignalSelectionChanged);
17900 
17901   QCalendarWidget_hook_hook_currentPageChanged(FCurrentPageChangedHook, @SignalCurrentPageChanged);
17902 
17903   QObject_children(Widget, @Children);
17904   for i := 0 to High(Children) do
17905   begin
17906     AnObject := QObjectH(Children[i]);
17907     if QObject_isWidgetType(AnObject) then
17908     begin
17909       {do not localize !!}
17910       if QObject_inherits(AnObject,'QAbstractScrollArea') then
17911       begin
17912         WP := QAbstractScrollArea_viewport(QAbstractScrollAreaH(AnObject));
17913         QWidget_setMouseTracking(WP, True);
17914         FCalViewportEventHook := QObject_hook_create(WP);
17915         QObject_hook_hook_events(FCalViewportEventHook, @calViewportEventFilter);
17916         setProperty(QWidgetH(AnObject), 'lclwidget', Int64(PtrUInt(Self)));
17917         FCalViewAreaEventHook := QObject_hook_create(QWidgetH(AnObject));
17918         QObject_hook_hook_events(FCalViewAreaEventHook, @AreaViewEventFilter);
17919       end;
17920     end;
17921   end;
17922 end;
17923 
17924 procedure TQtCalendar.DetachEvents;
17925 begin
17926   if FCalViewAreaEventHook <> nil then
17927   begin
17928     QObject_hook_destroy(FCalViewAreaEventHook);
17929     FCalViewAreaEventHook := nil;
17930   end;
17931   if FCalViewportEventHook <> nil then
17932   begin
17933     QObject_hook_destroy(FCalViewportEventHook);
17934     FCalViewportEventHook := nil;
17935   end;
17936   if FClickedHook <> nil then
17937   begin
17938     QCalendarWidget_hook_destroy(FClickedHook);
17939     FClickedHook := nil;
17940   end;
17941   if FActivatedHook <> nil then
17942   begin
17943     QCalendarWidget_hook_destroy(FActivatedHook);
17944     FActivatedHook := nil;
17945   end;
17946   if FSelectionChangedHook <> nil then
17947   begin
17948     QCalendarWidget_hook_destroy(FSelectionChangedHook);
17949     FSelectionChangedHook := nil;
17950   end;
17951   if FCurrentPageChangedHook <> nil then
17952   begin
17953     QCalendarWidget_hook_destroy(FCurrentPageChangedHook);
17954     FCurrentPageChangedHook := nil;
17955   end;
17956   inherited DetachEvents;
17957 end;
17958 
EventFilternull17959 function TQtCalendar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
17960   cdecl;
17961 begin
17962   Result := False;
17963   if (QEvent_Type(Event) = QEventKeyPress) or (QEvent_Type(Event) = QEventKeyRelease) then
17964     exit;
17965   Result := inherited EventFilter(Sender, Event);
17966 end;
17967 
AreaViewEventFilternull17968 function TQtCalendar.AreaViewEventFilter(Sender: QObjectH; Event: QEventH
17969   ): Boolean; cdecl;
17970 var
17971   ADate: QDateH;
17972   AKey: Integer;
17973 begin
17974   Result := False;
17975   if (LCLObject <> nil) and ((QEvent_type(Event) = QEventKeyPress) or
17976     (QEvent_type(Event) = QEventKeyRelease)) then
17977   begin
17978     AKey := QKeyEvent_key(QKeyEventH(Event));
17979     Result := SlotKey(Widget, Event);
17980     if (QEvent_type(Event) = QEventKeyRelease) and
17981       ( (AKey = QtKey_Up) or (AKey = QtKey_Left) or
17982         (AKey = QtKey_Right) or (AKey = QtKey_Down) ) then
17983     begin
17984       ADate := QDate_create();
17985       QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), ADate);
17986       DeliverDayChanged(ADate);
17987       QDate_destroy(ADate);
17988     end;
17989   end;
17990 end;
17991 
calViewportEventFilternull17992 function TQtCalendar.calViewportEventFilter(Sender: QObjectH; Event: QEventH
17993   ): Boolean; cdecl;
17994 begin
17995   {we install only mouse dblclick event on QCalendar viewport,
17996    since inside signalActivated we don't know is it signalled from
17997    dblclick or by pressing return key.}
17998   Result := False;
17999   QEvent_accept(Event);
18000   if (LCLObject <> nil) then
18001   begin
18002     case QEvent_type(Event) of
18003       QEventMouseMove: Result := SlotMouseMove(Sender, Event);
18004       QEventEnter,
18005       QEventLeave: Result := SlotMouseEnter(Sender, Event);
18006       QEventMouseButtonDblClick: FMouseDoubleClicked := True;
18007       QEventWheel:
18008         begin
18009           if not getEnabled then
18010           begin
18011             QEvent_ignore(Event);
18012             QWidget_setAttribute(QWidgetH(Sender), QtWA_NoMousePropagation, False);
18013           end;
18014         end;
18015     end;
18016   end;
18017 end;
18018 
HitTestnull18019 function TQtCalendar.HitTest(const APoint: TPoint): byte;
18020 var
18021   Layout: QLayoutH;
18022   CalendarBody: QWidgetH;
18023   HeaderRect, BodyRect: TRect;
18024   AQtPoint: TQtPoint;
18025   Index: QModelIndexH;
18026 begin
18027   Result := 0;
18028   Layout := QWidget_layout(Widget);
18029   // layout must have 2 items:
18030   // 1 - navigation bar
18031   // 2 - calendar model
18032   if QLayout_count(Layout) <> 2 then
18033     Exit;
18034   QLayoutItem_geometry(QLayout_itemAt(Layout, 0), @HeaderRect);
18035   QLayoutItem_geometry(QLayout_itemAt(Layout, 1), @BodyRect);
18036   if PtInRect(HeaderRect, APoint) then
18037   begin
18038     // we are in the header
18039     Result := 3;
18040     // todo: detail result more - button / month / year
18041   end
18042   else
18043   if PtInRect(BodyRect, APoint) then
18044   begin
18045     CalendarBody := QLayoutItem_widget(QLayout_itemAt(Layout, 1));
18046     AQtPoint := QtPoint(APoint.X, APoint.Y);
18047     QWidget_mapFrom(CalendarBody, @AQtPoint, Widget, @AQtPoint);
18048     Index := QModelIndex_create();
18049     try
18050       QTableView_indexAt(QTableWidgetH(CalendarBody), Index, @AQtPoint);
18051       if (QCalendarWidget_horizontalHeaderFormat(QCalendarWidgetH(Widget)) = QCalendarWidgetNoHorizontalHeader) or
18052          (QModelIndex_row(Index) > 0) then
18053       begin
18054         if (QCalendarWidget_verticalHeaderFormat(QCalendarWidgetH(Widget)) = QCalendarWidgetNoVerticalHeader) or
18055            (QModelIndex_column(Index) > 0) then
18056           Result := 1
18057         else
18058           Result := 2;
18059       end;
18060     finally
18061       QModelIndex_destroy(Index);
18062     end;
18063   end;
18064 end;
18065 
18066 procedure TQtCalendar.SetDisplaySettings(
18067       const AHHdrFmt: QCalendarWidgetHorizontalHeaderFormat;
18068       const AVHdrFmt: QCalendarWidgetVerticalHeaderFormat;
18069       const ASelMode: QCalendarWidgetSelectionMode;
18070       const ANavBarVisible: Boolean; const AGridVisible: Boolean;
18071       const AStartMonday: Boolean);
18072 begin
18073   QCalendarWidget_setHorizontalHeaderFormat(QCalendarWidgetH(Widget), AHHdrFmt);
18074   QCalendarWidget_setNavigationBarVisible(QCalendarWidgetH(Widget), ANavBarVisible);
18075   QCalendarWidget_setVerticalHeaderFormat(QCalendarWidgetH(Widget), AVHdrFmt);
18076   QCalendarWidget_setGridVisible(QCalendarWidgetH(Widget), AGridVisible);
18077   if AStartMonday then
18078     QCalendarWidget_setFirstDayOfWeek(QCalendarWidgetH(Widget), QtMonday)
18079   else
18080     QCalendarWidget_setFirstDayOfWeek(QCalendarWidgetH(Widget), QtSunday);
18081   QCalendarWidget_setSelectionMode(QCalendarWidgetH(Widget), ASelMode);
18082 end;
18083 
TQtCalendar.DeliverDayChangednull18084 function TQtCalendar.DeliverDayChanged(ADate: QDateH): boolean;
18085 var
18086   y,m,d: Integer;
18087   Msg: TLMessage;
18088 begin
18089   Result := False;
18090   FillChar(Msg{%H-}, SizeOf(Msg), #0);
18091   Msg.Msg := LM_DAYCHANGED;
18092   y := QDate_year(ADate);
18093   m := QDate_month(ADate);
18094   d := QDate_day(ADate);
18095   Result := (y <> aYear) or (m <> aMonth) or (d <> aDay);
18096   if Result then
18097     DeliverMessage(Msg);
18098   aYear := y;
18099   aMonth := m;
18100   aDay := d;
18101 end;
18102 
18103 {------------------------------------------------------------------------------
18104   Function: TQtCalendar.SignalActivated
18105   Params:  None
18106   Returns: Nothing
18107            Sends signal when RETURN pressed on selected date.
18108  ------------------------------------------------------------------------------}
18109 procedure TQtCalendar.SignalActivated(ADate: QDateH); cdecl;
18110 var
18111   AKeyEvent: QKeyEventH;
18112   AMouseEvent: QMouseEventH;
18113   APos, AGlobalPos: TQtPoint;
18114   APosF, AGlobalPosF: TQtPointF;
18115 begin
18116   {$IFDEF VerboseQt}
18117   writeln('TQtCalendar.signalActivated ');
18118   {$ENDIF}
18119 
18120   DeliverDayChanged(ADate);
18121 
18122   {avoid OnAcceptDate() to trigger twice if doubleclicked
18123    via FMouseDoubleClicked, also send dummy Key events to LCL when item
18124    activated (only QtKey_Return activates)}
18125   if not FMouseDoubleClicked then
18126   begin
18127     AKeyEvent := QKeyEvent_create(QEventKeyPress, QtKey_Return, QtNoModifier);
18128     SlotKey(Widget, AKeyEvent);
18129     QEvent_destroy(AKeyEvent);
18130     AKeyEvent := QKeyEvent_create(QEventKeyRelease, QtKey_Return, QtNoModifier);
18131     SlotKey(Widget, AKeyEvent);
18132     QEvent_destroy(AKeyEvent);
18133   end else
18134   begin
18135     FMouseDoubleClicked := False;
18136     if QWidget_underMouse(Widget) then
18137     begin
18138       QCursor_pos(@AGlobalPos);
18139       QWidget_mapFromGlobal(Widget, @APos, @AGlobalPos);
18140       APosF.X := APos.X;
18141       APosF.Y := APos.Y;
18142       AGlobalPosF.X := AGlobalPos.X;
18143       AGlobalPosF.Y := AGlobalPos.Y;
18144       AMouseEvent := QMouseEvent_create(QEventMouseButtonDblClick, @APosF,
18145         @AGlobalPosF, QtLeftButton, QtLeftButton,
18146         QGUIApplication_keyboardModifiers());
18147       SlotMouse(Widget, AMouseEvent);
18148       QMouseEvent_destroy(AMouseEvent);
18149     end;
18150   end;
18151 end;
18152 
18153 {------------------------------------------------------------------------------
18154   Function: TQtCalendar.SignalClicked
18155   Params:  None
18156   Returns: Nothing
18157            Sends msg LM_DAYCHANGED when OldDate<>NewDate
18158  ------------------------------------------------------------------------------}
18159 procedure TQtCalendar.SignalClicked(ADate: QDateH); cdecl;
18160 var
18161   AEvent: QMouseEventH;
18162   APos, AGlobalPos: TQtPoint;
18163   APosF, AGlobalPosF: TQtPointF;
18164 begin
18165   {$IFDEF VerboseQt}
18166   writeln('TQtCalendar.signalClicked');
18167   {$ENDIF}
18168   DeliverDayChanged(ADate);
18169 
18170   if QWidget_underMouse(Widget) then
18171   begin
18172     {we create dummy event for LCL, and call directly SlotMouse() - no need
18173     to send it via event loop}
18174     QCursor_pos(@AGlobalPos);
18175     QWidget_mapFromGlobal(Widget, @APos, @AGlobalPos);
18176     APosF.X := APos.X;
18177     APosF.Y := APos.Y;
18178     AGlobalPosF.X := AGlobalPos.X;
18179     AGlobalPosF.Y := AGlobalPos.Y;
18180     AEvent := QMouseEvent_create(QEventMouseButtonPress, @APosF, @AGlobalPosF,
18181       QtLeftButton, QtLeftButton, QGUIApplication_keyboardModifiers());
18182     SlotMouse(Widget, AEvent);
18183     QMouseEvent_destroy(AEvent);
18184     AEvent := QMouseEvent_create(QEventMouseButtonRelease, @APosF, @AGlobalPosF,
18185       QtLeftButton, QtLeftButton, QGUIApplication_keyboardModifiers());
18186     SlotMouse(Widget, AEvent);
18187     QMouseEvent_destroy(AEvent);
18188   end;
18189 end;
18190 
18191 {------------------------------------------------------------------------------
18192   Function: TQtCalendar.SignalSelectionChanged
18193   Params:  None
18194   Returns: Nothing
18195 
18196   Notes: no event for date changed by keyboard ?!?
18197    always triggers even if selection isn't changed ...
18198    this is not Qt4 bug ... tested with pure Qt C++ app
18199  ------------------------------------------------------------------------------}
18200 procedure TQtCalendar.SignalSelectionChanged; cdecl;
18201 var
18202   Msg: TLMessage;
18203 begin
18204   {$IFDEF VerboseQt}
18205   writeln('TQtCalendar.SignalSelectionChanged');
18206   {$ENDIF}
18207   if InUpdate then
18208     exit;
18209   FillChar(Msg{%H-}, SizeOf(Msg), #0);
18210   Msg.Msg := LM_SELCHANGE;
18211   DeliverMessage(Msg);
18212 end;
18213 
18214 {------------------------------------------------------------------------------
18215   Function: TQtCalendar.SignalCurrentPageChanged
18216   Params:  None
18217   Returns: Nothing
18218 
18219   Notes: fixme what's wrong with those values ?!?
18220    with pure Qt C++ app this works ok, but via bindings get
18221    impossible year & month values ...
18222  ------------------------------------------------------------------------------}
18223 procedure TQtCalendar.signalCurrentPageChanged(p1, p2: Integer); cdecl;
18224 var
18225   Msg: TLMessage;
18226   ADate: QDateH;
18227   HasChanges: Boolean;
18228   TempYear, TempMonth: Integer;
18229 begin
18230   {$IFDEF VerboseQt}
18231   writeln('TQtCalendar.SignalCurrentPageChanged p1=',p1,' p2=',p2,' AMonth=',AMonth,' AYear=',AYear);
18232   {$ENDIF}
18233   if InUpdate then
18234     exit;
18235   TempYear := AYear;
18236   TempMonth := AMonth;
18237   FillChar(Msg{%H-}, SizeOf(Msg), #0);
18238   HasChanges := (TempYear <> p1) or (TempMonth <> p2);
18239 
18240   if HasChanges then
18241   begin
18242     ADate := QDate_create();
18243     try
18244       QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), ADate);
18245       QDate_setDate(ADate, p1, p2, QDate_day(ADate));
18246       SetSelectedDate(ADate);
18247     finally
18248       QDate_destroy(ADate);
18249     end;
18250   end;
18251 
18252   if TempYear <> p1 then
18253   begin
18254     Msg.Msg := LM_YEARCHANGED;
18255     DeliverMessage(Msg);
18256   end;
18257 
18258   if TempMonth <> p2 then
18259   begin
18260     Msg.Msg := LM_MONTHCHANGED;
18261     DeliverMessage(Msg);
18262   end;
18263 
18264   if HasChanges then
18265   begin
18266     Msg.Msg := LM_CHANGED;
18267     DeliverMessage(Msg);
18268   end;
18269 end;
18270 
18271 { TQtHintWindow }
18272 
CreateWidgetnull18273 function TQtHintWindow.CreateWidget(const AParams: TCreateParams): QWidgetH;
18274 var
18275   Parent: QWidgetH;
18276 begin
18277   FHasPaint := True;
18278   FNeedRestoreVisible := False;
18279   if AParams.WndParent <> 0 then
18280     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
18281   else
18282   if QApplication_activeModalWidget <> nil then
18283     Parent := QApplication_activeModalWidget
18284   else
18285     Parent := nil;
18286   Result := QWidget_create(Parent, QtToolTip);
18287   FDeleteLater := True;
18288   MenuBar := nil;
18289   {$IFDEF QTSCROLLABLEFORMS}
18290   ScrollArea := nil;
18291   {$ENDIF}
18292 end;
18293 
18294 procedure TQtHintWindow.InitializeWidget;
18295 begin
18296   inherited InitializeWidget;
18297   {$IFDEF HASX11}
18298   QtWidgetSet.AddHintHandle(Self);
18299   {$ENDIF}
18300 end;
18301 
18302 procedure TQtHintWindow.DeInitializeWidget;
18303 begin
18304   {$IFDEF HASX11}
18305   QtWidgetSet.RemoveHintHandle(Self);
18306   {$ENDIF}
18307   inherited DeInitializeWidget;
18308 end;
18309 
CanPaintBackgroundnull18310 function TQtHintWindow.CanPaintBackground: Boolean;
18311 begin
18312   Result := CanSendLCLMessage and getEnabled and
18313     (LCLObject.Color <> clDefault);
18314 end;
18315 
18316 procedure TQtHintWindow.SetDefaultColorRoles;
18317 begin
18318   WidgetColorRole := QPaletteToolTipBase;
18319   TextColorRole := QPaletteToolTipText;
18320 end;
18321 
18322 procedure TQtHintWindow.setVisible(AVisible: Boolean);
18323 var
18324   D: TRect;
18325   R: TRect;
18326   Pt: TQtPoint;
18327   ScreenNumber: integer;
18328 begin
18329   // must use ClassType comparision here since qt is buggy about hints.#16551
18330   if AVisible and
18331     ((LCLObject.ClassType = THintWindow) or
18332       (LCLObject.InheritsFrom(THintWindow))) then
18333   begin
18334     R := getGeometry;
18335 
18336     if QDesktopWidget_isVirtualDesktop(QApplication_desktop()) then
18337     begin
18338       Pt.x := R.Left;
18339       Pt.y := R.Top;
18340       ScreenNumber := QDesktopWidget_screenNumber(QApplication_desktop(), @Pt);
18341     end
18342     else
18343     begin
18344       if Widget <> nil then
18345         ScreenNumber := QDesktopWidget_screenNumber(QApplication_desktop(), Widget)
18346       else
18347         ScreenNumber := 0;
18348     end;
18349     {$IFDEF DARWIN}
18350     QDesktopWidget_availableGeometry(QApplication_desktop() ,@D, ScreenNumber);
18351     {$ELSE}
18352     QDesktopWidget_screenGeometry(QApplication_desktop() ,@D, ScreenNumber);
18353     {$ENDIF}
18354 
18355     // place hint window within monitor rect
18356     if R.Right-R.Left > D.Right-D.Left then // check width
18357       R.Right := R.Left + D.Right-D.Left;
18358     if R.Bottom-R.Top > D.Bottom-D.Top then // check height
18359       R.Bottom := R.Top + D.Bottom-D.Top;
18360     if R.Left < D.Left then
18361       OffsetRect(R, D.Left-R.Left, 0);
18362     if R.Top < D.Top then
18363       OffsetRect(R, 0, D.Top-R.Top);
18364     if (R.Right > D.Right) then
18365       OffsetRect(R, D.Right-R.Right, 0);
18366     if (R.Bottom > D.Bottom) then
18367       OffsetRect(R, 0, D.Bottom-R.Bottom);
18368 
18369     move(R.Left, R.Top);
18370   end;
18371   inherited setVisible(AVisible);
18372 end;
18373 
18374 { TQtPage }
18375 
CreateWidgetnull18376 function TQtPage.CreateWidget(const AParams: TCreateParams): QWidgetH;
18377 var
18378   Parent: QWidgetH;
18379 begin
18380   FHasPaint := True;
18381   if AParams.WndParent <> 0 then
18382     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
18383   else
18384     Parent := nil;
18385   Result := QWidget_create(Parent);
18386 end;
18387 
TQtPage.EventFilternull18388 function TQtPage.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
18389 var
18390   ASize: TSize;
18391   ACapture: HWND;
18392   B: Boolean;
18393 begin
18394   Result := False;
18395   if LCLObject = nil then
18396     exit;
18397   if (QEvent_type(Event) = QEventResize) then
18398   begin
18399     if (csDestroying in LCLObject.ComponentState) or
18400       (csDestroyingHandle in LCLObject.ControlState) then
18401         exit;
18402     if not testAttribute(QtWA_Mapped) then
18403     begin
18404       ASize := QResizeEvent_size(QResizeEventH(Event))^;
18405       {$IFDEF VerboseQtResize}
18406       DebugLn('TQtPage.EventFilter widget is not mapped, resize event size=',dbgs(ASize));
18407       {$ENDIF}
18408       if (ASize.cx = 0) and (ASize.cy = 0) then
18409       begin
18410         ASize.cx := LCLObject.Width;
18411         ASize.cy := LCLObject.Height;
18412         {$IFDEF VerboseQtResize}
18413         DebugLn('TQtPage.EventFilter sending LCL size as size=',dbgs(ASize),' since our size is still 0x0');
18414         {$ENDIF}
18415       end;
18416       DelayResizeEvent(QWidgetH(Sender), ASize);
18417       exit;
18418     end;
18419   end else
18420   if (QEvent_type(Event) = QEventShow) then
18421   begin
18422     if Assigned(DragManager) and DragManager.IsDragging then
18423       ACapture := GetCapture
18424     else
18425       ACapture := 0;
18426     B := (ACapture <> 0) and (ACapture <> HWND(Self));
18427     Result := inherited EventFilter(Sender, Event);
18428     if B then
18429     begin
18430       QtWidgetSet.InvalidateWidgetAtCache;
18431       SetCapture(0);
18432       SetCapture(HWND(Self));
18433     end;
18434   end else
18435   Result := inherited EventFilter(Sender, Event);
18436 end;
18437 
TQtPage.getIconnull18438 function TQtPage.getIcon: QIconH;
18439 begin
18440   Result := FIcon;
18441 end;
18442 
getIndexnull18443 function TQtPage.getIndex(const ATextChanging: Boolean = False): Integer;
18444 var
18445   AParent: QTabWidgetH;
18446 
CanReturnIndexnull18447   function CanReturnIndex: Boolean;
18448   begin
18449     Result := AParent <> nil;
18450     if Result then
18451       Result := QWidget_isVisible(AParent) or LCLObject.HandleObjectShouldBeVisible;
18452   end;
18453 
18454 begin
18455   AParent := getTabWidget;
18456   if CanReturnIndex or ATextChanging then
18457     Result := QTabWidget_indexOf(AParent, Widget)
18458   else
18459   if not QObject_inherits(QWidget_parentWidget(Widget),'QStackedWidget') then
18460     Result := 0
18461   else
18462     Result := -1;
18463 end;
18464 
getTabWidgetnull18465 function TQtPage.getTabWidget: QTabWidgetH;
18466 var
18467   AParent: QWidgetH;
18468 begin
18469   // it is placed to the stack widget and stack widget into tab widget
18470   AParent := QWidget_parentWidget(Widget);
18471   // do not localize !
18472   if (AParent <> nil) and QObject_inherits(AParent,'QStackedWidget') then
18473     Result := QTabWidgetH(QWidget_parentWidget(AParent))
18474   else
18475     Result := nil;
18476 end;
18477 
18478 procedure TQtPage.setIcon(const AIcon: QIconH);
18479 var
18480   AParent: QTabWidgetH;
18481   TabWidget: TQtTabWidget;
18482 begin
18483   FIcon := AIcon;
18484   AParent := getTabWidget;
18485   if AParent <> nil then
18486   begin
18487     if ChildOfComplexWidget = ccwTabWidget then
18488     begin
18489       TabWidget := TQtTabWidget(LCLObject.Parent.Handle);
18490       TabWidget.setTabIcon(TabWidget.indexOf(Widget), AIcon);
18491     end else
18492       QTabWidget_setTabIcon(AParent, getIndex, AIcon);
18493   end;
18494 end;
18495 
18496 procedure TQtPage.setText(const W: WideString);
18497 var
18498   AParent: QTabWidgetH;
18499   Index: integer;
18500 begin
18501   inherited setText(W);
18502   AParent := getTabWidget;
18503   if (AParent <> nil) then
18504   begin
18505     Index := getIndex(True);
18506     if Index <> -1 then
18507       QTabWidget_setTabText(AParent, Index, @W);
18508   end;
18509 end;
18510 
18511 { TQtAbstractItemView }
18512 
TQtAbstractItemView.GetOwnerDrawnnull18513 function TQtAbstractItemView.GetOwnerDrawn: Boolean;
18514 begin
18515   Result := FNewDelegate <> nil;
18516 end;
18517 
TQtAbstractItemView.getIconSizenull18518 function TQtAbstractItemView.getIconSize: TSize;
18519 begin
18520   QAbstractItemView_iconSize(QAbstractItemViewH(Widget), @Result);
18521 end;
18522 
TQtAbstractItemView.GetItemFlagsnull18523 function TQtAbstractItemView.GetItemFlags(AIndex: Integer): QtItemFlags;
18524 begin
18525   Result := QtNoItemFlags;
18526 end;
18527 
18528 procedure TQtAbstractItemView.setIconSize(const AValue: TSize);
18529 begin
18530   QAbstractItemView_setIconSize(QAbstractItemViewH(Widget), @AValue);
18531 end;
18532 
18533 procedure TQtAbstractItemView.SetItemFlags(AIndex: Integer; AValue: QtItemFlags
18534   );
18535 begin
18536   // must be overrided !
18537 end;
18538 
18539 procedure TQtAbstractItemView.SetOwnerDrawn(const AValue: Boolean);
18540 begin
18541   if AValue and (FNewDelegate = nil) then
18542   begin
18543     FNewDelegate := QLCLItemDelegate_create(Widget);
18544 
18545     QLCLItemDelegate_override_sizeHint(FNewDelegate, @ItemDelegateSizeHint);
18546 
18547     QLCLItemDelegate_override_Paint(FNewDelegate, @ItemDelegatePaint);
18548 
18549     FOldDelegate := QAbstractItemView_itemDelegate(QAbstractItemViewH(Widget));
18550     QAbstractItemView_setItemDelegate(QAbstractItemViewH(Widget), FNewDelegate);
18551   end
18552   else
18553   if ((not AValue) and (FNewDelegate <> nil)) then
18554   begin
18555     {TQtAbstractItemView.SetOwnerDrawn: this call avoid sporadic AVs with
18556      QLCLItemDelegate_destroy(FNewDelegate).
18557      howto reproduce: comment next code line, recompile laz, and then in oi click
18558      in first field eg. Action (TForm), now push kbd down arrow let it pass all properties,
18559      you'll have crash at Constraints property.}
18560     FNewDelegate := QLCLItemDelegateH(QAbstractItemView_itemDelegate(QAbstractItemViewH(Widget)));
18561     QAbstractItemView_setItemDelegate(QAbstractItemViewH(Widget), FOldDelegate);
18562     QLCLItemDelegate_destroy(FNewDelegate);
18563     FNewDelegate := nil;
18564   end;
18565 end;
18566 
18567 procedure TQtAbstractItemView.OwnerDataNeeded(ARect: TRect);
18568 begin
18569   // override
18570 end;
18571 
18572 procedure TQtAbstractItemView.PostponedMouseRelease(AEvent: QEventH);
18573  // postpone mouse release for LCL
18574 var
18575   ev: QMouseEventH;
18576   APos, AGlobalPos: TQtPoint;
18577   APosF, AGlobalPosF: TQtPointF;
18578 begin
18579   if QEvent_type(AEvent) = QEventMouseButtonRelease then
18580   begin
18581     ev := QMouseEventH(AEvent);
18582     QMouseEvent_pos(ev, @APos);
18583     QMouseEvent_globalPos(ev, @AGlobalPos);
18584     APosF.X := APos.X;
18585     APosF.Y := APos.Y;
18586     AGlobalPosF.X := AGlobalPos.X;
18587     AGlobalPosF.Y := AGlobalPos.Y;
18588     FSavedEvent := QMouseEvent_create(QEventMouseButtonRelease,
18589       @APosF, @AGlobalPosF,
18590       QMouseEvent_button(ev), QMouseEvent_buttons(ev),
18591       QInputEvent_modifiers(QInputEventH(AEvent)));
18592     FSavedEventTimer := QTimer_create(Widget);
18593     FSavedEventTimerHook := QTimer_hook_create(FSavedEventTimer);
18594     QTimer_hook_hook_timeout(FSavedEventTimerHook,
18595       @PostponedMouseReleaseTimerEvent);
18596     QTimer_setInterval(FSavedEventTimer, 5);
18597     QTimer_setSingleShot(FSavedEventTimer, True);
18598     QTimer_start(FSavedEventTimer);
18599   end;
18600 end;
18601 
18602 procedure TQtAbstractItemView.PostponedMouseReleaseTimerEvent(); cdecl;
18603 begin
18604   if FSavedEvent <> nil then
18605   begin
18606     SlotMouse(Widget, FSavedEvent);
18607     QMouseEvent_destroy(FSavedEvent);
18608     FSavedEvent := nil;
18609     QTimer_hook_destroy(FSavedEventTimerHook);
18610     QTimer_destroy(FSavedEventTimer);
18611     FSavedEventTimer := nil;
18612     FSavedEventTimerHook := nil;
18613   end;
18614 end;
18615 
18616 constructor TQtAbstractItemView.Create(const AWinControl: TWinControl;
18617   const AParams: TCreateParams);
18618 begin
18619   inherited Create(AWinControl, AParams);
18620   FOldDelegate := nil;
18621   FNewDelegate := nil;
18622 end;
18623 
18624 destructor TQtAbstractItemView.Destroy;
18625 begin
18626   if FNewDelegate <> nil then
18627     SetOwnerDrawn(False);
18628   inherited Destroy;
18629 end;
18630 
18631 procedure TQtAbstractItemView.signalActivated(index: QModelIndexH); cdecl;
18632 var
18633   Msg: TLMessage;
18634 begin
18635   // writeln('SIGNAL: TQtAbstractItemView.signalActivated');
18636   FillChar(Msg{%H-}, SizeOf(Msg), 0);
18637   Msg.Msg := LM_ACTIVATE;
18638   DeliverMessage( Msg );
18639 end;
18640 
18641 procedure TQtAbstractItemView.signalClicked(index: QModelIndexH); cdecl;
18642 begin
18643   {use to be overriden by descedants, don''t implement it here,
18644    or U get in trouble with TQtListView && TQtListWidget items.}
18645 end;
18646 
18647 procedure TQtAbstractItemView.signalDoubleClicked(index: QModelIndexH); cdecl;
18648 begin
18649   {use to be overriden by descedants, don''t implement it here,
18650    or U get in trouble with TQtListView && TQtListWidget items.}
18651 end;
18652 
18653 procedure TQtAbstractItemView.signalEntered(index: QModelIndexH); cdecl;
18654 var
18655   Msg: TLMessage;
18656 begin
18657   FillChar(Msg{%H-}, SizeOf(Msg), 0);
18658   Msg.Msg := LM_ENTER;
18659   DeliverMessage( Msg );
18660 end;
18661 
18662 procedure TQtAbstractItemView.signalPressed(index: QModelIndexH); cdecl;
18663 begin
18664   {should be overriden by descedants}
18665 end;
18666 
18667 procedure TQtAbstractItemView.signalViewportEntered; cdecl;
18668 begin
18669   {should be overriden by descedants}
18670 end;
18671 
18672 procedure TQtAbstractItemView.AttachEvents;
18673 begin
18674   inherited AttachEvents;
18675   FSignalActivated := QAbstractItemView_hook_create(Widget);
18676   FSignalClicked := QAbstractItemView_hook_create(Widget);
18677   FSignalDoubleClicked := QAbstractItemView_hook_create(Widget);
18678   FSignalEntered := QAbstractItemView_hook_create(Widget);
18679   FSignalPressed := QAbstractItemView_hook_create(Widget);
18680   FSignalViewportEntered := QAbstractItemView_hook_create(Widget);
18681 
18682   QAbstractItemView_hook_hook_activated(FSignalActivated, @SignalActivated);
18683 
18684   QAbstractItemView_hook_hook_clicked(FSignalClicked, @SignalClicked);
18685 
18686   QAbstractItemView_hook_hook_doubleClicked(FSignalDoubleClicked, @SignalDoubleClicked);
18687 
18688   QAbstractItemView_hook_hook_entered(FSignalEntered, @SignalEntered);
18689 
18690   QAbstractItemView_hook_hook_pressed(FSignalPressed, @SignalPressed);
18691 
18692   QAbstractItemView_hook_hook_viewportEntered(FSignalViewportEntered, @SignalViewportEntered);
18693 
18694   FAbstractItemViewportEventHook := QObject_hook_create(viewportWidget);
18695   QObject_hook_hook_events(FAbstractItemViewportEventHook, @itemViewViewportEventFilter);
18696 
18697   // initialize scrollbars
18698   verticalScrollBar;
18699   horizontalScrollBar;
18700 
18701 end;
18702 
18703 procedure TQtAbstractItemView.DetachEvents;
18704 begin
18705   if FSignalActivated <> nil then
18706   begin
18707     QAbstractItemView_hook_destroy(FSignalActivated);
18708     FSignalActivated := nil;
18709   end;
18710   if FSignalClicked <> nil then
18711   begin
18712     QAbstractItemView_hook_destroy(FSignalClicked);
18713     FSignalClicked := nil;
18714   end;
18715   if FSignalDoubleClicked <> nil then
18716   begin
18717     QAbstractItemView_hook_destroy(FSignalDoubleClicked);
18718     FSignalDoubleClicked := nil;
18719   end;
18720   if FSignalEntered <> nil then
18721   begin
18722     QAbstractItemView_hook_destroy(FSignalEntered);
18723     FSignalEntered := nil;
18724   end;
18725   if FSignalPressed <> nil then
18726   begin
18727     QAbstractItemView_hook_destroy(FSignalPressed);
18728     FSignalPressed := nil;
18729   end;
18730   if FSignalViewportEntered <> nil then
18731   begin
18732     QAbstractItemView_hook_destroy(FSignalViewportEntered);
18733     FSignalViewportEntered := nil;
18734   end;
18735   if FAbstractItemViewportEventHook <> nil then
18736   begin
18737     QObject_hook_destroy(FAbstractItemViewportEventHook);
18738     FAbstractItemViewportEventHook := nil;
18739   end;
18740   inherited DetachEvents;
18741 end;
18742 
TQtAbstractItemView.itemViewViewportEventFilternull18743 function TQtAbstractItemView.itemViewViewportEventFilter(Sender: QObjectH;
18744   Event: QEventH): Boolean; cdecl;
18745 var
18746   R: TRect;
18747   ASize: TSize;
18748   AResizeEvent: QResizeEventH;
18749 begin
18750   {we install only mouse events on QAbstractItemView viewport}
18751   Result := False;
18752   QEvent_accept(Event);
18753 
18754   if (LCLObject = nil) then
18755     exit;
18756 
18757   BeginEventProcessing;
18758   try
18759     {ownerdata is needed only before qt paint's data}
18760     if (ViewStyle >= 0) and FOwnerData and
18761       (QEvent_type(Event) = QEventPaint) then
18762     begin
18763       QPaintEvent_rect(QPaintEventH(Event), @R);
18764       OwnerDataNeeded(R);
18765     end;
18766 
18767     case QEvent_type(Event) of
18768       QEventResize:
18769       begin
18770         if Assigned(FOwner) then
18771           ASize := FOwner.getSize
18772         else
18773           ASize := getSize;
18774         AResizeEvent := QResizeEvent_create(@ASize, @ASize);
18775         try
18776           SlotResize(AResizeEvent);
18777         finally
18778           QEvent_destroy(AResizeEvent);
18779         end;
18780       end;
18781       QEventHide:
18782         if QWidget_mouseGrabber() = QWidgetH(Sender) then
18783           ReleaseCapture;
18784       QEventMouseButtonPress,
18785       QEventMouseButtonRelease,
18786       QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
18787       QEventContextMenu: Result := SlotContextMenu(Sender, Event);
18788       else
18789       begin
18790         if not (ViewStyle in [Ord(vsIcon), Ord(vsSmallIcon)]) then
18791         begin
18792           {do not change selection if mousepressed and mouse moved}
18793           Result := (QEvent_type(Event) = QEventMouseMove) and
18794             hasFocus and (QGUIApplication_mouseButtons() > 0);
18795           QEvent_ignore(Event);
18796         end;
18797       end;
18798     end;
18799   finally
18800     EndEventProcessing;
18801   end;
18802 end;
18803 
18804 procedure TQtAbstractItemView.setDefaultColorRoles;
18805 begin
18806   WidgetColorRole := QPaletteBase;
18807   TextColorRole := QPaletteText;
18808 end;
18809 
18810 procedure TQtAbstractItemView.clearSelection;
18811 begin
18812   QAbstractItemView_clearSelection(QAbstractItemViewH(Widget));
18813 end;
18814 
getModelnull18815 function TQtAbstractItemView.getModel: QAbstractItemModelH;
18816 begin
18817   Result := QAbstractItemView_model(QAbstractItemViewH(Widget));
18818 end;
18819 
TQtAbstractItemView.getRowHeightnull18820 function TQtAbstractItemView.getRowHeight(ARowIndex: integer): integer;
18821 begin
18822   Result := QAbstractItemView_sizeHintForRow(QAbstractItemViewH(Widget),
18823     ARowIndex);
18824 end;
18825 
TQtAbstractItemView.getSelectionModenull18826 function TQtAbstractItemView.getSelectionMode: QAbstractItemViewSelectionMode;
18827 begin
18828   Result := QAbstractItemView_SelectionMode(QAbstractItemViewH(Widget));
18829 end;
18830 
getTopItemnull18831 function TQtAbstractItemView.getTopItem: integer;
18832 begin
18833   Result := -1;
18834 end;
18835 
18836 {------------------------------------------------------------------------------
18837   Function: TQtAbstractItemView.getVisibleRowCount
18838   Params:  Boolean
18839   Returns: if AFirstVisibleOnly = False (default) then it returns number
18840   of visible rows, or 0 if there's no visible rows.
18841   When AFirstVisibleOnly = True then it returns index of first visible row,
18842   otherwise result is -1.
18843   This function is used by TQtTreeWidget and TQtListWidget.
18844  ------------------------------------------------------------------------------}
getVisibleRowCountnull18845 function TQtAbstractItemView.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
18846 begin
18847   Result := 0;
18848 end;
18849 
18850 procedure TQtAbstractItemView.modelIndex(retval: QModelIndexH; row, column: Integer; parent: QModelIndexH = nil);
18851 begin
18852   QAbstractItemModel_index(getModel, retval, row, column, parent);
18853 end;
18854 
TQtAbstractItemView.visualRectnull18855 function TQtAbstractItemView.visualRect(Index: QModelIndexH): TRect;
18856 begin
18857   QAbstractItemView_visualRect(QAbstractItemViewH(Widget), @Result, Index);
18858 end;
18859 
18860 procedure TQtAbstractItemView.setEditTriggers(
18861   ATriggers: QAbstractItemViewEditTriggers);
18862 begin
18863   QAbstractItemView_setEditTriggers(QAbstractItemViewH(Widget), ATriggers);
18864 end;
18865 
18866 procedure TQtAbstractItemView.setSelectionMode(
18867   AMode: QAbstractItemViewSelectionMode);
18868 begin
18869   QAbstractItemView_setSelectionMode(QAbstractItemViewH(Widget), AMode);
18870 end;
18871 
18872 procedure TQtAbstractItemView.setSelectionBehavior(
18873   ABehavior: QAbstractItemViewSelectionBehavior);
18874 begin
18875   QAbstractItemView_setSelectionBehavior(QAbstractItemViewH(Widget), ABehavior);
18876 end;
18877 
18878 procedure TQtAbstractItemView.setWordWrap(const AValue: Boolean);
18879 begin
18880   // override
18881 end;
18882 
18883 procedure TQtAbstractItemView.ItemDelegateSizeHint(
18884   option: QStyleOptionViewItemH; index: QModelIndexH; Size: PSize); cdecl;
18885 var
18886   Msg: TLMMeasureItem;
18887   MeasureItemStruct: TMeasureItemStruct;
18888   decorationSize: TSize;
18889   Metric: Integer;
18890 begin
18891   QStyleOptionViewItem_decorationSize(option, @decorationSize);
18892   Metric := QStyle_pixelMetric(QApplication_style(), QStylePM_FocusFrameVMargin, nil, nil) * 2;
18893   MeasureItemStruct.itemID := UINT(QModelIndex_row(index));
18894   MeasureItemStruct.itemWidth := UINT(Size^.cx);
18895   MeasureItemStruct.itemHeight := UINT(Max(Size^.cy, (decorationSize.cy + Metric)));
18896   Msg.Msg := LM_MEASUREITEM;
18897   Msg.MeasureItemStruct := @MeasureItemStruct;
18898   DeliverMessage(Msg);
18899   Size^.cx := Longint(MeasureItemStruct.itemWidth);
18900   Size^.cy := Longint(MeasureItemStruct.itemHeight);
18901 end;
18902 
18903 procedure TQtAbstractItemView.ItemDelegatePaint(painter: QPainterH;
18904   option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
18905 begin
18906   // should be overrided
18907 end;
18908 
18909 { TQtRubberBand }
18910 
CreateWidgetnull18911 function TQtRubberBand.CreateWidget(const AParams: TCreateParams): QWidgetH;
18912 var
18913   Parent: QWidgetH;
18914 begin
18915   if AParams.WndParent <> 0 then
18916     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
18917   else
18918     Parent := nil;
18919   Result := QRubberBand_create(FShape, Parent);
18920 end;
18921 
18922 constructor TQtRubberBand.Create(const AWinControl: TWinControl;
18923   const AParams: TCreateParams);
18924 begin
18925   FShape := QRubberBandLine;
18926   inherited Create(AWinControl, AParams);
18927 end;
18928 
18929 procedure TQtRubberBand.move(ANewLeft, ANewTop: Integer);
18930 begin
18931   QRubberBand_move(QRubberBandH(Widget), ANewLeft, ANewTop);
18932 end;
18933 
18934 procedure TQtRubberBand.Resize(ANewWidth, ANewHeight: Integer);
18935 begin
18936   QRubberBand_resize(QRubberBandH(Widget), ANewWidth, ANewHeight);
18937 end;
18938 
18939 procedure TQtRubberBand.setGeometry(ARect: TRect);
18940 begin
18941   QRubberBand_setGeometry(QRubberBandH(Widget), @ARect);
18942 end;
18943 
TQtRubberBand.getShapenull18944 function TQtRubberBand.getShape: QRubberBandShape;
18945 begin
18946   Result := QRubberBand_shape(QRubberBandH(Widget));
18947 end;
18948 
18949 procedure TQtRubberBand.setShape(AShape: QRubberBandShape);
18950 begin
18951   if getShape <> AShape then
18952   begin
18953     // recreate widget
18954     FShape := AShape;
18955     RecreateWidget;
18956     AttachEvents;
18957   end;
18958 end;
18959 
18960 { TQtFileDialog }
18961 
TQtFileDialog.CreateWidgetnull18962 function TQtFileDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags): QWidgetH;
18963 begin
18964   Result := QFileDialog_create(parent, f);
18965   {$ifndef QT_NATIVE_DIALOGS}
18966   FBackBtn := nil;
18967   FForwardBtn := nil;
18968   FUpBtn := nil;
18969   FFileNameEdit := nil;
18970   FComboType := nil;
18971   FComboHistory := nil;
18972   FSideView := nil;;
18973   FTreeView := nil;
18974   FListView := nil;
18975 
18976   FTreeViewEventFilter := nil; // detailed view
18977   FListViewEventFilter := nil; // small icons
18978   FSideViewEventFilter := nil; // sidebar
18979   FFileNameEditEventFilter := nil; // filename editor
18980   FComboTypeEventFilter := nil;
18981   FComboHistoryEventFilter := nil;
18982   {$endif}
18983 end;
18984 
18985 procedure TQtFileDialog.AttachEvents;
18986 begin
18987   inherited AttachEvents;
18988 
18989   FCurrentChangedHook := QFileDialog_hook_create(Widget);
18990   FDirecotyEnteredHook := QFileDialog_hook_create(Widget);
18991   FFilterSelectedHook := QFileDialog_hook_create(Widget);
18992 
18993   QFileDialog_hook_hook_filterSelected(FFilterSelectedHook, @FilterSelectedEvent);
18994 
18995   QFileDialog_hook_hook_currentChanged(FCurrentChangedHook, @CurrentChangedEvent);
18996 
18997   QFileDialog_hook_hook_directoryEntered(FDirecotyEnteredHook, @DirectoryEnteredEvent);
18998 end;
18999 
19000 procedure TQtFileDialog.DetachEvents;
19001 begin
19002   if FCurrentChangedHook <> nil then
19003   begin
19004     QFileDialog_hook_destroy(FCurrentChangedHook);
19005     FCurrentChangedHook := nil;
19006   end;
19007   if FFilterSelectedHook <> nil then
19008   begin
19009     QFileDialog_hook_destroy(FFilterSelectedHook);
19010     FFilterSelectedHook := nil;
19011   end;
19012   if FDirecotyEnteredHook <> nil then
19013   begin
19014     QFileDialog_hook_destroy(FDirecotyEnteredHook);
19015     FDirecotyEnteredHook := nil;
19016   end;
19017   {$ifndef QT_NATIVE_DIALOGS}
19018   if FTreeViewEventFilter <> nil then
19019   begin
19020     QObject_hook_destroy(FTreeViewEventFilter);
19021     FTreeViewEventFilter := nil;
19022   end;
19023   if FListViewEventFilter <> nil then
19024   begin
19025     QObject_hook_destroy(FListViewEventFilter);
19026     FListViewEventFilter := nil;
19027   end;
19028   if FSideViewEventFilter <> nil then
19029   begin
19030     QObject_hook_destroy(FSideViewEventFilter);
19031     FSideViewEventFilter := nil;
19032   end;
19033   if FFileNameEditEventFilter <> nil then
19034   begin
19035     QObject_hook_destroy(FFileNameEditEventFilter);
19036     FFileNameEditEventFilter := nil;
19037   end;
19038   if FComboTypeEventFilter <> nil then
19039   begin
19040     QObject_hook_destroy(FComboTypeEventFilter);
19041     FComboTypeEventFilter := nil;
19042   end;
19043   if FComboHistoryEventFilter <> nil then
19044   begin
19045     QObject_hook_destroy(FComboHistoryEventFilter);
19046     FComboHistoryEventFilter := nil;
19047   end;
19048   {$endif}
19049   inherited DetachEvents;
19050 end;
19051 
19052 {$ifndef QT_NATIVE_DIALOGS}
TQtFileDialog.EventFilternull19053 function TQtFileDialog.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
19054   cdecl;
19055 begin
19056   Result := False;
19057   if Sender <> Widget then
19058   begin
19059     // TODO: Ctrl + Letter for Open/Save button trigger
19060     // ALT + Left, Up, Right to navigate (Backward, Up parent, Forward) in list.
19061     // ALT + E to focus fileedit
19062     // ALT + H to focus lookInCombo (history combo)
19063     // ALT + L to focus view
19064     // ALT + N to create new folder (TODO)
19065     // ALT + S to select sidebar
19066     // ALT + T to focus file type combo
19067     // ALT + V to change view style (TODO)
19068     case QEvent_type(Event) of
19069       QEventKeyPress:
19070         begin
19071           if (QKeyEvent_modifiers(QKeyEventH(Event)) and QtAltModifier <> 0) then
19072           begin
19073             case QKeyEvent_key(QKeyEventH(Event)) of
19074               QtKey_Left:
19075                 begin
19076                   if Assigned(FBackBtn) and QWidget_isVisible(FBackBtn) and
19077                     QWidget_isEnabled(FBackBtn) then
19078                     QAbstractButton_click(QAbstractButtonH(FBackBtn));
19079                   Result := True;
19080                 end;
19081               QtKey_Right:
19082                 begin
19083                   if Assigned(FForwardBtn) and QWidget_isVisible(FForwardBtn) and
19084                     QWidget_isEnabled(FForwardBtn) then
19085                     QAbstractButton_click(QAbstractButtonH(FForwardBtn));
19086                   Result := True;
19087                 end;
19088               QtKey_Up:
19089                 begin
19090                   if Assigned(FUpBtn) and QWidget_isVisible(FUpBtn) and
19091                     QWidget_isEnabled(FUpBtn) then
19092                     QAbstractButton_click(QAbstractButtonH(FUpBtn));
19093                   Result := True;
19094                 end;
19095               QtKey_E:
19096                 begin
19097                   if Assigned(FFileNameEdit) and
19098                     QWidget_isVisible(FFileNameEdit) and
19099                     QWidget_isEnabled(FFileNameEdit) and
19100                     not QWidget_hasFocus(FFileNameEdit) then
19101                     QWidget_setFocus(FFileNameEdit);
19102                   Result := True;
19103                 end;
19104               QtKey_H:
19105                 begin
19106                   if Assigned(FComboHistory) and
19107                     QWidget_isVisible(FComboHistory) and
19108                     QWidget_isEnabled(FComboHistory) and
19109                     not QWidget_hasFocus(FComboHistory) then
19110                       QWidget_setFocus(FComboHistory);
19111                   Result := True;
19112                 end;
19113               QtKey_L:
19114                 begin
19115                   if Assigned(FTreeView) and
19116                     QWidget_isVisible(FTreeView) and
19117                     QWidget_isEnabled(FTreeView) and
19118                     not QWidget_hasFocus(FTreeView) then
19119                     QWidget_setFocus(FTreeView)
19120                   else
19121                   if Assigned(FListView) and
19122                     QWidget_isVisible(FListView) and
19123                     QWidget_isEnabled(FListView) and
19124                     not QWidget_hasFocus(FListView) then
19125                     QWidget_setFocus(FListView);
19126                   Result := True;
19127                 end;
19128               QtKey_N:
19129                 begin
19130                   //TODO: create newfolder
19131                   Result := True;
19132                 end;
19133               QtKey_S:
19134                 begin
19135                   // select sidebar
19136                   if Assigned(FSideView) and
19137                     QWidget_isVisible(FSideView) and
19138                     QWidget_isEnabled(FSideView) and
19139                     not QWidget_hasFocus(FSideView) then
19140                     QWidget_setFocus(FSideView);
19141                   Result := True;
19142                 end;
19143               QtKey_T:
19144                 begin
19145                   // focus combo filetype
19146                   if Assigned(FComboType) and
19147                     QWidget_isVisible(FComboType) and
19148                     QWidget_isEnabled(FComboType) and
19149                     not QWidget_hasFocus(FComboType) then
19150                       QWidget_setFocus(FComboType);
19151                   Result := True;
19152                 end;
19153               QtKey_V:
19154                 begin
19155                   //TODO: change viewStyle
19156                   Result := True;
19157                 end;
19158             end;
19159           end;
19160         end;
19161     end;
19162   end else
19163     Result := inherited EventFilter(Sender, Event);
19164 end;
19165 {$endif}
19166 
TQtFileDialog.selectFilenull19167 function TQtFileDialog.selectFile: WideString;
19168 begin
19169   QFileDialog_selectFile(QFileDialogH(Widget), @Result);
19170 end;
19171 
19172 procedure TQtFileDialog.selectedFiles(retval: QStringListH);
19173 begin
19174   QFileDialog_selectedFiles(QFileDialogH(Widget), retval);
19175 end;
19176 
19177 procedure TQtFileDialog.setAcceptMode(const AMode: QFileDialogAcceptMode);
19178 begin
19179   QFileDialog_setAcceptMode(QFileDialogH(Widget), AMode)
19180 end;
19181 
19182 procedure TQtFileDialog.setConfirmOverwrite(const AValue: Boolean);
19183 begin
19184   QFileDialog_setConfirmOverwrite(QFileDialogH(Widget), AValue);
19185 end;
19186 
19187 procedure TQtFileDialog.setDirectory(const ADirectory: WideString);
19188 begin
19189   QFileDialog_setDirectory(QFileDialogH(Widget), @ADirectory);
19190 end;
19191 
19192 procedure TQtFileDialog.setHistory(AList: TStrings);
19193 var
19194   List: QStringListH;
19195   i: Integer;
19196   WStr: WideString;
19197 begin
19198   List := QStringList_create();
19199   try
19200     for i := 0 to AList.Count - 1 do
19201     begin
19202       WStr := GetUTF8String(AList.Strings[i]);
19203       QStringList_append(List, @WStr);
19204     end;
19205     QFileDialog_setHistory(QFileDialogH(Widget), List);
19206   finally
19207     QStringList_destroy(List);
19208   end;
19209 end;
19210 
19211 procedure TQtFileDialog.setFileMode(const AMode: QFileDialogFileMode);
19212 begin
19213   QFileDialog_setFileMode(QFileDialogH(Widget), AMode);
19214 end;
19215 
19216 procedure TQtFileDialog.setFilter(const AFilter: WideString);
19217 begin
19218   QFileDialog_setNameFilter(QFileDialogH(Widget), @AFilter);
19219 end;
19220 
19221 procedure TQtFileDialog.setLabelText(const ALabel: QFileDialogDialogLabel;
19222   const AText: WideString);
19223 begin
19224   QFileDialog_setLabelText(QFileDialogH(Widget), ALabel, @AText);
19225 end;
19226 
19227 procedure TQtFileDialog.setReadOnly(const AReadOnly: Boolean);
19228 begin
19229   QFileDialog_setReadOnly(QFileDialogH(Widget), AReadOnly);
19230 end;
19231 
19232 procedure TQtFileDialog.setSelectedFilter(const ASelFilter: WideString);
19233 begin
19234   QFileDialog_selectNameFilter(QFileDialogH(Widget), @ASelFilter);
19235 end;
19236 
19237 procedure TQtFileDialog.setViewMode(const AMode: QFileDialogViewMode);
19238 begin
19239   QFileDialog_setViewMode(QFileDialogH(Widget), AMode);
19240 end;
19241 
19242 {------------------------------------------------------------------------------
19243   Function: TQtFileDialog.setShortcuts
19244   Params:  None
19245   Returns: Nothing
19246   Qt non-native dialogs doesn't set keyboard shortcuts, so we must do that.
19247   This functions hooks eventFilter of all widgets on QFileDialog.
19248  ------------------------------------------------------------------------------}
19249 {$ifndef QT_NATIVE_DIALOGS}
19250 procedure TQtFileDialog.setShortcuts(const AIsOpenDialog: Boolean);
19251 var
19252   AnIter: TQtObjectDump;
19253   i: Integer;
19254   Obj: QObjectH;
19255   WStr: WideString;
19256   ToolTip: WideString;
19257 begin
19258   // if there's auto recognition enabled then don''t set shortcuts
19259   // cause we are maybe native dialog and then boomer.
19260   if not QFileDialog_testOption(QFileDialogH(Widget),
19261     QFileDialogDontUseNativeDialog) then
19262     exit;
19263   FForwardBtn := nil;
19264   FBackBtn := nil;
19265   FUpBtn := nil;
19266 
19267   AnIter := TQtObjectDump.Create(Widget);
19268   try
19269     AnIter.DumpObject;
19270 
19271     for i := 0 to AnIter.ObjList.Count - 1 do
19272     begin
19273       Obj := QObjectH(AnIter.Objlist.Items[i]);
19274       if AnIter.IsWidget(Obj) then
19275       begin
19276         WStr := AnIter.GetObjectName(Obj);
19277         if (WStr = 'treeView') or (WStr = 'listView') or (WStr = 'sidebar') then
19278         begin
19279           if FForwardBtn = nil then
19280           begin
19281             FForwardBtn := AnIter.FindWidgetByName('forwardButton');
19282             if FForwardBtn <> nil then
19283             begin
19284               ToolTip := 'Forward (Alt + Right)';
19285               QWidget_setToolTip(FForwardBtn, @ToolTip);
19286             end;
19287           end;
19288           if FBackBtn = nil then
19289           begin
19290             FBackBtn := AnIter.FindWidgetByName('backButton');
19291             if FBackBtn <> nil then
19292             begin
19293               ToolTip := 'Back (Alt + Left)';
19294               QWidget_setToolTip(FBackBtn, @ToolTip);
19295             end;
19296           end;
19297           if FUpBtn = nil then
19298           begin
19299             FUpBtn := AnIter.FindWidgetByName('toParentButton');
19300             if FUpBtn <> nil then
19301             begin
19302               ToolTip := 'To parent directory (Alt + Up)';
19303               QWidget_setToolTip(FUpBtn, @ToolTip);
19304             end;
19305           end;
19306 
19307           if FForwardBtn <> nil then
19308           begin
19309             if WStr = 'treeView' then
19310             begin
19311               FTreeView := QWidgetH(Obj);
19312               FTreeViewEventFilter := QObject_hook_create(Obj);
19313               QObject_hook_hook_events(FTreeViewEventFilter, @EventFilter);
19314               ToolTip := 'Alt + L to focus this widget';
19315               QWidget_setToolTip(FTreeView, @ToolTip);
19316             end else
19317             if WStr = 'listView' then
19318             begin
19319               FListView := QWidgetH(Obj);
19320               FListViewEventFilter := QObject_hook_create(Obj);
19321               QObject_hook_hook_events(FListViewEventFilter, @EventFilter);
19322               ToolTip := 'Alt + L to focus this widget';
19323               QWidget_setToolTip(FListView, @ToolTip);
19324             end else
19325             if WStr = 'sidebar' then
19326             begin
19327               FSideView := QWidgetH(Obj);
19328               FSideViewEventFilter := QObject_hook_create(Obj);
19329               QObject_hook_hook_events(FSideViewEventFilter, @EventFilter);
19330               ToolTip := 'Alt + S to focus this widget';
19331               QWidget_setToolTip(FSideView, @ToolTip);
19332             end;
19333 
19334           end;
19335         end else
19336         if WStr = 'fileNameEdit' then
19337         begin
19338           FFileNameEdit := QWidgetH(Obj);
19339           FFileNameEditEventFilter := QObject_hook_create(Obj);
19340           QObject_hook_hook_events(FFileNameEditEventFilter, @EventFilter);
19341           ToolTip := 'Alt + E to focus this widget';
19342           QWidget_setToolTip(FFileNameEdit, @ToolTip);
19343         end else
19344         if WStr = 'fileTypeCombo' then
19345         begin
19346           FComboType := QWidgetH(Obj);
19347           FComboTypeEventFilter := QObject_hook_create(Obj);
19348           QObject_hook_hook_events(FComboTypeEventFilter, @EventFilter);
19349           ToolTip := 'Alt + T to focus this widget';
19350           QWidget_setToolTip(FComboType, @ToolTip);
19351         end else
19352         if WStr = 'lookInCombo' then
19353         begin
19354           FComboHistory := QWidgetH(Obj);
19355           FComboHistoryEventFilter := QObject_hook_create(Obj);
19356           QObject_hook_hook_events(FComboHistoryEventFilter, @EventFilter);
19357           ToolTip := 'Alt + H to focus this widget';
19358           QWidget_setToolTip(FComboHistory, @ToolTip);
19359         end;
19360       end;
19361     end;
19362 
19363   finally
19364     AnIter.Free;
19365   end;
19366 end;
19367 {$endif}
19368 
19369 procedure TQtFileDialog.FilterSelectedEvent(filter: PWideString); cdecl;
19370 var
19371   List: TQtStringList;
19372   index: Integer;
19373 begin
19374   if filter <> nil then
19375   begin
19376     List := TQtStringList.Create;
19377     getFilters(List.Handle);
19378     index := List.IndexOf(UTF16ToUTF8(filter^));
19379     if index <> -1 then
19380       TFileDialog(FDialog).IntfFileTypeChanged(index + 1);
19381     List.Free;
19382   end;
19383 end;
19384 
19385 procedure TQtFileDialog.CurrentChangedEvent(path: PWideString); cdecl;
19386 begin
19387   if FDialog is TOpenDialog then
19388   begin
19389     TOpenDialog(FDialog).FileName := UTF16ToUTF8(path^);
19390     TOpenDialog(FDialog).DoSelectionChange;
19391   end;
19392 end;
19393 
19394 procedure TQtFileDialog.DirectoryEnteredEvent(directory: PWideString); cdecl;
19395 begin
19396   if FDialog is TOpenDialog then
19397     TOpenDialog(FDialog).DoFolderChange;
19398 end;
19399 
19400 procedure TQtFileDialog.getFilters(const retval: QStringListH);
19401 begin
19402   QFileDialog_nameFilters(QFileDialogH(Widget), retval);
19403 end;
19404 
19405 { TQtFilePreviewDialog }
19406 
CreateWidgetnull19407 function TQtFilePreviewDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags
19408   ): QWidgetH;
19409 begin
19410   {$ifndef QT_NATIVE_DIALOGS}
19411   FPreviewWidget := nil;
19412   FTextWidget := nil;
19413   {$endif}
19414   Result := inherited CreateWidget(parent, f);
19415 end;
19416 
19417 {$ifndef QT_NATIVE_DIALOGS}
19418 
19419 procedure TQtFilePreviewDialog.initializePreview(
19420   const APreviewControl: TWinControl);
19421 var
19422   ALayout: QGridLayoutH;
19423   ATitle: WideString;
19424   W, H: Integer;
19425 begin
19426   ALayout := QGridLayoutH(QWidget_layout(Widget));
19427   ATitle := 'No image';
19428   FTextWidget := QLabel_create(PWideString(@ATitle), Widget);
19429   QFrame_setFrameShape(FTextWidget, QFrameStyledPanel);
19430   QLabel_setWordWrap(FTextWidget, True);
19431   QLabel_setScaledContents(FTextWidget, True);
19432   QLabel_setAlignment(FTextWidget, QtAlignCenter);
19433   ATitle := '';
19434   FPreviewWidget := QLabel_create(PWideString(@ATitle), Widget);
19435   QLabel_setAlignment(FPreviewWidget, QtAlignCenter);
19436 
19437   W := QWidget_width(Widget) div 5;
19438   H := W;
19439 
19440   if Assigned(APreviewControl) then
19441   begin
19442     APreviewControl.Width := W;
19443     APreviewControl.Height := H;
19444   end;
19445 
19446   QWidget_setGeometry(FTextWidget, 0, 0, W, 32);
19447   QWidget_setMaximumHeight(FTextWidget, 32);
19448   QWidget_setMaximumWidth(FTextWidget, W);
19449   QWidget_setMinimumWidth(FTextWidget, W);
19450 
19451   QWidget_setGeometry(FPreviewWidget, 0, 0, W, H);
19452   QWidget_setMaximumHeight(FPreviewWidget, H);
19453   QWidget_setMaximumWidth(FPreviewWidget, W);
19454   QLabel_setScaledContents(FPreviewWidget, True);
19455   (*
19456   do not use layout, Qt asserts with message that another layout already exists.
19457   ABox := QVBoxLayout_create(Widget);
19458   QBoxLayout_addWidget(ABox, FTextWidget, 0, QtAlignTop);
19459   // QBoxLayout_addWidget();
19460   QBoxLayout_addWidget(ABox, FPreviewWidget, 0, QtAlignCenter);
19461   QBoxLayout_addStretch(ABox);
19462   *)
19463   QGridLayout_addWidget(ALayout, FTextWidget, 1, 3, 3, 1, QtAlignTop);
19464   QGridLayout_addWidget(ALayout, FPreviewWidget, 1, 3, 3, 1, QtAlignCenter);
19465   QGridLayout_columnStretch(ALayout, 3);
19466 end;
19467 
19468 procedure TQtFilePreviewDialog.CurrentChangedEvent(path: PWideString); cdecl;
19469 var
19470   APixmap: QPixmapH;
19471   ATitle: WideString;
19472   ASize: TSize;
19473   ANewPixmap: QPixmapH;
19474 begin
19475   if Assigned(FPreviewWidget) then
19476   begin
19477     APixmap := QPixmap_create(path);
19478     if QPixmap_isNull(APixmap) then
19479     begin
19480       ATitle := 'Not an image';
19481       QLabel_setText(FTextWidget, @ATitle);
19482       ATitle := ' ';
19483       QLabel_setText(FPreviewWidget, @ATitle);
19484       QWidget_setToolTip(FTextWidget, @ATitle);
19485       QWidget_setToolTip(FPreviewWidget, @ATitle);
19486       QPixmap_destroy(APixmap);
19487     end else
19488     begin
19489       QPixmap_size(APixmap, @ASize);
19490       if path <> nil then
19491         ATitle := '' // ExtractFileName(path^)
19492       else
19493         ATitle := 'error file';
19494       if path <> nil then
19495         ATitle := Format('%d x %d x %d',[ASize.cx, ASize.cy, QPixmap_depth(APixmap)]);
19496       QLabel_setText(FTextWidget, @ATitle);
19497       ATitle := ExtractFileName(path^);
19498       QWidget_setToolTip(FTextWidget, @ATitle);
19499       ATitle := ATitle + LineEnding + Format('w %d x h %d x %d',[ASize.cx, ASize.cy, QPixmap_depth(APixmap)]);
19500       QWidget_setToolTip(FPreviewWidget, @ATitle);
19501       ANewPixmap := QPixmap_create;
19502       // QPixmap_scaled(APixmap, ANewPixmap,
19503       //  128, 128, QtKeepAspectRatio, QtSmoothTransformation);
19504       QLabel_setPixmap(FPreviewWidget, APixmap);
19505       QPixmap_destroy(APixmap);
19506       QPixmap_destroy(ANewPixmap);
19507     end;
19508 
19509   end;
19510   TOpenDialog(FDialog).FileName := UTF16ToUTF8(path^);
19511   TOpenDialog(FDialog).DoSelectionChange;
19512 end;
19513 {$ENDIF}
19514 
19515 { TQtGraphicView }
19516 
CreateWidgetnull19517 function TQtGraphicsView.CreateWidget(const AParams: TCreateParams): QWidgetH;
19518 var
19519   Parent: QWidgetH;
19520 begin
19521   FHasPaint := True;
19522   if AParams.WndParent <> 0 then
19523     Parent := TQtWidget(AParams.WndParent).GetContainerWidget
19524   else
19525     Parent := nil;
19526   Result := QGraphicsView_create(Parent);
19527 end;
19528 
19529 { TQtDesignWidget }
19530 
CreateWidgetnull19531 function TQtDesignWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
19532 begin
19533   Result := inherited CreateWidget(AParams);
19534   FDesignControl := QWidget_create(Result);
19535   QWidget_setMouseTracking(FDesignControl, True);
19536   setProperty(FDesignControl, 'lclwidget', Int64(PtrUInt(Self)));
19537   QtWidgetSet.AddHandle(Self);
19538   BringDesignerToFront;
19539 end;
19540 
19541 procedure TQtDesignWidget.DestroyWidget;
19542 begin
19543   inherited DestroyWidget;
19544   FDesignControl := nil;
19545 end;
19546 
19547 procedure TQtDesignWidget.SlotDesignControlPaint(Sender: QObjectH; Event: QEventH); cdecl;
19548 var
19549   Msg: TLMPaint;
19550   AStruct: PPaintStruct;
19551   P: TPoint;
19552   B: Boolean;
19553 begin
19554   {$ifdef VerboseQt}
19555     WriteLn('TQtDesignWidget.SlotDesignControlPaint ', dbgsName(LCLObject));
19556   {$endif}
19557 
19558   if (LCLObject is TWinControl) then
19559   begin
19560     FillChar(Msg{%H-}, SizeOf(Msg), #0);
19561 
19562     Msg.Msg := LM_PAINT;
19563     New(AStruct);
19564     FillChar(AStruct^, SizeOf(TPaintStruct), 0);
19565     Msg.PaintStruct := AStruct;
19566 
19567     with PaintData do
19568     begin
19569       PaintWidget := FDesignControl;
19570       ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
19571       if ClipRect = nil then
19572         New(ClipRect);
19573       QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
19574     end;
19575 
19576     Msg.DC := BeginPaint(THandle(Self), AStruct^);
19577     FDesignContext := Msg.DC;
19578 
19579     Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
19580     Msg.PaintStruct^.hdc := FDesignContext;
19581 
19582     P := getClientOffset;
19583     inc(P.X, FScrollX);
19584     inc(P.Y, FScrollY);
19585     TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
19586 
19587     // send paint message
19588     try
19589       // Saving clip rect and clip region
19590       try
19591         LCLObject.WindowProc(TLMessage(Msg));
19592       finally
19593         Dispose(PaintData.ClipRect);
19594         Fillchar(FPaintData, SizeOf(FPaintData), 0);
19595         FDesignContext := 0;
19596         EndPaint(THandle(Self), AStruct^);
19597         Dispose(AStruct);
19598       end;
19599     except
19600       // prevent recursive repainting !
19601       B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
19602       if B then
19603         QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
19604       try
19605         Application.HandleException(nil);
19606       finally
19607         if B and Assigned(Application) and not Application.Terminated then
19608           QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
19609       end;
19610     end;
19611   end;
19612 end;
19613 
19614 procedure TQtDesignWidget.BringDesignerToFront;
19615 begin
19616   if FDesignControl <> nil then
19617     QWidget_raise(FDesignControl);
19618 end;
19619 
19620 procedure TQtDesignWidget.ResizeDesigner;
19621 var
19622   R: TRect;
19623 begin
19624   if FDesignControl = nil then
19625     Exit;
19626   // FDesignControl must be same as form area,
19627   // since we use QWidget, not QMainWindow in design time.
19628   QWidget_contentsRect(Widget, @R);
19629   with R do
19630   begin
19631     QWidget_move(FDesignControl, Left, Top);
19632     QWidget_resize(FDesignControl, Right - Left, Bottom - Top);
19633   end;
19634 end;
19635 
GetContextnull19636 function TQtDesignWidget.GetContext: HDC;
19637 begin
19638   if FDesignContext <> 0 then
19639     Result := FDesignContext
19640   else
19641     Result := FContext;
19642 end;
19643 
DesignControlEventFilternull19644 function TQtDesignWidget.DesignControlEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
19645 var
19646   p, AGlobalPos: TQtPoint;
19647   APosF, AGlobalPosF: TQtPointF;
19648   pt: TPoint;
19649   R: TRect;
19650   Control: TControl;
19651   MouseEvent: QMouseEventH;
19652   WidgetToNotify: QWidgetH;
19653   WSQtWidget: TWSWinControlClass;
19654   Action: QActionH;
19655   AWidget: TQtWidget;
19656   ATabWidget: TQtTabWidget;
19657   ATabIndex: Integer;
19658 begin
19659   Result := False;
19660   QEvent_Accept(Event);
19661   if LCLObject = nil then
19662     exit;
19663   if QEvent_type(Event) = QEventDestroy then
19664   begin
19665     {FDesignControl is always destroyed by it's parent,
19666      only thing we need is to remove dynamic property.}
19667     RemoveProperty(FDesignControl,'lclwidget');
19668     exit;
19669   end;
19670   BeginEventProcessing;
19671   try
19672     case QEvent_type(Event) of
19673       QEventMouseButtonPress,
19674       QEventMouseButtonRelease:
19675       begin
19676         QMouseEvent_pos(QMouseEventH(Event), @p);
19677         OffsetMousePos(@p);
19678         pt := Point(p.x, p.y);
19679         Control := LCLObject.ControlAtPos(pt, [capfRecursive, capfAllowWinControls]);
19680 
19681         if Control is TWinControl then
19682         begin
19683           AWidget := TQtWidget(TWinControl(Control).Handle);
19684           if (Control is TCustomTabControl) and
19685             (AWidget.ChildOfComplexWidget <> ccwTTabControl) then
19686             WidgetToNotify := TQtTabWidget(TWinControl(Control).Handle).TabBar.Widget
19687           else
19688             WidgetToNotify := TQtWidget(TWinControl(Control).Handle).Widget;
19689 
19690           QMouseEvent_pos(QMouseEventH(Event), @p);
19691           QWidget_mapFrom(WidgetToNotify, @p, Widget, @p);
19692           Pt := Point(p.x, p.y);
19693 
19694           WSQtWidget := TWSWinControlClass(TWinControl(Control).WidgetSetClass);
19695 
19696           if WSQtWidget.GetDesignInteractive(TWinControl(Control), Pt) then
19697           begin
19698             if (Control is TCustomTabControl) and
19699               (AWidget.ChildOfComplexWidget <> ccwTTabControl) then
19700             begin
19701               ATabWidget := TQtTabWidget(TWinControl(Control).Handle);
19702               ATabIndex := ATabWidget.tabAt(Pt);
19703               if ATabIndex >= 0 then
19704                 ATabWidget.setCurrentIndex(ATabIndex);
19705             end else
19706             begin
19707               QMouseEvent_globalpos(QMouseEventH(Event), @AGlobalPos);
19708               APosF.X := P.X;
19709               APosF.Y := P.y;
19710               AGlobalPosF.X := AGlobalPos.X;
19711               AGlobalPosF.Y := AGlobalPos.Y;
19712               MouseEvent := QMouseEvent_create(QEvent_type(Event), @APosF,
19713                 @AGlobalPosF,
19714                 QMouseEvent_button(QMouseEventH(Event)),
19715                 QMouseEvent_buttons(QMouseEventH(Event)),
19716                 QInputEvent_modifiers(QInputEventH(Event))
19717                 );
19718               QCoreApplication_postEvent(WidgetToNotify, MouseEvent, 1);
19719             end;
19720           end;
19721         end else
19722         begin
19723           QMouseEvent_globalPos(QMouseEventH(Event), @p);
19724           WidgetToNotify := QApplication_widgetAt(@p);
19725           if (WidgetToNotify <> nil) then
19726           begin
19727             if TQtMainWindow(Self).MenuBar.Widget <> nil then
19728             begin
19729               QMouseEvent_Pos(QMouseEventH(Event), @p);
19730               QWidget_geometry(TQtMainWindow(Self).MenuBar.Widget, @R);
19731               pt := Point(P.X, P.Y);
19732               if LCLIntf.PtInRect(R, pt) then
19733               begin
19734                 Action := QMenuBar_actionAt(QMenuBarH(TQtMainWindow(Self).MenuBar.Widget), @p);
19735                 if Action <> nil then
19736                 begin
19737                   QCoreApplication_notify(QCoreApplication_instance(), TQtMainWindow(Self).MenuBar.Widget, Event);
19738                   QEvent_accept(Event);
19739                   Result := True;
19740                 end;
19741               end;
19742             end;
19743           end;
19744         end;
19745       end;
19746       QEventPaint: SlotDesignControlPaint(Sender, Event);
19747     end;
19748   finally
19749     EndEventProcessing;
19750   end;
19751 end;
19752 
TQtDesignWidget.EventFilternull19753 function TQtDesignWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
19754 begin
19755   Result := False;
19756   QEvent_accept(Event);
19757   if LCLObject = nil then
19758     exit;
19759 
19760   BeginEventProcessing;
19761   try
19762     case QEvent_type(Event) of
19763       QEventWindowActivate:
19764       begin
19765         Result := inherited EventFilter(Sender, Event);
19766         setFocus;
19767         BringDesignerToFront;
19768       end;
19769       QEventChildAdded,
19770       QEventChildRemoved: BringDesignerToFront;
19771       QEventResize:
19772         begin
19773           Result := inherited EventFilter(Sender, Event);
19774           ResizeDesigner;
19775         end;
19776       else
19777         Result := inherited EventFilter(Sender, Event);
19778     end;
19779   finally
19780     EndEventProcessing;
19781   end;
19782 end;
19783 
19784 procedure TQtDesignWidget.AttachEvents;
19785 begin
19786   inherited AttachEvents;
19787   if FDesignControl <> nil then
19788   begin
19789     FDesignControlEventHook := QObject_hook_create(FDesignControl);
19790     QObject_hook_hook_events(FDesignControlEventHook, @DesignControlEventFilter);
19791   end;
19792 end;
19793 
19794 procedure TQtDesignWidget.DetachEvents;
19795 begin
19796   if FDesignControlEventHook <> nil then
19797   begin
19798     QObject_hook_destroy(FDesignControlEventHook);
19799     FDesignControlEventHook := nil;
19800   end;
19801   inherited DetachEvents;
19802 end;
19803 
19804 procedure TQtDesignWidget.lowerWidget;
19805 begin
19806   inherited lowerWidget;
19807   BringDesignerToFront;
19808 end;
19809 
19810 procedure TQtDesignWidget.raiseWidget;
19811 begin
19812   inherited raiseWidget;
19813   BringDesignerToFront;
19814 end;
19815 
19816 { TQtMessageBox }
19817 
TQtMessageBox.getMsgBoxTypenull19818 function TQtMessageBox.getMsgBoxType: QMessageBoxIcon;
19819 begin
19820   Result := QMessageBox_icon(QMessageBoxH(Widget));
19821 end;
19822 
19823 procedure TQtMessageBox.setDetailText(const AValue: WideString);
19824 var
19825   Str: WideString;
19826 begin
19827   Str := GetUTF8String(AValue);
19828   QMessageBox_setDetailedText(QMessageBoxH(Widget), @Str);
19829 end;
19830 
TQtMessageBox.getMessageStrnull19831 function TQtMessageBox.getMessageStr: WideString;
19832 var
19833   Str: WideString;
19834 begin
19835   QMessageBox_text(QMessageBoxH(Widget), @Str);
19836   Result := UTF16ToUTF8(Str);
19837 end;
19838 
TQtMessageBox.getDetailTextnull19839 function TQtMessageBox.getDetailText: WideString;
19840 var
19841   Str: WideString;
19842 begin
19843   QMessageBox_detailedText(QMessageBoxH(Widget), @Str);
19844   Result := UTF16ToUTF8(Str);
19845 end;
19846 
19847 procedure TQtMessageBox.setMessageStr(const AValue: WideString);
19848 var
19849   Str: WideString;
19850 begin
19851   Str := GetUTF8String(AValue);
19852   QMessageBox_setText(QMessageBoxH(Widget), @Str);
19853 end;
19854 
19855 procedure TQtMessageBox.setMsgBoxType(const AValue: QMessageBoxIcon);
19856 begin
19857   QMessageBox_setIcon(QMessageBoxH(Widget), AValue);
19858 end;
19859 
19860 procedure TQtMessageBox.setTitle(const AValue: WideString);
19861 begin
19862   if AValue <> FTitle then
19863   begin
19864     FTitle := GetUTF8String(AValue);
19865     QMessageBox_setWindowTitle(QMessageBoxH(Widget), @FTitle);
19866   end;
19867 end;
19868 
TQtMessageBox.CreateWidgetnull19869 function TQtMessageBox.CreateWidget(AParent: QWidgetH): QWidgetH;
19870 begin
19871   FHasPaint := False;
19872   Result := QMessageBox_create(AParent);
19873   QMessageBox_setWindowModality(QMessageBoxH(Result), QtApplicationModal);
19874 end;
19875 
19876 constructor TQtMessageBox.Create(AParent: QWidgetH);
19877 begin
19878   WidgetColorRole := QPaletteWindow;
19879   TextColorRole := QPaletteWindowText;
19880   FOwner := nil;
19881   FCentralWidget := nil;
19882   FOwnWidget := True;
19883   FProps := nil;
19884   LCLObject := nil;
19885   FKeysToEat := [];
19886   FHasPaint := False;
19887   {$IFDEF TQTMESSAGEBOXUSEPARENT}
19888   if AParent = nil then
19889     AParent := QApplication_activeWindow;
19890   {$ENDIF}
19891   Widget := CreateWidget(AParent);
19892   setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
19893   QtWidgetSet.AddHandle(Self);
19894 end;
19895 
19896 procedure TQtMessageBox.AttachEvents;
19897 begin
19898   inherited AttachEvents;
19899   FMBEventHook := QObject_hook_create(Widget);
19900   QObject_hook_hook_events(FMBEventHook, @EventFilter);
19901 end;
19902 
19903 procedure TQtMessageBox.DetachEvents;
19904 begin
19905   if FMBEventHook <> nil then
19906   begin
19907     QObject_hook_destroy(FMBEventHook);
19908     FMBEventHook := nil;
19909   end;
19910   inherited DetachEvents;
19911 end;
19912 
TQtMessageBox.EventFilternull19913 function TQtMessageBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
19914   cdecl;
19915 begin
19916   {we'll need it later. QMessageBox uses it's own eventLoop !}
19917   Result := False;
19918   QEvent_accept(Event);
19919   if LCLObject <> nil then
19920     Result := inherited EventFilter(Sender, Event)
19921   else
19922   begin
19923     case QEvent_type(Event) of
19924       QEventKeyPress:
19925       begin
19926         if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Escape) and
19927           (QMessageBox_escapeButton(QMessageBoxH(Sender)) = nil) then
19928         begin
19929           QDialog_done(QDialogH(Sender), Ord(QDialogRejected));
19930           Result := True;
19931         end;
19932       end;
19933       QEventClose:
19934       begin
19935         if QMessageBox_escapeButton(QMessageBoxH(Sender)) = nil then
19936         begin
19937           QDialog_done(QDialogH(Sender), Ord(QDialogRejected));
19938           Result := True;
19939         end;
19940       end;
19941     end;
19942   end;
19943 end;
19944 
19945 procedure TQtMessageBox.SetButtonProps(ABtn: QPushButtonH; AResult: Int64; const ADefaultBtn: Boolean; const AEscapeBtn: Boolean);
19946 var
19947   v: QVariantH;
19948 begin
19949   if ADefaultBtn then
19950     QMessageBox_setDefaultButton(QMessageBoxH(Widget), ABtn);
19951 
19952   if AEscapeBtn then
19953     QMessageBox_setEscapeButton(QMessageBoxH(Widget), ABtn);
19954 
19955   v := QVariant_create(AResult);
19956   try
19957     QObject_setProperty(ABtn, 'lclmsgboxbutton', v);
19958   finally
19959     QVariant_destroy(v);
19960   end;
19961 end;
19962 
TQtMessageBox.AddButtonnull19963 function TQtMessageBox.AddButton(ACaption: WideString; ABtnType: QMessageBoxStandardButton;
19964    AResult: Int64; const ADefaultBtn: Boolean; const AEscapeBtn: Boolean): QPushButtonH;
19965 var
19966   Str: WideString;
19967 begin
19968   Result := QMessageBox_addButton(QMessageBoxH(Widget), ABtnType);
19969   Str := GetUTF8String(ACaption);
19970   QAbstractButton_setText(Result, @Str);
19971   SetButtonProps(Result, AResult, ADefaultBtn, AEscapeBtn);
19972 end;
19973 
TQtMessageBox.AddButtonnull19974 function TQtMessageBox.AddButton(ACaption: WideString; AResult: Int64; const ADefaultBtn: Boolean;
19975   const AEscapeBtn: Boolean): QPushButtonH;
19976 var
19977   Str: WideString;
19978 begin
19979   Str := GetUTF8String(ACaption);
19980   Result := QMessageBox_addButton(QMessageBoxH(Widget), @Str, QMessageBoxActionRole);
19981   SetButtonProps(Result, AResult, ADefaultBtn, AEscapeBtn);
19982 end;
19983 
TQtMessageBox.execnull19984 function TQtMessageBox.exec: Int64;
19985 var
19986   ABtn: QPushButtonH;
19987   v: QVariantH;
19988   ok: Boolean;
19989   QResult: Int64;
19990 begin
19991   Result := mrCancel;
19992   {$IFDEF QTDIALOGS_USES_QT_LOOP}
19993   QDialog_exec(QMessageBoxH(Widget));
19994   {$ELSE}
19995   QMessageBox_setWindowModality(QMessageBoxH(Widget), QtApplicationModal);
19996   QWidget_show(Widget);
19997 
19998   {$IFDEF HASX11}
19999   if (QtWidgetSet.WindowManagerName = 'metacity') then
20000       X11Raise(QWidget_winID(Widget));
20001   {$ENDIF}
20002   {$IFDEF TQTMESSAGEBOXUSEPARENT}
20003   QWidget_activateWindow(Widget);
20004   QWidget_raise(Widget);
20005   {$ENDIF}
20006 
20007   repeat
20008     QCoreApplication_processEvents();
20009     Application.Idle(true);
20010   until not QWidget_isVisible(Widget) or Application.Terminated;
20011   {$ENDIF}
20012   ABtn := QPushButtonH(QMessageBox_clickedButton(QMessageBoxH(Widget)));
20013   if ABtn <> nil then
20014   begin
20015     v := QVariant_create();
20016     try
20017       QObject_property(ABtn, v, 'lclmsgboxbutton');
20018       if QVariant_isValid(v) then
20019       begin
20020         QResult := QVariant_toLongLong(v, @Ok);
20021         if Ok then
20022           Result := QResult;
20023       end;
20024     finally
20025       QVariant_destroy(v);
20026     end;
20027   end;
20028 end;
20029 
20030 end.
20031