Andrew
11th April 2007, 14:39
Hi,
I wanted to change a minor thing in QListWidget
I don't like how drop indicator is working.
In the current default behaviour, if you move the drag item(s) around and if the cursor is on the right position, the drop indicator appears after \ before an item or even on the entire item (if you change and a flag to the item flags)
Now, I searched in the doc and source code to see how can I make the region which determines to display the drop indicator after \ before an item, a little big bigger.
My result now is that it can be done only if I re-write drag move and drop events.
So I have 2 issues:
1. to make the dropindicator 'zone' a little bigger.
2. when dropping an item over another item the default behaviour will append the dragged item at the end of the list.
for #2: i end up in this code which shows clearly this behaviour:
bool QAbstractItemViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
{
.....
// If we are allowed to do the drop
if (model->supportedDropActions() & event->proposedAction()) {
int row = -1;
int col = -1;
if ((index != root) &&
(model->flags(index) & Qt::ItemIsDropEnabled
|| model->flags(index.parent()) & Qt::ItemIsDropEnabled)) {
dropIndicatorPosition = position(event->pos(), q->visualRect(index));
switch (dropIndicatorPosition) {
case QAbstractItemView::AboveItem:
row = index.row();
col = index.column();
index = index.parent();
break;
case QAbstractItemView::BelowItem:
row = index.row() + 1;
col = index.column();
index = index.parent();
break;
case QAbstractItemView::OnItem:
case QAbstractItemView::OnViewport:
break;
}
} else {
dropIndicatorPosition = QAbstractItemView::OnViewport;
}
*dropIndex = index;
*dropRow = row;
*dropCol = col;
return true;
}
return false;
}
so this means that if the dragged item is on another item the OUT variables dropIndex is -1which makes QListWidget::dropEvent( ) to append at the end.
void QListWidget::dropEvent(QDropEvent *event) {
.....
if (d->dropOn(event, &row, &col, &topIndex)) {
.....
// insert them back in at their new positions
for (int i = 0; i < persIndexes.count(); ++i) {
// Either at a specific point or appended
if (row == -1) {
insertItem(count(), taken.takeFirst()); <---------- ends up here
} else {
int r = dropRow.row() >= 0 ? dropRow.row() : row;
insertItem(qMin(r, count()), taken.takeFirst());
}
}
why QAbstractItemView::OnItem is implemented like this is a mistery to me.
I wanted to change a minor thing in QListWidget
I don't like how drop indicator is working.
In the current default behaviour, if you move the drag item(s) around and if the cursor is on the right position, the drop indicator appears after \ before an item or even on the entire item (if you change and a flag to the item flags)
Now, I searched in the doc and source code to see how can I make the region which determines to display the drop indicator after \ before an item, a little big bigger.
My result now is that it can be done only if I re-write drag move and drop events.
So I have 2 issues:
1. to make the dropindicator 'zone' a little bigger.
2. when dropping an item over another item the default behaviour will append the dragged item at the end of the list.
for #2: i end up in this code which shows clearly this behaviour:
bool QAbstractItemViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
{
.....
// If we are allowed to do the drop
if (model->supportedDropActions() & event->proposedAction()) {
int row = -1;
int col = -1;
if ((index != root) &&
(model->flags(index) & Qt::ItemIsDropEnabled
|| model->flags(index.parent()) & Qt::ItemIsDropEnabled)) {
dropIndicatorPosition = position(event->pos(), q->visualRect(index));
switch (dropIndicatorPosition) {
case QAbstractItemView::AboveItem:
row = index.row();
col = index.column();
index = index.parent();
break;
case QAbstractItemView::BelowItem:
row = index.row() + 1;
col = index.column();
index = index.parent();
break;
case QAbstractItemView::OnItem:
case QAbstractItemView::OnViewport:
break;
}
} else {
dropIndicatorPosition = QAbstractItemView::OnViewport;
}
*dropIndex = index;
*dropRow = row;
*dropCol = col;
return true;
}
return false;
}
so this means that if the dragged item is on another item the OUT variables dropIndex is -1which makes QListWidget::dropEvent( ) to append at the end.
void QListWidget::dropEvent(QDropEvent *event) {
.....
if (d->dropOn(event, &row, &col, &topIndex)) {
.....
// insert them back in at their new positions
for (int i = 0; i < persIndexes.count(); ++i) {
// Either at a specific point or appended
if (row == -1) {
insertItem(count(), taken.takeFirst()); <---------- ends up here
} else {
int r = dropRow.row() >= 0 ? dropRow.row() : row;
insertItem(qMin(r, count()), taken.takeFirst());
}
}
why QAbstractItemView::OnItem is implemented like this is a mistery to me.