- fix: Contents in class browser not correctly updated when close the last editor for project.

- fix: When all editors closed, switch browser mode dosen't correct update the class browser;

  - stream line codes for project parser and  close browser
This commit is contained in:
Roy Qu 2022-11-07 11:24:23 +08:00
parent 63de2e72b1
commit fba7bd953c
8 changed files with 75 additions and 57 deletions

View File

@ -1,3 +1,8 @@
Red Panda C++ Version 2.4
- fix: Contents in class browser not correctly updated when close the last editor for project.
- fix: When all editors closed, switch browser mode dosen't correct update the class browser;
Red Panda C++ Version 2.3 Red Panda C++ Version 2.3
- fix: When start parsing and exit app, app may crash - fix: When start parsing and exit app, app may crash

View File

@ -1144,10 +1144,12 @@ void MainWindow::rebuildOpenedFileHisotryMenu()
void MainWindow::updateClassBrowserForEditor(Editor *editor) void MainWindow::updateClassBrowserForEditor(Editor *editor)
{ {
if (mQuitting) { if (mQuitting) {
mClassBrowserModel.beginUpdate();
mClassBrowserModel.setParser(nullptr); mClassBrowserModel.setParser(nullptr);
mClassBrowserModel.setCurrentFile(""); mClassBrowserModel.setCurrentFile("");
mClassBrowserModel.setCurrentFiles(QStringList()); mClassBrowserModel.endUpdate();
return; return;
} }
@ -1172,29 +1174,29 @@ void MainWindow::updateClassBrowserForEditor(Editor *editor)
mClassBrowserModel.setParser(editor->parser()); mClassBrowserModel.setParser(editor->parser());
if (editor->inProject()) { if (editor->inProject()) {
mClassBrowserModel.setClassBrowserType(mProject->options().classBrowserType); mClassBrowserModel.setClassBrowserType(mProject->options().classBrowserType);
mClassBrowserModel.setCurrentFiles(mProject->unitFiles());
} else { } else {
mClassBrowserModel.setClassBrowserType(ProjectClassBrowserType::CurrentFile); mClassBrowserModel.setClassBrowserType(ProjectClassBrowserType::CurrentFile);
mClassBrowserModel.setCurrentFiles(QStringList());
} }
mClassBrowserModel.setCurrentFile(editor->filename()); mClassBrowserModel.setCurrentFile(editor->filename());
mClassBrowserModel.endUpdate(); mClassBrowserModel.endUpdate();
} else if (mProject) { } else if (mProject) {
if (mClassBrowserModel.parser() == mProject->cppParser()) { if (mClassBrowserModel.parser() == mProject->cppParser()) {
mClassBrowserModel.beginUpdate();
mClassBrowserModel.setCurrentFile(""); mClassBrowserModel.setCurrentFile("");
mClassBrowserModel.endUpdate();
return; return;
} }
mClassBrowserModel.beginUpdate(); mClassBrowserModel.beginUpdate();
mClassBrowserModel.setParser(mProject->cppParser()); mClassBrowserModel.setParser(mProject->cppParser());
mClassBrowserModel.setClassBrowserType(mProject->options().classBrowserType); mClassBrowserModel.setClassBrowserType(mProject->options().classBrowserType);
mClassBrowserModel.setCurrentFiles(mProject->unitFiles());
mClassBrowserModel.setCurrentFile(""); mClassBrowserModel.setCurrentFile("");
mClassBrowserModel.endUpdate(); mClassBrowserModel.endUpdate();
} else { } else {
mClassBrowserModel.beginUpdate();
mClassBrowserModel.setParser(nullptr); mClassBrowserModel.setParser(nullptr);
mClassBrowserModel.setCurrentFile(""); mClassBrowserModel.setCurrentFile("");
mClassBrowserModel.setCurrentFiles(QStringList()); mClassBrowserModel.endUpdate();
return; return;
} }
} }
@ -3358,10 +3360,11 @@ void MainWindow::onClassBrowserContextMenu(const QPoint &pos)
menu.addAction(mClassBrowser_Sort_By_Type); menu.addAction(mClassBrowser_Sort_By_Type);
menu.addAction(mClassBrowser_Show_Inherited); menu.addAction(mClassBrowser_Show_Inherited);
Editor * editor = mEditorList->getEditor(); Editor * editor = mEditorList->getEditor();
if (editor) { if ((editor &&editor->inProject()) || mProject) {
menu.addSeparator(); menu.addSeparator();
menu.addAction(mClassBrowser_Show_CurrentFile); menu.addAction(mClassBrowser_Show_CurrentFile);
menu.addAction(mClassBrowser_Show_WholeProject); menu.addAction(mClassBrowser_Show_WholeProject);
if (mProject) { if (mProject) {
mClassBrowser_Show_CurrentFile->setChecked(mProject->options().classBrowserType==ProjectClassBrowserType::CurrentFile); mClassBrowser_Show_CurrentFile->setChecked(mProject->options().classBrowserType==ProjectClassBrowserType::CurrentFile);
mClassBrowser_Show_WholeProject->setChecked(mProject->options().classBrowserType==ProjectClassBrowserType::WholeProject); mClassBrowser_Show_WholeProject->setChecked(mProject->options().classBrowserType==ProjectClassBrowserType::WholeProject);
@ -4201,7 +4204,7 @@ void MainWindow::onClassBrowserChangeScope()
mProject->options().classBrowserType=classBrowserType; mProject->options().classBrowserType=classBrowserType;
mProject->saveOptions(); mProject->saveOptions();
Editor* editor = mEditorList->getEditor(); Editor* editor = mEditorList->getEditor();
if (editor && editor->inProject() && if ((!editor || editor->inProject()) &&
mClassBrowserModel.classBrowserType()!=classBrowserType) { mClassBrowserModel.classBrowserType()!=classBrowserType) {
mClassBrowserModel.setClassBrowserType(classBrowserType); mClassBrowserModel.setClassBrowserType(classBrowserType);
} }
@ -6354,7 +6357,7 @@ void MainWindow::on_actionAdd_to_project_triggered()
PProjectModelNode folderNode = mProject->pointerToNode(node); PProjectModelNode folderNode = mProject->pointerToNode(node);
foreach (const QString& filename, dialog.selectedFiles()) { foreach (const QString& filename, dialog.selectedFiles()) {
PProjectUnit newUnit = mProject->addUnit(filename,folderNode); PProjectUnit newUnit = mProject->addUnit(filename,folderNode);
mProject->cppParser()->addFileToScan(filename,true); mProject->cppParser()->addProjectFile(filename,true);
QString branch; QString branch;
if (pSettings->vcs().gitOk() && mProject->model()->iconProvider()->VCSRepository()->hasRepository(branch)) { if (pSettings->vcs().gitOk() && mProject->model()->iconProvider()->VCSRepository()->hasRepository(branch)) {
QString output; QString output;
@ -6372,7 +6375,6 @@ void MainWindow::on_actionAdd_to_project_triggered()
} }
} }
} }
mClassBrowserModel.setCurrentFiles(mProject->unitFiles());
mProject->saveAll(); mProject->saveAll();
updateProjectView(); updateProjectView();
parseFileList(mProject->cppParser()); parseFileList(mProject->cppParser());
@ -6400,14 +6402,9 @@ void MainWindow::on_actionRemove_from_project_triggered()
if (!folderNode) if (!folderNode)
continue; continue;
PProjectUnit unit = folderNode->pUnit.lock(); PProjectUnit unit = folderNode->pUnit.lock();
if (mProject->cppParser()) {
mProject->cppParser()->invalidateFile(unit->fileName());
mProject->cppParser()->removeProjectFile(unit->fileName());
}
mProject->removeUnit(unit, true, removeFile); mProject->removeUnit(unit, true, removeFile);
}; };
mClassBrowserModel.beginUpdate(); mClassBrowserModel.beginUpdate();
mClassBrowserModel.setCurrentFiles(mProject->unitFiles());
mClassBrowserModel.endUpdate(); mClassBrowserModel.endUpdate();
ui->projectView->selectionModel()->clearSelection(); ui->projectView->selectionModel()->clearSelection();
mProject->saveAll(); mProject->saveAll();
@ -6716,9 +6713,8 @@ void MainWindow::newProjectUnitFile()
setProjectViewCurrentUnit(newUnit); setProjectViewCurrentUnit(newUnit);
mProject->saveAll(); mProject->saveAll();
if (mProject->cppParser())
mProject->cppParser()->addFileToScan(newFileName,true); parseFileList(mProject->cppParser());
mClassBrowserModel.setCurrentFiles(mProject->unitFiles());
Editor * editor = mProject->openUnit(newUnit, false); Editor * editor = mProject->openUnit(newUnit, false);
if (editor) if (editor)
editor->activate(); editor->activate();
@ -6848,7 +6844,6 @@ QString MainWindow::switchHeaderSourceTarget(Editor *editor)
void MainWindow::onProjectViewNodeRenamed() void MainWindow::onProjectViewNodeRenamed()
{ {
mClassBrowserModel.setCurrentFiles(mProject->unitFiles());
updateProjectView(); updateProjectView();
} }
@ -7964,9 +7959,6 @@ void MainWindow::on_actionNew_Header_triggered()
PProjectUnit newUnit=mProject->addUnit(headerFilename,mProject->rootNode()); PProjectUnit newUnit=mProject->addUnit(headerFilename,mProject->rootNode());
mProject->saveAll(); mProject->saveAll();
mProject->cppParser()->addFileToScan(headerFilename,true);
mClassBrowserModel.setCurrentFiles(mProject->unitFiles());
parseFileList(mProject->cppParser()); parseFileList(mProject->cppParser());
setProjectViewCurrentUnit(newUnit); setProjectViewCurrentUnit(newUnit);
updateProjectView(); updateProjectView();
@ -8044,11 +8036,6 @@ void MainWindow::on_actionNew_Class_triggered()
newUnit=mProject->addUnit(sourceFilename,mProject->rootNode()); newUnit=mProject->addUnit(sourceFilename,mProject->rootNode());
setProjectViewCurrentUnit(newUnit); setProjectViewCurrentUnit(newUnit);
mProject->saveAll(); mProject->saveAll();
mProject->cppParser()->addFileToScan(sourceFilename,true);
mProject->cppParser()->addFileToScan(headerFilename,true);
mClassBrowserModel.setCurrentFiles(mProject->unitFiles());
parseFileList(mProject->cppParser()); parseFileList(mProject->cppParser());
updateProjectView(); updateProjectView();

View File

@ -1121,18 +1121,17 @@ int CppParser::getFirstTemplateParamEnd(const QString &s, int startAt)
return startAt; return startAt;
} }
void CppParser::addFileToScan(const QString& value, bool inProject) void CppParser::addProjectFile(const QString &fileName, bool needScan)
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);
//value.replace('/','\\'); // only accept full file names //value.replace('/','\\'); // only accept full file names
// Update project listing // Update project listing
if (inProject) mProjectFiles.insert(fileName);
mProjectFiles.insert(value);
// Only parse given file // Only parse given file
if (!mPreprocessor.scannedFiles().contains(value)) { if (needScan && !mPreprocessor.scannedFiles().contains(fileName)) {
mFilesToScan.insert(value); mFilesToScan.insert(fileName);
} }
} }
@ -5273,6 +5272,11 @@ void CppParser::parseCommandTypeAndArgs(QString &command, QString &typeSuffix, Q
} }
const QSet<QString> &CppParser::projectFiles() const
{
return mProjectFiles;
}
ParserLanguage CppParser::language() const ParserLanguage CppParser::language() const
{ {
return mLanguage; return mLanguage;

View File

@ -34,7 +34,7 @@ public:
~CppParser(); ~CppParser();
void addHardDefineByLine(const QString& line); void addHardDefineByLine(const QString& line);
void addFileToScan(const QString& value, bool inProject = false); void addProjectFile(const QString &fileName, bool needScan);
void addIncludePath(const QString& value); void addIncludePath(const QString& value);
void removeProjectFile(const QString& value); void removeProjectFile(const QString& value);
void addProjectIncludePath(const QString& value); void addProjectIncludePath(const QString& value);
@ -143,6 +143,8 @@ public:
ParserLanguage language() const; ParserLanguage language() const;
void setLanguage(ParserLanguage newLanguage); void setLanguage(ParserLanguage newLanguage);
const QSet<QString> &projectFiles() const;
signals: signals:
void onProgress(const QString& fileName, int total, int current); void onProgress(const QString& fileName, int total, int current);
void onBusy(); void onBusy();

View File

@ -526,6 +526,18 @@ void Project::rebuildNodes()
} }
bool Project::removeUnit(PProjectUnit& unit, bool doClose , bool removeFile) bool Project::removeUnit(PProjectUnit& unit, bool doClose , bool removeFile)
{
bool result=internalRemoveUnit(unit,doClose,removeFile);
if (result) {
mParser->invalidateFile(unit->fileName());
mParser->removeProjectFile(unit->fileName());
emit unitRemoved(unit->fileName());
}
return result;
}
bool Project::internalRemoveUnit(PProjectUnit& unit, bool doClose , bool removeFile)
{ {
if (!unit) if (!unit)
return false; return false;
@ -609,7 +621,7 @@ void Project::resetParserProjectFiles()
mParser->clearProjectFiles(); mParser->clearProjectFiles();
mParser->clearProjectIncludePaths(); mParser->clearProjectIncludePaths();
foreach (const PProjectUnit& unit, mUnits) { foreach (const PProjectUnit& unit, mUnits) {
mParser->addFileToScan(unit->fileName(),true); mParser->addProjectFile(unit->fileName(),true);
} }
foreach (const QString& s, mOptions.includeDirs) { foreach (const QString& s, mOptions.includeDirs) {
mParser->addProjectIncludePath(s); mParser->addProjectIncludePath(s);
@ -693,32 +705,37 @@ void Project::saveLayout()
} }
} }
void Project::renameUnit(PProjectUnit& unit, const QString &sFileName) void Project::renameUnit(PProjectUnit& unit, const QString &newFileName)
{ {
if (!unit) if (!unit)
return; return;
if (sFileName.compare(unit->fileName(),PATH_SENSITIVITY)==0) if (newFileName.compare(unit->fileName(),PATH_SENSITIVITY)==0)
return; return;
if (mParser) { if (mParser) {
mParser->removeProjectFile(unit->fileName()); mParser->removeProjectFile(unit->fileName());
mParser->addFileToScan(sFileName,true); mParser->addProjectFile(newFileName,true);
} }
Editor * editor=unitEditor(unit); Editor * editor=unitEditor(unit);
if (editor) { if (editor) {
//prevent recurse //prevent recurse
editor->saveAs(sFileName,true); editor->saveAs(newFileName,true);
} else { } else {
if (mParser) if (mParser)
mParser->invalidateFile(unit->fileName()); mParser->invalidateFile(unit->fileName());
copyFile(unit->fileName(),sFileName,true); copyFile(unit->fileName(),newFileName,true);
if (mParser) if (mParser)
mParser->parseFile(sFileName,true); mParser->parseFile(newFileName,true);
} }
removeUnit(unit,false,true);
internalRemoveUnit(unit,false,true);
PProjectModelNode parentNode = unit->node()->parent.lock(); PProjectModelNode parentNode = unit->node()->parent.lock();
unit = addUnit(sFileName,parentNode); internalAddUnit(newFileName,parentNode);
setModified(true); setModified(true);
emit unitRenamed(unit->fileName(),newFileName);
emit nodeRenamed(); emit nodeRenamed();
} }
@ -1202,6 +1219,16 @@ PProjectModelNode Project::addFolder(PProjectModelNode parentFolder,const QStrin
} }
PProjectUnit Project::addUnit(const QString &inFileName, PProjectModelNode parentNode) PProjectUnit Project::addUnit(const QString &inFileName, PProjectModelNode parentNode)
{
PProjectUnit newUnit=internalAddUnit(inFileName, parentNode);
if (newUnit) {
mParser->addProjectFile(newUnit->fileName(),true);
emit unitAdded(newUnit->fileName());
}
return newUnit;
}
PProjectUnit Project::internalAddUnit(const QString &inFileName, PProjectModelNode parentNode)
{ {
// Don't add if it already exists // Don't add if it already exists
if (fileAlreadyExists(inFileName)) { if (fileAlreadyExists(inFileName)) {

View File

@ -290,10 +290,17 @@ public:
void renameFolderNode(PProjectModelNode node, const QString newName); void renameFolderNode(PProjectModelNode node, const QString newName);
void loadUnitLayout(Editor *e); void loadUnitLayout(Editor *e);
signals: signals:
void unitRemoved(const QString& fileName);
void unitAdded(const QString& fileName);
void unitRenamed(const QString& oldFileName, const QString& newFileName);
void nodeRenamed(); void nodeRenamed();
void modifyChanged(bool value); void modifyChanged(bool value);
private: private:
bool internalRemoveUnit(PProjectUnit& unit, bool doClose, bool removeFile);
PProjectUnit internalAddUnit(const QString& inFileName,
PProjectModelNode parentNode);
bool assignTemplate(const std::shared_ptr<ProjectTemplate> aTemplate, bool useCpp); bool assignTemplate(const std::shared_ptr<ProjectTemplate> aTemplate, bool useCpp);
void checkProjectFileForUpdate(SimpleIni& ini); void checkProjectFileForUpdate(SimpleIni& ini);
void createFolderNodes(); void createFolderNodes();

View File

@ -278,9 +278,9 @@ void ClassBrowserModel::addMembers()
return; return;
filterChildren(mRoot,p->statements); filterChildren(mRoot,p->statements);
} else { } else {
if (mCurrentFiles.isEmpty()) if (mParser->projectFiles().isEmpty())
return; return;
foreach(const QString& file,mCurrentFiles) { foreach(const QString& file,mParser->projectFiles()) {
PFileIncludes p = mParser->findFileIncludes(file); PFileIncludes p = mParser->findFileIncludes(file);
if (!p) if (!p)
return; return;
@ -427,16 +427,6 @@ ClassBrowserNode* ClassBrowserModel::getParentNode(const PStatement &parentState
return parentNode.get(); return parentNode.get();
} }
const QStringList &ClassBrowserModel::currentFiles() const
{
return mCurrentFiles;
}
void ClassBrowserModel::setCurrentFiles(const QStringList &newCurrentFiles)
{
mCurrentFiles = newCurrentFiles;
}
QModelIndex ClassBrowserModel::modelIndexForStatement(const QString &key) QModelIndex ClassBrowserModel::modelIndexForStatement(const QString &key)
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);

View File

@ -62,9 +62,6 @@ public:
ProjectClassBrowserType classBrowserType() const; ProjectClassBrowserType classBrowserType() const;
void setClassBrowserType(ProjectClassBrowserType newClassBrowserType); void setClassBrowserType(ProjectClassBrowserType newClassBrowserType);
const QStringList &currentFiles() const;
void setCurrentFiles(const QStringList &newCurrentFiles);
QModelIndex modelIndexForStatement(const QString& key); QModelIndex modelIndexForStatement(const QString& key);
signals: signals:
void refreshStarted(); void refreshStarted();
@ -90,7 +87,6 @@ private:
int mUpdateCount; int mUpdateCount;
QMutex mMutex; QMutex mMutex;
QString mCurrentFile; QString mCurrentFile;
QStringList mCurrentFiles;
std::shared_ptr<QHash<StatementKind, std::shared_ptr<ColorSchemeItem> > > mColors; std::shared_ptr<QHash<StatementKind, std::shared_ptr<ColorSchemeItem> > > mColors;
ProjectClassBrowserType mClassBrowserType; ProjectClassBrowserType mClassBrowserType;