[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    [PATCH] Open/Save dialog completion fix
From:       Rafael =?utf-8?q?Fern=C3=A1ndez_L=C3=B3pez?= <ereslibre () kde ! org>
Date:       2008-12-22 15:37:14
Message-ID: 200812221637.17737.ereslibre () kde ! org
[Download RAW message or body]

[Attachment #2 (multipart/mixed)]


Hi there,

When fixing some things on Open/Save dialog I noticed when you have 
autocompletion in a folder with items, for example: "foo", "bar". If you write 
on the location edit combo "fó" the completion still shows "foo", what is 
obviously wrong.

I have written a patch, but also on my debugging way I found a QLineEdit bug, 
at least I think is a bug, that has been already reported to Qt Software.

So, let's go step by step:

The attached patch fixes this problem, so if you write "f" the completion shows 
obviously "foo", while if you do "fó" the autocompletion combo is hidden, 
since there are no more hits. This seems mainly a porting problem (haven't 
tested if this works on KDE 3).

Now, why I changed keyPressEvent with keyReleaseEvent ? This is the second 
part of this issue. QLineEdit seems to have an issue. I have written two test 
cases:

http://media.ereslibre.es/2008/12/test
and
http://media.ereslibre.es/2008/12/test2

On the first one (which is actually a QTestLib test case) you will see that if 
you "emulate" keyboard key presses, you get 5 key presses and 5 key releases 
when emulating "tést" writing.

On test2, which is an app with console output, writing "qué tal" will you get 
this on console (pasted here so it is easier for you):

[ereslibre@laptop-freedom:~/test2]$ ./test2
key press => q
key release
key press  => u
key release
key release  => é
key release
key press => 
key release
key press  => t
key release
key press  => a
key release
key press  => l
key release

Basically, as you can see you don't get any key press event when writing "é". 
It is curious to check that if you write " ´ ´ ´ ´ ´ ´ ´ ´" you only get key releases 
events too... so this sounds like a bug to me.

For this reason I changed the keyPressEvent to keyReleaseEvent on the patch.

So now the question is:

Should I commit this to SVN, or better wait till this QLineEdit is fixed in Qt 
and commit it on the keyPressEvent a bit modified, but following the same idea 
?


Regards,
Rafael Fernández López.

["kdelibs.diff" (text/x-patch)]

diff --git a/kdeui/widgets/klineedit.cpp b/kdeui/widgets/klineedit.cpp
index 5260c31..f24a810 100644
--- a/kdeui/widgets/klineedit.cpp
+++ b/kdeui/widgets/klineedit.cpp
@@ -144,6 +144,8 @@ public:
 
     KCompletionBox *completionBox;
 
+    QString m_oldText;
+
     int overlap;
 
     bool italicizePlaceholder:1;
@@ -649,7 +651,7 @@ void KLineEdit::resizeEvent( QResizeEvent * ev )
     QLineEdit::resizeEvent(ev);
 }
 
-void KLineEdit::keyPressEvent( QKeyEvent *e )
+void KLineEdit::keyReleaseEvent( QKeyEvent *e )
 {
     const int key = e->key() | e->modifiers();
 
@@ -750,12 +752,12 @@ void KLineEdit::keyPressEvent( QKeyEvent *e )
                  ( e->key() == Qt::Key_Right || e->key() == Qt::Key_Left ) &&
                  e->modifiers()==Qt::NoButton )
             {
-                const QString old_txt = text();
+                const QString old_txt = d->m_oldText;
                 d->disableRestoreSelection = true;
                 const int start = selectionStart();
 
                 deselect();
-                QLineEdit::keyPressEvent ( e );
+                QLineEdit::keyReleaseEvent ( e );
                 const int cPosition=cursorPosition();
                 setText(old_txt);
                 setCursorPosition(cPosition);
@@ -765,6 +767,7 @@ void KLineEdit::keyPressEvent( QKeyEvent *e )
                     setSelection(start, old_txt.length());
 
                 d->disableRestoreSelection = false;
+                d->m_oldText = text();
                 return;
             }
 
@@ -811,7 +814,7 @@ void KLineEdit::keyPressEvent( QKeyEvent *e )
                 }
 
                 d->disableRestoreSelection = true;
