View Issue Details

IDProjectCategoryView StatusLast Update
0027079LazarusWidgetsetpublic2015-02-12 21:35
ReporterValdas JankūnasAssigned ToZeljan Rikalo 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platformlinux 64 bitOSKubuntu 14.04OS Version
Product Version1.3 (SVN)Product Build46976M 
Target Version1.2.8Fixed in Version1.3 (SVN) 
Summary0027079: [Qt] when exiting from TEdit it reports wrong SelStart in OnEditingDone
DescriptionTry attached example project:
 - focus Edit;
 - press Enter key: all text in Edit will be selected;
 - now focus Memo with mouse click: in OnEditingDone event of Edit you got wrong SelStart (which is at end of text).

 I think this is wrong because:
 - in Gtk2 after exiting Edit in event OnEditingDone always reports SelStart as is was before auto-deselection (or selection-hiding);
 - in Win same as in Gtk2 (correct);
 - when exiting from Edit there is no way to know correct SelStart in OnEditing event.
TagsNo tags attached.
Fixed in Revision47191
LazTarget1.2.8
WidgetsetQT
Attached Files
  • example.tar.gz (128,370 bytes)
  • qt_selstart_sellength.diff (3,598 bytes)
    Index: lcl/interfaces/qt/qtwidgets.pas
    ===================================================================
    --- lcl/interfaces/qt/qtwidgets.pas	(revision 47081)
    +++ lcl/interfaces/qt/qtwidgets.pas	(working copy)
    @@ -792,6 +792,8 @@
     
       TQtLineEdit = class(TQtWidget, IQtEdit)
       private
    +    FCachedSelectionLen: integer;
    +    FCachedSelectionStart: integer;
         FNumbersOnly: boolean;
         FIntValidator: QIntValidatorH;
         FTextChanged: QLineEdit_hookH;
    @@ -834,6 +836,8 @@
         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;
    @@ -8610,6 +8614,8 @@
     var
       Parent: QWidgetH;
     begin
    +  FCachedSelectionStart := -1;
    +  FCachedSelectionLen := -1;
       FIntValidator := nil;
       FNumbersOnly := False;
       if AParams.WndParent <> 0 then
    @@ -8644,7 +8650,12 @@
       if hasSelectedText then
         Result := QLineEdit_selectionStart(QLineEditH(Widget))
       else
    -    Result := getCursorPosition;
    +  begin
    +    if (CachedSelectionStart <> -1) and not hasFocus then
    +      Result := CachedSelectionStart
    +    else
    +      Result := getCursorPosition;
    +  end;
     end;
     
     function TQtLineEdit.getSelectionLength: Integer;
    @@ -8654,10 +8665,14 @@
       if hasSelectedText then
       begin
         W := getSelectedText;
    -    Result := Length(W);
    -  end
    -  else
    -    Result := 0;
    +    Result := UTF8Length(W);
    +  end else
    +  begin
    +    if (CachedSelectionStart <> -1) and (CachedSelectionLen <> -1) then
    +      Result := CachedSelectionLen
    +    else
    +      Result := 0;
    +  end;
     end;
     
     function TQtLineEdit.getText: WideString;
    @@ -8747,6 +8762,17 @@
       if LCLObject = nil then
         exit;
     
    +  if (QEvent_type(Event) = QEventFocusOut) then
    +  begin
    +    CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(Widget));
    +    CachedSelectionLen := UTF8Length(getSelectedText);
    +  end else
    +  if (QEvent_type(Event) = QEventFocusIn) then
    +  begin
    +    CachedSelectionStart := -1;
    +    CachedSelectionLen := -1;
    +  end;
    +
       if (ChildOfComplexWidget = ccwComboBox) and
         ((QEvent_type(Event) = QEventPaint) or (QEvent_type(Event) = QEventResize))
         and (LCLObject.HandleAllocated) then
    @@ -10532,6 +10558,24 @@
       BeginEventProcessing;
       try
         case QEvent_type(Event) of
    +      QEventFocusOut:
    +      begin
    +        if Assigned(FLineEdit) and FLineEdit.getVisible then
    +        begin
    +          FLineEdit.CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(FLineEdit.Widget));
    +          FLineEdit.CachedSelectionLen := UTF8Length(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
    @@ -10768,7 +10812,7 @@
       if (LineEdit <> nil) and QLineEdit_hasSelectedText(LineEdit) then
       begin
         QLineEdit_selectedText(LineEdit, @W);
    -    Result := Length(W);
    +    Result := UTF8Length(W);
       end
       else
         Result := 0;
    

Activities

Valdas Jankūnas

2014-11-23 22:05

reporter  

example.tar.gz (128,370 bytes)

Zeljan Rikalo

2014-11-24 13:09

developer   ~0079352

That's because QLineEdit deselects text in focus out event. OnEditingDone should fire before Qt fires it's focus out event.

Zeljan Rikalo

2014-12-04 09:41

developer  

qt_selstart_sellength.diff (3,598 bytes)
Index: lcl/interfaces/qt/qtwidgets.pas
===================================================================
--- lcl/interfaces/qt/qtwidgets.pas	(revision 47081)
+++ lcl/interfaces/qt/qtwidgets.pas	(working copy)
@@ -792,6 +792,8 @@
 
   TQtLineEdit = class(TQtWidget, IQtEdit)
   private
+    FCachedSelectionLen: integer;
+    FCachedSelectionStart: integer;
     FNumbersOnly: boolean;
     FIntValidator: QIntValidatorH;
     FTextChanged: QLineEdit_hookH;
@@ -834,6 +836,8 @@
     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;
@@ -8610,6 +8614,8 @@
 var
   Parent: QWidgetH;
 begin
+  FCachedSelectionStart := -1;
+  FCachedSelectionLen := -1;
   FIntValidator := nil;
   FNumbersOnly := False;
   if AParams.WndParent <> 0 then
@@ -8644,7 +8650,12 @@
   if hasSelectedText then
     Result := QLineEdit_selectionStart(QLineEditH(Widget))
   else
-    Result := getCursorPosition;
+  begin
+    if (CachedSelectionStart <> -1) and not hasFocus then
+      Result := CachedSelectionStart
+    else
+      Result := getCursorPosition;
+  end;
 end;
 
 function TQtLineEdit.getSelectionLength: Integer;
@@ -8654,10 +8665,14 @@
   if hasSelectedText then
   begin
     W := getSelectedText;
-    Result := Length(W);
-  end
-  else
-    Result := 0;
+    Result := UTF8Length(W);
+  end else
+  begin
+    if (CachedSelectionStart <> -1) and (CachedSelectionLen <> -1) then
+      Result := CachedSelectionLen
+    else
+      Result := 0;
+  end;
 end;
 
 function TQtLineEdit.getText: WideString;
@@ -8747,6 +8762,17 @@
   if LCLObject = nil then
     exit;
 
+  if (QEvent_type(Event) = QEventFocusOut) then
+  begin
+    CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(Widget));
+    CachedSelectionLen := UTF8Length(getSelectedText);
+  end else
+  if (QEvent_type(Event) = QEventFocusIn) then
+  begin
+    CachedSelectionStart := -1;
+    CachedSelectionLen := -1;
+  end;
+
   if (ChildOfComplexWidget = ccwComboBox) and
     ((QEvent_type(Event) = QEventPaint) or (QEvent_type(Event) = QEventResize))
     and (LCLObject.HandleAllocated) then
