Undo deletion
This commit is contained in:
parent
05d6c06603
commit
453003cb25
2 changed files with 145 additions and 1 deletions
|
|
@ -74,6 +74,115 @@ private:
|
||||||
NodeVolumeState m_next{};
|
NodeVolumeState m_next{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DeleteVirtualNodeCommand : public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct VirtualNodeData {
|
||||||
|
QString name;
|
||||||
|
QString description;
|
||||||
|
Potato::MediaClass mediaClass;
|
||||||
|
int channels;
|
||||||
|
int rate;
|
||||||
|
QPointF position;
|
||||||
|
NodeVolumeState volumeState;
|
||||||
|
};
|
||||||
|
|
||||||
|
DeleteVirtualNodeCommand(GraphEditorWidget *widget,
|
||||||
|
QtNodes::BasicGraphicsScene *scene,
|
||||||
|
const QList<QtNodes::NodeId> &nodeIds)
|
||||||
|
: m_widget(widget)
|
||||||
|
, m_scene(scene)
|
||||||
|
{
|
||||||
|
if (!widget || !scene) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PipeWireGraphModel *model = widget->m_model;
|
||||||
|
if (!model) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto nodeId : nodeIds) {
|
||||||
|
const Potato::NodeInfo *info = model->nodeInfo(nodeId);
|
||||||
|
if (!info || info->type != Potato::NodeType::Virtual) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VirtualNodeData data;
|
||||||
|
data.name = info->name;
|
||||||
|
data.description = info->description;
|
||||||
|
data.mediaClass = info->mediaClass;
|
||||||
|
const int inPortSize = static_cast<int>(info->inputPorts.size());
|
||||||
|
const int outPortSize = static_cast<int>(info->outputPorts.size());
|
||||||
|
data.channels = (inPortSize > outPortSize) ? inPortSize : outPortSize;
|
||||||
|
if (data.channels == 0) {
|
||||||
|
data.channels = 2;
|
||||||
|
}
|
||||||
|
data.rate = 48000;
|
||||||
|
data.position = model->nodeData(nodeId, QtNodes::NodeRole::Position).toPointF();
|
||||||
|
|
||||||
|
NodeVolumeState volumeState;
|
||||||
|
if (model->nodeVolumeState(info->id, volumeState)) {
|
||||||
|
data.volumeState = volumeState;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_virtualNodes.append(data);
|
||||||
|
m_nodeIds.append(nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
setText(QString("Delete Virtual Node"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void undo() override
|
||||||
|
{
|
||||||
|
if (!m_widget || m_virtualNodes.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *controller = m_widget->m_controller;
|
||||||
|
auto *model = m_widget->m_model;
|
||||||
|
if (!controller || !model) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &data : m_virtualNodes) {
|
||||||
|
bool success = false;
|
||||||
|
if (data.mediaClass == Potato::MediaClass::AudioSource) {
|
||||||
|
success = controller->createVirtualSource(data.name, data.description, data.channels, data.rate);
|
||||||
|
} else {
|
||||||
|
success = controller->createVirtualSink(data.name, data.description, data.channels, data.rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
m_widget->m_pendingPastePositions.insert(data.name, data.position);
|
||||||
|
m_widget->m_pendingPasteVolumes.insert(data.name, data.volumeState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void redo() override
|
||||||
|
{
|
||||||
|
if (!m_widget) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PipeWireGraphModel *model = m_widget->m_model;
|
||||||
|
if (!model) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto nodeId : m_nodeIds) {
|
||||||
|
model->deleteNode(nodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GraphEditorWidget *m_widget = nullptr;
|
||||||
|
QtNodes::BasicGraphicsScene *m_scene = nullptr;
|
||||||
|
QList<VirtualNodeData> m_virtualNodes;
|
||||||
|
QList<QtNodes::NodeId> m_nodeIds;
|
||||||
|
};
|
||||||
|
|
||||||
GraphEditorWidget::GraphEditorWidget(Potato::PipeWireController *controller, QWidget *parent)
|
GraphEditorWidget::GraphEditorWidget(Potato::PipeWireController *controller, QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_controller(controller)
|
, m_controller(controller)
|
||||||
|
|
@ -1369,7 +1478,40 @@ void GraphEditorWidget::duplicateSelection()
|
||||||
|
|
||||||
void GraphEditorWidget::deleteSelection()
|
void GraphEditorWidget::deleteSelection()
|
||||||
{
|
{
|
||||||
if (m_scene) {
|
if (!m_scene) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<QGraphicsItem*> items = m_scene->selectedItems();
|
||||||
|
QList<QtNodes::NodeId> virtualNodeIds;
|
||||||
|
QList<QtNodes::NodeId> otherNodeIds;
|
||||||
|
|
||||||
|
for (auto *item : items) {
|
||||||
|
if (auto *nodeObj = qgraphicsitem_cast<QtNodes::NodeGraphicsObject*>(item)) {
|
||||||
|
const Potato::NodeInfo *info = m_model->nodeInfo(nodeObj->nodeId());
|
||||||
|
if (info && info->type == Potato::NodeType::Virtual) {
|
||||||
|
virtualNodeIds.append(nodeObj->nodeId());
|
||||||
|
} else if (info) {
|
||||||
|
otherNodeIds.append(nodeObj->nodeId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!virtualNodeIds.isEmpty()) {
|
||||||
|
m_scene->undoStack().push(new DeleteVirtualNodeCommand(this, m_scene, virtualNodeIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!otherNodeIds.isEmpty()) {
|
||||||
|
m_scene->clearSelection();
|
||||||
|
for (const auto nodeId : otherNodeIds) {
|
||||||
|
if (const auto *nodeObj = m_scene->nodeGraphicsObject(nodeId)) {
|
||||||
|
const_cast<QtNodes::NodeGraphicsObject*>(nodeObj)->setSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_scene->undoStack().push(new QtNodes::DeleteCommand(m_scene));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virtualNodeIds.isEmpty() && otherNodeIds.isEmpty() && !items.isEmpty()) {
|
||||||
m_scene->undoStack().push(new QtNodes::DeleteCommand(m_scene));
|
m_scene->undoStack().push(new QtNodes::DeleteCommand(m_scene));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,14 @@ class QSplitter;
|
||||||
class QTabWidget;
|
class QTabWidget;
|
||||||
class PresetManager;
|
class PresetManager;
|
||||||
class VolumeChangeCommand;
|
class VolumeChangeCommand;
|
||||||
|
class DeleteVirtualNodeCommand;
|
||||||
|
|
||||||
class GraphEditorWidget : public QWidget
|
class GraphEditorWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
friend class VolumeChangeCommand;
|
friend class VolumeChangeCommand;
|
||||||
|
friend class DeleteVirtualNodeCommand;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GraphEditorWidget(Potato::PipeWireController *controller, QWidget *parent = nullptr);
|
explicit GraphEditorWidget(Potato::PipeWireController *controller, QWidget *parent = nullptr);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue