mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-03-03 10:57:40 +01:00
Drag and drop
This commit is contained in:
parent
ee587d0809
commit
8442143efc
@ -271,7 +271,10 @@ bool MainWindow::canPerformOperation(Operation operation) const
|
||||
return isSelected;
|
||||
|
||||
case Operation::Paste:
|
||||
return !QApplication::clipboard()->text().isEmpty();
|
||||
{
|
||||
const QMimeData* mimeData = QApplication::clipboard()->mimeData();
|
||||
return mimeData && mimeData->hasFormat(PageItemModel::getMimeDataType());
|
||||
}
|
||||
|
||||
case Operation::RotateLeft:
|
||||
case Operation::RotateRight:
|
||||
|
@ -21,7 +21,7 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
@ -167,7 +167,7 @@
|
||||
<string>Remove Selection</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+R</string>
|
||||
<string>Del</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRestoreRemovedItems">
|
||||
|
@ -375,5 +375,177 @@ std::set<int> PageGroupItem::getDocumentIndices() const
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList PageItemModel::mimeTypes() const
|
||||
{
|
||||
return { getMimeDataType() };
|
||||
}
|
||||
|
||||
QMimeData* PageItemModel::mimeData(const QModelIndexList& indexes) const
|
||||
{
|
||||
if (indexes.isEmpty())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QMimeData* mimeData = new QMimeData;
|
||||
|
||||
QByteArray serializedData;
|
||||
{
|
||||
QDataStream stream(&serializedData, QIODevice::WriteOnly);
|
||||
for (const QModelIndex& index : indexes)
|
||||
{
|
||||
stream << index.row();
|
||||
}
|
||||
}
|
||||
|
||||
mimeData->setData(getMimeDataType(), serializedData);
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
bool PageItemModel::canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(column);
|
||||
Q_UNUSED(parent);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case Qt::CopyAction:
|
||||
case Qt::MoveAction:
|
||||
case Qt::IgnoreAction:
|
||||
break;
|
||||
|
||||
case Qt::LinkAction:
|
||||
case Qt::TargetMoveAction:
|
||||
return false;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return data && data->hasFormat(getMimeDataType());
|
||||
}
|
||||
|
||||
bool PageItemModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
|
||||
{
|
||||
if (action == Qt::IgnoreAction)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!data->hasFormat(getMimeDataType()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (column > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int insertRow = rowCount(QModelIndex());
|
||||
if (row > -1)
|
||||
{
|
||||
insertRow = row;
|
||||
}
|
||||
else if (parent.isValid())
|
||||
{
|
||||
insertRow = parent.row();
|
||||
}
|
||||
|
||||
std::vector<int> rows;
|
||||
|
||||
QByteArray serializedData = data->data(getMimeDataType());
|
||||
QDataStream stream(&serializedData, QIODevice::ReadOnly);
|
||||
while (!stream.atEnd())
|
||||
{
|
||||
int row = -1;
|
||||
stream >> row;
|
||||
rows.push_back(row);
|
||||
}
|
||||
|
||||
qSort(rows);
|
||||
|
||||
// Sanity checks on rows
|
||||
if (rows.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (rows.front() < 0 || rows.back() >= rowCount(QModelIndex()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<PageGroupItem> newItems = m_pageGroupItems;
|
||||
std::vector<PageGroupItem> workItems;
|
||||
|
||||
// When moving, update insert row
|
||||
if (action == Qt::MoveAction)
|
||||
{
|
||||
const int originalInsertRow = insertRow;
|
||||
if (rows.front() < originalInsertRow)
|
||||
{
|
||||
++insertRow;
|
||||
}
|
||||
|
||||
for (int currentRow : rows)
|
||||
{
|
||||
if (currentRow < originalInsertRow)
|
||||
{
|
||||
--insertRow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
workItems.reserve(rows.size());
|
||||
for (int currentRow : rows)
|
||||
{
|
||||
workItems.push_back(m_pageGroupItems[currentRow]);
|
||||
}
|
||||
|
||||
// When move, delete old page items
|
||||
if (action == Qt::MoveAction)
|
||||
{
|
||||
for (auto it = rows.rbegin(); it != rows.rend(); ++it)
|
||||
{
|
||||
newItems.erase(std::next(newItems.begin(), *it));
|
||||
}
|
||||
}
|
||||
|
||||
// Insert work items at a given position
|
||||
newItems.insert(std::next(newItems.begin(), insertRow), workItems.begin(), workItems.end());
|
||||
|
||||
if (newItems != m_pageGroupItems)
|
||||
{
|
||||
beginResetModel();
|
||||
m_pageGroupItems = std::move(newItems);
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::DropActions PageItemModel::supportedDropActions() const
|
||||
{
|
||||
return Qt::CopyAction | Qt::MoveAction;
|
||||
}
|
||||
|
||||
Qt::DropActions PageItemModel::supportedDragActions() const
|
||||
{
|
||||
return Qt::CopyAction | Qt::MoveAction;
|
||||
}
|
||||
|
||||
Qt::ItemFlags PageItemModel::flags(const QModelIndex& index) const
|
||||
{
|
||||
Qt::ItemFlags flags = BaseClass::flags(index);
|
||||
|
||||
if (index.isValid())
|
||||
{
|
||||
flags |= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
} // namespace pdfdocpage
|
||||
|
@ -60,6 +60,9 @@ class PageItemModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = QAbstractItemModel;
|
||||
|
||||
public:
|
||||
explicit PageItemModel(QObject* parent);
|
||||
|
||||
@ -69,6 +72,13 @@ public:
|
||||
virtual int rowCount(const QModelIndex& parent) const override;
|
||||
virtual int columnCount(const QModelIndex& parent) const override;
|
||||
virtual QVariant data(const QModelIndex& index, int role) const override;
|
||||
virtual QStringList mimeTypes() const override;
|
||||
virtual QMimeData* mimeData(const QModelIndexList& indexes) const override;
|
||||
virtual bool canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) const override;
|
||||
virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override;
|
||||
virtual Qt::DropActions supportedDropActions() const override;
|
||||
virtual Qt::DropActions supportedDragActions() const override;
|
||||
virtual Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
|
||||
/// Adds document to the model, inserts one single page group containing
|
||||
/// the whole document. Returns index of a newly added document. If document
|
||||
@ -102,6 +112,8 @@ public:
|
||||
void group(const QModelIndexList& list);
|
||||
void ungroup(const QModelIndexList& list);
|
||||
|
||||
static QString getMimeDataType() { return QLatin1String("application/pagemodel.PDF4QtDocPageOrganizer"); }
|
||||
|
||||
private:
|
||||
void createDocumentGroup(int index);
|
||||
QString getGroupNameFromDocument(int index) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user