diff --git a/NEWS.md b/NEWS.md index 71437e1d..22e7e537 100644 --- a/NEWS.md +++ b/NEWS.md @@ -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 diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 6243bb4e..f96ef232 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -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(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); diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 1e0fc487..1eb109a7 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -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 diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index db272acf..307d323b 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -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; diff --git a/RedPandaIDE/parser/parserutils.h b/RedPandaIDE/parser/parserutils.h index 0f711e73..21d8dea6 100644 --- a/RedPandaIDE/parser/parserutils.h +++ b/RedPandaIDE/parser/parserutils.h @@ -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 }; diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp index 54f50712..472d22c8 100644 --- a/RedPandaIDE/project.cpp +++ b/RedPandaIDE/project.cpp @@ -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 diff --git a/RedPandaIDE/projectoptions.cpp b/RedPandaIDE/projectoptions.cpp index fe38aceb..d286bb99 100644 --- a/RedPandaIDE/projectoptions.cpp +++ b/RedPandaIDE/projectoptions.cpp @@ -54,5 +54,6 @@ ProjectOptions::ProjectOptions() staticLink = true; addCharset = true; modelType = ProjectModelType::FileSystem; + classBrowserType = ProjectClassBrowserType::CurrentFile; execEncoding = ENCODING_SYSTEM_DEFAULT; } diff --git a/RedPandaIDE/projectoptions.h b/RedPandaIDE/projectoptions.h index 28848b91..864f5e13 100644 --- a/RedPandaIDE/projectoptions.h +++ b/RedPandaIDE/projectoptions.h @@ -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 diff --git a/RedPandaIDE/projecttemplate.cpp b/RedPandaIDE/projecttemplate.cpp index 74012232..f9408cde 100644 --- a/RedPandaIDE/projecttemplate.cpp +++ b/RedPandaIDE/projecttemplate.cpp @@ -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); } diff --git a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts index f94567d9..58329a9a 100644 --- a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts +++ b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts @@ -4676,6 +4676,14 @@ Can't open last open information file '%1' for write! + + In current file + + + + In current project + + NewClassDialog @@ -4933,11 +4941,11 @@ Can't save file - Impossível salvar arquivo + Impossível salvar arquivo Can't save file '%1' - Impossível salvar arquivo '%1' + Impossível salvar arquivo '%1' Error Load File diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts index a2de02a4..dcbe77b4 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts @@ -188,17 +188,17 @@ p, li { white-space: pre-wrap; } BacktraceModel - + Function 函数 - + Filename 文件名 - + Line @@ -206,37 +206,37 @@ p, li { white-space: pre-wrap; } BookmarkModel - + Save file '%1' failed. 保存文件'%1'失败。 - + Can't open file '%1' for write. 无法写入文件'%1'. - + Error in json file '%1':%2 : %3 JSON文件'%1':%2中存在错误:%3 - + Can't open file '%1' for read. 无法读取文件'%1'. - + Description 描述 - + Line - + Filename 文件名 @@ -244,17 +244,17 @@ p, li { white-space: pre-wrap; } BreakpointModel - + Filename 文件名 - + Line - + Condition 条件 @@ -563,27 +563,27 @@ p, li { white-space: pre-wrap; } - 编译时间: %1 秒 - + [Error] [错误] - + [Warning] [警告] - + [Info] [信息] - + [Note] [说明] - + The compiler process for '%1' failed to start. 无法启动编译器进程'%1'。 @@ -592,27 +592,27 @@ p, li { white-space: pre-wrap; } 无法启动编译进程。 - + The compiler process crashed after starting successfully. 编译进程启动后崩溃。 - + The last waitFor...() function timed out. waitFor()函数等待超时。 - + An error occurred when attempting to write to the compiler process. 在向编译进程输入内容时出错。 - + An error occurred when attempting to read from the compiler process. 在从编译进程读取内容时出错。 - + An unknown error occurred. 发生了未知错误。 @@ -1253,27 +1253,27 @@ Are you really want to continue? 无法在"%1"找到gdb server - + Execute to evaluate 执行以求值 - + Save file '%1' failed. 保存文件'%1'失败。 - + Can't open file '%1' for write. 无法写入文件'%1'. - + Error in json file '%1':%2 : %3 JSON文件'%1':%2中存在错误:%3 - + Can't open file '%1' for read. 无法读取文件'%1'. @@ -1282,22 +1282,22 @@ Are you really want to continue? 不在当前语境中 - + Compile 编译 - + Source file is more recent than executable. 源文件比程序文件新。 - + Recompile? 重新编译? - + Signal "%1" Received: 收到信号"%1": @@ -1305,7 +1305,7 @@ Are you really want to continue? Editor - + untitled 无标题 @@ -1318,13 +1318,13 @@ Are you really want to continue? 失败 - - - - - - - + + + + + + + Error 错误 @@ -1333,44 +1333,44 @@ Are you really want to continue? 无法写入文件"%1" - + Save As 另存为 - + File %1 already openned! 文件%1已经被打开! - + The text to be copied exceeds count limit! 要复制的内容超过了行数限制! - + The text to be copied exceeds character limit! 要复制的内容超过了字符数限制! - + The text to be cut exceeds count limit! 要剪切的内容超过了行数限制! - + The text to be cut exceeds character limit! 要剪切的内容超过了字符数限制! - + Print Document 打印文档 - - - + + + Ctrl+click for more info Ctrl+单击以获取更多信息 @@ -1379,27 +1379,27 @@ Are you really want to continue? 未找到符号'%1'! - + astyle not found 找不到astyle程序 - + Can't find astyle in "%1". 找不到astyle程序"%1". - + Break point condition 断点条件 - + Enter the condition of the breakpoint: 输入当前断点的生效条件: - + Readonly 只读 @@ -3894,18 +3894,18 @@ Are you really want to continue? MainWindow - + Red Panda C++ 小熊猫C++ - - - - - + + + + + Issues 编译器 @@ -3979,7 +3979,7 @@ Are you really want to continue? - + Debug Console 调试主控台 @@ -4113,8 +4113,8 @@ Are you really want to continue? - - + + Compile 编译 @@ -4192,9 +4192,9 @@ Are you really want to continue? - - - + + + Copy 复制 @@ -4205,7 +4205,7 @@ Are you really want to continue? - + Paste 粘贴 @@ -4216,8 +4216,8 @@ Are you really want to continue? - - + + Select All 选择全部 @@ -4343,7 +4343,7 @@ Are you really want to continue? - + New Problem Set 新建试题集 @@ -4362,14 +4362,14 @@ Are you really want to continue? - + Save Problem Set 保存试题集 - + Load Problem Set 载入试题集 @@ -4430,7 +4430,7 @@ Are you really want to continue? - + Run All Cases Run Current Case 运行所有案例 @@ -4723,7 +4723,7 @@ Are you really want to continue? - + Clear all breakpoints 删除所有断点 @@ -4888,7 +4888,7 @@ Are you really want to continue? 保存为模板... - + New File 新建文件 @@ -4929,7 +4929,7 @@ Are you really want to continue? - + Rename Symbol 重命名符号 @@ -4950,13 +4950,13 @@ Are you really want to continue? - + Export As RTF 导出为RTF - + Export As HTML 导出为HTML @@ -5225,7 +5225,7 @@ Are you really want to continue? 运行参数... - + File Encoding 文件编码 @@ -5235,32 +5235,32 @@ Are you really want to continue? 文件历史 - - - - - - + + + + + + Debugging 正在调试 - - - - - - + + + + + + Running 正在运行 - - - - - - + + + + + + Compiling 正在编译 @@ -5269,23 +5269,23 @@ Are you really want to continue? 行:%1 列:%2 已选择:%3 总行数:%4 总长度:%5 - + Line:%1 Col:%2 Selected:%3 Lines:%4 Length:%5 Line: %1 Col: %2 Selected: %3 Lines: %4 Length: %5 行: %1 列: %2 已选择 :%3 总行数: %4 总长度: %5 - + Read Only 只读 - + Insert 插入 - + Overwrite 覆写 @@ -5298,133 +5298,133 @@ Are you really want to continue? 你确定要关闭'%1'吗? - - + + Confirm 确认 - - - + + + Source file is not compiled. 源文件尚未编译。 - - + + Compile now? 现在编译? - - + + Source file is more recent than executable. 源文件比可执行程序新。 - + Recompile now? 重新编译? - - - - + + + + Wrong Compiler Settings 错误的编译器设置 - - - - + + + + Compiler is set not to generate executable. 编译器被设置为不生成可执行文件。 - - + + We need the executabe to run problem case. 我们需要可执行文件来运行试题案例。 - + No compiler set 无编译器设置 - + No compiler set is configured. 没有配置编译器设置。 - + Can't start debugging. 无法启动调试器 - - + + Enable debugging 启用调试参数 - - + + You have not enabled debugging info (-g3) and/or stripped it from the executable (-s) in Compiler Options.<BR /><BR />Do you want to correct this now? 当前编译设置中未启用调试选项(-g3),或启用了信息剥除选项(-s)<br /><br/>是否纠正这一问题? - + Project not built 项目尚未构建 - + Project hasn't been built. Build it now? 项目尚未构建。是否构建? - + Host applcation missing 宿主程序不存在 - + DLL project needs a host application to run. 动态链接库(DLL)需要一个宿主程序来运行。 - + But it's missing. 但它不存在。 - + Host application not exists 宿主程序不存在 - + Host application file '%1' doesn't exist. 宿主程序'%1'不存在。 - - + + Please correct this before start debugging 请在调试前改正设置。 - + Recompile? 重新编译? - - + + Save last open info error 保存上次打开信息失败 @@ -5433,60 +5433,60 @@ Are you really want to continue? 无法删除旧上次打开信息文件'%1' - + Can't save last open info file '%1' 无法保存上次打开信息文件'%1' - - + + Load last open info error 载入上次打开信息失败 - - + + Can't load last open info file '%1' 无法载入上次打开信息文件'%1' - + Open Source File 打开源代码文件 - - + + Batch Set Cases 批量设置案例 - + Show detail debug logs 显示详细调试器日志 - + Copy all 全部复制 - + Go to Line 跳转到行 - + Line - + Template Exists 模板已存在 - + Template %1 already exists. Do you want to overwrite? 模板%1已存在。是否覆盖? @@ -5494,9 +5494,9 @@ Are you really want to continue? - - - + + + Clear 清除 @@ -5512,7 +5512,7 @@ Are you really want to continue? - + Problem Set %1 试题集%1 @@ -5533,68 +5533,68 @@ Are you really want to continue? 或者选择使用其他的网络端口。 - - + + Rebuild Project 重新构建项目 - - + + Project has been modified, do you want to rebuild it? 项目已经被修改过,是否需要重新构建? - + Auto Save Error 自动保存出错 - + Auto save "%1" to "%2" failed:%3 自动保存"%1"到"%2"失败:%3 - + Properties... 试题属性... - + Set Problem Set Name 设置试题集名称 - + Problem Set Name: 试题集名称: - + Remove 删除 - + Remove All Bookmarks 删除全部书签 - + Modify Description 修改描述 - - - + + + Bookmark Description 书签描述 - - - + + + Description: 描述: @@ -5603,184 +5603,194 @@ Are you really want to continue? 在调试主控台中显示调试器输出 - + Remove this search 清除这次搜索 - + Clear all searches 删除所有搜索 - + Breakpoint condition... 断点条件... - + Break point condition 断点条件 - + Enter the condition of the breakpoint: 输入当前断点的生效条件: - + Remove All Breakpoints Remove all breakpoints 删除所有断点 - + Remove Breakpoint 删除当前断点 - + Rename File 重命名文件 - - + + Add Folder 添加文件夹 - - + + New folder 新文件夹 - + Folder name: 文件夹: - + Rename Folder 重命名 - + Can't open last open information file '%1' for write! 无法写入配置文件'%1'。 - + Run Current Case 运行当前案例 - + Remove Folder 删除文件夹 - + Switch to normal view 切换为普通视图 - + Switch to custom view 切换为自定义视图 - + Sort By Type 按类型排序 - + Sort alphabetically 按名称排序 - + Show inherited members 显示继承的成员 - + Goto declaration 跳转到声明处 - + Goto definition 跳转到定义处 - - + + In current file + 仅当前文件 + + + + In current project + 整个项目 + + + + New Folder 新建文件夹 - + Rename 重命名 - - - - + + + + Delete 删除 - + Open in Editor 在编辑器中打开 - + Open in External Program 使用外部程序打开 - + Open in Terminal 在终端中打开 - + Open in Windows Explorer 在Windows浏览器中打开 - + Character sets 字符集 - + Convert to %1 转换为%1编码 - + %1 files autosaved 已自动保存%1个文件 - + Set answer to... 设置答案源代码... - + select other file... 选择其他文件... - + Select Answer Source File 选择答案源代码文件 @@ -5790,7 +5800,7 @@ Are you really want to continue? C/C++源代码文件 (*.c *.cpp *.cc *.cxx) - + New Folder %1 新建文件夹%1 @@ -5803,67 +5813,67 @@ Are you really want to continue? 无标题%1 - + Do you really want to delete %1? 你真的要删除%1吗? - + Do you really want to delete %1 files? 你真的要删除%1个文件吗? - + Save project 保存项目 - + The project '%1' has modifications. 项目'%1'有改动。 - - + + Do you want to save it? 需要保存吗? - - + + File Changed 文件已发生变化 - + New Project File? 新建项目文件? - + Do you want to add the new file to the project? 您是否要将新建的文件加入项目? - - - + + + Save Error 保存失败 - + Change Project Compiler Set 改变项目编译器配置集 - + Change the project's compiler set will lose all custom compiler set options. 改变项目的编译器配置集会导致所有的自定义编译器选项被重置。 - - + + Do you really want to do that? 你真的想要那么做吗? @@ -5872,119 +5882,119 @@ Are you really want to continue? 批量设置案例 - + Choose input files 选择输入数据文件 - + Input data files (*.in) 输入数据文件 (*.in) - + untitled%1 无标题%1 - + Modify Watch 修改监视表达式 - + Watch Expression 监视表达式 - + Do you really want to clear all breakpoints in this file? 您真的要清除该文件的所有断点吗? - + New project 新建项目 - + Close %1 and start new project? 关闭'%1'以打开新项目? - + Folder not exist 文件夹不存在 - + Folder '%1' doesn't exist. Create it now? 文件夹'%1'不存在。是否创建? - + Can't create folder 无法创建文件夹 - + Failed to create folder '%1'. 创建文件夹'%1'失败。 - + Save new project as - + Folder %1 is not empty. 文件夹%1不是空的。 - + Do you really want to delete it? 你真的要删除它吗? - + Change working folder 改变工作文件夹 - + File '%1' is not in the current working folder. File '%1' is not in the current working folder 文件'%1'不在当前工作文件夹中。 - + Do you want to change working folder to '%1'? 是否将工作文件夹改设为'%1'? - + Can't Commit 无法提交 - + Git needs user info to commit. Git需要用信息进行提交。 - + Choose Input Data File 选择输入数据文件 - - + + All files (*.*) 所有文件 (*.*) - + Choose Expected Output Data File Choose Expected Input Data File 选择期望输出文件 @@ -5996,59 +6006,59 @@ Are you really want to continue? - + Choose Working Folder 选择工作文件夹 - - + + Header Exists 头文件已存在 - - + + Header file "%1" already exists! 头文件"%1"已存在! - + Source Exists 源文件已存在! - + Source file "%1" already exists! 源文件"%1"已存在! - + Can't commit! 无法提交! - + The following files are in conflicting: 下列文件处于冲突状态,请解决后重新添加和提交: - + Commit Message 提交信息 - + Commit Message: 提交信息: - + Commit Failed 提交失败 - + Commit message shouldn't be empty! 提交信息不能为空! @@ -6057,137 +6067,137 @@ Are you really want to continue? 小熊猫Dev-C++项目文件 (*.dev) - + New project fail 新建项目失败 - + Can't assign project template 无法使用模板创建项目 - + Remove file 删除文件 - + Remove the file from disk? 同时从硬盘上删除文件? - - - + + + untitled 无标题 - + New Project File Name 新的项目文件名 - + File Name: 文件名: - + File Already Exists! 文件已存在! - + File '%1' already exists! 文件'%1'已经存在! - + Add to project 添加到项目 - + C/C++ Source Files (*.c *.cpp *.cc *.cxx) C/C++源代码文件 (*.c *.cpp *.cc *.cxx) - + This operation will remove all cases for the current problem. 本操作会删除此试题的所有案例。 - + Red Panda C++ project file (*.dev) 小熊猫C++项目文件(*.dev) - + Rename Error 重命名出错 - + Symbol '%1' is defined in system header. 符号'%1'在系统头文件中定义,无法修改。 - + New Name 新名称 - - + + Replace Error 替换出错 - + Can't open file '%1' for replace! 无法打开文件'%1'进行替换! - + Contents has changed since last search! 内容和上次查找时不一致。 - + Rich Text Format Files (*.rtf) RTF格式文件 (*.rtf) - + HTML Files (*.html) HTML文件 (*.html) - + The current problem set is not empty. 当前的试题集不是空的。 - + Problem %1 试题%1 - - + + Problem Set Files (*.pbs) 试题集文件 (*.pbs) - + Load Error 载入失败 - - + + Problem Case %1 试题案例%1 @@ -6197,16 +6207,16 @@ Are you really want to continue? - - - - - - - - - - + + + + + + + + + + Error 错误 @@ -6216,96 +6226,96 @@ Are you really want to continue? 项目历史 - + Load Theme Error 载入主题失败 - - + + Clear History 清除历史 - - + + Version Control 版本控制 - + File '%1' was changed. 磁盘文件'%1'已被修改。 - + Reload its content from disk? 是否重新读取它的内容? - + File '%1' was removed. 磁盘文件'%1'已被删除。 - + Keep it open? 是否保持它在小熊猫C++中打开的编辑窗口? - + Open 打开 - + Compile Failed 编译失败 - + Run Failed 运行失败 - - - - + + + + Confirm Convertion 确认转换 - - - - + + + + The editing file will be saved using %1 encoding. <br />This operation can't be reverted. <br />Are you sure to continue? 当前编辑器中的文件将会使用%1编码保存。<br />这项操作无法被撤回。<br />你确定要继续吗? - + New Watch Expression 新监视表达式 - + Enter Watch Expression (it is recommended to use 'this->' for class members): 输入监视表达式 - + Parsing file %1 of %2: "%3" (%1/%2)正在解析文件"%3" - - + + Done parsing %1 files in %2 seconds 完成%1个文件的解析,用时%2秒 - + (%1 files per second) (每秒%1个文件) @@ -6644,120 +6654,118 @@ Are you really want to continue? 找不到项目文件'%1'! - + untitled 无标题 - Can't save file - 无法保存文件 + 无法保存文件 - Can't save file '%1' - 无法保存文件'%1'. + 无法保存文件'%1'. - + Error Load File 载入文件错误 - - + + Error 错误 - + Can't create folder %1 无法创建文件夹%1 - + Warning 警告 - - + + Can't save file %1 无法保存文件%1 - + File Exists 文件已存在 - + File '%1' is already in the project 文件'%1'已在项目中 - + Project Updated 项目已升级 - + Your project was succesfully updated to a newer file format! 已成功将项目升级到新的格式 - + If something has gone wrong, we kept a backup-file: '%1'... 旧项目文件备份在'%1'。 - + Headers 头文件 - + Sources 源文件 - + Others 其他文件 - + Settings need update 设置需要更新 - + The compiler settings format of Red Panda C++ has changed. The compiler settings format of Dev-C++ has changed. 小熊猫C++的编译器设置格式已发生改变。 - + Please update your settings at Project >> Project Options >> Compiler and save your project. 请在项目 >> 项目属性 >> 编译器设置中修改您的设置并保存您的项目 - + Compiler not found 未找到编译器 - + The compiler set you have selected for this project, no longer exists. 您为该项目设置的编译器不存在。 - + It will be substituted by the global compiler set. 它将会被全局编译器设置代替。 - + Developed using the Red Panda C++ IDE Developed using the Red Panda Dev-C++ IDE 使用小熊猫C++编辑器开发 @@ -6863,32 +6871,32 @@ Are you really want to continue? - 资源文件: %1 - + Compiling project changes... 正在编译项目修改... - + - Project Filename: %1 - 项目文件名: %1 - + - Compiler Set Name: %1 - 编译器配置: %1 - + Processing makefile: 正在处理makefile... - + - makefile processer: %1 - makefile处理器: %1 - + - Command: %1 %2 - 命令: %1 %2 @@ -7226,32 +7234,32 @@ Are you really want to continue? ProjectModel - + File exists 文件已存在 - + File '%1' already exists. Delete it now? 文件'%1'已存在。是否删除? - + Remove failed 删除失败 - + Failed to remove file '%1' 无法删除文件'%1' - + Rename failed 改名失败 - + Failed to rename file '%1' to '%2' 无法将文件'%1'改名为'%2' @@ -7483,7 +7491,7 @@ Are you really want to continue? QApplication - + Error 错误 @@ -7491,12 +7499,12 @@ Are you really want to continue? QObject - + Save 保存 - + Save changes to %1? 将修改保存到"%1"? @@ -7553,7 +7561,7 @@ Are you really want to continue? 无法写入配置文件夹"%1" - + Can't load autolink settings 无法载入自动链接设置 @@ -7857,22 +7865,22 @@ Are you really want to continue? 下标"%1"越界 - + bytes 字节 - + KB KB - + MB MB - + GB GB @@ -8158,12 +8166,12 @@ Are you really want to continue? 无标题 - + constructor 构造函数 - + destructor 析构函数 @@ -8180,7 +8188,7 @@ Are you really want to continue? - + Can't open file '%1' for write. 无法写入文件'%1'. @@ -8199,12 +8207,12 @@ Are you really want to continue? RegisterModel - + Register 寄存器 - + Value @@ -8632,14 +8640,14 @@ Are you really want to continue? 性能 - + Compiler Set 编译器配置集 - + Compiler @@ -8651,7 +8659,7 @@ Are you really want to continue? 自动链接 - + @@ -8727,15 +8735,15 @@ Are you really want to continue? 杂项 - - + + Program Runner 程序运行 - + Problem Set 试题集 @@ -8906,42 +8914,42 @@ Are you really want to continue? StdinCompiler - + Checking file syntax... 正在检查语法... - + - Filename: %1 - 文件名: %1 - + - Compiler Set Name: %1 - 编译器配置: %1 - + Can't find the compiler for file %1 找不到适合文件%1的编译器 - + The Compiler '%1' doesn't exists! 编译器程序'%1'不存在! - + Processing %1 source file: 正在处理%1源程序文件: - + %1 Compiler: %2 %1编译器: %2 - + Command: %1 %2 命令: %1 %2 @@ -9013,22 +9021,22 @@ Are you really want to continue? TodoModel - + Filename 文件名 - + Line - + Column - + Content 内容 @@ -9225,14 +9233,14 @@ Are you really want to continue? JSON文件'%1':%2中存在错误:%3 - - + + Execute to evaluate 执行以求值 - - + + Not Valid 在当前作用域中无效 @@ -9241,17 +9249,17 @@ Are you really want to continue? 无法读取文件'%1'. - + Expression 表达式 - + Type 类型 - + Value diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts index aeea4d47..23169567 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts @@ -4529,6 +4529,14 @@ Can't open last open information file '%1' for write! + + In current file + + + + In current project + + NewClassDialog @@ -4780,14 +4788,6 @@ untitled - - Can't save file - - - - Can't save file '%1' - - Error Load File diff --git a/RedPandaIDE/widgets/classbrowser.cpp b/RedPandaIDE/widgets/classbrowser.cpp index 488495f4..d6776dc5 100644 --- a/RedPandaIDE/widgets/classbrowser.cpp +++ b/RedPandaIDE/widgets/classbrowser.cpp @@ -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 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(); 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(); 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 > > &ClassBrowserModel::colors() const { return mColors; diff --git a/RedPandaIDE/widgets/classbrowser.h b/RedPandaIDE/widgets/classbrowser.h index 7274b3ca..e628d6dc 100644 --- a/RedPandaIDE/widgets/classbrowser.h +++ b/RedPandaIDE/widgets/classbrowser.h @@ -19,6 +19,7 @@ #include #include "parser/cppparser.h" +#include "../projectoptions.h" struct ClassBrowserNode { ClassBrowserNode* parent; @@ -55,27 +56,37 @@ public: void beginUpdate(); void endUpdate(); - const std::shared_ptr > > &colors() const; void setColors(const std::shared_ptr > > &newColors); + ProjectClassBrowserType classBrowserType() const; + void setClassBrowserType(ProjectClassBrowserType newClassBrowserType); + + const QStringList ¤tFiles() 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 mDummyStatements; + QHash mScopeNodes; QVector mNodes; PCppParser mParser; bool mUpdating; int mUpdateCount; QMutex mMutex; QString mCurrentFile; + QStringList mCurrentFiles; std::shared_ptr > > mColors; + ProjectClassBrowserType mClassBrowserType; };