mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-18 17:28:29 +02:00
20259 lines
596 KiB
ObjectPascal
20259 lines
596 KiB
ObjectPascal
{
|
||
*****************************************************************************
|
||
* QtWidgets.pas *
|
||
* -------------- *
|
||
* *
|
||
* *
|
||
*****************************************************************************
|
||
|
||
*****************************************************************************
|
||
This file is part of the Lazarus Component Library (LCL)
|
||
|
||
See the file COPYING.modifiedLGPL.txt, included in this distribution,
|
||
for details about the license.
|
||
*****************************************************************************
|
||
}
|
||
unit qtwidgets;
|
||
|
||
{$mode objfpc}{$H+}
|
||
|
||
interface
|
||
|
||
{$I qtdefines.inc}
|
||
|
||
uses
|
||
// Bindings
|
||
qt5,
|
||
qtobjects, qtint,
|
||
// Free Pascal
|
||
Classes, SysUtils, Types,
|
||
// LCL
|
||
LCLType, LCLProc, LazUTF8, LCLIntf, LMessages, Graphics, Forms, Controls,
|
||
ComCtrls, ExtCtrls, StdCtrls, Menus, Dialogs, ImgList;
|
||
|
||
type
|
||
// forward declarations
|
||
TQtListWidget = class;
|
||
TQtViewPort = class;
|
||
|
||
TByteSet = set of byte;
|
||
|
||
{Used to know if our widget is part of some complex widget.
|
||
Only for TQtWidgets created by CreateFrom & attach it's events.
|
||
For now only combobox added for it's lineedit but not for droplist
|
||
which doesn't attach it's event filter.
|
||
We'll need it later for TQtScrollBar and probably TQtTabWidget}
|
||
TChildOfComplexWidget = (ccwNone,
|
||
ccwComboBox,
|
||
ccwTreeWidget,
|
||
ccwAbstractScrollArea,
|
||
ccwCustomControl,
|
||
ccwScrollingWinControl,
|
||
ccwScrollingWindow,
|
||
ccwTabWidget,
|
||
ccwTTabControl);
|
||
|
||
TQtGroupBoxType = (tgbtNormal,
|
||
tgbtCheckGroup,
|
||
tgbtRadioGroup);
|
||
|
||
{state is setted up only when LCL is doing changes.}
|
||
TQtWidgetState = (qtwsColorUpdating, qtwsFontUpdating, qtwsSizeUpdating,
|
||
qtwsPositionUpdating, qtwsInsideRightMouseButtonPressEvent,
|
||
qtwsHiddenInsideRightMouseButtonPressEvent,
|
||
qtwsForceSendMove {mantis #34589 , LM_MOVE from ScrollWindowEx(SW_SCROLLCHILDREN)});
|
||
|
||
TQtWidgetStates = set of TQtWidgetState;
|
||
|
||
// records
|
||
TPaintData = record
|
||
PaintWidget: QWidgetH;
|
||
ClipRect: Prect;
|
||
ClipRegion: QRegionH;
|
||
end;
|
||
|
||
// interfaces
|
||
|
||
{ IQtTextEdit }
|
||
|
||
{ IQtEdit }
|
||
|
||
IQtEdit = interface
|
||
['{035CA259-4442-4E82-9E70-96A114DD3BC6}']
|
||
function getCursorPosition: TPoint;
|
||
function getMaxLength: Integer;
|
||
function getSelectionStart: Integer;
|
||
function getSelectionLength: Integer;
|
||
function isUndoAvailable: Boolean;
|
||
procedure setEchoMode(const AMode: QLineEditEchoMode);
|
||
procedure setMaxLength(const ALength: Integer);
|
||
procedure setReadOnly(const AReadOnly: Boolean);
|
||
procedure setSelection(const AStart, ALength: Integer);
|
||
procedure setBorder(const ABorder: Boolean);
|
||
procedure setCursorPosition(const ACursorPosition: Integer);
|
||
procedure setTextHint(const ATextHint: string);
|
||
procedure Cut;
|
||
procedure Copy;
|
||
procedure Paste;
|
||
procedure Undo;
|
||
end;
|
||
|
||
// classes
|
||
|
||
{ TQtWidget }
|
||
|
||
TQtWidget = class(TQtObject, IUnknown)
|
||
private
|
||
FInResizeEvent: boolean;
|
||
FWidgetState: TQtWidgetStates;
|
||
FWidgetDefaultFont: TQtFont;
|
||
FWidgetLCLFont: TQtFont;
|
||
FWidgetNeedFontColorInitialization: Boolean;
|
||
FChildOfComplexWidget: TChildOfComplexWidget;
|
||
FOwnWidget: Boolean;
|
||
FProps: TStringList;
|
||
FPaintData: TPaintData;
|
||
FCentralWidget: QWidgetH;
|
||
FContext: HDC;
|
||
FParams: TCreateParams;
|
||
FDefaultCursor: QCursorH;
|
||
FKeysToEat: TByteSet;
|
||
FText: WideString;
|
||
FHasCaret: Boolean;
|
||
FLastCaretPos: TQtPoint;
|
||
FHasPaint: Boolean;
|
||
FOwner: TQtWidget;
|
||
|
||
FWidgetColorRole: QPaletteColorRole;
|
||
FTextColorRole: QPaletteColorRole;
|
||
FPalette: TQtWidgetPalette;
|
||
|
||
{TQtWidget.scroll() info}
|
||
FScrollX: Integer;
|
||
FScrollY: Integer;
|
||
|
||
function GetPalette: TQtWidgetPalette;
|
||
function GetProps(const AnIndex: String): pointer;
|
||
function getScrolledOffset: TPoint;
|
||
function GetStyleSheet: WideString;
|
||
function GetWidget: QWidgetH;
|
||
function LCLKeyToQtKey(AKey: Word): Integer;
|
||
function QtButtonsToLCLButtons(AButtons: QtMouseButton): PtrInt;
|
||
function QtKeyModifiersToKeyState(AModifiers: QtKeyboardModifiers;
|
||
const AIsKeyEvent: Boolean;
|
||
AEvent: QKeyEventH = nil): PtrInt;
|
||
function QtKeyToLCLKey(AKey: Integer; AText: WideString;
|
||
AEvent: QKeyEventH): Word;
|
||
procedure SetLastCaretPos(const AValue: TQtPoint);
|
||
procedure SetProps(const AnIndex: String; const AValue: pointer);
|
||
procedure SetStyleSheet(const AValue: WideString);
|
||
procedure SetWidget(const AValue: QWidgetH);
|
||
function ShiftStateToQtModifiers(Shift: TShiftState): QtModifier;
|
||
protected
|
||
// IUnknown implementation
|
||
function QueryInterface(constref iid: TGuid; out obj): LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||
function _AddRef: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||
function _Release: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||
function GetContext: HDC; virtual;
|
||
function CreateWidget(const Params: TCreateParams):QWidgetH; virtual;
|
||
procedure DestroyWidget; virtual;
|
||
procedure SetHasCaret(const AValue: Boolean);
|
||
function ProcessArrowKeys: Boolean; virtual;
|
||
|
||
class procedure removeProperty(AObject: QObjectH; APropName: PAnsiChar);
|
||
class procedure setProperty(AObject: QObjectH; APropName: PAnsiChar; APropValue: Int64);
|
||
public
|
||
LCLObject: TWinControl;
|
||
public
|
||
constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); virtual; overload;
|
||
constructor CreateFrom(const AWinControl: TWinControl; AWidget: QWidgetH); virtual;
|
||
procedure InitializeAccessibility; virtual;
|
||
procedure InitializeWidget; virtual;
|
||
procedure DeInitializeWidget; virtual;
|
||
procedure RecreateWidget;
|
||
procedure DestroyNotify(AWidget: TQtWidget); virtual;
|
||
|
||
destructor Destroy; override;
|
||
function GetContainerWidget: QWidgetH; virtual;
|
||
procedure Release; override;
|
||
procedure Destroyed; cdecl; override;
|
||
public
|
||
function WinIDNeeded: boolean; virtual;
|
||
function CanAdjustClientRectOnResize: Boolean; virtual;
|
||
function CanChangeFontColor: Boolean; virtual;
|
||
function CanSendLCLMessage: Boolean;
|
||
function CanPaintBackground: Boolean; virtual;
|
||
{delays resize event of complex widgets or when LCLObject have caspComputingBounds in AutoSizePhases}
|
||
procedure DelayResizeEvent(AWidget: QWidgetH; ANewSize: TSize);
|
||
function DeliverMessage(var Msg; const AIsInputEvent: Boolean = False): LRESULT; virtual;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
function getAcceptDropFiles: Boolean; virtual;
|
||
{precise measure of text with widget''s current font when canvas.handle isn''t available}
|
||
function measureText(AText: WideString; AFlags: cardinal): TRect;
|
||
procedure SetNoMousePropagation(Sender: QWidgetH; const ANoMousePropagation: Boolean); virtual;
|
||
procedure SetLCLFont(AFont: TQtFont);
|
||
procedure SlotShow(vShow: Boolean); cdecl;
|
||
function SlotClose: Boolean; cdecl; virtual;
|
||
procedure SlotDestroy; cdecl;
|
||
function slotDropFiles(Sender: QObjectH; Event: QEventH): Boolean;
|
||
function SlotHover(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function SlotKey(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; virtual; cdecl;
|
||
procedure SlotNCMouse(Sender: QObjectH; Event: QEventH); cdecl;
|
||
function SlotMouseEnter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function SlotMouseMove(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function SlotMouseWheel(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
procedure SlotMove(Event: QEventH); cdecl;
|
||
procedure SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl; virtual;
|
||
procedure SlotPaint(Sender: QObjectH; Event: QEventH); cdecl; virtual;
|
||
procedure SlotResize(Event: QEventH); cdecl;
|
||
function SlotContextMenu(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
procedure SlotWhatsThis(Sender: QObjectH; Event: QEventH); cdecl;
|
||
procedure SlotLCLMessage(Sender: QObjectH; Event: QEventH); cdecl;
|
||
public
|
||
procedure Activate; virtual;
|
||
procedure BringToFront;
|
||
procedure clearMask;
|
||
procedure OffsetMousePos(APoint: PQtPoint); virtual;
|
||
procedure Update(ARect: PRect = nil); virtual;
|
||
procedure UpdateRegion(ARgn: QRegionH); virtual;
|
||
procedure Repaint(ARect: PRect = nil); virtual;
|
||
procedure setWindowTitle(Str: PWideString);
|
||
procedure WindowTitle(Str: PWideString);
|
||
procedure Hide;
|
||
procedure Show;
|
||
procedure ShowNormal;
|
||
procedure ShowMinimized;
|
||
procedure ShowMaximized;
|
||
procedure ShowFullScreen;
|
||
function getActionByIndex(AIndex: Integer): QActionH;
|
||
function getAutoFillBackground: Boolean;
|
||
function getClientBounds: TRect; virtual;
|
||
function getClientOffset: TPoint; virtual;
|
||
function getEnabled: Boolean;
|
||
function getFont: QFontH;
|
||
function getFocusPolicy: QtFocusPolicy;
|
||
function getFrameGeometry: TRect; virtual;
|
||
function getGeometry: TRect; virtual;
|
||
function getLayoutDirection: QtLayoutDirection;
|
||
function getVisible: Boolean; virtual;
|
||
function getVisibleTo(AWidget: QWidgetH): Boolean; virtual;
|
||
function getOwner: TQtWidget;
|
||
function getParent: QWidgetH;
|
||
function getPos: TQtPoint;
|
||
function getFrameSize: TSize; virtual;
|
||
function getSize: TSize;
|
||
function getText: WideString; virtual;
|
||
function getTextStatic: Boolean; virtual;
|
||
function getHeight: Integer;
|
||
function getUpdatesEnabled: Boolean;
|
||
function getWidth: Integer;
|
||
function getWindow: TQtWidget;
|
||
function getWindowState: QtWindowStates; {$IFDEF QTSCROLLABLEFORMS}virtual;{$ENDIF}
|
||
procedure grabMouse; virtual;
|
||
function hasFocus: Boolean; virtual;
|
||
function IsActiveWindow: Boolean;
|
||
function isMinimized: Boolean;
|
||
function isMaximized: Boolean;
|
||
function IsFramedWidget: boolean; virtual;
|
||
function isFullScreen: Boolean;
|
||
function IsWindow: Boolean;
|
||
procedure lowerWidget; virtual;
|
||
function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; virtual;
|
||
function MapFromGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; virtual;
|
||
procedure move(ANewLeft, ANewTop: Integer); virtual;
|
||
procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); virtual;
|
||
procedure raiseWidget; virtual;
|
||
procedure stackUnder(AWidget: QWidgetH); virtual;
|
||
procedure frame_resize(ANewWidth, ANewHeight: Integer);
|
||
procedure Resize(ANewWidth, ANewHeight: Integer); virtual;
|
||
procedure releaseMouse;
|
||
procedure scroll(dx, dy: integer; ARect: PRect = nil); virtual;
|
||
procedure setAutoFillBackground(const AValue: Boolean);
|
||
procedure setAttribute(const Attr: QtWidgetAttribute; const TurnOn: Boolean = True);
|
||
procedure setBackgroundRole(const ARole: QPaletteColorRole);
|
||
procedure setDefaultColor(const DefaultColorType: TDefaultColorType);
|
||
procedure setColor(const Value: PQColor); virtual;
|
||
function getContextMenuPolicy: QtContextMenuPolicy; virtual;
|
||
procedure setContextMenuPolicy(const AValue: QtContextMenuPolicy); virtual;
|
||
procedure setCursor(const ACursor: QCursorH); virtual;
|
||
procedure setDefaultColorRoles; virtual;
|
||
procedure setEnabled(p1: Boolean);
|
||
procedure setFocus;
|
||
procedure setFocusPolicy(const APolicy: QtFocusPolicy); virtual;
|
||
procedure setFocusProxy(const AWidget: QWidgetH);
|
||
procedure setFont(AFont: QFontH);
|
||
procedure setGeometry(ARect: TRect); virtual;
|
||
procedure setInitialFontColor(AControl: TWinControl); virtual;
|
||
procedure setLayoutDirection(ADirection: QtLayoutDirection);
|
||
procedure setMaximumSize(AWidth, AHeight: Integer);
|
||
procedure setMask(AMask: QBitmapH); overload;
|
||
procedure setMask(AMask: QRegionH); overload;
|
||
procedure setMinimumSize(AWidth, AHeight: Integer);
|
||
procedure setParent(parent: QWidgetH); virtual;
|
||
procedure setText(const W: WideString); virtual;
|
||
procedure setTextColor(const Value: PQColor); virtual;
|
||
procedure setVisible(AVisible: Boolean); virtual;
|
||
procedure setWindowFlags(_type: QtWindowFlags);
|
||
procedure setWindowIcon(AIcon: QIconH);
|
||
procedure setWindowModality(windowModality: QtWindowModality);
|
||
procedure setWindowOpacity(opacity: double);
|
||
procedure setWidth(p1: Integer);
|
||
procedure setHeight(p1: Integer);
|
||
procedure setUpdatesEnabled(const AEnabled: Boolean);
|
||
procedure setWindowState(AState: QtWindowStates);
|
||
procedure sizeHint(size: PSize);
|
||
function testAttribute(const AAttribute: QtWidgetAttribute): boolean;
|
||
function windowFlags: QtWindowFlags;
|
||
function windowModality: QtWindowModality;
|
||
function grabWindow(const X, Y, Width, Height: integer; AWidget: QWidgetH=
|
||
nil): QPixmapH;
|
||
property ChildOfComplexWidget: TChildOfComplexWidget read FChildOfComplexWidget write FChildOfComplexWidget;
|
||
property Context: HDC read GetContext;
|
||
property HasCaret: Boolean read FHasCaret write SetHasCaret;
|
||
property HasPaint: Boolean read FHasPaint write FHasPaint;
|
||
property InResizeEvent: boolean read FInResizeEvent write FInResizeEvent;
|
||
property KeysToEat: TByteSet read FKeysToEat write FKeysToEat;
|
||
property LastCaretPos: TQtPoint read FLastCaretPos write SetLastCaretPos;
|
||
property ScrolledOffset: TPoint read getScrolledOffset;
|
||
property StyleSheet: WideString read GetStyleSheet write SetStyleSheet;
|
||
property PaintData: TPaintData read FPaintData write FPaintData;
|
||
property Palette: TQtWidgetPalette read GetPalette;
|
||
property Props[AnIndex:String]:pointer read GetProps write SetProps;
|
||
property TextColorRole: QPaletteColorRole read FTextColorRole write FTextColorRole;
|
||
property Widget: QWidgetH read GetWidget write SetWidget;
|
||
property WidgetColorRole: QPaletteColorRole read FWidgetColorRole write FWidgetColorRole;
|
||
property WidgetState: TQtWidgetStates read FWidgetState write FWidgetState;
|
||
end;
|
||
|
||
{ TQtAbstractSlider , inherited by TQtScrollBar, TQtTrackBar }
|
||
|
||
TQtAbstractSlider = class(TQtWidget)
|
||
private
|
||
FSliderPressed: Boolean;
|
||
FSliderReleased: Boolean;
|
||
FRangeChangedHook: QAbstractSlider_hookH;
|
||
FSliderMovedHook: QAbstractSlider_hookH;
|
||
FSliderPressedHook: QAbstractSlider_hookH;
|
||
FSliderReleasedHook: QAbstractSlider_hookH;
|
||
FValueChangedHook: QAbstractSlider_hookH;
|
||
FActionTriggeredHook: QAbstractSlider_hookH;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
|
||
procedure SlotSliderMoved(p1: Integer); cdecl; virtual;
|
||
procedure SlotValueChanged(p1: Integer); cdecl; virtual;
|
||
procedure SlotActionTriggered(action: Integer); cdecl; virtual;
|
||
procedure SlotRangeChanged(minimum: Integer; maximum: Integer); cdecl; virtual;
|
||
procedure SlotSliderPressed; cdecl;
|
||
procedure SlotSliderReleased; cdecl; virtual;
|
||
public
|
||
function CanChangeFontColor: Boolean; override;
|
||
function getInvertedAppereance: Boolean;
|
||
function getInvertedControls: Boolean;
|
||
function getOrientation: QtOrientation;
|
||
function getValue: Integer;
|
||
function getPageStep: Integer;
|
||
function getMin: Integer;
|
||
function getMax: Integer;
|
||
function getSingleStep: Integer;
|
||
function getSliderDown: Boolean;
|
||
function getSliderPosition: Integer;
|
||
function getTracking: Boolean;
|
||
|
||
procedure setInvertedAppereance(p1: Boolean); virtual;
|
||
procedure setInvertedControls(p1: Boolean); virtual;
|
||
|
||
procedure setMaximum(p1: Integer); virtual;
|
||
procedure setMinimum(p1: Integer); virtual;
|
||
|
||
procedure setOrientation(p1: QtOrientation); virtual;
|
||
procedure setPageStep(p1: Integer); virtual;
|
||
procedure setRange(minimum: Integer; maximum: Integer); virtual;
|
||
procedure setSingleStep(p1: Integer); virtual;
|
||
procedure setSliderDown(p1: Boolean); virtual;
|
||
procedure setSliderPosition(p1: Integer); virtual;
|
||
procedure setTracking(p1: Boolean); virtual;
|
||
procedure setValue(p1: Integer); virtual;
|
||
property SliderPressed: Boolean read FSliderPressed;
|
||
property SliderReleased: Boolean read FSliderReleased;
|
||
end;
|
||
|
||
{ TQtScrollBar }
|
||
|
||
TQtScrollBar = class(TQtAbstractSlider)
|
||
private
|
||
FTrackPos: Integer;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
|
||
procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
|
||
procedure SlotSliderReleased; cdecl; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure AttachEvents; override;
|
||
property TrackPos: Integer read FTrackPos write FTrackPos;
|
||
end;
|
||
|
||
{ TQtFrame }
|
||
|
||
TQtFrame = class(TQtWidget)
|
||
private
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
function CanPaintBackground: Boolean; override;
|
||
procedure SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl; override;
|
||
procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
|
||
procedure setFrameStyle(p1: Integer);
|
||
procedure setFrameShape(p1: QFrameShape);
|
||
procedure setFrameShadow(p1: QFrameShadow);
|
||
end;
|
||
|
||
{ TQtAbstractScrollArea }
|
||
|
||
TQtAbstractScrollArea = class(TQtFrame)
|
||
private
|
||
function getScrollBarsPolicy(AIndex: Boolean): QtScrollBarPolicy;
|
||
protected
|
||
FHScrollbar: TQtScrollBar;
|
||
FVScrollbar: TQtScrollbar;
|
||
procedure setScrollBarPolicy(AIndex: Boolean;
|
||
const AValue: QtScrollBarPolicy);
|
||
public
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure grabMouse; override;
|
||
function GetContainerWidget: QWidgetH; override;
|
||
function getClientOffset: TPoint; override;
|
||
function getClientBounds: TRect; override;
|
||
function getScrollFrameOffset: Integer;
|
||
function getViewOrigin: TPoint;
|
||
function viewportWidget: QWidgetH;
|
||
function horizontalScrollBar: TQtScrollBar;
|
||
procedure InitializeAccessibility; override;
|
||
function verticalScrollBar: TQtScrollBar;
|
||
procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
|
||
procedure setHorizontalScrollBar(AScrollBar: TQtScrollBar);
|
||
procedure setVerticalScrollBar(AScrollBar: TQtScrollBar);
|
||
procedure setScrollStyle(AScrollStyle: TScrollStyle);
|
||
procedure SetNoMousePropagation(Sender: QWidgetH; const ANoMousePropagation: Boolean); override;
|
||
procedure DestroyNotify(AWidget: TQtWidget); override;
|
||
destructor Destroy; override;
|
||
procedure Update(ARect: PRect = nil); override;
|
||
procedure UpdateRegion(ARgn: QRegionH); override;
|
||
procedure Repaint(ARect: PRect = nil); override;
|
||
property ScrollBarPolicy[AIndex: Boolean]: QtScrollBarPolicy read getScrollBarsPolicy write setScrollBarPolicy;
|
||
end;
|
||
|
||
{ TQtCustomControl }
|
||
|
||
TQtCustomControl = class(TQtAbstractScrollArea)
|
||
private
|
||
FCornerWidget: TQtWidget;
|
||
FViewPortWidget: TQtViewPort;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
function ProcessArrowKeys: Boolean; override;
|
||
public
|
||
destructor Destroy; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure ViewPortEventFilter(event: QEventH; retval: PBoolean); cdecl;
|
||
procedure Destroyed; cdecl; override;
|
||
procedure DestroyNotify(AWidget: TQtWidget); override;
|
||
public
|
||
function CanAdjustClientRectOnResize: Boolean; override;
|
||
function cornerWidget: TQtWidget;
|
||
procedure InitializeAccessibility; override;
|
||
function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
|
||
function MapFromGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
|
||
function viewport: TQtViewPort;
|
||
procedure preferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); override;
|
||
procedure setCornerWidget(AWidget: TQtWidget);
|
||
procedure setCursor(const ACursor: QCursorH); override;
|
||
procedure setViewport(const AViewPort: QWidgetH);
|
||
procedure setVisible(AVisible: Boolean); override;
|
||
procedure viewportNeeded; virtual;
|
||
procedure viewportDelete; virtual;
|
||
end;
|
||
|
||
{ TQtViewPort }
|
||
|
||
TQtViewPort = class(TQtWidget)
|
||
private
|
||
{when our viewport is invisible then we must keep track of scrolling. issue #29239}
|
||
FInvisibleX: integer;
|
||
FInvisibleY: integer;
|
||
public
|
||
function CanPaintBackground: Boolean; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure InitializeWidget; override;
|
||
procedure scroll(dx, dy: integer; ARect: PRect = nil); override;
|
||
procedure stackUnder(AWidget: QWidgetH); override;
|
||
end;
|
||
|
||
{ TQtGraphicView }
|
||
|
||
TQtGraphicsView = class(TQtAbstractScrollArea)
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
end;
|
||
|
||
{ TQtArrow }
|
||
|
||
TQtArrow = class(TQtFrame)
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
ArrowType: Integer;
|
||
end;
|
||
|
||
{ TQtAbstractButton }
|
||
|
||
TQtAbstractButton = class(TQtWidget)
|
||
protected
|
||
function ProcessArrowKeys: Boolean; override;
|
||
public
|
||
function CanPaintBackground: Boolean; override;
|
||
function getIconSize: TSize; virtual;
|
||
function getText: WideString; override;
|
||
procedure setIcon(AIcon: QIconH); virtual;
|
||
procedure setIconSize(Size: PSize); virtual;
|
||
procedure setShortcut(AShortCutK1, AShortCutK2: TShortcut);
|
||
procedure setText(const W: WideString); override;
|
||
procedure Toggle;
|
||
function isChecked: Boolean;
|
||
function isDown: Boolean;
|
||
procedure setCheckable(p1: Boolean);
|
||
procedure setChecked(p1: Boolean);
|
||
procedure setDefaultColorRoles; override;
|
||
procedure setDown(p1: Boolean);
|
||
procedure SignalPressed; cdecl;
|
||
procedure SignalReleased; cdecl;
|
||
procedure SignalClicked({%H-}Checked: Boolean = False); cdecl;
|
||
procedure SignalClicked2; cdecl;
|
||
end;
|
||
|
||
{ TQtPushButton }
|
||
|
||
TQtPushButton = class(TQtAbstractButton)
|
||
private
|
||
FClickedHook: QAbstractButton_hookH;
|
||
FToggledHook: QAbstractButton_hookH;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
|
||
public
|
||
procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
|
||
public
|
||
procedure SetDefault(const ADefault: Boolean);
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
procedure SlotClicked; cdecl; virtual;
|
||
procedure SlotToggled({%H-}AChecked: Boolean); cdecl; virtual;
|
||
end;
|
||
|
||
{ TQtBitBtn }
|
||
|
||
TQtBitBtn = class(TQtPushButton)
|
||
private
|
||
FGlyphLayout: Integer;
|
||
FIcon: QIconH;
|
||
FIconSize: TSize;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
|
||
public
|
||
destructor Destroy; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure preferredSize(var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
|
||
|
||
function getIconSize: TSize; override;
|
||
function getText: WideString; override;
|
||
procedure setIcon(AIcon: QIconH); override;
|
||
procedure setIconSize(Size: PSize); override;
|
||
procedure setText(const W: WideString); override;
|
||
|
||
property GlyphLayout: Integer read FGlyphLayout write FGlyphLayout;
|
||
end;
|
||
|
||
{ TQtToggleBox }
|
||
|
||
TQtToggleBox = class(TQtPushButton)
|
||
public
|
||
procedure SlotClicked; cdecl; override;
|
||
procedure SlotToggled({%H-}AChecked: Boolean); cdecl; override;
|
||
end;
|
||
|
||
{ TQtMainWindow }
|
||
|
||
TQtMenuBar = class;
|
||
TQtToolBar = class;
|
||
TQtStatusBar = class;
|
||
|
||
{ TQtMDIArea }
|
||
|
||
TQtMDIArea = class(TQtAbstractScrollArea)
|
||
private
|
||
FViewPortEventHook: QObject_hookH;
|
||
FSubWindowActivationHook: QMdiArea_hookH;
|
||
procedure SubWindowActivated(AWindow: QMDISubWindowH); cdecl;
|
||
protected
|
||
function ScrollViewEventFilter(Sender: QObjectH; Event: QEventH): boolean; cdecl;
|
||
public
|
||
constructor Create(const AParent: QWidgetH); overload;
|
||
destructor Destroy; override;
|
||
function getClientOffset: TPoint; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function ActiveSubWindow: QMdiSubWindowH;
|
||
procedure ActivateSubWindow(AMdiWindow: QMdiSubWindowH);
|
||
end;
|
||
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
{ TQtWindowArea }
|
||
|
||
{Scrollbars on qt forms}
|
||
TQtWindowArea = class(TQtAbstractScrollArea)
|
||
private
|
||
FViewPortEventHook: QObject_hookH;
|
||
public
|
||
procedure AttachEvents; override;
|
||
function CanAdjustClientRectOnResize: Boolean; override;
|
||
procedure DetachEvents; override;
|
||
function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
|
||
procedure scroll(dx, dy: integer; ARect: PRect = nil); override;
|
||
{abstractscrollarea events}
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
{viewport events}
|
||
function ScrollViewEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function getWindowState: QtWindowStates; override;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
TQtMainWindow = class(TQtWidget)
|
||
private
|
||
FBlocked: Boolean;
|
||
FFirstPaintEvent: boolean;
|
||
FIsFrameWindow: Boolean;
|
||
LayoutWidget: QBoxLayoutH;
|
||
FCWEventHook: QObject_hookH;
|
||
FShowOnTaskBar: Boolean;
|
||
FPopupParent: QWidgetH;
|
||
FMDIStateHook: QMdiSubWindow_hookH;
|
||
protected
|
||
function CreateWidget(const {%H-}AParams: TCreateParams):QWidgetH; override;
|
||
procedure ChangeParent(NewParent: QWidgetH);
|
||
procedure UpdateParent;
|
||
public
|
||
QtFormBorderStyle: Integer;
|
||
QtFormStyle: Integer;
|
||
IsMainForm: Boolean;
|
||
MDIAreaHandle: TQtMDIArea; // valid only if we are fsMDIForm
|
||
MDIChildArea: TQtMDIArea; // valid only if we are fsMDIChild
|
||
MenuBar: TQtMenuBar;
|
||
ToolBar: TQtToolBar;
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
ScrollArea: TQtWindowArea;
|
||
{$ENDIF}
|
||
destructor Destroy; override;
|
||
|
||
procedure BeginUpdate; override;
|
||
procedure EndUpdate; override;
|
||
|
||
procedure Activate; override;
|
||
function CanAdjustClientRectOnResize: Boolean; override;
|
||
function getAcceptDropFiles: Boolean; override;
|
||
function GetContainerWidget: QWidgetH; override;
|
||
procedure grabMouse; override;
|
||
function getClientBounds: TRect; override;
|
||
function getClientOffset: TPoint; override;
|
||
|
||
function getText: WideString; override;
|
||
function getTextStatic: Boolean; override;
|
||
|
||
function MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean = False): TPoint; override;
|
||
|
||
procedure Update(ARect: PRect = nil); override;
|
||
procedure UpdateRegion(ARgn: QRegionH); override;
|
||
procedure Repaint(ARect: PRect = nil); override;
|
||
|
||
procedure Resize(ANewWidth, ANewHeight: Integer); override;
|
||
procedure setText(const W: WideString); override;
|
||
procedure setMenuBar(AMenuBar: QMenuBarH);
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure MDIChildWindowStateChanged(AOldState: QtWindowStates; ANewState: QtWindowStates); cdecl;
|
||
function IsMdiChild: Boolean;
|
||
function IsModal: Boolean;
|
||
function MdiChildCount: integer;
|
||
procedure OffsetMousePos(APoint: PQtPoint); override;
|
||
procedure setAcceptDropFiles(AValue: Boolean);
|
||
procedure setColor(const Value: PQColor); override;
|
||
procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
|
||
procedure SlotActivateWindow(vActivate: Boolean); cdecl;
|
||
procedure slotWindowStateChange; cdecl;
|
||
procedure setShowInTaskBar(AValue: Boolean);
|
||
procedure setRealPopupParent(NewParent: QWidgetH);
|
||
property Blocked: Boolean read FBlocked write FBlocked;
|
||
property IsFrameWindow: Boolean read FIsFrameWindow write FIsFrameWindow; {check if our LCLObject is TCustomFrame}
|
||
property FirstPaintEvent: boolean read FFirstPaintEvent write FFirstPaintEvent; {only for x11 - if firstpaintevent arrived we are 100% sure that frame is 100% accurate}
|
||
property ShowOnTaskBar: Boolean read FShowOnTaskBar;
|
||
public
|
||
function WinIDNeeded: boolean; override;
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function CWEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
end;
|
||
|
||
{ TQtHintWindow }
|
||
|
||
TQtHintWindow = class(TQtMainWindow)
|
||
private
|
||
FNeedRestoreVisible: Boolean;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
|
||
public
|
||
function WinIDNeeded: boolean; override;
|
||
procedure InitializeWidget; override;
|
||
procedure DeInitializeWidget; override;
|
||
function CanPaintBackground: Boolean; override;
|
||
procedure SetDefaultColorRoles; override;
|
||
procedure setVisible(AVisible: Boolean); override;
|
||
property NeedRestoreVisible: Boolean read FNeedRestoreVisible write FNeedRestoreVisible;
|
||
end;
|
||
|
||
{ TQtStaticText }
|
||
|
||
TQtStaticText = class(TQtFrame)
|
||
private
|
||
function GetWordWrap: Boolean;
|
||
procedure SetWordWrap(AValue: Boolean);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
function CanPaintBackground: Boolean; override;
|
||
function getText: WideString; override;
|
||
procedure setText(const W: WideString); override;
|
||
procedure setAlignment(const AAlignment: QtAlignment);
|
||
property WordWrap: Boolean read GetWordWrap write SetWordWrap;
|
||
end;
|
||
|
||
{ TQtCheckBox }
|
||
|
||
TQtCheckBox = class(TQtAbstractButton)
|
||
private
|
||
FStateChangedHook : QCheckBox_hookH;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
function CheckState: QtCheckState;
|
||
procedure setCheckState(state: QtCheckState);
|
||
procedure setTriState(AAllowGrayed: Boolean);
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
procedure signalStateChanged(p1: Integer); cdecl;
|
||
end;
|
||
|
||
{ TQtRadioButton }
|
||
|
||
TQtRadioButton = class(TQtAbstractButton)
|
||
private
|
||
FToggledHook: QAbstractButton_hookH;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
procedure SignalToggled(Checked: Boolean); cdecl;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
end;
|
||
|
||
{ TQtGroupBox }
|
||
|
||
TQtGroupBox = class(TQtWidget)
|
||
private
|
||
FGroupBoxType: TQtGroupBoxType;
|
||
FCWEventHook: QObject_hookH;
|
||
function GetCheckBoxState: boolean;
|
||
function GetCheckBoxVisible: boolean;
|
||
procedure SetCheckBoxState(AValue: boolean);
|
||
procedure SetCheckBoxVisible(AValue: boolean);
|
||
procedure setLayoutThemeMargins(ALayout: QLayoutH; AWidget: QWidgetH);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function CanPaintBackground: Boolean; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
function getClientBounds: TRect; override;
|
||
function getText: WideString; override;
|
||
procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
|
||
{%H-}WithThemeSpace: Boolean); override;
|
||
procedure setText(const W: WideString); override;
|
||
procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
|
||
procedure Update(ARect: PRect = nil); override;
|
||
procedure UpdateRegion(ARgn: QRegionH); override;
|
||
procedure Repaint(ARect: PRect = nil); override;
|
||
|
||
property GroupBoxType: TQtGroupBoxType read FGroupBoxType write FGroupBoxType;
|
||
property CheckBoxState: boolean read GetCheckBoxState write SetCheckBoxState;
|
||
property CheckBoxVisible: boolean read GetCheckBoxVisible write SetCheckBoxVisible;
|
||
end;
|
||
|
||
{ TQtToolBar }
|
||
|
||
TQtToolBar = class(TQtWidget)
|
||
private
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
end;
|
||
|
||
{ TQtToolButton }
|
||
|
||
TQtToolButton = class(TQtAbstractButton)
|
||
private
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
end;
|
||
|
||
{ TQtTrackBar }
|
||
|
||
TQtTrackBar = class(TQtAbstractSlider)
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
function getTickInterval: Integer;
|
||
procedure setTickPosition(Value: QSliderTickPosition);
|
||
procedure setTickInterval(Value: Integer);
|
||
public
|
||
procedure AttachEvents; override;
|
||
|
||
procedure SlotSliderMoved(p1: Integer); cdecl; override;
|
||
procedure SlotValueChanged(p1: Integer); cdecl; override;
|
||
end;
|
||
|
||
{ TQtLineEdit }
|
||
|
||
TQtLineEdit = class(TQtWidget, IQtEdit)
|
||
private
|
||
FCachedSelectionLen: integer;
|
||
FCachedSelectionStart: integer;
|
||
FNumbersOnly: boolean;
|
||
FIntValidator: QIntValidatorH;
|
||
FTextChanged: QLineEdit_hookH;
|
||
function getTextMargins: TRect;
|
||
procedure SetNumbersOnly(AValue: boolean);
|
||
procedure setTextMargins(ARect: TRect);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
procedure setTextHint(const ATextHint: string);
|
||
public
|
||
function getAlignment: QtAlignment;
|
||
function getCursorPosition: TPoint;
|
||
function getMaxLength: Integer;
|
||
function getSelectedText: WideString;
|
||
function getSelectionStart: Integer;
|
||
function getSelectionLength: Integer;
|
||
function getText: WideString; override;
|
||
function getTextStatic: Boolean; override;
|
||
function isUndoAvailable: Boolean;
|
||
function hasSelectedText: Boolean;
|
||
procedure selectAll;
|
||
procedure setAlignment(const AAlignment: QtAlignment);
|
||
procedure setBorder(const ABorder: Boolean);
|
||
procedure setCursorPosition(const ACursorPosition: Integer);
|
||
procedure setDefaultColorRoles; override;
|
||
procedure setEchoMode(const AMode: QLineEditEchoMode);
|
||
procedure setInputMask(const AMask: WideString);
|
||
procedure setMaxLength(const ALength: Integer);
|
||
procedure setReadOnly(const AReadOnly: Boolean);
|
||
procedure setSelection(const AStart, ALength: Integer);
|
||
procedure setText(const AText: WideString); override;
|
||
procedure Cut;
|
||
procedure Copy;
|
||
procedure Paste;
|
||
procedure Undo;
|
||
public
|
||
destructor Destroy; override;
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
|
||
{%H-}WithThemeSpace: Boolean); override;
|
||
procedure SignalTextChanged(p1: PWideString); cdecl;
|
||
property CachedSelectionStart: integer read FCachedSelectionStart write FCachedSelectionStart;
|
||
property CachedSelectionLen: integer read FCachedSelectionLen write FCachedSelectionLen;
|
||
property NumbersOnly: boolean read FNumbersOnly write SetNumbersOnly;
|
||
property TextMargins: TRect read GetTextMargins write SetTextMargins;
|
||
end;
|
||
|
||
{ TQtTextEdit }
|
||
|
||
TQtTextEdit = class(TQtAbstractScrollArea, IQtEdit)
|
||
private
|
||
FViewportEventHook: QObject_hookH;
|
||
FUndoAvailableHook: QTextEdit_hookH;
|
||
FTextChangedHook: QTextEdit_hookH;
|
||
FUndoAvailable: Boolean;
|
||
function GetAcceptRichText: Boolean;
|
||
procedure SetAcceptRichText(AValue: Boolean);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
procedure setTextHint(const ATextHint: string);
|
||
public
|
||
FList: TStrings;
|
||
procedure Append(const AStr: WideString);
|
||
procedure ClearText;
|
||
function getAlignment: QtAlignment;
|
||
function getBlockCount: Integer;
|
||
function getCursorPosition: TPoint;
|
||
function getMaxLength: Integer;
|
||
function getText: WideString; override;
|
||
function getTextStatic: Boolean; override;
|
||
function getSelectionStart: Integer;
|
||
function getSelectionEnd: Integer;
|
||
function getSelectionLength: Integer;
|
||
procedure appendLine(AText: WideString);
|
||
procedure insertLine(const AIndex: integer; AText: WideString);
|
||
function isUndoAvailable: Boolean;
|
||
procedure removeLine(const AIndex: integer);
|
||
procedure setAlignment(const AAlignment: QtAlignment);
|
||
procedure setBorder(const ABorder: Boolean);
|
||
procedure setCursorPosition(const ACursorPosition: Integer);
|
||
procedure setDefaultColorRoles; override;
|
||
procedure setEchoMode(const AMode: QLineEditEchoMode);
|
||
procedure setLineWrapMode(const AMode: QTextEditLineWrapMode);
|
||
procedure setMaxLength(const ALength: Integer);
|
||
procedure setLineText(const AIndex: integer; AText: WideString);
|
||
procedure setText(const AText: WideString); override;
|
||
procedure setReadOnly(const AReadOnly: Boolean);
|
||
procedure setSelection(const AStart, ALength: Integer);
|
||
procedure setTabChangesFocus(const AValue: Boolean);
|
||
procedure Cut;
|
||
procedure Copy;
|
||
procedure Paste;
|
||
procedure Undo;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function viewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function getContextMenuPolicy: QtContextMenuPolicy; override;
|
||
procedure setContextMenuPolicy(const AValue: QtContextMenuPolicy); override;
|
||
procedure SignalUndoAvailable(b: Boolean); cdecl;
|
||
procedure SignalTextChanged(); cdecl;
|
||
property AcceptRichText: Boolean read GetAcceptRichText write SetAcceptRichText;
|
||
end;
|
||
|
||
{ TQtTabBar }
|
||
TQtTabBar = class(TQtWidget)
|
||
private
|
||
FSavedIndexOnPageChanging: Integer; // used to handle OnPageChanging AllowChange param
|
||
FTabBarChangedHook: QTabBar_hookH;
|
||
FTabBarMovedHook: QTabBar_hookH;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function GetTabRect(const AIndex: integer): TRect;
|
||
// under some themes tabs doesn't start at 0,0 (eg. MacOSX)
|
||
function TabBarOffset: TPoint;
|
||
procedure SignalTabBarMoved(fromIndex: integer; toIndex: Integer); cdecl;
|
||
procedure SignalTabBarCurrentChanged(Index: Integer); cdecl;
|
||
function SlotTabBarMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure SetTabFontColor(AIndex: Integer; AColor: TQColor);
|
||
end;
|
||
|
||
{ TQtTabWidget }
|
||
|
||
TQtTabWidget = class(TQtWidget)
|
||
private
|
||
FCurrentChangedHook: QTabWidget_hookH;
|
||
FCloseRequestedHook: QTabWidget_hookH;
|
||
FStackedWidgetHook: QObject_hookH;
|
||
FSwitchTabsByKeyboard: boolean;
|
||
FTabBar: TQtTabBar;
|
||
FStackWidget: QWidgetH;
|
||
function getShowTabs: Boolean;
|
||
function getStackWidget: QWidgetH;
|
||
function getTabBar: TQtTabBar;
|
||
procedure setShowTabs(const AValue: Boolean);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
destructor Destroy; override;
|
||
procedure DestroyNotify(AWidget: TQtWidget); override;
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure SignalCurrentChanged(Index: Integer); cdecl;
|
||
procedure SignalCloseRequested(Index: Integer); cdecl;
|
||
public
|
||
function indexOf(const AWidget: QWidgetH): integer;
|
||
function insertTab(index: Integer; page: QWidgetH; p2: WideString): Integer; overload;
|
||
function insertTab(index: Integer; page: QWidgetH; icon: QIconH; p2: WideString): Integer; overload;
|
||
function getCount: Integer;
|
||
function getClientBounds: TRect; override;
|
||
function getCurrentIndex: Integer;
|
||
function GetLCLPageIndex(AIndex: Integer): Integer;
|
||
function getTabPosition: QTabWidgetTabPosition;
|
||
procedure removeTab(AIndex: Integer);
|
||
procedure setCurrentIndex(AIndex: Integer);
|
||
procedure setCurrentWidget(APage: TQtWidget; const AIsMoved: Boolean);
|
||
procedure setTabPosition(ATabPosition: QTabWidgetTabPosition);
|
||
procedure setTabIcon(index: Integer; icon: QIconH);
|
||
procedure setTabText(index: Integer; p2: WideString);
|
||
procedure setTabsClosable(AValue: Boolean);
|
||
function tabAt(APoint: TPoint): Integer;
|
||
|
||
property ShowTabs: Boolean read getShowTabs write setShowTabs;
|
||
property TabBar: TQtTabBar read getTabBar;
|
||
property StackWidget: QWidgetH read getStackWidget;
|
||
property SwitchTabsByKeyboard: boolean read FSwitchTabsByKeyboard write FSwitchTabsByKeyboard;
|
||
end;
|
||
|
||
{ TQtComboBox }
|
||
|
||
TQtComboBox = class(TQtWidget, IQtEdit)
|
||
private
|
||
FKeyEnterFix: boolean; {issue #31574}
|
||
FMouseFixPos: TQtPoint;
|
||
// hooks
|
||
FChangeHook: QComboBox_hookH;
|
||
FActivateHook: QComboBox_hookH;
|
||
FOwnerDrawn: Boolean;
|
||
FSelectHook: QComboBox_hookH;
|
||
FDropListEventHook: QObject_hookH;
|
||
// parts
|
||
FLineEdit: TQtLineEdit;
|
||
FDropList: TQtListWidget;
|
||
FDropListVisibleInternal: Boolean;
|
||
function GetDropList: TQtListWidget;
|
||
function GetLineEdit: TQtLineEdit;
|
||
procedure InternalIntfGetItems; // calls TCustomComboBox(LCLObject).IntfGetItems
|
||
procedure SetOwnerDrawn(const AValue: Boolean);
|
||
procedure slotPaintCombo(Sender: QObjectH; Event: QEventH); cdecl;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
// IQtEdit implementation
|
||
function getCursorPosition: TPoint;
|
||
function getMaxLength: Integer;
|
||
function getSelectionStart: Integer;
|
||
function getSelectionLength: Integer;
|
||
function isUndoAvailable: Boolean;
|
||
procedure setEchoMode(const AMode: QLineEditEchoMode);
|
||
procedure setMaxLength(const ALength: Integer);
|
||
procedure setReadOnly(const AReadOnly: Boolean);
|
||
procedure setSelection(const AStart, ALength: Integer);
|
||
procedure setCursorPosition(const ACursorPosition: Integer);
|
||
procedure setTextHint(const ATextHint: string);
|
||
procedure Cut;
|
||
procedure Copy;
|
||
procedure Paste;
|
||
procedure Undo;
|
||
public
|
||
FList: TStrings;
|
||
destructor Destroy; override;
|
||
procedure DestroyNotify(AWidget: TQtWidget); override;
|
||
procedure ClearItems;
|
||
procedure setBorder(const ABorder: Boolean);
|
||
function currentIndex: Integer;
|
||
function findText(AText: WideString): Integer;
|
||
function getDroppedDown: Boolean;
|
||
function getEditable: Boolean;
|
||
function getItemText(AIndex: Integer): WideString;
|
||
function getMaxVisibleItems: Integer;
|
||
function getText: WideString; override;
|
||
function getTextStatic: Boolean; override;
|
||
procedure insertItem(AIndex: Integer; AText: String); overload;
|
||
procedure insertItem(AIndex: Integer; AText: PWideString); overload;
|
||
procedure setCurrentIndex(index: Integer);
|
||
procedure setDefaultColorRoles; override;
|
||
procedure setDroppedDown(const ADroppedDown: Boolean);
|
||
procedure setMaxVisibleItems(ACount: Integer);
|
||
procedure setEditable(const AValue: Boolean);
|
||
procedure setItemText(AIndex: Integer; AText: String);
|
||
procedure setText(const W: WideString); override;
|
||
procedure removeItem(AIndex: Integer);
|
||
|
||
property DropList: TQtListWidget read GetDropList;
|
||
property LineEdit: TQtLineEdit read GetLineEdit;
|
||
property OwnerDrawn: Boolean read FOwnerDrawn write SetOwnerDrawn;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure preferredSize(var PreferredWidth, PreferredHeight: integer;
|
||
{%H-}WithThemeSpace: Boolean); override;
|
||
|
||
procedure SlotActivate(index: Integer); cdecl;
|
||
procedure SlotChange(p1: PWideString); cdecl;
|
||
procedure SlotSelect(index: Integer); cdecl;
|
||
procedure SlotDropListVisibility(AVisible: Boolean); cdecl;
|
||
procedure FixMouseUp; // qt eats MouseRelease event when popup is shown, so we'll fix it
|
||
end;
|
||
|
||
{ TQtAbstractSpinBox}
|
||
|
||
TQtAbstractSpinBox = class(TQtWidget, IQtEdit)
|
||
private
|
||
{$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
|
||
FParentShowPassed: PtrInt;
|
||
{$ENDIF}
|
||
FEditingFinishedHook: QAbstractSpinBox_hookH;
|
||
FLineEditHook: QObject_hookH;
|
||
FTextChangedHook: QLineEdit_hookH;
|
||
// parts
|
||
FLineEdit: QLineEditH;
|
||
FTextChangedByValueChanged: Boolean;
|
||
function GetLineEdit: QLineEditH;
|
||
function LineEditEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
// IQtEdit implementation
|
||
function getCursorPosition: TPoint;
|
||
function getMaxLength: Integer;
|
||
function getSelectionStart: Integer;
|
||
function getSelectionLength: Integer;
|
||
function isUndoAvailable: Boolean;
|
||
procedure setEchoMode(const AMode: QLineEditEchoMode);
|
||
procedure setMaxLength(const ALength: Integer);
|
||
procedure setSelection(const AStart, ALength: Integer);
|
||
procedure setCursorPosition(const ACursorPosition: Integer);
|
||
procedure SignalLineEditTextChanged(AnonParam1: PWideString); virtual; cdecl;
|
||
procedure setTextHint(const ATextHint: string);
|
||
procedure Cut;
|
||
procedure Copy;
|
||
procedure Paste;
|
||
procedure Undo;
|
||
property TextChangedByValueChanged: Boolean read FTextChangedByValueChanged write FTextChangedByValueChanged;
|
||
public
|
||
function getValue: Double; virtual; abstract;
|
||
function getReadOnly: Boolean;
|
||
function getText: WideString; override;
|
||
function getTextStatic: Boolean; override;
|
||
procedure setAlignment(const AAlignment: QtAlignment);
|
||
procedure setBorder(const ABorder: Boolean);
|
||
procedure setDefaultColorRoles; override;
|
||
procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
|
||
procedure setMinimum(const v: Double); virtual; abstract;
|
||
procedure setMaximum(const v: Double); virtual; abstract;
|
||
procedure setSingleStep(const v: Double); virtual; abstract;
|
||
procedure setReadOnly(const r: Boolean);
|
||
procedure setValue(const v: Double); virtual; abstract;
|
||
procedure setText(const W: WideString); override;
|
||
|
||
property LineEdit: QLineEditH read GetLineEdit;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
|
||
procedure SignalEditingFinished; cdecl;
|
||
end;
|
||
|
||
{ TQtFloatSpinBox }
|
||
|
||
TQtFloatSpinBox = class(TQtAbstractSpinBox)
|
||
private
|
||
FValue: Double;
|
||
FValueChangedHook: QDoubleSpinBox_hookH;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
function getValue: Double; override;
|
||
procedure setDecimals(const v: integer);
|
||
procedure setMinimum(const v: Double); override;
|
||
procedure setMaximum(const v: Double); override;
|
||
procedure setSingleStep(const v: Double); override;
|
||
procedure setValue(const v: Double); override;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
procedure SignalValueChanged(p1: Double); cdecl;
|
||
end;
|
||
|
||
{ TQtSpinBox }
|
||
|
||
TQtSpinBox = class(TQtAbstractSpinBox)
|
||
private
|
||
FValue: Integer;
|
||
FValueChangedHook: QSpinBox_hookH;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
function getValue: Double; override;
|
||
procedure setMinimum(const v: Double); override;
|
||
procedure setMaximum(const v: Double); override;
|
||
procedure setSingleStep(const v: Double); override;
|
||
procedure setValue(const v: Double); override;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
|
||
procedure SignalValueChanged(p1: Integer); cdecl;
|
||
end;
|
||
|
||
{ TQtAbstractItemView }
|
||
|
||
TQtAbstractItemView = class(TQtAbstractScrollArea)
|
||
private
|
||
FAllowGrayed: boolean;
|
||
FSavedEvent: QMouseEventH;
|
||
FSavedEventTimer: QTimerH;
|
||
FSavedEventTimerHook: QTimer_hookH;
|
||
FCheckable: boolean;
|
||
FHideSelection: Boolean;
|
||
FOldDelegate: QAbstractItemDelegateH;
|
||
FNewDelegate: QLCLItemDelegateH;
|
||
FOwnerData: Boolean;
|
||
FSignalActivated: QAbstractItemView_hookH;
|
||
FSignalClicked: QAbstractItemView_hookH;
|
||
FSignalDoubleClicked: QAbstractItemView_hookH;
|
||
FSignalEntered: QAbstractItemView_hookH;
|
||
FSignalPressed: QAbstractItemView_hookH;
|
||
FSignalViewportEntered: QAbstractItemView_hookH;
|
||
FAbstractItemViewportEventHook: QObject_hookH;
|
||
FSyncingItems: Boolean;
|
||
FViewStyle: Integer;
|
||
function getIconSize: TSize;
|
||
function GetOwnerDrawn: Boolean;
|
||
procedure setIconSize(const AValue: TSize);
|
||
procedure SetOwnerDrawn(const AValue: Boolean);
|
||
protected
|
||
function GetItemFlags(AIndex: Integer): QtItemFlags; virtual;
|
||
procedure SetItemFlags(AIndex: Integer; AValue: QtItemFlags); virtual;
|
||
procedure OwnerDataNeeded(ARect: TRect); virtual;
|
||
procedure PostponedMouseRelease(AEvent: QEventH); virtual;
|
||
procedure PostponedMouseReleaseTimerEvent(); cdecl; virtual;
|
||
public
|
||
constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); override;
|
||
destructor Destroy; override;
|
||
procedure signalActivated(index: QModelIndexH); cdecl; virtual;
|
||
procedure signalClicked(index: QModelIndexH); cdecl; virtual;
|
||
procedure signalDoubleClicked(index: QModelIndexH); cdecl; virtual;
|
||
procedure signalEntered(index: QModelIndexH); cdecl; virtual;
|
||
procedure signalPressed(index: QModelIndexH); cdecl; virtual;
|
||
procedure signalViewportEntered; cdecl; virtual;
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
|
||
function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; virtual;
|
||
procedure setDefaultColorRoles; override;
|
||
public
|
||
procedure clearSelection; virtual;
|
||
function getModel: QAbstractItemModelH;
|
||
function getRowHeight(ARowIndex: integer): integer;
|
||
function getSelectionMode: QAbstractItemViewSelectionMode;
|
||
function getTopItem: integer; virtual;
|
||
function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; virtual;
|
||
|
||
procedure modelIndex(retval: QModelIndexH; row, column: Integer; parent: QModelIndexH = nil);
|
||
function visualRect(Index: QModelIndexH): TRect;
|
||
procedure setEditTriggers(ATriggers: QAbstractItemViewEditTriggers);
|
||
procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); virtual;
|
||
procedure setSelectionBehavior(ABehavior: QAbstractItemViewSelectionBehavior);
|
||
procedure setWordWrap(const AValue: Boolean); virtual;
|
||
property AllowGrayed: boolean read FAllowGrayed write FAllowGrayed;
|
||
property Checkable: boolean read FCheckable write FCheckable;
|
||
property HideSelection: Boolean read FHideSelection write FHideSelection;
|
||
property IconSize: TSize read getIconSize write setIconSize;
|
||
property ItemFlags[AIndex: Integer]: QtItemFlags read GetItemFlags write SetItemFlags;
|
||
property OwnerDrawn: Boolean read GetOwnerDrawn write SetOwnerDrawn;
|
||
property OwnerData: Boolean read FOwnerData write FOwnerData;
|
||
property SyncingItems: Boolean read FSyncingItems write FSyncingItems;
|
||
property ViewStyle: Integer read FViewStyle write FViewStyle;
|
||
public
|
||
procedure ItemDelegateSizeHint(option: QStyleOptionViewItemH; index: QModelIndexH; Size: PSize); cdecl; virtual;
|
||
procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; virtual;
|
||
end;
|
||
|
||
{ TQtListView }
|
||
|
||
TQtListView = class(TQtAbstractItemView)
|
||
private
|
||
function getBatchSize: integer;
|
||
function getGridSize: TSize;
|
||
function getSpacing: Integer;
|
||
procedure setBatchSize(const AValue: integer);
|
||
procedure setSpacing(const AValue: integer);
|
||
procedure setGridSize(const AValue: TSize);
|
||
public
|
||
procedure setLayoutMode(const ALayoutMode: QListViewLayoutMode);
|
||
procedure setMovement(const AMovement: QListViewMovement);
|
||
procedure setResizeMode(const AResizeMode: QListViewResizeMode);
|
||
procedure setUniformItemSizes(const AEnable: Boolean);
|
||
procedure setViewFlow(const AFlow: QListViewFlow);
|
||
procedure setViewMode(const AMode: QListViewViewMode);
|
||
procedure setWordWrap(const AValue: Boolean); override;
|
||
procedure setWrapping(const AWrapping: Boolean);
|
||
procedure LayoutItems;
|
||
property BatchSize: integer read getBatchSize write setBatchSize;
|
||
property GridSize: TSize read getGridSize write setGridSize;
|
||
property Spacing: Integer read getSpacing write setSpacing;
|
||
end;
|
||
|
||
{ TQtListWidget }
|
||
|
||
TQtListWidget = class(TQtListView)
|
||
private
|
||
FCheckBoxClicked: Boolean;
|
||
FSavedSelection: TPtrIntArray;
|
||
FCurrentItemChangedHook: QListWidget_hookH;
|
||
FSelectionChangeHook: QListWidget_hookH;
|
||
FItemClickedHook: QListWidget_hookH;
|
||
FItemTextChangedHook: QListWidget_hookH;
|
||
FDelayedCheckItem: QListWidgetItemH;
|
||
FDontPassSelChange: Boolean;
|
||
procedure HandleCheckChangedEvent(const AMousePos: TQtPoint;
|
||
AItem: QListWidgetItemH; AEvent: QEventH);
|
||
function GetItemChecked(AIndex: Integer): Boolean;
|
||
function getItemCount: Integer;
|
||
function GetItemEnabled(AIndex: Integer): Boolean;
|
||
function GetSelected(AIndex: Integer): Boolean;
|
||
procedure SetItemChecked(AIndex: Integer; AValue: Boolean);
|
||
procedure setItemCount(const AValue: Integer);
|
||
procedure SetItemEnabled(AIndex: Integer; AValue: Boolean);
|
||
procedure SetSelected(AIndex: Integer; AValue: Boolean);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
procedure OwnerDataNeeded(ARect: TRect); override;
|
||
function GetItemFlags(AIndex: Integer): QtItemFlags; override;
|
||
procedure SetItemFlags(AIndex: Integer; AValue: QtItemFlags); override;
|
||
procedure SetItemLastCheckState(AItem: QListWidgetItemH);
|
||
procedure SetItemLastCheckStateInternal(AItem: QListWidgetItemH; AState: QtCheckState);
|
||
procedure SetNextStateMap(AItem: QListWidgetItemH); virtual;
|
||
public
|
||
FList: TStrings;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
procedure InitializeWidget; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
|
||
procedure signalCurrentItemChanged(current: QListWidgetItemH; previous: QListWidgetItemH); cdecl; virtual;
|
||
procedure signalItemTextChanged(ANewText: PWideString); cdecl; virtual;
|
||
procedure signalItemClicked(item: QListWidgetItemH); cdecl; virtual;
|
||
procedure signalSelectionChanged(); cdecl; virtual;
|
||
procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; override;
|
||
public
|
||
procedure clearSelection; override;
|
||
procedure ClearItems;
|
||
function currentRow: Integer;
|
||
function currentItem: QListWidgetItemH;
|
||
function GetItemLastCheckState(AItem: QListWidgetItemH): QtCheckState;
|
||
function IndexAt(APoint: PQtPoint): Integer;
|
||
procedure insertItem(AIndex: Integer; AText: String); overload;
|
||
procedure insertItem(AIndex: Integer; AText: PWideString); overload;
|
||
function itemAt(APoint: TPoint): QListWidgetItemH; overload;
|
||
function itemAt(x: Integer; y: Integer): QListWidgetItemH; overload;
|
||
function getItem(AIndex: Integer): QListWidgetItemH;
|
||
function getItemSelected(AItem: QListWidgetItemH): Boolean;
|
||
function getItemVisible(AItem: QListWidgetItemH): Boolean;
|
||
function getRow(AItem: QListWidgetItemH): integer;
|
||
function getSelCount: Integer;
|
||
function getTopItem: integer; override;
|
||
function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; override;
|
||
function getVisualItemRect(AItem: QListWidgetItemH): TRect;
|
||
function selectedItems: TPtrIntArray;
|
||
procedure setCurrentRow(row: Integer);
|
||
procedure setCurrentItem(AItem: QListWidgetItemH; const AIsSet: Boolean = True);
|
||
procedure setItemText(AIndex: Integer; AText: String); overload;
|
||
procedure setItemText(AIndex: Integer; AText: String; AAlignment: Integer); overload;
|
||
procedure setItemSelected(AItem: QListWidgetItemH; const ASelect: Boolean);
|
||
procedure setItemVisible(AItem: QListWidgetItemH; const AVisible: Boolean);
|
||
procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); override;
|
||
procedure scrollToItem(row: integer; hint: QAbstractItemViewScrollHint);
|
||
procedure removeItem(AIndex: Integer);
|
||
function rowCount: integer;
|
||
procedure ExchangeItems(const AIndex1, AIndex2: Integer);
|
||
procedure MoveItem(const AFromIndex, AToIndex: Integer);
|
||
property ItemCount: Integer read getItemCount write setItemCount;
|
||
property ItemChecked[AIndex: Integer]: Boolean read GetItemChecked write SetItemChecked;
|
||
property Enabled[AIndex: Integer]: Boolean read GetItemEnabled write SetItemEnabled;
|
||
property Selected[AIndex: Integer]: Boolean read GetSelected write SetSelected;
|
||
end;
|
||
|
||
{ TQtCheckListBox }
|
||
|
||
TQtCheckListBox = class (TQtListWidget)
|
||
private
|
||
FItemChangedHook: QListWidget_hookH;
|
||
function GetItemCheckState(AIndex: Integer): QtCheckState;
|
||
procedure SetItemCheckState(AIndex: Integer; AValue: QtCheckState);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
procedure SetNextStateMap(AItem: QListWidgetItemH); override;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
|
||
procedure signalCurrentItemChanged(current: QListWidgetItemH; previous: QListWidgetItemH); cdecl; override;
|
||
procedure signalItemClicked(item: QListWidgetItemH); cdecl; override;
|
||
procedure signalSelectionChanged(); cdecl; override;
|
||
procedure signalItemChanged(item: QListWidgetItemH); cdecl;
|
||
property ItemCheckState[AIndex: Integer]: QtCheckState read GetItemCheckState write SetItemCheckState;
|
||
end;
|
||
|
||
{ TQtHeaderView }
|
||
|
||
TQtHeaderView = class (TQtAbstractItemView)
|
||
private
|
||
FSectionClicked: QHeaderView_hookH;
|
||
function getClickable: Boolean;
|
||
function getMinSectionSize: Integer;
|
||
procedure setClickable(const AValue: Boolean);
|
||
procedure setMinSectionSize(const AValue: Integer);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure SignalSectionClicked(logicalIndex: Integer); cdecl;
|
||
function getResizeMode(AIndex: Integer): QHeaderViewResizeMode;
|
||
procedure setResizeMode(AResizeMode: QHeaderViewResizeMode); overload;
|
||
procedure setResizeMode(AIndex: Integer; AResizeMode: QHeaderViewResizeMode); overload;
|
||
function sectionSize(AIndex: Integer): Integer;
|
||
function sectionSizeHint(AIndex: Integer): Integer;
|
||
procedure moveSection(AFromIndex: Integer; AToIndex: Integer);
|
||
procedure resizeSection(ASection: Integer; ASize: Integer);
|
||
procedure setHighlightSections(AValue: Boolean);
|
||
procedure setDefaultSectionSize(AValue: Integer);
|
||
function SortIndicatorOrder: QtSortOrder;
|
||
procedure SetSortIndicator(const AColumn: Integer; const AOrder: QtSortOrder);
|
||
procedure SetSortIndicatorVisible(AVisible: Boolean);
|
||
procedure setStretchLastSection(AValue: Boolean);
|
||
property Clickable: Boolean read getClickable write setClickable;
|
||
property MinSectionSize: Integer read getMinSectionSize write setMinSectionSize;
|
||
end;
|
||
|
||
{ TQtTreeView }
|
||
|
||
TQtTreeView = class (TQtAbstractItemView)
|
||
private
|
||
function getColVisible(AIndex: Integer): Boolean;
|
||
function getColWidth(AIndex: Integer): Integer;
|
||
function GetUniformRowHeights: Boolean;
|
||
procedure setColVisible(AIndex: Integer; const AValue: Boolean);
|
||
procedure setColWidth(AIndex: Integer; const AValue: Integer);
|
||
procedure SetUniformRowHeights(const AValue: Boolean);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
procedure setAllColumnsShowFocus(AValue: Boolean);
|
||
procedure setWordWrap(const AValue: Boolean); override;
|
||
procedure setRootIsDecorated(AValue: Boolean);
|
||
property ColWidth[AIndex: Integer]: Integer read getColWidth write setColWidth;
|
||
property ColVisible[AIndex: Integer]: Boolean read getColVisible write setColVisible;
|
||
property UniformRowHeights: Boolean read GetUniformRowHeights write SetUniformRowHeights;
|
||
end;
|
||
|
||
{ TQtTreeWidget }
|
||
|
||
TQtTreeWidget = class(TQtTreeView)
|
||
private
|
||
FSelection: TFPList;
|
||
FHeader: TQtHeaderView;
|
||
{$IFDEF TEST_QT_SORTING}
|
||
FCanSort: Boolean; // it can sort items only when LCL says so !
|
||
FSorting: Boolean;
|
||
FSortChanged: QHeaderView_hookH;
|
||
{$ENDIF}
|
||
FItemActivatedHook: QTreeWidget_hookH;
|
||
FItemEnteredHook: QTreeWidget_hookH;
|
||
FSelectionChangedHook: QTreeWidget_hookH;
|
||
FDelayedCheckItem: QTreeWidgetItemH;
|
||
|
||
procedure HandleCheckChangedEvent(const AMousePos: TQtPoint;
|
||
AItem: QTreeWidgetItemH; AEvent: QEventH);
|
||
|
||
function GetItemLastCheckStateInternal(AItem: QTreeWidgetItemH): QtCheckState;
|
||
procedure SetItemLastCheckStateInternal(AItem: QTreeWidgetItemH; AState: QtCheckState);
|
||
|
||
function getColCount: Integer;
|
||
function getHeader: TQtHeaderView;
|
||
function GetItemChecked(AIndex: Integer): Boolean;
|
||
function getItemCount: Integer;
|
||
function getMaxColSize(ACol: Integer): Integer;
|
||
function getMinColSize(ACol: Integer): Integer;
|
||
function getSortEnabled: Boolean;
|
||
procedure setColCount(const AValue: Integer);
|
||
procedure SetItemChecked(AIndex: Integer; AValue: Boolean);
|
||
procedure setItemCount(const AValue: Integer);
|
||
procedure setMaxColSize(ACol: Integer; const AValue: Integer);
|
||
procedure setMinColSize(ACol: Integer; const AValue: Integer);
|
||
procedure setSortEnabled(const AValue: Boolean);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
procedure OwnerDataNeeded(ARect: TRect); override;
|
||
public
|
||
destructor Destroy; override;
|
||
procedure DestroyNotify(AWidget: TQtWidget); override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
function itemViewViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
procedure ItemDelegatePaint(painter: QPainterH; option: QStyleOptionViewItemH; index: QModelIndexH); cdecl; override;
|
||
procedure ClearItems;
|
||
procedure clearSelection; override;
|
||
procedure DeleteItem(const AIndex: integer);
|
||
function currentRow: Integer;
|
||
procedure setCurrentRow(row: Integer);
|
||
function currentItem: QTreeWidgetItemH;
|
||
procedure setCurrentItem(AItem: QTreeWidgetItemH);
|
||
|
||
function getRow(AItem: QTreeWidgetItemH): integer;
|
||
function headerItem: QTreeWidgetItemH;
|
||
function itemAt(APoint: TPoint): QTreeWidgetItemH; overload;
|
||
function itemAt(x: Integer; y: Integer): QTreeWidgetItemH; overload;
|
||
procedure insertTopLevelItem(AIndex: Integer; AItem: QTreeWidgetItemH);
|
||
function takeTopLevelItem(AIndex: Integer): QTreeWidgetItemH;
|
||
function topLevelItem(AIndex: Integer): QTreeWidgetItemH;
|
||
function visualItemRect(AItem: QTreeWidgetItemH): TRect;
|
||
function getHeaderHeight(out AOrientation: QtOrientation): Integer;
|
||
function getItemVisible(AItem: QTreeWidgetItemH): Boolean;
|
||
function getTopItem: integer; override;
|
||
function getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer; override;
|
||
procedure setItemVisible(AItem: QTreeWidgetItemH; Const AVisible: Boolean);
|
||
procedure setItemText(AItem: QTreeWidgetItemH; const AColumn: Integer;
|
||
const AText: WideString; const AAlignment: QtAlignment);
|
||
procedure setItemData(AItem: QTreeWidgetItemH; const AColumn: Integer;
|
||
Data: Pointer; const ARole: Integer = Ord(QtUserRole));
|
||
function selCount: Integer;
|
||
function selectedItems: TPtrIntArray;
|
||
procedure setHeaderVisible(AVisible: Boolean);
|
||
procedure setItemSelected(AItem: QTreeWidgetItemH; ASelect: Boolean);
|
||
procedure setStretchLastSection(AValue: Boolean);
|
||
procedure scrollToItem(Item: QTreeWidgetItemH; hint: QAbstractItemViewScrollHint);
|
||
{$IFDEF TEST_QT_SORTING}
|
||
// direct Qt sorting via QtUserData ptr = our TListItem, crashes sometimes - qt bug.
|
||
procedure sortItems(Acolumn: Integer; AOrder: QtSortOrder);
|
||
{$ENDIF}
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
procedure ExchangeItems(const AIndex1, AIndex2: Integer);
|
||
procedure MoveItem(const AFromIndex, AToIndex: Integer);
|
||
function getClientBounds: TRect; override;
|
||
function getClientOffset: TPoint; override;
|
||
|
||
procedure setSelectionMode(AMode: QAbstractItemViewSelectionMode); override;
|
||
procedure SignalItemActivated(item: QTreeWidgetItemH; column: Integer); cdecl;
|
||
procedure SignalItemEntered(item: QTreeWidgetItemH; column: Integer); cdecl;
|
||
procedure SignalCurrentItemChanged(current: QTreeWidgetItemH; previous: QTreeWidgetItemH); cdecl;
|
||
procedure SignalSelectionChanged(); cdecl;
|
||
{$IFDEF TEST_QT_SORTING}
|
||
procedure SignalSortIndicatorChanged(ALogicalIndex: Integer; AOrder: QtSortOrder); cdecl;
|
||
property CanSort: Boolean read FCanSort write FCanSort;
|
||
{$ENDIF}
|
||
property ColCount: Integer read getColCount write setColCount;
|
||
property Header: TQtHeaderView read getHeader;
|
||
property ItemChecked[AIndex: Integer]: Boolean read GetItemChecked write SetItemChecked;
|
||
property ItemCount: Integer read getItemCount write setItemCount;
|
||
property MaxColSize[ACol: Integer]: Integer read getMaxColSize write setMaxColSize;
|
||
property MinColSize[ACol: Integer]: Integer read getMinColSize write setMinColSize;
|
||
property SortEnabled: Boolean read getSortEnabled write setSortEnabled;
|
||
{$IFDEF TEST_QT_SORTING}
|
||
property Sorting: Boolean read FSorting write FSorting;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
{TQtTableView}
|
||
|
||
TQtTableView = class(TQtAbstractItemView)
|
||
private
|
||
FVerticalHeader: TQtHeaderView;
|
||
FHorizontalHeader: TQtHeaderView;
|
||
public
|
||
function verticalHeader: TQtHeaderView;
|
||
function horizontalHeader: TQtHeaderView;
|
||
function CreateWidget(const Params: TCreateParams): QWidgetH; override;
|
||
function getViewPort: QWidgetH;
|
||
function getClientBounds: TRect; override;
|
||
procedure grabMouse; override;
|
||
procedure setVisible(AVisible: Boolean); override;
|
||
function getGridStyle: QtPenStyle;
|
||
procedure setGridStyle(ANewStyle: QtPenStyle);
|
||
public
|
||
destructor Destroy; override;
|
||
end;
|
||
|
||
{ TQtMenu }
|
||
|
||
TQtMenu = class(TQtWidget)
|
||
private
|
||
FLastTick: QWord; // issue #22872
|
||
FActions: TFPList;
|
||
FIcon: QIconH;
|
||
FTriggeredHook: QAction_hookH;
|
||
FHoveredHook: QAction_hookH;
|
||
FAboutToShowHook: QMenu_hookH;
|
||
FAboutToHideHook: QMenu_hookH;
|
||
FActionEventFilter: QObject_hookH;
|
||
FActionHandle: QActionH;
|
||
FMenuItem: TMenuItem;
|
||
FTrackButton: QtMouseButtons;
|
||
procedure setActionGroups(AItem: TMenuItem);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
|
||
procedure DoPopupClose;
|
||
public
|
||
constructor Create(const AMenuItem: TMenuItem); overload;
|
||
destructor Destroy; override;
|
||
procedure InitializeWidget; override;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
|
||
procedure SlotHovered; cdecl;
|
||
procedure SlotAboutToShow; cdecl;
|
||
procedure SlotAboutToHide; cdecl;
|
||
procedure SlotDestroy; cdecl;
|
||
procedure SlotTriggered(checked: Boolean = False); cdecl;
|
||
function ActionEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
public
|
||
function actionHandle: QActionH;
|
||
function addMenu(AMenu: QMenuH): QActionH;
|
||
function insertMenu(AIndex: Integer; AMenu: QMenuH; AItem: TMenuItem): QActionH;
|
||
function getHasSubMenu: boolean;
|
||
function getText: WideString; override;
|
||
function getVisible: Boolean; override;
|
||
function MenuItemEnabled: boolean;
|
||
procedure PopUp(pos: PQtPoint; at: QActionH = nil);
|
||
procedure Exec(pos: PQtPoint; at: QActionH = nil);
|
||
procedure removeActionGroup;
|
||
procedure setChecked(p1: Boolean);
|
||
procedure setCheckable(p1: Boolean);
|
||
procedure setHasSubmenu(AValue: Boolean);
|
||
procedure setIcon(AIcon: QIconH);
|
||
procedure setImage(AImage: TQtImage);
|
||
procedure setSeparator(AValue: Boolean);
|
||
procedure setShortcut(AShortCutK1, AShortCutK2: TShortcut);
|
||
procedure setText(const W: WideString); override;
|
||
procedure setVisible(AVisible: Boolean); override;
|
||
property trackButton: QtMouseButton read FTrackButton write FTrackButton;
|
||
end;
|
||
|
||
{ TQtMenuBar }
|
||
|
||
TQtMenuBar = class(TQtWidget)
|
||
private
|
||
{$IFNDEF DARWIN}
|
||
FCatchNextResizeEvent: Boolean; {needed during design time}
|
||
FNumOfActions: PtrInt;
|
||
{$ENDIF}
|
||
FVisible: Boolean;
|
||
FHeight: Integer;
|
||
FIsApplicationMainMenu: Boolean;
|
||
public
|
||
constructor Create(const AParent: QWidgetH); overload;
|
||
public
|
||
{$IFNDEF DARWIN}
|
||
function IsDesigning: Boolean;
|
||
{$ENDIF}
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
function addMenu(AMenu: QMenuH): QActionH;
|
||
function insertMenu(AIndex: Integer; AMenu: QMenuH): QActionH;
|
||
function getGeometry: TRect; override;
|
||
end;
|
||
|
||
{ TQtProgressBar }
|
||
|
||
TQtProgressBar = class(TQtWidget)
|
||
private
|
||
FValueChangedHook: QProgressBar_hookH;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
procedure SignalValueChanged(Value: Integer); cdecl;
|
||
procedure setFocusPolicy(const APolicy: QtFocusPolicy); override;
|
||
public
|
||
procedure reset;
|
||
procedure setRange(minimum: Integer; maximum: Integer);
|
||
procedure setTextVisible(visible: Boolean);
|
||
procedure setAlignment(const AAlignment: QtAlignment);
|
||
procedure setTextDirection(textDirection: QProgressBarDirection);
|
||
procedure setValue(value: Integer);
|
||
procedure setOrientation(p1: QtOrientation);
|
||
procedure setInvertedAppearance(invert: Boolean);
|
||
end;
|
||
|
||
{ TQtStatusBarPanel }
|
||
|
||
TQtStatusBarPanel = class(TQtFrame)
|
||
private
|
||
FId: Integer;
|
||
procedure DrawItem(Sender: QObjectH; Event: QEventH);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
property ID: Integer read FId write FId;
|
||
end;
|
||
|
||
{ TQtStatusBar }
|
||
|
||
TQtStatusBar = class(TQtWidget)
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
|
||
public
|
||
Panels: array of TQtStatusBarPanel;
|
||
procedure setColor(const Value: PQColor); override;
|
||
procedure showMessage(text: PWideString; timeout: Integer = 0);
|
||
procedure addWidget(AWidget: QWidgetH; AStretch: Integer = 0);
|
||
procedure removeWidget(AWidget: QWidgetH);
|
||
function isSizeGripEnabled: Boolean;
|
||
procedure setSizeGripEnabled(const Value: Boolean);
|
||
function SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; override; cdecl;
|
||
end;
|
||
|
||
{ TQtDialog }
|
||
|
||
TQtDialog = class(TQtWidget)
|
||
private
|
||
FDialogEventHook: QObject_hookH;
|
||
protected
|
||
FDialog: TCommonDialog;
|
||
function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; virtual; overload;
|
||
public
|
||
constructor Create(ADialog: TCommonDialog; parent: QWidgetH = nil; f: QtWindowFlags = 0); overload;
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function DeliverMessage(var Msg; const AIsInputEvent: Boolean = False): LRESULT; override;
|
||
function SlotClose: Boolean; cdecl; override;
|
||
public
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
function exec: Integer;
|
||
procedure setSizeGripEnabled(const AEnabled: Boolean);
|
||
end;
|
||
|
||
{ TQtFileDialog }
|
||
|
||
TQtFileDialog = class(TQtDialog)
|
||
private
|
||
{$ifndef QT_NATIVE_DIALOGS}
|
||
FBackBtn: QWidgetH;
|
||
FForwardBtn: QWidgetH;
|
||
FUpBtn: QWidgetH;
|
||
FFileNameEdit: QWidgetH;
|
||
FComboType: QWidgetH;
|
||
FComboHistory: QWidgetH;
|
||
FSideView: QWidgetH;
|
||
FTreeView: QWidgetH;
|
||
FListView: QWidgetH;
|
||
FTreeViewEventFilter: QObject_hookH;
|
||
FListViewEventFilter: QObject_hookH;
|
||
FSideViewEventFilter: QObject_hookH;
|
||
FFileNameEditEventFilter: QObject_hookH;
|
||
FComboTypeEventFilter: QObject_hookH;
|
||
FComboHistoryEventFilter: QObject_hookH;
|
||
{$endif}
|
||
FCurrentChangedHook: QFileDialog_hookH;
|
||
FDirecotyEnteredHook: QFileDialog_hookH;
|
||
FFilterSelectedHook: QFileDialog_hookH;
|
||
protected
|
||
function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; override;
|
||
public
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
{$ifndef QT_NATIVE_DIALOGS}
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
{$endif}
|
||
procedure CurrentChangedEvent(path: PWideString); cdecl; virtual;
|
||
procedure FilterSelectedEvent(filter: PWideString); cdecl;
|
||
procedure DirectoryEnteredEvent(directory: PWideString); cdecl;
|
||
public
|
||
procedure getFilters(const retval: QStringListH);
|
||
function selectFile: WideString;
|
||
procedure selectedFiles(retval: QStringListH);
|
||
procedure setAcceptMode(const AMode: QFileDialogAcceptMode);
|
||
procedure setConfirmOverwrite(const AValue: Boolean);
|
||
procedure setDirectory(const ADirectory: WideString);
|
||
procedure setHistory(AList: TStrings);
|
||
procedure setFileMode(const AMode: QFileDialogFileMode);
|
||
procedure setFilter(const AFilter: WideString);
|
||
procedure setLabelText(const ALabel: QFileDialogDialogLabel; const AText: WideString);
|
||
procedure setReadOnly(const AReadOnly: Boolean);
|
||
procedure setSelectedFilter(const ASelFilter: WideString);
|
||
procedure setViewMode(const AMode: QFileDialogViewMode);
|
||
{$ifndef QT_NATIVE_DIALOGS}
|
||
procedure setShortcuts(const AIsOpenDialog: Boolean);
|
||
{$endif}
|
||
end;
|
||
|
||
{ TQtFilePreviewDialog }
|
||
|
||
TQtFilePreviewDialog = class(TQtFileDialog)
|
||
private
|
||
{$ifndef QT_NATIVE_DIALOGS}
|
||
FTextWidget: QLabelH;
|
||
FPreviewWidget: QLabelH;
|
||
{$ENDIF}
|
||
protected
|
||
function CreateWidget(parent: QWidgetH; f: QtWindowFlags):QWidgetH; override;
|
||
public
|
||
{$ifndef QT_NATIVE_DIALOGS}
|
||
procedure initializePreview(const APreviewControl: TWinControl);
|
||
procedure CurrentChangedEvent(path: PWideString); cdecl; override;
|
||
property PreviewWidget: QLabelH read FPreviewWidget;
|
||
property TextWidget: QLabelH read FTextWidget;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
{ TQtMessageBox }
|
||
|
||
TQtMessageBox = class(TQtWidget)
|
||
private
|
||
FMBEventHook: QObject_hookH;
|
||
FTitle: WideString;
|
||
function getDetailText: WideString;
|
||
function getMessageStr: WideString;
|
||
function getMsgBoxType: QMessageBoxIcon;
|
||
function GetTextFormat: QtTextFormat;
|
||
procedure setDetailText(const AValue: WideString);
|
||
procedure setMessageStr(const AValue: WideString);
|
||
procedure setMsgBoxType(const AValue: QMessageBoxIcon);
|
||
procedure SetTextFormat(AValue: QtTextFormat);
|
||
procedure setTitle(const AValue: WideString);
|
||
protected
|
||
function CreateWidget(AParent: QWidgetH):QWidgetH; overload;
|
||
public
|
||
constructor Create(AParent: QWidgetH); overload;
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
public
|
||
function AddButton(ACaption: WideString; ABtnType: QMessageBoxStandardButton; AResult: Int64;
|
||
const ADefaultBtn: Boolean; const AEscapeBtn: Boolean = False): QPushButtonH; overload;
|
||
function AddButton(ACaption: WideString; AResult: Int64;
|
||
const ADefaultBtn: Boolean; const AEscapeBtn: Boolean = False): QPushButtonH;
|
||
procedure SetButtonProps(ABtn: QPushButtonH; AResult: Int64; const ADefaultBtn: Boolean;
|
||
const AEscapeBtn: Boolean);
|
||
function exec: Int64;
|
||
property DetailText: WideString read getDetailText write setDetailText;
|
||
property MessageStr: WideString read getMessageStr write setMessageStr;
|
||
property MsgBoxType:QMessageBoxIcon read getMsgBoxType write setMsgBoxType;
|
||
property Title: WideString read FTitle write setTitle;
|
||
property TextFormat: QtTextFormat read GetTextFormat write SetTextFormat;
|
||
end;
|
||
|
||
{ TQtCalendar }
|
||
|
||
TQtCalendar = class(TQtWidget)
|
||
private
|
||
FMouseDoubleClicked: Boolean;
|
||
FCalViewportEventHook: QObject_hookH;
|
||
FCalViewAreaEventHook: QObject_hookH;
|
||
FClickedHook: QCalendarWidget_hookH;
|
||
FActivatedHook: QCalendarWidget_hookH;
|
||
FSelectionChangedHook: QCalendarWidget_hookH;
|
||
FCurrentPageChangedHook: QCalendarWidget_hookH;
|
||
function DeliverDayChanged(ADate: QDateH): boolean;
|
||
function GetDateTime: TDateTime;
|
||
procedure SetDateTime(const AValue: TDateTime);
|
||
procedure SetSelectedDate(const AValue: QDateH);
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
AYear, AMonth, ADay: Word;
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
function AreaViewEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function calViewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function HitTest(const APoint: TPoint): byte;
|
||
procedure SetDisplaySettings(
|
||
const AHHdrFmt: QCalendarWidgetHorizontalHeaderFormat;
|
||
const AVHdrFmt: QCalendarWidgetVerticalHeaderFormat;
|
||
const ASelMode: QCalendarWidgetSelectionMode;
|
||
const ANavBarVisible: Boolean; const AGridVisible: Boolean);
|
||
procedure SetFirstDayOfWeek(const ADayOfWeek: QtDayOfWeek);
|
||
procedure SignalActivated(ADate: QDateH); cdecl;
|
||
procedure SignalClicked(ADate: QDateH); cdecl;
|
||
procedure SignalSelectionChanged; cdecl;
|
||
procedure SignalCurrentPageChanged(p1, p2: Integer); cdecl;
|
||
property DateTime: TDateTime read GetDateTime write SetDateTime;
|
||
end;
|
||
|
||
// for page control / notebook
|
||
|
||
{ TQtPage }
|
||
|
||
TQtPage = class(TQtWidget)
|
||
protected
|
||
FIcon: QIconH;
|
||
function CreateWidget(const AParams: TCreateParams):QWidgetH; override;
|
||
public
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
function getIcon: QIconH;
|
||
function getIndex(const ATextChanging: Boolean = False): Integer;
|
||
function getTabWidget: QTabWidgetH;
|
||
procedure setIcon(const AIcon: QIconH);
|
||
procedure setText(const W: WideString); override;
|
||
end;
|
||
|
||
{ TQtRubberBand }
|
||
|
||
TQtRubberBand = class(TQtWidget)
|
||
private
|
||
FShape: QRubberBandShape;
|
||
protected
|
||
function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
|
||
public
|
||
constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); override;
|
||
|
||
// QRubberBand have it's own move,resize and setGeometry
|
||
procedure move(ANewLeft, ANewTop: Integer); override;
|
||
procedure Resize(ANewWidth, ANewHeight: Integer); override;
|
||
procedure setGeometry(ARect: TRect); override;
|
||
|
||
function getShape: QRubberBandShape;
|
||
procedure setShape(AShape: QRubberBandShape);
|
||
end;
|
||
|
||
{ TQtDesignWidget }
|
||
|
||
TQtDesignWidget = class(TQtMainWindow)
|
||
protected
|
||
FDesignControlEventHook: QObject_hookH;
|
||
FDesignControl: QWidgetH;
|
||
FDesignContext: HDC;
|
||
function CreateWidget(const AParams: TCreateParams): QWidgetH; override;
|
||
procedure DestroyWidget; override;
|
||
procedure SlotDesignControlPaint(Sender: QObjectH; Event: QEventH); cdecl;
|
||
procedure BringDesignerToFront;
|
||
procedure ResizeDesigner;
|
||
function GetContext: HDC; override;
|
||
public
|
||
function DesignControlEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
|
||
|
||
procedure AttachEvents; override;
|
||
procedure DetachEvents; override;
|
||
|
||
procedure lowerWidget; override;
|
||
procedure raiseWidget; override;
|
||
public
|
||
property DesignContext: HDC read FDesignContext;
|
||
end;
|
||
|
||
const
|
||
AlignmentMap: array[TAlignment] of QtAlignment =
|
||
(
|
||
{taLeftJustify } QtAlignLeft,
|
||
{taRightJustify} QtAlignRight,
|
||
{taCenter } QtAlignHCenter
|
||
);
|
||
|
||
QtCheckStateRole = Ord(QtUserRole) + 1;
|
||
QtListViewOwnerDataRole = Ord(QtUserRole) + 2;
|
||
|
||
{$IFDEF QTACCESSIBILITY}
|
||
const
|
||
QtAXObjectName = 'AxObject';
|
||
axActionNamePress = 'Press';
|
||
axActionNameIncrease = 'Increase';
|
||
axActionNameDecrease = 'Decrease';
|
||
axActionNameShowMenu = 'ShowMenu';
|
||
axActionNameSetFocus = 'SetFocus';
|
||
axActionNameToggle = 'Toggle';
|
||
axActionNameScrolLeft = 'Scroll Left';
|
||
axActionNameScrollRight = 'Scroll Right';
|
||
axActionNameScrollUp = 'Scroll Up';
|
||
axActionNameScrollDown = 'Scroll Down';
|
||
axActionNamePreviousPage = 'Previous Page';
|
||
axActionNameNextPage = 'Next Page';
|
||
|
||
function LazRoleToQtRole(ALazRole: TLazAccessibilityRole): QAccessibleRole;
|
||
function CreateAccessibleName(AObject: TLazAccessibleObject): String;
|
||
function QtAxFactory(name: QStringH; obj: QObjectH): QAccessibleInterfaceH; cdecl;
|
||
|
||
type
|
||
TQtAccessibleObject = class(TObject)
|
||
private
|
||
FLazAxObject: TLazAccessibleObject;
|
||
FAxWidget: QWidgetH;
|
||
public
|
||
constructor Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
|
||
destructor Destroy; override;
|
||
procedure actionNamesOverride(names: PWideString) cdecl; virtual; abstract;
|
||
procedure childOverride(index: integer; out child: QAccessibleInterfaceH) cdecl; virtual;
|
||
procedure childAtOverride(x: integer; y: integer; out child: QAccessibleInterfaceH) cdecl; virtual; abstract;
|
||
procedure childCountOverride(count: PInteger) cdecl; virtual;
|
||
procedure doActionOverride(name: PWideString) cdecl; virtual; abstract;
|
||
procedure indexOfChildOverride() cdecl; virtual; abstract;
|
||
procedure parentOverride(out parent: QAccessibleInterfaceH) cdecl; virtual; abstract;
|
||
procedure rectOverride(left, top, width, height: PInteger) cdecl; virtual; abstract;
|
||
procedure roleOverride(out role: QAccessibleRole) cdecl; virtual;
|
||
procedure stateOverride(out state: QAccessibleState) cdecl; virtual; abstract;
|
||
procedure textOverride(text: QAccessibleText; retval: PWideString) cdecl; virtual;
|
||
function isVisible: Boolean; virtual;
|
||
end;
|
||
|
||
TQtAccessibleTree = class(TQtAccessibleObject)
|
||
public
|
||
constructor Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
|
||
procedure childOverride(index: integer; out child: QAccessibleInterfaceH) cdecl; virtual;
|
||
procedure childCountOverride(count: PInteger) cdecl; virtual;
|
||
end;
|
||
|
||
TQtAccessibleTreeRow = class(TQtAccessibleObject)
|
||
public
|
||
constructor Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
|
||
procedure actionNamesOverride(names: PWideString)cdecl; override;
|
||
procedure childCountOverride(count: PInteger)cdecl; override;
|
||
procedure doActionOverride(name: PWideString)cdecl; override;
|
||
procedure parentOverride(out parent: QAccessibleInterfaceH)cdecl; override;
|
||
procedure rectOverride(left, top, width, height: PInteger) cdecl; override;
|
||
procedure roleOverride(out role: QAccessibleRole)cdecl; override;
|
||
procedure textOverride(text: QAccessibleText; retval: PWideString) cdecl; override;
|
||
function isVisible: Boolean; override;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
implementation
|
||
|
||
uses
|
||
Buttons,
|
||
math,
|
||
qtCaret,
|
||
qtproc,
|
||
qtprivate,
|
||
WSControls
|
||
{$IFDEF HASX11}
|
||
,keysym
|
||
{$ENDIF}
|
||
;
|
||
|
||
const
|
||
Forbid_TCN_SELCHANGE = -3;
|
||
Allow_TCN_SELCHANGE = -2;
|
||
|
||
type
|
||
TWinControlAccess = class(TWinControl)
|
||
end;
|
||
TCustomListViewAccess = class(TCustomListView);
|
||
|
||
var
|
||
LastMouse: TLastMouseInfo;
|
||
|
||
{ TQtWidget }
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.Create
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
constructor TQtWidget.Create(const AWinControl: TWinControl; const AParams: TCreateParams);
|
||
begin
|
||
inherited Create;
|
||
FOwner := nil;
|
||
FCentralWidget := nil;
|
||
FOwnWidget := True;
|
||
// Initializes the properties
|
||
FProps := nil;
|
||
LCLObject := AWinControl;
|
||
FKeysToEat := [VK_TAB, VK_RETURN, VK_ESCAPE];
|
||
FHasPaint := False;
|
||
|
||
FParams := AParams;
|
||
InitializeWidget;
|
||
InitializeAccessibility;
|
||
end;
|
||
|
||
constructor TQtWidget.CreateFrom(const AWinControl: TWinControl;
|
||
AWidget: QWidgetH);
|
||
begin
|
||
inherited Create;
|
||
|
||
FOwner := nil;
|
||
FOwnWidget := False;
|
||
FCentralWidget := nil;
|
||
// Initializes the properties
|
||
FProps := niL;
|
||
LCLObject := AWinControl;
|
||
FKeysToEat := [VK_TAB, VK_RETURN, VK_ESCAPE];
|
||
|
||
// Creates the widget
|
||
Widget := AWidget;
|
||
|
||
FDefaultCursor := QCursor_create();
|
||
QWidget_cursor(Widget, FDefaultCursor);
|
||
FWidgetLCLFont := nil;
|
||
FWidgetDefaultFont := TQtFont.Create(QWidget_font(AWidget));
|
||
|
||
// set Handle->QWidget map
|
||
setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
|
||
FillChar(FPaintData, sizeOf(FPaintData), 0);
|
||
|
||
QtWidgetSet.AddHandle(Self);
|
||
// set focus policy
|
||
if (LCLObject <> nil) and not (Self is TQtMainWindow) then
|
||
setFocusPolicy(QtClickFocus);
|
||
|
||
// Set mouse move messages policy
|
||
QWidget_setMouseTracking(Widget, True);
|
||
|
||
InitializeAccessibility;
|
||
end;
|
||
|
||
procedure TQtWidget.InitializeAccessibility;
|
||
{$IFDEF QTACCESSIBILITY}
|
||
var
|
||
WStr: WideString;
|
||
LCLAxObject: TLazAccessibleObject;
|
||
{$ENDIF}
|
||
begin
|
||
{$IFDEF QTACCESSIBILITY}
|
||
if Assigned(LCLObject) then begin
|
||
LCLAxObject := LCLObject.GetAccessibleObject;
|
||
if (LCLAxObject <> nil) then begin
|
||
WStr := GetUtf8String(CreateAccessibleName(LCLAxObject));
|
||
QWidget_setAccessibleName(Widget, @WStr);
|
||
WStr := GetUtf8String(LCLAxObject.AccessibleDescription);
|
||
QWidget_setAccessibleDescription(Widget, @WStr);
|
||
end;
|
||
end
|
||
else begin
|
||
WStr := GetUtf8String(ClassName);
|
||
QWidget_setAccessibleName(Widget, @WStr);
|
||
end;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TQtWidget.InitializeWidget;
|
||
begin
|
||
FInResizeEvent := False;
|
||
// default states
|
||
FWidgetState := [];
|
||
// default color roles
|
||
FWidgetNeedFontColorInitialization := False;
|
||
SetDefaultColorRoles;
|
||
FPalette := nil;
|
||
FHasCaret := False;
|
||
FLastCaretPos := QtPoint(-1, -1);
|
||
ChildOfComplexWidget := ccwNone;
|
||
// creates the widget
|
||
Widget := CreateWidget(FParams);
|
||
|
||
// retrieve default cursor on create
|
||
FDefaultCursor := QCursor_create();
|
||
QWidget_cursor(Widget, FDefaultCursor);
|
||
|
||
FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
|
||
FWidgetLCLFont := nil;
|
||
|
||
|
||
// apply initial position and size
|
||
move(FParams.X, FParams.Y);
|
||
if GetContainerWidget <> Widget then
|
||
QWidget_resize(GetContainerWidget, FParams.Width, FParams.Height);
|
||
|
||
Resize(FParams.Width, FParams.Height);
|
||
|
||
FScrollX := 0;
|
||
FScrollY := 0;
|
||
|
||
{$ifdef VerboseQt}
|
||
DebugLn('TQtWidget.InitializeWidget: Self:%x Widget:%x was created for control %s',
|
||
[PtrUInt(Self), PtrUInt(Widget), LCLObject.Name]);
|
||
{$endif}
|
||
|
||
// set Handle->QWidget map
|
||
setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
|
||
QtWidgetSet.AddHandle(Self);
|
||
|
||
FillChar(FPaintData, sizeOf(FPaintData), 0);
|
||
|
||
// Sets it's initial properties
|
||
|
||
// set focus policy
|
||
if Assigned(LCLObject) then
|
||
begin
|
||
if (Self is TQtMainWindow) and
|
||
(
|
||
TQtMainWindow(Self).IsMDIChild or
|
||
Assigned(TQtMainWindow(Self).MDIAreaHandle) or
|
||
(csNoFocus in LCLObject.ControlStyle)
|
||
) then
|
||
begin
|
||
if TQtMainWindow(Self).IsMDIChild or
|
||
Assigned(TQtMainWindow(Self).MDIAreaHandle) then
|
||
begin
|
||
QWidget_setFocusPolicy(FCentralWidget, QtNoFocus);
|
||
end else
|
||
begin
|
||
if LCLObject.TabStop then
|
||
setFocusPolicy(QtWheelFocus)
|
||
else
|
||
setFocusPolicy(QtNoFocus);
|
||
end;
|
||
end else
|
||
begin
|
||
if (Self is TQtMainWindow) then
|
||
setFocusPolicy(QtTabFocus) // issue #28880
|
||
else
|
||
if (csNoFocus in LCLObject.ControlStyle) then
|
||
begin
|
||
if LCLObject.TabStop then
|
||
setFocusPolicy(QtTabFocus)
|
||
else
|
||
setFocusPolicy(QtNoFocus);
|
||
end else
|
||
if (Self is TQtTabWidget) then
|
||
setFocusPolicy(QtTabFocus)
|
||
else
|
||
setFocusPolicy(QtClickFocus);
|
||
end;
|
||
|
||
if LCLObject.Perform(LM_NCHITTEST, 0, 0)=HTTRANSPARENT then
|
||
begin
|
||
setAttribute(QtWA_TransparentForMouseEvents);
|
||
setWindowFlags(windowFlags or QtWindowTransparentForInput);
|
||
end;
|
||
|
||
if (csDesigning in LCLObject.ComponentState) and not
|
||
(Self is TQtMainWindow) and
|
||
HasPaint and
|
||
getAutoFillBackground or
|
||
((csDesigning in LCLObject.ComponentState) and
|
||
(ClassType = TQtTabWidget)) then
|
||
setAutoFillBackground(False);
|
||
end;
|
||
|
||
|
||
// Set mouse move messages policy
|
||
QWidget_setMouseTracking(Widget, True);
|
||
|
||
if Assigned(LCLObject) and FWidgetNeedFontColorInitialization then
|
||
setInitialFontColor(LCLObject);
|
||
if (FParams.Style and WS_VISIBLE) = 0 then
|
||
QWidget_hide(Widget)
|
||
else
|
||
QWidget_show(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.DeInitializeWidget;
|
||
begin
|
||
QtWidgetSet.RemoveHandle(Self);
|
||
DetachEvents;
|
||
|
||
if Widget <> nil then
|
||
removeProperty(Widget, 'lclwidget');
|
||
|
||
QCursor_destroy(FDefaultCursor);
|
||
|
||
if HasCaret then
|
||
DestroyCaret;
|
||
|
||
if Assigned(FWidgetDefaultFont) then
|
||
FreeThenNil(FWidgetDefaultFont);
|
||
if Assigned(FWidgetLCLFont) then
|
||
FreeThenNil(FWidgetLCLFont);
|
||
|
||
if FPalette <> nil then
|
||
begin
|
||
FPalette.Free;
|
||
FPalette := nil;
|
||
end;
|
||
|
||
DestroyWidget;
|
||
end;
|
||
|
||
procedure TQtWidget.RecreateWidget;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// update createparams
|
||
with getPos do
|
||
begin
|
||
FParams.X := X;
|
||
FParams.Y := Y;
|
||
end;
|
||
with getSize do
|
||
begin
|
||
FParams.Width := cx;
|
||
FParams.Height := cy;
|
||
end;
|
||
|
||
if Widget <> nil then
|
||
Parent := QWidget_parentWidget(Widget)
|
||
else
|
||
Parent := nil;
|
||
FParams.WndParent := HwndFromWidgetH(Parent);
|
||
DeinitializeWidget;
|
||
InitializeWidget;
|
||
InitializeAccessibility;
|
||
end;
|
||
|
||
procedure TQtWidget.DestroyNotify(AWidget: TQtWidget);
|
||
begin
|
||
if AWidget = FOwner then
|
||
FOwner := nil;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.Destroy
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
destructor TQtWidget.Destroy;
|
||
begin
|
||
DeinitializeWidget;
|
||
|
||
if FProps <> nil then
|
||
begin
|
||
FProps.Free;
|
||
FProps:=nil;
|
||
end;
|
||
|
||
if FPaintData.ClipRegion <> nil then
|
||
begin
|
||
QRegion_Destroy(FPaintData.ClipRegion);
|
||
FPaintData.ClipRegion:=nil;
|
||
end;
|
||
|
||
if FOwner <> nil then
|
||
FOwner.DestroyNotify(Self);
|
||
|
||
inherited Destroy;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.GetContainerWidget
|
||
Params: None
|
||
Returns: The widget of the control on top of which other controls
|
||
should be placed
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.GetContainerWidget: QWidgetH;
|
||
begin
|
||
if FCentralWidget <> nil then
|
||
Result := FCentralWidget
|
||
else
|
||
Result := Widget;
|
||
end;
|
||
|
||
procedure TQtWidget.Release;
|
||
begin
|
||
LCLObject := nil;
|
||
{always hide widget since we use QObject_deleteLater(). issue #27781}
|
||
if (Widget <> nil) then
|
||
Hide;
|
||
inherited Release;
|
||
end;
|
||
|
||
procedure TQtWidget.Destroyed; cdecl;
|
||
begin
|
||
Widget := nil;
|
||
Release;
|
||
end;
|
||
|
||
function TQtWidget.WinIDNeeded: boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.CanAdjustClientRectOnResize
|
||
Params: None
|
||
Returns: Boolean
|
||
Checks if our control can call LCLObject.DoAdjustClientRect from SlotResize.
|
||
This avoids deadlocks with autosizing.
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.CanAdjustClientRectOnResize: Boolean;
|
||
begin
|
||
Result := True;
|
||
end;
|
||
|
||
function TQtWidget.CanChangeFontColor: Boolean;
|
||
begin
|
||
Result := True;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.CanSendLCLMessage
|
||
Params: None
|
||
Returns: Boolean
|
||
If returns FALSE then we should not send any message to LCL since our
|
||
LCLObject is probably being destroyed or it has csDestroying flag on.
|
||
This is very important to know before calling NotifyApplicationUserInput,
|
||
which is often called from mouse & keyboard events.
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.CanSendLCLMessage: Boolean;
|
||
begin
|
||
Result := (LCLObject <> nil) and (Widget <> nil) and getVisible and
|
||
not ((csDestroying in LCLObject.ComponentState) or
|
||
(csDestroyingHandle in LCLObject.ControlState));
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.CanPaintBackground
|
||
Params: None
|
||
Returns: Boolean
|
||
Makes decision if control background need to be painted.
|
||
Look at SlotPaintBg().
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.CanPaintBackground: Boolean;
|
||
begin
|
||
{TODO: we must override this function for some classes
|
||
until clDefault is implemented in LCL.Then we can easy
|
||
ask EqualTQColor() for diff between
|
||
Palette.DefaultColor and current LCLObject.Color}
|
||
Result := False;
|
||
end;
|
||
|
||
procedure TQtWidget.DelayResizeEvent(AWidget: QWidgetH; ANewSize: TSize);
|
||
var
|
||
ALCLResizeEvent: QLCLMessageEventH;
|
||
begin
|
||
ALCLResizeEvent := QLCLMessageEvent_create(LCLQt_DelayResizeEvent, 0, PtrUInt(ANewSize.cx), PtrUInt(ANewSize.cy), 0);
|
||
QCoreApplication_postEvent(AWidget, ALCLResizeEvent);
|
||
end;
|
||
|
||
{$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtKeys)}
|
||
function EventTypeToStr(Event:QEventH):string;
|
||
// Qt 3 events
|
||
const
|
||
QEventChildInsertedRequest = 67;
|
||
QEventChildInserted = 70;
|
||
QEventLayoutHint = 72;
|
||
begin
|
||
case QEvent_type(Event) of
|
||
QEventNone: result:='QEventNone';
|
||
QEventTimer: result:='QEventTimer';
|
||
QEventMouseButtonPress: result:='QEventMouseButtonPress';
|
||
QEventMouseButtonRelease: result:='QEventMouseButtonRelease';
|
||
QEventMouseButtonDblClick: result:='QEventMouseButtonDblClick';
|
||
QEventMouseMove: result:='QEventMouseMove';
|
||
QEventKeyPress: result:='QEventKeyPress';
|
||
QEventKeyRelease: result:='QEventKeyRelease';
|
||
QEventFocusIn: result:='QEventFocusIn';
|
||
QEventFocusOut: result:='QEventFocusOut';
|
||
QEventEnter: result:='QEventEnter';
|
||
QEventLeave: result:='QEventLeave';
|
||
QEventPaint: result:='QEventPaint';
|
||
QEventMove: result:='QEventMove';
|
||
QEventResize: result:='QEventResize';
|
||
QEventCreate: result:='QEventCreate';
|
||
QEventDestroy: result:='QEventDestroy';
|
||
QEventShow: result:='QEventShow';
|
||
QEventHide: result:='QEventHide';
|
||
QEventClose: result:='QEventClose';
|
||
QEventQuit: result:='QEventQuit';
|
||
QEventParentChange: result:='QEventParentChange';
|
||
QEventThreadChange: result:='QEventThreadChange';
|
||
QEventWindowActivate: result:='QEventWindowActivate';
|
||
QEventWindowDeactivate: result:='QEventWindowDeactivate';
|
||
QEventShowToParent: result:='QEventShowToParent';
|
||
QEventHideToParent: result:='QEventHideToParent';
|
||
QEventWheel: result:='QEventWheel';
|
||
QEventWindowTitleChange: result:='QEventWindowTitleChange';
|
||
QEventWindowIconChange: result:='QEventWindowIconChange';
|
||
QEventApplicationWindowIconChange: result:='QEventApplicationWindowIconChange';
|
||
QEventApplicationFontChange: result:='QEventApplicationFontChange';
|
||
QEventApplicationLayoutDirectionChange: result:='QEventApplicationLayoutDirectionChange';
|
||
QEventApplicationPaletteChange: result:='QEventApplicationPaletteChange';
|
||
QEventPaletteChange: result:='QEventPaletteChange';
|
||
QEventClipboard: result:='QEventClipboard';
|
||
QEventSpeech: result:='QEventSpeech';
|
||
QEventMetaCall: result:='QEventMetaCall';
|
||
QEventSockAct: result:='QEventSockAct';
|
||
QEventShortcutOverride: result:='QEventShortcutOverride';
|
||
QEventDeferredDelete: result:='QEventDeferredDelete';
|
||
QEventDragEnter: result:='QEventDragEnter';
|
||
QEventDragMove: result:='QEventDragMove';
|
||
QEventDragLeave: result:='QEventDragLeave';
|
||
QEventDrop: result:='QEventDrop';
|
||
QEventDragResponse: result:='QEventDragResponse';
|
||
// QEventChildInsertedRequest: result:='(Qt3) QEventChildAdded'; //qt3
|
||
QEventChildAdded: result:='QEventChildAdded';
|
||
QEventChildPolished: result:='QEventChildPolished';
|
||
// QEventChildInserted: result:='(Qt3) QEventChildAdded'; // qt3
|
||
// QEventLayoutHint: result:='(Qt3) QEventChildAdded'; // qt3
|
||
QEventChildRemoved: result:='QEventChildRemoved';
|
||
QEventShowWindowRequest: result:='QEventShowWindowRequest';
|
||
QEventPolishRequest: result:='QEventPolishRequest';
|
||
QEventPolish: result:='QEventPolish';
|
||
QEventLayoutRequest: result:='QEventLayoutRequest';
|
||
QEventUpdateRequest: result:='QEventUpdateRequest';
|
||
QEventUpdateLater: result:='QEventUpdateLater';
|
||
QEventEmbeddingControl: result:='QEventEmbeddingControl';
|
||
QEventActivateControl: result:='QEventActivateControl';
|
||
QEventDeactivateControl: result:='QEventDeactivateControl';
|
||
QEventContextMenu: result:='QEventContextMenu';
|
||
QEventInputMethod: result:='QEventInputMethod';
|
||
QEventTabletMove: result:='QEventTabletMove';
|
||
QEventLocaleChange: result:='QEventLocaleChange';
|
||
QEventLanguageChange: result:='QEventLanguageChange';
|
||
QEventLayoutDirectionChange: result:='QEventLayoutDirectionChange';
|
||
QEventStyle: result:='QEventStyle';
|
||
QEventTabletPress: result:='QEventTabletPress';
|
||
QEventTabletRelease: result:='QEventTabletRelease';
|
||
QEventOkRequest: result:='QEventOkRequest';
|
||
QEventHelpRequest: result:='QEventHelpRequest';
|
||
QEventIconDrag: result:='QEventIconDrag';
|
||
QEventFontChange: result:='QEventFontChange';
|
||
QEventEnabledChange: result:='QEventEnabledChange';
|
||
QEventActivationChange: result:='QEventActivationChange';
|
||
QEventStyleChange: result:='QEventStyleChange';
|
||
QEventIconTextChange: result:='QEventIconTextChange';
|
||
QEventModifiedChange: result:='QEventModifiedChange';
|
||
QEventWindowBlocked: result:='QEventWindowBlocked';
|
||
QEventWindowUnblocked: result:='QEventWindowUnblocked';
|
||
QEventWindowStateChange: result:='QEventWindowStateChange';
|
||
QEventMouseTrackingChange: result:='QEventMouseTrackingChange';
|
||
QEventToolTip: result:='QEventToolTip';
|
||
QEventWhatsThis: result:='QEventWhatsThis';
|
||
QEventStatusTip: result:='QEventStatusTip';
|
||
QEventActionChanged: result:='QEventActionChanged';
|
||
QEventActionAdded: result:='QEventActionAdded';
|
||
QEventActionRemoved: result:='QEventActionRemoved';
|
||
QEventFileOpen: result:='QEventFileOpen';
|
||
QEventShortcut: result:='QEventShortcut';
|
||
QEventWhatsThisClicked: result:='QEventWhatsThisClicked';
|
||
QEventToolBarChange: result:='QEventToolBarChange';
|
||
QEventApplicationActivated: result:='QEventApplicationActivated';
|
||
QEventApplicationDeactivated: result:='QEventApplicationDeactivated';
|
||
QEventQueryWhatsThis: result:='QEventQueryWhatsThis';
|
||
QEventEnterWhatsThisMode: result:='QEventEnterWhatsThisMode';
|
||
QEventLeaveWhatsThisMode: result:='QEventLeaveWhatsThisMode';
|
||
QEventZOrderChange: result:='QEventZOrderChange';
|
||
QEventHoverEnter: result:='QEventHoverEnter';
|
||
QEventHoverLeave: result:='QEventHoverLeave';
|
||
QEventHoverMove: result:='QEventHoverMove';
|
||
QEventParentAboutToChange: result:='QEventParentAboutToChange';
|
||
QEventWinEventAct: result:='QEventWinEventAct';
|
||
QEventAcceptDropsChange: result:='QEventAcceptDropsChange';
|
||
QEventZeroTimerEvent: result:='QEventZeroTimerEvent';
|
||
QEventNonClientAreaMouseMove: result:='QEventNonClientAreaMouseMove';
|
||
QEventNonClientAreaMouseButtonPress: result:='QEventNonClientAreaMouseButtonPress';
|
||
QEventNonClientAreaMouseButtonRelease: result:='QEventNonClientAreaMouseButtonRelease';
|
||
QEventNonClientAreaMouseButtonDblClick: result:='QEventNonClientAreaMouseButtonDblClick';
|
||
QEventMacSizeChange: result := 'QEventMacSizeChange';
|
||
QEventContentsRectChange: result := 'QEventContentsRectChange';
|
||
QEventMacGLWindowChange: result := 'QEventMacGLWindowChange';
|
||
QEventFutureCallOut: result := 'QEventFutureCallOut';
|
||
QEventGraphicsSceneResize: result := 'QEventGraphicsSceneResize';
|
||
QEventGraphicsSceneMove: result := 'QEventGraphicsSceneMove';
|
||
QEventCursorChange: result := 'QEventCursorChange';
|
||
QEventToolTipChange: result := 'QEventToolTipChange';
|
||
QEventNetworkReplyUpdated: result := 'QEventNetworkReplyUpdated';
|
||
QEventGrabMouse: result := 'QEventGrabMouse';
|
||
QEventUngrabMouse: result := 'QEventUngrabMouse';
|
||
QEventGrabKeyboard: result := 'QEventGrabKeyboard';
|
||
QEventUngrabKeyboard: result := 'QEventUngrabKeyboard';
|
||
QEventUser: result:='QEventUser';
|
||
QEventMaxUser: result:='QEventMaxUser';
|
||
200: Result := 'QEventCloseSoftwareInputPanel';
|
||
203: Result := 'QEventWinIdChange';
|
||
else
|
||
Result := Format('Unknown event: %d', [QEvent_type(Event)]);
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.EventFilter
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
{$IFDEF MSWINDOWS}
|
||
AContextEvent: QContextMenuEventH;
|
||
{$ENDIF}
|
||
QColor, OldColor: TQColor;
|
||
ColorRef: TColorRef;
|
||
QtEdit: IQtEdit;
|
||
R: TRect;
|
||
Pt: TQtPoint;
|
||
ANewSize: TSize;
|
||
AResizeEvent: QResizeEventH;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
|
||
BeginEventProcessing;
|
||
try
|
||
{$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
|
||
WriteLn('TQtWidget.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
|
||
' LCLObject=', dbgsName(LCLObject),
|
||
' Event=', EventTypeToStr(Event),' inUpdate=',InUpdate);
|
||
{$endif}
|
||
|
||
if LCLObject <> nil then
|
||
begin
|
||
case QEvent_type(Event) of
|
||
LCLQt_DelayResizeEvent:
|
||
begin
|
||
ANewSize.cx := LongInt(QLCLMessageEvent_getWParam(QLCLMessageEventH(Event)));
|
||
ANewSize.cy := LongInt(QLCLMessageEvent_getLParam(QLCLMessageEventH(Event)));
|
||
AResizeEvent := QResizeEvent_create(@ANewSize, @ANewSize);
|
||
try
|
||
{$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('>LCLQt_DelayResizeEvent: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
|
||
{$ENDIF}
|
||
SlotResize(AResizeEvent);
|
||
{$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('<LCLQt_DelayResizeEvent: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
|
||
{$ENDIF}
|
||
finally
|
||
QResizeEvent_destroy(AResizeEvent);
|
||
end;
|
||
Result := True;
|
||
end;
|
||
QEventFontChange:
|
||
begin
|
||
//explanation for this event usage: issue #19695
|
||
if not (qtwsFontUpdating in WidgetState) and
|
||
not LCLObject.IsParentFont then
|
||
begin
|
||
if Assigned(FWidgetLCLFont) then
|
||
AssignQtFont(FWidgetLCLFont.FHandle, QWidget_font(QWidgetH(Sender)))
|
||
else
|
||
AssignQtFont(FWidgetDefaultFont.FHandle, QWidget_font(QWidgetH(Sender)));
|
||
end;
|
||
end;
|
||
QEventEnabledChange:
|
||
begin
|
||
// if we are disabled, imediatelly invalidate widgetAt cache
|
||
if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
|
||
QtWidgetSet.InvalidateWidgetAtCache
|
||
else
|
||
if QtWidgetSet.IsValidWidgetAtCachePointer then
|
||
begin
|
||
Pt := QtPoint(0, 0);
|
||
QWidget_mapToGlobal(Widget, @Pt, @Pt);
|
||
QWidget_geometry(Widget, @R);
|
||
R := Rect(Pt.X, Pt.Y, Pt.X + (R.Right - R.Left), Pt.Y + (R.Bottom - R.Top));
|
||
if PtInRect(R, QtWidgetSet.GetWidgetAtCachePoint) then
|
||
QtWidgetSet.InvalidateWidgetAtCache;
|
||
end;
|
||
// issue #25922
|
||
if Assigned(FPalette) and Assigned(LCLObject) then
|
||
begin
|
||
// DebugLn('QEventEnabledChange: ',dbgsName(LCLObject),' enabled ',dbgs(getEnabled));
|
||
if not getEnabled then
|
||
Palette.setTextColor(@Palette.DisabledTextColor)
|
||
else
|
||
setInitialFontColor(LCLObject);
|
||
end;
|
||
end;
|
||
QEventShow:
|
||
begin
|
||
SlotShow(True);
|
||
{$IFDEF MSWINDOWS}
|
||
if (qtwsInsideRightMouseButtonPressEvent in FWidgetState) and
|
||
(qtwsHiddenInsideRightMouseButtonPressEvent in FWidgetState) then
|
||
begin
|
||
Exclude(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
|
||
Exclude(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
|
||
if (LastMouse.WinControl = LCLObject) and
|
||
(QGUIApplication_mouseButtons and QtRightButton <> 0) then
|
||
begin
|
||
Pt := QtPoint(LastMouse.MousePos.X, LastMouse.MousePos.Y);
|
||
AContextEvent := QContextMenuEvent_create(QContextMenuEventMouse, @Pt);
|
||
QCoreApplication_postEvent(Sender, AContextEvent);
|
||
LastMouse.MousePos := Point(Pt.X, Pt.Y);
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
end;
|
||
QEventHide:
|
||
begin
|
||
if QWidget_mouseGrabber() = Widget then
|
||
ReleaseCapture;
|
||
SlotShow(False);
|
||
{$IFDEF MSWINDOWS}
|
||
if qtwsInsideRightMouseButtonPressEvent in FWidgetState then
|
||
Include(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
|
||
{$ENDIF}
|
||
end;
|
||
QEventClose:
|
||
if not SlotClose then
|
||
begin
|
||
QEvent_ignore(Event);
|
||
Result := True;
|
||
end;
|
||
QEventDestroy: SlotDestroy;
|
||
QEventEnter,
|
||
QEventLeave: Result := SlotMouseEnter(Sender, Event);
|
||
|
||
QEventHoverEnter,
|
||
QEventHoverLeave,
|
||
QEventHoverMove: Result := SlotHover(Sender, Event);
|
||
|
||
QEventDrop,
|
||
QEventDragMove,
|
||
QEventDragEnter:
|
||
begin
|
||
Result := getAcceptDropFiles;
|
||
if (Result) and (QEvent_type(Event) = QEventDrop) then
|
||
Result := slotDropFiles(Sender, Event);
|
||
end;
|
||
|
||
QEventKeyPress,
|
||
QEventKeyRelease:
|
||
begin
|
||
{non-spontaneous key events are garbage in Qt >= 4.4 for non edits}
|
||
Result := QEvent_spontaneous(Event) or Supports(Self, IQtEdit, QtEdit);
|
||
if Result then
|
||
Result := SlotKey(Sender, Event) or (LCLObject is TCustomControl);
|
||
end;
|
||
|
||
//Dead keys (used to compose chars like "ó" by pressing 'o) do not trigger EventKeyPress
|
||
//and therefore no KeyDown,Utf8KeyPress,KeyPress
|
||
QEventInputMethod:
|
||
begin
|
||
Result := SlotInputMethod(Sender, Event);
|
||
end;
|
||
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
|
||
QEventMouseMove: Result := SlotMouseMove(Sender, Event);
|
||
QEventWheel:
|
||
begin
|
||
if not getEnabled then
|
||
begin
|
||
QEvent_ignore(Event);
|
||
QWidget_setAttribute(QWidgetH(Sender), QtWA_NoMousePropagation, False);
|
||
end else
|
||
Result := SlotMouseWheel(Sender, Event);
|
||
end;
|
||
QEventMove: SlotMove(Event);
|
||
QEventResize: SlotResize(Event);
|
||
QEventContentsRectChange:
|
||
begin
|
||
if ChildOfComplexWidget = ccwScrollingWinControl then
|
||
begin
|
||
// Result := (caspComputingBounds in LCLObject.AutoSizePhases);
|
||
QEvent_ignore(Event);
|
||
end;
|
||
if LCLObject.ClientRectNeedsInterfaceUpdate then
|
||
begin
|
||
{$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
|
||
if ChildOfComplexWidget = ccwScrollingWinControl then
|
||
begin
|
||
if Self is TQtViewport then
|
||
QWidget_rect(Widget, @R)
|
||
else
|
||
QWidget_rect(TQtAbstractScrollArea(Self).viewportWidget, @R);
|
||
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)));
|
||
end else
|
||
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));
|
||
{$ENDIF}
|
||
if not (caspComputingBounds in LCLObject.AutoSizePhases) then
|
||
begin
|
||
{$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
|
||
DebugLn(' QEventContentsRectChange(',dbgsName(LCLObject),' call DoAdjustClientRectChange !');
|
||
{$ENDIF}
|
||
if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
|
||
else
|
||
LCLObject.DoAdjustClientRectChange(True);
|
||
end else
|
||
begin
|
||
{$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
|
||
DebugLn(' QEventContentsRectChange(',dbgsName(LCLObject),' call InvalidatePrefferedSize !');
|
||
{$ENDIF}
|
||
if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
|
||
else
|
||
LCLObject.InvalidatePreferredSize;
|
||
end;
|
||
end;
|
||
end;
|
||
QEventPaint:
|
||
begin
|
||
if canPaintBackground and (LCLObject.Color <> clDefault) then
|
||
SlotPaintBg(Sender, Event);
|
||
if FHasPaint then
|
||
SlotPaint(Sender, Event);
|
||
end;
|
||
QEventContextMenu:
|
||
Result := SlotContextMenu(Sender, Event);
|
||
QEventNonClientAreaMouseButtonPress:
|
||
begin
|
||
SlotNCMouse(Sender, Event);
|
||
end;
|
||
QEventPaletteChange,
|
||
QEventStyleChange:
|
||
begin
|
||
if (FPalette <> nil) and not InUpdate and not Palette.InReload then
|
||
begin
|
||
OldColor := Palette.CurrentColor;
|
||
// now set our fpalette ColorRef from LCL
|
||
if LCLObject.Color <> clDefault then
|
||
begin
|
||
ColorRef := ColorToRGB(LCLObject.Color);
|
||
QColor_fromRgb(@QColor,Red(ColorRef),Green(ColorRef),Blue(ColorRef));
|
||
end else
|
||
QColor := Palette.DefaultColor;
|
||
if not EqualTQColor(OldColor, QColor) then
|
||
begin
|
||
Palette.ReloadPaletteBegin;
|
||
try
|
||
SetColor(@QColor);
|
||
Result := True;
|
||
QEvent_accept(Event);
|
||
finally
|
||
Palette.ReloadPaletteEnd;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
QEventQueryWhatsThis: Result := True;
|
||
QEventWhatsThis:
|
||
begin
|
||
SlotWhatsThis(Sender, Event);
|
||
// TODO: we need to stop event by Result := True; but then we also need
|
||
// to ask qt to leave Whats This mode. Currently we have no means to do so
|
||
end;
|
||
QEventLCLMessage:
|
||
begin
|
||
SlotLCLMessage(Sender, Event);
|
||
Result := True;
|
||
end;
|
||
else
|
||
QEvent_ignore(Event);
|
||
end;
|
||
end
|
||
else
|
||
QEvent_ignore(Event);
|
||
|
||
{fixes #14544 and others when we loose our LCLObject
|
||
after delivering message to LCL.}
|
||
if (LCLObject = nil) and
|
||
((QEvent_type(Event) = QEventMouseButtonPress) or
|
||
(QEvent_type(Event) = QEventMouseButtonRelease) or
|
||
(QEvent_type(Event) = QEventMouseButtonDblClick) or
|
||
(QEvent_type(Event) = QEventMouseMove) or
|
||
(QEvent_type(Event) = QEventHoverEnter) or
|
||
(QEvent_type(Event) = QEventHoverLeave) or
|
||
(QEvent_type(Event) = QEventHoverMove) or
|
||
(QEvent_type(Event) = QEventKeyPress) or
|
||
(QEvent_type(Event) = QEventKeyRelease)) then
|
||
Result := True;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end;
|
||
|
||
function TQtWidget.getAcceptDropFiles: Boolean;
|
||
var
|
||
Form: TCustomForm;
|
||
begin
|
||
Result := False;
|
||
Form := GetParentForm(LCLObject);
|
||
if Assigned(Form) and (Form.HandleAllocated) then
|
||
Result := TQtMainWindow(Form.Handle).getAcceptDropFiles;
|
||
end;
|
||
|
||
function TQtWidget.measureText(AText: WideString; AFlags: cardinal): TRect;
|
||
var
|
||
AMetrics: QFontMetricsH;
|
||
AFont: QFontH;
|
||
begin
|
||
Result := Rect(0, 0, 0, 0);
|
||
if Assigned(LCLObject) and Assigned(LCLObject.Font) and
|
||
LCLObject.Font.HandleAllocated then
|
||
AFont := TQtFont(LCLObject.Font.Reference.Handle).FHandle
|
||
else
|
||
AFont := QWidget_font(Widget);
|
||
AMetrics := QFontMetrics_create(AFont);
|
||
try
|
||
QFontMetrics_boundingRect(AMetrics, @Result, @AText);
|
||
finally
|
||
QFontMetrics_destroy(AMetrics);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtWidget.SetNoMousePropagation(Sender: QWidgetH;
|
||
const ANoMousePropagation: Boolean);
|
||
begin
|
||
QWidget_setAttribute(Sender, QtWA_NoMousePropagation, ANoMousePropagation);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SetLCLFont
|
||
Params: None
|
||
Returns: Nothing
|
||
Sets FWidgetLCLFont , font which is different from FWidgetDefaultFont
|
||
so we can keep track over it inside QEventFontChange.
|
||
This routine does nothing if called outside of TQtWSControl.SetFont,
|
||
since qtwdFontUpdating must be in WidgetState
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtWidget.SetLCLFont(AFont: TQtFont);
|
||
begin
|
||
if not (qtwsFontUpdating in FWidgetState) then
|
||
exit;
|
||
if Assigned(FWidgetLCLFont) then
|
||
FreeThenNil(FWidgetLCLFont);
|
||
if not IsFontEqual(FWidgetDefaultFont, AFont) and (AFont.FHandle <> nil) then
|
||
FWidgetLCLFont := TQtFont.Create(AFont.FHandle);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SlotShow
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtWidget.SlotShow(vShow: Boolean); cdecl;
|
||
var
|
||
Msg: TLMShowWindow;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtWidget.SlotShow Name', LCLObject.Name, ' vShow: ', dbgs(vShow));
|
||
{$endif}
|
||
|
||
{do not pass message to LCL if LCL setted up control visibility}
|
||
if inUpdate then
|
||
exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
Msg.Msg := LM_SHOWWINDOW;
|
||
Msg.Show := vShow;
|
||
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.Close
|
||
Params: None
|
||
Returns: Nothing
|
||
|
||
Note: LCL uses LM_CLOSEQUERY to set the form visibility and if we don<6F>t send this
|
||
message, you won<6F>t be able to show a form twice.
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.SlotClose: Boolean; cdecl;
|
||
var
|
||
Msg : TLMessage;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtWidget.SlotClose');
|
||
{$endif}
|
||
FillChar(Msg{%H-}, SizeOf(Msg), 0);
|
||
|
||
Msg.Msg := LM_CLOSEQUERY;
|
||
|
||
DeliverMessage(Msg);
|
||
|
||
Result := False;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SlotDestroy
|
||
Params: None
|
||
Returns: Nothing
|
||
|
||
Currently commented because it was raising exception on software exit
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtWidget.SlotDestroy; cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtWidget.SlotDestroy');
|
||
{$endif}
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_DESTROY;
|
||
DeliverMessage(Msg);
|
||
Release;
|
||
end;
|
||
|
||
function TQtWidget.slotDropFiles(Sender: QObjectH; Event: QEventH): Boolean;
|
||
var
|
||
MimeData: QMimeDataH;
|
||
QStrList: QStringListH;
|
||
ByteArr: QByteArrayH;
|
||
i: Integer;
|
||
WStr: WideString;
|
||
GotFiles: Boolean;
|
||
FilesList: TStrings;
|
||
Files: Array of String;
|
||
ParentForm: TCustomForm;
|
||
Url: QUrlH;
|
||
begin
|
||
Result := False;
|
||
GotFiles := False;
|
||
MimeData := QDropEvent_mimeData(QDropEventH(Event));
|
||
QStrList := QStringList_create();
|
||
try
|
||
QMimeData_formats(MimeData, QStrList);
|
||
for i := QStringList_size(QStrList) - 1 downto 0 do
|
||
begin
|
||
QStringList_at(QStrList, @WStr, i);
|
||
GotFiles := (WStr = 'text/plain') or (WStr = 'text/uri-list');
|
||
if GotFiles then
|
||
break;
|
||
end;
|
||
finally
|
||
QStringList_destroy(QStrList);
|
||
end;
|
||
if not GotFiles then
|
||
exit;
|
||
ByteArr := QByteArray_create();
|
||
try
|
||
QMimeData_data(MimeData, ByteArr, @WStr);
|
||
if not QByteArray_isNull(ByteArr) then
|
||
begin
|
||
WStr := QByteArray_constData(ByteArr);
|
||
FilesList := TStringList.Create;
|
||
try
|
||
FilesList.Text := UTF16ToUTF8(WStr);
|
||
|
||
if (FilesList.Count > 0) and
|
||
( (FilesList[FilesList.Count-1] = #0)
|
||
or
|
||
(FilesList[FilesList.Count-1] = '') ) then
|
||
SetLength(Files, FilesList.Count - 1)
|
||
else
|
||
SetLength(Files, FilesList.Count);
|
||
for i := 0 to High(Files) do
|
||
begin
|
||
WStr := GetUTF8String(FilesList.Strings[i]);
|
||
Url := QUrl_create(@WStr);
|
||
QUrl_toLocalFile(Url, @WStr);
|
||
Files[i] := UTF16ToUTF8(WStr);
|
||
QUrl_destroy(Url);
|
||
end;
|
||
finally
|
||
FilesList.Free;
|
||
end;
|
||
QDropEvent_setDropAction(QDropEventH(Event), QtCopyAction);
|
||
QDropEvent_acceptProposedAction(QDropEventH(Event));
|
||
|
||
Application.IntfDropFiles(Files);
|
||
if ClassType = TQtMainWindow then
|
||
TCustomForm(LCLObject).IntfDropFiles(Files)
|
||
else
|
||
begin
|
||
ParentForm := TCustomForm(LCLObject.IntfGetDropFilesTarget);
|
||
if ParentForm is TCustomForm then
|
||
ParentForm.IntfDropFiles(Files);
|
||
end;
|
||
|
||
Result := True;
|
||
end;
|
||
finally
|
||
QByteArray_destroy(ByteArr);
|
||
end;
|
||
end;
|
||
|
||
function TQtWidget.SlotHover(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
MouseMsg: TLMMouseMove absolute Msg;
|
||
MousePos: TQtPoint;
|
||
begin
|
||
Result := False;
|
||
if not CanSendLCLMessage then
|
||
Exit(True);
|
||
|
||
if (QGUIApplication_mouseButtons() = 0) and
|
||
not QWidget_hasMouseTracking(QWidgetH(Sender)) then // in other case MouseMove will be hooked
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
// MousePos :=
|
||
QHoverEvent_pos(QHoverEventH(Event), @MousePos);
|
||
OffsetMousePos(@MousePos);
|
||
|
||
case QEvent_type(Event) of
|
||
QEventHoverEnter: Msg.Msg := LM_MOUSEENTER;
|
||
QEventHoverLeave: Msg.Msg := LM_MOUSELEAVE;
|
||
QEventHoverMove:
|
||
begin
|
||
MouseMsg.Msg := LM_MOUSEMOVE;
|
||
MouseMsg.XPos := SmallInt(MousePos.X);
|
||
MouseMsg.YPos := SmallInt(MousePos.Y);
|
||
end;
|
||
end;
|
||
NotifyApplicationUserInput(LCLObject, Msg.Msg);
|
||
if not CanSendLCLMessage then
|
||
exit(True);
|
||
DeliverMessage(Msg);
|
||
SetNoMousePropagation(QWidgetH(Sender), True);
|
||
end;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SlotKey
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.SlotKey(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
const
|
||
CN_KeyDownMsgs: array[Boolean] of UINT = (CN_KEYDOWN, CN_SYSKEYDOWN);
|
||
CN_KeyUpMsgs: array[Boolean] of UINT = (CN_KEYUP, CN_SYSKEYUP);
|
||
LM_KeyDownMsgs: array[Boolean] of UINT = (LM_KEYDOWN, LM_SYSKEYDOWN);
|
||
LM_KeyUpMsgs: array[Boolean] of UINT = (LM_KEYUP, LM_SYSKEYUP);
|
||
CN_CharMsg: array[Boolean] of UINT = (CN_CHAR, CN_SYSCHAR);
|
||
LM_CharMsg: array[Boolean] of UINT = (LM_CHAR, LM_SYSCHAR);
|
||
var
|
||
KeyMsg: TLMKey;
|
||
CharMsg: TLMChar;
|
||
Modifiers: QtKeyboardModifiers;
|
||
IsSysKey: Boolean;
|
||
Text: WideString;
|
||
UTF8Text: String; // use to prevent 3 time convertion from WideString to utf8 string
|
||
UTF8Char: TUTF8Char;
|
||
ACharCode: Word;
|
||
AKeyCode: Word;
|
||
LCLModifiers: Word;
|
||
{$IFDEF UNIX}
|
||
ScanCode: LongWord;
|
||
{$ENDIF}
|
||
AChar: Char;
|
||
AKeyEvent: QKeyEventH;
|
||
GlobalAction: Integer;
|
||
{$IFDEF VerboseQtKeys}
|
||
s: String;
|
||
s1: String;
|
||
NativeModifiers: LongWord;
|
||
{$ENDIF}
|
||
|
||
function IsControlKey: Boolean;
|
||
var
|
||
AQtKey: Cardinal;
|
||
begin
|
||
// do not send UTF8KeyPress for control keys
|
||
AQtKey := QKeyEvent_key(QKeyEventH(Event));
|
||
|
||
// Enter, Return and Backspace should be sent to LCL in UTF8KeyPress,
|
||
// so skip them here
|
||
|
||
Result := (AQtKey = QtKey_Backtab) or // issue #35448
|
||
// ((AQtKey >= QtKey_Escape) and (AQtKey <= QtKey_Backtab)) or
|
||
((AQtKey >= QtKey_Insert) and (AQtKey <= QtKey_Clear)) or
|
||
((AQtKey >= QtKey_Home) and (AQtKey <= QtKey_PageDown)) or
|
||
((AQtKey >= QtKey_F1) and (AQtKey <= QtKey_Direction_L)) or
|
||
(AQtKey = QtKey_Direction_R);
|
||
end;
|
||
|
||
function EatArrowKeys: Boolean;
|
||
var
|
||
AQtKey: Cardinal;
|
||
begin
|
||
AQtKey := QKeyEvent_key(QKeyEventH(Event));
|
||
Result := not ProcessArrowKeys and ((AQtKey = QtKey_Left) or (AQtKey = QtKey_Right)
|
||
or (AQtKey = QtKey_Up) or (AQtKey = QtKey_Down));
|
||
end;
|
||
|
||
function SendChangedKey: boolean;
|
||
begin
|
||
if UTF8Char <> UTF8Text then
|
||
Text := UTF8ToUTF16(Utf8Char)
|
||
else
|
||
if Word(AChar) <> CharMsg.CharCode then
|
||
Text := Char(CharMsg.CharCode);
|
||
|
||
AKeyEvent := QKeyEvent_create( {ExtendedKeyEvent(}
|
||
QEvent_type(Event),
|
||
LCLKeyToQtKey(KeyMsg.CharCode),
|
||
Modifiers,
|
||
0,
|
||
KeyMsg.CharCode,
|
||
0,
|
||
@Text,
|
||
QKeyEvent_isAutoRepeat(QKeyEventH(Event)),
|
||
QKeyEvent_count(QKeyEventH(Event))
|
||
);
|
||
try
|
||
Result := QObject_event(Sender, AKeyEvent);
|
||
finally
|
||
QKeyEvent_destroy(AKeyEvent);
|
||
end;
|
||
|
||
end;
|
||
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
DebugLn('TQtWidget.SlotKey ', dbgsname(LCLObject));
|
||
{$endif}
|
||
|
||
Result := True;
|
||
|
||
if not CanSendLCLMessage then
|
||
exit;
|
||
|
||
FillChar(KeyMsg{%H-}, SizeOf(KeyMsg), #0);
|
||
FillChar(CharMsg{%H-}, SizeOf(CharMsg), #0);
|
||
UTF8Text := '';
|
||
UTF8Char := '';
|
||
AChar := #0;
|
||
|
||
// Detects special keys (shift, alt, control, etc)
|
||
Modifiers := QKeyEvent_modifiers(QKeyEventH(Event));
|
||
{$IFDEF HASX11}
|
||
//qt reports WRONG combination under X11 sometimes when Shift + LeftAlt
|
||
//are pressed, so we must fix modifiers, ssMeta will be reported in keys.
|
||
if (QtShiftModifier and Modifiers <> 0) and (QtMetaModifier and Modifiers <> 0) then
|
||
begin
|
||
if (QtAltModifier and Modifiers = 0) and
|
||
(QKeyEvent_nativeVirtualKey(QKeyEventH(Event)) = XK_Meta_L) then
|
||
Modifiers := (Modifiers and not QtMetaModifier) or QtAltModifier;
|
||
end;
|
||
{$ENDIF}
|
||
IsSysKey := (QtAltModifier and Modifiers) <> $0;
|
||
|
||
AKeyCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
|
||
|
||
LCLModifiers := QtKeyModifiersToKeyState(Modifiers, True, QKeyEventH(Event));
|
||
|
||
if QKeyEvent_isAutoRepeat(QKeyEventH(Event)) then
|
||
LCLModifiers := LCLModifiers or KF_REPEAT;
|
||
|
||
if QEvent_type(Event) = QEventKeyRelease then
|
||
LCLModifiers := LCLModifiers or KF_UP;
|
||
|
||
{$ifdef windows}
|
||
ACharCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
|
||
KeyMsg.CharCode := ACharCode;
|
||
if (Modifiers = QtAltModifier or QtControlModifier) then
|
||
begin
|
||
if (QtWidgetSet.GetWinKeyState(VK_RMENU) < 0) and
|
||
(QtWidgetSet.GetWinKeyState(VK_LCONTROL) < 0) then
|
||
begin
|
||
IsSysKey := False;
|
||
LCLModifiers := 0;
|
||
Modifiers := QtGroupSwitchModifier;
|
||
|
||
if QKeyEvent_isAutoRepeat(QKeyEventH(Event)) then
|
||
LCLModifiers := LCLModifiers or KF_REPEAT;
|
||
|
||
if QEvent_type(Event) = QEventKeyRelease then
|
||
LCLModifiers := LCLModifiers or KF_UP;
|
||
end;
|
||
end;
|
||
{$endif}
|
||
KeyMsg.KeyData := PtrInt((AKeyCode shl 16) or (LCLModifiers shl 16) or $0001);
|
||
|
||
// Loads the UTF-8 character associated with the keypress, if any
|
||
QKeyEvent_text(QKeyEventH(Event), @Text);
|
||
|
||
{$IFDEF DARWIN}
|
||
// qt on mac passes #3 instead of #13 when QtKey_Enter (numpad) is pressed
|
||
// so our keypress get wrong about key. issue #20896
|
||
if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Enter) and (length(Text) = 1) then
|
||
Text := #13;
|
||
|
||
ScanCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
|
||
{$IFDEF VerboseQtKeys}
|
||
// ScanCode := QKeyEvent_key(QKeyEventH(Event));
|
||
writeln('!!!**** NATIVEVIRTUALKEY=',ScanCode,' lenText=',length(Text),' Modifiers ',Modifiers,' AKEYCODE=',AKeyCode);
|
||
{$ENDIF}
|
||
|
||
// set groupswitch for Shift+Option.
|
||
if (length(Text) = 1) and
|
||
((Modifiers = QtAltModifier or QtShiftModifier) or ((Modifiers = QtAltModifier) and (ScanCode > 0))) then
|
||
begin
|
||
ScanCode := QKeyEvent_key(QKeyEventH(Event));
|
||
// Arrow keys are reserved by macOSX keyboard commands
|
||
// http://support.apple.com/kb/ht1343
|
||
if (ScanCode <> QtKey_Left) and (ScanCode <> QtKey_Up) and
|
||
(ScanCode <> QtKey_Right) and (ScanCode <> QtKey_Down) then
|
||
begin
|
||
Modifiers := QtGroupSwitchModifier;
|
||
LCLModifiers := QtKeyModifiersToKeyState(Modifiers, True, QKeyEventH(Event));
|
||
KeyMsg.KeyData := PtrInt((LCLModifiers shl 16) or $0001);
|
||
IsSysKey := False; // was true above
|
||
end;
|
||
ScanCode := 0;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
{$IFDEF VerboseQtKeys}
|
||
writeln('> TQtWidget.SlotKey dump begin event=',EventTypeToStr(Event),' IsSysKey ',IsSysKey);
|
||
|
||
S := '';
|
||
if Modifiers and QtShiftModifier <> 0 then
|
||
S := 'SHIFT,';
|
||
if Modifiers and QtControlModifier <> 0 then
|
||
S := S + 'CONTROL,';
|
||
|
||
if Modifiers and QtAltModifier <> 0 then
|
||
S := S + 'ALT,';
|
||
|
||
if Modifiers and QtMetaModifier <> 0 then
|
||
S := S + 'META,';
|
||
|
||
if Modifiers and QtKeypadModifier <> 0 then
|
||
S := S + 'KEYPAD,';
|
||
|
||
if Modifiers and QtGroupSwitchModifier <> 0 then
|
||
S := S + 'GROUPSWITCH,';
|
||
|
||
if Modifiers and QtKeyboardModifierMask <> 0 then
|
||
S := S + 'KEYBOARDMODIFIERMASK,';
|
||
|
||
if S <> '' then
|
||
Delete(S, length(S), 1)
|
||
else
|
||
S := 'NONE';
|
||
|
||
|
||
NativeModifiers := QKeyEvent_NativeModifiers(QKeyEventH(Event));
|
||
S1 := '';
|
||
|
||
if NativeModifiers and QtShiftModifier <> 0 then
|
||
S1 := 'SHIFT,';
|
||
if NativeModifiers and QtControlModifier <> 0 then
|
||
S1 := S1 + 'CONTROL,';
|
||
|
||
if NativeModifiers and QtAltModifier <> 0 then
|
||
S1 := S1 + 'ALT,';
|
||
|
||
if NativeModifiers and QtMetaModifier <> 0 then
|
||
S1 := S1 + 'META,';
|
||
|
||
if NativeModifiers and QtKeypadModifier <> 0 then
|
||
S1 := S1 + 'KEYPAD,';
|
||
|
||
if NativeModifiers and QtGroupSwitchModifier <> 0 then
|
||
S1 := S1 + 'GROUPSWITCH,';
|
||
|
||
if NativeModifiers and QtKeyboardModifierMask <> 0 then
|
||
S1 := S1 + 'KEYBOARDMODIFIERMASK,';
|
||
|
||
if S1 <> '' then
|
||
Delete(S1, length(S1), 1)
|
||
else
|
||
S1 := 'NONE';
|
||
|
||
writeln(' KEY=',QKeyEvent_key(QKeyEventH(Event)),' COUNT=',
|
||
QKeyEvent_count(QKeyEventH(Event)),' TEXT=',Text);
|
||
writeln(' LCLKEY=',QtKeyToLCLKey(QKeyEvent_key(QKeyEventH(Event)), Text,
|
||
QKeyEventH(Event)),' SPONTANEOUS ', QEvent_spontaneous(Event));
|
||
writeln(' MODIFIERS: ',S,' NATIVEMODIFIERS: ',S1);
|
||
writeln(' HASEXTENDEDINFO: ',QKeyEvent_hasExtendedInfo(QKeyEventH(Event)),
|
||
' ISAUTOREPEAT: ',QKeyEvent_isAutoRepeat(QKeyEventH(Event)));
|
||
writeln(' NATIVESCANCODE: ',QKeyEvent_nativeScanCode(QKeyEventH(Event)),
|
||
' NATIVEVIRTUALKEY: ',QKeyEvent_nativeVirtualKey(QKeyEventH(Event)));
|
||
|
||
writeln('Key compression ? ',
|
||
QWidget_testAttribute(QWidgetH(Sender), QtWA_KeyCompression));
|
||
writeln('< TQtWidget.SlotKey dump end event=',EventTypeToStr(Event));
|
||
{$ENDIF}
|
||
|
||
{we must intercept modifiers for main form menu (if any). issue #18709}
|
||
if (Modifiers = QtAltModifier) then
|
||
begin
|
||
if (QApplication_activeModalWidget() = nil) and
|
||
(QEvent_type(Event) <> QEventKeyRelease) and
|
||
QtWidgetSet.ShortcutInGlobalActions('Alt+'+Text, GlobalAction) then
|
||
begin
|
||
QtWidgetSet.TriggerGlobalAction(GlobalAction);
|
||
exit;
|
||
end;
|
||
end;
|
||
|
||
{$note TQtWidget.SlotKey: this is workaround for Qt bug which reports
|
||
wrong keys with Shift+Ctrl pressed. Fixes #13470.
|
||
LAST REVISION: Qt-4.7.4 20111023 fc14. zeljko}
|
||
{$IFDEF UNIX}
|
||
{$IFDEF DARWIN}
|
||
// under darwin we must use nativeVirtualKey since nativeScanCode
|
||
// isn't returned under carbon and cocoa.
|
||
if (QtVersionMajor = 5) and (QtVersionMinor >= 2) and
|
||
(Modifiers = QtShiftModifier or QtControlModifier) then
|
||
begin
|
||
ScanCode := QKeyEvent_nativeVirtualKey(QKeyEventH(Event));
|
||
if (length(Text) = 1) and (ScanCode in [10,18..23,25,26,28,29]) then
|
||
begin
|
||
if ScanCode = 10 then
|
||
ScanCode := VK_UNDEFINED
|
||
else
|
||
if ScanCode in [18..21] then
|
||
ScanCode := ScanCode + 31
|
||
else
|
||
if ScanCode = 23 then
|
||
ScanCode := 53
|
||
else
|
||
if ScanCode = 22 then
|
||
ScanCode := 54
|
||
else
|
||
if ScanCode = 26 then
|
||
ScanCode := 55
|
||
else
|
||
if ScanCode = 28 then
|
||
ScanCode := 56
|
||
else
|
||
if ScanCode = 25 then
|
||
ScanCode := 57
|
||
else
|
||
if ScanCode = 29 then
|
||
ScanCode := 48;
|
||
|
||
KeyMsg.CharCode := Word(ScanCode);
|
||
if (Modifiers = QtShiftModifier or QtControlModifier) then
|
||
Text := '';
|
||
end;
|
||
end;
|
||
{$ELSE}
|
||
if (Modifiers = QtShiftModifier or QtControlModifier) or
|
||
(Modifiers = QtShiftModifier) then
|
||
begin
|
||
ScanCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
|
||
if (length(Text) = 1) and (ScanCode in [10..19]) then
|
||
begin
|
||
if ScanCode = 19 then
|
||
ScanCode := 48
|
||
else
|
||
ScanCode := ScanCode + 39;
|
||
KeyMsg.CharCode := Word(ScanCode);
|
||
if (Modifiers = QtShiftModifier or QtControlModifier) then
|
||
Text := '';
|
||
end;
|
||
end else
|
||
if (Modifiers = QtShiftModifier or QtAltModifier) then
|
||
begin
|
||
ScanCode := QKeyEvent_nativeScanCode(QKeyEventH(Event));
|
||
if (length(Text) = 1) and (ScanCode in [10..19]) then
|
||
begin
|
||
if ScanCode = 19 then
|
||
ScanCode := 48
|
||
else
|
||
ScanCode := ScanCode + 39;
|
||
KeyMsg.CharCode := Word(ScanCode);
|
||
if (Modifiers = QtShiftModifier or QtAltModifier) then
|
||
Text := '';
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
{$ENDIF}
|
||
|
||
// Translates a Qt4 Key to a LCL VK_* key
|
||
if KeyMsg.CharCode = 0 then
|
||
begin
|
||
ACharCode := QtKeyToLCLKey(QKeyEvent_key(QKeyEventH(Event)), Text, QKeyEventH(Event));
|
||
KeyMsg.CharCode := ACharCode;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Sends the adequate key messages
|
||
------------------------------------------------------------------------------}
|
||
case QEvent_type(Event) of
|
||
QEventKeyPress: KeyMsg.Msg := CN_KeyDownMsgs[IsSysKey];
|
||
QEventKeyRelease: KeyMsg.Msg := CN_KeyUpMsgs[IsSysKey];
|
||
end;
|
||
|
||
{$ifdef VerboseQt}
|
||
WriteLn(' message CN_Keys: ', KeyMsg.Msg);
|
||
{$endif}
|
||
if KeyMsg.CharCode <> VK_UNKNOWN then
|
||
begin
|
||
NotifyApplicationUserInput(LCLObject, KeyMsg.Msg);
|
||
|
||
if not CanSendLCLMessage or (Sender = nil) then
|
||
exit;
|
||
|
||
if (DeliverMessage(KeyMsg, True) <> 0) or (KeyMsg.CharCode=VK_UNKNOWN) then
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('handled CN_Keys');
|
||
{$endif}
|
||
Exit;
|
||
end;
|
||
|
||
if not CanSendLCLMessage or (Sender = nil) then
|
||
exit;
|
||
|
||
// here we should let widgetset to handle key
|
||
//...
|
||
case QEvent_type(Event) of
|
||
QEventKeyPress: KeyMsg.Msg := LM_KeyDownMsgs[IsSysKey];
|
||
QEventKeyRelease: KeyMsg.Msg := LM_KeyUpMsgs[IsSysKey];
|
||
end;
|
||
{$ifdef VerboseQt}
|
||
WriteLn(' message LM_Keys: ', KeyMsg.Msg);
|
||
{$endif}
|
||
if not EatArrowKeys then
|
||
begin
|
||
NotifyApplicationUserInput(LCLObject, KeyMsg.Msg);
|
||
|
||
if not CanSendLCLMessage or (Sender = nil) then
|
||
exit;
|
||
|
||
if (DeliverMessage(KeyMsg, True) <> 0) or (KeyMsg.CharCode=VK_UNKNOWN) then
|
||
begin
|
||
// the LCL handled the key
|
||
{$ifdef VerboseQt}
|
||
WriteLn('handled LM_Keys');
|
||
{$endif}
|
||
Result := KeyMsg.CharCode=VK_UNKNOWN;
|
||
Exit;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{ if our LCLObject dissappeared in the meantime just exit, otherwise
|
||
we'll run into problems.}
|
||
if not CanSendLCLMessage or (Sender = nil) then
|
||
exit;
|
||
|
||
|
||
{ Also sends a utf-8 key event for key down }
|
||
if (QEvent_type(Event) = QEventKeyPress) and (Length(Text) <> 0) then
|
||
begin
|
||
UTF8Text := UTF16ToUTF8(Text);
|
||
UTF8Char := UTF8Text;
|
||
{$ifdef VerboseQt}
|
||
WriteLn('sending char ', UTF8Char);
|
||
{$endif}
|
||
if not IsControlKey and LCLObject.IntfUTF8KeyPress(UTF8Char, 1, IsSysKey) then
|
||
begin
|
||
// the LCL has handled the key
|
||
{$ifdef VerboseQt}
|
||
WriteLn('handled!');
|
||
{$endif}
|
||
Exit;
|
||
end;
|
||
|
||
if not CanSendLCLMessage or (Sender = nil) then
|
||
exit;
|
||
|
||
if (UTF8Char <> UTF8Text) then
|
||
begin
|
||
// process changed key and exit.
|
||
// issue #26103
|
||
SendChangedKey;
|
||
exit;
|
||
end;
|
||
|
||
// create the CN_CHAR / CN_SYSCHAR message
|
||
FillChar(CharMsg, SizeOf(CharMsg), 0);
|
||
CharMsg.Msg := CN_CharMsg[IsSysKey];
|
||
CharMsg.KeyData := KeyMsg.KeyData;
|
||
AChar := Text[1];
|
||
CharMsg.CharCode := Word(AChar);
|
||
|
||
//Send message to LCL
|
||
{$ifdef VerboseQt}
|
||
WriteLn(' message: ', CharMsg.Msg);
|
||
{$endif}
|
||
NotifyApplicationUserInput(LCLObject, CharMsg.Msg);
|
||
|
||
if not CanSendLCLMessage or (Sender = nil) then
|
||
exit;
|
||
|
||
if (DeliverMessage(CharMsg, True) <> 0) or (CharMsg.CharCode = VK_UNKNOWN) then
|
||
begin
|
||
// the LCL has handled the key
|
||
{$ifdef VerboseQt}
|
||
WriteLn('handled!');
|
||
{$endif}
|
||
Exit;
|
||
end;
|
||
|
||
//Here is where we (interface) can do something with the key
|
||
//...
|
||
|
||
//Send a LM_(SYS)CHAR
|
||
CharMsg.Msg := LM_CharMsg[IsSysKey];
|
||
|
||
{$ifdef VerboseQt}
|
||
WriteLn(' message: ', CharMsg.Msg);
|
||
{$endif}
|
||
if not CanSendLCLMessage or (Sender = nil) then
|
||
exit;
|
||
|
||
NotifyApplicationUserInput(LCLObject, CharMsg.Msg);
|
||
|
||
if not CanSendLCLMessage or (Sender = nil) then
|
||
exit;
|
||
|
||
DeliverMessage(CharMsg, True);
|
||
if not CanSendLCLMessage or (Sender = nil) then
|
||
exit;
|
||
end;
|
||
|
||
// check if data was changed during key handling
|
||
if CanSendLCLMessage and (Sender <> nil) and
|
||
((KeyMsg.CharCode <> ACharCode) or (UTF8Char <> UTF8Text) or
|
||
(Word(AChar) <> CharMsg.CharCode)) then
|
||
begin
|
||
// data was changed
|
||
// moved to nested proc because of issue #26103
|
||
SendChangedKey;
|
||
end else
|
||
begin
|
||
Result := KeyMsg.CharCode in KeysToEat;
|
||
end;
|
||
end;
|
||
|
||
function TQtWidget.SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
InputEvent: QInputMethodEventH;
|
||
WStr: WideString;
|
||
UnicodeChar: Cardinal;
|
||
UnicodeOutLen: integer;
|
||
KeyEvent: QKeyEventH;
|
||
begin
|
||
Result := True;
|
||
if not (QEvent_type(Event) = QEventInputMethod) then Exit;
|
||
{$ifdef VerboseQt}
|
||
DebugLn('TQtWidget.SlotInputMethod ', dbgsname(LCLObject));
|
||
{$endif}
|
||
InputEvent := QInputMethodEventH(Event);
|
||
QInputMethodEvent_commitString(InputEvent, @WStr);
|
||
UnicodeChar := UTF8CodepointToUnicode(PChar(WStr), UnicodeOutLen);
|
||
{$IFDEF VerboseQtKeys}
|
||
writeln('> TQtWidget.SlotInputMethod ',dbgsname(LCLObject),' event=QEventInputMethod:');
|
||
writeln(' commmitString ',WStr,' len ',length(WStr),' UnicodeChar ',UnicodeChar,
|
||
' UnicodeLen ',UnicodeOutLen);
|
||
writeln(' sending QEventKeyPress');
|
||
{$ENDIF}
|
||
|
||
KeyEvent := QKeyEvent_create(QEventKeyPress, PtrInt(UnicodeChar), QGUIApplication_keyboardModifiers, @WStr, False, 1);
|
||
try
|
||
// do not send it to queue, just pass it to SlotKey
|
||
Result := SlotKey(Sender, KeyEvent);
|
||
finally
|
||
QKeyEvent_destroy(KeyEvent);
|
||
end;
|
||
{$IFDEF VerboseQtKeys}
|
||
writeln('< TQtWidget.SlotInputMethod End: ',dbgsname(LCLObject),' event=QEventInputMethod, sent QEventKeyPress');
|
||
{$ENDIF}
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SlotMouse
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
Msg: TLMMouse;
|
||
MousePos: TQtPoint;
|
||
MButton: QTMouseButton;
|
||
Modifiers: QtKeyboardModifiers;
|
||
SaveWidget: QWidgetH;
|
||
LazButton: Byte;
|
||
LazPos: TPoint;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtWidget.SlotMouse ',DbgSName(Self));
|
||
{$endif}
|
||
|
||
Result := False; // allow qt to handle message
|
||
|
||
if not CanSendLCLMessage then
|
||
exit(True);
|
||
|
||
if (LCLObject <> nil) and
|
||
(not (csDesigning in LCLObject.ComponentState) and not getEnabled) then
|
||
Exit;
|
||
|
||
// idea of multi click implementation is taken from gtk
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
// MousePos :=
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
OffsetMousePos(@MousePos);
|
||
|
||
Modifiers := QInputEvent_modifiers(QInputEventH(Event));
|
||
Msg.Keys := QtKeyModifiersToKeyState(Modifiers, False, nil);
|
||
|
||
Msg.XPos := SmallInt(MousePos.X);
|
||
Msg.YPos := SmallInt(MousePos.Y);
|
||
|
||
MButton := QMouseEvent_Button(QMouseEventH(Event));
|
||
LazPos := Point(MousePos.X, MousePos.Y);
|
||
case MButton of
|
||
QtLeftButton: LazButton := 1;
|
||
QtRightButton: LazButton := 2;
|
||
QtMidButton: LazButton := 3;
|
||
QtXButton1, QtXButton2: LazButton := 4;
|
||
else Exit; // Sometimes mouse wheel triggers an invalid button value. Ignore it.
|
||
end;
|
||
// do not pass mouse button into keys (TShiftState). issue #20916
|
||
if (QEvent_type(Event) <> QEventMouseButtonRelease)
|
||
or (((MButton and QtLeftButton) = 0) and ((MButton and QtRightButton) = 0) and
|
||
((MButton and QtMidButton) = 0))
|
||
then
|
||
Msg.Keys := Msg.Keys or QtButtonsToLCLButtons(MButton);
|
||
Msg.Msg := CheckMouseButtonDownUp(TLCLIntfHandle(Self), LCLObject, LastMouse, LazPos, LazButton,
|
||
QEvent_type(Event) in [QEventMouseButtonPress, QEventMouseButtonDblClick]);
|
||
case LastMouse.ClickCount of
|
||
2: Msg.Keys := Msg.Keys or MK_DOUBLECLICK;
|
||
3: Msg.Keys := Msg.Keys or MK_TRIPLECLICK;
|
||
4: Msg.Keys := Msg.Keys or MK_QUADCLICK;
|
||
end;
|
||
|
||
case QEvent_type(Event) of
|
||
QEventMouseButtonPress, QEventMouseButtonDblClick:
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
if (QEvent_type(Event) = QEventMouseButtonPress) and
|
||
(MButton = QtRightButton) then
|
||
Include(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
|
||
try
|
||
{$ENDIF}
|
||
|
||
NotifyApplicationUserInput(LCLObject, Msg.Msg);
|
||
|
||
if not CanSendLCLMessage or (Sender = nil) then
|
||
exit(True);
|
||
|
||
DeliverMessage(Msg, True);
|
||
|
||
{$IFDEF MSWINDOWS}
|
||
finally
|
||
if (QEvent_type(Event) = QEventMouseButtonPress) and
|
||
(MButton = QtRightButton) then
|
||
begin
|
||
Exclude(FWidgetState, qtwsInsideRightMouseButtonPressEvent);
|
||
Exclude(FWidgetState, qtwsHiddenInsideRightMouseButtonPressEvent);
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
// Check if our objects exists since LCL can destroy object during
|
||
// mouse events...
|
||
if CanSendLCLMessage and (Sender <> nil) then
|
||
SetNoMousePropagation(QWidgetH(Sender), True)
|
||
else
|
||
exit(True);
|
||
end;
|
||
QEventMouseButtonRelease:
|
||
begin
|
||
SaveWidget := nil;
|
||
if (FChildOfComplexWidget = ccwCustomControl) and (FOwner <> nil) then
|
||
SaveWidget := Widget;
|
||
|
||
NotifyApplicationUserInput(LCLObject, Msg.Msg);
|
||
|
||
if (SaveWidget <> nil) and (SaveWidget <> Widget) then
|
||
exit(True);
|
||
|
||
if not CanSendLCLMessage or (Sender = nil) then
|
||
exit(True);
|
||
|
||
DeliverMessage(Msg, True);
|
||
if (SaveWidget <> nil) and (SaveWidget <> Widget) then
|
||
exit(True);
|
||
|
||
// Check if our objects exists since LCL can destroy object during
|
||
// mouse events...
|
||
if CanSendLCLMessage and (Sender <> nil) then
|
||
SetNoMousePropagation(QWidgetH(Sender), True)
|
||
else
|
||
exit(True);
|
||
|
||
{ Clicking on buttons operates differently, because QEventMouseButtonRelease
|
||
is sent if you click a control, drag the mouse out of it and release, but
|
||
buttons should not be clicked on this case. }
|
||
if CanSendLCLMessage and (Sender <> nil) and
|
||
not (LCLObject is TCustomButton) then
|
||
begin
|
||
Msg.Msg := LM_CLICKED;
|
||
DeliverMessage(Msg, True);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtWidget.SlotNCMouse(Sender: QObjectH; Event: QEventH); cdecl;
|
||
var
|
||
AHeader: TRect;
|
||
APoint: TQtPoint;
|
||
begin
|
||
//Drag&Dock support TCustomForm => Start BeginDrag()
|
||
if (LCLObject is TCustomForm) and
|
||
not (csDesigning in LCLObject.ComponentState) and
|
||
(TWinControlAccess(LCLObject).DragKind = dkDock) and
|
||
(TWinControlAccess(LCLObject).DragMode = dmAutomatic) and
|
||
(QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
|
||
begin
|
||
QMouseEvent_globalPos(QMouseEventH(Event), @APoint);
|
||
AHeader := getGeometry;
|
||
with getFrameGeometry do
|
||
AHeader.Top := Top;
|
||
|
||
// remove various buttons from header (how to request their pos cross platform?):
|
||
Inc(AHeader.Left, 20); // system menu
|
||
Dec(AHeader.Right, 80); // close, min, max buttons
|
||
if AHeader.Right < AHeader.Left then
|
||
AHeader.Right := AHeader.Left + 1;
|
||
|
||
// we can skip translation of coords to global since we already working with window
|
||
// check for title
|
||
if PtInRect(AHeader, Point(APoint.x, APoint.y)) then
|
||
LCLObject.BeginDrag(true);
|
||
end;
|
||
end;
|
||
|
||
function TQtWidget.SlotMouseEnter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
Result := False;
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
case QEvent_type(Event) of
|
||
QEventEnter: Msg.Msg := LM_MOUSEENTER;
|
||
QEventLeave: Msg.Msg := LM_MOUSELEAVE;
|
||
end;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
function TQtWidget.QtButtonsToLCLButtons(AButtons: QtMouseButton): PtrInt;
|
||
begin
|
||
Result := 0;
|
||
if (QtLeftButton and AButtons) <> 0 then
|
||
Result := Result or MK_LBUTTON;
|
||
|
||
if (QtRightButton and AButtons) <> 0 then
|
||
Result := Result or MK_RBUTTON;
|
||
|
||
if (QtMidButton and AButtons) <> 0 then
|
||
Result := Result or MK_MBUTTON;
|
||
|
||
if (QtXButton1 and AButtons) <> 0 then
|
||
Result := Result or MK_XBUTTON1;
|
||
|
||
if (QtXButton2 and AButtons) <> 0 then
|
||
Result := Result or MK_XBUTTON2;
|
||
end;
|
||
|
||
function TQtWidget.QtKeyModifiersToKeyState(AModifiers: QtKeyboardModifiers;
|
||
const AIsKeyEvent: Boolean; AEvent: QKeyEventH = nil): PtrInt;
|
||
begin
|
||
// TODO: remove AIsKeyEvent later
|
||
Result := 0;
|
||
if AModifiers and QtShiftModifier <> 0 then
|
||
Result := Result or MK_SHIFT;
|
||
if AModifiers and QtControlModifier <> 0 then
|
||
Result := Result or MK_CONTROL;
|
||
if AModifiers and QtAltModifier <> 0 then
|
||
begin
|
||
if AIsKeyEvent then
|
||
Result := Result or KF_ALTDOWN
|
||
else
|
||
Result := Result or MK_ALT;
|
||
end;
|
||
// $20000000;
|
||
{ TODO: add support for ALT, META and NUMKEYPAD }
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SlotMouseMove
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.SlotMouseMove(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
Msg: TLMMouseMove;
|
||
MousePos: TQtPoint;
|
||
GlobPos: TQtPoint;
|
||
R: TRect;
|
||
P: TPoint;
|
||
NewEvent: QEventH;
|
||
W: QWidgetH;
|
||
FrameBorder: Integer;
|
||
TitleBarHeight: Integer;
|
||
SenderWidget: QWidgetH;
|
||
SavedLCLObject: PtrUint;
|
||
begin
|
||
Result := False;
|
||
if not CanSendLCLMessage or (Sender = nil) or
|
||
not QObject_isWidgetType(Sender) then
|
||
Exit(True);
|
||
|
||
SenderWidget := QWidgetH(Sender);
|
||
|
||
if not (csCaptureMouse in LCLObject.ControlStyle) and
|
||
not QWidget_isWindow(SenderWidget) and
|
||
not DragManager.IsDragging then
|
||
begin
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
QMouseEvent_globalPos(QMouseEventH(Event), @GlobPos);
|
||
|
||
// get parent form, so check if mouse is out of parent form first.
|
||
W := QWidget_window(SenderWidget);
|
||
|
||
if W <> nil then
|
||
begin
|
||
QWidget_frameGeometry(W, @R);
|
||
|
||
// exclude borders from frame
|
||
FrameBorder := GetPixelMetric(QStylePM_DefaultFrameWidth, nil, W);
|
||
TitleBarHeight := GetPixelMetric(QStylePM_TitleBarHeight, nil, W);
|
||
|
||
inc(R.Left, FrameBorder);
|
||
inc(R.Top, TitleBarHeight);
|
||
dec(R.Right, FrameBorder);
|
||
dec(R.Bottom, FrameBorder);
|
||
|
||
P := Point(GlobPos.X, GlobPos.Y);
|
||
if not PtInRect(R, P) then
|
||
MousePos := QtPoint(-1, -1);
|
||
|
||
if not QWidget_underMouse(SenderWidget) then
|
||
begin
|
||
if (MousePos.X >= 0) and (MousePos.Y >= 0) then
|
||
begin
|
||
QWidget_setAttribute(SenderWidget, QtWA_UnderMouse, True);
|
||
NewEvent := QEvent_create(QEventEnter);
|
||
QCoreApplication_postEvent(SenderWidget, NewEvent, 100);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
if not (csCaptureMouse in LCLObject.ControlStyle) and
|
||
(QGUIApplication_mouseButtons() <> QtNoButton) and
|
||
(((MousePos.X < 0) or (MousePos.Y < 0)) or
|
||
((MousePos.X > getWidth) or (MousePos.Y > getHeight))) then
|
||
begin
|
||
if not QWidget_underMouse(SenderWidget) then
|
||
exit;
|
||
setCursor(FDefaultCursor);
|
||
NewEvent := QEvent_create(QEventLeave);
|
||
QCoreApplication_postEvent(SenderWidget, NewEvent, 100);
|
||
exit;
|
||
end;
|
||
end;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
// MousePos :=
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
OffsetMousePos(@MousePos);
|
||
|
||
Msg.XPos := SmallInt(MousePos.X);
|
||
Msg.YPos := SmallInt(MousePos.Y);
|
||
|
||
Msg.Keys := QtButtonsToLCLButtons(QMouseEvent_Buttons(QMouseEventH(Event)))
|
||
or QtKeyModifiersToKeyState(QInputEvent_modifiers(QInputEventH(Event)), False, nil);
|
||
|
||
Msg.Msg := LM_MOUSEMOVE;
|
||
|
||
SetNoMousePropagation(SenderWidget, True);
|
||
SavedLCLObject := PtrUInt(LCLObject);
|
||
|
||
NotifyApplicationUserInput(LCLObject, Msg.Msg);
|
||
|
||
if (SavedLCLObject <> PtrUInt(LCLObject)) or not CanSendLCLMessage then
|
||
exit(True);
|
||
|
||
DeliverMessage(Msg, True);
|
||
|
||
if (SavedLCLObject <> PtrUInt(LCLObject)) or not CanSendLCLMessage then
|
||
exit(True);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SlotMouseWheel
|
||
Params: None
|
||
Returns: Nothing
|
||
|
||
Qt stores the delta in 1/8 of a degree
|
||
Most mouses scroll 15 degrees each time
|
||
|
||
Msg.WheelDelta: -1 for up, 1 for down
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.SlotMouseWheel(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
Msg: TLMMouseEvent;
|
||
MousePos: TQtPoint;
|
||
Modifiers: QtKeyboardModifiers;
|
||
ModifierState: PtrInt;
|
||
{$IFDEF DARWIN}
|
||
CCtl: TQtAbstractScrollArea;
|
||
{$ENDIF}
|
||
begin
|
||
Result := False;
|
||
if not CanSendLCLMessage then
|
||
exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
QWheelEvent_Pos(QWheelEventH(Event), @MousePos);
|
||
OffsetMousePos(@MousePos);
|
||
|
||
Modifiers := QInputEvent_modifiers(QInputEventH(Event));
|
||
Msg.State := [];
|
||
ModifierState := QtKeyModifiersToKeyState(Modifiers, False, nil);
|
||
if (ModifierState and MK_SHIFT) <> 0 then
|
||
Msg.State := [ssShift];
|
||
if (ModifierState and MK_CONTROL) <> 0 then
|
||
Msg.State := [ssCtrl] + Msg.State;
|
||
if (ModifierState and MK_ALT) <> 0 then
|
||
Msg.State := [ssAlt] + Msg.State;
|
||
|
||
LastMouse.WinControl := LCLObject;
|
||
LastMouse.WinHandle := TLCLIntfHandle(Self);
|
||
LastMouse.MousePos := Point(MousePos.X, MousePos.Y);
|
||
|
||
Msg.X := SmallInt(MousePos.X);
|
||
Msg.Y := SmallInt(MousePos.Y);
|
||
|
||
Msg.WheelDelta := SmallInt(QWheelEvent_delta(QWheelEventH(Event)));
|
||
|
||
Msg.Msg := LM_MOUSEWHEEL;
|
||
if QWheelEvent_orientation(QWheelEventH(Event)) = QtHorizontal then
|
||
begin
|
||
Msg.Msg := LM_MOUSEHWHEEL;
|
||
Msg.WheelDelta := -Msg.WheelDelta;
|
||
end;
|
||
|
||
{$IFDEF DARWIN}
|
||
// LCL expects delta +-120, we must fix it. issue #20888
|
||
if (ChildOfComplexWidget in [ccwCustomControl, ccwAbstractScrollArea,
|
||
ccwScrollingWinControl]) then
|
||
begin
|
||
if (Msg.WheelDelta > 0) then
|
||
Msg.WheelDelta := 1
|
||
else
|
||
Msg.WheelDelta := -1;
|
||
Msg.WheelDelta := (120 * Msg.WheelDelta) div Mouse.WheelScrollLines;
|
||
if FOwner <> nil then
|
||
begin
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if (FOwner is TQtMainWindow) then
|
||
CCtl := TQtMainWindow(FOwner).ScrollArea
|
||
else
|
||
{$ENDIF}
|
||
CCtl := TQtAbstractScrollArea(FOwner);
|
||
end else
|
||
CCtl := TQtAbstractScrollArea(Self);
|
||
//now fix ugly behaviour.
|
||
if (Msg.WheelDelta > 0) and (CCtl.FVScrollbar.getVisible) and
|
||
((CCtl.FVScrollBar = Self) or
|
||
(Assigned(CCtl.FVScrollbar) and (Self <> CCtl.FHScrollbar))) then
|
||
begin
|
||
if CCtl.FVScrollbar.getSliderPosition <= 1 then
|
||
Msg.WheelDelta := 120;
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
NotifyApplicationUserInput(LCLObject, Msg.Msg);
|
||
|
||
if not CanSendLCLMessage then
|
||
exit(True);
|
||
|
||
Result := DeliverMessage(Msg, True) <> 0;
|
||
|
||
if not CanSendLCLMessage then
|
||
exit(True);
|
||
|
||
SetNoMousePropagation(QWidgetH(Sender), False);
|
||
|
||
{propagate mousewheel to parent if our sender is TPanel,
|
||
fixes problem with mousewheel scroll with lazreport}
|
||
if (LCLObject <> nil) and
|
||
not (csDesigning in LCLObject.ComponentState) and
|
||
(LCLObject is TPanel) and
|
||
Assigned(LCLObject.Parent) then
|
||
Result := TQtWidget(LCLObject.Parent.Handle).DeliverMessage(Msg) <> 0;
|
||
end;
|
||
|
||
procedure TQtWidget.SlotMove(Event: QEventH); cdecl;
|
||
var
|
||
Msg: TLMMove;
|
||
APos: TQtPoint;
|
||
{$IFDEF HASX11}
|
||
ACurrPos: TQtPoint;
|
||
{$ENDIF}
|
||
FrameRect, WindowRect: TRect;
|
||
ForceSendMove: boolean;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtWidget.SlotMove');
|
||
{$endif}
|
||
|
||
if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
|
||
QtWidgetSet.InvalidateWidgetAtCache;
|
||
// do not loop with LCL
|
||
if InUpdate {$ifdef darwin} and not (qtwsForceSendMove in WidgetState){$endif} then
|
||
exit;
|
||
|
||
ForceSendMove := False; {mantis #34589}
|
||
if not QEvent_spontaneous(Event) and Assigned(LCLObject) and Assigned(LCLObject.Parent) then
|
||
// only children of 1st level should move.
|
||
ForceSendMove := qtwsForceSendMove in TQtWidget(LCLObject.Parent.Handle).WidgetState;
|
||
|
||
{$ifdef darwin}
|
||
// issue #34698
|
||
if not ForceSendMove and not QEvent_spontaneous(Event) and Assigned(LCLObject) and
|
||
(Self is TQtMainWindow) and not TQtMainWindow(Self).IsMdiChild then
|
||
begin
|
||
ForceSendMove := qtwsForceSendMove in WidgetState;
|
||
Exclude(FWidgetState, qtwsForceSendMove);
|
||
end;
|
||
{$endif}
|
||
|
||
if ForceSendMove then
|
||
// send message mantis #34589
|
||
else
|
||
if not QEvent_spontaneous(Event) or
|
||
(not QEvent_spontaneous(Event) and
|
||
((Self is TQtMainWindow) and not
|
||
TQtMainWindow(Self).IsMdiChild)) then
|
||
Exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
Msg.Msg := LM_MOVE;
|
||
|
||
Msg.MoveType := Msg.MoveType or Move_SourceIsInterface;
|
||
|
||
APos := QMoveEvent_pos(QMoveEventH(Event))^;
|
||
FrameRect := getFrameGeometry;
|
||
WindowRect := getGeometry;
|
||
|
||
// here is explanation why frameGeometry sometimes
|
||
// doesn't return correct results under X11
|
||
// http://doc.qt.nokia.com/4.7/application-windows.html#window-geometry
|
||
// issue #18658
|
||
{$IFDEF HASX11}
|
||
if (LCLObject is TCustomForm) and EqualRect(FrameRect, WindowRect) and
|
||
(TCustomForm(LCLObject).BorderStyle <> bsNone) and
|
||
(not (TCustomForm(LCLObject).FormStyle in [fsMDIChild,fsSplash]) or
|
||
(csDesigning in LCLObject.ComponentState)) then
|
||
begin
|
||
ACurrPos := getPos;
|
||
// do not send garbage to LCL. This window isn't decorated yet by WM.
|
||
if (ACurrPos.X = WindowRect.Left) and (ACurrPos.Y = WindowRect.Top) then
|
||
exit;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
Msg.XPos := SmallInt(APos.x - (WindowRect.Left - FrameRect.Left));
|
||
Msg.YPos := SmallInt(APos.y - (WindowRect.Top - FrameRect.Top));
|
||
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SlotPaintBg
|
||
Params: None
|
||
Returns: Nothing.
|
||
|
||
Paints widget background.
|
||
Only for classes which have HasPaint=False and AutoFillBackground=False
|
||
and solid color different to default one (eg. clBtnFace for buttons).
|
||
Current allowed classes are: All TQtCheckBox,TQtRadioButton,
|
||
TQtPushButton (X11 only), TQtStaticText and TQtGroupBox.
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtWidget.SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl;
|
||
var
|
||
Painter: QPainterH;
|
||
Brush: QBrushH;
|
||
Color: TQColor;
|
||
R: TRect;
|
||
begin
|
||
if CanSendLCLMessage and (LCLObject is TWinControl) and (FContext = 0) then
|
||
begin
|
||
if LCLObject.Color = clDefault then
|
||
Color := Palette.DefaultColor
|
||
else
|
||
ColorRefToTQColor(ColorToRGB(LCLObject.Color), Color);
|
||
Painter := QPainter_create(QWidget_to_QPaintDevice(QWidgetH(Sender)));
|
||
{$IFDEF USEQT4COMPATIBILEPAINTER}
|
||
QPainter_setRenderHint(Painter, QPainterQt4CompatiblePainting);
|
||
{$ENDIF}
|
||
Brush := QBrush_create(@Color, QtSolidPattern);
|
||
try
|
||
QPaintEvent_rect(QPaintEventH(Event), @R);
|
||
QPainter_fillRect(Painter, @R, Brush);
|
||
QPainter_end(Painter);
|
||
finally
|
||
QBrush_destroy(Brush);
|
||
QPainter_destroy(Painter);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SlotPaint
|
||
Params: None
|
||
Returns: Nothing
|
||
|
||
Sends a LM_PAINT message to the LCL. This is for windowed controls only
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtWidget.SlotPaint(Sender: QObjectH; Event: QEventH); cdecl;
|
||
var
|
||
Msg: TLMPaint;
|
||
AStruct: PPaintStruct;
|
||
P: TPoint;
|
||
B: Boolean;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtWidget.SlotPaint ', dbgsName(LCLObject));
|
||
{$endif}
|
||
if CanSendLCLMessage and (LCLObject is TWinControl) and (FContext = 0) then
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
Msg.Msg := LM_PAINT;
|
||
New(AStruct);
|
||
FillChar(AStruct^, SizeOf(TPaintStruct), 0);
|
||
Msg.PaintStruct := AStruct;
|
||
|
||
with PaintData do
|
||
begin
|
||
PaintWidget := QWidgetH(Sender);
|
||
ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
|
||
if ClipRect = nil then
|
||
New(ClipRect);
|
||
QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
|
||
end;
|
||
|
||
Msg.DC := BeginPaint(THandle(Self), AStruct^);
|
||
FContext := Msg.DC;
|
||
|
||
Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
|
||
Msg.PaintStruct^.hdc := FContext;
|
||
|
||
P := getClientOffset;
|
||
|
||
if (Self is TQtGroupBox) and (QWidgetH(Sender) = FCentralWidget) then
|
||
begin
|
||
P.X := 0;
|
||
P.Y := 0;
|
||
end;
|
||
inc(P.X, FScrollX);
|
||
inc(P.Y, FScrollY);
|
||
TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
|
||
|
||
// send paint message
|
||
try
|
||
// Saving clip rect and clip region
|
||
try
|
||
LCLObject.WindowProc(TLMessage(Msg));
|
||
if HasCaret then
|
||
begin
|
||
if GlobalCaretDirty then
|
||
QtCaret.ShowCaret(Self);
|
||
QtCaret.DrawCaret;
|
||
end;
|
||
finally
|
||
Dispose(PaintData.ClipRect);
|
||
Fillchar(FPaintData, SizeOf(FPaintData), 0);
|
||
FContext := 0;
|
||
EndPaint(THandle(Self), AStruct^);
|
||
Dispose(AStruct);
|
||
end;
|
||
except
|
||
// prevent recursive repainting !
|
||
B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
|
||
if B then
|
||
QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
|
||
try
|
||
Application.HandleException(nil);
|
||
finally
|
||
if B and Assigned(Application) and not Application.Terminated then
|
||
QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SlotResize
|
||
Params: None
|
||
Returns: Nothing
|
||
|
||
Sends a LM_SIZE message to the LCL.
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtWidget.SlotResize(Event: QEventH); cdecl;
|
||
var
|
||
Msg: TLMSize;
|
||
NewSize: TSize;
|
||
{$IFDEF VerboseQtResizeError}
|
||
R: TRect;
|
||
{$ENDIF}
|
||
B: Boolean;
|
||
AQtClientRect: TRect;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtWidget.SlotResize');
|
||
{$endif}
|
||
|
||
if QtWidgetSet.IsWidgetAtCache(HWND(Self)) then
|
||
QtWidgetSet.InvalidateWidgetAtCache;
|
||
|
||
// return size w/o frame
|
||
NewSize := QResizeEvent_size(QResizeEventH(Event))^;
|
||
|
||
if not Assigned(LCLObject) then exit;
|
||
|
||
if InResizeEvent or (Assigned(FOwner) and FOwner.InResizeEvent) then
|
||
begin
|
||
{$IFDEF VerboseQtResizeError}
|
||
if not InUpdate then
|
||
begin
|
||
DebugLn('============================================================================');
|
||
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 !');
|
||
DebugLn(dbgsName(LCLObject),' self=',dbgsName(Self),' already in SlotResize needClientRectAdjust',dbgs(LCLObject.ClientRectNeedsInterfaceUpdate),
|
||
' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
|
||
R := getClientBounds;
|
||
DebugLn('LCL CACHED CLIENT WxH=',dbgs(LCLObject.CachedClientWidth),'x',dbgs(LCLObject.CachedClientHeight),
|
||
' QtClient=',dbgs(R));
|
||
DebugLn('============================================================================');
|
||
end;
|
||
{$ENDIF}
|
||
exit;
|
||
end;
|
||
if Assigned(FOwner) then
|
||
FOwner.InResizeEvent := True;
|
||
InResizeEvent := True;
|
||
try
|
||
// do not loop with LCL but do not apply it to TQtMainWindow !
|
||
if not (csDesigning in LCLObject.ComponentState) and
|
||
not ((ClassType = TQtMainWindow) {$IFDEF QTSCROLLABLEFORMS} or (ClassType = TQtWindowArea){$ENDIF})
|
||
and InUpdate then
|
||
begin
|
||
AQtClientRect := Rect(0, 0, 0, 0);
|
||
if FOwner <> nil then
|
||
B := GetClientRect(HWND(Self.FOwner), AQtClientRect)
|
||
else
|
||
B := GetClientRect(HWND(Self), AQtClientRect);
|
||
if B and EqualRect(LCLObject.ClientRect, AQtClientRect) then
|
||
begin
|
||
{$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('==========',dbgsName(LCLObject),'.SlotResize inUpdate.LCLObject.ClientRect is ok,do not send LMSize');
|
||
{$ENDIF}
|
||
exit;
|
||
end else
|
||
begin
|
||
{$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('====***====',dbgsName(LCLObject),'.SlotResize inUpdate but LCL.ClientRect isn''t adjusted. CanAdjust=',dbgs(CanAdjustClientRectOnResize),' CAPS=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' NeedUpd ',dbgs(LCLObject.ClientRectNeedsInterfaceUpdate));
|
||
{$ENDIF}
|
||
if LCLObject.ClientRectNeedsInterfaceUpdate and
|
||
not (caspComputingBounds in LCLObject.AutoSizePhases) then
|
||
begin
|
||
LCLObject.DoAdjustClientRectChange(True);
|
||
exit;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{keep LCL value while designing pageControl}
|
||
if (csDesigning in LCLObject.ComponentState) and InUpdate and
|
||
((Self is TQtPage) or (Self is TQtTabWidget)) then
|
||
exit;
|
||
|
||
if CanAdjustClientRectOnResize and
|
||
LCLObject.ClientRectNeedsInterfaceUpdate then
|
||
begin
|
||
// postpone resize event if we are computingbounds otherwise
|
||
// we can run into infinite size loop.
|
||
if (caspComputingBounds in LCLObject.AutoSizePhases) then
|
||
begin
|
||
{$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('WARNING: *TQtWidget.SlotResize caspComputingBounds=true* ! ',dbgsname(LCLObject),':',dbgsName(Self),' inUpdate=',dbgs(inUpdate),' Time: ',dbgs(GetTickCount));
|
||
{$ENDIF}
|
||
if ChildOfComplexWidget <> ccwScrollingWinControl then
|
||
DelayResizeEvent(Widget, NewSize);
|
||
exit;
|
||
end else
|
||
begin
|
||
LCLObject.DoAdjustClientRectChange;
|
||
end;
|
||
end;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
Msg.Msg := LM_SIZE;
|
||
|
||
case getWindowState of
|
||
QtWindowMinimized: Msg.SizeType := SIZE_MINIMIZED;
|
||
QtWindowMaximized: Msg.SizeType := SIZE_MAXIMIZED;
|
||
QtWindowFullScreen: Msg.SizeType := SIZE_FULLSCREEN;
|
||
else
|
||
Msg.SizeType := SIZE_RESTORED;
|
||
end;
|
||
|
||
Msg.SizeType := Msg.SizeType or Size_SourceIsInterface;
|
||
|
||
Msg.Width := Word(NewSize.cx);
|
||
Msg.Height := Word(NewSize.cy);
|
||
|
||
DeliverMessage(Msg);
|
||
finally
|
||
if ASsigned(FOwner) then
|
||
FOwner.InResizeEvent := False;
|
||
InResizeEvent := False;
|
||
end;
|
||
end;
|
||
|
||
function TQtWidget.SlotContextMenu(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
Msg: TLMContextMenu;
|
||
MousePos: TQtPoint;
|
||
|
||
procedure SendMouseReleaseEventToSelf;
|
||
var
|
||
AEvent: QEventH;
|
||
Modifiers: QtKeyboardModifiers;
|
||
APos, AGlobalPos: TQtPoint;
|
||
APosF, AGlobalPosF: TQtPointF;
|
||
begin
|
||
APos := QContextMenuEvent_pos(QContextMenuEventH(Event))^;
|
||
AGlobalPos := QContextMenuEvent_globalPos(QContextMenuEventH(Event))^;
|
||
APosF.X := APos.X;
|
||
APosF.Y := APos.Y;
|
||
AGlobalPosF.X := AGlobalPos.x;
|
||
AGlobalPosF.Y := AGlobalPos.y;
|
||
Modifiers := QInputEvent_modifiers(QInputEventH(Event));
|
||
AEvent := QMouseEvent_create(QEventMouseButtonRelease,
|
||
@APosF,
|
||
@AGlobalPosF,
|
||
QtRightButton,
|
||
QtRightButton,
|
||
Modifiers);
|
||
QCoreApplication_postEvent(Widget, AEvent, 1);
|
||
end;
|
||
|
||
begin
|
||
if not CanSendLCLMessage then
|
||
Exit(False);
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
MousePos := QContextMenuEvent_globalPos(QContextMenuEventH(Event))^;
|
||
|
||
Msg.Msg := LM_CONTEXTMENU;
|
||
if FOwner <> nil then
|
||
Msg.hWnd := HWND(FOwner)
|
||
else
|
||
Msg.hWnd := HWND(Self);
|
||
if QContextMenuEvent_reason(QContextMenuEventH(Event)) = QContextMenuEventKeyboard then
|
||
begin
|
||
Msg.XPos := -1;
|
||
Msg.YPos := -1;
|
||
end
|
||
else
|
||
begin
|
||
Msg.XPos := SmallInt(MousePos.X);
|
||
Msg.YPos := SmallInt(MousePos.Y);
|
||
end;
|
||
|
||
Result := DeliverMessage(Msg) <> 0;
|
||
|
||
if Result then
|
||
QEvent_accept(Event)
|
||
else
|
||
begin
|
||
if Assigned(LCLObject.PopupMenu) then
|
||
QEvent_ignore(Event);
|
||
SetNoMousePropagation(QWidgetH(Sender), False);
|
||
if (FOwner <> nil) and
|
||
((FChildOfComplexWidget = ccwCustomControl) or
|
||
(FChildOfComplexWidget = ccwScrollingWinControl)) then
|
||
SetNoMousePropagation(FOwner.Widget, False);
|
||
end;
|
||
|
||
if Result and (csDesigning in LCLObject.ComponentState) then
|
||
SendMouseReleaseEventToSelf;
|
||
end;
|
||
|
||
procedure TQtWidget.SlotWhatsThis(Sender: QObjectH; Event: QEventH); cdecl;
|
||
var
|
||
Data: THelpInfo;
|
||
begin
|
||
if not CanSendLCLMessage then
|
||
exit;
|
||
Data.cbSize := SizeOf(Data);
|
||
Data.iContextType := HELPINFO_WINDOW;
|
||
Data.iCtrlId := 0;
|
||
Data.hItemHandle := THandle(Sender);
|
||
Data.dwContextId := 0;
|
||
with QHelpEvent_globalPos(QHelpEventH(Event))^ do
|
||
Data.MousePos := Point(X, Y);
|
||
Application.HelpCommand(0, {%H-}PtrInt(@Data));
|
||
end;
|
||
|
||
procedure TQtWidget.SlotLCLMessage(Sender: QObjectH; Event: QEventH); cdecl;
|
||
var
|
||
MessageEvent: QLCLMessageEventH absolute Event;
|
||
Msg: TLMessage;
|
||
begin
|
||
Msg.msg := Cardinal(QLCLMessageEvent_getMsg(MessageEvent));
|
||
Msg.wParam := PtrInt(QLCLMessageEvent_getWParam(MessageEvent));
|
||
Msg.lParam := PtrInt(QLCLMessageEvent_getLParam(MessageEvent));
|
||
Msg.Result := 0;
|
||
QLCLMessageEvent_setMsgResult(MessageEvent, PtrUInt(DeliverMessage(Msg)));
|
||
end;
|
||
|
||
procedure TQtWidget.Activate;
|
||
begin
|
||
QWidget_activateWindow(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.BringToFront;
|
||
begin
|
||
Activate;
|
||
raiseWidget;
|
||
end;
|
||
|
||
procedure TQtWidget.clearMask;
|
||
begin
|
||
QWidget_clearMask(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.OffsetMousePos(APoint: PQtPoint);
|
||
begin
|
||
with getClientOffset do
|
||
begin
|
||
dec(APoint^.x, x);
|
||
dec(APoint^.y, y);
|
||
end;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SetColor
|
||
Params: QColorH
|
||
Returns: Nothing
|
||
|
||
Changes the color of a widget
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtWidget.setColor(const Value: PQColor);
|
||
begin
|
||
Palette.setColor(Value);
|
||
end;
|
||
|
||
function TQtWidget.getContextMenuPolicy: QtContextMenuPolicy;
|
||
begin
|
||
Result := QWidget_contextMenuPolicy(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.setContextMenuPolicy(const AValue: QtContextMenuPolicy);
|
||
begin
|
||
QWidget_setContextMenuPolicy(Widget, AValue);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.SetTextColor
|
||
Params: QColorH
|
||
Returns: Nothing
|
||
|
||
Changes the text color of a widget
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtWidget.setTextColor(const Value: PQColor);
|
||
begin
|
||
Palette.setTextColor(Value);
|
||
end;
|
||
|
||
procedure TQtWidget.setCursor(const ACursor: QCursorH);
|
||
begin
|
||
{$IFDEF DARWIN}
|
||
if not QWidget_isVisible(Widget) then
|
||
exit;
|
||
{$ENDIF}
|
||
if ACursor <> nil then
|
||
QWidget_setCursor(Widget, ACursor)
|
||
else
|
||
QWidget_setCursor(Widget, FDefaultCursor);
|
||
end;
|
||
|
||
procedure TQtWidget.setDefaultColorRoles;
|
||
begin
|
||
FWidgetColorRole := QPaletteWindow;
|
||
FTextColorRole := QPaletteWindowText;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.Update
|
||
Params: None
|
||
Returns: Nothing
|
||
|
||
Schedules a paint event for processing when Qt returns to the main event loop
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtWidget.Update(ARect: PRect = nil);
|
||
begin
|
||
if ARect <> nil then
|
||
QWidget_update(Widget, ARect)
|
||
else
|
||
QWidget_update(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.UpdateRegion(ARgn: QRegionH);
|
||
begin
|
||
if ARgn <> nil then
|
||
QWidget_update(Widget, ARgn)
|
||
else
|
||
QWidget_update(Widget);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.Repaint
|
||
Params: None
|
||
Returns: Nothing
|
||
|
||
Repaints the control imediately
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtWidget.Repaint(ARect: PRect = nil);
|
||
begin
|
||
if ARect <> nil then
|
||
QWidget_repaint(Widget, ARect)
|
||
else
|
||
QWidget_repaint(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.setWindowTitle(Str: PWideString);
|
||
begin
|
||
QWidget_setWindowTitle(Widget, Str);
|
||
end;
|
||
|
||
procedure TQtWidget.WindowTitle(Str: PWideString);
|
||
begin
|
||
QWidget_WindowTitle(Widget, Str);
|
||
end;
|
||
|
||
procedure TQtWidget.Hide;
|
||
begin
|
||
QWidget_hide(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.Show;
|
||
begin
|
||
QWidget_show(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.ShowNormal;
|
||
begin
|
||
QWidget_showNormal(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.ShowMinimized;
|
||
begin
|
||
QWidget_showMinimized(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.ShowMaximized;
|
||
begin
|
||
QWidget_showMaximized(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.ShowFullScreen;
|
||
begin
|
||
QWidget_showFullScreen(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getActionByIndex(AIndex: Integer): QActionH;
|
||
var
|
||
ActionList: TPtrIntArray;
|
||
begin
|
||
QWidget_actions(Widget, @ActionList);
|
||
if (AIndex >= 0) and (AIndex < Length(ActionList)) then
|
||
Result := QActionH(ActionList[AIndex])
|
||
else
|
||
Result := nil;
|
||
end;
|
||
|
||
function TQtWidget.getAutoFillBackground: Boolean;
|
||
begin
|
||
Result := QWidget_autoFillBackground(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getEnabled: Boolean;
|
||
begin
|
||
if Widget = nil then
|
||
exit(False);
|
||
Result := QWidget_isEnabled(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getFont: QFontH;
|
||
begin
|
||
Result := QWidget_font(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getFocusPolicy: QtFocusPolicy;
|
||
begin
|
||
Result := QWidget_focusPolicy(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getFrameGeometry: TRect;
|
||
begin
|
||
QWidget_frameGeometry(Widget, @Result);
|
||
end;
|
||
|
||
function TQtWidget.getGeometry: TRect;
|
||
begin
|
||
QWidget_geometry(Widget, @Result);
|
||
end;
|
||
|
||
function TQtWidget.getLayoutDirection: QtLayoutDirection;
|
||
begin
|
||
Result := QWidget_layoutDirection(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getVisible: Boolean;
|
||
begin
|
||
if Widget = nil then
|
||
exit(False);
|
||
Result := QWidget_isVisible(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getVisibleTo(AWidget: QWidgetH): Boolean;
|
||
begin
|
||
if Widget = nil then
|
||
exit(False);
|
||
Result := QWidget_isVisibleTo(Widget, AWidget);
|
||
end;
|
||
|
||
function TQtWidget.getOwner: TQtWidget;
|
||
begin
|
||
Result := FOwner;
|
||
end;
|
||
|
||
function TQtWidget.getParent: QWidgetH;
|
||
begin
|
||
Result := QWidget_parentWidget(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getPos: TQtPoint;
|
||
begin
|
||
QWidget_pos(Widget, @Result);
|
||
end;
|
||
|
||
function TQtWidget.getFrameSize: TSize;
|
||
begin
|
||
QWidget_frameSize(Widget, @Result);
|
||
end;
|
||
|
||
function TQtWidget.getSize: TSize;
|
||
begin
|
||
QWidget_size(Widget, @Result);
|
||
end;
|
||
|
||
function TQtWidget.getText: WideString;
|
||
begin
|
||
Result := FText;
|
||
end;
|
||
|
||
function TQtWidget.getTextStatic: Boolean;
|
||
begin
|
||
Result := True;
|
||
end;
|
||
|
||
function TQtWidget.getHeight: Integer;
|
||
begin
|
||
Result := QWidget_height(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getUpdatesEnabled: Boolean;
|
||
begin
|
||
Result := QWidget_updatesEnabled(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getWidth: Integer;
|
||
begin
|
||
Result := QWidget_width(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getWindow: TQtWidget;
|
||
var
|
||
W: QWidgetH;
|
||
begin
|
||
Result := nil;
|
||
W := QWidget_window(Widget);
|
||
if W <> nil then
|
||
Result := TQtWidget(HwndFromWidgetH(W));
|
||
end;
|
||
|
||
function TQtWidget.getWindowState: QtWindowStates;
|
||
begin
|
||
Result := QWidget_windowState(Widget);
|
||
end;
|
||
|
||
function TQtWidget.getClientBounds: TRect;
|
||
{$IFDEF VerboseQtResizeError}
|
||
var
|
||
R: TRect;
|
||
{$ENDIF}
|
||
begin
|
||
QWidget_contentsRect(getContainerWidget, @Result);
|
||
{only when FOwner implements it's own getClientBounds !
|
||
Valid for FOwner: TQtTabWidget, TQtAbstractScrollArea and it's successors}
|
||
if (FOwner <> nil) and
|
||
not (ChildOfComplexWidget in [ccwComboBox]) then
|
||
begin
|
||
{$IFDEF VerboseQtResizeError}
|
||
R := FOwner.getClientBounds;
|
||
if not EqualRect(R, Result) then
|
||
DebugLn('WARNING: Providing wrong clientRect ',dbgs(Result),' for ',dbgsName(LCLObject),' from ',dbgsName(Self),' FOwner ',dbgsName(FOwner),' ==>',dbgs(R));
|
||
Result := R;
|
||
{$ELSE}
|
||
Result := FOwner.getClientBounds;
|
||
{$ENDIF}
|
||
end;
|
||
end;
|
||
|
||
function TQtWidget.getClientOffset: TPoint;
|
||
var
|
||
P: TQtPoint;
|
||
R: TRect;
|
||
{$IFDEF VerboseQtResizeError}
|
||
Pt: TPoint;
|
||
{$ENDIF}
|
||
begin
|
||
// we need an offset of container inside widget, but if container = widget then
|
||
// offset = 0
|
||
{$IFDEF VerboseQtResizeError}
|
||
if Widget <> GetContainerWidget then
|
||
QWidget_pos(GetContainerWidget, @P)
|
||
else
|
||
P := QtPoint(0, 0);
|
||
R := getClientBounds;
|
||
Result := Point(P.x + R.Left, P.y + R.Top);
|
||
if (FOwner <> nil) and
|
||
not (ChildOfComplexWidget in [ccwComboBox]) then
|
||
begin
|
||
Pt := FOwner.getClientOffset;
|
||
if (Pt.x <> Result.x) or (Pt.y <> Result.y) then
|
||
DebugLn('WARNING: Providing wrong clientOffset ',dbgs(Result),' for ',dbgsName(LCLObject),' from ',dbgsName(Self),' FOwner ',dbgsName(FOwner),' ==>',dbgs(Pt));
|
||
Result := Pt;
|
||
end;
|
||
{$ELSE}
|
||
if (FOwner <> nil) and
|
||
not (ChildOfComplexWidget in [ccwComboBox]) then
|
||
begin
|
||
Result := FOwner.getClientOffset;
|
||
end else
|
||
begin
|
||
if Widget <> GetContainerWidget then
|
||
QWidget_pos(GetContainerWidget, @P)
|
||
else
|
||
P := QtPoint(0, 0);
|
||
R := getClientBounds;
|
||
Result := Point(P.x + R.Left, P.y + R.Top);
|
||
end;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TQtWidget.grabMouse;
|
||
begin
|
||
//DumpStack;
|
||
//DebugLn(['current grab is: ', dbgs(QWidget_mouseGrabber())]);
|
||
//DebugLn(['grab mouse for: ', dbgsName(LCLObject), ' : ', dbgs(Widget)]);
|
||
QWidget_grabMouse(Widget);
|
||
end;
|
||
|
||
function TQtWidget.hasFocus: Boolean;
|
||
begin
|
||
Result := QWidget_hasFocus(Widget);
|
||
end;
|
||
|
||
function TQtWidget.IsActiveWindow: Boolean;
|
||
begin
|
||
Result := QWidget_isActiveWindow(Widget);
|
||
end;
|
||
|
||
function TQtWidget.isMinimized: Boolean;
|
||
begin
|
||
Result := QWidget_isMinimized(Widget);
|
||
end;
|
||
|
||
function TQtWidget.isMaximized: Boolean;
|
||
begin
|
||
Result := QWidget_isMaximized(Widget);
|
||
end;
|
||
|
||
function TQtWidget.IsFramedWidget: boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
function TQtWidget.isFullScreen: Boolean;
|
||
begin
|
||
Result := QWidget_isFullScreen(Widget);
|
||
end;
|
||
|
||
function TQtWidget.IsWindow: Boolean;
|
||
begin
|
||
Result := QWidget_isWindow(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.lowerWidget;
|
||
begin
|
||
QWidget_lower(Widget);
|
||
end;
|
||
|
||
function TQtWidget.MapToGlobal(APt: TPoint;
|
||
const AWithScrollOffset: Boolean = False): TPoint;
|
||
var
|
||
Pt: TQtPoint;
|
||
NewPt: TQtPoint;
|
||
begin
|
||
Pt := QtPoint(APt.X, APt.Y);
|
||
NewPt := QtPoint(0, 0);
|
||
QWidget_mapToGlobal(GetContainerWidget, @NewPt, @Pt);
|
||
Result := Point(NewPt.x, NewPt.y);
|
||
end;
|
||
|
||
function TQtWidget.MapFromGlobal(APt: TPoint;
|
||
const AWithScrollOffset: Boolean = False): TPoint;
|
||
var
|
||
Pt: TQtPoint;
|
||
NewPt: TQtPoint;
|
||
begin
|
||
Pt := QtPoint(APt.X, APt.Y);
|
||
NewPt := QtPoint(0, 0);
|
||
QWidget_mapFromGlobal(GetContainerWidget, @NewPt, @Pt);
|
||
Result := Point(NewPt.x, NewPt.y);
|
||
end;
|
||
|
||
procedure TQtWidget.move(ANewLeft, ANewTop: Integer);
|
||
begin
|
||
QWidget_move(Widget, ANewLeft, ANewTop);
|
||
end;
|
||
|
||
procedure TQtWidget.preferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean);
|
||
var
|
||
PrefSize: TSize;
|
||
begin
|
||
sizeHint(@PrefSize);
|
||
if (PrefSize.cx >= 0) and (PrefSize.cy >=0) then
|
||
begin
|
||
PreferredWidth := PrefSize.cx;
|
||
PreferredHeight := PrefSize.cy;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtWidget.raiseWidget;
|
||
begin
|
||
QWidget_raise(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.stackUnder(AWidget: QWidgetH);
|
||
begin
|
||
QWidget_stackUnder(Widget, AWidget);
|
||
end;
|
||
|
||
procedure TQtWidget.frame_resize(ANewWidth, ANewHeight: Integer);
|
||
var
|
||
R1, R2: TRect;
|
||
dw, dh: integer;
|
||
begin
|
||
R1 := getGeometry;
|
||
R2 := getFrameGeometry;
|
||
dw := (R1.Left - R2.Left) + (R2.Right - R1.Right);
|
||
dh := (R1.Top - R2.Top) + (R2.Bottom - R1.Bottom);
|
||
QWidget_resize(Widget, ANewWidth - dw, ANewHeight - dh);
|
||
end;
|
||
|
||
procedure TQtWidget.Resize(ANewWidth, ANewHeight: Integer);
|
||
begin
|
||
QWidget_resize(Widget, ANewWidth, ANewHeight);
|
||
end;
|
||
|
||
procedure TQtWidget.releaseMouse;
|
||
var
|
||
AGrabWidget: QWidgetH;
|
||
begin
|
||
// capture widget can be one of children of Widget if Widget is complex control
|
||
// so better to look for current Capture widget to release it
|
||
// instead of pass Widget as argument
|
||
AGrabWidget := QWidget_mouseGrabber();
|
||
//DebugLn(['releasing current grab: ', dbgs(AGrabWidget)]);
|
||
if AGrabWidget <> nil then
|
||
QWidget_releaseMouse(AGrabWidget);
|
||
end;
|
||
|
||
procedure TQtWidget.scroll(dx, dy: integer; ARect: PRect = nil);
|
||
begin
|
||
if ARect = nil then
|
||
QWidget_scroll(getContainerWidget, dx, dy)
|
||
else
|
||
QWidget_scroll(getContainerWidget, dx, dy, ARect);
|
||
end;
|
||
|
||
procedure TQtWidget.setAutoFillBackground(const AValue: Boolean);
|
||
begin
|
||
QWidget_setAutoFillBackground(Widget, AValue);
|
||
end;
|
||
|
||
procedure TQtWidget.setAttribute(const Attr: QtWidgetAttribute;
|
||
const TurnOn: Boolean);
|
||
begin
|
||
QWidget_setAttribute(Widget, Attr, TurnOn);
|
||
end;
|
||
|
||
procedure TQtWidget.setBackgroundRole(const ARole: QPaletteColorRole);
|
||
begin
|
||
QWidget_setBackgroundRole(Widget, ARole);
|
||
end;
|
||
|
||
procedure TQtWidget.setDefaultColor(const DefaultColorType: TDefaultColorType);
|
||
begin
|
||
case DefaultColorType of
|
||
dctBrush: setColor(@Palette.DefaultColor);
|
||
dctFont: setTextColor(@Palette.DefaultTextColor);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtWidget.setEnabled(p1: Boolean);
|
||
begin
|
||
if not p1 and (HWND(Self) = GetCapture) then
|
||
ReleaseCapture;
|
||
QWidget_setEnabled(Widget, p1);
|
||
end;
|
||
|
||
procedure TQtWidget.setFocus;
|
||
begin
|
||
if getFocusPolicy <> QtNoFocus then
|
||
QWidget_setFocus(Widget, QtTabFocusReason)
|
||
else
|
||
QWidget_setFocus(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.setFocusPolicy(const APolicy: QtFocusPolicy);
|
||
begin
|
||
QWidget_setFocusPolicy(Widget, APolicy);
|
||
end;
|
||
|
||
procedure TQtWidget.setFocusProxy(const AWidget: QWidgetH);
|
||
begin
|
||
QWidget_setFocusProxy(Widget, AWidget);
|
||
end;
|
||
|
||
procedure TQtWidget.setFont(AFont: QFontH);
|
||
begin
|
||
QWidget_setFont(Widget, AFont);
|
||
end;
|
||
|
||
procedure TQtWidget.setGeometry(ARect: TRect);
|
||
begin
|
||
QWidget_setGeometry(Widget, @ARect);
|
||
end;
|
||
|
||
procedure TQtWidget.setInitialFontColor(AControl: TWinControl);
|
||
var
|
||
QColor: TQColor;
|
||
ColorRef: TColorRef;
|
||
begin
|
||
if AControl.Font.Color = clDefault then
|
||
begin
|
||
BeginUpdate;
|
||
Palette.ForceColor := True;
|
||
SetDefaultColor(dctFont);
|
||
Palette.ForceColor := False;
|
||
EndUpdate;
|
||
end
|
||
else
|
||
begin
|
||
ColorRef := ColorToRGB(AControl.Font.Color);
|
||
QColor_fromRgb(@QColor,Red(ColorRef),Green(ColorRef),Blue(ColorRef));
|
||
BeginUpdate;
|
||
Palette.ForceColor := True;
|
||
SetTextColor(@QColor);
|
||
Palette.ForceColor := False;
|
||
EndUpdate;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtWidget.setLayoutDirection(ADirection: QtLayoutDirection);
|
||
begin
|
||
QWidget_setLayoutDirection(Widget, ADirection);
|
||
end;
|
||
|
||
procedure TQtWidget.setMaximumSize(AWidth, AHeight: Integer);
|
||
begin
|
||
QWidget_setMaximumSize(Widget, AWidth, AHeight);
|
||
end;
|
||
|
||
procedure TQtWidget.setMask(AMask: QBitmapH);
|
||
begin
|
||
QWidget_setMask(Widget, AMask);
|
||
end;
|
||
|
||
procedure TQtWidget.setMask(AMask: QRegionH);
|
||
begin
|
||
QWidget_setMask(Widget, AMask);
|
||
end;
|
||
|
||
procedure TQtWidget.setMinimumSize(AWidth, AHeight: Integer);
|
||
begin
|
||
QWidget_setMinimumSize(Widget, AWidth, AHeight);
|
||
end;
|
||
|
||
procedure TQtWidget.setVisible(AVisible: Boolean);
|
||
begin
|
||
QWidget_setVisible(Widget, AVisible);
|
||
end;
|
||
|
||
function TQtWidget.windowModality: QtWindowModality;
|
||
begin
|
||
Result := QWidget_windowModality(Widget);
|
||
end;
|
||
|
||
function TQtWidget.grabWindow(const X, Y, Width, Height: integer; AWidget: QWidgetH): QPixmapH;
|
||
var
|
||
AWidgetID: PtrUInt;
|
||
AWindow: QWindowH;
|
||
AScreen: QScreenH;
|
||
begin
|
||
if AWidget = nil then
|
||
AWidget := Widget;
|
||
if (Width > 0) and (Height > 0) then
|
||
Result := QPixmap_create(Width, Height)
|
||
else
|
||
Result := QPixmap_create();
|
||
AWidgetID := QWidget_winId(AWidget);
|
||
AWindow := QWidget_windowHandle(AWidget);
|
||
if AWindow <> nil then
|
||
AScreen := QWindow_screen(AWindow)
|
||
else
|
||
AScreen := QGuiApplication_primaryScreen();
|
||
|
||
if (Width > 0) and (Height > 0) then
|
||
QScreen_grabWindow(AScreen, Result, AWidgetID, X, Y, Width, Height)
|
||
else
|
||
QScreen_grabWindow(AScreen, Result, AWidgetID, X, Y);
|
||
end;
|
||
|
||
procedure TQtWidget.setWindowModality(windowModality: QtWindowModality);
|
||
begin
|
||
QWidget_setWindowModality(Widget, windowModality);
|
||
end;
|
||
|
||
procedure TQtWidget.setWindowOpacity(opacity: double);
|
||
begin
|
||
QWidget_setWindowOpacity(Widget, opacity);
|
||
end;
|
||
|
||
procedure TQtWidget.setParent(parent: QWidgetH);
|
||
begin
|
||
QWidget_setParent(Widget, parent);
|
||
end;
|
||
|
||
procedure TQtWidget.setText(const W: WideString);
|
||
begin
|
||
FText := W;
|
||
end;
|
||
|
||
procedure TQtWidget.setWindowFlags(_type: QtWindowFlags);
|
||
begin
|
||
QWidget_setWindowFlags(Widget, _type);
|
||
end;
|
||
|
||
procedure TQtWidget.setWindowIcon(AIcon: QIconH);
|
||
var
|
||
DestroyIcon: Boolean;
|
||
begin
|
||
DestroyIcon := AIcon = nil;
|
||
if DestroyIcon then
|
||
AIcon := QIcon_create();
|
||
QWidget_setWindowIcon(Widget, AIcon);
|
||
if DestroyIcon then
|
||
QIcon_destroy(AIcon);
|
||
end;
|
||
|
||
function TQtWidget.windowFlags: QtWindowFlags;
|
||
begin
|
||
Result := QWidget_windowFlags(Widget);
|
||
end;
|
||
|
||
procedure TQtWidget.setWidth(p1: Integer);
|
||
var
|
||
R: TRect;
|
||
begin
|
||
R := getGeometry;
|
||
R.Right := R.Left + p1;
|
||
setGeometry(R);
|
||
end;
|
||
|
||
procedure TQtWidget.setHeight(p1: Integer);
|
||
var
|
||
R: TRect;
|
||
begin
|
||
R := getGeometry;
|
||
R.Bottom := R.Top + p1;
|
||
setGeometry(R);
|
||
end;
|
||
|
||
procedure TQtWidget.setUpdatesEnabled(const AEnabled: Boolean);
|
||
begin
|
||
QWidget_setUpdatesEnabled(Widget, AEnabled);
|
||
end;
|
||
|
||
procedure TQtWidget.setWindowState(AState: QtWindowStates);
|
||
begin
|
||
QWidget_setWindowState(Widget, AState);
|
||
end;
|
||
|
||
procedure TQtWidget.sizeHint(size: PSize);
|
||
begin
|
||
QWidget_sizeHint(Widget, size);
|
||
end;
|
||
|
||
function TQtWidget.testAttribute(const AAttribute: QtWidgetAttribute): boolean;
|
||
begin
|
||
Result := QWidget_testAttribute(Widget, AAttribute);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.QtKeyToLCLKey
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.QtKeyToLCLKey(AKey: Integer; AText: WideString;
|
||
AEvent: QKeyEventH): Word;
|
||
begin
|
||
// The big problem here with unicode keys
|
||
// Example: for Russian letter A qt returns AKey = $0410 and this is
|
||
// absolutely correct: 0400 - 04FF - is russian unicode space and
|
||
// 0410 is defined as "CYRILLIC CAPITAL LETTER A"
|
||
|
||
Result := VK_UNKNOWN;
|
||
case AKey of
|
||
QtKey_0..QtKey_9: Result := VK_0 + (AKey - QtKey_0);
|
||
QtKey_At: Result := VK_2; // some bug, but Ctrl + Shit + 2 produce QtKey_At
|
||
QtKey_Escape: Result := VK_ESCAPE;
|
||
QtKey_Tab: Result := VK_TAB;
|
||
QtKey_Backtab: Result := VK_TAB; // ???
|
||
QtKey_Backspace: Result := VK_BACK;
|
||
QtKey_Return: Result := VK_RETURN;
|
||
QtKey_Enter: Result := VK_RETURN;
|
||
QtKey_Insert: Result := VK_INSERT;
|
||
QtKey_Delete: Result := VK_DELETE;
|
||
QtKey_Pause: Result := VK_PAUSE;
|
||
QtKey_Print: Result := VK_PRINT;
|
||
QtKey_SysReq: Result := VK_UNKNOWN; // ???
|
||
QtKey_Clear: Result := VK_CLEAR;
|
||
QtKey_Home: Result := VK_HOME;
|
||
QtKey_End: Result := VK_END;
|
||
QtKey_Left: Result := VK_LEFT;
|
||
QtKey_Up: Result := VK_UP;
|
||
QtKey_Right: Result := VK_RIGHT;
|
||
QtKey_Down: Result := VK_DOWN;
|
||
QtKey_PageUp: Result := VK_PRIOR;
|
||
QtKey_PageDown: Result := VK_NEXT;
|
||
QtKey_Shift: Result := VK_SHIFT; // There is also RSHIFT
|
||
QtKey_Control: Result := VK_CONTROL; // There is also RCONTROL
|
||
QtKey_Meta:
|
||
begin
|
||
//TODO: Qt sends meta key, but info about left & right is in nativeScanCode
|
||
{$IFDEF HASX11}
|
||
if QKeyEvent_nativeVirtualKey(AEvent) = XK_Super_L then
|
||
Result := VK_LWIN
|
||
else
|
||
if QKeyEvent_nativeVirtualKey(AEvent) = XK_Super_R then
|
||
Result := VK_RWIN
|
||
else
|
||
Result := VK_MENU;
|
||
{$ELSE}
|
||
Result := VK_LWIN;
|
||
{$ENDIF}
|
||
end;
|
||
QtKey_Alt: Result := VK_MENU;
|
||
QtKey_AltGr: Result := VK_RMENU;
|
||
QtKey_CapsLock: Result := VK_CAPITAL;
|
||
QtKey_NumLock: Result := VK_NUMLOCK;
|
||
QtKey_ScrollLock: Result := VK_SCROLL;
|
||
QtKey_F1..QtKey_F24: Result := VK_F1 + (AKey - QtKey_F1);
|
||
QtKey_F25..
|
||
QtKey_F35: Result := VK_UNKNOWN;
|
||
QtKey_Super_L: Result := VK_LWIN;
|
||
QtKey_Super_R: Result := VK_RWIN;
|
||
QtKey_Menu: Result := VK_APPS;
|
||
QtKey_Hyper_L,
|
||
QtKey_Hyper_R: Result := VK_UNKNOWN;
|
||
QtKey_Help: Result := VK_HELP;
|
||
QtKey_Direction_L,
|
||
QtKey_Direction_R,
|
||
QtKey_Exclam,QtKey_NumberSign..
|
||
QtKey_AmperSand,
|
||
QtKey_ParenLeft,
|
||
QtKey_ParenRight: Result := VK_UNKNOWN;
|
||
QtKey_Asterisk: Result := VK_MULTIPLY;
|
||
QtKey_Plus: Result := VK_ADD;
|
||
QtKey_Comma: Result := VK_SEPARATOR;
|
||
QtKey_Minus: Result := VK_SUBTRACT;
|
||
QtKey_Period: Result := VK_DECIMAL;
|
||
QtKey_Slash: Result := VK_DIVIDE;
|
||
QtKey_Equal: Result := VK_OEM_PLUS;
|
||
|
||
QtKey_Colon,
|
||
QtKey_Semicolon: Result := VK_OEM_1;
|
||
QtKey_AsciiTilde: Result := VK_OEM_3;
|
||
QtKey_BraceLeft,
|
||
QtKey_BracketLeft: Result := VK_OEM_4;
|
||
QtKey_BackSlash: Result := VK_OEM_5;
|
||
QtKey_BraceRight,
|
||
QtKey_BracketRight: Result := VK_OEM_6;
|
||
QtKey_QuoteDbl,
|
||
QtKey_Apostrophe: Result := VK_OEM_7;
|
||
QtKey_Less: Result := VK_OEM_COMMA;
|
||
QtKey_Greater: Result := VK_OEM_PERIOD;
|
||
|
||
QtKey_ydiaeresis,
|
||
QtKey_Multi_key..
|
||
QtKey_No: Result := VK_UNKNOWN;
|
||
QtKey_Cancel: Result := VK_CANCEL;
|
||
QtKey_Printer: Result := VK_PRINT;
|
||
QtKey_Execute: Result := VK_EXECUTE;
|
||
QtKey_Sleep: Result := VK_SLEEP;
|
||
QtKey_Play: Result := VK_PLAY;
|
||
QtKey_Zoom: Result := VK_ZOOM;
|
||
QtKey_Context1..
|
||
QtKey_Flip,
|
||
QtKey_unknown: Result := VK_UNKNOWN;
|
||
else
|
||
if AKey in [0..255] then // Qt:AKey = VK_KEY in many cases
|
||
Result := AKey
|
||
else
|
||
if AText <> '' then
|
||
begin
|
||
// use QChar to understand whether we have unicode letter or number here or no
|
||
// then try to map that char to VK_ code
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtWidget.SetLastCaretPos(const AValue: TQtPoint);
|
||
begin
|
||
FLastCaretPos := AValue;
|
||
end;
|
||
|
||
procedure TQtWidget.SetHasCaret(const AValue: Boolean);
|
||
begin
|
||
FHasCaret := AValue;
|
||
end;
|
||
|
||
function TQtWidget.ProcessArrowKeys: Boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
class procedure TQtWidget.removeProperty(AObject: QObjectH; APropName: PAnsiChar);
|
||
var
|
||
AVariant: QVariantH;
|
||
begin
|
||
AVariant := QVariant_create;
|
||
QObject_setProperty(AObject, APropName, AVariant);
|
||
QVariant_destroy(AVariant);
|
||
end;
|
||
|
||
class procedure TQtWidget.setProperty(AObject: QObjectH; APropName: PAnsiChar; APropValue: Int64);
|
||
var
|
||
AVariant: QVariantH;
|
||
begin
|
||
AVariant := QVariant_create(APropValue);
|
||
QObject_setProperty(AObject, APropName, AVariant);
|
||
QVariant_destroy(AVariant);
|
||
end;
|
||
|
||
function TQtWidget.LCLKeyToQtKey(AKey: Word): Integer;
|
||
const
|
||
VKKeyToQtKeyMap: array[0..255] of Integer = // Keyboard mapping table
|
||
(
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_Cancel,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_Backspace,
|
||
QtKey_Tab,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_Clear,
|
||
QtKey_Return,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_Shift,
|
||
QtKey_Control,
|
||
QtKey_Alt,
|
||
QtKey_Pause,
|
||
QtKey_CapsLock,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_Escape,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_Mode_switch,
|
||
QtKey_Space,
|
||
QtKey_PageUp,
|
||
QtKey_PageDown,
|
||
QtKey_End,
|
||
QtKey_Home,
|
||
QtKey_Left,
|
||
QtKey_Up,
|
||
QtKey_Right,
|
||
QtKey_Down,
|
||
QtKey_Select,
|
||
QtKey_Printer,
|
||
QtKey_Execute,
|
||
QtKey_Print,
|
||
QtKey_Insert,
|
||
QtKey_Delete,
|
||
QtKey_Help,
|
||
QtKey_0,
|
||
QtKey_1,
|
||
QtKey_2,
|
||
QtKey_3,
|
||
QtKey_4,
|
||
QtKey_5,
|
||
QtKey_6,
|
||
QtKey_7,
|
||
QtKey_8,
|
||
QtKey_9,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_A,
|
||
QtKey_B,
|
||
QtKey_C,
|
||
QtKey_D,
|
||
QtKey_E,
|
||
QtKey_F,
|
||
QtKey_G,
|
||
QtKey_H,
|
||
QtKey_I,
|
||
QtKey_J,
|
||
QtKey_K,
|
||
QtKey_L,
|
||
QtKey_M,
|
||
QtKey_N,
|
||
QtKey_O,
|
||
QtKey_P,
|
||
QtKey_Q,
|
||
QtKey_R,
|
||
QtKey_S,
|
||
QtKey_T,
|
||
QtKey_U,
|
||
QtKey_V,
|
||
QtKey_W,
|
||
QtKey_X,
|
||
QtKey_Y,
|
||
QtKey_Z,
|
||
QtKey_Meta,
|
||
QtKey_Meta,
|
||
QtKey_Menu,
|
||
QtKey_unknown,
|
||
QtKey_Sleep,
|
||
QtKey_0,
|
||
QtKey_1,
|
||
QtKey_2,
|
||
QtKey_3,
|
||
QtKey_4,
|
||
QtKey_5,
|
||
QtKey_6,
|
||
QtKey_7,
|
||
QtKey_8,
|
||
QtKey_9,
|
||
QtKey_Asterisk,
|
||
QtKey_Plus,
|
||
QtKey_Comma,
|
||
QtKey_Minus,
|
||
QtKey_Period,
|
||
QtKey_Slash,
|
||
QtKey_F1,
|
||
QtKey_F2,
|
||
QtKey_F3,
|
||
QtKey_F4,
|
||
QtKey_F5,
|
||
QtKey_F6,
|
||
QtKey_F7,
|
||
QtKey_F8,
|
||
QtKey_F9,
|
||
QtKey_F10,
|
||
QtKey_F11,
|
||
QtKey_F12,
|
||
QtKey_F13,
|
||
QtKey_F14,
|
||
QtKey_F15,
|
||
QtKey_F16,
|
||
QtKey_F17,
|
||
QtKey_F18,
|
||
QtKey_F19,
|
||
QtKey_F20,
|
||
QtKey_F21,
|
||
QtKey_F22,
|
||
QtKey_F23,
|
||
QtKey_F24,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_NumLock,
|
||
QtKey_ScrollLock,
|
||
QtKey_unknown,
|
||
QtKey_Massyo,
|
||
QtKey_Touroku,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_Shift,
|
||
QtKey_Shift,
|
||
QtKey_Control,
|
||
QtKey_Control,
|
||
QtKey_Alt,
|
||
QtKey_Alt,
|
||
QtKey_Back,
|
||
QtKey_Forward,
|
||
QtKey_Refresh,
|
||
QtKey_Stop,
|
||
QtKey_Search,
|
||
QtKey_Favorites,
|
||
QtKey_HomePage,
|
||
QtKey_VolumeMute,
|
||
QtKey_VolumeDown,
|
||
QtKey_VolumeUp,
|
||
QtKey_MediaNext,
|
||
QtKey_MediaPrevious,
|
||
QtKey_MediaStop,
|
||
QtKey_MediaPlay,
|
||
QtKey_LaunchMail,
|
||
QtKey_LaunchMedia,
|
||
QtKey_Launch0,
|
||
QtKey_Launch1,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_1,
|
||
QtKey_Plus,
|
||
QtKey_Comma,
|
||
QtKey_Minus,
|
||
QtKey_Period,
|
||
QtKey_2,
|
||
QtKey_3,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_4,
|
||
QtKey_5,
|
||
QtKey_6,
|
||
QtKey_7,
|
||
QtKey_8,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_Play,
|
||
QtKey_Zoom,
|
||
QtKey_unknown,
|
||
QtKey_unknown,
|
||
QtKey_Clear,
|
||
QtKey_unknown
|
||
);
|
||
begin
|
||
if AKey > 255 then
|
||
Result := QtKey_unknown
|
||
else
|
||
Result := VKKeyToQtKeyMap[AKey];
|
||
end;
|
||
|
||
function TQtWidget.ShiftStateToQtModifiers(Shift: TShiftState): QtModifier;
|
||
begin
|
||
Result := 0;
|
||
if ssCtrl in Shift then inc(Result, QtCTRL);
|
||
if ssShift in Shift then Inc(Result, QtSHIFT);
|
||
if ssMeta in Shift then Inc(Result, QtMETA);
|
||
if ssAlt in Shift then Inc(Result, QtALT);
|
||
end;
|
||
|
||
function TQtWidget.QueryInterface(constref iid: TGuid; out obj): LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||
begin
|
||
if GetInterface(iid, obj) then
|
||
Result := 0
|
||
else
|
||
Result := E_NOINTERFACE;
|
||
end;
|
||
|
||
function TQtWidget._AddRef: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||
begin
|
||
Result := -1; // no ref counting
|
||
end;
|
||
|
||
function TQtWidget._Release: LongInt; {$IFDEF WINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||
begin
|
||
Result := -1;
|
||
end;
|
||
|
||
function TQtWidget.GetProps(const AnIndex: String): pointer;
|
||
var
|
||
i: Integer;
|
||
begin
|
||
if (Fprops<>nil) then
|
||
begin
|
||
i:=Fprops.IndexOf(AnIndex);
|
||
if i>=0 then
|
||
begin
|
||
result:=Fprops.Objects[i];
|
||
exit;
|
||
end;
|
||
end;
|
||
result := nil;
|
||
end;
|
||
|
||
function TQtWidget.getScrolledOffset: TPoint;
|
||
begin
|
||
Result := Point(-FScrollX, -FScrollY);
|
||
end;
|
||
|
||
function TQtWidget.GetStyleSheet: WideString;
|
||
var
|
||
WStr: WideString;
|
||
begin
|
||
QWidget_styleSheet(Widget, @WStr);
|
||
Result := UTF16ToUTF8(WStr);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtWidget.GetPalette
|
||
Params: Nothing
|
||
Returns: TQtWidgetPalette
|
||
|
||
Assigns default widget palette, also takes care of widget colors changing.
|
||
------------------------------------------------------------------------------}
|
||
function TQtWidget.GetPalette: TQtWidgetPalette;
|
||
begin
|
||
if not Assigned(FPalette) then
|
||
begin
|
||
if (ClassType = TQtCustomControl) then
|
||
FPalette := TQtWidgetPalette.Create(WidgetColorRole, TextColorRole,
|
||
TQtCustomControl(Self).viewport.Widget)
|
||
else
|
||
FPalette := TQtWidgetPalette.Create(WidgetColorRole, TextColorRole, Widget);
|
||
end;
|
||
Result := FPalette;
|
||
end;
|
||
|
||
function TQtWidget.GetContext: HDC;
|
||
begin
|
||
Result := FContext;
|
||
end;
|
||
|
||
function TQtWidget.GetWidget: QWidgetH;
|
||
begin
|
||
Result := QWidgetH(TheObject);
|
||
end;
|
||
|
||
function TQtWidget.DeliverMessage(var Msg;
|
||
const AIsInputEvent: Boolean = False): LRESULT;
|
||
var
|
||
AEvent: Cardinal;
|
||
begin
|
||
Result := LRESULT(AIsInputEvent);
|
||
if LCLObject = nil then
|
||
Exit;
|
||
AEvent := TLMessage(Msg).Msg;
|
||
try
|
||
if LCLObject.HandleAllocated then
|
||
begin
|
||
LCLObject.WindowProc(TLMessage(Msg));
|
||
Result := TLMessage(Msg).Result;
|
||
end;
|
||
except
|
||
Result := 1;
|
||
if AIsInputEvent and (LCLObject = nil) and (PtrUInt(Widget) = 0) and
|
||
QtWidgetSet.IsValidHandle(HWND(Self)) then
|
||
begin
|
||
DebugLn(Format('WARNING: %s has been destroyed while processing input event %u result %u',
|
||
[ClassName, AEvent, Result]));
|
||
end else
|
||
Application.HandleException(nil);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtWidget.SetProps(const AnIndex: String; const AValue: pointer);
|
||
var
|
||
i: Integer;
|
||
begin
|
||
if FProps=nil then
|
||
begin
|
||
FProps:=TStringList.Create;
|
||
FProps.Sorted:=true;
|
||
end;
|
||
i := Fprops.IndexOf(AnIndex);
|
||
if i < 0 then
|
||
i := FProps.Add(AnIndex);
|
||
Fprops.Objects[i] := TObject(AValue);
|
||
end;
|
||
|
||
procedure TQtWidget.SetStyleSheet(const AValue: WideString);
|
||
var
|
||
WStr: WideString;
|
||
begin
|
||
WStr := GetUTF8String(AValue);
|
||
QWidget_setStyleSheet(Widget, @WStr);
|
||
end;
|
||
|
||
procedure TQtWidget.SetWidget(const AValue: QWidgetH);
|
||
begin
|
||
TheObject := AValue;
|
||
end;
|
||
|
||
function TQtWidget.CreateWidget(const Params: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
FHasPaint := True;
|
||
|
||
if Params.WndParent <> 0 then
|
||
Parent := TQtWidget(Params.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
|
||
Widget := QWidget_create(Parent);
|
||
Result := Widget;
|
||
end;
|
||
|
||
procedure TQtWidget.DestroyWidget;
|
||
begin
|
||
if (Widget <> nil) and FOwnWidget then
|
||
QObject_deleteLater(Widget);
|
||
Widget := nil;
|
||
end;
|
||
|
||
{ TQtAbstractButton }
|
||
|
||
procedure TQtAbstractButton.setIcon(AIcon: QIconH);
|
||
begin
|
||
QAbstractButton_setIcon(QAbstractButtonH(Widget), AIcon);
|
||
end;
|
||
|
||
procedure TQtAbstractButton.setIconSize(Size: PSize);
|
||
begin
|
||
QAbstractButton_setIconSize(QAbstractButtonH(Widget), Size);
|
||
end;
|
||
|
||
procedure TQtAbstractButton.setShortcut(AShortCutK1, AShortCutK2: TShortcut);
|
||
var
|
||
Key: Word;
|
||
Shift: TShiftState;
|
||
QtK1, QtK2: integer;
|
||
KeySequence: QKeySequenceH;
|
||
begin
|
||
QtK1 := 0;
|
||
QtK2 := 0;
|
||
if AShortCutK1 <> 0 then
|
||
begin
|
||
ShortCutToKey(AShortCutK1, Key, Shift);
|
||
QtK1 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
|
||
if AShortCutK2 <> 0 then
|
||
begin
|
||
ShortCutToKey(AShortCutK2, Key, Shift);
|
||
QtK2 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
|
||
end;
|
||
end;
|
||
KeySequence := QKeySequence_create(QtK1, QtK2);
|
||
QAbstractButton_setShortcut(QAbstractButtonH(Widget), KeySequence);
|
||
QKeySequence_destroy(KeySequence);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractButton.SetText
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractButton.SetText(const W: WideString);
|
||
begin
|
||
QAbstractButton_setText(QAbstractButtonH(Widget), @W);
|
||
end;
|
||
|
||
function TQtAbstractButton.ProcessArrowKeys: Boolean;
|
||
begin
|
||
Result := True;
|
||
end;
|
||
|
||
function TQtAbstractButton.CanPaintBackground: Boolean;
|
||
begin
|
||
Result := CanSendLCLMessage and getEnabled and
|
||
(LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
|
||
// DO NOT REMOVE ! QCheckBox,QRadioButton default = clBackground !
|
||
end;
|
||
|
||
function TQtAbstractButton.getIconSize: TSize;
|
||
begin
|
||
QAbstractButton_iconSize(QAbstractButtonH(Widget), @Result);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractButton.Text
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtAbstractButton.getText: WideString;
|
||
begin
|
||
QAbstractButton_text(QAbstractButtonH(Widget), @Result);
|
||
end;
|
||
|
||
procedure TQtAbstractButton.Toggle;
|
||
begin
|
||
QAbstractButton_toggle(QAbstractButtonH(Widget));
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractButton.isChecked
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtAbstractButton.isChecked: Boolean;
|
||
begin
|
||
Result := QAbstractButton_isChecked(QAbstractButtonH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractButton.isDown: Boolean;
|
||
begin
|
||
Result := QAbstractButton_isDown(QAbstractButtonH(Widget));
|
||
end;
|
||
|
||
procedure TQtAbstractButton.setCheckable(p1: Boolean);
|
||
begin
|
||
QAbstractButton_setCheckable(QAbstractButtonH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractButton.setChecked
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractButton.setChecked(p1: Boolean);
|
||
begin
|
||
QAbstractButton_setChecked(QAbstractButtonH(Widget), p1);
|
||
end;
|
||
|
||
procedure TQtAbstractButton.setDefaultColorRoles;
|
||
begin
|
||
WidgetColorRole := QPaletteButton;
|
||
TextColorRole := QPaletteButtonText;
|
||
end;
|
||
|
||
procedure TQtAbstractButton.setDown(p1: Boolean);
|
||
begin
|
||
QAbstractButton_setDown(QAbstractButtonH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractButton.SignalPressed
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractButton.SignalPressed; cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_KEYDOWN;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractButton.SignalReleased
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractButton.SignalReleased; cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_KEYUP;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractButton.SignalClicked
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractButton.SignalClicked(Checked: Boolean = False); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_CHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractButton.SignalClicked2
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractButton.SignalClicked2; cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_CLICKED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{ TQtPushButton }
|
||
|
||
function TQtPushButton.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QPushButton_create(Parent);
|
||
end;
|
||
|
||
procedure TQtPushButton.preferredSize(var PreferredWidth,
|
||
PreferredHeight: integer; WithThemeSpace: Boolean);
|
||
var
|
||
Size: TSize;
|
||
|
||
function AutoSizeButtonFromStyle(const ASize: TSize): TSize;
|
||
var
|
||
AOpt: QStyleOptionButtonH;
|
||
AText: WideString;
|
||
AMetrics: QFontMetricsH;
|
||
BtnWidth: Integer;
|
||
BtnHeight: Integer;
|
||
AIcon: QIconH;
|
||
IconSize: TSize;
|
||
{style pixel metrics}
|
||
BtnMargin, FocusH, FocusV, ShiftH, ShiftV: Integer;
|
||
begin
|
||
Result := ASize;
|
||
AOpt := QStyleOptionButton_create();
|
||
QStyleOption_initFrom(AOpt, Widget);
|
||
AText := getText;
|
||
QStyleOptionButton_setText(AOpt, @AText);
|
||
AMetrics := QFontMetrics_create(QWidget_font(Widget));
|
||
try
|
||
QStyleOption_fontMetrics(AOpt, AMetrics);
|
||
BtnWidth := QFontMetrics_width(AMetrics, PWideString(@AText));
|
||
BtnHeight := QFontMetrics_height(AMetrics);
|
||
Result.cx := BtnWidth;
|
||
Result.cy := BtnHeight;
|
||
|
||
BtnMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
|
||
FocusV := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
|
||
FocusH := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
|
||
ShiftH := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
|
||
ShiftV := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
|
||
|
||
if ShiftH = 0 then
|
||
ShiftH := FocusH;
|
||
|
||
//writeln('ButtonSizeFromStyle: Metrics W=',BtnWidth,' H=',BtnHeight,
|
||
// ' BtnMargin ',BtnMargin,' FocusV ',FocusV,' FocusH ',FocusH,
|
||
// ' ShiftH ',ShiftH,' ShiftV ',ShiftV);
|
||
|
||
Result.cx := Result.cx + BtnMargin + (FocusH * 2) + (ShiftH * 2);
|
||
Result.cy := Result.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2);
|
||
|
||
// now check if we have icon
|
||
AIcon := QIcon_create();
|
||
try
|
||
QAbstractButton_icon(QPushButtonH(Widget), AIcon);
|
||
if not QIcon_isNull(AIcon) then
|
||
begin
|
||
QAbstractButton_iconSize(QPushButtonH(Widget), @IconSize);
|
||
Result.cx := Result.cx + IconSize.cx + (FocusH * 2) + (ShiftH * 2);
|
||
if IconSize.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2) > Result.cy then
|
||
Result.cy := IconSize.cy + BtnMargin + (FocusV * 2) + (ShiftV * 2);
|
||
end;
|
||
finally
|
||
QIcon_destroy(AIcon);
|
||
end;
|
||
|
||
finally
|
||
QStyleOptionButton_destroy(AOpt);
|
||
QFontMetrics_destroy(AMetrics);
|
||
end;
|
||
end;
|
||
begin
|
||
// qt doesn't return proper autosize for us.QSizePolicy class is missing.
|
||
QPushButton_sizeHint(QPushButtonH(Widget), @Size);
|
||
{qtlcl implementation of buttons autosizing, replace if/when we
|
||
get QSizePolicy class into bindings}
|
||
if Assigned(LCLObject) and LCLObject.AutoSize then
|
||
Size := AutoSizeButtonFromStyle(Size);
|
||
PreferredWidth := Size.cx;
|
||
PreferredHeight := Size.cy;
|
||
end;
|
||
|
||
procedure TQtPushButton.SetDefault(const ADefault: Boolean);
|
||
begin
|
||
QPushButton_setDefault(QPushButtonH(Widget), ADefault);
|
||
end;
|
||
|
||
procedure TQtPushButton.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
FClickedHook := QAbstractButton_hook_create(Widget);
|
||
QAbstractButton_hook_hook_clicked2(FClickedHook, @SlotClicked);
|
||
|
||
FToggledHook := QAbstractButton_hook_create(Widget);
|
||
QAbstractButton_hook_hook_toggled(FToggledHook, @SlotToggled);
|
||
end;
|
||
|
||
procedure TQtPushButton.DetachEvents;
|
||
begin
|
||
if FClickedHook <> nil then
|
||
begin
|
||
QAbstractButton_hook_destroy(FClickedHook);
|
||
FClickedHook := nil;
|
||
end;
|
||
if FToggledHook <> nil then
|
||
begin
|
||
QAbstractButton_hook_destroy(FToggledHook);
|
||
FToggledHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtPushButton.SlotClicked
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtPushButton.SlotClicked; cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), 0);
|
||
Msg.Msg := LM_CLICKED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
procedure TQtPushButton.SlotToggled(AChecked: Boolean); cdecl;
|
||
begin
|
||
// override later (eg. TQtToggleBox)
|
||
end;
|
||
|
||
{ TQtBitBtn }
|
||
|
||
function TQtBitBtn.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
HasPaint := True;
|
||
FGlyphLayout := 0;
|
||
FText := '';
|
||
FIcon := nil;
|
||
FIconSize.cx := 0;
|
||
FIconSize.cy := 0;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QPushButton_create(Parent);
|
||
end;
|
||
|
||
destructor TQtBitBtn.Destroy;
|
||
begin
|
||
if Assigned(FIcon) then
|
||
QIcon_destroy(FIcon);
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function TQtBitBtn.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
|
||
function IconValid: boolean;
|
||
begin
|
||
Result := Assigned(FIcon) and not QIcon_isNull(FIcon) and
|
||
(FIconSize.cx > 0) and (FIconSize.cy > 0);
|
||
end;
|
||
|
||
function PaintBtn: Boolean;
|
||
var
|
||
APainter: QPainterH;
|
||
R: TRect;
|
||
R2: TRect;
|
||
R3: TRect;
|
||
BMargin, HMargin, VMargin, SHorz, SVert: Integer;
|
||
IconMode: QIconMode;
|
||
IconAlign: QtAlignment;
|
||
CenterOffset, W {, H}: Integer;
|
||
AFontMetrics: QFontMetricsH;
|
||
AText: WideString;
|
||
DTFLAGS: DWord;
|
||
ContentSize: TSize;
|
||
IconDistance: Integer;
|
||
IconMargin: Integer;
|
||
begin
|
||
Result := False;
|
||
if (FIcon = nil) then
|
||
exit;
|
||
|
||
// paint button
|
||
QObject_event(Widget, Event);
|
||
|
||
IconDistance := TCustomBitBtn(LCLObject).Spacing;
|
||
if IconDistance < 0 then
|
||
IconDistance := 4; {qt default}
|
||
|
||
IconMargin := TCustomBitBtn(LCLObject).Margin;
|
||
|
||
// now we paint icon & text
|
||
APainter := QPainter_create(QWidget_to_QPaintDevice(Widget));
|
||
{$IFDEF USEQT4COMPATIBILEPAINTER}
|
||
QPainter_setRenderHint(APainter, QPainterQt4CompatiblePainting);
|
||
{$ENDIF}
|
||
AText := FText;
|
||
try
|
||
QPainter_setBackgroundMode(APainter, QtTransparentMode);
|
||
QWidget_rect(Widget, @R);
|
||
|
||
BMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
|
||
VMargin := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
|
||
HMargin := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
|
||
SHorz := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
|
||
SVert := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
|
||
|
||
if SHorz = 0 then
|
||
SHorz := HMargin;
|
||
|
||
if not getEnabled then
|
||
IconMode := QIconDisabled
|
||
else
|
||
if QWidget_underMouse(Widget) then
|
||
IconMode := QIconActive
|
||
else
|
||
IconMode := QIconNormal;
|
||
|
||
inc(R.Left, HMargin + SHorz);
|
||
inc(R.Top, VMargin + SVert);
|
||
dec(R.Right, HMargin + SHorz);
|
||
dec(R.Bottom, VMargin + SVert);
|
||
|
||
W := R.Right - R.Left;
|
||
// H := R.Bottom - R.Top;
|
||
|
||
ContentSize.CX := 0;
|
||
ContentSize.CY := 0;
|
||
R3 := Rect(0, 0, 0, 0);
|
||
|
||
DTFlags := DT_CENTER or DT_VCENTER;
|
||
if IconValid then
|
||
begin
|
||
R2 := R;
|
||
AFontMetrics := QFontMetrics_create(QPainter_font(APainter));
|
||
QPainter_fontMetrics(APainter, AFontMetrics);
|
||
|
||
// QtTextShowMnemonic = $0800
|
||
if FText = '' then
|
||
R3 := Rect(0, 0, 0, 0)
|
||
else
|
||
QFontMetrics_boundingRect(AFontMetrics, PRect(@R3), 0, 0,
|
||
QWidget_width(Widget), QWidget_height(Widget), QtAlignLeft or $0800,
|
||
PWideString(@AText));
|
||
|
||
QFontMetrics_destroy(AFontMetrics);
|
||
|
||
ContentSize.cx := (R3.Right - R3.Left) + FIconSize.cx + IconDistance;
|
||
ContentSize.cy := FIconSize.cy + IconDistance + (R3.Bottom - R3.Top);
|
||
|
||
if FText = '' then
|
||
IconAlign := QtAlignHCenter or QtAlignVCenter
|
||
else
|
||
case GlyphLayout of
|
||
1: // right
|
||
begin
|
||
DTFLAGS := DT_RIGHT or DT_VCENTER;
|
||
dec(R2.Right, BMargin div 2);
|
||
IconAlign := QtAlignRight or QtAlignVCenter;
|
||
dec(R2.Right, FIconSize.cx);
|
||
end;
|
||
2: // top
|
||
begin
|
||
inc(R2.Top, BMargin div 2);
|
||
IconAlign := QtAlignTop or QtAlignHCenter;
|
||
inc(R2.Top, FIconSize.cy);
|
||
end;
|
||
3: // bottom
|
||
begin
|
||
dec(R2.Bottom, BMargin div 2);
|
||
IconAlign := QtAlignBottom or QtAlignHCenter;
|
||
dec(R2.Bottom, FIconSize.cy);
|
||
end;
|
||
else
|
||
begin // left
|
||
DTFLAGS := DT_LEFT or DT_VCENTER;
|
||
inc(R2.Left, BMargin div 2);
|
||
IconAlign := QtAlignLeft or QtAlignVCenter;
|
||
inc(R2.Left, FIconSize.cx);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
if IconValid then
|
||
begin
|
||
if FGlyphLayout in [0, 1] then
|
||
begin
|
||
CenterOffset := ((R.Right - R.Left) div 2) - (ContentSize.cx div 2);
|
||
if W - ContentSize.cx - CenterOffset < 0 then
|
||
CenterOffset := 0;
|
||
end else
|
||
CenterOffset := ((R.Bottom - R.Top) div 2) - (ContentSize.cy div 2);
|
||
|
||
if IconMargin >= 0 then
|
||
CenterOffset := IconMargin;
|
||
|
||
if FText <> '' then
|
||
begin
|
||
if FGlyphLayout = 0 then
|
||
inc(R.Left, CenterOffset)
|
||
else
|
||
if FGlyphLayout = 1 then
|
||
dec(R.Right, CenterOffset)
|
||
else
|
||
if FGlyphLayout = 2 then
|
||
inc(R.Top, CenterOffset)
|
||
else
|
||
if FGlyphLayout = 3 then
|
||
dec(R.Bottom, CenterOffset);
|
||
end;
|
||
|
||
QIcon_paint(FIcon, APainter, @R, IconAlign, IconMode);
|
||
|
||
R := R2;
|
||
if FGlyphLayout = 0 then
|
||
inc(R.Left, CenterOffset + IconDistance)
|
||
else
|
||
if FGlyphLayout = 1 then
|
||
dec(R.Right, CenterOffset + IconDistance)
|
||
else
|
||
if FGlyphLayout = 2 then
|
||
inc(R.Top, CenterOffset + IconDistance)
|
||
else
|
||
if FGlyphLayout = 3 then
|
||
dec(R.Bottom, CenterOffset + IconDistance);
|
||
end;
|
||
|
||
if AText <> '' then
|
||
QPainter_drawText(APainter, R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
|
||
DTFlagsToQtFlags(DTFLAGS), @AText);
|
||
|
||
QPainter_end(APainter);
|
||
Result := True;
|
||
finally
|
||
QPainter_destroy(APainter);
|
||
end;
|
||
end;
|
||
begin
|
||
Result := False;
|
||
if (LCLObject <> nil) and (QEvent_type(Event) = QEventPaint) and (FContext = 0) then
|
||
Result := PaintBtn
|
||
else
|
||
Result:=inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
procedure TQtBitBtn.preferredSize(var PreferredWidth, PreferredHeight: integer;
|
||
WithThemeSpace: Boolean);
|
||
const
|
||
IconDistance = 4; // hardcoded in qt libs
|
||
var
|
||
AOpt: QStyleOptionButtonH;
|
||
AText: WideString;
|
||
AMetrics: QFontMetricsH;
|
||
TextSize: TSize;
|
||
{style pixel metrics}
|
||
BtnMargin, FocusH, FocusV, ShiftH, ShiftV, fsh, fsvm: Integer;
|
||
begin
|
||
AOpt := QStyleOptionButton_create();
|
||
QStyleOption_initFrom(AOpt, Widget);
|
||
AText := getText;
|
||
QStyleOptionButton_setText(AOpt, @AText);
|
||
AMetrics := QFontMetrics_create(QWidget_font(Widget));
|
||
try
|
||
QStyleOption_fontMetrics(AOpt, AMetrics);
|
||
|
||
// QtTextShowMnemonic = $0800
|
||
if AText <> '' then
|
||
QFontMetrics_size(AMetrics, PSize(@TextSize),
|
||
QtAlignLeft or $0800, PWideString(@AText))
|
||
else
|
||
TextSize := Size(0, 0);
|
||
BtnMargin := GetPixelMetric(QStylePM_ButtonMargin, nil, Widget);
|
||
FocusV := GetPixelMetric(QStylePM_FocusFrameVMargin, nil, Widget);
|
||
FocusH := GetPixelMetric(QStylePM_FocusFrameHMargin, nil, Widget);
|
||
ShiftH := GetPixelMetric(QStylePM_ButtonShiftHorizontal, nil, Widget);
|
||
ShiftV := GetPixelMetric(QStylePM_ButtonShiftVertical, nil, Widget);
|
||
if ShiftH = 0 then
|
||
ShiftH := FocusH;
|
||
fsh := (FocusH * 2) + (ShiftH * 2);
|
||
fsvm := (FocusV * 2) + (ShiftV * 2) + BtnMargin;
|
||
PreferredWidth := TextSize.cx + fsh + BtnMargin;
|
||
PreferredHeight := TextSize.cy + fsvm;
|
||
|
||
// now check if we have icon
|
||
if Assigned(FIcon) and not QIcon_isNull(FIcon) then
|
||
begin
|
||
Inc(PreferredWidth, FIconSize.cx + fsh);
|
||
if FIconSize.cy + fsvm > PreferredHeight then
|
||
PreferredHeight := FIconSize.cy + fsvm;
|
||
if FText <> '' then
|
||
begin
|
||
if FGlyphLayout in [2, 3] then
|
||
Inc(PreferredHeight, TextSize.cy + IconDistance)
|
||
else
|
||
Inc(PreferredWidth, IconDistance);
|
||
end;
|
||
end;
|
||
|
||
if ShiftV = 0 then
|
||
Inc(PreferredHeight, 1);
|
||
finally
|
||
QStyleOptionButton_destroy(AOpt);
|
||
QFontMetrics_destroy(AMetrics);
|
||
end;
|
||
end;
|
||
|
||
function TQtBitBtn.getIconSize: TSize;
|
||
begin
|
||
Result := FIconSize;
|
||
end;
|
||
|
||
function TQtBitBtn.getText: WideString;
|
||
begin
|
||
Result := FText;
|
||
end;
|
||
|
||
procedure TQtBitBtn.setIcon(AIcon: QIconH);
|
||
begin
|
||
if Assigned(FIcon) then
|
||
begin
|
||
QIcon_destroy(FIcon);
|
||
FIcon := nil;
|
||
end;
|
||
FIcon := QIcon_create(AIcon);
|
||
if getVisible then
|
||
Update(nil);
|
||
end;
|
||
|
||
procedure TQtBitBtn.setIconSize(Size: PSize);
|
||
begin
|
||
FIconSize.cx := 0;
|
||
FIconSize.cy := 0;
|
||
if Size <> nil then
|
||
FIconSize := Size^;
|
||
if getVisible then
|
||
Update(nil);
|
||
end;
|
||
|
||
procedure TQtBitBtn.setText(const W: WideString);
|
||
begin
|
||
FText := W;
|
||
if getVisible then
|
||
Update(nil);
|
||
end;
|
||
|
||
{ TQtToggleBox }
|
||
|
||
procedure TQtToggleBox.SlotClicked; cdecl;
|
||
begin
|
||
// do nothing with ToggleBox
|
||
end;
|
||
|
||
procedure TQtToggleBox.SlotToggled(AChecked: Boolean); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
if InUpdate then
|
||
exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_CHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
|
||
{ TQtMDIArea }
|
||
|
||
procedure TQtMDIArea.SubWindowActivated(AWindow: QMDISubWindowH); cdecl;
|
||
var
|
||
ActiveChild: TQtMainWindow;
|
||
H: HWND;
|
||
W: QWidgetH;
|
||
WW: TQtWidget;
|
||
begin
|
||
{we must fix qt bugs here. QWidget_focusWidget() is lost when
|
||
activating mdichild via BringToFront (eg from menu)}
|
||
if AWindow <> nil then
|
||
begin
|
||
H := HwndFromWidgetH(AWindow);
|
||
if H <> 0 then
|
||
ActiveChild := TQtMainWindow(H)
|
||
else
|
||
ActiveChild := nil;
|
||
|
||
if ActiveChild = nil then
|
||
exit;
|
||
|
||
W := QWidget_focusWidget(AWindow);
|
||
if (W <> nil) and (W <> AWindow) then
|
||
begin
|
||
H := HwndFromWidgetH(W);
|
||
if H <> 0 then
|
||
begin
|
||
WW := TQtWidget(H);
|
||
{$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
|
||
writeln('TQtMDIArea.SubWindowActivated: *=* Current focus widget ',dbgsName(WW.LCLObject));
|
||
{$ENDIF}
|
||
{trigger QMDIArea to update it's focusWidget (it could be nil) }
|
||
QWidget_setFocus(WW.Widget, QtActiveWindowFocusReason);
|
||
end;
|
||
end else
|
||
begin
|
||
// fallback when qt completely looses it's mind about focusWidget() inside
|
||
// mdi form.
|
||
{$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
|
||
writeln('TQtMDIArea.SubWindowActivated: fallback - ask TCustomForm.ActiveControl ',
|
||
dbgsName(TCustomForm(ActiveChild.LCLObject).ActiveControl));
|
||
{$ENDIF}
|
||
if Assigned(ActiveChild.LCLObject) and
|
||
Assigned(TCustomForm(ActiveChild.LCLObject).ActiveControl) and
|
||
TCustomForm(ActiveChild.LCLObject).ActiveControl.HandleAllocated then
|
||
begin
|
||
WW := TQtWidget(TCustomForm(ActiveChild.LCLObject).ActiveControl.Handle);
|
||
{$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)}
|
||
writeln('**** SUCCESSFULLY ACTIVATED FOCUS PATCH ****');
|
||
{$ENDIF}
|
||
QWidget_setFocus(WW.Widget, QtActiveWindowFocusReason);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
constructor TQtMDIArea.Create(const AParent: QWidgetH);
|
||
begin
|
||
Create;
|
||
Widget := QMdiArea_create(AParent);
|
||
FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
|
||
FWidgetLCLFont := nil;
|
||
Palette.ForceColor := True;
|
||
setDefaultColor(dctFont);
|
||
Palette.ForceColor := False;
|
||
FSubWindowActivationHook := QMdiArea_hook_create(Widget);
|
||
QMdiArea_hook_hook_subWindowActivated(FSubWindowActivationHook, @SubWindowActivated);
|
||
QWidget_setMouseTracking(Widget, True);
|
||
FillChar(FPaintData, sizeOf(FPaintData), 0);
|
||
setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
|
||
setProperty(viewportWidget, 'lclwidget', Int64(PtrUInt(Self)));
|
||
QtWidgetSet.AddHandle(Self);
|
||
end;
|
||
|
||
destructor TQtMDIArea.Destroy;
|
||
begin
|
||
if FSubWindowActivationHook <> nil then
|
||
begin
|
||
QMdiArea_hook_destroy(FSubWindowActivationHook);
|
||
FSubWindowActivationHook := nil;
|
||
end;
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function TQtMDIArea.getClientOffset: TPoint;
|
||
begin
|
||
if Assigned(FOwner) then
|
||
Result := FOwner.getClientOffset
|
||
else
|
||
Result := inherited getClientOffset;
|
||
end;
|
||
|
||
procedure TQtMDIArea.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FViewPortEventHook := QObject_hook_create(QAbstractScrollArea_viewport(QAbstractScrollAreaH(Widget)));
|
||
QObject_hook_hook_events(FViewPortEventHook, @ScrollViewEventFilter);
|
||
end;
|
||
|
||
procedure TQtMDIArea.DetachEvents;
|
||
begin
|
||
if Assigned(FViewPortEventHook) then
|
||
begin
|
||
QObject_hook_destroy(FViewPortEventHook);
|
||
FViewPortEventHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtMDIArea.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
case QEvent_type(Event) of
|
||
QEventPaint: ;
|
||
QEventMouseButtonPress, QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick: ;
|
||
QEventMouseMove, QEventWheel: ;
|
||
QEventEnter,
|
||
QEventLeave: Result := SlotMouseEnter(Sender, Event);
|
||
else
|
||
Result:=inherited EventFilter(Sender, Event);
|
||
end;
|
||
end;
|
||
|
||
function TQtMDIArea.ScrollViewEventFilter(Sender: QObjectH; Event: QEventH
|
||
): boolean; cdecl;
|
||
var
|
||
R: TRect;
|
||
Brush: QBrushH;
|
||
Color: TQColor;
|
||
Painter: QPainterH;
|
||
APoint, APos, AOldPos, ANewPos, AGlobalPos: TQtPoint;
|
||
APosF, AGlobalPosF: TQtPointF;
|
||
AEvent: QEventH;
|
||
APaintEvent: QPaintEventH;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
case QEvent_type(Event) of
|
||
QEventMouseButtonPress, QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick:
|
||
begin
|
||
// new event with parent coordinates
|
||
QMouseEvent_pos(QMouseEventH(Event), @APos);
|
||
QWidget_mapToParent(Widget, @APoint, @APos);
|
||
APosF.x := APoint.X;
|
||
APosF.y := APoint.y;
|
||
QMouseEvent_globalPos(QMouseEventH(Event), @AGlobalPos);
|
||
AGlobalPosF.X := AGlobalPos.X;
|
||
AGlobalPosF.Y := AGlobalPos.Y;
|
||
AEvent := QMouseEvent_create(QEvent_type(Event), @APosF, @AGlobalPosF,
|
||
QMouseEvent_button(QMouseEventH(Event)), QMouseEvent_buttons(QMouseEventH(Event)), QInputEvent_modifiers(QInputEventH(Event)));
|
||
try
|
||
Result := SlotMouse(Sender, AEvent);
|
||
finally
|
||
QEvent_destroy(AEvent);
|
||
end;
|
||
end;
|
||
QEventMouseMove:
|
||
begin
|
||
QMouseEvent_globalPos(QMouseEventH(Event), @AGlobalPos);
|
||
QMouseEvent_pos(QMouseEventH(Event), @APos);
|
||
QWidget_mapToParent(Widget, @APoint, @APos);
|
||
APosF.x := APoint.X;
|
||
APosF.y := APoint.y;
|
||
AGlobalPosF.X := AGlobalPos.X;
|
||
AGlobalPosF.Y := AGlobalPos.Y;
|
||
AEvent := QMouseEvent_create(QEvent_type(Event), @APosF, @AGlobalPosF,
|
||
QMouseEvent_button(QMouseEventH(Event)), QMouseEvent_buttons(QMouseEventH(Event)), QInputEvent_modifiers(QInputEventH(Event)));
|
||
try
|
||
Result := SlotMouseMove(Sender, AEvent);
|
||
finally
|
||
QEvent_destroy(AEvent);
|
||
end;
|
||
end;
|
||
|
||
QEventWheel:
|
||
begin
|
||
// APos :=
|
||
QWheelEvent_pos(QWheelEventH(Event), @APos);
|
||
QWidget_mapToParent(Widget, @APoint, @APos);
|
||
APosF.X := APoint.X;
|
||
APosF.Y := APoint.Y;
|
||
AEvent := QWheelEvent_create(@APosF, QWheelEvent_delta(QWheelEventH(Event)), QWheelEvent_buttons(QWheelEventH(Event)),
|
||
QInputEvent_modifiers(QInputEventH(Event)), QWheelEvent_orientation(QWheelEventH(Event)));
|
||
try
|
||
Result := SlotMouseWheel(Sender, AEvent);
|
||
finally
|
||
QEvent_destroy(AEvent);
|
||
end;
|
||
end;
|
||
|
||
QEventEnter,
|
||
QEventLeave: Result := SlotMouseEnter(Sender, Event);
|
||
QEventHoverEnter,
|
||
QEventHoverLeave,
|
||
QEventHoverMove:
|
||
begin
|
||
// APos :=
|
||
QHoverEvent_pos(QHoverEventH(Event), @APos);
|
||
QHoverEvent_oldPos(QHoverEventH(Event), @AOldPos);
|
||
QWidget_mapToParent(Widget, @APoint, @APos);
|
||
QWidget_mapToParent(Widget, @ANewPos, @AOldPos);
|
||
APosF.X := APoint.X;
|
||
APosF.Y := APoint.Y;
|
||
AGlobalPosF.X := ANewPos.X;
|
||
AGlobalPosF.Y := ANewPos.Y;
|
||
QHoverEvent_create(QEvent_type(Event), @APosF, @AGlobalPosF);
|
||
try
|
||
Result := SlotHover(Sender, AEvent);
|
||
finally
|
||
QEvent_destroy(AEvent);
|
||
end;
|
||
end;
|
||
QEventPaint:
|
||
begin
|
||
QPaintEvent_rect(QPaintEventH(Event), @R);
|
||
if CanSendLCLMessage and (LCLObject is TWinControl) then
|
||
begin
|
||
Brush := QBrush_create;
|
||
QMdiArea_background(QMDIAreaH(Widget), Brush);
|
||
Color := QBrush_color(Brush)^;
|
||
QBrush_destroy(Brush);
|
||
Painter := QPainter_create(QWidget_to_QPaintDevice(QWidgetH(Sender)));
|
||
{$IFDEF USEQT4COMPATIBILEPAINTER}
|
||
QPainter_setRenderHint(Painter, QPainterQt4CompatiblePainting);
|
||
{$ENDIF}
|
||
Brush := QBrush_create(@Color, QtSolidPattern);
|
||
try
|
||
QPaintEvent_rect(QPaintEventH(Event), @R);
|
||
QPainter_fillRect(Painter, @R, Brush);
|
||
QPainter_end(Painter);
|
||
finally
|
||
QBrush_destroy(Brush);
|
||
QPainter_destroy(Painter);
|
||
end;
|
||
APos.X := 0;
|
||
APos.Y := 0;
|
||
QWidget_mapToParent(Widget, @APoint, @APos);
|
||
FScrollX := -APoint.x;
|
||
FScrollY := -APoint.Y;
|
||
APaintEvent := QPaintEvent_create(PRect(@R));
|
||
try
|
||
SlotPaint(Sender, Event);
|
||
finally
|
||
FScrollX := 0;
|
||
FScrollY := 0;
|
||
QPaintEvent_destroy(APaintEvent);
|
||
end;
|
||
Result := True; // do not paint MDIArea again
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TQtMDIArea.ActiveSubWindow: QMdiSubWindowH;
|
||
begin
|
||
Result := QMdiArea_activeSubWindow(QMdiAreaH(Widget));
|
||
end;
|
||
|
||
procedure TQtMDIArea.ActivateSubWindow(AMdiWindow: QMdiSubWindowH);
|
||
begin
|
||
if AMdiWindow <> nil then
|
||
QMdiArea_setActiveSubWindow(QMdiAreaH(Widget), AMdiWindow);
|
||
end;
|
||
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
|
||
{ TQtWindowArea }
|
||
|
||
procedure TQtWindowArea.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FViewPortEventHook := QObject_hook_create(viewportWidget);
|
||
QObject_hook_hook_events(FViewPortEventHook, @ScrollViewEventFilter);
|
||
end;
|
||
|
||
function TQtWindowArea.CanAdjustClientRectOnResize: Boolean;
|
||
begin
|
||
Result := True;
|
||
end;
|
||
|
||
procedure TQtWindowArea.DetachEvents;
|
||
begin
|
||
if Assigned(FViewPortEventHook) then
|
||
begin
|
||
QObject_hook_destroy(FViewPortEventHook);
|
||
FViewPortEventHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtWindowArea.MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean
|
||
): TPoint;
|
||
var
|
||
Pt: TPoint;
|
||
ARet, AParam: TQtPoint;
|
||
R: TRect;
|
||
begin
|
||
Result := inherited MapToGlobal(APt);
|
||
|
||
if ((Result.X < 0) or (Result.Y < 0)) and Assigned(FOwner) and (FOwner is TQtMainWindow) and
|
||
not TQtMainWindow(FOwner).IsMDIChild and
|
||
not (csDesigning in TQtMainWindow(FOwner).LCLObject.ComponentState) then
|
||
begin
|
||
QWidget_geometry(Widget, @R);
|
||
if (R.Left >=0) and (R.Top >=0) then {this is valid geometry}
|
||
exit;
|
||
{all we know is when mapToGlobal returns wrong result is that geometry is wrong}
|
||
if Assigned(FOwner) and (FOwner is TQtMainWindow) and not TQtMainWindow(FOwner).IsMdiChild then
|
||
begin
|
||
ARet.X := 0;
|
||
ARet.Y := 0;
|
||
AParam.X := APt.X;
|
||
AParam.Y := APt.Y;
|
||
if Assigned(TQtMainWindow(FOwner).MenuBar) and TQtMainWindow(FOwner).MenuBar.getVisible then
|
||
begin
|
||
QWidget_mapToGlobal(TQtMainWindow(FOwner).MenuBar.Widget, @ARet, @AParam);
|
||
inc(ARet.Y, QWidget_height(TQtMainWindow(FOwner).MenuBar.Widget));
|
||
Result.X := ARet.X;
|
||
Result.Y := ARet.Y;
|
||
end else
|
||
begin
|
||
QWidget_mapToGlobal(TQtMainWindow(FOwner).Widget, @ARet, @AParam);
|
||
Result.X := ARet.X;
|
||
Result.Y := ARet.Y;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
if AWithScrollOffset then
|
||
begin
|
||
Pt := ScrolledOffset;
|
||
dec(Result.X, Pt.X);
|
||
dec(Result.Y, Pt.Y);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtWindowArea.scroll(dx, dy: integer; ARect: PRect);
|
||
begin
|
||
inherited scroll(dx, dy, ARect);
|
||
FScrollX := FScrollX + dx;
|
||
FScrollY := FScrollY + dy;
|
||
end;
|
||
|
||
function TQtWindowArea.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
begin
|
||
Result := False;
|
||
if (LCLObject = nil) then
|
||
exit;
|
||
if (QEvent_Type(Event) in [QEventMouseButtonPress, QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick, QEventMouseMove, QEventWheel, QEventPaint,
|
||
QEventHoverEnter, QEventHoverMove, QEventHoverLeave, QEventResize]) then
|
||
exit;
|
||
|
||
{$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
|
||
if (QEvent_type(Event)=QEventWindowActivate) or
|
||
(QEvent_type(Event)=QEventWindowDeactivate) or
|
||
(QEvent_type(Event)=QEventShow) or
|
||
(QEvent_type(Event)=QEventShowToParent) or
|
||
(QEvent_type(Event)=QEventShowWindowRequest) or
|
||
(QEvent_type(Event)=QEventResize) or
|
||
(QEvent_type(Event)=QEventContentsRectChange) or
|
||
(QEvent_type(Event)=QEventUpdateLater) or
|
||
(QEvent_type(Event)=QEventUpdateRequest) or
|
||
(QEvent_type(Event)=QEventPaint) or
|
||
(QEvent_type(Event)=QEventWinIdChange) or
|
||
(QEvent_type(Event)=QEventExpose) or
|
||
(QEvent_type(Event)=QEventWindowTitleChange) or
|
||
(QEvent_type(Event)=QEventActivationChange) or
|
||
(QEvent_type(Event)=QEventWindowStateChange) then
|
||
WriteLn(' TQtWindowArea.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
|
||
' LCLObject=', dbgsName(LCLObject),
|
||
' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
|
||
{$endif}
|
||
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
function TQtWindowArea.ScrollViewEventFilter(Sender: QObjectH; Event: QEventH
|
||
): Boolean; cdecl;
|
||
var
|
||
ASize: TSize;
|
||
AResizeEvent: QResizeEventH;
|
||
begin
|
||
Result := False;
|
||
if LCLObject = nil then
|
||
exit;
|
||
|
||
{$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
|
||
if (QEvent_type(Event)=QEventWindowActivate) or
|
||
(QEvent_type(Event)=QEventWindowDeactivate) or
|
||
(QEvent_type(Event)=QEventShow) or
|
||
(QEvent_type(Event)=QEventShowToParent) or
|
||
(QEvent_type(Event)=QEventShowWindowRequest) or
|
||
(QEvent_type(Event)=QEventResize) or
|
||
(QEvent_type(Event)=QEventContentsRectChange) or
|
||
(QEvent_type(Event)=QEventUpdateLater) or
|
||
(QEvent_type(Event)=QEventUpdateRequest) or
|
||
(QEvent_type(Event)=QEventPaint) or
|
||
(QEvent_type(Event)=QEventWinIdChange) or
|
||
(QEvent_type(Event)=QEventExpose) or
|
||
(QEvent_type(Event)=QEventWindowTitleChange) or
|
||
(QEvent_type(Event)=QEventActivationChange) or
|
||
(QEvent_type(Event)=QEventWindowStateChange) then
|
||
WriteLn(' TQtWindowAreaViewport.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
|
||
' LCLObject=', dbgsName(LCLObject),
|
||
' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
|
||
{$endif}
|
||
|
||
BeginEventProcessing;
|
||
try
|
||
if (QEvent_Type(Event) in [QEventContextMenu, QEventHoverEnter, QEventPaint,
|
||
QEventHoverMove, QEventHoverLeave, QEventHide,
|
||
{must be added, see issue #29159}
|
||
QEventMouseMove]) then
|
||
begin
|
||
if (FOwner is TQtMainWindow) and not TQtMainWindow(FOwner).IsFrameWindow and
|
||
(TCustomForm(LCLObject).FormStyle = fsMDIForm) and
|
||
(TQtMainWindow(FOwner).MDIAreaHandle <> nil) then
|
||
// paint via MDIAreaHandle viewport hook
|
||
else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end else
|
||
case QEvent_type(Event) of
|
||
QEventResize:
|
||
begin
|
||
if FOwner <> nil then
|
||
begin
|
||
{TQtMainWindow does not send resize event if ScrollArea is assigned,
|
||
it is done here when viewport geometry is finally updated by Qt.}
|
||
ASize := FOwner.getSize;
|
||
AResizeEvent := QResizeEvent_create(@ASize, @ASize);
|
||
try
|
||
// issue #28596 and others of TCustomControl clientrect related
|
||
if CanAdjustClientRectOnResize and
|
||
LCLObject.ClientRectNeedsInterfaceUpdate then
|
||
begin
|
||
{$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('TQtWindowArea.ScrollViewEventFilter invalidatingClientRectCache ',dbgsName(Self),' LCL=',dbgsName(LCLObject));
|
||
{$ENDIF}
|
||
LCLObject.InvalidateClientRectCache(False);
|
||
end;
|
||
SlotResize(AResizeEvent);
|
||
finally
|
||
QEvent_destroy(AResizeEvent);
|
||
end;
|
||
end else
|
||
LCLObject.DoAdjustClientRectChange;
|
||
end;
|
||
QEventWheel:
|
||
if not getEnabled then
|
||
inherited EventFilter(Sender, Event);
|
||
QEventLayoutRequest:
|
||
begin
|
||
if FOwner <> nil then
|
||
begin
|
||
if LCLObject.ClientRectNeedsInterfaceUpdate then
|
||
begin
|
||
{$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('TQtWindowArea.Viewport: ',dbgsName(LCLObject),' QEventLayoutRequest calling DoAdjustClientRectChange CASP=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' ***** !!!! ');
|
||
{$ENDIF}
|
||
Self.LCLObject.DoAdjustClientRectChange(True);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end;
|
||
|
||
function TQtWindowArea.getWindowState: QtWindowStates;
|
||
begin
|
||
Result := inherited getWindowState;
|
||
if Assigned(LCLObject) then
|
||
Result := TQtMainWindow(LCLObject.Handle).getWindowState;
|
||
end;
|
||
|
||
{$ENDIF}
|
||
|
||
|
||
{ TQtMainWindow }
|
||
|
||
function TQtMainWindow.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
procedure SetScrollAreaRules;
|
||
begin
|
||
FCentralWidget := ScrollArea.Widget;
|
||
ScrollArea.ChildOfComplexWidget := ccwAbstractScrollArea;
|
||
ScrollArea.LCLObject := LCLObject;
|
||
|
||
QFrame_setFrameShape(QAbstractScrollAreaH(ScrollArea.Widget), QFrameNoFrame);
|
||
QWidget_setBackgroundRole(ScrollArea.viewportWidget, QPaletteNoRole);
|
||
QWidget_setAutoFillBackground(ScrollArea.viewportWidget, False);
|
||
setProperty(ScrollArea.viewportWidget, 'lclwidget', Int64(PtrUInt(Self)));
|
||
|
||
// we must set minimum heigth / width to 1 otherwise we'll have strange
|
||
// effect eg. with main ide bar window (small size and cannot resize).
|
||
//QWidget_setMinimumHeight(FCentralWidget, 1);
|
||
//QWidget_setMinimumWidth(FCentralWidget, 1);
|
||
QWidget_setSizePolicy(FCentralWidget, QSizePolicyIgnored, QSizePolicyIgnored);
|
||
|
||
ScrollArea.setScrollBarPolicy(True, QtScrollBarAlwaysOff);
|
||
ScrollArea.setScrollBarPolicy(False, QtScrollBarAlwaysOff);
|
||
ScrollArea.HasPaint := True;
|
||
ScrollArea.FOwner := Self;
|
||
end;
|
||
{$ENDIF}
|
||
var
|
||
p: QPaletteH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtMainWindow.CreateWidget Name: ', LCLObject.Name);
|
||
{$endif}
|
||
|
||
FFirstPaintEvent := False;
|
||
FBlocked := False;
|
||
FShowOnTaskBar := False;
|
||
QtFormBorderStyle := Ord(bsSizeable);
|
||
QtFormStyle := Ord(fsNormal);
|
||
FHasPaint := True;
|
||
FPopupParent := nil;
|
||
MDIAreaHandle := nil;
|
||
MDIChildArea := nil;
|
||
FMDIStateHook := nil;
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
ScrollArea := nil;
|
||
{$ENDIF}
|
||
|
||
IsMainForm := (LCLObject <> nil) and (LCLObject = Application.MainForm);
|
||
|
||
IsFrameWindow := not IsMainForm and (LCLObject is TCustomFrame);
|
||
if IsFrameWindow then
|
||
QtFormBorderStyle := Ord(bsNone);
|
||
|
||
if IsMainForm then
|
||
begin
|
||
|
||
Result := QMainWindow_create(nil, QtWindow);
|
||
|
||
MenuBar := TQtMenuBar.Create(Result);
|
||
|
||
if not (csDesigning in LCLObject.ComponentState) then
|
||
MenuBar.FIsApplicationMainMenu := True
|
||
else
|
||
{$IFNDEF DARWIN}
|
||
MenuBar.setProperty(MenuBar.Widget,'lcldesignmenubar',1)
|
||
{$ENDIF}
|
||
;
|
||
|
||
if (Application.MainForm <> nil) and
|
||
(Application.MainForm.FormStyle = fsMDIForm) and
|
||
not (csDesigning in LCLObject.ComponentState) then
|
||
begin
|
||
FCentralWidget := QWidget_create(Result);
|
||
MDIAreaHandle := TQtMDIArea.Create(Result);
|
||
MDIAreaHandle.FOwner := Self;
|
||
MDIAreaHandle.LCLObject := LCLObject;
|
||
MDIAreaHandle.AttachEvents;
|
||
p := QWidget_palette(FCentralWidget);
|
||
if p <> nil then
|
||
QMdiArea_setBackground(QMdiAreaH(MdiAreaHandle.Widget), QPalette_background(P));
|
||
QWidget_setParent(MdiAreaHandle.Widget, FCentralWidget);
|
||
QMdiArea_setActivationOrder(QMdiAreaH(MdiAreaHandle.Widget), QMdiAreaActivationHistoryOrder);
|
||
QMdiArea_setOption(QMdiAreaH(MdiAreaHandle.Widget),
|
||
QMdiAreaDontMaximizeSubWindowOnActivation, True);
|
||
end
|
||
else
|
||
begin
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
ScrollArea := TQtWindowArea.CreateFrom(LCLObject, QAbstractScrollArea_create(Result));
|
||
SetScrollAreaRules;
|
||
{$ELSE}
|
||
FCentralWidget := QWidget_create(Result);
|
||
{$ENDIF}
|
||
MDIAreaHandle := nil;
|
||
end;
|
||
|
||
if FCentralWidget <> nil then
|
||
begin
|
||
QMainWindow_setCentralWidget(QMainWindowH(Result), FCentralWidget);
|
||
QWidget_setMouseTracking(FCentralWidget, True);
|
||
end;
|
||
|
||
if not (csDesigning in LCLObject.ComponentState) then
|
||
QMainWindow_setDockOptions(QMainWindowH(Result), QMainWindowAnimatedDocks);
|
||
end else
|
||
begin
|
||
if IsMdiChild then
|
||
begin
|
||
|
||
if TQtMainWindow(Application.MainForm.Handle).MDIAreaHandle = nil then
|
||
raise Exception.Create('MDIChild can be added to MDIForm only !');
|
||
|
||
FFirstPaintEvent := True;
|
||
|
||
Result := QMdiSubWindow_create(nil, QtWindow);
|
||
|
||
// QMdiSubWindow already have an layout
|
||
|
||
LayoutWidget := QBoxLayoutH(QWidget_layout(Result));
|
||
if LayoutWidget <> nil then
|
||
QBoxLayout_destroy(LayoutWidget);
|
||
end else
|
||
begin
|
||
if not IsFrameWindow and (TCustomForm(LCLObject).FormStyle = fsSplash) and
|
||
not (csDesigning in LCLObject.ComponentState) then
|
||
begin
|
||
FFirstPaintEvent := True;
|
||
Result := QWidget_create(nil, QtSplashScreen);
|
||
end else
|
||
Result := QWidget_create(nil, QtWindow);
|
||
|
||
QWidget_setAttribute(Result, QtWA_Hover);
|
||
QWidget_setMouseTracking(Result, True);
|
||
end;
|
||
|
||
// Main menu bar
|
||
{$IFDEF DARWIN}
|
||
MenuBar := TQtMenuBar.Create(nil);
|
||
{$ELSE}
|
||
MenuBar := TQtMenuBar.Create(Result);
|
||
if (csDesigning in LCLObject.ComponentState) then
|
||
MenuBar.setProperty(MenuBar.Widget,'lcldesignmenubar',1);
|
||
{$ENDIF}
|
||
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if QWidget_windowType(Result) = QtSplashScreen then
|
||
FCentralWidget := QWidget_create(Result)
|
||
else
|
||
begin
|
||
ScrollArea := TQtWindowArea.CreateFrom(LCLObject, QAbstractScrollArea_create(Result));
|
||
SetScrollAreaRules;
|
||
end;
|
||
{$ELSE}
|
||
FCentralWidget := QWidget_create(Result);
|
||
{$ENDIF}
|
||
QWidget_setMouseTracking(FCentralWidget, True);
|
||
|
||
LayoutWidget := QBoxLayout_create(QBoxLayoutTopToBottom, Result);
|
||
|
||
QBoxLayout_setSpacing(LayoutWidget, 0);
|
||
QLayout_setContentsMargins(LayoutWidget, 0, 0, 0, 0);
|
||
|
||
// we must fix mouse events in QMDISubWindow by
|
||
// adding FCentralWidget as it''s widget
|
||
if IsMdiChild then
|
||
QMdiSubWindow_setWidget(QMdiSubWindowH(Result), FCentralWidget);
|
||
|
||
QLayout_addWidget(LayoutWidget, FCentralWidget);
|
||
QWidget_setLayout(Result, QLayoutH(LayoutWidget));
|
||
QWidget_setAttribute(Result, QtWA_DeleteOnClose);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtMainWindow.ChangeParent(NewParent: QWidgetH);
|
||
var
|
||
Flags: QtWindowFlags;
|
||
Visible: Boolean;
|
||
begin
|
||
if NewParent <> Widget then
|
||
begin
|
||
Visible := getVisible;
|
||
Flags := windowFlags;
|
||
setParent(NewParent);
|
||
setWindowFlags(Flags);
|
||
setVisible(Visible);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtMainWindow.UpdateParent;
|
||
begin
|
||
ChangeParent(FPopupParent);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtMainWindow.Destroy
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
destructor TQtMainWindow.Destroy;
|
||
begin
|
||
// The main window takes care of the menubar handle
|
||
{handle validator is added since we added events to
|
||
menubar in r33309 (because of font changes).
|
||
Events are attached in TQtWSCustomForm.CreateHandle
|
||
Sometimes in various combinations we can
|
||
crash here because MenuBar <> nil but not valid handle.
|
||
Now it's totally safe.}
|
||
if QtWidgetSet.IsValidHandle(HWND(MenuBar)) then
|
||
begin
|
||
MenuBar.DetachEvents;
|
||
if FOwnWidget and (MenuBar.Widget <> nil) then
|
||
QObject_deleteLater(MenuBar.Widget);
|
||
MenuBar.Widget := nil;
|
||
FreeThenNil(MenuBar);
|
||
end;
|
||
|
||
if MDIAreaHandle <> nil then
|
||
begin
|
||
MDIAreaHandle.DetachEvents;
|
||
MDIAreaHandle.Widget := nil;
|
||
FreeThenNil(MDIAreaHandle);
|
||
end;
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if QtWidgetSet.IsValidHandle(HWND(ScrollArea)) then
|
||
begin
|
||
ScrollArea.DetachEvents;
|
||
ScrollArea.Widget := nil;
|
||
FreeAndNil(ScrollArea);
|
||
end;
|
||
{$ENDIF}
|
||
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TQtMainWindow.BeginUpdate;
|
||
begin
|
||
inherited BeginUpdate;
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if Assigned(ScrollArea) then
|
||
ScrollArea.BeginUpdate;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TQtMainWindow.EndUpdate;
|
||
begin
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if Assigned(ScrollArea) then
|
||
ScrollArea.EndUpdate;
|
||
{$ENDIF}
|
||
inherited EndUpdate;
|
||
end;
|
||
|
||
procedure TQtMainWindow.Activate;
|
||
begin
|
||
if IsMDIChild then
|
||
QMdiArea_setActiveSubWindow(QMdiSubWindow_mdiArea(QMdiSubWindowH(Widget)),
|
||
QMdiSubWindowH(Widget))
|
||
else
|
||
inherited Activate;
|
||
{$IFDEF DARWIN}
|
||
QWidget_raise(Widget);
|
||
{$ENDIF}
|
||
{$IFDEF HASX11}
|
||
if IsWayland then
|
||
QWidget_raise(Widget)
|
||
else
|
||
if (QtWidgetSet.WindowManagerName = 'xfwm4') and not IsMDIChild and
|
||
QWidget_isModal(Widget) then
|
||
begin
|
||
if X11GetActivewindow <> Widget then
|
||
X11Raise(QWidget_winID(Widget));
|
||
end else
|
||
if not QWidget_isModal(Widget) then
|
||
begin
|
||
if (QtWidgetSet.WindowManagerName = 'metacity') and not IsMDIChild then
|
||
X11Raise(QWidget_winID(Widget))
|
||
else
|
||
QWidget_raise(Widget);
|
||
end;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
function TQtMainWindow.CanAdjustClientRectOnResize: Boolean;
|
||
begin
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
Result := not Assigned(ScrollArea);
|
||
{$ELSE}
|
||
Result:=inherited CanAdjustClientRectOnResize;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
function TQtMainWindow.getAcceptDropFiles: Boolean;
|
||
begin
|
||
Result := QWidget_acceptDrops(Widget);
|
||
end;
|
||
|
||
function TQtMainWindow.GetContainerWidget: QWidgetH;
|
||
begin
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if IsFrameWindow then
|
||
Result := ScrollArea.GetContainerWidget
|
||
else
|
||
if not Assigned(ScrollArea) or (QWidget_windowType(Widget) = QtToolTip) or
|
||
(QWidget_windowType(Widget) = QtSplashScreen) or
|
||
(TCustomForm(LCLObject).FormStyle = fsMdiForm) then
|
||
Result := inherited GetContainerWidget
|
||
else
|
||
Result := ScrollArea.GetContainerWidget;
|
||
{$ELSE}
|
||
Result := inherited GetContainerWidget;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TQtMainWindow.grabMouse;
|
||
begin
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if not Assigned(ScrollArea) then
|
||
inherited grabMouse
|
||
else
|
||
ScrollArea.grabMouse;
|
||
{$ELSE}
|
||
inherited grabMouse;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
function TQtMainWindow.getClientBounds: TRect;
|
||
begin
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if Assigned(ScrollArea) then
|
||
begin
|
||
if not ScrollArea.testAttribute(QtWA_PendingResizeEvent) then
|
||
Result := ScrollArea.getClientBounds
|
||
else
|
||
Result := inherited GetClientBounds;
|
||
end else
|
||
{$ENDIF}
|
||
Result:=inherited getClientBounds;
|
||
end;
|
||
|
||
function TQtMainWindow.getClientOffset: TPoint;
|
||
begin
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if Assigned(ScrollArea) then
|
||
Result := ScrollArea.getClientOffset
|
||
else
|
||
Result := inherited getClientOffset;
|
||
if Assigned(ScrollArea) and Assigned(MenuBar) and
|
||
(MenuBar.getVisible) then
|
||
inc(Result.Y, MenuBar.getHeight);
|
||
{$ELSE}
|
||
Result:=inherited getClientOffset;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
function TQtMainWindow.getText: WideString;
|
||
begin
|
||
WindowTitle(@Result);
|
||
end;
|
||
|
||
function TQtMainWindow.getTextStatic: Boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
function TQtMainWindow.MapToGlobal(APt: TPoint; const AWithScrollOffset: Boolean
|
||
): TPoint;
|
||
begin
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if Assigned(ScrollArea) then
|
||
Result := ScrollArea.MapToGlobal(APt, AWithScrollOffset)
|
||
else
|
||
Result := inherited MapToGlobal(APt, AWithScrollOffset);
|
||
{$ELSE}
|
||
Result := inherited MapToGlobal(APt, AWithScrollOffset);
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TQtMainWindow.Update(ARect: PRect);
|
||
var
|
||
R,R1: TRect;
|
||
begin
|
||
if Assigned(MDIAreaHandle) and not IsMDIChild then
|
||
begin
|
||
if ARect = nil then
|
||
QWidget_update(MDIAreaHandle.viewportWidget)
|
||
else
|
||
begin
|
||
R1 := ARect^;
|
||
QWidget_geometry(MDIAreaHandle.Widget, @R);
|
||
OffsetRect(R1, -R.Left, -R.Top);
|
||
QWidget_update(MDIAreaHandle.viewportWidget, @R1);
|
||
end;
|
||
end else
|
||
inherited Update(ARect);
|
||
end;
|
||
|
||
procedure TQtMainWindow.UpdateRegion(ARgn: QRegionH);
|
||
var
|
||
R1, R: TRect;
|
||
ANewRgn: QRegionH;
|
||
begin
|
||
if Assigned(MDIAreaHandle) and not IsMDIChild then
|
||
begin
|
||
if ARgn = nil then
|
||
QWidget_update(MDIAreaHandle.viewportWidget)
|
||
else
|
||
begin
|
||
QRegion_boundingRect(ARgn, @R1);
|
||
QWidget_geometry(MDIAreaHandle.Widget, @R);
|
||
OffsetRect(R1, -R.Left, -R.Top);
|
||
ANewRgn := QRegion_create(PRect(@R1));
|
||
QWidget_update(MDIAreaHandle.viewportWidget, ANewRgn);
|
||
QRegion_destroy(ANewRgn);
|
||
end;
|
||
end else
|
||
inherited UpdateRegion(ARgn);
|
||
end;
|
||
|
||
procedure TQtMainWindow.Repaint(ARect: PRect);
|
||
var
|
||
R, R1: TRect;
|
||
begin
|
||
if Assigned(MDIAreaHandle) and not IsMDIChild then
|
||
begin
|
||
if ARect = nil then
|
||
QWidget_repaint(MDIAreaHandle.viewportWidget)
|
||
else
|
||
begin
|
||
R1 := ARect^;
|
||
QWidget_geometry(MDIAreaHandle.Widget, @R);
|
||
OffsetRect(R1, -R.Left, -R.Top);
|
||
QWidget_repaint(MDIAreaHandle.viewportWidget, @R1);
|
||
end;
|
||
end else
|
||
inherited Repaint(ARect);
|
||
end;
|
||
|
||
procedure TQtMainWindow.Resize(ANewWidth, ANewHeight: Integer);
|
||
begin
|
||
if not IsMDIChild and not IsFrameWindow and
|
||
(TCustomForm(LCLObject).BorderStyle in [bsDialog, bsNone, bsSingle]) and
|
||
not (csDesigning in LCLObject.ComponentState) then
|
||
QWidget_setFixedSize(Widget, ANewWidth, ANewHeight)
|
||
else
|
||
inherited Resize(ANewWidth, ANewHeight);
|
||
end;
|
||
|
||
procedure TQtMainWindow.setText(const W: WideString);
|
||
begin
|
||
setWindowTitle(@W);
|
||
end;
|
||
|
||
procedure TQtMainWindow.setMenuBar(AMenuBar: QMenuBarH);
|
||
begin
|
||
if IsMainForm then
|
||
QMainWindow_setMenuBar(QMainWindowH(Widget), AMenuBar)
|
||
else
|
||
QLayout_setMenuBar(LayoutWidget, AMenuBar);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtMainWindow.EventFilter
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtMainWindow.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
var
|
||
AStateEvent: QWindowStateChangeEventH;
|
||
AState: QtWindowStates;
|
||
AOldState: QtWindowStates;
|
||
CanSendEvent: Boolean;
|
||
{$IFDEF MSWINDOWS}
|
||
i: Integer;
|
||
AForm: TCustomForm;
|
||
w: QWidgetH;
|
||
{$ENDIF}
|
||
{$IFDEF HASX11}
|
||
IsMinimizeEvent: Boolean;
|
||
{$ENDIF}
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject = nil then
|
||
exit;
|
||
|
||
{$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
|
||
if (QEvent_type(Event)=QEventWindowActivate) or
|
||
(QEvent_type(Event)=QEventWindowDeactivate) or
|
||
(QEvent_type(Event)=QEventShow) or
|
||
(QEvent_type(Event)=QEventShowToParent) or
|
||
(QEvent_type(Event)=QEventShowWindowRequest) or
|
||
(QEvent_type(Event)=QEventResize) or
|
||
(QEvent_type(Event)=QEventContentsRectChange) or
|
||
(QEvent_type(Event)=QEventUpdateLater) or
|
||
(QEvent_type(Event)=QEventUpdateRequest) or
|
||
(QEvent_type(Event)=QEventPaint) or
|
||
(QEvent_type(Event)=QEventWinIdChange) or
|
||
(QEvent_type(Event)=QEventExpose) or
|
||
(QEvent_type(Event)=QEventWindowTitleChange) or
|
||
(QEvent_type(Event)=QEventActivationChange) or
|
||
(QEvent_type(Event)=QEventWindowStateChange) then
|
||
WriteLn('TQtMainWindow.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
|
||
' LCLObject=', dbgsName(LCLObject),
|
||
' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
|
||
{$endif}
|
||
|
||
{$IFDEF MSWINDOWS}
|
||
if (QEvent_type(Event) = QEventWinIDChange) and not FFirstPaintEvent then
|
||
FFirstPaintEvent := True;
|
||
{$ENDIF}
|
||
|
||
{$IFDEF HASX11}
|
||
if (QEvent_type(Event) = QEventPaint) and not FFirstPaintEvent then
|
||
FFirstPaintEvent := True;
|
||
{$ENDIF}
|
||
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if Assigned(ScrollArea) and not IsMDIChild then
|
||
begin
|
||
if QEvent_type(Event) in
|
||
[QEventPaint, QEventContextMenu, QEventWheel] then
|
||
exit;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
BeginEventProcessing;
|
||
try
|
||
case QEvent_type(Event) of
|
||
QEventHide:
|
||
begin
|
||
Result := inherited EventFilter(Sender, Event);
|
||
{as of r46623 (issue #26893) we use QObject_deleteLater
|
||
instead of QWidget_destroy.
|
||
QMDIArea does not respond after that, so we must activate next mdichild
|
||
according to mdi standards.Looks like Qt4 bug.}
|
||
if not Application.Terminated and IsMDIChild then
|
||
begin
|
||
if Assigned(MDIChildArea) then
|
||
begin
|
||
if (MDIChildArea.ActiveSubWindow = nil) or
|
||
(MDIChildArea.ActiveSubWindow = Widget) then
|
||
begin
|
||
if not QWidget_isVisibleTo(Widget, MDIChildArea.Widget) then
|
||
QMdiArea_activatePreviousSubWindow(QMDIAreaH(MDIChildArea.Widget));
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
QEventMouseMove: // issue #29159
|
||
begin
|
||
if (Self is TQtHintWindow) or (IsMdiChild or
|
||
(Assigned(LCLObject) and (csDesigning in LCLObject.ComponentState))) then
|
||
Result := inherited EventFilter(Sender, Event)
|
||
else
|
||
Result := False;
|
||
end;
|
||
{$ENDIF}
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick:
|
||
begin
|
||
if IsMdiChild then
|
||
begin
|
||
if QMouseEvent_y(QMouseEventH(Event)) <= GetPixelMetric(
|
||
QStylePM_TitleBarHeight, nil, Widget) then
|
||
QEvent_ignore(Event)
|
||
else
|
||
Result := SlotMouse(Sender, Event);
|
||
end else
|
||
Result := SlotMouse(Sender, Event);
|
||
end;
|
||
QEventWindowUnblocked: Blocked := False;
|
||
QEventWindowBlocked: Blocked := True;
|
||
QEventWindowActivate:
|
||
begin
|
||
if not IsMDIChild then
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
// issues #26463, #29744, must restore app if we activate non modal window from taskbar
|
||
if (Application.ModalLevel > 0) and
|
||
(QApplication_activeModalWidget <> nil) and QWidget_isMinimized(QApplication_activeModalWidget) then
|
||
begin
|
||
W := QApplication_activeModalWidget;
|
||
// back to tray
|
||
BeginUpdate;
|
||
ShowMinimized;
|
||
EndUpdate;
|
||
AState := QWidget_windowState(W);
|
||
AState := AState and not QtWindowMinimized;
|
||
QWidget_setWindowState(W, AState);
|
||
end else
|
||
{$ENDIF}
|
||
SlotActivateWindow(True);
|
||
end;
|
||
end;
|
||
QEventWindowDeactivate: if not IsMDIChild then SlotActivateWindow(False);
|
||
QEventShowToParent: ; // do nothing for TQtMainWindow, but leave it unhandled
|
||
QEventWindowStateChange:
|
||
begin
|
||
if IsMDIChild then
|
||
begin
|
||
//do not process QEventWindowStateChange for MDI children !
|
||
//we are doing that job in MDIChildWindowStateChanged slot.
|
||
exit;
|
||
end;
|
||
|
||
CanSendEvent := True;
|
||
{$IFDEF HASX11}
|
||
// for X11 we must ask state of each modified window.
|
||
AState := getWindowState;
|
||
|
||
IsMinimizeEvent := AState and QtWindowMinimized <> 0;
|
||
if IsMinimizeEvent then
|
||
begin
|
||
CanSendEvent := IsCurrentDesktop(Widget);
|
||
QtWidgetSet.FMinimizedByPager := not CanSendEvent;
|
||
if IsMainForm and QtWidgetSet.FMinimizedByPager then
|
||
QtWidgetSet.HideAllHints;
|
||
end;
|
||
{$ENDIF}
|
||
if IsMainForm and CanSendEvent then
|
||
begin
|
||
{$IFNDEF HASX11}
|
||
AState := getWindowState;
|
||
{$ENDIF}
|
||
AStateEvent := QWindowStateChangeEventH(Event);
|
||
AOldState := QWindowStateChangeEvent_oldState(AStateEvent);
|
||
if AState and QtWindowMinimized <> 0 then
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
for i := 0 to Screen.CustomFormZOrderCount - 1 do
|
||
begin
|
||
AForm := Screen.CustomFormsZOrdered[i];
|
||
if (AForm <> Application.MainForm) and
|
||
// (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and
|
||
AForm.HandleAllocated and AForm.Visible then
|
||
begin
|
||
W := TQtWidget(AForm.Handle).Widget;
|
||
if not QWidget_isMinimized(W) then
|
||
begin
|
||
TQtWidget(AForm.Handle).BeginUpdate;
|
||
try
|
||
QWidget_showMinimized(W);
|
||
finally
|
||
TQtWidget(AForm.Handle).EndUpdate;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
Application.IntfAppMinimize;
|
||
end
|
||
else
|
||
if (AOldState and QtWindowMinimized <> 0) or
|
||
(AOldState and QtWindowMaximized <> 0) or
|
||
(AOldState and QtWindowFullScreen <> 0) then
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
for i := 0 to Screen.CustomFormZOrderCount - 1 do
|
||
begin
|
||
AForm := Screen.CustomFormsZOrdered[i];
|
||
if (AForm <> Application.MainForm) and
|
||
// (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and
|
||
AForm.HandleAllocated and AForm.Visible then
|
||
begin
|
||
W := TQtWidget(AForm.Handle).Widget;
|
||
if QWidget_isMinimized(W) then
|
||
begin
|
||
TQtWidget(AForm.Handle).BeginUpdate;
|
||
try
|
||
QWidget_showNormal(W);
|
||
finally
|
||
TQtWidget(AForm.Handle).EndUpdate;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
Application.IntfAppRestore;
|
||
{$ELSE}
|
||
|
||
{$IFDEF HASX11}
|
||
// do not activate lazarus app if it wasn't active during
|
||
// pager switch !
|
||
if (AOldState and QtWindowMinimized <> 0) and
|
||
QtWidgetSet.FMinimizedByPager then
|
||
begin
|
||
QtWidgetSet.FMinimizedByPager := False;
|
||
QtWidgetSet.RestoreAllHints;
|
||
end else
|
||
{$ENDIF}
|
||
Application.IntfAppRestore;
|
||
{$ENDIF}
|
||
end;
|
||
end;
|
||
if CanSendEvent and not IsFrameWindow then
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
AForm := TCustomForm(LCLObject);
|
||
if (fsModal in AForm.FormState) then
|
||
begin
|
||
AOldState := QWindowStateChangeEvent_oldState(QWindowStateChangeEventH(Event));
|
||
AState := GetWindowState;
|
||
SlotWindowStateChange;
|
||
if (AState and QtWindowMinimized = QtWindowMinimized) and (AOldState and QtWindowMinimized = 0) then
|
||
Application.Minimize
|
||
else
|
||
if (AOldState and QtWindowMinimized = QtWindowMinimized) and (AState and QtWindowMinimized = 0) then
|
||
Application.Restore;
|
||
end else
|
||
if (AForm.FormStyle in [fsStayOnTop, fsSystemStayOnTop]) and InUpdate then
|
||
// do not trigger LCL
|
||
else
|
||
{$ENDIF}
|
||
SlotWindowStateChange;
|
||
end;
|
||
end;
|
||
QEventDrop,
|
||
QEventDragMove,
|
||
QEventDragEnter:
|
||
begin
|
||
Result := getAcceptDropFiles;
|
||
if (Result) and (QEvent_type(Event) = QEventDrop) then
|
||
Result := slotDropFiles(Sender, Event);
|
||
end;
|
||
QEventResize:
|
||
begin
|
||
// issue #34698
|
||
{$ifdef darwin}
|
||
if (QResizeEvent_oldSize(QResizeEventH(Event))^.cx = -1) and (QResizeEvent_oldSize(QResizeEventH(Event))^.cy = -1) then
|
||
include(FWidgetState, qtwsForceSendMove);
|
||
{$endif}
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if not Assigned(ScrollArea) then
|
||
{$ENDIF}
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
QEventPaint:
|
||
begin
|
||
{do not send paint or resize event to LCL if we are pure TCustomForm,
|
||
CWEvent or ScrollArea.EventFilter will process it.
|
||
So call SlotPaint only if we are eg TQtHintWindow.}
|
||
if (FCentralWidget = nil) or (FCentralWidget = Widget) then
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtMainWindow.MDIChildWindowStateChanged(AOldState: QtWindowStates;
|
||
ANewState: QtWindowStates); cdecl;
|
||
var
|
||
AOld, ANew: QtWindowStates;
|
||
Arr: TPtrIntArray;
|
||
i: Integer;
|
||
W: QMDISubWindowH;
|
||
B: Boolean;
|
||
FoundWin: Boolean;
|
||
begin
|
||
// check if state is same without active flag, in that case don't inform lcl.
|
||
AOld := AOldState and not QtWindowActive;
|
||
ANew := ANewState and not QtWindowActive;
|
||
if AOld = ANew then
|
||
exit;
|
||
|
||
{inform LCL about change}
|
||
SlotWindowStateChange;
|
||
|
||
if (AOldState and QtWindowMinimized <> 0) and (ANewState and QtWindowMinimized = 0) and
|
||
(ANewState and QtWindowMaximized = 0) and LCLObject.ClientRectNeedsInterfaceUpdate then
|
||
LCLObject.DoAdjustClientRectChange(True);
|
||
|
||
{activate next mdi in chain if we are minimized}
|
||
if Assigned(MDIChildArea) and
|
||
(ANewState and QtWindowMinimized = QtWindowMinimized) and
|
||
(ANewState and QtWindowActive = QtWindowActive) then
|
||
begin
|
||
QMdiArea_subWindowList(QMdiAreaH(MDIChildArea.Widget), @Arr);
|
||
// activate only if MDIChild is not minimized !
|
||
// we are using *history activation order*,
|
||
// so we must take into account index of
|
||
// current minimized win.
|
||
B := False;
|
||
FoundWin := False;
|
||
for i := High(Arr) downto 0 do
|
||
begin
|
||
W := QMdiSubWindowH(Arr[i]);
|
||
AOld := QWidget_windowState(W);
|
||
B := W = Widget;
|
||
if B and (W <> Widget) and (AOld and QtWindowMinimized = 0) then
|
||
begin
|
||
FoundWin := True;
|
||
MDIChildArea.ActivateSubWindow(W);
|
||
break;
|
||
end;
|
||
end;
|
||
// not found lower index window, search for higher one
|
||
if not FoundWin then
|
||
begin
|
||
for i := High(Arr) downto 0 do
|
||
begin
|
||
W := QMdiSubWindowH(Arr[i]);
|
||
AOld := QWidget_windowState(W);
|
||
if (W <> Widget) and (AOld and QtWindowMinimized = 0) then
|
||
begin
|
||
MDIChildArea.ActivateSubWindow(W);
|
||
break;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
end;
|
||
end;
|
||
|
||
function TQtMainWindow.IsMdiChild: Boolean;
|
||
begin
|
||
Result := (LCLObject <> nil) and not IsFrameWindow and not
|
||
(csDesigning in LCLObject.ComponentState) and
|
||
(TCustomForm(LCLObject).FormStyle = fsMDIChild) and not IsFormDesign(LCLObject);
|
||
end;
|
||
|
||
function TQtMainWindow.IsModal: Boolean;
|
||
begin
|
||
Result := QWidget_isModal(Widget);
|
||
end;
|
||
|
||
function TQtMainWindow.MdiChildCount: integer;
|
||
var
|
||
Arr: TPtrIntArray;
|
||
Area: QMdiAreaH;
|
||
begin
|
||
Result := 0;
|
||
if IsMdiChild then
|
||
Area := QMdiSubWindow_mdiArea(QMdiSubWindowH(Widget))
|
||
else
|
||
Area := QMDIAreaH(MDIAreaHandle.Widget);
|
||
if Area <> nil then
|
||
begin
|
||
QMdiArea_subWindowList(Area, @Arr);
|
||
Result := High(Arr);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtMainWindow.OffsetMousePos(APoint: PQtPoint);
|
||
begin
|
||
if not IsMdiChild then
|
||
inherited OffsetMousePos(APoint);
|
||
end;
|
||
|
||
procedure TQtMainWindow.setAcceptDropFiles(AValue: Boolean);
|
||
begin
|
||
QWidget_setAcceptDrops(Widget, AValue);
|
||
end;
|
||
|
||
procedure TQtMainWindow.setColor(const Value: PQColor);
|
||
var
|
||
p: QPaletteH;
|
||
begin
|
||
inherited setColor(Value);
|
||
if Assigned(MDIAreaHandle) and Assigned(FCentralWidget) then
|
||
begin
|
||
p := QWidget_palette(FCentralWidget);
|
||
if p <> nil then
|
||
QMdiArea_setBackground(QMdiAreaH(MdiAreaHandle.Widget), QPalette_background(P));
|
||
end;
|
||
end;
|
||
|
||
procedure TQtMainWindow.setFocusPolicy(const APolicy: QtFocusPolicy);
|
||
begin
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
if Assigned(ScrollArea) then
|
||
ScrollArea.setFocusPolicy(APolicy)
|
||
else
|
||
inherited setFocusPolicy(APolicy);
|
||
{$ELSE}
|
||
inherited setFocusPolicy(APolicy);
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TQtMainWindow.SlotActivateWindow(vActivate: Boolean); cdecl;
|
||
var
|
||
Msg: TLMActivate;
|
||
FIsActivated: Boolean;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtWidget.SlotActivateWindow Name', LCLObject.Name, ' vActivate: ', dbgs(vActivate));
|
||
{$endif}
|
||
|
||
if IsFrameWindow then
|
||
exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
FIsActivated := TCustomForm(LCLObject).Active;
|
||
{do not send activate if form is already activated,
|
||
also do not send activate if TCustomForm.Parent is assigned
|
||
since it's form embedded into another control or form}
|
||
if (vActivate = FIsActivated) or (LCLObject.Parent <> nil) then
|
||
exit;
|
||
|
||
Msg.Msg := LM_ACTIVATE;
|
||
if vActivate then
|
||
Msg.Active := WA_ACTIVE
|
||
else
|
||
Msg.Active := WA_INACTIVE;
|
||
Msg.ActiveWindow := LCLObject.Handle;
|
||
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtMainWindow.SlotWindowStateChange
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtMainWindow.slotWindowStateChange; cdecl;
|
||
var
|
||
Msg: TLMSize;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtMainWindow.SlotWindowStateChange');
|
||
{$endif}
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
Msg.Msg := LM_SIZE;
|
||
Msg.SizeType := SIZE_RESTORED;
|
||
|
||
if getWindowState and QtWindowMinimized <> 0 then
|
||
Msg.SizeType := SIZE_MINIMIZED
|
||
else
|
||
if (getWindowState and QtWindowFullScreen <> 0) then
|
||
Msg.SizeType := SIZE_FULLSCREEN
|
||
else
|
||
if (getWindowState and QtWindowMaximized <> 0) then
|
||
Msg.SizeType := SIZE_MAXIMIZED;
|
||
|
||
Msg.SizeType := Msg.SizeType or Size_SourceIsInterface;
|
||
|
||
{Mdichild sends size of minimized title, and that's bad, after restore client
|
||
rect is mismatched and provokes OnResize events.We are sending
|
||
to the LCL Width and Height of LCLObject so resize event won't trigger.
|
||
issue #27518}
|
||
if IsMDIChild and Assigned(LCLObject) and
|
||
(getWindowState and QtWindowMinimized <> 0) then
|
||
begin
|
||
Msg.Width := Word(LCLObject.Width);
|
||
Msg.Height := Word(LCLObject.Height);
|
||
end else
|
||
begin
|
||
Msg.Width := Word(getWidth);
|
||
Msg.Height := Word(getHeight);
|
||
end;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
procedure TQtMainWindow.setShowInTaskBar(AValue: Boolean);
|
||
begin
|
||
FShowOnTaskBar := AValue;
|
||
{$IFNDEF HASX11}
|
||
if not QWidget_isModal(Widget) then
|
||
UpdateParent;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TQtMainWindow.setRealPopupParent(NewParent: QWidgetH);
|
||
begin
|
||
FPopupParent := NewParent;
|
||
UpdateParent;
|
||
end;
|
||
|
||
function TQtMainWindow.WinIDNeeded: boolean;
|
||
begin
|
||
Result := False;
|
||
{$IFDEF HASX11}
|
||
if Assigned(LCLObject) and not IsFormDesign(LCLObject) and
|
||
not IsMdiChild and (LCLObject.Parent = nil) and not testAttribute(QtWA_Mapped) and
|
||
QWidget_isTopLevel(Widget) then
|
||
Result := True;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TQtMainWindow.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
FCWEventHook := nil;
|
||
{$ENDIF}
|
||
if (FCentralWidget <> nil)
|
||
{$IFDEF QTSCROLLABLEFORMS} and not Assigned(ScrollArea){$ENDIF} then
|
||
begin
|
||
FCWEventHook := QObject_hook_create(FCentralWidget);
|
||
QObject_hook_hook_events(FCWEventHook, @CWEventFilter);
|
||
end;
|
||
if IsMDIChild then
|
||
begin
|
||
FMDIStateHook := QMdiSubWindow_hook_create(Widget);
|
||
QMdiSubWindow_hook_hook_windowStateChanged(FMDIStateHook,
|
||
@MDIChildWindowStateChanged);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtMainWindow.DetachEvents;
|
||
begin
|
||
if FCWEventHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FCWEventHook);
|
||
FCWEventHook := nil;
|
||
end;
|
||
|
||
if FMDIStateHook <> nil then
|
||
begin
|
||
QMdiSubWindow_hook_destroy(FMDIStateHook);
|
||
FMDIStateHook := nil;
|
||
end;
|
||
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtMainWindow.CWEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
R: TRect;
|
||
R2: TRect;
|
||
i: Integer;
|
||
begin
|
||
Result := False;
|
||
|
||
if LCLObject <> nil then
|
||
begin
|
||
case QEvent_type(Event) of
|
||
QEventPaint: Result := inherited EventFilter(Sender, Event);
|
||
QEventResize:
|
||
begin
|
||
{mdi area part begins}
|
||
if MdiAreaHandle <> nil then
|
||
begin
|
||
{first must get contents rect - all except main menu}
|
||
QWidget_contentsRect(FCentralWidget, @R);
|
||
{TODO: find better way to find out which controls are top,left,right & bottom aligned ...}
|
||
for i := 0 to LCLObject.ControlCount - 1 do
|
||
begin
|
||
if (LCLObject.Controls[i] is TWinControl) and
|
||
(TWinControl(LCLObject.Controls[i]).Align in [alTop, alLeft, alRight, alBottom]) then
|
||
begin
|
||
R2 := TWinControl(LCLObject.Controls[i]).BoundsRect;
|
||
case TWinControl(LCLObject.Controls[i]).Align of
|
||
alLeft: R.Left := R.Left + (R2.Right - R2.Left);
|
||
alTop: R.Top := R.Top + (R2.Bottom - R2.Top);
|
||
alRight: R.Right := R.Right - (R2.Right - R2.Left);
|
||
alBottom: R.Bottom := R.Bottom - (R2.Bottom - R2.Top);
|
||
end;
|
||
end;
|
||
end; {components loop}
|
||
QWidget_setGeometry(MDIAreaHandle.Widget, @R);
|
||
end;
|
||
{mdi area part end}
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{ TQtStaticText }
|
||
|
||
function TQtStaticText.GetWordWrap: Boolean;
|
||
begin
|
||
Result := QLabel_wordWrap(QLabelH(Widget));
|
||
end;
|
||
|
||
procedure TQtStaticText.SetWordWrap(AValue: Boolean);
|
||
begin
|
||
QLabel_setWordWrap(QLabelH(Widget), AValue);
|
||
end;
|
||
|
||
function TQtStaticText.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtStaticText.Create');
|
||
{$endif}
|
||
FWidgetNeedFontColorInitialization := True;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QLabel_create(Parent);
|
||
end;
|
||
|
||
function TQtStaticText.CanPaintBackground: Boolean;
|
||
begin
|
||
Result := CanSendLCLMessage and getEnabled and
|
||
(LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtStaticText.SetText
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtStaticText.SetText(const W: WideString);
|
||
var
|
||
AmpersandPos: Integer;
|
||
LocalW: WideString;
|
||
begin
|
||
LocalW := W;
|
||
if TCustomStaticText(LCLObject).ShowAccelChar then
|
||
begin
|
||
// replace '&' by underline
|
||
AmpersandPos := Pos('&', W);
|
||
if AmpersandPos > 0 then
|
||
begin
|
||
LocalW := Copy(W, 1, AmpersandPos - 1) + '<u>';
|
||
if AmpersandPos < Length(W) then
|
||
LocalW := LocalW + W[AmpersandPos + 1];
|
||
LocalW := LocalW + '</u>' + Copy(W, AmpersandPos + 2, Length(W));
|
||
end;
|
||
end;
|
||
QLabel_setText(QLabelH(Widget), @LocalW);
|
||
end;
|
||
|
||
procedure TQtStaticText.setAlignment(const AAlignment: QtAlignment);
|
||
begin
|
||
QLabel_setAlignment(QLabelH(Widget), AAlignment);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtStaticText.Text
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtStaticText.getText: WideString;
|
||
begin
|
||
QLabel_text(QLabelH(Widget), @Result);
|
||
end;
|
||
|
||
{ TQtCheckBox }
|
||
|
||
function TQtCheckBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtCheckBox.Create');
|
||
{$endif}
|
||
TextColorRole := QPaletteWindowText;
|
||
FWidgetNeedFontColorInitialization := True;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
|
||
Result := QCheckBox_create(Parent);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCheckBox.CheckState
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtCheckBox.CheckState: QtCheckState;
|
||
begin
|
||
Result := QCheckBox_checkState(QCheckBoxH(Widget));
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCheckBox.setCheckState
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtCheckBox.setCheckState(state: QtCheckState);
|
||
begin
|
||
QCheckBox_setCheckState(QCheckBoxH(Widget), state);
|
||
end;
|
||
|
||
procedure TQtCheckBox.setTriState(AAllowGrayed: Boolean);
|
||
begin
|
||
QCheckBox_setTristate(QCheckBoxH(Widget), AAllowGrayed);
|
||
end;
|
||
|
||
procedure TQtCheckBox.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FStateChangedHook := QCheckBox_hook_create(Widget);
|
||
QCheckBox_hook_hook_stateChanged(FStateChangedHook, @SignalStateChanged);
|
||
end;
|
||
|
||
procedure TQtCheckBox.DetachEvents;
|
||
begin
|
||
if FStateChangedHook <> nil then
|
||
begin
|
||
QCheckBox_hook_destroy(FStateChangedHook);
|
||
FStateChangedHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCheckBox.signalStateChanged
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtCheckBox.signalStateChanged(p1: Integer); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
if not InUpdate then
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_CHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
end;
|
||
|
||
{ TQtRadioButton }
|
||
|
||
function TQtRadioButton.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtRadioButton.Create');
|
||
{$endif}
|
||
TextColorRole := QPaletteWindowText;
|
||
FWidgetNeedFontColorInitialization := True;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QRadioButton_create(Parent);
|
||
// hide widget by default
|
||
QWidget_hide(Result);
|
||
end;
|
||
|
||
procedure TQtRadioButton.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FToggledHook := QAbstractButton_hook_create(Widget);
|
||
QAbstractButton_hook_hook_toggled(FToggledHook, @SignalToggled);
|
||
end;
|
||
|
||
procedure TQtRadioButton.DetachEvents;
|
||
begin
|
||
if FToggledHook <> nil then
|
||
begin
|
||
QAbstractButton_hook_destroy(FToggledHook);
|
||
FToggledHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
procedure TQtRadioButton.SignalToggled(Checked: Boolean); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
if not InUpdate then
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_CHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
end;
|
||
|
||
function TQtRadioButton.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
begin
|
||
Result := inherited EventFilter(Sender, Event);
|
||
if (LCLObject <> nil) and
|
||
((QEvent_type(Event) in [QEventMouseButtonPress, QEventMouseButtonRelease])
|
||
or
|
||
((QEvent_type(Event) in [QEventKeyPress, QEventKeyRelease]) and
|
||
(QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
|
||
isChecked))
|
||
then
|
||
Result := False;
|
||
end;
|
||
|
||
{ TQtGroupBox }
|
||
|
||
procedure TQtGroupBox.setLayoutThemeMargins(ALayout: QLayoutH; AWidget: QWidgetH);
|
||
var
|
||
LeftMargin: Integer;
|
||
TopMargin: Integer;
|
||
RightMargin: Integer;
|
||
BottomMargin, AStyleMetric: Integer;
|
||
begin
|
||
if ALayout = nil then
|
||
exit;
|
||
QWidget_getContentsMargins(AWidget,@LeftMargin, @TopMargin, @RightMargin, @BottomMargin);
|
||
|
||
AStyleMetric := QStyle_pixelMetric(QApplication_style(), QStyleSE_DockWidgetTitleBarText, nil, Widget);
|
||
|
||
{issue #37576}
|
||
{if (AStyle = 'fusion') or (AStyle = 'gtk2') or
|
||
(AStyle = 'qt5ct-style') then}
|
||
if AStyleMetric = 0 then
|
||
else
|
||
if (getText = '') then
|
||
TopMargin := BottomMargin;
|
||
|
||
QLayout_setContentsMargins(ALayout, LeftMargin, TopMargin, RightMargin, BottomMargin);
|
||
QLayout_invalidate(ALayout);
|
||
|
||
if (LCLObject <> nil) and testAttribute(QtWA_Mapped) then
|
||
begin
|
||
{$IFDEF VerboseQtResize}
|
||
DebugLn('TQtGroupBox.setLayoutThemeMargins: ',dbgsName(LCLObject),' casp: ',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' mapped ',dbgs(testAttribute(QtWA_Mapped)));
|
||
{$ENDIF}
|
||
LCLObject.DoAdjustClientRectChange(False);
|
||
LCLObject.InvalidateClientRectCache(True);
|
||
end;
|
||
end;
|
||
|
||
function TQtGroupBox.GetCheckBoxVisible: boolean;
|
||
begin
|
||
Result := QGroupBox_isCheckable(QGroupBoxH(Widget));
|
||
end;
|
||
|
||
function TQtGroupBox.GetCheckBoxState: boolean;
|
||
begin
|
||
Result := CheckBoxVisible and QGroupBox_isChecked(QGroupBoxH(Widget));
|
||
end;
|
||
|
||
procedure TQtGroupBox.SetCheckBoxState(AValue: boolean);
|
||
begin
|
||
if CheckBoxVisible then
|
||
QGroupBox_setChecked(QGroupBoxH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtGroupBox.SetCheckBoxVisible(AValue: boolean);
|
||
begin
|
||
QGroupBox_setCheckable(QGroupBoxH(Widget), AValue);
|
||
end;
|
||
|
||
function TQtGroupBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Layout: QBoxLayoutH;
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtGroupBox.Create ');
|
||
{$endif}
|
||
FGroupBoxType := tgbtNormal;
|
||
FHasPaint := True;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QGroupBox_create(Parent);
|
||
FCentralWidget := QStackedWidget_create(Result);
|
||
QWidget_setMouseTracking(FCentralWidget, True);
|
||
{we set QtNoFocus by default, since we don't want
|
||
FCentralWidget grabs focus on mouse click}
|
||
QWidget_setFocusPolicy(FCentralWidget, QtNoFocus);
|
||
|
||
Layout := QVBoxLayout_create(Result);
|
||
QLayout_addWidget(Layout, FCentralWidget);
|
||
QWidget_setLayout(Result, QLayoutH(Layout));
|
||
QWidget_setAttribute(Result, QtWA_LayoutOnEntireRect, True);
|
||
end;
|
||
|
||
procedure TQtGroupBox.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
if FCentralWidget <> nil then
|
||
begin
|
||
FCWEventHook := QObject_hook_create(FCentralWidget);
|
||
QObject_hook_hook_events(FCWEventHook, @EventFilter);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtGroupBox.DetachEvents;
|
||
begin
|
||
if FCWEventHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FCWEventHook);
|
||
FCWEventHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtGroupBox.CanPaintBackground: Boolean;
|
||
begin
|
||
Result := CanSendLCLMessage and getEnabled and
|
||
(LCLObject.Color <> clDefault);
|
||
end;
|
||
|
||
function TQtGroupBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
var
|
||
ResizeEvent: QResizeEventH;
|
||
NewSize, OldSize: TSize;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject = nil then
|
||
exit;
|
||
|
||
if (Sender = FCentralWidget) then
|
||
begin
|
||
case QEvent_type(Event) of
|
||
QEventPaint: Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
exit;
|
||
end;
|
||
{For possible problems with Mouse events check issue #29572 and #32186}
|
||
case QEvent_type(Event) of
|
||
QEventPaint:
|
||
begin
|
||
Result := False;
|
||
// paint complete background, like gtk2 does
|
||
if CanPaintBackground then
|
||
SlotPaintBg(Sender, Event);
|
||
// issue #28155, we are painting our FCentralWidget, not QGroupBox
|
||
// Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
QEventFontChange:
|
||
begin
|
||
Result := inherited EventFilter(Sender, Event);
|
||
setLayoutThemeMargins(QWidget_layout(Widget), Widget);
|
||
end;
|
||
QEventStyleChange: setLayoutThemeMargins(QWidget_layout(Widget), Widget);
|
||
QEventContentsRectChange:
|
||
begin
|
||
if testAttribute(QtWA_Mapped) then
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
QEventShow:
|
||
begin
|
||
{$IFDEF VerboseQtResize}
|
||
DebugLn('TQtGroupBox.QEventShow: ',dbgsName(LCLObject),' casp=',dbgs(caspComputingBounds in LCLObject.AutoSizePhases),' mapped=',dbgs(testAttribute(QtWA_Mapped)));
|
||
{$ENDIF}
|
||
LCLObject.DoAdjustClientRectChange(False);
|
||
SlotShow(True);
|
||
{send dummy LM_SIZE to LCL}
|
||
if (FGroupBoxType <> tgbtNormal) and
|
||
LCLObject.ClientRectNeedsInterfaceUpdate then
|
||
begin
|
||
OldSize.cx := LCLObject.Height;
|
||
OldSize.cy := LCLObject.Width;
|
||
NewSize := OldSize;
|
||
inc(OldSize.cx);
|
||
inc(OldSize.cy);
|
||
ResizeEvent := QResizeEvent_create(@NewSize, @OldSize);
|
||
QCoreApplication_postEvent(Widget, ResizeEvent, -1);
|
||
end;
|
||
end;
|
||
else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
end;
|
||
|
||
function TQtGroupBox.getClientBounds: TRect;
|
||
var
|
||
R, R1: TRect;
|
||
L: Integer;
|
||
T: Integer;
|
||
aRight: Integer;
|
||
B: Integer;
|
||
AStyleOption: QStyleOptionGroupBoxH;
|
||
APixelMetric: Integer;
|
||
begin
|
||
QWidget_contentsRect(Widget, @R);
|
||
if Assigned(FCentralWidget) then
|
||
QWidget_rect(FCentralWidget, @R1)
|
||
else
|
||
R1 := Rect(0, 0, 0, 0);
|
||
Result := R;
|
||
OffsetRect(Result, -Result.Left, -Result.Top);
|
||
{$IFNDEF HASX11}
|
||
if testAttribute(QtWA_Mapped) and QWidget_testAttribute(FCentralWidget, QtWA_Mapped) then
|
||
QWidget_rect(FCentralWidget, @Result)
|
||
else
|
||
{$ENDIF}
|
||
begin
|
||
if Assigned(FCentralWidget) and not IsRectEmpty(R1) then
|
||
begin
|
||
R := R1;
|
||
R1.Left := 0;
|
||
R1.Top := 0;
|
||
R1.Right := R1.Right - R.Left;
|
||
R1.Bottom := R1.Bottom - R.Top;
|
||
QWidget_getContentsMargins(Widget,@L, @T, @aRight, @B);
|
||
AStyleOption := QStyleOptionGroupBox_create;
|
||
APixelMetric := QStyle_pixelMetric(QApplication_style(), QStylePM_DefaultChildMargin, AStyleOption, Widget);
|
||
if APixelMetric = 4 then
|
||
APixelMetric := 9
|
||
else
|
||
APixelMetric := 0;
|
||
QStyleOptionGroupBox_destroy(AStyleOption);
|
||
inc(Result.Bottom, APixelMetric);
|
||
{$IFDEF VerboseQtResize}
|
||
DebugLn('>>>>>>>>>>> TQtGroupBox.getClientBounds(',dbgsName(LCLObject),') setting clientBounds was ',dbgs(R),' changed to ',dbgs(R1),' from result ',dbgs(Result));
|
||
DebugLn(' MARGINS ARE ',Format('l %d t %d r %d b %d',[L, T, ARight, B]),' APixelMetric=',dbgs(APixelMetric));
|
||
{$ENDIF}
|
||
exit;
|
||
end;
|
||
end;
|
||
{$IFDEF VerboseQtResize}
|
||
DebugLn('TQtGroupBox.getClientBounds(',dbgsName(LCLObject),') R=',dbgs(R),' Result=',dbgs(Result),' CENTRALWIDGET=',dbgs(R1),' mapped ',dbgs(testAttribute(QtWA_Mapped)));
|
||
{$ENDIF}
|
||
end;
|
||
|
||
function TQtGroupBox.getText: WideString;
|
||
begin
|
||
QGroupBox_title(QGroupBoxH(Widget), @Result);
|
||
end;
|
||
|
||
procedure TQtGroupBox.preferredSize(var PreferredWidth,
|
||
PreferredHeight: integer; WithThemeSpace: Boolean);
|
||
var
|
||
L, T, R, B: Integer;
|
||
ASize: TSize;
|
||
begin
|
||
if WithThemeSpace then
|
||
QWidget_getContentsMargins(Widget,@L, @T, @R, @B)
|
||
else
|
||
begin
|
||
L := 0;
|
||
T := 0;
|
||
R := 0;
|
||
B := 0;
|
||
end;
|
||
QGroupBox_minimumSizeHint(QGroupBoxH(Widget), @ASize);
|
||
PreferredWidth := ASize.cx + L + R;
|
||
PreferredHeight := ASize.cy + B + T;
|
||
{$IFDEF VerboseQtResize}
|
||
DebugLn('TQtGroupBox.preferredSize(',dbgsName(LCLObject),' PrefW=',dbgs(PreferredWidth),
|
||
' PrefH=',dbgs(PreferredHeight),' Mapped ? ',dbgs(testAttribute(QtWA_Mapped)),
|
||
' SizeHint ',dbgs(ASize),' casp ',dbgs(caspComputingBounds in LCLObject.AutoSizePhases));
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TQtGroupBox.setText(const W: WideString);
|
||
begin
|
||
QGroupBox_setTitle(QGroupBoxH(Widget), @W);
|
||
setLayoutThemeMargins(QWidget_Layout(Widget), Widget);
|
||
end;
|
||
|
||
procedure TQtGroupBox.setFocusPolicy(const APolicy: QtFocusPolicy);
|
||
begin
|
||
if Assigned(LCLObject) and not LCLObject.TabStop then
|
||
inherited setFocusPolicy(QtNoFocus)
|
||
else
|
||
inherited setFocusPolicy(APolicy);
|
||
end;
|
||
|
||
procedure TQtGroupBox.Update(ARect: PRect);
|
||
var
|
||
P: TPoint;
|
||
R: TRect;
|
||
begin
|
||
if Assigned(FCentralWidget) then
|
||
begin
|
||
if ARect <> nil then
|
||
begin
|
||
P := getClientOffset;
|
||
R := ARect^;
|
||
OffsetRect(R, -P.X, -P.Y);
|
||
QWidget_update(FCentralWidget, @R);
|
||
end else
|
||
QWidget_update(FCentralWidget);
|
||
end else
|
||
inherited Update(ARect);
|
||
end;
|
||
|
||
procedure TQtGroupBox.UpdateRegion(ARgn: QRegionH);
|
||
var
|
||
P: TPoint;
|
||
begin
|
||
if Assigned(FCentralWidget) then
|
||
begin
|
||
if ARgn <> nil then
|
||
begin
|
||
P := getClientOffset;
|
||
QRegion_translate(ARgn, -P.X, -P.Y);
|
||
QWidget_update(FCentralWidget, ARgn)
|
||
end else
|
||
QWidget_update(FCentralWidget);
|
||
end else
|
||
inherited UpdateRegion(ARgn);
|
||
end;
|
||
|
||
procedure TQtGroupBox.Repaint(ARect: PRect);
|
||
var
|
||
P: TPoint;
|
||
R: TRect;
|
||
begin
|
||
if Assigned(FCentralWidget) then
|
||
begin
|
||
if ARect <> nil then
|
||
begin
|
||
P := getClientOffset;
|
||
R := ARect^;
|
||
OffsetRect(R, -P.X, -P.Y);
|
||
QWidget_repaint(FCentralWidget, @R);
|
||
end else
|
||
QWidget_repaint(FCentralWidget);
|
||
end else
|
||
inherited Repaint(ARect);
|
||
end;
|
||
|
||
{ TQtFrame }
|
||
|
||
function TQtFrame.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtFrame.Create');
|
||
{$endif}
|
||
FHasPaint := True;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QFrame_create(Parent);
|
||
end;
|
||
|
||
function TQtFrame.CanPaintBackground: Boolean;
|
||
begin
|
||
Result := CanSendLCLMessage and {getEnabled and}
|
||
(LCLObject.Color <> clBackground) and (LCLObject.Color <> clDefault);
|
||
end;
|
||
|
||
procedure TQtFrame.SlotPaintBg(Sender: QObjectH; Event: QEventH); cdecl;
|
||
var
|
||
Painter: QPainterH;
|
||
Brush: QBrushH;
|
||
Color: TQColor;
|
||
R: TRect;
|
||
begin
|
||
if CanSendLCLMessage and (LCLObject is TWinControl) then
|
||
begin
|
||
if LCLObject.Color = clDefault then
|
||
Color := Palette.DefaultColor
|
||
else
|
||
ColorRefToTQColor(ColorToRGB(LCLObject.Color), Color);
|
||
Painter := QPainter_create(QWidget_to_QPaintDevice(QWidgetH(Sender)));
|
||
Brush := QBrush_create(@Color, QtSolidPattern);
|
||
try
|
||
QPaintEvent_rect(QPaintEventH(Event), @R);
|
||
QPainter_fillRect(Painter, @R, Brush);
|
||
if (LCLObject is TCustomPanel) and (TCustomPanel(LCLObject).BorderStyle <> bsNone) then
|
||
q_DrawShadePanel(Painter, PRect(@R), Palette.Handle, True, 2);
|
||
QPainter_end(Painter);
|
||
finally
|
||
QBrush_destroy(Brush);
|
||
QPainter_destroy(Painter);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtFrame.setFocusPolicy(const APolicy: QtFocusPolicy);
|
||
begin
|
||
if Assigned(LCLObject) and not LCLObject.TabStop then
|
||
inherited setFocusPolicy(QtNoFocus)
|
||
else
|
||
inherited setFocusPolicy(APolicy);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtFrame.setFrameStyle
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtFrame.setFrameStyle(p1: Integer);
|
||
begin
|
||
QFrame_setFrameStyle(QFrameH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtFrame.setFrameShape
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtFrame.setFrameShape(p1: QFrameShape);
|
||
begin
|
||
QFrame_setFrameShape(QFrameH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtFrame.setFrameShadow
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtFrame.setFrameShadow(p1: QFrameShadow);
|
||
begin
|
||
QFrame_setFrameShadow(QFrameH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtArrow.CreateWidget
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtArrow.CreateWidget(const AParams: TCreateParams):QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtArrow.Create');
|
||
{$endif}
|
||
FHasPaint := True;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QFrame_create(Parent);
|
||
end;
|
||
|
||
function TQtAbstractSlider.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtAbstractSlider.Create');
|
||
{$endif}
|
||
|
||
FSliderPressed := False;
|
||
FSliderReleased:= False;
|
||
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QAbstractSlider_create(Parent);
|
||
end;
|
||
|
||
procedure TQtAbstractSlider.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FRangeChangedHook := QAbstractSlider_hook_create(Widget);
|
||
FSliderMovedHook := QAbstractSlider_hook_create(Widget);
|
||
FSliderPressedHook := QAbstractSlider_hook_create(Widget);
|
||
FSliderReleasedHook := QAbstractSlider_hook_create(Widget);
|
||
FValueChangedHook := QAbstractSlider_hook_create(Widget);
|
||
FActionTriggeredHook := QAbstractSlider_hook_create(Widget);
|
||
end;
|
||
|
||
procedure TQtAbstractSlider.DetachEvents;
|
||
begin
|
||
if FRangeChangedHook <> nil then
|
||
begin
|
||
QAbstractSlider_hook_destroy(FRangeChangedHook);
|
||
FRangeChangedHook := nil;
|
||
end;
|
||
if FSliderMovedHook <> nil then
|
||
begin
|
||
QAbstractSlider_hook_destroy(FSliderMovedHook);
|
||
FSliderMovedHook := nil;
|
||
end;
|
||
if FSliderPressedHook <> nil then
|
||
begin
|
||
QAbstractSlider_hook_destroy(FSliderPressedHook);
|
||
FSliderPressedHook := nil;
|
||
end;
|
||
if FSliderReleasedHook <> nil then
|
||
begin
|
||
QAbstractSlider_hook_destroy(FSliderReleasedHook);
|
||
FSliderReleasedHook := nil;
|
||
end;
|
||
if FValueChangedHook <> nil then
|
||
begin
|
||
QAbstractSlider_hook_destroy(FValueChangedHook);
|
||
FValueChangedHook := nil;
|
||
end;
|
||
if FActionTriggeredHook <> nil then
|
||
begin
|
||
QAbstractSlider_hook_destroy(FActionTriggeredHook);
|
||
FActionTriggeredHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtAbstractSlider.getValue: Integer;
|
||
begin
|
||
Result := QAbstractSlider_value(QAbstractSliderH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractSlider.getPageStep: Integer;
|
||
begin
|
||
Result := QAbstractSlider_pageStep(QAbstractSliderH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractSlider.getMin: Integer;
|
||
begin
|
||
Result := QAbstractSlider_minimum(QAbstractSliderH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractSlider.getMax: Integer;
|
||
begin
|
||
Result := QAbstractSlider_maximum(QAbstractSliderH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractSlider.getSingleStep: Integer;
|
||
begin
|
||
Result := QAbstractSlider_singleStep(QAbstractSliderH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractSlider.getSliderDown: Boolean;
|
||
begin
|
||
Result := QAbstractSlider_isSliderDown(QAbstractSliderH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractSlider.getSliderPosition: Integer;
|
||
begin
|
||
Result := QAbstractSlider_sliderPosition(QAbstractSliderH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractSlider.getTracking: Boolean;
|
||
begin
|
||
Result := QAbstractSlider_hasTracking(QAbstractSliderH(Widget));
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.rangeChanged
|
||
Params: minimum,maximum: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.SlotRangeChanged(minimum: Integer; maximum: Integer); cdecl;
|
||
begin
|
||
{ TODO: find out what needs to be done on rangeChanged event
|
||
Possibilities: repaint or recount pageSize() }
|
||
{$ifdef VerboseQt}
|
||
writeln('TQtAbstractSlider.rangeChanged() to min=',minimum,' max=',maximum);
|
||
{$endif}
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setInvertedAppereance
|
||
Params: p1: Boolean
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setInvertedAppereance(p1: Boolean);
|
||
begin
|
||
QAbstractSlider_setInvertedAppearance(QAbstractSliderH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setInvertedControls
|
||
Params: p1: Boolean
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setInvertedControls(p1: Boolean);
|
||
begin
|
||
QAbstractSlider_setInvertedControls(QAbstractSliderH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setMaximum
|
||
Params: p1: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setMaximum(p1: Integer);
|
||
begin
|
||
QAbstractSlider_setMaximum(QAbstractSliderH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setMinimum
|
||
Params: p1: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setMinimum(p1: Integer);
|
||
begin
|
||
QAbstractSlider_setMinimum(QAbstractSliderH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setOrientation
|
||
Params: p1: QtOrientation (QtHorizontal or QtVertical)
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setOrientation(p1: QtOrientation);
|
||
begin
|
||
QAbstractSlider_setOrientation(QAbstractSliderH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setPageStep
|
||
Params: p1: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setPageStep(p1: Integer);
|
||
begin
|
||
QAbstractSlider_setPageStep(QAbstractSliderH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setRange
|
||
Params: minimum,maximum: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setRange(minimum: Integer; maximum: Integer);
|
||
begin
|
||
QAbstractSlider_setRange(QAbstractSliderH(Widget), minimum, maximum);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setSingleStep
|
||
Params: p1: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setSingleStep(p1: Integer);
|
||
begin
|
||
QAbstractSlider_setSingleStep(QAbstractSliderH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setSliderDown
|
||
Params: p1: Boolean
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setSliderDown(p1: Boolean);
|
||
begin
|
||
QAbstractSlider_setSliderDown(QAbstractSliderH(Widget), p1);
|
||
end;
|
||
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setSliderPosition
|
||
Params: p1: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setSliderPosition(p1: Integer);
|
||
begin
|
||
QAbstractSlider_setSliderPosition(QAbstractSliderH(Widget), p1);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setTracking
|
||
Params: p1: Boolean
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setTracking(p1: Boolean);
|
||
begin
|
||
QAbstractSlider_setTracking(QAbstractSliderH(Widget), p1);
|
||
end;
|
||
|
||
{-----------------------------------------------------------------------------
|
||
Function: TQtAbstractSlider.setValue
|
||
Params: p1: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractSlider.setValue(p1: Integer);
|
||
begin
|
||
QAbstractSlider_setValue(QAbstractSliderH(Widget), p1);
|
||
end;
|
||
|
||
procedure TQtAbstractSlider.SlotSliderMoved(p1: Integer); cdecl;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
writeln('TQtAbstractSlider.sliderMoved() to pos=',p1);
|
||
{$endif}
|
||
|
||
// there's no need to deliver this message
|
||
// since ValueChanged does it's job correct, also for tracking on/off
|
||
// this signal must stay empty because of ttrackbar !
|
||
end;
|
||
|
||
procedure TQtAbstractSlider.SlotSliderPressed; cdecl;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
writeln('TQtAbstractSlider.sliderPressed()');
|
||
{$endif}
|
||
FSliderPressed := True;
|
||
FSliderReleased := False;
|
||
end;
|
||
|
||
procedure TQtAbstractSlider.SlotSliderReleased; cdecl;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
writeln('TQtAbstractSlider.sliderReleased()');
|
||
{$endif}
|
||
FSliderPressed := False;
|
||
FSliderReleased := True;
|
||
end;
|
||
|
||
function TQtAbstractSlider.CanChangeFontColor: Boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
function TQtAbstractSlider.getInvertedAppereance: Boolean;
|
||
begin
|
||
Result := QAbstractSlider_invertedAppearance(QAbstractSliderH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractSlider.getInvertedControls: Boolean;
|
||
begin
|
||
Result := QAbstractSlider_invertedControls(QAbstractSliderH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractSlider.getOrientation: QtOrientation;
|
||
begin
|
||
Result := QAbstractSlider_orientation(QAbstractSliderH(Widget));
|
||
end;
|
||
|
||
procedure TQtAbstractSlider.SlotValueChanged(p1: Integer); cdecl;
|
||
var
|
||
LMScroll: TLMScroll;
|
||
b: Boolean;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
writeln('TQtAbstractSlider.SlotValueChanged() to value ',p1,' inUpdate ',inUpdate,' maxIs ',getMax,
|
||
' FChildOfComplexWidget ',FChildOfComplexWidget);
|
||
{$endif}
|
||
|
||
FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
|
||
|
||
LMScroll.ScrollBar := PtrUInt(Self);
|
||
|
||
if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
|
||
LMScroll.Msg := LM_HSCROLL
|
||
else
|
||
LMScroll.Msg := LM_VSCROLL;
|
||
|
||
LMScroll.Pos := p1;
|
||
LMScroll.ScrollCode := SIF_POS;
|
||
|
||
if not InUpdate then
|
||
DeliverMessage(LMScroll);
|
||
|
||
b := p1 = getMax;
|
||
|
||
if not InUpdate or (getVisible and ((p1=getMin) or b)) then
|
||
begin
|
||
if b and (FChildOfComplexWidget = ccwAbstractScrollArea) and
|
||
not InUpdate and getVisible then
|
||
QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
|
||
QAbstractSliderSliderToMaximum);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtAbstractSlider.SlotActionTriggered(action: Integer); cdecl;
|
||
const
|
||
SliderActions: Array[0..7] of QAbstractSliderSliderAction = (
|
||
QAbstractSliderSliderNoAction, QAbstractSliderSliderSingleStepAdd,
|
||
QAbstractSliderSliderSingleStepSub, QAbstractSliderSliderPageStepAdd,
|
||
QAbstractSliderSliderPageStepSub, QAbstractSliderSliderToMinimum,
|
||
QAbstractSliderSliderToMaximum, QAbstractSliderSliderMove );
|
||
var
|
||
LMScroll: TLMScroll;
|
||
SliderAction: QAbstractSliderSliderAction;
|
||
begin
|
||
|
||
if InUpdate then
|
||
exit;
|
||
|
||
{$ifdef VerboseQt}
|
||
writeln('TQtAbstractSlider.SlotActionTriggered() action = ',action,' inUpdate ',inUpdate);
|
||
{$endif}
|
||
|
||
FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
|
||
|
||
LMScroll.ScrollBar := PtrUInt(Self);
|
||
|
||
if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
|
||
LMScroll.Msg := LM_HSCROLL
|
||
else
|
||
LMScroll.Msg := LM_VSCROLL;
|
||
|
||
if SliderPressed then
|
||
LMScroll.Pos := getSliderPosition
|
||
else
|
||
LMScroll.Pos := getValue;
|
||
|
||
SliderAction := SliderActions[Action];
|
||
|
||
case SliderAction of
|
||
QAbstractSliderSliderNoAction:
|
||
begin
|
||
// this is called from mouse release while qt still thinks that
|
||
// slider is pressed, we must update position.issue #14728, #21610
|
||
if getSliderDown then
|
||
begin
|
||
LMScroll.ScrollCode := SB_THUMBPOSITION;
|
||
DeliverMessage(LMScroll);
|
||
end;
|
||
LMScroll.ScrollCode := SB_ENDSCROLL;
|
||
end;
|
||
QAbstractSliderSliderSingleStepAdd:
|
||
begin
|
||
if LMScroll.Msg = LM_HSCROLL then
|
||
LMScroll.ScrollCode := SB_LINERIGHT
|
||
else
|
||
LMScroll.ScrollCode := SB_LINEDOWN;
|
||
end;
|
||
QAbstractSliderSliderSingleStepSub:
|
||
begin
|
||
if LMScroll.Msg = LM_HSCROLL then
|
||
LMScroll.ScrollCode := SB_LINELEFT
|
||
else
|
||
LMScroll.ScrollCode := SB_LINEUP;
|
||
end;
|
||
QAbstractSliderSliderPageStepAdd:
|
||
begin
|
||
if LMScroll.Msg = LM_HSCROLL then
|
||
LMScroll.ScrollCode := SB_PAGERIGHT
|
||
else
|
||
LMScroll.ScrollCode := SB_PAGEDOWN;
|
||
end;
|
||
QAbstractSliderSliderPageStepSub:
|
||
begin
|
||
if LMScroll.Msg = LM_HSCROLL then
|
||
LMScroll.ScrollCode := SB_PAGELEFT
|
||
else
|
||
LMScroll.ScrollCode := SB_PAGEUP;
|
||
end;
|
||
QAbstractSliderSliderToMinimum:
|
||
begin
|
||
if LMScroll.Msg = LM_HSCROLL then
|
||
LMScroll.ScrollCode := SB_LEFT
|
||
else
|
||
LMScroll.ScrollCode := SB_TOP;
|
||
end;
|
||
QAbstractSliderSliderToMaximum:
|
||
begin
|
||
// issue #21610
|
||
// if we are reaching maximum with eg. mouse wheel
|
||
// and our parent is TScrollingWinControl then update thumbposition.
|
||
if not getSliderDown then
|
||
begin
|
||
LMScroll.ScrollCode := SB_THUMBPOSITION;
|
||
DeliverMessage(LMScroll);
|
||
end;
|
||
|
||
if LMScroll.Msg = LM_HSCROLL then
|
||
LMScroll.ScrollCode := SB_RIGHT
|
||
else
|
||
LMScroll.ScrollCode := SB_BOTTOM;
|
||
end;
|
||
QAbstractSliderSliderMove:
|
||
begin
|
||
if getTracking then
|
||
LMScroll.ScrollCode := SB_THUMBTRACK
|
||
else
|
||
if not getSliderDown then
|
||
LMScroll.ScrollCode := SB_THUMBPOSITION;
|
||
end;
|
||
end;
|
||
|
||
DeliverMessage(LMScroll);
|
||
end;
|
||
|
||
{ TQtScrollBar }
|
||
|
||
function TQtScrollBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtScrollBar.Create');
|
||
{$endif}
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
FTrackPos := 0;
|
||
Result := QScrollBar_create(Parent);
|
||
QWidget_setFocusPolicy(Result, QtNoFocus);
|
||
FHasPaint := True;
|
||
end;
|
||
|
||
procedure TQtScrollBar.preferredSize(var PreferredWidth,
|
||
PreferredHeight: integer; WithThemeSpace: Boolean);
|
||
var
|
||
Size: TSize;
|
||
begin
|
||
QScrollBar_sizeHint(QScrollBarH(Widget), @Size);
|
||
PreferredWidth := Size.cx;
|
||
PreferredHeight := Size.cy;
|
||
end;
|
||
|
||
procedure TQtScrollBar.setFocusPolicy(const APolicy: QtFocusPolicy);
|
||
begin
|
||
if FOwnWidget and Assigned(LCLObject) and not LCLObject.TabStop then
|
||
inherited setFocusPolicy(QtNoFocus)
|
||
else
|
||
inherited setFocusPolicy(APolicy);
|
||
end;
|
||
|
||
procedure TQtScrollBar.SlotSliderReleased; cdecl;
|
||
var
|
||
AValue: Integer;
|
||
LMScroll: TLMScroll;
|
||
begin
|
||
inherited SlotSliderReleased;
|
||
if
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
((ChildOfComplexWidget = ccwAbstractScrollArea) and (FOwner <> nil) and
|
||
(FOwner is TQtWindowArea)) or
|
||
{$ENDIF}
|
||
((ChildOfComplexWidget = ccwAbstractScrollArea) and (FOwner <> nil) and
|
||
(FOwner.ChildOfComplexWidget in [ccwCustomControl])) then
|
||
begin
|
||
AValue := getValue;
|
||
if AValue <= getMin then
|
||
QAbstractSlider_triggerAction(QAbstractSliderH(Widget), QAbstractSliderSliderToMinimum)
|
||
else
|
||
if AValue >= getMax then
|
||
QAbstractSlider_triggerAction(QAbstractSliderH(Widget), QAbstractSliderSliderToMaximum)
|
||
else
|
||
begin
|
||
FillChar(LMScroll{%H-}, SizeOf(LMScroll), #0);
|
||
|
||
LMScroll.ScrollBar := PtrUInt(Self);
|
||
|
||
if QAbstractSlider_orientation(QAbstractSliderH(Widget)) = QtHorizontal then
|
||
LMScroll.Msg := LM_HSCROLL
|
||
else
|
||
LMScroll.Msg := LM_VSCROLL;
|
||
|
||
LMScroll.Pos := getSliderPosition;
|
||
if not GetTracking then
|
||
LMScroll.ScrollCode := SB_THUMBPOSITION
|
||
else
|
||
LMScroll.ScrollCode := SB_THUMBTRACK;
|
||
DeliverMessage(LMScroll);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TQtScrollBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
|
||
if LCLObject = nil then
|
||
exit;
|
||
|
||
case QEvent_type(Event) of
|
||
{if any of those events returs TRUE our scrollbar becomes invisible.}
|
||
QEventMouseMove,
|
||
QEventWheel,
|
||
QEventPaint,
|
||
QEventKeyPress,
|
||
QEventKeyRelease:
|
||
begin
|
||
if FOwnWidget and (FOwner = nil) and
|
||
((QEvent_type(Event) = QEventKeyPress) or
|
||
(QEvent_type(Event) = QEventKeyRelease)) then
|
||
Result := inherited EventFilter(Sender, Event)
|
||
else
|
||
if (QEvent_type(Event) = QEventWheel) and Assigned(FOwner) and
|
||
(
|
||
(FOwner is TQtAbstractScrollArea)
|
||
) then
|
||
begin
|
||
|
||
// issue #25992
|
||
if not getVisible then
|
||
Result := FOwner.SlotMouseWheel(FOwner.Widget, Event)
|
||
else
|
||
begin
|
||
// issue #27675.Do not send wheel event from cbox when dropped down.
|
||
// LCL thinks that combobox sent that event so we have undesirable effects.
|
||
if (FOwner.ChildOfComplexWidget = ccwComboBox) and getEnabled then
|
||
Result := False
|
||
else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
// do not scroll when disabled or issue #25992
|
||
if not getEnabled then
|
||
Result := True
|
||
else
|
||
if not getVisible then
|
||
begin
|
||
if {$IFDEF QTSCROLLABLEFORMS}(FOwner is TQtWindowArea) or {$ENDIF}
|
||
(FOwner.ChildOfComplexWidget in
|
||
[ccwScrollingWinControl, ccwScrollingWindow]) then
|
||
Result := True;
|
||
end;
|
||
end else
|
||
Result := False;
|
||
if (QEvent_type(Event) = QEventKeyRelease) and not
|
||
(QKeyEvent_isAutoRepeat(QKeyEventH(event))) then
|
||
begin
|
||
case QKeyEvent_key(QKeyEventH(Event)) of
|
||
QtKey_Left, QtKey_Up, QtKey_Right, QtKey_Down,
|
||
QtKey_PageUp, QtKey_PageDown, QtKey_Home, QtKey_End:
|
||
QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
|
||
QAbstractSliderSliderNoAction);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
QEventMouseButtonRelease:
|
||
QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
|
||
QAbstractSliderSliderNoAction);
|
||
else
|
||
if FOwnWidget then
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtScrollBar.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
QAbstractSlider_hook_hook_rangeChanged(FRangeChangedHook, @SlotRangeChanged);
|
||
|
||
QAbstractSlider_hook_hook_sliderMoved(FSliderMovedHook, @SlotSliderMoved);
|
||
|
||
QAbstractSlider_hook_hook_sliderPressed(FSliderPressedHook, @SlotSliderPressed);
|
||
|
||
QAbstractSlider_hook_hook_sliderReleased(FSliderReleasedHook, @SlotSliderReleased);
|
||
|
||
QAbstractSlider_hook_hook_valueChanged(FValueChangedHook, @SlotValueChanged);
|
||
|
||
QAbstractSlider_hook_hook_actionTriggered(FActionTriggeredHook, @SlotActionTriggered);
|
||
end;
|
||
|
||
{ TQtToolBar }
|
||
|
||
function TQtToolBar.CreateWidget(const AParams: TCreateParams):QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtToolBar.Create');
|
||
{$endif}
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QToolBar_create(Parent);
|
||
end;
|
||
|
||
{ TQtToolButton }
|
||
|
||
function TQtToolButton.CreateWidget(const AParams: TCreateParams):QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtToolButton.Create');
|
||
{$endif}
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QToolButton_create(Parent);
|
||
end;
|
||
|
||
{ TQtTrackBar }
|
||
|
||
function TQtTrackBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtTrackBar.Create');
|
||
{$endif}
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QSlider_create(Parent);
|
||
end;
|
||
|
||
function TQtTrackBar.getTickInterval: Integer;
|
||
begin
|
||
Result := QSlider_tickInterval(QSliderH(Widget));
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTrackBar.setTickPosition
|
||
Params: Value: QSliderTickPosition
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------ }
|
||
procedure TQtTrackBar.setTickPosition(Value: QSliderTickPosition);
|
||
begin
|
||
QSlider_setTickPosition(QSliderH(Widget), Value);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTrackBar.setTickInterval
|
||
Params: Value: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------ }
|
||
procedure TQtTrackBar.SetTickInterval(Value: Integer);
|
||
begin
|
||
QSlider_setTickInterval(QSliderH(Widget), Value);
|
||
end;
|
||
|
||
procedure TQtTrackBar.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
QAbstractSlider_hook_hook_sliderMoved(FSliderMovedHook, @SlotSliderMoved);
|
||
|
||
QAbstractSlider_hook_hook_sliderPressed(FSliderPressedHook, @SlotSliderPressed);
|
||
|
||
QAbstractSlider_hook_hook_sliderReleased(FSliderReleasedHook, @SlotSliderReleased);
|
||
|
||
QAbstractSlider_hook_hook_valueChanged(FValueChangedHook, @SlotValueChanged);
|
||
end;
|
||
|
||
procedure TQtTrackBar.SlotSliderMoved(p1: Integer); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
writeln('TQtTrackBar.SlotSliderMoved() p1=',p1);
|
||
{$endif}
|
||
if SliderPressed and not InUpdate then
|
||
begin
|
||
Msg.Msg := 0; // shutup compiler
|
||
FillChar(Msg, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_CHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTrackBar.SlotValueChanged(p1: Integer); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
writeln('TQtTrackBar.SlotValueChanged() p1=',p1);
|
||
{$endif}
|
||
|
||
if not SliderPressed and not InUpdate then
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_CHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
end;
|
||
|
||
{ TQtLineEdit }
|
||
|
||
function TQtLineEdit.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
FCachedSelectionStart := -1;
|
||
FCachedSelectionLen := -1;
|
||
FIntValidator := nil;
|
||
FNumbersOnly := False;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QLineEdit_create(Parent);
|
||
end;
|
||
|
||
function TQtLineEdit.getAlignment: QtAlignment;
|
||
begin
|
||
Result := QLineEdit_alignment(QLineEditH(Widget));
|
||
end;
|
||
|
||
function TQtLineEdit.getCursorPosition: TPoint;
|
||
begin
|
||
Result.Y := 0;
|
||
Result.X := QLineEdit_cursorPosition(QLineEditH(Widget));
|
||
end;
|
||
|
||
function TQtLineEdit.getMaxLength: Integer;
|
||
begin
|
||
Result := QLineEdit_maxLength(QLineEditH(Widget));
|
||
end;
|
||
|
||
function TQtLineEdit.getSelectedText: WideString;
|
||
begin
|
||
Result := '';
|
||
QLineEdit_selectedText(QLineEditH(Widget), @Result);
|
||
end;
|
||
|
||
function TQtLineEdit.getSelectionStart: Integer;
|
||
begin
|
||
if hasSelectedText then
|
||
Result := QLineEdit_selectionStart(QLineEditH(Widget))
|
||
else
|
||
begin
|
||
if (CachedSelectionStart <> -1) and not hasFocus then
|
||
Result := CachedSelectionStart
|
||
else
|
||
Result := getCursorPosition.X;
|
||
end;
|
||
end;
|
||
|
||
function TQtLineEdit.getSelectionLength: Integer;
|
||
var
|
||
W: WideString;
|
||
begin
|
||
if hasSelectedText then
|
||
begin
|
||
W := getSelectedText;
|
||
Result := UTF16Length(W);
|
||
end else
|
||
begin
|
||
if (CachedSelectionStart <> -1) and (CachedSelectionLen <> -1) then
|
||
Result := CachedSelectionLen
|
||
else
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
|
||
function TQtLineEdit.getText: WideString;
|
||
begin
|
||
Result := '';
|
||
QLineEdit_text(QLineEditH(Widget), @Result);
|
||
end;
|
||
|
||
function TQtLineEdit.getTextMargins: TRect;
|
||
var
|
||
L, T, R, B: Integer;
|
||
begin
|
||
QLineEdit_getTextMargins(QLineEditH(Widget), @L, @T, @R, @B);
|
||
Result := Rect(L, T, R, B);
|
||
end;
|
||
|
||
procedure TQtLineEdit.SetNumbersOnly(AValue: boolean);
|
||
begin
|
||
if FNumbersOnly=AValue then Exit;
|
||
FNumbersOnly:=AValue;
|
||
if Assigned(FIntValidator) then
|
||
begin
|
||
QLineEdit_setValidator(QLineEditH(Widget), nil);
|
||
QIntValidator_destroy(FIntValidator);
|
||
FIntValidator := nil;
|
||
end;
|
||
if FNumbersOnly then
|
||
begin
|
||
FIntValidator := QIntValidator_create(0, MAXINT, Widget);
|
||
QLineEdit_setValidator(QLineEditH(Widget), FIntValidator);
|
||
end;
|
||
end;
|
||
|
||
function TQtLineEdit.getTextStatic: Boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
function TQtLineEdit.isUndoAvailable: Boolean;
|
||
begin
|
||
Result := QLineEdit_isUndoAvailable(QLineEditH(Widget));
|
||
end;
|
||
|
||
function TQtLineEdit.hasSelectedText: Boolean;
|
||
begin
|
||
Result := QLineEdit_hasSelectedText(QLineEditH(Widget));
|
||
end;
|
||
|
||
procedure TQtLineEdit.selectAll;
|
||
begin
|
||
QLineEdit_selectAll(QLineEditH(Widget));
|
||
end;
|
||
|
||
procedure TQtLineEdit.setAlignment(const AAlignment: QtAlignment);
|
||
begin
|
||
QLineEdit_setAlignment(QLineEditH(Widget), AAlignment);
|
||
end;
|
||
|
||
procedure TQtLineEdit.setBorder(const ABorder: Boolean);
|
||
begin
|
||
QLineEdit_setFrame(QLineEditH(Widget), ABorder);
|
||
end;
|
||
|
||
procedure TQtLineEdit.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
FTextChanged := QLineEdit_hook_create(Widget);
|
||
QLineEdit_hook_hook_textChanged(FTextChanged, @SignalTextChanged);
|
||
end;
|
||
|
||
procedure TQtLineEdit.DetachEvents;
|
||
begin
|
||
if FTextChanged <> nil then
|
||
begin
|
||
QLineEdit_hook_destroy(FTextChanged);
|
||
FTextChanged := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtLineEdit.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject = nil then
|
||
exit;
|
||
|
||
if (QEvent_type(Event) = QEventFocusOut) then
|
||
begin
|
||
CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(Widget));
|
||
CachedSelectionLen := UTF16Length(getSelectedText);
|
||
end else
|
||
if (QEvent_type(Event) = QEventFocusIn) then
|
||
begin
|
||
CachedSelectionStart := -1;
|
||
CachedSelectionLen := -1;
|
||
end;
|
||
|
||
if (ChildOfComplexWidget = ccwComboBox) and (QEvent_type(Event) = QEventMove) then
|
||
exit;
|
||
|
||
if (ChildOfComplexWidget = ccwComboBox) and
|
||
((QEvent_type(Event) = QEventPaint) or (QEvent_type(Event) = QEventResize))
|
||
and (LCLObject.HandleAllocated) then
|
||
begin
|
||
Result := TQtComboBox(LCLObject.Handle).InUpdate or
|
||
(csDesigning in LCLObject.ComponentState);
|
||
if (QEvent_type(Event) = QEventPaint) and (csDesigning in LCLObject.ComponentState) then
|
||
QObject_event(Sender, Event);
|
||
if Result then
|
||
QEvent_ignore(Event)
|
||
else
|
||
begin
|
||
// issue #26040
|
||
if (QEvent_type(Event) = QEventResize) then
|
||
LCLObject.DoAdjustClientRectChange
|
||
else
|
||
Result:=inherited EventFilter(Sender, Event);
|
||
end;
|
||
end else
|
||
Result:=inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
procedure TQtLineEdit.preferredSize(var PreferredWidth,
|
||
PreferredHeight: integer; WithThemeSpace: Boolean);
|
||
var
|
||
Size: TSize;
|
||
begin
|
||
QLineEdit_sizeHint(QLineEditH(Widget), @Size);
|
||
PreferredHeight := Size.cy;
|
||
PreferredWidth := Size.cx;
|
||
end;
|
||
|
||
procedure TQtLineEdit.setCursorPosition(const ACursorPosition: Integer);
|
||
begin
|
||
QLineEdit_setCursorPosition(QLineEditH(Widget), ACursorPosition);
|
||
end;
|
||
|
||
procedure TQtLineEdit.setDefaultColorRoles;
|
||
begin
|
||
WidgetColorRole := QPaletteBase;
|
||
TextColorRole := QPaletteText;
|
||
end;
|
||
|
||
procedure TQtLineEdit.setEchoMode(const AMode: QLineEditEchoMode);
|
||
begin
|
||
QLineEdit_setEchoMode(QLineEditH(Widget), AMode);
|
||
end;
|
||
|
||
procedure TQtLineEdit.setInputMask(const AMask: WideString);
|
||
begin
|
||
QLineEdit_setInputMask(QLineEditH(Widget), @AMask);
|
||
end;
|
||
|
||
procedure TQtLineEdit.setMaxLength(const ALength: Integer);
|
||
begin
|
||
QLineEdit_setMaxLength(QLineEditH(Widget), ALength);
|
||
end;
|
||
|
||
procedure TQtLineEdit.setReadOnly(const AReadOnly: Boolean);
|
||
begin
|
||
QLineEdit_setReadOnly(QLineEditH(Widget), AReadOnly);
|
||
end;
|
||
|
||
procedure TQtLineEdit.setSelection(const AStart, ALength: Integer);
|
||
begin
|
||
if AStart >= 0 then
|
||
begin
|
||
if ALength > 0 then
|
||
QLineEdit_setSelection(QLineEditH(Widget), AStart, ALength)
|
||
else
|
||
setCursorPosition(AStart);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtLineEdit.setText(const AText: WideString);
|
||
begin
|
||
QLineEdit_setText(QLineEditH(Widget), @AText);
|
||
if not getEnabled then
|
||
setSelection(0, 0);
|
||
end;
|
||
|
||
procedure TQtLineEdit.setTextHint(const ATextHint: string);
|
||
var
|
||
W: WideString;
|
||
begin
|
||
W := UTF8ToUTF16(ATextHint);
|
||
QLineEdit_setPlaceholderText(QLineEditH(Widget), @W);
|
||
end;
|
||
|
||
procedure TQtLineEdit.setTextMargins(ARect: TRect);
|
||
begin
|
||
with ARect do
|
||
QLineEdit_setTextMargins(QLineEditH(Widget), Left, Top, Right, Bottom);
|
||
end;
|
||
|
||
procedure TQtLineEdit.Cut;
|
||
begin
|
||
QLineEdit_cut(QLineEditH(Widget));
|
||
end;
|
||
|
||
procedure TQtLineEdit.Copy;
|
||
begin
|
||
QLineEdit_copy(QLineEditH(Widget));
|
||
end;
|
||
|
||
procedure TQtLineEdit.Paste;
|
||
begin
|
||
QLineEdit_paste(QLineEditH(Widget));
|
||
end;
|
||
|
||
procedure TQtLineEdit.Undo;
|
||
begin
|
||
QLineEdit_undo(QLineEditH(Widget));
|
||
end;
|
||
|
||
destructor TQtLineEdit.Destroy;
|
||
begin
|
||
if Assigned(FIntValidator) then
|
||
begin
|
||
QIntValidator_destroy(FIntValidator);
|
||
FIntValidator := nil;
|
||
end;
|
||
inherited Destroy;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtLineEdit.SignalTextChanged
|
||
Params: PWideString
|
||
Returns: Nothing
|
||
|
||
Fires OnChange() event of TCustomEdit
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtLineEdit.SignalTextChanged(p1: PWideString); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := CM_TEXTCHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{ TQtTextEdit }
|
||
|
||
function TQtTextEdit.GetAcceptRichText: Boolean;
|
||
begin
|
||
Result := QTextEdit_acceptRichText(QTextEditH(Widget));
|
||
end;
|
||
|
||
procedure TQtTextEdit.SetAcceptRichText(AValue: Boolean);
|
||
begin
|
||
QTextEdit_setAcceptRichText(QTextEditH(Widget), AValue);
|
||
end;
|
||
|
||
function TQtTextEdit.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtTextEdit.Create');
|
||
{$endif}
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QTextEdit_create(Parent);
|
||
FKeysToEat := [];
|
||
FUndoAvailable := False;
|
||
{drops are handled by slotDropFiles()}
|
||
QWidget_setAcceptDrops(Result, False);
|
||
end;
|
||
|
||
procedure TQtTextEdit.Append(const AStr: WideString);
|
||
begin
|
||
QTextEdit_append(QTextEditH(Widget), @AStr);
|
||
end;
|
||
|
||
procedure TQtTextEdit.ClearText;
|
||
begin
|
||
QTextEdit_clear(QTextEditH(Widget));
|
||
end;
|
||
|
||
function TQtTextEdit.getAlignment: QtAlignment;
|
||
begin
|
||
Result := QTextEdit_alignment(QTextEditH(Widget));
|
||
end;
|
||
|
||
function TQtTextEdit.getBlockCount: Integer;
|
||
begin
|
||
Result := QTextDocument_blockCount(QTextEdit_document(QTextEditH(Widget)));
|
||
end;
|
||
|
||
function TQtTextEdit.getCursorPosition: TPoint;
|
||
var
|
||
TextCursor: QTextCursorH;
|
||
begin
|
||
TextCursor := QTextCursor_create();
|
||
QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
|
||
if QTextCursor_isNull(TextCursor) then
|
||
Result := Point(0, 0)
|
||
else
|
||
begin
|
||
Result.X := QTextCursor_positionInBlock(TextCursor);
|
||
Result.Y := QTextCursor_blockNumber(TextCursor);
|
||
end;
|
||
QTextCursor_destroy(TextCursor);
|
||
end;
|
||
|
||
function TQtTextEdit.getMaxLength: Integer;
|
||
begin
|
||
{$note implement TQtTextEdit.getMaxLength}
|
||
Result := 0;
|
||
end;
|
||
|
||
function TQtTextEdit.getText: WideString;
|
||
begin
|
||
Result := '';
|
||
QTextEdit_toPlainText(QTextEditH(Widget), @Result);
|
||
end;
|
||
|
||
function TQtTextEdit.getTextStatic: Boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
function TQtTextEdit.getSelectionStart: Integer;
|
||
var
|
||
TextCursor: QTextCursorH;
|
||
begin
|
||
TextCursor := QTextCursor_create();
|
||
QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
|
||
Result := QTextCursor_selectionStart(TextCursor);
|
||
QTextCursor_destroy(TextCursor);
|
||
end;
|
||
|
||
function TQtTextEdit.getSelectionEnd: Integer;
|
||
var
|
||
TextCursor: QTextCursorH;
|
||
begin
|
||
TextCursor := QTextCursor_create();
|
||
QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
|
||
Result := QTextCursor_selectionEnd(TextCursor);
|
||
QTextCursor_destroy(TextCursor);
|
||
end;
|
||
|
||
function TQtTextEdit.getSelectionLength: Integer;
|
||
begin
|
||
Result := getSelectionEnd - getSelectionStart;
|
||
end;
|
||
|
||
function TQtTextEdit.isUndoAvailable: Boolean;
|
||
begin
|
||
Result := QTextEdit_isUndoRedoEnabled(QTextEditH(Widget)) and FUndoAvailable;
|
||
end;
|
||
|
||
procedure TQtTextEdit.setEchoMode(const AMode: QLineEditEchoMode);
|
||
begin
|
||
{$note implement TQtTextEdit.setEchoMode}
|
||
end;
|
||
|
||
procedure TQtTextEdit.setLineWrapMode(const AMode: QTextEditLineWrapMode);
|
||
begin
|
||
QTextEdit_setLineWrapMode(QTextEditH(Widget), AMode);
|
||
end;
|
||
|
||
procedure TQtTextEdit.setMaxLength(const ALength: Integer);
|
||
begin
|
||
{$note implement TQtTextEdit.setMaxLength}
|
||
end;
|
||
|
||
procedure TQtTextEdit.appendLine(AText: WideString);
|
||
var
|
||
QtCursor: QTextCursorH;
|
||
WrapMode: QTextEditLineWrapMode;
|
||
begin
|
||
WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
|
||
{we must remove wrapping to get correct line !}
|
||
setLineWrapMode(QTextEditNoWrap);
|
||
QtCursor := QTextCursor_create();
|
||
try
|
||
QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
|
||
QTextCursor_beginEditBlock(QtCursor);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorEnd,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_insertBlock(QtCursor);
|
||
QTextCursor_insertText(QtCursor, @AText);
|
||
QTextCursor_endEditBlock(QtCursor);
|
||
finally
|
||
QTextCursor_destroy(QtCursor);
|
||
setLineWrapMode(WrapMode);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTextEdit.insertLine(const AIndex: integer; AText: WideString);
|
||
var
|
||
QtCursor: QTextCursorH;
|
||
WrapMode: QTextEditLineWrapMode;
|
||
begin
|
||
WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
|
||
{we must remove wrapping to get correct line !}
|
||
setLineWrapMode(QTextEditNoWrap);
|
||
QtCursor := QTextCursor_create();
|
||
try
|
||
QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
|
||
QTextCursor_beginEditBlock(QtCursor);
|
||
// QTextCursor slowness
|
||
// https://bugreports.qt-project.org/browse/QTBUG-3554
|
||
// differentiate append vs. insert issue #22715
|
||
// added check for AIndex. issue #29670
|
||
if (AIndex > 0) and (AIndex >= FList.Count - 1) then
|
||
begin
|
||
QTextCursor_movePosition(QtCursor, QTextCursorEnd,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_insertBlock(QtCursor);
|
||
end else
|
||
begin
|
||
QTextCursor_movePosition(QtCursor, QTextCursorStart,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
|
||
QTextCursorMoveAnchor, 1);
|
||
end;
|
||
|
||
QTextCursor_movePosition(QtCursor, QTextCursorDown,
|
||
QTextCursorMoveAnchor, AIndex);
|
||
// QTextCursor slowness
|
||
// https://bugreports.qt-project.org/browse/QTBUG-3554
|
||
// differentiate append vs. insert issue #22715
|
||
if AIndex < FList.Count - 1 then
|
||
begin
|
||
QTextCursor_insertBlock(QtCursor);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorUp,
|
||
QTextCursorMoveAnchor, 1);
|
||
end;
|
||
QTextCursor_insertText(QtCursor, @AText);
|
||
QTextCursor_endEditBlock(QtCursor);
|
||
finally
|
||
QTextCursor_destroy(QtCursor);
|
||
setLineWrapMode(WrapMode);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTextEdit.removeLine(const AIndex: integer);
|
||
var
|
||
QtCursor: QTextCursorH;
|
||
B: Boolean;
|
||
WrapMode: QTextEditLineWrapMode;
|
||
Diff: Integer;
|
||
begin
|
||
Diff := getBlockCount - AIndex;
|
||
{we must remove wrapping to get correct line !}
|
||
WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
|
||
setLineWrapMode(QTextEditNoWrap);
|
||
QtCursor := QTextCursor_create();
|
||
try
|
||
QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
|
||
QTextCursor_beginEditBlock(QtCursor);
|
||
// small optimization if we delete from end of list
|
||
if Diff <= 2 then
|
||
begin
|
||
QTextCursor_movePosition(QtCursor, QTextCursorEnd,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorUp,
|
||
QTextCursorMoveAnchor, Diff - 1);
|
||
end else
|
||
begin
|
||
QTextCursor_movePosition(QtCursor, QTextCursorStart,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorDown,
|
||
QTextCursorMoveAnchor, AIndex);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorEndOfLine,
|
||
QTextCursorMoveAnchor, 1);
|
||
end;
|
||
|
||
QTextCursor_select(QtCursor, QTextCursorLineUnderCursor);
|
||
B := QTextCursor_hasSelection(QtCursor);
|
||
if not B then
|
||
QTextCursor_deleteChar(QtCursor)
|
||
else
|
||
QTextCursor_deletePreviousChar(QtCursor);
|
||
|
||
if (AIndex = 0) then
|
||
begin
|
||
QTextCursor_movePosition(QtCursor, QTextCursorStart,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorDown,
|
||
QTextCursorMoveAnchor, 1);
|
||
end;
|
||
if B then
|
||
QTextCursor_deletePreviousChar(QtCursor);
|
||
QTextCursor_endEditBlock(QtCursor);
|
||
finally
|
||
QTextCursor_destroy(QtCursor);
|
||
setLineWrapMode(WrapMode);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTextEdit.setLineText(const AIndex: integer; AText: WideString);
|
||
var
|
||
QtCursor: QTextCursorH;
|
||
WrapMode: QTextEditLineWrapMode;
|
||
begin
|
||
{we must remove wrapping to get correct line !}
|
||
WrapMode := QTextEdit_lineWrapMode(QTextEditH(Widget));
|
||
setLineWrapMode(QTextEditNoWrap);
|
||
QtCursor := QTextCursor_create();
|
||
try
|
||
QTextEdit_textCursor(QTextEditH(Widget), QtCursor);
|
||
QTextCursor_beginEditBlock(QtCursor);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorStart,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorStartOfLine,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorDown,
|
||
QTextCursorMoveAnchor, AIndex);
|
||
QTextCursor_select(QtCursor, QTextCursorLineUnderCursor);
|
||
QTextCursor_removeSelectedText(QtCursor);
|
||
QTextCursor_insertText(QtCursor, @AText);
|
||
QTextCursor_movePosition(QtCursor, QTextCursorEndOfLine,
|
||
QTextCursorMoveAnchor, 1);
|
||
QTextCursor_endEditBlock(QtCursor);
|
||
finally
|
||
QTextCursor_destroy(QtCursor);
|
||
setLineWrapMode(WrapMode);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTextEdit.setText(const AText: WideString);
|
||
begin
|
||
QTextEdit_setPlainText(QTextEditH(Widget), @AText);
|
||
end;
|
||
|
||
procedure TQtTextEdit.setTextHint(const ATextHint: string);
|
||
var
|
||
W: WideString;
|
||
begin
|
||
W := UTF8ToUTF16(ATextHint);
|
||
QTextEdit_setPlaceholderText(QTextEditH(Widget), @W);
|
||
end;
|
||
|
||
procedure TQtTextEdit.setReadOnly(const AReadOnly: Boolean);
|
||
begin
|
||
QTextEdit_setReadOnly(QTextEditH(Widget), AReadOnly);
|
||
end;
|
||
|
||
procedure TQtTextEdit.setSelection(const AStart, ALength: Integer);
|
||
var
|
||
TextCursor: QTextCursorH;
|
||
maxPosition: Integer;
|
||
doc: QTextDocumentH;
|
||
begin
|
||
if AStart >= 0 then
|
||
begin
|
||
TextCursor := QTextCursor_create();
|
||
QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
|
||
|
||
doc := QTextCursor_document(Textcursor);
|
||
maxPosition := QTextDocument_characterCount(doc) - 1;
|
||
|
||
QTextCursor_clearSelection(TextCursor);
|
||
QTextCursor_setPosition(TextCursor, Min(AStart, maxPosition));
|
||
QTextCursor_setPosition(TextCursor, Min(AStart + ALength, maxPosition), QTextCursorKeepAnchor);
|
||
|
||
QTextEdit_setTextCursor(QTextEditH(Widget), TextCursor);
|
||
QTextCursor_destroy(TextCursor);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTextEdit.setTabChangesFocus(const AValue: Boolean);
|
||
begin
|
||
QTextEdit_setTabChangesFocus(QTextEditH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtTextEdit.Cut;
|
||
begin
|
||
QTextEdit_cut(QTextEditH(Widget));
|
||
end;
|
||
|
||
procedure TQtTextEdit.Copy;
|
||
begin
|
||
QTextEdit_copy(QTextEditH(Widget));
|
||
end;
|
||
|
||
procedure TQtTextEdit.Paste;
|
||
begin
|
||
QTextEdit_paste(QTextEditH(Widget));
|
||
end;
|
||
|
||
procedure TQtTextEdit.Undo;
|
||
begin
|
||
QTextEdit_undo(QTextEditH(Widget));
|
||
end;
|
||
|
||
procedure TQtTextEdit.setAlignment(const AAlignment: QtAlignment);
|
||
var
|
||
TextCursor: QTextCursorH;
|
||
begin
|
||
// QTextEdit supports alignment for every paragraph. We need to align all text.
|
||
// So, we should select all text, set format, and clear selection
|
||
|
||
// 1. Select all text
|
||
QTextEdit_selectAll(QTextEditH(Widget));
|
||
|
||
// 2. Set format
|
||
QTextEdit_setAlignment(QTextEditH(Widget), AAlignment);
|
||
|
||
// 3. Clear selection. To unselect all document we must create new text cursor,
|
||
// get format from Text Edit, clear selection in cursor and set it back to Text Edit
|
||
TextCursor := QTextCursor_create();
|
||
QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
|
||
QTextCursor_clearSelection(TextCursor);
|
||
QTextEdit_setTextCursor(QTextEditH(Widget), TextCursor);
|
||
QTextCursor_destroy(TextCursor);
|
||
end;
|
||
|
||
procedure TQtTextEdit.setBorder(const ABorder: Boolean);
|
||
begin
|
||
if ABorder then
|
||
QFrame_setFrameShape(QFrameH(Widget), QFrameStyledPanel)
|
||
else
|
||
QFrame_setFrameShape(QFrameH(Widget), QFrameNoFrame);
|
||
end;
|
||
|
||
procedure TQtTextEdit.setCursorPosition(const ACursorPosition: Integer);
|
||
var
|
||
TextCursor: QTextCursorH;
|
||
begin
|
||
TextCursor := QTextCursor_create();
|
||
QTextEdit_textCursor(QTextEditH(Widget), TextCursor);
|
||
if not QTextCursor_isNull(TextCursor) then
|
||
QTextCursor_setPosition(TextCursor, ACursorPosition);
|
||
QTextCursor_destroy(TextCursor);
|
||
end;
|
||
|
||
procedure TQtTextEdit.setDefaultColorRoles;
|
||
begin
|
||
WidgetColorRole := QPaletteBase;
|
||
TextColorRole := QPaletteText;
|
||
end;
|
||
|
||
procedure TQtTextEdit.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
FUndoAvailableHook := QTextEdit_hook_create(Widget);
|
||
QTextEdit_hook_hook_undoAvailable(FUndoAvailableHook, @SignalUndoAvailable);
|
||
|
||
FTextChangedHook := QTextEdit_hook_create(Widget);
|
||
QTextEdit_hook_hook_textChanged(FTextChangedHook, @SignalTextChanged);
|
||
|
||
FViewportEventHook := QObject_hook_create(viewportWidget);
|
||
QObject_hook_hook_events(FViewportEventHook, @viewportEventFilter);
|
||
// initialize scrollbars
|
||
verticalScrollBar;
|
||
horizontalScrollBar;
|
||
end;
|
||
|
||
procedure TQtTextEdit.DetachEvents;
|
||
begin
|
||
if FUndoAvailableHook <> nil then
|
||
begin
|
||
QTextEdit_hook_destroy(FUndoAvailableHook);
|
||
FUndoAvailableHook := nil;
|
||
end;
|
||
|
||
if FTextChangedHook <> nil then
|
||
begin
|
||
QTextEdit_hook_destroy(FTextChangedHook);
|
||
FTextChangedHook := nil;
|
||
end;
|
||
|
||
if FViewportEventHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FViewportEventHook);
|
||
FViewportEventHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtTextEdit.viewportEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
case QEvent_type(Event) of
|
||
QEventContextMenu: Result := SlotContextMenu(Sender, Event);
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
|
||
QEventMouseMove: Result := SlotMouseMove(Sender, Event);
|
||
end;
|
||
end;
|
||
|
||
function TQtTextEdit.getContextMenuPolicy: QtContextMenuPolicy;
|
||
begin
|
||
Result := QWidget_contextMenuPolicy(viewPortWidget);
|
||
end;
|
||
|
||
procedure TQtTextEdit.setContextMenuPolicy(const AValue: QtContextMenuPolicy);
|
||
begin
|
||
QWidget_setContextMenuPolicy(viewportWidget, AValue);
|
||
end;
|
||
|
||
procedure TQtTextEdit.SignalUndoAvailable(b: Boolean); cdecl;
|
||
begin
|
||
FUndoAvailable := b;
|
||
end;
|
||
|
||
procedure TQtTextEdit.SignalTextChanged(); cdecl;
|
||
var
|
||
Mess: TLMessage;
|
||
begin
|
||
if (LCLObject = nil) or not GetVisible then
|
||
exit;
|
||
if Assigned(FList) then
|
||
TQtMemoStrings(FList).TextChanged := True;
|
||
if not InUpdate then
|
||
begin
|
||
FillChar(Mess{%H-}, SizeOf(Mess), #0);
|
||
Mess.Msg := CM_TEXTCHANGED;
|
||
DeliverMessage(Mess);
|
||
end;
|
||
end;
|
||
|
||
{ TQtTabBar }
|
||
|
||
procedure TQtTabBar.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FTabBarChangedHook := QTabBar_hook_create(QTabBarH(Widget));
|
||
FTabBarMovedHook := QTabBar_hook_create(QTabBarH(Widget));
|
||
QTabBar_hook_hook_currentChanged(FTabBarChangedHook, @SignalTabBarCurrentChanged);
|
||
QTabBar_hook_hook_tabMoved(FTabBarMovedHook, @SignalTabBarMoved);
|
||
end;
|
||
|
||
procedure TQtTabBar.DetachEvents;
|
||
begin
|
||
if FTabBarMovedHook <> nil then
|
||
begin
|
||
QTabBar_hook_destroy(FTabBarMovedHook);
|
||
FTabBarMovedHook := nil;
|
||
end;
|
||
if FTabBarChangedHook <> nil then
|
||
begin
|
||
QTabBar_hook_destroy(FTabBarChangedHook);
|
||
FTabBarChangedHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtTabBar.GetTabRect(const AIndex: integer): TRect;
|
||
var
|
||
Pt: TPoint;
|
||
begin
|
||
QTabBar_tabRect(QTabBarH(Widget), @Result, AIndex);
|
||
if Assigned(FOwner) then
|
||
begin
|
||
Pt := TabBarOffset;
|
||
OffsetRect(Result, Pt.X, Pt.Y);
|
||
end;
|
||
end;
|
||
|
||
function TQtTabBar.TabBarOffset: TPoint;
|
||
var
|
||
R: TRect;
|
||
begin
|
||
Result := Point(0, 0);
|
||
if Assigned(FOwner) then
|
||
begin
|
||
QWidget_geometry(Widget, @R);
|
||
case TQtTabWidget(FOwner).getTabPosition of
|
||
QTabWidgetNorth,
|
||
QTabWidgetSouth:
|
||
begin
|
||
if R.Left < 0 then
|
||
R.Left := 0;
|
||
// issue #28591
|
||
if QWidget_layoutDirection(Widget) = QtRightToLeft then
|
||
Result.X := 0
|
||
else
|
||
Result.X := R.Left;
|
||
end;
|
||
QTabWidgetEast,
|
||
QTabWidgetWest:
|
||
begin
|
||
if R.Top < 0 then
|
||
R.Top := 0;
|
||
Result.Y := R.Top;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTabBar.SignalTabBarMoved(fromIndex: integer; toIndex: Integer);
|
||
cdecl;
|
||
var
|
||
ANewIndex: Integer;
|
||
begin
|
||
if LCLObject = nil then
|
||
Exit;
|
||
// DebugLn('TQtTabBar.SignalTabBarMoved From=',dbgs(fromIndex),' to ',dbgs(toIndex),' FSavedIndexOnPageChanging=',dbgs(FSavedIndexOnPageChanging));
|
||
if Assigned(FOwner) and not (FOwner.ChildOfComplexWidget = ccwTTabControl) then
|
||
begin
|
||
ANewIndex := TQtTabWidget(FOwner).GetLCLPageIndex(toIndex);
|
||
TQtTabWidget(FOwner).setCurrentWidget(TQtWidget(TCustomTabControl(LCLObject).Page[ANewIndex].Handle), True);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTabBar.SignalTabBarCurrentChanged(Index: Integer); cdecl;
|
||
var
|
||
Msg: TLMNotify;
|
||
Hdr: TNmHdr;
|
||
begin
|
||
if LCLObject = nil then
|
||
Exit;
|
||
|
||
if TQtTabWidget(LCLObject.Handle).InUpdate then
|
||
exit;
|
||
FillChar(Msg{%H-}, SizeOf(Msg), 0);
|
||
Msg.Msg := LM_NOTIFY;
|
||
FillChar(Hdr{%H-}, SizeOf(Hdr), 0);
|
||
|
||
Hdr.hwndFrom := LCLObject.Handle;
|
||
Hdr.Code := TCN_SELCHANGE;
|
||
Hdr.idFrom := PtrUInt(TQtTabWidget(LCLObject.Handle).GetLCLPageIndex(Index));
|
||
Msg.NMHdr := @Hdr;
|
||
Msg.Result := 0;
|
||
if FSavedIndexOnPageChanging = Forbid_TCN_SELCHANGE then
|
||
FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE
|
||
else
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
function TQtTabBar.SlotTabBarMouse(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
var
|
||
MousePos, AGlobalPos: TQtPoint;
|
||
APosF, AGlobalPosF: TQtPointF;
|
||
NewEvent: QMouseEventH;
|
||
R: TRect;
|
||
R1: TRect;
|
||
BaseHeight: Integer;
|
||
ForcedMouseGrab: Boolean;
|
||
begin
|
||
Result := False;
|
||
|
||
if not CanSendLCLMessage then
|
||
exit;
|
||
|
||
// MousePos :=
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
|
||
if Assigned(FOwner) then
|
||
begin
|
||
R := TQtTabWidget(FOwner).getGeometry;
|
||
R1 := getGeometry;
|
||
BaseHeight := GetPixelMetric(QStylePM_TabBarBaseHeight, nil, nil);
|
||
|
||
case TQtTabWidget(FOwner).getTabPosition of
|
||
QTabWidgetNorth:
|
||
begin
|
||
MousePos.Y := R.Top - (R1.Bottom - MousePos.Y);
|
||
MousePos.X := MousePos.X - BaseHeight;
|
||
end;
|
||
QTabWidgetWest:
|
||
begin
|
||
MousePos.x := R.Left - (R1.Right - MousePos.X);
|
||
MousePos.y := MousePos.Y - BaseHeight;
|
||
end;
|
||
QTabWidgetEast:
|
||
begin
|
||
MousePos.X := R1.Left + MousePos.X - BaseHeight;
|
||
MousePos.y := MousePos.Y - BaseHeight;
|
||
end;
|
||
QTabWidgetSouth:
|
||
begin
|
||
MousePos.Y := R1.Top + MousePos.Y - BaseHeight;
|
||
MousePos.X := MousePos.X - BaseHeight;
|
||
end;
|
||
end;
|
||
QMouseEvent_globalPos(QMouseEventH(Event), @AGlobalPos);
|
||
APosF.X := MousePos.X;
|
||
APosF.Y := MousePos.Y;
|
||
AGlobalPosF.X := AGlobalPos.X;
|
||
AGlobalPosF.Y := AGlobalPos.Y;
|
||
NewEvent := QMouseEvent_create(QEvent_type(Event), @APosF,
|
||
@AGlobalPosF,
|
||
QMouseEvent_button(QMouseEventH(Event)),
|
||
QMouseEvent_buttons(QMouseEventH(Event)),
|
||
QInputEvent_modifiers(QInputEventH(Event))
|
||
);
|
||
|
||
ForcedMouseGrab := False;
|
||
if QEvent_type(Event) = QEventMouseButtonPress then
|
||
ForcedMouseGrab := not ((QWidget_mouseGrabber = Widget) or
|
||
(Assigned(FOwner) and (QWidget_mouseGrabber = FOwner.Widget)));
|
||
|
||
SlotMouse(Sender, NewEvent);
|
||
QMouseEvent_destroy(NewEvent);
|
||
|
||
ForcedMouseGrab := ForcedMouseGrab and
|
||
(Assigned(FOwner) and (QWidget_mouseGrabber = FOwner.Widget));
|
||
|
||
if ForcedMouseGrab then
|
||
QWidget_grabMouse(Widget);
|
||
|
||
end else
|
||
SlotMouse(Sender, Event);
|
||
end;
|
||
|
||
function TQtTabBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
|
||
function StopShortcutEvent: boolean;
|
||
begin
|
||
Result := Assigned(FOwner) and (FOwner.ChildOfComplexWidget <> ccwTTabControl) and
|
||
not TQtTabWidget(FOwner).FSwitchTabsByKeyboard and (QKeyEvent_matches(QKeyEventH(Event), QKeySequenceNextChild) or
|
||
QKeyEvent_matches(QKeyEventH(Event), QKeySequencePreviousChild));
|
||
end;
|
||
|
||
{$IFDEF QT_ENABLE_LCL_PAINT_TABS}
|
||
var
|
||
R: TRect;
|
||
{$ENDIF}
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject = nil then
|
||
exit;
|
||
{$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
|
||
WriteLn('TQtTabBar.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
|
||
' LCLObject=', dbgsName(LCLObject),
|
||
' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
|
||
{$endif}
|
||
|
||
BeginEventProcessing;
|
||
try
|
||
case QEvent_type(Event) of
|
||
{$IFDEF QT_ENABLE_LCL_PAINT_TABS}
|
||
QEventPaint:
|
||
begin
|
||
QPaintEvent_rect(QPaintEventH(Event), @R);
|
||
// qt paints tab
|
||
QObject_event(Sender, Event);
|
||
// LCL can do whatever now
|
||
SlotPaint(Sender, Event);
|
||
Result := True;
|
||
QEvent_ignore(Event);
|
||
end;
|
||
{$ENDIF}
|
||
QEventShortcutOverride: Result := StopShortcutEvent;
|
||
QEventKeyPress,
|
||
QEventKeyRelease:
|
||
begin
|
||
if (QEvent_type(Event) = QEventKeyPress) then
|
||
FSavedIndexOnPageChanging := QTabBar_currentIndex(QTabBarH(Widget));
|
||
SlotKey(Sender, Event);
|
||
if (LCLObject = nil) or
|
||
((LCLObject <> nil) and not LCLObject.HandleAllocated) then
|
||
Result := True;
|
||
if not Result then
|
||
Result := StopShortcutEvent;
|
||
end;
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick:
|
||
begin
|
||
if QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton then
|
||
begin
|
||
if (QEvent_type(Event) = QEventMouseButtonPress) then
|
||
FSavedIndexOnPageChanging := QTabBar_currentIndex(QTabBarH(Widget));
|
||
Result := SlotTabBarMouse(Sender, Event);
|
||
if (LCLObject = nil) or
|
||
((LCLObject <> nil) and not LCLObject.HandleAllocated) then
|
||
Result := True
|
||
else
|
||
SetNoMousePropagation(QWidgetH(Sender), False);
|
||
end;
|
||
end;
|
||
else
|
||
QEvent_ignore(Event);
|
||
end;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTabBar.SetTabFontColor(AIndex: Integer; AColor: TQColor);
|
||
begin
|
||
QTabBar_setTabTextColor(QTabBarH(Widget), AIndex, @AColor);
|
||
end;
|
||
|
||
{ TQtTabWidget }
|
||
|
||
function TQtTabWidget.getTabBar: TQtTabBar;
|
||
begin
|
||
if FTabBar = nil then
|
||
begin
|
||
{$note TQtTabWidget.getTabBar: we can remove QLCLTabWidget, and get it like StackWidget,
|
||
objectName is qt_tabwidget_tabbar.}
|
||
FTabBar := TQtTabBar.CreateFrom(LCLObject, QLCLTabWidget_tabBarHandle(QTabWidgetH(Widget)));
|
||
{$IFDEF QT_ENABLE_LCL_PAINT_TABS}
|
||
FTabBar.HasPaint := True;
|
||
{$ENDIF}
|
||
FTabBar.FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE;
|
||
FTabBar.FOwner := Self;
|
||
FTabBar.AttachEvents;
|
||
end;
|
||
Result := FTabBar;
|
||
end;
|
||
|
||
function TQtTabWidget.getShowTabs: Boolean;
|
||
begin
|
||
Result := TabBar.getVisible;
|
||
end;
|
||
|
||
function TQtTabWidget.getStackWidget: QWidgetH;
|
||
var
|
||
List: TPtrIntArray;
|
||
Obj: QObjectH;
|
||
i: Integer;
|
||
WStr: WideString;
|
||
begin
|
||
if FStackWidget = nil then
|
||
begin
|
||
QObject_children(Widget, @List);
|
||
for i := 0 to High(List) do
|
||
begin
|
||
Obj := QObjectH(List[i]);
|
||
QObject_objectName(Obj, @WStr);
|
||
{do not localize !}
|
||
if WStr = 'qt_tabwidget_stackedwidget' then
|
||
begin
|
||
FStackWidget := QWidgetH(List[i]);
|
||
break;
|
||
end;
|
||
end;
|
||
FCentralWidget := FStackWidget;
|
||
end;
|
||
Result := FStackWidget;
|
||
end;
|
||
|
||
procedure TQtTabWidget.setShowTabs(const AValue: Boolean);
|
||
begin
|
||
TabBar.setVisible(AValue);
|
||
end;
|
||
|
||
function TQtTabWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtTabWidget.Create');
|
||
{$endif}
|
||
FSwitchTabsByKeyboard := False; {shortcuts are enabled by default under qt, but not under LCL}
|
||
FWidgetNeedFontColorInitialization := True;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QTabWidget_create(Parent);
|
||
|
||
{note: for some reason tabbar scroll buttons are not enabled as default option
|
||
under mac - but under linux & win are. Qt docs says that this options is enabled
|
||
as default ... possible qt bug}
|
||
{$ifdef darwin}
|
||
QTabWidget_setUsesScrollButtons(QTabWidgetH(Result), True);
|
||
{$endif}
|
||
end;
|
||
|
||
destructor TQtTabWidget.Destroy;
|
||
begin
|
||
FTabBar.Free;
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TQtTabWidget.DestroyNotify(AWidget: TQtWidget);
|
||
begin
|
||
if AWidget = FTabBar then
|
||
FTabBar := nil;
|
||
inherited DestroyNotify(AWidget);
|
||
end;
|
||
|
||
function TQtTabWidget.GetLCLPageIndex(AIndex: Integer): Integer;
|
||
var
|
||
I: Integer;
|
||
begin
|
||
Result := AIndex;
|
||
if (LCLObject = nil) or
|
||
(csDesigning in LCLObject.ComponentState) or
|
||
not (LCLObject is TCustomTabControl) then
|
||
Exit;
|
||
I := 0;
|
||
while (I < TCustomTabControl(LCLObject).PageCount) and (I <= Result) do
|
||
begin
|
||
if not TCustomTabControl(LCLObject).Page[I].TabVisible then
|
||
Inc(Result);
|
||
Inc(I);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTabWidget.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
{initialize our tabbar}
|
||
TabBar;
|
||
|
||
FCurrentChangedHook := QTabWidget_hook_create(Widget);
|
||
QTabWidget_hook_hook_currentChanged(FCurrentChangedHook, @SignalCurrentChanged);
|
||
|
||
FCloseRequestedHook := QTabWidget_hook_create(Widget);
|
||
QTabWidget_hook_hook_tabCloseRequested(FCloseRequestedHook, @SignalCloseRequested);
|
||
|
||
FStackedWidgetHook := QObject_hook_create(StackWidget);
|
||
QObject_hook_hook_events(FStackedWidgetHook, @EventFilter);
|
||
|
||
end;
|
||
|
||
procedure TQtTabWidget.DetachEvents;
|
||
begin
|
||
|
||
if FStackedWidgetHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FStackedWidgetHook);
|
||
FStackedWidgetHook := nil;
|
||
end;
|
||
if FCurrentChangedHook <> nil then
|
||
begin
|
||
QTabWidget_hook_destroy(FCurrentChangedHook);
|
||
FCurrentChangedHook := nil;
|
||
end;
|
||
if FCloseRequestedHook <> nil then
|
||
begin
|
||
QTabWidget_hook_destroy(FCloseRequestedHook);
|
||
FCloseRequestedHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtTabWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
var
|
||
{$IFDEF QT_ENABLE_LCL_PAINT_TABS}
|
||
R: TRect;
|
||
TabGeom: TRect;
|
||
Pt: TPoint;
|
||
{$ENDIF}
|
||
ALCLEvent: QLCLMessageEventH;
|
||
ANewSize: TSize;
|
||
begin
|
||
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject = nil then
|
||
exit;
|
||
|
||
if (Sender = FStackWidget) then
|
||
begin
|
||
{$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
|
||
WriteLn('TQtTabWidget.EventFilter: STACKWIDGET Sender=', IntToHex(PtrUInt(Sender),8),
|
||
' LCLObject=', dbgsName(LCLObject),
|
||
' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
|
||
{$endif}
|
||
{leave this for debugging purposes}
|
||
exit;
|
||
end;
|
||
|
||
BeginEventProcessing;
|
||
try
|
||
case QEvent_type(Event) of
|
||
QEventResize:
|
||
begin
|
||
ANewSize := QResizeEvent_size(QResizeEventH(Event))^;
|
||
DelayResizeEvent(QWidgetH(Sender), ANewSize); // delay resize event since we are complex widget
|
||
end;
|
||
{$IFDEF QT_ENABLE_LCL_PAINT_TABS}
|
||
QEventPaint:
|
||
begin
|
||
{this paint event comes after tabbar paint event,
|
||
so we have to exclude our tabs from painting}
|
||
QPaintEvent_rect(QPaintEventH(Event), @R);
|
||
QWidget_geometry(TabBar.Widget, @TabGeom);
|
||
Pt.X := R.Left;
|
||
Pt.Y := R.Top;
|
||
Result := PtInRect(TabGeom, Pt) and
|
||
(R.Bottom - R.Top = TabGeom.Bottom - TabGeom.Top) and
|
||
(TabAt(Pt) >= 0);
|
||
if Result then
|
||
QEvent_ignore(Event);
|
||
end;
|
||
{$ENDIF}
|
||
LCLQt_DelayLayoutRequest:
|
||
begin
|
||
if LCLObject.ClientRectNeedsInterfaceUpdate then
|
||
begin
|
||
{$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('<*><*> TQtTabWidget calling DoAdjustClientRectChange() from LCLQt_DelayLayoutRequest ...');
|
||
{$ENDIF}
|
||
LCLObject.DoAdjustClientRectChange(True);
|
||
end;
|
||
Result := True;
|
||
end;
|
||
QEventLayoutRequest:
|
||
begin
|
||
//behaviour is changed because of issue #21805.
|
||
//we send delayed event so LCL can read clientRect at the right time.
|
||
ALCLEvent := QLCLMessageEvent_create(LCLQt_DelayLayoutRequest, 0,
|
||
0, 0, 0);
|
||
QCoreApplication_postEvent(Sender, ALCLEvent);
|
||
end;
|
||
QEventKeyPress,
|
||
QEventKeyRelease: QEvent_ignore(Event);
|
||
QEventWheel:
|
||
begin
|
||
if not getEnabled then
|
||
inherited EventFilter(Sender, Event)
|
||
else
|
||
QEvent_ignore(Event);
|
||
end;
|
||
else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTabWidget.insertTab
|
||
Params: index: Integer; page: QWidgetH; p2: PWideString
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtTabWidget.insertTab(index: Integer; page: QWidgetH; p2: WideString): Integer; overload;
|
||
begin
|
||
Result := insertTab(index, page, nil, p2);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTabWidget.insertTab
|
||
Params: index: Integer; page: QWidgetH; icon: QIconH; p2: PWideString
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtTabWidget.insertTab(index: Integer; page: QWidgetH; icon: QIconH; p2: WideString): Integer; overload;
|
||
var
|
||
UseAdd: Boolean;
|
||
begin
|
||
UseAdd := Index > getCount - 1;
|
||
if icon <> nil then
|
||
begin
|
||
if UseAdd then
|
||
Result := QTabWidget_addTab(QTabWidgetH(Widget), page, icon, @p2)
|
||
else
|
||
Result := QTabWidget_insertTab(QTabWidgetH(Widget), index, page, icon, @p2)
|
||
end else
|
||
begin
|
||
if UseAdd then
|
||
Result := QTabWidget_addTab(QTabWidgetH(Widget), page, @p2)
|
||
else
|
||
Result := QTabWidget_insertTab(QTabWidgetH(Widget), index, page, @p2);
|
||
end;
|
||
end;
|
||
|
||
function TQtTabWidget.getCount: Integer;
|
||
begin
|
||
Result := QTabWidget_count(QTabWidgetH(Widget));
|
||
end;
|
||
|
||
function TQtTabWidget.getClientBounds: TRect;
|
||
begin
|
||
QWidget_contentsRect(StackWidget, @Result);
|
||
end;
|
||
|
||
function TQtTabWidget.getCurrentIndex: Integer;
|
||
begin
|
||
Result := QTabWidget_currentIndex(QTabWidgetH(Widget));
|
||
end;
|
||
|
||
function TQtTabWidget.getTabPosition: QTabWidgetTabPosition;
|
||
begin
|
||
Result := QTabWidget_tabPosition(QTabWidgetH(Widget));
|
||
end;
|
||
|
||
procedure TQtTabWidget.removeTab(AIndex: Integer);
|
||
begin
|
||
QTabWidget_removeTab(QTabWidgetH(Widget), AIndex);
|
||
end;
|
||
|
||
procedure TQtTabWidget.setCurrentIndex(AIndex: Integer);
|
||
begin
|
||
QTabWidget_setCurrentIndex(QTabWidgetH(Widget), AIndex);
|
||
end;
|
||
|
||
procedure TQtTabWidget.setCurrentWidget(APage: TQtWidget; const AIsMoved: Boolean);
|
||
begin
|
||
QTabWidget_setCurrentWidget(QTabWidgetH(Widget), APage.Widget);
|
||
if AIsMoved and (Assigned(LCLObject) and not (csDesigning in LCLObject.ComponentState)) then
|
||
APage.setFocus;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTabWidget.setTabPosition
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtTabWidget.setTabPosition(ATabPosition: QTabWidgetTabPosition);
|
||
begin
|
||
QTabWidget_setTabPosition(QTabWidgetH(Widget), ATabPosition);
|
||
end;
|
||
|
||
procedure TQtTabWidget.setTabIcon(index: Integer; icon: QIconH);
|
||
begin
|
||
QTabWidget_setTabIcon(QTabWidgetH(Widget), index, icon);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTabWidget.SignalCurrentChanged
|
||
Params: None
|
||
Returns: Nothing
|
||
Changes ActivePage of TPageControl
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtTabWidget.SignalCurrentChanged(Index: Integer); cdecl;
|
||
var
|
||
Msg: TLMNotify;
|
||
Hdr: TNmHdr;
|
||
i: Integer;
|
||
begin
|
||
if (LCLObject = nil) or InUpdate or not GetVisible then
|
||
begin
|
||
if TabBar.FSavedIndexOnPageChanging <> Forbid_TCN_SELCHANGE then
|
||
TabBar.FSavedIndexOnPageChanging := Allow_TCN_SELCHANGE;
|
||
exit;
|
||
end;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), 0);
|
||
Msg.Msg := LM_NOTIFY;
|
||
FillChar(Hdr{%H-}, SizeOf(Hdr), 0);
|
||
|
||
Hdr.hwndFrom := LCLObject.Handle;
|
||
Hdr.Code := TCN_SELCHANGING;
|
||
Hdr.idFrom := PtrUInt(GetLCLPageIndex(Index));
|
||
Msg.NMHdr := @Hdr;
|
||
Msg.Result := 0;
|
||
if (DeliverMessage(Msg) <> 0) and (Index >= 0) and
|
||
(TabBar.FSavedIndexOnPageChanging >= 0) then
|
||
begin
|
||
BeginUpdate;
|
||
try
|
||
i := TabBar.FSavedIndexOnPageChanging;
|
||
FTabBar.FSavedIndexOnPageChanging := Forbid_TCN_SELCHANGE;
|
||
setCurrentIndex(i);
|
||
finally
|
||
EndUpdate;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTabWidget.SignalCloseRequested(Index: Integer); cdecl;
|
||
var
|
||
APage: TCustomPage;
|
||
begin
|
||
APage := TCustomTabControl(LCLObject).Page[GetLCLPageIndex(Index)];
|
||
if not APage.HandleAllocated then
|
||
Exit;
|
||
TCustomTabControl(LCLObject).DoCloseTabClicked(APage);
|
||
end;
|
||
|
||
function TQtTabWidget.indexOf(const AWidget: QWidgetH): integer;
|
||
begin
|
||
Result := QTabWidget_indexOf(QTabWidgetH(Widget), AWidget);
|
||
end;
|
||
|
||
procedure TQtTabWidget.setTabText(index: Integer; p2: WideString);
|
||
begin
|
||
QTabWidget_setTabText(QTabWidgetH(Widget), index, @p2);
|
||
end;
|
||
|
||
procedure TQtTabWidget.setTabsClosable(AValue: Boolean);
|
||
begin
|
||
QTabWidget_setTabsClosable(QTabWidgetH(Widget), AValue);
|
||
end;
|
||
|
||
function TQtTabWidget.tabAt(APoint: TPoint): Integer;
|
||
var
|
||
AQtPoint: TQtPoint;
|
||
R: TRect;
|
||
begin
|
||
if (APoint.Y < 0) or (APoint.X < 0) then
|
||
begin
|
||
{some themes (eg. MacOSX) moves tab buttons
|
||
into the middle of parent, so we must
|
||
take it's geometry into account.}
|
||
R := TabBar.getGeometry;
|
||
QWidget_pos(getStackWidget, @AQtPoint);
|
||
AQtPoint.x := AQtPoint.x + APoint.x;
|
||
AQtPoint.y := AQtPoint.y + APoint.y;
|
||
|
||
if R.Left <> 0 then
|
||
dec(AQtPoint.x, R.Left);
|
||
if R.Top <> 0 then
|
||
dec(AQtPoint.y, R.Top);
|
||
end else
|
||
AQtPoint := QtPoint(APoint.x, APoint.y);
|
||
Result := QTabBar_tabAt(QTabBarH(TabBar.Widget), @AQtPoint);
|
||
end;
|
||
|
||
{ TQtComboBox }
|
||
|
||
function TQtComboBox.GetLineEdit: TQtLineEdit;
|
||
begin
|
||
if not getEditable then
|
||
begin
|
||
FLineEdit := nil
|
||
end
|
||
else
|
||
begin
|
||
if FLineEdit = nil then
|
||
begin
|
||
FLineEdit := TQtLineEdit.CreateFrom(LCLObject, QComboBox_lineEdit(QComboBoxH(Widget)));
|
||
FLineEdit.FOwner := Self;
|
||
QObject_disconnect(FLineEdit.Widget, '2returnPressed()', Widget, '1_q_returnPressed()');
|
||
FLineEdit.ChildOfComplexWidget := ccwComboBox;
|
||
FLineEdit.AttachEvents;
|
||
end;
|
||
end;
|
||
Result := FLineEdit;
|
||
end;
|
||
|
||
procedure TQtComboBox.SetOwnerDrawn(const AValue: Boolean);
|
||
begin
|
||
FOwnerDrawn := AValue;
|
||
if FDropList <> nil then
|
||
FDropList.OwnerDrawn := FOwnerDrawn;
|
||
end;
|
||
|
||
function TQtComboBox.GetDropList: TQtListWidget;
|
||
begin
|
||
if FDropList = nil then
|
||
begin
|
||
FDropList := TQtListWidget.CreateFrom(LCLObject, QListWidget_create());
|
||
FDropList.FOwner := Self;
|
||
FDropList.setAttribute(QtWA_NoMousePropagation, False);
|
||
FDropList.OwnerDrawn := OwnerDrawn;
|
||
FDropList.ChildOfComplexWidget := ccwComboBox;
|
||
QComboBox_setModel(QComboBoxH(Widget), FDropList.getModel);
|
||
QComboBox_setView(QComboBoxH(Widget), QListWidgetH(FDropList.Widget));
|
||
FDropList.AttachEvents;
|
||
end;
|
||
Result := FDropList;
|
||
end;
|
||
|
||
function TQtComboBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtComboBox.Create');
|
||
{$endif}
|
||
FKeyEnterFix := False; {issue #31574}
|
||
FMouseFixPos := QtPoint(-1, -1);
|
||
FDropListVisibleInternal := False;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QComboBox_create(Parent);
|
||
// disable AutoCompletion. LCL has its own
|
||
QComboBox_setAutoCompletion(QComboboxH(Result), False);
|
||
FLineEdit := nil;
|
||
FOwnerDrawn := False;
|
||
end;
|
||
|
||
function TQtComboBox.getCursorPosition: TPoint;
|
||
begin
|
||
Result := Point(0, 0);
|
||
if LineEdit <> nil then
|
||
Result.X := LineEdit.getCursorPosition.X;
|
||
end;
|
||
|
||
function TQtComboBox.getMaxLength: Integer;
|
||
begin
|
||
if LineEdit <> nil then
|
||
Result := LineEdit.getMaxLength
|
||
else
|
||
Result := 0;
|
||
end;
|
||
|
||
function TQtComboBox.getSelectionStart: Integer;
|
||
begin
|
||
if (LineEdit <> nil) then
|
||
Result := LineEdit.getSelectionStart
|
||
else
|
||
Result := 0;
|
||
end;
|
||
|
||
function TQtComboBox.getSelectionLength: Integer;
|
||
begin
|
||
if (LineEdit <> nil) then
|
||
Result := LineEdit.getSelectionLength
|
||
else
|
||
Result := 0;
|
||
end;
|
||
|
||
function TQtComboBox.isUndoAvailable: Boolean;
|
||
begin
|
||
if LineEdit <> nil then
|
||
Result := LineEdit.isUndoAvailable
|
||
else
|
||
Result := False;
|
||
end;
|
||
|
||
procedure TQtComboBox.setBorder(const ABorder: Boolean);
|
||
begin
|
||
QComboBox_setFrame(QComboBoxH(Widget), ABorder);
|
||
end;
|
||
|
||
procedure TQtComboBox.setEchoMode(const AMode: QLineEditEchoMode);
|
||
begin
|
||
if LineEdit <> nil then
|
||
LineEdit.setEchoMode(AMode);
|
||
end;
|
||
|
||
procedure TQtComboBox.setMaxLength(const ALength: Integer);
|
||
begin
|
||
if LineEdit <> nil then
|
||
LineEdit.setMaxLength(ALength);
|
||
end;
|
||
|
||
procedure TQtComboBox.setReadOnly(const AReadOnly: Boolean);
|
||
begin
|
||
setEditable(not AReadOnly);
|
||
end;
|
||
|
||
procedure TQtComboBox.setSelection(const AStart, ALength: Integer);
|
||
begin
|
||
if LineEdit <> nil then
|
||
LineEdit.setSelection(AStart, ALength);
|
||
end;
|
||
|
||
procedure TQtComboBox.setCursorPosition(const ACursorPosition: Integer);
|
||
begin
|
||
if LineEdit <> nil then
|
||
LineEdit.setCursorPosition(ACursorPosition);
|
||
end;
|
||
|
||
procedure TQtComboBox.setTextHint(const ATextHint: string);
|
||
begin
|
||
if getEditable then
|
||
LineEdit.setTextHint(ATextHint);
|
||
end;
|
||
|
||
procedure TQtComboBox.Cut;
|
||
begin
|
||
if LineEdit <> nil then
|
||
LineEdit.Cut;
|
||
end;
|
||
|
||
procedure TQtComboBox.Copy;
|
||
begin
|
||
if LineEdit <> nil then
|
||
LineEdit.Copy;
|
||
end;
|
||
|
||
procedure TQtComboBox.Paste;
|
||
begin
|
||
if LineEdit <> nil then
|
||
LineEdit.Paste;
|
||
end;
|
||
|
||
procedure TQtComboBox.Undo;
|
||
begin
|
||
if LineEdit <> nil then
|
||
LineEdit.Undo;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtComboBox.Destroy
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
destructor TQtComboBox.Destroy;
|
||
begin
|
||
FDropList.Free;
|
||
FLineEdit.Free;
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TQtComboBox.DestroyNotify(AWidget: TQtWidget);
|
||
begin
|
||
if AWidget = FLineEdit then
|
||
FLineEdit := nil;
|
||
if AWidget = FDropList then
|
||
FDropList := nil;
|
||
|
||
if Assigned(FList) then
|
||
FList := nil;
|
||
|
||
inherited DestroyNotify(AWidget);
|
||
end;
|
||
|
||
procedure TQtComboBox.InternalIntfGetItems;
|
||
begin
|
||
TCustomComboBox(LCLObject).IntfGetItems;
|
||
// because of issue #25032 we must call it here
|
||
if getEnabled then
|
||
SlotDropListVisibility(True);
|
||
end;
|
||
|
||
procedure TQtComboBox.ClearItems;
|
||
begin
|
||
QComboBox_clear(QComboBoxH(Widget));
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtComboBox.currentIndex
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtComboBox.currentIndex: Integer;
|
||
begin
|
||
Result := QComboBox_currentIndex(QComboBoxH(Widget));
|
||
end;
|
||
|
||
function TQtComboBox.findText(AText: WideString): Integer;
|
||
begin
|
||
Result := QComboBox_findText(QComboBoxH(Widget), @AText, QtMatchStartsWith);
|
||
end;
|
||
|
||
function TQtComboBox.getDroppedDown: Boolean;
|
||
begin
|
||
Result := QWidget_isVisible(QComboBox_view(QComboBoxH(Widget)));
|
||
end;
|
||
|
||
function TQtComboBox.getEditable: Boolean;
|
||
begin
|
||
Result := QComboBox_isEditable(QComboBoxH(Widget));
|
||
end;
|
||
|
||
function TQtComboBox.getItemText(AIndex: Integer): WideString;
|
||
begin
|
||
Result := '';
|
||
QComboBox_itemText(QComboBoxH(Widget), @Result, AIndex);
|
||
end;
|
||
|
||
function TQtComboBox.getMaxVisibleItems: Integer;
|
||
begin
|
||
Result := QComboBox_maxVisibleItems(QComboboxH(Widget));
|
||
end;
|
||
|
||
function TQtComboBox.getText: WideString;
|
||
begin
|
||
Result := '';
|
||
QComboBox_currentText(QComboBoxH(Widget), @Result);
|
||
if FOwnerDrawn and (FLineEdit = nil) and
|
||
(Result = '') and (Result <> FText) then
|
||
Result := FText;
|
||
end;
|
||
|
||
function TQtComboBox.getTextStatic: Boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
procedure TQtComboBox.insertItem(AIndex: Integer; AText: String);
|
||
var
|
||
Str: WideString;
|
||
begin
|
||
Str := GetUtf8String(AText);
|
||
insertItem(AIndex, @Str);
|
||
end;
|
||
|
||
procedure TQtComboBox.insertItem(AIndex: Integer; AText: PWideString);
|
||
begin
|
||
QComboBox_insertItem(QComboBoxH(WIdget), AIndex, AText, QVariant_create());
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtComboBox.Destroy
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtComboBox.setCurrentIndex(index: Integer);
|
||
begin
|
||
// don't fire any events when we are changing it from the LCL side
|
||
BeginUpdate;
|
||
QComboBox_setCurrentIndex(QComboBoxH(Widget), index);
|
||
EndUpdate;
|
||
end;
|
||
|
||
procedure TQtComboBox.setDefaultColorRoles;
|
||
begin
|
||
WidgetColorRole := QPaletteBase;
|
||
TextColorRole := QPaletteText;
|
||
end;
|
||
|
||
procedure TQtComboBox.setDroppedDown(const ADroppedDown: Boolean);
|
||
begin
|
||
if ADroppedDown <> QWidget_isVisible(QComboBox_view(QComboBoxH(Widget))) then
|
||
begin
|
||
if ADroppedDown then
|
||
begin
|
||
InternalIntfGetItems;
|
||
QComboBox_showPopup(QComboBoxH(Widget));
|
||
end else
|
||
QComboBox_hidePopup(QComboBoxH(Widget));
|
||
end;
|
||
end;
|
||
|
||
procedure TQtComboBox.setMaxVisibleItems(ACount: Integer);
|
||
begin
|
||
QComboBox_setMaxVisibleItems(QComboboxH(Widget), ACount);
|
||
end;
|
||
|
||
procedure TQtComboBox.setEditable(const AValue: Boolean);
|
||
begin
|
||
QComboBox_setEditable(QComboBoxH(Widget), AValue);
|
||
if not AValue then
|
||
FreeAndNil(FLineEdit)
|
||
else
|
||
begin
|
||
LineEdit.setFocusPolicy(getFocusPolicy);
|
||
setText(FText);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtComboBox.setItemText(AIndex: Integer; AText: String);
|
||
var
|
||
Str: WideString;
|
||
item: QListWidgetItemH;
|
||
R: TRect;
|
||
begin
|
||
if (AIndex >= 0) and (AIndex < QComboBox_count(QComboBoxH(Widget))) then
|
||
begin
|
||
Str := GetUTF8String(AText);
|
||
QComboBox_setItemText(QComboBoxH(Widget), AIndex, @Str);
|
||
{we must update our custom delegate}
|
||
if (FDropList <> nil) and
|
||
(FDropList.getVisible) and
|
||
(FDropList.OwnerDrawn) then
|
||
begin
|
||
Item := FDropList.getItem(AIndex);
|
||
if Item <> nil then
|
||
begin
|
||
R := FDropList.getVisualItemRect(Item);
|
||
FDropList.Update(@R);
|
||
end;
|
||
end;
|
||
end else
|
||
insertItem(AIndex, AText);
|
||
end;
|
||
|
||
procedure TQtComboBox.setText(const W: WideString);
|
||
begin
|
||
if FLineEdit = nil then
|
||
FText := W
|
||
else
|
||
QComboBox_setEditText(QComboBoxH(Widget), @W);
|
||
end;
|
||
|
||
procedure TQtComboBox.removeItem(AIndex: Integer);
|
||
begin
|
||
QComboBox_removeItem(QComboBoxH(Widget), AIndex);
|
||
end;
|
||
|
||
procedure TQtComboBox.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
FActivateHook := QComboBox_hook_create(Widget);
|
||
FChangeHook := QComboBox_hook_create(Widget);
|
||
FSelectHook := QComboBox_hook_create(Widget);
|
||
|
||
// OnChange event if itemindex changed by mouse or kbd
|
||
QComboBox_hook_hook_activated(FActivateHook, @SlotActivate);
|
||
|
||
// OnChange event -> fires only when text changed
|
||
QComboBox_hook_hook_editTextChanged(FChangeHook, @SlotChange);
|
||
// OnSelect event
|
||
QComboBox_hook_hook_currentIndexChanged(FSelectHook, @SlotSelect);
|
||
|
||
// DropList events
|
||
FDropListEventHook := QObject_hook_create(DropList.Widget);
|
||
QObject_hook_hook_events(FDropListEventHook, @EventFilter);
|
||
end;
|
||
|
||
procedure TQtComboBox.DetachEvents;
|
||
begin
|
||
if FDropListEventHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FDropListEventHook);
|
||
FDropListEventHook := nil;
|
||
end;
|
||
if FActivateHook <> nil then
|
||
begin
|
||
QComboBox_hook_destroy(FActivateHook);
|
||
FActivateHook := nil;
|
||
end;
|
||
if FChangeHook <> nil then
|
||
begin
|
||
QComboBox_hook_destroy(FChangeHook);
|
||
FChangeHook := nil;
|
||
end;
|
||
if FSelectHook <> nil then
|
||
begin
|
||
QComboBox_hook_destroy(FSelectHook);
|
||
FSelectHook := nil;
|
||
end;
|
||
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
procedure TQtComboBox.slotPaintCombo(Sender: QObjectH; Event: QEventH); cdecl;
|
||
var
|
||
Msg: TLMPaint;
|
||
AStruct: PPaintStruct;
|
||
MsgItem: TLMDrawListItem;
|
||
DrawStruct: TDrawListItemStruct;
|
||
P: TPoint;
|
||
Opt: QStyleOptionComboBoxH;
|
||
R: TRect;
|
||
State: QStyleState;
|
||
CurrIndex: Integer;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtComboBox.SlotPaintCombo ', dbgsName(LCLObject));
|
||
{$endif}
|
||
CurrIndex := currentIndex;
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
Msg.Msg := LM_PAINT;
|
||
New(AStruct);
|
||
FillChar(AStruct^, SizeOf(TPaintStruct), 0);
|
||
Msg.PaintStruct := AStruct;
|
||
|
||
with PaintData do
|
||
begin
|
||
PaintWidget := Widget;
|
||
ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
|
||
if ClipRect = nil then
|
||
New(ClipRect);
|
||
QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
|
||
end;
|
||
|
||
Msg.DC := BeginPaint(THandle(Self), AStruct^);
|
||
FContext := Msg.DC;
|
||
|
||
Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
|
||
Msg.PaintStruct^.hdc := FContext;
|
||
|
||
P := getClientOffset;
|
||
inc(P.X, FScrollX);
|
||
inc(P.Y, FScrollY);
|
||
TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
|
||
|
||
TQtDeviceContext(Msg.DC).save;
|
||
try
|
||
Opt := QStyleOptionComboBox_create();
|
||
QStyleOption_initFrom(Opt, Widget);
|
||
State := QStyleOption_state(opt);
|
||
QStyleOption_rect(Opt, @R);
|
||
QPainter_setClipRect(TQtDeviceContext(Msg.DC).Widget, @R);
|
||
|
||
QStyle_drawComplexControl(QApplication_style(), QStyleCC_ComboBox, Opt,
|
||
TQtDeviceContext(Msg.DC).Widget, Widget);
|
||
QStyle_subControlRect(QApplication_style(), @R, QStyleCC_ComboBox, Opt,
|
||
QStyleSC_ComboBoxEditField , Widget);
|
||
if CurrIndex < 0 then
|
||
begin
|
||
QStyleOptionComboBox_setCurrentText(Opt, @FText);
|
||
QStyle_drawControl(QApplication_style(), QStyleCE_ComboBoxLabel, opt,
|
||
TQtDeviceContext(Msg.DC).Widget, Widget);
|
||
end;
|
||
|
||
finally
|
||
QStyleOptionComboBox_destroy(Opt);
|
||
TQtDeviceContext(Msg.DC).restore;
|
||
end;
|
||
|
||
inc(R.Top);
|
||
dec(R.Bottom);
|
||
QPainter_setClipRect(TQTDeviceContext(Msg.DC).Widget, @R);
|
||
|
||
DrawStruct.ItemID := UINT(CurrIndex);
|
||
DrawStruct.Area := R;
|
||
DrawStruct.DC := Msg.DC;
|
||
|
||
DrawStruct.ItemState := [];
|
||
|
||
// selected
|
||
if (State and QStyleState_Selected) <> 0 then
|
||
Include(DrawStruct.ItemState, odSelected);
|
||
// disabled
|
||
if (State and QStyleState_Enabled) = 0 then
|
||
Include(DrawStruct.ItemState, odDisabled);
|
||
// focused (QStyleState_FocusAtBorder?)
|
||
if ((State and QStyleState_HasFocus) <> 0) or
|
||
((State and QStyleState_FocusAtBorder) <> 0) then
|
||
Include(DrawStruct.ItemState, odFocused);
|
||
// hotlight
|
||
if (State and QStyleState_MouseOver) <> 0 then
|
||
Include(DrawStruct.ItemState, odHotLight);
|
||
|
||
MsgItem.Msg := LM_DRAWLISTITEM;
|
||
MsgItem.DrawListItemStruct := @DrawStruct;
|
||
|
||
try
|
||
if CurrIndex >= 0 then
|
||
DeliverMessage(MsgItem);
|
||
finally
|
||
Dispose(PaintData.ClipRect);
|
||
Fillchar(FPaintData, SizeOf(FPaintData), 0);
|
||
FContext := 0;
|
||
EndPaint(THandle(Self), AStruct^);
|
||
Dispose(AStruct);
|
||
end;
|
||
end;
|
||
|
||
{this routine is called ONLY from dropdown list viewport event filter
|
||
when QEventShow occurs.It sends MouseRelease event to LCL !
|
||
Should not be used in any other case.}
|
||
procedure TQtComboBox.FixMouseUp;
|
||
var
|
||
MouseEvent: QMouseEventH;
|
||
AMouseFixPosF: TQtPointF;
|
||
begin
|
||
if (FMouseFixPos.x = -1) and (FMouseFixPos.y = -1) then
|
||
exit;
|
||
if QGUIApplication_mouseButtons = QtLeftButton then
|
||
begin
|
||
AMouseFixPosF.X := FMouseFixPos.X;
|
||
AMouseFixPosF.Y := FMouseFixPos.Y;
|
||
MouseEvent := QMouseEvent_create(QEventMouseButtonRelease, @AMouseFixPosF, QtLeftButton,
|
||
QtLeftButton, QGUIApplication_keyboardModifiers());
|
||
QCoreApplication_postEvent(Widget, MouseEvent);
|
||
end;
|
||
end;
|
||
|
||
function TQtComboBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
R, R1: TRect;
|
||
ButtonRect: TRect;
|
||
P: TQtPoint;
|
||
Pt: TPoint;
|
||
Opt: QStyleOptionComboBoxH;
|
||
begin
|
||
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
|
||
if LCLObject = nil then
|
||
exit;
|
||
|
||
if (FDropList <> nil) and (Sender = FDropList.Widget) then
|
||
begin
|
||
if (Byte(QEvent_type(Event)) in [QEventKeyPress, QEventKeyRelease,QEventFontChange]) then
|
||
begin
|
||
Result := inherited EventFilter(Sender, Event);
|
||
if Result and (QEvent_type(Event) = QEventKeyPress) then
|
||
FKeyEnterFix := True; {issue #31574}
|
||
end;
|
||
QEvent_ignore(Event);
|
||
exit;
|
||
end;
|
||
|
||
BeginEventProcessing;
|
||
try
|
||
if FKeyEnterFix and (Byte(QEvent_type(Event)) in [QEventMouseButtonPress, QEventMouseButtonDblClick,
|
||
QEventMouseButtonRelease, QEventKeyPress, QEventHide, QEventShow]) then
|
||
FKeyEnterFix := False; {issue #31574}
|
||
case QEvent_type(Event) of
|
||
QEventFocusOut:
|
||
begin
|
||
if Assigned(FLineEdit) and FLineEdit.getVisible then
|
||
begin
|
||
FLineEdit.CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(FLineEdit.Widget));
|
||
FLineEdit.CachedSelectionLen := UTF16Length(FLineEdit.getSelectedText);
|
||
end;
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
QEventFocusIn:
|
||
begin
|
||
if Assigned(FLineEdit) and FLineEdit.getVisible then
|
||
begin
|
||
FLineEdit.CachedSelectionStart := -1;
|
||
FLineEdit.CachedSelectionLen := -1;
|
||
end;
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
QEventHide:
|
||
begin
|
||
if getVisible then
|
||
SlotShow(False);
|
||
end;
|
||
QEventPaint:
|
||
begin
|
||
if FOwnerDrawn and not getEditable then
|
||
begin
|
||
SlotPaintCombo(Widget, Event);
|
||
Result := True;
|
||
QEvent_accept(Event);
|
||
end;
|
||
end;
|
||
QEventMouseButtonRelease:
|
||
begin
|
||
FMouseFixPos := QtPoint(-1, -1);
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
QEventMouseButtonPress:
|
||
begin
|
||
if not FDropListVisibleInternal and
|
||
(QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
|
||
begin
|
||
// some themes have empty space around combo button !
|
||
|
||
QMouseEvent_pos(QMouseEventH(Event), @P);
|
||
FMouseFixPos := P;
|
||
|
||
// our combo geometry
|
||
R := getGeometry;
|
||
|
||
Pt := Point(P.X, P.Y);
|
||
|
||
// our combo arrow position when we are editable combobox
|
||
if getEditable then
|
||
begin
|
||
opt := QStyleOptionComboBox_create();
|
||
QStyle_subControlRect(QApplication_style(), @R1, QStyleCC_ComboBox,
|
||
opt, QStyleSC_ComboBoxArrow, QComboBoxH(Widget));
|
||
QStyleOptionComboBox_destroy(opt);
|
||
R := Rect(0, 0, R.Right - R.Left, R.Bottom - R.Top);
|
||
ButtonRect := Rect(R.Right + R1.Left, R.Top,
|
||
R.Right - R1.Right, R.Bottom);
|
||
end else
|
||
begin
|
||
ButtonRect := R;
|
||
OffsetRect(ButtonRect, -R.Left, -R.Top);
|
||
end;
|
||
|
||
if PtInRect(ButtonRect, Pt) then
|
||
InternalIntfGetItems;
|
||
end;
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
QEventMouseButtonDblClick:
|
||
begin
|
||
// avoid crash on unfocused combobox raised from
|
||
// eg. TStringGrid as picklist.
|
||
// crash happens when combo is hidden in cell, and then we
|
||
// dbl click on position of combo button. Control raises combo
|
||
// and propagate dbl click to combobox which must grab focus in
|
||
// that case.
|
||
if CanSendLCLMessage and getEnabled and not hasFocus then
|
||
setFocus;
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
QEventKeyPress:
|
||
begin
|
||
if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_F4) or
|
||
((QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
|
||
not getEditable) then
|
||
begin
|
||
if not FDropListVisibleInternal then
|
||
InternalIntfGetItems
|
||
else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
QEventKeyRelease:
|
||
begin
|
||
{issue #31574}
|
||
if not FKeyEnterFix then
|
||
Result := inherited EventFilter(Sender, Event);
|
||
FKeyEnterFix := False;
|
||
end;
|
||
else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtComboBox.preferredSize(var PreferredWidth,
|
||
PreferredHeight: integer; WithThemeSpace: Boolean);
|
||
var
|
||
Size: TSize;
|
||
begin
|
||
QComboBox_sizeHint(QComboBoxH(Widget), @Size);
|
||
PreferredWidth := Size.cx;
|
||
PreferredHeight := Size.cy;
|
||
end;
|
||
|
||
procedure TQtComboBox.SlotActivate(index: Integer); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
if InUpdate then
|
||
Exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_ACTIVATE;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
procedure TQtComboBox.SlotChange(p1: PWideString); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
if InUpdate then
|
||
Exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
Msg.Msg := LM_CHANGED;
|
||
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
procedure TQtComboBox.SlotSelect(index: Integer); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
if InUpdate then
|
||
exit;
|
||
|
||
{we must fire OnChange() if it isn''t editable
|
||
since SlotChange() fires only for editable
|
||
comboboxes }
|
||
if not getEditable then
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_CHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
FillChar(Msg, SizeOf(Msg), #0);
|
||
|
||
Msg.Msg := LM_SELCHANGE;
|
||
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
procedure TQtComboBox.SlotDropListVisibility(AVisible: Boolean); cdecl;
|
||
const
|
||
VisibilityToCodeMap: array[Boolean] of Word =
|
||
(
|
||
CBN_CLOSEUP,
|
||
CBN_DROPDOWN
|
||
);
|
||
var
|
||
Msg : TLMCommand;
|
||
begin
|
||
if InUpdate then
|
||
Exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), 0);
|
||
Msg.Msg := CN_COMMAND;
|
||
Msg.NotifyCode := VisibilityToCodeMap[AVisible];
|
||
|
||
DeliverMessage(Msg);
|
||
FDropListVisibleInternal := AVisible;
|
||
end;
|
||
|
||
{ TQtAbstractSpinBox }
|
||
|
||
function TQtAbstractSpinBox.GetLineEdit: QLineEditH;
|
||
begin
|
||
if FLineEdit = nil then
|
||
FLineEdit := QLCLAbstractSpinBox_lineEditHandle(QAbstractSpinBoxH(Widget));
|
||
if Assigned(FLineEdit) and not Assigned(FLineEditHook) then
|
||
begin
|
||
FLineEditHook := QObject_hook_create(FLineEdit);
|
||
QObject_hook_hook_events(FLineEditHook, @LineEditEventFilter);
|
||
FTextChangedHook := QLineEdit_hook_create(FLineEdit);
|
||
QLineEdit_hook_hook_textChanged(FTextChangedHook, @SignalLineEditTextChanged);
|
||
end;
|
||
Result := FLineEdit;
|
||
end;
|
||
|
||
function TQtAbstractSpinBox.LineEditEventFilter(Sender: QObjectH; Event: QEventH
|
||
): Boolean; cdecl;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if QEvent_type(Event) = QEventFontChange then
|
||
Result := EventFilter(QWidgetH(Sender), Event);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.SignalLineEditTextChanged(AnonParam1: PWideString); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
if FTextChangedByValueChanged then
|
||
begin
|
||
FTextChangedByValueChanged := False;
|
||
Exit;
|
||
end;
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := CM_TEXTCHANGED;
|
||
if not InUpdate then
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.setTextHint(const ATextHint: string);
|
||
var
|
||
W: WideString;
|
||
begin
|
||
if Assigned(FLineEdit) and not (csDesigning in LCLObject.ComponentState) then
|
||
begin
|
||
W := UTF8ToUTF16(ATextHint);
|
||
QLineEdit_setPlaceholderText(FLineEdit, @W);
|
||
end;
|
||
end;
|
||
|
||
function TQtAbstractSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtAbstractSpinBox.Create');
|
||
{$endif}
|
||
FLineEditHook := nil;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
FTextChangedByValueChanged := False;
|
||
Result := QAbstractSpinBox_create(Parent);
|
||
end;
|
||
|
||
function TQtAbstractSpinBox.getMaxLength: Integer;
|
||
begin
|
||
if LineEdit <> nil then
|
||
Result := QLineEdit_maxLength(LineEdit)
|
||
else
|
||
Result := 0;
|
||
end;
|
||
|
||
function TQtAbstractSpinBox.getSelectionStart: Integer;
|
||
begin
|
||
if (LineEdit <> nil) then
|
||
begin
|
||
if QLineEdit_hasSelectedText(LineEdit) then
|
||
Result := QLineEdit_selectionStart(LineEdit)
|
||
else
|
||
Result := QLineEdit_cursorPosition(LineEdit);
|
||
end
|
||
else
|
||
Result := 0;
|
||
end;
|
||
|
||
function TQtAbstractSpinBox.getSelectionLength: Integer;
|
||
var
|
||
W: WideString;
|
||
begin
|
||
if (LineEdit <> nil) and QLineEdit_hasSelectedText(LineEdit) then
|
||
begin
|
||
QLineEdit_selectedText(LineEdit, @W);
|
||
Result := UTF16Length(W);
|
||
end
|
||
else
|
||
Result := 0;
|
||
end;
|
||
|
||
function TQtAbstractSpinBox.isUndoAvailable: Boolean;
|
||
begin
|
||
if LineEdit <> nil then
|
||
Result := QLineEdit_isUndoAvailable(LineEdit)
|
||
else
|
||
Result := False;
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.setBorder(const ABorder: Boolean);
|
||
begin
|
||
QAbstractSpinBox_setFrame(QAbstractSpinBoxH(Widget), ABorder);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.setCursorPosition(const ACursorPosition: Integer);
|
||
begin
|
||
if LineEdit <> nil then
|
||
QLineEdit_setCursorPosition(LineEdit, ACursorPosition);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.setDefaultColorRoles;
|
||
begin
|
||
WidgetColorRole := QPaletteBase;
|
||
TextColorRole := QPaletteText;
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.setEchoMode(const AMode: QLineEditEchoMode);
|
||
begin
|
||
if LineEdit <> nil then
|
||
QLineEdit_setEchoMode(LineEdit, AMode);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.setMaxLength(const ALength: Integer);
|
||
begin
|
||
if LineEdit <> nil then
|
||
QLineEdit_setMaxLength(LineEdit, ALength);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.setSelection(const AStart, ALength: Integer);
|
||
begin
|
||
if (LineEdit <> nil) and (AStart >= 0) then
|
||
begin
|
||
if ALength > 0 then
|
||
QLineEdit_setSelection(LineEdit, AStart, ALength)
|
||
else
|
||
QLineEdit_setCursorPosition(LineEdit, AStart);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.Cut;
|
||
begin
|
||
if LineEdit <> nil then
|
||
QLineEdit_cut(LineEdit);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.Copy;
|
||
begin
|
||
if LineEdit <> nil then
|
||
QLineEdit_copy(LineEdit);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.Paste;
|
||
begin
|
||
if LineEdit <> nil then
|
||
QLineEdit_paste(LineEdit);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.Undo;
|
||
begin
|
||
if LineEdit <> nil then
|
||
QLineEdit_undo(LineEdit);
|
||
end;
|
||
|
||
function TQtAbstractSpinBox.getCursorPosition: TPoint;
|
||
begin
|
||
Result := Point(0, 0);
|
||
if LineEdit <> nil then
|
||
Result.X := QLineEdit_cursorPosition(LineEdit);
|
||
end;
|
||
|
||
function TQtAbstractSpinBox.getReadOnly: Boolean;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtAbstractSpinBox.IsReadOnly');
|
||
{$endif}
|
||
Result := QAbstractSpinBox_isReadOnly(QAbstractSpinBoxH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractSpinBox.getText: WideString;
|
||
begin
|
||
if LineEdit <> nil then
|
||
QLineEdit_text(LineEdit, @Result)
|
||
else
|
||
Result := '';
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtAbstractSpinBox.GetText Result=',Result);
|
||
{$endif}
|
||
end;
|
||
|
||
function TQtAbstractSpinBox.getTextStatic: Boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.setAlignment(const AAlignment: QtAlignment);
|
||
begin
|
||
QAbstractSpinBox_setAlignment(QSpinBoxH(Widget), AAlignment);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.setFocusPolicy(const APolicy: QtFocusPolicy);
|
||
begin
|
||
inherited setFocusPolicy(APolicy);
|
||
QWidget_setFocusPolicy(LineEdit, APolicy);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.setReadOnly(const r: Boolean);
|
||
begin
|
||
QAbstractSpinBox_setReadOnly(QAbstractSpinBoxH(Widget), r);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.setText(const W: WideString);
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtAbstractSpinBox.SetText W=',w);
|
||
{$endif}
|
||
if (LineEdit <> nil) then
|
||
QLineEdit_setText(LineEdit, @W)
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
FEditingFinishedHook := QAbstractSpinBox_hook_create(Widget);
|
||
{TODO: find out which TLMessage should be sended }
|
||
QAbstractSpinBox_hook_hook_editingFinished(FEditingFinishedHook, @SignalEditingFinished);
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.DetachEvents;
|
||
begin
|
||
if FEditingFinishedHook <> nil then
|
||
begin
|
||
QAbstractSpinBox_hook_destroy(FEditingFinishedHook);
|
||
FEditingFinishedHook := nil;
|
||
end;
|
||
|
||
if FLineEditHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FLineEditHook);
|
||
FLineEditHook := nil;
|
||
end;
|
||
|
||
if FTextChangedHook <> nil then
|
||
begin
|
||
QLineEdit_hook_destroy(FTextChangedHook);
|
||
FTextChangedHook := nil;
|
||
end;
|
||
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtAbstractSpinBox.EventFilter(Sender: QObjectH; Event: QEventH
|
||
): Boolean; cdecl;
|
||
var
|
||
IsDeleteKey: Boolean;
|
||
begin
|
||
if (QEvent_type(Event) = QEventKeyPress) or
|
||
(QEvent_type(Event) = QEventKeyRelease) then
|
||
IsDeleteKey := (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Delete) and
|
||
(QKeyEvent_modifiers(QKeyEventH(Event)) = QtNoModifier)
|
||
else
|
||
IsDeleteKey := False;
|
||
Result := inherited EventFilter(Sender, Event);
|
||
{we must pass delete key to qt, qabstractspinbox doesn't like what we do}
|
||
if IsDeleteKey then
|
||
Result := False;
|
||
{$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
|
||
if (FParentShowPassed = 1) then
|
||
begin
|
||
if QEvent_type(Event) <> QEventPaint then
|
||
begin
|
||
inc(FParentShowPassed);
|
||
BeginUpdate;
|
||
setValue(getValue);
|
||
EndUpdate;
|
||
end;
|
||
end;
|
||
|
||
if (QEvent_type(Event) = QEventShowToParent) and
|
||
(FParentShowPassed = 0) then
|
||
inc(FParentShowPassed);
|
||
{$ENDIF}
|
||
|
||
end;
|
||
|
||
procedure TQtAbstractSpinBox.SignalEditingFinished; cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtAbstractSpinBox.SignalEditingFinished');
|
||
{$endif}
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
{ TODO: Find out which message should be sended here
|
||
problem:
|
||
everything is fine when we work with mouse, or
|
||
press TabKey to select next control, but if we
|
||
connect OnKeyDown and say eg. VK_RETURN: SelectNext(ActiveControl, true, true)
|
||
then spinedit text is always selected, nothing important but looks ugly.}
|
||
// Msg.Msg := LM_EXIT;
|
||
// DeliverMessage(Msg);
|
||
end;
|
||
|
||
{ TQtFloatSpinBox }
|
||
|
||
function TQtFloatSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtFloatSpinBox.Create');
|
||
{$endif}
|
||
{$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
|
||
FParentShowPassed := 0;
|
||
{$ENDIF}
|
||
FValue := 0;
|
||
FLineEditHook := nil;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QDoubleSpinBox_create(Parent);
|
||
end;
|
||
|
||
function TQtFloatSpinBox.getValue: Double;
|
||
begin
|
||
Result := FValue;
|
||
end;
|
||
|
||
procedure TQtFloatSpinBox.setDecimals(const v: integer);
|
||
begin
|
||
QDoubleSpinBox_setDecimals(QDoubleSpinBoxH(Widget), v);
|
||
end;
|
||
|
||
procedure TQtFloatSpinBox.setMinimum(const v: Double);
|
||
begin
|
||
QDoubleSpinBox_setMinimum(QDoubleSpinBoxH(Widget), v);
|
||
end;
|
||
|
||
procedure TQtFloatSpinBox.setMaximum(const v: Double);
|
||
begin
|
||
QDoubleSpinBox_setMaximum(QDoubleSpinBoxH(Widget), v);
|
||
end;
|
||
|
||
procedure TQtFloatSpinBox.setSingleStep(const v: Double);
|
||
begin
|
||
QDoubleSpinBox_setSingleStep(QDoubleSpinBoxH(Widget), v);
|
||
end;
|
||
|
||
procedure TQtFloatSpinBox.setValue(const v: Double);
|
||
begin
|
||
FValue := v;
|
||
QDoubleSpinBox_setValue(QDoubleSpinBoxH(Widget), FValue);
|
||
end;
|
||
|
||
procedure TQtFloatSpinBox.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FValueChangedHook := QDoubleSpinBox_hook_create(Widget);
|
||
QDoubleSpinBox_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
|
||
end;
|
||
|
||
procedure TQtFloatSpinBox.DetachEvents;
|
||
begin
|
||
if FValueChangedHook <> nil then
|
||
begin
|
||
QDoubleSpinBox_hook_destroy(FValueChangedHook);
|
||
FValueChangedHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
procedure TQtFloatSpinBox.SignalValueChanged(p1: Double); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
FValue := p1;
|
||
FTextChangedByValueChanged := True;
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := CM_TEXTCHANGED;
|
||
if not InUpdate then
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{ TQtSpinBox }
|
||
|
||
function TQtSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtSpinBox.Create');
|
||
{$endif}
|
||
{$IF DEFINED(CPU64) AND NOT DEFINED(WIN64)}
|
||
FParentShowPassed := 0;
|
||
{$ENDIF}
|
||
FLineEditHook := nil;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QSpinBox_create(Parent);
|
||
end;
|
||
|
||
function TQtSpinBox.getValue: Double;
|
||
begin
|
||
Result := FValue;
|
||
end;
|
||
|
||
procedure TQtSpinBox.setMinimum(const v: Double);
|
||
begin
|
||
QSpinBox_setMinimum(QSpinBoxH(Widget), round(v));
|
||
end;
|
||
|
||
procedure TQtSpinBox.setMaximum(const v: Double);
|
||
begin
|
||
QSpinBox_setMaximum(QSpinBoxH(Widget), round(v));
|
||
end;
|
||
|
||
procedure TQtSpinBox.setSingleStep(const v: Double);
|
||
begin
|
||
QSpinBox_setSingleStep(QSpinBoxH(Widget), round(v));
|
||
end;
|
||
|
||
procedure TQtSpinBox.setValue(const v: Double);
|
||
begin
|
||
FValue := Round(v);
|
||
QSpinBox_setValue(QSpinBoxH(Widget), round(v));
|
||
end;
|
||
|
||
procedure TQtSpinBox.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FValueChangedHook := QSpinBox_hook_create(Widget);
|
||
QSpinBox_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
|
||
end;
|
||
|
||
procedure TQtSpinBox.DetachEvents;
|
||
begin
|
||
if FValueChangedHook <> nil then
|
||
begin
|
||
QSpinBox_hook_destroy(FValueChangedHook);
|
||
FValueChangedHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
procedure TQtSpinBox.SignalValueChanged(p1: Integer); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
FValue := p1;
|
||
FTextChangedByValueChanged := True;
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := CM_TEXTCHANGED;
|
||
if not InUpdate then
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{ TQtListView }
|
||
|
||
function TQtListView.getBatchSize: integer;
|
||
begin
|
||
Result := QListView_batchSize(QListViewH(Widget));
|
||
end;
|
||
|
||
function TQtListView.getGridSize: TSize;
|
||
begin
|
||
QListView_gridSize(QListViewH(Widget), @Result);
|
||
end;
|
||
|
||
function TQtListView.getSpacing: Integer;
|
||
begin
|
||
Result := QListView_spacing(QListViewH(Widget));
|
||
end;
|
||
|
||
procedure TQtListView.setBatchSize(const AValue: integer);
|
||
begin
|
||
QListView_setBatchSize(QListViewH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtListView.setGridSize(const AValue: TSize);
|
||
begin
|
||
QListView_setGridSize(QListViewH(Widget), @AValue);
|
||
end;
|
||
|
||
procedure TQtListView.setLayoutMode(const ALayoutMode: QListViewLayoutMode);
|
||
begin
|
||
QListView_setLayoutMode(QListViewH(Widget), ALayoutMode);
|
||
end;
|
||
|
||
procedure TQtListView.setMovement(const AMovement: QListViewMovement);
|
||
begin
|
||
QListView_setMovement(QListViewH(Widget), AMovement);
|
||
end;
|
||
|
||
procedure TQtListView.setResizeMode(const AResizeMode: QListViewResizeMode);
|
||
begin
|
||
QListView_setResizeMode(QListViewH(Widget), AResizeMode);
|
||
end;
|
||
|
||
procedure TQtListView.setSpacing(const AValue: integer);
|
||
begin
|
||
QListView_setSpacing(QListViewH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtListView.setUniformItemSizes(const AEnable: Boolean);
|
||
begin
|
||
QListView_setUniformItemSizes(QListViewH(Widget), AEnable);
|
||
end;
|
||
|
||
procedure TQtListView.setViewFlow(const AFlow: QListViewFlow);
|
||
begin
|
||
QListView_setFlow(QListViewH(Widget), AFlow);
|
||
end;
|
||
|
||
procedure TQtListView.setViewMode(const AMode: QListViewViewMode);
|
||
begin
|
||
QListView_setViewMode(QListViewH(Widget), AMode);
|
||
end;
|
||
|
||
procedure TQtListView.setWordWrap(const AValue: Boolean);
|
||
begin
|
||
QListView_setWordWrap(QListViewH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtListView.setWrapping(const AWrapping: Boolean);
|
||
begin
|
||
QListView_setWrapping(QListViewH(Widget), AWrapping);
|
||
end;
|
||
|
||
procedure TQtListView.LayoutItems;
|
||
begin
|
||
QListView_doItemsLayout(QListViewH(Widget));
|
||
end;
|
||
|
||
{ TQtListWidget }
|
||
|
||
function TQtListWidget.getItemCount: Integer;
|
||
begin
|
||
Result := QListWidget_count(QListWidgetH(Widget));
|
||
end;
|
||
|
||
function TQtListWidget.GetItemChecked(AIndex: Integer): Boolean;
|
||
var
|
||
AItem: QListWidgetItemH;
|
||
begin
|
||
Result := False;
|
||
AItem := getItem(AIndex);
|
||
if Assigned(AItem) then
|
||
Result := QListWidgetItem_checkState(AItem) = QtChecked;
|
||
end;
|
||
|
||
function TQtListWidget.GetItemEnabled(AIndex: Integer): Boolean;
|
||
var
|
||
AItem: QListWidgetItemH;
|
||
begin
|
||
Result := False;
|
||
AItem := getItem(AIndex);
|
||
if Assigned(AItem) then
|
||
Result := QListWidgetItem_flags(AItem) and QtItemIsEnabled <> 0;
|
||
end;
|
||
|
||
function TQtListWidget.GetSelected(AIndex: Integer): Boolean;
|
||
var
|
||
AItem: QListWidgetItemH;
|
||
begin
|
||
Result := False;
|
||
AItem := getItem(AIndex);
|
||
if Assigned(AItem) then
|
||
Result := getItemSelected(AItem);
|
||
end;
|
||
|
||
procedure TQtListWidget.SetItemChecked(AIndex: Integer; AValue: Boolean);
|
||
var
|
||
AItem: QListWidgetItemH;
|
||
begin
|
||
AItem := getItem(AIndex);
|
||
if Assigned(AItem) then
|
||
begin
|
||
if AValue then
|
||
QListWidgetItem_setCheckState(AItem, QtChecked)
|
||
else
|
||
QListWidgetItem_setCheckState(AItem, QtUnChecked);
|
||
SetItemLastCheckState(AItem);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtListWidget.setItemCount(const AValue: Integer);
|
||
var
|
||
i: Integer;
|
||
AList: QStringListH;
|
||
WStr: WideString;
|
||
begin
|
||
if AValue = ItemCount then
|
||
exit;
|
||
BeginUpdate;
|
||
try
|
||
ClearItems;
|
||
AList := QStringList_create();
|
||
WStr := '';
|
||
for i := 1 to AValue do
|
||
QStringList_append(AList, @WStr);
|
||
QListWidget_addItems(QListWidgetH(Widget), AList);
|
||
QStringList_destroy(AList);
|
||
finally
|
||
EndUpdate;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtListWidget.SetItemEnabled(AIndex: Integer; AValue: Boolean);
|
||
var
|
||
AItem: QListWidgetItemH;
|
||
Flags: QtItemFlags;
|
||
begin
|
||
AItem := getItem(AIndex);
|
||
if Assigned(AItem) then
|
||
begin
|
||
Flags := QListWidgetItem_flags(AItem);
|
||
if AValue then
|
||
Flags := Flags or QtItemIsEnabled
|
||
else
|
||
Flags := Flags and not QtItemIsEnabled;
|
||
QListWidgetItem_setFlags(AItem, Flags);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtListWidget.SetSelected(AIndex: Integer; AValue: Boolean);
|
||
begin
|
||
if (AIndex >= 0) and (AIndex < RowCount) then
|
||
setItemSelected(getItem(AIndex), AValue);
|
||
end;
|
||
|
||
function TQtListWidget.GetItemLastCheckState(AItem: QListWidgetItemH
|
||
): QtCheckState;
|
||
var
|
||
v: QVariantH;
|
||
ok: Boolean;
|
||
begin
|
||
Result := QtUnChecked;
|
||
if AItem = nil then
|
||
exit;
|
||
v := QVariant_create();
|
||
QListWidgetItem_data(AItem, v, QtCheckStateRole);
|
||
ok := False;
|
||
if QVariant_isValid(v) then
|
||
Result := QtCheckState(QVariant_toInt(v, @Ok));
|
||
QVariant_destroy(v);
|
||
end;
|
||
|
||
procedure TQtListWidget.SetItemLastCheckState(AItem: QListWidgetItemH);
|
||
var
|
||
AState: QtCheckState;
|
||
begin
|
||
if AItem = nil then
|
||
exit;
|
||
AState := QListWidgetItem_checkState(AItem);
|
||
SetItemLastCheckStateInternal(AItem, AState);
|
||
end;
|
||
|
||
procedure TQtListWidget.SetItemLastCheckStateInternal(AItem: QListWidgetItemH;
|
||
AState: QtCheckState);
|
||
var
|
||
v: QVariantH;
|
||
begin
|
||
v := QVariant_create(Ord(AState));
|
||
QListWidgetItem_setData(AItem, QtCheckStateRole, v);
|
||
QVariant_destroy(v);
|
||
end;
|
||
|
||
procedure TQtListWidget.SetNextStateMap(AItem: QListWidgetItemH);
|
||
begin
|
||
// does the job only for TQtCheckListBox
|
||
end;
|
||
|
||
function TQtListWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
FCheckBoxClicked := False;
|
||
FDelayedCheckItem := nil;
|
||
SetLength(FSavedSelection, 0);
|
||
AllowGrayed := False;
|
||
FSavedEvent := nil;
|
||
FSavedEventTimer := nil;
|
||
FSavedEventTimerHook := nil;
|
||
|
||
FViewStyle := -1;
|
||
FSyncingItems := False;
|
||
FCheckable := False;
|
||
FDontPassSelChange := False;
|
||
FOwnerData := False;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QListWidget_create(Parent);
|
||
end;
|
||
|
||
type
|
||
TCustomListViewHack = class(TCustomListView);
|
||
|
||
procedure TQtListWidget.OwnerDataNeeded(ARect: TRect);
|
||
var
|
||
R: TRect;
|
||
TopItem: Integer;
|
||
i: Integer;
|
||
VHeight: Integer; // viewport height
|
||
RowHeight, AImagesWidth: Integer;
|
||
item: QListWidgetItemH;
|
||
v, v2, v3: QVariantH;
|
||
WStr: WideString;
|
||
DataStr: WideString;
|
||
ImgList: TCustomImageList;
|
||
AImageIndex: TImageIndex;
|
||
Bmp: TBitmap;
|
||
AIcon: QIconH;
|
||
AOk, AStateImages: Boolean;
|
||
ASize: TSize;
|
||
ImgListRes: TScaledImageListResolution;
|
||
begin
|
||
|
||
{do not set items during design time}
|
||
if (csDesigning in LCLObject.ComponentState) then
|
||
exit;
|
||
|
||
if ItemCount < 1 then
|
||
exit;
|
||
|
||
{TODO: add QtDecorationRole (icon) etc ... }
|
||
QWidget_contentsRect(viewportWidget, @R);
|
||
VHeight := R.Bottom - R.Top;
|
||
|
||
item := itemAt(0, 1);
|
||
if item <> nil then
|
||
begin
|
||
TopItem := getRow(Item);
|
||
RowHeight := getRowHeight(TopItem);
|
||
|
||
if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
|
||
exit;
|
||
|
||
i := 0;
|
||
|
||
while (i < (VHeight + RowHeight)) do
|
||
begin
|
||
item := itemAt(0, i + 1);
|
||
if (item <> nil) then
|
||
begin
|
||
TopItem := getRow(Item);
|
||
RowHeight := getRowHeight(TopItem);
|
||
|
||
if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
|
||
break;
|
||
|
||
AStateImages := False;
|
||
ImgList := TCustomListViewHack(LCLObject).SmallImages;
|
||
if Assigned(ImgList) then
|
||
AImagesWidth := TCustomListViewHack(LCLObject).SmallImagesWidth
|
||
else
|
||
begin
|
||
ImgList := TCustomListViewHack(LCLObject).StateImages;
|
||
if Assigned(ImgList) then
|
||
AImagesWidth := TCustomListViewHack(LCLObject).StateImagesWidth;
|
||
AStateImages := True;
|
||
end;
|
||
if Assigned(ImgList) then
|
||
begin
|
||
ImgListRes := ImgList.ResolutionForPPI[
|
||
AImagesWidth,
|
||
TCustomListViewHack(LCLObject).Font.PixelsPerInch,
|
||
TCustomListViewHack(LCLObject).GetCanvasScaleFactor];
|
||
QListWidgetItem_sizeHint(item, @ASize);
|
||
if (ASize.cx <> ImgListRes.Width) or (ASize.cx <> ImgListRes.Height) then
|
||
begin
|
||
ASize.cx := ImgListRes.Width;
|
||
ASize.cy := ImgListRes.Height;
|
||
QListWidgetItem_setSizeHint(item, @ASize);
|
||
end;
|
||
if AStateImages then
|
||
AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].StateIndex
|
||
else
|
||
AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].ImageIndex;
|
||
if (ImgListRes.Count > 0) and
|
||
((AImageIndex >= 0) and (AImageIndex < ImgListRes.Count)) then
|
||
begin
|
||
Bmp := TBitmap.Create;
|
||
try
|
||
ImgListRes.GetBitmap(AImageIndex, Bmp);
|
||
v2 := QVariant_create;
|
||
QListWidgetItem_data(item, v2, QtListViewOwnerDataRole);
|
||
if not QVariant_isNull(v2) then
|
||
begin
|
||
AOk := True;
|
||
if QVariant_toInt(v2, @AOk) <> AImageIndex then
|
||
begin
|
||
v2 := QVariant_create(AImageIndex);
|
||
QListWidgetItem_setData(item, QtListViewOwnerDataRole, v2);
|
||
QVariant_destroy(v2);
|
||
QListWidgetItem_setIcon(item, TQtImage(Bmp.Handle).AsIcon)
|
||
end;
|
||
// else we are imageIndex and that''s fine.
|
||
end else
|
||
begin
|
||
v2 := QVariant_create(AImageIndex);
|
||
QListWidgetItem_setData(item, QtListViewOwnerDataRole, v2);
|
||
QVariant_destroy(v2);
|
||
QListWidgetItem_setIcon(item, TQtImage(Bmp.Handle).AsIcon);
|
||
end;
|
||
finally
|
||
Bmp.Free;
|
||
end;
|
||
end else
|
||
if (AImageIndex < 0) then
|
||
begin
|
||
v2 := QVariant_create;
|
||
AIcon := QIcon_create;
|
||
try
|
||
QListWidgetItem_data(item, v2, QtListViewOwnerDataRole);
|
||
if not QVariant_isNull(v2) then
|
||
begin
|
||
v3 := QVariant_create;
|
||
try
|
||
QListWidgetItem_setData(item, QtListViewOwnerDataRole, v3);
|
||
finally
|
||
QVariant_destroy(v3);
|
||
end;
|
||
end;
|
||
QListWidgetItem_icon(item, AIcon);
|
||
if not QIcon_isNull(AIcon) then
|
||
QListWidgetItem_setIcon(item, nil);
|
||
finally
|
||
QVariant_destroy(v2);
|
||
QIcon_destroy(AIcon);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].Caption);
|
||
|
||
// reduce paint overhead by checking text
|
||
v := QVariant_create();
|
||
QListWidgetItem_data(item, v, Ord(QtDisplayRole));
|
||
if QVariant_isValid(v) then
|
||
QVariant_toString(v, @DataStr)
|
||
else
|
||
DataStr := '';
|
||
QVariant_destroy(v);
|
||
|
||
// ASelected := not TCustomListViewHack(LCLObject).Items[TopItem].Selected;
|
||
|
||
if (DataStr <> WStr) then
|
||
begin
|
||
v := QVariant_create(PWideString(@WStr));
|
||
try
|
||
QListWidgetItem_setData(item, Ord(QtDisplayRole), v);
|
||
finally
|
||
QVariant_destroy(v);
|
||
end;
|
||
end;
|
||
|
||
// if (QListWidgetItem_isSelected(Item) <> ASelected) then
|
||
// QListWidgetItem_setSelected(Item, ASelected);
|
||
|
||
end else
|
||
break;
|
||
|
||
inc(i, RowHeight);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TQtListWidget.GetItemFlags(AIndex: Integer): QtItemFlags;
|
||
var
|
||
AItem: QListWidgetItemH;
|
||
begin
|
||
Result := inherited GetItemFlags(AIndex);
|
||
AItem := getItem(AIndex);
|
||
if Assigned(AItem) then
|
||
Result := QListWidgetItem_flags(AItem);
|
||
end;
|
||
|
||
procedure TQtListWidget.SetItemFlags(AIndex: Integer; AValue: QtItemFlags);
|
||
var
|
||
AItem: QListWidgetItemH;
|
||
begin
|
||
inherited SetItemFlags(AIndex, AValue);
|
||
AItem := getItem(AIndex);
|
||
if Assigned(AItem) then
|
||
QListWidgetItem_setFlags(AItem, AValue);
|
||
end;
|
||
|
||
procedure TQtListWidget.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
FCurrentItemChangedHook := QListWidget_hook_create(Widget);
|
||
FSelectionChangeHook := QListWidget_hook_create(Widget);
|
||
FItemClickedHook := QListWidget_hook_create(Widget);
|
||
FItemTextChangedHook := QListWidget_hook_create(Widget);
|
||
|
||
// used only when we are handle of TListView
|
||
QListWidget_hook_hook_currentItemChanged(FCurrentItemChangedHook,
|
||
@signalCurrentItemChanged);
|
||
|
||
// OnSelectionChange event (listbox)
|
||
QListWidget_hook_hook_itemSelectionChanged(FSelectionChangeHook, @signalSelectionChanged);
|
||
QListWidget_hook_hook_itemClicked(FItemClickedHook, @signalItemClicked);
|
||
QListWidget_hook_hook_currentTextChanged(FItemTextChangedHook, @signalItemTextChanged);
|
||
end;
|
||
|
||
procedure TQtListWidget.DetachEvents;
|
||
begin
|
||
if FCurrentItemChangedHook <> nil then
|
||
begin
|
||
QListWidget_hook_destroy(FCurrentItemChangedHook);
|
||
FCurrentItemChangedHook := nil;
|
||
end;
|
||
if FSelectionChangeHook <> nil then
|
||
begin
|
||
QListWidget_hook_destroy(FSelectionChangeHook);
|
||
FSelectionChangeHook := nil;
|
||
end;
|
||
if FItemClickedHook <> nil then
|
||
begin
|
||
QListWidget_hook_destroy(FItemClickedHook);
|
||
FItemClickedHook := nil;
|
||
end;
|
||
if FItemTextChangedHook <> nil then
|
||
begin
|
||
QListWidget_hook_destroy(FItemTextChangedHook);
|
||
FItemTextChangedHook := nil;
|
||
end;
|
||
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
procedure TQtListWidget.InitializeWidget;
|
||
begin
|
||
inherited InitializeWidget;
|
||
// by default horz scrollbars is off. it is set by SetScrollWidth
|
||
setScrollBarPolicy(False, QtScrollBarAlwaysOff);
|
||
end;
|
||
|
||
function TQtListWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
var
|
||
ev: QEventH;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject = nil then
|
||
exit;
|
||
|
||
if (FChildOfComplexWidget = ccwComboBox) and (FOwner <> nil) then
|
||
begin
|
||
case QEvent_type(Event) of
|
||
QEventHide:
|
||
begin
|
||
{we must delay SlotDropDownVisiblity according to #9574
|
||
so order is OnChange(if editable)->OnSelect->OnCloseUp }
|
||
ev := QEvent_create(QEventHideToParent);
|
||
QCoreApplication_postEvent(Sender, ev);
|
||
end;
|
||
QEventHideToParent: TQtComboBox(FOwner).SlotDropListVisibility(False);
|
||
end;
|
||
end else
|
||
begin
|
||
if (QEvent_type(Event) = QEventResize) then
|
||
// let the viewport send resize
|
||
else
|
||
if (QEvent_type(Event) = QEventMouseButtonPress) or
|
||
(QEvent_type(Event) = QEventMouseButtonRelease) then
|
||
{eat mouse button events when we are TListView class.
|
||
Such events are handled by itemViewportEventFilter.
|
||
With Qt TListBox and TCheckListBox are also affected. issue #21318}
|
||
else
|
||
begin
|
||
Result:=inherited EventFilter(Sender, Event);
|
||
if Checkable and
|
||
(QEvent_type(Event) = QEventKeyPress) and
|
||
(QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) then
|
||
begin
|
||
if CurrentItem <> nil then
|
||
begin
|
||
HandleCheckChangedEvent(QtPoint(0, 0), currentItem, Event);
|
||
if OwnerDrawn and not (Self is TQtCheckListBox) then
|
||
begin
|
||
if QListWidgetItem_checkState(currentItem) = QtUnChecked then
|
||
QListWidgetItem_setCheckState(currentItem, QtChecked)
|
||
else
|
||
QListWidgetItem_setCheckState(currentItem, QtUnchecked);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtListWidget.HandleCheckChangedEvent(const AMousePos: TQtPoint;
|
||
AItem: QListWidgetItemH; AEvent: QEventH);
|
||
var
|
||
xx: Integer;
|
||
B: Boolean;
|
||
|
||
procedure SendMessage(AnItem: QListWidgetItemH);
|
||
var
|
||
Msg: TLMNotify;
|
||
NMLV: TNMListView;
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
|
||
|
||
Msg.Msg := CN_NOTIFY;
|
||
|
||
NMLV.hdr.hwndfrom := HWND(Self);
|
||
NMLV.hdr.code := LVN_ITEMCHANGED;
|
||
|
||
NMLV.iItem := QListWidget_row(QListWidgetH(Widget), AnItem);
|
||
|
||
NMLV.uNewState := UINT(B);
|
||
NMLV.uChanged := LVIF_STATE;
|
||
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
|
||
// DebugLn('HandleCheckableMouseDown sending LVN_ITEMCHANGED ...');
|
||
DeliverMessage(Msg);
|
||
end;
|
||
begin
|
||
if not Checkable or (AItem = nil) or (ViewStyle < 0) then
|
||
exit;
|
||
|
||
if ((QEvent_type(AEvent) = QEventMouseButtonPress) or
|
||
(QEvent_type(AEvent) = QEventMouseButtonDblClick)) and
|
||
(QMouseEvent_button(QMouseEventH(AEvent)) = QtLeftButton) then
|
||
begin
|
||
if (QListWidgetItem_flags(AItem) and QtItemIsUserCheckable) <> 0 then
|
||
begin
|
||
xx := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
|
||
if ((AMousePos.X > 2) and (AMousePos.X <= (xx + 2))) then
|
||
begin
|
||
B := QListWidgetItem_checkState(AItem) = QtUnChecked;
|
||
if B then
|
||
SetItemLastCheckStateInternal(AItem, QtChecked)
|
||
else
|
||
SetItemLastCheckStateInternal(AItem, QtUnChecked);
|
||
|
||
// if AItem is deleted in mouse event FDelayedCheckItem becomes nil and that's fine. issue #32869
|
||
FDelayedCheckItem := AItem;
|
||
SendMessage(AItem);
|
||
end;
|
||
end;
|
||
end else
|
||
if QEvent_type(AEvent) = LCLQt_ItemViewAfterMouseRelease then
|
||
begin
|
||
if (FDelayedCheckItem <> nil) and (FDelayedCheckItem <> AItem) then
|
||
begin
|
||
SetItemLastCheckStateInternal(FDelayedCheckItem, QListWidgetItem_checkState(FDelayedCheckItem));
|
||
SendMessage(FDelayedCheckItem);
|
||
end;
|
||
FDelayedCheckItem := nil;
|
||
SetItemLastCheckStateInternal(AItem, QListWidgetItem_checkState(AItem));
|
||
SendMessage(AItem);
|
||
end else
|
||
if (QEvent_type(AEvent) = QEventKeyPress) and
|
||
(QKeyEvent_key(QKeyEventH(AEvent)) = QtKey_Space) then
|
||
begin
|
||
FDelayedCheckItem := nil;
|
||
B := QListWidgetItem_checkState(AItem) = QtUnChecked;
|
||
if B then
|
||
SetItemLastCheckStateInternal(AItem, QtChecked)
|
||
else
|
||
SetItemLastCheckStateInternal(AItem, QtUnChecked);
|
||
|
||
SendMessage(AItem);
|
||
end;
|
||
end;
|
||
|
||
function TQtListWidget.itemViewViewportEventFilter(Sender: QObjectH;
|
||
Event: QEventH): Boolean; cdecl;
|
||
var
|
||
Item, CurrItem: QListWidgetItemH;
|
||
MousePos: TQtPoint;
|
||
X: Integer;
|
||
Arr: TPtrIntArray;
|
||
Modifiers: QtKeyboardModifiers;
|
||
ItemRow, CurrItemRow: Integer;
|
||
ALCLEvent: QLCLMessageEventH;
|
||
R: TRect;
|
||
DC: TQtDeviceContext;
|
||
AMsgData: PtrUInt;
|
||
|
||
procedure SendEventToParent;
|
||
begin
|
||
//issue #21318
|
||
SlotMouse(Widget, Event);
|
||
end;
|
||
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
|
||
if (FChildOfComplexWidget = ccwComboBox) and (FOwner <> nil) then
|
||
begin
|
||
if QEvent_type(Event) = QEventShow then
|
||
TQtComboBox(FOwner).FixMouseUp;
|
||
exit;
|
||
end;
|
||
|
||
if (LCLObject <> nil) then
|
||
begin
|
||
if ViewStyle >= 0 then
|
||
begin
|
||
if (QEvent_type(Event) = QEventPaint) and (Sender = viewportWidget) then
|
||
begin
|
||
HasPaint := True;
|
||
QPaintEvent_rect(QPaintEventH(Event), @R);
|
||
if FOwnerData then
|
||
OwnerDataNeeded(R);
|
||
DC := TQtDeviceContext.Create(QWidgetH(Sender), True);
|
||
try
|
||
TCustomListViewAccess(LCLObject).Canvas.handle := HDC(DC);
|
||
TCustomListViewAccess(LCLObject).IntfCustomDraw(dtControl, cdPrePaint, 0, 0, [], @R);
|
||
finally
|
||
TCustomListViewAccess(LCLObject).Canvas.handle := 0;
|
||
DC.Free;
|
||
end;
|
||
end else
|
||
if getEnabled and (QEvent_type(Event) = LCLQt_ItemViewAfterMouseRelease) then
|
||
begin
|
||
ALCLEvent := QLCLMessageEventH(Event);
|
||
Item := QListWidgetItemH(QLCLMessageEvent_getLParam(ALCLEvent));
|
||
// sync lcl with qt state. This is needed only when mouse is pressed
|
||
// and moved out of item, or pressed on item and released over checkbox
|
||
if (Item <> nil) and (GetItemLastCheckState(Item) <>
|
||
QListWidgetItem_checkState(Item)) then
|
||
begin
|
||
MousePos := QtPoint(0, 0); // shutup compiler
|
||
if QLCLMessageEvent_getMsg(ALCLEvent) > 0 then
|
||
QListWidgetItem_setCheckState(Item, GetItemLastCheckState(Item));
|
||
HandleCheckChangedEvent(MousePos, Item, Event);
|
||
end;
|
||
end else
|
||
if getEnabled and (QEvent_type(Event) = QEventMouseButtonRelease) then
|
||
begin
|
||
if OwnerDrawn and Checkable then
|
||
begin
|
||
// MousePos :=
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
Item := itemAt(MousePos.x, MousePos.y);
|
||
|
||
if (Item <> nil) and
|
||
((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
|
||
begin
|
||
x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
|
||
if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
|
||
begin
|
||
if QListWidgetItem_checkState(Item) = QtUnchecked then
|
||
QListWidgetItem_setCheckState(Item, QtChecked)
|
||
else
|
||
QListWidgetItem_setCheckState(Item, QtUnChecked);
|
||
end;
|
||
end;
|
||
Result := SlotMouse(Sender, Event);
|
||
end else
|
||
begin
|
||
PostponedMouseRelease(Event);
|
||
if Checkable then
|
||
begin
|
||
// MousePos :=
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
Item := itemAt(MousePos.x, MousePos.y);
|
||
if (Item <> nil) then
|
||
begin
|
||
if Assigned(LCLObject) and LCLObject.Dragging then
|
||
AMsgData := Ord(QListWidgetItem_checkState(Item)) + 1
|
||
else
|
||
AMsgData := 0;
|
||
ALCLEvent := QLCLMessageEvent_create(LCLQt_ItemViewAfterMouseRelease, AMsgData,
|
||
PtrUInt(Item), PtrUInt(Item), 0);
|
||
QCoreApplication_postEvent(Sender, ALCLEvent);
|
||
end;
|
||
end;
|
||
end;
|
||
end else
|
||
begin
|
||
if getEnabled and (QEvent_type(Event) = QEventMouseButtonPress) then
|
||
begin
|
||
// MousePos :=
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
Item := itemAt(MousePos.x, MousePos.y);
|
||
if Item = nil then
|
||
FSavedSelection := selectedItems
|
||
else
|
||
begin
|
||
// qt selection in QListWidget is ugly, and LCL needs that info
|
||
// when mouse button is pressed, not after that, so we
|
||
// trigger selectionChanged() here
|
||
// Multiselection needs special handling to get proper
|
||
// order of OnSelectItem.
|
||
if (getSelectionMode > QAbstractItemViewSingleSelection) or FOwnerData then
|
||
begin
|
||
Modifiers := QInputEvent_modifiers(QInputEventH(Event));
|
||
SlotMouse(Sender, Event);
|
||
|
||
HandleCheckChangedEvent(MousePos, Item, Event);
|
||
|
||
if not QListWidgetItem_isSelected(Item) then
|
||
begin
|
||
if Modifiers = 0 then
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
|
||
QItemSelectionModelClearAndSelect or QItemSelectionModelCurrent)
|
||
else
|
||
if (Modifiers and QtControlModifier <> 0) then
|
||
begin
|
||
X := getSelCount;
|
||
// DebugLn('**** Called SELECT IN 1 X=', dbgs(X),' is curr ? ',dbgs(CurrentItem = Item));
|
||
if CurrentItem = Item then
|
||
X := 0;
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
|
||
QItemSelectionModelSelect);
|
||
if (X <= 1) then
|
||
signalCurrentItemChanged(Item, nil);
|
||
end else
|
||
if (Modifiers and QtShiftModifier <> 0) then
|
||
begin
|
||
// select this and all other's (calculate is it up or down)
|
||
X := getSelCount;
|
||
CurrItem := currentItem; //<-- doesn't smell good with QtShiftModifier
|
||
if CurrItem = nil then // <-- do not crash
|
||
CurrItem := Item;
|
||
ItemRow := getRow(Item);
|
||
CurrItemRow := getRow(CurrItem);
|
||
if (ItemRow < CurrItemRow) and (ItemRow >= 0) then
|
||
begin
|
||
for x := CurrItemRow + 1 to rowCount - 1 do
|
||
begin
|
||
CurrItem := getItem(x);
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
|
||
QItemSelectionModelClear or QItemSelectionModelDeselect);
|
||
end;
|
||
for x := CurrItemRow downto ItemRow do
|
||
begin
|
||
CurrItem := getItem(x);
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
|
||
QItemSelectionModelSelect);
|
||
end;
|
||
end else
|
||
if (ItemRow > CurrItemRow) then
|
||
begin
|
||
for x := 0 to CurrItemRow - 1 do
|
||
begin
|
||
CurrItem := getItem(x);
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
|
||
QItemSelectionModelClear or QItemSelectionModelDeselect);
|
||
end;
|
||
for x := ItemRow downto CurrItemRow do
|
||
begin
|
||
CurrItem := getItem(x);
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget), CurrItem,
|
||
QItemSelectionModelSelect);
|
||
end;
|
||
end;
|
||
end;
|
||
end else
|
||
begin
|
||
X := getSelCount;
|
||
if (Modifiers = 0) and (X > 1) then
|
||
begin
|
||
Arr := selectedItems;
|
||
for x := 0 to High(Arr) do
|
||
begin
|
||
if QListWidgetItemH(Arr[x]) <> Item then
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget),
|
||
QListWidgetItemH(Arr[x]), QItemSelectionModelDeSelect);
|
||
end;
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
|
||
QItemSelectionModelSelectCurrent);
|
||
end else
|
||
if (Modifiers and QtControlModifier <> 0) then
|
||
begin
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget), Item,
|
||
QItemSelectionModelDeSelect);
|
||
if (X = 1) or (currentItem = Item) then
|
||
signalCurrentItemChanged(nil, Item);
|
||
end;
|
||
end;
|
||
QEvent_ignore(Event);
|
||
Result := True;
|
||
exit;
|
||
end else
|
||
begin
|
||
SlotMouse(Sender, Event);
|
||
HandleCheckChangedEvent(MousePos, Item, Event);
|
||
if not QListWidgetItem_isSelected(Item) then
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget), Item, QItemSelectionModelClearAndSelect);
|
||
QEvent_ignore(Event);
|
||
Result := True;
|
||
exit;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
if getEnabled and Checkable and (QEvent_type(Event) = QEventMouseButtonDblClick) then
|
||
begin
|
||
// MousePos :=
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
Item := itemAt(MousePos.x, MousePos.y);
|
||
if Item <> nil then
|
||
HandleCheckChangedEvent(MousePos, Item, Event);
|
||
end;
|
||
|
||
Result := inherited itemViewViewportEventFilter(Sender, Event);
|
||
end;
|
||
end else
|
||
case QEvent_type(Event) of
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick:
|
||
begin
|
||
if getEnabled and Checkable and
|
||
(QEvent_type(Event) <> QEventMouseButtonDblClick) and
|
||
(QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
|
||
begin
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
Item := itemAt(MousePos.x, MousePos.y);
|
||
if (Item <> nil) and
|
||
((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
|
||
begin
|
||
x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
|
||
if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
|
||
begin
|
||
FCheckBoxClicked := True;
|
||
SetItemLastCheckState(Item);
|
||
{signalItemClicked() fires !}
|
||
end else
|
||
SendEventToParent;
|
||
end else
|
||
SendEventToParent;
|
||
end else
|
||
SendEventToParent;
|
||
end;
|
||
else
|
||
Result := inherited itemViewViewportEventFilter(Sender, Event);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtListWidget.signalCurrentItemChanged(current: QListWidgetItemH;
|
||
previous: QListWidgetItemH); cdecl;
|
||
var
|
||
Msg: TLMNotify;
|
||
NMLV: TNMListView;
|
||
ASubIndex: Integer;
|
||
AIndex: Integer;
|
||
begin
|
||
// only when TQtListWidget is handle of TListView !
|
||
if ViewStyle = -1 then
|
||
exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
|
||
|
||
Msg.Msg := CN_NOTIFY;
|
||
|
||
NMLV.hdr.hwndfrom := LCLObject.Handle;
|
||
NMLV.hdr.code := LVN_ITEMCHANGING;
|
||
|
||
if Current <> nil then
|
||
AIndex := getRow(Current)
|
||
else
|
||
AIndex := -1;
|
||
|
||
ASubIndex := 0;
|
||
|
||
NMLV.iItem := AIndex;
|
||
NMLV.iSubItem := ASubIndex;
|
||
NMLV.uNewState := LVIS_SELECTED;
|
||
NMLV.uChanged := LVIF_STATE;
|
||
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
DeliverMessage(Msg);
|
||
|
||
// if getSelectionMode > QAbstractItemViewSingleSelection then
|
||
// DebugLn('*** MultiSelect: SignalCurrentItemChanged Current ',dbgs(Current),' Previous ',dbgs(Previous));
|
||
|
||
FSyncingItems := True;
|
||
try
|
||
if Current <> nil then
|
||
begin
|
||
FillChar(Msg, SizeOf(Msg), #0);
|
||
FillChar(NMLV, SizeOf(NMLV), #0);
|
||
Msg.Msg := CN_NOTIFY;
|
||
NMLV.hdr.hwndfrom := LCLObject.Handle;
|
||
NMLV.hdr.code := LVN_ITEMCHANGED;
|
||
NMLV.iItem := AIndex;
|
||
NMLV.iSubItem := ASubIndex;
|
||
if QListWidget_isItemSelected(QListWidgetH(Widget), Current) then
|
||
NMLV.uNewState := LVIS_SELECTED
|
||
else
|
||
NMLV.uOldState := LVIS_SELECTED;
|
||
NMLV.uChanged := LVIF_STATE;
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
DeliverMessage(Msg);
|
||
|
||
// send focused msg
|
||
NMLV.uOldState := 0;
|
||
NMLV.uNewState := LVIS_FOCUSED;
|
||
NMLV.uChanged := LVIF_STATE;
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
DeliverMessage(Msg);
|
||
|
||
end;
|
||
|
||
if Previous <> nil then
|
||
begin
|
||
FillChar(Msg, SizeOf(Msg), #0);
|
||
FillChar(NMLV, SizeOf(NMLV), #0);
|
||
Msg.Msg := CN_NOTIFY;
|
||
NMLV.hdr.hwndfrom := LCLObject.Handle;
|
||
NMLV.hdr.code := LVN_ITEMCHANGED;
|
||
NMLV.iItem := getRow(Previous);
|
||
ASubIndex := 0;
|
||
NMLV.iSubItem := ASubIndex;
|
||
if QListWidget_isItemSelected(QListWidgetH(Widget), Previous) then
|
||
NMLV.uNewState := LVIS_SELECTED
|
||
else
|
||
NMLV.uOldState := LVIS_SELECTED;
|
||
NMLV.uChanged := LVIF_STATE;
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
finally
|
||
FSyncingItems := False;
|
||
end;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtListWidget.SlotSelectionChange
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
|
||
procedure TQtListWidget.signalSelectionChanged(); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
i: Integer;
|
||
Item: QListWidgetItemH;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtListWidget.signalSelectionChange');
|
||
{$endif}
|
||
|
||
if FDontPassSelChange then
|
||
begin
|
||
FDontPassSelChange := False;
|
||
Exit;
|
||
end;
|
||
|
||
if (ViewStyle >= 0) and (InUpdate or
|
||
(not InUpdate and (length(FSavedSelection) = 0)) ) then
|
||
exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_SELCHANGE;
|
||
if (FChildOfComplexWidget <> ccwComboBox) then
|
||
begin
|
||
if (ViewStyle < 0) and (getSelCount > 0) then
|
||
DeliverMessage(Msg)
|
||
else
|
||
if (ViewStyle >= 0) then
|
||
begin
|
||
if getSelCount = 0 then
|
||
begin
|
||
for i := 0 to High(FSavedSelection) do
|
||
begin
|
||
Item := QListWidgetItemH(FSavedSelection[i]);
|
||
if (Item <> nil) then
|
||
signalCurrentItemChanged(nil, Item);
|
||
end;
|
||
end;
|
||
setLength(FSavedSelection, 0);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtListWidget.signalItemTextChanged(ANewText: PWideString); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtListWidget.signalItemTextChanged');
|
||
{$endif}
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := CM_TEXTCHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
procedure TQtListWidget.signalItemClicked(item: QListWidgetItemH); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
ItemRow: Integer;
|
||
MsgN: TLMNotify;
|
||
NMLV: TNMListView;
|
||
R: TRect;
|
||
Pt: TPoint;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtListWidget.signalItemClicked');
|
||
{$endif}
|
||
if (ViewStyle >= 0) and (FChildOfComplexWidget <> ccwComboBox) then
|
||
begin
|
||
FillChar(MsgN{%H-}, SizeOf(MsgN), #0);
|
||
FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
|
||
|
||
MsgN.Msg := LM_CLICKED;
|
||
|
||
NMLV.hdr.hwndfrom := LCLObject.Handle;
|
||
NMLV.hdr.code := NM_CLICK;
|
||
|
||
NMLV.iItem := getRow(Item);
|
||
|
||
NMLV.iSubItem := 0;
|
||
NMLV.uNewState := UINT(NM_CLICK);
|
||
NMLV.uChanged := LVIS_SELECTED;
|
||
|
||
QListWidget_visualItemRect(QListWidgetH(Widget), @R, Item);
|
||
|
||
pt.X := R.Left;
|
||
pt.Y := R.Top;
|
||
|
||
NMLV.ptAction := pt;
|
||
|
||
MsgN.NMHdr := @NMLV.hdr;
|
||
|
||
DeliverMessage(MsgN);
|
||
end;
|
||
|
||
if Checkable then
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_CHANGED;
|
||
ItemRow := QListWidget_row(QListWidgetH(Widget), Item);
|
||
Msg.WParam := ItemRow;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
end;
|
||
|
||
procedure TQtListWidget.ItemDelegatePaint(painter: QPainterH;
|
||
option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
|
||
var
|
||
Msg: TLMDrawListItem;
|
||
DrawStruct: TDrawListItemStruct;
|
||
State: QStyleState;
|
||
R: TRect;
|
||
ItemIndex, SubItemIndex: Integer;
|
||
ACustomState: TCustomDrawState;
|
||
ATarget: TCustomDrawTarget;
|
||
TmpDC1, TmpDC2: HDC;
|
||
SkipDefault: Boolean;
|
||
Item: QListWidgetItemH;
|
||
APaintResult: TCustomDrawResult;
|
||
begin
|
||
if (ViewStyle >= 0) and not (FChildOfComplexWidget = ccwComboBox) then
|
||
begin
|
||
State := QStyleOption_state(option);
|
||
ACustomState := [cdsDefault];
|
||
(*
|
||
cdsSelected,
|
||
cdsGrayed,
|
||
cdsDisabled,
|
||
cdsChecked,
|
||
cdsFocused,
|
||
cdsDefault,
|
||
cdsHot,
|
||
cdsMarked,
|
||
cdsIndeterminate
|
||
*)
|
||
|
||
if (State and QStyleState_Selected) <> 0 then
|
||
Include(ACustomState, cdsSelected);
|
||
// disabled
|
||
if (State and QStyleState_Enabled) = 0 then
|
||
Include(ACustomState, cdsDisabled);
|
||
// focused (QStyleState_FocusAtBorder?)
|
||
if (State and QStyleState_HasFocus) <> 0 then
|
||
Include(ACustomState, cdsFocused);
|
||
// hotlight
|
||
if (State and QStyleState_MouseOver) <> 0 then
|
||
Include(ACustomState, cdsHot);
|
||
|
||
ItemIndex := QModelIndex_row(index);
|
||
SubItemIndex := QModelIndex_column(index);
|
||
|
||
// checked does not work under qt for some reason ?!?
|
||
if Checkable then
|
||
begin
|
||
// if (State and QStyleState_On <> 0) then
|
||
// Include(ACustomState, cdsChecked);
|
||
Item := getItem(ItemIndex);
|
||
if Assigned(Item) and (QListWidgetItem_checkState(Item) = QtChecked) then
|
||
Include(ACustomState, cdsChecked);
|
||
end;
|
||
|
||
QStyle_drawControl(QApplication_style, QStyleCE_ItemViewItem, Option, painter, viewportWidget);
|
||
|
||
// NOW WE ARE DRAWING ITEMS ...
|
||
QPainter_save(painter);
|
||
if TCustomListView(LCLObject).Canvas.HandleAllocated then
|
||
TmpDC2 := TCustomListView(LCLObject).Canvas.GetUpdatedHandle([csHandleValid])
|
||
else
|
||
TmpDC2 := 0;
|
||
TmpDC1 := HDC(TQtDeviceContext.CreateFromPainter(painter));
|
||
TCustomListView(LCLObject).Canvas.Handle := TmpDC1;
|
||
try
|
||
R := visualRect(index);
|
||
|
||
if SubItemIndex <= 0 then
|
||
ATarget := dtItem
|
||
else
|
||
ATarget := dtSubItem;
|
||
|
||
// here we do only OnCustomDrawItem and OnCustomDrawSubItem
|
||
// OnCustomDraw is done inside itemViewportEventFilter.
|
||
|
||
APaintResult := TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPrePaint, ItemIndex, SubItemIndex, ACustomState, @R);
|
||
SkipDefault := cdrSkipDefault in APaintResult;
|
||
|
||
if not SkipDefault then // do default paint by unknown magic
|
||
QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
|
||
|
||
// issue #27315
|
||
if cdrNotifyPostpaint in APaintResult then
|
||
TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPostPaint, ItemIndex, SubItemIndex, ACustomState, @R);
|
||
|
||
finally
|
||
TCustomListView(LCLObject).Canvas.Handle := TmpDC2;
|
||
TQtDeviceContext(TmpDC1).Free;
|
||
QPainter_restore(painter);
|
||
end;
|
||
end else
|
||
begin
|
||
QPainter_save(painter);
|
||
State := QStyleOption_state(option);
|
||
DrawStruct.ItemID := UINT(QModelIndex_row(index));
|
||
|
||
DrawStruct.Area := visualRect(index);
|
||
DrawStruct.DC := HDC(TQtDeviceContext.CreateFromPainter(painter));
|
||
|
||
DrawStruct.ItemState := [];
|
||
// selected
|
||
if (State and QStyleState_Selected) <> 0 then
|
||
Include(DrawStruct.ItemState, odSelected);
|
||
// disabled
|
||
if (State and QStyleState_Enabled) = 0 then
|
||
Include(DrawStruct.ItemState, odDisabled);
|
||
// focused (QStyleState_FocusAtBorder?)
|
||
if (State and QStyleState_HasFocus) <> 0 then
|
||
Include(DrawStruct.ItemState, odFocused);
|
||
// hotlight
|
||
if (State and QStyleState_MouseOver) <> 0 then
|
||
Include(DrawStruct.ItemState, odHotLight);
|
||
// checked
|
||
if Checkable then
|
||
begin
|
||
// if (State and QStyleState_On <> 0) then
|
||
// Include(ACustomState, cdsChecked);
|
||
Item := getItem(QModelIndex_row(index));
|
||
if Assigned(Item) and (QListWidgetItem_checkState(Item) = QtChecked) then
|
||
Include(DrawStruct.ItemState, odChecked);
|
||
end;
|
||
|
||
{ todo: over states:
|
||
|
||
odGrayed, odChecked,
|
||
odDefault, odInactive, odNoAccel,
|
||
odNoFocusRect, odReserved1, odReserved2, odComboBoxEdit
|
||
}
|
||
Msg.Msg := LM_DRAWLISTITEM;
|
||
Msg.DrawListItemStruct := @DrawStruct;
|
||
DeliverMessage(Msg);
|
||
|
||
QPainter_restore(painter);
|
||
|
||
TQtDeviceContext(DrawStruct.DC).Free;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtListWidget.clearSelection;
|
||
begin
|
||
inherited clearSelection;
|
||
SetLength(FSavedSelection, 0);
|
||
end;
|
||
|
||
procedure TQtListWidget.ClearItems;
|
||
begin
|
||
SetLength(FSavedSelection, 0);
|
||
QListWidget_clear(QListWidgetH(Widget));
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtListWidget.currentRow
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtListWidget.currentRow: Integer;
|
||
begin
|
||
Result := QListWidget_currentRow(QListWidgetH(Widget));
|
||
end;
|
||
|
||
function TQtListWidget.currentItem: QListWidgetItemH;
|
||
begin
|
||
Result := QListWidget_currentItem(QListWidgetH(Widget));
|
||
end;
|
||
|
||
function TQtListWidget.IndexAt(APoint: PQtPoint): Integer;
|
||
var
|
||
AModelIndex: QModelIndexH;
|
||
begin
|
||
AModelIndex := QModelIndex_create();
|
||
QListView_indexAt(QListWidgetH(Widget), AModelIndex, APoint);
|
||
Result := QModelIndex_row(AModelIndex);
|
||
QModelIndex_destroy(AModelIndex);
|
||
end;
|
||
|
||
procedure TQtListWidget.insertItem(AIndex: Integer; AText: String);
|
||
var
|
||
Str: WideString;
|
||
begin
|
||
Str := GetUtf8String(AText);
|
||
insertItem(AIndex, @Str);
|
||
end;
|
||
|
||
procedure TQtListWidget.insertItem(AIndex: Integer; AText: PWideString);
|
||
var
|
||
Item: QListWidgetItemH;
|
||
begin
|
||
Item := QListWidgetItem_create(AText, nil, Ord(QListWidgetItemType));
|
||
if Checkable then
|
||
QListWidgetItem_setCheckState(Item, QtUnChecked)
|
||
else
|
||
if (ViewStyle = Ord(vsIcon)) and not (FChildOfComplexWidget = ccwComboBox) then
|
||
QListWidgetItem_setTextAlignment(Item, QtAlignHCenter);
|
||
QListWidget_insertItem(QListWidgetH(Widget), AIndex, Item);
|
||
end;
|
||
|
||
function TQtListWidget.itemAt(APoint: TPoint): QListWidgetItemH;
|
||
begin
|
||
Result := ItemAt(APoint.X, APoint.Y);
|
||
end;
|
||
|
||
function TQtListWidget.itemAt(x: Integer; y: Integer): QListWidgetItemH;
|
||
begin
|
||
Result := QListWidget_itemAt(QListWidgetH(Widget), x, y);
|
||
end;
|
||
|
||
function TQtListWidget.getItem(AIndex: Integer): QListWidgetItemH;
|
||
begin
|
||
if (AIndex >= 0) and (AIndex < rowCount) then
|
||
Result := QListWidget_item(QListWidgetH(Widget), AIndex)
|
||
else
|
||
Result := nil;
|
||
end;
|
||
|
||
function TQtListWidget.getItemSelected(AItem: QListWidgetItemH): Boolean;
|
||
begin
|
||
if AItem <> nil then
|
||
Result := QListWidget_isItemSelected(QListWidgetH(Widget), AItem)
|
||
else
|
||
Result := False;
|
||
end;
|
||
|
||
function TQtListWidget.getItemVisible(AItem: QListWidgetItemH): Boolean;
|
||
begin
|
||
if AItem = nil then
|
||
Result := False
|
||
else
|
||
Result := not QListWidget_isItemHidden(QListWidgetH(Widget), AItem);
|
||
end;
|
||
|
||
function TQtListWidget.getRow(AItem: QListWidgetItemH): integer;
|
||
begin
|
||
if AItem = nil then
|
||
Result := -1
|
||
else
|
||
Result := QListWidget_row(QListWidgetH(Widget), AItem);
|
||
end;
|
||
|
||
function TQtListWidget.getSelCount: Integer;
|
||
begin
|
||
Result := length(selectedItems);
|
||
end;
|
||
|
||
function TQtListWidget.getTopItem: integer;
|
||
begin
|
||
Result := getVisibleRowCount(True);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtListWidget.getVisibleRowCount
|
||
Params: Boolean
|
||
Returns: if AFirstVisibleOnly = False (default) then it returns number
|
||
of visible rows, or 0 if there's no visible rows.
|
||
When AFirstVisibleOnly = True then it returns index of first visible row,
|
||
otherwise result is -1.
|
||
------------------------------------------------------------------------------}
|
||
function TQtListWidget.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
|
||
var
|
||
R: TRect;
|
||
i: integer;
|
||
item: QListWidgetItemH;
|
||
RowIndex: integer;
|
||
RowHeight: integer;
|
||
begin
|
||
if AFirstVisibleOnly then
|
||
Result := -1
|
||
else
|
||
Result := 0;
|
||
QWidget_contentsRect(viewportWidget, @R);
|
||
i := 0;
|
||
repeat
|
||
item := itemAt(0, i);
|
||
if item <> nil then
|
||
begin
|
||
RowIndex := getRow(Item);
|
||
if AFirstVisibleOnly then
|
||
begin
|
||
Result := RowIndex;
|
||
break;
|
||
end;
|
||
RowHeight := getRowHeight(RowIndex);
|
||
inc(Result);
|
||
if RowHeight <= 0 then
|
||
RowHeight := 1;
|
||
inc(i, RowHeight);
|
||
end else
|
||
inc(i, 1);
|
||
until i >= R.Bottom;
|
||
end;
|
||
|
||
function TQtListWidget.getVisualItemRect(AItem: QListWidgetItemH): TRect;
|
||
begin
|
||
Result := Rect(0, 0, 0, 0);
|
||
if AItem <> nil then
|
||
QListWidget_visualItemRect(QListWidgetH(Widget), @Result, AItem);
|
||
end;
|
||
|
||
function TQtListWidget.selectedItems: TPtrIntArray;
|
||
begin
|
||
QListWidget_selectedItems(QListWidgetH(Widget), @Result);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtListWidget.setCurrentRow
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtListWidget.setCurrentRow(row: Integer);
|
||
begin
|
||
if (getSelectionMode <> QAbstractItemViewSingleSelection) and (row < 0) then
|
||
row := 0;
|
||
|
||
if currentRow <> row then
|
||
begin
|
||
FDontPassSelChange := True;
|
||
QListWidget_setCurrentRow(QListWidgetH(Widget), row);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtListWidget.setCurrentItem(AItem: QListWidgetItemH;
|
||
const AIsSet: Boolean = True);
|
||
begin
|
||
if AIsSet then
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget), AItem);
|
||
end;
|
||
|
||
procedure TQtListWidget.setItemText(AIndex: Integer; AText: String);
|
||
var
|
||
Item: QListWidgetItemH;
|
||
Str: WideString;
|
||
R: TRect;
|
||
begin
|
||
Str := GetUTF8String(AText);
|
||
if (AIndex >= 0) and (AIndex < rowCount) then
|
||
begin
|
||
Item := getItem(AIndex);
|
||
QListWidgetItem_setText(Item, @Str);
|
||
{we must update our custom delegate}
|
||
if OwnerDrawn then
|
||
begin
|
||
R := getVisualItemRect(Item);
|
||
Update(@R);
|
||
end;
|
||
end else
|
||
insertItem(AIndex, @Str);
|
||
end;
|
||
|
||
procedure TQtListWidget.setItemText(AIndex: Integer; AText: String;
|
||
AAlignment: Integer);
|
||
var
|
||
Item: QListWidgetItemH;
|
||
Str: WideString;
|
||
R: TRect;
|
||
begin
|
||
Str := GetUTF8String(AText);
|
||
if (AIndex >= 0) and (AIndex < rowCount) then
|
||
begin
|
||
Item := getItem(AIndex);
|
||
QListWidgetItem_setText(Item, @Str);
|
||
QListWidgetItem_setTextAlignment(Item, AAlignment);
|
||
{we must update our custom delegate}
|
||
if OwnerDrawn then
|
||
begin
|
||
R := getVisualItemRect(Item);
|
||
Update(@R);
|
||
end;
|
||
end else
|
||
insertItem(AIndex, @Str);
|
||
end;
|
||
|
||
procedure TQtListWidget.setItemSelected(AItem: QListWidgetItemH;
|
||
const ASelect: Boolean);
|
||
begin
|
||
if AItem <> nil then
|
||
QListWidget_setItemSelected(QListWidgetH(Widget), AItem, ASelect);
|
||
end;
|
||
|
||
procedure TQtListWidget.setItemVisible(AItem: QListWidgetItemH;
|
||
const AVisible: Boolean);
|
||
begin
|
||
if AItem <> nil then
|
||
QListWidget_setItemHidden(QListWidgetH(Widget), AItem, not AVisible);
|
||
end;
|
||
|
||
procedure TQtListWidget.setSelectionMode(AMode: QAbstractItemViewSelectionMode);
|
||
var
|
||
SavedItem: QListWidgetItemH;
|
||
Arr: TPtrIntArray;
|
||
i: Integer;
|
||
begin
|
||
SavedItem := nil;
|
||
// this code is here due to Qt bug with QListView/QListWidget ..
|
||
// QTreeWidget works correct .. clearSelection does not trigger signals
|
||
// so we must do that manually.
|
||
if (ViewStyle > 0) and (AMode < QAbstractItemViewMultiSelection) and
|
||
(getSelectionMode > QAbstractItemViewSingleSelection) then
|
||
begin
|
||
SavedItem := CurrentItem;
|
||
Arr := selectedItems;
|
||
if not ((SavedItem <> nil) and (QListWidgetItem_isSelected(SavedItem))) then
|
||
begin
|
||
SavedItem := nil;
|
||
if length(Arr) > 0 then
|
||
SavedItem := QListWidgetItemH(Arr[0]);
|
||
end;
|
||
for i := 0 to High(Arr) do
|
||
begin
|
||
if QListWidgetItemH(Arr[i]) <> SavedItem then
|
||
begin
|
||
QListWidgetItem_setSelected(QListWidgetItemH(Arr[i]), False);
|
||
signalCurrentItemChanged(nil, QListWidgetItemH(Arr[i]));
|
||
end;
|
||
end;
|
||
clearSelection;
|
||
end;
|
||
inherited setSelectionMode(AMode);
|
||
if SavedItem <> nil then
|
||
setItemSelected(SavedItem, True);
|
||
end;
|
||
|
||
procedure TQtListWidget.scrollToItem(row: integer;
|
||
hint: QAbstractItemViewScrollHint);
|
||
var
|
||
Item: QListWidgetItemH;
|
||
begin
|
||
Item := getItem(Row);
|
||
QListWidget_scrollToItem(QListWidgetH(Widget), Item, hint);
|
||
end;
|
||
|
||
procedure TQtListWidget.removeItem(AIndex: Integer);
|
||
var
|
||
Item: QListWidgetItemH;
|
||
begin
|
||
if (currentRow = AIndex) then
|
||
if (getSelectionMode = QAbstractItemViewSingleSelection) then
|
||
setCurrentRow(-1);
|
||
Item := QListWidget_takeitem(QListWidgetH(Widget), AIndex);
|
||
if FDelayedCheckItem = Item then
|
||
FDelayedCheckItem := nil;
|
||
QListWidgetItem_destroy(Item);
|
||
end;
|
||
|
||
function TQtListWidget.rowCount: integer;
|
||
begin
|
||
Result := QListWidget_count(QListWidgetH(Widget));
|
||
end;
|
||
|
||
procedure TQtListWidget.ExchangeItems(const AIndex1, AIndex2: Integer);
|
||
var
|
||
ItemTo, ItemFrom: QListWidgetItemH;
|
||
R: TRect;
|
||
begin
|
||
if AIndex1 = AIndex2 then
|
||
exit;
|
||
|
||
if AIndex1 < AIndex2 then
|
||
begin
|
||
ItemTo := QListWidget_takeItem(QListWidgetH(Widget), AIndex2);
|
||
ItemFrom := QListWidget_takeItem(QListWidgetH(Widget), AIndex1);
|
||
QListWidget_insertItem(QListWidgetH(Widget), AIndex1, ItemTo);
|
||
QListWidget_insertItem(QListWidgetH(Widget), AIndex2, ItemFrom);
|
||
end else
|
||
begin
|
||
ItemFrom := QListWidget_takeItem(QListWidgetH(Widget), AIndex1);
|
||
ItemTo := QListWidget_takeItem(QListWidgetH(Widget), AIndex2);
|
||
QListWidget_insertItem(QListWidgetH(Widget), AIndex2, ItemFrom);
|
||
QListWidget_insertItem(QListWidgetH(Widget), AIndex1, ItemTo);
|
||
end;
|
||
|
||
if OwnerDrawn then
|
||
begin
|
||
R := getVisualItemRect(ItemTo);
|
||
Update(@R);
|
||
R := getVisualItemRect(ItemFrom);
|
||
Update(@R);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtListWidget.MoveItem(const AFromIndex, AToIndex: Integer);
|
||
var
|
||
Item: QListWidgetItemH;
|
||
R: TRect;
|
||
begin
|
||
Item := QListWidget_takeItem(QListWidgetH(Widget), AFromIndex);
|
||
QListWidget_insertItem(QListWidgetH(Widget), AToIndex, Item);
|
||
if OwnerDrawn then
|
||
begin
|
||
R := getVisualItemRect(Item);
|
||
Update(@R);
|
||
end;
|
||
end;
|
||
|
||
{ TQtCheckListBox }
|
||
|
||
function TQtCheckListBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
FCheckBoxClicked := False;
|
||
FDelayedCheckItem := nil;
|
||
FSavedEvent := nil;
|
||
FSavedEventTimer := nil;
|
||
FSavedEventTimerHook := nil;
|
||
|
||
FViewStyle := -1;
|
||
FSyncingItems := False;
|
||
FDontPassSelChange := False;
|
||
FOwnerData := False;
|
||
|
||
FCheckable := True;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QListWidget_create(Parent);
|
||
end;
|
||
|
||
procedure TQtCheckListBox.SetNextStateMap(AItem: QListWidgetItemH);
|
||
var
|
||
ACurrState: QtCheckState;
|
||
begin
|
||
inherited SetNextStateMap(AItem);
|
||
if (AItem = nil) or not AllowGrayed then
|
||
exit;
|
||
ACurrState := GetItemLastCheckState(AItem);
|
||
|
||
case ACurrState of
|
||
QtUnchecked: ItemCheckState[GetRow(AItem)] := QtPartiallyChecked;
|
||
QtPartiallyChecked: ItemCheckState[GetRow(AItem)] := QtChecked;
|
||
QtChecked: ItemCheckState[GetRow(AItem)] := QtUnChecked;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtCheckListBox.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FItemChangedHook := QListWidget_hook_create(Widget);
|
||
QListWidget_hook_hook_itemChanged(FItemChangedHook, @signalItemChanged);
|
||
end;
|
||
|
||
procedure TQtCheckListBox.DetachEvents;
|
||
begin
|
||
if FItemChangedHook <> nil then
|
||
begin
|
||
QListWidget_hook_destroy(FItemChangedHook);
|
||
FItemChangedHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtCheckListBox.EventFilter(Sender: QObjectH; Event: QEventH
|
||
): Boolean; cdecl;
|
||
begin
|
||
Result := False;
|
||
if (QEvent_type(Event) = QEventKeyPress) and
|
||
((QKeyEvent_key(QKeyEventH(Event)) = QtKey_Up) or
|
||
(QKeyEvent_key(QKeyEventH(Event)) = QtKey_Down)) then
|
||
begin
|
||
{issue #31697}
|
||
Result:=inherited EventFilter(Sender, Event);
|
||
if ItemCount > 0 then
|
||
begin
|
||
if (getSelCount = 0) then
|
||
begin
|
||
Selected[0] := True;
|
||
Result := True;
|
||
end;
|
||
inherited signalSelectionChanged();
|
||
end;
|
||
end else
|
||
if (QEvent_type(Event) = QEventMouseButtonDblClick) then
|
||
// issue #25089
|
||
else
|
||
Result:=inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
function TQtCheckListBox.itemViewViewportEventFilter(Sender: QObjectH;
|
||
Event: QEventH): Boolean; cdecl;
|
||
var
|
||
MousePos: TQtPoint;
|
||
Item: QListWidgetItemH;
|
||
x: Integer;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if (LCLObject <> nil) then
|
||
begin
|
||
case QEvent_type(Event) of
|
||
QEventMouseButtonRelease,
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonDblClick:
|
||
begin
|
||
// issue #21318
|
||
// MousePos :=
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
Item := itemAt(MousePos.x, MousePos.y);
|
||
if QEvent_Type(Event) = QEventMouseButtonDblClick then
|
||
begin
|
||
SlotMouse(Widget, Event);
|
||
QEvent_ignore(Event);
|
||
// qt capture locks for some reason under qt-4.7.4 ?!?
|
||
// when we dbl click on viewport without checkable items
|
||
if (Item = nil) and (Sender = QWidget_mouseGrabber) then
|
||
QWidget_releaseMouse(QWidgetH(Sender));
|
||
end else
|
||
begin
|
||
Result := SlotMouse(Sender, Event);
|
||
if (Item <> nil) and (OwnerDrawn) and
|
||
(QEvent_type(Event) = QEventMouseButtonRelease) and
|
||
((QListWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
|
||
begin
|
||
x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
|
||
if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
|
||
begin
|
||
if QListWidgetItem_checkState(Item) = QtUnchecked then
|
||
QListWidgetItem_setCheckState(Item, QtChecked)
|
||
else
|
||
QListWidgetItem_setCheckState(Item, QtUnChecked);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
if (QEvent_Type(Event) = QEventMouseButtonPress) then
|
||
begin
|
||
// change current row , this works fine with qt < 4.8
|
||
if Assigned(Item) and
|
||
((currentItem <> Item) or not QListWidgetItem_isSelected(Item)) then
|
||
begin
|
||
// DebugLn('TQtCheckListBox forced item change');
|
||
{issue #31697}
|
||
QListWidget_setCurrentItem(QListWidgetH(Widget), Item, QItemSelectionModelSelectCurrent);
|
||
inherited signalSelectionChanged();
|
||
end;
|
||
end;
|
||
end;
|
||
else
|
||
begin
|
||
{do not change selection if mousepressed and mouse moved}
|
||
Result := (QEvent_type(Event) = QEventMouseMove) and
|
||
hasFocus and (QGUIApplication_mouseButtons() > 0);
|
||
QEvent_ignore(Event);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtCheckListBox.signalCurrentItemChanged(current: QListWidgetItemH;
|
||
previous: QListWidgetItemH); cdecl;
|
||
begin
|
||
// Do nothing
|
||
// inherited signalCurrentItemChanged(current, previous);
|
||
end;
|
||
|
||
procedure TQtCheckListBox.signalItemClicked(item: QListWidgetItemH); cdecl;
|
||
begin
|
||
|
||
if InUpdate or not GetVisible then
|
||
exit;
|
||
{$note seem that we have qtbug with tristate listwidget items, so
|
||
we must handle statemap somehow}
|
||
|
||
//TODO try to fix nextstatemap
|
||
if FCheckBoxClicked then
|
||
begin
|
||
FCheckBoxClicked := False;
|
||
SetNextStateMap(item);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtCheckListBox.signalSelectionChanged(); cdecl;
|
||
begin
|
||
// DO NOTHING
|
||
// inherited signalSelectionChanged;
|
||
end;
|
||
|
||
procedure TQtCheckListBox.signalItemChanged(item: QListWidgetItemH); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
if InUpdate or not GetVisible then
|
||
exit;
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_CHANGED;
|
||
Msg.WParam := PtrInt(QListWidget_row(QListWidgetH(Widget), Item));
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
function TQtCheckListBox.GetItemCheckState(AIndex: Integer): QtCheckState;
|
||
var
|
||
AItem: QListWidgetItemH;
|
||
begin
|
||
Result := QtUnChecked;
|
||
if (AIndex >= 0) and (AIndex < rowCount) then
|
||
begin
|
||
AItem := QListWidget_item(QListWidgetH(Widget), AIndex);
|
||
if AItem <> nil then
|
||
Result := QListWidgetItem_checkState(AItem);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtCheckListBox.SetItemCheckState(AIndex: Integer;
|
||
AValue: QtCheckState);
|
||
var
|
||
AItem: QListWidgetItemH;
|
||
begin
|
||
if (AIndex >= 0) and (AIndex < rowCount) then
|
||
begin
|
||
AItem := QListWidget_item(QListWidgetH(Widget), AIndex);
|
||
if AItem <> nil then
|
||
begin
|
||
QListWidgetItem_setCheckState(AItem, AValue);
|
||
SetItemLastCheckState(AItem);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{ TQtHeaderView }
|
||
|
||
function TQtHeaderView.getClickable: Boolean;
|
||
begin
|
||
// QHeaderView_sectionsClickable();
|
||
Result := QHeaderView_sectionsClickable(QHeaderViewH(Widget));
|
||
end;
|
||
|
||
function TQtHeaderView.getMinSectionSize: Integer;
|
||
begin
|
||
Result := QHeaderView_minimumSectionSize(QHeaderViewH(Widget));
|
||
end;
|
||
|
||
function TQtHeaderView.SortIndicatorOrder: QtSortOrder;
|
||
begin
|
||
Result := QHeaderView_sortIndicatorOrder(QHeaderViewH(Widget));
|
||
end;
|
||
|
||
procedure TQtHeaderView.setClickable(const AValue: Boolean);
|
||
begin
|
||
QHeaderView_setSectionsClickable(QHeaderViewH(Widget), AValue);
|
||
// QHeaderView_setClickable(QHeaderViewH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtHeaderView.setMinSectionSize(const AValue: Integer);
|
||
begin
|
||
QHeaderView_setMinimumSectionSize(QHeaderViewH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtHeaderView.SetSortIndicator(const AColumn: Integer;
|
||
const AOrder: QtSortOrder);
|
||
begin
|
||
QHeaderView_setSortIndicator(QHeaderViewH(Widget), AColumn, AOrder);
|
||
end;
|
||
|
||
procedure TQtHeaderView.SetSortIndicatorVisible(AVisible: Boolean);
|
||
begin
|
||
QHeaderView_setSortIndicatorShown(QHeaderViewH(Widget), AVisible);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtHeaderView.CreateWidget
|
||
Params: None
|
||
Returns: Widget (QHeaderViewH)
|
||
------------------------------------------------------------------------------}
|
||
function TQtHeaderView.CreateWidget(const AParams: TCreateParams):QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtHeaderView.Create');
|
||
{$endif}
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
|
||
Result := QHeaderView_create(QtHorizontal, Parent);
|
||
end;
|
||
|
||
procedure TQtHeaderView.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FSectionClicked := QHeaderView_hook_create(Widget);
|
||
QHeaderView_hook_hook_sectionClicked(FSectionClicked, @SignalSectionClicked);
|
||
end;
|
||
|
||
procedure TQtHeaderView.DetachEvents;
|
||
begin
|
||
if FSectionClicked <> nil then
|
||
begin
|
||
QHeaderView_hook_destroy(FSectionClicked);
|
||
FSectionClicked := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtHeaderView.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if (FOwner <> nil) and (LCLObject <> nil) then
|
||
begin
|
||
if (FChildOfComplexWidget = ccwTreeWidget) and
|
||
(QEvent_type(Event) = QEventFocusIn) then
|
||
begin
|
||
Result := True;
|
||
QEvent_ignore(Event);
|
||
QWidget_setFocus(FOwner.Widget);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TQtHeaderView.itemViewViewportEventFilter(Sender: QObjectH;
|
||
Event: QEventH): Boolean; cdecl;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
case QEvent_type(Event) of
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick: ; {do nothing here - signal is fired}
|
||
else
|
||
Result := inherited itemViewViewportEventFilter(Sender, Event);
|
||
end;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtHeaderView.SignalSectionClicked
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtHeaderView.SignalSectionClicked(logicalIndex: Integer); cdecl;
|
||
var
|
||
Msg: TLMNotify;
|
||
NMLV: TNMListView;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
writeln('TQtHeaderView.signalSectionClicked index ',logicalIndex);
|
||
{$endif}
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
|
||
|
||
Msg.Msg := CN_NOTIFY;
|
||
NMLV.hdr.hwndfrom := LCLObject.Handle;
|
||
NMLV.hdr.code := LVN_COLUMNCLICK;
|
||
NMLV.iItem := -1;
|
||
NMLV.iSubItem := logicalIndex;
|
||
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
|
||
DeliverMessage(Msg);
|
||
|
||
end;
|
||
|
||
function TQtHeaderView.getResizeMode(AIndex: Integer): QHeaderViewResizeMode;
|
||
begin
|
||
Result := QHeaderView_sectionResizeMode(QHeaderViewH(Widget), AIndex);
|
||
// Result := QHeaderView_resizeMode(QHeaderViewH(Widget), AIndex);
|
||
end;
|
||
|
||
procedure TQtHeaderView.setResizeMode(AResizeMode: QHeaderViewResizeMode);
|
||
begin
|
||
QHeaderView_setSectionResizeMode(QHeaderViewH(Widget), AResizeMode);
|
||
// QHeaderView_setResizeMode(QHeaderViewH(Widget), AResizeMode);
|
||
end;
|
||
|
||
procedure TQtHeaderView.setResizeMode(AIndex: Integer;
|
||
AResizeMode: QHeaderViewResizeMode);
|
||
begin
|
||
QHeaderView_setSectionResizeMode(QHeaderViewH(Widget), AIndex, AResizeMode);
|
||
// QHeaderView_setResizeMode(QHeaderViewH(Widget), AIndex, AResizeMode);
|
||
end;
|
||
|
||
function TQtHeaderView.sectionSize(AIndex: Integer): Integer;
|
||
begin
|
||
Result := QHeaderView_sectionSize(QHeaderViewH(Widget), AIndex);
|
||
end;
|
||
|
||
function TQtHeaderView.sectionSizeHint(AIndex: Integer): Integer;
|
||
begin
|
||
Result := QHeaderView_sectionSizeHint(QHeaderViewH(Widget), AIndex);
|
||
end;
|
||
|
||
procedure TQtHeaderView.moveSection(AFromIndex: Integer; AToIndex: Integer);
|
||
begin
|
||
QHeaderView_moveSection(QHeaderViewH(Widget), AFromIndex, AToIndex);
|
||
end;
|
||
|
||
procedure TQtHeaderView.resizeSection(ASection: Integer; ASize: Integer);
|
||
begin
|
||
QHeaderView_resizeSection(QHeaderViewH(Widget), ASection, ASize);
|
||
end;
|
||
|
||
procedure TQtHeaderView.setHighlightSections(AValue: Boolean);
|
||
begin
|
||
QHeaderView_setHighlightSections(QHeaderViewH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtHeaderView.setDefaultSectionSize(AValue: Integer);
|
||
begin
|
||
QHeaderView_setDefaultSectionSize(QHeaderViewH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtHeaderView.setStretchLastSection(AValue: Boolean);
|
||
begin
|
||
QHeaderView_setStretchLastSection(QHeaderViewH(Widget), AValue);
|
||
end;
|
||
|
||
{ TQtTreeView }
|
||
|
||
function TQtTreeView.getColVisible(AIndex: Integer): Boolean;
|
||
begin
|
||
Result := not QTreeView_isColumnHidden(QTreeViewH(Widget), AIndex);
|
||
end;
|
||
|
||
function TQtTreeView.getColWidth(AIndex: Integer): Integer;
|
||
begin
|
||
Result := QTreeView_columnWidth(QTreeViewH(Widget), AIndex);
|
||
end;
|
||
|
||
function TQtTreeView.GetUniformRowHeights: Boolean;
|
||
begin
|
||
Result := QTreeView_uniformRowHeights(QTreeViewH(Widget));
|
||
end;
|
||
|
||
procedure TQtTreeView.setColVisible(AIndex: Integer; const AValue: Boolean);
|
||
begin
|
||
QTreeView_setColumnHidden(QTreeViewH(Widget), AIndex, not AValue);
|
||
end;
|
||
|
||
procedure TQtTreeView.setColWidth(AIndex: Integer; const AValue: Integer);
|
||
begin
|
||
QTreeView_setColumnWidth(QTreeViewH(Widget), AIndex, AValue);
|
||
end;
|
||
|
||
procedure TQtTreeView.SetUniformRowHeights(const AValue: Boolean);
|
||
begin
|
||
QTreeView_setUniformRowHeights(QTreeViewH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtTreeView.setWordWrap(const AValue: Boolean);
|
||
begin
|
||
QTreeView_setWordWrap(QTreeViewH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtTreeView.setRootIsDecorated(AValue: Boolean);
|
||
begin
|
||
QTreeView_setRootIsDecorated(QTreeViewH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtTreeView.setAllColumnsShowFocus(AValue: Boolean);
|
||
begin
|
||
QTreeView_setAllColumnsShowFocus(QTreeViewH(Widget), AValue);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTreeView.CreateWidget
|
||
Params: None
|
||
Returns: Widget (QTreeViewH)
|
||
------------------------------------------------------------------------------}
|
||
function TQtTreeView.CreateWidget(const AParams: TCreateParams):QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtTreeView.Create');
|
||
{$endif}
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QTreeView_create(Parent);
|
||
end;
|
||
|
||
{ TQtTreeWidget }
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTreeWidget.CreateWidget
|
||
Params: None
|
||
Returns: Widget (QTreeWidgetH)
|
||
------------------------------------------------------------------------------}
|
||
function TQtTreeWidget.CreateWidget(const AParams: TCreateParams):QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtTreeWidget.Create');
|
||
{$endif}
|
||
FDelayedCheckItem := nil;
|
||
AllowGrayed := False;
|
||
FSelection := TFPList.Create;
|
||
FSavedEvent := nil;
|
||
FSavedEventTimer := nil;
|
||
FSavedEventTimerHook := nil;
|
||
FViewStyle := -1;
|
||
FCheckable := False;
|
||
FHideSelection := False;
|
||
FOwnerData := False;
|
||
FSyncingItems := False;
|
||
{$IFDEF TEST_QT_SORTING}
|
||
FCanSort := False;
|
||
FSorting := False;
|
||
{$ENDIF}
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QTreeWidget_create(Parent);
|
||
FHeader := nil;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTreeWidget.Destroy
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
destructor TQtTreeWidget.Destroy;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtTreeWidget.Destroy');
|
||
{$endif}
|
||
FSelection.Free;
|
||
if Assigned(FHeader) then
|
||
FHeader.Free;
|
||
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.DestroyNotify(AWidget: TQtWidget);
|
||
begin
|
||
if AWidget = FHeader then
|
||
FHeader := nil;
|
||
inherited DestroyNotify(AWidget);
|
||
end;
|
||
|
||
function TQtTreeWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
var
|
||
item: QTreeWidgetItemH;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject = nil then
|
||
exit;
|
||
if QEvent_Type(Event) = QEventResize then
|
||
// let the viewport send resize
|
||
else
|
||
if Checkable then
|
||
begin
|
||
if (QEvent_type(Event) = QEventKeyPress) and
|
||
(QKeyEvent_key(QKeyEventH(Event)) = QtKey_Space) and
|
||
(QKeyEvent_modifiers(QKeyEventH(Event)) and QtControlModifier = 0) then
|
||
begin
|
||
Result:=inherited EventFilter(Sender, Event);
|
||
if not Result then
|
||
begin
|
||
Item := currentItem;
|
||
if Item <> nil then
|
||
begin
|
||
Item := topLevelItem(getRow(Item));
|
||
if (Item <> nil) and
|
||
((QTreeWidget_currentColumn(QTreeWidgetH(Widget)) = 0) or
|
||
TCustomListView(LCLObject).RowSelect) then
|
||
HandleCheckChangedEvent(QtPoint(0, 0), Item, Event);
|
||
if OwnerDrawn then
|
||
begin
|
||
if QTreeWidgetItem_checkState(Item, 0) = QtUnChecked then
|
||
QTreeWidgetItem_setCheckState(Item, 0, QtChecked)
|
||
else
|
||
QTreeWidgetItem_setCheckState(Item, 0, QtUnchecked);
|
||
end;
|
||
end;
|
||
end else
|
||
QEvent_ignore(Event);
|
||
end else
|
||
Result:=inherited EventFilter(Sender, Event);
|
||
end else
|
||
if ((QEvent_type(Event) = QEventMouseButtonPress) or
|
||
(QEvent_type(Event) = QEventMouseButtonRelease))
|
||
and (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) then
|
||
{eat mouse button events -> signalItemClicked is fired}
|
||
else
|
||
Result:=inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
procedure TQtTreeWidget.SetItemLastCheckStateInternal(AItem: QTreeWidgetItemH;
|
||
AState: QtCheckState);
|
||
var
|
||
v: QVariantH;
|
||
begin
|
||
v := QVariant_create(Ord(AState));
|
||
QTreeWidgetItem_setData(AItem, 0, QtCheckStateRole, v);
|
||
QVariant_destroy(v);
|
||
end;
|
||
|
||
procedure TQtTreeWidget.HandleCheckChangedEvent(const AMousePos: TQtPoint;
|
||
AItem: QTreeWidgetItemH; AEvent: QEventH);
|
||
var
|
||
xx: Integer;
|
||
B: Boolean;
|
||
R: TRect;
|
||
|
||
procedure SendMessage(AnItem: QTreeWidgetItemH);
|
||
var
|
||
Msg: TLMNotify;
|
||
NMLV: TNMListView;
|
||
begin
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
|
||
|
||
Msg.Msg := CN_NOTIFY;
|
||
|
||
NMLV.hdr.hwndfrom := LCLObject.Handle;
|
||
NMLV.hdr.code := LVN_ITEMCHANGED;
|
||
|
||
|
||
NMLV.iItem := GetRow(AnItem);
|
||
|
||
NMLV.uOldState := UINT(Ord(not B));
|
||
NMLV.uNewState := UINT(Ord(B));
|
||
NMLV.uChanged := LVIF_STATE;
|
||
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
{$IFDEF QT_DEBUGTQTTREEWIDGET}
|
||
DebugLn('TQtTreeWidget.HandleCheckableMouseDown sending LVN_ITEMCHANGED Checked ',dbgs(B));
|
||
{$ENDIF}
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
begin
|
||
if not Checkable or (AItem = nil) or (ViewStyle < 0) then
|
||
exit;
|
||
|
||
if ((QEvent_type(AEvent) = QEventMouseButtonPress) or
|
||
(QEvent_type(AEvent) = QEventMouseButtonDblClick)) and
|
||
(QMouseEvent_button(QMouseEventH(AEvent)) = QtLeftButton) then
|
||
begin
|
||
if (QTreeWidgetItem_flags(AItem) and QtItemIsUserCheckable) <> 0 then
|
||
begin
|
||
xx := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
|
||
R := visualItemRect(AItem);
|
||
if ((AMousePos.X > 2) and (AMousePos.X <= (xx + 2)))
|
||
and (AMousePos.Y > R.Top + 1) and (AMousePos.Y < (R.Bottom - 2)) then
|
||
begin
|
||
B := QTreeWidgetItem_checkState(AItem, 0) = QtUnChecked;
|
||
if B then
|
||
SetItemLastCheckStateInternal(AItem, QtChecked)
|
||
else
|
||
SetItemLastCheckStateInternal(AItem, QtUnChecked);
|
||
|
||
// if AItem is deleted in mouse event FDelayedCheckItem becomes nil and that's fine. issue #32869
|
||
FDelayedCheckItem := AItem;
|
||
SendMessage(AItem);
|
||
end;
|
||
end;
|
||
end else
|
||
if (QEvent_type(AEvent) = LCLQt_ItemViewAfterMouseRelease) then
|
||
begin
|
||
if (FDelayedCheckItem <> nil) and (FDelayedCheckItem <> AItem) then
|
||
begin
|
||
SetItemLastCheckStateInternal(FDelayedCheckItem, QTreeWidgetItem_checkState(FDelayedCheckItem, 0));
|
||
SendMessage(FDelayedCheckItem);
|
||
end;
|
||
FDelayedCheckItem := nil;
|
||
SetItemLastCheckStateInternal(AItem, QTreeWidgetItem_checkState(AItem, 0));
|
||
SendMessage(AItem);
|
||
end else
|
||
if (QEvent_type(AEvent) = QEventKeyPress) and
|
||
(QKeyEvent_key(QKeyEventH(AEvent)) = QtKey_Space) then
|
||
begin
|
||
FDelayedCheckItem := nil;
|
||
B := QTreeWidgetItem_checkState(AItem, 0) = QtUnChecked;
|
||
if B then
|
||
SetItemLastCheckStateInternal(AItem, QtChecked)
|
||
else
|
||
SetItemLastCheckStateInternal(AItem, QtUnChecked);
|
||
|
||
SendMessage(AItem);
|
||
end;
|
||
end;
|
||
|
||
function TQtTreeWidget.GetItemLastCheckStateInternal(AItem: QTreeWidgetItemH
|
||
): QtCheckState;
|
||
var
|
||
v: QVariantH;
|
||
ok: Boolean;
|
||
begin
|
||
Result := QtUnChecked;
|
||
if AItem = nil then
|
||
exit;
|
||
v := QVariant_create();
|
||
QTreeWidgetItem_data(AItem, v, 0, QtCheckStateRole);
|
||
ok := False;
|
||
if QVariant_isValid(v) then
|
||
Result := QtCheckState(QVariant_toInt(v, @Ok));
|
||
QVariant_destroy(v);
|
||
end;
|
||
|
||
function TQtTreeWidget.itemViewViewportEventFilter(Sender: QObjectH;
|
||
Event: QEventH): Boolean; cdecl;
|
||
var
|
||
MousePos: TQtPoint;
|
||
Item: QTreeWidgetItemH;
|
||
ALCLEvent: QLCLMessageEventH;
|
||
W: QHeaderViewH;
|
||
R: TRect;
|
||
DC: TQtDeviceContext;
|
||
x: Integer;
|
||
AMsgData: PtrUInt;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject = nil then
|
||
exit;
|
||
BeginEventProcessing;
|
||
try
|
||
if (QEvent_type(Event) = QEventPaint) and
|
||
not Self.FOwnerData and (Sender = viewportWidget) then
|
||
begin
|
||
HasPaint := True;
|
||
QPaintEvent_rect(QPaintEventH(Event), @R);
|
||
DC := TQtDeviceContext.Create(QWidgetH(Sender), True);
|
||
try
|
||
TCustomListViewAccess(LCLObject).Canvas.handle := HDC(DC);
|
||
TCustomListViewAccess(LCLObject).IntfCustomDraw(dtControl, cdPrePaint, 0, 0, [], @R);
|
||
finally
|
||
TCustomListViewAccess(LCLObject).Canvas.handle := 0;
|
||
DC.Free;
|
||
end;
|
||
end else
|
||
if (ViewStyle = Ord(vsReport)) and Checkable and getEnabled then
|
||
begin
|
||
if QEvent_type(Event) = LCLQt_ItemViewAfterMouseRelease then
|
||
begin
|
||
ALCLEvent := QLCLMessageEventH(Event);
|
||
Item := QTreeWidgetItemH(QLCLMessageEvent_getLParam(ALCLEvent));
|
||
// sync lcl with qt state. This is needed only when mouse is pressed
|
||
// and moved out of item, or pressed on item and released over checkbox
|
||
if (Item <> nil) and (GetItemLastCheckStateInternal(Item) <>
|
||
QTreeWidgetItem_checkState(Item, 0)) then
|
||
begin
|
||
MousePos := QtPoint(0, 0); // shutup compiler
|
||
if QLCLMessageEvent_getMsg(ALCLEvent) > 0 then
|
||
QTreeWidgetItem_setCheckState(Item, 0, GetItemLastCheckStateInternal(Item));
|
||
HandleCheckChangedEvent(MousePos, Item, Event);
|
||
end;
|
||
end else
|
||
if ((QEvent_type(Event) = QEventMouseButtonPress) or
|
||
(QEvent_type(Event) = QEventMouseButtonDblClick)) then
|
||
begin
|
||
// MousePos :=
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
Item := itemAt(MousePos.x, MousePos.y);
|
||
Result := inherited itemViewViewportEventFilter(Sender, Event);
|
||
|
||
if Item <> nil then
|
||
HandleCheckChangedEvent(MousePos, Item, Event);
|
||
end else
|
||
if (QEvent_type(Event) = QEventMouseButtonRelease) then
|
||
begin
|
||
if OwnerDrawn and Checkable then
|
||
begin
|
||
// MousePos :=
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
Item := itemAt(MousePos.x, MousePos.y);
|
||
if (Item <> nil) and
|
||
((QTreeWidgetItem_flags(Item) and QtItemIsUserCheckable) <> 0) then
|
||
begin
|
||
x := GetPixelMetric(QStylePM_IndicatorWidth, nil, Widget);
|
||
if ((MousePos.X > 2) and (MousePos.X < (X + 2))) then
|
||
begin
|
||
if QTreeWidgetItem_checkState(Item, 0) = QtUnchecked then
|
||
QTreeWidgetItem_setCheckState(Item, 0, QtChecked)
|
||
else
|
||
QTreeWidgetItem_setCheckState(Item, 0, QtUnChecked);
|
||
end;
|
||
end;
|
||
Result := SlotMouse(Sender, Event);
|
||
end else
|
||
begin
|
||
if Checkable then
|
||
begin
|
||
// MousePos :=
|
||
QMouseEvent_pos(QMouseEventH(Event), @MousePos);
|
||
Item := itemAt(MousePos.x, MousePos.y);
|
||
if Item <> nil then
|
||
begin
|
||
Item := topLevelItem(GetRow(Item));
|
||
if Assigned(LCLObject) and LCLObject.Dragging then
|
||
AMsgData := Ord(QTreeWidgetItem_checkState(Item, 0)) + 1
|
||
else
|
||
AMsgData := 0;
|
||
ALCLEvent := QLCLMessageEvent_create(LCLQt_ItemViewAfterMouseRelease, AMsgData,
|
||
PtrUInt(Item), PtrUInt(Item), 0);
|
||
QCoreApplication_postEvent(Sender, ALCLEvent);
|
||
end;
|
||
end;
|
||
Result := inherited itemViewViewportEventFilter(Sender, Event);
|
||
end;
|
||
end else
|
||
if (QEvent_type(Event) = QEventMouseMove) and (LCLObject <> nil) then
|
||
begin
|
||
W := QTreeView_header(QTreeViewH(Widget));
|
||
if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
|
||
begin
|
||
BeginEventProcessing;
|
||
try
|
||
Result := SlotMouseMove(Sender, Event);
|
||
// allow dnd inside listview (vsReport and vsList only).
|
||
if not Result and Assigned(LCLObject) and LCLObject.Dragging then
|
||
Result := True;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end else
|
||
Result := inherited itemViewViewportEventFilter(Sender, Event);
|
||
end;
|
||
end else
|
||
begin
|
||
if (QEvent_type(Event) = QEventMouseMove) and (LCLObject <> nil) then
|
||
begin
|
||
W := QTreeView_header(QTreeViewH(Widget));
|
||
if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
|
||
begin
|
||
BeginEventProcessing;
|
||
try
|
||
Result := SlotMouseMove(Sender, Event);
|
||
// allow dnd inside listview (vsReport and vsList only).
|
||
if not Result and Assigned(LCLObject) and LCLObject.Dragging then
|
||
Result := True;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end else
|
||
Result := inherited itemViewViewportEventFilter(Sender, Event);
|
||
end else
|
||
Result := inherited itemViewViewportEventFilter(Sender, Event);
|
||
end;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.OwnerDataNeeded(ARect: TRect);
|
||
var
|
||
R: TRect;
|
||
TopItem: Integer;
|
||
i: Integer;
|
||
j: Integer;
|
||
ChildCount: Integer;
|
||
VHeight: Integer; // viewport height
|
||
RowHeight, AImagesWidth: Integer;
|
||
item: QTreeWidgetItemH;
|
||
itemChild: QTreeWidgetItemH;
|
||
v,v2,v3: QVariantH;
|
||
WStr, TempStr: WideString;
|
||
ASelected: Boolean;
|
||
ImgList: TCustomImageList;
|
||
AImageIndex: TImageIndex;
|
||
Bmp: TBitmap;
|
||
AOk, AStateImages: Boolean;
|
||
AIcon: QIconH;
|
||
ASize: TSize;
|
||
ImgListRes: TScaledImageListResolution;
|
||
begin
|
||
{do not set items during design time}
|
||
if csDesigning in LCLObject.ComponentState then
|
||
exit;
|
||
|
||
if QTreeWidget_topLevelItemCount(QTreeWidgetH(Widget)) < 1 then
|
||
exit;
|
||
|
||
{TODO: add QtDecorationRole (icon) etc ... }
|
||
QWidget_contentsRect(viewportWidget, @R);
|
||
VHeight := R.Bottom - R.Top;
|
||
|
||
item := QTreeWidget_itemAt(QTreeWidgetH(Widget), 0, 1);
|
||
if item <> nil then
|
||
begin
|
||
|
||
TopItem := getRow(item);
|
||
RowHeight := getRowHeight(TopItem);
|
||
|
||
if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
|
||
exit;
|
||
|
||
i := 0;
|
||
while (i < (VHeight + RowHeight)) do
|
||
begin
|
||
item := QTreeWidget_itemAt(QTreeWidgetH(Widget), 0, i + 1);
|
||
if item <> nil then
|
||
begin
|
||
|
||
TopItem := getRow(item);
|
||
RowHeight := getRowHeight(TopItem);
|
||
if (TopItem < 0) or (TopItem > TCustomListViewHack(LCLObject).Items.Count - 1) then
|
||
continue;
|
||
|
||
WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].Caption);
|
||
ASelected := TCustomListViewHack(LCLObject).Items[TopItem].Selected;
|
||
|
||
v := QVariant_create(PWideString(@WStr));
|
||
try
|
||
v2 := QVariant_create;
|
||
try
|
||
TempStr := '';
|
||
QTreeWidgetItem_data(item, v2, 0, Ord(QtDisplayRole));
|
||
if not QVariant_isNull(v2) then
|
||
QVariant_toString(v2, @TempStr);
|
||
if TempStr <> WStr then
|
||
QTreeWidgetItem_setData(item, 0, Ord(QtDisplayRole), v);
|
||
finally
|
||
QVariant_destroy(v2);
|
||
end;
|
||
|
||
AStateImages := False;
|
||
// set imageindex, part of comment in issue #27233
|
||
ImgList := TCustomListViewHack(LCLObject).SmallImages;
|
||
if Assigned(ImgList) then
|
||
AImagesWidth := TCustomListViewHack(LCLObject).SmallImagesWidth
|
||
else
|
||
begin
|
||
ImgList := TCustomListViewHack(LCLObject).StateImages;
|
||
if Assigned(ImgList) then
|
||
AImagesWidth := TCustomListViewHack(LCLObject).StateImagesWidth;
|
||
AStateImages := True;
|
||
end;
|
||
if Assigned(ImgList) then
|
||
begin
|
||
ImgListRes := ImgList.ResolutionForPPI[
|
||
AImagesWidth,
|
||
TCustomListViewHack(LCLObject).Font.PixelsPerInch,
|
||
TCustomListViewHack(LCLObject).GetCanvasScaleFactor];
|
||
QTreeWidgetItem_sizeHint(item, @ASize, 0);
|
||
if (ASize.cx <> ImgListRes.Width) or (ASize.cx <> ImgListRes.Height) then
|
||
begin
|
||
ASize.cx := ImgListRes.Width;
|
||
ASize.cy := ImgListRes.Height;
|
||
QTreeWidgetItem_setSizeHint(item, 0, @ASize);
|
||
end;
|
||
if AStateImages then
|
||
AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].StateIndex
|
||
else
|
||
AImageIndex := TCustomListViewHack(LCLObject).Items[TopItem].ImageIndex;
|
||
if (ImgListRes.Count > 0) and
|
||
((AImageIndex >= 0) and (AImageIndex < ImgListRes.Count)) then
|
||
begin
|
||
Bmp := TBitmap.Create;
|
||
try
|
||
ImgListRes.GetBitmap(AImageIndex, Bmp);
|
||
v2 := QVariant_create;
|
||
QTreeWidgetItem_data(item, v2, 0, QtListViewOwnerDataRole);
|
||
if not QVariant_isNull(v2) then
|
||
begin
|
||
AOk := True;
|
||
if QVariant_toInt(v2, @AOk) <> AImageIndex then
|
||
begin
|
||
v2 := QVariant_create(AImageIndex);
|
||
QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v2);
|
||
QVariant_destroy(v2);
|
||
QTreeWidgetItem_setIcon(item, 0, TQtImage(Bmp.Handle).AsIcon)
|
||
end;
|
||
// else we are imageIndex and that''s fine.
|
||
end else
|
||
begin
|
||
v2 := QVariant_create(AImageIndex);
|
||
QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v2);
|
||
QVariant_destroy(v2);
|
||
QTreeWidgetItem_setIcon(item, 0, TQtImage(Bmp.Handle).AsIcon);
|
||
end;
|
||
finally
|
||
Bmp.Free;
|
||
end;
|
||
end else
|
||
if (AImageIndex < 0) then
|
||
begin
|
||
v2 := QVariant_create;
|
||
AIcon := QIcon_create;
|
||
try
|
||
QTreeWidgetItem_data(item, v2, 0, QtListViewOwnerDataRole);
|
||
if not QVariant_isNull(v2) then
|
||
begin
|
||
v3 := QVariant_create;
|
||
try
|
||
QTreeWidgetItem_setData(item, 0, QtListViewOwnerDataRole, v3);
|
||
finally
|
||
QVariant_destroy(v3);
|
||
end;
|
||
end;
|
||
QTreeWidgetItem_icon(item, AIcon, 0);
|
||
if not QIcon_isNull(AIcon) then
|
||
QTreeWidgetItem_setIcon(item, 0, nil);
|
||
finally
|
||
QVariant_destroy(v2);
|
||
QIcon_destroy(AIcon);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
// set alignment, issue #27233
|
||
if TCustomListViewHack(LCLObject).Columns.Count > 0 then
|
||
begin
|
||
case TCustomListViewHack(LCLObject).Column[0].Alignment of
|
||
taRightJustify: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignRight);
|
||
taCenter: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignCenter);
|
||
taLeftJustify: QTreeWidgetItem_setTextAlignment(item, 0, QtAlignLeft);
|
||
end;
|
||
end;
|
||
finally
|
||
QVariant_destroy(v);
|
||
end;
|
||
|
||
ChildCount := QTreeWidgetItem_childCount(Item);
|
||
if ChildCount = TCustomListViewHack(LCLObject).Items[TopItem].SubItems.Count then
|
||
begin
|
||
for j := 0 to ChildCount - 1 do
|
||
begin
|
||
itemChild := QTreeWidgetItem_child(item, j);
|
||
if itemChild <> nil then
|
||
begin
|
||
WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].SubItems[j]);
|
||
v := QVariant_create(PWideString(@WStr));
|
||
v2 := QVariant_create;
|
||
try
|
||
TempStr := '';
|
||
QTreeWidgetItem_data(itemChild, v2, j, Ord(QtDisplayRole));
|
||
if not QVariant_isNull(v2) then
|
||
QVariant_toString(v2, @TempStr);
|
||
if TempStr <> WStr then
|
||
QTreeWidgetItem_setData(itemChild, j, Ord(QtDisplayRole), v);
|
||
finally
|
||
QVariant_destroy(v2);
|
||
QVariant_destroy(v);
|
||
end;
|
||
end;
|
||
end;
|
||
end else
|
||
begin
|
||
for j := 0 to TCustomListViewHack(LCLObject).Items[TopItem].SubItems.Count - 1 do
|
||
begin
|
||
WStr := GetUTF8String(TCustomListViewHack(LCLObject).Items[TopItem].SubItems[j]);
|
||
v := QVariant_create(PWideString(@WStr));
|
||
QTreeWidgetItem_setData(item, j + 1, Ord(QtDisplayRole), v);
|
||
|
||
// set alignment, issue #27233
|
||
if (TCustomListViewHack(LCLObject).Columns.Count > 0) then
|
||
begin
|
||
case TCustomListViewHack(LCLObject).Column[j + 1].Alignment of
|
||
taRightJustify: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignRight);
|
||
taCenter: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignCenter);
|
||
taLeftJustify: QTreeWidgetItem_setTextAlignment(item, j + 1, QtAlignLeft);
|
||
end;
|
||
end;
|
||
QVariant_destroy(v);
|
||
end;
|
||
end;
|
||
if QTreeWidgetItem_isSelected(Item) <> ASelected then
|
||
QTreeWidgetItem_setSelected(Item, ASelected);
|
||
end;
|
||
|
||
inc(i, RowHeight);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.ItemDelegatePaint(painter: QPainterH;
|
||
option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
|
||
var
|
||
Msg: TLMDrawListItem;
|
||
DrawStruct: TDrawListItemStruct;
|
||
State: QStyleState;
|
||
R: TRect;
|
||
ItemIndex, SubItemIndex: Integer;
|
||
ACustomState: TCustomDrawState;
|
||
ATarget: TCustomDrawTarget;
|
||
TmpDC1, TmpDC2: HDC;
|
||
SkipDefault: Boolean;
|
||
APaintResult: TCustomDrawResult;
|
||
|
||
function IsItemEmpty: boolean;
|
||
var
|
||
AText: WideString;
|
||
AIcon: QIconH;
|
||
begin
|
||
QTreeWidgetItem_text(topLevelItem(ItemIndex), @AText, SubItemIndex);
|
||
AIcon := QIcon_create;
|
||
QTreeWidgetItem_icon(topLevelItem(ItemIndex), AIcon, SubItemIndex);
|
||
Result := (AText = '') and QIcon_isNull(AIcon);
|
||
QIcon_destroy(AIcon);
|
||
end;
|
||
|
||
begin
|
||
if TCustomListViewAccess(LCLObject).OwnerDraw and (ViewStyle = Ord(vsReport)) then
|
||
begin
|
||
QPainter_save(painter);
|
||
State := QStyleOption_state(option);
|
||
DrawStruct.ItemID := UINT(QModelIndex_row(index));
|
||
|
||
DrawStruct.Area := visualRect(index);
|
||
DrawStruct.DC := HDC(TQtDeviceContext.CreateFromPainter(painter));
|
||
|
||
DrawStruct.ItemState := [];
|
||
// selected
|
||
if (State and QStyleState_Selected) <> 0 then
|
||
Include(DrawStruct.ItemState, odSelected);
|
||
// disabled
|
||
if (State and QStyleState_Enabled) = 0 then
|
||
Include(DrawStruct.ItemState, odDisabled);
|
||
// focused (QStyleState_FocusAtBorder?)
|
||
if (State and QStyleState_HasFocus) <> 0 then
|
||
Include(DrawStruct.ItemState, odFocused);
|
||
// hotlight
|
||
if (State and QStyleState_MouseOver) <> 0 then
|
||
Include(DrawStruct.ItemState, odHotLight);
|
||
|
||
// checked does not work as we expected.
|
||
if Checkable and (QModelIndex_column(index) <= 0) then
|
||
begin
|
||
// if (State and QStyleState_On <> 0) and (ATarget = dtItem) then
|
||
// Include(ACustomState, cdsChecked);
|
||
if QTreeWidgetItem_checkState(topLevelItem(QModelIndex_row(index)), 0) <> QtUnchecked then
|
||
Include(DrawStruct.ItemState, odChecked);
|
||
end;
|
||
|
||
{ todo: over states:
|
||
|
||
odGrayed, odChecked,
|
||
odDefault, odInactive, odNoAccel,
|
||
odNoFocusRect, odReserved1, odReserved2, odComboBoxEdit
|
||
}
|
||
Msg.Msg := CN_DRAWITEM;
|
||
Msg.DrawListItemStruct := @DrawStruct;
|
||
DeliverMessage(Msg);
|
||
|
||
QPainter_restore(painter);
|
||
|
||
TQtDeviceContext(DrawStruct.DC).Free;
|
||
end else
|
||
begin
|
||
State := QStyleOption_state(option);
|
||
ACustomState := [cdsDefault];
|
||
|
||
if (State and QStyleState_Selected) <> 0 then
|
||
Include(ACustomState, cdsSelected);
|
||
// disabled
|
||
if (State and QStyleState_Enabled) = 0 then
|
||
Include(ACustomState, cdsDisabled);
|
||
// focused (QStyleState_FocusAtBorder?)
|
||
if (State and QStyleState_HasFocus) <> 0 then
|
||
Include(ACustomState, cdsFocused);
|
||
// hotlight
|
||
if (State and QStyleState_MouseOver) <> 0 then
|
||
Include(ACustomState, cdsHot);
|
||
|
||
ItemIndex := QModelIndex_row(index);
|
||
SubItemIndex := QModelIndex_column(index);
|
||
|
||
if SubItemIndex <= 0 then
|
||
ATarget := dtItem
|
||
else
|
||
ATarget := dtSubItem;
|
||
|
||
// checked does not work as we expected.
|
||
if Checkable and (ATarget = dtItem) then
|
||
begin
|
||
// if (State and QStyleState_On <> 0) and (ATarget = dtItem) then
|
||
// Include(ACustomState, cdsChecked);
|
||
if QTreeWidgetItem_checkState(topLevelItem(ItemIndex), 0) <> QtUnchecked then
|
||
Include(ACustomState, cdsChecked);
|
||
end;
|
||
|
||
QStyle_drawControl(QApplication_style, QStyleCE_ItemViewItem, Option, painter, viewportWidget);
|
||
|
||
// NOW WE ARE DRAWING ITEMS ...
|
||
QPainter_save(painter);
|
||
if TCustomListView(LCLObject).Canvas.HandleAllocated then
|
||
TmpDC2 := TCustomListView(LCLObject).Canvas.GetUpdatedHandle([csHandleValid])
|
||
else
|
||
TmpDC2 := 0;
|
||
TmpDC1 := HDC(TQtDeviceContext.CreateFromPainter(painter));
|
||
TCustomListView(LCLObject).Canvas.Handle := TmpDC1;
|
||
try
|
||
R := visualRect(index);
|
||
// here we do only OnCustomDrawItem and OnCustomDrawSubItem
|
||
// OnCustomDraw is done inside itemViewportEventFilter.
|
||
if IsItemEmpty then
|
||
QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
|
||
|
||
APaintResult := TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPrePaint, ItemIndex, SubItemIndex, ACustomState, @R);
|
||
SkipDefault := cdrSkipDefault in APaintResult;
|
||
|
||
if not SkipDefault then // do default paint by unknown magic
|
||
begin
|
||
if not IsItemEmpty then
|
||
QAbstractItemDelegate_paint(FOldDelegate, painter, Option, index);
|
||
end;
|
||
// issue #27315
|
||
if cdrNotifyPostpaint in APaintResult then
|
||
TCustomListViewAccess(LCLObject).IntfCustomDraw(ATarget, cdPostPaint, ItemIndex, SubItemIndex, ACustomState, @R);
|
||
finally
|
||
TCustomListView(LCLObject).Canvas.Handle := TmpDC2;
|
||
TQtDeviceContext(TmpDC1).Free;
|
||
QPainter_restore(painter);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.ClearItems;
|
||
begin
|
||
FSelection.Clear;
|
||
QTreeWidget_clear(QTreeWidgetH(Widget));
|
||
end;
|
||
|
||
procedure TQtTreeWidget.clearSelection;
|
||
begin
|
||
inherited clearSelection;
|
||
FSelection.Clear;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.DeleteItem(const AIndex: integer);
|
||
var
|
||
Item: QTreeWidgetItemH;
|
||
Index: Integer;
|
||
begin
|
||
Item := topLevelItem(AIndex);
|
||
if Item <> nil then
|
||
Index := FSelection.IndexOf(Item)
|
||
else
|
||
Index := -1;
|
||
if Index <> -1 then
|
||
FSelection.Remove(Item);
|
||
if FDelayedCheckItem = Item then
|
||
FDelayedCheckItem := nil;
|
||
Item := takeTopLevelItem(AIndex);
|
||
if Item <> nil then
|
||
QTreeWidgetItem_destroy(Item);
|
||
end;
|
||
|
||
function TQtTreeWidget.getHeader: TQtHeaderView;
|
||
begin
|
||
{while designing TQtHeaderView is a no-no}
|
||
if not (csDesigning in LCLObject.ComponentState) and (FHeader = nil) then
|
||
begin
|
||
FHeader := TQtHeaderView.CreateFrom(LCLObject, QTreeView_header(QTreeViewH(Widget)));
|
||
FHeader.FOwner := Self;
|
||
FHeader.FChildOfComplexWidget := ccwTreeWidget;
|
||
QHeaderView_setSectionsMovable(QHeaderViewH(FHeader.Widget), False);
|
||
{$IFDEF TEST_QT_SORTING}
|
||
FSortChanged := QHeaderView_hook_create(FHeader.Widget);
|
||
QHeaderView_hook_hook_sortIndicatorChanged(FSortChanged,
|
||
@SignalSortIndicatorChanged);
|
||
{$ENDIF}
|
||
FHeader.AttachEvents;
|
||
end;
|
||
Result := FHeader;
|
||
end;
|
||
|
||
function TQtTreeWidget.GetItemChecked(AIndex: Integer): Boolean;
|
||
var
|
||
AItem: QTreeWidgetItemH;
|
||
begin
|
||
Result := False;
|
||
AItem := topLevelItem(AIndex);
|
||
if AItem <> nil then
|
||
Result := GetItemLastCheckStateInternal(AItem) = QtChecked;
|
||
// Result := QTreeWidgetItem_checkState(AItem, 0) = QtChecked;
|
||
end;
|
||
|
||
function TQtTreeWidget.getItemCount: Integer;
|
||
begin
|
||
Result := QTreeWidget_topLevelItemCount(QTreeWidgetH(Widget));
|
||
end;
|
||
|
||
function TQtTreeWidget.getMaxColSize(ACol: Integer): Integer;
|
||
begin
|
||
{$note QSizeH implementation missing for TQtTreeWidget.getMaxColSize}
|
||
Result := MAXINT -1;
|
||
end;
|
||
|
||
function TQtTreeWidget.getMinColSize(ACol: Integer): Integer;
|
||
begin
|
||
{$note QSizeH implementation missing for TQtTreeWidget.getMinColSize}
|
||
Result := 0;
|
||
end;
|
||
|
||
function TQtTreeWidget.getSortEnabled: Boolean;
|
||
begin
|
||
Result := QTreeView_isSortingEnabled(QTreeViewH(Widget));
|
||
end;
|
||
|
||
function TQtTreeWidget.getColCount: Integer;
|
||
begin
|
||
Result := QTreeWidget_columnCount(QTreeWidgetH(Widget));
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setColCount(const AValue: Integer);
|
||
begin
|
||
QTreeWidget_setColumnCount(QTreeWidgetH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtTreeWidget.SetItemChecked(AIndex: Integer; AValue: Boolean);
|
||
var
|
||
AItem: QTreeWidgetItemH;
|
||
AState: QtCheckState;
|
||
begin
|
||
AItem := topLevelItem(AIndex);
|
||
if AItem <> nil then
|
||
begin
|
||
if AValue then
|
||
AState := QtChecked
|
||
else
|
||
AState := QtUnChecked;
|
||
|
||
QTreeWidgetItem_setCheckState(AItem, 0, AState);
|
||
SetItemLastCheckStateInternal(AItem, AState);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setItemCount(const AValue: Integer);
|
||
var
|
||
i: Integer;
|
||
j: Integer;
|
||
Items: TPtrIntArray;
|
||
Item: QTreeWidgetItemH;
|
||
ItemChild: QTreeWidgetItemH;
|
||
begin
|
||
if AValue = ItemCount then
|
||
exit;
|
||
BeginUpdate;
|
||
try
|
||
ClearItems;
|
||
SetLength(Items, AValue);
|
||
for i := 0 to High(Items) do
|
||
begin
|
||
Item := QTreeWidgetItem_create(QTreeWidgetH(Widget), Ord(QTreeWidgetItemType));
|
||
for j := 0 to ColCount - 1 do
|
||
begin
|
||
ItemChild := QTreeWidgetItem_create(item, Ord(QTreeWidgetItemType));
|
||
QTreeWidgetItem_addChild(item, ItemChild);
|
||
end;
|
||
Items[i] := PtrUInt(Item);
|
||
end;
|
||
if length(Items) > 0 then
|
||
QTreeWidget_addTopLevelItems(QTreeWidgetH(Widget), @Items);
|
||
finally
|
||
EndUpdate;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setMaxColSize(ACol: Integer; const AValue: Integer);
|
||
begin
|
||
{$note QSizeH implementation missing for TQtTreeWidget.setMaxColSize}
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setMinColSize(ACol: Integer; const AValue: Integer);
|
||
begin
|
||
QHeaderView_setMinimumSectionSize(QTreeView_header(QTreeViewH(Widget)), AValue);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTreeWidget.setSortEnabled
|
||
Params: Boolean
|
||
Returns: Nothing
|
||
Enables sorting of items.
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtTreeWidget.setSortEnabled(const AValue: Boolean);
|
||
begin
|
||
QTreeView_setSortingEnabled(QTreeWidgetH(Widget), AValue);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTreeWidget.CurrentRow
|
||
Params: None
|
||
Returns: Integer
|
||
------------------------------------------------------------------------------}
|
||
function TQtTreeWidget.currentRow: Integer;
|
||
var
|
||
TWI: QTreeWidgetItemH;
|
||
begin
|
||
TWI := QTreeWidget_currentItem(QTreeWidgetH(Widget));
|
||
Result := getRow(TWI);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTreeWidget.setCurrentRow
|
||
Params: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtTreeWidget.setCurrentRow(row: Integer);
|
||
var
|
||
TWI: QTreeWidgetItemH;
|
||
begin
|
||
TWI := QTreeWidget_topLevelItem(QTreeWidgetH(Widget), Row);
|
||
QTreeWidget_setCurrentItem(QTreeWidgetH(Widget), TWI);
|
||
end;
|
||
|
||
function TQtTreeWidget.currentItem: QTreeWidgetItemH;
|
||
begin
|
||
Result := QTreeWidget_currentItem(QTreeWidgetH(Widget));
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setCurrentItem(AItem: QTreeWidgetItemH);
|
||
begin
|
||
QTreeWidget_setCurrentItem(QTreeWidgetH(Widget), AItem);
|
||
end;
|
||
|
||
function TQtTreeWidget.getRow(AItem: QTreeWidgetItemH): integer;
|
||
begin
|
||
Result := QTreeWidget_indexOfTopLevelItem(QTreeWidgetH(Widget), AItem);
|
||
end;
|
||
|
||
function TQtTreeWidget.headerItem: QTreeWidgetItemH;
|
||
begin
|
||
Result := QTreeWidget_headerItem(QTreeWidgetH(Widget));
|
||
end;
|
||
|
||
function TQtTreeWidget.itemAt(APoint: TPoint): QTreeWidgetItemH;
|
||
begin
|
||
Result := itemAt(APoint.X, APoint.Y);
|
||
end;
|
||
|
||
function TQtTreeWidget.itemAt(x: Integer; y: Integer): QTreeWidgetItemH;
|
||
begin
|
||
Result := QTreeWidget_itemAt(QTreeWidgetH(Widget), x, y);
|
||
end;
|
||
|
||
procedure TQtTreeWidget.insertTopLevelItem(AIndex: Integer;
|
||
AItem: QTreeWidgetItemH);
|
||
begin
|
||
QTreeWidget_insertTopLevelItem(QTreeWidgetH(Widget), AIndex, AItem);
|
||
end;
|
||
|
||
function TQtTreeWidget.takeTopLevelItem(AIndex: Integer): QTreeWidgetItemH;
|
||
begin
|
||
Result := QTreeWidget_takeTopLevelItem(QTreeWidgetH(Widget), AIndex);
|
||
end;
|
||
|
||
function TQtTreeWidget.topLevelItem(AIndex: Integer): QTreeWidgetItemH;
|
||
begin
|
||
Result := QTreeWidget_topLevelItem(QTreeWidgetH(Widget), AIndex);
|
||
end;
|
||
|
||
function TQtTreeWidget.visualItemRect(AItem: QTreeWidgetItemH): TRect;
|
||
var
|
||
ItemRect: TRect;
|
||
begin
|
||
QTreeWidget_visualItemRect(QTreeWidgetH(Widget), @ItemRect, AItem);
|
||
Result := ItemRect;
|
||
end;
|
||
|
||
function TQtTreeWidget.getHeaderHeight(out AOrientation: QtOrientation): Integer;
|
||
var
|
||
W: QHeaderViewH;
|
||
begin
|
||
Result := 0;
|
||
AOrientation := QtHorizontal;
|
||
W := QTreeView_header(QTreeViewH(Widget));
|
||
if QWidget_isVisible(W) and QWidget_isVisibleTo(W, Widget) then
|
||
begin
|
||
AOrientation := QHeaderView_orientation(W);
|
||
if AOrientation = QtHorizontal then
|
||
Result := QWidget_height(W)
|
||
else
|
||
Result := QWidget_width(W);
|
||
end;
|
||
end;
|
||
|
||
function TQtTreeWidget.getItemVisible(AItem: QTreeWidgetItemH): Boolean;
|
||
begin
|
||
Result := not QTreeWidget_isItemHidden(QTreeWidgetH(Widget), AItem);
|
||
end;
|
||
|
||
function TQtTreeWidget.getTopItem: integer;
|
||
begin
|
||
Result := getVisibleRowCount(True);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTreeWidget.getVisibleRowCount
|
||
Params: Boolean
|
||
Returns: if AFirstVisibleOnly = False (default) then it returns number
|
||
of visible rows, or 0 if there's no visible rows.
|
||
When AFirstVisibleOnly = True then it returns index of first visible row,
|
||
otherwise result is -1.
|
||
------------------------------------------------------------------------------}
|
||
function TQtTreeWidget.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
|
||
var
|
||
R: TRect;
|
||
i: integer;
|
||
item: QTreeWidgetItemH;
|
||
RowIndex: integer;
|
||
RowHeight: integer;
|
||
begin
|
||
if AFirstVisibleOnly then
|
||
Result := -1
|
||
else
|
||
Result := 0;
|
||
QWidget_contentsRect(viewportWidget, @R);
|
||
i := 0;
|
||
repeat
|
||
item := itemAt(0, i);
|
||
if item <> nil then
|
||
begin
|
||
RowIndex := getRow(Item);
|
||
if AFirstVisibleOnly then
|
||
begin
|
||
Result := RowIndex;
|
||
break;
|
||
end;
|
||
RowHeight := getRowHeight(RowIndex);
|
||
if RowHeight <= 0 then
|
||
RowHeight := 1;
|
||
inc(Result);
|
||
inc(i, RowHeight);
|
||
end else
|
||
inc(i, 1);
|
||
until i >= R.Bottom;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setItemVisible(AItem: QTreeWidgetItemH;
|
||
const AVisible: Boolean);
|
||
begin
|
||
QTreeWidget_setItemHidden(QTreeWidgetH(Widget), AItem, not AVisible);
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setItemText(AItem: QTreeWidgetItemH;
|
||
const AColumn: Integer; const AText: WideString; const AAlignment: QtAlignment
|
||
);
|
||
begin
|
||
QTreeWidgetItem_setText(AItem, AColumn, @AText);
|
||
QTreeWidgetItem_setTextAlignment(AItem, AColumn, AAlignment);
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setItemData(AItem: QTreeWidgetItemH;
|
||
const AColumn: Integer; Data: Pointer; const ARole: Integer = Ord(QtUserRole));
|
||
var
|
||
v: QVariantH;
|
||
begin
|
||
if Data = nil then
|
||
v := QVariant_create
|
||
else
|
||
v := QVariant_create(Int64({%H-}PtrUInt(Data)));
|
||
QTreeWidgetItem_setData(AItem, AColumn, ARole, v);
|
||
QVariant_destroy(v);
|
||
end;
|
||
|
||
function TQtTreeWidget.selCount: Integer;
|
||
begin
|
||
Result := length(selectedItems);
|
||
end;
|
||
|
||
function TQtTreeWidget.selectedItems: TPtrIntArray;
|
||
begin
|
||
QTreeWidget_selectedItems(QTreeWidgetH(Widget), @Result);
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setHeaderVisible(AVisible: Boolean);
|
||
begin
|
||
if (csDesigning in LCLObject.ComponentState) then
|
||
QTreeView_setHeaderHidden(QTreeViewH(Widget), not AVisible)
|
||
else
|
||
Header.setVisible(AVisible);
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setItemSelected(AItem: QTreeWidgetItemH;
|
||
ASelect: Boolean);
|
||
var
|
||
Msg: TLMNotify;
|
||
NMLV: TNMListView;
|
||
AParent: QTreeWidgetItemH;
|
||
AIndex: Integer;
|
||
ASubIndex: Integer;
|
||
begin
|
||
|
||
if not InUpdate and
|
||
(((FSelection.Count > 0) and (FSelection.IndexOf(AItem) <> -1)) or
|
||
(QTreeWidget_isItemSelected(QTreeWidgetH(Widget), AItem) = ASelect)) then
|
||
exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
|
||
Msg.Msg := CN_NOTIFY;
|
||
|
||
NMLV.hdr.hwndfrom := LCLObject.Handle;
|
||
NMLV.hdr.code := LVN_ITEMCHANGED;
|
||
|
||
AIndex := getRow(AItem);
|
||
|
||
if AIndex = -1 then
|
||
exit;
|
||
|
||
AParent := QTreeWidgetItem_parent(AItem);
|
||
|
||
if AParent <> nil then
|
||
ASubIndex := QTreeWidgetItem_indexOfChild(AParent, AItem)
|
||
else
|
||
ASubIndex := 0;
|
||
|
||
|
||
NMLV.iItem := AIndex;
|
||
NMLV.iSubItem := ASubIndex;
|
||
if not ASelect then
|
||
NMLV.uOldState := LVIS_SELECTED
|
||
else
|
||
NMLV.uNewState := LVIS_SELECTED;
|
||
NMLV.uChanged := LVIF_STATE;
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
|
||
QTreeWidget_setItemSelected(QTreeWidgetH(Widget), AItem, ASelect);
|
||
if not FSyncingItems then
|
||
begin
|
||
{$IFDEF QT_DEBUGTQTTREEWIDGET}
|
||
DebugLn('TQtTreeWidget.setItemSelected() delivering ASelect ',dbgs(ASelect));
|
||
{$ENDIF}
|
||
DeliverMessage(Msg);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setStretchLastSection(AValue: Boolean);
|
||
begin
|
||
if (csDesigning in LCLObject.ComponentState) then
|
||
QHeaderView_setStretchLastSection(QTreeView_header(QTreeViewH(Widget)),
|
||
AValue)
|
||
else
|
||
Header.setStretchLastSection(AValue);
|
||
end;
|
||
|
||
procedure TQtTreeWidget.scrollToItem(Item: QTreeWidgetItemH;
|
||
hint: QAbstractItemViewScrollHint);
|
||
begin
|
||
QTreeWidget_scrollToItem(QTreeWidgetH(Widget), Item, hint);
|
||
end;
|
||
|
||
{$IFDEF TEST_QT_SORTING}
|
||
procedure TQtTreeWidget.sortItems(Acolumn: Integer; AOrder: QtSortOrder);
|
||
var
|
||
StdModel: QStandardItemModelH;
|
||
begin
|
||
// there's bug with QStandardItemModel persistent index update, we
|
||
// use InternalUpdate in QtWSComCtrls !
|
||
if not FCanSort then
|
||
exit;
|
||
try
|
||
if ItemCount = 0 then
|
||
exit;
|
||
StdModel := QStandardItemModelH(getModel);
|
||
// writeln('Sorting called ...SortRole=',QStandardItemModel_sortRole(StdModel));
|
||
if QStandardItemModel_sortRole(StdModel) <> Ord(QtUserRole) then
|
||
QStandardItemModel_setSortRole(StdModel, Ord(QtUserRole));
|
||
setUpdatesEnabled(False);
|
||
QStandardItemModel_sort(StdModel, AColumn, AOrder);
|
||
setUpdatesEnabled(True);
|
||
finally
|
||
FCanSort := False;
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
procedure TQtTreeWidget.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
FItemActivatedHook := QTreeWidget_hook_create(Widget);
|
||
FItemEnteredHook := QTreeWidget_hook_create(Widget);
|
||
FSelectionChangedHook := QTreeWidget_hook_create(Widget);
|
||
QTreeWidget_hook_hook_ItemActivated(FItemActivatedHook, @SignalItemActivated);
|
||
QTreeWidget_hook_hook_ItemEntered(FItemEnteredHook, @SignalItemEntered);
|
||
QTreeWidget_hook_hook_itemSelectionChanged(FSelectionChangedHook, @SignalSelectionChanged);
|
||
end;
|
||
|
||
procedure TQtTreeWidget.DetachEvents;
|
||
begin
|
||
if FItemActivatedHook <> nil then
|
||
begin
|
||
QTreeWidget_hook_destroy(FItemActivatedHook);
|
||
FItemActivatedHook := nil;
|
||
end;
|
||
|
||
if FItemEnteredHook <> nil then
|
||
begin
|
||
QTreeWidget_hook_destroy(FItemEnteredHook);
|
||
FItemEnteredHook := nil;
|
||
end;
|
||
if FSelectionChangedHook <> nil then
|
||
begin
|
||
QTreeWidget_hook_destroy(FSelectionChangedHook);
|
||
FSelectionChangedHook := nil;
|
||
end;
|
||
|
||
{$IFDEF TEST_QT_SORTING}
|
||
if FSortChanged <> nil then
|
||
begin
|
||
QHeaderView_hook_destroy(FSortChanged);
|
||
FSortChanged := nil;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.ExchangeItems(const AIndex1, AIndex2: Integer);
|
||
var
|
||
ItemFrom: QTreeWidgetItemH;
|
||
ItemTo: QTreeWidgetItemH;
|
||
R: TRect;
|
||
begin
|
||
|
||
if AIndex1 = AIndex2 then
|
||
exit;
|
||
|
||
if AIndex1 < AIndex2 then
|
||
begin
|
||
ItemTo := takeTopLevelItem(AIndex2);
|
||
ItemFrom := takeTopLevelItem(AIndex1);
|
||
insertTopLevelItem(AIndex1, ItemTo);
|
||
insertTopLevelItem(AIndex2, ItemFrom);
|
||
end else
|
||
begin
|
||
ItemFrom := takeTopLevelItem(AIndex1);
|
||
ItemTo := takeTopLevelItem(AIndex2);
|
||
insertTopLevelItem(AIndex2, ItemFrom);
|
||
insertTopLevelItem(AIndex1, ItemTo);
|
||
end;
|
||
|
||
if OwnerDrawn then
|
||
begin
|
||
R := VisualItemRect(ItemFrom);
|
||
Update(@R);
|
||
R := VisualItemRect(ItemTo);
|
||
Update(@R);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.MoveItem(const AFromIndex, AToIndex: Integer);
|
||
var
|
||
Item: QTreeWidgetItemH;
|
||
R: TRect;
|
||
begin
|
||
Item := takeTopLevelItem(AFromIndex);
|
||
insertTopLevelItem(AToIndex, Item);
|
||
if OwnerDrawn then
|
||
begin
|
||
R := VisualItemRect(Item);
|
||
Update(@R);
|
||
end;
|
||
end;
|
||
|
||
function TQtTreeWidget.getClientBounds: TRect;
|
||
begin
|
||
Result := inherited getClientBounds;
|
||
end;
|
||
|
||
function TQtTreeWidget.getClientOffset: TPoint;
|
||
var
|
||
Offset: Integer;
|
||
AOrientation: QtOrientation;
|
||
begin
|
||
Offset := getHeaderHeight(AOrientation);
|
||
if Offset > 0 then
|
||
Result := Point(0, 0)
|
||
else
|
||
Result := inherited getClientOffset;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.setSelectionMode(AMode: QAbstractItemViewSelectionMode);
|
||
var
|
||
SavedItem: QTreeWidgetItemH;
|
||
i: Integer;
|
||
Arr: TPtrIntArray;
|
||
begin
|
||
SavedItem := nil;
|
||
if (ViewStyle > 0) and (AMode < QAbstractItemViewMultiSelection) and
|
||
(getSelectionMode > QAbstractItemViewSingleSelection) then
|
||
begin
|
||
SavedItem := CurrentItem;
|
||
Arr := selectedItems;
|
||
if not ((SavedItem <> nil) and (QTreeWidgetItem_isSelected(SavedItem))) then
|
||
begin
|
||
SavedItem := nil;
|
||
if length(Arr) > 0 then
|
||
SavedItem := QTreeWidgetItemH(Arr[0]);
|
||
end;
|
||
for i := 0 to High(Arr) do
|
||
begin
|
||
if QTreeWidgetItemH(Arr[i]) <> SavedItem then
|
||
begin
|
||
QTreeWidgetItem_setSelected(QTreeWidgetItemH(Arr[i]), False);
|
||
signalCurrentItemChanged(nil, QTreeWidgetItemH(Arr[i]));
|
||
end;
|
||
end;
|
||
clearSelection;
|
||
end;
|
||
inherited setSelectionMode(AMode);
|
||
if SavedItem <> nil then
|
||
setItemSelected(SavedItem, True);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTreeWidget.SignalItemActivated
|
||
Params: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtTreeWidget.SignalItemActivated(item: QTreeWidgetItemH;
|
||
column: Integer); cdecl;
|
||
var
|
||
Msg: TLMNotify;
|
||
NMLV: TNMListView;
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
|
||
|
||
Msg.Msg := CN_NOTIFY;
|
||
|
||
NMLV.hdr.hwndfrom := LCLObject.Handle;
|
||
NMLV.hdr.code := LVN_ITEMCHANGED;
|
||
|
||
NMLV.iItem := getRow(Item);
|
||
|
||
NMLV.iSubItem := Column;
|
||
NMLV.uOldState := 0;
|
||
NMLV.uNewState := LVIS_FOCUSED;
|
||
NMLV.uChanged := LVIF_STATE;
|
||
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
DeliverMessage( Msg);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTreeWidget.SignalItemEntered
|
||
Params: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtTreeWidget.SignalItemEntered(item: QTreeWidgetItemH;
|
||
column: Integer); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_ENTER;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtTreeWidget.SignalCurrentItemChanged
|
||
Params: Integer
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtTreeWidget.SignalCurrentItemChanged(current: QTreeWidgetItemH;
|
||
previous: QTreeWidgetItemH); cdecl;
|
||
var
|
||
Msg: TLMNotify;
|
||
NMLV: TNMListView;
|
||
AParent: QTreeWidgetItemH;
|
||
ASubIndex: Integer;
|
||
AIndex: Integer;
|
||
ListItem: TListItem;
|
||
B: Boolean;
|
||
Item: QTreeWidgetItemH;
|
||
begin
|
||
if Current = nil then
|
||
Item := Previous
|
||
else
|
||
Item := Current;
|
||
{$IFDEF QT_DEBUGTQTTREEWIDGET}
|
||
writeln('SignalCurrentItemChangedNG CUR=',dbgHex(PtrUInt(Current)),
|
||
' PREV=',dbgHex(PtrUInt(Previous)),
|
||
' InUpdate ',InUpdate,' Curr=PREVIOUS ? ',Current = Previous);
|
||
{$ENDIF}
|
||
|
||
if (Item <> nil) and (Current = Previous) then
|
||
exit;
|
||
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
FillChar(NMLV{%H-}, SizeOf(NMLV), #0);
|
||
|
||
Msg.Msg := CN_NOTIFY;
|
||
|
||
NMLV.hdr.hwndfrom := LCLObject.Handle;
|
||
NMLV.hdr.code := LVN_ITEMCHANGING;
|
||
|
||
AIndex := getRow(Item);
|
||
AParent := nil;
|
||
if Item <> nil then
|
||
AParent := QTreeWidgetItem_parent(Item);
|
||
|
||
if AParent <> nil then
|
||
ASubIndex := QTreeWidgetItem_indexOfChild(AParent, Item)
|
||
else
|
||
ASubIndex := 0;
|
||
|
||
NMLV.iItem := AIndex;
|
||
NMLV.iSubItem := ASubIndex;
|
||
if (Item <> nil) and (Item = Previous) then
|
||
NMLV.uOldState := LVIS_SELECTED
|
||
else
|
||
NMLV.uNewState := LVIS_SELECTED;
|
||
NMLV.uChanged := LVIF_STATE;
|
||
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
DeliverMessage(Msg);
|
||
|
||
FSyncingItems := True;
|
||
try
|
||
if Current <> nil then
|
||
begin
|
||
ListItem := nil;
|
||
B := False;
|
||
if (ViewStyle = Ord(vsReport)) and (Previous <> nil) then
|
||
begin
|
||
ListItem := TCustomListViewHack(LCLObject).Selected;
|
||
if ListItem <> nil then
|
||
B := ListItem.Index = AIndex;
|
||
end;
|
||
FillChar(Msg, SizeOf(Msg), #0);
|
||
FillChar(NMLV, SizeOf(NMLV), #0);
|
||
Msg.Msg := CN_NOTIFY;
|
||
NMLV.hdr.hwndfrom := LCLObject.Handle;
|
||
NMLV.hdr.code := LVN_ITEMCHANGED;
|
||
NMLV.iItem := AIndex;
|
||
NMLV.iSubItem := ASubIndex;
|
||
if (FSelection.Count > 0) and (FSelection.IndexOf(Current) <> -1) then
|
||
NMLV.uNewState := LVIS_SELECTED
|
||
else
|
||
NMLV.uOldState := LVIS_SELECTED;
|
||
NMLV.uChanged := LVIF_STATE;
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
if not B then
|
||
DeliverMessage(Msg);
|
||
|
||
|
||
// send focused msg
|
||
NMLV.uNewState := 0;
|
||
NMLV.uOldState := 0;
|
||
NMLV.iSubItem := -1;
|
||
if (FSelection.Count > 0) and (FSelection.IndexOf(Current) <> -1) then
|
||
NMLV.uNewState := LVIS_FOCUSED
|
||
else
|
||
NMLV.uOldState := LVIS_FOCUSED;
|
||
NMLV.uChanged := LVIF_STATE;
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
if not B then
|
||
DeliverMessage(Msg);
|
||
|
||
end;
|
||
|
||
if (Previous <> nil) then
|
||
begin
|
||
AIndex := getRow(Previous);
|
||
ListItem := nil;
|
||
B := False;
|
||
// From Qt docs:
|
||
// This signal is emitted when the current item changes.
|
||
// The current item is specified by current, and this replaces
|
||
// the previous current item.
|
||
// So, if Current = nil, do not ask TListView anything ! issue #18701
|
||
if (ViewStyle = Ord(vsReport)) and (Current <> nil) and
|
||
(Current <> Previous) then
|
||
begin
|
||
ListItem := TCustomListViewHack(LCLObject).Selected;
|
||
if ListItem <> nil then
|
||
B := ListItem.Index = AIndex;
|
||
end;
|
||
|
||
FillChar(Msg, SizeOf(Msg), #0);
|
||
FillChar(NMLV, SizeOf(NMLV), #0);
|
||
Msg.Msg := CN_NOTIFY;
|
||
NMLV.hdr.hwndfrom := LCLObject.Handle;
|
||
NMLV.hdr.code := LVN_ITEMCHANGED;
|
||
NMLV.iItem := AIndex;
|
||
AParent := QTreeWidgetItem_parent(Previous);
|
||
if AParent <> nil then
|
||
ASubIndex := QTreeWidgetItem_indexOfChild(AParent, Previous)
|
||
else
|
||
ASubIndex := 0;
|
||
NMLV.iSubItem := ASubIndex;
|
||
|
||
if QTreeWidget_isItemSelected(QTreeWidgetH(Widget), Previous) then
|
||
NMLV.uNewState := LVIS_SELECTED
|
||
else
|
||
NMLV.uOldState := LVIS_SELECTED;
|
||
|
||
NMLV.uChanged := LVIF_STATE;
|
||
Msg.NMHdr := @NMLV.hdr;
|
||
if not B then
|
||
DeliverMessage(Msg);
|
||
end;
|
||
finally
|
||
FSyncingItems := False;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtTreeWidget.SignalSelectionChanged(); cdecl;
|
||
var
|
||
Arr: TPtrIntArray;
|
||
ItemsList: TFPList;
|
||
i: Integer;
|
||
j: Integer;
|
||
|
||
procedure RemoveUnselectedItems;
|
||
var
|
||
x: Integer;
|
||
Index: Integer;
|
||
AnItem: QTreeWidgetItemH;
|
||
begin
|
||
// we are removing only items which are not in selection, to avoid
|
||
// duplicated triggering of TListView.OnSelectItem
|
||
for x := ItemsList.Count - 1 downto 0 do
|
||
begin
|
||
Index := FSelection.IndexOf(ItemsList.Items[x]);
|
||
if Index = -1 then
|
||
begin
|
||
AnItem := QTreeWidgetItemH(ItemsList.Items[x]);
|
||
SignalCurrentItemChanged(nil, AnItem);
|
||
ItemsList.Remove(AnItem);
|
||
end;
|
||
end;
|
||
ItemsList.Clear;
|
||
end;
|
||
begin
|
||
ItemsList := TFPList.Create;
|
||
try
|
||
if FSelection.Count > 0 then
|
||
ItemsList.Assign(FSelection);
|
||
FSelection.Clear;
|
||
Arr := selectedItems;
|
||
|
||
{$IFDEF QT_DEBUGTQTTREEWIDGET}
|
||
writeln('TQtTreeWidget.SignalSelectionChanged NewSel count ',length(Arr),
|
||
' InUpdate ',InUpdate,
|
||
' OldSel count ',ItemsList.Count);
|
||
{$ENDIF}
|
||
|
||
for i := 0 to High(Arr) do
|
||
FSelection.Add(QTreeWidgetItemH(Arr[i]));
|
||
|
||
if not InUpdate then
|
||
begin
|
||
if FSelection.Count = 0 then
|
||
RemoveUnSelectedItems
|
||
else
|
||
if (getSelectionMode in [QAbstractItemViewMultiSelection,
|
||
QAbstractItemViewExtendedSelection]) and
|
||
(ItemsList.Count >= 1) then // and (FSelection.Count <> ItemsList.Count) then
|
||
begin
|
||
RemoveUnSelectedItems;
|
||
for i := 0 to FSelection.Count - 1 do
|
||
SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]), nil);
|
||
end else
|
||
for i := 0 to FSelection.Count - 1 do
|
||
begin
|
||
if ItemsList.Count > 0 then
|
||
begin
|
||
for j := 0 to ItemsList.Count - 1 do
|
||
SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]),
|
||
QTreeWidgetItemH(ItemsList.Items[j]));
|
||
end else
|
||
SignalCurrentItemChanged(QTreeWidgetItemH(FSelection.Items[i]), nil);
|
||
end;
|
||
end;
|
||
finally
|
||
ItemsList.Free;
|
||
end;
|
||
end;
|
||
|
||
{$IFDEF TEST_QT_SORTING}
|
||
procedure TQtTreeWidget.SignalSortIndicatorChanged(ALogicalIndex: Integer;
|
||
AOrder: QtSortOrder); cdecl;
|
||
begin
|
||
if FSorting or not Assigned(LCLObject) or not
|
||
QHeaderView_isSortIndicatorShown(QHeaderViewH(Header.Widget)) then
|
||
exit;
|
||
if not FCanSort then
|
||
exit;
|
||
FSorting := True;
|
||
try
|
||
if ALogicalIndex >= 0 then
|
||
sortItems(ALogicalIndex, AOrder);
|
||
finally
|
||
FSorting := False;
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
{TQtTableView}
|
||
|
||
function TQtTableView.CreateWidget(const Params: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtTableView.CreateWidget');
|
||
{$endif}
|
||
HasPaint := False;
|
||
if Params.WndParent <> 0 then
|
||
Parent := TQtWidget(Params.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QTableView_create(Parent);
|
||
end;
|
||
|
||
function TQtTableView.verticalHeader: TQtHeaderView;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtTableView.verticalHeader');
|
||
{$endif}
|
||
if FVerticalHeader = nil then
|
||
FVerticalHeader := TQtHeaderView.CreateFrom(LCLObject, QTableView_verticalHeader(QTableViewH(Widget)));
|
||
Result := FVerticalHeader;
|
||
end;
|
||
|
||
function TQtTableView.horizontalHeader: TQtHeaderView;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtTableView.horizontalHeader');
|
||
{$endif}
|
||
if FHorizontalHeader = nil then
|
||
FHorizontalHeader := TQtHeaderView.CreateFrom(LCLObject, QTableView_horizontalHeader(QTableViewH(Widget)));
|
||
Result := FHorizontalHeader;
|
||
end;
|
||
|
||
procedure TQtTableView.setVisible(AVisible: Boolean);
|
||
begin
|
||
QWidget_setVisible(Widget, AVisible);
|
||
end;
|
||
|
||
function TQtTableView.getGridStyle: QtPenStyle;
|
||
begin
|
||
Result := QTableView_gridStyle(QTableViewH(Widget));
|
||
end;
|
||
|
||
procedure TQtTableView.setGridStyle(ANewStyle: QtPenStyle);
|
||
begin
|
||
QTableView_setGridStyle(QTableViewH(Widget), ANewStyle);
|
||
end;
|
||
|
||
destructor TQtTableView.Destroy;
|
||
begin
|
||
if FVerticalHeader <> nil then
|
||
FVerticalHeader.Free;
|
||
if FHorizontalHeader <> nil then
|
||
FHorizontalHeader.Free;
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function TQtTableView.getViewPort: QWidgetH;
|
||
begin
|
||
Result := viewportWidget;
|
||
end;
|
||
|
||
function TQtTableView.getClientBounds: TRect;
|
||
begin
|
||
QWidget_contentsRect(Widget, @Result);
|
||
end;
|
||
|
||
procedure TQtTableView.grabMouse;
|
||
begin
|
||
QWidget_grabMouse(Widget);
|
||
end;
|
||
|
||
{ TQtMenu }
|
||
|
||
function TQtMenu.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
AGroup: TQtActionGroup;
|
||
Parent: QWidgetH;
|
||
begin
|
||
FTrackButton := QtNoButton;
|
||
FLastTick := 0;
|
||
FIcon := nil;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QMenu_create(Parent);
|
||
FDeleteLater := True;
|
||
FActionHandle := nil;
|
||
FActions := TFPList.Create;
|
||
AGroup := TQtActionGroup.Create(Result);
|
||
if FMenuItem <> nil then
|
||
AGroup.GroupIndex := FMenuItem.GroupIndex
|
||
else
|
||
AGroup.GroupIndex := -1;
|
||
AGroup.Exclusive := False;
|
||
FActions.Add(AGroup);
|
||
end;
|
||
|
||
procedure TQtMenu.InitializeWidget;
|
||
begin
|
||
FWidgetState := [];
|
||
ChildOfComplexWidget := ccwNone;
|
||
WidgetColorRole := QPaletteWindow;
|
||
TextColorRole := QPaletteText;
|
||
Widget := CreateWidget(FParams);
|
||
setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
|
||
QtWidgetSet.AddHandle(Self);
|
||
FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
|
||
FWidgetLCLFont := nil;
|
||
end;
|
||
|
||
constructor TQtMenu.Create(const AMenuItem: TMenuItem);
|
||
var
|
||
AParams: TCreateParams;
|
||
begin
|
||
FillChar(AParams{%H-}, SizeOf(AParams), #0);
|
||
FMenuItem := AMenuItem;
|
||
inherited Create(nil, AParams);
|
||
end;
|
||
|
||
destructor TQtMenu.Destroy;
|
||
var
|
||
i: integer;
|
||
begin
|
||
if FIcon <> nil then
|
||
QIcon_destroy(FIcon);
|
||
|
||
if Assigned(FActions) then
|
||
begin
|
||
for i := 0 to FActions.Count - 1 do
|
||
TQtActionGroup(FActions.Items[i]).Free;
|
||
|
||
FActions.Free;
|
||
end;
|
||
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TQtMenu.AttachEvents;
|
||
begin
|
||
FTriggeredHook := QAction_hook_create(ActionHandle);
|
||
FHoveredHook := QAction_hook_create(ActionHandle);
|
||
FAboutToShowHook := QMenu_hook_create(Widget);
|
||
FAboutToHideHook := QMenu_hook_create(Widget);
|
||
FEventHook := QObject_hook_create(Widget);
|
||
|
||
QAction_hook_hook_triggered(FTriggeredHook, @SlotTriggered);
|
||
|
||
QAction_hook_hook_hovered(FHoveredHook, @SlotHovered);
|
||
|
||
QMenu_hook_hook_aboutToShow(FAboutToShowHook, @SlotAboutToShow);
|
||
|
||
QMenu_hook_hook_aboutToHide(FAboutToHideHook, @SlotAboutToHide);
|
||
|
||
QObject_hook_hook_events(FEventHook, @EventFilter);
|
||
end;
|
||
|
||
procedure TQtMenu.DetachEvents;
|
||
begin
|
||
if FActionEventFilter <> nil then
|
||
begin
|
||
QObject_hook_destroy(FActionEventFilter);
|
||
FActionEventFilter := nil;
|
||
end;
|
||
|
||
if FTriggeredHook <> nil then
|
||
begin
|
||
QAction_hook_destroy(FTriggeredHook);
|
||
FTriggeredHook := nil;
|
||
end;
|
||
|
||
if FHoveredHook <> nil then
|
||
begin
|
||
QAction_hook_destroy(FHoveredHook);
|
||
FHoveredHook := nil;
|
||
end;
|
||
|
||
if FAboutToShowHook <> nil then
|
||
begin
|
||
QMenu_hook_destroy(FAboutToShowHook);
|
||
FAboutToShowHook := nil;
|
||
end;
|
||
|
||
if FAboutToHideHook <> nil then
|
||
begin
|
||
QMenu_hook_destroy(FAboutToHideHook);
|
||
FAboutToHideHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
procedure TQtMenu.SlotHovered; cdecl;
|
||
begin
|
||
FMenuItem.IntfDoSelect;
|
||
end;
|
||
|
||
procedure TQtMenu.SlotAboutToShow; cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
//issues #22872 (flickering), #24979 (actions)
|
||
if Assigned(FMenuItem) and
|
||
not (FMenuItem.Menu is TPopupMenu) then
|
||
begin
|
||
// DebugLn('TQtMenu.SlotAboutToShow ',dbgsName(FMenuItem));
|
||
if GetTickCount64 - FLastTick > 10 then
|
||
begin
|
||
FLastTick := GetTickCount64;
|
||
FillChar(Msg{%H-}, SizeOf(Msg), 0);
|
||
Msg.msg := LM_ACTIVATE;
|
||
if Assigned(FMenuItem) then
|
||
FMenuItem.Dispatch(Msg);
|
||
FLastTick := GetTickCount64;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtMenu.SlotAboutToHide; cdecl;
|
||
var
|
||
Event: QLCLMessageEventH;
|
||
begin
|
||
if FMenuItem.Menu is TPopupMenu then
|
||
begin
|
||
Event := QLCLMessageEvent_create(LCLQt_PopupMenuClose);
|
||
QCoreApplication_postEvent(Widget, Event);
|
||
end;
|
||
// DebugLn('TQtMenu.SlotAboutToHide ',dbgsName(FMenuItem));
|
||
FLastTick := GetTickCount64; // issue #22872, #24979
|
||
end;
|
||
|
||
procedure TQtMenu.DoPopupClose;
|
||
begin
|
||
if FMenuItem.Menu is TPopupMenu then
|
||
TPopupMenu(FMenuItem.Menu).Close;
|
||
end;
|
||
|
||
procedure TQtMenu.SlotDestroy; cdecl;
|
||
begin
|
||
Widget := nil;
|
||
end;
|
||
|
||
procedure TQtMenu.PopUp(pos: PQtPoint; at: QActionH);
|
||
begin
|
||
QMenu_popup(QMenuH(Widget), pos, at);
|
||
end;
|
||
|
||
procedure TQtMenu.Exec(pos: PQtPoint; at: QActionH);
|
||
begin
|
||
QMenu_exec(QMenuH(Widget), pos, at);
|
||
end;
|
||
|
||
function TQtMenu.actionHandle: QActionH;
|
||
begin
|
||
if FActionHandle = nil then
|
||
begin
|
||
if FActionEventFilter <> nil then
|
||
begin
|
||
QObject_hook_destroy(FActionEventFilter);
|
||
FActionEventFilter := nil;
|
||
end;
|
||
FActionHandle := QMenu_menuAction(QMenuH(Widget));
|
||
FActionEventFilter := QObject_hook_create(FActionHandle);
|
||
QObject_hook_hook_events(FActionEventFilter, @ActionEventFilter);
|
||
end;
|
||
Result := FActionHandle;
|
||
end;
|
||
|
||
function TQtMenu.addMenu(AMenu: QMenuH): QActionH;
|
||
begin
|
||
setHasSubmenu(True);
|
||
Result := QMenu_addMenu(QMenuH(Widget), AMenu);
|
||
end;
|
||
|
||
procedure TQtMenu.removeActionGroup;
|
||
var
|
||
Action: QActionGroupH;
|
||
begin
|
||
Action := QAction_actionGroup(ActionHandle);
|
||
if Action <> nil then
|
||
QActionGroup_removeAction(Action, ActionHandle);
|
||
end;
|
||
|
||
procedure TQtMenu.setActionGroups(AItem: TMenuItem);
|
||
var
|
||
i: integer;
|
||
b: Boolean = True;
|
||
Group: TQtActionGroup;
|
||
begin
|
||
for i := 0 to FActions.Count - 1 do
|
||
begin
|
||
Group := TQtActionGroup(FActions.Items[i]);
|
||
if Group.GroupIndex = AItem.GroupIndex then
|
||
begin
|
||
QAction_setEnabled(TQtMenu(AItem.Handle).actionHandle, AItem.Enabled);
|
||
QAction_setVisible(TQtMenu(AItem.Handle).actionHandle, AItem.Visible);
|
||
Group.addAction(TQtMenu(AItem.Handle).actionHandle);
|
||
Group.Exclusive := AItem.RadioItem;
|
||
Group.Visible := True;
|
||
Group.Enabled := True;
|
||
b := False;
|
||
break;
|
||
end;
|
||
end;
|
||
if b then
|
||
begin
|
||
Group := TQtActionGroup.Create(Widget);
|
||
Group.Exclusive := AItem.RadioItem;
|
||
Group.GroupIndex := AItem.GroupIndex;
|
||
QAction_setEnabled(TQtMenu(AItem.Handle).actionHandle, AItem.Enabled);
|
||
QAction_setVisible(TQtMenu(AItem.Handle).actionHandle, AItem.Visible);
|
||
Group.addAction(TQtMenu(AItem.Handle).actionHandle);
|
||
Group.Visible := True;
|
||
Group.Enabled := True;
|
||
FActions.Add(Group);
|
||
end;
|
||
end;
|
||
|
||
function TQtMenu.insertMenu(AIndex: Integer; AMenu: QMenuH; AItem: TMenuItem): QActionH;
|
||
var
|
||
actionBefore: QActionH;
|
||
begin
|
||
|
||
setHasSubmenu(True);
|
||
|
||
if (AItem <> nil) and not AItem.IsLine then
|
||
setActionGroups(AItem);
|
||
|
||
actionBefore := getActionByIndex(AIndex);
|
||
|
||
if actionBefore <> nil then
|
||
Result := QMenu_insertMenu(QMenuH(Widget), actionBefore, AMenu)
|
||
else
|
||
Result := QMenu_addMenu(QMenuH(Widget), AMenu);
|
||
end;
|
||
|
||
function TQtMenu.getHasSubMenu: boolean;
|
||
begin
|
||
Result := QAction_menu(ActionHandle) <> nil;
|
||
end;
|
||
|
||
function TQtMenu.getVisible: Boolean;
|
||
begin
|
||
if ActionHandle = nil then
|
||
exit(False);
|
||
Result := QAction_isVisible(ActionHandle);
|
||
end;
|
||
|
||
function TQtMenu.getText: WideString;
|
||
begin
|
||
QAction_text(ActionHandle, @Result);
|
||
end;
|
||
|
||
procedure TQtMenu.setText(const W: WideString);
|
||
begin
|
||
QAction_setText(ActionHandle, @W);
|
||
end;
|
||
|
||
procedure TQtMenu.setVisible(AVisible: Boolean);
|
||
begin
|
||
QAction_setVisible(ActionHandle, AVisible);
|
||
end;
|
||
|
||
procedure TQtMenu.setChecked(p1: Boolean);
|
||
begin
|
||
setCheckable(p1);
|
||
QAction_setChecked(ActionHandle, p1);
|
||
end;
|
||
|
||
procedure TQtMenu.setCheckable(p1: Boolean);
|
||
begin
|
||
if FMenuItem.RadioItem or FMenuItem.ShowAlwaysCheckable then
|
||
QAction_setCheckable(ActionHandle, True)
|
||
else
|
||
QAction_setCheckable(ActionHandle, p1);
|
||
end;
|
||
|
||
procedure TQtMenu.setHasSubmenu(AValue: Boolean);
|
||
begin
|
||
if AValue then
|
||
QAction_setMenu(ActionHandle, QMenuH(Widget))
|
||
else
|
||
QAction_setMenu(ActionHandle, nil);
|
||
end;
|
||
|
||
procedure TQtMenu.setIcon(AIcon: QIconH);
|
||
begin
|
||
QMenu_setIcon(QMenuH(Widget), AIcon);
|
||
end;
|
||
|
||
procedure TQtMenu.setImage(AImage: TQtImage);
|
||
begin
|
||
if FIcon <> nil then
|
||
begin
|
||
QIcon_destroy(FIcon);
|
||
FIcon := nil;
|
||
end;
|
||
|
||
if AImage <> nil then
|
||
FIcon := AImage.AsIcon()
|
||
else
|
||
FIcon := QIcon_create();
|
||
|
||
setIcon(FIcon);
|
||
end;
|
||
|
||
procedure TQtMenu.setSeparator(AValue: Boolean);
|
||
begin
|
||
QAction_setSeparator(ActionHandle, AValue);
|
||
end;
|
||
|
||
procedure TQtMenu.setShortcut(AShortCutK1, AShortCutK2: TShortcut);
|
||
var
|
||
Key: Word;
|
||
Shift: TShiftState;
|
||
QtK1, QtK2: integer;
|
||
KeySequence: QKeySequenceH;
|
||
begin
|
||
QtK1 := 0;
|
||
QtK2 := 0;
|
||
if AShortCutK1 <> 0 then
|
||
begin
|
||
ShortCutToKey(AShortCutK1, Key, Shift);
|
||
QtK1 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
|
||
if AShortCutK2 <> 0 then
|
||
begin
|
||
ShortCutToKey(AShortCutK2, Key, Shift);
|
||
QtK2 := LCLKeyToQtKey(Key) or ShiftStateToQtModifiers(Shift);
|
||
end;
|
||
end;
|
||
// there is no need in destroying QKeySequnce
|
||
KeySequence := QKeySequence_create(QtK1, QtK2);
|
||
QAction_setShortcut(ActionHandle, KeySequence);
|
||
QKeySequence_destroy(KeySequence);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Method: TQtMenu.SlotTriggered
|
||
|
||
Callback for menu item click
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtMenu.SlotTriggered(checked: Boolean); cdecl;
|
||
var
|
||
Event: QLCLMessageEventH;
|
||
begin
|
||
Event := QLCLMessageEvent_create(LCLQt_PopupMenuTriggered);
|
||
QCoreApplication_postEvent(Widget, Event, 1 {high priority});
|
||
end;
|
||
|
||
function TQtMenu.ActionEventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
var
|
||
TempAction: QActionH;
|
||
Group: QActionGroupH;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if Assigned(FMenuItem) and (QEvent_type(Event) = QEventActionChanged) then
|
||
begin
|
||
{qt shouldn't change checkables in any case, LCL should do that !}
|
||
TempAction := QActionEvent_action(QActionEventH(Event));
|
||
if (TempAction <> nil) and
|
||
QAction_isCheckable(TempAction) and
|
||
(QAction_isChecked(TempAction) <> FMenuItem.Checked) then
|
||
begin
|
||
Group := QAction_actionGroup(TempAction);
|
||
if Group <> nil then
|
||
begin
|
||
if QActionGroup_isExclusive(Group) then
|
||
QObject_blockSignals(Group, True)
|
||
else
|
||
QObject_blockSignals(TempAction, True);
|
||
end else
|
||
QObject_blockSignals(TempAction, True);
|
||
|
||
QAction_setChecked(TempAction, FMenuItem.Checked);
|
||
|
||
if QObject_signalsBlocked(TempAction) then
|
||
begin
|
||
QObject_blockSignals(TempAction, False);
|
||
Result := True;
|
||
QEvent_ignore(Event);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TQtMenu.MenuItemEnabled: boolean;
|
||
var
|
||
AParentMenu: TMenuItem;
|
||
begin
|
||
if not Assigned(FMenuItem) then
|
||
begin
|
||
Result := getEnabled;
|
||
exit;
|
||
end;
|
||
|
||
Result := FMenuItem.Enabled;
|
||
AParentMenu := FMenuItem.Parent;
|
||
while AParentMenu <> nil do
|
||
begin
|
||
Result := AParentMenu.Enabled;
|
||
if not Result then
|
||
break;
|
||
AParentMenu := AParentMenu.Parent;
|
||
end;
|
||
end;
|
||
|
||
function TQtMenu.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
TempAction: QActionH;
|
||
APos: TQtPoint;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
|
||
case QEvent_type(Event) of
|
||
LCLQt_PopupMenuTriggered:
|
||
begin
|
||
{$IFDEF HASX11}
|
||
// make interface snappy after menuitem triggers
|
||
if Assigned(Application) and not Application.Terminated then
|
||
begin
|
||
if QApplication_activePopupWidget = nil then
|
||
begin
|
||
if QApplication_activeModalWidget <> nil then
|
||
QWidget_repaint(QApplication_activeModalWidget)
|
||
else
|
||
if QApplication_activeWindow <> nil then
|
||
QWidget_repaint(QApplication_activeWindow);
|
||
QCoreApplication_processEvents(QEventLoopAllEvents);
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
FillChar(Msg{%H-}, SizeOf(Msg), 0);
|
||
Msg.msg := LM_ACTIVATE;
|
||
if MenuItemEnabled then
|
||
FMenuItem.Dispatch(Msg);
|
||
Result := True;
|
||
end;
|
||
LCLQt_PopupMenuClose:
|
||
begin
|
||
DoPopupClose;
|
||
Result := True;
|
||
end;
|
||
QEventDestroy: SlotDestroy;
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonRelease:
|
||
begin
|
||
Result := (FTrackButton = QtLeftButton) and
|
||
(QMouseEvent_button(QMouseEventH(Event)) <> FTrackButton);
|
||
if Assigned(FMenuItem) and not (FMenuItem.Menu is TPopupMenu) then
|
||
begin
|
||
QMouseEvent_pos(QMouseEventH(Event), @APos);
|
||
TempAction := QMenu_actionAt(QMenuH(Widget),
|
||
@APos);
|
||
{trigger LCL if root of menu have OnClick() connected,
|
||
since qt won't do that for us.}
|
||
if (QMouseEvent_button(QMouseEventH(Event)) = QtLeftButton) and
|
||
Assigned(FMenuItem.OnClick) and
|
||
(TempAction = nil) and not (FMenuItem.IsInMenuBar) then
|
||
SlotTriggered();
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{ TQtMenuBar }
|
||
|
||
constructor TQtMenuBar.Create(const AParent: QWidgetH);
|
||
begin
|
||
Create;
|
||
Widget := QMenuBar_create(AParent);
|
||
{$IFNDEF DARWIN}
|
||
FCatchNextResizeEvent := False;
|
||
FNumOfActions := 0;
|
||
{$ENDIF}
|
||
FOwnWidget := AParent = nil;
|
||
FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget));
|
||
FWidgetLCLFont := nil;
|
||
FHeight := getHeight;
|
||
FVisible := False;
|
||
FIsApplicationMainMenu := False;
|
||
Palette.ForceColor := True;
|
||
setDefaultColor(dctFont);
|
||
Palette.ForceColor := False;
|
||
setVisible(FVisible);
|
||
QtWidgetSet.AddHandle(Self);
|
||
InitializeAccessibility;
|
||
end;
|
||
|
||
{$IFNDEF DARWIN}
|
||
function TQtMenuBar.IsDesigning: Boolean;
|
||
var
|
||
V: QVariantH;
|
||
B: Boolean;
|
||
begin
|
||
Result := (Widget <> nil);
|
||
if not Result then
|
||
exit(False);
|
||
|
||
Result := False;
|
||
v := QVariant_create();
|
||
try
|
||
B := False;
|
||
QObject_property(Widget, v, 'lcldesignmenubar');
|
||
if QVariant_isValid(v) and not QVariant_isNull(v) then
|
||
Result := QVariant_toInt(V, @B) = 1;
|
||
finally
|
||
QVariant_destroy(v);
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
function TQtMenuBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
{$IFNDEF DARWIN}
|
||
procedure UpdateDesignerClientRect;
|
||
var
|
||
WParent: QWidgetH;
|
||
Window: HWND;
|
||
ACtl: TWinControl;
|
||
begin
|
||
WParent := getParent;
|
||
if (WParent <> nil) then
|
||
begin
|
||
Window := HwndFromWidgetH(WParent);
|
||
if (Window <> 0) and (TQtWidget(Window) is TQtDesignWidget) and
|
||
(TQtWidget(Window).getVisible) then
|
||
begin
|
||
ACtl := TQtMainWindow(Window).LCLObject;
|
||
if Assigned(ACtl) and not (csDestroying in ACtl.ComponentState) then
|
||
begin
|
||
{$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('TQtMenuBar.EventFilter: before DoAdjustClientRecChange=',
|
||
dbgs(ACtl.ClientRect));
|
||
{$ENDIF}
|
||
ACtl.DoAdjustClientRectChange(True);
|
||
{$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('TQtMenuBar.EventFilter: after DoAdjustClientRecChange=',
|
||
dbgs(ACtl.ClientRect));
|
||
{$ENDIF}
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if (QEvent_type(Event) = QEventFontChange) then
|
||
AssignQtFont(FWidgetDefaultFont.FHandle, QWidget_font(QWidgetH(Sender)));
|
||
|
||
{$IFNDEF DARWIN}
|
||
if (QEvent_type(Event) = QEventResize) then
|
||
begin
|
||
// adjusts client rect of designer form.
|
||
if FCatchNextResizeEvent then
|
||
begin
|
||
FCatchNextResizeEvent := False;
|
||
if IsDesigning then
|
||
UpdateDesignerClientRect;
|
||
end;
|
||
end else
|
||
if (QEvent_type(Event) = QEventActionAdded) then
|
||
begin
|
||
if IsDesigning then
|
||
begin
|
||
inc(FNumOfActions);
|
||
FCatchNextResizeEvent := FNumOfActions = 1;
|
||
{$IFDEF VerboseQtEvents}
|
||
DebugLn(Format('TQtMenuBar: Added new action now have %d actions ',
|
||
[FNumOfActions]));
|
||
{$ENDIF}
|
||
end;
|
||
end else
|
||
if (QEvent_type(Event) = QEventActionRemoved) then
|
||
begin
|
||
if IsDesigning then
|
||
begin
|
||
dec(FNumOfActions);
|
||
{$IFDEF VerboseQtEvents}
|
||
DebugLn(Format('TQtMenuBar: Removed action still have %d actions ',
|
||
[FNumOfActions]));
|
||
{$ENDIF}
|
||
FCatchNextResizeEvent := FNumOfActions = 0;
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
function TQtMenuBar.addMenu(AMenu: QMenuH): QActionH;
|
||
begin
|
||
if not FVisible then
|
||
begin
|
||
FVisible := True;
|
||
setVisible(FVisible);
|
||
end;
|
||
Result := QMenuBar_addMenu(QMenuBarH(Widget), AMenu);
|
||
end;
|
||
|
||
function TQtMenuBar.insertMenu(AIndex: Integer; AMenu: QMenuH): QActionH;
|
||
var
|
||
actionBefore: QActionH;
|
||
Actions: TPtrIntArray;
|
||
Action: QActionH;
|
||
i: Integer;
|
||
seq: QKeySequenceH;
|
||
WStr: WideString;
|
||
begin
|
||
if not FVisible then
|
||
begin
|
||
FVisible := True;
|
||
setVisible(FVisible);
|
||
end;
|
||
actionBefore := getActionByIndex(AIndex);
|
||
if actionBefore <> nil then
|
||
Result := QMenuBar_insertMenu(QMenuBarH(Widget), actionBefore, AMenu)
|
||
else
|
||
Result := QMenuBar_addMenu(QMenuBarH(Widget), AMenu);
|
||
if FIsApplicationMainMenu then
|
||
begin
|
||
QWidget_actions(Widget, @Actions);
|
||
QtWidgetSet.ClearGlobalActions;
|
||
for i := 0 to High(Actions) do
|
||
begin
|
||
Action := QActionH(Actions[i]);
|
||
seq := QKeySequence_create();
|
||
try
|
||
if QKeySequence_isEmpty(seq) then
|
||
begin
|
||
QAction_shortcut(Action, seq);
|
||
WStr := '';
|
||
QAction_text(Action, @WStr);
|
||
QKeySequence_destroy(seq);
|
||
seq := nil;
|
||
seq := QKeySequence_create();
|
||
QKeySequence_mnemonic(seq, @WStr);
|
||
if not QKeySequence_isEmpty(seq) then
|
||
begin
|
||
QAction_setShortcutContext(Action, QtApplicationShortcut);
|
||
QtWidgetSet.AddGlobalAction(Action);
|
||
end;
|
||
end;
|
||
finally
|
||
QKeySequence_destroy(seq);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TQtMenuBar.getGeometry: TRect;
|
||
begin
|
||
Result := inherited getGeometry;
|
||
|
||
// workaround since after attaching menu it takes 0 height
|
||
if Result.Bottom = 0 then
|
||
Result.Bottom := FHeight;
|
||
end;
|
||
|
||
{ TQtProgressBar }
|
||
|
||
function TQtProgressBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQProgressBar.Create');
|
||
{$endif}
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QProgressBar_create(Parent);
|
||
end;
|
||
|
||
procedure TQtProgressBar.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
FValueChangedHook := QProgressBar_hook_create(Widget);
|
||
QProgressBar_hook_hook_valueChanged(FValueChangedHook, @SignalValueChanged);
|
||
end;
|
||
|
||
procedure TQtProgressBar.DetachEvents;
|
||
begin
|
||
if FValueChangedHook <> nil then
|
||
begin
|
||
QProgressBar_hook_destroy(FValueChangedHook);
|
||
FValueChangedHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
procedure TQtProgressBar.setRange(minimum: Integer; maximum: Integer);
|
||
begin
|
||
QProgressBar_setRange(QProgressBarH(Widget), minimum, maximum);
|
||
end;
|
||
|
||
procedure TQtProgressBar.setTextVisible(visible: Boolean);
|
||
begin
|
||
QProgressBar_setTextVisible(QProgressBarH(Widget), visible);
|
||
end;
|
||
|
||
procedure TQtProgressBar.setAlignment(const AAlignment: QtAlignment);
|
||
begin
|
||
QProgressBar_setAlignment(QProgressBarH(Widget), AAlignment);
|
||
end;
|
||
|
||
procedure TQtProgressBar.setTextDirection(textDirection: QProgressBarDirection);
|
||
begin
|
||
QProgressBar_setTextDirection(QProgressBarH(Widget), textDirection);
|
||
end;
|
||
|
||
procedure TQtProgressBar.setValue(value: Integer);
|
||
begin
|
||
QProgressBar_setValue(QProgressBarH(Widget), value);
|
||
end;
|
||
|
||
procedure TQtProgressBar.setOrientation(p1: QtOrientation);
|
||
begin
|
||
QProgressBar_setOrientation(QProgressBarH(Widget), p1);
|
||
end;
|
||
|
||
procedure TQtProgressBar.setInvertedAppearance(invert: Boolean);
|
||
begin
|
||
QProgressBar_setInvertedAppearance(QProgressBarH(Widget), invert);
|
||
end;
|
||
|
||
procedure TQtProgressBar.SignalValueChanged(Value: Integer); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_CHANGED;
|
||
if not InUpdate then
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
procedure TQtProgressBar.setFocusPolicy(const APolicy: QtFocusPolicy);
|
||
begin
|
||
if APolicy = QtNoFocus then
|
||
QWidget_setFocusPolicy(Widget, APolicy)
|
||
else
|
||
QWidget_setFocusPolicy(Widget, QtTabFocus);
|
||
end;
|
||
|
||
procedure TQtProgressBar.reset;
|
||
begin
|
||
QProgressBar_reset(QProgressBarH(Widget));
|
||
end;
|
||
|
||
{ TQtStatusBarPanel }
|
||
|
||
function TQtStatusBarPanel.CreateWidget(const AParams: TCreateParams
|
||
): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtStatusBarPanel.Create');
|
||
{$endif}
|
||
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QLabel_create(Parent);
|
||
end;
|
||
|
||
procedure TQtStatusBarPanel.DrawItem(Sender: QObjectH; Event: QEventH);
|
||
var
|
||
Msg: TLMDrawItems;
|
||
AStruct: TPaintStruct;
|
||
ItemStruct: PDrawItemStruct;
|
||
P: TPoint;
|
||
B: Boolean;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtWidget.DrawItem ', dbgsName(LCLObject));
|
||
{$endif}
|
||
if CanSendLCLMessage and (LCLObject is TWinControl) and (FContext = 0) then
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
Msg.Msg := LM_DRAWITEM;
|
||
FillChar(AStruct{%H-}, SizeOf(TPaintStruct), 0);
|
||
FillChar(ItemStruct{%H-}, SizeOf(TDrawItemStruct), 0);
|
||
New(ItemStruct);
|
||
|
||
with PaintData do
|
||
begin
|
||
PaintWidget := QWidgetH(Sender);
|
||
ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
|
||
if ClipRect = nil then
|
||
New(ClipRect);
|
||
QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
|
||
end;
|
||
|
||
ItemStruct^.itemID := UINT(ID);
|
||
ItemStruct^._hDC := BeginPaint(THandle(Self), AStruct);
|
||
FContext := ItemStruct^._hDC;
|
||
ItemStruct^.rcItem := PaintData.ClipRect^;
|
||
ItemStruct^.hwndItem := HWND(Self);
|
||
Msg.Ctl := LCLObject.Handle;
|
||
Msg.DrawItemStruct := ItemStruct;
|
||
|
||
P := getClientOffset;
|
||
inc(P.X, FScrollX);
|
||
inc(P.Y, FScrollY);
|
||
TQtDeviceContext(FContext).translate(P.X, P.Y);
|
||
|
||
// send paint message
|
||
try
|
||
try
|
||
LCLObject.WindowProc(TLMessage(Msg));
|
||
finally
|
||
Dispose(PaintData.ClipRect);
|
||
Fillchar(FPaintData, SizeOf(FPaintData), 0);
|
||
FContext := 0;
|
||
EndPaint(THandle(Self), AStruct);
|
||
Dispose(ItemStruct);
|
||
end;
|
||
except
|
||
// prevent recursive repainting !
|
||
B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
|
||
if B then
|
||
QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
|
||
try
|
||
Application.HandleException(nil);
|
||
finally
|
||
if B and Assigned(Application) and not Application.Terminated then
|
||
QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TQtStatusBarPanel.EventFilter(Sender: QObjectH; Event: QEventH
|
||
): Boolean; cdecl;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject = nil then
|
||
exit;
|
||
if HasPaint and (QEvent_type(Event) = QEventPaint) then
|
||
begin
|
||
DrawItem(Sender, Event);
|
||
Result := True;
|
||
end;
|
||
end;
|
||
|
||
{ TQtStatusBar }
|
||
|
||
function TQtStatusBar.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
SetLength(Panels, 0);
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QStatusBar_create(Parent);
|
||
Widget := Result;
|
||
end;
|
||
|
||
procedure TQtStatusBar.setColor(const Value: PQColor);
|
||
var
|
||
I: Integer;
|
||
P: QPaletteH;
|
||
WP: QPaletteH;
|
||
begin
|
||
inherited setColor(Value);
|
||
QWidget_setAutoFillBackground(Widget, not EqualTQColor(Palette.CurrentColor, Palette.DefaultColor));
|
||
for i := 0 to High(self.Panels) do
|
||
begin
|
||
P := QWidget_palette(getContainerWidget);
|
||
WP := QWidget_palette(Panels[i].Widget);
|
||
QWidget_setAutoFillBackground(Panels[i].Widget, not EqualTQColor(Palette.CurrentColor, Palette.DefaultColor));
|
||
QPalette_setBrush(WP, QPaletteWindow, QPalette_background(P));
|
||
end;
|
||
end;
|
||
|
||
procedure TQtStatusBar.showMessage(text: PWideString; timeout: Integer);
|
||
begin
|
||
QStatusBar_showMessage(QStatusBarH(Widget), text, timeout);
|
||
end;
|
||
|
||
procedure TQtStatusBar.addWidget(AWidget: QWidgetH; AStretch: Integer = 0);
|
||
begin
|
||
QStatusBar_addWidget(QStatusBarH(Widget), AWidget, AStretch);
|
||
end;
|
||
|
||
procedure TQtStatusBar.removeWidget(AWidget: QWidgetH);
|
||
begin
|
||
QStatusBar_removeWidget(QStatusBarH(Widget), AWidget);
|
||
end;
|
||
|
||
function TQtStatusBar.isSizeGripEnabled: Boolean;
|
||
begin
|
||
Result := QStatusBar_isSizeGripEnabled(QStatusBarH(Widget));
|
||
end;
|
||
|
||
procedure TQtStatusBar.setSizeGripEnabled(const Value: Boolean);
|
||
begin
|
||
QStatusBar_setSizeGripEnabled(QStatusBarH(Widget), Value);
|
||
end;
|
||
|
||
function TQtStatusBar.SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
begin
|
||
inherited SlotMouse(Sender, Event);
|
||
Result := True; // cancel event propagation
|
||
end;
|
||
|
||
{ TQtDialog }
|
||
|
||
function TQtDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags): QWidgetH;
|
||
begin
|
||
Result := QDialog_create(parent, f);
|
||
end;
|
||
|
||
constructor TQtDialog.Create(ADialog: TCommonDialog; parent: QWidgetH; f: QtWindowFlags);
|
||
begin
|
||
WidgetColorRole := QPaletteWindow;
|
||
TextColorRole := QPaletteWindowText;
|
||
FOwner := nil;
|
||
FCentralWidget := nil;
|
||
FOwnWidget := True;
|
||
FProps := nil;
|
||
LCLObject := nil;
|
||
FKeysToEat := [];
|
||
FHasPaint := False;
|
||
FDialog := ADialog;
|
||
Widget := CreateWidget(parent, f);
|
||
setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
|
||
QtWidgetSet.AddHandle(Self);
|
||
end;
|
||
|
||
procedure TQtDialog.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FDialogEventHook := QObject_hook_create(Widget);
|
||
QObject_hook_hook_events(FDialogEventHook, @EventFilter);
|
||
end;
|
||
|
||
procedure TQtDialog.DetachEvents;
|
||
begin
|
||
if FDialogEventHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FDialogEventHook);
|
||
FDialogEventHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtDialog.DeliverMessage(var Msg;
|
||
const AIsInputEvent: Boolean = False): LRESULT;
|
||
begin
|
||
try
|
||
if FDialog.HandleAllocated then
|
||
begin
|
||
FDialog.Dispatch(TLMessage(Msg));
|
||
Result := TLMessage(Msg).Result;
|
||
end else
|
||
Result := 0;
|
||
except
|
||
Application.HandleException(nil);
|
||
end;
|
||
end;
|
||
|
||
function TQtDialog.SlotClose: Boolean; cdecl;
|
||
begin
|
||
Result := True;
|
||
FDialog.DoCanClose(Result);
|
||
end;
|
||
|
||
function TQtDialog.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
begin
|
||
{we'll need it later. QDialog uses it's own eventLoop !}
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject <> nil then
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
function TQtDialog.exec: Integer;
|
||
{$IFDEF HASX11}
|
||
var
|
||
AWND: HWND;
|
||
{$ENDIF}
|
||
begin
|
||
{$IF DEFINED(DARWIN) OR DEFINED(QT_DIALOGS_USE_QT_LOOP)}
|
||
Result := QDialog_exec(QDialogH(Widget));
|
||
{$ELSE}
|
||
if QWidget_testAttribute(Widget, QtWA_DeleteOnClose) then
|
||
Result := QDialog_exec(QDialogH(Widget))
|
||
else
|
||
begin
|
||
QWidget_setWindowModality(Widget ,QtApplicationModal);
|
||
QWidget_show(Widget);
|
||
repeat
|
||
QCoreApplication_processEvents();
|
||
Application.Idle(true);
|
||
until not QWidget_isVisible(Widget) or Application.Terminated;
|
||
Result := QDialog_result(QDialogH(Widget));
|
||
end;
|
||
{$ENDIF}
|
||
{$IFDEF HASX11}
|
||
if (QtWidgetSet.WindowManagerName = 'xfwm4') and (QApplication_activeModalWidget() <> nil) then
|
||
begin
|
||
AWND := HwndFromWidgetH(QApplication_activeModalWidget());
|
||
if (AWND <> 0) and (X11GetActivewindow <> TQtWidget(AWND).Widget) then
|
||
X11Raise(QWidget_winID(TQtWidget(AWND).Widget));
|
||
end;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TQtDialog.setSizeGripEnabled(const AEnabled: Boolean);
|
||
begin
|
||
QDialog_setSizeGripEnabled(QDialogH(Widget), AEnabled);
|
||
end;
|
||
|
||
{ TQtViewPort }
|
||
|
||
function TQtViewPort.CanPaintBackground: Boolean;
|
||
begin
|
||
Result := CanSendLCLMessage and getEnabled and
|
||
(FChildOfComplexWidget in [ccwCustomControl, ccwScrollingWinControl]) and
|
||
(LCLObject.Color <> clBtnFace) and (LCLObject.Color <> clBackground);
|
||
end;
|
||
|
||
function TQtViewPort.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
ASize: TSize;
|
||
AResizeEvent: QResizeEventH;
|
||
begin
|
||
Result := False;
|
||
{$IF DEFINED(VerboseQt) OR DEFINED(VerboseQtEvents)}
|
||
if (QEvent_type(Event) = QEventResize) or
|
||
(QEvent_type(Event) = QEventLayoutRequest) or
|
||
(QEvent_type(Event) = QEventWheel) then
|
||
WriteLn('TQtViewPort.EventFilter: Sender=', IntToHex(PtrUInt(Sender),8),
|
||
' LCLObject=', dbgsName(LCLObject),
|
||
' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
|
||
{$endif}
|
||
case QEvent_type(Event) of
|
||
QEventShow,
|
||
QEventShowToParent:
|
||
begin
|
||
{Qt does not track scrolled offset of widget when it''s not visible.issue #29239}
|
||
if (FInvisibleX <> 0) or (FInvisibleY <> 0) then
|
||
begin
|
||
QWidget_scroll(Widget, FInvisibleX, FInvisibleY);
|
||
FInvisibleX := 0;
|
||
FInvisibleY := 0;
|
||
end;
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
QEventMove: ; // do not flood LCL with viewport position
|
||
QEventResize:
|
||
begin
|
||
// immediate update clientRect !
|
||
if FOwner <> nil then
|
||
begin
|
||
{TQtCustomControl does not send resize event, it is done here
|
||
when viewport geometry is finally updated by Qt.}
|
||
ASize := FOwner.getSize;
|
||
AResizeEvent := QResizeEvent_create(@ASize, @ASize);
|
||
try
|
||
// issue #28596 and others of TCustomControl clientrect related
|
||
if CanAdjustClientRectOnResize and
|
||
LCLObject.ClientRectNeedsInterfaceUpdate then
|
||
begin
|
||
{$IF DEFINED(VerboseSizeMsg) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('TQtViewPort.EventFilter invalidatingClientRectCache ',dbgsName(Self),' LCL=',dbgsName(LCLObject));
|
||
{$ENDIF}
|
||
LCLObject.InvalidateClientRectCache(False);
|
||
end;
|
||
FOwner.SlotResize(AResizeEvent);
|
||
finally
|
||
QEvent_destroy(AResizeEvent);
|
||
end;
|
||
end else
|
||
begin
|
||
{$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize)}
|
||
DebugLn('TQtViewport: QEventResize wrong call....possible ERROR');
|
||
{$ENDIF}
|
||
LCLObject.DoAdjustClientRectChange;
|
||
end;
|
||
end;
|
||
QEventWheel:
|
||
if not getEnabled then
|
||
inherited EventFilter(Sender, Event);
|
||
QEventLayoutRequest:
|
||
begin
|
||
if FOwner <> nil then
|
||
begin
|
||
if LCLObject.ClientRectNeedsInterfaceUpdate then
|
||
begin
|
||
{$IF DEFINED(VerboseQtEvents) OR DEFINED(VerboseQtResize) OR DEFINED(VerboseSizeMsg)}
|
||
if caspComputingBounds in LCLObject.AutoSizePhases then
|
||
DebugLn('TQtViewport of ',dbgsName(LCLObject),' QEventLayoutRequest calling DoAdjustClientRectChange. CASP=TRUE *** !!!!');
|
||
{$ENDIF}
|
||
LCLObject.DoAdjustClientRectChange(True);
|
||
end;
|
||
end;
|
||
end;
|
||
else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtViewPort.InitializeWidget;
|
||
begin
|
||
FInvisibleX := 0;
|
||
FInvisibleY := 0;
|
||
inherited InitializeWidget;
|
||
end;
|
||
|
||
procedure TQtViewPort.scroll(dx, dy: integer; ARect: PRect = nil);
|
||
begin
|
||
if not getVisible then
|
||
begin
|
||
FInvisibleX += dx;
|
||
FInvisibleY += dy;
|
||
end else
|
||
inherited scroll(dx, dy, ARect);
|
||
FScrollX := FScrollX + dx;
|
||
FScrollY := FScrollY + dy;
|
||
end;
|
||
|
||
procedure TQtViewPort.stackUnder(AWidget: QWidgetH);
|
||
begin
|
||
// do nothing for TQtViewPort
|
||
// inherited stackUnder(AWidget);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractScrollArea.horizontalScrollbar
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
|
||
procedure TQtAbstractScrollArea.setScrollBarPolicy(AIndex: Boolean;
|
||
const AValue: QtScrollBarPolicy);
|
||
var
|
||
Area: QAbstractScrollAreaH;
|
||
begin
|
||
Area := QAbstractScrollAreaH(Widget);
|
||
if getScrollBarsPolicy(AIndex) <> AValue then
|
||
begin
|
||
if AIndex then
|
||
QAbstractScrollArea_setVerticalScrollBarPolicy(Area, AValue)
|
||
else
|
||
QAbstractScrollArea_setHorizontalScrollBarPolicy(Area, AValue);
|
||
|
||
if Assigned(LCLObject) and LCLObject.ClientRectNeedsInterfaceUpdate then
|
||
begin
|
||
if not (caspComputingBounds in LCLObject.AutoSizePhases) then
|
||
LCLObject.DoAdjustClientRectChange(True);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TQtAbstractScrollArea.EventFilter(Sender: QObjectH; Event: QEventH
|
||
): Boolean; cdecl;
|
||
var
|
||
w: QWidgetH;
|
||
begin
|
||
Result := False;
|
||
|
||
if (QEvent_type(Event) = QEventHide) then
|
||
begin
|
||
// issue #28880
|
||
w := QWidget_mouseGrabber;
|
||
if w <> nil then
|
||
begin
|
||
if w = Widget then
|
||
ReleaseCapture
|
||
else
|
||
if w = viewportWidget then
|
||
ReleaseCapture;
|
||
end;
|
||
end else
|
||
if (QEvent_type(Event) = QEventResize) then
|
||
// DebugLn('***TQtAbstractScrollArea.EventFilter QEventResize(',dbgsName(LCLObject),') EAT !')
|
||
else
|
||
if (QEvent_type(Event) = QEventWheel) and
|
||
not (FChildOfComplexWidget in
|
||
[ccwCustomControl, ccwScrollingWinControl, ccwScrollingWindow]) then
|
||
// issue #25992.Do not propagate wheel event to lcl, it is done via TQtScrollBar.EventFilter.
|
||
else
|
||
Result:=inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
procedure TQtAbstractScrollArea.grabMouse;
|
||
var
|
||
W: QWidgetH;
|
||
begin
|
||
W := viewportWidget;
|
||
if (W <> nil) and QWidget_isVisible(W) and QWidget_isEnabled(W) then
|
||
QWidget_grabMouse(W)
|
||
else
|
||
inherited grabMouse;
|
||
end;
|
||
|
||
function TQtAbstractScrollArea.GetContainerWidget: QWidgetH;
|
||
begin
|
||
Result := viewportWidget;
|
||
end;
|
||
|
||
function TQtAbstractScrollArea.getClientOffset: TPoint;
|
||
begin
|
||
with getClientBounds do
|
||
Result := Point(Left, Top);
|
||
end;
|
||
|
||
function TQtAbstractScrollArea.getScrollFrameOffset: Integer;
|
||
begin
|
||
Result := 0;
|
||
if (QStyle_styleHint(QApplication_style(),
|
||
QStyleSH_ScrollView_FrameOnlyAroundContents) <> 0) then
|
||
Result := QStyle_pixelMetric(QApplication_style(), QStylePM_ScrollView_ScrollBarSpacing, nil, Widget);
|
||
end;
|
||
|
||
function TQtAbstractScrollArea.getClientBounds: TRect;
|
||
var
|
||
HaveBar: Boolean;
|
||
ASize: TSize;
|
||
begin
|
||
if not QWidget_testAttribute(viewportWidget, QtWA_Mapped) then
|
||
begin
|
||
ASize := getSize;
|
||
QWidget_contentsRect(Widget, @Result);
|
||
if (ASize.cx > 0) and (ASize.cy > 0) and (QStyle_styleHint(QApplication_style(),
|
||
QStyleSH_ScrollView_FrameOnlyAroundContents) <= 0) then
|
||
begin
|
||
HaveBar := Assigned(FVScrollbar);
|
||
if HaveBar and (verticalScrollBar.getVisibleTo(Widget)) then
|
||
dec(Result.Right, verticalScrollBar.getWidth);
|
||
|
||
HaveBar := Assigned(FHScrollbar);
|
||
if HaveBar and (horizontalScrollBar.getVisibleTo(Widget)) then
|
||
dec(Result.Bottom, horizontalScrollBar.getHeight);
|
||
end;
|
||
OffsetRect(Result, -Result.Left, -Result.Top);
|
||
{$IF DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
|
||
DebugLn('TQtAbstractScrollArea.GetClientBounds(not mapped): ',dbgsName(LCLObject),':',dbgsName(Self),' ',dbgs(Result),' ChildComplex=',dbgs(Ord(ChildOfComplexWidget)));
|
||
{$ENDIF}
|
||
end else
|
||
begin
|
||
QWidget_rect(viewportWidget, @Result);
|
||
{$IF DEFINED(VerboseQtResize) OR DEFINED(VerboseQScrollBarShowHide)}
|
||
DebugLn('TQtAbstractScrollArea.GetClientBounds: ',dbgsName(LCLObject),':',dbgsName(Self),' ',dbgs(Result),' ChildComplex=',dbgs(Ord(ChildOfComplexWidget)));
|
||
{$ENDIF}
|
||
end;
|
||
end;
|
||
|
||
function TQtAbstractScrollArea.getViewOrigin: TPoint;
|
||
var
|
||
R: TRect;
|
||
begin
|
||
QWidget_rect(viewportWidget, @R);
|
||
// current bindings (2.1) does not assign TopLeft so it's always 0,0
|
||
Result := R.TopLeft;
|
||
end;
|
||
|
||
function TQtAbstractScrollArea.viewportWidget: QWidgetH;
|
||
begin
|
||
Result := QAbstractScrollArea_viewport(QAbstractScrollAreaH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractScrollArea.getScrollBarsPolicy(AIndex: Boolean
|
||
): QtScrollBarPolicy;
|
||
var
|
||
Area: QAbstractScrollAreaH;
|
||
begin
|
||
Area := QAbstractScrollAreaH(Widget);
|
||
if AIndex then
|
||
Result := QAbstractScrollArea_verticalScrollBarPolicy(Area)
|
||
else
|
||
Result := QAbstractScrollArea_horizontalScrollBarPolicy(Area);
|
||
end;
|
||
|
||
function TQtAbstractScrollArea.horizontalScrollBar: TQtScrollBar;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQAbstractScrollArea.horizontalScrollBar');
|
||
{$endif}
|
||
if FHScrollBar = nil then
|
||
begin
|
||
FHScrollBar := TQtScrollBar.CreateFrom(LCLObject,
|
||
QAbstractScrollArea_horizontalScrollBar(QAbstractScrollAreaH(Widget)));
|
||
|
||
if FHScrollBar.getTracking then
|
||
FHScrollBar.TrackPos := SB_POLICY_CONTINUOUS
|
||
else
|
||
FHScrollBar.TrackPos := SB_POLICY_DISCONTINUOUS;
|
||
|
||
FHScrollBar.ChildOfComplexWidget := ccwAbstractScrollArea;
|
||
FHScrollBar.FOwner := Self;
|
||
FHScrollBar.setFocusPolicy(QtNoFocus);
|
||
|
||
if not FHScrollBar.CanChangeFontColor then
|
||
begin
|
||
with FHScrollBar do
|
||
begin
|
||
Palette.ForceColor := True;
|
||
setDefaultColor(dctFont);
|
||
Palette.ForceColor := False;
|
||
end;
|
||
end;
|
||
FHScrollBar.AttachEvents;
|
||
end;
|
||
Result := FHScrollBar;
|
||
end;
|
||
|
||
procedure TQtAbstractScrollArea.InitializeAccessibility;
|
||
var
|
||
WStr: WideString;
|
||
begin
|
||
inherited InitializeAccessibility;
|
||
WStr := GetUtf8String(ClassName+':ViewPort');
|
||
QWidget_setAccessibleName(viewPortWidget, @WStr);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractScrollArea.verticalScrollbar
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtAbstractScrollArea.verticalScrollBar: TQtScrollBar;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQAbstractScrollArea.verticalScrollBar');
|
||
{$endif}
|
||
if FVScrollBar = nil then
|
||
begin
|
||
FVScrollbar := TQtScrollBar.CreateFrom(LCLObject,
|
||
QAbstractScrollArea_verticalScrollBar(QAbstractScrollAreaH(Widget)));;
|
||
if FVScrollBar.getTracking then
|
||
FVScrollBar.TrackPos := SB_POLICY_CONTINUOUS
|
||
else
|
||
FVScrollBar.TrackPos := SB_POLICY_DISCONTINUOUS;
|
||
FVScrollBar.ChildOfComplexWidget := ccwAbstractScrollArea;
|
||
FVScrollBar.FOwner := Self;
|
||
FVScrollBar.setFocusPolicy(QtNoFocus);
|
||
if not FVScrollBar.CanChangeFontColor then
|
||
begin
|
||
with FVScrollBar do
|
||
begin
|
||
Palette.ForceColor := True;
|
||
setDefaultColor(dctFont);
|
||
Palette.ForceColor := False;
|
||
end;
|
||
end;
|
||
FVScrollbar.AttachEvents;
|
||
end;
|
||
Result := FVScrollBar;
|
||
end;
|
||
|
||
procedure TQtAbstractScrollArea.setFocusPolicy(const APolicy: QtFocusPolicy);
|
||
begin
|
||
QWidget_setFocusPolicy(Widget, APolicy);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractScrollArea.setHorizontalScrollbar
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractScrollArea.setHorizontalScrollBar(AScrollBar: TQtScrollBar);
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQAbstractScrollArea.setHorizontalScrollBar');
|
||
{$endif}
|
||
FHScrollbar := AScrollBar;
|
||
if Assigned(FHScrollBar) then
|
||
QAbstractScrollArea_setHorizontalScrollBar(QAbstractScrollAreaH(Widget), QScrollBarH(FHScrollBar.Widget));
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractScrollArea.setVerticalScrollbar
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtAbstractScrollArea.setVerticalScrollBar(AScrollBar: TQtScrollBar);
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQAbstractScrollArea.setVerticalScrollBar');
|
||
{$endif}
|
||
FVScrollBar := AScrollBar;
|
||
if Assigned(FVScrollBar) then
|
||
QAbstractScrollArea_setVerticalScrollBar(QAbstractScrollAreaH(Widget), QScrollBarH(FVScrollBar.Widget));
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractScrollArea.setScrollStyle
|
||
Params: None
|
||
Returns: Nothing
|
||
Setting scrollbar''s policy (LCL TScrollStyle)
|
||
-----------------------------------------------------------------------------}
|
||
procedure TQtAbstractScrollArea.setScrollStyle(AScrollStyle: TScrollStyle);
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQAbstractScrollArea.setScrollStyle');
|
||
{$endif}
|
||
case AScrollStyle of
|
||
ssNone:
|
||
begin
|
||
ScrollBarPolicy[True] := QtScrollBarAlwaysOff;
|
||
ScrollBarPolicy[False] := QtScrollBarAlwaysOff;
|
||
end;
|
||
ssHorizontal, ssVertical:
|
||
begin
|
||
ScrollBarPolicy[AScrollStyle = ssVertical] := QtScrollBarAlwaysOn;
|
||
end;
|
||
ssBoth:
|
||
begin
|
||
ScrollBarPolicy[True] := QtScrollBarAlwaysOn;
|
||
ScrollBarPolicy[False] := QtScrollBarAlwaysOn;
|
||
end;
|
||
ssAutoHorizontal, ssAutoVertical:
|
||
begin
|
||
ScrollBarPolicy[AScrollStyle = ssAutoVertical] := QtScrollBarAsNeeded;
|
||
end;
|
||
ssAutoBoth:
|
||
begin
|
||
ScrollBarPolicy[True] := QtScrollBarAsNeeded;
|
||
ScrollBarPolicy[False] := QtScrollBarAsNeeded;
|
||
end;
|
||
end;
|
||
|
||
end;
|
||
|
||
procedure TQtAbstractScrollArea.SetNoMousePropagation(Sender: QWidgetH;
|
||
const ANoMousePropagation: Boolean);
|
||
begin
|
||
// keep it so because sender can be dangling pointer from qt inside
|
||
// mouse event of viewportWidget ! issue #26466
|
||
if Sender = viewportWidget then
|
||
inherited SetNoMousePropagation(Sender, False)
|
||
else
|
||
inherited SetNoMousePropagation(Sender, ANoMousePropagation);
|
||
end;
|
||
|
||
procedure TQtAbstractScrollArea.DestroyNotify(AWidget: TQtWidget);
|
||
begin
|
||
if AWidget = FHScrollbar then
|
||
FHScrollbar := nil;
|
||
|
||
if AWidget = FVScrollbar then
|
||
FVScrollbar := nil;
|
||
|
||
inherited DestroyNotify(AWidget);
|
||
end;
|
||
|
||
destructor TQtAbstractScrollArea.Destroy;
|
||
begin
|
||
FreeAndNil(FHScrollBar);
|
||
FreeAndNil(FVScrollBar);
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TQtAbstractScrollArea.Update(ARect: PRect);
|
||
var
|
||
P: TPoint;
|
||
begin
|
||
if ARect <> nil then
|
||
begin
|
||
P := getClientOffset;
|
||
OffsetRect(ARect^, -P.X , -P.Y);
|
||
QWidget_update(viewportWidget, ARect);
|
||
end else
|
||
QWidget_update(viewportWidget);
|
||
end;
|
||
|
||
procedure TQtAbstractScrollArea.UpdateRegion(ARgn: QRegionH);
|
||
begin
|
||
if ARgn <> nil then
|
||
QWidget_update(viewportWidget, ARgn)
|
||
else
|
||
QWidget_update(viewportWidget);
|
||
end;
|
||
|
||
procedure TQtAbstractScrollArea.Repaint(ARect: PRect);
|
||
var
|
||
P: TPoint;
|
||
begin
|
||
if ARect <> nil then
|
||
begin
|
||
P := getClientOffset;
|
||
OffsetRect(ARect^, -P.X , -P.Y);
|
||
QWidget_repaint(viewportWidget, ARect);
|
||
end else
|
||
QWidget_repaint(viewportWidget);
|
||
end;
|
||
|
||
{ TQtCustomControl }
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCustomControl.CreateWidget
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtCustomControl.CreateWidget(const AParams: TCreateParams):QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtCustomControl.CreateWidget');
|
||
{$endif}
|
||
FHasPaint := True;
|
||
FViewPortWidget := nil;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QLCLAbstractScrollArea_create(Parent);
|
||
|
||
FChildOfComplexWidget := ccwCustomControl;
|
||
|
||
if (LCLObject is TScrollingWinControl) then
|
||
FChildOfComplexWidget := ccwScrollingWinControl
|
||
else
|
||
QWidget_setAutoFillBackground(Result, False);
|
||
|
||
QWidget_setAttribute(Result, QtWA_InputMethodEnabled);
|
||
end;
|
||
|
||
function TQtCustomControl.ProcessArrowKeys: Boolean;
|
||
begin
|
||
Result := True;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCustomControl.Destroy
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
destructor TQtCustomControl.Destroy;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtCustomControl.Destroy');
|
||
{$endif}
|
||
viewportDelete;
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function TQtCustomControl.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if (LCLObject = nil) then
|
||
exit;
|
||
|
||
if (QEvent_type(Event) in [
|
||
QEventPaint,
|
||
QEventResize, // TQtViewport.EventFilter sends resize !
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick,
|
||
QEventContextMenu
|
||
]) and
|
||
(ClassType = TQtCustomControl) then
|
||
Result := False
|
||
else
|
||
if QEvent_type(Event) = QEventWheel then
|
||
begin
|
||
if not getEnabled then
|
||
inherited EventFilter(Sender, Event)
|
||
else
|
||
if not horizontalScrollBar.getVisible and
|
||
not verticalScrollBar.getVisible then
|
||
Result := inherited EventFilter(Sender, Event)
|
||
else
|
||
Result := False;
|
||
end else
|
||
{$IFDEF MSWINDOWS}
|
||
{sometimes our IDE completely freezes, after screensaver activated
|
||
or OS sleep state / hibernation under Win32 (if cursor stays
|
||
inside SourceEditor), so if application is deactivated by OS
|
||
we must release mouse grab. }
|
||
if QEvent_type(Event) = QEventApplicationDeactivate then
|
||
begin
|
||
if HWND(Self) = GetCapture then
|
||
ReleaseCapture;
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end else
|
||
{$ENDIF}
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
procedure TQtCustomControl.ViewPortEventFilter(event: QEventH; retval: PBoolean); cdecl;
|
||
var
|
||
MouseEventTyp: Boolean;
|
||
begin
|
||
{$ifdef VerboseViewPortEventFilter}
|
||
WriteLn('ViewPortEventFilter ',QEvent_type(Event));
|
||
{$endif}
|
||
|
||
QEvent_accept(Event);
|
||
|
||
case QEvent_type(Event) of
|
||
QEventResize,
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick,
|
||
QEventMouseMove,
|
||
QEventWheel,
|
||
QEventContextMenu,
|
||
QEventPaint:
|
||
begin
|
||
MouseEventTyp := (QEvent_type(Event) = QEventMouseButtonPress) or
|
||
(QEvent_type(Event) = QEventMouseButtonRelease) or
|
||
(QEvent_type(Event) = QEventMouseButtonDblClick) or
|
||
(QEvent_type(Event) = QEventWheel) or
|
||
(QEvent_type(Event) = QEventMouseMove);
|
||
|
||
if (QEvent_type(Event) = QEventWheel) then
|
||
QLCLAbstractScrollArea_InheritedViewportEvent(QLCLAbstractScrollAreaH(Widget), event);
|
||
|
||
retval^ := True;
|
||
|
||
if FViewPortWidget <> nil then
|
||
Viewport.EventFilter(ViewPortWidget, Event);
|
||
|
||
// do not allow qt to call notifications on user input events (mouse)
|
||
// otherwise we can crash since our object maybe does not exist
|
||
// after mouse clicks
|
||
if not MouseEventTyp then
|
||
QEvent_ignore(Event);
|
||
end;
|
||
else
|
||
retval^ := QLCLAbstractScrollArea_InheritedViewportEvent(QLCLAbstractScrollAreaH(Widget), event);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtCustomControl.Destroyed; cdecl;
|
||
begin
|
||
viewportDelete;
|
||
inherited Destroyed;
|
||
end;
|
||
|
||
procedure TQtCustomControl.DestroyNotify(AWidget: TQtWidget);
|
||
begin
|
||
if AWidget = FCornerWidget then
|
||
FCornerWidget := nil;
|
||
|
||
if AWidget = FViewPortWidget then
|
||
FViewPortWidget := nil;
|
||
|
||
inherited DestroyNotify(AWidget);
|
||
end;
|
||
|
||
function TQtCustomControl.CanAdjustClientRectOnResize: Boolean;
|
||
begin
|
||
// DoAdjustClientRectChange(); is called from TQtViewport resize event !
|
||
Result := True;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCustomControl.cornerWidget
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtCustomControl.cornerWidget: TQtWidget;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQAbstractScrollArea.cornerWidget');
|
||
{$endif}
|
||
Result := FCornerWidget;
|
||
end;
|
||
|
||
function TQtCustomControl.MapToGlobal(APt: TPoint;
|
||
const AWithScrollOffset: Boolean = False): TPoint;
|
||
var
|
||
Pt: TPoint;
|
||
begin
|
||
Result := inherited MapToGlobal(APt);
|
||
if AWithScrollOffset and (ChildOfComplexWidget = ccwScrollingWinControl) then
|
||
begin
|
||
Pt := viewport.ScrolledOffset;
|
||
dec(Result.X, Pt.X);
|
||
dec(Result.Y, Pt.Y);
|
||
end;
|
||
end;
|
||
|
||
function TQtCustomControl.MapFromGlobal(APt: TPoint;
|
||
const AWithScrollOffset: Boolean = False): TPoint;
|
||
begin
|
||
//TODO: see what to do with ccwScrollingWinControl
|
||
Result := inherited MapFromGlobal(APt);
|
||
end;
|
||
|
||
procedure TQtCustomControl.InitializeAccessibility;
|
||
{$IFDEF QTACCESSIBILITY}
|
||
var
|
||
LCLAxObject: TLazAccessibleObject;
|
||
{$ENDIF}
|
||
begin
|
||
inherited InitializeAccessibility;
|
||
{$IFDEF QTACCESSIBILITY}
|
||
if (LCLObject <> nil) then begin
|
||
// TWinControl.Handle is still not set so can't do handle creation through LCLAxObject.CreateHandle
|
||
LCLAxObject := LCLObject.GetAccessibleObject;
|
||
if LCLAxObject.AccessibleRole = larTreeView then
|
||
LCLAxObject.Handle :=
|
||
HWND(TQtAccessibleTree.Create(LCLAxObject, Widget))
|
||
else
|
||
LCLAxObject.Handle :=
|
||
HWND(TQtAccessibleObject.Create(LCLAxObject, Widget));
|
||
end;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCustomControl.setCornerWidget
|
||
Params: TQtWidget
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtCustomControl.setCornerWidget(AWidget: TQtWidget);
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQAbstractScrollArea.setCornerWidget');
|
||
{$endif}
|
||
FCornerWidget := AWidget;
|
||
if Assigned(FCornerWidget) then
|
||
QAbstractScrollArea_setCornerWidget(QAbstractScrollAreaH(Widget), FCornerWidget.Widget)
|
||
else
|
||
QAbstractScrollArea_setCornerWidget(QAbstractScrollAreaH(Widget), NiL);
|
||
end;
|
||
|
||
procedure TQtCustomControl.setCursor(const ACursor: QCursorH);
|
||
begin
|
||
if (LCLObject is TCustomControl) and HasPaint then
|
||
viewport.setCursor(ACursor)
|
||
else
|
||
inherited setCursor(ACursor);
|
||
end;
|
||
|
||
procedure TQtCustomControl.setViewport(const AViewPort: QWidgetH);
|
||
begin
|
||
QAbstractScrollArea_setViewport(QAbstractScrollAreaH(Widget), AViewPort);
|
||
end;
|
||
|
||
procedure TQtCustomControl.setVisible(AVisible: Boolean);
|
||
begin
|
||
inherited setVisible(AVisible);
|
||
if FViewPortWidget <> nil then
|
||
FViewPortWidget.setVisible(AVisible);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCustomControl.viewport
|
||
Params: None
|
||
Returns: viewport widget of QAbstractScrollArea
|
||
------------------------------------------------------------------------------}
|
||
function TQtCustomControl.viewport: TQtViewPort;
|
||
begin
|
||
viewportNeeded;
|
||
Result := FViewPortWidget;
|
||
end;
|
||
|
||
procedure TQtCustomControl.preferredSize(var PreferredWidth,
|
||
PreferredHeight: integer; WithThemeSpace: Boolean);
|
||
begin
|
||
if LCLObject is TCustomControl then
|
||
begin
|
||
PreferredWidth := 0;
|
||
PreferredHeight := 0;
|
||
end else
|
||
inherited preferredSize(PreferredWidth, PreferredHeight, WithThemeSpace);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCustomControl.viewportNeeded
|
||
Params: None
|
||
Returns: Nothing
|
||
Creates viewport widget for QAbstractScrollArea
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtCustomControl.viewportNeeded;
|
||
var
|
||
AParams: TCreateParams;
|
||
begin
|
||
if FViewPortWidget <> niL then
|
||
exit;
|
||
FillChar(AParams{%H-}, SizeOf(AParams), #0);
|
||
FViewPortWidget := TQtViewPort.Create(LCLObject, AParams);
|
||
FViewPortWidget.setFocusProxy(Widget);
|
||
FViewPortWidget.setBackgroundRole(QPaletteNoRole);
|
||
FViewPortWidget.setAutoFillBackground(False);
|
||
FViewPortWidget.FOwner := Self;
|
||
FViewPortWidget.FChildOfComplexWidget := FChildOfComplexWidget;
|
||
|
||
// some events will be redirected to scroll area
|
||
FViewPortWidget.AttachEvents;
|
||
|
||
QLCLAbstractScrollArea_override_viewportEvent(QLCLAbstractScrollAreaH(Widget),
|
||
@ViewPortEventFilter);
|
||
|
||
setViewport(FViewPortWidget.Widget);
|
||
end;
|
||
|
||
procedure TQtCustomControl.viewportDelete;
|
||
begin
|
||
if Assigned(FViewPortWidget) then
|
||
begin
|
||
QLCLAbstractScrollArea_override_viewportEvent(QLCLAbstractScrollAreaH(Widget),
|
||
QLCLAbstractScrollArea_viewportEvent_Override(NilMethod));
|
||
FViewPortWidget.FOwner := nil;
|
||
FViewPortWidget.Release;
|
||
FViewPortWidget := nil;
|
||
end;
|
||
end;
|
||
|
||
{ TQtCalendar }
|
||
|
||
function TQtCalendar.GetDateTime: TDateTime;
|
||
var
|
||
Date: QDateH;
|
||
begin
|
||
Date := QDate_create();
|
||
QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), Date);
|
||
AYear := QDate_year(Date);
|
||
AMonth := QDate_month(Date);
|
||
ADay := QDate_day(Date);
|
||
QDate_destroy(Date);
|
||
Result := EncodeDate(AYear, AMonth, ADay);
|
||
end;
|
||
|
||
procedure TQtCalendar.SetDateTime(const AValue: TDateTime);
|
||
var
|
||
Date: QDateH;
|
||
begin
|
||
DecodeDate(AValue, AYear, AMonth, ADay);
|
||
Date := QDate_create(AYear, AMonth, ADay);
|
||
QCalendarWidget_setCurrentPage(QCalendarWidgetH(Widget),
|
||
AYear, AMonth);
|
||
SetSelectedDate(Date);
|
||
QDate_destroy(Date);
|
||
end;
|
||
|
||
procedure TQtCalendar.SetSelectedDate(const AValue: QDateH);
|
||
begin
|
||
QCalendarWidget_setSelectedDate(QCalendarWidgetH(Widget), AValue);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCalendar.CreateWidget
|
||
Params: None
|
||
Returns: Nothing
|
||
------------------------------------------------------------------------------}
|
||
function TQtCalendar.CreateWidget(const AParams: TCreateParams):QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
// Creates the widget
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtCalendar.Create');
|
||
{$endif}
|
||
FMouseDoubleClicked := False;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QCalendarWidget_create(Parent);
|
||
end;
|
||
|
||
procedure TQtCalendar.AttachEvents;
|
||
var
|
||
i: integer;
|
||
Children: TPtrIntArray;
|
||
AnObject: QObjectH;
|
||
WP: QWidgetH;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
FClickedHook := QCalendarWidget_hook_create(Widget);
|
||
FActivatedHook := QCalendarWidget_hook_create(Widget);
|
||
FSelectionChangedHook := QCalendarWidget_hook_create(Widget);
|
||
FCurrentPageChangedHook := QCalendarWidget_hook_create(Widget);
|
||
|
||
QCalendarWidget_hook_hook_clicked(FClickedHook, @SignalClicked);
|
||
|
||
QCalendarWidget_hook_hook_activated(FActivatedHook, @SignalActivated);
|
||
|
||
QCalendarWidget_hook_hook_selectionChanged(FSelectionChangedHook, @SignalSelectionChanged);
|
||
|
||
QCalendarWidget_hook_hook_currentPageChanged(FCurrentPageChangedHook, @SignalCurrentPageChanged);
|
||
|
||
QObject_children(Widget, @Children);
|
||
for i := 0 to High(Children) do
|
||
begin
|
||
AnObject := QObjectH(Children[i]);
|
||
if QObject_isWidgetType(AnObject) then
|
||
begin
|
||
{do not localize !!}
|
||
if QObject_inherits(AnObject,'QAbstractScrollArea') then
|
||
begin
|
||
WP := QAbstractScrollArea_viewport(QAbstractScrollAreaH(AnObject));
|
||
QWidget_setMouseTracking(WP, True);
|
||
FCalViewportEventHook := QObject_hook_create(WP);
|
||
QObject_hook_hook_events(FCalViewportEventHook, @calViewportEventFilter);
|
||
setProperty(QWidgetH(AnObject), 'lclwidget', Int64(PtrUInt(Self)));
|
||
FCalViewAreaEventHook := QObject_hook_create(QWidgetH(AnObject));
|
||
QObject_hook_hook_events(FCalViewAreaEventHook, @AreaViewEventFilter);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtCalendar.DetachEvents;
|
||
begin
|
||
if FCalViewAreaEventHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FCalViewAreaEventHook);
|
||
FCalViewAreaEventHook := nil;
|
||
end;
|
||
if FCalViewportEventHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FCalViewportEventHook);
|
||
FCalViewportEventHook := nil;
|
||
end;
|
||
if FClickedHook <> nil then
|
||
begin
|
||
QCalendarWidget_hook_destroy(FClickedHook);
|
||
FClickedHook := nil;
|
||
end;
|
||
if FActivatedHook <> nil then
|
||
begin
|
||
QCalendarWidget_hook_destroy(FActivatedHook);
|
||
FActivatedHook := nil;
|
||
end;
|
||
if FSelectionChangedHook <> nil then
|
||
begin
|
||
QCalendarWidget_hook_destroy(FSelectionChangedHook);
|
||
FSelectionChangedHook := nil;
|
||
end;
|
||
if FCurrentPageChangedHook <> nil then
|
||
begin
|
||
QCalendarWidget_hook_destroy(FCurrentPageChangedHook);
|
||
FCurrentPageChangedHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtCalendar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
begin
|
||
Result := False;
|
||
if (QEvent_Type(Event) = QEventKeyPress) or (QEvent_Type(Event) = QEventKeyRelease) then
|
||
exit;
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
function TQtCalendar.AreaViewEventFilter(Sender: QObjectH; Event: QEventH
|
||
): Boolean; cdecl;
|
||
var
|
||
ADate: QDateH;
|
||
AKey: Integer;
|
||
begin
|
||
Result := False;
|
||
if (LCLObject <> nil) and ((QEvent_type(Event) = QEventKeyPress) or
|
||
(QEvent_type(Event) = QEventKeyRelease)) then
|
||
begin
|
||
AKey := QKeyEvent_key(QKeyEventH(Event));
|
||
Result := SlotKey(Widget, Event);
|
||
if (QEvent_type(Event) = QEventKeyRelease) and
|
||
( (AKey = QtKey_Up) or (AKey = QtKey_Left) or
|
||
(AKey = QtKey_Right) or (AKey = QtKey_Down) ) then
|
||
begin
|
||
ADate := QDate_create();
|
||
QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), ADate);
|
||
DeliverDayChanged(ADate);
|
||
QDate_destroy(ADate);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TQtCalendar.calViewportEventFilter(Sender: QObjectH; Event: QEventH
|
||
): Boolean; cdecl;
|
||
begin
|
||
{we install only mouse dblclick event on QCalendar viewport,
|
||
since inside signalActivated we don't know is it signalled from
|
||
dblclick or by pressing return key.}
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if (LCLObject <> nil) then
|
||
begin
|
||
case QEvent_type(Event) of
|
||
QEventMouseMove: Result := SlotMouseMove(Sender, Event);
|
||
QEventEnter,
|
||
QEventLeave: Result := SlotMouseEnter(Sender, Event);
|
||
QEventMouseButtonDblClick: FMouseDoubleClicked := True;
|
||
QEventWheel:
|
||
begin
|
||
if not getEnabled then
|
||
begin
|
||
QEvent_ignore(Event);
|
||
QWidget_setAttribute(QWidgetH(Sender), QtWA_NoMousePropagation, False);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TQtCalendar.HitTest(const APoint: TPoint): byte;
|
||
var
|
||
Layout: QLayoutH;
|
||
CalendarBody: QWidgetH;
|
||
HeaderRect, BodyRect: TRect;
|
||
AQtPoint: TQtPoint;
|
||
Index: QModelIndexH;
|
||
begin
|
||
Result := 0;
|
||
Layout := QWidget_layout(Widget);
|
||
// layout must have 2 items:
|
||
// 1 - navigation bar
|
||
// 2 - calendar model
|
||
if QLayout_count(Layout) <> 2 then
|
||
Exit;
|
||
QLayoutItem_geometry(QLayout_itemAt(Layout, 0), @HeaderRect);
|
||
QLayoutItem_geometry(QLayout_itemAt(Layout, 1), @BodyRect);
|
||
if PtInRect(HeaderRect, APoint) then
|
||
begin
|
||
// we are in the header
|
||
Result := 3;
|
||
// todo: detail result more - button / month / year
|
||
end
|
||
else
|
||
if PtInRect(BodyRect, APoint) then
|
||
begin
|
||
CalendarBody := QLayoutItem_widget(QLayout_itemAt(Layout, 1));
|
||
AQtPoint := QtPoint(APoint.X, APoint.Y);
|
||
QWidget_mapFrom(CalendarBody, @AQtPoint, Widget, @AQtPoint);
|
||
Index := QModelIndex_create();
|
||
try
|
||
QTableView_indexAt(QTableWidgetH(CalendarBody), Index, @AQtPoint);
|
||
if (QCalendarWidget_horizontalHeaderFormat(QCalendarWidgetH(Widget)) = QCalendarWidgetNoHorizontalHeader) or
|
||
(QModelIndex_row(Index) > 0) then
|
||
begin
|
||
if (QCalendarWidget_verticalHeaderFormat(QCalendarWidgetH(Widget)) = QCalendarWidgetNoVerticalHeader) or
|
||
(QModelIndex_column(Index) > 0) then
|
||
Result := 1
|
||
else
|
||
Result := 2;
|
||
end;
|
||
finally
|
||
QModelIndex_destroy(Index);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtCalendar.SetDisplaySettings(
|
||
const AHHdrFmt: QCalendarWidgetHorizontalHeaderFormat;
|
||
const AVHdrFmt: QCalendarWidgetVerticalHeaderFormat;
|
||
const ASelMode: QCalendarWidgetSelectionMode;
|
||
const ANavBarVisible: Boolean; const AGridVisible: Boolean);
|
||
begin
|
||
QCalendarWidget_setHorizontalHeaderFormat(QCalendarWidgetH(Widget), AHHdrFmt);
|
||
QCalendarWidget_setNavigationBarVisible(QCalendarWidgetH(Widget), ANavBarVisible);
|
||
QCalendarWidget_setVerticalHeaderFormat(QCalendarWidgetH(Widget), AVHdrFmt);
|
||
QCalendarWidget_setGridVisible(QCalendarWidgetH(Widget), AGridVisible);
|
||
QCalendarWidget_setSelectionMode(QCalendarWidgetH(Widget), ASelMode);
|
||
end;
|
||
|
||
procedure TQtCalendar.SetFirstDayOfWeek(const ADayOfWeek: QtDayOfWeek);
|
||
begin
|
||
QCalendarWidget_setFirstDayOfWeek(QCalendarWidgetH(Widget), ADayOfWeek);
|
||
end;
|
||
|
||
function TQtCalendar.DeliverDayChanged(ADate: QDateH): boolean;
|
||
var
|
||
y,m,d: Integer;
|
||
Msg: TLMessage;
|
||
begin
|
||
Result := False;
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_DAYCHANGED;
|
||
y := QDate_year(ADate);
|
||
m := QDate_month(ADate);
|
||
d := QDate_day(ADate);
|
||
Result := (y <> aYear) or (m <> aMonth) or (d <> aDay);
|
||
if Result then
|
||
DeliverMessage(Msg);
|
||
aYear := y;
|
||
aMonth := m;
|
||
aDay := d;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCalendar.SignalActivated
|
||
Params: None
|
||
Returns: Nothing
|
||
Sends signal when RETURN pressed on selected date.
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtCalendar.SignalActivated(ADate: QDateH); cdecl;
|
||
var
|
||
AKeyEvent: QKeyEventH;
|
||
AMouseEvent: QMouseEventH;
|
||
APos, AGlobalPos: TQtPoint;
|
||
APosF, AGlobalPosF: TQtPointF;
|
||
begin
|
||
{$IFDEF VerboseQt}
|
||
writeln('TQtCalendar.signalActivated ');
|
||
{$ENDIF}
|
||
|
||
DeliverDayChanged(ADate);
|
||
|
||
{avoid OnAcceptDate() to trigger twice if doubleclicked
|
||
via FMouseDoubleClicked, also send dummy Key events to LCL when item
|
||
activated (only QtKey_Return activates)}
|
||
if not FMouseDoubleClicked then
|
||
begin
|
||
AKeyEvent := QKeyEvent_create(QEventKeyPress, QtKey_Return, QtNoModifier);
|
||
SlotKey(Widget, AKeyEvent);
|
||
QEvent_destroy(AKeyEvent);
|
||
AKeyEvent := QKeyEvent_create(QEventKeyRelease, QtKey_Return, QtNoModifier);
|
||
SlotKey(Widget, AKeyEvent);
|
||
QEvent_destroy(AKeyEvent);
|
||
end else
|
||
begin
|
||
FMouseDoubleClicked := False;
|
||
if QWidget_underMouse(Widget) then
|
||
begin
|
||
QCursor_pos(@AGlobalPos);
|
||
QWidget_mapFromGlobal(Widget, @APos, @AGlobalPos);
|
||
APosF.X := APos.X;
|
||
APosF.Y := APos.Y;
|
||
AGlobalPosF.X := AGlobalPos.X;
|
||
AGlobalPosF.Y := AGlobalPos.Y;
|
||
AMouseEvent := QMouseEvent_create(QEventMouseButtonDblClick, @APosF,
|
||
@AGlobalPosF, QtLeftButton, QtLeftButton,
|
||
QGUIApplication_keyboardModifiers());
|
||
SlotMouse(Widget, AMouseEvent);
|
||
QMouseEvent_destroy(AMouseEvent);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCalendar.SignalClicked
|
||
Params: None
|
||
Returns: Nothing
|
||
Sends msg LM_DAYCHANGED when OldDate<>NewDate
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtCalendar.SignalClicked(ADate: QDateH); cdecl;
|
||
var
|
||
AEvent: QMouseEventH;
|
||
APos, AGlobalPos: TQtPoint;
|
||
APosF, AGlobalPosF: TQtPointF;
|
||
begin
|
||
{$IFDEF VerboseQt}
|
||
writeln('TQtCalendar.signalClicked');
|
||
{$ENDIF}
|
||
DeliverDayChanged(ADate);
|
||
|
||
if QWidget_underMouse(Widget) then
|
||
begin
|
||
{we create dummy event for LCL, and call directly SlotMouse() - no need
|
||
to send it via event loop}
|
||
QCursor_pos(@AGlobalPos);
|
||
QWidget_mapFromGlobal(Widget, @APos, @AGlobalPos);
|
||
APosF.X := APos.X;
|
||
APosF.Y := APos.Y;
|
||
AGlobalPosF.X := AGlobalPos.X;
|
||
AGlobalPosF.Y := AGlobalPos.Y;
|
||
AEvent := QMouseEvent_create(QEventMouseButtonPress, @APosF, @AGlobalPosF,
|
||
QtLeftButton, QtLeftButton, QGUIApplication_keyboardModifiers());
|
||
SlotMouse(Widget, AEvent);
|
||
QMouseEvent_destroy(AEvent);
|
||
AEvent := QMouseEvent_create(QEventMouseButtonRelease, @APosF, @AGlobalPosF,
|
||
QtLeftButton, QtLeftButton, QGUIApplication_keyboardModifiers());
|
||
SlotMouse(Widget, AEvent);
|
||
QMouseEvent_destroy(AEvent);
|
||
end;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCalendar.SignalSelectionChanged
|
||
Params: None
|
||
Returns: Nothing
|
||
|
||
Notes: no event for date changed by keyboard ?!?
|
||
always triggers even if selection isn't changed ...
|
||
this is not Qt4 bug ... tested with pure Qt C++ app
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtCalendar.SignalSelectionChanged; cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
{$IFDEF VerboseQt}
|
||
writeln('TQtCalendar.SignalSelectionChanged');
|
||
{$ENDIF}
|
||
if InUpdate then
|
||
exit;
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
Msg.Msg := LM_SELCHANGE;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtCalendar.SignalCurrentPageChanged
|
||
Params: None
|
||
Returns: Nothing
|
||
|
||
Notes: fixme what's wrong with those values ?!?
|
||
with pure Qt C++ app this works ok, but via bindings get
|
||
impossible year & month values ...
|
||
------------------------------------------------------------------------------}
|
||
procedure TQtCalendar.signalCurrentPageChanged(p1, p2: Integer); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
ADate: QDateH;
|
||
HasChanges: Boolean;
|
||
TempYear, TempMonth: Integer;
|
||
begin
|
||
{$IFDEF VerboseQt}
|
||
writeln('TQtCalendar.SignalCurrentPageChanged p1=',p1,' p2=',p2,' AMonth=',AMonth,' AYear=',AYear);
|
||
{$ENDIF}
|
||
if InUpdate then
|
||
exit;
|
||
TempYear := AYear;
|
||
TempMonth := AMonth;
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
HasChanges := (TempYear <> p1) or (TempMonth <> p2);
|
||
|
||
if HasChanges then
|
||
begin
|
||
ADate := QDate_create();
|
||
try
|
||
QCalendarWidget_selectedDate(QCalendarWidgetH(Widget), ADate);
|
||
QDate_setDate(ADate, p1, p2, QDate_day(ADate));
|
||
SetSelectedDate(ADate);
|
||
finally
|
||
QDate_destroy(ADate);
|
||
end;
|
||
end;
|
||
|
||
if TempYear <> p1 then
|
||
begin
|
||
Msg.Msg := LM_YEARCHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
if TempMonth <> p2 then
|
||
begin
|
||
Msg.Msg := LM_MONTHCHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
|
||
if HasChanges then
|
||
begin
|
||
Msg.Msg := LM_CHANGED;
|
||
DeliverMessage(Msg);
|
||
end;
|
||
end;
|
||
|
||
{ TQtHintWindow }
|
||
|
||
function TQtHintWindow.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
FFirstPaintEvent := True;
|
||
FHasPaint := True;
|
||
FNeedRestoreVisible := False;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
if QApplication_activeModalWidget <> nil then
|
||
Parent := QApplication_activeModalWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QWidget_create(Parent, QtToolTip);
|
||
FDeleteLater := True;
|
||
MenuBar := nil;
|
||
{$IFDEF QTSCROLLABLEFORMS}
|
||
ScrollArea := nil;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
function TQtHintWindow.WinIDNeeded: boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
procedure TQtHintWindow.InitializeWidget;
|
||
begin
|
||
inherited InitializeWidget;
|
||
{$IFDEF HASX11}
|
||
QtWidgetSet.AddHintHandle(Self);
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TQtHintWindow.DeInitializeWidget;
|
||
begin
|
||
{$IFDEF HASX11}
|
||
QtWidgetSet.RemoveHintHandle(Self);
|
||
{$ENDIF}
|
||
inherited DeInitializeWidget;
|
||
end;
|
||
|
||
function TQtHintWindow.CanPaintBackground: Boolean;
|
||
begin
|
||
Result := CanSendLCLMessage and getEnabled and
|
||
(LCLObject.Color <> clDefault);
|
||
end;
|
||
|
||
procedure TQtHintWindow.SetDefaultColorRoles;
|
||
begin
|
||
WidgetColorRole := QPaletteToolTipBase;
|
||
TextColorRole := QPaletteToolTipText;
|
||
end;
|
||
|
||
procedure TQtHintWindow.setVisible(AVisible: Boolean);
|
||
var
|
||
D: TRect;
|
||
R: TRect;
|
||
Pt: TQtPoint;
|
||
ScreenNumber: integer;
|
||
begin
|
||
// must use ClassType comparision here since qt is buggy about hints.#16551
|
||
if AVisible and
|
||
((LCLObject.ClassType = THintWindow) or
|
||
(LCLObject.InheritsFrom(THintWindow))) then
|
||
begin
|
||
R := getGeometry;
|
||
|
||
if QDesktopWidget_isVirtualDesktop(QApplication_desktop()) then
|
||
begin
|
||
Pt.x := R.Left;
|
||
Pt.y := R.Top;
|
||
ScreenNumber := QDesktopWidget_screenNumber(QApplication_desktop(), @Pt);
|
||
end
|
||
else
|
||
begin
|
||
if Widget <> nil then
|
||
ScreenNumber := QDesktopWidget_screenNumber(QApplication_desktop(), Widget)
|
||
else
|
||
ScreenNumber := 0;
|
||
end;
|
||
{$IFDEF DARWIN}
|
||
QDesktopWidget_availableGeometry(QApplication_desktop() ,@D, ScreenNumber);
|
||
{$ELSE}
|
||
QDesktopWidget_screenGeometry(QApplication_desktop() ,@D, ScreenNumber);
|
||
{$ENDIF}
|
||
|
||
// place hint window within monitor rect
|
||
if R.Right-R.Left > D.Right-D.Left then // check width
|
||
R.Right := R.Left + D.Right-D.Left;
|
||
if R.Bottom-R.Top > D.Bottom-D.Top then // check height
|
||
R.Bottom := R.Top + D.Bottom-D.Top;
|
||
if R.Left < D.Left then
|
||
OffsetRect(R, D.Left-R.Left, 0);
|
||
if R.Top < D.Top then
|
||
OffsetRect(R, 0, D.Top-R.Top);
|
||
if (R.Right > D.Right) then
|
||
OffsetRect(R, D.Right-R.Right, 0);
|
||
if (R.Bottom > D.Bottom) then
|
||
OffsetRect(R, 0, D.Bottom-R.Bottom);
|
||
|
||
move(R.Left, R.Top);
|
||
end;
|
||
inherited setVisible(AVisible);
|
||
end;
|
||
|
||
{ TQtPage }
|
||
|
||
function TQtPage.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
FHasPaint := True;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QWidget_create(Parent);
|
||
end;
|
||
|
||
function TQtPage.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
ASize: TSize;
|
||
ACapture: HWND;
|
||
B: Boolean;
|
||
begin
|
||
Result := False;
|
||
if LCLObject = nil then
|
||
exit;
|
||
if (QEvent_type(Event) = QEventResize) then
|
||
begin
|
||
if (csDestroying in LCLObject.ComponentState) or
|
||
(csDestroyingHandle in LCLObject.ControlState) then
|
||
exit;
|
||
if not testAttribute(QtWA_Mapped) then
|
||
begin
|
||
ASize := QResizeEvent_size(QResizeEventH(Event))^;
|
||
{$IFDEF VerboseQtResize}
|
||
DebugLn('TQtPage.EventFilter widget is not mapped, resize event size=',dbgs(ASize));
|
||
{$ENDIF}
|
||
if (ASize.cx = 0) and (ASize.cy = 0) then
|
||
begin
|
||
ASize.cx := LCLObject.Width;
|
||
ASize.cy := LCLObject.Height;
|
||
{$IFDEF VerboseQtResize}
|
||
DebugLn('TQtPage.EventFilter sending LCL size as size=',dbgs(ASize),' since our size is still 0x0');
|
||
{$ENDIF}
|
||
end;
|
||
DelayResizeEvent(QWidgetH(Sender), ASize);
|
||
exit;
|
||
end;
|
||
end else
|
||
if (QEvent_type(Event) = QEventShow) and Assigned(LCLObject) and
|
||
not (csDesigning in LCLObject.ComponentState) then
|
||
begin
|
||
if Assigned(DragManager) and DragManager.IsDragging then
|
||
ACapture := GetCapture
|
||
else
|
||
ACapture := 0;
|
||
B := (ACapture <> 0) and (ACapture <> HWND(Self));
|
||
Result := inherited EventFilter(Sender, Event);
|
||
if B then
|
||
begin
|
||
QtWidgetSet.InvalidateWidgetAtCache;
|
||
SetCapture(0);
|
||
SetCapture(HWND(Self));
|
||
end;
|
||
end else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
|
||
function TQtPage.getIcon: QIconH;
|
||
begin
|
||
Result := FIcon;
|
||
end;
|
||
|
||
function TQtPage.getIndex(const ATextChanging: Boolean = False): Integer;
|
||
var
|
||
AParent: QTabWidgetH;
|
||
|
||
function CanReturnIndex: Boolean;
|
||
begin
|
||
Result := AParent <> nil;
|
||
if Result then
|
||
Result := QWidget_isVisible(AParent) or LCLObject.HandleObjectShouldBeVisible;
|
||
end;
|
||
|
||
begin
|
||
AParent := getTabWidget;
|
||
if CanReturnIndex or ATextChanging then
|
||
Result := QTabWidget_indexOf(AParent, Widget)
|
||
else
|
||
if not QObject_inherits(QWidget_parentWidget(Widget),'QStackedWidget') then
|
||
Result := 0
|
||
else
|
||
Result := -1;
|
||
end;
|
||
|
||
function TQtPage.getTabWidget: QTabWidgetH;
|
||
var
|
||
AParent: QWidgetH;
|
||
begin
|
||
// it is placed to the stack widget and stack widget into tab widget
|
||
AParent := QWidget_parentWidget(Widget);
|
||
// do not localize !
|
||
if (AParent <> nil) and QObject_inherits(AParent,'QStackedWidget') then
|
||
Result := QTabWidgetH(QWidget_parentWidget(AParent))
|
||
else
|
||
Result := nil;
|
||
end;
|
||
|
||
procedure TQtPage.setIcon(const AIcon: QIconH);
|
||
var
|
||
AParent: QTabWidgetH;
|
||
TabWidget: TQtTabWidget;
|
||
begin
|
||
FIcon := AIcon;
|
||
AParent := getTabWidget;
|
||
if AParent <> nil then
|
||
begin
|
||
if ChildOfComplexWidget = ccwTabWidget then
|
||
begin
|
||
TabWidget := TQtTabWidget(LCLObject.Parent.Handle);
|
||
TabWidget.setTabIcon(TabWidget.indexOf(Widget), AIcon);
|
||
end else
|
||
QTabWidget_setTabIcon(AParent, getIndex, AIcon);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtPage.setText(const W: WideString);
|
||
var
|
||
AParent: QTabWidgetH;
|
||
Index: integer;
|
||
begin
|
||
inherited setText(W);
|
||
AParent := getTabWidget;
|
||
if (AParent <> nil) then
|
||
begin
|
||
Index := getIndex(True);
|
||
if Index <> -1 then
|
||
QTabWidget_setTabText(AParent, Index, @W);
|
||
end;
|
||
end;
|
||
|
||
{ TQtAbstractItemView }
|
||
|
||
function TQtAbstractItemView.GetOwnerDrawn: Boolean;
|
||
begin
|
||
Result := FNewDelegate <> nil;
|
||
end;
|
||
|
||
function TQtAbstractItemView.getIconSize: TSize;
|
||
begin
|
||
QAbstractItemView_iconSize(QAbstractItemViewH(Widget), @Result);
|
||
end;
|
||
|
||
function TQtAbstractItemView.GetItemFlags(AIndex: Integer): QtItemFlags;
|
||
begin
|
||
Result := QtNoItemFlags;
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.setIconSize(const AValue: TSize);
|
||
begin
|
||
QAbstractItemView_setIconSize(QAbstractItemViewH(Widget), @AValue);
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.SetItemFlags(AIndex: Integer; AValue: QtItemFlags
|
||
);
|
||
begin
|
||
// must be overrided !
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.SetOwnerDrawn(const AValue: Boolean);
|
||
begin
|
||
if AValue and (FNewDelegate = nil) then
|
||
begin
|
||
FNewDelegate := QLCLItemDelegate_create(Widget);
|
||
|
||
QLCLItemDelegate_override_sizeHint(FNewDelegate, @ItemDelegateSizeHint);
|
||
|
||
QLCLItemDelegate_override_Paint(FNewDelegate, @ItemDelegatePaint);
|
||
|
||
FOldDelegate := QAbstractItemView_itemDelegate(QAbstractItemViewH(Widget));
|
||
QAbstractItemView_setItemDelegate(QAbstractItemViewH(Widget), FNewDelegate);
|
||
end
|
||
else
|
||
if ((not AValue) and (FNewDelegate <> nil)) then
|
||
begin
|
||
{TQtAbstractItemView.SetOwnerDrawn: this call avoid sporadic AVs with
|
||
QLCLItemDelegate_destroy(FNewDelegate).
|
||
howto reproduce: comment next code line, recompile laz, and then in oi click
|
||
in first field eg. Action (TForm), now push kbd down arrow let it pass all properties,
|
||
you'll have crash at Constraints property.}
|
||
FNewDelegate := QLCLItemDelegateH(QAbstractItemView_itemDelegate(QAbstractItemViewH(Widget)));
|
||
QAbstractItemView_setItemDelegate(QAbstractItemViewH(Widget), FOldDelegate);
|
||
QLCLItemDelegate_destroy(FNewDelegate);
|
||
FNewDelegate := nil;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.OwnerDataNeeded(ARect: TRect);
|
||
begin
|
||
// override
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.PostponedMouseRelease(AEvent: QEventH);
|
||
// postpone mouse release for LCL
|
||
var
|
||
ev: QMouseEventH;
|
||
APos, AGlobalPos: TQtPoint;
|
||
APosF, AGlobalPosF: TQtPointF;
|
||
begin
|
||
if QEvent_type(AEvent) = QEventMouseButtonRelease then
|
||
begin
|
||
ev := QMouseEventH(AEvent);
|
||
QMouseEvent_pos(ev, @APos);
|
||
QMouseEvent_globalPos(ev, @AGlobalPos);
|
||
APosF.X := APos.X;
|
||
APosF.Y := APos.Y;
|
||
AGlobalPosF.X := AGlobalPos.X;
|
||
AGlobalPosF.Y := AGlobalPos.Y;
|
||
FSavedEvent := QMouseEvent_create(QEventMouseButtonRelease,
|
||
@APosF, @AGlobalPosF,
|
||
QMouseEvent_button(ev), QMouseEvent_buttons(ev),
|
||
QInputEvent_modifiers(QInputEventH(AEvent)));
|
||
FSavedEventTimer := QTimer_create(Widget);
|
||
FSavedEventTimerHook := QTimer_hook_create(FSavedEventTimer);
|
||
QTimer_hook_hook_timeout(FSavedEventTimerHook,
|
||
@PostponedMouseReleaseTimerEvent);
|
||
QTimer_setInterval(FSavedEventTimer, 5);
|
||
QTimer_setSingleShot(FSavedEventTimer, True);
|
||
QTimer_start(FSavedEventTimer);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.PostponedMouseReleaseTimerEvent(); cdecl;
|
||
begin
|
||
if FSavedEvent <> nil then
|
||
begin
|
||
SlotMouse(Widget, FSavedEvent);
|
||
QMouseEvent_destroy(FSavedEvent);
|
||
FSavedEvent := nil;
|
||
QTimer_hook_destroy(FSavedEventTimerHook);
|
||
QTimer_destroy(FSavedEventTimer);
|
||
FSavedEventTimer := nil;
|
||
FSavedEventTimerHook := nil;
|
||
end;
|
||
end;
|
||
|
||
constructor TQtAbstractItemView.Create(const AWinControl: TWinControl;
|
||
const AParams: TCreateParams);
|
||
begin
|
||
inherited Create(AWinControl, AParams);
|
||
FOldDelegate := nil;
|
||
FNewDelegate := nil;
|
||
end;
|
||
|
||
destructor TQtAbstractItemView.Destroy;
|
||
begin
|
||
if FNewDelegate <> nil then
|
||
SetOwnerDrawn(False);
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.signalActivated(index: QModelIndexH); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
// writeln('SIGNAL: TQtAbstractItemView.signalActivated');
|
||
FillChar(Msg{%H-}, SizeOf(Msg), 0);
|
||
Msg.Msg := LM_ACTIVATE;
|
||
DeliverMessage( Msg );
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.signalClicked(index: QModelIndexH); cdecl;
|
||
begin
|
||
{use to be overriden by descedants, don''t implement it here,
|
||
or U get in trouble with TQtListView && TQtListWidget items.}
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.signalDoubleClicked(index: QModelIndexH); cdecl;
|
||
begin
|
||
{use to be overriden by descedants, don''t implement it here,
|
||
or U get in trouble with TQtListView && TQtListWidget items.}
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.signalEntered(index: QModelIndexH); cdecl;
|
||
var
|
||
Msg: TLMessage;
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), 0);
|
||
Msg.Msg := LM_ENTER;
|
||
DeliverMessage( Msg );
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.signalPressed(index: QModelIndexH); cdecl;
|
||
begin
|
||
{should be overriden by descedants}
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.signalViewportEntered; cdecl;
|
||
begin
|
||
{should be overriden by descedants}
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FSignalActivated := QAbstractItemView_hook_create(Widget);
|
||
FSignalClicked := QAbstractItemView_hook_create(Widget);
|
||
FSignalDoubleClicked := QAbstractItemView_hook_create(Widget);
|
||
FSignalEntered := QAbstractItemView_hook_create(Widget);
|
||
FSignalPressed := QAbstractItemView_hook_create(Widget);
|
||
FSignalViewportEntered := QAbstractItemView_hook_create(Widget);
|
||
|
||
QAbstractItemView_hook_hook_activated(FSignalActivated, @SignalActivated);
|
||
|
||
QAbstractItemView_hook_hook_clicked(FSignalClicked, @SignalClicked);
|
||
|
||
QAbstractItemView_hook_hook_doubleClicked(FSignalDoubleClicked, @SignalDoubleClicked);
|
||
|
||
QAbstractItemView_hook_hook_entered(FSignalEntered, @SignalEntered);
|
||
|
||
QAbstractItemView_hook_hook_pressed(FSignalPressed, @SignalPressed);
|
||
|
||
QAbstractItemView_hook_hook_viewportEntered(FSignalViewportEntered, @SignalViewportEntered);
|
||
|
||
FAbstractItemViewportEventHook := QObject_hook_create(viewportWidget);
|
||
QObject_hook_hook_events(FAbstractItemViewportEventHook, @itemViewViewportEventFilter);
|
||
|
||
// initialize scrollbars
|
||
verticalScrollBar;
|
||
horizontalScrollBar;
|
||
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.DetachEvents;
|
||
begin
|
||
if FSignalActivated <> nil then
|
||
begin
|
||
QAbstractItemView_hook_destroy(FSignalActivated);
|
||
FSignalActivated := nil;
|
||
end;
|
||
if FSignalClicked <> nil then
|
||
begin
|
||
QAbstractItemView_hook_destroy(FSignalClicked);
|
||
FSignalClicked := nil;
|
||
end;
|
||
if FSignalDoubleClicked <> nil then
|
||
begin
|
||
QAbstractItemView_hook_destroy(FSignalDoubleClicked);
|
||
FSignalDoubleClicked := nil;
|
||
end;
|
||
if FSignalEntered <> nil then
|
||
begin
|
||
QAbstractItemView_hook_destroy(FSignalEntered);
|
||
FSignalEntered := nil;
|
||
end;
|
||
if FSignalPressed <> nil then
|
||
begin
|
||
QAbstractItemView_hook_destroy(FSignalPressed);
|
||
FSignalPressed := nil;
|
||
end;
|
||
if FSignalViewportEntered <> nil then
|
||
begin
|
||
QAbstractItemView_hook_destroy(FSignalViewportEntered);
|
||
FSignalViewportEntered := nil;
|
||
end;
|
||
if FAbstractItemViewportEventHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FAbstractItemViewportEventHook);
|
||
FAbstractItemViewportEventHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtAbstractItemView.itemViewViewportEventFilter(Sender: QObjectH;
|
||
Event: QEventH): Boolean; cdecl;
|
||
var
|
||
R: TRect;
|
||
ASize: TSize;
|
||
AResizeEvent: QResizeEventH;
|
||
begin
|
||
{we install only mouse events on QAbstractItemView viewport}
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
|
||
if (LCLObject = nil) then
|
||
exit;
|
||
|
||
BeginEventProcessing;
|
||
try
|
||
{ownerdata is needed only before qt paint's data}
|
||
if (ViewStyle >= 0) and FOwnerData and
|
||
(QEvent_type(Event) = QEventPaint) then
|
||
begin
|
||
QPaintEvent_rect(QPaintEventH(Event), @R);
|
||
OwnerDataNeeded(R);
|
||
end;
|
||
|
||
case QEvent_type(Event) of
|
||
QEventResize:
|
||
begin
|
||
if Assigned(FOwner) then
|
||
ASize := FOwner.getSize
|
||
else
|
||
ASize := getSize;
|
||
AResizeEvent := QResizeEvent_create(@ASize, @ASize);
|
||
try
|
||
SlotResize(AResizeEvent);
|
||
finally
|
||
QEvent_destroy(AResizeEvent);
|
||
end;
|
||
end;
|
||
QEventHide:
|
||
if QWidget_mouseGrabber() = QWidgetH(Sender) then
|
||
ReleaseCapture;
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonRelease,
|
||
QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
|
||
QEventContextMenu: Result := SlotContextMenu(Sender, Event);
|
||
else
|
||
begin
|
||
if not (ViewStyle in [Ord(vsIcon), Ord(vsSmallIcon)]) then
|
||
begin
|
||
{do not change selection if mousepressed and mouse moved}
|
||
Result := (QEvent_type(Event) = QEventMouseMove) and
|
||
hasFocus and (QGUIApplication_mouseButtons() > 0);
|
||
QEvent_ignore(Event);
|
||
end;
|
||
end;
|
||
end;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.setDefaultColorRoles;
|
||
begin
|
||
WidgetColorRole := QPaletteBase;
|
||
TextColorRole := QPaletteText;
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.clearSelection;
|
||
begin
|
||
QAbstractItemView_clearSelection(QAbstractItemViewH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractItemView.getModel: QAbstractItemModelH;
|
||
begin
|
||
Result := QAbstractItemView_model(QAbstractItemViewH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractItemView.getRowHeight(ARowIndex: integer): integer;
|
||
begin
|
||
Result := QAbstractItemView_sizeHintForRow(QAbstractItemViewH(Widget),
|
||
ARowIndex);
|
||
end;
|
||
|
||
function TQtAbstractItemView.getSelectionMode: QAbstractItemViewSelectionMode;
|
||
begin
|
||
Result := QAbstractItemView_SelectionMode(QAbstractItemViewH(Widget));
|
||
end;
|
||
|
||
function TQtAbstractItemView.getTopItem: integer;
|
||
begin
|
||
Result := -1;
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtAbstractItemView.getVisibleRowCount
|
||
Params: Boolean
|
||
Returns: if AFirstVisibleOnly = False (default) then it returns number
|
||
of visible rows, or 0 if there's no visible rows.
|
||
When AFirstVisibleOnly = True then it returns index of first visible row,
|
||
otherwise result is -1.
|
||
This function is used by TQtTreeWidget and TQtListWidget.
|
||
------------------------------------------------------------------------------}
|
||
function TQtAbstractItemView.getVisibleRowCount(const AFirstVisibleOnly: boolean = false): integer;
|
||
begin
|
||
Result := 0;
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.modelIndex(retval: QModelIndexH; row, column: Integer; parent: QModelIndexH = nil);
|
||
begin
|
||
QAbstractItemModel_index(getModel, retval, row, column, parent);
|
||
end;
|
||
|
||
function TQtAbstractItemView.visualRect(Index: QModelIndexH): TRect;
|
||
begin
|
||
QAbstractItemView_visualRect(QAbstractItemViewH(Widget), @Result, Index);
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.setEditTriggers(
|
||
ATriggers: QAbstractItemViewEditTriggers);
|
||
begin
|
||
QAbstractItemView_setEditTriggers(QAbstractItemViewH(Widget), ATriggers);
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.setSelectionMode(
|
||
AMode: QAbstractItemViewSelectionMode);
|
||
begin
|
||
QAbstractItemView_setSelectionMode(QAbstractItemViewH(Widget), AMode);
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.setSelectionBehavior(
|
||
ABehavior: QAbstractItemViewSelectionBehavior);
|
||
begin
|
||
QAbstractItemView_setSelectionBehavior(QAbstractItemViewH(Widget), ABehavior);
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.setWordWrap(const AValue: Boolean);
|
||
begin
|
||
// override
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.ItemDelegateSizeHint(
|
||
option: QStyleOptionViewItemH; index: QModelIndexH; Size: PSize); cdecl;
|
||
var
|
||
Msg: TLMMeasureItem;
|
||
MeasureItemStruct: TMeasureItemStruct;
|
||
decorationSize: TSize;
|
||
Metric: Integer;
|
||
begin
|
||
QStyleOptionViewItem_decorationSize(option, @decorationSize);
|
||
Metric := QStyle_pixelMetric(QApplication_style(), QStylePM_FocusFrameVMargin, nil, nil) * 2;
|
||
MeasureItemStruct.itemID := UINT(QModelIndex_row(index));
|
||
MeasureItemStruct.itemWidth := UINT(Size^.cx);
|
||
MeasureItemStruct.itemHeight := UINT(Max(Size^.cy, (decorationSize.cy + Metric)));
|
||
Msg.Msg := LM_MEASUREITEM;
|
||
Msg.MeasureItemStruct := @MeasureItemStruct;
|
||
DeliverMessage(Msg);
|
||
Size^.cx := Longint(MeasureItemStruct.itemWidth);
|
||
Size^.cy := Longint(MeasureItemStruct.itemHeight);
|
||
end;
|
||
|
||
procedure TQtAbstractItemView.ItemDelegatePaint(painter: QPainterH;
|
||
option: QStyleOptionViewItemH; index: QModelIndexH); cdecl;
|
||
begin
|
||
// should be overrided
|
||
end;
|
||
|
||
{ TQtRubberBand }
|
||
|
||
function TQtRubberBand.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QRubberBand_create(FShape, Parent);
|
||
end;
|
||
|
||
constructor TQtRubberBand.Create(const AWinControl: TWinControl;
|
||
const AParams: TCreateParams);
|
||
begin
|
||
FShape := QRubberBandLine;
|
||
inherited Create(AWinControl, AParams);
|
||
end;
|
||
|
||
procedure TQtRubberBand.move(ANewLeft, ANewTop: Integer);
|
||
begin
|
||
QRubberBand_move(QRubberBandH(Widget), ANewLeft, ANewTop);
|
||
end;
|
||
|
||
procedure TQtRubberBand.Resize(ANewWidth, ANewHeight: Integer);
|
||
begin
|
||
QRubberBand_resize(QRubberBandH(Widget), ANewWidth, ANewHeight);
|
||
end;
|
||
|
||
procedure TQtRubberBand.setGeometry(ARect: TRect);
|
||
begin
|
||
QRubberBand_setGeometry(QRubberBandH(Widget), @ARect);
|
||
end;
|
||
|
||
function TQtRubberBand.getShape: QRubberBandShape;
|
||
begin
|
||
Result := QRubberBand_shape(QRubberBandH(Widget));
|
||
end;
|
||
|
||
procedure TQtRubberBand.setShape(AShape: QRubberBandShape);
|
||
begin
|
||
if getShape <> AShape then
|
||
begin
|
||
// recreate widget
|
||
FShape := AShape;
|
||
RecreateWidget;
|
||
AttachEvents;
|
||
end;
|
||
end;
|
||
|
||
{ TQtFileDialog }
|
||
|
||
function TQtFileDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags): QWidgetH;
|
||
begin
|
||
Result := QFileDialog_create(parent, f);
|
||
{$ifndef QT_NATIVE_DIALOGS}
|
||
FBackBtn := nil;
|
||
FForwardBtn := nil;
|
||
FUpBtn := nil;
|
||
FFileNameEdit := nil;
|
||
FComboType := nil;
|
||
FComboHistory := nil;
|
||
FSideView := nil;;
|
||
FTreeView := nil;
|
||
FListView := nil;
|
||
|
||
FTreeViewEventFilter := nil; // detailed view
|
||
FListViewEventFilter := nil; // small icons
|
||
FSideViewEventFilter := nil; // sidebar
|
||
FFileNameEditEventFilter := nil; // filename editor
|
||
FComboTypeEventFilter := nil;
|
||
FComboHistoryEventFilter := nil;
|
||
{$endif}
|
||
end;
|
||
|
||
procedure TQtFileDialog.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
|
||
FCurrentChangedHook := QFileDialog_hook_create(Widget);
|
||
FDirecotyEnteredHook := QFileDialog_hook_create(Widget);
|
||
FFilterSelectedHook := QFileDialog_hook_create(Widget);
|
||
|
||
QFileDialog_hook_hook_filterSelected(FFilterSelectedHook, @FilterSelectedEvent);
|
||
|
||
QFileDialog_hook_hook_currentChanged(FCurrentChangedHook, @CurrentChangedEvent);
|
||
|
||
QFileDialog_hook_hook_directoryEntered(FDirecotyEnteredHook, @DirectoryEnteredEvent);
|
||
end;
|
||
|
||
procedure TQtFileDialog.DetachEvents;
|
||
begin
|
||
if FCurrentChangedHook <> nil then
|
||
begin
|
||
QFileDialog_hook_destroy(FCurrentChangedHook);
|
||
FCurrentChangedHook := nil;
|
||
end;
|
||
if FFilterSelectedHook <> nil then
|
||
begin
|
||
QFileDialog_hook_destroy(FFilterSelectedHook);
|
||
FFilterSelectedHook := nil;
|
||
end;
|
||
if FDirecotyEnteredHook <> nil then
|
||
begin
|
||
QFileDialog_hook_destroy(FDirecotyEnteredHook);
|
||
FDirecotyEnteredHook := nil;
|
||
end;
|
||
{$ifndef QT_NATIVE_DIALOGS}
|
||
if FTreeViewEventFilter <> nil then
|
||
begin
|
||
QObject_hook_destroy(FTreeViewEventFilter);
|
||
FTreeViewEventFilter := nil;
|
||
end;
|
||
if FListViewEventFilter <> nil then
|
||
begin
|
||
QObject_hook_destroy(FListViewEventFilter);
|
||
FListViewEventFilter := nil;
|
||
end;
|
||
if FSideViewEventFilter <> nil then
|
||
begin
|
||
QObject_hook_destroy(FSideViewEventFilter);
|
||
FSideViewEventFilter := nil;
|
||
end;
|
||
if FFileNameEditEventFilter <> nil then
|
||
begin
|
||
QObject_hook_destroy(FFileNameEditEventFilter);
|
||
FFileNameEditEventFilter := nil;
|
||
end;
|
||
if FComboTypeEventFilter <> nil then
|
||
begin
|
||
QObject_hook_destroy(FComboTypeEventFilter);
|
||
FComboTypeEventFilter := nil;
|
||
end;
|
||
if FComboHistoryEventFilter <> nil then
|
||
begin
|
||
QObject_hook_destroy(FComboHistoryEventFilter);
|
||
FComboHistoryEventFilter := nil;
|
||
end;
|
||
{$endif}
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
{$ifndef QT_NATIVE_DIALOGS}
|
||
function TQtFileDialog.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
begin
|
||
Result := False;
|
||
if Sender <> Widget then
|
||
begin
|
||
// TODO: Ctrl + Letter for Open/Save button trigger
|
||
// ALT + Left, Up, Right to navigate (Backward, Up parent, Forward) in list.
|
||
// ALT + E to focus fileedit
|
||
// ALT + H to focus lookInCombo (history combo)
|
||
// ALT + L to focus view
|
||
// ALT + N to create new folder (TODO)
|
||
// ALT + S to select sidebar
|
||
// ALT + T to focus file type combo
|
||
// ALT + V to change view style (TODO)
|
||
case QEvent_type(Event) of
|
||
QEventKeyPress:
|
||
begin
|
||
if (QKeyEvent_modifiers(QKeyEventH(Event)) and QtAltModifier <> 0) then
|
||
begin
|
||
case QKeyEvent_key(QKeyEventH(Event)) of
|
||
QtKey_Left:
|
||
begin
|
||
if Assigned(FBackBtn) and QWidget_isVisible(FBackBtn) and
|
||
QWidget_isEnabled(FBackBtn) then
|
||
QAbstractButton_click(QAbstractButtonH(FBackBtn));
|
||
Result := True;
|
||
end;
|
||
QtKey_Right:
|
||
begin
|
||
if Assigned(FForwardBtn) and QWidget_isVisible(FForwardBtn) and
|
||
QWidget_isEnabled(FForwardBtn) then
|
||
QAbstractButton_click(QAbstractButtonH(FForwardBtn));
|
||
Result := True;
|
||
end;
|
||
QtKey_Up:
|
||
begin
|
||
if Assigned(FUpBtn) and QWidget_isVisible(FUpBtn) and
|
||
QWidget_isEnabled(FUpBtn) then
|
||
QAbstractButton_click(QAbstractButtonH(FUpBtn));
|
||
Result := True;
|
||
end;
|
||
QtKey_E:
|
||
begin
|
||
if Assigned(FFileNameEdit) and
|
||
QWidget_isVisible(FFileNameEdit) and
|
||
QWidget_isEnabled(FFileNameEdit) and
|
||
not QWidget_hasFocus(FFileNameEdit) then
|
||
QWidget_setFocus(FFileNameEdit);
|
||
Result := True;
|
||
end;
|
||
QtKey_H:
|
||
begin
|
||
if Assigned(FComboHistory) and
|
||
QWidget_isVisible(FComboHistory) and
|
||
QWidget_isEnabled(FComboHistory) and
|
||
not QWidget_hasFocus(FComboHistory) then
|
||
QWidget_setFocus(FComboHistory);
|
||
Result := True;
|
||
end;
|
||
QtKey_L:
|
||
begin
|
||
if Assigned(FTreeView) and
|
||
QWidget_isVisible(FTreeView) and
|
||
QWidget_isEnabled(FTreeView) and
|
||
not QWidget_hasFocus(FTreeView) then
|
||
QWidget_setFocus(FTreeView)
|
||
else
|
||
if Assigned(FListView) and
|
||
QWidget_isVisible(FListView) and
|
||
QWidget_isEnabled(FListView) and
|
||
not QWidget_hasFocus(FListView) then
|
||
QWidget_setFocus(FListView);
|
||
Result := True;
|
||
end;
|
||
QtKey_N:
|
||
begin
|
||
//TODO: create newfolder
|
||
Result := True;
|
||
end;
|
||
QtKey_S:
|
||
begin
|
||
// select sidebar
|
||
if Assigned(FSideView) and
|
||
QWidget_isVisible(FSideView) and
|
||
QWidget_isEnabled(FSideView) and
|
||
not QWidget_hasFocus(FSideView) then
|
||
QWidget_setFocus(FSideView);
|
||
Result := True;
|
||
end;
|
||
QtKey_T:
|
||
begin
|
||
// focus combo filetype
|
||
if Assigned(FComboType) and
|
||
QWidget_isVisible(FComboType) and
|
||
QWidget_isEnabled(FComboType) and
|
||
not QWidget_hasFocus(FComboType) then
|
||
QWidget_setFocus(FComboType);
|
||
Result := True;
|
||
end;
|
||
QtKey_V:
|
||
begin
|
||
//TODO: change viewStyle
|
||
Result := True;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
{$endif}
|
||
|
||
function TQtFileDialog.selectFile: WideString;
|
||
begin
|
||
QFileDialog_selectFile(QFileDialogH(Widget), @Result);
|
||
end;
|
||
|
||
procedure TQtFileDialog.selectedFiles(retval: QStringListH);
|
||
begin
|
||
QFileDialog_selectedFiles(QFileDialogH(Widget), retval);
|
||
end;
|
||
|
||
procedure TQtFileDialog.setAcceptMode(const AMode: QFileDialogAcceptMode);
|
||
begin
|
||
QFileDialog_setAcceptMode(QFileDialogH(Widget), AMode)
|
||
end;
|
||
|
||
procedure TQtFileDialog.setConfirmOverwrite(const AValue: Boolean);
|
||
begin
|
||
QFileDialog_setConfirmOverwrite(QFileDialogH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtFileDialog.setDirectory(const ADirectory: WideString);
|
||
begin
|
||
QFileDialog_setDirectory(QFileDialogH(Widget), @ADirectory);
|
||
end;
|
||
|
||
procedure TQtFileDialog.setHistory(AList: TStrings);
|
||
var
|
||
List: QStringListH;
|
||
i: Integer;
|
||
WStr: WideString;
|
||
begin
|
||
List := QStringList_create();
|
||
try
|
||
for i := 0 to AList.Count - 1 do
|
||
begin
|
||
WStr := GetUTF8String(AList.Strings[i]);
|
||
QStringList_append(List, @WStr);
|
||
end;
|
||
QFileDialog_setHistory(QFileDialogH(Widget), List);
|
||
finally
|
||
QStringList_destroy(List);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtFileDialog.setFileMode(const AMode: QFileDialogFileMode);
|
||
begin
|
||
QFileDialog_setFileMode(QFileDialogH(Widget), AMode);
|
||
end;
|
||
|
||
procedure TQtFileDialog.setFilter(const AFilter: WideString);
|
||
begin
|
||
QFileDialog_setNameFilter(QFileDialogH(Widget), @AFilter);
|
||
end;
|
||
|
||
procedure TQtFileDialog.setLabelText(const ALabel: QFileDialogDialogLabel;
|
||
const AText: WideString);
|
||
begin
|
||
QFileDialog_setLabelText(QFileDialogH(Widget), ALabel, @AText);
|
||
end;
|
||
|
||
procedure TQtFileDialog.setReadOnly(const AReadOnly: Boolean);
|
||
begin
|
||
QFileDialog_setReadOnly(QFileDialogH(Widget), AReadOnly);
|
||
end;
|
||
|
||
procedure TQtFileDialog.setSelectedFilter(const ASelFilter: WideString);
|
||
begin
|
||
QFileDialog_selectNameFilter(QFileDialogH(Widget), @ASelFilter);
|
||
end;
|
||
|
||
procedure TQtFileDialog.setViewMode(const AMode: QFileDialogViewMode);
|
||
begin
|
||
QFileDialog_setViewMode(QFileDialogH(Widget), AMode);
|
||
end;
|
||
|
||
{------------------------------------------------------------------------------
|
||
Function: TQtFileDialog.setShortcuts
|
||
Params: None
|
||
Returns: Nothing
|
||
Qt non-native dialogs doesn't set keyboard shortcuts, so we must do that.
|
||
This functions hooks eventFilter of all widgets on QFileDialog.
|
||
------------------------------------------------------------------------------}
|
||
{$ifndef QT_NATIVE_DIALOGS}
|
||
procedure TQtFileDialog.setShortcuts(const AIsOpenDialog: Boolean);
|
||
var
|
||
AnIter: TQtObjectDump;
|
||
i: Integer;
|
||
Obj: QObjectH;
|
||
WStr: WideString;
|
||
ToolTip: WideString;
|
||
begin
|
||
// if there's auto recognition enabled then don''t set shortcuts
|
||
// cause we are maybe native dialog and then boomer.
|
||
if not QFileDialog_testOption(QFileDialogH(Widget),
|
||
QFileDialogDontUseNativeDialog) then
|
||
exit;
|
||
FForwardBtn := nil;
|
||
FBackBtn := nil;
|
||
FUpBtn := nil;
|
||
|
||
AnIter := TQtObjectDump.Create(Widget);
|
||
try
|
||
AnIter.DumpObject;
|
||
|
||
for i := 0 to AnIter.ObjList.Count - 1 do
|
||
begin
|
||
Obj := QObjectH(AnIter.Objlist.Items[i]);
|
||
if AnIter.IsWidget(Obj) then
|
||
begin
|
||
WStr := AnIter.GetObjectName(Obj);
|
||
if (WStr = 'treeView') or (WStr = 'listView') or (WStr = 'sidebar') then
|
||
begin
|
||
if FForwardBtn = nil then
|
||
begin
|
||
FForwardBtn := AnIter.FindWidgetByName('forwardButton');
|
||
if FForwardBtn <> nil then
|
||
begin
|
||
ToolTip := 'Forward (Alt + Right)';
|
||
QWidget_setToolTip(FForwardBtn, @ToolTip);
|
||
end;
|
||
end;
|
||
if FBackBtn = nil then
|
||
begin
|
||
FBackBtn := AnIter.FindWidgetByName('backButton');
|
||
if FBackBtn <> nil then
|
||
begin
|
||
ToolTip := 'Back (Alt + Left)';
|
||
QWidget_setToolTip(FBackBtn, @ToolTip);
|
||
end;
|
||
end;
|
||
if FUpBtn = nil then
|
||
begin
|
||
FUpBtn := AnIter.FindWidgetByName('toParentButton');
|
||
if FUpBtn <> nil then
|
||
begin
|
||
ToolTip := 'To parent directory (Alt + Up)';
|
||
QWidget_setToolTip(FUpBtn, @ToolTip);
|
||
end;
|
||
end;
|
||
|
||
if FForwardBtn <> nil then
|
||
begin
|
||
if WStr = 'treeView' then
|
||
begin
|
||
FTreeView := QWidgetH(Obj);
|
||
FTreeViewEventFilter := QObject_hook_create(Obj);
|
||
QObject_hook_hook_events(FTreeViewEventFilter, @EventFilter);
|
||
ToolTip := 'Alt + L to focus this widget';
|
||
QWidget_setToolTip(FTreeView, @ToolTip);
|
||
end else
|
||
if WStr = 'listView' then
|
||
begin
|
||
FListView := QWidgetH(Obj);
|
||
FListViewEventFilter := QObject_hook_create(Obj);
|
||
QObject_hook_hook_events(FListViewEventFilter, @EventFilter);
|
||
ToolTip := 'Alt + L to focus this widget';
|
||
QWidget_setToolTip(FListView, @ToolTip);
|
||
end else
|
||
if WStr = 'sidebar' then
|
||
begin
|
||
FSideView := QWidgetH(Obj);
|
||
FSideViewEventFilter := QObject_hook_create(Obj);
|
||
QObject_hook_hook_events(FSideViewEventFilter, @EventFilter);
|
||
ToolTip := 'Alt + S to focus this widget';
|
||
QWidget_setToolTip(FSideView, @ToolTip);
|
||
end;
|
||
|
||
end;
|
||
end else
|
||
if WStr = 'fileNameEdit' then
|
||
begin
|
||
FFileNameEdit := QWidgetH(Obj);
|
||
FFileNameEditEventFilter := QObject_hook_create(Obj);
|
||
QObject_hook_hook_events(FFileNameEditEventFilter, @EventFilter);
|
||
ToolTip := 'Alt + E to focus this widget';
|
||
QWidget_setToolTip(FFileNameEdit, @ToolTip);
|
||
end else
|
||
if WStr = 'fileTypeCombo' then
|
||
begin
|
||
FComboType := QWidgetH(Obj);
|
||
FComboTypeEventFilter := QObject_hook_create(Obj);
|
||
QObject_hook_hook_events(FComboTypeEventFilter, @EventFilter);
|
||
ToolTip := 'Alt + T to focus this widget';
|
||
QWidget_setToolTip(FComboType, @ToolTip);
|
||
end else
|
||
if WStr = 'lookInCombo' then
|
||
begin
|
||
FComboHistory := QWidgetH(Obj);
|
||
FComboHistoryEventFilter := QObject_hook_create(Obj);
|
||
QObject_hook_hook_events(FComboHistoryEventFilter, @EventFilter);
|
||
ToolTip := 'Alt + H to focus this widget';
|
||
QWidget_setToolTip(FComboHistory, @ToolTip);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
finally
|
||
AnIter.Free;
|
||
end;
|
||
end;
|
||
{$endif}
|
||
|
||
procedure TQtFileDialog.FilterSelectedEvent(filter: PWideString); cdecl;
|
||
var
|
||
List: TQtStringList;
|
||
index: Integer;
|
||
begin
|
||
if filter <> nil then
|
||
begin
|
||
List := TQtStringList.Create;
|
||
getFilters(List.Handle);
|
||
index := List.IndexOf(UTF16ToUTF8(filter^));
|
||
if index <> -1 then
|
||
TFileDialog(FDialog).IntfFileTypeChanged(index + 1);
|
||
List.Free;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtFileDialog.CurrentChangedEvent(path: PWideString); cdecl;
|
||
begin
|
||
if FDialog is TOpenDialog then
|
||
begin
|
||
TOpenDialog(FDialog).FileName := UTF16ToUTF8(path^);
|
||
TOpenDialog(FDialog).DoSelectionChange;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtFileDialog.DirectoryEnteredEvent(directory: PWideString); cdecl;
|
||
begin
|
||
if FDialog is TOpenDialog then
|
||
TOpenDialog(FDialog).DoFolderChange;
|
||
end;
|
||
|
||
procedure TQtFileDialog.getFilters(const retval: QStringListH);
|
||
begin
|
||
QFileDialog_nameFilters(QFileDialogH(Widget), retval);
|
||
end;
|
||
|
||
{ TQtFilePreviewDialog }
|
||
|
||
function TQtFilePreviewDialog.CreateWidget(parent: QWidgetH; f: QtWindowFlags
|
||
): QWidgetH;
|
||
begin
|
||
{$ifndef QT_NATIVE_DIALOGS}
|
||
FPreviewWidget := nil;
|
||
FTextWidget := nil;
|
||
{$endif}
|
||
Result := inherited CreateWidget(parent, f);
|
||
end;
|
||
|
||
{$ifndef QT_NATIVE_DIALOGS}
|
||
|
||
procedure TQtFilePreviewDialog.initializePreview(
|
||
const APreviewControl: TWinControl);
|
||
var
|
||
ALayout: QGridLayoutH;
|
||
ATitle: WideString;
|
||
W, H: Integer;
|
||
begin
|
||
ALayout := QGridLayoutH(QWidget_layout(Widget));
|
||
ATitle := 'No image';
|
||
FTextWidget := QLabel_create(PWideString(@ATitle), Widget);
|
||
QFrame_setFrameShape(FTextWidget, QFrameStyledPanel);
|
||
QLabel_setWordWrap(FTextWidget, True);
|
||
QLabel_setScaledContents(FTextWidget, True);
|
||
QLabel_setAlignment(FTextWidget, QtAlignCenter);
|
||
ATitle := '';
|
||
FPreviewWidget := QLabel_create(PWideString(@ATitle), Widget);
|
||
QLabel_setAlignment(FPreviewWidget, QtAlignCenter);
|
||
|
||
W := QWidget_width(Widget) div 5;
|
||
H := W;
|
||
|
||
if Assigned(APreviewControl) then
|
||
begin
|
||
APreviewControl.Width := W;
|
||
APreviewControl.Height := H;
|
||
end;
|
||
|
||
QWidget_setGeometry(FTextWidget, 0, 0, W, 32);
|
||
QWidget_setMaximumHeight(FTextWidget, 32);
|
||
QWidget_setMaximumWidth(FTextWidget, W);
|
||
QWidget_setMinimumWidth(FTextWidget, W);
|
||
|
||
QWidget_setGeometry(FPreviewWidget, 0, 0, W, H);
|
||
QWidget_setMaximumHeight(FPreviewWidget, H);
|
||
QWidget_setMaximumWidth(FPreviewWidget, W);
|
||
QLabel_setScaledContents(FPreviewWidget, True);
|
||
(*
|
||
do not use layout, Qt asserts with message that another layout already exists.
|
||
ABox := QVBoxLayout_create(Widget);
|
||
QBoxLayout_addWidget(ABox, FTextWidget, 0, QtAlignTop);
|
||
// QBoxLayout_addWidget();
|
||
QBoxLayout_addWidget(ABox, FPreviewWidget, 0, QtAlignCenter);
|
||
QBoxLayout_addStretch(ABox);
|
||
*)
|
||
QGridLayout_addWidget(ALayout, FTextWidget, 1, 3, 3, 1, QtAlignTop);
|
||
QGridLayout_addWidget(ALayout, FPreviewWidget, 1, 3, 3, 1, QtAlignCenter);
|
||
QGridLayout_columnStretch(ALayout, 3);
|
||
end;
|
||
|
||
procedure TQtFilePreviewDialog.CurrentChangedEvent(path: PWideString); cdecl;
|
||
var
|
||
APixmap: QPixmapH;
|
||
ATitle: WideString;
|
||
ASize: TSize;
|
||
ANewPixmap: QPixmapH;
|
||
begin
|
||
if Assigned(FPreviewWidget) then
|
||
begin
|
||
APixmap := QPixmap_create(path);
|
||
if QPixmap_isNull(APixmap) then
|
||
begin
|
||
ATitle := 'Not an image';
|
||
QLabel_setText(FTextWidget, @ATitle);
|
||
ATitle := ' ';
|
||
QLabel_setText(FPreviewWidget, @ATitle);
|
||
QWidget_setToolTip(FTextWidget, @ATitle);
|
||
QWidget_setToolTip(FPreviewWidget, @ATitle);
|
||
QPixmap_destroy(APixmap);
|
||
end else
|
||
begin
|
||
QPixmap_size(APixmap, @ASize);
|
||
if path <> nil then
|
||
ATitle := '' // ExtractFileName(path^)
|
||
else
|
||
ATitle := 'error file';
|
||
if path <> nil then
|
||
ATitle := Format('%d x %d x %d',[ASize.cx, ASize.cy, QPixmap_depth(APixmap)]);
|
||
QLabel_setText(FTextWidget, @ATitle);
|
||
ATitle := ExtractFileName(path^);
|
||
QWidget_setToolTip(FTextWidget, @ATitle);
|
||
ATitle := ATitle + LineEnding + Format('w %d x h %d x %d',[ASize.cx, ASize.cy, QPixmap_depth(APixmap)]);
|
||
QWidget_setToolTip(FPreviewWidget, @ATitle);
|
||
ANewPixmap := QPixmap_create;
|
||
// QPixmap_scaled(APixmap, ANewPixmap,
|
||
// 128, 128, QtKeepAspectRatio, QtSmoothTransformation);
|
||
QLabel_setPixmap(FPreviewWidget, APixmap);
|
||
QPixmap_destroy(APixmap);
|
||
QPixmap_destroy(ANewPixmap);
|
||
end;
|
||
|
||
end;
|
||
TOpenDialog(FDialog).FileName := UTF16ToUTF8(path^);
|
||
TOpenDialog(FDialog).DoSelectionChange;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
{ TQtGraphicView }
|
||
|
||
function TQtGraphicsView.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
var
|
||
Parent: QWidgetH;
|
||
begin
|
||
FHasPaint := True;
|
||
if AParams.WndParent <> 0 then
|
||
Parent := TQtWidget(AParams.WndParent).GetContainerWidget
|
||
else
|
||
Parent := nil;
|
||
Result := QGraphicsView_create(Parent);
|
||
end;
|
||
|
||
{ TQtDesignWidget }
|
||
|
||
function TQtDesignWidget.CreateWidget(const AParams: TCreateParams): QWidgetH;
|
||
begin
|
||
Result := inherited CreateWidget(AParams);
|
||
FDesignControl := QWidget_create(Result);
|
||
QWidget_setMouseTracking(FDesignControl, True);
|
||
setProperty(FDesignControl, 'lclwidget', Int64(PtrUInt(Self)));
|
||
QtWidgetSet.AddHandle(Self);
|
||
BringDesignerToFront;
|
||
end;
|
||
|
||
procedure TQtDesignWidget.DestroyWidget;
|
||
begin
|
||
inherited DestroyWidget;
|
||
FDesignControl := nil;
|
||
end;
|
||
|
||
procedure TQtDesignWidget.SlotDesignControlPaint(Sender: QObjectH; Event: QEventH); cdecl;
|
||
var
|
||
Msg: TLMPaint;
|
||
AStruct: PPaintStruct;
|
||
P: TPoint;
|
||
B: Boolean;
|
||
begin
|
||
{$ifdef VerboseQt}
|
||
WriteLn('TQtDesignWidget.SlotDesignControlPaint ', dbgsName(LCLObject));
|
||
{$endif}
|
||
|
||
if (LCLObject is TWinControl) then
|
||
begin
|
||
FillChar(Msg{%H-}, SizeOf(Msg), #0);
|
||
|
||
Msg.Msg := LM_PAINT;
|
||
New(AStruct);
|
||
FillChar(AStruct^, SizeOf(TPaintStruct), 0);
|
||
Msg.PaintStruct := AStruct;
|
||
|
||
with PaintData do
|
||
begin
|
||
PaintWidget := FDesignControl;
|
||
ClipRegion := QPaintEvent_Region(QPaintEventH(Event));
|
||
if ClipRect = nil then
|
||
New(ClipRect);
|
||
QPaintEvent_Rect(QPaintEventH(Event), ClipRect);
|
||
end;
|
||
|
||
Msg.DC := BeginPaint(THandle(Self), AStruct^);
|
||
FDesignContext := Msg.DC;
|
||
|
||
Msg.PaintStruct^.rcPaint := PaintData.ClipRect^;
|
||
Msg.PaintStruct^.hdc := FDesignContext;
|
||
|
||
P := getClientOffset;
|
||
inc(P.X, FScrollX);
|
||
inc(P.Y, FScrollY);
|
||
TQtDeviceContext(Msg.DC).translate(P.X, P.Y);
|
||
|
||
// send paint message
|
||
try
|
||
// Saving clip rect and clip region
|
||
try
|
||
LCLObject.WindowProc(TLMessage(Msg));
|
||
finally
|
||
Dispose(PaintData.ClipRect);
|
||
Fillchar(FPaintData, SizeOf(FPaintData), 0);
|
||
FDesignContext := 0;
|
||
EndPaint(THandle(Self), AStruct^);
|
||
Dispose(AStruct);
|
||
end;
|
||
except
|
||
// prevent recursive repainting !
|
||
B := (Sender <> nil) and QtWidgetSet.IsValidHandle(HWND(Self));
|
||
if B then
|
||
QWidget_setUpdatesEnabled(QWidgetH(Sender), False);
|
||
try
|
||
Application.HandleException(nil);
|
||
finally
|
||
if B and Assigned(Application) and not Application.Terminated then
|
||
QWidget_setUpdatesEnabled(QWidgetH(Sender), True);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtDesignWidget.BringDesignerToFront;
|
||
begin
|
||
if FDesignControl <> nil then
|
||
QWidget_raise(FDesignControl);
|
||
end;
|
||
|
||
procedure TQtDesignWidget.ResizeDesigner;
|
||
var
|
||
R: TRect;
|
||
begin
|
||
if FDesignControl = nil then
|
||
Exit;
|
||
// FDesignControl must be same as form area,
|
||
// since we use QWidget, not QMainWindow in design time.
|
||
QWidget_contentsRect(Widget, @R);
|
||
with R do
|
||
begin
|
||
QWidget_move(FDesignControl, Left, Top);
|
||
QWidget_resize(FDesignControl, Right - Left, Bottom - Top);
|
||
end;
|
||
end;
|
||
|
||
function TQtDesignWidget.GetContext: HDC;
|
||
begin
|
||
if FDesignContext <> 0 then
|
||
Result := FDesignContext
|
||
else
|
||
Result := FContext;
|
||
end;
|
||
|
||
function TQtDesignWidget.DesignControlEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
var
|
||
p, AGlobalPos: TQtPoint;
|
||
APosF, AGlobalPosF: TQtPointF;
|
||
pt: TPoint;
|
||
R: TRect;
|
||
Control: TControl;
|
||
MouseEvent: QMouseEventH;
|
||
WidgetToNotify: QWidgetH;
|
||
WSQtWidget: TWSWinControlClass;
|
||
Action: QActionH;
|
||
AWidget: TQtWidget;
|
||
ATabWidget: TQtTabWidget;
|
||
ATabIndex: Integer;
|
||
begin
|
||
Result := False;
|
||
QEvent_Accept(Event);
|
||
if LCLObject = nil then
|
||
exit;
|
||
if QEvent_type(Event) = QEventDestroy then
|
||
begin
|
||
{FDesignControl is always destroyed by it's parent,
|
||
only thing we need is to remove dynamic property.}
|
||
RemoveProperty(FDesignControl,'lclwidget');
|
||
exit;
|
||
end;
|
||
BeginEventProcessing;
|
||
try
|
||
case QEvent_type(Event) of
|
||
QEventMouseButtonPress,
|
||
QEventMouseButtonRelease:
|
||
begin
|
||
QMouseEvent_pos(QMouseEventH(Event), @p);
|
||
OffsetMousePos(@p);
|
||
pt := Point(p.x, p.y);
|
||
Control := LCLObject.ControlAtPos(pt, [capfRecursive, capfAllowWinControls]);
|
||
|
||
if Control is TWinControl then
|
||
begin
|
||
AWidget := TQtWidget(TWinControl(Control).Handle);
|
||
if (Control is TCustomTabControl) and
|
||
(AWidget.ChildOfComplexWidget <> ccwTTabControl) then
|
||
WidgetToNotify := TQtTabWidget(TWinControl(Control).Handle).TabBar.Widget
|
||
else
|
||
WidgetToNotify := TQtWidget(TWinControl(Control).Handle).Widget;
|
||
|
||
QMouseEvent_pos(QMouseEventH(Event), @p);
|
||
QWidget_mapFrom(WidgetToNotify, @p, Widget, @p);
|
||
Pt := Point(p.x, p.y);
|
||
|
||
WSQtWidget := TWSWinControlClass(TWinControl(Control).WidgetSetClass);
|
||
|
||
if WSQtWidget.GetDesignInteractive(TWinControl(Control), Pt) then
|
||
begin
|
||
if (Control is TCustomTabControl) and
|
||
(AWidget.ChildOfComplexWidget <> ccwTTabControl) then
|
||
begin
|
||
ATabWidget := TQtTabWidget(TWinControl(Control).Handle);
|
||
ATabIndex := ATabWidget.tabAt(Pt);
|
||
if ATabIndex >= 0 then
|
||
ATabWidget.setCurrentIndex(ATabIndex);
|
||
end else
|
||
begin
|
||
QMouseEvent_globalpos(QMouseEventH(Event), @AGlobalPos);
|
||
APosF.X := P.X;
|
||
APosF.Y := P.y;
|
||
AGlobalPosF.X := AGlobalPos.X;
|
||
AGlobalPosF.Y := AGlobalPos.Y;
|
||
MouseEvent := QMouseEvent_create(QEvent_type(Event), @APosF,
|
||
@AGlobalPosF,
|
||
QMouseEvent_button(QMouseEventH(Event)),
|
||
QMouseEvent_buttons(QMouseEventH(Event)),
|
||
QInputEvent_modifiers(QInputEventH(Event))
|
||
);
|
||
QCoreApplication_postEvent(WidgetToNotify, MouseEvent, 1);
|
||
end;
|
||
end;
|
||
end else
|
||
begin
|
||
QMouseEvent_globalPos(QMouseEventH(Event), @p);
|
||
WidgetToNotify := QApplication_widgetAt(@p);
|
||
if (WidgetToNotify <> nil) then
|
||
begin
|
||
if TQtMainWindow(Self).MenuBar.Widget <> nil then
|
||
begin
|
||
QMouseEvent_Pos(QMouseEventH(Event), @p);
|
||
QWidget_geometry(TQtMainWindow(Self).MenuBar.Widget, @R);
|
||
pt := Point(P.X, P.Y);
|
||
if LCLIntf.PtInRect(R, pt) then
|
||
begin
|
||
Action := QMenuBar_actionAt(QMenuBarH(TQtMainWindow(Self).MenuBar.Widget), @p);
|
||
if Action <> nil then
|
||
begin
|
||
QCoreApplication_notify(QCoreApplication_instance(), TQtMainWindow(Self).MenuBar.Widget, Event);
|
||
QEvent_accept(Event);
|
||
Result := True;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
QEventPaint: SlotDesignControlPaint(Sender, Event);
|
||
end;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end;
|
||
|
||
function TQtDesignWidget.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
begin
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject = nil then
|
||
exit;
|
||
|
||
BeginEventProcessing;
|
||
try
|
||
case QEvent_type(Event) of
|
||
QEventWindowActivate:
|
||
begin
|
||
Result := inherited EventFilter(Sender, Event);
|
||
setFocus;
|
||
BringDesignerToFront;
|
||
end;
|
||
QEventChildAdded,
|
||
QEventChildRemoved: BringDesignerToFront;
|
||
QEventResize:
|
||
begin
|
||
Result := inherited EventFilter(Sender, Event);
|
||
ResizeDesigner;
|
||
end;
|
||
else
|
||
Result := inherited EventFilter(Sender, Event);
|
||
end;
|
||
finally
|
||
EndEventProcessing;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtDesignWidget.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
if FDesignControl <> nil then
|
||
begin
|
||
FDesignControlEventHook := QObject_hook_create(FDesignControl);
|
||
QObject_hook_hook_events(FDesignControlEventHook, @DesignControlEventFilter);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtDesignWidget.DetachEvents;
|
||
begin
|
||
if FDesignControlEventHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FDesignControlEventHook);
|
||
FDesignControlEventHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
procedure TQtDesignWidget.lowerWidget;
|
||
begin
|
||
inherited lowerWidget;
|
||
BringDesignerToFront;
|
||
end;
|
||
|
||
procedure TQtDesignWidget.raiseWidget;
|
||
begin
|
||
inherited raiseWidget;
|
||
BringDesignerToFront;
|
||
end;
|
||
|
||
{ TQtMessageBox }
|
||
|
||
function TQtMessageBox.getMsgBoxType: QMessageBoxIcon;
|
||
begin
|
||
Result := QMessageBox_icon(QMessageBoxH(Widget));
|
||
end;
|
||
|
||
function TQtMessageBox.GetTextFormat: QtTextFormat;
|
||
begin
|
||
Result := QMessageBox_textFormat(QMessageBoxH(Widget));
|
||
end;
|
||
|
||
procedure TQtMessageBox.setDetailText(const AValue: WideString);
|
||
var
|
||
Str: WideString;
|
||
begin
|
||
Str := GetUTF8String(AValue);
|
||
QMessageBox_setDetailedText(QMessageBoxH(Widget), @Str);
|
||
end;
|
||
|
||
function TQtMessageBox.getMessageStr: WideString;
|
||
var
|
||
Str: WideString;
|
||
begin
|
||
QMessageBox_text(QMessageBoxH(Widget), @Str);
|
||
Result := UTF16ToUTF8(Str);
|
||
end;
|
||
|
||
function TQtMessageBox.getDetailText: WideString;
|
||
var
|
||
Str: WideString;
|
||
begin
|
||
QMessageBox_detailedText(QMessageBoxH(Widget), @Str);
|
||
Result := UTF16ToUTF8(Str);
|
||
end;
|
||
|
||
procedure TQtMessageBox.setMessageStr(const AValue: WideString);
|
||
var
|
||
Str: WideString;
|
||
begin
|
||
Str := GetUTF8String(AValue);
|
||
QMessageBox_setText(QMessageBoxH(Widget), @Str);
|
||
end;
|
||
|
||
procedure TQtMessageBox.setMsgBoxType(const AValue: QMessageBoxIcon);
|
||
begin
|
||
QMessageBox_setIcon(QMessageBoxH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtMessageBox.SetTextFormat(AValue: QtTextFormat);
|
||
begin
|
||
QMessageBox_setTextFormat(QMessageBoxH(Widget), AValue);
|
||
end;
|
||
|
||
procedure TQtMessageBox.setTitle(const AValue: WideString);
|
||
begin
|
||
if AValue <> FTitle then
|
||
begin
|
||
FTitle := GetUTF8String(AValue);
|
||
QMessageBox_setWindowTitle(QMessageBoxH(Widget), @FTitle);
|
||
end;
|
||
end;
|
||
|
||
function TQtMessageBox.CreateWidget(AParent: QWidgetH): QWidgetH;
|
||
begin
|
||
FHasPaint := False;
|
||
Result := QMessageBox_create(AParent);
|
||
QMessageBox_setWindowModality(QMessageBoxH(Result), QtApplicationModal);
|
||
end;
|
||
|
||
constructor TQtMessageBox.Create(AParent: QWidgetH);
|
||
begin
|
||
WidgetColorRole := QPaletteWindow;
|
||
TextColorRole := QPaletteWindowText;
|
||
FOwner := nil;
|
||
FCentralWidget := nil;
|
||
FOwnWidget := True;
|
||
FProps := nil;
|
||
LCLObject := nil;
|
||
FKeysToEat := [];
|
||
FHasPaint := False;
|
||
{$IFDEF TQTMESSAGEBOXUSEPARENT}
|
||
if AParent = nil then
|
||
AParent := QApplication_activeWindow;
|
||
{$ENDIF}
|
||
Widget := CreateWidget(AParent);
|
||
{$IFNDEF QTDIALOGSUSEHTMLTEXT}
|
||
TextFormat := QtPlainText;
|
||
{$ENDIF}
|
||
setProperty(Widget, 'lclwidget', Int64(PtrUInt(Self)));
|
||
QtWidgetSet.AddHandle(Self);
|
||
end;
|
||
|
||
procedure TQtMessageBox.AttachEvents;
|
||
begin
|
||
inherited AttachEvents;
|
||
FMBEventHook := QObject_hook_create(Widget);
|
||
QObject_hook_hook_events(FMBEventHook, @EventFilter);
|
||
end;
|
||
|
||
procedure TQtMessageBox.DetachEvents;
|
||
begin
|
||
if FMBEventHook <> nil then
|
||
begin
|
||
QObject_hook_destroy(FMBEventHook);
|
||
FMBEventHook := nil;
|
||
end;
|
||
inherited DetachEvents;
|
||
end;
|
||
|
||
function TQtMessageBox.EventFilter(Sender: QObjectH; Event: QEventH): Boolean;
|
||
cdecl;
|
||
begin
|
||
{we'll need it later. QMessageBox uses it's own eventLoop !}
|
||
Result := False;
|
||
QEvent_accept(Event);
|
||
if LCLObject <> nil then
|
||
Result := inherited EventFilter(Sender, Event)
|
||
else
|
||
begin
|
||
case QEvent_type(Event) of
|
||
QEventKeyPress:
|
||
begin
|
||
if (QKeyEvent_key(QKeyEventH(Event)) = QtKey_Escape) and
|
||
(QMessageBox_escapeButton(QMessageBoxH(Sender)) = nil) then
|
||
begin
|
||
QDialog_done(QDialogH(Sender), Ord(QDialogRejected));
|
||
Result := True;
|
||
end;
|
||
end;
|
||
QEventClose:
|
||
begin
|
||
if QMessageBox_escapeButton(QMessageBoxH(Sender)) = nil then
|
||
begin
|
||
QDialog_done(QDialogH(Sender), Ord(QDialogRejected));
|
||
Result := True;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtMessageBox.SetButtonProps(ABtn: QPushButtonH; AResult: Int64; const ADefaultBtn: Boolean; const AEscapeBtn: Boolean);
|
||
var
|
||
v: QVariantH;
|
||
begin
|
||
if ADefaultBtn then
|
||
QMessageBox_setDefaultButton(QMessageBoxH(Widget), ABtn);
|
||
|
||
if AEscapeBtn then
|
||
QMessageBox_setEscapeButton(QMessageBoxH(Widget), ABtn);
|
||
|
||
v := QVariant_create(AResult);
|
||
try
|
||
QObject_setProperty(ABtn, 'lclmsgboxbutton', v);
|
||
finally
|
||
QVariant_destroy(v);
|
||
end;
|
||
end;
|
||
|
||
function TQtMessageBox.AddButton(ACaption: WideString; ABtnType: QMessageBoxStandardButton;
|
||
AResult: Int64; const ADefaultBtn: Boolean; const AEscapeBtn: Boolean): QPushButtonH;
|
||
var
|
||
Str: WideString;
|
||
begin
|
||
Result := QMessageBox_addButton(QMessageBoxH(Widget), ABtnType);
|
||
Str := GetUTF8String(ACaption);
|
||
QAbstractButton_setText(Result, @Str);
|
||
SetButtonProps(Result, AResult, ADefaultBtn, AEscapeBtn);
|
||
end;
|
||
|
||
function TQtMessageBox.AddButton(ACaption: WideString; AResult: Int64; const ADefaultBtn: Boolean;
|
||
const AEscapeBtn: Boolean): QPushButtonH;
|
||
var
|
||
Str: WideString;
|
||
begin
|
||
Str := GetUTF8String(ACaption);
|
||
Result := QMessageBox_addButton(QMessageBoxH(Widget), @Str, QMessageBoxActionRole);
|
||
SetButtonProps(Result, AResult, ADefaultBtn, AEscapeBtn);
|
||
end;
|
||
|
||
function TQtMessageBox.exec: Int64;
|
||
var
|
||
ABtn: QPushButtonH;
|
||
v: QVariantH;
|
||
ok: Boolean;
|
||
QResult: Int64;
|
||
begin
|
||
Result := mrCancel;
|
||
{$IFDEF QTDIALOGS_USES_QT_LOOP}
|
||
QDialog_exec(QMessageBoxH(Widget));
|
||
{$ELSE}
|
||
QMessageBox_setWindowModality(QMessageBoxH(Widget), QtApplicationModal);
|
||
QWidget_show(Widget);
|
||
|
||
{$IFDEF HASX11}
|
||
if (QtWidgetSet.WindowManagerName = 'metacity') then
|
||
X11Raise(QWidget_winID(Widget));
|
||
{$ENDIF}
|
||
{$IFDEF TQTMESSAGEBOXUSEPARENT}
|
||
QWidget_activateWindow(Widget);
|
||
QWidget_raise(Widget);
|
||
{$ENDIF}
|
||
|
||
repeat
|
||
QCoreApplication_processEvents();
|
||
Application.Idle(true);
|
||
until not QWidget_isVisible(Widget) or Application.Terminated;
|
||
{$ENDIF}
|
||
ABtn := QPushButtonH(QMessageBox_clickedButton(QMessageBoxH(Widget)));
|
||
if ABtn <> nil then
|
||
begin
|
||
v := QVariant_create();
|
||
try
|
||
QObject_property(ABtn, v, 'lclmsgboxbutton');
|
||
if QVariant_isValid(v) then
|
||
begin
|
||
QResult := QVariant_toLongLong(v, @Ok);
|
||
if Ok then
|
||
Result := QResult;
|
||
end;
|
||
finally
|
||
QVariant_destroy(v);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
|
||
{$IFDEF QTACCESSIBILITY}
|
||
function LazRoleToQtRole(ALazRole: TLazAccessibilityRole): QAccessibleRole;
|
||
begin
|
||
case ALazRole of
|
||
larIgnore: Result := QAccessibleClient; // Qt follows ATSPI roles and doesn't have an ignore
|
||
larAnimation: Result := QAccessibleAnimation;
|
||
larButton: Result := QAccessibleButton;
|
||
larCell: Result := QAccessibleCell;
|
||
larChart: Result := QAccessibleChart;
|
||
larCheckBox: Result := QAccessibleCheckBox;
|
||
larClock: Result := QAccessibleClock;
|
||
larColorPicker: Result := QAccessibleColorChooser;
|
||
larColumn: Result := QAccessibleColumn;
|
||
larComboBox: Result := QAccessibleComboBox;
|
||
larDateField: Result := QAccessibleStaticText;
|
||
larGrid: Result := QAccessibleTable;
|
||
larGroup: Result := QAccessibleGrouping;
|
||
larImage: Result := QAccessibleGraphic;
|
||
larLabel: Result := QAccessibleStaticText;
|
||
larListBox: Result := QAccessibleList;
|
||
larListItem: Result := QAccessibleListItem;
|
||
larMenuBar: Result := QAccessibleMenuBar;
|
||
larMenuItem: Result := QAccessibleMenuItem;
|
||
larProgressIndicator: Result := QAccessibleProgressBar;
|
||
larRadioButton: Result := QAccessibleRadioButton;
|
||
larResizeGrip: Result := QAccessibleGrip;
|
||
larRow: Result := QAccessibleRow;
|
||
larScrollBar: Result := QAccessibleScrollBar;
|
||
larSpinner: Result := QAccessibleSpinBox;
|
||
larTabControl: Result := QAccessiblePageTab;
|
||
larText: Result := QAccessibleSTaticText;
|
||
larTextEditorMultiline: Result := QAccessibleEditableText;
|
||
larTextEditorSingleline: Result := QAccessibleEditableText;
|
||
larToolBar: Result := QAccessibleToolBar;
|
||
larToolBarButton: Result := QAccessibleButton;
|
||
larTrackBar: Result := QAccessibleSlider;
|
||
larTreeView: Result := QAccessibleTree;
|
||
larTreeItem: Result := QAccessibleTreeItem;
|
||
larWindow: Result := QAccessibleWindow;
|
||
else
|
||
// including larIgnore, larUnknown
|
||
Result := QAccessibleNoRole;
|
||
end;
|
||
end;
|
||
|
||
function CreateAccessibleName(AObject: TLazAccessibleObject): String;
|
||
var
|
||
TargControl: TControl;
|
||
S: String;
|
||
begin
|
||
S := '';
|
||
if Assigned(AObject) then begin
|
||
if AObject.AccessibleName <> '' then
|
||
S := AObject.AccessibleName;
|
||
if (S = '') and (AObject.OwnerControl <> nil) then begin
|
||
TargControl := AObject.OwnerControl;
|
||
S := TargControl.Caption;
|
||
if S = '' then
|
||
S := TargControl.Name;
|
||
if S = '' then
|
||
S := TargControl.ClassName;
|
||
end;
|
||
end;
|
||
Result := S;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
function LCLControlRectToQtScreenRect(ARect: TRect; AControl: TControl): TRect;
|
||
var
|
||
Pt: TPoint;
|
||
begin
|
||
Pt := AControl.ClientToScreen(ARect.TopLeft);
|
||
Result := Rect(Pt.X, Pt.Y, Pt.X + ARect.Width, Pt.Y + ARect.Height);
|
||
end;
|
||
|
||
function QtScreenPointToLCLControlPoint(APoint: TPoint; AControl: TControl): TPoint;
|
||
begin
|
||
Result := AControl.ScreenToClient(APoint);
|
||
end;
|
||
|
||
{$IFDEF QTACCESSIBILITY}
|
||
function QtAxFactory(name: QStringH; obj: QObjectH): QAccessibleInterfaceH; cdecl;
|
||
var
|
||
CreateLCLAccessibleInterface: Boolean;
|
||
H: HWND;
|
||
QtObj: TQtObject;
|
||
objName: string;
|
||
WStr: WideString;
|
||
begin
|
||
Result := nil;
|
||
CreateLCLAccessibleInterface := False;
|
||
if QObject_isWidgetType(obj) then begin
|
||
QObject_objectName(obj, @WStr);
|
||
objName := UTF16ToUTF8(WStr);
|
||
if (objName = QtAXObjectName) then
|
||
CreateLCLAccessibleInterface := True
|
||
else begin
|
||
H := HwndFromWidgetH(QWidgeth(obj));
|
||
if (H <> 0) then begin
|
||
QtObj := TQtObject(H);
|
||
if (QtObj is TQtCustomControl) then
|
||
CreateLCLAccessibleInterface := True;
|
||
end
|
||
end
|
||
end;
|
||
|
||
if CreateLCLAccessibleInterface then begin
|
||
Result := QLCLAccessibleWidget_Create(QWidgetH(obj), QAccessibleClient, nil);
|
||
end
|
||
else
|
||
Result := nil;
|
||
end;
|
||
|
||
constructor TQtAccessibleObject.Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
|
||
var
|
||
WStr: WideString;
|
||
AxInterface: QLCLAccessibleWidgetH;
|
||
begin
|
||
inherited Create;
|
||
FLazAxObject := ALazAxObject;
|
||
if (AWidget = QWidgetH(0)) then begin
|
||
FAxWidget := QWidget_Create();
|
||
WStr := GetUtf8String(QtAXObjectName);
|
||
QObject_setObjectName(FAxWidget, @WStr);
|
||
end
|
||
else
|
||
FAxWidget := AWidget;
|
||
|
||
AxInterface := QLCLAccessibleWidgetH(QAccessible_queryAccessibleInterface(FAxWidget));
|
||
QLCLAccessibleWidget_override_child(AxInterface, @childOverride);
|
||
QLCLAccessibleWidget_override_childCount(AxInterface, @childCountOverride);
|
||
QLCLAccessibleWidget_override_role(AxInterface, @roleOverride);
|
||
QLCLAccessibleWidget_override_text(AxInterface, @textOverride);
|
||
end;
|
||
|
||
destructor TQtAccessibleObject.Destroy;
|
||
var
|
||
WStr: WideString;
|
||
objName: string;
|
||
begin
|
||
QObject_objectName(FAxWidget, @WStr);
|
||
objName := UTF16ToUTF8(WStr);
|
||
if (objName = QtAXObjectName) then
|
||
QObject_Destroy(FAxWidget);
|
||
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TQtAccessibleObject.childOverride(index: integer; out child: QAccessibleInterfaceH) cdecl;
|
||
var
|
||
childCount: Integer;
|
||
lclAxChild: TLazAccessibleObject;
|
||
qtAxObject: TQtAccessibleObject;
|
||
begin
|
||
child := QAccessibleInterfaceH(0);
|
||
childCount := 0;
|
||
lclAxChild := FLazAxObject.GetFirstChildAccessibleObject;
|
||
while Assigned(lclAxChild) and (childCount < index) do begin
|
||
inc(ChildCount);
|
||
lclAxChild := FLazAxObject.GetNextChildAccessibleObject;
|
||
end;
|
||
if Assigned(lclAxChild) and (lclAxChild.Handle <> 0) then begin
|
||
qtAxObject := TQtAccessibleObject(lclAxChild.Handle);
|
||
child := QAccessible_queryAccessibleInterface(qtAxObject.FAxWidget);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtAccessibleObject.childCountOverride(count: PInteger) cdecl;
|
||
var
|
||
childCount: Integer;
|
||
lclAxChild: TLazAccessibleObject;
|
||
begin
|
||
childCount := 0;
|
||
lclAxChild := FLazAxObject.GetFirstChildAccessibleObject;
|
||
while Assigned(lclAxChild) do begin
|
||
inc(ChildCount);
|
||
lclAxChild := FLazAxObject.GetNextChildAccessibleObject;
|
||
end;
|
||
count^ := childCount;
|
||
end;
|
||
|
||
procedure TQtAccessibleObject.roleOverride(out role: QAccessibleRole) cdecl;
|
||
begin
|
||
if (FLazAxObject <> nil) then
|
||
role := LazRoleToQtRole(FLazAxObject.AccessibleRole)
|
||
else
|
||
role := QAccessibleNoRole;
|
||
end;
|
||
|
||
procedure TQtAccessibleObject.textOverride(text: QAccessibleText; retval: PWideString) cdecl;
|
||
begin
|
||
case text of
|
||
QAccessibleName:
|
||
retval^ := GetUtf8String(CreateAccessibleName(FLazAxObject));
|
||
QAccessibleDescription:
|
||
retval^ := GetUtf8String(FLazAxObject.AccessibleDescription);
|
||
QAccessibleValue:
|
||
retval^ := GetUtf8String(FLazAxObject.AccessibleValue);
|
||
else
|
||
retval^ := GetUtf8String('');
|
||
end;
|
||
end;
|
||
|
||
function TQtAccessibleObject.isVisible: Boolean;
|
||
begin
|
||
Result := FLazAxObject.OwnerControl.Visible;
|
||
end;
|
||
|
||
constructor TQtAccessibleTree.Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
|
||
var
|
||
AxInterface: QLCLAccessibleWidgetH;
|
||
begin
|
||
inherited Create(ALazAxObject, AWidget);
|
||
|
||
AxInterface := QLCLAccessibleWidgetH(QAccessible_queryAccessibleInterface(FAxWidget));
|
||
QLCLAccessibleWidget_override_child(AxInterface, @childOverride);
|
||
QLCLAccessibleWidget_override_childCount(AxInterface, @childCountOverride);
|
||
end;
|
||
|
||
procedure TQtAccessibleTree.childOverride(index: integer; out child: QAccessibleInterfaceH); cdecl;
|
||
var
|
||
ChildIndex: Integer;
|
||
LCLAxChild: TLazAccessibleObject;
|
||
RowAxObject: TQtAccessibleTreeRow;
|
||
begin
|
||
child := QAccessibleInterfaceH(0);
|
||
ChildIndex := 0;
|
||
for LCLAxChild in FLazAxObject do begin
|
||
RowAxObject := TQtAccessibleTreeRow(LCLAxChild.Handle);
|
||
if RowAxObject.isVisible then begin
|
||
if ChildIndex = index then begin
|
||
child := QAccessible_queryAccessibleInterface(RowAxObject.FAxWidget);
|
||
Exit;
|
||
end;
|
||
Inc(ChildIndex);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TQtAccessibleTree.childCountOverride(count: PInteger); cdecl;
|
||
var
|
||
Tree: TCustomTreeView;
|
||
TreeNode: TTreeNode;
|
||
ChildCount: Integer;
|
||
begin
|
||
Tree := TCustomTreeView(FLazAxObject.OwnerControl);
|
||
ChildCount := 0;
|
||
TreeNode := Tree.Items.GetFirstVisibleNode;
|
||
while (TreeNode <> nil) do begin
|
||
Inc(ChildCount);
|
||
TreeNode := TreeNode.GetNextVisible;
|
||
end;
|
||
count^ := ChildCount;
|
||
end;
|
||
|
||
|
||
constructor TQtAccessibleTreeRow.Create(ALazAxObject: TLazAccessibleObject; AWidget: QWidgetH);
|
||
var
|
||
AxInterface: QLCLAccessibleWidgetH;
|
||
begin
|
||
inherited Create(ALazAxObject, AWidget);
|
||
|
||
AxInterface := QLCLAccessibleWidgetH(QAccessible_queryAccessibleInterface(FAxWidget));
|
||
QLCLAccessibleWidget_override_actionNames(AxInterface, @actionNamesOverride);
|
||
QLCLAccessibleWidget_override_child(AxInterface, nil);
|
||
QLCLAccessibleWidget_override_childAt(AxInterface, nil);
|
||
QLCLAccessibleWidget_override_childCount(AxInterface, @childCountOverride);
|
||
QLCLAccessibleWidget_override_doAction(AxInterface, @doActionOverride);
|
||
QLCLAccessibleWidget_override_parent(AxInterface, @parentOVerride);
|
||
QLCLAccessibleWidget_override_rect(AxInterface, @rectOverride);
|
||
QLCLAccessibleWidget_override_role(AxInterface, @roleOverride);
|
||
QLCLAccessibleWidget_override_text(AxInterface, @textOverride);
|
||
end;
|
||
|
||
procedure TQtAccessibleTreeRow.actionNamesOverride(names: PWideString)cdecl;
|
||
begin
|
||
names^ := GetUtf8String(axActionNamePress); // Takes a comma separated string of actions
|
||
end;
|
||
|
||
procedure TQtAccessibleTreeRow.doActionOverride(name: PWideString)cdecl;
|
||
var s: string;
|
||
TreeNode: TTreeNode;
|
||
begin
|
||
s := UTF16ToUTF8(name^);
|
||
if s = axActionNamePress then begin
|
||
TreeNode := TTreeNode(FLazAxObject.DataObject);
|
||
TreeNode.TreeView.Select(TreeNode);
|
||
end;
|
||
end;
|
||
|
||
procedure TQtAccessibleTreeRow.childCountOverride(count: PInteger)cdecl;
|
||
begin
|
||
count^ := 0;
|
||
end;
|
||
|
||
procedure TQtAccessibleTreeRow.parentOverride(out parent: QAccessibleInterfaceH)cdecl;
|
||
begin
|
||
parent := QLCLAccessibleWidgetH(QAccessible_queryAccessibleInterface(
|
||
TQtAccessibleObject(FLazAxObject.Parent.Handle).FAxWidget));
|
||
end;
|
||
|
||
procedure TQtAccessibleTreeRow.rectOverride(left, top, width, height: PInteger)cdecl;
|
||
var
|
||
TreeNode: TTreeNode;
|
||
NodeR: TRect;
|
||
R: TRect;
|
||
begin
|
||
TreeNode := TTreeNode(FLazAxObject.DataObject);
|
||
NodeR := TreeNode.DisplayRect(False);
|
||
R := LCLControlRectToQtScreenRect(NodeR, TreeNode.TreeView);
|
||
left^ := R.Left;
|
||
top^ := R.Top;
|
||
width^ := R.Width;
|
||
height^ := R.Height;
|
||
end;
|
||
|
||
procedure TQtAccessibleTreeRow.roleOverride(out role: QAccessibleRole)cdecl;
|
||
begin
|
||
role := QAccessibleTreeItem;
|
||
end;
|
||
|
||
procedure TQtAccessibleTreeRow.textOverride(text: QAccessibleText; retval: PWideString) cdecl;
|
||
var
|
||
TreeNode: TTreeNode;
|
||
begin
|
||
TreeNode := TTreeNode(FLazAxObject.DataObject);
|
||
case text of
|
||
QAccessibleName, QAccessibleDescription, QAccessibleValue:
|
||
retval^ := GetUtf8String(TreeNode.Text);
|
||
else
|
||
retval^ := GetUtf8String('');
|
||
end;
|
||
end;
|
||
|
||
function TQtAccessibleTreeRow.isVisible:Boolean;
|
||
var
|
||
TreeNode: TTreeNode;
|
||
begin
|
||
TreeNode := TTreeNode(FLazAxObject.DataObject);
|
||
Result := TreeNode.IsVisible;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
|
||
|
||
|
||
end.
|