2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 Denis Mingulov
|
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
2010-07-16 11:18:30 +02:00
|
|
|
|
|
|
|
|
#include "classviewmanager.h"
|
2022-10-25 18:10:16 +02:00
|
|
|
|
2010-07-16 11:18:30 +02:00
|
|
|
#include "classviewparser.h"
|
|
|
|
|
#include "classviewutils.h"
|
|
|
|
|
|
2021-08-30 10:58:08 +02:00
|
|
|
#include <cppeditor/cppeditorconstants.h>
|
|
|
|
|
#include <cppeditor/cppmodelmanager.h>
|
2010-07-16 11:18:30 +02:00
|
|
|
#include <coreplugin/progressmanager/progressmanager.h>
|
2022-10-25 18:10:16 +02:00
|
|
|
#include <projectexplorer/session.h>
|
2014-09-26 09:14:03 +02:00
|
|
|
#include <texteditor/texteditor.h>
|
2010-07-16 11:18:30 +02:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QThread>
|
2021-02-18 15:02:54 +01:00
|
|
|
#include <QTimer>
|
2010-07-16 11:18:30 +02:00
|
|
|
|
2013-08-30 09:22:42 +02:00
|
|
|
using namespace Core;
|
2021-03-01 15:01:35 +01:00
|
|
|
using namespace ProjectExplorer;
|
2020-06-26 13:59:38 +02:00
|
|
|
using namespace Utils;
|
2013-08-30 09:22:42 +02:00
|
|
|
|
2022-11-24 15:28:39 +01:00
|
|
|
namespace ClassView::Internal {
|
2010-07-16 11:18:30 +02:00
|
|
|
|
|
|
|
|
///////////////////////////////// ManagerPrivate //////////////////////////////////
|
|
|
|
|
|
2011-07-06 17:40:54 +02:00
|
|
|
// static variable initialization
|
2018-11-04 22:40:59 +01:00
|
|
|
static Manager *managerInstance = nullptr;
|
2011-07-06 17:40:54 +02:00
|
|
|
|
2010-07-16 11:18:30 +02:00
|
|
|
/*!
|
2013-05-24 17:35:14 +02:00
|
|
|
\class ClassView::Internal::Manager
|
|
|
|
|
|
|
|
|
|
\brief The Manager class implements a class view manager that interacts with
|
|
|
|
|
other \QC plugins and acts as a proxy between them and the parser.
|
|
|
|
|
|
|
|
|
|
The parser is moved to a separate thread and is connected to the manager by
|
|
|
|
|
using signals and slots. Manager's signals starting with 'request' are for
|
|
|
|
|
the parser.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\fn explicit ClassView::Internal::Manager(QObject *parent = 0)
|
|
|
|
|
|
|
|
|
|
Creates a shared instance of a \a parent object.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\fn void ClassView::Internal::Manager::treeDataUpdate(QSharedPointer<QStandardItem> result)
|
|
|
|
|
|
|
|
|
|
Emits a signal about a tree data update (to tree view). \a result holds the
|
|
|
|
|
item with the current tree.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\class ManagerPrivate
|
2011-01-07 08:07:35 +01:00
|
|
|
\internal
|
2013-05-24 17:35:14 +02:00
|
|
|
\brief The ManagerPrivate class contains private class data for the Manager
|
|
|
|
|
class.
|
2010-07-16 11:18:30 +02:00
|
|
|
\sa Manager
|
2013-05-24 17:35:14 +02:00
|
|
|
*/
|
|
|
|
|
|
2011-07-06 17:40:54 +02:00
|
|
|
class ManagerPrivate
|
2010-07-16 11:18:30 +02:00
|
|
|
{
|
2011-07-06 17:40:54 +02:00
|
|
|
public:
|
2021-02-16 17:44:28 +01:00
|
|
|
Parser *m_parser = nullptr;
|
|
|
|
|
QThread m_parserThread;
|
2021-02-16 14:01:16 +01:00
|
|
|
ParserTreeItem::ConstPtr m_root;
|
|
|
|
|
|
2021-02-18 15:02:54 +01:00
|
|
|
QTimer m_timer;
|
2021-03-01 15:01:35 +01:00
|
|
|
QSet<FilePath> m_awaitingDocuments;
|
2021-02-18 15:02:54 +01:00
|
|
|
|
2011-01-07 08:07:35 +01:00
|
|
|
//! Internal manager state. \sa Manager::state
|
2018-11-04 22:40:59 +01:00
|
|
|
bool state = false;
|
2011-01-07 08:07:35 +01:00
|
|
|
|
2010-07-16 11:18:30 +02:00
|
|
|
//! there is some massive operation ongoing so temporary we should wait
|
2018-11-04 22:40:59 +01:00
|
|
|
bool disableCodeParser = false;
|
2010-07-16 11:18:30 +02:00
|
|
|
|
2021-02-18 15:02:54 +01:00
|
|
|
void cancelScheduledUpdate();
|
|
|
|
|
void resetParser();
|
|
|
|
|
ParserTreeItem::ConstPtr findItemByRoot(const QStandardItem *item, bool skipRoot = false) const;
|
|
|
|
|
};
|
2010-07-16 11:18:30 +02:00
|
|
|
|
2021-02-18 15:02:54 +01:00
|
|
|
void ManagerPrivate::cancelScheduledUpdate()
|
2010-07-16 11:18:30 +02:00
|
|
|
{
|
2021-02-18 15:02:54 +01:00
|
|
|
m_timer.stop();
|
|
|
|
|
m_awaitingDocuments.clear();
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
2021-02-18 15:02:54 +01:00
|
|
|
void ManagerPrivate::resetParser()
|
2010-07-16 11:18:30 +02:00
|
|
|
{
|
2021-02-18 15:02:54 +01:00
|
|
|
cancelScheduledUpdate();
|
2021-03-01 15:01:35 +01:00
|
|
|
|
|
|
|
|
QHash<FilePath, QPair<QString, FilePaths>> projectData;
|
|
|
|
|
for (const Project *project : SessionManager::projects()) {
|
|
|
|
|
projectData.insert(project->projectFilePath(),
|
2022-09-30 11:12:51 +02:00
|
|
|
{project->displayName(), project->files(Project::SourceFiles)});
|
2021-03-01 15:01:35 +01:00
|
|
|
}
|
|
|
|
|
QMetaObject::invokeMethod(m_parser, [this, projectData]() {
|
|
|
|
|
m_parser->resetData(projectData);
|
|
|
|
|
}, Qt::QueuedConnection);
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-24 17:35:14 +02:00
|
|
|
/*!
|
2021-02-16 14:01:16 +01:00
|
|
|
Returns the internal tree item for \a item. \a skipRoot skips the root
|
|
|
|
|
item.
|
2013-05-24 17:35:14 +02:00
|
|
|
*/
|
2021-02-18 15:02:54 +01:00
|
|
|
ParserTreeItem::ConstPtr ManagerPrivate::findItemByRoot(const QStandardItem *item, bool skipRoot) const
|
2021-02-16 14:01:16 +01:00
|
|
|
{
|
|
|
|
|
if (!item)
|
|
|
|
|
return ParserTreeItem::ConstPtr();
|
|
|
|
|
|
|
|
|
|
// go item by item to the root
|
|
|
|
|
QList<const QStandardItem *> uiList;
|
|
|
|
|
const QStandardItem *cur = item;
|
|
|
|
|
while (cur) {
|
|
|
|
|
uiList.append(cur);
|
|
|
|
|
cur = cur->parent();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (skipRoot && uiList.count() > 0)
|
|
|
|
|
uiList.removeLast();
|
|
|
|
|
|
2021-02-18 15:02:54 +01:00
|
|
|
ParserTreeItem::ConstPtr internal = m_root;
|
2021-02-16 14:01:16 +01:00
|
|
|
while (uiList.count() > 0) {
|
|
|
|
|
cur = uiList.last();
|
|
|
|
|
uiList.removeLast();
|
|
|
|
|
const SymbolInformation &inf = Internal::symbolInformationFromItem(cur);
|
|
|
|
|
internal = internal->child(inf);
|
|
|
|
|
if (internal.isNull())
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return internal;
|
|
|
|
|
}
|
2013-05-24 17:35:14 +02:00
|
|
|
|
2021-02-18 15:02:54 +01:00
|
|
|
///////////////////////////////// Manager //////////////////////////////////
|
|
|
|
|
|
|
|
|
|
Manager::Manager(QObject *parent)
|
|
|
|
|
: QObject(parent),
|
|
|
|
|
d(new ManagerPrivate())
|
|
|
|
|
{
|
|
|
|
|
d->m_parser = new Parser();
|
|
|
|
|
d->m_parser->moveToThread(&d->m_parserThread);
|
|
|
|
|
connect(&d->m_parserThread, &QThread::finished, d->m_parser, &QObject::deleteLater);
|
|
|
|
|
managerInstance = this;
|
|
|
|
|
|
|
|
|
|
// register - to be able send between signal/slots
|
|
|
|
|
qRegisterMetaType<QSharedPointer<QStandardItem> >("QSharedPointer<QStandardItem>");
|
|
|
|
|
|
|
|
|
|
initialize();
|
|
|
|
|
|
|
|
|
|
// start a separate thread for the parser
|
|
|
|
|
d->m_parserThread.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Manager::~Manager()
|
|
|
|
|
{
|
|
|
|
|
d->m_parserThread.quit();
|
|
|
|
|
d->m_parserThread.wait();
|
|
|
|
|
delete d;
|
|
|
|
|
managerInstance = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Manager *Manager::instance()
|
|
|
|
|
{
|
|
|
|
|
return managerInstance;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-16 14:01:16 +01:00
|
|
|
/*!
|
|
|
|
|
Checks \a item for lazy data population of a QStandardItemModel.
|
|
|
|
|
*/
|
2013-12-04 13:46:12 +01:00
|
|
|
bool Manager::canFetchMore(QStandardItem *item, bool skipRoot) const
|
2010-07-16 11:18:30 +02:00
|
|
|
{
|
2021-02-18 15:02:54 +01:00
|
|
|
ParserTreeItem::ConstPtr ptr = d->findItemByRoot(item, skipRoot);
|
2021-02-16 14:01:16 +01:00
|
|
|
if (ptr.isNull())
|
|
|
|
|
return false;
|
|
|
|
|
return ptr->canFetchMore(item);
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-24 17:35:14 +02:00
|
|
|
/*!
|
|
|
|
|
Checks \a item for lazy data population of a QStandardItemModel.
|
|
|
|
|
\a skipRoot item is needed for the manual update, call not from model.
|
|
|
|
|
*/
|
2010-07-16 11:18:30 +02:00
|
|
|
void Manager::fetchMore(QStandardItem *item, bool skipRoot)
|
|
|
|
|
{
|
2021-02-18 15:02:54 +01:00
|
|
|
ParserTreeItem::ConstPtr ptr = d->findItemByRoot(item, skipRoot);
|
2021-02-16 14:01:16 +01:00
|
|
|
if (ptr.isNull())
|
|
|
|
|
return;
|
|
|
|
|
ptr->fetchMore(item);
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
2013-12-04 13:46:12 +01:00
|
|
|
bool Manager::hasChildren(QStandardItem *item) const
|
|
|
|
|
{
|
2021-02-18 15:02:54 +01:00
|
|
|
ParserTreeItem::ConstPtr ptr = d->findItemByRoot(item);
|
2021-02-16 14:01:16 +01:00
|
|
|
if (ptr.isNull())
|
|
|
|
|
return false;
|
2021-02-16 15:48:08 +01:00
|
|
|
return ptr->childCount();
|
2013-12-04 13:46:12 +01:00
|
|
|
}
|
|
|
|
|
|
2010-07-16 11:18:30 +02:00
|
|
|
void Manager::initialize()
|
|
|
|
|
{
|
2021-02-18 15:02:54 +01:00
|
|
|
d->m_timer.setSingleShot(true);
|
2016-05-29 00:07:28 +03:00
|
|
|
|
2010-10-30 21:54:23 +02:00
|
|
|
// connections to enable/disable navi widget factory
|
2016-05-29 00:07:28 +03:00
|
|
|
SessionManager *sessionManager = SessionManager::instance();
|
|
|
|
|
connect(sessionManager, &SessionManager::projectAdded,
|
2021-03-01 15:01:35 +01:00
|
|
|
this, [this](Project *project) {
|
|
|
|
|
const FilePath projectPath = project->projectFilePath();
|
|
|
|
|
const QString projectName = project->displayName();
|
|
|
|
|
const FilePaths projectFiles = project->files(Project::SourceFiles);
|
|
|
|
|
QMetaObject::invokeMethod(d->m_parser, [this, projectPath, projectName, projectFiles]() {
|
|
|
|
|
d->m_parser->addProject(projectPath, projectName, projectFiles);
|
|
|
|
|
}, Qt::QueuedConnection);
|
|
|
|
|
});
|
2016-05-29 00:07:28 +03:00
|
|
|
connect(sessionManager, &SessionManager::projectRemoved,
|
2021-03-01 15:01:35 +01:00
|
|
|
this, [this](Project *project) {
|
|
|
|
|
const FilePath projectPath = project->projectFilePath();
|
|
|
|
|
QMetaObject::invokeMethod(d->m_parser, [this, projectPath]() {
|
|
|
|
|
d->m_parser->removeProject(projectPath);
|
|
|
|
|
}, Qt::QueuedConnection);
|
|
|
|
|
});
|
2010-07-16 11:18:30 +02:00
|
|
|
|
|
|
|
|
// connect to the progress manager for signals about Parsing tasks
|
2016-05-29 00:07:28 +03:00
|
|
|
connect(ProgressManager::instance(), &ProgressManager::taskStarted,
|
2021-02-08 12:22:21 +01:00
|
|
|
this, [this](Id type) {
|
2021-08-30 10:58:08 +02:00
|
|
|
if (type != CppEditor::Constants::TASK_INDEX)
|
2021-02-08 12:22:21 +01:00
|
|
|
return;
|
2010-07-16 11:18:30 +02:00
|
|
|
|
2021-02-08 12:22:21 +01:00
|
|
|
// disable tree updates to speed up
|
|
|
|
|
d->disableCodeParser = true;
|
2021-02-18 15:02:54 +01:00
|
|
|
d->cancelScheduledUpdate();
|
2021-02-08 12:22:21 +01:00
|
|
|
});
|
|
|
|
|
connect(ProgressManager::instance(), &ProgressManager::allTasksFinished,
|
|
|
|
|
this, [this](Id type) {
|
2021-08-30 10:58:08 +02:00
|
|
|
if (type != CppEditor::Constants::TASK_INDEX)
|
2021-02-08 12:22:21 +01:00
|
|
|
return;
|
2010-07-16 11:18:30 +02:00
|
|
|
|
2021-02-08 12:22:21 +01:00
|
|
|
// parsing is finished, enable tree updates
|
|
|
|
|
d->disableCodeParser = false;
|
2010-07-16 11:18:30 +02:00
|
|
|
|
2021-02-08 12:22:21 +01:00
|
|
|
// do nothing if Manager is disabled
|
|
|
|
|
if (!state())
|
|
|
|
|
return;
|
2010-07-16 11:18:30 +02:00
|
|
|
|
2021-02-08 12:22:21 +01:00
|
|
|
// request to update a tree to the current state
|
2021-02-18 15:02:54 +01:00
|
|
|
d->resetParser();
|
2021-02-08 12:22:21 +01:00
|
|
|
});
|
2010-07-16 11:18:30 +02:00
|
|
|
|
2021-02-16 17:44:28 +01:00
|
|
|
connect(d->m_parser, &Parser::treeRegenerated,
|
2021-02-16 14:01:16 +01:00
|
|
|
this, [this](const ParserTreeItem::ConstPtr &root) {
|
|
|
|
|
d->m_root = root;
|
|
|
|
|
|
2021-02-08 16:52:42 +01:00
|
|
|
if (!state())
|
|
|
|
|
return;
|
|
|
|
|
|
2021-02-16 14:01:16 +01:00
|
|
|
QSharedPointer<QStandardItem> rootItem(new QStandardItem());
|
2021-02-16 15:48:08 +01:00
|
|
|
d->m_root->fetchMore(rootItem.data());
|
2021-02-16 14:01:16 +01:00
|
|
|
emit treeDataUpdate(rootItem);
|
2021-02-08 16:52:42 +01:00
|
|
|
}, Qt::QueuedConnection);
|
2011-01-06 18:34:06 +01:00
|
|
|
|
|
|
|
|
// connect to the cpp model manager for signals about document updates
|
2021-08-30 10:58:08 +02:00
|
|
|
CppEditor::CppModelManager *codeModelManager = CppEditor::CppModelManager::instance();
|
2011-01-06 18:34:06 +01:00
|
|
|
|
|
|
|
|
// when code manager signals that document is updated - handle it by ourselves
|
2021-08-30 10:58:08 +02:00
|
|
|
connect(codeModelManager, &CppEditor::CppModelManager::documentUpdated,
|
2021-02-08 12:22:21 +01:00
|
|
|
this, [this](CPlusPlus::Document::Ptr doc) {
|
|
|
|
|
// do nothing if Manager is disabled
|
|
|
|
|
if (!state())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// do nothing if updates are disabled
|
|
|
|
|
if (d->disableCodeParser)
|
|
|
|
|
return;
|
|
|
|
|
|
2021-02-18 15:02:54 +01:00
|
|
|
if (doc.data() == nullptr)
|
|
|
|
|
return;
|
|
|
|
|
|
2022-11-21 16:48:50 +01:00
|
|
|
d->m_awaitingDocuments.insert(doc->filePath());
|
2021-02-18 15:02:54 +01:00
|
|
|
d->m_timer.start(400); // Accumulate multiple requests into one, restarts the timer
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(&d->m_timer, &QTimer::timeout, this, [this]() {
|
2021-03-01 15:01:35 +01:00
|
|
|
const QSet<FilePath> docsToBeUpdated = d->m_awaitingDocuments;
|
2021-02-18 15:02:54 +01:00
|
|
|
d->cancelScheduledUpdate();
|
|
|
|
|
if (!state() || d->disableCodeParser) // enabling any of them will trigger the total update
|
|
|
|
|
return;
|
|
|
|
|
QMetaObject::invokeMethod(d->m_parser, [this, docsToBeUpdated]() {
|
|
|
|
|
d->m_parser->updateDocuments(docsToBeUpdated);
|
|
|
|
|
}, Qt::QueuedConnection);
|
|
|
|
|
});
|
|
|
|
|
|
2021-08-30 10:58:08 +02:00
|
|
|
connect(codeModelManager, &CppEditor::CppModelManager::aboutToRemoveFiles,
|
2021-02-16 17:44:28 +01:00
|
|
|
d->m_parser, &Parser::removeFiles, Qt::QueuedConnection);
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-24 17:35:14 +02:00
|
|
|
/*!
|
|
|
|
|
Gets the internal manager state. If it is disabled, does not emit signals
|
|
|
|
|
about parsing requests. If enabled, does parsing in the background even if
|
|
|
|
|
the navigation pane is not visible. Returns true if the manager is enabled,
|
|
|
|
|
false otherwise.
|
|
|
|
|
|
|
|
|
|
\sa setState, stateChanged
|
|
|
|
|
*/
|
|
|
|
|
|
2010-07-16 11:18:30 +02:00
|
|
|
bool Manager::state() const
|
|
|
|
|
{
|
2011-07-06 17:40:54 +02:00
|
|
|
return d->state;
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-24 17:35:14 +02:00
|
|
|
/*!
|
|
|
|
|
Sets the internal manager \a state to \c true if the manager has to be
|
|
|
|
|
enabled, otherwise sets it to \c false.
|
|
|
|
|
|
|
|
|
|
\sa state, stateChanged
|
|
|
|
|
*/
|
|
|
|
|
|
2010-07-16 11:18:30 +02:00
|
|
|
void Manager::setState(bool state)
|
|
|
|
|
{
|
2011-07-06 17:40:54 +02:00
|
|
|
if (state == d->state)
|
2010-07-16 11:18:30 +02:00
|
|
|
return;
|
|
|
|
|
|
2011-07-06 17:40:54 +02:00
|
|
|
d->state = state;
|
2010-07-16 11:18:30 +02:00
|
|
|
|
2021-02-08 12:22:21 +01:00
|
|
|
if (state) // enabled - request a current snapshots etc?..
|
2021-02-18 15:02:54 +01:00
|
|
|
d->resetParser();
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-24 17:35:14 +02:00
|
|
|
/*!
|
|
|
|
|
Reacts to the \a visibility of one navigation pane widget being changed
|
|
|
|
|
(there might be a lot of them).
|
|
|
|
|
|
|
|
|
|
\sa setState, state
|
|
|
|
|
*/
|
|
|
|
|
|
2010-07-16 11:18:30 +02:00
|
|
|
void Manager::onWidgetVisibilityIsChanged(bool visibility)
|
|
|
|
|
{
|
|
|
|
|
// activate data handling - when 1st time 'Class View' will be open
|
2021-02-08 12:22:21 +01:00
|
|
|
if (!visibility)
|
|
|
|
|
return;
|
|
|
|
|
setState(true);
|
2021-03-01 15:01:35 +01:00
|
|
|
// TODO: this one may change into getter (when a new class view widget is being shown)
|
2021-02-16 17:44:28 +01:00
|
|
|
QMetaObject::invokeMethod(d->m_parser, &Parser::requestCurrentState, Qt::QueuedConnection);
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-24 17:35:14 +02:00
|
|
|
/*!
|
|
|
|
|
Opens the text editor for the file \a fileName on \a line (1-based) and
|
2018-11-02 14:17:12 +01:00
|
|
|
\a column (0-based).
|
2013-05-24 17:35:14 +02:00
|
|
|
*/
|
|
|
|
|
|
2022-11-24 15:28:39 +01:00
|
|
|
void Manager::gotoLocation(const FilePath &filePath, int line, int column)
|
2010-07-16 11:18:30 +02:00
|
|
|
{
|
2022-11-24 15:28:39 +01:00
|
|
|
EditorManager::openEditorAt({filePath, line, column});
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-24 17:35:14 +02:00
|
|
|
/*!
|
|
|
|
|
Opens the text editor for any of the symbol locations in the \a list.
|
|
|
|
|
|
|
|
|
|
\sa Manager::gotoLocations
|
|
|
|
|
*/
|
|
|
|
|
|
2010-07-16 11:18:30 +02:00
|
|
|
void Manager::gotoLocations(const QList<QVariant> &list)
|
|
|
|
|
{
|
2019-11-15 18:42:11 +01:00
|
|
|
QSet<SymbolLocation> locations = Internal::roleToLocations(list);
|
2014-10-17 09:32:17 +02:00
|
|
|
if (locations.size() == 0)
|
2010-07-16 11:18:30 +02:00
|
|
|
return;
|
|
|
|
|
|
2014-10-17 09:32:17 +02:00
|
|
|
// Default to first known location
|
2021-02-16 01:37:49 +01:00
|
|
|
auto locationIt = locations.constBegin();
|
2014-10-17 09:32:17 +02:00
|
|
|
if (locations.size() > 1) {
|
|
|
|
|
// The symbol has multiple locations. Check if we are already at one location,
|
|
|
|
|
// and if so, cycle to the "next" one
|
|
|
|
|
auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(EditorManager::currentEditor());
|
2010-07-16 11:18:30 +02:00
|
|
|
if (textEditor) {
|
2014-10-17 09:32:17 +02:00
|
|
|
// check if current cursor position is a known location of the symbol
|
2022-11-24 15:28:39 +01:00
|
|
|
const FilePath filePath = textEditor->document()->filePath();
|
2014-10-17 09:32:17 +02:00
|
|
|
int line;
|
|
|
|
|
int column;
|
|
|
|
|
textEditor->convertPosition(textEditor->position(), &line, &column);
|
2022-11-24 15:28:39 +01:00
|
|
|
const SymbolLocation current(filePath, line, column);
|
2021-02-16 01:37:49 +01:00
|
|
|
if (auto it = locations.constFind(current), end = locations.constEnd(); it != end) {
|
2014-10-17 09:32:17 +02:00
|
|
|
// we already are at the symbol, cycle to next location
|
|
|
|
|
++it;
|
|
|
|
|
if (it == end)
|
2017-10-20 15:48:31 +02:00
|
|
|
it = locations.constBegin();
|
2021-02-16 01:37:49 +01:00
|
|
|
locationIt = it;
|
2014-10-17 09:32:17 +02:00
|
|
|
}
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
}
|
2021-02-16 01:37:49 +01:00
|
|
|
const SymbolLocation &location = *locationIt;
|
2018-11-02 14:17:12 +01:00
|
|
|
// line is 1-based, column is 0-based
|
2022-11-24 15:28:39 +01:00
|
|
|
gotoLocation(location.filePath(), location.line(), location.column() - 1);
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-24 17:35:14 +02:00
|
|
|
/*!
|
|
|
|
|
Switches to flat mode (without subprojects) if \a flat is set to \c true.
|
|
|
|
|
*/
|
|
|
|
|
|
2010-07-16 11:18:30 +02:00
|
|
|
void Manager::setFlatMode(bool flat)
|
|
|
|
|
{
|
2021-02-16 17:44:28 +01:00
|
|
|
QMetaObject::invokeMethod(d->m_parser, [this, flat]() {
|
|
|
|
|
d->m_parser->setFlatMode(flat);
|
2021-02-08 12:22:21 +01:00
|
|
|
}, Qt::QueuedConnection);
|
2010-07-16 11:18:30 +02:00
|
|
|
}
|
|
|
|
|
|
2022-11-24 15:28:39 +01:00
|
|
|
} // ClassView::Internal
|