Finish work in drag&drop of Actions
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <QInputDialog>
|
||||
#include <QDebug>
|
||||
|
||||
#include "projectserialization.h"
|
||||
#include "models/projecttreemodel.h"
|
||||
#include "dialogs/preferencesdialog.h"
|
||||
#include "dialogs/spritepropertiesdialog.h"
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -15,10 +15,22 @@ public:
|
||||
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
Qt::DropActions supportedDragActions() const override;
|
||||
|
||||
QStringList mimeTypes() const override;
|
||||
QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
|
||||
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
||||
|
||||
QMap<int, QVariant> itemData(const QModelIndex &index) const override;
|
||||
bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles) override;
|
||||
|
||||
bool removeRows(int row, int count, const QModelIndex &parent) override;
|
||||
bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
|
||||
|
||||
ActionsContainer *actionsContainer() const { return m_actionsContainer; }
|
||||
void setActionsContainer(ActionsContainer *actionsContainer);
|
||||
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
#include <QDrag>
|
||||
#include <QMimeData>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
#include "projectserialization.h"
|
||||
#include "stdserialization.h"
|
||||
|
||||
ActionDragWidget::ActionDragWidget(QWidget *parent) :
|
||||
QToolButton{parent}
|
||||
{
|
||||
@@ -33,8 +37,12 @@ void ActionDragWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
drag->setPixmap(this->icon().pixmap(QSize{32, 32}));
|
||||
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData("custom", QByteArray{"aaaaaa"});
|
||||
QByteArray encoded;
|
||||
QDataStream stream(&encoded, QDataStream::WriteOnly);
|
||||
stream << Action{ExecuteCodeAction{ .script = "hatschi" }};
|
||||
mimeData->setData("custom", encoded);
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);
|
||||
Qt::DropAction dropAction = drag->exec(Qt::CopyAction);
|
||||
qDebug() << dropAction;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include <QMenu>
|
||||
#include <QKeySequence>
|
||||
|
||||
#include "models/actionscontainermodel.h"
|
||||
#include "dialogs/codeactiondialog.h"
|
||||
@@ -84,16 +85,55 @@ void ActionsContainerWidget::actionsContextMenuRequested(const QPoint &pos)
|
||||
auto action = index.isValid() ? m_actionsModel->getAction(index) : nullptr;
|
||||
|
||||
QMenu menu{this};
|
||||
menu.addAction(tr("&Edit Values"), this, [this,index](){ actionDoubleClicked(index); })->setEnabled(action);
|
||||
if (auto action = menu.addAction(tr("&Edit Values"), this, [this,index](){
|
||||
actionDoubleClicked(index);
|
||||
}))
|
||||
action->setEnabled(action);
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("C&ut"))->setEnabled(false);
|
||||
menu.addAction(tr("&Copy"))->setEnabled(false);
|
||||
menu.addAction(tr("&Paste"))->setEnabled(false);
|
||||
if (auto action = menu.addAction(tr("C&ut"), this, [this](){
|
||||
QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!"));
|
||||
}))
|
||||
{
|
||||
action->setEnabled(action);
|
||||
action->setShortcut(QKeySequence::Cut);
|
||||
}
|
||||
if (auto action = menu.addAction(tr("&Copy"), this, [this](){
|
||||
QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!"));
|
||||
}))
|
||||
{
|
||||
action->setEnabled(action);
|
||||
action->setShortcut(QKeySequence::Copy);
|
||||
}
|
||||
if (auto action = menu.addAction(tr("&Paste"), this, [this](){
|
||||
QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!"));
|
||||
}))
|
||||
{
|
||||
action->setEnabled(action);
|
||||
action->setShortcut(QKeySequence::Paste);
|
||||
}
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("&Delete"))->setEnabled(false);
|
||||
if (auto action = menu.addAction(tr("&Delete"), this, [this,index](){
|
||||
if (!m_actionsModel->removeRow(index.row()))
|
||||
QMessageBox::warning(this, tr("Could not remove action!"), tr("Could not remove action!"));
|
||||
}))
|
||||
{
|
||||
action->setEnabled(action);
|
||||
action->setShortcut(QKeySequence::Delete);
|
||||
}
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("Select &All"))->setEnabled(false);
|
||||
if (auto action = menu.addAction(tr("Select &All"), this, [this](){
|
||||
QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!"));
|
||||
}))
|
||||
{
|
||||
action->setEnabled(m_actionsModel->actionsContainer() && !m_actionsModel->actionsContainer()->empty());
|
||||
action->setShortcut(QKeySequence::SelectAll);
|
||||
}
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("C&lear"))->setEnabled(false);
|
||||
if (auto action = menu.addAction(tr("C&lear"), this, [this](){
|
||||
QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!"));
|
||||
}))
|
||||
{
|
||||
action->setEnabled(m_actionsModel->actionsContainer() && !m_actionsModel->actionsContainer()->empty());
|
||||
}
|
||||
menu.exec(m_ui->listViewActions->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
<height>667</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
@@ -56,7 +59,7 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
|
||||
Reference in New Issue
Block a user