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.
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).
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);
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
Created attachment 3513 [details] Screenshot showin the problem with 2003/11/31 build
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.
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);