@@ -10532,6 +10558,24 @@
   BeginEventProcessing;
   try
     case QEvent_type(Event) of
+      QEventFocusOut:
+      begin
+        if Assigned(FLineEdit) and FLineEdit.getVisible then
+        begin
+          FLineEdit.CachedSelectionStart := QLineEdit_selectionStart(QLineEditH(FLineEdit.Widget));
+          FLineEdit.CachedSelectionLen := UTF8Length(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
@@ -10768,7 +10812,7 @@
   if (LineEdit <> nil) and QLineEdit_hasSelectedText(LineEdit) then
   begin
     QLineEdit_selectedText(LineEdit, @W);
-    Result := Length(W);
+    Result := UTF8Length(W);
   end
   else
     Result := 0;

Zeljan Rikalo

2014-12-04 09:42

developer   ~0079629

Please test with attached patch against trunk lazarus and give feedback. Also, this will be backported to 1.2.8.

Valdas Jankūnas

2014-12-10 11:32

reporter   ~0079732

Tested - works OK. Thanks.

Zeljan Rikalo

2014-12-13 14:24

developer   ~0079786

Please test and close if ok.

Issue History

Date Modified Username Field Change
2014-11-23 22:05 Valdas Jankūnas New Issue
2014-11-23 22:05 Valdas Jankūnas File Added: example.tar.gz
2014-11-24 13:07 Zeljan Rikalo Assigned To => Zeljan Rikalo
2014-11-24 13:07 Zeljan Rikalo Status new => assigned
2014-11-24 13:09 Zeljan Rikalo Note Added: 0079352
2014-12-04 09:41 Zeljan Rikalo File Added: qt_selstart_sellength.diff
2014-12-04 09:42 Zeljan Rikalo LazTarget => -
2014-12-04 09:42 Zeljan Rikalo Note Added: 0079629
2014-12-04 09:42 Zeljan Rikalo Status assigned => feedback
2014-12-10 11:32 Valdas Jankūnas Note Added: 0079732
2014-12-10 11:32 Valdas Jankūnas Status feedback => assigned
2014-12-13 14:24 Zeljan Rikalo Fixed in Revision => 47191
2014-12-13 14:24 Zeljan Rikalo LazTarget - => 1.2.8
2014-12-13 14:24 Zeljan Rikalo Note Added: 0079786
2014-12-13 14:24 Zeljan Rikalo Status assigned => resolved
2014-12-13 14:24 Zeljan Rikalo Fixed in Version => 1.3 (SVN)
2014-12-13 14:24 Zeljan Rikalo Resolution open => fixed
2014-12-13 14:24 Zeljan Rikalo Target Version => 1.2.8
2015-02-12 21:35 Valdas Jankūnas Status resolved => closed