Cabana: Added support for undo & redo (#26440)
* undo/redo
* display command list to rolling the state backwards or forward
* update detailview after rolling states
* add * to title bar to indicate dbc has changed
* fix signal pointer address changed after removed
* cleanup
* fix id error
* clear undo stack after dbc file changed
* cleanup
* use map
* cleanup
* typo
old-commit-hash: 7c922eafe9
taco
parent
e48e9b30f0
commit
5f80ca6359
14 changed files with 277 additions and 110 deletions
@ -0,0 +1,75 @@ |
|||||||
|
#include "tools/cabana/commands.h" |
||||||
|
|
||||||
|
// EditMsgCommand
|
||||||
|
|
||||||
|
EditMsgCommand::EditMsgCommand(const QString &id, const QString &title, int size, QUndoCommand *parent) |
||||||
|
: id(id), new_title(title), new_size(size), QUndoCommand(parent) { |
||||||
|
if (auto msg = dbc()->msg(id)) { |
||||||
|
old_title = msg->name; |
||||||
|
old_size = msg->size; |
||||||
|
} |
||||||
|
setText(QObject::tr("Edit message %1:%2").arg(DBCManager::parseId(id).second).arg(title)); |
||||||
|
} |
||||||
|
|
||||||
|
void EditMsgCommand::undo() { |
||||||
|
if (old_title.isEmpty()) |
||||||
|
dbc()->removeMsg(id); |
||||||
|
else |
||||||
|
dbc()->updateMsg(id, old_title, old_size); |
||||||
|
} |
||||||
|
|
||||||
|
void EditMsgCommand::redo() { |
||||||
|
dbc()->updateMsg(id, new_title, new_size); |
||||||
|
} |
||||||
|
|
||||||
|
// RemoveMsgCommand
|
||||||
|
|
||||||
|
RemoveMsgCommand::RemoveMsgCommand(const QString &id, QUndoCommand *parent) : id(id), QUndoCommand(parent) { |
||||||
|
if (auto msg = dbc()->msg(id)) { |
||||||
|
message = *msg; |
||||||
|
setText(QObject::tr("Remove message %1:%2").arg(DBCManager::parseId(id).second).arg(message.name)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void RemoveMsgCommand::undo() { |
||||||
|
if (!message.name.isEmpty()) { |
||||||
|
dbc()->updateMsg(id, message.name, message.size); |
||||||
|
for (auto &[name, s] : message.sigs) |
||||||
|
dbc()->addSignal(id, s); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void RemoveMsgCommand::redo() { |
||||||
|
if (!message.name.isEmpty()) |
||||||
|
dbc()->removeMsg(id); |
||||||
|
} |
||||||
|
|
||||||
|
// AddSigCommand
|
||||||
|
|
||||||
|
AddSigCommand::AddSigCommand(const QString &id, const Signal &sig, QUndoCommand *parent) |
||||||
|
: id(id), signal(sig), QUndoCommand(parent) { |
||||||
|
setText(QObject::tr("Add signal %1 to %2").arg(sig.name.c_str()).arg(DBCManager::parseId(id).second)); |
||||||
|
} |
||||||
|
|
||||||
|
void AddSigCommand::undo() { dbc()->removeSignal(id, signal.name.c_str()); } |
||||||
|
void AddSigCommand::redo() { dbc()->addSignal(id, signal); } |
||||||
|
|
||||||
|
// RemoveSigCommand
|
||||||
|
|
||||||
|
RemoveSigCommand::RemoveSigCommand(const QString &id, const Signal *sig, QUndoCommand *parent) |
||||||
|
: id(id), signal(*sig), QUndoCommand(parent) { |
||||||
|
setText(QObject::tr("Remove signal %1 from %2").arg(signal.name.c_str()).arg(DBCManager::parseId(id).second)); |
||||||
|
} |
||||||
|
|
||||||
|
void RemoveSigCommand::undo() { dbc()->addSignal(id, signal); } |
||||||
|
void RemoveSigCommand::redo() { dbc()->removeSignal(id, signal.name.c_str()); } |
||||||
|
|
||||||
|
// EditSignalCommand
|
||||||
|
|
||||||
|
EditSignalCommand::EditSignalCommand(const QString &id, const Signal *sig, const Signal &new_sig, QUndoCommand *parent) |
||||||
|
: id(id), old_signal(*sig), new_signal(new_sig), QUndoCommand(parent) { |
||||||
|
setText(QObject::tr("Edit signal %1").arg(old_signal.name.c_str())); |
||||||
|
} |
||||||
|
|
||||||
|
void EditSignalCommand::undo() { dbc()->updateSignal(id, new_signal.name.c_str(), old_signal); } |
||||||
|
void EditSignalCommand::redo() { dbc()->updateSignal(id, old_signal.name.c_str(), new_signal); } |
@ -0,0 +1,63 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <QUndoCommand> |
||||||
|
|
||||||
|
#include "tools/cabana/canmessages.h" |
||||||
|
#include "tools/cabana/dbcmanager.h" |
||||||
|
|
||||||
|
class EditMsgCommand : public QUndoCommand { |
||||||
|
public: |
||||||
|
EditMsgCommand(const QString &id, const QString &title, int size, QUndoCommand *parent = nullptr); |
||||||
|
void undo() override; |
||||||
|
void redo() override; |
||||||
|
|
||||||
|
private: |
||||||
|
const QString id; |
||||||
|
QString old_title, new_title; |
||||||
|
int old_size = 0, new_size = 0; |
||||||
|
}; |
||||||
|
|
||||||
|
class RemoveMsgCommand : public QUndoCommand { |
||||||
|
public: |
||||||
|
RemoveMsgCommand(const QString &id, QUndoCommand *parent = nullptr); |
||||||
|
void undo() override; |
||||||
|
void redo() override; |
||||||
|
|
||||||
|
private: |
||||||
|
const QString id; |
||||||
|
DBCMsg message; |
||||||
|
}; |
||||||
|
|
||||||
|
class AddSigCommand : public QUndoCommand { |
||||||
|
public: |
||||||
|
AddSigCommand(const QString &id, const Signal &sig, QUndoCommand *parent = nullptr); |
||||||
|
void undo() override; |
||||||
|
void redo() override; |
||||||
|
|
||||||
|
private: |
||||||
|
const QString id; |
||||||
|
Signal signal = {}; |
||||||
|
}; |
||||||
|
|
||||||
|
class RemoveSigCommand : public QUndoCommand { |
||||||
|
public: |
||||||
|
RemoveSigCommand(const QString &id, const Signal *sig, QUndoCommand *parent = nullptr); |
||||||
|
void undo() override; |
||||||
|
void redo() override; |
||||||
|
|
||||||
|
private: |
||||||
|
const QString id; |
||||||
|
Signal signal = {}; |
||||||
|
}; |
||||||
|
|
||||||
|
class EditSignalCommand : public QUndoCommand { |
||||||
|
public: |
||||||
|
EditSignalCommand(const QString &id, const Signal *sig, const Signal &new_sig, QUndoCommand *parent = nullptr); |
||||||
|
void undo() override; |
||||||
|
void redo() override; |
||||||
|
|
||||||
|
private: |
||||||
|
const QString id; |
||||||
|
Signal old_signal = {}; |
||||||
|
Signal new_signal = {}; |
||||||
|
}; |
Loading…
Reference in new issue