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{};
|
||||
};
|
||||
|
||||
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)
|
||||
: QWidget(parent)
|
||||
, m_controller(controller)
|
||||
|
|
@ -1369,7 +1478,40 @@ void GraphEditorWidget::duplicateSelection()
|
|||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,14 @@ class QSplitter;
|
|||
class QTabWidget;
|
||||
class PresetManager;
|
||||
class VolumeChangeCommand;
|
||||
class DeleteVirtualNodeCommand;
|
||||
|
||||
class GraphEditorWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class VolumeChangeCommand;
|
||||
friend class DeleteVirtualNodeCommand;
|
||||
|
||||
public:
|
||||
explicit GraphEditorWidget(Potato::PipeWireController *controller, QWidget *parent = nullptr);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue