- 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:
parent
c9e4238329
commit
e0c4ba201d
4
NEWS.md
4
NEWS.md
|
@ -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
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue