예제 #1
0
/** @short Reimplemented to show custom pixmap during drag&drop

  Qt's model-view classes don't provide any means of interfering with the
  QDrag's pixmap so we just rip off QAbstractItemView::startDrag and provide
  our own QPixmap.
*/
void MsgListView::startDrag(Qt::DropActions supportedActions)
{
    // indexes for column 0, i.e. subject
    QModelIndexList baseIndexes;

    Q_FOREACH(const QModelIndex &index, selectedIndexes()) {
        if (!(model()->flags(index) & Qt::ItemIsDragEnabled))
            continue;
        if (index.column() == Imap::Mailbox::MsgListModel::SUBJECT)
            baseIndexes << index;
    }

    if (!baseIndexes.isEmpty()) {
        QMimeData *data = model()->mimeData(baseIndexes);
        if (!data)
            return;

        // use screen width and itemDelegate()->sizeHint() to determine size of the pixmap
        int screenWidth = QApplication::desktop()->screenGeometry(this).width();
        int maxWidth = qMax(400, screenWidth / 4);
        QSize size(maxWidth, 0);

        // Show a "+ X more items" text after so many entries
        const int maxItems = 20;

        QStyleOptionViewItem opt;
        opt.initFrom(this);
        opt.rect.setWidth(maxWidth);
        opt.rect.setHeight(itemDelegate()->sizeHint(opt, baseIndexes.at(0)).height());
        size.setHeight(qMin(maxItems + 1, baseIndexes.size()) * opt.rect.height());
        // State_Selected provides for nice background of the items
        opt.state |= QStyle::State_Selected;

        // paint list of selected items using itemDelegate() to be consistent with style
        QPixmap pixmap(size);
        pixmap.fill(Qt::transparent);
        QPainter p(&pixmap);

        for (int i = 0; i < baseIndexes.size(); ++i) {
            opt.rect.moveTop(i * opt.rect.height());
            if (i == maxItems) {
                p.fillRect(opt.rect, palette().color(QPalette::Disabled, QPalette::Highlight));
                p.setBrush(palette().color(QPalette::Disabled, QPalette::HighlightedText));
                p.drawText(opt.rect, Qt::AlignRight, tr("+ %n additional item(s)", 0, baseIndexes.size() - maxItems));
                break;
            }
            itemDelegate()->paint(&p, opt, baseIndexes.at(i));
        }

        QDrag *drag = new QDrag(this);
        drag->setPixmap(pixmap);
        drag->setMimeData(data);
        drag->setHotSpot(QPoint(0, 0));

        Qt::DropAction dropAction = Qt::IgnoreAction;
        if (defaultDropAction() != Qt::IgnoreAction && (supportedActions & defaultDropAction()))
            dropAction = defaultDropAction();
        else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
            dropAction = Qt::CopyAction;
        if (drag->exec(supportedActions, dropAction) == Qt::MoveAction) {
            // QAbstractItemView::startDrag calls d->clearOrRemove() here, so
            // this is a copy of QAbstractItemModelPrivate::clearOrRemove();
            const QItemSelection selection = selectionModel()->selection();
            QList<QItemSelectionRange>::const_iterator it = selection.constBegin();

            if (!dragDropOverwriteMode()) {
                for (; it != selection.constEnd(); ++it) {
                    QModelIndex parent = it->parent();
                    if (it->left() != 0)
                        continue;
                    if (it->right() != (model()->columnCount(parent) - 1))
                        continue;
                    int count = it->bottom() - it->top() + 1;
                    model()->removeRows(it->top(), count, parent);
                }
            } else {
                // we can't remove the rows so reset the items (i.e. the view is like a table)
                QModelIndexList list = selection.indexes();
                for (int i = 0; i < list.size(); ++i) {
                    QModelIndex index = list.at(i);
                    QMap<int, QVariant> roles = model()->itemData(index);
                    for (QMap<int, QVariant>::Iterator it = roles.begin(); it != roles.end(); ++it)
                        it.value() = QVariant();
                    model()->setItemData(index, roles);
                }
            }
        }
    }
}
int QAbstractItemView::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QAbstractScrollArea::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: pressed((*reinterpret_cast< const QModelIndex(*)>(_a[1]))); break;
        case 1: clicked((*reinterpret_cast< const QModelIndex(*)>(_a[1]))); break;
        case 2: doubleClicked((*reinterpret_cast< const QModelIndex(*)>(_a[1]))); break;
        case 3: activated((*reinterpret_cast< const QModelIndex(*)>(_a[1]))); break;
        case 4: entered((*reinterpret_cast< const QModelIndex(*)>(_a[1]))); break;
        case 5: viewportEntered(); break;
        case 6: reset(); break;
        case 7: setRootIndex((*reinterpret_cast< const QModelIndex(*)>(_a[1]))); break;
        case 8: doItemsLayout(); break;
        case 9: selectAll(); break;
        case 10: edit((*reinterpret_cast< const QModelIndex(*)>(_a[1]))); break;
        case 11: clearSelection(); break;
        case 12: setCurrentIndex((*reinterpret_cast< const QModelIndex(*)>(_a[1]))); break;
        case 13: scrollToTop(); break;
        case 14: scrollToBottom(); break;
        case 15: update((*reinterpret_cast< const QModelIndex(*)>(_a[1]))); break;
        case 16: dataChanged((*reinterpret_cast< const QModelIndex(*)>(_a[1])),(*reinterpret_cast< const QModelIndex(*)>(_a[2]))); break;
        case 17: rowsInserted((*reinterpret_cast< const QModelIndex(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3]))); break;
        case 18: rowsAboutToBeRemoved((*reinterpret_cast< const QModelIndex(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3]))); break;
        case 19: selectionChanged((*reinterpret_cast< const QItemSelection(*)>(_a[1])),(*reinterpret_cast< const QItemSelection(*)>(_a[2]))); break;
        case 20: currentChanged((*reinterpret_cast< const QModelIndex(*)>(_a[1])),(*reinterpret_cast< const QModelIndex(*)>(_a[2]))); break;
        case 21: updateEditorData(); break;
        case 22: updateEditorGeometries(); break;
        case 23: updateGeometries(); break;
        case 24: verticalScrollbarAction((*reinterpret_cast< int(*)>(_a[1]))); break;
        case 25: horizontalScrollbarAction((*reinterpret_cast< int(*)>(_a[1]))); break;
        case 26: verticalScrollbarValueChanged((*reinterpret_cast< int(*)>(_a[1]))); break;
        case 27: horizontalScrollbarValueChanged((*reinterpret_cast< int(*)>(_a[1]))); break;
        case 28: closeEditor((*reinterpret_cast< QWidget*(*)>(_a[1])),(*reinterpret_cast< QAbstractItemDelegate::EndEditHint(*)>(_a[2]))); break;
        case 29: commitData((*reinterpret_cast< QWidget*(*)>(_a[1]))); break;
        case 30: editorDestroyed((*reinterpret_cast< QObject*(*)>(_a[1]))); break;
        case 31: d_func()->_q_columnsAboutToBeRemoved((*reinterpret_cast< const QModelIndex(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3]))); break;
        case 32: d_func()->_q_columnsRemoved((*reinterpret_cast< const QModelIndex(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3]))); break;
        case 33: d_func()->_q_rowsRemoved((*reinterpret_cast< const QModelIndex(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2])),(*reinterpret_cast< int(*)>(_a[3]))); break;
        case 34: d_func()->_q_modelDestroyed(); break;
        case 35: d_func()->_q_layoutChanged(); break;
        case 36: d_func()->_q_fetchMore(); break;
        }
        _id -= 37;
    }
#ifndef QT_NO_PROPERTIES
      else if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< bool*>(_v) = hasAutoScroll(); break;
        case 1: *reinterpret_cast< int*>(_v) = autoScrollMargin(); break;
        case 2: *reinterpret_cast<int*>(_v) = QFlag(editTriggers()); break;
        case 3: *reinterpret_cast< bool*>(_v) = tabKeyNavigation(); break;
        case 4: *reinterpret_cast< bool*>(_v) = showDropIndicator(); break;
        case 5: *reinterpret_cast< bool*>(_v) = dragEnabled(); break;
        case 6: *reinterpret_cast< bool*>(_v) = dragDropOverwriteMode(); break;
        case 7: *reinterpret_cast< DragDropMode*>(_v) = dragDropMode(); break;
        case 8: *reinterpret_cast< bool*>(_v) = alternatingRowColors(); break;
        case 9: *reinterpret_cast< SelectionMode*>(_v) = selectionMode(); break;
        case 10: *reinterpret_cast< SelectionBehavior*>(_v) = selectionBehavior(); break;
        case 11: *reinterpret_cast< QSize*>(_v) = iconSize(); break;
        case 12: *reinterpret_cast< Qt::TextElideMode*>(_v) = textElideMode(); break;
        case 13: *reinterpret_cast< ScrollMode*>(_v) = verticalScrollMode(); break;
        case 14: *reinterpret_cast< ScrollMode*>(_v) = horizontalScrollMode(); break;
        }
        _id -= 15;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: setAutoScroll(*reinterpret_cast< bool*>(_v)); break;
        case 1: setAutoScrollMargin(*reinterpret_cast< int*>(_v)); break;
        case 2: setEditTriggers(QFlag(*reinterpret_cast<int*>(_v))); break;
        case 3: setTabKeyNavigation(*reinterpret_cast< bool*>(_v)); break;
        case 4: setDropIndicatorShown(*reinterpret_cast< bool*>(_v)); break;
        case 5: setDragEnabled(*reinterpret_cast< bool*>(_v)); break;
        case 6: setDragDropOverwriteMode(*reinterpret_cast< bool*>(_v)); break;
        case 7: setDragDropMode(*reinterpret_cast< DragDropMode*>(_v)); break;
        case 8: setAlternatingRowColors(*reinterpret_cast< bool*>(_v)); break;
        case 9: setSelectionMode(*reinterpret_cast< SelectionMode*>(_v)); break;
        case 10: setSelectionBehavior(*reinterpret_cast< SelectionBehavior*>(_v)); break;
        case 11: setIconSize(*reinterpret_cast< QSize*>(_v)); break;
        case 12: setTextElideMode(*reinterpret_cast< Qt::TextElideMode*>(_v)); break;
        case 13: setVerticalScrollMode(*reinterpret_cast< ScrollMode*>(_v)); break;
        case 14: setHorizontalScrollMode(*reinterpret_cast< ScrollMode*>(_v)); break;
        }
        _id -= 15;
    } else if (_c == QMetaObject::ResetProperty) {
        _id -= 15;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= 15;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= 15;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= 15;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= 15;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= 15;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}
int QAbstractItemView::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QAbstractScrollArea::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        if (_id < 39)
            qt_static_metacall(this, _c, _id, _a);
        _id -= 39;
    }
#ifndef QT_NO_PROPERTIES
      else if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< bool*>(_v) = hasAutoScroll(); break;
        case 1: *reinterpret_cast< int*>(_v) = autoScrollMargin(); break;
        case 2: *reinterpret_cast<int*>(_v) = QFlag(editTriggers()); break;
        case 3: *reinterpret_cast< bool*>(_v) = tabKeyNavigation(); break;
        case 4: *reinterpret_cast< bool*>(_v) = showDropIndicator(); break;
        case 5: *reinterpret_cast< bool*>(_v) = dragEnabled(); break;
        case 6: *reinterpret_cast< bool*>(_v) = dragDropOverwriteMode(); break;
        case 7: *reinterpret_cast< DragDropMode*>(_v) = dragDropMode(); break;
        case 8: *reinterpret_cast< Qt::DropAction*>(_v) = defaultDropAction(); break;
        case 9: *reinterpret_cast< bool*>(_v) = alternatingRowColors(); break;
        case 10: *reinterpret_cast< SelectionMode*>(_v) = selectionMode(); break;
        case 11: *reinterpret_cast< SelectionBehavior*>(_v) = selectionBehavior(); break;
        case 12: *reinterpret_cast< QSize*>(_v) = iconSize(); break;
        case 13: *reinterpret_cast< Qt::TextElideMode*>(_v) = textElideMode(); break;
        case 14: *reinterpret_cast< ScrollMode*>(_v) = verticalScrollMode(); break;
        case 15: *reinterpret_cast< ScrollMode*>(_v) = horizontalScrollMode(); break;
        }
        _id -= 16;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: setAutoScroll(*reinterpret_cast< bool*>(_v)); break;
        case 1: setAutoScrollMargin(*reinterpret_cast< int*>(_v)); break;
        case 2: setEditTriggers(QFlag(*reinterpret_cast<int*>(_v))); break;
        case 3: setTabKeyNavigation(*reinterpret_cast< bool*>(_v)); break;
        case 4: setDropIndicatorShown(*reinterpret_cast< bool*>(_v)); break;
        case 5: setDragEnabled(*reinterpret_cast< bool*>(_v)); break;
        case 6: setDragDropOverwriteMode(*reinterpret_cast< bool*>(_v)); break;
        case 7: setDragDropMode(*reinterpret_cast< DragDropMode*>(_v)); break;
        case 8: setDefaultDropAction(*reinterpret_cast< Qt::DropAction*>(_v)); break;
        case 9: setAlternatingRowColors(*reinterpret_cast< bool*>(_v)); break;
        case 10: setSelectionMode(*reinterpret_cast< SelectionMode*>(_v)); break;
        case 11: setSelectionBehavior(*reinterpret_cast< SelectionBehavior*>(_v)); break;
        case 12: setIconSize(*reinterpret_cast< QSize*>(_v)); break;
        case 13: setTextElideMode(*reinterpret_cast< Qt::TextElideMode*>(_v)); break;
        case 14: setVerticalScrollMode(*reinterpret_cast< ScrollMode*>(_v)); break;
        case 15: setHorizontalScrollMode(*reinterpret_cast< ScrollMode*>(_v)); break;
        }
        _id -= 16;
    } else if (_c == QMetaObject::ResetProperty) {
        _id -= 16;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= 16;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= 16;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= 16;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= 16;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= 16;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}
