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
			
			
				vw-mqb-aeb
			
			
		
							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