work save
This commit is contained in:
parent
41b9c53146
commit
13b4b9804c
|
@ -25,6 +25,7 @@ SOURCES += \
|
|||
qsynedit/SearchBase.cpp \
|
||||
qsynedit/SearchRegex.cpp \
|
||||
settingsdialog/debuggeneralwidget.cpp \
|
||||
widgets/classbrowser.cpp \
|
||||
widgets/cpudialog.cpp \
|
||||
debugger.cpp \
|
||||
editor.cpp \
|
||||
|
@ -87,6 +88,7 @@ HEADERS += \
|
|||
qsynedit/SearchBase.h \
|
||||
qsynedit/SearchRegex.h \
|
||||
settingsdialog/debuggeneralwidget.h \
|
||||
widgets/classbrowser.h \
|
||||
widgets/cpudialog.h \
|
||||
debugger.h \
|
||||
editor.h \
|
||||
|
|
|
@ -3517,6 +3517,11 @@ void CppParser::updateSerialId()
|
|||
mSerialId = QString("%1 %2").arg(mParserId).arg(mSerialCount);
|
||||
}
|
||||
|
||||
const QString &CppParser::serialId() const
|
||||
{
|
||||
return mSerialId;
|
||||
}
|
||||
|
||||
int CppParser::parserId() const
|
||||
{
|
||||
return mParserId;
|
||||
|
|
|
@ -110,6 +110,8 @@ public:
|
|||
|
||||
int parserId() const;
|
||||
|
||||
const QString &serialId() const;
|
||||
|
||||
signals:
|
||||
void onProgress(const QString& fileName, int total, int current);
|
||||
void onBusy();
|
||||
|
@ -346,5 +348,5 @@ private:
|
|||
QRecursiveMutex mMutex;
|
||||
GetFileStreamCallBack mOnGetFileStream;
|
||||
};
|
||||
|
||||
using PCppParser = std::shared_ptr<CppParser>;
|
||||
#endif // CPPPARSER_H
|
||||
|
|
|
@ -0,0 +1,297 @@
|
|||
#include "classbrowser.h"
|
||||
#include "../utils.h"
|
||||
|
||||
ClassBrowserModel::ClassBrowserModel(QObject *parent):QAbstractItemModel(parent)
|
||||
{
|
||||
mRoot = new ClassBrowserNode();
|
||||
mRoot->parent = nullptr;
|
||||
mRoot->statement = PStatement();
|
||||
mRoot->childrenFetched = true;
|
||||
mUpdating = false;
|
||||
mUpdateCount = 0;
|
||||
mShowInheritedMembers = false;
|
||||
}
|
||||
|
||||
ClassBrowserModel::~ClassBrowserModel()
|
||||
{
|
||||
delete mRoot;
|
||||
}
|
||||
|
||||
QModelIndex ClassBrowserModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!hasIndex(row,column,parent))
|
||||
return QModelIndex();
|
||||
|
||||
ClassBrowserNode *parentNode;
|
||||
if (!parent.isValid()) { // top level
|
||||
parentNode = mRoot;
|
||||
} else {
|
||||
parentNode = static_cast<ClassBrowserNode *>(parent.internalPointer());
|
||||
}
|
||||
return createIndex(row,column,parentNode->children[row]);
|
||||
}
|
||||
|
||||
QModelIndex ClassBrowserModel::parent(const QModelIndex &child) const
|
||||
{
|
||||
if (child.isValid()) {
|
||||
return QModelIndex();
|
||||
}
|
||||
ClassBrowserNode *childNode = static_cast<ClassBrowserNode *>(child.internalPointer());
|
||||
ClassBrowserNode *parentNode = childNode->parent;
|
||||
if (parentNode->parent == nullptr) //it's root node
|
||||
return QModelIndex();
|
||||
|
||||
ClassBrowserNode *grandNode = parentNode->parent;
|
||||
int row = grandNode->children.indexOf(parentNode);
|
||||
return createIndex(row,0,parentNode);
|
||||
}
|
||||
|
||||
int ClassBrowserModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
ClassBrowserNode *parentNode;
|
||||
if (!parent.isValid()) { // top level
|
||||
parentNode = mRoot;
|
||||
} else {
|
||||
parentNode = static_cast<ClassBrowserNode *>(parent.internalPointer());
|
||||
}
|
||||
return parentNode->children.count();
|
||||
}
|
||||
|
||||
int ClassBrowserModel::columnCount(const QModelIndex&) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ClassBrowserModel::fetchMore(const QModelIndex &parent)
|
||||
{
|
||||
if (!parent.isValid()) { // top level
|
||||
return;
|
||||
}
|
||||
|
||||
ClassBrowserNode *parentNode = static_cast<ClassBrowserNode *>(parent.internalPointer());
|
||||
if (!parentNode->childrenFetched) {
|
||||
parentNode->childrenFetched = true;
|
||||
if (parentNode->statement && !parentNode->statement->children.isEmpty())
|
||||
filterChildren(parentNode, parentNode->statement->children);
|
||||
}
|
||||
}
|
||||
|
||||
bool ClassBrowserModel::canFetchMore(const QModelIndex &parent) const
|
||||
{
|
||||
|
||||
if (!parent.isValid()) { // top level
|
||||
return false;
|
||||
}
|
||||
|
||||
ClassBrowserNode *parentNode = static_cast<ClassBrowserNode *>(parent.internalPointer());
|
||||
if (!parentNode->childrenFetched) {
|
||||
if (parentNode->statement && !parentNode->statement->children.isEmpty())
|
||||
return true;
|
||||
else
|
||||
parentNode->childrenFetched = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant ClassBrowserModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid()){
|
||||
return QVariant();
|
||||
}
|
||||
ClassBrowserNode *node = static_cast<ClassBrowserNode *>(index.internalPointer());
|
||||
if (!node)
|
||||
return QVariant();
|
||||
if (role == Qt::DisplayRole) {
|
||||
if (node->statement) {
|
||||
return node->statement->command;
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
const PCppParser &ClassBrowserModel::cppParser() const
|
||||
{
|
||||
return mParser;
|
||||
}
|
||||
|
||||
void ClassBrowserModel::setCppParser(const PCppParser &newCppParser)
|
||||
{
|
||||
if (mParser) {
|
||||
disconnect(mParser.get(),
|
||||
&CppParser::onEndParsing,
|
||||
this,
|
||||
&ClassBrowserModel::fillStatements);
|
||||
}
|
||||
mParser = newCppParser;
|
||||
if (mParser) {
|
||||
connect(mParser.get(),
|
||||
&CppParser::onEndParsing,
|
||||
this,
|
||||
&ClassBrowserModel::fillStatements);
|
||||
if (!mParser->parsing())
|
||||
fillStatements();
|
||||
}
|
||||
}
|
||||
|
||||
void ClassBrowserModel::clear()
|
||||
{
|
||||
beginResetModel();
|
||||
mRoot->children.clear();
|
||||
mNodes.clear();
|
||||
mDummyStatements.clear();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void ClassBrowserModel::fillStatements()
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (mUpdateCount!=0)
|
||||
return;
|
||||
mUpdating = true;
|
||||
beginResetModel();
|
||||
clear();
|
||||
{
|
||||
auto action = finally([this]{
|
||||
endResetModel();
|
||||
mUpdating = false;
|
||||
});
|
||||
if (!mParser)
|
||||
return;
|
||||
if (!mParser->enabled())
|
||||
return;
|
||||
if (!mParser->freeze())
|
||||
return;
|
||||
{
|
||||
auto action2 = finally([this]{
|
||||
mParser->unFreeze();
|
||||
});
|
||||
QString mParserSerialId = mParser->serialId();
|
||||
if (!mCurrentFile.isEmpty()) {
|
||||
QSet<QString> includedFiles = mParser->getFileIncludes(mCurrentFile);
|
||||
|
||||
addMembers(includedFiles);
|
||||
// Remember selection
|
||||
// if fLastSelection <> '' then
|
||||
// ReSelect;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClassBrowserModel::calculateChildrenCounts(const QModelIndex &index)
|
||||
{
|
||||
ClassBrowserNode *parentNode;
|
||||
if (!index.isValid()) { // top level
|
||||
parentNode = mRoot;
|
||||
} else {
|
||||
parentNode = static_cast<ClassBrowserNode *>(index.internalPointer());
|
||||
}
|
||||
if (!parentNode->childrenFetched && parentNode->statement) {
|
||||
parentNode->childrenFetched = true;
|
||||
filterChildren(parentNode, parentNode->statement->children);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassBrowserModel::addChild(ClassBrowserNode *node, PStatement statement)
|
||||
{
|
||||
PClassBrowserNode newNode = std::make_shared<ClassBrowserNode>();
|
||||
newNode->parent = node;
|
||||
newNode->statement = statement;
|
||||
newNode->childrenInited = false;
|
||||
node->children.append(newNode.get());
|
||||
mNodes.append(newNode);
|
||||
}
|
||||
|
||||
void ClassBrowserModel::addMembers(const QSet<QString> &includedFiles)
|
||||
{
|
||||
// show statements in the file
|
||||
PFileIncludes p = mParser->findFileIncludes(mCurrentFile);
|
||||
if (!p)
|
||||
return;
|
||||
filterChildren(mRoot,p->statements);
|
||||
}
|
||||
|
||||
void ClassBrowserModel::filterChildren(ClassBrowserNode *node, const StatementMap &statements)
|
||||
{
|
||||
for (PStatement statement:statements) {
|
||||
if (statement->kind == StatementKind::skBlock)
|
||||
continue;
|
||||
if (statement->isInherited && !mShowInheritedMembers)
|
||||
continue;
|
||||
|
||||
if (statement == node->statement) // prevent infinite recursion
|
||||
continue;
|
||||
|
||||
if (statement->scope == StatementScope::ssLocal)
|
||||
continue;
|
||||
|
||||
|
||||
// if (fStatementsType = cbstProject) then begin
|
||||
// if not Statement^._InProject then
|
||||
// Continue;
|
||||
// if Statement^._Static and not SameText(Statement^._FileName,fCurrentFile)
|
||||
// and not SameText(Statement^._FileName,fCurrentFile) then
|
||||
// Continue;
|
||||
// end;
|
||||
|
||||
// we only test and handle orphan statements in the top level (node->statement is null)
|
||||
PStatement parentScope = statement->parentScope.lock();
|
||||
if ((parentScope!=node->statement) && (!node->statement)) {
|
||||
|
||||
// // we only handle orphan statements when type is cbstFile
|
||||
// if fStatementsType <> cbstFile then
|
||||
// Continue;
|
||||
|
||||
// //should not happend, just in case of error
|
||||
if (!parentScope)
|
||||
continue;
|
||||
|
||||
// Processing the orphan statement
|
||||
while (statement) {
|
||||
//the statement's parent is in this file, so it's not a real orphan
|
||||
if ((parentScope->fileName==mCurrentFile)
|
||||
||(parentScope->definitionFileName==mCurrentFile))
|
||||
break;
|
||||
|
||||
PStatement dummyParent = mDummyStatements.value(parentScope->fullName,PStatement());
|
||||
if (dummyParent) {
|
||||
dummyParent->children.insert(statement->command,statement);
|
||||
break;
|
||||
}
|
||||
dummyParent = createDummy(parentScope);
|
||||
dummyParent->children.insert(statement->command,statement);
|
||||
//we are adding an orphan statement, just add it
|
||||
statement = dummyParent;
|
||||
parentScope = statement->parentScope.lock();
|
||||
if (!parentScope) {
|
||||
addChild(node,statement);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (statement->kind == StatementKind::skNamespace) {
|
||||
PStatement dummy = mDummyStatements.value(statement->fullName,PStatement());
|
||||
if (dummy) {
|
||||
for (PStatement child: statement->children) {
|
||||
dummy->children.insert(child->command,child);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
dummy = createDummy(statement);
|
||||
dummy->children = statement->children;
|
||||
addChild(node,dummy);
|
||||
} else {
|
||||
addChild(node,statement);
|
||||
}
|
||||
}
|
||||
// if sortAlphabetically and sortByType then begin
|
||||
// filtered.Sort(@CompareByAlphaAndType);
|
||||
// end else if sortAlphabetically then begin
|
||||
// filtered.Sort(@CompareByAlpha);
|
||||
// end else if sortByType then begin
|
||||
// filtered.Sort(@CompareByType);
|
||||
// end;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef CLASSBROWSER_H
|
||||
#define CLASSBROWSER_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include "parser/cppparser.h"
|
||||
|
||||
struct ClassBrowserNode {
|
||||
ClassBrowserNode* parent;
|
||||
PStatement statement;
|
||||
QVector<ClassBrowserNode *> children;
|
||||
bool childrenFetched;
|
||||
};
|
||||
|
||||
using PClassBrowserNode = std::shared_ptr<ClassBrowserNode>;
|
||||
|
||||
class ClassBrowserModel : public QAbstractItemModel{
|
||||
Q_OBJECT
|
||||
// QAbstractItemModel interface
|
||||
public:
|
||||
explicit ClassBrowserModel(QObject* parent=nullptr);
|
||||
~ClassBrowserModel();
|
||||
ClassBrowserModel& operator=(const ClassBrowserModel& model) = delete;
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
QModelIndex parent(const QModelIndex &child) const override;
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
void fetchMore(const QModelIndex &parent) override;
|
||||
bool canFetchMore(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
const PCppParser &cppParser() const;
|
||||
void setCppParser(const PCppParser &newCppParser);
|
||||
void clear();
|
||||
public slots:
|
||||
void fillStatements();
|
||||
private:
|
||||
void addChild(ClassBrowserNode* node, PStatement statement);
|
||||
void addMembers(const QSet<QString>& includedFiles);
|
||||
void filterChildren(ClassBrowserNode * node, const StatementMap& statements);
|
||||
private:
|
||||
ClassBrowserNode * mRoot;
|
||||
QHash<QString,PStatement> mDummyStatements;
|
||||
QVector<PClassBrowserNode> mNodes;
|
||||
PCppParser mParser;
|
||||
bool mUpdating;
|
||||
int mUpdateCount;
|
||||
QRecursiveMutex mMutex;
|
||||
QString mCurrentFile;
|
||||
bool mShowInheritedMembers;
|
||||
|
||||
};
|
||||
|
||||
#endif // CLASSBROWSER_H
|
Loading…
Reference in New Issue