- fix: namespace members defined in multiple places not correctly merged in the class browser

- 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
This commit is contained in:
Roy Qu 2022-10-23 15:22:26 +08:00
parent 012628aef3
commit 471b3d6f26
14 changed files with 733 additions and 546 deletions

View File

@ -5,6 +5,12 @@ Red Panda C++ Version 2.0
- fix: save/load bookmark doesn't work
- fix: if project has custom makefile but not enabled, project won't auto generate makefile.
- fix: File path of Issues in project compilation is relative, and can't be correctly marked in the editors.
- fix: editor & class browser not correct updated when editor is switched but not focused
- enhancement: show all project statements in the class browser
- fix: namespace members defined in multiple places not correctly merged in the class browser
- 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
Red Panda C++ Version 1.5

View File

@ -1117,30 +1117,47 @@ void MainWindow::rebuildOpenedFileHisotryMenu()
void MainWindow::updateClassBrowserForEditor(Editor *editor)
{
if (!editor) {
if (mQuitting) {
mClassBrowserModel.setParser(nullptr);
mClassBrowserModel.setCurrentFile("");
return;
}
if (mQuitting)
return;
// if not devCodeCompletion.Enabled then
// Exit;
if ((mClassBrowserModel.currentFile() == editor->filename())
&& (mClassBrowserModel.parser() == editor->parser()))
return;
mClassBrowserModel.beginUpdate();
{
auto action = finally([this] {
mClassBrowserModel.endUpdate();
});
if (editor) {
if ((mClassBrowserModel.currentFile() == editor->filename())
&& (mClassBrowserModel.parser() == editor->parser()))
return;
if (mClassBrowserModel.parser() == editor->parser() && mClassBrowserModel.classBrowserType()==ProjectClassBrowserType::WholeProject) {
mClassBrowserModel.setCurrentFile(editor->filename());
return;
}
mClassBrowserModel.beginUpdate();
mClassBrowserModel.setParser(editor->parser());
// if e.InProject then begin
// ClassBrowser.StatementsType := devClassBrowsing.StatementsType;
// end else
// ClassBrowser.StatementsType := cbstFile;
if (editor->inProject()) {
mClassBrowserModel.setClassBrowserType(mProject->options().classBrowserType);
mClassBrowserModel.setCurrentFiles(mProject->unitFiles());
} else
mClassBrowserModel.setClassBrowserType(ProjectClassBrowserType::CurrentFile);
mClassBrowserModel.setCurrentFile(editor->filename());
mClassBrowserModel.endUpdate();
} else if (mProject) {
if (mClassBrowserModel.parser() == mProject->cppParser()) {
mClassBrowserModel.setCurrentFile("");
return;
}
mClassBrowserModel.beginUpdate();
mClassBrowserModel.setParser(mProject->cppParser());
mClassBrowserModel.setClassBrowserType(mProject->options().classBrowserType);
mClassBrowserModel.setCurrentFiles(mProject->unitFiles());
mClassBrowserModel.setCurrentFile("");
mClassBrowserModel.endUpdate();
} else {
mClassBrowserModel.setParser(nullptr);
mClassBrowserModel.setCurrentFile("");
return;
}
}
@ -2757,6 +2774,14 @@ void MainWindow::buildContextMenus()
mClassBrowser_goto_definition = createActionFor(
tr("Goto definition"),
ui->tabStructure);
mClassBrowser_Show_CurrentFile = createActionFor(
tr("In current file"),
ui->tabStructure);
mClassBrowser_Show_CurrentFile->setCheckable(true);
mClassBrowser_Show_WholeProject = createActionFor(
tr("In current project"),
ui->tabStructure);
mClassBrowser_Show_WholeProject->setCheckable(true);
mClassBrowser_Sort_By_Name->setChecked(pSettings->ui().classBrowserSortAlpha());
mClassBrowser_Sort_By_Type->setChecked(pSettings->ui().classBrowserSortType());
@ -2774,6 +2799,12 @@ void MainWindow::buildContextMenus()
connect(mClassBrowser_goto_declaration,&QAction::triggered,
this, &MainWindow::onClassBrowserGotoDeclaration);
connect(mClassBrowser_Show_CurrentFile,&QAction::triggered,
this, &MainWindow::onClassBrowserChangeScope);
connect(mClassBrowser_Show_WholeProject,&QAction::triggered,
this, &MainWindow::onClassBrowserChangeScope);
//toolbar for class browser
mClassBrowserToolbar = new QWidget();
{
@ -3272,6 +3303,16 @@ void MainWindow::onClassBrowserContextMenu(const QPoint &pos)
menu.addAction(mClassBrowser_Sort_By_Name);
menu.addAction(mClassBrowser_Sort_By_Type);
menu.addAction(mClassBrowser_Show_Inherited);
Editor * editor = mEditorList->getEditor();
if (editor) {
menu.addSeparator();
menu.addAction(mClassBrowser_Show_CurrentFile);
menu.addAction(mClassBrowser_Show_WholeProject);
if (mProject) {
mClassBrowser_Show_CurrentFile->setChecked(mProject->options().classBrowserType==ProjectClassBrowserType::CurrentFile);
mClassBrowser_Show_WholeProject->setChecked(mProject->options().classBrowserType==ProjectClassBrowserType::WholeProject);
}
}
menu.exec(ui->projectView->mapToGlobal(pos));
}
@ -4000,7 +4041,24 @@ void MainWindow::onFilesViewOpen()
void MainWindow::onClassBrowserGotoDeclaration()
{
on_classBrowser_doubleClicked(ui->classBrowser->currentIndex());
QModelIndex index = ui->classBrowser->currentIndex();
if (!index.isValid())
return ;
ClassBrowserNode * node = static_cast<ClassBrowserNode*>(index.internalPointer());
if (!node)
return ;
PStatement statement = node->statement;
if (!statement) {
return;
}
QString filename;
int line;
filename = statement->fileName;
line = statement->line;
Editor* e=openFile(filename);
if (e) {
e->setCaretPositionAndActivate(line,1);
}
}
void MainWindow::onClassBrowserGotoDefinition()
@ -4046,6 +4104,25 @@ void MainWindow::onClassBrowserSortByName()
mClassBrowserModel.fillStatements();
}
void MainWindow::onClassBrowserChangeScope()
{
if (!mProject)
return;
ProjectClassBrowserType classBrowserType;
if (mProject->options().classBrowserType==ProjectClassBrowserType::CurrentFile) {
classBrowserType=ProjectClassBrowserType::WholeProject;
} else {
classBrowserType=ProjectClassBrowserType::CurrentFile;
}
mProject->options().classBrowserType=classBrowserType;
mProject->saveOptions();
Editor* editor = mEditorList->getEditor();
if (editor && editor->inProject() &&
mClassBrowserModel.classBrowserType()!=classBrowserType) {
mClassBrowserModel.setClassBrowserType(classBrowserType);
}
}
void MainWindow::onProjectSwitchCustomViewMode()
{
mProject->setModelType(ProjectModelType::Custom);
@ -6256,8 +6333,27 @@ void MainWindow::on_classBrowser_doubleClicked(const QModelIndex &index)
}
QString filename;
int line;
filename = statement->fileName;
line = statement->line;
Editor* currentEditor = mEditorList->getEditor();
if (currentEditor) {
if (statement->fileName == currentEditor->filename()
&& statement->definitionFileName!=currentEditor->filename()) {
filename = statement->definitionFileName;
line = statement->definitionLine;
} else if (statement->fileName != currentEditor->filename()
&& statement->definitionFileName==currentEditor->filename()) {
filename = statement->fileName;
line = statement->line;
} else if (currentEditor->caretY()==statement->line) {
filename = statement->definitionFileName;
line = statement->definitionLine;
} else {
filename = statement->fileName;
line = statement->line;
}
} else {
filename = statement->fileName;
line = statement->line;
}
Editor* e = openFile(filename);
if (e) {
e->setCaretPositionAndActivate(line,1);

View File

@ -347,6 +347,8 @@ private slots:
void onClassBrowserShowInherited();
void onClassBrowserSortByType();
void onClassBrowserSortByName();
void onClassBrowserChangeScope();
void onProjectSwitchCustomViewMode();
void onProjectSwitchFileSystemViewMode();
void onProjectRemoveFolder();
@ -814,6 +816,8 @@ private:
QAction * mClassBrowser_Show_Inherited;
QAction * mClassBrowser_goto_declaration;
QAction * mClassBrowser_goto_definition;
QAction * mClassBrowser_Show_CurrentFile;
QAction * mClassBrowser_Show_WholeProject;
QWidget * mClassBrowserToolbar;
//actions for files view

View File

@ -2593,7 +2593,8 @@ void CppParser::handlePreprocessor()
if (delimPos>=0) {
mCurrentFile = s.mid(0,delimPos).trimmed();
mIsSystemHeader = isSystemHeaderFile(mCurrentFile) || isProjectHeaderFile(mCurrentFile);
mIsProjectFile = mProjectFiles.contains(mCurrentFile); mIsHeader = isHFile(mCurrentFile);
mIsProjectFile = mProjectFiles.contains(mCurrentFile);
mIsHeader = isHFile(mCurrentFile);
// Mention progress to user if we enter a NEW file
bool ok;

View File

@ -69,25 +69,25 @@ enum class SkipType {
enum StatementKind {
skUnknown,
skNamespace,
skNamespaceAlias,
skClass,
skPreprocessor,
skEnumType,
skEnumClassType,
skEnum,
skTypedef,
skClass,
skFunction,
skVariable,
skGlobalVariable,
skLocalVariable,
skEnum,
skOperator,
skConstructor,
skDestructor,
skVariable,
skParameter,
skNamespace,
skNamespaceAlias,
skBlock,
skUserCodeSnippet, // user code template
skKeyword, // keywords
skGlobalVariable,
skLocalVariable,
skAlias
};

View File

@ -1027,6 +1027,7 @@ bool Project::saveAsTemplate(const QString &templateFolder,
ini->SetValue("Project","Encoding",mOptions.encoding.toUtf8());
if (mOptions.modelType!=ProjectModelType::FileSystem)
ini->SetLongValue("Project", "ModelType", (int)mOptions.modelType);
ini->SetLongValue("Project","ClassBrowserType", (int)mOptions.classBrowserType);
int i=0;
foreach (const PProjectUnit &unit, mUnits) {
@ -1118,6 +1119,7 @@ void Project::saveOptions()
ini.SetValue("Project","ExecEncoding", mOptions.execEncoding);
ini.SetValue("Project","Encoding",toByteArray(mOptions.encoding));
ini.SetLongValue("Project","ModelType", (int)mOptions.modelType);
ini.SetLongValue("Project","ClassBrowserType", (int)mOptions.classBrowserType);
//for Red Panda Dev C++ 6 compatibility
ini.SetLongValue("Project","UseUTF8",mOptions.encoding == ENCODING_UTF8);
@ -1947,6 +1949,7 @@ void Project::loadOptions(SimpleIni& ini)
mOptions.supportXPThemes = ini.GetBoolValue("Project", "SupportXPThemes", false);
mOptions.compilerSet = ini.GetLongValue("Project", "CompilerSet", pSettings->compilerSets().defaultIndex());
mOptions.modelType = (ProjectModelType)ini.GetLongValue("Project", "ModelType", (int)ProjectModelType::Custom);
mOptions.classBrowserType = (ProjectClassBrowserType)ini.GetLongValue("Project", "ClassBrowserType", (int)ProjectClassBrowserType::CurrentFile);
if (mOptions.compilerSet >= (int)pSettings->compilerSets().size()
|| mOptions.compilerSet < 0) { // TODO: change from indices to names

View File

@ -54,5 +54,6 @@ ProjectOptions::ProjectOptions()
staticLink = true;
addCharset = true;
modelType = ProjectModelType::FileSystem;
classBrowserType = ProjectClassBrowserType::CurrentFile;
execEncoding = ENCODING_SYSTEM_DEFAULT;
}

View File

@ -25,6 +25,11 @@ enum class ProjectModelType {
Custom
};
enum class ProjectClassBrowserType {
CurrentFile,
WholeProject
};
enum class ProjectType {
GUI=0,
Console=1,
@ -92,5 +97,6 @@ struct ProjectOptions{
QByteArray execEncoding;
QString encoding;
ProjectModelType modelType;
ProjectClassBrowserType classBrowserType;
};
#endif // PROJECTOPTIONS_H

View File

@ -161,6 +161,7 @@ void ProjectTemplate::readTemplateFile(const QString &fileName)
mOptions.encoding = fromByteArray(mIni->GetValue("Project","Encoding", ENCODING_AUTO_DETECT));
}
mOptions.modelType = (ProjectModelType)mIni->GetLongValue("Project", "ModelType", (int)ProjectModelType::FileSystem);
mOptions.classBrowserType = (ProjectClassBrowserType)mIni->GetLongValue("Project", "ClassBrowserType", (int)ProjectClassBrowserType::CurrentFile);
}

View File

@ -4676,6 +4676,14 @@
<source>Can&apos;t open last open information file &apos;%1&apos; for write!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>In current file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>In current project</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NewClassDialog</name>
@ -4933,11 +4941,11 @@
</message>
<message>
<source>Can&apos;t save file</source>
<translation>Impossível salvar arquivo</translation>
<translation type="vanished">Impossível salvar arquivo</translation>
</message>
<message>
<source>Can&apos;t save file &apos;%1&apos;</source>
<translation>Impossível salvar arquivo &apos;%1&apos;</translation>
<translation type="vanished">Impossível salvar arquivo &apos;%1&apos;</translation>
</message>
<message>
<source>Error Load File</source>

File diff suppressed because it is too large Load Diff

View File

@ -4529,6 +4529,14 @@
<source>Can&apos;t open last open information file &apos;%1&apos; for write!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>In current file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>In current project</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NewClassDialog</name>
@ -4780,14 +4788,6 @@
<source>untitled</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Can&apos;t save file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Can&apos;t save file &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error Load File</source>
<translation type="unfinished"></translation>

View File

@ -206,6 +206,7 @@ void ClassBrowserModel::clear()
mRoot->children.clear();
mNodes.clear();
mDummyStatements.clear();
mScopeNodes.clear();
endResetModel();
}
@ -230,25 +231,15 @@ void ClassBrowserModel::fillStatements()
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();
// Remember selection
// if fLastSelection <> '' then
// ReSelect;
}
QString mParserSerialId = mParser->serialId();
if (!mCurrentFile.isEmpty()) {
addMembers();
}
mParser->unFreeze();
}
}
void ClassBrowserModel::addChild(ClassBrowserNode *node, PStatement statement)
PClassBrowserNode ClassBrowserModel::addChild(ClassBrowserNode *node, const PStatement& statement)
{
PClassBrowserNode newNode = std::make_shared<ClassBrowserNode>();
newNode->parent = node;
@ -256,23 +247,71 @@ void ClassBrowserModel::addChild(ClassBrowserNode *node, PStatement statement)
// newNode->childrenFetched = false;
node->children.append(newNode.get());
mNodes.append(newNode);
if (statement->kind == StatementKind::skClass
|| statement->kind == StatementKind::skNamespace)
mScopeNodes.insert(statement->fullName,newNode);
//don't show enum type's children values (they are displayed in parent scope)
if (statement->kind != StatementKind::skEnumType)
if (statement->kind != StatementKind::skEnumType) {
filterChildren(newNode.get(), statement->children);
}
return newNode;
}
void ClassBrowserModel::addMembers()
{
// show statements in the file
PFileIncludes p = mParser->findFileIncludes(mCurrentFile);
if (!p)
return;
filterChildren(mRoot,p->statements);
if (mClassBrowserType==ProjectClassBrowserType::CurrentFile) {
// show statements in the file
PFileIncludes p = mParser->findFileIncludes(mCurrentFile);
if (!p)
return;
filterChildren(mRoot,p->statements);
} else {
foreach(const QString& file,mCurrentFiles) {
PFileIncludes p = mParser->findFileIncludes(file);
if (!p)
return;
filterChildren(mRoot,p->statements);
}
}
sortNode(mRoot);
}
void ClassBrowserModel::sortNode(ClassBrowserNode *node)
{
if (pSettings->ui().classBrowserSortAlpha()
&& pSettings->ui().classBrowserSortType()) {
std::sort(node->children.begin(),node->children.end(),
[](ClassBrowserNode* node1,ClassBrowserNode* node2) {
if (node1->statement->kind < node2->statement->kind) {
return true;
} else if (node1->statement->kind == node2->statement->kind) {
return node1->statement->command.toLower() < node2->statement->command.toLower();
} else {
return false;
}
});
} else if (pSettings->ui().classBrowserSortAlpha()) {
std::sort(node->children.begin(),node->children.end(),
[](ClassBrowserNode* node1,ClassBrowserNode* node2) {
return node1->statement->command.toLower() < node2->statement->command.toLower();
});
} else if (pSettings->ui().classBrowserSortType()) {
std::sort(node->children.begin(),node->children.end(),
[](ClassBrowserNode* node1,ClassBrowserNode* node2) {
return node1->statement->kind < node2->statement->kind;
});
}
foreach(ClassBrowserNode* child,node->children) {
sortNode(child);
}
}
void ClassBrowserModel::filterChildren(ClassBrowserNode *node, const StatementMap &statements)
{
for (PStatement statement:statements) {
if (mClassBrowserType==ProjectClassBrowserType::WholeProject
&& !statement->inProject)
continue;
if (statement->kind == StatementKind::skBlock)
continue;
if (statement->isInherited && !pSettings->ui().classBrowserShowInherited())
@ -284,91 +323,51 @@ void ClassBrowserModel::filterChildren(ClassBrowserNode *node, const StatementMa
if (statement->scope == StatementScope::ssLocal)
continue;
if (pSettings->codeCompletion().hideSymbolsStartsWithTwoUnderLine()
&& statement->command.startsWith("__"))
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;
if (pSettings->codeCompletion().hideSymbolsStartsWithUnderLine()
&& statement->command.startsWith('_'))
continue;
// 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;
if ( (mClassBrowserType==ProjectClassBrowserType::CurrentFile)
&& (parentScope!=node->statement)
&& (!parentScope || !node->statement
|| parentScope->fullName!=node->statement->fullName)) {
// //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);
}
if ((parentScope->fileName==mCurrentFile)
||(parentScope->definitionFileName==mCurrentFile))
continue;
ClassBrowserNode *dummyNode = getParentNode(parentScope,1);
if (dummyNode)
addChild(dummyNode,statement);
} else if (statement->kind == StatementKind::skNamespace) {
//PStatement dummy = mDummyStatements.value(statement->fullName,PStatement());
PClassBrowserNode dummyNode = mScopeNodes.value(statement->fullName,PClassBrowserNode());
if (dummyNode) {
filterChildren(dummyNode.get(),statement->children);
continue;
} else {
PStatement dummy = createDummy(statement);
dummy->children = statement->children;
dummyNode = addChild(node,dummy);
}
dummy = createDummy(statement);
dummy->children = statement->children;
addChild(node,dummy);
} else {
addChild(node,statement);
}
}
if (pSettings->ui().classBrowserSortAlpha()
&& pSettings->ui().classBrowserSortType()) {
std::sort(node->children.begin(),node->children.end(),
[](ClassBrowserNode* node1,ClassBrowserNode* node2) {
if (node1->statement->kind < node2->statement->kind) {
return true;
} else if (node1->statement->kind == node2->statement->kind) {
return node1->statement->command < node2->statement->command;
} else {
return false;
}
});
} else if (pSettings->ui().classBrowserSortAlpha()) {
std::sort(node->children.begin(),node->children.end(),
[](ClassBrowserNode* node1,ClassBrowserNode* node2) {
return node1->statement->command < node2->statement->command;
});
} else if (pSettings->ui().classBrowserSortType()) {
std::sort(node->children.begin(),node->children.end(),
[](ClassBrowserNode* node1,ClassBrowserNode* node2) {
return node1->statement->kind < node2->statement->kind;
});
}
}
PStatement ClassBrowserModel::createDummy(PStatement statement)
PStatement ClassBrowserModel::createDummy(const PStatement& statement)
{
PStatement result = std::make_shared<Statement>();
result->parentScope = statement->parentScope;
@ -393,6 +392,49 @@ PStatement ClassBrowserModel::createDummy(PStatement statement)
return result;
}
ClassBrowserNode* ClassBrowserModel::getParentNode(const PStatement &parentStatement, int depth)
{
if (depth>10)
return nullptr;
if (!parentStatement)
return mRoot;
if (parentStatement->kind!=skClass
&& parentStatement->kind!=skNamespace)
return mRoot;
PClassBrowserNode parentNode = mScopeNodes.value(parentStatement->fullName,PClassBrowserNode());
if (!parentNode) {
PStatement dummyParent = createDummy(parentStatement);
//todo: find the correct parent node
ClassBrowserNode *grandNode = getParentNode(parentStatement->parentScope.lock(), depth+1);
parentNode = addChild(grandNode,dummyParent);
}
return parentNode.get();
}
const QStringList &ClassBrowserModel::currentFiles() const
{
return mCurrentFiles;
}
void ClassBrowserModel::setCurrentFiles(const QStringList &newCurrentFiles)
{
mCurrentFiles = newCurrentFiles;
}
ProjectClassBrowserType ClassBrowserModel::classBrowserType() const
{
return mClassBrowserType;
}
void ClassBrowserModel::setClassBrowserType(ProjectClassBrowserType newClassBrowserType)
{
if (mClassBrowserType != newClassBrowserType) {
beginUpdate();
mClassBrowserType = newClassBrowserType;
endUpdate();
}
}
const std::shared_ptr<QHash<StatementKind, std::shared_ptr<ColorSchemeItem> > > &ClassBrowserModel::colors() const
{
return mColors;

View File

@ -19,6 +19,7 @@
#include <QAbstractItemModel>
#include "parser/cppparser.h"
#include "../projectoptions.h"
struct ClassBrowserNode {
ClassBrowserNode* parent;
@ -55,27 +56,37 @@ public:
void beginUpdate();
void endUpdate();
const std::shared_ptr<QHash<StatementKind, std::shared_ptr<ColorSchemeItem> > > &colors() const;
void setColors(const std::shared_ptr<QHash<StatementKind, std::shared_ptr<ColorSchemeItem> > > &newColors);
ProjectClassBrowserType classBrowserType() const;
void setClassBrowserType(ProjectClassBrowserType newClassBrowserType);
const QStringList &currentFiles() const;
void setCurrentFiles(const QStringList &newCurrentFiles);
public slots:
void fillStatements();
private:
void addChild(ClassBrowserNode* node, PStatement statement);
PClassBrowserNode addChild(ClassBrowserNode* node, const PStatement& statement);
void addMembers();
void sortNode(ClassBrowserNode * node);
void filterChildren(ClassBrowserNode * node, const StatementMap& statements);
PStatement createDummy(PStatement statement);
PStatement createDummy(const PStatement& statement);
ClassBrowserNode* getParentNode(const PStatement &parentStatement, int depth);
private:
ClassBrowserNode * mRoot;
QHash<QString,PStatement> mDummyStatements;
QHash<QString,PClassBrowserNode> mScopeNodes;
QVector<PClassBrowserNode> mNodes;
PCppParser mParser;
bool mUpdating;
int mUpdateCount;
QMutex mMutex;
QString mCurrentFile;
QStringList mCurrentFiles;
std::shared_ptr<QHash<StatementKind, std::shared_ptr<ColorSchemeItem> > > mColors;
ProjectClassBrowserType mClassBrowserType;
};