Finish work in drag&drop of Actions

This commit is contained in:
2024-01-04 20:22:39 +01:00
parent 7571c4b1ad
commit ffe4a99baa
12 changed files with 782 additions and 489 deletions
+180 -2
View File
@@ -2,6 +2,10 @@
#include <QDebug>
#include <QIcon>
#include <QMimeData>
#include "projectserialization.h"
#include "stdserialization.h"
ActionsContainerModel::ActionsContainerModel(QObject *parent) :
QAbstractListModel{parent}
@@ -86,7 +90,7 @@ Qt::DropActions ActionsContainerModel::supportedDropActions() const
{
auto actions = QAbstractListModel::supportedDropActions();
actions |= Qt::MoveAction;
actions |= Qt::TargetMoveAction;
// actions |= Qt::TargetMoveAction;
return actions;
}
@@ -94,10 +98,184 @@ Qt::DropActions ActionsContainerModel::supportedDragActions() const
{
auto actions = QAbstractListModel::supportedDragActions();
actions |= Qt::MoveAction;
actions |= Qt::TargetMoveAction;
// actions |= Qt::TargetMoveAction;
return actions;
}
QStringList ActionsContainerModel::mimeTypes() const
{
return {"custom"};
}
QMimeData *ActionsContainerModel::mimeData(const QModelIndexList &indexes) const
{
if (!m_actionsContainer)
return nullptr;
if (indexes.size() <= 0)
return nullptr;
QStringList types = mimeTypes();
if (types.isEmpty())
return nullptr;
QMimeData *data = new QMimeData;
QString format = types.at(0);
QByteArray encoded;
QDataStream stream(&encoded, QDataStream::WriteOnly);
for (const auto &index : indexes)
{
const Action &action = *std::next(std::cbegin(*m_actionsContainer), index.row());
stream << action;
}
data->setData(format, encoded);
return data;
}
bool ActionsContainerModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
{
if (!m_actionsContainer)
{
qWarning() << "no container";
return false;
}
// if the drop is on an item, reject drop
if (parent.isValid() && row == -1 && column == -1)
{
// qWarning() << "drop on item";
return false;
}
return QAbstractListModel::canDropMimeData(data, action, row, column, parent);
}
bool ActionsContainerModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
if (!m_actionsContainer)
{
qWarning() << "no container";
return false;
}
// check if the action is supported
if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
{
qWarning() << "wrong action";
return false;
}
// if the drop is on an item, replace the data in the items
if (parent.isValid() && row == -1 && column == -1)
{
// qWarning() << "drop on item";
return false;
}
// check if the format is supported
QStringList types = mimeTypes();
if (types.isEmpty())
return false;
QString format = types.at(0);
if (!data->hasFormat(format))
{
qWarning() << "wrong format";
return false;
}
if (row > rowCount(parent))
row = rowCount(parent);
if (row == -1)
row = rowCount(parent);
if (column == -1)
column = 0;
// decode and insert
QByteArray encoded = data->data(format);
QDataStream stream(&encoded, QDataStream::ReadOnly);
QList<Action> actions;
while (!stream.atEnd())
{
Action action;
stream >> action;
actions << std::move(action);
}
if (actions.isEmpty())
{
qWarning() << "empty actions";
return false;
}
beginInsertRows({}, row, row + actions.size() - 1);
auto iter = std::next(std::begin(*m_actionsContainer), row);
for (auto &action : actions)
iter = m_actionsContainer->insert(iter, std::move(action));
endInsertRows();
return true;
}
QMap<int, QVariant> ActionsContainerModel::itemData(const QModelIndex &index) const
{
auto itemData = QAbstractListModel::itemData(index);
qDebug() << index << itemData;
return itemData;
}
bool ActionsContainerModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
{
auto setItemData = QAbstractListModel::setItemData(index, roles);
qDebug() << index << roles << setItemData;
return setItemData;
}
bool ActionsContainerModel::removeRows(int row, int count, const QModelIndex &parent)
{
qDebug() << row << count << parent.isValid();
if (!m_actionsContainer)
return false;
if (parent.isValid())
return false;
if (row < 0 || std::size_t(row) >= m_actionsContainer->size())
{
qWarning() << "unexpected row" << row;
return false;
}
if (count < 0 || std::size_t(count) > m_actionsContainer->size() - row)
{
qWarning() << "unexpected row+count" << count << row;
return false;
}
beginRemoveRows({}, row, row + count - 1);
auto begin = std::next(std::begin(*m_actionsContainer), row);
auto end = std::next(begin, count);
m_actionsContainer->erase(begin, end);
endRemoveRows();
return true;
}
bool ActionsContainerModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
{
qDebug() << sourceRow << count << destinationChild;
if (!m_actionsContainer)
return false;
if (sourceParent.isValid())
return false;
if (destinationParent.isValid())
return false;
if (count != 1)
return false;
beginMoveRows({}, sourceRow, sourceRow, {}, destinationChild);
m_actionsContainer->splice(std::next(std::begin(*m_actionsContainer), destinationChild), *m_actionsContainer, std::next(std::begin(*m_actionsContainer), sourceRow));
endMoveRows();
return true;
}
void ActionsContainerModel::setActionsContainer(ActionsContainer *actionsContainer)
{
beginResetModel();