added some comments.

This commit is contained in:
2025-08-06 16:44:08 +02:00
parent 87de9c1f33
commit f41b00d8ff
5 changed files with 90 additions and 44 deletions

View File

@@ -27,12 +27,11 @@ void XQNodeStore::dumpList( const QString& title ) const
XQCommand::XQCommand(CmdType cmdType, XQModel* modelView ) XQCommand::XQCommand(CmdType cmdType, XQModel* modelView )
: _cmdType{ cmdType }, _modelView(modelView) : _cmdType{ cmdType }, _model(modelView)
{ {
} }
XQCommand::~XQCommand() XQCommand::~XQCommand()
{ {
qDebug() << " --- command destructor: " << toString(); qDebug() << " --- command destructor: " << toString();
@@ -49,22 +48,34 @@ void XQCommand::setCommandType( XQCommand::CmdType cmdType )
_cmdType = cmdType; _cmdType = cmdType;
} }
//! ruft 'onCommandRedo' 'meines' models auf.
void XQCommand::redo() void XQCommand::redo()
{ {
_modelView->onCommandRedo( *this ); _model->onCommandRedo( *this );
} }
//! ruft 'onCommandUndo' 'meines' models auf.
void XQCommand::undo() void XQCommand::undo()
{ {
_modelView->onCommandUndo( *this ); _model->onCommandUndo( *this );
} }
//! gibt den urpsrungs-index dieses commands zurück.
const QModelIndex& XQCommand::originIndex() const const QModelIndex& XQCommand::originIndex() const
{ {
return _originIndex; return _originIndex;
} }
//! merkt sich den ersten QModelIndex der von diesem command
//! betroffenen items. zusätzlich wird der command-text erzeugt.
void XQCommand::setOriginIndex( const QModelIndex& origin ) void XQCommand::setOriginIndex( const QModelIndex& origin )
{ {
QString cmdText("%1: %2 (%3)"); QString cmdText("%1: %2 (%3)");
@@ -78,17 +89,24 @@ void XQCommand::setOriginIndex( const QModelIndex& origin )
} }
//! erzeugt aus den 'selected indices' eine liste mit der jewiligen knotenposition,
//! der item-zeile und dem content-knoten.
void XQCommand::saveNodes( const QModelIndexList& list ) void XQCommand::saveNodes( const QModelIndexList& list )
{ {
clear(); clear();
// über jede zeil
for( auto entry : list ) for( auto entry : list )
{ {
XQNodePtr contentNode = XQItem::xqItemFromIndex( entry ).contentNode(); // knoten holen
// im command speichern wir den original knoten, nicht eine kopie, wie im clipboard. const XQNodePtr& contentNode = XQItem::xqItemFromIndex( entry ).contentNode();
// hier speichern wir den original knoten, nicht einen clone, wie im clipboard.
push_back( {entry.row(), contentNode->own_pos(), contentNode } ); push_back( {entry.row(), contentNode->own_pos(), contentNode } );
} }
} }
//! erzeugt einen string aus dem command-type, fürs debuggen.
QString XQCommand::toString() QString XQCommand::toString()
{ {

View File

@@ -85,7 +85,7 @@ public:
protected: protected:
CmdType _cmdType{cmdInvalid}; CmdType _cmdType{cmdInvalid};
XQModel* _modelView{}; // needed for redo() / undo() XQModel* _model{}; // needed for redo() / undo()
QModelIndex _originIndex; QModelIndex _originIndex;
/* /*

View File

@@ -255,52 +255,47 @@ void XQModel::onCommandUndo( XQCommand& command )
// undo-/redo-able stuff // undo-/redo-able stuff
/** //! markierte knoten entfernen, 'command' enthält die liste
* @brief XQModel::cmdCutRows Cut the rows whose positions have been store in the command.
* @param command
*/
void XQModel::cmdCut( XQCommand& command ) void XQModel::cmdCut( XQCommand& command )
{ {
// wir gehen rückwärts über alle gemerkten knoten ... // wir gehen rückwärts über alle gemerkten knoten ...
for (auto it = command.rbegin(); it != command.rend(); ++it) for (auto it = command.rbegin(); it != command.rend(); ++it)
{ {
// ... holen das erste item, das auch den content node enthält // ... holen das erste item, das auch den content node enthält
const XQNodeBackup& entry = *it; //const XQNodeBackup& entry = *it;
XQItem& firstItem = xqFirstItem( (*it).itemPos ); //XQItem& firstItem = xqFirstItem( (*it).itemPos );
qDebug() << " --- Cut: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id; //qDebug() << " --- Cut: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id;
// jetzt löschen, dabei wird die parent-verbindung entfernt // jetzt löschen, dabei wird die parent-verbindung entfernt
const XQNodeBackup& entry = *it;
entry.contentNode->unlink_self(); entry.contentNode->unlink_self();
removeRow(entry.itemPos ); removeRow(entry.itemPos );
} }
} }
//! entfernte knoten aus wieder einfügen , 'command' enthält die liste
// clone to clipboard, remove items
void XQModel::cmdCutUndo( XQCommand& command ) void XQModel::cmdCutUndo( XQCommand& command )
{ {
command.dumpList("UNDO Cut"); // die anfangsposition
_sections.dump(); int itmPos = command.first().itemPos;
// die 'zuständige' section rausfinden
int xx = command.first().itemPos; const XQModelSection& section = _sections.sectionFromRow( itmPos );
const XQModelSection& section = _sections.sectionFromRow( xx ); // über alle einträge ...
for (auto& entry : command ) for (auto& entry : command )
{ {
XQNodePtr savedNode = entry.contentNode; const XQNodePtr& savedNode = entry.contentNode;
// __fix! should not bee _contentRoot! // __fix! should not be _contentRoot!
savedNode->add_me_at( entry.nodePos, _contentRoot ); savedNode->add_me_at( entry.nodePos, _contentRoot );
XQItemList list = _itemFactory.makeContentRow( savedNode, section.sheetRootNode ); XQItemList list = _itemFactory.makeContentRow( savedNode, section.sheetRootNode );
XQItem& firstItem = *((XQItem*)list[0]); XQItem& firstItem = *((XQItem*)list[0]);
qDebug() << " --- Cut Undo: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id; qDebug() << " --- Cut Undo: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id << " count: " << entry.contentNode.use_count();
insertRow( entry.itemPos, list ); insertRow( entry.itemPos, list );
} }
} }
//! clipboard inhalte einfügen
void XQModel::cmdPaste( XQCommand& command ) void XQModel::cmdPaste( XQCommand& command )
{ {
// selection holen ... // selection holen ...
@@ -320,11 +315,19 @@ void XQModel::cmdPaste( XQCommand& command )
// wir pasten das clipboard // wir pasten das clipboard
for (auto& entry : _clipBoard ) for (auto& entry : _clipBoard )
{ {
//
// siehe! und es war schrott!
//
// das ist ein clon
XQNodePtr savedNode = entry.contentNode; XQNodePtr savedNode = entry.contentNode;
// der wir hier rein gelinkt
XQItemList list = _itemFactory.makeContentRow( savedNode, section.sheetRootNode ); XQItemList list = _itemFactory.makeContentRow( savedNode, section.sheetRootNode );
// wir klonen den knoten aus dem clipbord // wir klonen den knoten aus dem clipbord
savedNode->clone(section.contentRootNode )->add_me_at( nodePos ); savedNode->clone(section.contentRootNode )->add_me_at( nodePos );
insertRow( insRow, list ); insertRow( insRow, list );
const QModelIndex& selIdx = list[0]->index(); const QModelIndex& selIdx = list[0]->index();
_treeView->selectionModel()->select(selIdx, QItemSelectionModel::Select | QItemSelectionModel::Rows); _treeView->selectionModel()->select(selIdx, QItemSelectionModel::Select | QItemSelectionModel::Rows);
// zur nächsten zeile // zur nächsten zeile

View File

@@ -85,7 +85,7 @@ public:
virtual void cmdNew( XQCommand& command ); virtual void cmdNew( XQCommand& command );
virtual void cmdNewUndo( XQCommand& command ); virtual void cmdNewUndo( XQCommand& command );
// wtf!? /*
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override
{ {
qDebug() << " --- setData: " << value.toString(); qDebug() << " --- setData: " << value.toString();
@@ -96,6 +96,7 @@ public:
{ {
return QStandardItemModel::data( index, role ); return QStandardItemModel::data( index, role );
} }
*/
public slots: public slots:

View File

@@ -34,7 +34,13 @@
namespace znode namespace znode
{ {
/// ----------------- snip 8< ----------------------------------------------------------------------------------------------------------------------------- /*
- die payload attributes wird 'drangeerbt'. sollte die nicht besser ge-templatet sein?
- die finder sollten besser ausgelagert sein
*/
// forward declaration of base class zbasic_node ... // forward declaration of base class zbasic_node ...
//template<class str_t> //template<class str_t>
@@ -45,7 +51,7 @@ namespace znode
//using zshared_node = std::shared_ptr<zbasic_node<str_t>>; //using zshared_node = std::shared_ptr<zbasic_node<str_t>>;
// main class //! einfache tree-klasse, besonderheit: der nutzlast-string-type ist templated.
template<class str_t> template<class str_t>
class zbasic_node : public zid, public zpayload<str_t>, public std::enable_shared_from_this<zbasic_node<str_t>> class zbasic_node : public zid, public zpayload<str_t>, public std::enable_shared_from_this<zbasic_node<str_t>>
{ {
@@ -88,29 +94,30 @@ namespace znode
public: public:
//! shortcut auf std::make_shared...
static zshared_node make_node( str_cref arg1, str_cref arg2 = "" , zshared_cref parent = nullptr ) static zshared_node make_node( str_cref arg1, str_cref arg2 = "" , zshared_cref parent = nullptr )
{ {
return std::make_shared<zbasic_node>( arg1, arg2, parent ); return std::make_shared<zbasic_node>( arg1, arg2, parent );
} }
//! leerer konstruktor
zbasic_node() = default; zbasic_node() = default;
// ... //! konstruktor mit tag_name und optionalem elternknoten
zbasic_node( str_cref tag_name, zshared_cref parent = nullptr ) zbasic_node( str_cref tag_name, zshared_cref parent = nullptr )
: zpayload<str_t>{tag_name}, _parent{parent} : zpayload<str_t>{tag_name}, _parent{parent}
{ {
} }
//! konstruktor mit tag_name, value und optionalem elternknoten
// ...
zbasic_node( str_cref tag_name, str_cref value, zshared_cref parent = nullptr ) zbasic_node( str_cref tag_name, str_cref value, zshared_cref parent = nullptr )
: zpayload<str_t>{tag_name,value}, _parent{parent} : zpayload<str_t>{tag_name,value}, _parent{parent}
{ {
} }
//! konstruktor mit tag_name, attributlist und optionalem elternknoten
zbasic_node( str_cref tag_name, const str_list& attributes, zshared_cref parent = nullptr ) zbasic_node( str_cref tag_name, const str_list& attributes, zshared_cref parent = nullptr )
: zbasic_node{tag_name, parent} : zbasic_node{tag_name, parent}
{ {
@@ -122,16 +129,18 @@ namespace znode
} }
} }
//! default destruktor
virtual ~zbasic_node() = default; virtual ~zbasic_node() = default;
// Kopieren ist hier nicht sinnvoll (Child-Pointer müssen konsistent bleiben) //! kopieren ist hier nicht sinnvoll
zbasic_node(const zbasic_node&) = delete; zbasic_node(const zbasic_node&) = delete;
zbasic_node& operator=(const zbasic_node&) = delete; zbasic_node& operator=(const zbasic_node&) = delete;
// Bewegen geht (shared_from_this bleibt gültig) // 'move' geht (shared_from_this bleibt gültig)
zbasic_node(zbasic_node&&) noexcept = default; zbasic_node(zbasic_node&&) noexcept = default;
zbasic_node& operator=(zbasic_node&&) noexcept = default; zbasic_node& operator=(zbasic_node&&) noexcept = default;
//! erzeugt eine deep-copy von 'mir' _mit_ allen kindknoten
virtual zshared_node clone(const zshared_node& parent = nullptr ) const virtual zshared_node clone(const zshared_node& parent = nullptr ) const
{ {
// copy als shared ptr erzeugen // copy als shared ptr erzeugen
@@ -148,12 +157,13 @@ namespace znode
} }
// STL-ish traverse iterators //! stl-ish traverse iterators
auto begin() auto begin()
{ {
return ziterator(this); return ziterator(this);
} }
//! stl-ish traverse iterators
auto end() auto end()
{ {
return ziterator(nullptr); return ziterator(nullptr);
@@ -162,7 +172,7 @@ namespace znode
// ... set_int // ... set_int
// ... as_int // ... as_int
//zweak_node parent() //! erzeugt einen shared_ptr
zshared_node parent() const zshared_node parent() const
{ {
return _parent.lock(); return _parent.lock();
@@ -221,21 +231,29 @@ namespace znode
return int(children().size() - 1); return int(children().size() - 1);
} }
//! fügt einen knoten in meine kinderliste ein und macht mich
//! zu dessen elternknoten.
int add_child_at( int idx, const zshared_node& node ) int add_child_at( int idx, const zshared_node& node )
{ {
// _fixme! was ist, wenn da schon ein elternknoten ist?
_children.insert(children().begin() + idx, node ); _children.insert(children().begin() + idx, node );
node->_parent = this->shared_from_this(); node->_parent = this->shared_from_this();
return int(children().size() - 1); return int(children().size() - 1);
} }
//! fügt einen shard_ptr von 'mir' in die kinderliste meines elternknotens ein.
void add_me_at( int offset ) void add_me_at( int offset )
{ {
if( parent() ) if( parent() )
parent()->add_child_at( offset, this->shared_from_this() ); parent()->add_child_at( offset, this->shared_from_this() );
else else
qDebug() << " -- fick2"; // shold throw? throw std::runtime_error("add_me_at(offset): no parent node");
} }
//! fügt einen shard_ptr von 'mir' in die kinderliste des übergebenen knotens ein
//! und macht diesen zu meinem elternknoten.
void add_me_at( int offset, const zshared_node& parent_node ) void add_me_at( int offset, const zshared_node& parent_node )
{ {
if( parent_node ) if( parent_node )
@@ -244,7 +262,10 @@ namespace znode
parent_node->add_child_at( offset, this->shared_from_this() ); parent_node->add_child_at( offset, this->shared_from_this() );
} }
else else
qDebug() << " -- fick4"; // shold throw? {
throw std::runtime_error("add_me_at(offset,parent): no parent node");
}
} }
int own_pos() int own_pos()
@@ -278,14 +299,17 @@ namespace znode
return removed; return removed;
} }
//! entfernt 'mich' aus der kinderliste des elternknotens.
void unlink_self() void unlink_self()
{ {
if(parent()) if(parent())
parent()->unlink_child( this->shared_from_this() ); parent()->unlink_child( this->shared_from_this() );
else else
qDebug() << " -- fuck: "; throw std::runtime_error("unlink_self(): no parent node");
} }
//! findet den ersten kind-knoten mit dem attribut 'attrkey' welches den
//! wert 'attrvalue' hat.
zshared_node find_child_by_attribute(str_cref attrkey, str_cref attrvalue ) zshared_node find_child_by_attribute(str_cref attrkey, str_cref attrvalue )
{ {
for( auto child : _children ) for( auto child : _children )
@@ -297,7 +321,7 @@ namespace znode
return zshared_node(); return zshared_node();
} }
//
zshared_node find_child_by_tag_name(str_cref tagname ) zshared_node find_child_by_tag_name(str_cref tagname )
{ {
for( auto child : _children ) for( auto child : _children )