Example #1
0
/*!
    \reimp
 */
QItemSelection QIdentityProxyModel::mapSelectionToSource(const QItemSelection& selection) const
{
    Q_D(const QIdentityProxyModel);
    QItemSelection sourceSelection;

    if (!d->model)
        return sourceSelection;

    QItemSelection::const_iterator it = selection.constBegin();
    const QItemSelection::const_iterator end = selection.constEnd();
    for ( ; it != end; ++it) {
        Q_ASSERT(it->model() == this);
        const QItemSelectionRange range(mapToSource(it->topLeft()), mapToSource(it->bottomRight()));
        sourceSelection.append(range);
    }

    return sourceSelection;
}
/** @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);
                }
            }
        }
    }
}
Example #3
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);
         }
       }
     }
   }
 }