From ac0184724f055e2aea022103efb03242987da0d1 Mon Sep 17 00:00:00 2001 From: paul Date: Sun, 29 Mar 2009 09:06:48 +0000 Subject: [PATCH] gtk, gtk2, win32: don't call OnChange twice when we change TEdit text (bug #0013102) gtk2: don't call OnChange more than one time when we change TMemo text git-svn-id: trunk@19151 - --- lcl/include/customedit.inc | 14 ++++++--- lcl/interfaces/gtk/gtkwsstdctrls.pp | 9 ++++++ lcl/interfaces/gtk2/gtk2memostrings.inc | 37 ++++++++++++++++------- lcl/interfaces/gtk2/gtk2wscontrols.pp | 32 -------------------- lcl/interfaces/gtk2/gtk2wscustommemo.inc | 38 ++++++++++++++++++------ lcl/interfaces/gtk2/gtk2wsstdctrls.pp | 1 + lcl/stdctrls.pp | 1 + 7 files changed, 77 insertions(+), 55 deletions(-) diff --git a/lcl/include/customedit.inc b/lcl/include/customedit.inc index 6a6a42d5d0..e77d85b821 100644 --- a/lcl/include/customedit.inc +++ b/lcl/include/customedit.inc @@ -37,6 +37,16 @@ begin TWSCustomEditClass(WidgetSetClass).SetAlignment(Self, FAlignment); end; +procedure TCustomEdit.CMTextChanged(var Message: TLMessage); +begin + if not (wcfCreatingHandle in FWinControlFlags) then + begin + Modified := True; + if HandleAllocated then + Change; + end; +end; + {------------------------------------------------------------------------------ Method: TCustomEdit.Create Params: none @@ -460,11 +470,7 @@ begin end; if not (wcfCreatingHandle in FWinControlFlags) then - begin Modified := True; - if HandleAllocated then - Change; - end; end; procedure TCustomEdit.Change; diff --git a/lcl/interfaces/gtk/gtkwsstdctrls.pp b/lcl/interfaces/gtk/gtkwsstdctrls.pp index 4970400aeb..f9badbed72 100644 --- a/lcl/interfaces/gtk/gtkwsstdctrls.pp +++ b/lcl/interfaces/gtk/gtkwsstdctrls.pp @@ -155,6 +155,7 @@ type class procedure SetReadOnly(const ACustomEdit: TCustomEdit; NewReadOnly: boolean); override; class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override; class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer); override; + class procedure SetText(const AWinControl: TWinControl; const AText: string); override; class procedure GetPreferredSize(const AWinControl: TWinControl; var PreferredWidth, PreferredHeight: integer; @@ -1250,6 +1251,14 @@ begin NewLength); end; +class procedure TGtkWSCustomEdit.SetText(const AWinControl: TWinControl; + const AText: string); +begin + if not WSCheckHandleAllocated(AWinControl, 'SetText') then + Exit; + gtk_entry_set_text(PGtkEntry(AWinControl.Handle), PChar(AText)); +end; + class procedure TGtkWSCustomEdit.GetPreferredSize(const AWinControl: TWinControl; var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); begin diff --git a/lcl/interfaces/gtk2/gtk2memostrings.inc b/lcl/interfaces/gtk2/gtk2memostrings.inc index d71005ed7d..fdac209aae 100644 --- a/lcl/interfaces/gtk2/gtk2memostrings.inc +++ b/lcl/interfaces/gtk2/gtk2memostrings.inc @@ -21,10 +21,11 @@ type constructor Create(TextView : PGtkTextView; TheOwner: TWinControl); destructor Destroy; override; procedure Assign(Source : TPersistent); override; + procedure AddStrings(TheStrings: TStrings); override; procedure Clear; override; procedure Delete(Index : integer); override; procedure Insert(Index : integer; const S: string); override; - procedure SetText(TheText: PChar); override; + procedure SetTextStr(const Value: string); override; //procedure Sort; virtual; procedure QueueCursorMove(APosition: Integer); public @@ -126,18 +127,30 @@ begin end; procedure TGtk2MemoStrings.Assign(Source: TPersistent); +var + S: TStrings absolute Source; begin - if (Source=Self) or (Source=nil) then exit; - if Source is TStrings then begin - gtk_text_buffer_set_text(FGtkBuf, PChar(TStrings(Source).Text), -1); - exit; - end; - Inherited Assign(Source); + if Source is TStrings then + begin + // to prevent Clear and then SetText we need to use our own Assign + QuoteChar := S.QuoteChar; + Delimiter := S.Delimiter; + NameValueSeparator := S.NameValueSeparator; + TextLineBreakStyle := S.TextLineBreakStyle; + Text := S.Text; + end + else + inherited Assign(Source); +end; + +procedure TGtk2MemoStrings.AddStrings(TheStrings: TStrings); +begin + SetTextStr(GetTextStr + TStrings(TheStrings).Text); end; procedure TGtk2MemoStrings.Clear; begin - gtk_text_buffer_set_text(FGtkBuf, PChar(''), -1); + SetText(''); end; procedure TGtk2MemoStrings.Delete(Index: integer); @@ -188,9 +201,13 @@ begin gtk_text_buffer_insert(FGtkBuf, @StartIter, PChar(NewLine) ,-1); end; -procedure TGtk2MemoStrings.SetText(TheText: PChar); +procedure TGtk2MemoStrings.SetTextStr(const Value: string); begin - gtk_text_buffer_set_text(FGtkBuf, TheText, -1); + if (Value <> Text) then + begin + LockOnChange(PGtkObject(Owner.Handle), 1); + gtk_text_buffer_set_text(FGtkBuf, PChar(Value), -1); + end; end; procedure TGtk2MemoStrings.QueueCursorMove(APosition: Integer); diff --git a/lcl/interfaces/gtk2/gtk2wscontrols.pp b/lcl/interfaces/gtk2/gtk2wscontrols.pp index 513e65a704..a71d5a8cac 100644 --- a/lcl/interfaces/gtk2/gtk2wscontrols.pp +++ b/lcl/interfaces/gtk2/gtk2wscontrols.pp @@ -65,7 +65,6 @@ type class procedure SetBiDiMode(const AWinControl: TWinControl; UseRightToLeftAlign, UseRightToLeftReading, UseRightToLeftScrollBar : Boolean); override; class function GetText(const AWinControl: TWinControl; var AText: String): Boolean; override; - class procedure SetText(const AWinControl: TWinControl; const AText: string); override; class procedure SetBorderStyle(const AWinControl: TWinControl; const ABorderStyle: TBorderStyle); override; end; @@ -276,37 +275,6 @@ begin end; end; -class procedure TGtk2WSWinControl.SetText(const AWinControl: TWinControl; - const AText: string); -var - P : Pointer; - TextBuf: PGtkTextBuffer; - StartIter: TGtkTextIter; - pLabel: pchar; -begin - P := Pointer(AWinControl.Handle); - - pLabel := pchar(AText); - - case AWinControl.fCompStyle of - csMemo : begin - TextBuf := gtk_text_view_get_buffer(PGtkTextView(GetWidgetInfo(P, True)^.CoreWidget)); - gtk_text_buffer_set_text(TextBuf, plabel, -1); - gtk_text_buffer_get_start_iter(TextBuf, @StartIter); - gtk_text_buffer_place_cursor(TextBuf, @StartIter); - //debugln('TGtkWSWinControl.SetText A ',dbgs(gtk_text_get_length(PGtkText(P))),' AText="',AText,'"'); - //gtk_text_freeze(PGtkText(P)); - //gtk_text_set_point(PGtkText(P), 0); - //gtk_text_forward_delete(PGtkText(P), gtk_text_get_length(PGtkText(P))); - //gtk_text_insert(PGtkText(P), nil, nil, nil, pLabel, -1); - //gtk_text_thaw(PGtkText(P)); - //debugln('TGtkWSWinControl.SetText B ',dbgs(gtk_text_get_length(PGtkText(P)))); - end; - else - TGtkWSWinControl{(ClassParent)}.SetText(AWinControl, AText); - end; -end; - class procedure TGtk2WSWinControl.SetBorderStyle( const AWinControl: TWinControl; const ABorderStyle: TBorderStyle); var diff --git a/lcl/interfaces/gtk2/gtk2wscustommemo.inc b/lcl/interfaces/gtk2/gtk2wscustommemo.inc index d623dc42bd..a7033f4403 100644 --- a/lcl/interfaces/gtk2/gtk2wscustommemo.inc +++ b/lcl/interfaces/gtk2/gtk2wscustommemo.inc @@ -2,18 +2,23 @@ { Callbacks } -procedure Gtk2WS_MemoChanged( AGtkTextBuffer: PGtkTextBuffer; WidgetInfo: PWidgetInfo); cdecl; +procedure Gtk2WS_MemoChanged(AGtkTextBuffer: PGtkTextBuffer; WidgetInfo: PWidgetInfo); cdecl; var - Mess : TLMessage; + Mess: TLMessage; begin EventTrace('Gtk2WS_MemoChanged', WidgetInfo^.LCLObject); + if WidgetInfo^.ChangeLock > 0 then + begin + Dec(WidgetInfo^.ChangeLock); + Exit; + end; Mess.Msg := CM_TEXTCHANGED; DeliverMessage(WidgetInfo^.LCLObject, Mess); end; -procedure Gtk2WS_MemoCutToClip( widget: PGtkWidget; WidgetInfo: PWidgetInfo); cdecl; +procedure Gtk2WS_MemoCutToClip(widget: PGtkWidget; WidgetInfo: PWidgetInfo); cdecl; var - Mess : TLMessage; + Mess: TLMessage; begin EventTrace('Gtk2WS_MemoCutToClip', WidgetInfo^.LCLObject); if (Widget=nil) then ; @@ -21,9 +26,9 @@ begin DeliverMessage(WidgetInfo^.LCLObject, Mess); end; -procedure Gtk2WS_MemoCopyToClip( widget: PGtkWidget; WidgetInfo: PWidgetInfo); cdecl; +procedure Gtk2WS_MemoCopyToClip(widget: PGtkWidget; WidgetInfo: PWidgetInfo); cdecl; var - Mess : TLMessage; + Mess: TLMessage; begin EventTrace('Gtk2WS_MemoCopyToClip', WidgetInfo^.LCLObject); if (Widget=nil) then ; @@ -31,9 +36,9 @@ begin DeliverMessage(WidgetInfo^.LCLObject, Mess); end; -procedure Gtk2WS_MemoPasteFromClip( widget: PGtkWidget; WidgetInfo: PWidgetInfo); cdecl; +procedure Gtk2WS_MemoPasteFromClip(widget: PGtkWidget; WidgetInfo: PWidgetInfo); cdecl; var - Mess : TLMessage; + Mess: TLMessage; begin EventTrace('Gtk2WS_MemoPasteFromClip', WidgetInfo^.LCLObject); if (Widget=nil) then ; @@ -124,7 +129,8 @@ begin SetMainWidget(Widget, TempWidget); GetWidgetInfo(Widget, True)^.CoreWidget := TempWidget; - gtk_text_view_set_editable (PGtkTextView(TempWidget), not TCustomMemo(AWinControl).ReadOnly); + gtk_text_buffer_set_text(gtk_text_view_get_buffer(PGtkTextView(TempWidget)), PChar(TCustomMemo(AWinControl).Text), -1); + gtk_text_view_set_editable(PGtkTextView(TempWidget), not TCustomMemo(AWinControl).ReadOnly); gtk_text_view_set_justification(PGtkTextView(TempWidget), aGtkJustification[TCustomMemo(AWinControl).Alignment]); if TCustomMemo(AWinControl).WordWrap then gtk_text_view_set_wrap_mode(PGtkTextView(TempWidget), GTK_WRAP_WORD) @@ -274,6 +280,20 @@ begin gtk_entry_set_editable(GTK_ENTRY(Widget), not ACustomEdit.ReadOnly); end; +class procedure TGtk2WSCustomMemo.SetText(const AWinControl: TWinControl; + const AText: string); +var + TextBuf: PGtkTextBuffer; + StartIter: TGtkTextIter; +begin + if not WSCheckHandleAllocated(AWinControl, 'SetText') then + Exit; + TextBuf := gtk_text_view_get_buffer(PGtkTextView(GetWidgetInfo(Pointer(AWinControl.Handle), True)^.CoreWidget)); + gtk_text_buffer_set_text(TextBuf, PChar(AText), -1); + gtk_text_buffer_get_start_iter(TextBuf, @StartIter); + gtk_text_buffer_place_cursor(TextBuf, @StartIter); +end; + class procedure TGtk2WSCustomMemo.GetPreferredSize( const AWinControl: TWinControl; var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); diff --git a/lcl/interfaces/gtk2/gtk2wsstdctrls.pp b/lcl/interfaces/gtk2/gtk2wsstdctrls.pp index 49819cda71..7dba687f46 100644 --- a/lcl/interfaces/gtk2/gtk2wsstdctrls.pp +++ b/lcl/interfaces/gtk2/gtk2wsstdctrls.pp @@ -206,6 +206,7 @@ type class procedure SetCharCase(const ACustomEdit: TCustomEdit; NewCase: TEditCharCase); override; class procedure SetMaxLength(const ACustomEdit: TCustomEdit; NewLength: integer); override; class procedure SetReadOnly(const ACustomEdit: TCustomEdit; NewReadOnly: boolean); override; + class procedure SetText(const AWinControl: TWinControl; const AText: string); override; class procedure GetPreferredSize(const AWinControl: TWinControl; var PreferredWidth, PreferredHeight: integer; diff --git a/lcl/stdctrls.pp b/lcl/stdctrls.pp index 0d70093186..7e95941d01 100644 --- a/lcl/stdctrls.pp +++ b/lcl/stdctrls.pp @@ -688,6 +688,7 @@ type procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); override; procedure CreateWnd; override; + procedure CMTextChanged(var Message: TLMessage); message CM_TEXTCHANGED; procedure TextChanged; override; procedure Change; dynamic; procedure DoEnter; override;