engine: internals supporting the facade migration

UndoStack push_pre_executed, FolderAddChild-based true folder moves,
NodeViewDeleteCommand delete-then-reconnect support, event emission
points for the facade event bus, and related internal adjustments.
This commit is contained in:
2026-07-26 22:43:09 +08:00
parent e9f173916f
commit f95590e924
38 changed files with 302 additions and 746 deletions
+36
View File
@@ -105,6 +105,42 @@ void UndoStack::push(UndoCommand *command, const QString &name)
update_actions();
}
void UndoStack::push_pre_executed(UndoCommand *command, const QString &name)
{
MultiUndoCommand *mcu = dynamic_cast<MultiUndoCommand *>(command);
if (mcu && mcu->child_count() == 0) {
delete command;
return;
}
// Clear any redoable commands
this->beginRemoveRows(QModelIndex(), commands_.size(),
commands_.size() + undone_commands_.size());
if (can_redo()) {
for (auto it = undone_commands_.cbegin(); it != undone_commands_.cend();
it++) {
delete (*it).command;
}
undone_commands_.clear();
}
this->endRemoveRows();
// Push without redoing: the caller already executed the children.
this->beginInsertRows(QModelIndex(), commands_.size(), commands_.size());
commands_.push_back({ command, name });
this->endInsertRows();
// Delete oldest
if (commands_.size() > k_max_undo_commands) {
this->beginRemoveRows(QModelIndex(), 0, 0);
delete commands_.front().command;
commands_.pop_front();
this->endRemoveRows();
}
update_actions();
}
void UndoStack::jump(size_t index)
{
while (commands_.size() > index) {
+43
View File
@@ -40,6 +40,15 @@ public:
void push(UndoCommand *command, const QString &name);
/**
* @brief Push a command that has already been executed (redo skipped).
*
* Used by the facade undo-group: child commands are added to the group
* and executed eagerly, then the whole group is pushed with this method
* so it is not redone again. Empty commands are discarded.
*/
void push_pre_executed(UndoCommand *command, const QString &name);
void jump(size_t index);
void clear();
@@ -78,6 +87,40 @@ public:
virtual bool
hasChildren(const QModelIndex &parent = QModelIndex()) const override;
// Facade accessors (oakengine/undo.h C ABI): row-based history queries.
// Rows 0..done_count()-1 are done commands (commands_ in order), rows
// done_count()..command_count()-1 are undone commands (undone_commands_
// in order, most recently undone first).
int command_count() const
{
return int(commands_.size() + undone_commands_.size());
}
int done_count() const
{
return int(commands_.size());
}
bool command_is_done(int row) const
{
return row >= 0 && row < done_count();
}
QString command_name(int row) const
{
if (row < 0 || row >= command_count()) {
return QString();
}
if (row < done_count()) {
auto it = commands_.begin();
std::advance(it, row);
return it->name;
}
auto it = undone_commands_.begin();
std::advance(it, row - done_count());
return it->name;
}
signals:
void index_changed(int i);