diff --git a/lcl/interfaces/qt/qtobjects.pas b/lcl/interfaces/qt/qtobjects.pas index bb8875a770..5757070431 100644 --- a/lcl/interfaces/qt/qtobjects.pas +++ b/lcl/interfaces/qt/qtobjects.pas @@ -830,6 +830,7 @@ function QtDefaultContext: TQtDeviceContext; function QtScreenContext: TQtDeviceContext; procedure AssignQtFont(FromFont: QFontH; ToFont: QFontH); +function IsFontEqual(AFont1, AFont2: TQtFont): Boolean; implementation @@ -941,6 +942,28 @@ begin QFont_setStyleStrategy(ToFont, QFont_styleStrategy(FromFont)); end; +function IsFontEqual(AFont1, AFont2: TQtFont): Boolean; +var + AInfo1, AInfo2: TQtFontInfo; +begin + Result := False; + if (AFont1 = nil) or (AFont2 = nil) then + exit; + if (AFont1.FHandle = nil) or (AFont2.FHandle = nil) then + exit; + AInfo1 := AFont1.FontInfo; + AInfo2 := AFont2.FontInfo; + if (AInfo1 = nil) or (AInfo2 = nil) then + exit; + Result := (AInfo1.Family = AInfo2.Family) and (AInfo1.Bold = AInfo2.Bold) and + (AInfo1.Italic = AInfo2.Italic) and (AInfo1.FixedPitch = AInfo2.FixedPitch) and + (AInfo1.Underline = AInfo2.Underline) and (AInfo1.Overline = AInfo2.OverLine) and + (AInfo1.PixelSize = AInfo2.PixelSize) and (AInfo1.PointSize = AInfo2.PointSize) and + (AInfo1.StrikeOut = AInfo2.StrikeOut) and (AInfo1.Weight = AInfo2.Weight) and + (AInfo1.RawMode = AInfo2.RawMode) and (AInfo1.Style = AInfo2.Style) and + (AInfo1.StyleHint = AInfo2.StyleHint); +end; + { TQtFontInfo } function TQtFontInfo.GetBold: Boolean; @@ -2939,12 +2962,8 @@ begin SelFont := AFont; if (AFont.FHandle <> nil) and (Widget <> nil) then begin - if not FOwnPainter then - begin - QFnt := QPainter_font(Widget); - AssignQtFont(AFont.FHandle, QFnt); - end else - QPainter_setFont(Widget, QFontH(AFont.FHandle)); + QFnt := QPainter_font(Widget); + AssignQtFont(AFont.FHandle, QFnt); vFont.Angle := AFont.Angle; end; end; diff --git a/lcl/interfaces/qt/qtwidgets.pas b/lcl/interfaces/qt/qtwidgets.pas index 46733c8673..4fde56a2a8 100644 --- a/lcl/interfaces/qt/qtwidgets.pas +++ b/lcl/interfaces/qt/qtwidgets.pas @@ -106,6 +106,8 @@ type TQtWidget = class(TQtObject, IUnknown) private FWidgetState: TQtWidgetStates; + FWidgetDefaultFont: TQtFont; + FWidgetLCLFont: TQtFont; FWidgetNeedFontColorInitialization: Boolean; FChildOfComplexWidget: TChildOfComplexWidget; FOwnWidget: Boolean; @@ -185,6 +187,7 @@ type function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override; function getAcceptDropFiles: Boolean; virtual; 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; @@ -929,9 +932,11 @@ type FParentShowPassed: PtrInt; {$endif} FEditingFinishedHook: QAbstractSpinBox_hookH; + FLineEditHook: QObject_hookH; // parts FLineEdit: QLineEditH; function GetLineEdit: QLineEditH; + function LineEditEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; protected function CreateWidget(const AParams: TCreateParams):QWidgetH; override; // IQtEdit implementation @@ -1429,6 +1434,7 @@ type public constructor Create(const AParent: QWidgetH); overload; public + 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; @@ -1768,6 +1774,8 @@ begin 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))); @@ -1799,6 +1807,10 @@ begin // 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); @@ -1863,6 +1875,11 @@ begin if HasCaret then DestroyCaret; + if Assigned(FWidgetDefaultFont) then + FreeThenNil(FWidgetDefaultFont); + if Assigned(FWidgetLCLFont) then + FreeThenNil(FWidgetLCLFont); + if FPalette <> nil then begin FPalette.Free; @@ -2180,7 +2197,15 @@ begin case QEvent_type(Event) of QEventFontChange: begin - //TODO: for issue #19695 + //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 @@ -2345,6 +2370,25 @@ 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 @@ -5141,6 +5185,7 @@ begin // The main window takes care of the menubar handle if MenuBar <> nil then begin + MenuBar.DetachEvents; MenuBar.Widget := nil; MenuBar.Free; end; @@ -8431,6 +8476,8 @@ begin if (FDropList <> nil) and (Sender = FDropList.Widget) then begin + if QEvent_type(Event) = QEventFontChange then + Result := inherited EventFilter(Sender, Event); QEvent_ignore(Event); exit; end; @@ -8602,9 +8649,23 @@ 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); + 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; + function TQtAbstractSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH; var Parent: QWidgetH; @@ -8613,6 +8674,7 @@ begin {$ifdef VerboseQt} WriteLn('TQtAbstractSpinBox.Create'); {$endif} + FLineEditHook := nil; if AParams.WndParent <> 0 then Parent := TQtWidget(AParams.WndParent).GetContainerWidget else @@ -8792,6 +8854,12 @@ begin QAbstractSpinBox_hook_destroy(FEditingFinishedHook); FEditingFinishedHook := nil; end; + + if FLineEditHook <> nil then + begin + QObject_hook_destroy(FLineEditHook); + FLineEditHook := nil; + end; inherited DetachEvents; end; @@ -8862,6 +8930,7 @@ begin FParentShowPassed := 0; {$endif} FValue := 0; + FLineEditHook := nil; if AParams.WndParent <> 0 then Parent := TQtWidget(AParams.WndParent).GetContainerWidget else @@ -8941,6 +9010,7 @@ begin {$ifdef CPU64 and not WIN64} FParentShowPassed := 0; {$endif} + FLineEditHook := nil; if AParams.WndParent <> 0 then Parent := TQtWidget(AParams.WndParent).GetContainerWidget else @@ -11586,6 +11656,8 @@ begin 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); @@ -11989,6 +12061,8 @@ constructor TQtMenuBar.Create(const AParent: QWidgetH); begin Create; Widget := QMenuBar_create(AParent); + FWidgetDefaultFont := TQtFont.Create(QWidget_font(Widget)); + FWidgetLCLFont := nil; FHeight := getHeight; FVisible := False; FIsApplicationMainMenu := False; @@ -11998,6 +12072,15 @@ begin setVisible(FVisible); end; +function TQtMenuBar.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; + cdecl; +begin + Result := False; + QEvent_accept(Event); + if (QEvent_type(Event) = QEventFontChange) then + AssignQtFont(FWidgetDefaultFont.FHandle, QWidget_font(QWidgetH(Sender))); +end; + function TQtMenuBar.addMenu(AMenu: QMenuH): QActionH; begin if not FVisible then diff --git a/lcl/interfaces/qt/qtwscontrols.pp b/lcl/interfaces/qt/qtwscontrols.pp index e42f747fdb..b51edd0744 100644 --- a/lcl/interfaces/qt/qtwscontrols.pp +++ b/lcl/interfaces/qt/qtwscontrols.pp @@ -578,6 +578,7 @@ begin QtWidget.BeginUpdate; QtWidget.WidgetState := QtWidget.WidgetState + [qtwsFontUpdating]; try + QtWidget.SetLCLFont(TQtFont(AFont.Reference.Handle)); QtWidget.setFont(TQtFont(AFont.Reference.Handle).FHandle); // tscrollbar, ttrackbar etc. diff --git a/lcl/interfaces/qt/qtwsforms.pp b/lcl/interfaces/qt/qtwsforms.pp index 6b1421856f..9b58bc2e8a 100644 --- a/lcl/interfaces/qt/qtwsforms.pp +++ b/lcl/interfaces/qt/qtwsforms.pp @@ -197,6 +197,7 @@ begin // Sets Various Events QtMainWindow.AttachEvents; + QtMainWindow.MenuBar.AttachEvents; if (AForm.FormStyle in [fsMDIChild]) and (Application.MainForm.FormStyle = fsMdiForm) and