-                QLineEdit::keyPressEvent ( e );
+                QLineEdit::keyReleaseEvent ( e );
                 d->disableRestoreSelection = false;
 
                 QString txt = text();
@@ -842,6 +845,7 @@ void KLineEdit::keyPressEvent( QKeyEvent *e )
                     e->accept();
                 }
 
+                d->m_oldText = text();
                 return;
             }
 
@@ -849,9 +853,9 @@ void KLineEdit::keyPressEvent( QKeyEvent *e )
 
         else if (( mode == KGlobalSettings::CompletionPopup ||
                    mode == KGlobalSettings::CompletionPopupAuto ) &&
-                   noModifier && !e->text().isEmpty() )
+                   noModifier )
         {
-            const QString old_txt = text();
+            const QString old_txt = d->m_oldText;
             const bool hasUserSelection=d->userSelection;
             const bool hadSelection=hasSelectedText();
             bool cursorNotAtEnd=false;
@@ -865,8 +869,8 @@ void KLineEdit::keyPressEvent( QKeyEvent *e )
             // as if there was no selection. After processing the key event, we
             // can set the new autocompletion again.
             if (hadSelection && !hasUserSelection && start>cPos &&
-               ( (!keycode.isEmpty() && keycode.unicode()->isPrint()) ||
-                 e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete ) )
+               ( !keycode.isEmpty() && (keycode.unicode()->isPrint() ||
+                 e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete ) ) )
             {
                 del();
                 setCursorPosition(cPos);
@@ -876,17 +880,19 @@ void KLineEdit::keyPressEvent( QKeyEvent *e )
             const int selectedLength=selectedText().length();
 
             d->disableRestoreSelection = true;
-            QLineEdit::keyPressEvent ( e );
+            QLineEdit::keyReleaseEvent ( e );
             d->disableRestoreSelection = false;
 
+
             if (( selectedLength != selectedText().length() ) && !hasUserSelection )
                 slotRestoreSelectionColors(); // and set userSelection to true
 
             QString txt = text();
             int len = txt.length();
             if ( ( txt != old_txt || txt != e->text() ) && len/* && ( \
                cursorPosition() == len || force )*/ &&
-                 ( (!keycode.isEmpty() && keycode.unicode()->isPrint()) ||
-                   e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete) )
+                 ( !keycode.isEmpty() && (keycode.unicode()->isPrint() ||
+                   e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete) ) &&
+                 ( keycode.unicode()->category() != QChar::Symbol_Modifier || txt != \
old_txt ) )  {
                 if ( e->key() == Qt::Key_Backspace )
                 {
@@ -918,6 +924,7 @@ void KLineEdit::keyPressEvent( QKeyEvent *e )
             else if (!len && d->completionBox && d->completionBox->isVisible())
                 d->completionBox->hide();
 
+            d->m_oldText = text();
             return;
         }
 
@@ -1007,10 +1014,12 @@ void KLineEdit::keyPressEvent( QKeyEvent *e )
     const int selectedLength = selectedText().length();
 
     // Let QLineEdit handle any other keys events.
-    QLineEdit::keyPressEvent ( e );
+    QLineEdit::keyReleaseEvent ( e );
 
     if ( selectedLength != selectedText().length() )
         slotRestoreSelectionColors(); // and set userSelection to true
+
+    d->m_oldText = text();
 }
 
 void KLineEdit::mouseDoubleClickEvent( QMouseEvent* e )
diff --git a/kdeui/widgets/klineedit.h b/kdeui/widgets/klineedit.h
index 62514d2..cb6d08c 100644
--- a/kdeui/widgets/klineedit.h
+++ b/kdeui/widgets/klineedit.h
@@ -511,9 +511,9 @@ protected:
     /**
     * Re-implemented for internal reasons.  API not affected.
     *
-    * See QLineEdit::keyPressEvent().
+    * See QLineEdit::keyReleaseEvent().
     */
-    virtual void keyPressEvent( QKeyEvent * );
+    virtual void keyReleaseEvent( QKeyEvent * );
 
     /**
     * Re-implemented for internal reasons.  API not affected.


["signature.asc" (application/pgp-signature)]

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic