Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 3

Qt-interest Archive, June 2007
Qt 4.3.0 PATCH: fix item selection when dragging over a list


Message 1 in thread

Since Qt4 a QTreeWidget has the nasty habit of toggling
items when dragging over them. The attached example demonstrates
this.

Run the attached example and see a QTreeWidget with
many items, where every other one is selected. Maximize the
window vertically to see the entire list.
In my application there is often the need to (de)select a group
of items in a list where selected and deselected items are mixed.
What I need is a way that allows the user to,
for instance, click on item 1 (which deselects it) and drag the mouse
cursor down to, say, item 20 in order to have the first 20 items
deselected. In Qt3 this worked right out of the box - when clicking
on an item and dragging over others, the new selection state of
the item that has been clicked on was also applied to all the items
the user dragged over.

Unfortunately this was broken in Qt4 (where the selection state of
the items the user drags over is toggled - which, quite frankly, I
can't imagine has any useful application), and TT is apparently
not willing to do anything about this.

The attached patch brings back the expected behavior - at least it
works for me that way.
Maybe this is also useful for others.

Klaus Schmidinger
#include <qapplication.h>
#include <qapplication.h>
#include <qdialog.h>
#include <qlayout.h>
#include <qheaderview.h>
#include <qtreewidget.h>

class cSelectTree : public QTreeWidget {
public:
  cSelectTree(QWidget *parent);
  };

cSelectTree::cSelectTree(QWidget *parent)
:QTreeWidget(parent)
{
  setSelectionMode(QAbstractItemView::MultiSelection);
  setColumnCount(3);
  setRootIsDecorated(false);
  QTreeWidgetItem *h = headerItem();
  h->setText(0, "Test");
  for (int i = 1; i <= 50; ++i) {
      QTreeWidgetItem *b = new QTreeWidgetItem(this);
      b->setText(0, "This is item number " + QString::number(i));
      b->setFlags(b->flags() | Qt::ItemIsEditable);
      if (i & 1)
         setItemSelected(b, true);
      }
  resizeColumnToContents(0);
}

class cDialog : public QDialog {
public:
  cDialog(QWidget *parent);
  };

cDialog::cDialog(QWidget *parent)
{
  QVBoxLayout *vbl = new QVBoxLayout(this);
  vbl->addWidget(new cSelectTree(this));
}

int main(int argc, char *argv[])
{
  QApplication myapp(argc, argv);
  cDialog *cd = new cDialog(NULL);
  cd->show();
  return myapp.exec();
}
# fix selecting items in lists when dragging over them (TT#110876)
# fix selecting items in lists when dragging over them (TT#110876)
--- src/gui/itemviews/qabstractitemview.cpp.001	2007-05-25 15:30:23.000000000 +0200
+++ src/gui/itemviews/qabstractitemview.cpp	2007-06-11 13:59:34.521331834 +0200
@@ -441,6 +441,7 @@
     : QAbstractScrollArea(*(new QAbstractItemViewPrivate), parent)
 {
     d_func()->init();
+    mouseMoveSelect = 0;
 }
 
 /*!
@@ -1383,6 +1384,7 @@
             d->delayedAutoScroll.start(QApplication::doubleClickInterval()+100, this);
         }
 
+        mouseMoveSelect = d->selectionModel->isSelected(index) ? 1 : -1;
     }
 }
 
@@ -1464,7 +1466,9 @@
 
     if ((event->buttons() & Qt::LeftButton) && d->selectionAllowed(index) && d->selectionModel) {
         setState(DragSelectingState);
-        QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
+        QItemSelectionModel::SelectionFlags command =
+          mouseMoveSelect ? (mouseMoveSelect > 0 ? QItemSelectionModel::Select : QItemSelectionModel::Deselect) | QItemSelectionModel::Current | QItemSelectionModel::Rows
+                          : selectionCommand(index, event);
 
         // Do the normalize ourselves, since QRect::normalized() is flawed
         QRect selectionRect = QRect(topLeft, bottomRight);
@@ -1486,6 +1490,7 @@
 {
     Q_D(QAbstractItemView);
 
+    mouseMoveSelect = 0;
     QPoint pos = event->pos();
     QPersistentModelIndex index = indexAt(pos);
 
# fix selecting items in lists when dragging over them (TT#110876)
# fix selecting items in lists when dragging over them (TT#110876)
--- src/gui/itemviews/qabstractitemview.h.001	2007-05-25 15:30:24.000000000 +0200
+++ src/gui/itemviews/qabstractitemview.h	2007-06-11 13:56:09.688853088 +0200
@@ -329,6 +329,9 @@
 
     friend class QTreeViewPrivate; // needed to compile with MSVC
     friend class QAccessibleItemRow;
+#define QT_PATCH_CS20070611_2
+//XXX fix selecting items in lists when dragging over them (TT#110876)
+    int mouseMoveSelect;
 };
 
 Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractItemView::EditTriggers)