- fix: Crash when editing a function at the end of file without ; or {

- enhancement: Add the "parsing TODOs" option in Options Dialog / Editor / Misc
  - enhancement: Remove todos/bookmarks/breakpoints when deleting file from project
  - enhancement: Rename filenames in todos/bookmarks/breakpoints  when renaming project file
This commit is contained in:
Roy Qu 2022-11-07 21:44:12 +08:00
parent c9e4238329
commit e0c4ba201d
15 changed files with 155 additions and 62 deletions

View File

@ -3,6 +3,10 @@ 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;
- fix: "check when open/save" and "check when caret line changed" in Options Dialog / Editor / Syntax Check don't work
- fix: Crash when editing a function at the end of file without ; or {
- enhancement: Add the "parsing TODOs" option in Options Dialog / Editor / Misc
- enhancement: Remove todos/bookmarks/breakpoints when deleting file from project
- enhancement: Rename filenames in todos/bookmarks/breakpoints when renaming project file
Red Panda C++ Version 2.3

View File

@ -1843,6 +1843,29 @@ void BreakpointModel::removeBreakpoint(int row, bool forProject)
endRemoveRows();
}
void BreakpointModel::removeBreakpointsInFile(const QString &fileName, bool forProject)
{
QList<PBreakpoint> & lst=forProject?mProjectBreakpoints:mBreakpoints;
for (int i=lst.count()-1;i>=0;i--) {
if (lst[i]->filename==fileName)
removeBreakpoint(i,forProject);
}
}
void BreakpointModel::renameBreakpointFilenames(const QString &oldFileName, const QString &newFileName, bool forProject)
{
QList<PBreakpoint> & lst=forProject?mProjectBreakpoints:mBreakpoints;
for (int i=lst.count()-1;i>=0;i--) {
if (lst[i]->filename==oldFileName) {
lst[i]->filename=newFileName;
if (forProject == mIsForProject) {
QModelIndex index=createIndex(i,0);
emit dataChanged(index,index);
}
}
}
}
void BreakpointModel::invalidateAllBreakpointNumbers()
{
foreach (PBreakpoint bp,mBreakpoints) {

View File

@ -130,6 +130,8 @@ public:
void addBreakpoint(PBreakpoint p, bool forProject);
void clear(bool forProject);
void removeBreakpoint(int index, bool forProject);
void removeBreakpointsInFile(const QString& fileName, bool forProject);
void renameBreakpointFilenames(const QString& oldFileName,const QString& newFileName, bool forProject);
PBreakpoint setBreakPointCondition(int index, const QString& condition, bool forProject);
const QList<PBreakpoint>& breakpoints(bool forProject) const {
return forProject?mProjectBreakpoints:mBreakpoints;

View File

@ -350,7 +350,7 @@ bool Editor::saveAs(const QString &name, bool fromProject){
clearSyntaxIssues();
pMainWindow->fileSystemWatcher()->removePath(mFilename);
if (pSettings->codeCompletion().enabled() && mParser) {
if (pSettings->codeCompletion().enabled() && mParser && !inProject()) {
mParser->invalidateFile(mFilename);
}
@ -395,10 +395,13 @@ bool Editor::saveAs(const QString &name, bool fromProject){
}
applyColorScheme(pSettings->editor().colorScheme());
if (!inProject())
reparse(false);
if (pSettings->editor().syntaxCheckWhenSave())
checkSyntaxInBack();
if (!inProject())
reparseTodo();
if (!shouldOpenInReadonly()) {
@ -2775,6 +2778,7 @@ void Editor::reparseTodo()
return;
if (!highlighter())
return;
if (pSettings->editor().parseTodos())
pMainWindow->todoParser()->parseFile(mFilename, inProject());
}

View File

@ -1127,7 +1127,7 @@ void MainWindow::rebuildOpenedFileHisotryMenu()
//menu takes the ownership
QAction* action = new QAction(filename,mMenuRecentProjects);
connect(action, &QAction::triggered, [filename,this](bool){
this->openProject(filename);
openProject(filename);
});
mMenuRecentProjects->addAction(action);
}
@ -1430,6 +1430,7 @@ void MainWindow::openProject(const QString &filename, bool openFiles)
changeFileExt(mProject->filename(), PROJECT_DEBUG_EXT),
mProject->directory());
mTodoModel.setIsForProject(true);
if (pSettings->editor().parseTodos())
mTodoParser->parseFiles(mProject->unitFiles());
if (openFiles) {
@ -1455,6 +1456,7 @@ void MainWindow::openProject(const QString &filename, bool openFiles)
mClassBrowserModel.endUpdate();
if (oldEditor)
mEditorList->closeEditor(oldEditor);
setupSlotsForProject();
//updateForEncodingInfo();
}
@ -4565,6 +4567,7 @@ void MainWindow::onTodoParsingFile(const QString& filename)
{
mTodoModel.removeTodosForFile(filename);
}
void MainWindow::onTodoParseStarted()
{
mTodoModel.clear();
@ -6295,8 +6298,6 @@ void MainWindow::on_actionNew_Project_triggered()
}
mProject->saveAll();
updateProjectView();
mTodoParser->parseFiles(mProject->unitFiles());
scanActiveProject(true);
Editor* editor = mEditorList->getEditor();
updateClassBrowserForEditor(editor);
if (editor) {
@ -6308,8 +6309,12 @@ void MainWindow::on_actionNew_Project_triggered()
ui->projectView->setCurrentIndex(index);
}
}
scanActiveProject(true);
if (pSettings->editor().parseTodos())
mTodoParser->parseFiles(mProject->unitFiles());
if (pSettings->ui().showProject())
ui->tabExplorer->setCurrentWidget(ui->tabProject);
setupSlotsForProject();
}
pSettings->ui().setNewProjectDialogWidth(dialog.width());
pSettings->ui().setNewProjectDialogHeight(dialog.height());
@ -6842,6 +6847,49 @@ QString MainWindow::switchHeaderSourceTarget(Editor *editor)
return QString();
}
void MainWindow::setupSlotsForProject()
{
connect(mProject.get(), &Project::unitAdded,
this, &MainWindow::onProjectUnitAdded);
connect(mProject.get(), &Project::unitRemoved,
this, &MainWindow::onProjectUnitRemoved);
connect(mProject.get(), &Project::unitRenamed,
this, &MainWindow::onProjectUnitRenamed);
}
void MainWindow::onProjectUnitAdded(const QString &filename)
{
mProject->cppParser()->addProjectFile(filename,true);
if (pSettings->editor().parseTodos()) {
mTodoParser->parseFile(filename,true);
}
}
void MainWindow::onProjectUnitRemoved(const QString &filename)
{
mProject->cppParser()->invalidateFile(filename);
mProject->cppParser()->removeProjectFile(filename);
if (pSettings->editor().parseTodos()) {
mTodoModel.removeTodosForFile(filename);
}
mDebugger->breakpointModel()->removeBreakpointsInFile(filename,true);
mBookmarkModel->removeBookmarks(filename,true);
}
void MainWindow::onProjectUnitRenamed(const QString &oldFilename, const QString &newFilename)
{
mProject->cppParser()->invalidateFile(oldFilename);
mProject->cppParser()->removeProjectFile(oldFilename);
mProject->cppParser()->addProjectFile(newFilename,true);
parseFileList(mProject->cppParser());
if (pSettings->editor().parseTodos()) {
mTodoModel.removeTodosForFile(oldFilename);
mTodoParser->parseFile(newFilename,true);
}
mBookmarkModel->renameBookmarkFile(oldFilename,newFilename,true);
mDebugger->breakpointModel()->renameBreakpointFilenames(oldFilename,newFilename,true);
}
void MainWindow::onProjectViewNodeRenamed()
{
updateProjectView();
@ -7023,6 +7071,11 @@ void MainWindow::onEditorRenamed(const QString &oldFilename, const QString &newF
{
if (firstSave)
mOJProblemSetModel.updateProblemAnswerFilename(oldFilename, newFilename);
Editor * editor=mEditorList->getOpenedEditorByFilename(newFilename);
if (editor && !editor->inProject()) {
mBookmarkModel->renameBookmarkFile(oldFilename,newFilename,false);
mDebugger->breakpointModel()->renameBreakpointFilenames(oldFilename,newFilename,false);
}
}
void MainWindow::on_EditorTabsLeft_currentChanged(int)

View File

@ -293,6 +293,10 @@ private:
QString switchHeaderSourceTarget(Editor *editor);
private slots:
void setupSlotsForProject();
void onProjectUnitAdded(const QString &filename);
void onProjectUnitRemoved(const QString &filename);
void onProjectUnitRenamed(const QString &oldFilename, const QString& newFilename);
void onProjectViewNodeRenamed();
void setDockExplorerToArea(const Qt::DockWidgetArea &area);
void setDockMessagesToArea(const Qt::DockWidgetArea &area);

View File

@ -2619,10 +2619,11 @@ void CppParser::handleMethod(StatementKind functionKind,const QString &sType, co
} else
mIndex++;
}
}
if (mIndex>=mTokenizer.tokenCount())
return;
// Check if this is a prototype
if (mTokenizer[mIndex]->text.startsWith(';')
|| mTokenizer[mIndex]->text.startsWith('}')) {// prototype

View File

@ -329,8 +329,6 @@ PProjectModelNode Project::makeProjectNode()
PProjectUnit Project::newUnit(PProjectModelNode parentNode, const QString& customFileName)
{
PProjectUnit newUnit = std::make_shared<ProjectUnit>(this);
// Select folder to add unit to
if (!parentNode)
parentNode = mRootNode; // project root node
@ -348,47 +346,7 @@ PProjectUnit Project::newUnit(PProjectModelNode parentNode, const QString& custo
} else {
s = cleanPath(dir.absoluteFilePath(customFileName));
}
if (mOptions.modelType == ProjectModelType::FileSystem) {
// in file system mode, parentNode is determined by file's path
parentNode = getParentFileSystemFolderNode(s);
}
// Add
// Set all properties
newUnit->setFileName(s);
newUnit->setFolder(getNodePath(parentNode));
PProjectModelNode node = makeNewFileNode(newUnit,newUnit->priority(),parentNode);
newUnit->setNode(node);
mUnits.insert(newUnit->fileName(), newUnit);
//parentNode.Expand(True);
switch(getFileType(customFileName)) {
case FileType::CSource:
newUnit->setCompile(true);
newUnit->setCompileCpp(false);
newUnit->setLink(true);
break;
case FileType::CppSource:
newUnit->setCompile(true);
newUnit->setCompileCpp(true);
newUnit->setLink(true);
break;
case FileType::WindowsResourceSource:
newUnit->setCompile(true);
newUnit->setCompileCpp(mOptions.isCpp);
newUnit->setLink(false);
break;
default:
newUnit->setCompile(false);
newUnit->setCompileCpp(false);
newUnit->setLink(false);
}
newUnit->setPriority(1000);
newUnit->setOverrideBuildCmd(false);
newUnit->setBuildCmd("");
newUnit->setEncoding(toByteArray(mOptions.encoding));
mParser->addProjectFile(newUnit->fileName(),true);
PProjectUnit newUnit = internalAddUnit(s,parentNode);
emit unitAdded(newUnit->fileName());
return newUnit;
}
@ -533,8 +491,6 @@ 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;
@ -1225,7 +1181,6 @@ PProjectUnit Project::addUnit(const QString &inFileName, PProjectModelNode paren
{
PProjectUnit newUnit=internalAddUnit(inFileName, parentNode);
if (newUnit) {
mParser->addProjectFile(newUnit->fileName(),true);
emit unitAdded(newUnit->fileName());
}
return newUnit;

View File

@ -216,6 +216,8 @@ public:
void setModified(bool value);
PProjectModelNode addFolder(PProjectModelNode parentFolder, const QString& s);
PProjectUnit newUnit(PProjectModelNode parentNode,
const QString& customFileName="");
PProjectUnit addUnit(const QString& inFileName,
PProjectModelNode parentNode);
QString folder();
@ -227,8 +229,6 @@ public:
QString getNodePath(PProjectModelNode node);
void incrementBuildNumber();
PProjectUnit newUnit(PProjectModelNode parentNode,
const QString& customFileName="");
Editor* openUnit(PProjectUnit& unit, bool forceOpen=true);
Editor* openUnit(PProjectUnit& unit, const PProjectEditorLayout& layout);
Editor* unitEditor(const PProjectUnit& unit) const;

View File

@ -665,6 +665,16 @@ void Settings::Editor::setAutoFormatWhenSaved(bool newAutoFormatWhenSaved)
mAutoFormatWhenSaved = newAutoFormatWhenSaved;
}
bool Settings::Editor::parseTodos() const
{
return mParseTodos;
}
void Settings::Editor::setParseTodos(bool newParseTodos)
{
mParseTodos = newParseTodos;
}
bool Settings::Editor::highlightCurrentWord() const
{
return mHighlightCurrentWord;
@ -1246,6 +1256,7 @@ void Settings::Editor::doSave()
saveValue("undo_limit",mUndoLimit);
saveValue("undo_memory_usage", mUndoMemoryUsage);
saveValue("auto_format_when_saved", mAutoFormatWhenSaved);
saveValue("parse_todos",mParseTodos);
//tooltips
saveValue("enable_tooltips",mEnableTooltips);
@ -1389,6 +1400,8 @@ void Settings::Editor::doLoad()
mUndoLimit = intValue("undo_limit",0);
mUndoMemoryUsage = intValue("undo_memory_usage", 10);
mAutoFormatWhenSaved = boolValue("auto_format_when_saved", false);
mParseTodos = boolValue("parse_todos",true);
//tooltips
mEnableTooltips = boolValue("enable_tooltips",true);

View File

@ -367,6 +367,9 @@ public:
bool autoFormatWhenSaved() const;
void setAutoFormatWhenSaved(bool newAutoFormatWhenSaved);
bool parseTodos() const;
void setParseTodos(bool newParseTodos);
private:
//General
// indents
@ -476,6 +479,7 @@ public:
int mUndoLimit;
int mUndoMemoryUsage;
bool mAutoFormatWhenSaved;
bool mParseTodos;
//hints tooltip

View File

@ -67,6 +67,7 @@ void EditorMiscWidget::doLoad()
ui->spinMaxUndo->setValue(pSettings->editor().undoLimit());
ui->spinMaxUndoMemory->setValue(pSettings->editor().undoMemoryUsage());
ui->chkAutoReformat->setChecked(pSettings->editor().autoFormatWhenSaved());
ui->chkParseTodos->setChecked(pSettings->editor().parseTodos());
}
void EditorMiscWidget::doSave()
@ -84,6 +85,8 @@ void EditorMiscWidget::doSave()
pSettings->editor().setUndoLimit(ui->spinMaxUndo->value());
pSettings->editor().setUndoMemoryUsage(ui->spinMaxUndoMemory->value());
pSettings->editor().setAutoFormatWhenSaved(ui->chkAutoReformat->isChecked());
pSettings->editor().setParseTodos(ui->chkParseTodos->isChecked());
pSettings->editor().save();
pMainWindow->updateEditorSettings();

View File

@ -29,9 +29,9 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkAutoDetectFileEncoding">
<widget class="QCheckBox" name="chkParseTodos">
<property name="text">
<string>Auto detect encoding when openning files</string>
<string>Parse TODOs</string>
</property>
</widget>
</item>
@ -147,6 +147,13 @@
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkAutoDetectFileEncoding">
<property name="text">
<string>Auto detect encoding when openning files</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">

View File

@ -138,6 +138,25 @@ void BookmarkModel::removeBookmarks(const QString &filename, bool forProject)
}
}
void BookmarkModel::renameBookmarkFile(const QString& oldFilename, const QString& newFilename, bool forProject)
{
QList<PBookmark> bookmarks;
if (forProject)
bookmarks = mProjectBookmarks;
else
bookmarks = mBookmarks;
for (int i=bookmarks.count()-1;i>=0;i--) {
PBookmark bookmark = bookmarks[i];
if (bookmark->filename.compare(oldFilename, PATH_SENSITIVITY) == 0) {
bookmark->filename=newFilename;
if (forProject==mIsForProject) {
QModelIndex index=createIndex(i,2);
emit dataChanged(index,index);
}
}
}
}
void BookmarkModel::clear(bool forProject)
{
if (forProject==mIsForProject)

View File

@ -43,6 +43,7 @@ public:
PBookmark bookmark(const QString&filename, int line);
bool removeBookmark(const QString&filename, int line, bool forProject);
void removeBookmarks(const QString& filename, bool forProject);
void renameBookmarkFile(const QString& oldFilename, const QString& newFilename, bool forProject);
void clear(bool forProject);
bool updateDescription(const QString&filename, int line, const QString& description, bool forProject);
bool updateDescription(const QString&filename, int line, const QString& description);