diff --git a/NEWS.md b/NEWS.md index 22e7e537..a45c423e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,7 @@ Red Panda C++ Version 2.0 - fix: correctly display statements whose parent is not in the current file - fix: statements is the class browser is correctly sorted - enhancement: Weither double click on the class browser should goto definition/declaration, depends on the current cursor position + - enhancement: keep current position in the class browser after contents modified Red Panda C++ Version 1.5 diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index f96ef232..a2a2bb6e 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -362,6 +362,11 @@ MainWindow::MainWindow(QWidget *parent) ui->classBrowser->setModel(&mClassBrowserModel); delete m; + connect(&mClassBrowserModel, &ClassBrowserModel::refreshStarted, + this, &MainWindow::onClassBrowserRefreshStart); + connect(&mClassBrowserModel, &ClassBrowserModel::refreshEnd, + this, &MainWindow::onClassBrowserRefreshEnd); + connect(&mFileSystemWatcher,&QFileSystemWatcher::fileChanged, this, &MainWindow::onFileChanged); @@ -4123,6 +4128,33 @@ void MainWindow::onClassBrowserChangeScope() } } +void MainWindow::onClassBrowserRefreshStart() +{ + mClassBrowserCurrentStatement=""; + QModelIndex index = ui->classBrowser->currentIndex(); + if (!index.isValid()) + return ; + ClassBrowserNode * node = static_cast(index.internalPointer()); + if (!node) + return ; + PStatement statement = node->statement; + if (!statement) { + return; + } + mClassBrowserCurrentStatement=statement->fullName; +} + +void MainWindow::onClassBrowserRefreshEnd() +{ + QModelIndex index = mClassBrowserModel.modelIndexForStatement(mClassBrowserCurrentStatement); + if (index.isValid()) { +#if QT_VERSION >= QT_VERSION_CHECK(5,15,0) + ui->classBrowser->expandRecursively(index); +#endif + ui->classBrowser->setCurrentIndex(index); + } +} + void MainWindow::onProjectSwitchCustomViewMode() { mProject->setModelType(ProjectModelType::Custom); diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 1eb109a7..ca0af6f7 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -348,6 +348,8 @@ private slots: void onClassBrowserSortByType(); void onClassBrowserSortByName(); void onClassBrowserChangeScope(); + void onClassBrowserRefreshStart(); + void onClassBrowserRefreshEnd(); void onProjectSwitchCustomViewMode(); void onProjectSwitchFileSystemViewMode(); @@ -767,6 +769,8 @@ private: OJProblemModel mOJProblemModel; int mOJProblemSetNameCounter; + QString mClassBrowserCurrentStatement; + bool mCheckSyntaxInBack; bool mShouldRemoveAllSettings; PCompileSuccessionTask mCompileSuccessionTask; diff --git a/RedPandaIDE/widgets/classbrowser.cpp b/RedPandaIDE/widgets/classbrowser.cpp index d6776dc5..c11469b9 100644 --- a/RedPandaIDE/widgets/classbrowser.cpp +++ b/RedPandaIDE/widgets/classbrowser.cpp @@ -205,6 +205,8 @@ void ClassBrowserModel::clear() beginResetModel(); mRoot->children.clear(); mNodes.clear(); + mNodeIndex.clear(); + mProcessedStatements.clear(); mDummyStatements.clear(); mScopeNodes.clear(); endResetModel(); @@ -218,12 +220,14 @@ void ClassBrowserModel::fillStatements() return; mUpdating = true; } + emit refreshStarted(); beginResetModel(); clear(); { auto action = finally([this]{ endResetModel(); mUpdating = false; + emit refreshEnd(); }); if (!mParser) return; @@ -247,6 +251,8 @@ PClassBrowserNode ClassBrowserModel::addChild(ClassBrowserNode *node, const PSta // newNode->childrenFetched = false; node->children.append(newNode.get()); mNodes.append(newNode); + mNodeIndex.insert(statement->fullName,newNode); + mProcessedStatements.insert(statement.get()); if (statement->kind == StatementKind::skClass || statement->kind == StatementKind::skNamespace) mScopeNodes.insert(statement->fullName,newNode); @@ -312,6 +318,10 @@ void ClassBrowserModel::filterChildren(ClassBrowserNode *node, const StatementMa if (mClassBrowserType==ProjectClassBrowserType::WholeProject && !statement->inProject) continue; + + if (mProcessedStatements.contains(statement.get())) + continue; + if (statement->kind == StatementKind::skBlock) continue; if (statement->isInherited && !pSettings->ui().classBrowserShowInherited()) @@ -421,6 +431,24 @@ void ClassBrowserModel::setCurrentFiles(const QStringList &newCurrentFiles) mCurrentFiles = newCurrentFiles; } +QModelIndex ClassBrowserModel::modelIndexForStatement(const QString &fullname) +{ + QMutexLocker locker(&mMutex); + if (mUpdating) + return QModelIndex(); + PClassBrowserNode node=mNodeIndex.value(fullname,PClassBrowserNode()); + if (!node) + return QModelIndex(); + + ClassBrowserNode *parentNode=node->parent; + if (!parentNode) + return QModelIndex(); + int row=parentNode->children.indexOf(node.get()); + if (row<0) + return QModelIndex(); + return createIndex(row,0,node.get()); +} + ProjectClassBrowserType ClassBrowserModel::classBrowserType() const { return mClassBrowserType; @@ -465,7 +493,7 @@ void ClassBrowserModel::endUpdate() mUpdateCount--; if (mUpdateCount == 0) { if (mParser && !mParser->parsing()) { - this->fillStatements(); + fillStatements(); } } } diff --git a/RedPandaIDE/widgets/classbrowser.h b/RedPandaIDE/widgets/classbrowser.h index e628d6dc..6012d146 100644 --- a/RedPandaIDE/widgets/classbrowser.h +++ b/RedPandaIDE/widgets/classbrowser.h @@ -65,6 +65,10 @@ public: const QStringList ¤tFiles() const; void setCurrentFiles(const QStringList &newCurrentFiles); + QModelIndex modelIndexForStatement(const QString& fullname); +signals: + void refreshStarted(); + void refreshEnd(); public slots: void fillStatements(); private: @@ -78,6 +82,8 @@ private: ClassBrowserNode * mRoot; QHash mDummyStatements; QHash mScopeNodes; + QHash mNodeIndex; + QSet mProcessedStatements; QVector mNodes; PCppParser mParser; bool mUpdating;