예제 #4
0
void TreeViewWidget::startDrag(Qt::DropActions pSupportedActions)
{
    // This a reimplementation of QAbstractItemView::startDrag, so that we can
    // provide OpenCOR with a better pixmap for the drag object
    // Note: indeed, on Windows, the pixmap only shows the dragged item that are
    //       visible in the QTreeView. Also, if there an item covers several
    //       columns, then the pixmap will show several 'cells' some of them
    //       empty if a column is empty, so... instead we want to provide a
    //       generic pixmap which looks 'good' on all platforms...

    // Retrieve the selected draggable items, if any
    // Note: the following code is based on
    //       QAbstractItemViewPrivate::selectedDraggableIndexes...

    QModelIndexList selectedDraggableIndexes = selectedIndexes();

    for (int i = selectedDraggableIndexes.count()-1; i >= 0; --i)
        if (   !(model()->flags(selectedDraggableIndexes[i]) & Qt::ItemIsDragEnabled)
            || selectedDraggableIndexes[i].column())
            // The current selected item is not draggable or is not in the first
            // column
            // Note: regarding the test on the column number, it is because we
            //       may have a model data that requires several columns (e.g.
            //       QFileSystemModel) in which case selectedIndexes would
            //       return a number of indexes equal to the number of rows
            //       times the number of columns while we only want a number of
            //       indexes to be equal to the number of rows (since we have a
            //       selection mode of QAbstractItemView::ExtendedSelection)

            selectedDraggableIndexes.removeAt(i);

    // Start the dragging action is there is at least one selected draggable
    // item

    if (selectedDraggableIndexes.count()) {
        // There is at least one selected draggable item, so create a QMimeData
        // object for it

        QMimeData *mimeData = model()->mimeData(selectedDraggableIndexes);

        if (!mimeData)
            return;

        // Create the pixmap that will be associated with the dragging action

        QPixmap pixmap((selectedDraggableIndexes.count() == 1)?
                           ":oxygen/mimetypes/application-x-zerosize.png":
                           ":oxygen/places/document-multiple.png");

        // Create the drag object

        QDrag *drag = new QDrag(this);

        drag->setMimeData(mimeData);
        drag->setPixmap(pixmap);
        drag->setHotSpot(QPoint(0.5*pixmap.width(), 0.5*pixmap.height()));

        // Do the dragging itself

        Qt::DropAction realDefaultDropAction = Qt::IgnoreAction;

        if (   (defaultDropAction() != Qt::IgnoreAction)
            && (pSupportedActions & defaultDropAction()))
            realDefaultDropAction = defaultDropAction();
        else if (   (pSupportedActions & Qt::CopyAction)
                 && (dragDropMode() != QAbstractItemView::InternalMove))
            realDefaultDropAction = Qt::CopyAction;

        if (drag->exec(pSupportedActions, realDefaultDropAction) == Qt::MoveAction) {
            // We want to move the items
            // Note: the following code is based on
            //       QAbstractItemViewPrivate::clearOrRemove...

            const QItemSelection selection = selectionModel()->selection();

            if (!dragDropOverwriteMode()) {
                foreach (const QItemSelectionRange &itemSelectionRange, selection) {
                    QModelIndex parent = itemSelectionRange.parent();

                    if (itemSelectionRange.left())
                        continue;

                    if (itemSelectionRange.right() != (model()->columnCount(parent)-1))
                        continue;

                    model()->removeRows(itemSelectionRange.top(),
                                        itemSelectionRange.bottom()-itemSelectionRange.top()+1,
                                        parent);
                }
            } else {
예제 #5
0
 void MacroTreeView::startDrag(Qt::DropActions supportedActions)
 {
   QModelIndexList indexes = selectionModel()->selectedRows();
   for(int i = indexes.count() - 1 ; i >= 0; --i)
   {
     if (!(indexes.at(i).isValid()) || !(model()->flags(indexes.at(i)) & Qt::ItemIsDragEnabled))
     {
       indexes.removeAt(i);
     }
   }
   if (indexes.count() > 0)
   {
     QMimeData *data = model()->mimeData(indexes);
     if (!data)
     {
       return;
     }
     QPixmap dragPixmap(":/icons/resources/macro.png");
     QModelIndex srcIndex = dynamic_cast<QSortFilterProxyModel*>(model())->mapToSource(indexes[0]);
     const ModelItemMacro* item = static_cast<const ModelItemMacro*>(srcIndex.internalPointer());
     graph::Vertex::Ptr dummyVertex = app::MacroManager::instance().createVertexInstance(item->macro().signature());
     if (!dummyVertex.isNull())
     {
       graph::VertexItem::Ptr vertexItem = dummyVertex->sceneItem().staticCast<graph::VertexItem>();
       if (!vertexItem.isNull())
       {
         dragPixmap = vertexItem->paintToPixmap();
       }
       app::MacroManager::instance().deleteVertexInstance(dummyVertex);
     }
     data->setImageData(dragPixmap.toImage());
     QDrag* dragObjectPtr = new QDrag(this);
     dragObjectPtr->setPixmap(dragPixmap);
     dragObjectPtr->setMimeData(data);
     dragObjectPtr->setHotSpot(dragPixmap.rect().center());
     Qt::DropAction defDropAction = Qt::IgnoreAction;
     if (defaultDropAction() != Qt::IgnoreAction && (supportedActions & defaultDropAction()))
     {
       defDropAction = defaultDropAction();
     }
     else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
     {
       defDropAction = Qt::CopyAction;
     }
     if (dragObjectPtr->exec(supportedActions, defDropAction) == Qt::MoveAction)
     {
       // clear or remove dragged items
       const QItemSelection selection = selectionModel()->selection();
       QList<QItemSelectionRange>::const_iterator it = selection.constBegin();
       if (!dragDropOverwriteMode())
       {
         for (; it != selection.constEnd(); ++it)
         {
           QModelIndex parent = (*it).parent();
           if ((*it).left() != 0)
             continue;
           if ((*it).right() != (model()->columnCount(parent) - 1))
             continue;
           int count = (*it).bottom() - (*it).top() + 1;
           model()->removeRows((*it).top(), count, parent);
         }
       }
       else
       {
         QModelIndexList list = selection.indexes();
         for (int i=0; i < list.size(); ++i)
         {
           QModelIndex index = list.at(i);
           QMap<int, QVariant> roles = model()->itemData(index);
           for (QMap<int, QVariant>::Iterator it = roles.begin(); it != roles.end(); ++it)
           {
             it.value() = QVariant();
           }
           model()->setItemData(index, roles);
         }
       }
     }
   }
 }