Gtk2: remember selection when edit looses focus.Also preselect test when AutoSelect is true.Patch by Fabrizio Fellini modified by me for autoselect rule. fixes issues #23219,#23246

git-svn-id: trunk@39217 -
This commit is contained in:
zeljko 2012-11-01 08:27:48 +00:00
parent 0d4c4b84ed
commit a0224f784a
2 changed files with 45 additions and 7 deletions

View File

@ -884,6 +884,9 @@ begin
end; end;
end; end;
type
TCustomEditHack = class(TCustomEdit);
function GTKFocusCB(widget: PGtkWidget; event: PGdkEventFocus; data: gPointer): GBoolean; cdecl; function GTKFocusCB(widget: PGtkWidget; event: PGdkEventFocus; data: gPointer): GBoolean; cdecl;
var var
Mess : TLMessage; Mess : TLMessage;
@ -967,13 +970,15 @@ begin
AInfo := GetWidgetInfo(Widget); AInfo := GetWidgetInfo(Widget);
if AInfo <> nil then if AInfo <> nil then
begin begin
if AInfo^.CursorPos > 0 then if (AInfo^.LCLObject is TCustomEdit) and
not TCustomEditHack(AInfo^.LCLObject).AutoSelect then
if (AInfo^.CursorPos > 0) or (AInfo^.SelLength > 0) then
begin begin
// gtk_entry_set_position(PGtkEntry(Widget), AInfo^.CursorPos); // gtk_entry_set_position(PGtkEntry(Widget), AInfo^.CursorPos);
// gtk_editable_select_region(PGtkEditable(Widget), AInfo^.CursorPos, AInfo^.CursorPos); // gtk_editable_select_region(PGtkEditable(Widget), AInfo^.CursorPos, AInfo^.CursorPos);
// do not trigger signals, only update pos for lcl // do not trigger signals, only update pos for lcl
PGtkEntry(Widget)^.current_pos := AInfo^.CursorPos; PGtkEntry(Widget)^.current_pos := AInfo^.CursorPos;
PGtkEntry(Widget)^.selection_bound := AInfo^.CursorPos; PGtkEntry(Widget)^.selection_bound := AInfo^.CursorPos + AInfo^.SelLength;
end; end;
end; end;
end; end;
@ -1037,7 +1042,7 @@ end;
function GtkEntryDelayClearCursorPos(AGtkWidget: Pointer): GBoolean; cdecl; function GtkEntryDelayClearCursorPos(AGtkWidget: Pointer): GBoolean; cdecl;
var var
Info: PWidgetInfo; Info: PWidgetInfo;
AStart,AEnd: gint; //AStart,AEnd: gint;
begin begin
Result := AGtkWidget <> nil; Result := AGtkWidget <> nil;
if AGtkWidget <> nil then if AGtkWidget <> nil then
@ -1046,8 +1051,8 @@ begin
Info := GetWidgetInfo(AGtkWidget); Info := GetWidgetInfo(AGtkWidget);
if Info <> nil then if Info <> nil then
begin begin
gtk_editable_get_selection_bounds(PGtkEditable(AGtkWidget),@AStart, @AEnd); //gtk_editable_get_selection_bounds(PGtkEditable(AGtkWidget),@AStart, @AEnd);
Info^.CursorPos := AEnd; //Info^.CursorPos := AEnd;
gtk_editable_select_region(PGtkEditable(AGtkWidget), 0, 0); gtk_editable_select_region(PGtkEditable(AGtkWidget), 0, 0);
end; end;
end; end;
@ -1057,6 +1062,8 @@ function GTKKillFocusCBAfter(widget: PGtkWidget; event:PGdkEventFocus;
data: gPointer) : GBoolean; cdecl; data: gPointer) : GBoolean; cdecl;
var var
Mess : TLMessage; Mess : TLMessage;
Info: PWidgetInfo;
AStart,AEnd: gint;
{$IFDEF VerboseFocus} {$IFDEF VerboseFocus}
LCLObject: TObject; LCLObject: TObject;
CurFocusWidget: PGtkWidget; CurFocusWidget: PGtkWidget;
@ -1112,7 +1119,24 @@ begin
// do not show selection when widget is unfocused // do not show selection when widget is unfocused
// issues #18164,#21897,#23182 // issues #18164,#21897,#23182
if GtkWidgetIsA(Widget, gtk_type_entry) then if GtkWidgetIsA(Widget, gtk_type_entry) then
begin
g_idle_add(@GtkEntryDelayClearCursorPos, Widget); g_idle_add(@GtkEntryDelayClearCursorPos, Widget);
//save now CursorPos and SelStart in WidgetInfo
if (Widget <> nil) then
begin
Info := GetWidgetInfo(Widget);
if Info <> nil then
begin
if (Info^.LCLObject is TCustomEdit) and
not TCustomEditHack(Info^.LCLObject).AutoSelect then
begin
gtk_editable_get_selection_bounds(PGtkEditable(Widget),@AStart, @AEnd);
Info^.CursorPos := Min(AStart, AEnd);
Info^.SelLength := Abs(AEnd - AStart);
end;
end;
end;
end;
Result:=true; Result:=true;
end; end;

View File

@ -1155,24 +1155,38 @@ class function TGtk2WSCustomEdit.GetSelStart(const ACustomEdit: TCustomEdit
): integer; ): integer;
var var
Entry: PGtkEntry; Entry: PGtkEntry;
AInfo: PWidgetInfo;
begin begin
Result := 0; Result := 0;
if not WSCheckHandleAllocated(ACustomEdit, 'GetSelStart') then if not WSCheckHandleAllocated(ACustomEdit, 'GetSelStart') then
Exit; Exit;
Entry := {%H-}PGtkEntry(ACustomEdit.Handle); Entry := {%H-}PGtkEntry(ACustomEdit.Handle);
Result := Min(Entry^.current_pos, Entry^.selection_bound) if gtk_widget_has_focus(PGtkWidget(Entry)) then
Result := Min(Entry^.current_pos, Entry^.selection_bound)
else begin
AInfo := GetWidgetInfo(PGtkWidget(Entry));
if AInfo <> nil then
Result := AInfo^.CursorPos;
end;
end; end;
class function TGtk2WSCustomEdit.GetSelLength(const ACustomEdit: TCustomEdit class function TGtk2WSCustomEdit.GetSelLength(const ACustomEdit: TCustomEdit
): integer; ): integer;
var var
Entry: PGtkEntry; Entry: PGtkEntry;
AInfo: PWidgetInfo;
begin begin
Result := 0; Result := 0;
if not WSCheckHandleAllocated(ACustomEdit, 'GetSelLength') then if not WSCheckHandleAllocated(ACustomEdit, 'GetSelLength') then
Exit; Exit;
Entry := {%H-}PGtkEntry(ACustomEdit.Handle); Entry := {%H-}PGtkEntry(ACustomEdit.Handle);
Result := ABS(Entry^.current_pos - Entry^.selection_bound); if gtk_widget_has_focus(PGtkWidget(Entry)) then
Result := ABS(Entry^.current_pos - Entry^.selection_bound)
else begin
AInfo := GetWidgetInfo(PGtkWidget(Entry));
if AInfo <> nil then
Result := AInfo^.SelLength;
end;
end; end;
function gtk2WSDelayedSelStart(Data: Pointer): gboolean; cdecl; function gtk2WSDelayedSelStart(Data: Pointer): gboolean; cdecl;