Bug 66025 - When deleting a message in a thread, the selector moved to the next thread while highlight moves to next message in same thread
Summary: When deleting a message in a thread, the selector moved to the next thread wh...
Status: RESOLVED FIXED
Alias: None
Product: kmail
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Compiled Sources Linux
: NOR major
Target Milestone: ---
Assignee: kdepim bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-10-14 13:30 UTC by Oded Arbel
Modified: 2007-09-14 12:17 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
Screenshot showin the problem with 2003/11/31 build (201.96 KB, image/jpeg)
2003-12-02 10:41 UTC, Helio Chissini de Castro
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Oded Arbel 2003-10-14 13:30:23 UTC
Version:            (using KDE Devel)
Installed from:    Compiled sources
OS:          Linux

When Standing on the first message of a thread (possibly also other messages in a thread) and deleting it, the most anoying thing happens - the message selector (the dotted rectangle around a message line in the list, which also dictates what message is shown in the message preview) moves to the first message on the next thread, while the highlight (the color bar highlighting a message in the list which is used for selection) moves to the next message in the original thread.

What actually happening is in two stages:
1. the original message is marked for deleting, and both the selector and highlight move to the next message in the thread.
2. the original message is removed from the list and the selector jumps to the next thread while the highlight stays where it is.

Except for being wrong, this is very confusing as the most visible element (the highligh - which is also used to denote messages selected for action) points to one message, while the selector (and the message preview) is showing another. pressing delete again will now delete the message where the selector is - which is not the one the highlight is selecting.

I think that unless explicitly manipulated by the user, the selector and highlight should point to the same message (at least when there is only one message highlighted).
In addition, when deleting a message in a thread the selector (with the hightlight) should stay on the next message in the thread.
Comment 1 Oded Arbel 2003-10-14 13:39:57 UTC
Correction - the incorrect behavior is a bit more complicated then I first described : 
 
- if the message being deleted has siblings (messages on the same level of the thread as 
the current message), the selector jumps to the next sibling - if the above description, the 
message being deleted is the top of the thread and so it jumps to the next message on 
the top level = the start of the next message. 
- else, no siblings for this message - i.e. all the other messages are childs of the original 
message, the selector then jumps to the last message of the sub-thread (of all messages 
under the deleted message). 
Comment 2 Till Adam 2003-10-14 23:13:38 UTC
Subject: kdepim/kmail

CVS commit by tilladam: 

If a message is removed from the headers list the one below it becomes the
current item. It loses that state if it is subsequently rethreaded because
it is a child of the removed message, since rethreading uses take() and 
insert(). Remember the current item before reparenting and reset it 
afterwards.

Thanks, Oded, for the excellent bug report.

CCMAIL: 66025-done@bugs.kde.org


  M +5 -0      kmheaders.cpp   1.571


--- kdepim/kmail/kmheaders.cpp  #1.570:1.571
@@ -1273,4 +1273,6 @@ void KMHeaders::msgRemoved(int id, QStri
 
   KMHeaderItem *removedItem = mItems[id];
+  KMHeaderItem *currentItem = currentHeaderItem();
+
   for (int i = id; i < (int)mItems.size() - 1; ++i) {
     mItems[i] = mItems[i+1];
@@ -1345,4 +1347,7 @@ void KMHeaders::msgRemoved(int id, QStri
   mImperfectlyThreadedList.removeRef(removedItem);
   delete removedItem;
+  // we might have rethreaded it, in which case its current state will be lost
+  if ( currentItem && currentItem != removedItem )
+    setCurrentItem( currentItem );
   END_TIMER(msgRemoved);
   SHOW_TIMER(msgRemoved);


Comment 3 Helio Chissini de Castro 2003-12-02 10:39:56 UTC
Unfortunately not fixed or broke again..
Now is worst, because after you delete first message in thread, the cursor not only jumps to beginning of next thread, but mark all previous thread messgaes as read ( if you have 0 seconds reak mar like me ).
Just to mention, my options to header in perferences dialog is:
- Display messages sizes turned on
- Thread list of message headers
- Open threads that contain new, unread or important....

I'll will attach a screenshot showing exactly moment that happens this one, with an about to confirm date of build
Comment 4 Helio Chissini de Castro 2003-12-02 10:41:26 UTC
Created attachment 3513 [details]
Screenshot showin the problem with 2003/11/31 build
Comment 5 Oded Arbel 2003-12-11 17:06:47 UTC
Indeed the behavior is broken again. I can't reproduce the behavior in the above, but on my system it behaves thus:
- when positioning the selector (and viewing) the first message of a thread, with the thread open, I press delete.
- the message is deleted, the thread resorted and the selector position on the next message of the same thread.
- BUT, the message actually viewed in the preview window is the message directly below the end of the current thread, and that message is also marked read (kmail is set to auto mark read when viewed).
- If there is no message below the thread (last thread in the message list), then the message viewed (and marked read) is the message directly above the now selected message, be it the last message of the previous open thread or the first message of the previous collapsed thread.
- Even though the selector (highligt) in the message list is pointing to the correct message, pressing delete at this point will remove the message viewed in the preview pane which is not the selected message.
Comment 6 Till Adam 2003-12-11 18:30:15 UTC
Subject: kdepim/kmail

CVS commit by tilladam: 

During rethreading when a message is added to or removed from the headers
list it can happen that the current item is take()en and put somewhere
else. qlistview then emits currentChanged, which triggers hightlightMessage
which (wrongly, for our purposes) selects the next sibling of the current 
message. Since we take care of selecting a sensible message ourselves now,
that is not desirable. Disconnect the currentChanged signal during re-
threading to fix that.

CCMAIL: 66025-done@bugs.kde.org


  M +23 -1     kmheaders.cpp   1.598


--- kdepim/kmail/kmheaders.cpp  #1.597:1.598
@@ -1188,4 +1188,11 @@ void KMHeaders::msgAdded(int id)
     // The message we just added might be a better parent for one of the as of
     // yet imperfectly threaded messages. Let's find out.
+    
+    /* In case the current item is taken during reparenting, prevent qlistview
+     * from selecting some unrelated item as a result of take() emitting 
+     * currentChanged. */
+    disconnect( this, SIGNAL(currentChanged(QListViewItem*)),
+           this, SLOT(highlightMessage(QListViewItem*)));
+
     if ( !msgId.isEmpty() ) {
       QPtrListIterator<KMHeaderItem> it(mImperfectlyThreadedList);
@@ -1264,4 +1271,8 @@ void KMHeaders::msgAdded(int id)
   }
 
+  /* restore signal */
+  connect( this, SIGNAL(currentChanged(QListViewItem*)),
+           this, SLOT(highlightMessage(QListViewItem*)));
+
   END_TIMER(msgAdded);
   SHOW_TIMER(msgAdded);
@@ -1278,4 +1289,11 @@ void KMHeaders::msgRemoved(int id, QStri
   CREATE_TIMER(msgRemoved);
   START_TIMER(msgRemoved);
+  /* 
+   * qlistview has its own ideas about what to select as the next
+   * item once this one is removed. Sine we have already selected
+   * something in prepare/finalizeMove that's counter productive 
+   */
+  disconnect( this, SIGNAL(currentChanged(QListViewItem*)),
+              this, SLOT(highlightMessage(QListViewItem*)));
 
   KMHeaderItem *removedItem = mItems[id];
@@ -1359,4 +1377,9 @@ void KMHeaders::msgRemoved(int id, QStri
     setSelectionAnchor( currentItem() );
   }
+  
+  /* restore signal */
+  connect( this, SIGNAL(currentChanged(QListViewItem*)),
+           this, SLOT(highlightMessage(QListViewItem*)));
+
   END_TIMER(msgRemoved);
   SHOW_TIMER(msgRemoved);