mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Drag and drop
This commit is contained in:
@ -271,7 +271,10 @@ bool MainWindow::canPerformOperation(Operation operation) const
|
|||||||
return isSelected;
|
return isSelected;
|
||||||
|
|
||||||
case Operation::Paste:
|
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::RotateLeft:
|
||||||
case Operation::RotateRight:
|
case Operation::RotateRight:
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="dragDropMode">
|
<property name="dragDropMode">
|
||||||
<enum>QAbstractItemView::InternalMove</enum>
|
<enum>QAbstractItemView::DragDrop</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="defaultDropAction">
|
<property name="defaultDropAction">
|
||||||
<enum>Qt::MoveAction</enum>
|
<enum>Qt::MoveAction</enum>
|
||||||
@ -167,7 +167,7 @@
|
|||||||
<string>Remove Selection</string>
|
<string>Remove Selection</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut">
|
<property name="shortcut">
|
||||||
<string>Ctrl+R</string>
|
<string>Del</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionRestoreRemovedItems">
|
<action name="actionRestoreRemovedItems">
|
||||||
|
@ -375,5 +375,177 @@ std::set<int> PageGroupItem::getDocumentIndices() const
|
|||||||
return result;
|
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
|
} // namespace pdfdocpage
|
||||||
|
@ -60,6 +60,9 @@ class PageItemModel : public QAbstractItemModel
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
using BaseClass = QAbstractItemModel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PageItemModel(QObject* parent);
|
explicit PageItemModel(QObject* parent);
|
||||||
|
|
||||||
@ -69,6 +72,13 @@ public:
|
|||||||
virtual int rowCount(const QModelIndex& parent) const override;
|
virtual int rowCount(const QModelIndex& parent) const override;
|
||||||
virtual int columnCount(const QModelIndex& parent) const override;
|
virtual int columnCount(const QModelIndex& parent) const override;
|
||||||
virtual QVariant data(const QModelIndex& index, int role) 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
|
/// Adds document to the model, inserts one single page group containing
|
||||||
/// the whole document. Returns index of a newly added document. If document
|
/// the whole document. Returns index of a newly added document. If document
|
||||||
@ -102,6 +112,8 @@ public:
|
|||||||
void group(const QModelIndexList& list);
|
void group(const QModelIndexList& list);
|
||||||
void ungroup(const QModelIndexList& list);
|
void ungroup(const QModelIndexList& list);
|
||||||
|
|
||||||
|
static QString getMimeDataType() { return QLatin1String("application/pagemodel.PDF4QtDocPageOrganizer"); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createDocumentGroup(int index);
|
void createDocumentGroup(int index);
|
||||||
QString getGroupNameFromDocument(int index) const;
|
QString getGroupNameFromDocument(int index) const;
|
||||||
|
Reference in New Issue
Block a user