From df4afd12699c92a216397d521879d2a70a77fdc2 Mon Sep 17 00:00:00 2001 From: Julia Date: Sun, 26 Nov 2023 19:52:18 +0100 Subject: [PATCH 01/38] WIP: migrate ContextTableModel to BaseTreeModel --- .../models/context_table_model.h | 54 ++--- .../models/context_table_model.cpp | 190 +++++++++++------- .../graph_widget/graph_context_manager.cpp | 4 - 3 files changed, 145 insertions(+), 103 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h index 65a2e69dfdc..6882b1089d0 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h @@ -27,11 +27,28 @@ #include "hal_core/defines.h" #include "gui/graph_widget/contexts/graph_context.h" +#include "gui/basic_tree_model/base_tree_model.h" + -#include namespace hal { + class ContextTreeItem : public BaseTreeItem + { + + private: + GraphContext* mContext; + public: + + ContextTreeItem(GraphContext* context); + QVariant getData(int column) const override; + void setData(QList data) override; + void setDataAtIndex(int index, QVariant& data) override; + void appendData(QVariant data) override; + int getColumnCount() const override; + int row() const; + }; + /** * @ingroup utility_widgets-context * @brief Base model for the ContextManagerWidget to manage GraphContext%s. @@ -41,7 +58,7 @@ namespace hal * the ContextManagerWidget to store and display the data. For specific information on how to * implement a table model, refer to qt's QAbstractTableModel class and its examples. */ - class ContextTableModel : public QAbstractTableModel + class ContextTableModel : public BaseTreeModel { Q_OBJECT @@ -57,17 +74,16 @@ namespace hal */ ///@{ int rowCount(const QModelIndex& parent = QModelIndex()) const override; - int columnCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& inddex, int role = Qt::DisplayRole) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; ///@} /** * Adds a given GraphContext to the model. * * @param context - The context to add. + * @param parent - The Parent of the context. */ - void addContext(GraphContext* context); + void addContext(GraphContext* context, BaseTreeItem* parent); /** * Removes a given GraphContext from the model. @@ -93,28 +109,12 @@ namespace hal QModelIndex getIndex(GraphContext* context) const; /** - * Begins a row insert operation. Parameter is not used. - * - * @param context - Not used. - */ - void beginInsertContext(GraphContext* context); - - /** - * Ends a row insert operation. - */ - void endInsertContext(); - - /** - * Begins a remove row operation. The given context is removed. + * Returns the index where the specified ContextTreeitem can be found. * - * @param context - The context to remove. - */ - void beginRemoveContext(GraphContext* context); - - /** - * Ends a remove row operation. + * @param item - The ContextTreeitem to search for in the item model + * @returns the model index of the specified ContextTreeitem */ - void endRemoveContext(); + QModelIndex getIndex(const BaseTreeItem * const item) const; /** * Resets the model (removes all GraphContext%s). @@ -126,11 +126,11 @@ namespace hal * * @return A vector of all GraphContext%s. */ - const QVector& list() const { return mContextList; } + const QVector& list() const; private Q_SLOTS: void handleDataChanged(); private: - QVector mContextList; + std::map mContextMap; }; } // namespace hal diff --git a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp index bce038cd056..f0d4dcb6648 100644 --- a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp @@ -4,53 +4,86 @@ namespace hal { - ContextTableModel::ContextTableModel(QObject* parent) : QAbstractTableModel(parent) + + ContextTreeItem::ContextTreeItem(GraphContext *context) : + BaseTreeItem(), + mContext(context) { } - int ContextTableModel::rowCount(const QModelIndex& parent) const + QVariant ContextTreeItem::getData(int column) const + { + switch(column) + { + case 0: + { + return mContext->getNameWithDirtyState(); + break; + } + case 1: + { + return mContext->getTimestamp().toString(Qt::SystemLocaleShortDate); + break; + } + } + } + + void ContextTreeItem::setData(QList data) { - Q_UNUSED(parent) - return mContextList.size(); } - int ContextTableModel::columnCount(const QModelIndex& parent) const + void ContextTreeItem::setDataAtIndex(int index, QVariant &data) { - Q_UNUSED(parent) + } + + void ContextTreeItem::appendData(QVariant data) + { + + } + + int ContextTreeItem::getColumnCount() const + { return 2; } - QVariant ContextTableModel::data(const QModelIndex& index, int role) const + int ContextTreeItem::row() const { - if(!index.isValid()) - return QVariant(); + BaseTreeItem* parent = getParent(); + if (!parent) return 0; + return parent->getRowForChild(this); + } + + ContextTableModel::ContextTableModel(QObject* parent) : BaseTreeModel(parent) + { + setHeaderLabels(QStringList() << "View Name" << "Timestamp"); + } + + int ContextTableModel::rowCount(const QModelIndex& parent) const + { + Q_UNUSED(parent) + + return mContextMap.size(); + } + - if(index.row() >= mContextList.size() || index.row() < 0) + QVariant ContextTableModel::data(const QModelIndex& index, int role) const + { + if (!index.isValid()) return QVariant(); - const GraphContext* context = mContextList.at(index.row()); + ContextTreeItem* item = static_cast(index.internalPointer()); - if(!context) + if (!item) return QVariant(); if(role == Qt::DisplayRole) { switch(index.column()) { - case 0: return context->getNameWithDirtyState(); break; - case 1: return context->getTimestamp().toString(Qt::SystemLocaleShortDate); break; - default: return QVariant(); - } - } - - if(role == Qt::UserRole) - { - switch(index.column()) - { - case 0: return context->getNameWithDirtyState(); break; - case 1: return context->getTimestamp(); break; + case 0: return item->getData(0); break; + case 1: return item->getData(1); break; default: return QVariant(); } } @@ -58,72 +91,60 @@ namespace hal return QVariant(); } - QVariant ContextTableModel::headerData(int section, Qt::Orientation orientation, int role) const + void ContextTableModel::clear() { - if(role != Qt::DisplayRole) - return QVariant(); + beginResetModel(); - if(orientation == Qt::Horizontal) - { - switch(section) - { - case 0: return "View Name"; break; - case 1: return "Timestamp"; break; - default: QVariant(); - } - } - else if(orientation == Qt::Vertical) - { - return section + 1; - } + BaseTreeModel::clear(); + mContextMap.clear(); - return QVariant(); + endResetModel(); } - void ContextTableModel::beginInsertContext(GraphContext* context) + void ContextTableModel::addContext(GraphContext* context, BaseTreeItem* parent) { - Q_UNUSED(context) + ContextTreeItem* item = new ContextTreeItem(context); - beginInsertRows(QModelIndex(), mContextList.size(), mContextList.size()); - } + item->setParent(parent); - void ContextTableModel::endInsertContext() - { + QModelIndex index = getIndex(parent); + + int row = parent->getChildCount(); + beginInsertRows(index, row, row); + parent->appendChild(item); endInsertRows(); - } - void ContextTableModel::beginRemoveContext(GraphContext* context) - { - const int row = mContextList.indexOf(context); - beginRemoveRows(QModelIndex(), row, row); - } + mContextMap.insert({context, item}); - void ContextTableModel::endRemoveContext() - { - endRemoveRows(); + //connect(context,&GraphContext::dataChanged,this,&ContextTableModel::handleDataChanged); + connect(context, &GraphContext::dataChanged, this, [item, this]() { + Q_EMIT dataChanged(getIndex(item), getIndex(item)); + }); } - void ContextTableModel::clear() + void ContextTableModel::removeContext(GraphContext *context) { - beginResetModel(); + ContextTreeItem* item = mContextMap.find(context)->second; + ContextTreeItem* parent = static_cast(item->getParent()); + assert(item); + assert(parent); - mContextList.clear(); + QModelIndex index = getIndex(parent); - endResetModel(); - } + int row = item->row(); - void ContextTableModel::addContext(GraphContext* context) - { - mContextList.append(context); - connect(context,&GraphContext::dataChanged,this,&ContextTableModel::handleDataChanged); - } + beginRemoveRows(index, row, row); + parent->removeChild(item); + endRemoveRows(); - void ContextTableModel::removeContext(GraphContext *context) - { - mContextList.removeAll(context); + delete item; + + std::map::iterator it; + it = mContextMap.find (context); + mContextMap.erase (it); } - void ContextTableModel::handleDataChanged() + /*void ContextTableModel::handleDataChanged() { GraphContext* gc = static_cast(sender()); if (!gc) return; @@ -142,10 +163,35 @@ namespace hal GraphContext* ContextTableModel::getContext(const QModelIndex& index) const { return (mContextList)[index.row()]; + }*/ + + QModelIndex ContextTableModel::getIndex(const BaseTreeItem* const item) const + { + assert(item); + + QVector row_numbers; + const BaseTreeItem* current_item = item; + + while (current_item != mRootItem) + { + row_numbers.append(static_cast(current_item)->row()); + current_item = current_item->getParent(); + } + + QModelIndex model_index = index(0, 0, QModelIndex()); + + for (QVector::const_reverse_iterator i = row_numbers.crbegin(); i != row_numbers.crend(); ++i) + model_index = index(*i, 0, model_index); + + return model_index; } - QModelIndex ContextTableModel::getIndex(GraphContext* context) const + const QVector &ContextTableModel::list() const { - return createIndex(mContextList.indexOf(context), 0); + QVector key; + for (auto it = mContextMap.begin(); it != mContextMap.end(); ++it) { + key.push_back(it->first); + } + return key; } } diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index a0be39acec9..df6afdeb2b4 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -58,9 +58,7 @@ namespace hal context->scene()->setDebugGridEnabled(mSettingDebugGrid->value().toBool()); connect(mSettingDebugGrid, &SettingsItemCheckbox::boolChanged, context->scene(), &GraphicsScene::setDebugGridEnabled); - mContextTableModel->beginInsertContext(context); mContextTableModel->addContext(context); - mContextTableModel->endInsertContext(); Q_EMIT contextCreated(context); @@ -89,9 +87,7 @@ namespace hal { Q_EMIT deletingContext(ctx); - mContextTableModel->beginRemoveContext(ctx); mContextTableModel->removeContext(ctx); - mContextTableModel->endRemoveContext(); delete ctx; } From 58f431522e47baedfc77da9ca4f78e3e0dc45159 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Mon, 4 Dec 2023 22:53:45 +0100 Subject: [PATCH 02/38] WIP: Migrate views to basetreemodel; Add directories to views --- .../context_manager_widget.h | 2 +- .../models/context_table_model.h | 25 +++++++++--- .../gui/graph_widget/graph_context_manager.h | 6 +-- .../context_manager_widget.cpp | 4 +- .../models/context_table_model.cpp | 39 ++++++++++++------- .../graph_widget/graph_context_manager.cpp | 6 +-- 6 files changed, 53 insertions(+), 29 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index ab6748c9387..7f398b63342 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -176,7 +176,7 @@ namespace hal GraphTabWidget* mTabView; QTableView* mContextTableView; - ContextTableModel* mContextTableModel; + ContextTreeModel* mContextTableModel; ContextTableProxyModel* mContextTableProxyModel; Searchbar* mSearchbar; diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h index 6882b1089d0..d52d3a0c1af 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h @@ -33,11 +33,24 @@ namespace hal { + + class ContextDirectory + { + private: + u32 mId; + QString mName; + + public: + ContextDirectory(u32 id, QString name):mId(id), mName(name){} + + }; + class ContextTreeItem : public BaseTreeItem { private: GraphContext* mContext; + ContextDirectory* mDirectory; public: ContextTreeItem(GraphContext* context); @@ -47,6 +60,7 @@ namespace hal void appendData(QVariant data) override; int getColumnCount() const override; int row() const; + bool isDirectory() const; }; /** @@ -58,7 +72,7 @@ namespace hal * the ContextManagerWidget to store and display the data. For specific information on how to * implement a table model, refer to qt's QAbstractTableModel class and its examples. */ - class ContextTableModel : public BaseTreeModel + class ContextTreeModel : public BaseTreeModel { Q_OBJECT @@ -68,12 +82,12 @@ namespace hal * * @param parent - The widget's parent. */ - ContextTableModel(QObject* parent = nullptr); + ContextTreeModel(QObject* parent = nullptr); /** @name Overwritten model functions */ ///@{ - int rowCount(const QModelIndex& parent = QModelIndex()) const override; + //int rowCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& inddex, int role = Qt::DisplayRole) const override; ///@} @@ -83,7 +97,7 @@ namespace hal * @param context - The context to add. * @param parent - The Parent of the context. */ - void addContext(GraphContext* context, BaseTreeItem* parent); + void addContext(GraphContext* context, BaseTreeItem* parent = nullptr); /** * Removes a given GraphContext from the model. @@ -114,7 +128,7 @@ namespace hal * @param item - The ContextTreeitem to search for in the item model * @returns the model index of the specified ContextTreeitem */ - QModelIndex getIndex(const BaseTreeItem * const item) const; + //QModelIndex getIndex(const BaseTreeItem * const item) const; /** * Resets the model (removes all GraphContext%s). @@ -131,6 +145,7 @@ namespace hal void handleDataChanged(); private: + ContextTreeItem *mCurrentDirectory; std::map mContextMap; }; } // namespace hal diff --git a/plugins/gui/include/gui/graph_widget/graph_context_manager.h b/plugins/gui/include/gui/graph_widget/graph_context_manager.h index 494e14bddfc..e479ecaf975 100644 --- a/plugins/gui/include/gui/graph_widget/graph_context_manager.h +++ b/plugins/gui/include/gui/graph_widget/graph_context_manager.h @@ -42,7 +42,7 @@ namespace hal class GraphShader; class GraphContext; - class ContextTableModel; + class ContextTreeModel; class SettingsItemCheckbox; /** @@ -342,7 +342,7 @@ namespace hal * * @returns the context table model */ - ContextTableModel* getContextTableModel() const; + ContextTreeModel* getContextTableModel() const; /** * Deletes all contexts. @@ -390,7 +390,7 @@ namespace hal private: // QVector mGraphContexts; - ContextTableModel* mContextTableModel; + ContextTreeModel* mContextTableModel; u32 mMaxContextId; void dump(const QString& title, u32 mid, u32 xid) const; SettingsItemCheckbox* mSettingDebugGrid; diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index bc319c56cc1..23b99faaf14 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -107,8 +107,8 @@ namespace hal connect(mContextTableView, &QTableView::customContextMenuRequested, this, &ContextManagerWidget::handleContextMenuRequest); connect(mContextTableView, &QTableView::doubleClicked, this, &ContextManagerWidget::handleOpenContextClicked); connect(mContextTableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ContextManagerWidget::handleSelectionChanged); - connect(mContextTableModel, &ContextTableModel::rowsRemoved, this, &ContextManagerWidget::handleDataChanged); - connect(mContextTableModel, &ContextTableModel::rowsInserted, this, &ContextManagerWidget::handleDataChanged); + connect(mContextTableModel, &ContextTreeModel::rowsRemoved, this, &ContextManagerWidget::handleDataChanged); + connect(mContextTableModel, &ContextTreeModel::rowsInserted, this, &ContextManagerWidget::handleDataChanged); connect(mSearchbar, &Searchbar::triggerNewSearch, this, &ContextManagerWidget::updateSearchIcon); connect(mSearchbar, &Searchbar::triggerNewSearch, mContextTableProxyModel, &ContextTableProxyModel::startSearch); diff --git a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp index f0d4dcb6648..dd7fa4e674a 100644 --- a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp @@ -55,20 +55,25 @@ namespace hal return parent->getRowForChild(this); } - ContextTableModel::ContextTableModel(QObject* parent) : BaseTreeModel(parent) + bool ContextTreeItem::isDirectory() const + { + return mDirectory != nullptr; + } + + ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr) { setHeaderLabels(QStringList() << "View Name" << "Timestamp"); } - int ContextTableModel::rowCount(const QModelIndex& parent) const + /*int ContextTreeModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent) return mContextMap.size(); - } + }*/ - QVariant ContextTableModel::data(const QModelIndex& index, int role) const + QVariant ContextTreeModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); @@ -91,7 +96,7 @@ namespace hal return QVariant(); } - void ContextTableModel::clear() + void ContextTreeModel::clear() { beginResetModel(); @@ -101,13 +106,19 @@ namespace hal endResetModel(); } - void ContextTableModel::addContext(GraphContext* context, BaseTreeItem* parent) + void ContextTreeModel::addContext(GraphContext* context, BaseTreeItem* parent) { ContextTreeItem* item = new ContextTreeItem(context); - item->setParent(parent); + if (parent) + item->setParent(parent); + else if(mCurrentDirectory) + item->setParent(mCurrentDirectory); + else + item->setParent(mRootItem); + - QModelIndex index = getIndex(parent); + QModelIndex index = getIndexFromItem(parent); int row = parent->getChildCount(); beginInsertRows(index, row, row); @@ -118,18 +129,18 @@ namespace hal //connect(context,&GraphContext::dataChanged,this,&ContextTableModel::handleDataChanged); connect(context, &GraphContext::dataChanged, this, [item, this]() { - Q_EMIT dataChanged(getIndex(item), getIndex(item)); + Q_EMIT dataChanged(getIndexFromItem(item), getIndexFromItem(item)); }); } - void ContextTableModel::removeContext(GraphContext *context) + void ContextTreeModel::removeContext(GraphContext *context) { ContextTreeItem* item = mContextMap.find(context)->second; ContextTreeItem* parent = static_cast(item->getParent()); assert(item); assert(parent); - QModelIndex index = getIndex(parent); + QModelIndex index = getIndexFromItem(parent); int row = item->row(); @@ -165,7 +176,7 @@ namespace hal return (mContextList)[index.row()]; }*/ - QModelIndex ContextTableModel::getIndex(const BaseTreeItem* const item) const + /* QModelIndex ContextTableModel::getIndex(const BaseTreeItem* const item) const { assert(item); @@ -184,9 +195,9 @@ namespace hal model_index = index(*i, 0, model_index); return model_index; - } + }*/ - const QVector &ContextTableModel::list() const + const QVector &ContextTreeModel::list() const { QVector key; for (auto it = mContextMap.begin(); it != mContextMap.end(); ++it) { diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index df6afdeb2b4..52e599f74f7 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -30,7 +30,7 @@ namespace hal "Appearance:Graph View", "If set net grouping colors are also applied to input and output pins of gates"); - GraphContextManager::GraphContextManager() : mContextTableModel(new ContextTableModel()), mMaxContextId(0) + GraphContextManager::GraphContextManager() : mContextTableModel(new ContextTreeModel()), mMaxContextId(0) { mSettingDebugGrid = new SettingsItemCheckbox("GUI Debug Grid", "debug/grid", @@ -528,7 +528,7 @@ namespace hal return new ModuleShader(context); } - ContextTableModel* GraphContextManager::getContextTableModel() const + ContextTreeModel* GraphContextManager::getContextTableModel() const { return mContextTableModel; } @@ -599,9 +599,7 @@ namespace hal continue; } - mContextTableModel->beginInsertContext(context); mContextTableModel->addContext(context); - mContextTableModel->endInsertContext(); if (visibleFlag) Q_EMIT contextCreated(context); } From b2858e32181b042140fd6cce0f97ffba37ed8bda Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Mon, 11 Dec 2023 12:29:20 +0100 Subject: [PATCH 03/38] Make ContextTableModel migrate to a BaseTreeModel --- .../context_manager_widget.h | 7 +- .../models/context_table_model.h | 24 +++--- .../context_manager_widget.cpp | 85 ++++++++++++++----- .../models/context_table_model.cpp | 83 +++++++++++++++--- 4 files changed, 150 insertions(+), 49 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index 7f398b63342..bf0619fa94d 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -40,6 +40,8 @@ #include #include #include +#include + namespace hal @@ -84,7 +86,7 @@ namespace hal ContextManagerWidget(GraphTabWidget* tab_view, QWidget* parent = nullptr); /** - * Selects the given context if possible (if it is indeed in the widget's ContextTableModel). + * Selects the given context if possible (if it is indeed in the widget's ContextTreeModel). * * @param context - The context to select. */ @@ -175,7 +177,7 @@ namespace hal private: GraphTabWidget* mTabView; - QTableView* mContextTableView; + QTreeView* mContextTreeView; ContextTreeModel* mContextTableModel; ContextTableProxyModel* mContextTableProxyModel; @@ -209,6 +211,7 @@ namespace hal QShortcut* mShortCutDeleteItem; + void handleCreateClicked(const QPoint& point); void handleCreateContextClicked(); void handleRenameContextClicked(); void handleDuplicateContextClicked(); diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h index d52d3a0c1af..aa8eaacfa49 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h @@ -54,6 +54,7 @@ namespace hal public: ContextTreeItem(GraphContext* context); + ContextTreeItem(ContextDirectory* directory); QVariant getData(int column) const override; void setData(QList data) override; void setDataAtIndex(int index, QVariant& data) override; @@ -61,6 +62,7 @@ namespace hal int getColumnCount() const override; int row() const; bool isDirectory() const; + bool isContext() const; }; /** @@ -91,6 +93,14 @@ namespace hal QVariant data(const QModelIndex& inddex, int role = Qt::DisplayRole) const override; ///@} + /** + * Adds a directory to the model. + * + * @param name - The name to the directory. + * @param parent - The Parent of the directory. + */ + void addDirectory(QString name, BaseTreeItem* parent = nullptr); + /** * Adds a given GraphContext to the model. * @@ -120,15 +130,7 @@ namespace hal * @param context - The context to convert. * @return The resulting index. */ - QModelIndex getIndex(GraphContext* context) const; - - /** - * Returns the index where the specified ContextTreeitem can be found. - * - * @param item - The ContextTreeitem to search for in the item model - * @returns the model index of the specified ContextTreeitem - */ - //QModelIndex getIndex(const BaseTreeItem * const item) const; + QModelIndex getIndexFromContext(GraphContext* context) const; /** * Resets the model (removes all GraphContext%s). @@ -140,12 +142,14 @@ namespace hal * * @return A vector of all GraphContext%s. */ - const QVector& list() const; + const QVector& list(); private Q_SLOTS: void handleDataChanged(); private: ContextTreeItem *mCurrentDirectory; std::map mContextMap; + QVector mContextList; + u32 mMinDirectoryId; }; } // namespace hal diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index 23b99faaf14..c13c2f7fa43 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -76,37 +76,37 @@ namespace hal mContextTableProxyModel->setSourceModel(mContextTableModel); mContextTableProxyModel->setSortRole(Qt::UserRole); - mContextTableView = new QTableView(this); - mContextTableView->setModel(mContextTableProxyModel); - mContextTableView->setSortingEnabled(true); - mContextTableView->setSelectionBehavior(QAbstractItemView::SelectRows); - mContextTableView->setSelectionMode(QAbstractItemView::SingleSelection); // ERROR ??? - mContextTableView->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); - mContextTableView->sortByColumn(1, Qt::SortOrder::DescendingOrder); - mContextTableView->verticalHeader()->hide(); - mContextTableView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + mContextTreeView = new QTreeView(this); + mContextTreeView->setModel(mContextTableProxyModel); + mContextTreeView->setSortingEnabled(true); + mContextTreeView->setSelectionBehavior(QAbstractItemView::SelectRows); + mContextTreeView->setSelectionMode(QAbstractItemView::SingleSelection); // ERROR ??? + mContextTreeView->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); + mContextTreeView->sortByColumn(1, Qt::SortOrder::DescendingOrder); + //mContextTreeView->verticalHeader()->hide(); + mContextTreeView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - mContextTableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - mContextTableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + //mContextTreeView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + //mContextTreeView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); - mContentLayout->addWidget(mContextTableView); + mContentLayout->addWidget(mContextTreeView); mContentLayout->addWidget(mSearchbar); mSearchbar->hide(); mSearchbar->setColumnNames(mContextTableProxyModel->getColumnNames()); enableSearchbar(mContextTableProxyModel->rowCount() > 0); - connect(mOpenAction, &QAction::triggered, this, &ContextManagerWidget::handleOpenContextClicked); + connect(mOpenAction, &QAction::triggered, this, &ContextManagerWidget::handleOpenContextClicked); connect(mNewViewAction, &QAction::triggered, this, &ContextManagerWidget::handleCreateContextClicked); connect(mRenameAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameContextClicked); connect(mDuplicateAction, &QAction::triggered, this, &ContextManagerWidget::handleDuplicateContextClicked); connect(mDeleteAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteContextClicked); connect(mSearchAction, &QAction::triggered, this, &ContextManagerWidget::toggleSearchbar); - connect(mContextTableView, &QTableView::customContextMenuRequested, this, &ContextManagerWidget::handleContextMenuRequest); - connect(mContextTableView, &QTableView::doubleClicked, this, &ContextManagerWidget::handleOpenContextClicked); - connect(mContextTableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ContextManagerWidget::handleSelectionChanged); + connect(mContextTreeView, &QTableView::customContextMenuRequested, this, &ContextManagerWidget::handleContextMenuRequest); + connect(mContextTreeView, &QTableView::doubleClicked, this, &ContextManagerWidget::handleOpenContextClicked); + connect(mContextTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ContextManagerWidget::handleSelectionChanged); connect(mContextTableModel, &ContextTreeModel::rowsRemoved, this, &ContextManagerWidget::handleDataChanged); connect(mContextTableModel, &ContextTreeModel::rowsInserted, this, &ContextManagerWidget::handleDataChanged); @@ -122,6 +122,45 @@ namespace hal connect(qApp, &QApplication::focusChanged, this, &ContextManagerWidget::handleDeleteShortcutOnFocusChanged); } + + void ContextManagerWidget::handleCreateClicked(const QPoint& point) + { + QModelIndex index = mContextTreeView->indexAt(point); + + if (!index.isValid()) + return; + + QMenu context_menu; + + QAction create_context; + QAction create_directory; + + create_context.setText("Create new view"); + create_context.setParent(&context_menu); + + create_directory.setText("Create new directory"); + create_directory.setParent(&context_menu); + + context_menu.addAction(&create_context); + context_menu.addAction(&create_directory); + + QAction* clicked = context_menu.exec(mContextTreeView->viewport()->mapToGlobal(point)); + + if (!clicked) + return; + + if (clicked == &create_context) + { + + } + + if (clicked == &create_directory) + { + + } + + } + void ContextManagerWidget::handleCreateContextClicked() { UserActionCompound* act = new UserActionCompound; @@ -177,7 +216,7 @@ namespace hal void ContextManagerWidget::handleDeleteContextClicked() { - QModelIndex current = mContextTableView->currentIndex(); + QModelIndex current = mContextTreeView->currentIndex(); if (!current.isValid()) return; GraphContext* clicked_context = getCurrentContext(); ActionDeleteObject* act = new ActionDeleteObject; @@ -197,7 +236,7 @@ namespace hal void ContextManagerWidget::handleContextMenuRequest(const QPoint& point) { - const QModelIndex clicked_index = mContextTableView->indexAt(point); + const QModelIndex clicked_index = mContextTreeView->indexAt(point); QMenu context_menu; @@ -211,7 +250,7 @@ namespace hal context_menu.addAction(mDeleteAction); } - context_menu.exec(mContextTableView->viewport()->mapToGlobal(point)); + context_menu.exec(mContextTreeView->viewport()->mapToGlobal(point)); } void ContextManagerWidget::handleDataChanged() @@ -229,18 +268,18 @@ namespace hal void ContextManagerWidget::selectViewContext(GraphContext* context) { - const QModelIndex source_model_index = mContextTableModel->getIndex(context); + const QModelIndex source_model_index = mContextTableModel->getIndexFromContext(context); const QModelIndex proxy_model_index = mContextTableProxyModel->mapFromSource(source_model_index); if(proxy_model_index.isValid()) - mContextTableView->setCurrentIndex(proxy_model_index); + mContextTreeView->setCurrentIndex(proxy_model_index); else - mContextTableView->clearSelection(); + mContextTreeView->clearSelection(); } GraphContext* ContextManagerWidget::getCurrentContext() { - QModelIndex proxy_model_index = mContextTableView->currentIndex(); + QModelIndex proxy_model_index = mContextTreeView->currentIndex(); QModelIndex source_model_index = mContextTableProxyModel->mapToSource(proxy_model_index); return mContextTableModel->getContext(source_model_index); diff --git a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp index dd7fa4e674a..49ded93c26a 100644 --- a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp @@ -2,6 +2,8 @@ #include "gui/gui_globals.h" +#include + namespace hal { @@ -11,6 +13,12 @@ namespace hal { } + ContextTreeItem::ContextTreeItem(ContextDirectory *directory) : + BaseTreeItem(), + mDirectory(directory) + { + } + QVariant ContextTreeItem::getData(int column) const { switch(column) @@ -60,7 +68,12 @@ namespace hal return mDirectory != nullptr; } - ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr) + bool ContextTreeItem::isContext() const + { + return mContext != nullptr; + } + + ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr), mMinDirectoryId(std::numeric_limits::max()) { setHeaderLabels(QStringList() << "View Name" << "Timestamp"); } @@ -96,6 +109,34 @@ namespace hal return QVariant(); } + void ContextTreeModel::addDirectory(QString name, BaseTreeItem *parent) + { + ContextDirectory* directory = new ContextDirectory(--mMinDirectoryId, name); + + ContextTreeItem* item = new ContextTreeItem(directory); + + if (parent) + item->setParent(parent); + else if(mCurrentDirectory) + item->setParent(mCurrentDirectory); + else + item->setParent(mRootItem); + + + QModelIndex index = getIndexFromItem(item->getParent()); + + int row = item->getParent()->getChildCount(); + beginInsertRows(index, row, row); + item->getParent()->appendChild(item); + endInsertRows(); + + + //connect(context,&GraphContext::dataChanged,this,&ContextTableModel::handleDataChanged); + /*connect(context, &GraphContext::dataChanged, this, [item, this]() { + Q_EMIT dataChanged(getIndexFromItem(item), getIndexFromItem(item)); + });*/ + } + void ContextTreeModel::clear() { beginResetModel(); @@ -118,11 +159,11 @@ namespace hal item->setParent(mRootItem); - QModelIndex index = getIndexFromItem(parent); + QModelIndex index = getIndexFromItem(item->getParent()); - int row = parent->getChildCount(); + int row = item->getParent()->getChildCount(); beginInsertRows(index, row, row); - parent->appendChild(item); + item->getParent()->appendChild(item); endInsertRows(); mContextMap.insert({context, item}); @@ -151,8 +192,13 @@ namespace hal delete item; std::map::iterator it; - it = mContextMap.find (context); - mContextMap.erase (it); + it = mContextMap.find(context); + mContextMap.erase(it); + } + + QModelIndex ContextTreeModel::getIndexFromContext(GraphContext *context) const + { + return getIndexFromItem(mContextMap.find(context)->second); } /*void ContextTableModel::handleDataChanged() @@ -169,12 +215,21 @@ namespace hal return; } } - } + }*/ - GraphContext* ContextTableModel::getContext(const QModelIndex& index) const + GraphContext* ContextTreeModel::getContext(const QModelIndex& index) const { - return (mContextList)[index.row()]; - }*/ + BaseTreeItem* item = getItemFromIndex(index); + + GraphContext* context; + for (auto &i : mContextMap) { + if (i.second == item) { + context = i.first; + break; + } + } + return context; + } /* QModelIndex ContextTableModel::getIndex(const BaseTreeItem* const item) const { @@ -197,12 +252,12 @@ namespace hal return model_index; }*/ - const QVector &ContextTreeModel::list() const + const QVector &ContextTreeModel::list() { - QVector key; + mContextList.clear(); for (auto it = mContextMap.begin(); it != mContextMap.end(); ++it) { - key.push_back(it->first); + mContextList.push_back(it->first); } - return key; + return mContextList; } } From 70c6378a8147efaa2d2098c0f23c630bae4d7891 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Sun, 17 Dec 2023 21:22:34 +0100 Subject: [PATCH 04/38] fix crash on wrongful click; add naming for directory --- .../context_manager_widget.h | 7 +- .../models/context_table_model.h | 1 + .../context_manager_widget.cpp | 93 +++++++++---------- .../models/context_table_model.cpp | 87 +++++++---------- 4 files changed, 85 insertions(+), 103 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index bf0619fa94d..28a5ef8d162 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -178,13 +178,15 @@ namespace hal GraphTabWidget* mTabView; QTreeView* mContextTreeView; - ContextTreeModel* mContextTableModel; + ContextTreeModel* mContextTreeModel; ContextTableProxyModel* mContextTableProxyModel; Searchbar* mSearchbar; QString mDisabledIconStyle; + QAction* mNewDirectoryAction; + QAction* mNewViewAction; QString mNewViewIconPath; QString mNewViewIconStyle; @@ -211,8 +213,9 @@ namespace hal QShortcut* mShortCutDeleteItem; - void handleCreateClicked(const QPoint& point); + void handleCreateClicked(); void handleCreateContextClicked(); + void handleCreateDirectoryClicked(); void handleRenameContextClicked(); void handleDuplicateContextClicked(); void handleDeleteContextClicked(); diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h index aa8eaacfa49..eb9ae3ff69c 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h @@ -42,6 +42,7 @@ namespace hal public: ContextDirectory(u32 id, QString name):mId(id), mName(name){} + QString getName() { return mName; } }; diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index c13c2f7fa43..64561ec3186 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -33,11 +33,12 @@ #include "gui/user_action/user_action_compound.h" #include #include +#include namespace hal { ContextManagerWidget::ContextManagerWidget(GraphTabWidget* tab_view, QWidget* parent) - : ContentWidget("Views", parent), mSearchbar(new Searchbar(this)), mNewViewAction(new QAction(this)), mRenameAction(new QAction(this)), mDuplicateAction(new QAction(this)), + : ContentWidget("Views", parent), mSearchbar(new Searchbar(this)), mNewDirectoryAction(new QAction(this)), mNewViewAction(new QAction(this)), mRenameAction(new QAction(this)), mDuplicateAction(new QAction(this)), mDeleteAction(new QAction(this)), mOpenAction(new QAction(this)) { //needed to load the properties @@ -46,13 +47,15 @@ namespace hal mOpenAction->setIcon(gui_utility::getStyledSvgIcon(mOpenIconStyle, mOpenIconPath)); mNewViewAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewViewIconPath)); + mNewDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewViewIconPath)); mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDuplicateIconStyle, mDuplicateIconPath)); mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath)); mOpenAction->setToolTip("Open"); - mNewViewAction->setToolTip("New"); + mNewViewAction->setToolTip("New View"); + mNewDirectoryAction->setToolTip("New Directory"); mRenameAction->setToolTip("Rename"); mDuplicateAction->setToolTip("Duplicate"); mDeleteAction->setToolTip("Delete"); @@ -60,6 +63,7 @@ namespace hal mOpenAction->setText("Open view"); mNewViewAction->setText("Create new view"); + mNewDirectoryAction->setText("Create new Directory"); mRenameAction->setText("Rename view"); mDuplicateAction->setText("Duplicate view"); mDeleteAction->setText("Delete view"); @@ -70,10 +74,10 @@ namespace hal //mDuplicateAction->setEnabled(false); //mDeleteAction->setEnabled(false); - mContextTableModel = gGraphContextManager->getContextTableModel(); + mContextTreeModel = gGraphContextManager->getContextTableModel(); mContextTableProxyModel = new ContextTableProxyModel(this); - mContextTableProxyModel->setSourceModel(mContextTableModel); + mContextTableProxyModel->setSourceModel(mContextTreeModel); mContextTableProxyModel->setSortRole(Qt::UserRole); mContextTreeView = new QTreeView(this); @@ -99,6 +103,7 @@ namespace hal connect(mOpenAction, &QAction::triggered, this, &ContextManagerWidget::handleOpenContextClicked); connect(mNewViewAction, &QAction::triggered, this, &ContextManagerWidget::handleCreateContextClicked); + connect(mNewDirectoryAction, &QAction::triggered, this, &ContextManagerWidget::handleCreateDirectoryClicked); connect(mRenameAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameContextClicked); connect(mDuplicateAction, &QAction::triggered, this, &ContextManagerWidget::handleDuplicateContextClicked); connect(mDeleteAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteContextClicked); @@ -107,8 +112,8 @@ namespace hal connect(mContextTreeView, &QTableView::customContextMenuRequested, this, &ContextManagerWidget::handleContextMenuRequest); connect(mContextTreeView, &QTableView::doubleClicked, this, &ContextManagerWidget::handleOpenContextClicked); connect(mContextTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ContextManagerWidget::handleSelectionChanged); - connect(mContextTableModel, &ContextTreeModel::rowsRemoved, this, &ContextManagerWidget::handleDataChanged); - connect(mContextTableModel, &ContextTreeModel::rowsInserted, this, &ContextManagerWidget::handleDataChanged); + connect(mContextTreeModel, &ContextTreeModel::rowsRemoved, this, &ContextManagerWidget::handleDataChanged); + connect(mContextTreeModel, &ContextTreeModel::rowsInserted, this, &ContextManagerWidget::handleDataChanged); connect(mSearchbar, &Searchbar::triggerNewSearch, this, &ContextManagerWidget::updateSearchIcon); connect(mSearchbar, &Searchbar::triggerNewSearch, mContextTableProxyModel, &ContextTableProxyModel::startSearch); @@ -122,45 +127,6 @@ namespace hal connect(qApp, &QApplication::focusChanged, this, &ContextManagerWidget::handleDeleteShortcutOnFocusChanged); } - - void ContextManagerWidget::handleCreateClicked(const QPoint& point) - { - QModelIndex index = mContextTreeView->indexAt(point); - - if (!index.isValid()) - return; - - QMenu context_menu; - - QAction create_context; - QAction create_directory; - - create_context.setText("Create new view"); - create_context.setParent(&context_menu); - - create_directory.setText("Create new directory"); - create_directory.setParent(&context_menu); - - context_menu.addAction(&create_context); - context_menu.addAction(&create_directory); - - QAction* clicked = context_menu.exec(mContextTreeView->viewport()->mapToGlobal(point)); - - if (!clicked) - return; - - if (clicked == &create_context) - { - - } - - if (clicked == &create_directory) - { - - } - - } - void ContextManagerWidget::handleCreateContextClicked() { UserActionCompound* act = new UserActionCompound; @@ -171,9 +137,24 @@ namespace hal act->exec(); } + void ContextManagerWidget::handleCreateDirectoryClicked() + { + bool confirm; + QString newName = QInputDialog::getText(this, "Directory name", "name:", QLineEdit::Normal, "", &confirm); + + if (confirm && !newName.isEmpty()) + { + mContextTreeModel->addDirectory(newName); + } + + } + void ContextManagerWidget::handleOpenContextClicked() { GraphContext* clicked_context = getCurrentContext(); + + if (!clicked_context) return; + mTabView->showContext(clicked_context); } @@ -181,6 +162,8 @@ namespace hal { GraphContext* clicked_context = getCurrentContext(); + if (!clicked_context) return; + QStringList used_context_names; for (const auto& context : gGraphContextManager->getContexts()) used_context_names.append(context->name()); @@ -207,6 +190,9 @@ namespace hal void ContextManagerWidget::handleDuplicateContextClicked() { GraphContext* clicked_context = getCurrentContext(); + + if (!clicked_context) return; + UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); act->addAction(new ActionCreateObject(UserActionObjectType::Context,clicked_context->name() + " (Copy)")); @@ -218,7 +204,11 @@ namespace hal { QModelIndex current = mContextTreeView->currentIndex(); if (!current.isValid()) return; + GraphContext* clicked_context = getCurrentContext(); + + if (!clicked_context) return; + ActionDeleteObject* act = new ActionDeleteObject; act->setObject(UserActionObject(clicked_context->id(),UserActionObjectType::Context)); act->exec(); @@ -241,6 +231,14 @@ namespace hal QMenu context_menu; context_menu.addAction(mNewViewAction); + context_menu.addAction(mNewDirectoryAction); + + GraphContext* clicked_context = getCurrentContext(); + + if (!clicked_context) { + context_menu.exec(mContextTreeView->viewport()->mapToGlobal(point)); + return; + } if (clicked_index.isValid()) { @@ -268,7 +266,7 @@ namespace hal void ContextManagerWidget::selectViewContext(GraphContext* context) { - const QModelIndex source_model_index = mContextTableModel->getIndexFromContext(context); + const QModelIndex source_model_index = mContextTreeModel->getIndexFromContext(context); const QModelIndex proxy_model_index = mContextTableProxyModel->mapFromSource(source_model_index); if(proxy_model_index.isValid()) @@ -282,11 +280,12 @@ namespace hal QModelIndex proxy_model_index = mContextTreeView->currentIndex(); QModelIndex source_model_index = mContextTableProxyModel->mapToSource(proxy_model_index); - return mContextTableModel->getContext(source_model_index); + return mContextTreeModel->getContext(source_model_index); } void ContextManagerWidget::setupToolbar(Toolbar* toolbar) { + toolbar->addAction(mNewDirectoryAction); toolbar->addAction(mNewViewAction); toolbar->addAction(mOpenAction); toolbar->addAction(mDuplicateAction); diff --git a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp index 49ded93c26a..c4e5f89b08c 100644 --- a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp @@ -9,29 +9,50 @@ namespace hal ContextTreeItem::ContextTreeItem(GraphContext *context) : BaseTreeItem(), - mContext(context) + mContext(context), + mDirectory(nullptr) { } ContextTreeItem::ContextTreeItem(ContextDirectory *directory) : BaseTreeItem(), - mDirectory(directory) + mDirectory(directory), + mContext(nullptr) { } QVariant ContextTreeItem::getData(int column) const { - switch(column) + if(isDirectory()) { - case 0: + switch(column) { - return mContext->getNameWithDirtyState(); - break; + case 0: + { + return mDirectory->getName(); + break; + } + case 1: + { + return ""; + break; + } } - case 1: + } + if(isContext()) + { + switch(column) { - return mContext->getTimestamp().toString(Qt::SystemLocaleShortDate); - break; + case 0: + { + return mContext->getNameWithDirtyState(); + break; + } + case 1: + { + return mContext->getTimestamp().toString(Qt::SystemLocaleShortDate); + break; + } } } } @@ -78,14 +99,6 @@ namespace hal setHeaderLabels(QStringList() << "View Name" << "Timestamp"); } - /*int ContextTreeModel::rowCount(const QModelIndex& parent) const - { - Q_UNUSED(parent) - - return mContextMap.size(); - }*/ - - QVariant ContextTreeModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) @@ -98,12 +111,14 @@ namespace hal if(role == Qt::DisplayRole) { + switch(index.column()) { case 0: return item->getData(0); break; case 1: return item->getData(1); break; default: return QVariant(); } + } return QVariant(); @@ -201,26 +216,11 @@ namespace hal return getIndexFromItem(mContextMap.find(context)->second); } - /*void ContextTableModel::handleDataChanged() - { - GraphContext* gc = static_cast(sender()); - if (!gc) return; - for (int irow = 0; irow < mContextList.size(); ++irow) - { - if (gc == mContextList.at(irow)) - { - QModelIndex inx0 = index(irow,0); - QModelIndex inx1 = index(irow,1); - Q_EMIT dataChanged(inx0,inx1); - return; - } - } - }*/ - GraphContext* ContextTreeModel::getContext(const QModelIndex& index) const { BaseTreeItem* item = getItemFromIndex(index); + if (static_cast(item)->isDirectory()) return nullptr; GraphContext* context; for (auto &i : mContextMap) { if (i.second == item) { @@ -231,27 +231,6 @@ namespace hal return context; } - /* QModelIndex ContextTableModel::getIndex(const BaseTreeItem* const item) const - { - assert(item); - - QVector row_numbers; - const BaseTreeItem* current_item = item; - - while (current_item != mRootItem) - { - row_numbers.append(static_cast(current_item)->row()); - current_item = current_item->getParent(); - } - - QModelIndex model_index = index(0, 0, QModelIndex()); - - for (QVector::const_reverse_iterator i = row_numbers.crbegin(); i != row_numbers.crend(); ++i) - model_index = index(*i, 0, model_index); - - return model_index; - }*/ - const QVector &ContextTreeModel::list() { mContextList.clear(); From cf75caf5e841175d00ba44d037d618bb1198edb6 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Mon, 18 Dec 2023 15:45:37 +0100 Subject: [PATCH 05/38] WIP: Update currentdirectory in ContextTreeModel --- .../models/context_table_model.h | 6 ++- .../context_manager_widget.cpp | 5 +-- .../models/context_table_model.cpp | 42 +++++++++++++++---- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h index eb9ae3ff69c..49d317f072d 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h @@ -48,7 +48,6 @@ namespace hal class ContextTreeItem : public BaseTreeItem { - private: GraphContext* mContext; ContextDirectory* mDirectory; @@ -143,9 +142,12 @@ namespace hal * * @return A vector of all GraphContext%s. */ - const QVector& list(); + const QVector& list(); + private Q_SLOTS: void handleDataChanged(); + void itemFocusChanged(const QModelIndex &newIndex); + private: ContextTreeItem *mCurrentDirectory; diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index 64561ec3186..ef6414da129 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -87,11 +87,8 @@ namespace hal mContextTreeView->setSelectionMode(QAbstractItemView::SingleSelection); // ERROR ??? mContextTreeView->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); mContextTreeView->sortByColumn(1, Qt::SortOrder::DescendingOrder); - //mContextTreeView->verticalHeader()->hide(); mContextTreeView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - //mContextTreeView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - //mContextTreeView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); mContentLayout->addWidget(mContextTreeView); @@ -124,7 +121,7 @@ namespace hal connect(ContentManager::sSettingDeleteItem, &SettingsItemKeybind::keySequenceChanged, mShortCutDeleteItem, &QShortcut::setKey); connect(mShortCutDeleteItem, &QShortcut::activated, this, &ContextManagerWidget::handleDeleteContextClicked); - connect(qApp, &QApplication::focusChanged, this, &ContextManagerWidget::handleDeleteShortcutOnFocusChanged); + connect(qApp, &QApplication::focusChanged, this, &ContextManagerWidget::handleDeleteShortcutOnFocusChanged); } void ContextManagerWidget::handleCreateContextClicked() diff --git a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp index c4e5f89b08c..86f5e07225a 100644 --- a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp @@ -1,8 +1,11 @@ #include "gui/context_manager_widget/models/context_table_model.h" #include "gui/gui_globals.h" +#include "gui/gui_utils/graphics.h" #include +#include + namespace hal { @@ -97,6 +100,8 @@ namespace hal ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr), mMinDirectoryId(std::numeric_limits::max()) { setHeaderLabels(QStringList() << "View Name" << "Timestamp"); + //connect(qApp, &QApplication::focusChanged, this, &ContextTreeModel::itemFocusChanged); + } QVariant ContextTreeModel::data(const QModelIndex& index, int role) const @@ -109,16 +114,30 @@ namespace hal if (!item) return QVariant(); - if(role == Qt::DisplayRole) + switch (role) { - - switch(index.column()) + case Qt::DecorationRole: { - case 0: return item->getData(0); break; - case 1: return item->getData(1); break; - default: return QVariant(); + break; } - + case Qt::DisplayRole: + { + switch(index.column()) + { + case 0: return item->getData(0); break; + case 1: return item->getData(1); break; + default: return QVariant(); + } + break; + } + case Qt::BackgroundRole: + { + if (item->isDirectory()) + return QColor(QColor( 32, 32, 32)); + break; + } + default: + return QVariant(); } return QVariant(); @@ -140,6 +159,8 @@ namespace hal QModelIndex index = getIndexFromItem(item->getParent()); + mCurrentDirectory = item; + int row = item->getParent()->getChildCount(); beginInsertRows(index, row, row); item->getParent()->appendChild(item); @@ -239,4 +260,11 @@ namespace hal } return mContextList; } + + void ContextTreeModel::itemFocusChanged(const QModelIndex &newIndex) + { + BaseTreeItem* currentItem = getItemFromIndex(newIndex); + if(currentItem != mRootItem && static_cast(currentItem)->isDirectory()) + mCurrentDirectory = static_cast(currentItem); + } } From 6dfa474baade8266ea8fd120a3fcbb9e7133e0a4 Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 18 Dec 2023 23:59:18 +0100 Subject: [PATCH 06/38] Added 'add directory' icon --- .../context_manager_widget.h | 4 + plugins/gui/resources/gui_resources.qrc | 1 + plugins/gui/resources/icons/plusdir.svg | 69 +++++++ plugins/gui/resources/icons/views-dir.svg | 63 ++++++ plugins/gui/resources/icons/views-view.svg | 191 ++++++++++++++++++ plugins/gui/resources/stylesheet/dark.qss | 1 + plugins/gui/resources/stylesheet/light.qss | 1 + .../context_manager_widget.cpp | 12 +- 8 files changed, 341 insertions(+), 1 deletion(-) create mode 100755 plugins/gui/resources/icons/plusdir.svg create mode 100755 plugins/gui/resources/icons/views-dir.svg create mode 100755 plugins/gui/resources/icons/views-view.svg diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index 28a5ef8d162..aac2852caa0 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -62,6 +62,7 @@ namespace hal Q_OBJECT Q_PROPERTY(QString disabledIconStyle READ disabledIconStyle WRITE setDisabledIconStyle) Q_PROPERTY(QString newViewIconPath READ newViewIconPath WRITE setNewViewIconPath) + Q_PROPERTY(QString newDirIconPath READ newDirIconPath WRITE setNewDirIconPath) Q_PROPERTY(QString newViewIconStyle READ newViewIconStyle WRITE setNewViewIconStyle) Q_PROPERTY(QString renameIconPath READ renameIconPath WRITE setRenameIconPath) Q_PROPERTY(QString renameIconStyle READ renameIconStyle WRITE setRenameIconStyle) @@ -121,6 +122,7 @@ namespace hal ///@{ QString disabledIconStyle() const; QString newViewIconPath() const; + QString newDirIconPath() const; QString newViewIconStyle() const; QString renameIconPath() const; QString renameIconStyle() const; @@ -140,6 +142,7 @@ namespace hal ///@{ void setDisabledIconStyle(const QString &path); void setNewViewIconPath(const QString &path); + void setNewDirIconPath(const QString &path); void setNewViewIconStyle(const QString &style); void setRenameIconPath(const QString &path); void setRenameIconStyle(const QString &style); @@ -189,6 +192,7 @@ namespace hal QAction* mNewViewAction; QString mNewViewIconPath; + QString mNewDirIconPath; QString mNewViewIconStyle; QAction* mRenameAction; diff --git a/plugins/gui/resources/gui_resources.qrc b/plugins/gui/resources/gui_resources.qrc index 804397056c4..c334ab9ed4f 100644 --- a/plugins/gui/resources/gui_resources.qrc +++ b/plugins/gui/resources/gui_resources.qrc @@ -64,6 +64,7 @@ icons/new-file.svg icons/pen.svg icons/plus.svg + icons/plusdir.svg icons/trashcan.svg icons/0189-tree.svg icons/0086-keyboard.svg diff --git a/plugins/gui/resources/icons/plusdir.svg b/plugins/gui/resources/icons/plusdir.svg new file mode 100755 index 00000000000..b1d9fae80db --- /dev/null +++ b/plugins/gui/resources/icons/plusdir.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/plugins/gui/resources/icons/views-dir.svg b/plugins/gui/resources/icons/views-dir.svg new file mode 100755 index 00000000000..4927deece64 --- /dev/null +++ b/plugins/gui/resources/icons/views-dir.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/gui/resources/icons/views-view.svg b/plugins/gui/resources/icons/views-view.svg new file mode 100755 index 00000000000..cb71c9b3f50 --- /dev/null +++ b/plugins/gui/resources/icons/views-view.svg @@ -0,0 +1,191 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/gui/resources/stylesheet/dark.qss b/plugins/gui/resources/stylesheet/dark.qss index c435968bc0d..2a1c41c4427 100755 --- a/plugins/gui/resources/stylesheet/dark.qss +++ b/plugins/gui/resources/stylesheet/dark.qss @@ -1128,6 +1128,7 @@ hal--ContextManagerWidget qproperty-newViewIconStyle: "all->#e8e8e8"; qproperty-newViewIconPath: ":/icons/plus"; + qproperty-newDirIconPath: ":/icons/plusdir"; qproperty-renameIconStyle: "all->#e8e8e8"; qproperty-renameIconPath: ":/icons/pen"; diff --git a/plugins/gui/resources/stylesheet/light.qss b/plugins/gui/resources/stylesheet/light.qss index 2094bdb0cd3..0afb057a6de 100755 --- a/plugins/gui/resources/stylesheet/light.qss +++ b/plugins/gui/resources/stylesheet/light.qss @@ -1153,6 +1153,7 @@ hal--ContextManagerWidget qproperty-newViewIconStyle: "all->#FFFFFF"; qproperty-newViewIconPath: ":/icons/plus"; + qproperty-newDirIconPath: ":/icons/plusdir"; qproperty-renameIconStyle: "all->#FFFFFF"; qproperty-renameIconPath: ":/icons/pen"; diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index ef6414da129..05501bb4c6f 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -47,7 +47,7 @@ namespace hal mOpenAction->setIcon(gui_utility::getStyledSvgIcon(mOpenIconStyle, mOpenIconPath)); mNewViewAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewViewIconPath)); - mNewDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewViewIconPath)); + mNewDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewDirIconPath)); mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDuplicateIconStyle, mDuplicateIconPath)); mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); @@ -364,6 +364,11 @@ namespace hal return mNewViewIconPath; } + QString ContextManagerWidget::newDirIconPath() const + { + return mNewDirIconPath; + } + QString ContextManagerWidget::newViewIconStyle() const { return mNewViewIconStyle; @@ -434,6 +439,11 @@ namespace hal mNewViewIconPath = path; } + void ContextManagerWidget::setNewDirIconPath(const QString& path) + { + mNewDirIconPath = path; + } + void ContextManagerWidget::setNewViewIconStyle(const QString& style) { mNewViewIconStyle = style; From f6dd21917297fd351a73b95f8f01d15d9062ab87 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Tue, 19 Dec 2023 11:23:58 +0100 Subject: [PATCH 07/38] Make CurrentDirectory be set to the right directory --- .../context_manager_widget.h | 15 +++--- .../models/context_table_model.h | 10 +++- .../context_manager_widget.cpp | 50 ++++++++++--------- .../models/context_table_model.cpp | 13 ++--- 4 files changed, 51 insertions(+), 37 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index aac2852caa0..e224f1189dd 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -62,7 +62,6 @@ namespace hal Q_OBJECT Q_PROPERTY(QString disabledIconStyle READ disabledIconStyle WRITE setDisabledIconStyle) Q_PROPERTY(QString newViewIconPath READ newViewIconPath WRITE setNewViewIconPath) - Q_PROPERTY(QString newDirIconPath READ newDirIconPath WRITE setNewDirIconPath) Q_PROPERTY(QString newViewIconStyle READ newViewIconStyle WRITE setNewViewIconStyle) Q_PROPERTY(QString renameIconPath READ renameIconPath WRITE setRenameIconPath) Q_PROPERTY(QString renameIconStyle READ renameIconStyle WRITE setRenameIconStyle) @@ -100,6 +99,13 @@ namespace hal */ GraphContext* getCurrentContext(); + /** + * Get the currently selected directory in the table. + * + * @return The ContextTreeItem. + */ + ContextTreeItem* getCurrentItem(); + /** * Opens the currently selected GraphContext in hal's GraphTabWidget */ @@ -122,7 +128,6 @@ namespace hal ///@{ QString disabledIconStyle() const; QString newViewIconPath() const; - QString newDirIconPath() const; QString newViewIconStyle() const; QString renameIconPath() const; QString renameIconStyle() const; @@ -142,7 +147,6 @@ namespace hal ///@{ void setDisabledIconStyle(const QString &path); void setNewViewIconPath(const QString &path); - void setNewDirIconPath(const QString &path); void setNewViewIconStyle(const QString &style); void setRenameIconPath(const QString &path); void setRenameIconStyle(const QString &style); @@ -174,7 +178,7 @@ namespace hal private Q_SLOTS: - void handleDeleteShortcutOnFocusChanged(QWidget* oldWidget, QWidget* newWidget); + void handleFocusChanged(QWidget* oldWidget, QWidget* newWidget); private: @@ -182,7 +186,7 @@ namespace hal QTreeView* mContextTreeView; ContextTreeModel* mContextTreeModel; - ContextTableProxyModel* mContextTableProxyModel; + ContextTableProxyModel* mContextTreeProxyModel; Searchbar* mSearchbar; @@ -192,7 +196,6 @@ namespace hal QAction* mNewViewAction; QString mNewViewIconPath; - QString mNewDirIconPath; QString mNewViewIconStyle; QAction* mRenameAction; diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h index 49d317f072d..a48ef563cf5 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h @@ -142,11 +142,17 @@ namespace hal * * @return A vector of all GraphContext%s. */ - const QVector& list(); + const QVector& list(); + + /** + * Sets the CurrentDirectory. + * + * @param ContextTreeItem - The Currently focused Item. + */ + void setCurrentDirectory(ContextTreeItem* currentItem); private Q_SLOTS: void handleDataChanged(); - void itemFocusChanged(const QModelIndex &newIndex); private: diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index 05501bb4c6f..283f6dffb1f 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -47,7 +47,7 @@ namespace hal mOpenAction->setIcon(gui_utility::getStyledSvgIcon(mOpenIconStyle, mOpenIconPath)); mNewViewAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewViewIconPath)); - mNewDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewDirIconPath)); + mNewDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewViewIconPath)); mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDuplicateIconStyle, mDuplicateIconPath)); mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); @@ -76,12 +76,12 @@ namespace hal mContextTreeModel = gGraphContextManager->getContextTableModel(); - mContextTableProxyModel = new ContextTableProxyModel(this); - mContextTableProxyModel->setSourceModel(mContextTreeModel); - mContextTableProxyModel->setSortRole(Qt::UserRole); + mContextTreeProxyModel = new ContextTableProxyModel(this); + mContextTreeProxyModel->setSourceModel(mContextTreeModel); + mContextTreeProxyModel->setSortRole(Qt::UserRole); mContextTreeView = new QTreeView(this); - mContextTreeView->setModel(mContextTableProxyModel); + mContextTreeView->setModel(mContextTreeProxyModel); mContextTreeView->setSortingEnabled(true); mContextTreeView->setSelectionBehavior(QAbstractItemView::SelectRows); mContextTreeView->setSelectionMode(QAbstractItemView::SingleSelection); // ERROR ??? @@ -95,8 +95,8 @@ namespace hal mContentLayout->addWidget(mSearchbar); mSearchbar->hide(); - mSearchbar->setColumnNames(mContextTableProxyModel->getColumnNames()); - enableSearchbar(mContextTableProxyModel->rowCount() > 0); + mSearchbar->setColumnNames(mContextTreeProxyModel->getColumnNames()); + enableSearchbar(mContextTreeProxyModel->rowCount() > 0); connect(mOpenAction, &QAction::triggered, this, &ContextManagerWidget::handleOpenContextClicked); connect(mNewViewAction, &QAction::triggered, this, &ContextManagerWidget::handleCreateContextClicked); @@ -113,7 +113,7 @@ namespace hal connect(mContextTreeModel, &ContextTreeModel::rowsInserted, this, &ContextManagerWidget::handleDataChanged); connect(mSearchbar, &Searchbar::triggerNewSearch, this, &ContextManagerWidget::updateSearchIcon); - connect(mSearchbar, &Searchbar::triggerNewSearch, mContextTableProxyModel, &ContextTableProxyModel::startSearch); + connect(mSearchbar, &Searchbar::triggerNewSearch, mContextTreeProxyModel, &ContextTableProxyModel::startSearch); mShortCutDeleteItem = new QShortcut(ContentManager::sSettingDeleteItem->value().toString(), this); mShortCutDeleteItem->setEnabled(false); @@ -121,7 +121,7 @@ namespace hal connect(ContentManager::sSettingDeleteItem, &SettingsItemKeybind::keySequenceChanged, mShortCutDeleteItem, &QShortcut::setKey); connect(mShortCutDeleteItem, &QShortcut::activated, this, &ContextManagerWidget::handleDeleteContextClicked); - connect(qApp, &QApplication::focusChanged, this, &ContextManagerWidget::handleDeleteShortcutOnFocusChanged); + connect(qApp, &QApplication::focusChanged, this, &ContextManagerWidget::handleFocusChanged); } void ContextManagerWidget::handleCreateContextClicked() @@ -250,7 +250,7 @@ namespace hal void ContextManagerWidget::handleDataChanged() { - enableSearchbar(mContextTableProxyModel->rowCount() > 0); + enableSearchbar(mContextTreeProxyModel->rowCount() > 0); } void ContextManagerWidget::updateSearchIcon() @@ -264,7 +264,7 @@ namespace hal void ContextManagerWidget::selectViewContext(GraphContext* context) { const QModelIndex source_model_index = mContextTreeModel->getIndexFromContext(context); - const QModelIndex proxy_model_index = mContextTableProxyModel->mapFromSource(source_model_index); + const QModelIndex proxy_model_index = mContextTreeProxyModel->mapFromSource(source_model_index); if(proxy_model_index.isValid()) mContextTreeView->setCurrentIndex(proxy_model_index); @@ -275,11 +275,23 @@ namespace hal GraphContext* ContextManagerWidget::getCurrentContext() { QModelIndex proxy_model_index = mContextTreeView->currentIndex(); - QModelIndex source_model_index = mContextTableProxyModel->mapToSource(proxy_model_index); + QModelIndex source_model_index = mContextTreeProxyModel->mapToSource(proxy_model_index); return mContextTreeModel->getContext(source_model_index); } + ContextTreeItem *ContextManagerWidget::getCurrentItem() + { + QModelIndex proxy_model_index = mContextTreeView->currentIndex(); + QModelIndex source_model_index = mContextTreeProxyModel->mapToSource(proxy_model_index); + + BaseTreeItem* currentItem = mContextTreeModel->getItemFromIndex(source_model_index); + if (currentItem != mContextTreeModel->getRootItem()) + return static_cast(currentItem); + + return nullptr; + } + void ContextManagerWidget::setupToolbar(Toolbar* toolbar) { toolbar->addAction(mNewDirectoryAction); @@ -364,11 +376,6 @@ namespace hal return mNewViewIconPath; } - QString ContextManagerWidget::newDirIconPath() const - { - return mNewDirIconPath; - } - QString ContextManagerWidget::newViewIconStyle() const { return mNewViewIconStyle; @@ -439,11 +446,6 @@ namespace hal mNewViewIconPath = path; } - void ContextManagerWidget::setNewDirIconPath(const QString& path) - { - mNewDirIconPath = path; - } - void ContextManagerWidget::setNewViewIconStyle(const QString& style) { mNewViewIconStyle = style; @@ -504,8 +506,10 @@ namespace hal mSearchActiveIconStyle = style; } - void ContextManagerWidget::handleDeleteShortcutOnFocusChanged(QWidget* oldWidget, QWidget* newWidget) + void ContextManagerWidget::handleFocusChanged(QWidget* oldWidget, QWidget* newWidget) { + mContextTreeModel->setCurrentDirectory(getCurrentItem()); + if(!newWidget) return; if(newWidget->parent() == this) { diff --git a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp index 86f5e07225a..c32ae394fa3 100644 --- a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp @@ -100,7 +100,6 @@ namespace hal ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr), mMinDirectoryId(std::numeric_limits::max()) { setHeaderLabels(QStringList() << "View Name" << "Timestamp"); - //connect(qApp, &QApplication::focusChanged, this, &ContextTreeModel::itemFocusChanged); } @@ -242,7 +241,7 @@ namespace hal BaseTreeItem* item = getItemFromIndex(index); if (static_cast(item)->isDirectory()) return nullptr; - GraphContext* context; + GraphContext* context = nullptr; for (auto &i : mContextMap) { if (i.second == item) { context = i.first; @@ -261,10 +260,12 @@ namespace hal return mContextList; } - void ContextTreeModel::itemFocusChanged(const QModelIndex &newIndex) + void ContextTreeModel::setCurrentDirectory(ContextTreeItem* currentItem) { - BaseTreeItem* currentItem = getItemFromIndex(newIndex); - if(currentItem != mRootItem && static_cast(currentItem)->isDirectory()) - mCurrentDirectory = static_cast(currentItem); + if(currentItem->isContext()) + mCurrentDirectory = (currentItem->getParent() == mRootItem) ? nullptr : static_cast(currentItem->getParent()); + + else if (currentItem->isDirectory()) + mCurrentDirectory = currentItem; } } From f042d4cf1d1c16360f309b8fe0418926ca08f678 Mon Sep 17 00:00:00 2001 From: joern274 Date: Tue, 19 Dec 2023 12:55:17 +0100 Subject: [PATCH 08/38] Item icons added for context manager tree --- .../models/context_table_model.h | 1 + .../gui/graph_widget/contexts/graph_context.h | 2 +- .../selection_details_icon_provider.h | 4 +- plugins/gui/resources/gui_resources.qrc | 2 + .../icons/{views-view.svg => view-ctx.svg} | 0 .../icons/{views-dir.svg => view-dir.svg} | 0 .../models/context_table_model.cpp | 45 ++++++++++--------- .../selection_details_icon_provider.cpp | 2 + 8 files changed, 31 insertions(+), 25 deletions(-) rename plugins/gui/resources/icons/{views-view.svg => view-ctx.svg} (100%) rename plugins/gui/resources/icons/{views-dir.svg => view-dir.svg} (100%) diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h index 49d317f072d..ade290e3e3f 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h @@ -63,6 +63,7 @@ namespace hal int row() const; bool isDirectory() const; bool isContext() const; + const GraphContext* context() const; }; /** diff --git a/plugins/gui/include/gui/graph_widget/contexts/graph_context.h b/plugins/gui/include/gui/graph_widget/contexts/graph_context.h index 1691e6b4178..b253a8d72f2 100644 --- a/plugins/gui/include/gui/graph_widget/contexts/graph_context.h +++ b/plugins/gui/include/gui/graph_widget/contexts/graph_context.h @@ -411,7 +411,7 @@ namespace hal * * @return The exclusive module id. */ - u32 getExclusiveModuleId() + u32 getExclusiveModuleId() const { return mExclusiveModuleId; } diff --git a/plugins/gui/include/gui/selection_details_widget/selection_details_icon_provider.h b/plugins/gui/include/gui/selection_details_widget/selection_details_icon_provider.h index a9d9cdf8cba..d04c1a4b25d 100644 --- a/plugins/gui/include/gui/selection_details_widget/selection_details_icon_provider.h +++ b/plugins/gui/include/gui/selection_details_widget/selection_details_icon_provider.h @@ -42,7 +42,7 @@ namespace hal SelectionDetailsIconProvider(QObject* parent = nullptr); static SelectionDetailsIconProvider* inst; public: - enum IconCategory { ModuleIcon = -1, GateIcon = -2, NetIcon = -3}; + enum IconCategory { ModuleIcon = -1, GateIcon = -2, NetIcon = -3, ViewDir = -4, ViewCtx = -5}; enum IconSize { NoIcon, SmallIcon, BigIcon }; Q_ENUM(IconSize) @@ -60,4 +60,4 @@ namespace hal static SelectionDetailsIconProvider* instance(); static SettingsItemDropdown* sIconSizeSetting; }; -} \ No newline at end of file +} diff --git a/plugins/gui/resources/gui_resources.qrc b/plugins/gui/resources/gui_resources.qrc index c334ab9ed4f..6a0363cb72a 100644 --- a/plugins/gui/resources/gui_resources.qrc +++ b/plugins/gui/resources/gui_resources.qrc @@ -105,6 +105,8 @@ icons/0503-invoke-gui.svg icons/tree-collapsed.svg icons/tree-expanded.svg + icons/view-ctx.svg + icons/view-dir.svg images/oval.svg diff --git a/plugins/gui/resources/icons/views-view.svg b/plugins/gui/resources/icons/view-ctx.svg similarity index 100% rename from plugins/gui/resources/icons/views-view.svg rename to plugins/gui/resources/icons/view-ctx.svg diff --git a/plugins/gui/resources/icons/views-dir.svg b/plugins/gui/resources/icons/view-dir.svg similarity index 100% rename from plugins/gui/resources/icons/views-dir.svg rename to plugins/gui/resources/icons/view-dir.svg diff --git a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp index 86f5e07225a..e3dcd38b94c 100644 --- a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp @@ -1,5 +1,5 @@ #include "gui/context_manager_widget/models/context_table_model.h" - +#include "gui/selection_details_widget/selection_details_icon_provider.h" #include "gui/gui_globals.h" #include "gui/gui_utils/graphics.h" @@ -19,8 +19,8 @@ namespace hal ContextTreeItem::ContextTreeItem(ContextDirectory *directory) : BaseTreeItem(), - mDirectory(directory), - mContext(nullptr) + mContext(nullptr), + mDirectory(directory) { } @@ -33,12 +33,10 @@ namespace hal case 0: { return mDirectory->getName(); - break; } case 1: { return ""; - break; } } } @@ -49,15 +47,19 @@ namespace hal case 0: { return mContext->getNameWithDirtyState(); - break; } case 1: { return mContext->getTimestamp().toString(Qt::SystemLocaleShortDate); - break; } } } + return QVariant(); + } + + const GraphContext* ContextTreeItem::context() const + { + return mContext; } void ContextTreeItem::setData(QList data) @@ -118,24 +120,23 @@ namespace hal { case Qt::DecorationRole: { - break; + if (index.column()) return QVariant(); // decorator only for first column + if (item->isDirectory()) + return QIcon(*SelectionDetailsIconProvider::instance()->getIcon(SelectionDetailsIconProvider::ViewDir,0)); + const GraphContext* ctx = item->context(); + u32 mid = 0; + if (ctx && (mid=ctx->getExclusiveModuleId()) != 0) + return QIcon(*SelectionDetailsIconProvider::instance()->getIcon(SelectionDetailsIconProvider::ModuleIcon,mid)); + return QIcon(*SelectionDetailsIconProvider::instance()->getIcon(SelectionDetailsIconProvider::ViewCtx,0)); } + case Qt::DisplayRole: - { - switch(index.column()) - { - case 0: return item->getData(0); break; - case 1: return item->getData(1); break; - default: return QVariant(); - } - break; - } + return item->getData(index.column()); + case Qt::BackgroundRole: - { - if (item->isDirectory()) - return QColor(QColor( 32, 32, 32)); - break; - } + // must declare color in dark/light style + return QVariant(); + default: return QVariant(); } diff --git a/plugins/gui/src/selection_details_widget/selection_details_icon_provider.cpp b/plugins/gui/src/selection_details_widget/selection_details_icon_provider.cpp index f6748dd9c44..a5f8a652eed 100644 --- a/plugins/gui/src/selection_details_widget/selection_details_icon_provider.cpp +++ b/plugins/gui/src/selection_details_widget/selection_details_icon_provider.cpp @@ -68,6 +68,8 @@ namespace hal mDefaultIcons[ModuleIcon] = new QIcon(gui_utility::getStyledSvgIcon(solidColor, ":/icons/ne_module")); mDefaultIcons[GateIcon] = new QIcon(gui_utility::getStyledSvgIcon(solidColor, ":/icons/ne_gate")); mDefaultIcons[NetIcon] = new QIcon(gui_utility::getStyledSvgIcon(solidColor, ":/icons/ne_net")); + mDefaultIcons[ViewDir] = new QIcon(gui_utility::getStyledSvgIcon(solidColor, ":/icons/view-dir")); + mDefaultIcons[ViewCtx] = new QIcon(gui_utility::getStyledSvgIcon(solidColor, ":/icons/view-ctx")); if (!mGateIcons.isEmpty()) { From 088fda9c3368fe5062a8836b9519e05fb569b770 Mon Sep 17 00:00:00 2001 From: joern274 Date: Tue, 19 Dec 2023 13:26:30 +0100 Subject: [PATCH 09/38] Lost 'add directory' icon on merge - added it again --- .../context_manager_widget/context_manager_widget.h | 4 ++++ .../context_manager_widget.cpp | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index e224f1189dd..8e29e67e3ca 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -62,6 +62,7 @@ namespace hal Q_OBJECT Q_PROPERTY(QString disabledIconStyle READ disabledIconStyle WRITE setDisabledIconStyle) Q_PROPERTY(QString newViewIconPath READ newViewIconPath WRITE setNewViewIconPath) + Q_PROPERTY(QString newDirIconPath READ newDirIconPath WRITE setNewDirIconPath) Q_PROPERTY(QString newViewIconStyle READ newViewIconStyle WRITE setNewViewIconStyle) Q_PROPERTY(QString renameIconPath READ renameIconPath WRITE setRenameIconPath) Q_PROPERTY(QString renameIconStyle READ renameIconStyle WRITE setRenameIconStyle) @@ -128,6 +129,7 @@ namespace hal ///@{ QString disabledIconStyle() const; QString newViewIconPath() const; + QString newDirIconPath() const; QString newViewIconStyle() const; QString renameIconPath() const; QString renameIconStyle() const; @@ -148,6 +150,7 @@ namespace hal void setDisabledIconStyle(const QString &path); void setNewViewIconPath(const QString &path); void setNewViewIconStyle(const QString &style); + void setNewDirIconPath(const QString &path); void setRenameIconPath(const QString &path); void setRenameIconStyle(const QString &style); void setDeleteIconPath(const QString &path); @@ -196,6 +199,7 @@ namespace hal QAction* mNewViewAction; QString mNewViewIconPath; + QString mNewDirIconPath; QString mNewViewIconStyle; QAction* mRenameAction; diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index 283f6dffb1f..f98e2c85d57 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -47,7 +47,7 @@ namespace hal mOpenAction->setIcon(gui_utility::getStyledSvgIcon(mOpenIconStyle, mOpenIconPath)); mNewViewAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewViewIconPath)); - mNewDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewViewIconPath)); + mNewDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewDirIconPath)); mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDuplicateIconStyle, mDuplicateIconPath)); mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); @@ -376,6 +376,11 @@ namespace hal return mNewViewIconPath; } + QString ContextManagerWidget::newDirIconPath() const + { + return mNewDirIconPath; + } + QString ContextManagerWidget::newViewIconStyle() const { return mNewViewIconStyle; @@ -446,6 +451,11 @@ namespace hal mNewViewIconPath = path; } + void ContextManagerWidget::setNewDirIconPath(const QString& path) + { + mNewDirIconPath = path; + } + void ContextManagerWidget::setNewViewIconStyle(const QString& style) { mNewViewIconStyle = style; From b4ad8eea25af965ced35ed6c4492ff8165800d88 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Wed, 20 Dec 2023 15:19:55 +0100 Subject: [PATCH 10/38] WIP: Fix new view placement in ContextTreeModel --- .../context_manager_widget.h | 5 ++++ .../models/context_table_model.h | 2 +- .../gui/graph_tab_widget/graph_tab_widget.h | 4 +-- .../context_manager_widget.cpp | 28 +++++++++++++------ .../models/context_table_model.cpp | 20 ++++++------- .../src/graph_tab_widget/graph_tab_widget.cpp | 2 +- 6 files changed, 39 insertions(+), 22 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index 8e29e67e3ca..0e908bd0792 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -112,6 +112,11 @@ namespace hal */ void handleOpenContextClicked(); + /** + * Handle double clicked + */ + void handleItemDoubleClicked(const QModelIndex &index); + /** * Initializes the Toolbar of the ContextManagerWidget. * diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h index ef9a9d42174..c0f0a3f98e3 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h @@ -63,7 +63,7 @@ namespace hal int row() const; bool isDirectory() const; bool isContext() const; - const GraphContext* context() const; + GraphContext* context() const; }; /** diff --git a/plugins/gui/include/gui/graph_tab_widget/graph_tab_widget.h b/plugins/gui/include/gui/graph_tab_widget/graph_tab_widget.h index 9cd59ab62f4..a4d06f741b1 100644 --- a/plugins/gui/include/gui/graph_tab_widget/graph_tab_widget.h +++ b/plugins/gui/include/gui/graph_tab_widget/graph_tab_widget.h @@ -81,7 +81,7 @@ namespace hal * * @param context - The GraphContext to show */ - void showContext(GraphContext* context); + void showContext(GraphContext *context); /** * Moves (and scales) the camera in the current GraphWidget to the current selection so that every selected @@ -226,7 +226,7 @@ namespace hal QMap mContextWidgetMap; - int getContextTabIndex(GraphContext* context) const; + int getContextTabIndex(const GraphContext *context) const; void addGraphWidgetTab(GraphContext* context); diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index f98e2c85d57..a861e17c5d8 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -98,7 +98,7 @@ namespace hal mSearchbar->setColumnNames(mContextTreeProxyModel->getColumnNames()); enableSearchbar(mContextTreeProxyModel->rowCount() > 0); - connect(mOpenAction, &QAction::triggered, this, &ContextManagerWidget::handleOpenContextClicked); + connect(mOpenAction, &QAction::triggered, this, &ContextManagerWidget::handleOpenContextClicked); connect(mNewViewAction, &QAction::triggered, this, &ContextManagerWidget::handleCreateContextClicked); connect(mNewDirectoryAction, &QAction::triggered, this, &ContextManagerWidget::handleCreateDirectoryClicked); connect(mRenameAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameContextClicked); @@ -106,8 +106,8 @@ namespace hal connect(mDeleteAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteContextClicked); connect(mSearchAction, &QAction::triggered, this, &ContextManagerWidget::toggleSearchbar); - connect(mContextTreeView, &QTableView::customContextMenuRequested, this, &ContextManagerWidget::handleContextMenuRequest); - connect(mContextTreeView, &QTableView::doubleClicked, this, &ContextManagerWidget::handleOpenContextClicked); + connect(mContextTreeView, &QTreeView::customContextMenuRequested, this, &ContextManagerWidget::handleContextMenuRequest); + connect(mContextTreeView, &QTreeView::doubleClicked, this, &ContextManagerWidget::handleItemDoubleClicked); connect(mContextTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ContextManagerWidget::handleSelectionChanged); connect(mContextTreeModel, &ContextTreeModel::rowsRemoved, this, &ContextManagerWidget::handleDataChanged); connect(mContextTreeModel, &ContextTreeModel::rowsInserted, this, &ContextManagerWidget::handleDataChanged); @@ -148,11 +148,25 @@ namespace hal void ContextManagerWidget::handleOpenContextClicked() { - GraphContext* clicked_context = getCurrentContext(); + GraphContext* defaultContext = getCurrentContext(); + if (!defaultContext) return; + mTabView->showContext(defaultContext); + } - if (!clicked_context) return; + void ContextManagerWidget::handleItemDoubleClicked(const QModelIndex &index) + { + ContextTreeItem* item = static_cast(mContextTreeModel->getItemFromIndex(index)); + if (item->isDirectory()){ + mContextTreeModel->setCurrentDirectory(item); + } + else { - mTabView->showContext(clicked_context); + GraphContext* clickedContext = item->context(); + + if (!clickedContext) return; + + mTabView->showContext(clickedContext); + } } void ContextManagerWidget::handleRenameContextClicked() @@ -518,8 +532,6 @@ namespace hal void ContextManagerWidget::handleFocusChanged(QWidget* oldWidget, QWidget* newWidget) { - mContextTreeModel->setCurrentDirectory(getCurrentItem()); - if(!newWidget) return; if(newWidget->parent() == this) { diff --git a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp index 3c403c11013..0d6e18ee990 100644 --- a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_table_model.cpp @@ -57,7 +57,7 @@ namespace hal return QVariant(); } - const GraphContext* ContextTreeItem::context() const + GraphContext *ContextTreeItem::context() const { return mContext; } @@ -149,21 +149,21 @@ namespace hal ContextTreeItem* item = new ContextTreeItem(directory); - if (parent) - item->setParent(parent); - else if(mCurrentDirectory) - item->setParent(mCurrentDirectory); - else - item->setParent(mRootItem); + BaseTreeItem* parentItem = parent; + if (!parentItem) + parentItem = mCurrentDirectory; + if (!parentItem) + parentItem = mRootItem; - QModelIndex index = getIndexFromItem(item->getParent()); + + QModelIndex index = getIndexFromItem(parentItem); mCurrentDirectory = item; - int row = item->getParent()->getChildCount(); + int row = parentItem->getChildCount(); beginInsertRows(index, row, row); - item->getParent()->appendChild(item); + parentItem->appendChild(item); endInsertRows(); diff --git a/plugins/gui/src/graph_tab_widget/graph_tab_widget.cpp b/plugins/gui/src/graph_tab_widget/graph_tab_widget.cpp index 8f4a4bef157..67e14f47115 100644 --- a/plugins/gui/src/graph_tab_widget/graph_tab_widget.cpp +++ b/plugins/gui/src/graph_tab_widget/graph_tab_widget.cpp @@ -322,7 +322,7 @@ namespace hal return 0; } - int GraphTabWidget::getContextTabIndex(GraphContext* context) const + int GraphTabWidget::getContextTabIndex(const GraphContext* context) const { for (int i = 0; i < mTabWidget->count(); i++) { From d132a560125c9fd288edc1a606a2d5a9599a911f Mon Sep 17 00:00:00 2001 From: joern274 Date: Fri, 22 Dec 2023 20:03:17 +0100 Subject: [PATCH 11/38] 1.Double-Click bugfix: access item by proxy 2.Renamed classes --- .../context_manager_widget/context_manager_widget.h | 8 ++++---- ...ntext_table_proxy_model.h => context_proxy_model.h} | 4 ++-- .../{context_table_model.h => context_tree_model.h} | 0 .../context_manager_widget/context_manager_widget.cpp | 9 +++++---- ...t_table_proxy_model.cpp => context_proxy_model.cpp} | 10 +++++----- ...{context_table_model.cpp => context_tree_model.cpp} | 2 +- plugins/gui/src/graph_widget/graph_context_manager.cpp | 2 +- plugins/gui/src/gui_api/gui_api.cpp | 2 +- 8 files changed, 19 insertions(+), 18 deletions(-) rename plugins/gui/include/gui/context_manager_widget/models/{context_table_proxy_model.h => context_proxy_model.h} (96%) rename plugins/gui/include/gui/context_manager_widget/models/{context_table_model.h => context_tree_model.h} (100%) rename plugins/gui/src/context_manager_widget/models/{context_table_proxy_model.cpp => context_proxy_model.cpp} (60%) rename plugins/gui/src/context_manager_widget/models/{context_table_model.cpp => context_tree_model.cpp} (99%) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index 0e908bd0792..0465199ca57 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -30,8 +30,8 @@ #include "hal_core/defines.h" #include "gui/graph_widget/contexts/graph_context.h" -#include "gui/context_manager_widget/models/context_table_model.h" -#include "gui/context_manager_widget/models/context_table_proxy_model.h" +#include "gui/context_manager_widget/models/context_tree_model.h" +#include "gui/context_manager_widget/models/context_proxy_model.h" #include "gui/searchbar/searchbar.h" #include "gui/settings/settings_items/settings_item_keybind.h" @@ -115,7 +115,7 @@ namespace hal /** * Handle double clicked */ - void handleItemDoubleClicked(const QModelIndex &index); + void handleItemDoubleClicked(const QModelIndex &proxyIndex); /** * Initializes the Toolbar of the ContextManagerWidget. @@ -194,7 +194,7 @@ namespace hal QTreeView* mContextTreeView; ContextTreeModel* mContextTreeModel; - ContextTableProxyModel* mContextTreeProxyModel; + ContextProxyModel* mContextTreeProxyModel; Searchbar* mSearchbar; diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_table_proxy_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_proxy_model.h similarity index 96% rename from plugins/gui/include/gui/context_manager_widget/models/context_table_proxy_model.h rename to plugins/gui/include/gui/context_manager_widget/models/context_proxy_model.h index a94617e3cc9..58f6049ca4d 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_table_proxy_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_proxy_model.h @@ -37,7 +37,7 @@ namespace hal * @ingroup utility_widgets-context * @brief A proxy model to filter the ContextTableModel by a given string. */ - class ContextTableProxyModel : public SearchProxyModel + class ContextProxyModel : public SearchProxyModel { Q_OBJECT @@ -47,7 +47,7 @@ namespace hal * * @param parent - The widget's parent. */ - ContextTableProxyModel(QObject* parent = nullptr); + ContextProxyModel(QObject* parent = nullptr); /** * Determines if the index specified by the row and its parent should be displayed diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_table_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h similarity index 100% rename from plugins/gui/include/gui/context_manager_widget/models/context_table_model.h rename to plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index a861e17c5d8..b324ff6d165 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -76,7 +76,7 @@ namespace hal mContextTreeModel = gGraphContextManager->getContextTableModel(); - mContextTreeProxyModel = new ContextTableProxyModel(this); + mContextTreeProxyModel = new ContextProxyModel(this); mContextTreeProxyModel->setSourceModel(mContextTreeModel); mContextTreeProxyModel->setSortRole(Qt::UserRole); @@ -113,7 +113,7 @@ namespace hal connect(mContextTreeModel, &ContextTreeModel::rowsInserted, this, &ContextManagerWidget::handleDataChanged); connect(mSearchbar, &Searchbar::triggerNewSearch, this, &ContextManagerWidget::updateSearchIcon); - connect(mSearchbar, &Searchbar::triggerNewSearch, mContextTreeProxyModel, &ContextTableProxyModel::startSearch); + connect(mSearchbar, &Searchbar::triggerNewSearch, mContextTreeProxyModel, &ContextProxyModel::startSearch); mShortCutDeleteItem = new QShortcut(ContentManager::sSettingDeleteItem->value().toString(), this); mShortCutDeleteItem->setEnabled(false); @@ -153,9 +153,10 @@ namespace hal mTabView->showContext(defaultContext); } - void ContextManagerWidget::handleItemDoubleClicked(const QModelIndex &index) + void ContextManagerWidget::handleItemDoubleClicked(const QModelIndex &proxyIndex) { - ContextTreeItem* item = static_cast(mContextTreeModel->getItemFromIndex(index)); + QModelIndex sourceIndex = mContextTreeProxyModel->mapToSource(proxyIndex); + ContextTreeItem* item = static_cast(mContextTreeModel->getItemFromIndex(sourceIndex)); if (item->isDirectory()){ mContextTreeModel->setCurrentDirectory(item); } diff --git a/plugins/gui/src/context_manager_widget/models/context_table_proxy_model.cpp b/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp similarity index 60% rename from plugins/gui/src/context_manager_widget/models/context_table_proxy_model.cpp rename to plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp index b37c53e8ba9..846b59b9488 100644 --- a/plugins/gui/src/context_manager_widget/models/context_table_proxy_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp @@ -1,4 +1,4 @@ -#include "gui/context_manager_widget/models/context_table_proxy_model.h" +#include "gui/context_manager_widget/models/context_proxy_model.h" #include "gui/gui_utils/sort.h" @@ -6,17 +6,17 @@ namespace hal { - ContextTableProxyModel::ContextTableProxyModel(QObject* parent) : SearchProxyModel(parent) + ContextProxyModel::ContextProxyModel(QObject* parent) : SearchProxyModel(parent) { } - bool ContextTableProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const + bool ContextProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { return checkRow(source_row, source_parent, 0, 1); } - bool ContextTableProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const + bool ContextProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { QVariant leftData = sourceModel()->data(left, Qt::UserRole); QVariant rightData = sourceModel()->data(right, Qt::UserRole); @@ -27,7 +27,7 @@ namespace hal return !(gui_utility::compare(gui_utility::mSortMechanism::natural, leftData.toString(), rightData.toString())); } - void ContextTableProxyModel::startSearch(QString text, int options) + void ContextProxyModel::startSearch(QString text, int options) { mSearchString = text; mSearchOptions = SearchOptions(options); diff --git a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp similarity index 99% rename from plugins/gui/src/context_manager_widget/models/context_table_model.cpp rename to plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index 0d6e18ee990..4d908668207 100644 --- a/plugins/gui/src/context_manager_widget/models/context_table_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -1,4 +1,4 @@ -#include "gui/context_manager_widget/models/context_table_model.h" +#include "gui/context_manager_widget/models/context_tree_model.h" #include "gui/selection_details_widget/selection_details_icon_provider.h" #include "gui/gui_globals.h" #include "gui/gui_utils/graphics.h" diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index 52e599f74f7..81a5295b446 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -1,6 +1,6 @@ #include "gui/graph_widget/graph_context_manager.h" -#include "gui/context_manager_widget/models/context_table_model.h" +#include "gui/context_manager_widget/models/context_tree_model.h" #include "gui/file_manager/file_manager.h" #include "gui/graph_widget/contexts/graph_context.h" #include "gui/graph_widget/graphics_scene.h" diff --git a/plugins/gui/src/gui_api/gui_api.cpp b/plugins/gui/src/gui_api/gui_api.cpp index 07734133b79..b2707dffe9d 100644 --- a/plugins/gui/src/gui_api/gui_api.cpp +++ b/plugins/gui/src/gui_api/gui_api.cpp @@ -14,7 +14,7 @@ #include "gui/user_action/action_unfold_module.h" #include "gui/user_action/action_move_node.h" #include "gui/graph_widget/graph_context_manager.h" -#include "gui/context_manager_widget/models/context_table_model.h" +#include "gui/context_manager_widget/models/context_tree_model.h" #include "hal_core/utilities/log.h" #include From 99201ad299b046057ae1dab4af047c54ad31e860 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Thu, 4 Jan 2024 11:58:39 +0100 Subject: [PATCH 12/38] add current directory change on click --- .../context_manager_widget.h | 5 +++++ .../context_manager_widget.cpp | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index 0465199ca57..ef10008a5ef 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -117,6 +117,11 @@ namespace hal */ void handleItemDoubleClicked(const QModelIndex &proxyIndex); + /** + * Handle clicked + */ + void handleItemClicked(const QModelIndex &proxyIndex); + /** * Initializes the Toolbar of the ContextManagerWidget. * diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index b324ff6d165..ab181f7484d 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -108,6 +108,7 @@ namespace hal connect(mContextTreeView, &QTreeView::customContextMenuRequested, this, &ContextManagerWidget::handleContextMenuRequest); connect(mContextTreeView, &QTreeView::doubleClicked, this, &ContextManagerWidget::handleItemDoubleClicked); + connect(mContextTreeView, &QTreeView::clicked, this, &ContextManagerWidget::handleItemClicked); connect(mContextTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ContextManagerWidget::handleSelectionChanged); connect(mContextTreeModel, &ContextTreeModel::rowsRemoved, this, &ContextManagerWidget::handleDataChanged); connect(mContextTreeModel, &ContextTreeModel::rowsInserted, this, &ContextManagerWidget::handleDataChanged); @@ -157,10 +158,10 @@ namespace hal { QModelIndex sourceIndex = mContextTreeProxyModel->mapToSource(proxyIndex); ContextTreeItem* item = static_cast(mContextTreeModel->getItemFromIndex(sourceIndex)); - if (item->isDirectory()){ - mContextTreeModel->setCurrentDirectory(item); - } - else { + + mContextTreeModel->setCurrentDirectory(item); + + if (item->isContext()) { GraphContext* clickedContext = item->context(); @@ -170,6 +171,15 @@ namespace hal } } + void ContextManagerWidget::handleItemClicked(const QModelIndex &proxyIndex) + { + QModelIndex sourceIndex = mContextTreeProxyModel->mapToSource(proxyIndex); + ContextTreeItem* item = static_cast(mContextTreeModel->getItemFromIndex(sourceIndex)); + + mContextTreeModel->setCurrentDirectory(item); + + } + void ContextManagerWidget::handleRenameContextClicked() { GraphContext* clicked_context = getCurrentContext(); From 0e08c5f3de2dc598233ea73d27bce148b13f9433 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Fri, 12 Jan 2024 12:59:17 +0100 Subject: [PATCH 13/38] Make new created directory current in view --- .../context_manager_widget/context_manager_widget.h | 5 +++++ .../models/context_tree_model.h | 3 +++ .../context_manager_widget.cpp | 13 +++++++++++++ .../models/context_tree_model.cpp | 5 +---- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index ef10008a5ef..79e7fc989e4 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -189,6 +189,11 @@ namespace hal */ void updateSearchIcon(); + /** + * Q_SLOT to select the Directory. + */ + void selectDirectory(ContextTreeItem* item); + private Q_SLOTS: void handleFocusChanged(QWidget* oldWidget, QWidget* newWidget); diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h index c0f0a3f98e3..cd0a13fe244 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h @@ -152,6 +152,9 @@ namespace hal */ void setCurrentDirectory(ContextTreeItem* currentItem); + Q_SIGNALS: + void directoryCreatedSignal(ContextTreeItem* item); + private Q_SLOTS: void handleDataChanged(); diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index ab181f7484d..a0b60fe6bc4 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -123,6 +123,8 @@ namespace hal connect(mShortCutDeleteItem, &QShortcut::activated, this, &ContextManagerWidget::handleDeleteContextClicked); connect(qApp, &QApplication::focusChanged, this, &ContextManagerWidget::handleFocusChanged); + + connect(mContextTreeModel, &ContextTreeModel::directoryCreatedSignal, this, &ContextManagerWidget::selectDirectory); } void ContextManagerWidget::handleCreateContextClicked() @@ -286,6 +288,17 @@ namespace hal mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath)); } + void ContextManagerWidget::selectDirectory(ContextTreeItem* item) + { + const QModelIndex source_model_index = mContextTreeModel->getIndexFromItem(static_cast(item)); + const QModelIndex proxy_model_index = mContextTreeProxyModel->mapFromSource(source_model_index); + + if(proxy_model_index.isValid()) + mContextTreeView->setCurrentIndex(proxy_model_index); + else + mContextTreeView->clearSelection(); + } + void ContextManagerWidget::selectViewContext(GraphContext* context) { const QModelIndex source_model_index = mContextTreeModel->getIndexFromContext(context); diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index 4d908668207..fa11aceadec 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -166,11 +166,8 @@ namespace hal parentItem->appendChild(item); endInsertRows(); + Q_EMIT directoryCreatedSignal(item); - //connect(context,&GraphContext::dataChanged,this,&ContextTableModel::handleDataChanged); - /*connect(context, &GraphContext::dataChanged, this, [item, this]() { - Q_EMIT dataChanged(getIndexFromItem(item), getIndexFromItem(item)); - });*/ } void ContextTreeModel::clear() From c7853efcce539d60d9ca1681b1b51f5c818fd8d1 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Wed, 17 Jan 2024 20:42:40 +0100 Subject: [PATCH 14/38] Change type UserActionObjectType::Context to UserActionObjectType::ContextView and UserActionObjectType::ContextDir --- .../models/context_tree_model.h | 6 ++++-- .../gui/user_action/user_action_object.h | 3 ++- .../context_manager_widget.cpp | 8 ++++---- .../models/context_tree_model.cpp | 4 ++-- .../graph_widget/contexts/graph_context.cpp | 4 ++-- .../src/graph_widget/graph_graphics_view.cpp | 20 +++++++++---------- plugins/gui/src/graph_widget/graph_widget.cpp | 4 ++-- plugins/gui/src/gui_api/gui_api.cpp | 10 +++++----- .../gui/src/module_widget/module_widget.cpp | 4 ++-- .../gui/src/netlist_relay/netlist_relay.cpp | 2 +- .../tree_navigation/selection_tree_view.cpp | 2 +- .../action_add_items_to_object.cpp | 2 +- .../src/user_action/action_create_object.cpp | 16 +++++++++++++-- .../src/user_action/action_delete_object.cpp | 2 +- .../src/user_action/action_fold_module.cpp | 4 ++-- .../action_remove_items_from_object.cpp | 2 +- .../src/user_action/action_rename_object.cpp | 2 +- .../src/user_action/action_unfold_module.cpp | 2 +- 18 files changed, 56 insertions(+), 41 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h index cd0a13fe244..34d52f4d624 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h @@ -39,9 +39,12 @@ namespace hal private: u32 mId; QString mName; + u32 mMinDirectoryId; public: - ContextDirectory(u32 id, QString name):mId(id), mName(name){} + ContextDirectory(QString name):mName(name), mMinDirectoryId(std::numeric_limits::max()){ + mId = --mMinDirectoryId; + } QString getName() { return mName; } }; @@ -163,6 +166,5 @@ namespace hal ContextTreeItem *mCurrentDirectory; std::map mContextMap; QVector mContextList; - u32 mMinDirectoryId; }; } // namespace hal diff --git a/plugins/gui/include/gui/user_action/user_action_object.h b/plugins/gui/include/gui/user_action/user_action_object.h index 572e608de2f..a3de7b57012 100644 --- a/plugins/gui/include/gui/user_action/user_action_object.h +++ b/plugins/gui/include/gui/user_action/user_action_object.h @@ -53,7 +53,8 @@ namespace hal Net, Grouping, Netlist, - Context, + ContextView, + ContextDir, Pin, PinGroup, MaxObjectType diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index a0b60fe6bc4..6ff9e180959 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -131,7 +131,7 @@ namespace hal { UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); - act->addAction(new ActionCreateObject(UserActionObjectType::Context, + act->addAction(new ActionCreateObject(UserActionObjectType::ContextView, QString::fromStdString(gNetlist->get_top_module()->get_name()))); act->addAction(new ActionAddItemsToObject({gNetlist->get_top_module()->get_id()}, {})); act->exec(); @@ -205,7 +205,7 @@ namespace hal if (ipd.exec() == QDialog::Accepted) { ActionRenameObject* act = new ActionRenameObject(ipd.textValue()); - act->setObject(UserActionObject(clicked_context->id(),UserActionObjectType::Context)); + act->setObject(UserActionObject(clicked_context->id(),UserActionObjectType::ContextView)); act->exec(); clicked_context->setExclusiveModuleId(0, false); } @@ -219,7 +219,7 @@ namespace hal UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); - act->addAction(new ActionCreateObject(UserActionObjectType::Context,clicked_context->name() + " (Copy)")); + act->addAction(new ActionCreateObject(UserActionObjectType::ContextView,clicked_context->name() + " (Copy)")); act->addAction(new ActionAddItemsToObject(clicked_context->modules(),clicked_context->gates())); act->exec(); } @@ -234,7 +234,7 @@ namespace hal if (!clicked_context) return; ActionDeleteObject* act = new ActionDeleteObject; - act->setObject(UserActionObject(clicked_context->id(),UserActionObjectType::Context)); + act->setObject(UserActionObject(clicked_context->id(),UserActionObjectType::ContextView)); act->exec(); } diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index fa11aceadec..47cfb5a041f 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -99,7 +99,7 @@ namespace hal return mContext != nullptr; } - ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr), mMinDirectoryId(std::numeric_limits::max()) + ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr) { setHeaderLabels(QStringList() << "View Name" << "Timestamp"); @@ -145,7 +145,7 @@ namespace hal void ContextTreeModel::addDirectory(QString name, BaseTreeItem *parent) { - ContextDirectory* directory = new ContextDirectory(--mMinDirectoryId, name); + ContextDirectory* directory = new ContextDirectory(name); ContextTreeItem* item = new ContextTreeItem(directory); diff --git a/plugins/gui/src/graph_widget/contexts/graph_context.cpp b/plugins/gui/src/graph_widget/contexts/graph_context.cpp index 17853eb8004..bb7b3d2c01d 100644 --- a/plugins/gui/src/graph_widget/contexts/graph_context.cpp +++ b/plugins/gui/src/graph_widget/contexts/graph_context.cpp @@ -712,7 +712,7 @@ namespace hal { QString name = QString::fromStdString(m->get_name()) + " (ID: " + QString::number(m->get_id()) + ")"; ActionRenameObject* act = new ActionRenameObject(name); - act->setObject(UserActionObject(this->id(), UserActionObjectType::Context)); + act->setObject(UserActionObject(this->id(), UserActionObjectType::ContextView)); act->exec(); } Q_EMIT(dataChanged()); @@ -945,7 +945,7 @@ namespace hal if (!found) { ActionRenameObject* act = new ActionRenameObject(new_name); - act->setObject(UserActionObject(this->id(),UserActionObjectType::Context)); + act->setObject(UserActionObject(this->id(),UserActionObjectType::ContextView)); act->exec(); break; } diff --git a/plugins/gui/src/graph_widget/graph_graphics_view.cpp b/plugins/gui/src/graph_widget/graph_graphics_view.cpp index f366d96afea..069fe6bbed7 100644 --- a/plugins/gui/src/graph_widget/graph_graphics_view.cpp +++ b/plugins/gui/src/graph_widget/graph_graphics_view.cpp @@ -104,7 +104,7 @@ namespace hal ActionRemoveItemsFromObject* act = new ActionRemoveItemsFromObject(gSelectionRelay->selectedModules(), gSelectionRelay->selectedGates()); - act->setObject(UserActionObject(ctx->id(),UserActionObjectType::Context)); + act->setObject(UserActionObject(ctx->id(),UserActionObjectType::ContextView)); // delete context/view if nothing left to show QSet remainingMods = ctx->modules() - gSelectionRelay->selectedModules(); @@ -144,7 +144,7 @@ namespace hal UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); QString name = QString::fromStdString(gNetlist->get_module_by_id(module_id)->get_name()) + " (ID: " + QString::number(module_id) + ")"; - act->addAction(new ActionCreateObject(UserActionObjectType::Context, name)); + act->addAction(new ActionCreateObject(UserActionObjectType::ContextView, name)); act->addAction(new ActionAddItemsToObject(selected_modules, selected_gates)); act->exec(); GraphContext* context = gGraphContextManager->getContextById(act->object().id()); @@ -157,7 +157,7 @@ namespace hal QString name = gGraphContextManager->nextViewName("Isolated View"); UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); - act->addAction(new ActionCreateObject(UserActionObjectType::Context, name)); + act->addAction(new ActionCreateObject(UserActionObjectType::ContextView, name)); act->addAction(new ActionAddItemsToObject(selected_modules, selected_gates)); act->exec(); GraphContext* context = gGraphContextManager->getContextById(act->object().id()); @@ -1065,7 +1065,7 @@ namespace hal QSet module_to_add; module_to_add.insert(module_dialog.selectedId()); ActionAddItemsToObject* act = new ActionAddItemsToObject(module_to_add, {}); - act->setObject(UserActionObject(context->id(), UserActionObjectType::Context)); + act->setObject(UserActionObject(context->id(), UserActionObjectType::ContextView)); act->exec(); } } @@ -1184,7 +1184,7 @@ namespace hal QSet gate_to_add; gate_to_add.insert(gate_dialog.selectedId()); ActionAddItemsToObject* act = new ActionAddItemsToObject({}, gate_to_add); - act->setObject(UserActionObject(context->id(), UserActionObjectType::Context)); + act->setObject(UserActionObject(context->id(), UserActionObjectType::ContextView)); act->exec(); } } @@ -1294,7 +1294,7 @@ namespace hal } ActionAddItemsToObject* act = new ActionAddItemsToObject({}, gatsNew); - act->setObject(UserActionObject(mGraphWidget->getContext()->id(),UserActionObjectType::Context)); + act->setObject(UserActionObject(mGraphWidget->getContext()->id(),UserActionObjectType::ContextView)); act->setPlacementHint(plc); act->exec(); } @@ -1312,7 +1312,7 @@ namespace hal gatsNew.insert(g->get_id()); } ActionAddItemsToObject* act = new ActionAddItemsToObject({}, gatsNew); - act->setObject(UserActionObject(mGraphWidget->getContext()->id(),UserActionObjectType::Context)); + act->setObject(UserActionObject(mGraphWidget->getContext()->id(),UserActionObjectType::ContextView)); act->exec(); } @@ -1407,7 +1407,7 @@ namespace hal } ActionAddItemsToObject* act = new ActionAddItemsToObject({},gats); - act->setObject(UserActionObject(mGraphWidget->getContext()->id(),UserActionObjectType::Context)); + act->setObject(UserActionObject(mGraphWidget->getContext()->id(),UserActionObjectType::ContextView)); act->setPlacementHint(plc); act->exec(); } @@ -1569,7 +1569,7 @@ namespace hal gates = context->getLayouter()->boxes().filterNotInView(gates); ActionAddItemsToObject* act = new ActionAddItemsToObject({},gates); - act->setObject(UserActionObject(context->id(),UserActionObjectType::Context)); + act->setObject(UserActionObject(context->id(),UserActionObjectType::ContextView)); if (gSelectionRelay->numberSelectedNodes()==1) { Node origin = (gSelectionRelay->numberSelectedModules()==1) @@ -1638,7 +1638,7 @@ namespace hal gates = context->getLayouter()->boxes().filterNotInView(gates); ActionAddItemsToObject* act = new ActionAddItemsToObject({},gates); - act->setObject(UserActionObject(context->id(),UserActionObjectType::Context)); + act->setObject(UserActionObject(context->id(),UserActionObjectType::ContextView)); if (gSelectionRelay->numberSelectedNodes()==1) { Node origin = (gSelectionRelay->numberSelectedModules()==1) diff --git a/plugins/gui/src/graph_widget/graph_widget.cpp b/plugins/gui/src/graph_widget/graph_widget.cpp index d42ce96eeaa..7d8d6a8ffc7 100644 --- a/plugins/gui/src/graph_widget/graph_widget.cpp +++ b/plugins/gui/src/graph_widget/graph_widget.cpp @@ -417,14 +417,14 @@ namespace hal if (!remove_modules.isEmpty() || !remove_gates.isEmpty()) { ActionRemoveItemsFromObject* act = new ActionRemoveItemsFromObject(remove_modules, remove_gates); - act->setObject(UserActionObject(mContext->id(), UserActionObjectType::Context)); + act->setObject(UserActionObject(mContext->id(), UserActionObjectType::ContextView)); act->exec(); } if (!nonvisible_modules.isEmpty() || !nonvisible_gates.isEmpty()) { ActionAddItemsToObject* act = new ActionAddItemsToObject(nonvisible_modules, nonvisible_gates); act->setPlacementHint(PlacementHint(placementMode, origin)); - act->setObject(UserActionObject(mContext->id(), UserActionObjectType::Context)); + act->setObject(UserActionObject(mContext->id(), UserActionObjectType::ContextView)); act->exec(); } diff --git a/plugins/gui/src/gui_api/gui_api.cpp b/plugins/gui/src/gui_api/gui_api.cpp index b2707dffe9d..c7d8016387d 100644 --- a/plugins/gui/src/gui_api/gui_api.cpp +++ b/plugins/gui/src/gui_api/gui_api.cpp @@ -503,7 +503,7 @@ namespace hal UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); - act->addAction(new ActionCreateObject(UserActionObjectType::Context, name)); + act->addAction(new ActionCreateObject(UserActionObjectType::ContextView, name)); act->addAction(new ActionAddItemsToObject(moduleIds, gateIds)); UserActionManager::instance()->executeActionBlockThread(act); @@ -524,7 +524,7 @@ namespace hal } ActionDeleteObject* act = new ActionDeleteObject(); - act->setObject(UserActionObject(id, UserActionObjectType::Context)); + act->setObject(UserActionObject(id, UserActionObjectType::ContextView)); UserActionManager::instance()->executeActionBlockThread(act); return true; } @@ -564,7 +564,7 @@ namespace hal QSet gateIds = pair.gateIds; ActionAddItemsToObject* act = new ActionAddItemsToObject(moduleIds,gateIds); - act->setObject(UserActionObject(id,UserActionObjectType::Context)); + act->setObject(UserActionObject(id,UserActionObjectType::ContextView)); UserActionManager::instance()->executeActionBlockThread(act); return true; } @@ -601,7 +601,7 @@ namespace hal gateIds.insert(gate->get_id()); ActionRemoveItemsFromObject* act = new ActionRemoveItemsFromObject(moduleIds,gateIds); - act->setObject(UserActionObject(id,UserActionObjectType::Context)); + act->setObject(UserActionObject(id,UserActionObjectType::ContextView)); UserActionManager::instance()->executeActionBlockThread(act); return true; } @@ -620,7 +620,7 @@ namespace hal //get context matching id and rename it ActionRenameObject* act = new ActionRenameObject(QString::fromStdString(name)); - act->setObject(UserActionObject(id,UserActionObjectType::Context)); + act->setObject(UserActionObject(id,UserActionObjectType::ContextView)); UserActionManager::instance()->executeActionBlockThread(act); return true; } diff --git a/plugins/gui/src/module_widget/module_widget.cpp b/plugins/gui/src/module_widget/module_widget.cpp index b10a12eb9be..21443463e2e 100644 --- a/plugins/gui/src/module_widget/module_widget.cpp +++ b/plugins/gui/src/module_widget/module_widget.cpp @@ -493,7 +493,7 @@ namespace hal UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); - act->addAction(new ActionCreateObject(UserActionObjectType::Context, name)); + act->addAction(new ActionCreateObject(UserActionObjectType::ContextView, name)); act->addAction(new ActionAddItemsToObject(moduleId, gateId)); act->exec(); } @@ -547,7 +547,7 @@ namespace hal UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); QString name = QString::fromStdString(module->get_name()) + " (ID: " + QString::number(moduleId) + ")"; - act->addAction(new ActionCreateObject(UserActionObjectType::Context, name)); + act->addAction(new ActionCreateObject(UserActionObjectType::ContextView, name)); act->addAction(new ActionAddItemsToObject({module->get_id()}, {})); if (unfold) act->addAction(new ActionUnfoldModule(module->get_id())); act->exec(); diff --git a/plugins/gui/src/netlist_relay/netlist_relay.cpp b/plugins/gui/src/netlist_relay/netlist_relay.cpp index 1132ffc8db2..7eb4eac4309 100644 --- a/plugins/gui/src/netlist_relay/netlist_relay.cpp +++ b/plugins/gui/src/netlist_relay/netlist_relay.cpp @@ -189,7 +189,7 @@ namespace hal // module exclusively connected to context, so delete context too UserActionCompound* compnd = new UserActionCompound; ActionDeleteObject* delCtx = new ActionDeleteObject; - delCtx->setObject(UserActionObject(ctx->id(), UserActionObjectType::Context)); + delCtx->setObject(UserActionObject(ctx->id(), UserActionObjectType::ContextView)); compnd->addAction(delCtx); compnd->addAction(delMod); compnd->exec(); diff --git a/plugins/gui/src/selection_details_widget/tree_navigation/selection_tree_view.cpp b/plugins/gui/src/selection_details_widget/tree_navigation/selection_tree_view.cpp index 5a6daba7c14..0b56dcf3037 100644 --- a/plugins/gui/src/selection_details_widget/tree_navigation/selection_tree_view.cpp +++ b/plugins/gui/src/selection_details_widget/tree_navigation/selection_tree_view.cpp @@ -228,7 +228,7 @@ namespace hal UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); - act->addAction(new ActionCreateObject(UserActionObjectType::Context, name)); + act->addAction(new ActionCreateObject(UserActionObjectType::ContextView, name)); act->addAction(new ActionAddItemsToObject(moduleId, gateId)); act->exec(); if (nd.type() == Node::Module) diff --git a/plugins/gui/src/user_action/action_add_items_to_object.cpp b/plugins/gui/src/user_action/action_add_items_to_object.cpp index 44b87bba1fe..5e95c102618 100644 --- a/plugins/gui/src/user_action/action_add_items_to_object.cpp +++ b/plugins/gui/src/user_action/action_add_items_to_object.cpp @@ -148,7 +148,7 @@ namespace hal else return false; break; - case UserActionObjectType::Context: + case UserActionObjectType::ContextView: ctx = gGraphContextManager->getContextById(mObject.id()); if (ctx) { diff --git a/plugins/gui/src/user_action/action_create_object.cpp b/plugins/gui/src/user_action/action_create_object.cpp index 2a73b467ae0..682577cbd50 100644 --- a/plugins/gui/src/user_action/action_create_object.cpp +++ b/plugins/gui/src/user_action/action_create_object.cpp @@ -117,14 +117,26 @@ namespace hal standardUndo = true; } break; - case UserActionObjectType::Context: + case UserActionObjectType::ContextView: { QString contextName = mObjectName.isEmpty() ? gGraphContextManager->nextDefaultName() : mObjectName; GraphContext* ctx = gGraphContextManager->createNewContext(contextName); if (mObject.id() > 0) gGraphContextManager->setContextId(ctx,mObject.id()); - setObject(UserActionObject(ctx->id(),UserActionObjectType::Context)); + setObject(UserActionObject(ctx->id(),UserActionObjectType::ContextView)); + standardUndo = true; + } + break; + case UserActionObjectType::ContextDir: + { + QString contextName = mObjectName.isEmpty() + ? gGraphContextManager->nextDefaultName() + : mObjectName; + + //ContextDirectory* directory = new ContextDirectory(--mMinDirectoryId, name); + + //setObject(UserActionObject(ctx->id(),UserActionObjectType::ContextDir)); standardUndo = true; } break; diff --git a/plugins/gui/src/user_action/action_delete_object.cpp b/plugins/gui/src/user_action/action_delete_object.cpp index c1ddee64cb1..22b4b1ae115 100644 --- a/plugins/gui/src/user_action/action_delete_object.cpp +++ b/plugins/gui/src/user_action/action_delete_object.cpp @@ -135,7 +135,7 @@ namespace hal } } break; - case UserActionObjectType::Context: + case UserActionObjectType::ContextView: ctx = gGraphContextManager->getContextById(mObject.id()); if (ctx) { diff --git a/plugins/gui/src/user_action/action_fold_module.cpp b/plugins/gui/src/user_action/action_fold_module.cpp index c20ea6bc8b0..c3e739e3d2c 100644 --- a/plugins/gui/src/user_action/action_fold_module.cpp +++ b/plugins/gui/src/user_action/action_fold_module.cpp @@ -74,11 +74,11 @@ namespace hal } ActionRemoveItemsFromObject* actr = new ActionRemoveItemsFromObject(mods,gats); - actr->setObject(UserActionObject(ctx->id(),UserActionObjectType::Context)); + actr->setObject(UserActionObject(ctx->id(),UserActionObjectType::ContextView)); addAction(actr); ActionAddItemsToObject* acta = new ActionAddItemsToObject({mObject.id()}); - acta->setObject(UserActionObject(ctx->id(),UserActionObjectType::Context)); + acta->setObject(UserActionObject(ctx->id(),UserActionObjectType::ContextView)); PlacementHint plc(PlacementHint::GridPosition); plc.addGridPosition(moduleToFold,polePosition); acta->setPlacementHint(plc); diff --git a/plugins/gui/src/user_action/action_remove_items_from_object.cpp b/plugins/gui/src/user_action/action_remove_items_from_object.cpp index 00719d3bdc0..a237065a053 100644 --- a/plugins/gui/src/user_action/action_remove_items_from_object.cpp +++ b/plugins/gui/src/user_action/action_remove_items_from_object.cpp @@ -74,7 +74,7 @@ namespace hal Grouping* grp; switch (mObject.type()) { - case UserActionObjectType::Context: + case UserActionObjectType::ContextView: ctx = gGraphContextManager->getContextById(mObject.id()); if (ctx) { diff --git a/plugins/gui/src/user_action/action_rename_object.cpp b/plugins/gui/src/user_action/action_rename_object.cpp index d5f6d3e35cb..5d18f6337d0 100644 --- a/plugins/gui/src/user_action/action_rename_object.cpp +++ b/plugins/gui/src/user_action/action_rename_object.cpp @@ -92,7 +92,7 @@ namespace hal case UserActionObjectType::Grouping: oldName = gContentManager->getGroupingManagerWidget()->getModel()->renameGrouping(mObject.id(), mNewName); break; - case UserActionObjectType::Context: + case UserActionObjectType::ContextView: ctx = gGraphContextManager->getContextById(mObject.id()); if (ctx) { diff --git a/plugins/gui/src/user_action/action_unfold_module.cpp b/plugins/gui/src/user_action/action_unfold_module.cpp index 27aa56049ec..9f8938d43c0 100644 --- a/plugins/gui/src/user_action/action_unfold_module.cpp +++ b/plugins/gui/src/user_action/action_unfold_module.cpp @@ -39,7 +39,7 @@ namespace hal case UserActionObjectType::Module: UserAction::setObject(obj); break; - case UserActionObjectType::Context: + case UserActionObjectType::ContextView: mContextId = obj.id(); break; default: From ca90c70e21f3881386592542a41e9f4fb22c39a1 Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 22 Jan 2024 17:57:25 +0100 Subject: [PATCH 15/38] Added parent-ID when creating new views or directories via UserAction --- .../models/context_tree_model.h | 11 ++- .../gui/graph_widget/graph_context_manager.h | 8 +- .../models/context_tree_model.cpp | 47 +++++++++-- .../graph_widget/graph_context_manager.cpp | 81 ++++++++++--------- .../src/user_action/action_create_object.cpp | 15 ++-- 5 files changed, 105 insertions(+), 57 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h index 34d52f4d624..09e53b5638f 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h @@ -45,8 +45,9 @@ namespace hal ContextDirectory(QString name):mName(name), mMinDirectoryId(std::numeric_limits::max()){ mId = --mMinDirectoryId; } - QString getName() { return mName; } - + QString name() const { return mName; } + u32 id() const { return mId; } + void setId(u32 id_) { mId = id_; } }; class ContextTreeItem : public BaseTreeItem @@ -66,6 +67,7 @@ namespace hal int row() const; bool isDirectory() const; bool isContext() const; + u32 getId() const; GraphContext* context() const; }; @@ -103,7 +105,9 @@ namespace hal * @param name - The name to the directory. * @param parent - The Parent of the directory. */ - void addDirectory(QString name, BaseTreeItem* parent = nullptr); + ContextDirectory* addDirectory(QString name, BaseTreeItem* parent = nullptr); + + BaseTreeItem* getParentDirectory(u32 directoryId) const; /** * Adds a given GraphContext to the model. @@ -163,6 +167,7 @@ namespace hal private: + BaseTreeItem* getParentDirectoryInternal(BaseTreeItem* parentItem, u32 directoryId) const; ContextTreeItem *mCurrentDirectory; std::map mContextMap; QVector mContextList; diff --git a/plugins/gui/include/gui/graph_widget/graph_context_manager.h b/plugins/gui/include/gui/graph_widget/graph_context_manager.h index e479ecaf975..0d2f60397b5 100644 --- a/plugins/gui/include/gui/graph_widget/graph_context_manager.h +++ b/plugins/gui/include/gui/graph_widget/graph_context_manager.h @@ -41,6 +41,7 @@ namespace hal class GraphLayouter; class GraphShader; class GraphContext; + class ContextDirectory; class ContextTreeModel; class SettingsItemCheckbox; @@ -72,7 +73,10 @@ namespace hal * @param name - The name of the new context. Names don't have to be unique. * @returns the created GraphContext */ - GraphContext* createNewContext(const QString& name); + GraphContext* createNewContext(const QString& name, u32 parentId = 0); + + + ContextDirectory* createNewDirectory(const QString &name, u32 parentId = 0); /** * Renames a GraphContext.
@@ -390,7 +394,7 @@ namespace hal private: // QVector mGraphContexts; - ContextTreeModel* mContextTableModel; + ContextTreeModel* mContextTreeModel; u32 mMaxContextId; void dump(const QString& title, u32 mid, u32 xid) const; SettingsItemCheckbox* mSettingDebugGrid; diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index 47cfb5a041f..952300ce44f 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -24,6 +24,13 @@ namespace hal { } + u32 ContextTreeItem::getId() const + { + if (mDirectory) return mDirectory->id(); + if (mContext) return mContext->id(); + return 0; + } + QVariant ContextTreeItem::getData(int column) const { if(isDirectory()) @@ -32,7 +39,7 @@ namespace hal { case 0: { - return mDirectory->getName(); + return mDirectory->name(); } case 1: { @@ -143,7 +150,29 @@ namespace hal return QVariant(); } - void ContextTreeModel::addDirectory(QString name, BaseTreeItem *parent) + BaseTreeItem* ContextTreeModel::getParentDirectory(u32 directoryId) const + { + return getParentDirectoryInternal(mRootItem, directoryId); + } + + BaseTreeItem* ContextTreeModel::getParentDirectoryInternal(BaseTreeItem *parentItem, u32 directoryId) const + { + for (BaseTreeItem* childItem : parentItem->getChildren()) + { + ContextTreeItem* ctxItem = static_cast(childItem); + if (ctxItem->isDirectory()) + { + if (ctxItem->getId() == directoryId) + return ctxItem; + BaseTreeItem* bti = getParentDirectoryInternal(childItem, directoryId); + if (bti) + return bti; + } + } + return nullptr; + } + + ContextDirectory* ContextTreeModel::addDirectory(QString name, BaseTreeItem *parent) { ContextDirectory* directory = new ContextDirectory(name); @@ -168,6 +197,7 @@ namespace hal Q_EMIT directoryCreatedSignal(item); + return directory; } void ContextTreeModel::clear() @@ -184,19 +214,20 @@ namespace hal { ContextTreeItem* item = new ContextTreeItem(context); + BaseTreeItem* finalParent; if (parent) - item->setParent(parent); + finalParent = parent; else if(mCurrentDirectory) - item->setParent(mCurrentDirectory); + finalParent = mCurrentDirectory; else - item->setParent(mRootItem); + finalParent = mRootItem; - QModelIndex index = getIndexFromItem(item->getParent()); + QModelIndex index = getIndexFromItem(finalParent); - int row = item->getParent()->getChildCount(); + int row = finalParent->getChildCount(); beginInsertRows(index, row, row); - item->getParent()->appendChild(item); + finalParent->appendChild(item); endInsertRows(); mContextMap.insert({context, item}); diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index 81a5295b446..b3fb4328eab 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -30,7 +30,7 @@ namespace hal "Appearance:Graph View", "If set net grouping colors are also applied to input and output pins of gates"); - GraphContextManager::GraphContextManager() : mContextTableModel(new ContextTreeModel()), mMaxContextId(0) + GraphContextManager::GraphContextManager() : mContextTreeModel(new ContextTreeModel()), mMaxContextId(0) { mSettingDebugGrid = new SettingsItemCheckbox("GUI Debug Grid", "debug/grid", @@ -49,7 +49,14 @@ namespace hal mSettingLayoutBoxes = new SettingsItemCheckbox("Optimize Box Layout", "graph_view/layout_boxes", true, "Graph View", "If disabled faster randomized placement."); } - GraphContext* GraphContextManager::createNewContext(const QString& name) + ContextDirectory* GraphContextManager::createNewDirectory(const QString& name, u32 parentId) + { + ContextDirectory* contextDir = mContextTreeModel->addDirectory(name, mContextTreeModel->getParentDirectory(parentId)); + return contextDir; + } + + + GraphContext* GraphContextManager::createNewContext(const QString& name, u32 parentId) { GraphContext* context = new GraphContext(++mMaxContextId, name); context->setLayouter(getDefaultLayouter(context)); @@ -58,7 +65,7 @@ namespace hal context->scene()->setDebugGridEnabled(mSettingDebugGrid->value().toBool()); connect(mSettingDebugGrid, &SettingsItemCheckbox::boolChanged, context->scene(), &GraphicsScene::setDebugGridEnabled); - mContextTableModel->addContext(context); + mContextTreeModel->addContext(context, mContextTreeModel->getParentDirectory(parentId)); Q_EMIT contextCreated(context); @@ -87,19 +94,19 @@ namespace hal { Q_EMIT deletingContext(ctx); - mContextTableModel->removeContext(ctx); + mContextTreeModel->removeContext(ctx); delete ctx; } QVector GraphContextManager::getContexts() const { - return mContextTableModel->list(); + return mContextTreeModel->list(); } GraphContext* GraphContextManager::getContextById(u32 id) const { - for (GraphContext* ctx : mContextTableModel->list()) + for (GraphContext* ctx : mContextTreeModel->list()) { if (ctx->id() == id) return ctx; @@ -109,7 +116,7 @@ namespace hal GraphContext* GraphContextManager::getCleanContext(const QString& name) const { - for (GraphContext* ctx : mContextTableModel->list()) + for (GraphContext* ctx : mContextTreeModel->list()) { if (ctx->name() == name && !ctx->isDirty()) return ctx; @@ -119,7 +126,7 @@ namespace hal GraphContext* GraphContextManager::getContextByExclusiveModuleId(u32 module_id) const { - for (GraphContext* ctx : mContextTableModel->list()) + for (GraphContext* ctx : mContextTreeModel->list()) { if (ctx->getExclusiveModuleId() == module_id) return ctx; @@ -140,7 +147,7 @@ namespace hal bool GraphContextManager::contextWithNameExists(const QString& name) const { - for (GraphContext* ctx : mContextTableModel->list()) + for (GraphContext* ctx : mContextTreeModel->list()) { if (ctx->name() == name) { @@ -152,7 +159,7 @@ namespace hal void GraphContextManager::handleModuleCreated(Module* m) const { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) if (context->getSpecialUpdate()) { context->add({m->get_id()}, {}); @@ -162,7 +169,7 @@ namespace hal void GraphContextManager::handleModuleRemoved(Module* m) { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { if (context->getExclusiveModuleId() == m->get_id()) { @@ -181,14 +188,14 @@ namespace hal void GraphContextManager::handleModuleNameChanged(Module* m) const { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) if (context->modules().contains(m->get_id())) context->scheduleSceneUpdate(); } void GraphContextManager::handleModuleTypeChanged(Module* m) const { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) if (context->modules().contains(m->get_id())) context->scheduleSceneUpdate(); } @@ -199,7 +206,7 @@ namespace hal QSet gateIDs; for (auto g : gates) gateIDs.insert(g->get_id()); - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) if (context->modules().contains(m->get_id()) // contains module || context->gates().intersects(gateIDs)) // contains gate from module context->scheduleSceneUpdate(); @@ -220,7 +227,7 @@ namespace hal current_module = current_module->get_parent_module(); } while (current_module); - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { if (context->isShowingModule(m->get_id(), {added_module}, {}, {}, {}) && !context->isShowingModule(added_module, {}, {}, {}, {})) context->add({added_module}, {}); @@ -254,7 +261,7 @@ namespace hal // and collides with handleModuleRemoved // dump("ModuleSubmoduleRemoved", m->get_id(), removed_module); - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { if (context->isScheduledRemove(Node(removed_module,Node::Module)) || context->isShowingModule(m->get_id(), {}, {}, {removed_module}, {})) @@ -280,7 +287,7 @@ namespace hal current_module = current_module->get_parent_module(); } while (current_module); - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { if (context->isShowingModule(m->get_id(), {}, {inserted_gate}, {}, {})) context->add({}, {inserted_gate}); @@ -304,7 +311,7 @@ namespace hal void GraphContextManager::handleModuleGateRemoved(Module* m, const u32 removed_gate) { // dump("ModuleGateRemoved", m->get_id(), removed_gate); - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { if (context->isScheduledRemove(Node(removed_gate,Node::Gate)) || context->isShowingModule(m->get_id(), {}, {}, {}, {removed_gate})) @@ -351,7 +358,7 @@ namespace hal xout << " " << g->get_id(); xout << "\n"; - for (GraphContext* ctx : mContextTableModel->list()) + for (GraphContext* ctx : mContextTreeModel->list()) { xout << "ctx " << ctx->id() << ":"; for (hal::Node nd : ctx->getLayouter()->positionToNodeMap().values()) @@ -365,7 +372,7 @@ namespace hal void GraphContextManager::handleModulePortsChanged(Module* m) { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) if (context->modules().contains(m->get_id())) { context->updateNets(); @@ -375,14 +382,14 @@ namespace hal void GraphContextManager::handleGateRemoved(Gate* g) const { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) if (context->gates().contains(g->get_id())) context->remove({}, {g->get_id()}); } void GraphContextManager::handleGateNameChanged(Gate* g) const { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) if (context->gates().contains(g->get_id())) context->scheduleSceneUpdate(); } @@ -397,21 +404,21 @@ namespace hal void GraphContextManager::handleNetRemoved(Net* n) const { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) if (context->nets().contains(n->get_id())) context->scheduleSceneUpdate(); } void GraphContextManager::handleNetNameChanged(Net* n) const { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) if (context->nets().contains(n->get_id())) context->scheduleSceneUpdate(); } void GraphContextManager::handleNetSourceAdded(Net* n, const u32 src_gate_id) const { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { if (context->nets().contains(n->get_id()) || context->gates().contains(src_gate_id)) { @@ -426,7 +433,7 @@ namespace hal { UNUSED(src_gate_id); - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { if (context->nets().contains(n->get_id())) { @@ -439,7 +446,7 @@ namespace hal void GraphContextManager::handleNetDestinationAdded(Net* n, const u32 dst_gate_id) const { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { if (context->nets().contains(n->get_id()) || context->gates().contains(dst_gate_id)) { @@ -454,7 +461,7 @@ namespace hal { UNUSED(dst_gate_id); - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { if (context->nets().contains(n->get_id())) { @@ -467,7 +474,7 @@ namespace hal void GraphContextManager::handleMarkedGlobalInput(u32 mNetId) { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { if (context->nets().contains(mNetId) || context->isShowingNetDestination(mNetId)) { @@ -479,7 +486,7 @@ namespace hal void GraphContextManager::handleMarkedGlobalOutput(u32 mNetId) { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { if (context->nets().contains(mNetId) || context->isShowingNetSource(mNetId)) { @@ -491,7 +498,7 @@ namespace hal void GraphContextManager::handleUnmarkedGlobalInput(u32 mNetId) { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) if (context->nets().contains(mNetId)) { context->applyChanges(); @@ -501,7 +508,7 @@ namespace hal void GraphContextManager::handleUnmarkedGlobalOutput(u32 mNetId) { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) if (context->nets().contains(mNetId)) { context->applyChanges(); @@ -530,15 +537,15 @@ namespace hal ContextTreeModel* GraphContextManager::getContextTableModel() const { - return mContextTableModel; + return mContextTreeModel; } void GraphContextManager::clear() { - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) delete context; - mContextTableModel->clear(); + mContextTreeModel->clear(); } GraphContext* GraphContextManager::restoreFromFile(const QString& filename) @@ -599,7 +606,7 @@ namespace hal continue; } - mContextTableModel->addContext(context); + mContextTreeModel->addContext(context); if (visibleFlag) Q_EMIT contextCreated(context); } @@ -627,7 +634,7 @@ namespace hal QJsonObject json; QJsonArray jsonViews; - for (GraphContext* context : mContextTableModel->list()) + for (GraphContext* context : mContextTreeModel->list()) { QJsonObject jsonView; context->writeToFile(jsonView); diff --git a/plugins/gui/src/user_action/action_create_object.cpp b/plugins/gui/src/user_action/action_create_object.cpp index 682577cbd50..13ea7597f5a 100644 --- a/plugins/gui/src/user_action/action_create_object.cpp +++ b/plugins/gui/src/user_action/action_create_object.cpp @@ -4,6 +4,7 @@ #include "hal_core/netlist/grouping.h" #include "gui/grouping/grouping_manager_widget.h" #include "gui/graph_widget/contexts/graph_context.h" +#include "gui/context_manager_widget/models/context_tree_model.h" namespace hal { @@ -122,21 +123,21 @@ namespace hal QString contextName = mObjectName.isEmpty() ? gGraphContextManager->nextDefaultName() : mObjectName; - GraphContext* ctx = gGraphContextManager->createNewContext(contextName); - if (mObject.id() > 0) gGraphContextManager->setContextId(ctx,mObject.id()); - setObject(UserActionObject(ctx->id(),UserActionObjectType::ContextView)); + GraphContext* ctxView = gGraphContextManager->createNewContext(contextName, mParentId); + if (mObject.id() > 0) gGraphContextManager->setContextId(ctxView,mObject.id()); + setObject(UserActionObject(ctxView->id(),UserActionObjectType::ContextView)); standardUndo = true; } break; case UserActionObjectType::ContextDir: { - QString contextName = mObjectName.isEmpty() + QString directoryName = mObjectName.isEmpty() ? gGraphContextManager->nextDefaultName() : mObjectName; - //ContextDirectory* directory = new ContextDirectory(--mMinDirectoryId, name); - - //setObject(UserActionObject(ctx->id(),UserActionObjectType::ContextDir)); + ContextDirectory* ctxDir = gGraphContextManager->createNewDirectory(directoryName, mParentId); + if (mObject.id() > 0) ctxDir->setId(mObject.id()); + setObject(UserActionObject(ctxDir->id(),UserActionObjectType::ContextDir)); standardUndo = true; } break; From a5f997d6266af6b7ea507ed2453c3d353b0cc3c6 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Sat, 27 Jan 2024 23:21:32 +0100 Subject: [PATCH 16/38] Add contextDir to action_delete_object; Change creation of directory to action_create_object --- .../context_manager_widget.h | 4 ++ .../models/context_tree_model.h | 12 +++++- .../gui/graph_widget/graph_context_manager.h | 11 ++++++ .../context_manager_widget.cpp | 39 ++++++++++++++++--- .../models/context_tree_model.cpp | 31 +++++++++++++-- .../graph_widget/graph_context_manager.cpp | 19 ++++++++- .../src/user_action/action_delete_object.cpp | 11 ++++++ 7 files changed, 113 insertions(+), 14 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index 79e7fc989e4..d0567cd8747 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -229,6 +229,8 @@ namespace hal QString mDeleteIconPath; QString mDeleteIconStyle; + QAction* mDeleteDirectoryAction; + QAction* mOpenAction; QString mOpenIconPath; QString mOpenIconStyle; @@ -245,6 +247,8 @@ namespace hal void handleRenameContextClicked(); void handleDuplicateContextClicked(); void handleDeleteContextClicked(); + void handleDeleteDirectoryClicked(); + void handleContextMenuRequest(const QPoint& point); void handleSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h index 09e53b5638f..61798f29d2d 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h @@ -69,6 +69,7 @@ namespace hal bool isContext() const; u32 getId() const; GraphContext* context() const; + ContextDirectory* directory() const; }; /** @@ -107,7 +108,7 @@ namespace hal */ ContextDirectory* addDirectory(QString name, BaseTreeItem* parent = nullptr); - BaseTreeItem* getParentDirectory(u32 directoryId) const; + BaseTreeItem* getDirectory(u32 directoryId) const; /** * Adds a given GraphContext to the model. @@ -124,6 +125,13 @@ namespace hal */ void removeContext(GraphContext* context); + /** + * Removes a given contextDirectory from the model. + * + * @param directory - The directory to remove. + */ + void removeDirectory(ContextDirectory* directory); + /** * Get the GraphContext from a given index. * @@ -167,7 +175,7 @@ namespace hal private: - BaseTreeItem* getParentDirectoryInternal(BaseTreeItem* parentItem, u32 directoryId) const; + BaseTreeItem* getDirectoryInternal(BaseTreeItem* parentItem, u32 directoryId) const; ContextTreeItem *mCurrentDirectory; std::map mContextMap; QVector mContextList; diff --git a/plugins/gui/include/gui/graph_widget/graph_context_manager.h b/plugins/gui/include/gui/graph_widget/graph_context_manager.h index 0d2f60397b5..438bdfbe0e2 100644 --- a/plugins/gui/include/gui/graph_widget/graph_context_manager.h +++ b/plugins/gui/include/gui/graph_widget/graph_context_manager.h @@ -95,6 +95,13 @@ namespace hal */ void deleteGraphContext(GraphContext* ctx); + /** + * Removes and deletes the given ContextDiretory. The passed pointer will be a nullptr afterwards.
+ * + * @param ctxDir - The ContextDirectory to delete. + */ + void deleteContextDirectory(ContextDirectory* ctxDir); + /** * Gets a list of all current GraphContext%s. * @@ -104,6 +111,9 @@ namespace hal GraphContext* getCleanContext(const QString& name) const; GraphContext* getContextById(u32 id) const; + + ContextDirectory* getDirectoryById(u32 id) const; + /** * Gets the context which is exclusively showing the module with the id module_id. * @@ -391,6 +401,7 @@ namespace hal */ void deletingContext(GraphContext* context); + private: // QVector mGraphContexts; diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index 6ff9e180959..a6a3bc90888 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -39,7 +39,7 @@ namespace hal { ContextManagerWidget::ContextManagerWidget(GraphTabWidget* tab_view, QWidget* parent) : ContentWidget("Views", parent), mSearchbar(new Searchbar(this)), mNewDirectoryAction(new QAction(this)), mNewViewAction(new QAction(this)), mRenameAction(new QAction(this)), mDuplicateAction(new QAction(this)), - mDeleteAction(new QAction(this)), mOpenAction(new QAction(this)) + mDeleteAction(new QAction(this)), mDeleteDirectoryAction(new QAction(this)), mOpenAction(new QAction(this)) { //needed to load the properties ensurePolished(); @@ -51,6 +51,7 @@ namespace hal mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDuplicateIconStyle, mDuplicateIconPath)); mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); + mDeleteDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath)); mOpenAction->setToolTip("Open"); @@ -59,6 +60,7 @@ namespace hal mRenameAction->setToolTip("Rename"); mDuplicateAction->setToolTip("Duplicate"); mDeleteAction->setToolTip("Delete"); + mDeleteDirectoryAction->setToolTip("Delete Directory"); mSearchAction->setToolTip("Search"); mOpenAction->setText("Open view"); @@ -67,6 +69,7 @@ namespace hal mRenameAction->setText("Rename view"); mDuplicateAction->setText("Duplicate view"); mDeleteAction->setText("Delete view"); + mDeleteDirectoryAction->setText("Delete directory"); mSearchAction->setText("Search"); //mOpenAction->setEnabled(false); @@ -104,6 +107,7 @@ namespace hal connect(mRenameAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameContextClicked); connect(mDuplicateAction, &QAction::triggered, this, &ContextManagerWidget::handleDuplicateContextClicked); connect(mDeleteAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteContextClicked); + connect(mDeleteDirectoryAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteDirectoryClicked); connect(mSearchAction, &QAction::triggered, this, &ContextManagerWidget::toggleSearchbar); connect(mContextTreeView, &QTreeView::customContextMenuRequested, this, &ContextManagerWidget::handleContextMenuRequest); @@ -144,9 +148,12 @@ namespace hal if (confirm && !newName.isEmpty()) { - mContextTreeModel->addDirectory(newName); - } - + UserActionCompound* act = new UserActionCompound; + act->setUseCreatedObject(); + act->addAction(new ActionCreateObject(UserActionObjectType::ContextDir, + QString::fromStdString(gNetlist->get_top_module()->get_name()))); + act->addAction(new ActionAddItemsToObject({gNetlist->get_top_module()->get_id()}, {})); + act->exec(); } } void ContextManagerWidget::handleOpenContextClicked() @@ -238,6 +245,20 @@ namespace hal act->exec(); } + void ContextManagerWidget::handleDeleteDirectoryClicked() + { + QModelIndex current = mContextTreeView->currentIndex(); + if (!current.isValid()) return; + + ContextDirectory* clicked_directory = getCurrentItem()->directory(); + + if (!clicked_directory) return; + + ActionDeleteObject* act = new ActionDeleteObject; + act->setObject(UserActionObject(clicked_directory->id(),UserActionObjectType::ContextDir)); + act->exec(); + } + void ContextManagerWidget::handleSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { Q_UNUSED(deselected); @@ -258,13 +279,14 @@ namespace hal context_menu.addAction(mNewDirectoryAction); GraphContext* clicked_context = getCurrentContext(); + ContextDirectory* clicked_directory = getCurrentItem()->directory(); - if (!clicked_context) { + if (!clicked_context && !clicked_directory) { context_menu.exec(mContextTreeView->viewport()->mapToGlobal(point)); return; } - if (clicked_index.isValid()) + if (clicked_index.isValid() && clicked_context) { context_menu.addAction(mOpenAction); context_menu.addAction(mDuplicateAction); @@ -272,6 +294,11 @@ namespace hal context_menu.addAction(mDeleteAction); } + if (clicked_index.isValid() && clicked_directory) + { + context_menu.addAction(mDeleteDirectoryAction); + } + context_menu.exec(mContextTreeView->viewport()->mapToGlobal(point)); } diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index 952300ce44f..05518cd6401 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -69,6 +69,11 @@ namespace hal return mContext; } + ContextDirectory *ContextTreeItem::directory() const + { + return mDirectory; + } + void ContextTreeItem::setData(QList data) { @@ -150,12 +155,12 @@ namespace hal return QVariant(); } - BaseTreeItem* ContextTreeModel::getParentDirectory(u32 directoryId) const + BaseTreeItem* ContextTreeModel::getDirectory(u32 directoryId) const { - return getParentDirectoryInternal(mRootItem, directoryId); + return getDirectoryInternal(mRootItem, directoryId); } - BaseTreeItem* ContextTreeModel::getParentDirectoryInternal(BaseTreeItem *parentItem, u32 directoryId) const + BaseTreeItem* ContextTreeModel::getDirectoryInternal(BaseTreeItem *parentItem, u32 directoryId) const { for (BaseTreeItem* childItem : parentItem->getChildren()) { @@ -164,7 +169,7 @@ namespace hal { if (ctxItem->getId() == directoryId) return ctxItem; - BaseTreeItem* bti = getParentDirectoryInternal(childItem, directoryId); + BaseTreeItem* bti = getDirectoryInternal(childItem, directoryId); if (bti) return bti; } @@ -260,6 +265,24 @@ namespace hal mContextMap.erase(it); } + void ContextTreeModel::removeDirectory(ContextDirectory *directory) + { + ContextTreeItem* item = static_cast(getDirectory(directory->id())); + ContextTreeItem* parent = static_cast(item->getParent()); + assert(item); + assert(parent); + + QModelIndex index = getIndexFromItem(parent); + + int row = item->row(); + + beginRemoveRows(index, row, row); + parent->removeChild(item); + endRemoveRows(); + + delete item; + } + QModelIndex ContextTreeModel::getIndexFromContext(GraphContext *context) const { return getIndexFromItem(mContextMap.find(context)->second); diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index b3fb4328eab..00bd0f63db4 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -51,7 +51,7 @@ namespace hal ContextDirectory* GraphContextManager::createNewDirectory(const QString& name, u32 parentId) { - ContextDirectory* contextDir = mContextTreeModel->addDirectory(name, mContextTreeModel->getParentDirectory(parentId)); + ContextDirectory* contextDir = mContextTreeModel->addDirectory(name, mContextTreeModel->getDirectory(parentId)); return contextDir; } @@ -65,7 +65,7 @@ namespace hal context->scene()->setDebugGridEnabled(mSettingDebugGrid->value().toBool()); connect(mSettingDebugGrid, &SettingsItemCheckbox::boolChanged, context->scene(), &GraphicsScene::setDebugGridEnabled); - mContextTreeModel->addContext(context, mContextTreeModel->getParentDirectory(parentId)); + mContextTreeModel->addContext(context, mContextTreeModel->getDirectory(parentId)); Q_EMIT contextCreated(context); @@ -99,6 +99,13 @@ namespace hal delete ctx; } + void GraphContextManager::deleteContextDirectory(ContextDirectory *ctxDir) + { + mContextTreeModel->removeDirectory(ctxDir); + + delete ctxDir; + } + QVector GraphContextManager::getContexts() const { return mContextTreeModel->list(); @@ -114,6 +121,14 @@ namespace hal return nullptr; } + ContextDirectory *GraphContextManager::getDirectoryById(u32 id) const + { + ContextDirectory * directory = static_cast(mContextTreeModel->getDirectory(id))->directory(); + if (directory) return directory; + + return nullptr; + } + GraphContext* GraphContextManager::getCleanContext(const QString& name) const { for (GraphContext* ctx : mContextTreeModel->list()) diff --git a/plugins/gui/src/user_action/action_delete_object.cpp b/plugins/gui/src/user_action/action_delete_object.cpp index 22b4b1ae115..2a796ad6147 100644 --- a/plugins/gui/src/user_action/action_delete_object.cpp +++ b/plugins/gui/src/user_action/action_delete_object.cpp @@ -37,6 +37,7 @@ namespace hal Gate* gat; Net* net; GraphContext* ctx; + ContextDirectory* ctxDir; LayoutLocker llock; @@ -145,6 +146,16 @@ namespace hal else return false; break; + case UserActionObjectType::ContextDir: + ctxDir = gGraphContextManager->getDirectoryById(mObject.id()); + if (ctxDir) + { + // TODO : Undo action + gGraphContextManager->deleteContextDirectory(ctxDir); + } + else + return false; + break; default: return false; } From a9e221f52eab5c39fd2747e0bef91501a6078347 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Fri, 2 Feb 2024 22:14:28 +0100 Subject: [PATCH 17/38] Fix directory naming; Fix chrash on directory deletion and then creation;WIP: Add renaming --- .../context_manager_widget.h | 7 +- .../models/context_tree_model.h | 2 + .../gui/graph_widget/graph_context_manager.h | 26 +++++++ .../context_manager_widget.cpp | 69 +++++++++++++------ .../models/context_tree_model.cpp | 7 +- .../graph_widget/graph_context_manager.cpp | 9 +++ .../src/user_action/action_rename_object.cpp | 15 ++++ 7 files changed, 110 insertions(+), 25 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index d0567cd8747..50dce2623b0 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -217,15 +217,17 @@ namespace hal QString mNewDirIconPath; QString mNewViewIconStyle; - QAction* mRenameAction; + QAction* mRenameViewAction; QString mRenameIconPath; QString mRenameIconStyle; + QAction* mRenameDirectoryAction; + QAction* mDuplicateAction; QString mDuplicateIconPath; QString mDuplicateIconStyle; - QAction* mDeleteAction; + QAction* mDeleteViewAction; QString mDeleteIconPath; QString mDeleteIconStyle; @@ -245,6 +247,7 @@ namespace hal void handleCreateContextClicked(); void handleCreateDirectoryClicked(); void handleRenameContextClicked(); + void handleRenameDirectoryClicked(); void handleDuplicateContextClicked(); void handleDeleteContextClicked(); void handleDeleteDirectoryClicked(); diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h index 61798f29d2d..ef7715c6e49 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h @@ -48,6 +48,8 @@ namespace hal QString name() const { return mName; } u32 id() const { return mId; } void setId(u32 id_) { mId = id_; } + void setName(QString name_) { mName = name_; } + }; class ContextTreeItem : public BaseTreeItem diff --git a/plugins/gui/include/gui/graph_widget/graph_context_manager.h b/plugins/gui/include/gui/graph_widget/graph_context_manager.h index 438bdfbe0e2..1acdf16d57f 100644 --- a/plugins/gui/include/gui/graph_widget/graph_context_manager.h +++ b/plugins/gui/include/gui/graph_widget/graph_context_manager.h @@ -87,6 +87,16 @@ namespace hal */ void renameGraphContextAction(GraphContext* ctx, const QString& newName); + /** + * Renames a contextDirectory.
+ * Emits the signal directoryRenamed. + * + * @param ctxDir - The contextDirectory to rename. Must not be a nullptr. + * @param newName - The new name of the directory + */ + void renameContextDirectoryAction(ContextDirectory* ctxDir, const QString& newName); + + /** * Removes and deletes the given GraphContext. The passed pointer will be a nullptr afterwards.
* Emits deletingContext before the deletion. @@ -401,6 +411,22 @@ namespace hal */ void deletingContext(GraphContext* context); + /** + * Q_SIGNAL that notifies about the renaming of a directory by the context manager. + * + * @param directory - The renamed directory + */ + void directoryRenamed(ContextDirectory* directory); + + /** + * Q_SIGNAL that notifies that a directory is about to be deleted. + * This signal is emitted before the directory is deleted. + * + * @param directory - The directory that is about to be deleted + */ + void deletingDirectory(ContextDirectory* directory); + + private: // QVector mGraphContexts; diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index a6a3bc90888..4b2f8308165 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -38,8 +38,8 @@ namespace hal { ContextManagerWidget::ContextManagerWidget(GraphTabWidget* tab_view, QWidget* parent) - : ContentWidget("Views", parent), mSearchbar(new Searchbar(this)), mNewDirectoryAction(new QAction(this)), mNewViewAction(new QAction(this)), mRenameAction(new QAction(this)), mDuplicateAction(new QAction(this)), - mDeleteAction(new QAction(this)), mDeleteDirectoryAction(new QAction(this)), mOpenAction(new QAction(this)) + : ContentWidget("Views", parent), mSearchbar(new Searchbar(this)), mNewDirectoryAction(new QAction(this)), mNewViewAction(new QAction(this)), mRenameViewAction(new QAction(this)), mRenameDirectoryAction(new QAction(this)), mDuplicateAction(new QAction(this)), + mDeleteViewAction(new QAction(this)), mDeleteDirectoryAction(new QAction(this)), mOpenAction(new QAction(this)) { //needed to load the properties ensurePolished(); @@ -48,27 +48,30 @@ namespace hal mOpenAction->setIcon(gui_utility::getStyledSvgIcon(mOpenIconStyle, mOpenIconPath)); mNewViewAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewViewIconPath)); mNewDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewDirIconPath)); - mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); + mRenameViewAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); + mRenameDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDuplicateIconStyle, mDuplicateIconPath)); - mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); + mDeleteViewAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); mDeleteDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath)); mOpenAction->setToolTip("Open"); mNewViewAction->setToolTip("New View"); mNewDirectoryAction->setToolTip("New Directory"); - mRenameAction->setToolTip("Rename"); + mRenameViewAction->setToolTip("Rename view"); + mRenameDirectoryAction->setToolTip("Rename directory"); mDuplicateAction->setToolTip("Duplicate"); - mDeleteAction->setToolTip("Delete"); + mDeleteViewAction->setToolTip("Delete"); mDeleteDirectoryAction->setToolTip("Delete Directory"); mSearchAction->setToolTip("Search"); mOpenAction->setText("Open view"); mNewViewAction->setText("Create new view"); mNewDirectoryAction->setText("Create new Directory"); - mRenameAction->setText("Rename view"); + mRenameViewAction->setText("Rename view"); + mRenameDirectoryAction->setText("Rename directory"); mDuplicateAction->setText("Duplicate view"); - mDeleteAction->setText("Delete view"); + mDeleteViewAction->setText("Delete view"); mDeleteDirectoryAction->setText("Delete directory"); mSearchAction->setText("Search"); @@ -104,9 +107,10 @@ namespace hal connect(mOpenAction, &QAction::triggered, this, &ContextManagerWidget::handleOpenContextClicked); connect(mNewViewAction, &QAction::triggered, this, &ContextManagerWidget::handleCreateContextClicked); connect(mNewDirectoryAction, &QAction::triggered, this, &ContextManagerWidget::handleCreateDirectoryClicked); - connect(mRenameAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameContextClicked); + connect(mRenameViewAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameContextClicked); + connect(mRenameDirectoryAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameDirectoryClicked); connect(mDuplicateAction, &QAction::triggered, this, &ContextManagerWidget::handleDuplicateContextClicked); - connect(mDeleteAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteContextClicked); + connect(mDeleteViewAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteContextClicked); connect(mDeleteDirectoryAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteDirectoryClicked); connect(mSearchAction, &QAction::triggered, this, &ContextManagerWidget::toggleSearchbar); @@ -150,8 +154,7 @@ namespace hal { UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); - act->addAction(new ActionCreateObject(UserActionObjectType::ContextDir, - QString::fromStdString(gNetlist->get_top_module()->get_name()))); + act->addAction(new ActionCreateObject(UserActionObjectType::ContextDir, newName)); act->addAction(new ActionAddItemsToObject({gNetlist->get_top_module()->get_id()}, {})); act->exec(); } } @@ -218,6 +221,25 @@ namespace hal } } + void ContextManagerWidget::handleRenameDirectoryClicked() + { + ContextDirectory* clicked_directory = getCurrentItem()->directory(); + + if (!clicked_directory) return; + + InputDialog ipd; + ipd.setWindowTitle("Rename directory"); + ipd.setInfoText("Please select a new name for the directory."); + ipd.setInputText(clicked_directory->name()); + + if (ipd.exec() == QDialog::Accepted) + { + ActionRenameObject* act = new ActionRenameObject(ipd.textValue()); + act->setObject(UserActionObject(clicked_directory->id(),UserActionObjectType::ContextDir)); + act->exec(); + } + } + void ContextManagerWidget::handleDuplicateContextClicked() { GraphContext* clicked_context = getCurrentContext(); @@ -290,13 +312,14 @@ namespace hal { context_menu.addAction(mOpenAction); context_menu.addAction(mDuplicateAction); - context_menu.addAction(mRenameAction); - context_menu.addAction(mDeleteAction); + context_menu.addAction(mRenameViewAction); + context_menu.addAction(mDeleteViewAction); } if (clicked_index.isValid() && clicked_directory) { context_menu.addAction(mDeleteDirectoryAction); + context_menu.addAction(mRenameDirectoryAction); } context_menu.exec(mContextTreeView->viewport()->mapToGlobal(point)); @@ -363,8 +386,10 @@ namespace hal toolbar->addAction(mNewViewAction); toolbar->addAction(mOpenAction); toolbar->addAction(mDuplicateAction); - toolbar->addAction(mRenameAction); - toolbar->addAction(mDeleteAction); + toolbar->addAction(mRenameViewAction); + toolbar->addAction(mRenameDirectoryAction); + toolbar->addAction(mDeleteViewAction); + toolbar->addAction(mDeleteDirectoryAction); toolbar->addAction(mSearchAction); } @@ -383,23 +408,23 @@ namespace hal void ContextManagerWidget::setToolbarButtonsEnabled(bool enabled) { mOpenAction->setEnabled(enabled); - mRenameAction->setEnabled(enabled); + mRenameViewAction->setEnabled(enabled); mDuplicateAction->setEnabled(enabled); - mDeleteAction->setEnabled(enabled); + mDeleteViewAction->setEnabled(enabled); if(enabled) { mOpenAction->setIcon(gui_utility::getStyledSvgIcon(mOpenIconStyle, mOpenIconPath)); - mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); + mRenameViewAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDuplicateIconStyle, mDuplicateIconPath)); - mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); + mDeleteViewAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); } else { mOpenAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mOpenIconPath)); - mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mRenameIconPath)); + mRenameViewAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mDuplicateIconPath)); - mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mDeleteIconPath)); + mDeleteViewAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mDeleteIconPath)); } } diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index 05518cd6401..ed3a3eb315a 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -114,7 +114,6 @@ namespace hal ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr) { setHeaderLabels(QStringList() << "View Name" << "Timestamp"); - } QVariant ContextTreeModel::data(const QModelIndex& index, int role) const @@ -268,6 +267,11 @@ namespace hal void ContextTreeModel::removeDirectory(ContextDirectory *directory) { ContextTreeItem* item = static_cast(getDirectory(directory->id())); + + if(item == mCurrentDirectory) { + mCurrentDirectory = nullptr; + } + ContextTreeItem* parent = static_cast(item->getParent()); assert(item); assert(parent); @@ -320,4 +324,5 @@ namespace hal else if (currentItem->isDirectory()) mCurrentDirectory = currentItem; } + } diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index 00bd0f63db4..5d06d554154 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -90,6 +90,13 @@ namespace hal Q_EMIT contextRenamed(ctx); } + void GraphContextManager::renameContextDirectoryAction(ContextDirectory *ctxDir, const QString &newName) + { + ctxDir->setName(newName); + + Q_EMIT directoryRenamed(ctxDir); + } + void GraphContextManager::deleteGraphContext(GraphContext* ctx) { Q_EMIT deletingContext(ctx); @@ -101,6 +108,8 @@ namespace hal void GraphContextManager::deleteContextDirectory(ContextDirectory *ctxDir) { + Q_EMIT deletingDirectory(ctxDir); + mContextTreeModel->removeDirectory(ctxDir); delete ctxDir; diff --git a/plugins/gui/src/user_action/action_rename_object.cpp b/plugins/gui/src/user_action/action_rename_object.cpp index 5d18f6337d0..8b7494e2405 100644 --- a/plugins/gui/src/user_action/action_rename_object.cpp +++ b/plugins/gui/src/user_action/action_rename_object.cpp @@ -1,5 +1,6 @@ #include "gui/user_action/action_rename_object.h" +#include "gui/context_manager_widget/models/context_tree_model.h" #include "gui/graph_widget/contexts/graph_context.h" #include "gui/grouping/grouping_manager_widget.h" #include "gui/grouping/grouping_table_model.h" @@ -53,6 +54,8 @@ namespace hal Gate* gat; Net* net; GraphContext* ctx; + ContextDirectory* ctxDir; + switch (mObject.type()) { case UserActionObjectType::Module: @@ -104,6 +107,18 @@ namespace hal return false; } break; + case UserActionObjectType::ContextDir: + ctxDir = gGraphContextManager->getDirectoryById(mObject.id()); + if (ctxDir) + { + oldName = ctxDir->name(); + gGraphContextManager->renameGraphContextAction(ctx, mNewName); + } + else + { + return false; + } + break; case UserActionObjectType::Pin: { mod = gNetlist->get_module_by_id(mParentObject.id()); if (!mod) From b2a6abc8b4c575803c2d4ee9d7277065dedf69bc Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Fri, 2 Feb 2024 22:19:45 +0100 Subject: [PATCH 18/38] Fix renaming of directory --- plugins/gui/src/user_action/action_rename_object.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/gui/src/user_action/action_rename_object.cpp b/plugins/gui/src/user_action/action_rename_object.cpp index 8b7494e2405..d3785b41cb2 100644 --- a/plugins/gui/src/user_action/action_rename_object.cpp +++ b/plugins/gui/src/user_action/action_rename_object.cpp @@ -112,7 +112,7 @@ namespace hal if (ctxDir) { oldName = ctxDir->name(); - gGraphContextManager->renameGraphContextAction(ctx, mNewName); + gGraphContextManager->renameContextDirectoryAction(ctxDir, mNewName); } else { From b5ae89a797d054b84bf650b66e07aabda3f02984 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Mon, 5 Feb 2024 23:30:35 +0100 Subject: [PATCH 19/38] WIP: Add directory JSON --- .../context_manager_widget.h | 13 +- .../models/context_tree_model.h | 25 ++- .../context_manager_widget.cpp | 172 +++++++++--------- .../models/context_tree_model.cpp | 47 ++++- .../graph_widget/graph_context_manager.cpp | 9 + 5 files changed, 160 insertions(+), 106 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index 50dce2623b0..8ce65434f96 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -217,22 +217,19 @@ namespace hal QString mNewDirIconPath; QString mNewViewIconStyle; - QAction* mRenameViewAction; + QAction* mRenameAction; QString mRenameIconPath; QString mRenameIconStyle; - QAction* mRenameDirectoryAction; QAction* mDuplicateAction; QString mDuplicateIconPath; QString mDuplicateIconStyle; - QAction* mDeleteViewAction; + QAction* mDeleteAction; QString mDeleteIconPath; QString mDeleteIconStyle; - QAction* mDeleteDirectoryAction; - QAction* mOpenAction; QString mOpenIconPath; QString mOpenIconStyle; @@ -246,11 +243,9 @@ namespace hal void handleCreateClicked(); void handleCreateContextClicked(); void handleCreateDirectoryClicked(); - void handleRenameContextClicked(); - void handleRenameDirectoryClicked(); + void handleRenameClicked(); void handleDuplicateContextClicked(); - void handleDeleteContextClicked(); - void handleDeleteDirectoryClicked(); + void handleDeleteClicked(); void handleContextMenuRequest(const QPoint& point); diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h index ef7715c6e49..d3c2080c978 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h @@ -40,11 +40,21 @@ namespace hal u32 mId; QString mName; u32 mMinDirectoryId; + u32 mParentId; public: - ContextDirectory(QString name):mName(name), mMinDirectoryId(std::numeric_limits::max()){ + ContextDirectory(QString name, u32 parentId):mName(name), mMinDirectoryId(std::numeric_limits::max()){ mId = --mMinDirectoryId; + mParentId = parentId; } + + /** + * Writes the directory to a given json object. + * + * @param json - The object to write to. + */ + void writeToFile(QJsonObject& json); + QString name() const { return mName; } u32 id() const { return mId; } void setId(u32 id_) { mId = id_; } @@ -162,6 +172,13 @@ namespace hal */ const QVector& list(); + /** + * Get all ContextDirectories of the model. + * + * @return A vector of all ContextDirectories. + */ + const QVector& directoryList(); + /** * Sets the CurrentDirectory. * @@ -172,14 +189,12 @@ namespace hal Q_SIGNALS: void directoryCreatedSignal(ContextTreeItem* item); - private Q_SLOTS: - void handleDataChanged(); - - private: BaseTreeItem* getDirectoryInternal(BaseTreeItem* parentItem, u32 directoryId) const; ContextTreeItem *mCurrentDirectory; std::map mContextMap; QVector mContextList; + QVector mDirectoryList; + }; } // namespace hal diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index 4b2f8308165..efad3cb08ee 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -38,8 +38,8 @@ namespace hal { ContextManagerWidget::ContextManagerWidget(GraphTabWidget* tab_view, QWidget* parent) - : ContentWidget("Views", parent), mSearchbar(new Searchbar(this)), mNewDirectoryAction(new QAction(this)), mNewViewAction(new QAction(this)), mRenameViewAction(new QAction(this)), mRenameDirectoryAction(new QAction(this)), mDuplicateAction(new QAction(this)), - mDeleteViewAction(new QAction(this)), mDeleteDirectoryAction(new QAction(this)), mOpenAction(new QAction(this)) + : ContentWidget("Views", parent), mSearchbar(new Searchbar(this)), mNewDirectoryAction(new QAction(this)), mNewViewAction(new QAction(this)), mRenameAction(new QAction(this)), mDuplicateAction(new QAction(this)), + mDeleteAction(new QAction(this)), mOpenAction(new QAction(this)) { //needed to load the properties ensurePolished(); @@ -48,31 +48,25 @@ namespace hal mOpenAction->setIcon(gui_utility::getStyledSvgIcon(mOpenIconStyle, mOpenIconPath)); mNewViewAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewViewIconPath)); mNewDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mNewViewIconStyle, mNewDirIconPath)); - mRenameViewAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); - mRenameDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); + mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDuplicateIconStyle, mDuplicateIconPath)); - mDeleteViewAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); - mDeleteDirectoryAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); + mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath)); mOpenAction->setToolTip("Open"); mNewViewAction->setToolTip("New View"); mNewDirectoryAction->setToolTip("New Directory"); - mRenameViewAction->setToolTip("Rename view"); - mRenameDirectoryAction->setToolTip("Rename directory"); + mRenameAction->setToolTip("Rename view"); mDuplicateAction->setToolTip("Duplicate"); - mDeleteViewAction->setToolTip("Delete"); - mDeleteDirectoryAction->setToolTip("Delete Directory"); + mDeleteAction->setToolTip("Delete"); mSearchAction->setToolTip("Search"); mOpenAction->setText("Open view"); mNewViewAction->setText("Create new view"); mNewDirectoryAction->setText("Create new Directory"); - mRenameViewAction->setText("Rename view"); - mRenameDirectoryAction->setText("Rename directory"); + mRenameAction->setText("Rename view"); mDuplicateAction->setText("Duplicate view"); - mDeleteViewAction->setText("Delete view"); - mDeleteDirectoryAction->setText("Delete directory"); + mDeleteAction->setText("Delete view"); mSearchAction->setText("Search"); //mOpenAction->setEnabled(false); @@ -107,11 +101,9 @@ namespace hal connect(mOpenAction, &QAction::triggered, this, &ContextManagerWidget::handleOpenContextClicked); connect(mNewViewAction, &QAction::triggered, this, &ContextManagerWidget::handleCreateContextClicked); connect(mNewDirectoryAction, &QAction::triggered, this, &ContextManagerWidget::handleCreateDirectoryClicked); - connect(mRenameViewAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameContextClicked); - connect(mRenameDirectoryAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameDirectoryClicked); + connect(mRenameAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameClicked); connect(mDuplicateAction, &QAction::triggered, this, &ContextManagerWidget::handleDuplicateContextClicked); - connect(mDeleteViewAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteContextClicked); - connect(mDeleteDirectoryAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteDirectoryClicked); + connect(mDeleteAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteClicked); connect(mSearchAction, &QAction::triggered, this, &ContextManagerWidget::toggleSearchbar); connect(mContextTreeView, &QTreeView::customContextMenuRequested, this, &ContextManagerWidget::handleContextMenuRequest); @@ -128,7 +120,7 @@ namespace hal mShortCutDeleteItem->setEnabled(false); connect(ContentManager::sSettingDeleteItem, &SettingsItemKeybind::keySequenceChanged, mShortCutDeleteItem, &QShortcut::setKey); - connect(mShortCutDeleteItem, &QShortcut::activated, this, &ContextManagerWidget::handleDeleteContextClicked); + connect(mShortCutDeleteItem, &QShortcut::activated, this, &ContextManagerWidget::handleDeleteClicked); connect(qApp, &QApplication::focusChanged, this, &ContextManagerWidget::handleFocusChanged); @@ -192,51 +184,53 @@ namespace hal } - void ContextManagerWidget::handleRenameContextClicked() + void ContextManagerWidget::handleRenameClicked() { - GraphContext* clicked_context = getCurrentContext(); - - if (!clicked_context) return; - - QStringList used_context_names; - for (const auto& context : gGraphContextManager->getContexts()) - used_context_names.append(context->name()); + ContextTreeItem* clicked_item = getCurrentItem(); - UniqueStringValidator unique_validator(used_context_names); - EmptyStringValidator empty_validator; + if (clicked_item->isContext()) { + GraphContext* clicked_context = clicked_item->context(); - InputDialog ipd; - ipd.setWindowTitle("Rename View"); - ipd.setInfoText("Please select a new unique name for the view."); - ipd.setInputText(clicked_context->name()); - ipd.addValidator(&unique_validator); - ipd.addValidator(&empty_validator); - - if (ipd.exec() == QDialog::Accepted) - { - ActionRenameObject* act = new ActionRenameObject(ipd.textValue()); - act->setObject(UserActionObject(clicked_context->id(),UserActionObjectType::ContextView)); - act->exec(); - clicked_context->setExclusiveModuleId(0, false); - } - } + if (!clicked_context) return; - void ContextManagerWidget::handleRenameDirectoryClicked() - { - ContextDirectory* clicked_directory = getCurrentItem()->directory(); + QStringList used_context_names; + for (const auto& context : gGraphContextManager->getContexts()) + used_context_names.append(context->name()); - if (!clicked_directory) return; + UniqueStringValidator unique_validator(used_context_names); + EmptyStringValidator empty_validator; - InputDialog ipd; - ipd.setWindowTitle("Rename directory"); - ipd.setInfoText("Please select a new name for the directory."); - ipd.setInputText(clicked_directory->name()); + InputDialog ipd; + ipd.setWindowTitle("Rename View"); + ipd.setInfoText("Please select a new unique name for the view."); + ipd.setInputText(clicked_context->name()); + ipd.addValidator(&unique_validator); + ipd.addValidator(&empty_validator); - if (ipd.exec() == QDialog::Accepted) - { - ActionRenameObject* act = new ActionRenameObject(ipd.textValue()); - act->setObject(UserActionObject(clicked_directory->id(),UserActionObjectType::ContextDir)); - act->exec(); + if (ipd.exec() == QDialog::Accepted) + { + ActionRenameObject* act = new ActionRenameObject(ipd.textValue()); + act->setObject(UserActionObject(clicked_context->id(),UserActionObjectType::ContextView)); + act->exec(); + clicked_context->setExclusiveModuleId(0, false); + } + } + else if (clicked_item->isDirectory()){ + ContextDirectory* clicked_directory = clicked_item->directory(); + + if (!clicked_directory) return; + + InputDialog ipd; + ipd.setWindowTitle("Rename directory"); + ipd.setInfoText("Please select a new name for the directory."); + ipd.setInputText(clicked_directory->name()); + + if (ipd.exec() == QDialog::Accepted) + { + ActionRenameObject* act = new ActionRenameObject(ipd.textValue()); + act->setObject(UserActionObject(clicked_directory->id(),UserActionObjectType::ContextDir)); + act->exec(); + } } } @@ -253,32 +247,34 @@ namespace hal act->exec(); } - void ContextManagerWidget::handleDeleteContextClicked() + void ContextManagerWidget::handleDeleteClicked() { - QModelIndex current = mContextTreeView->currentIndex(); + QModelIndex current = mContextTreeView->currentIndex(); if (!current.isValid()) return; - GraphContext* clicked_context = getCurrentContext(); + ContextTreeItem* currentItem = getCurrentItem(); - if (!clicked_context) return; + if (currentItem->isContext()) { + GraphContext* clicked_context = currentItem->context(); - ActionDeleteObject* act = new ActionDeleteObject; - act->setObject(UserActionObject(clicked_context->id(),UserActionObjectType::ContextView)); - act->exec(); - } + if (!clicked_context) return; - void ContextManagerWidget::handleDeleteDirectoryClicked() - { - QModelIndex current = mContextTreeView->currentIndex(); - if (!current.isValid()) return; + ActionDeleteObject* act = new ActionDeleteObject; + act->setObject(UserActionObject(clicked_context->id(),UserActionObjectType::ContextView)); + act->exec(); + } + else if (currentItem->isDirectory()) { - ContextDirectory* clicked_directory = getCurrentItem()->directory(); + ContextDirectory* clicked_directory = currentItem->directory(); + + if (!clicked_directory) return; + + ActionDeleteObject* act = new ActionDeleteObject; + act->setObject(UserActionObject(clicked_directory->id(),UserActionObjectType::ContextDir)); + act->exec(); + } - if (!clicked_directory) return; - ActionDeleteObject* act = new ActionDeleteObject; - act->setObject(UserActionObject(clicked_directory->id(),UserActionObjectType::ContextDir)); - act->exec(); } void ContextManagerWidget::handleSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) @@ -312,14 +308,14 @@ namespace hal { context_menu.addAction(mOpenAction); context_menu.addAction(mDuplicateAction); - context_menu.addAction(mRenameViewAction); - context_menu.addAction(mDeleteViewAction); + context_menu.addAction(mRenameAction); + context_menu.addAction(mDeleteAction); } if (clicked_index.isValid() && clicked_directory) { - context_menu.addAction(mDeleteDirectoryAction); - context_menu.addAction(mRenameDirectoryAction); + context_menu.addAction(mDeleteAction); + context_menu.addAction(mRenameAction); } context_menu.exec(mContextTreeView->viewport()->mapToGlobal(point)); @@ -386,10 +382,10 @@ namespace hal toolbar->addAction(mNewViewAction); toolbar->addAction(mOpenAction); toolbar->addAction(mDuplicateAction); - toolbar->addAction(mRenameViewAction); - toolbar->addAction(mRenameDirectoryAction); - toolbar->addAction(mDeleteViewAction); - toolbar->addAction(mDeleteDirectoryAction); + toolbar->addAction(mRenameAction); + toolbar->addAction(mRenameAction); + toolbar->addAction(mDeleteAction); + toolbar->addAction(mDeleteAction); toolbar->addAction(mSearchAction); } @@ -408,23 +404,23 @@ namespace hal void ContextManagerWidget::setToolbarButtonsEnabled(bool enabled) { mOpenAction->setEnabled(enabled); - mRenameViewAction->setEnabled(enabled); + mRenameAction->setEnabled(enabled); mDuplicateAction->setEnabled(enabled); - mDeleteViewAction->setEnabled(enabled); + mDeleteAction->setEnabled(enabled); if(enabled) { mOpenAction->setIcon(gui_utility::getStyledSvgIcon(mOpenIconStyle, mOpenIconPath)); - mRenameViewAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); + mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDuplicateIconStyle, mDuplicateIconPath)); - mDeleteViewAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); + mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); } else { mOpenAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mOpenIconPath)); - mRenameViewAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mRenameIconPath)); + mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mDuplicateIconPath)); - mDeleteViewAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mDeleteIconPath)); + mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mDeleteIconPath)); } } diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index ed3a3eb315a..aa02e235aab 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -2,6 +2,8 @@ #include "gui/selection_details_widget/selection_details_icon_provider.h" #include "gui/gui_globals.h" #include "gui/gui_utils/graphics.h" +#include "gui/user_action/action_delete_object.h" + #include #include @@ -178,9 +180,6 @@ namespace hal ContextDirectory* ContextTreeModel::addDirectory(QString name, BaseTreeItem *parent) { - ContextDirectory* directory = new ContextDirectory(name); - - ContextTreeItem* item = new ContextTreeItem(directory); BaseTreeItem* parentItem = parent; @@ -189,6 +188,10 @@ namespace hal if (!parentItem) parentItem = mRootItem; + ContextDirectory* directory = new ContextDirectory(name, (parentItem != mRootItem) ? static_cast(parentItem)->directory()->id() : 0); + + ContextTreeItem* item = new ContextTreeItem(directory); + QModelIndex index = getIndexFromItem(parentItem); @@ -199,6 +202,8 @@ namespace hal parentItem->appendChild(item); endInsertRows(); + mDirectoryList.push_back(directory); + Q_EMIT directoryCreatedSignal(item); return directory; @@ -236,7 +241,6 @@ namespace hal mContextMap.insert({context, item}); - //connect(context,&GraphContext::dataChanged,this,&ContextTableModel::handleDataChanged); connect(context, &GraphContext::dataChanged, this, [item, this]() { Q_EMIT dataChanged(getIndexFromItem(item), getIndexFromItem(item)); }); @@ -272,6 +276,23 @@ namespace hal mCurrentDirectory = nullptr; } + QList childCopy = item->getChildren(); + for (int i = 0; i < childCopy.length(); i++) { + ContextTreeItem* child = static_cast(childCopy[i]); + + if (child->isContext()) { + ActionDeleteObject* act = new ActionDeleteObject; + act->setObject(UserActionObject(child->context()->id(),UserActionObjectType::ContextView)); + act->exec(); + } + else if (child->isDirectory()) { + ActionDeleteObject* act = new ActionDeleteObject; + act->setObject(UserActionObject(child->directory()->id(),UserActionObjectType::ContextDir)); + act->exec(); + } + + } + ContextTreeItem* parent = static_cast(item->getParent()); assert(item); assert(parent); @@ -284,6 +305,11 @@ namespace hal parent->removeChild(item); endRemoveRows(); + auto it = std::find(mDirectoryList.begin(), mDirectoryList.end(), directory); + if (it != mDirectoryList.end()) { + mDirectoryList.erase(it); + } + delete item; } @@ -316,6 +342,12 @@ namespace hal return mContextList; } + const QVector &ContextTreeModel::directoryList() + { + return mDirectoryList; + } + + void ContextTreeModel::setCurrentDirectory(ContextTreeItem* currentItem) { if(currentItem->isContext()) @@ -325,4 +357,11 @@ namespace hal mCurrentDirectory = currentItem; } + void ContextDirectory::writeToFile(QJsonObject &json) + { + json["patrentId"] = (int) mParentId; + json["id"] = (int) mId; + json["name"] = mName; + } + } diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index 5d06d554154..c11a98557f9 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -665,6 +665,15 @@ namespace hal jsonViews.append(jsonView); } json["views"] = jsonViews; + + QJsonArray jsonDirectories; + for (ContextDirectory* directory : mContextTreeModel->directoryList()) + { + QJsonObject jsonDirectory; + directory->writeToFile(jsonDirectory); + jsonViews.append(jsonDirectory); + } + json["directories"] = jsonDirectories; return (jsFile.write(QJsonDocument(json).toJson(QJsonDocument::Compact)) >= 0); // neg return value indicates error } } // namespace hal From d024b5b07773124f56b80f390759864c751f663c Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Mon, 19 Feb 2024 11:47:20 +0100 Subject: [PATCH 20/38] Add Directories to json; Add parentId to views in json --- .../gui/graph_widget/contexts/graph_context.h | 6 ++++-- .../models/context_tree_model.cpp | 13 ++++++------- .../gui/src/graph_widget/contexts/graph_context.cpp | 4 ++-- .../gui/src/graph_widget/graph_context_manager.cpp | 9 +++++++-- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/plugins/gui/include/gui/graph_widget/contexts/graph_context.h b/plugins/gui/include/gui/graph_widget/contexts/graph_context.h index b253a8d72f2..ddb2d70c423 100644 --- a/plugins/gui/include/gui/graph_widget/contexts/graph_context.h +++ b/plugins/gui/include/gui/graph_widget/contexts/graph_context.h @@ -28,6 +28,7 @@ #include "gui/graph_widget/layouters/graph_layouter.h" #include "gui/graph_widget/shaders/graph_shader.h" #include "gui/gui_def.h" +#include "gui/basic_tree_model/base_tree_item.h" #include #include @@ -353,9 +354,10 @@ namespace hal /** * Writes the context (its modules, gates, nets) to a given json object. * - * @param json - The object to write to. + * @param json - The object to write to + * @param int - ParentId of the graphContext. */ - void writeToFile(QJsonObject& json); + void writeToFile(QJsonObject& json, int parentId); /** * Reads a context from a given json object. diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index aa02e235aab..c37a9d1105a 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -11,6 +11,12 @@ namespace hal { + void ContextDirectory::writeToFile(QJsonObject &json) + { + json["patrentId"] = (int) mParentId; + json["id"] = (int) mId; + json["name"] = mName; + } ContextTreeItem::ContextTreeItem(GraphContext *context) : BaseTreeItem(), @@ -357,11 +363,4 @@ namespace hal mCurrentDirectory = currentItem; } - void ContextDirectory::writeToFile(QJsonObject &json) - { - json["patrentId"] = (int) mParentId; - json["id"] = (int) mId; - json["name"] = mName; - } - } diff --git a/plugins/gui/src/graph_widget/contexts/graph_context.cpp b/plugins/gui/src/graph_widget/contexts/graph_context.cpp index bb7b3d2c01d..75bf0042e8b 100644 --- a/plugins/gui/src/graph_widget/contexts/graph_context.cpp +++ b/plugins/gui/src/graph_widget/contexts/graph_context.cpp @@ -808,14 +808,14 @@ namespace hal return true; } - void GraphContext::writeToFile(QJsonObject& json) + void GraphContext::writeToFile(QJsonObject& json, int parentId) { json["id"] = (int) mId; json["name"] = mName; json["timestamp"] = mTimestamp.toString(); json["exclusiveModuleId"] = (int) mExclusiveModuleId; json["visible"] = gContentManager->getGraphTabWidget()->visibleStatus(this); - + json["parentId"] = (int) parentId; /// modules QJsonArray jsonMods; for (u32 id : mModules) diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index c11a98557f9..767ce28c0c1 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -660,8 +660,13 @@ namespace hal QJsonArray jsonViews; for (GraphContext* context : mContextTreeModel->list()) { + BaseTreeItem* parent = mContextTreeModel->getItemFromIndex(mContextTreeModel->getIndexFromContext(context))->getParent(); + int parentId = 0; + if (parent != mContextTreeModel->getRootItem()) + parentId = static_cast(parent)->directory()->id(); + QJsonObject jsonView; - context->writeToFile(jsonView); + context->writeToFile(jsonView, parentId); jsonViews.append(jsonView); } json["views"] = jsonViews; @@ -671,7 +676,7 @@ namespace hal { QJsonObject jsonDirectory; directory->writeToFile(jsonDirectory); - jsonViews.append(jsonDirectory); + jsonDirectories.append(jsonDirectory); } json["directories"] = jsonDirectories; return (jsFile.write(QJsonDocument(json).toJson(QJsonDocument::Compact)) >= 0); // neg return value indicates error From 72840b863c6823ca43f84c3bc7748f1b147237cb Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Mon, 19 Feb 2024 14:10:24 +0100 Subject: [PATCH 21/38] WIP: Read directories from file --- .../models/context_tree_model.h | 24 ++++++++++-- .../models/context_tree_model.cpp | 13 +++++-- .../graph_widget/graph_context_manager.cpp | 38 ++++++++++++++++++- 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h index d3c2080c978..192a42848d3 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h @@ -39,12 +39,11 @@ namespace hal private: u32 mId; QString mName; - u32 mMinDirectoryId; u32 mParentId; public: - ContextDirectory(QString name, u32 parentId):mName(name), mMinDirectoryId(std::numeric_limits::max()){ - mId = --mMinDirectoryId; + ContextDirectory(QString name, u32 parentId, u32 id):mName(name){ + mId = id; mParentId = parentId; } @@ -55,6 +54,7 @@ namespace hal */ void writeToFile(QJsonObject& json); + QString name() const { return mName; } u32 id() const { return mId; } void setId(u32 id_) { mId = id_; } @@ -118,7 +118,7 @@ namespace hal * @param name - The name to the directory. * @param parent - The Parent of the directory. */ - ContextDirectory* addDirectory(QString name, BaseTreeItem* parent = nullptr); + ContextDirectory* addDirectory(QString name, BaseTreeItem* parent = nullptr, u32 id = 0); BaseTreeItem* getDirectory(u32 directoryId) const; @@ -186,6 +186,21 @@ namespace hal */ void setCurrentDirectory(ContextTreeItem* currentItem); + /** + * Sets the MinDirectoryId. + * + * @param u32 - id to set MinDirectoryId to. + */ + void setMinDirectoryId(u32 id_) { mMinDirectoryId = id_; } + + /** + * Get MinDirectoryId. + * + * @return MinDIrectoryId. + */ + u32 minDirectoryId() const { return mMinDirectoryId; } + + Q_SIGNALS: void directoryCreatedSignal(ContextTreeItem* item); @@ -195,6 +210,7 @@ namespace hal std::map mContextMap; QVector mContextList; QVector mDirectoryList; + u32 mMinDirectoryId; }; } // namespace hal diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index c37a9d1105a..b1d1ba1ed2c 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -13,7 +13,7 @@ namespace hal { void ContextDirectory::writeToFile(QJsonObject &json) { - json["patrentId"] = (int) mParentId; + json["parentId"] = (int) mParentId; json["id"] = (int) mId; json["name"] = mName; } @@ -119,7 +119,7 @@ namespace hal return mContext != nullptr; } - ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr) + ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr), mMinDirectoryId(std::numeric_limits::max()) { setHeaderLabels(QStringList() << "View Name" << "Timestamp"); } @@ -184,9 +184,14 @@ namespace hal return nullptr; } - ContextDirectory* ContextTreeModel::addDirectory(QString name, BaseTreeItem *parent) + ContextDirectory* ContextTreeModel::addDirectory(QString name, BaseTreeItem *parent, u32 id) { + if(id == 0) + id = --mMinDirectoryId; + else if (id < mMinDirectoryId) + mMinDirectoryId = id; + BaseTreeItem* parentItem = parent; if (!parentItem) @@ -194,7 +199,7 @@ namespace hal if (!parentItem) parentItem = mRootItem; - ContextDirectory* directory = new ContextDirectory(name, (parentItem != mRootItem) ? static_cast(parentItem)->directory()->id() : 0); + ContextDirectory* directory = new ContextDirectory(name, (parentItem != mRootItem) ? static_cast(parentItem)->directory()->id() : 0, id); ContextTreeItem* item = new ContextTreeItem(directory); diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index 767ce28c0c1..89f57217f33 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -582,6 +582,32 @@ namespace hal GraphContext* firstContext = nullptr; GraphContext* selectedContext = nullptr; + if (json.contains("directories") && json["directories"].isArray()) + { + QJsonArray jsonDirectories = json["directories"].toArray(); + int ndir = jsonDirectories.size(); + for (int idir = 0; idir < ndir; idir++) + { + QJsonObject jsondir = jsonDirectories.at(idir).toObject(); + if (!jsondir.contains("id") || !jsondir["id"].isDouble()) + continue; + u32 dirId = jsondir["id"].toInt(); + if (!jsondir.contains("name") || !jsondir["name"].isString()) + continue; + QString dirName = jsondir["name"].toString(); + if (!jsondir.contains("parentId")) + continue; + u32 dirParentId = jsondir["parentId"].toInt(); + + BaseTreeItem* dirParent = nullptr; + + if (dirParentId != 0) { + mContextTreeModel->getDirectory(dirParentId); + } + + mContextTreeModel->addDirectory(dirName, dirParent, dirId); + } + } if (json.contains("views") && json["views"].isArray()) { QJsonArray jsonViews = json["views"].toArray(); @@ -600,6 +626,16 @@ namespace hal int visibleFlag = 1; // default to visible before flag was invented if (jsonView.contains("visible")) visibleFlag = jsonView["visible"].toInt(); + if (!jsonView.contains("parentId")) + continue; + u32 viewParentId = jsonView["parentId"].toInt(); + BaseTreeItem* viewParent = nullptr; + + if (viewParentId != 0) { + mContextTreeModel->getDirectory(viewParentId); + } + + GraphContext* context = gGraphContextManager->getContextById(viewId); if (context) { @@ -630,7 +666,7 @@ namespace hal continue; } - mContextTreeModel->addContext(context); + mContextTreeModel->addContext(context, viewParent); if (visibleFlag) Q_EMIT contextCreated(context); } From db9f8c989cdb57cb11cb5be6582a46b6e03a3eab Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Sat, 2 Mar 2024 15:36:03 +0100 Subject: [PATCH 22/38] Fix json restore for directories and views --- plugins/gui/src/graph_widget/graph_context_manager.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index 89f57217f33..8e104dd922e 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -599,10 +599,10 @@ namespace hal continue; u32 dirParentId = jsondir["parentId"].toInt(); - BaseTreeItem* dirParent = nullptr; + BaseTreeItem* dirParent = mContextTreeModel->getRootItem(); if (dirParentId != 0) { - mContextTreeModel->getDirectory(dirParentId); + dirParent = mContextTreeModel->getDirectory(dirParentId); } mContextTreeModel->addDirectory(dirName, dirParent, dirId); @@ -629,10 +629,11 @@ namespace hal if (!jsonView.contains("parentId")) continue; u32 viewParentId = jsonView["parentId"].toInt(); - BaseTreeItem* viewParent = nullptr; + + BaseTreeItem* viewParent = mContextTreeModel->getRootItem(); if (viewParentId != 0) { - mContextTreeModel->getDirectory(viewParentId); + viewParent = mContextTreeModel->getDirectory(viewParentId); } From 7af3a7df9ec877b4c86aa0cbeb14f76af51edc9a Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Sat, 2 Mar 2024 23:20:24 +0100 Subject: [PATCH 23/38] Add undo action for directories and views --- .../gui/graph_widget/graph_context_manager.h | 2 +- .../context_manager_widget.cpp | 2 +- .../graph_widget/graph_context_manager.cpp | 2 +- .../src/user_action/action_delete_object.cpp | 20 +++++++++++++++++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/plugins/gui/include/gui/graph_widget/graph_context_manager.h b/plugins/gui/include/gui/graph_widget/graph_context_manager.h index 1acdf16d57f..db15c5aa147 100644 --- a/plugins/gui/include/gui/graph_widget/graph_context_manager.h +++ b/plugins/gui/include/gui/graph_widget/graph_context_manager.h @@ -366,7 +366,7 @@ namespace hal * * @returns the context table model */ - ContextTreeModel* getContextTableModel() const; + ContextTreeModel* getContextTreeModel() const; /** * Deletes all contexts. diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index efad3cb08ee..7c4a65d6cd9 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -74,7 +74,7 @@ namespace hal //mDuplicateAction->setEnabled(false); //mDeleteAction->setEnabled(false); - mContextTreeModel = gGraphContextManager->getContextTableModel(); + mContextTreeModel = gGraphContextManager->getContextTreeModel(); mContextTreeProxyModel = new ContextProxyModel(this); mContextTreeProxyModel->setSourceModel(mContextTreeModel); diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index 8e104dd922e..d0e22373d22 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -559,7 +559,7 @@ namespace hal return new ModuleShader(context); } - ContextTreeModel* GraphContextManager::getContextTableModel() const + ContextTreeModel* GraphContextManager::getContextTreeModel() const { return mContextTreeModel; } diff --git a/plugins/gui/src/user_action/action_delete_object.cpp b/plugins/gui/src/user_action/action_delete_object.cpp index 2a796ad6147..9ad9749b345 100644 --- a/plugins/gui/src/user_action/action_delete_object.cpp +++ b/plugins/gui/src/user_action/action_delete_object.cpp @@ -1,5 +1,7 @@ #include "gui/user_action/action_delete_object.h" +#include "gui/graph_widget/contexts/graph_context.h" +#include "gui/context_manager_widget/models/context_tree_model.h" #include "gui/graph_widget/layout_locker.h" #include "gui/grouping/grouping_manager_widget.h" #include "gui/grouping/grouping_table_model.h" @@ -140,7 +142,12 @@ namespace hal ctx = gGraphContextManager->getContextById(mObject.id()); if (ctx) { - // TODO : Undo action + UserActionCompound* act = new UserActionCompound; + act->setUseCreatedObject(); + act->addAction(new ActionCreateObject(UserActionObjectType::ContextView, ctx->name())); + act->addAction(new ActionAddItemsToObject(ctx->modules(), ctx->gates())); + + mUndoAction = act; gGraphContextManager->deleteGraphContext(ctx); } else @@ -150,7 +157,16 @@ namespace hal ctxDir = gGraphContextManager->getDirectoryById(mObject.id()); if (ctxDir) { - // TODO : Undo action + if (gGraphContextManager->getContextTreeModel()->getDirectory(ctxDir->id())->getChildCount() != 0) { + mUndoAction = nullptr; + } else { + UserActionCompound* act = new UserActionCompound; + act->setUseCreatedObject(); + act->addAction(new ActionCreateObject(UserActionObjectType::ContextDir, ctxDir->name())); + act->addAction(new ActionAddItemsToObject({gNetlist->get_top_module()->get_id()}, {})); + + mUndoAction = act; + } gGraphContextManager->deleteContextDirectory(ctxDir); } else From 33d7e8e4a1efaa1831feb126862751e391fb09b2 Mon Sep 17 00:00:00 2001 From: Julia Ritz Date: Sun, 3 Mar 2024 10:36:26 +0100 Subject: [PATCH 24/38] Fix context menu texts --- .../gui/src/context_manager_widget/context_manager_widget.cpp | 4 ++-- plugins/gui/src/user_action/action_delete_object.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index 7c4a65d6cd9..fd17ef992ee 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -64,9 +64,9 @@ namespace hal mOpenAction->setText("Open view"); mNewViewAction->setText("Create new view"); mNewDirectoryAction->setText("Create new Directory"); - mRenameAction->setText("Rename view"); + mRenameAction->setText("Rename item"); mDuplicateAction->setText("Duplicate view"); - mDeleteAction->setText("Delete view"); + mDeleteAction->setText("Delete item"); mSearchAction->setText("Search"); //mOpenAction->setEnabled(false); diff --git a/plugins/gui/src/user_action/action_delete_object.cpp b/plugins/gui/src/user_action/action_delete_object.cpp index 9ad9749b345..cd88a0e5f95 100644 --- a/plugins/gui/src/user_action/action_delete_object.cpp +++ b/plugins/gui/src/user_action/action_delete_object.cpp @@ -146,6 +146,7 @@ namespace hal act->setUseCreatedObject(); act->addAction(new ActionCreateObject(UserActionObjectType::ContextView, ctx->name())); act->addAction(new ActionAddItemsToObject(ctx->modules(), ctx->gates())); + act->setParentObject(mParentObject); mUndoAction = act; gGraphContextManager->deleteGraphContext(ctx); @@ -164,6 +165,7 @@ namespace hal act->setUseCreatedObject(); act->addAction(new ActionCreateObject(UserActionObjectType::ContextDir, ctxDir->name())); act->addAction(new ActionAddItemsToObject({gNetlist->get_top_module()->get_id()}, {})); + act->setParentObject(mParentObject); mUndoAction = act; } From 6b5ce6f75a1df4deeefc839ca3faf5857b78327c Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 4 Mar 2024 20:30:02 +0100 Subject: [PATCH 25/38] Store parent-ID in UNDO action when deleting view or dir --- .../gui/graph_widget/graph_context_manager.h | 4 ++- .../context_manager_widget.cpp | 4 +++ .../graph_widget/graph_context_manager.cpp | 27 +++++++++++++++++-- .../src/user_action/action_delete_object.cpp | 10 +++++-- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/plugins/gui/include/gui/graph_widget/graph_context_manager.h b/plugins/gui/include/gui/graph_widget/graph_context_manager.h index db15c5aa147..36582f917d0 100644 --- a/plugins/gui/include/gui/graph_widget/graph_context_manager.h +++ b/plugins/gui/include/gui/graph_widget/graph_context_manager.h @@ -122,6 +122,8 @@ namespace hal GraphContext* getContextById(u32 id) const; + u32 getParentId(u32 childId, bool isDirctory) const; + ContextDirectory* getDirectoryById(u32 id) const; /** @@ -362,7 +364,7 @@ namespace hal GraphShader* getDefaultShader(GraphContext* const context) const; /** - * Gets the table model for the contexts. + * Gets the tree model for the contexts. * * @returns the context table model */ diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index fd17ef992ee..9668324bc72 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -291,6 +291,10 @@ namespace hal { const QModelIndex clicked_index = mContextTreeView->indexAt(point); + // TODO change current directory : + // if clicked index is view : parent dir of view + // if clicked index is dir : this dir + QMenu context_menu; context_menu.addAction(mNewViewAction); diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index d0e22373d22..faa1ccbc928 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -55,6 +55,25 @@ namespace hal return contextDir; } + u32 GraphContextManager::getParentId(u32 childId, bool isDirctory) const + { + if (isDirctory) + { + BaseTreeItem* bti = mContextTreeModel->getDirectory(childId); + ContextTreeItem* parentItem = dynamic_cast(bti->getParent()); + if (parentItem) return parentItem->getId(); + return 0; + } + GraphContext* context = getContextById(childId); + if (!context) return 0; + QModelIndex inx = mContextTreeModel->getIndexFromContext(context); + if (!inx.isValid()) return 0; + BaseTreeItem* bti =mContextTreeModel->getItemFromIndex(inx); + if (!bti) return 0; + ContextTreeItem* parentItem = dynamic_cast(bti->getParent()); + if (parentItem) return parentItem->getId(); + return 0; + } GraphContext* GraphContextManager::createNewContext(const QString& name, u32 parentId) { @@ -132,8 +151,12 @@ namespace hal ContextDirectory *GraphContextManager::getDirectoryById(u32 id) const { - ContextDirectory * directory = static_cast(mContextTreeModel->getDirectory(id))->directory(); - if (directory) return directory; + BaseTreeItem* bti = mContextTreeModel->getDirectory(id); + if (bti) + { + ContextDirectory* directory = static_cast(bti)->directory(); + if (directory) return directory; + } return nullptr; } diff --git a/plugins/gui/src/user_action/action_delete_object.cpp b/plugins/gui/src/user_action/action_delete_object.cpp index cd88a0e5f95..7d5754f7c8c 100644 --- a/plugins/gui/src/user_action/action_delete_object.cpp +++ b/plugins/gui/src/user_action/action_delete_object.cpp @@ -144,7 +144,10 @@ namespace hal { UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); - act->addAction(new ActionCreateObject(UserActionObjectType::ContextView, ctx->name())); + ActionCreateObject* actCreate = new ActionCreateObject(UserActionObjectType::ContextView, ctx->name()); + actCreate->setObject(UserActionObject(ctx->id(),UserActionObjectType::ContextView)); + actCreate->setParentId(gGraphContextManager->getParentId(ctx->id(),false)); + act->addAction(actCreate); act->addAction(new ActionAddItemsToObject(ctx->modules(), ctx->gates())); act->setParentObject(mParentObject); @@ -163,7 +166,10 @@ namespace hal } else { UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); - act->addAction(new ActionCreateObject(UserActionObjectType::ContextDir, ctxDir->name())); + ActionCreateObject* actCreate = new ActionCreateObject(UserActionObjectType::ContextDir, ctxDir->name()); + actCreate->setObject(UserActionObject(ctxDir->id(),UserActionObjectType::ContextDir)); + actCreate->setParentId(gGraphContextManager->getParentId(ctxDir->id(),true)); + act->addAction(actCreate); act->addAction(new ActionAddItemsToObject({gNetlist->get_top_module()->get_id()}, {})); act->setParentObject(mParentObject); From e05b5c527b518a52b32795dabe23a1ff8204d69a Mon Sep 17 00:00:00 2001 From: joern274 Date: Fri, 3 May 2024 14:07:24 +0200 Subject: [PATCH 26/38] Move context tree items by user action (WIP) --- .../gui/basic_tree_model/base_tree_model.h | 2 + .../context_manager_widget.h | 26 ++- .../models/context_tree_model.h | 15 +- .../gui/graph_widget/graph_context_manager.h | 4 +- .../gui/user_action/action_move_item.h | 74 ++++++ .../gui/include/gui/user_action/user_action.h | 15 -- .../src/basic_tree_model/base_tree_model.cpp | 10 + .../context_manager_widget.cpp | 59 ++++- .../models/context_tree_model.cpp | 211 +++++++++++++++--- .../graph_widget/graph_context_manager.cpp | 23 +- plugins/gui/src/module_model/module_model.cpp | 6 +- .../action_add_items_to_object.cpp | 2 - .../src/user_action/action_create_object.cpp | 4 - .../gui/src/user_action/action_move_item.cpp | 83 +++++++ .../action_remove_items_from_object.cpp | 2 - .../src/user_action/action_rename_object.cpp | 2 - 16 files changed, 458 insertions(+), 80 deletions(-) create mode 100644 plugins/gui/include/gui/user_action/action_move_item.h create mode 100644 plugins/gui/src/user_action/action_move_item.cpp diff --git a/plugins/gui/include/gui/basic_tree_model/base_tree_model.h b/plugins/gui/include/gui/basic_tree_model/base_tree_model.h index 6969ab8d3ab..401aaf3a5e5 100644 --- a/plugins/gui/include/gui/basic_tree_model/base_tree_model.h +++ b/plugins/gui/include/gui/basic_tree_model/base_tree_model.h @@ -146,6 +146,8 @@ namespace hal */ BaseTreeItem* getRootItem() const; + void insertChildItem(BaseTreeItem* childItem, BaseTreeItem* parentItem = nullptr, int row = -1); + protected: RootTreeItem* mRootItem; }; diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index 8ce65434f96..007b4ce1297 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -194,10 +194,21 @@ namespace hal */ void selectDirectory(ContextTreeItem* item); + void handleRowsInserted(const QModelIndex &parent, int first, int last); + private Q_SLOTS: void handleFocusChanged(QWidget* oldWidget, QWidget* newWidget); + void handleCreateClicked(); + void handleCreateContextClicked(); + void handleCreateDirectoryClicked(); + void handleRenameClicked(); + void handleDuplicateContextClicked(); + void handleDeleteClicked(); + void handleMoveToplevelClicked(); + void handleContextMenuRequest(const QPoint& point); + void handleSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); private: GraphTabWidget* mTabView; @@ -234,23 +245,16 @@ namespace hal QString mOpenIconPath; QString mOpenIconStyle; + QAction* mMoveToplevelAction; + QString mMoveToplevelPath; + QString mMoveToplevelStyle; + QString mSearchIconPath; QString mSearchIconStyle; QString mSearchActiveIconStyle; QShortcut* mShortCutDeleteItem; - void handleCreateClicked(); - void handleCreateContextClicked(); - void handleCreateDirectoryClicked(); - void handleRenameClicked(); - void handleDuplicateContextClicked(); - void handleDeleteClicked(); - - - void handleContextMenuRequest(const QPoint& point); - void handleSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); - void setToolbarButtonsEnabled(bool enabled); void toggleSearchbar(); diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h index 192a42848d3..e3c08931632 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h @@ -29,7 +29,7 @@ #include "gui/graph_widget/contexts/graph_context.h" #include "gui/basic_tree_model/base_tree_model.h" - +#include namespace hal { @@ -122,6 +122,8 @@ namespace hal BaseTreeItem* getDirectory(u32 directoryId) const; + BaseTreeItem* getContext(u32 contextId) const; + /** * Adds a given GraphContext to the model. * @@ -163,7 +165,13 @@ namespace hal /** * Resets the model (removes all GraphContext%s). */ - void clear(); + void clear() override; + + Qt::ItemFlags flags(const QModelIndex& index) const override; + QStringList mimeTypes() const override; + QMimeData* mimeData(const QModelIndexList &indexes) const override; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; + bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override; /** * Get all GraphContext%s of the model. @@ -200,12 +208,13 @@ namespace hal */ u32 minDirectoryId() const { return mMinDirectoryId; } + bool moveItem(ContextTreeItem* itemToMove, BaseTreeItem* newParent, int row = -1); Q_SIGNALS: void directoryCreatedSignal(ContextTreeItem* item); private: - BaseTreeItem* getDirectoryInternal(BaseTreeItem* parentItem, u32 directoryId) const; + BaseTreeItem* getItemInternal(BaseTreeItem* parentItem, u32 id, bool isDirectory) const; ContextTreeItem *mCurrentDirectory; std::map mContextMap; QVector mContextList; diff --git a/plugins/gui/include/gui/graph_widget/graph_context_manager.h b/plugins/gui/include/gui/graph_widget/graph_context_manager.h index d1ad735176d..3436290eb02 100644 --- a/plugins/gui/include/gui/graph_widget/graph_context_manager.h +++ b/plugins/gui/include/gui/graph_widget/graph_context_manager.h @@ -123,7 +123,9 @@ namespace hal GraphContext* getContextById(u32 id) const; - u32 getParentId(u32 childId, bool isDirctory) const; + u32 getParentId(u32 childId, bool isDirectory) const; + + bool moveItem(u32 itemId, bool isDirectory, u32 parentId, int row = -1); ContextDirectory* getDirectoryById(u32 id) const; diff --git a/plugins/gui/include/gui/user_action/action_move_item.h b/plugins/gui/include/gui/user_action/action_move_item.h new file mode 100644 index 00000000000..7f77f2116e3 --- /dev/null +++ b/plugins/gui/include/gui/user_action/action_move_item.h @@ -0,0 +1,74 @@ +// MIT License +// +// Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved. +// Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved. +// Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved. +// Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once +#include "user_action.h" +#include +#include + +namespace hal +{ + /** + * @ingroup user_action + * @brief Moves a node. + * + * Moves a node to another grid position in the GraphicsScene. The Context ID should be provided by passing it in + * the UserActionObject of type UserActionObjectType::Context. + * + * Undo Action: ActionMoveItem + */ + class ActionMoveItem : public UserAction + { + u32 mSourceParentId; + u32 mTargetParentId; + + public: + /** + * Action constructor. + * + * Will move the tree item to new parent, + * action object must indicate tree item + */ + ActionMoveItem(u32 tgtId = 0, u32 srcId = 0); + + bool exec() override; + QString tagname() const override; + void writeToXml(QXmlStreamWriter& xmlOut) const override; + void readFromXml(QXmlStreamReader& xmlIn) override; + void addToHash(QCryptographicHash& cryptoHash) const override; + }; + + /** + * @ingroup user_action + * @brief UserActionFactory for ActionMoveItem + */ + class ActionMoveItemFactory : public UserActionFactory + { + public: + ActionMoveItemFactory(); + UserAction* newAction() const; + static ActionMoveItemFactory* sFactory; + }; +} diff --git a/plugins/gui/include/gui/user_action/user_action.h b/plugins/gui/include/gui/user_action/user_action.h index 610e073454b..4fe78a0a0bc 100644 --- a/plugins/gui/include/gui/user_action/user_action.h +++ b/plugins/gui/include/gui/user_action/user_action.h @@ -183,21 +183,6 @@ namespace hal static QString setToText(const QSet& set); static QSet setFromText(const QString& s); - /** - * Utility function to write the parent object. - * (Also checks if it is even necessary) - * - * @param xmlOut - The writer. - */ - void writeParentObjectToXml(QXmlStreamWriter& xmlOut) const; - - /** - * Utility function that can be used to read the parent object - * if necessary. (Also does the checking) - * - * @param xmlIn - The reader. - */ - void readParentObjectFromXml(QXmlStreamReader& xmlIn); }; /** diff --git a/plugins/gui/src/basic_tree_model/base_tree_model.cpp b/plugins/gui/src/basic_tree_model/base_tree_model.cpp index 99df4edf8f0..61dc281dca3 100644 --- a/plugins/gui/src/basic_tree_model/base_tree_model.cpp +++ b/plugins/gui/src/basic_tree_model/base_tree_model.cpp @@ -148,4 +148,14 @@ namespace hal return mRootItem; } + void BaseTreeModel::insertChildItem(BaseTreeItem* childItem, BaseTreeItem* parentItem, int row) + { + if (!parentItem) parentItem = mRootItem; + if (row < 0) row = parentItem->getChildCount(); + QModelIndex index = getIndexFromItem(parentItem); + beginInsertRows(index, row, row); + parentItem->appendChild(childItem); + endInsertRows(); + } + } diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index 7fa52f8764e..a111921d9ba 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -31,6 +31,7 @@ #include "gui/user_action/action_delete_object.h" #include "gui/user_action/action_rename_object.h" #include "gui/user_action/user_action_compound.h" +#include "gui/user_action/action_move_item.h" #include #include #include @@ -39,7 +40,7 @@ namespace hal { ContextManagerWidget::ContextManagerWidget(GraphTabWidget* tab_view, QWidget* parent) : ContentWidget("Views", parent), mSearchbar(new Searchbar(this)), mNewDirectoryAction(new QAction(this)), mNewViewAction(new QAction(this)), mRenameAction(new QAction(this)), mDuplicateAction(new QAction(this)), - mDeleteAction(new QAction(this)), mOpenAction(new QAction(this)) + mDeleteAction(new QAction(this)), mOpenAction(new QAction(this)), mMoveToplevelAction(new QAction(this)) { //needed to load the properties ensurePolished(); @@ -51,22 +52,25 @@ namespace hal mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDuplicateIconStyle, mDuplicateIconPath)); mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); + mMoveToplevelAction->setIcon(gui_utility::getStyledSvgIcon(mMoveToplevelStyle, mMoveToplevelPath)); mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath)); mOpenAction->setToolTip("Open"); - mNewViewAction->setToolTip("New View"); - mNewDirectoryAction->setToolTip("New Directory"); - mRenameAction->setToolTip("Rename view"); + mNewViewAction->setToolTip("New view"); + mNewDirectoryAction->setToolTip("New directory"); + mRenameAction->setToolTip("Rename"); mDuplicateAction->setToolTip("Duplicate"); mDeleteAction->setToolTip("Delete"); + mMoveToplevelAction->setToolTip("to toplevel"); mSearchAction->setToolTip("Search"); mOpenAction->setText("Open view"); mNewViewAction->setText("Create new view"); - mNewDirectoryAction->setText("Create new Directory"); + mNewDirectoryAction->setText("Create new directory"); mRenameAction->setText("Rename item"); mDuplicateAction->setText("Duplicate view"); mDeleteAction->setText("Delete item"); + mMoveToplevelAction->setText("Move to toplevel"); mSearchAction->setText("Search"); //mOpenAction->setEnabled(false); @@ -89,7 +93,9 @@ namespace hal mContextTreeView->sortByColumn(1, Qt::SortOrder::DescendingOrder); mContextTreeView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - + mContextTreeView->setDragEnabled(true); + mContextTreeView->setAcceptDrops(true); + mContextTreeView->setDropIndicatorShown(true); mContentLayout->addWidget(mContextTreeView); mContentLayout->addWidget(mSearchbar); @@ -104,6 +110,7 @@ namespace hal connect(mRenameAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameClicked); connect(mDuplicateAction, &QAction::triggered, this, &ContextManagerWidget::handleDuplicateContextClicked); connect(mDeleteAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteClicked); + connect(mMoveToplevelAction, &QAction::triggered, this, &ContextManagerWidget::handleMoveToplevelClicked); connect(mSearchAction, &QAction::triggered, this, &ContextManagerWidget::toggleSearchbar); connect(mContextTreeView, &QTreeView::customContextMenuRequested, this, &ContextManagerWidget::handleContextMenuRequest); @@ -125,6 +132,7 @@ namespace hal connect(qApp, &QApplication::focusChanged, this, &ContextManagerWidget::handleFocusChanged); connect(mContextTreeModel, &ContextTreeModel::directoryCreatedSignal, this, &ContextManagerWidget::selectDirectory); + connect(mContextTreeModel, &QAbstractItemModel::rowsInserted, this, &ContextManagerWidget::handleRowsInserted); } void ContextManagerWidget::handleCreateContextClicked() @@ -137,6 +145,15 @@ namespace hal act->exec(); } + void ContextManagerWidget::handleRowsInserted(const QModelIndex &parent, int first, int last) + { + mContextTreeView->expand(mContextTreeProxyModel->mapFromSource(parent)); + for (int irow = first; irow <= last; irow++) + { + mContextTreeView->expand(mContextTreeProxyModel->mapFromSource(mContextTreeModel->index(irow,0,parent))); + } + } + void ContextManagerWidget::handleCreateDirectoryClicked() { bool confirm; @@ -158,6 +175,30 @@ namespace hal mTabView->showContext(defaultContext); } + void ContextManagerWidget::handleMoveToplevelClicked() + { + ContextTreeItem* clicked_item = getCurrentItem(); + if (!clicked_item) return; + + UserActionObject uao; + if (clicked_item->isContext()) + uao = UserActionObject(clicked_item->context()->id(), UserActionObjectType::ContextView); + else if (clicked_item->isDirectory()) + uao = UserActionObject(clicked_item->directory()->id(), UserActionObjectType::ContextDir); + else + return; + + BaseTreeItem* bti = clicked_item->getParent(); + while (bti->getParent()) + bti = bti->getParent(); + + ActionMoveItem* act = new ActionMoveItem(0); + act->setObject(uao); + act->exec(); + + mContextTreeModel->moveItem(clicked_item,bti); + } + void ContextManagerWidget::handleItemDoubleClicked(const QModelIndex &proxyIndex) { QModelIndex sourceIndex = mContextTreeProxyModel->mapToSource(proxyIndex); @@ -330,6 +371,10 @@ namespace hal context_menu.addAction(mRenameAction); } + // unless parent is rootItem thus not a ContextTreeItem + if (dynamic_cast(item->getParent())) + context_menu.addAction(mMoveToplevelAction); + context_menu.exec(mContextTreeView->viewport()->mapToGlobal(point)); } @@ -395,8 +440,6 @@ namespace hal toolbar->addAction(mOpenAction); toolbar->addAction(mDuplicateAction); toolbar->addAction(mRenameAction); - toolbar->addAction(mRenameAction); - toolbar->addAction(mDeleteAction); toolbar->addAction(mDeleteAction); toolbar->addAction(mSearchAction); } diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index 38490034369..022345f9bc6 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -3,12 +3,11 @@ #include "gui/gui_globals.h" #include "gui/gui_utils/graphics.h" #include "gui/user_action/action_delete_object.h" - +#include "gui/user_action/action_move_item.h" #include #include - namespace hal { void ContextDirectory::writeToFile(QJsonObject &json) @@ -45,28 +44,22 @@ namespace hal { switch(column) { - case 0: - { - return mDirectory->name(); - } - case 1: - { - return ""; - } + case 0: + return mDirectory->name(); + default: + return ""; } } if(isContext()) { switch(column) { - case 0: - { - return mContext->getNameWithDirtyState(); - } - case 1: - { - return mContext->getTimestamp().toString(Qt::SystemLocaleShortDate); - } + case 0: + return mContext->getNameWithDirtyState(); + case 1: + return mContext->id(); + case 2: + return mContext->getTimestamp().toString(Qt::SystemLocaleShortDate); } } return QVariant(); @@ -99,7 +92,7 @@ namespace hal int ContextTreeItem::getColumnCount() const { - return 2; + return 3; } int ContextTreeItem::row() const @@ -121,7 +114,7 @@ namespace hal ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr), mMinDirectoryId(std::numeric_limits::max()) { - setHeaderLabels(QStringList() << "View Name" << "Timestamp"); + setHeaderLabels(QStringList() << "View Name" << "ID" << "Timestamp"); } QVariant ContextTreeModel::data(const QModelIndex& index, int role) const @@ -162,24 +155,172 @@ namespace hal return QVariant(); } + Qt::ItemFlags ContextTreeModel::flags(const QModelIndex& index) const + { + Qt::ItemFlags baseFlags = BaseTreeModel::flags(index); + return baseFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; + ContextTreeItem* item = dynamic_cast(getItemFromIndex(index)); + if (!item) + return baseFlags | Qt::ItemIsDropEnabled; // root item + + if (item->isContext()) + return baseFlags | Qt::ItemIsDragEnabled; + + if (item->isDirectory()) + return baseFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; + + Q_ASSERT(1==0); + return baseFlags; + } + + QStringList ContextTreeModel::mimeTypes() const + { + QStringList types; + types << "contexttreemodel/item"; + return types; + } + + QMimeData* ContextTreeModel::mimeData(const QModelIndexList& indexes) const + { + QMimeData* retval = new QMimeData; + // only single row allowed + int row = -1; + for (const QModelIndex& inx : indexes) + { + if (row < 0) + row = inx.row(); + else if (row != inx.row()) + return retval; + } + if (row < 0) + return retval; + + BaseTreeItem* bti = getItemFromIndex(indexes.at(0)); + BaseTreeItem* parentItem = bti->getParent(); + ContextTreeItem* item = dynamic_cast(bti); + if (!item) + { + qDebug() << "cannot cast" << indexes.at(0); + return retval; + } + QByteArray encodedData; + QDataStream stream(&encodedData, QIODevice::WriteOnly); + QString type; + int id; + if (item->isDirectory()) + { + id = item->directory()->id(); + type = "dir"; + } + else if (item->isContext()) + { + id = item->context()->id(); + type = "view"; + } + else + Q_ASSERT (1==0); + stream << type << id << row << (quintptr) parentItem; + retval->setText(type); + retval->setData("contexttreemodel/item", encodedData); + return retval; + } + + bool ContextTreeModel::canDropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) const + { + Q_UNUSED(column) + Q_UNUSED(action) + Q_UNUSED(row) + int moveRow = -1; + quintptr moveParent = 0; + if(!mimeData->formats().contains("contexttreemodel/item")) return false; + + BaseTreeItem* targetParentItem = getItemFromIndex(parent); + if (targetParentItem == mRootItem) return true; + ContextTreeItem* parentItem = dynamic_cast(getItemFromIndex(parent)); + if (!parentItem || parentItem->isContext()) return false; + + QString type; + int id; + auto encItem = mimeData->data("contexttreemodel/item"); + QDataStream dataStream(&encItem, QIODevice::ReadOnly); + dataStream >> type >> id >> moveRow >> moveParent; + + if (type == "dir") + { + if (parentItem->isDirectory() && (int) parentItem->directory()->id() == id) + return false; + } + + return true; + } + + bool ContextTreeModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) + { + Q_UNUSED(column); + Q_UNUSED(action); + + QString type; + int id; + int sourceRow = -1; + quintptr sourceParent = 0; + + auto encItem = mimeData->data("contexttreemodel/item"); + QDataStream dataStream(&encItem, QIODevice::ReadOnly); + dataStream >> type >> id >> sourceRow >> sourceParent; + + BaseTreeItem* targetParentItem = getItemFromIndex(parent); + ContextTreeItem* sourceParentItem = dynamic_cast((BaseTreeItem*) sourceParent); + + u32 targetId = 0; + ContextTreeItem* cti = dynamic_cast(targetParentItem); + if (cti) targetId = cti->getId(); + + UserActionObject uao; + + QModelIndex moveInx = index(sourceRow, 0, getIndexFromItem((BaseTreeItem*) sourceParent)); + ContextTreeItem* itemToMove = dynamic_cast(getItemFromIndex(moveInx)); + if (itemToMove->isContext()) + uao = UserActionObject(itemToMove->context()->id(), UserActionObjectType::ContextView); + else if (itemToMove->isDirectory()) + uao = UserActionObject(itemToMove->directory()->id(), UserActionObjectType::ContextDir); + else + return false; + + ActionMoveItem* act = new ActionMoveItem(targetId, sourceParentItem ? sourceParentItem->getId() : 0); + act->setObject(uao); + act->exec(); + return true; + } + + BaseTreeItem* ContextTreeModel::getDirectory(u32 directoryId) const { - return getDirectoryInternal(mRootItem, directoryId); + return getItemInternal(mRootItem, directoryId, true); + } + + BaseTreeItem* ContextTreeModel::getContext(u32 contextId) const + { + return getItemInternal(mRootItem, contextId, true); } - BaseTreeItem* ContextTreeModel::getDirectoryInternal(BaseTreeItem *parentItem, u32 directoryId) const + BaseTreeItem* ContextTreeModel::getItemInternal(BaseTreeItem *parentItem, u32 id, bool isDirectory) const { for (BaseTreeItem* childItem : parentItem->getChildren()) { ContextTreeItem* ctxItem = static_cast(childItem); if (ctxItem->isDirectory()) { - if (ctxItem->getId() == directoryId) + if (ctxItem->getId() == id && isDirectory) return ctxItem; - BaseTreeItem* bti = getDirectoryInternal(childItem, directoryId); + BaseTreeItem* bti = getItemInternal(childItem, id, isDirectory); if (bti) return bti; } + else if (ctxItem->isContext() && !isDirectory) + { + if (ctxItem->getId() == id) + return ctxItem; + } } return nullptr; } @@ -302,7 +443,6 @@ namespace hal act->setObject(UserActionObject(child->directory()->id(),UserActionObjectType::ContextDir)); act->exec(); } - } BaseTreeItem* parent = item->getParent(); @@ -369,4 +509,25 @@ namespace hal mCurrentDirectory = currentItem; } + bool ContextTreeModel::moveItem(ContextTreeItem* itemToMove, BaseTreeItem *newParent, int row) + { + if (!itemToMove || !newParent ) return false; + if (newParent != mRootItem) + { + ContextTreeItem* cti = dynamic_cast(newParent); + if (!cti || !cti->isDirectory()) return false; + } + + BaseTreeItem* oldParent = itemToMove->getParent(); + if (!oldParent) return false; + + int currentRow = itemToMove->row(); + beginRemoveRows(getIndexFromItem(oldParent), currentRow, currentRow); + oldParent->removeChild(itemToMove); + endRemoveRows(); + + insertChildItem(itemToMove, newParent, row); + + return true; + } } diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index 1198551ad57..dba64574e01 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -64,9 +64,28 @@ namespace hal return contextDir; } - u32 GraphContextManager::getParentId(u32 childId, bool isDirctory) const + + bool GraphContextManager::moveItem(u32 itemId, bool isDirectory, u32 parentId, int row) + { + ContextTreeItem* itemToMove = nullptr; + if (isDirectory) + itemToMove = dynamic_cast(mContextTreeModel->getDirectory(itemId)); + else + itemToMove = dynamic_cast(mContextTreeModel->getContext(itemId)); + + BaseTreeItem* parentItem = parentId + ? mContextTreeModel->getDirectory(parentId) + : mContextTreeModel->getRootItem(); + if (!parentItem || !itemToMove) return false; + + return mContextTreeModel->moveItem(itemToMove, parentItem, row); + } + + + + u32 GraphContextManager::getParentId(u32 childId, bool isDirectory) const { - if (isDirctory) + if (isDirectory) { BaseTreeItem* bti = mContextTreeModel->getDirectory(childId); ContextTreeItem* parentItem = dynamic_cast(bti->getParent()); diff --git a/plugins/gui/src/module_model/module_model.cpp b/plugins/gui/src/module_model/module_model.cpp index 28e9de94035..f91d763e9ba 100644 --- a/plugins/gui/src/module_model/module_model.cpp +++ b/plugins/gui/src/module_model/module_model.cpp @@ -714,12 +714,8 @@ namespace hal mModuleItemMaps[(int)itemType]->insertMulti(id,retval); if (!parentItem) parentItem = mRootItem; - QModelIndex index = getIndexFromItem(parentItem); - int row = parentItem->getChildCount(); mIsModifying = true; - beginInsertRows(index, row, row); - parentItem->appendChild(retval); - endInsertRows(); + insertChildItem(retval, parentItem); mIsModifying = false; return retval; diff --git a/plugins/gui/src/user_action/action_add_items_to_object.cpp b/plugins/gui/src/user_action/action_add_items_to_object.cpp index ab6a253f9a8..497a2805359 100644 --- a/plugins/gui/src/user_action/action_add_items_to_object.cpp +++ b/plugins/gui/src/user_action/action_add_items_to_object.cpp @@ -41,7 +41,6 @@ namespace hal void ActionAddItemsToObject::writeToXml(QXmlStreamWriter& xmlOut) const { - writeParentObjectToXml(xmlOut); if (mPlacementHint.mode() != PlacementHint::Standard) { UserActionObjectType::ObjectType tp = UserActionObjectType::fromNodeType(mPlacementHint.preferredOrigin().type()); @@ -65,7 +64,6 @@ namespace hal { while (xmlIn.readNextStartElement()) { - readParentObjectFromXml(xmlIn); if (xmlIn.name() == "placement") { u32 id = xmlIn.attributes().value("id").toInt(); diff --git a/plugins/gui/src/user_action/action_create_object.cpp b/plugins/gui/src/user_action/action_create_object.cpp index 72a78f64e2e..97f60788fd3 100644 --- a/plugins/gui/src/user_action/action_create_object.cpp +++ b/plugins/gui/src/user_action/action_create_object.cpp @@ -39,8 +39,6 @@ namespace hal void ActionCreateObject::writeToXml(QXmlStreamWriter& xmlOut) const { - //todo: remove parentId, switch entirely to parentObject - writeParentObjectToXml(xmlOut); xmlOut.writeTextElement("objectname", mObjectName); xmlOut.writeTextElement("parentid", QString::number(mParentId)); xmlOut.writeTextElement("linkedid", QString::number(mLinkedObjectId)); @@ -50,8 +48,6 @@ namespace hal { while (xmlIn.readNextStartElement()) { - //todo: emove parentId, switch entirely to parentObject - readParentObjectFromXml(xmlIn); if (xmlIn.name() == "objectname") mObjectName = xmlIn.readElementText(); if (xmlIn.name() == "parentid") diff --git a/plugins/gui/src/user_action/action_move_item.cpp b/plugins/gui/src/user_action/action_move_item.cpp new file mode 100644 index 00000000000..ebeb2cefa87 --- /dev/null +++ b/plugins/gui/src/user_action/action_move_item.cpp @@ -0,0 +1,83 @@ +#include "gui/user_action/action_move_item.h" +#include "gui/user_action/user_action_object.h" +#include +#include "gui/graph_widget/contexts/graph_context.h" +#include "gui/gui_globals.h" +#include "gui/graph_widget/layout_locker.h" +#include "gui/implementations/qpoint_extension.h" +#include "hal_core/utilities/log.h" +#include "gui/context_manager_widget/models/context_tree_model.h" + +namespace hal +{ + ActionMoveItemFactory::ActionMoveItemFactory() + : UserActionFactory("MoveNode") {;} + + ActionMoveItemFactory* ActionMoveItemFactory::sFactory = new ActionMoveItemFactory; + + UserAction* ActionMoveItemFactory::newAction() const + { + return new ActionMoveItem; + } + + ActionMoveItem::ActionMoveItem(u32 tgtId, u32 srcId) + : mSourceParentId(srcId), mTargetParentId(tgtId) + {;} + + QString ActionMoveItem::tagname() const + { + return ActionMoveItemFactory::sFactory->tagname(); + } + + void ActionMoveItem::addToHash(QCryptographicHash& cryptoHash) const + { + cryptoHash.addData((char*)(&mTargetParentId), sizeof(u32)); + } + + void ActionMoveItem::writeToXml(QXmlStreamWriter& xmlOut) const + { + xmlOut.writeTextElement("target_parent_id", QString("%1").arg(mTargetParentId)); + if (mSourceParentId) + xmlOut.writeTextElement("source_parent_id", QString("%1").arg(mSourceParentId)); + } + + void ActionMoveItem::readFromXml(QXmlStreamReader& xmlIn) + { + while (xmlIn.readNextStartElement()) + { + if (xmlIn.name() == "target_parent_id") + mTargetParentId = xmlIn.readElementText().toUInt(); + if (xmlIn.name() == "source_parent_id") + mSourceParentId = xmlIn.readElementText().toUInt(); + } + } + + bool ActionMoveItem::exec() + { + if (!mTargetParentId || !mObject.id()) return false; + + BaseTreeItem* bti = nullptr; + + switch (mObject.type()) { + case UserActionObjectType::ContextView: + bti = gGraphContextManager->getContextTreeModel()->getContext(mObject.id()); + break; + case UserActionObjectType::ContextDir: + bti = gGraphContextManager->getContextTreeModel()->getDirectory(mObject.id()); + break; + default: + break; + } + if (!bti) return false; + + if (!mSourceParentId) + { + ContextTreeItem* parCti = dynamic_cast(bti->getParent()); + if (parCti) mSourceParentId = parCti->getId(); + } + + mUndoAction = new ActionMoveItem(mSourceParentId, mTargetParentId); + + return UserAction::exec(); + } +} diff --git a/plugins/gui/src/user_action/action_remove_items_from_object.cpp b/plugins/gui/src/user_action/action_remove_items_from_object.cpp index 03683d937d7..d3598dd3c89 100644 --- a/plugins/gui/src/user_action/action_remove_items_from_object.cpp +++ b/plugins/gui/src/user_action/action_remove_items_from_object.cpp @@ -40,7 +40,6 @@ namespace hal void ActionRemoveItemsFromObject::writeToXml(QXmlStreamWriter& xmlOut) const { - writeParentObjectToXml(xmlOut); if (!mModules.isEmpty()) xmlOut.writeTextElement("modules", setToText(mModules)); if (!mGates.isEmpty()) @@ -55,7 +54,6 @@ namespace hal { while (xmlIn.readNextStartElement()) { - readParentObjectFromXml(xmlIn); if (xmlIn.name() == "modules") mModules = setFromText(xmlIn.readElementText()); else if (xmlIn.name() == "gates") diff --git a/plugins/gui/src/user_action/action_rename_object.cpp b/plugins/gui/src/user_action/action_rename_object.cpp index ba7ad0770c7..b126c331663 100644 --- a/plugins/gui/src/user_action/action_rename_object.cpp +++ b/plugins/gui/src/user_action/action_rename_object.cpp @@ -33,7 +33,6 @@ namespace hal void ActionRenameObject::writeToXml(QXmlStreamWriter& xmlOut) const { - writeParentObjectToXml(xmlOut); xmlOut.writeTextElement("name", mNewName); } @@ -41,7 +40,6 @@ namespace hal { while (xmlIn.readNextStartElement()) { - readParentObjectFromXml(xmlIn); if (xmlIn.name() == "name") mNewName = xmlIn.readElementText(); } From ef0c66cad65376bb7087e158ba59b3b55041c8b3 Mon Sep 17 00:00:00 2001 From: joern274 Date: Sun, 5 May 2024 23:25:21 +0200 Subject: [PATCH 27/38] Additional debug info to trace drop row --- .../context_manager_widget.h | 5 -- .../gui/user_action/action_move_item.h | 3 +- .../src/basic_tree_model/base_tree_item.cpp | 3 +- .../src/basic_tree_model/base_tree_model.cpp | 2 +- .../context_manager_widget.cpp | 36 +------------ .../models/context_tree_model.cpp | 52 +++++++++++++++---- .../gui/src/user_action/action_move_item.cpp | 12 +++-- 7 files changed, 57 insertions(+), 56 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index 007b4ce1297..18d6e995072 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -205,7 +205,6 @@ namespace hal void handleRenameClicked(); void handleDuplicateContextClicked(); void handleDeleteClicked(); - void handleMoveToplevelClicked(); void handleContextMenuRequest(const QPoint& point); void handleSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); @@ -245,10 +244,6 @@ namespace hal QString mOpenIconPath; QString mOpenIconStyle; - QAction* mMoveToplevelAction; - QString mMoveToplevelPath; - QString mMoveToplevelStyle; - QString mSearchIconPath; QString mSearchIconStyle; QString mSearchActiveIconStyle; diff --git a/plugins/gui/include/gui/user_action/action_move_item.h b/plugins/gui/include/gui/user_action/action_move_item.h index 7f77f2116e3..e4073ab216f 100644 --- a/plugins/gui/include/gui/user_action/action_move_item.h +++ b/plugins/gui/include/gui/user_action/action_move_item.h @@ -43,6 +43,7 @@ namespace hal { u32 mSourceParentId; u32 mTargetParentId; + int mTargetRow; public: /** @@ -51,7 +52,7 @@ namespace hal * Will move the tree item to new parent, * action object must indicate tree item */ - ActionMoveItem(u32 tgtId = 0, u32 srcId = 0); + ActionMoveItem(u32 tgtId = 0, u32 srcId = 0, int tgtRow = -1); bool exec() override; QString tagname() const override; diff --git a/plugins/gui/src/basic_tree_model/base_tree_item.cpp b/plugins/gui/src/basic_tree_model/base_tree_item.cpp index 493a803e68a..763304f5cd8 100644 --- a/plugins/gui/src/basic_tree_model/base_tree_item.cpp +++ b/plugins/gui/src/basic_tree_model/base_tree_item.cpp @@ -1,5 +1,5 @@ #include "gui/basic_tree_model/base_tree_item.h" - +#include namespace hal { @@ -45,6 +45,7 @@ namespace hal void BaseTreeItem::insertChild(int index, BaseTreeItem *child) { child->setParent(this); + std::cerr << "...chld " << index << std::endl; mChildren.insert(index, child); } diff --git a/plugins/gui/src/basic_tree_model/base_tree_model.cpp b/plugins/gui/src/basic_tree_model/base_tree_model.cpp index 61dc281dca3..9066ac917f3 100644 --- a/plugins/gui/src/basic_tree_model/base_tree_model.cpp +++ b/plugins/gui/src/basic_tree_model/base_tree_model.cpp @@ -154,7 +154,7 @@ namespace hal if (row < 0) row = parentItem->getChildCount(); QModelIndex index = getIndexFromItem(parentItem); beginInsertRows(index, row, row); - parentItem->appendChild(childItem); + parentItem->insertChild(row,childItem); endInsertRows(); } diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index a111921d9ba..0f553d5a9f1 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -40,7 +40,7 @@ namespace hal { ContextManagerWidget::ContextManagerWidget(GraphTabWidget* tab_view, QWidget* parent) : ContentWidget("Views", parent), mSearchbar(new Searchbar(this)), mNewDirectoryAction(new QAction(this)), mNewViewAction(new QAction(this)), mRenameAction(new QAction(this)), mDuplicateAction(new QAction(this)), - mDeleteAction(new QAction(this)), mOpenAction(new QAction(this)), mMoveToplevelAction(new QAction(this)) + mDeleteAction(new QAction(this)), mOpenAction(new QAction(this)) { //needed to load the properties ensurePolished(); @@ -52,7 +52,6 @@ namespace hal mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mRenameIconStyle, mRenameIconPath)); mDuplicateAction->setIcon(gui_utility::getStyledSvgIcon(mDuplicateIconStyle, mDuplicateIconPath)); mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(mDeleteIconStyle, mDeleteIconPath)); - mMoveToplevelAction->setIcon(gui_utility::getStyledSvgIcon(mMoveToplevelStyle, mMoveToplevelPath)); mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath)); mOpenAction->setToolTip("Open"); @@ -61,7 +60,6 @@ namespace hal mRenameAction->setToolTip("Rename"); mDuplicateAction->setToolTip("Duplicate"); mDeleteAction->setToolTip("Delete"); - mMoveToplevelAction->setToolTip("to toplevel"); mSearchAction->setToolTip("Search"); mOpenAction->setText("Open view"); @@ -70,7 +68,6 @@ namespace hal mRenameAction->setText("Rename item"); mDuplicateAction->setText("Duplicate view"); mDeleteAction->setText("Delete item"); - mMoveToplevelAction->setText("Move to toplevel"); mSearchAction->setText("Search"); //mOpenAction->setEnabled(false); @@ -110,7 +107,6 @@ namespace hal connect(mRenameAction, &QAction::triggered, this, &ContextManagerWidget::handleRenameClicked); connect(mDuplicateAction, &QAction::triggered, this, &ContextManagerWidget::handleDuplicateContextClicked); connect(mDeleteAction, &QAction::triggered, this, &ContextManagerWidget::handleDeleteClicked); - connect(mMoveToplevelAction, &QAction::triggered, this, &ContextManagerWidget::handleMoveToplevelClicked); connect(mSearchAction, &QAction::triggered, this, &ContextManagerWidget::toggleSearchbar); connect(mContextTreeView, &QTreeView::customContextMenuRequested, this, &ContextManagerWidget::handleContextMenuRequest); @@ -175,30 +171,6 @@ namespace hal mTabView->showContext(defaultContext); } - void ContextManagerWidget::handleMoveToplevelClicked() - { - ContextTreeItem* clicked_item = getCurrentItem(); - if (!clicked_item) return; - - UserActionObject uao; - if (clicked_item->isContext()) - uao = UserActionObject(clicked_item->context()->id(), UserActionObjectType::ContextView); - else if (clicked_item->isDirectory()) - uao = UserActionObject(clicked_item->directory()->id(), UserActionObjectType::ContextDir); - else - return; - - BaseTreeItem* bti = clicked_item->getParent(); - while (bti->getParent()) - bti = bti->getParent(); - - ActionMoveItem* act = new ActionMoveItem(0); - act->setObject(uao); - act->exec(); - - mContextTreeModel->moveItem(clicked_item,bti); - } - void ContextManagerWidget::handleItemDoubleClicked(const QModelIndex &proxyIndex) { QModelIndex sourceIndex = mContextTreeProxyModel->mapToSource(proxyIndex); @@ -371,10 +343,6 @@ namespace hal context_menu.addAction(mRenameAction); } - // unless parent is rootItem thus not a ContextTreeItem - if (dynamic_cast(item->getParent())) - context_menu.addAction(mMoveToplevelAction); - context_menu.exec(mContextTreeView->viewport()->mapToGlobal(point)); } @@ -659,6 +627,7 @@ namespace hal void ContextManagerWidget::handleFocusChanged(QWidget* oldWidget, QWidget* newWidget) { + Q_UNUSED(oldWidget); if(!newWidget) return; if(newWidget->parent() == this) { @@ -671,5 +640,4 @@ namespace hal return; } } - } diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index 022345f9bc6..a5b46ebecb8 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -46,6 +46,8 @@ namespace hal { case 0: return mDirectory->name(); + case 1: + return mDirectory->id(); default: return ""; } @@ -230,10 +232,30 @@ namespace hal Q_UNUSED(column) Q_UNUSED(action) Q_UNUSED(row) + + std::cerr << " test " << row << (parent.isValid() ? " valid" : " root") << std::endl; + + if (!parent.isValid()) + return true; // can always drop on root + int moveRow = -1; quintptr moveParent = 0; if(!mimeData->formats().contains("contexttreemodel/item")) return false; +/* + { + if (parent.isValid()) + { + ContextTreeItem* cti = dynamic_cast(getItemFromIndex(parent)); + if (cti) + qDebug() << "drop on " << (cti->isDirectory() ? "directory" : "view") << cti->getId() << row << column; + else + qDebug() << "drop on root " << row << column; + } + else + qDebug() << "drop no parent " << row << column; + } + */ BaseTreeItem* targetParentItem = getItemFromIndex(parent); if (targetParentItem == mRootItem) return true; ContextTreeItem* parentItem = dynamic_cast(getItemFromIndex(parent)); @@ -264,21 +286,15 @@ namespace hal int sourceRow = -1; quintptr sourceParent = 0; + std::cerr << "***drop " << row << (parent.isValid() ? " valid" : " root") << std::endl; auto encItem = mimeData->data("contexttreemodel/item"); QDataStream dataStream(&encItem, QIODevice::ReadOnly); dataStream >> type >> id >> sourceRow >> sourceParent; - - BaseTreeItem* targetParentItem = getItemFromIndex(parent); ContextTreeItem* sourceParentItem = dynamic_cast((BaseTreeItem*) sourceParent); - u32 targetId = 0; - ContextTreeItem* cti = dynamic_cast(targetParentItem); - if (cti) targetId = cti->getId(); - - UserActionObject uao; - QModelIndex moveInx = index(sourceRow, 0, getIndexFromItem((BaseTreeItem*) sourceParent)); ContextTreeItem* itemToMove = dynamic_cast(getItemFromIndex(moveInx)); + UserActionObject uao; if (itemToMove->isContext()) uao = UserActionObject(itemToMove->context()->id(), UserActionObjectType::ContextView); else if (itemToMove->isDirectory()) @@ -286,13 +302,26 @@ namespace hal else return false; - ActionMoveItem* act = new ActionMoveItem(targetId, sourceParentItem ? sourceParentItem->getId() : 0); + u32 targetId = 0; + + if (parent.isValid()) + { + BaseTreeItem* targetParentItem = getItemFromIndex(parent); + ContextTreeItem* cti = dynamic_cast(targetParentItem); + if (cti) + { + if (!cti->isDirectory()) return false; + targetId = cti->directory()->id(); + } + + } + + ActionMoveItem* act = new ActionMoveItem(targetId, sourceParentItem ? sourceParentItem->getId() : 0, row); act->setObject(uao); act->exec(); return true; } - BaseTreeItem* ContextTreeModel::getDirectory(u32 directoryId) const { return getItemInternal(mRootItem, directoryId, true); @@ -300,7 +329,7 @@ namespace hal BaseTreeItem* ContextTreeModel::getContext(u32 contextId) const { - return getItemInternal(mRootItem, contextId, true); + return getItemInternal(mRootItem, contextId, false); } BaseTreeItem* ContextTreeModel::getItemInternal(BaseTreeItem *parentItem, u32 id, bool isDirectory) const @@ -511,6 +540,7 @@ namespace hal bool ContextTreeModel::moveItem(ContextTreeItem* itemToMove, BaseTreeItem *newParent, int row) { + std::cerr << "...move " << row << std::endl; if (!itemToMove || !newParent ) return false; if (newParent != mRootItem) { diff --git a/plugins/gui/src/user_action/action_move_item.cpp b/plugins/gui/src/user_action/action_move_item.cpp index ebeb2cefa87..dbe1ebcebef 100644 --- a/plugins/gui/src/user_action/action_move_item.cpp +++ b/plugins/gui/src/user_action/action_move_item.cpp @@ -20,8 +20,8 @@ namespace hal return new ActionMoveItem; } - ActionMoveItem::ActionMoveItem(u32 tgtId, u32 srcId) - : mSourceParentId(srcId), mTargetParentId(tgtId) + ActionMoveItem::ActionMoveItem(u32 tgtId, u32 srcId, int tgtRow) + : mSourceParentId(srcId), mTargetParentId(tgtId), mTargetRow(tgtRow) {;} QString ActionMoveItem::tagname() const @@ -54,9 +54,11 @@ namespace hal bool ActionMoveItem::exec() { - if (!mTargetParentId || !mObject.id()) return false; + if (!mObject.id()) return false; + std::cerr << " actx " << mTargetRow << std::endl; BaseTreeItem* bti = nullptr; + bool isDirectory = false; switch (mObject.type()) { case UserActionObjectType::ContextView: @@ -64,6 +66,7 @@ namespace hal break; case UserActionObjectType::ContextDir: bti = gGraphContextManager->getContextTreeModel()->getDirectory(mObject.id()); + isDirectory = true; break; default: break; @@ -77,6 +80,9 @@ namespace hal } mUndoAction = new ActionMoveItem(mSourceParentId, mTargetParentId); + mUndoAction->setObject(mObject); + + gGraphContextManager->moveItem(mObject.id(), isDirectory, mTargetParentId, mTargetRow); return UserAction::exec(); } From f38bb1714138b974363efc79fa758aae68e9ce6b Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 8 May 2024 17:35:41 +0200 Subject: [PATCH 28/38] dropMimeData method moved from model to proxy --- .../models/context_proxy_model.h | 10 +- .../models/context_tree_model.h | 9 +- .../context_manager_widget.cpp | 1 - .../models/context_proxy_model.cpp | 198 +++++++++++++++++- .../models/context_tree_model.cpp | 174 +++------------ .../gui/src/user_action/action_move_item.cpp | 6 +- 6 files changed, 240 insertions(+), 158 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_proxy_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_proxy_model.h index 58f6049ca4d..624682aab92 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_proxy_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_proxy_model.h @@ -30,6 +30,7 @@ #include #include +#include namespace hal { @@ -60,6 +61,11 @@ namespace hal */ bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; + QStringList mimeTypes() const override; + QMimeData* mimeData(const QModelIndexList &indexes) const override; + bool dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; + bool canDropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override; + public Q_SLOTS: /** @@ -74,13 +80,13 @@ namespace hal protected: /** - * Defines the compare criteria of 2 data entries (might be defined for each column specifically). + * Defines the compare criteria of tree entries (might be defined for each column specifically). * * @param left - The first entry. * @param right - The seconds entry. * @return True if left < right, False otherwise. */ - bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; + bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; }; } // namespace hal diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h index e3c08931632..3f19afca49d 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h @@ -54,12 +54,10 @@ namespace hal */ void writeToFile(QJsonObject& json); - QString name() const { return mName; } u32 id() const { return mId; } void setId(u32 id_) { mId = id_; } void setName(QString name_) { mName = name_; } - }; class ContextTreeItem : public BaseTreeItem @@ -80,6 +78,8 @@ namespace hal bool isDirectory() const; bool isContext() const; u32 getId() const; + QString getName() const; + QDateTime getTimestamp() const; GraphContext* context() const; ContextDirectory* directory() const; }; @@ -169,9 +169,6 @@ namespace hal Qt::ItemFlags flags(const QModelIndex& index) const override; QStringList mimeTypes() const override; - QMimeData* mimeData(const QModelIndexList &indexes) const override; - bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; - bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override; /** * Get all GraphContext%s of the model. @@ -221,5 +218,7 @@ namespace hal QVector mDirectoryList; u32 mMinDirectoryId; + void dumpRecursion(ContextTreeItem* parent = nullptr, int level = 0) const; + }; } // namespace hal diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index 0f553d5a9f1..b88b2cde8ba 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -87,7 +87,6 @@ namespace hal mContextTreeView->setSelectionBehavior(QAbstractItemView::SelectRows); mContextTreeView->setSelectionMode(QAbstractItemView::SingleSelection); // ERROR ??? mContextTreeView->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); - mContextTreeView->sortByColumn(1, Qt::SortOrder::DescendingOrder); mContextTreeView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); mContextTreeView->setDragEnabled(true); diff --git a/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp b/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp index 4004a4bef64..db0e5497ad0 100644 --- a/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp @@ -1,6 +1,9 @@ #include "gui/context_manager_widget/models/context_proxy_model.h" #include "gui/gui_utils/sort.h" +#include "gui/basic_tree_model/base_tree_model.h" +#include "gui/context_manager_widget/models/context_tree_model.h" +#include "gui/user_action/action_move_item.h" #include @@ -18,13 +21,33 @@ namespace hal bool ContextProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - QVariant leftData = sourceModel()->data(left, Qt::UserRole); - QVariant rightData = sourceModel()->data(right, Qt::UserRole); + BaseTreeModel* model = static_cast(sourceModel()); + if (!model) return false; - if(leftData.userType() == QMetaType::QDateTime) - return leftData.toDateTime() > rightData.toDateTime(); - else - return !(gui_utility::compare(gui_utility::mSortMechanism::natural, leftData.toString(), rightData.toString())); + ContextTreeItem* ctiLeft = dynamic_cast(model->getItemFromIndex(left)); + ContextTreeItem* ctiRight = dynamic_cast(model->getItemFromIndex(right)); + + // root item first + if (!ctiRight) return false; + if (!ctiLeft) return true; + + // directory before view + if (ctiRight->isDirectory() && !ctiLeft->isDirectory()) return false; + if (ctiLeft->isDirectory() && !ctiRight->isDirectory()) return false; + + switch (left.column()) + { + case 0: + return gui_utility::compare(gui_utility::mSortMechanism::numerated, ctiLeft->getName(), ctiRight->getName()); + case 1: + return ctiLeft->getId() < ctiRight->getId(); + case 2: + return ctiLeft->getTimestamp() < ctiRight->getTimestamp(); + default: + break; + } + + return false; } void ContextProxyModel::startSearch(QString text, int options) @@ -33,4 +56,167 @@ namespace hal mSearchOptions = SearchOptions(options); invalidateFilter(); } + + QStringList ContextProxyModel::mimeTypes() const + { + return sourceModel()->mimeTypes(); + } + + QMimeData* ContextProxyModel::mimeData(const QModelIndexList &indexes) const + { + QMimeData* retval = new QMimeData; + // only single row allowed + int row = -1; + for (const QModelIndex& inx : indexes) + { + if (row < 0) + row = inx.row(); + else if (row != inx.row()) + return retval; + } + if (row < 0) + return retval; + + BaseTreeModel* model = static_cast(sourceModel()); + if (!model) return retval; + BaseTreeItem* bti = model->getItemFromIndex(mapToSource(indexes.at(0))); + BaseTreeItem* parentItem = bti->getParent(); + ContextTreeItem* item = dynamic_cast(bti); + if (!item) + { + qDebug() << "cannot cast" << indexes.at(0); + return retval; + } + QByteArray encodedData; + QDataStream stream(&encodedData, QIODevice::WriteOnly); + QString type; + int id; + if (item->isDirectory()) + { + id = item->directory()->id(); + type = "dir"; + } + else if (item->isContext()) + { + id = item->context()->id(); + type = "view"; + } + else + Q_ASSERT (1==0); + stream << type << id << row << (quintptr) parentItem; + retval->setText(type); + retval->setData("contexttreemodel/item", encodedData); + return retval; + + } + + bool ContextProxyModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) + { + Q_UNUSED(column); + Q_UNUSED(action); + + BaseTreeModel* model = static_cast(sourceModel()); + if (!model) return false; + + QString type; + int id; + int sourceRow = -1; + quintptr sourceParent = 0; + + std::cerr << "***drop " << row << (parent.isValid() ? " valid" : " root") << std::endl; + auto encItem = mimeData->data("contexttreemodel/item"); + QDataStream dataStream(&encItem, QIODevice::ReadOnly); + dataStream >> type >> id >> sourceRow >> sourceParent; + ContextTreeItem* sourceParentItem = dynamic_cast((BaseTreeItem*) sourceParent); + u32 sourceParentId = sourceParentItem ? sourceParentItem->getId() : 0; + + QModelIndex moveInx = model->index(sourceRow, 0, model->getIndexFromItem((BaseTreeItem*) sourceParent)); // source model index to item + ContextTreeItem* itemToMove = dynamic_cast(model->getItemFromIndex(moveInx)); + UserActionObject uao; + if (itemToMove->isContext()) + uao = UserActionObject(itemToMove->context()->id(), UserActionObjectType::ContextView); + else if (itemToMove->isDirectory()) + uao = UserActionObject(itemToMove->directory()->id(), UserActionObjectType::ContextDir); + else + return false; + + u32 targetParentId = 0; + + if (parent.isValid()) + { + BaseTreeItem* targetParentItem = model->getItemFromIndex(mapToSource(parent)); + ContextTreeItem* cti = dynamic_cast(targetParentItem); + if (cti) + { + if (!cti->isDirectory()) return false; + targetParentId = cti->directory()->id(); + } + + } + + if (sourceParentId == targetParentId) + { + if (sourceRow == row || sourceRow == row-1) return false; // nothing to do + if (sourceRow < row) row -= 1; // move up, take removed source item into account + } + + ActionMoveItem* act = new ActionMoveItem(targetParentId, sourceParentId, row); + act->setObject(uao); + act->exec(); + + return true; + } + + bool ContextProxyModel::canDropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) const + { + Q_UNUSED(column) + Q_UNUSED(action) + Q_UNUSED(row) + + BaseTreeModel* model = static_cast(sourceModel()); + if (!model) return false; + + std::cerr << " test " << row << (parent.isValid() ? " valid" : " root") << std::endl; + + if (!parent.isValid()) + return true; // can always drop on root + + int moveRow = -1; + quintptr moveParent = 0; + if(!mimeData->formats().contains("contexttreemodel/item")) return false; + +/* + { + if (parent.isValid()) + { + ContextTreeItem* cti = dynamic_cast(getItemFromIndex(parent)); + if (cti) + qDebug() << "drop on " << (cti->isDirectory() ? "directory" : "view") << cti->getId() << row << column; + else + qDebug() << "drop on root " << row << column; + } + else + qDebug() << "drop no parent " << row << column; + } + */ + BaseTreeItem* targetParentItem = model->getItemFromIndex(mapToSource(parent)); + if (targetParentItem == model->getRootItem()) return true; + ContextTreeItem* parentItem = dynamic_cast(targetParentItem); + if (!parentItem || parentItem->isContext()) return false; + + QString type; + int id; + auto encItem = mimeData->data("contexttreemodel/item"); + QDataStream dataStream(&encItem, QIODevice::ReadOnly); + dataStream >> type >> id >> moveRow >> moveParent; + + if (type == "dir") + { + if (parentItem->isDirectory() && (int) parentItem->directory()->id() == id) + return false; + } + + return true; + } + } diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index a5b46ebecb8..9f85e0d748a 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -3,7 +3,6 @@ #include "gui/gui_globals.h" #include "gui/gui_utils/graphics.h" #include "gui/user_action/action_delete_object.h" -#include "gui/user_action/action_move_item.h" #include #include @@ -38,6 +37,19 @@ namespace hal return 0; } + QString ContextTreeItem::getName() const + { + if (mDirectory) return mDirectory->name(); + if (mContext) return mContext->name(); + return QString(); + } + + QDateTime ContextTreeItem::getTimestamp() const + { + if (mContext) return mContext->getTimestamp(); + return QDateTime(); + } + QVariant ContextTreeItem::getData(int column) const { if(isDirectory()) @@ -46,8 +58,6 @@ namespace hal { case 0: return mDirectory->name(); - case 1: - return mDirectory->id(); default: return ""; } @@ -182,146 +192,6 @@ namespace hal return types; } - QMimeData* ContextTreeModel::mimeData(const QModelIndexList& indexes) const - { - QMimeData* retval = new QMimeData; - // only single row allowed - int row = -1; - for (const QModelIndex& inx : indexes) - { - if (row < 0) - row = inx.row(); - else if (row != inx.row()) - return retval; - } - if (row < 0) - return retval; - - BaseTreeItem* bti = getItemFromIndex(indexes.at(0)); - BaseTreeItem* parentItem = bti->getParent(); - ContextTreeItem* item = dynamic_cast(bti); - if (!item) - { - qDebug() << "cannot cast" << indexes.at(0); - return retval; - } - QByteArray encodedData; - QDataStream stream(&encodedData, QIODevice::WriteOnly); - QString type; - int id; - if (item->isDirectory()) - { - id = item->directory()->id(); - type = "dir"; - } - else if (item->isContext()) - { - id = item->context()->id(); - type = "view"; - } - else - Q_ASSERT (1==0); - stream << type << id << row << (quintptr) parentItem; - retval->setText(type); - retval->setData("contexttreemodel/item", encodedData); - return retval; - } - - bool ContextTreeModel::canDropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) const - { - Q_UNUSED(column) - Q_UNUSED(action) - Q_UNUSED(row) - - std::cerr << " test " << row << (parent.isValid() ? " valid" : " root") << std::endl; - - if (!parent.isValid()) - return true; // can always drop on root - - int moveRow = -1; - quintptr moveParent = 0; - if(!mimeData->formats().contains("contexttreemodel/item")) return false; - -/* - { - if (parent.isValid()) - { - ContextTreeItem* cti = dynamic_cast(getItemFromIndex(parent)); - if (cti) - qDebug() << "drop on " << (cti->isDirectory() ? "directory" : "view") << cti->getId() << row << column; - else - qDebug() << "drop on root " << row << column; - } - else - qDebug() << "drop no parent " << row << column; - } - */ - BaseTreeItem* targetParentItem = getItemFromIndex(parent); - if (targetParentItem == mRootItem) return true; - ContextTreeItem* parentItem = dynamic_cast(getItemFromIndex(parent)); - if (!parentItem || parentItem->isContext()) return false; - - QString type; - int id; - auto encItem = mimeData->data("contexttreemodel/item"); - QDataStream dataStream(&encItem, QIODevice::ReadOnly); - dataStream >> type >> id >> moveRow >> moveParent; - - if (type == "dir") - { - if (parentItem->isDirectory() && (int) parentItem->directory()->id() == id) - return false; - } - - return true; - } - - bool ContextTreeModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) - { - Q_UNUSED(column); - Q_UNUSED(action); - - QString type; - int id; - int sourceRow = -1; - quintptr sourceParent = 0; - - std::cerr << "***drop " << row << (parent.isValid() ? " valid" : " root") << std::endl; - auto encItem = mimeData->data("contexttreemodel/item"); - QDataStream dataStream(&encItem, QIODevice::ReadOnly); - dataStream >> type >> id >> sourceRow >> sourceParent; - ContextTreeItem* sourceParentItem = dynamic_cast((BaseTreeItem*) sourceParent); - - QModelIndex moveInx = index(sourceRow, 0, getIndexFromItem((BaseTreeItem*) sourceParent)); - ContextTreeItem* itemToMove = dynamic_cast(getItemFromIndex(moveInx)); - UserActionObject uao; - if (itemToMove->isContext()) - uao = UserActionObject(itemToMove->context()->id(), UserActionObjectType::ContextView); - else if (itemToMove->isDirectory()) - uao = UserActionObject(itemToMove->directory()->id(), UserActionObjectType::ContextDir); - else - return false; - - u32 targetId = 0; - - if (parent.isValid()) - { - BaseTreeItem* targetParentItem = getItemFromIndex(parent); - ContextTreeItem* cti = dynamic_cast(targetParentItem); - if (cti) - { - if (!cti->isDirectory()) return false; - targetId = cti->directory()->id(); - } - - } - - ActionMoveItem* act = new ActionMoveItem(targetId, sourceParentItem ? sourceParentItem->getId() : 0, row); - act->setObject(uao); - act->exec(); - return true; - } - BaseTreeItem* ContextTreeModel::getDirectory(u32 directoryId) const { return getItemInternal(mRootItem, directoryId, true); @@ -558,6 +428,24 @@ namespace hal insertChildItem(itemToMove, newParent, row); + dumpRecursion(); return true; } + + void ContextTreeModel::dumpRecursion(ContextTreeItem *parent, int level) const + { + BaseTreeItem* bti = parent; + for (int i=0; iisDirectory()) + std::cerr << parent->directory()->name().toStdString() << std::endl; + else + std::cerr << "[" << parent->context()->name().toStdString() << "] " << parent->context()->id() << std::endl; + } + if (!parent) bti = mRootItem; + for (BaseTreeItem* cld : bti->getChildren()) + dumpRecursion(dynamic_cast(cld), level+1); + } } diff --git a/plugins/gui/src/user_action/action_move_item.cpp b/plugins/gui/src/user_action/action_move_item.cpp index dbe1ebcebef..b8d9bd56de0 100644 --- a/plugins/gui/src/user_action/action_move_item.cpp +++ b/plugins/gui/src/user_action/action_move_item.cpp @@ -79,7 +79,11 @@ namespace hal if (parCti) mSourceParentId = parCti->getId(); } - mUndoAction = new ActionMoveItem(mSourceParentId, mTargetParentId); + int sourceRow = 0; + QModelIndex sourceIndex = gGraphContextManager->getContextTreeModel()->getIndexFromItem(bti); + if (sourceIndex.isValid()) + sourceRow = sourceIndex.row(); + mUndoAction = new ActionMoveItem(mSourceParentId, mTargetParentId, sourceRow); mUndoAction->setObject(mObject); gGraphContextManager->moveItem(mObject.id(), isDirectory, mTargetParentId, mTargetRow); From 0f0e5d15420646b95953d7431ff0be54f68c8f46 Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 8 May 2024 23:29:12 +0200 Subject: [PATCH 29/38] Debug messages removed --- plugins/gui/src/basic_tree_model/base_tree_item.cpp | 1 - .../src/context_manager_widget/context_manager_widget.cpp | 3 +++ .../context_manager_widget/models/context_proxy_model.cpp | 8 ++++---- .../context_manager_widget/models/context_tree_model.cpp | 3 +-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/plugins/gui/src/basic_tree_model/base_tree_item.cpp b/plugins/gui/src/basic_tree_model/base_tree_item.cpp index 763304f5cd8..17bc9a78d64 100644 --- a/plugins/gui/src/basic_tree_model/base_tree_item.cpp +++ b/plugins/gui/src/basic_tree_model/base_tree_item.cpp @@ -45,7 +45,6 @@ namespace hal void BaseTreeItem::insertChild(int index, BaseTreeItem *child) { child->setParent(this); - std::cerr << "...chld " << index << std::endl; mChildren.insert(index, child); } diff --git a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp index b88b2cde8ba..bdf7d86c20b 100644 --- a/plugins/gui/src/context_manager_widget/context_manager_widget.cpp +++ b/plugins/gui/src/context_manager_widget/context_manager_widget.cpp @@ -93,6 +93,9 @@ namespace hal mContextTreeView->setAcceptDrops(true); mContextTreeView->setDropIndicatorShown(true); + mContextTreeView->header()->setSortIndicator(-1, Qt::AscendingOrder); + mContextTreeView->header()->setSortIndicatorShown(false); + mContentLayout->addWidget(mContextTreeView); mContentLayout->addWidget(mSearchbar); diff --git a/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp b/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp index db0e5497ad0..f6343c7fd57 100644 --- a/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp @@ -79,7 +79,10 @@ namespace hal BaseTreeModel* model = static_cast(sourceModel()); if (!model) return retval; - BaseTreeItem* bti = model->getItemFromIndex(mapToSource(indexes.at(0))); + + QModelIndex sourceIndex = mapToSource(indexes.at(0)); + BaseTreeItem* bti = model->getItemFromIndex(sourceIndex); + row = sourceIndex.row(); BaseTreeItem* parentItem = bti->getParent(); ContextTreeItem* item = dynamic_cast(bti); if (!item) @@ -123,7 +126,6 @@ namespace hal int sourceRow = -1; quintptr sourceParent = 0; - std::cerr << "***drop " << row << (parent.isValid() ? " valid" : " root") << std::endl; auto encItem = mimeData->data("contexttreemodel/item"); QDataStream dataStream(&encItem, QIODevice::ReadOnly); dataStream >> type >> id >> sourceRow >> sourceParent; @@ -176,8 +178,6 @@ namespace hal BaseTreeModel* model = static_cast(sourceModel()); if (!model) return false; - std::cerr << " test " << row << (parent.isValid() ? " valid" : " root") << std::endl; - if (!parent.isValid()) return true; // can always drop on root diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index 9f85e0d748a..a930e3968f1 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -410,7 +410,6 @@ namespace hal bool ContextTreeModel::moveItem(ContextTreeItem* itemToMove, BaseTreeItem *newParent, int row) { - std::cerr << "...move " << row << std::endl; if (!itemToMove || !newParent ) return false; if (newParent != mRootItem) { @@ -428,7 +427,7 @@ namespace hal insertChildItem(itemToMove, newParent, row); - dumpRecursion(); + // dumpRecursion(); return true; } From af24cf1dd38662f58af414ba289895eef26f681b Mon Sep 17 00:00:00 2001 From: joern274 Date: Thu, 16 May 2024 10:00:11 +0200 Subject: [PATCH 30/38] Debug output removed --- plugins/gui/src/user_action/action_move_item.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/gui/src/user_action/action_move_item.cpp b/plugins/gui/src/user_action/action_move_item.cpp index b8d9bd56de0..567768da93e 100644 --- a/plugins/gui/src/user_action/action_move_item.cpp +++ b/plugins/gui/src/user_action/action_move_item.cpp @@ -56,7 +56,6 @@ namespace hal { if (!mObject.id()) return false; - std::cerr << " actx " << mTargetRow << std::endl; BaseTreeItem* bti = nullptr; bool isDirectory = false; From 2390bd8c0776a171bed3e64a1a3a9e7a8de93e7b Mon Sep 17 00:00:00 2001 From: joern274 Date: Thu, 30 May 2024 17:47:22 +0200 Subject: [PATCH 31/38] Fix MacOS build (remove not-implemented function header) --- .../include/gui/context_manager_widget/context_manager_widget.h | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h index 18d6e995072..4be01c06758 100644 --- a/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h +++ b/plugins/gui/include/gui/context_manager_widget/context_manager_widget.h @@ -199,7 +199,6 @@ namespace hal private Q_SLOTS: void handleFocusChanged(QWidget* oldWidget, QWidget* newWidget); - void handleCreateClicked(); void handleCreateContextClicked(); void handleCreateDirectoryClicked(); void handleRenameClicked(); From 1194a35c9715b5d77f67739ef8bb5ad66c2a82de Mon Sep 17 00:00:00 2001 From: Skaleee <78816681+Skaleee@users.noreply.github.com> Date: Sat, 8 Jun 2024 21:50:43 +0200 Subject: [PATCH 32/38] Added experimental python bindings for view-directory management. --- .../models/context_tree_model.h | 7 ++++ plugins/gui/include/gui/gui_api/gui_api.h | 11 ++++-- .../models/context_tree_model.cpp | 9 ++++- plugins/gui/src/gui_api/gui_api.cpp | 36 +++++++++++++++++++ .../src/python/python_gui_api_bindings.cpp | 25 +++++++++++++ 5 files changed, 85 insertions(+), 3 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h index 3f19afca49d..e912a088f5e 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h @@ -191,6 +191,13 @@ namespace hal */ void setCurrentDirectory(ContextTreeItem* currentItem); + /** + * Gets the CurrentDirectory. + * + * @return current directory. + */ + ContextTreeItem* getCurrentDirectory(); + /** * Sets the MinDirectoryId. * diff --git a/plugins/gui/include/gui/gui_api/gui_api.h b/plugins/gui/include/gui/gui_api/gui_api.h index c01f4acdc7a..8e7fc2ea10d 100644 --- a/plugins/gui/include/gui/gui_api/gui_api.h +++ b/plugins/gui/include/gui/gui_api/gui_api.h @@ -64,6 +64,14 @@ namespace hal static GridPlacement* getGridPlacement(int viewId); static bool setGridPlacement(int viewId, GridPlacement* gp); }; + + class Directory{ + public: + static int getCurrentDirectory(); + static void setCurrentDirectory(int id); + static int createNewDirectory(const std::string& name); + static void deleteDirectory(int id); + }; } @@ -561,8 +569,7 @@ namespace hal */ void deselect(const std::vector& gates, const std::vector& nets, const std::vector& modules); - int isolateInNewView(const std::vector, const std::vector); - + Q_SIGNALS: /** * Q_SIGNAL that is emitted whenever the view should be moved to a new selection. diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index a930e3968f1..b173a62c5af 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -401,13 +401,20 @@ namespace hal void ContextTreeModel::setCurrentDirectory(ContextTreeItem* currentItem) { - if(currentItem->isContext()) + if(currentItem == nullptr) + mCurrentDirectory = nullptr; // top-level directory + else if(currentItem->isContext()) mCurrentDirectory = (currentItem->getParent() == mRootItem) ? nullptr : static_cast(currentItem->getParent()); else if (currentItem->isDirectory()) mCurrentDirectory = currentItem; } + ContextTreeItem* ContextTreeModel::getCurrentDirectory() + { + return mCurrentDirectory; + } + bool ContextTreeModel::moveItem(ContextTreeItem* itemToMove, BaseTreeItem *newParent, int row) { if (!itemToMove || !newParent ) return false; diff --git a/plugins/gui/src/gui_api/gui_api.cpp b/plugins/gui/src/gui_api/gui_api.cpp index b29d5103e38..4d52bd42639 100644 --- a/plugins/gui/src/gui_api/gui_api.cpp +++ b/plugins/gui/src/gui_api/gui_api.cpp @@ -935,4 +935,40 @@ namespace hal return true; } + + int GuiApiClasses::Directory::getCurrentDirectory() + { + auto currentDirectory = gGraphContextManager->getContextTreeModel()->getCurrentDirectory(); + if(currentDirectory == nullptr) + return 0; + else + { + if(currentDirectory->directory() == nullptr) + return 0; + return currentDirectory->directory()->id(); + } + } + + void GuiApiClasses::Directory::setCurrentDirectory(int id) + { + ContextTreeItem* directory = static_cast(gGraphContextManager->getContextTreeModel()->getDirectory(id)); + gGraphContextManager->getContextTreeModel()->setCurrentDirectory(directory); + } + + int GuiApiClasses::Directory::createNewDirectory(const std::string& name) + { + ActionCreateObject* act = new ActionCreateObject(UserActionObjectType::ContextDir, QString::fromStdString(name)); + act->exec(); + auto id = act->object().id(); + return id; + } + + void GuiApiClasses::Directory::deleteDirectory(int id){ + /*ContextDirectory* directory = gGraphContextManager->getDirectoryById(id); + if(directory) + gGraphContextManager->deleteContextDirectory(directory);*/ + ActionDeleteObject* act = new ActionDeleteObject(); + act->setObject(UserActionObject(id, UserActionObjectType::ContextDir)); + act->exec(); + } } diff --git a/plugins/gui/src/python/python_gui_api_bindings.cpp b/plugins/gui/src/python/python_gui_api_bindings.cpp index 7086ec44334..2804838b3a3 100644 --- a/plugins/gui/src/python/python_gui_api_bindings.cpp +++ b/plugins/gui/src/python/python_gui_api_bindings.cpp @@ -230,6 +230,31 @@ PYBIND11_PLUGIN(hal_gui) )"); + py::class_(py_gui_api, "Directory") + .def_static("getCurrentDirectory", &GuiApiClasses::Directory::getCurrentDirectory,R"( + Gets the CurrentDirectory. + + :returns: ID of the current directory. 0, if it's the top level directory. + :rtype: int +)") + .def_static("setCurrentDirectory", &GuiApiClasses::Directory::setCurrentDirectory, py::arg("id"), R"( + Sets the CurrentDirectory. + + :param int id ID of the new current directory. +)") + .def_static("createNewDirectory", &GuiApiClasses::Directory::createNewDirectory, py::arg("name"), R"( + Creates a new directory under the current directory. + + :param string name: Name of the new directory. + :returns: ID of the new directory. + :rtype: int +)") + .def_static("deleteDirectory", &GuiApiClasses::Directory::deleteDirectory, py::arg("id"), R"( + Deletes the directory specified by a given id. + + :param int id: ID of the directory to delete. +)"); + py_gui_api.def("getSelectedGateIds", &GuiApi::getSelectedGateIds, R"( Get the gate ids of currently selected gates in the graph view of the GUI. From 82e31f64bf2f72123f497bef1a275f797f7371fb Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 10 Jun 2024 15:28:42 +0200 Subject: [PATCH 33/38] Bugfix: Python thread must block thread when executing user actions --- plugins/gui/src/gui_api/gui_api.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/gui/src/gui_api/gui_api.cpp b/plugins/gui/src/gui_api/gui_api.cpp index 4d52bd42639..52094b4e020 100644 --- a/plugins/gui/src/gui_api/gui_api.cpp +++ b/plugins/gui/src/gui_api/gui_api.cpp @@ -931,8 +931,7 @@ namespace hal bool GuiApiClasses::View::setGridPlacement(int viewId, GridPlacement *gp) { ActionMoveNode* act = new ActionMoveNode(viewId, gp); - act->exec(); - + UserActionManager::instance()->executeActionBlockThread(act); return true; } @@ -958,7 +957,7 @@ namespace hal int GuiApiClasses::Directory::createNewDirectory(const std::string& name) { ActionCreateObject* act = new ActionCreateObject(UserActionObjectType::ContextDir, QString::fromStdString(name)); - act->exec(); + UserActionManager::instance()->executeActionBlockThread(act); auto id = act->object().id(); return id; } @@ -969,6 +968,6 @@ namespace hal gGraphContextManager->deleteContextDirectory(directory);*/ ActionDeleteObject* act = new ActionDeleteObject(); act->setObject(UserActionObject(id, UserActionObjectType::ContextDir)); - act->exec(); + UserActionManager::instance()->executeActionBlockThread(act); } } From 962781a466231d64930c6b9f640592e97f1597fd Mon Sep 17 00:00:00 2001 From: Skaleee <78816681+Skaleee@users.noreply.github.com> Date: Wed, 12 Jun 2024 23:39:08 +0200 Subject: [PATCH 34/38] 1. Moved bindings from gui.Directory to gui.View 2. Implemented move-bindings --- plugins/gui/include/gui/gui_api/gui_api.h | 14 ++--- .../models/context_tree_model.cpp | 2 + plugins/gui/src/gui_api/gui_api.cpp | 52 +++++++++++++++++-- .../src/python/python_gui_api_bindings.cpp | 31 +++++++---- 4 files changed, 78 insertions(+), 21 deletions(-) diff --git a/plugins/gui/include/gui/gui_api/gui_api.h b/plugins/gui/include/gui/gui_api/gui_api.h index 8e7fc2ea10d..062ef464122 100644 --- a/plugins/gui/include/gui/gui_api/gui_api.h +++ b/plugins/gui/include/gui/gui_api/gui_api.h @@ -35,6 +35,7 @@ #include #include #include +#include namespace hal { @@ -63,14 +64,13 @@ namespace hal static ModuleGateIdPair getValidObjects(int viewId, const std::vector, const std::vector); static GridPlacement* getGridPlacement(int viewId); static bool setGridPlacement(int viewId, GridPlacement* gp); - }; - class Directory{ - public: - static int getCurrentDirectory(); - static void setCurrentDirectory(int id); - static int createNewDirectory(const std::string& name); - static void deleteDirectory(int id); + static u32 getCurrentDirectory(); + static void setCurrentDirectory(u32 id); + static u32 createNewDirectory(const std::string& name); + static void deleteDirectory(u32 id); + static void moveView(u32 viewId, std::optional destinationDirectoryId, std::optional row); + static void moveDirectory(u32 directoryId, std::optional destinationDirectoryId, std::optional row); }; } diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index b173a62c5af..27c1ec2f252 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -58,6 +58,8 @@ namespace hal { case 0: return mDirectory->name(); + case 1: + return mDirectory->id(); default: return ""; } diff --git a/plugins/gui/src/gui_api/gui_api.cpp b/plugins/gui/src/gui_api/gui_api.cpp index 52094b4e020..a9937851b66 100644 --- a/plugins/gui/src/gui_api/gui_api.cpp +++ b/plugins/gui/src/gui_api/gui_api.cpp @@ -13,6 +13,7 @@ #include "gui/user_action/action_fold_module.h" #include "gui/user_action/action_unfold_module.h" #include "gui/user_action/action_move_node.h" +#include "gui/user_action/action_move_item.h" #include "gui/graph_widget/graph_context_manager.h" #include "gui/context_manager_widget/models/context_tree_model.h" #include "hal_core/utilities/log.h" @@ -935,7 +936,7 @@ namespace hal return true; } - int GuiApiClasses::Directory::getCurrentDirectory() + u32 GuiApiClasses::View::getCurrentDirectory() { auto currentDirectory = gGraphContextManager->getContextTreeModel()->getCurrentDirectory(); if(currentDirectory == nullptr) @@ -948,13 +949,13 @@ namespace hal } } - void GuiApiClasses::Directory::setCurrentDirectory(int id) + void GuiApiClasses::View::setCurrentDirectory(u32 id) { ContextTreeItem* directory = static_cast(gGraphContextManager->getContextTreeModel()->getDirectory(id)); gGraphContextManager->getContextTreeModel()->setCurrentDirectory(directory); } - int GuiApiClasses::Directory::createNewDirectory(const std::string& name) + u32 GuiApiClasses::View::createNewDirectory(const std::string& name) { ActionCreateObject* act = new ActionCreateObject(UserActionObjectType::ContextDir, QString::fromStdString(name)); UserActionManager::instance()->executeActionBlockThread(act); @@ -962,7 +963,8 @@ namespace hal return id; } - void GuiApiClasses::Directory::deleteDirectory(int id){ + void GuiApiClasses::View::deleteDirectory(u32 id) + { /*ContextDirectory* directory = gGraphContextManager->getDirectoryById(id); if(directory) gGraphContextManager->deleteContextDirectory(directory);*/ @@ -970,4 +972,46 @@ namespace hal act->setObject(UserActionObject(id, UserActionObjectType::ContextDir)); UserActionManager::instance()->executeActionBlockThread(act); } + + void GuiApiClasses::View::moveView(u32 viewId, std::optional destinationDirectoryId, std::optional row) + { + BaseTreeItem* viewItem = gGraphContextManager->getContextTreeModel()->getContext(viewId); + if(!viewItem) + return; + + u32 parentId = 0; + BaseTreeItem* parentItem = viewItem->getParent(); + if(parentItem && gGraphContextManager->getContextTreeModel()->getRootItem() != parentItem) + parentId = dynamic_cast(parentItem)->getId(); + + UserActionObject uao = UserActionObject(viewId, UserActionObjectType::ContextView); + ActionMoveItem* act; + if(row.has_value()) + act = new ActionMoveItem(destinationDirectoryId.value_or(getCurrentDirectory()), parentId, row.value()); + else + act = new ActionMoveItem(destinationDirectoryId.value_or(getCurrentDirectory()), parentId); + act->setObject(uao); + act->exec(); + } + + void GuiApiClasses::View::moveDirectory(u32 directoryId, std::optional destinationDirectoryId, std::optional row) + { + BaseTreeItem* directoryItem = gGraphContextManager->getContextTreeModel()->getDirectory(directoryId); + if(!directoryItem) + return; + + u32 parentId = 0; + BaseTreeItem* parentItem = directoryItem->getParent(); + if(parentItem && gGraphContextManager->getContextTreeModel()->getRootItem() != parentItem) + parentId = dynamic_cast(parentItem)->getId(); + + UserActionObject uao = UserActionObject(directoryId, UserActionObjectType::ContextDir); + ActionMoveItem* act; + if(row.has_value()) + act = new ActionMoveItem(destinationDirectoryId.value_or(getCurrentDirectory()), parentId, row.value()); + else + act = new ActionMoveItem(destinationDirectoryId.value_or(getCurrentDirectory()), parentId); + act->setObject(uao); + act->exec(); + } } diff --git a/plugins/gui/src/python/python_gui_api_bindings.cpp b/plugins/gui/src/python/python_gui_api_bindings.cpp index 2804838b3a3..328882b9c78 100644 --- a/plugins/gui/src/python/python_gui_api_bindings.cpp +++ b/plugins/gui/src/python/python_gui_api_bindings.cpp @@ -219,40 +219,51 @@ PYBIND11_PLUGIN(hal_gui) :returns: GridPlacement of the specified view. :rtype: GridPlacement )") - - .def_static("setGridPlacement", &GuiApiClasses::View::setGridPlacement, py::arg("view_id"), py::arg("grid placement"), R"( Set grid placement to the view specified by id :param int viewId ID of the view. :param GridPlacement* gp: grid placement. :rtype: bool -)"); - - - py::class_(py_gui_api, "Directory") - .def_static("getCurrentDirectory", &GuiApiClasses::Directory::getCurrentDirectory,R"( +)") + .def_static("getCurrentDirectory", &GuiApiClasses::View::getCurrentDirectory,R"( Gets the CurrentDirectory. :returns: ID of the current directory. 0, if it's the top level directory. :rtype: int )") - .def_static("setCurrentDirectory", &GuiApiClasses::Directory::setCurrentDirectory, py::arg("id"), R"( + .def_static("setCurrentDirectory", &GuiApiClasses::View::setCurrentDirectory, py::arg("id"), R"( Sets the CurrentDirectory. :param int id ID of the new current directory. )") - .def_static("createNewDirectory", &GuiApiClasses::Directory::createNewDirectory, py::arg("name"), R"( + .def_static("createNewDirectory", &GuiApiClasses::View::createNewDirectory, py::arg("name"), R"( Creates a new directory under the current directory. :param string name: Name of the new directory. :returns: ID of the new directory. :rtype: int )") - .def_static("deleteDirectory", &GuiApiClasses::Directory::deleteDirectory, py::arg("id"), R"( + .def_static("deleteDirectory", &GuiApiClasses::View::deleteDirectory, py::arg("id"), R"( Deletes the directory specified by a given id. :param int id: ID of the directory to delete. +)") + .def_static("moveView", &GuiApiClasses::View::moveView, py::arg("viewId"), py::arg("destinationDirectoryId") = py::none(), py::arg("row") = py::none(), R"( + Moves a view to a directory. + + :param int viewId: ID of the view to move. + :param int destinationDirectoryId: ID of the destination directory to which the view will be moved. + If None, the view is instead moved to the current directory. + :param int row: The row index in the parent directory, where the view will be inserted. +)") + .def_static("moveDirectory", &GuiApiClasses::View::moveDirectory, py::arg("directoryId"), py::arg("destinationDirectoryId") = py::none(), py::arg("row") = py::none(), R"( + Moves a directory under another directory. + + :param int directoryId: ID of the directory to move. + :param int destinationDirectoryId: ID of the destination directory to which the directory will be moved. + If None, the directory is instead moved to the current directory. + :param int row: The row index in the parent directory, where the directory will be inserted. )"); From ac4c8a622ee36dfc67f325036314cc72c7e94a15 Mon Sep 17 00:00:00 2001 From: joern274 Date: Thu, 13 Jun 2024 17:46:55 +0200 Subject: [PATCH 35/38] disallow drop of directory into one of its (grand-)child directories --- .../models/context_proxy_model.cpp | 44 +++++++++++-------- .../models/context_tree_model.cpp | 1 - 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp b/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp index f6343c7fd57..a61a803cf83 100644 --- a/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp @@ -1,4 +1,4 @@ -#include "gui/context_manager_widget/models/context_proxy_model.h" +#include "gui/context_manager_widget/models/context_proxy_model.h" #include "gui/gui_utils/sort.h" #include "gui/basic_tree_model/base_tree_model.h" @@ -92,22 +92,22 @@ namespace hal } QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); - QString type; + QString moveType; int id; if (item->isDirectory()) { id = item->directory()->id(); - type = "dir"; + moveType = "dir"; } else if (item->isContext()) { id = item->context()->id(); - type = "view"; + moveType = "view"; } else Q_ASSERT (1==0); - stream << type << id << row << (quintptr) parentItem; - retval->setText(type); + stream << moveType << id << row << (quintptr) parentItem; + retval->setText(moveType); retval->setData("contexttreemodel/item", encodedData); return retval; @@ -121,14 +121,14 @@ namespace hal BaseTreeModel* model = static_cast(sourceModel()); if (!model) return false; - QString type; - int id; + QString moveType; + int moveId; int sourceRow = -1; quintptr sourceParent = 0; auto encItem = mimeData->data("contexttreemodel/item"); QDataStream dataStream(&encItem, QIODevice::ReadOnly); - dataStream >> type >> id >> sourceRow >> sourceParent; + dataStream >> moveType >> moveId >> sourceRow >> sourceParent; ContextTreeItem* sourceParentItem = dynamic_cast((BaseTreeItem*) sourceParent); u32 sourceParentId = sourceParentItem ? sourceParentItem->getId() : 0; @@ -199,21 +199,27 @@ namespace hal qDebug() << "drop no parent " << row << column; } */ - BaseTreeItem* targetParentItem = model->getItemFromIndex(mapToSource(parent)); - if (targetParentItem == model->getRootItem()) return true; - ContextTreeItem* parentItem = dynamic_cast(targetParentItem); - if (!parentItem || parentItem->isContext()) return false; + BaseTreeItem* tpar = model->getItemFromIndex(mapToSource(parent)); + if (tpar == model->getRootItem()) return true; + ContextTreeItem* targetParentItem = dynamic_cast(tpar); + if (!targetParentItem || targetParentItem->isContext()) return false; - QString type; - int id; + QString moveType; + int moveId; auto encItem = mimeData->data("contexttreemodel/item"); QDataStream dataStream(&encItem, QIODevice::ReadOnly); - dataStream >> type >> id >> moveRow >> moveParent; + dataStream >> moveType >> moveId >> moveRow >> moveParent; - if (type == "dir") + if (moveType == "dir") { - if (parentItem->isDirectory() && (int) parentItem->directory()->id() == id) - return false; + // target must not be the item itself or any (grand-)child of the item + ContextTreeItem* targetAnchestorItem = targetParentItem; + while (targetAnchestorItem) + { + if (targetAnchestorItem->isDirectory() && (int) targetAnchestorItem->directory()->id() == moveId) + return false; + targetAnchestorItem = dynamic_cast(targetAnchestorItem->getParent()); + } } return true; diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index 27c1ec2f252..46afb5d9c5f 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -228,7 +228,6 @@ namespace hal ContextDirectory* ContextTreeModel::addDirectory(QString name, BaseTreeItem *parent, u32 id) { - if(id == 0) id = --mMinDirectoryId; else if (id < mMinDirectoryId) From 873d674f1abb7443654119873e7a5af09bfa19f8 Mon Sep 17 00:00:00 2001 From: Skaleee <78816681+Skaleee@users.noreply.github.com> Date: Sat, 15 Jun 2024 18:37:00 +0200 Subject: [PATCH 36/38] 1. Changed directory IDs to be positive. IDs of new directories do not overlap with view-IDs. 2. Implemented bindings for getting the child views and directories of a given directory. --- .../models/context_tree_model.h | 44 ++++++++++------- plugins/gui/include/gui/gui_api/gui_api.h | 3 ++ .../models/context_tree_model.cpp | 49 +++++++++++++++---- .../graph_widget/graph_context_manager.cpp | 8 +-- plugins/gui/src/gui_api/gui_api.cpp | 18 +++++++ .../src/python/python_gui_api_bindings.cpp | 16 ++++++ 6 files changed, 109 insertions(+), 29 deletions(-) diff --git a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h index e912a088f5e..756fe944257 100644 --- a/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h +++ b/plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h @@ -112,17 +112,18 @@ namespace hal QVariant data(const QModelIndex& inddex, int role = Qt::DisplayRole) const override; ///@} + BaseTreeItem* getDirectory(u32 directoryId) const; + + BaseTreeItem* getContext(u32 contextId) const; + /** * Adds a directory to the model. * * @param name - The name to the directory. - * @param parent - The Parent of the directory. + * @param parentItem - The parent of the directory. + * @param id - The id of the directory. */ - ContextDirectory* addDirectory(QString name, BaseTreeItem* parent = nullptr, u32 id = 0); - - BaseTreeItem* getDirectory(u32 directoryId) const; - - BaseTreeItem* getContext(u32 contextId) const; + ContextDirectory* addDirectory(QString name, BaseTreeItem* parentItem, u32 id); /** * Adds a given GraphContext to the model. @@ -199,20 +200,31 @@ namespace hal ContextTreeItem* getCurrentDirectory(); /** - * Sets the MinDirectoryId. - * - * @param u32 - id to set MinDirectoryId to. + * Removes a tree item and inserts it under a new parent into a specific row. + * + * @param itemToMove - The tree item to be moved. + * @param newParent - The parent item, under which itemToMove is placed. + * @param row - The row in newParent, where itemToMove is inserted. + * If -1, then itemToMove is instead just appended to newParent. + * @return True, if the operation succeded. False, if not. */ - void setMinDirectoryId(u32 id_) { mMinDirectoryId = id_; } + bool moveItem(ContextTreeItem* itemToMove, BaseTreeItem* newParent, int row = -1); /** - * Get MinDirectoryId. - * - * @return MinDIrectoryId. + * Returns the ids of all direct child directories of a given parent directory. + * + * @param directoyId - The id of the parent directory. + * @return List of IDs of all directories, that are ordered directly under the parent directory. */ - u32 minDirectoryId() const { return mMinDirectoryId; } + std::vector getChildDirectoriesOf(u32 directoryId); - bool moveItem(ContextTreeItem* itemToMove, BaseTreeItem* newParent, int row = -1); + /** + * Returns the ids of all direct child contexts of a given parent directory. + * + * @param directoyId - The id of the parent directory. + * @return List of IDs of all contexts, that are ordered directly under the parent directory. + */ + std::vector getChildContextsOf(u32 directoryId); Q_SIGNALS: void directoryCreatedSignal(ContextTreeItem* item); @@ -223,9 +235,7 @@ namespace hal std::map mContextMap; QVector mContextList; QVector mDirectoryList; - u32 mMinDirectoryId; void dumpRecursion(ContextTreeItem* parent = nullptr, int level = 0) const; - }; } // namespace hal diff --git a/plugins/gui/include/gui/gui_api/gui_api.h b/plugins/gui/include/gui/gui_api/gui_api.h index 062ef464122..1e49a56037f 100644 --- a/plugins/gui/include/gui/gui_api/gui_api.h +++ b/plugins/gui/include/gui/gui_api/gui_api.h @@ -71,6 +71,9 @@ namespace hal static void deleteDirectory(u32 id); static void moveView(u32 viewId, std::optional destinationDirectoryId, std::optional row); static void moveDirectory(u32 directoryId, std::optional destinationDirectoryId, std::optional row); + + static std::optional> getChildDirectories(u32 directoryId); + static std::optional> getChildViews(u32 directoryId); }; } diff --git a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp index 46afb5d9c5f..a6c67300c19 100644 --- a/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp +++ b/plugins/gui/src/context_manager_widget/models/context_tree_model.cpp @@ -126,7 +126,7 @@ namespace hal return mContext != nullptr; } - ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr), mMinDirectoryId(std::numeric_limits::max()) + ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr) { setHeaderLabels(QStringList() << "View Name" << "ID" << "Timestamp"); } @@ -226,15 +226,8 @@ namespace hal return nullptr; } - ContextDirectory* ContextTreeModel::addDirectory(QString name, BaseTreeItem *parent, u32 id) + ContextDirectory* ContextTreeModel::addDirectory(QString name, BaseTreeItem *parentItem, u32 id) { - if(id == 0) - id = --mMinDirectoryId; - else if (id < mMinDirectoryId) - mMinDirectoryId = id; - - BaseTreeItem* parentItem = parent; - if (!parentItem) parentItem = mCurrentDirectory; if (!parentItem) @@ -455,4 +448,42 @@ namespace hal for (BaseTreeItem* cld : bti->getChildren()) dumpRecursion(dynamic_cast(cld), level+1); } + + std::vector ContextTreeModel::getChildDirectoriesOf(u32 directoryId) + { + BaseTreeItem* directoryItem = getDirectory(directoryId); + if(!directoryItem) + directoryItem = getRootItem(); + + QList children = directoryItem->getChildren(); + std::vector ids; + + for(BaseTreeItem* child : children) + { + ContextTreeItem* cti = dynamic_cast(child); + if(cti->isDirectory()) + ids.push_back(cti->getId()); + } + + return ids; + } + + std::vector ContextTreeModel::getChildContextsOf(u32 directoryId) + { + BaseTreeItem* directoryItem = getDirectory(directoryId); + if(!directoryItem) + directoryItem = getRootItem(); + + QList children = directoryItem->getChildren(); + std::vector ids; + + for(BaseTreeItem* child : children) + { + ContextTreeItem* cti = dynamic_cast(child); + if(cti->isContext()) + ids.push_back(cti->getId()); + } + + return ids; + } } diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index dba64574e01..2e7c97d34c2 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -60,7 +60,7 @@ namespace hal ContextDirectory* GraphContextManager::createNewDirectory(const QString& name, u32 parentId) { - ContextDirectory* contextDir = mContextTreeModel->addDirectory(name, mContextTreeModel->getDirectory(parentId)); + ContextDirectory* contextDir = mContextTreeModel->addDirectory(name, mContextTreeModel->getDirectory(parentId), ++mMaxContextId); return contextDir; } @@ -658,9 +658,11 @@ namespace hal BaseTreeItem* dirParent = mContextTreeModel->getRootItem(); - if (dirParentId != 0) { + if (dirParentId != 0) dirParent = mContextTreeModel->getDirectory(dirParentId); - } + + if (dirId < 0 || dirId > 0x7FFFFFFF) + dirId = ++mMaxContextId; mContextTreeModel->addDirectory(dirName, dirParent, dirId); } diff --git a/plugins/gui/src/gui_api/gui_api.cpp b/plugins/gui/src/gui_api/gui_api.cpp index a9937851b66..06524c0409f 100644 --- a/plugins/gui/src/gui_api/gui_api.cpp +++ b/plugins/gui/src/gui_api/gui_api.cpp @@ -1014,4 +1014,22 @@ namespace hal act->setObject(uao); act->exec(); } + + std::optional> GuiApiClasses::View::getChildDirectories(u32 directoryId) + { + ContextTreeItem* directoryItem = dynamic_cast(gGraphContextManager->getContextTreeModel()->getDirectory(directoryId)); + // Id 0 is the root item. It does not exist as a directory object, but child items can still be retrieved from it. + if(!directoryItem && directoryId != 0) + return std::nullopt; + return gGraphContextManager->getContextTreeModel()->getChildDirectoriesOf(directoryId); + } + + std::optional> GuiApiClasses::View::getChildViews(u32 directoryId) + { + ContextTreeItem* directoryItem = dynamic_cast(gGraphContextManager->getContextTreeModel()->getDirectory(directoryId)); + // Id 0 is the root item. It does not exist as a directory object, but child items can still be retrieved from it. + if(!directoryItem && directoryId != 0) + return std::nullopt; + return gGraphContextManager->getContextTreeModel()->getChildContextsOf(directoryId); + } } diff --git a/plugins/gui/src/python/python_gui_api_bindings.cpp b/plugins/gui/src/python/python_gui_api_bindings.cpp index 328882b9c78..ee93bf7f38d 100644 --- a/plugins/gui/src/python/python_gui_api_bindings.cpp +++ b/plugins/gui/src/python/python_gui_api_bindings.cpp @@ -264,6 +264,22 @@ PYBIND11_PLUGIN(hal_gui) :param int destinationDirectoryId: ID of the destination directory to which the directory will be moved. If None, the directory is instead moved to the current directory. :param int row: The row index in the parent directory, where the directory will be inserted. +)") + .def_static("getChildDirectories", &GuiApiClasses::View::getChildDirectories, py::arg("directoryId"), R"( + Returns the ids of all direct child directories of a given directory. + + :param int directoryId: ID of the parent directory, whose direct children will be returned + :returns: List of the ids of all direct child directories of the specified directory. + Returns None, if the given directory does not exist. + :rtype: list[int]|None +)") + .def_static("getChildViews", &GuiApiClasses::View::getChildViews, py::arg("directoryId"), R"( + Returns the ids of all direct child views of a given directory. + + :param int directoryId: ID of the parent directory, whose direct children will be returned + :returns: List of the ids of all direct child views of the specified directory. + Returns None, if the given directory does not exist. + :rtype: list[int]|None )"); From 8d034db2997e1558dc8e072c84de2ca6c2b9658b Mon Sep 17 00:00:00 2001 From: joern274 Date: Sun, 16 Jun 2024 15:35:26 +0200 Subject: [PATCH 37/38] Disallow moving view-directory into one of its descendents via Python script --- plugins/gui/src/gui_api/gui_api.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/plugins/gui/src/gui_api/gui_api.cpp b/plugins/gui/src/gui_api/gui_api.cpp index 06524c0409f..fe130306a45 100644 --- a/plugins/gui/src/gui_api/gui_api.cpp +++ b/plugins/gui/src/gui_api/gui_api.cpp @@ -1005,12 +1005,25 @@ namespace hal if(parentItem && gGraphContextManager->getContextTreeModel()->getRootItem() != parentItem) parentId = dynamic_cast(parentItem)->getId(); + u32 destId = destinationDirectoryId.value_or(getCurrentDirectory()); + BaseTreeItem* destAnchestor = gGraphContextManager->getContextTreeModel()->getDirectory(destId); + while (destAnchestor) + { + if (destAnchestor == directoryItem) + { + log_warning("gui", "Invalid attempt to move directory ID={} into dependend directory.", directoryId); + return; + } + destAnchestor = destAnchestor->getParent(); + } + + UserActionObject uao = UserActionObject(directoryId, UserActionObjectType::ContextDir); ActionMoveItem* act; if(row.has_value()) - act = new ActionMoveItem(destinationDirectoryId.value_or(getCurrentDirectory()), parentId, row.value()); + act = new ActionMoveItem(destId, parentId, row.value()); else - act = new ActionMoveItem(destinationDirectoryId.value_or(getCurrentDirectory()), parentId); + act = new ActionMoveItem(destId, parentId); act->setObject(uao); act->exec(); } From 4a54267d00641eb3e15687d408f9027fe2bbb8b9 Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 17 Jun 2024 16:31:45 +0200 Subject: [PATCH 38/38] Changelog updated --- CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2e457fe78e..c7fe1d4c3d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,14 @@ All notable changes to this project will be documented in this file. * added delete module action and shortcut * added entries for context menu * adapted appearance for menu content tree, selection details tree, grouping content tree (same model for all) + * refactored view widget + * changed appearance from tabular view to tree view + * added 'directory' elements to organize and manage groups of views + * added drag'n drop feature allowing to relocate views or directories to another branch in the tree + * added column for view ID + * added functions to Python GUI API to create, modify and delete views and directories + * added UNDO functionality for create/delete view and directory actions + * fixed sort-by-column feature. The tree is not sorted at program start thus showing elements in 'natural' order. * refactored search bar * changed appearance of search bar to be more intuitive * added menu for extended options - e.g. option to search in selected columns only @@ -61,7 +69,6 @@ All notable changes to this project will be documented in this file. * added support for Ubuntu 24.04 LTS * added INIT field declaration to FF-gate-types in example library * added drag'n drop feature allowing to move several nodes in graph view at same time - * added functions to Python GUI API to create, modify and delete views * added GUI PluginParameter type `ComboBox` for parameters that can be requested from plugin * added GUI PluginParameter types `Module` and `Gated` for parameters that can be requested from plugin * added `Show content` button to `Groupings` widget to show content of grouping as a list