diff --git a/NEWS.md b/NEWS.md index 68cf4a1b..6806c6b1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -31,6 +31,8 @@ Red Panda C++ Version 1.5 - fix: toggle block comment/delete to word begin/delete to word end are not correctly disabled when editor not open - fix: index out of range in cpp highlighter - fix: memory leak in code folding processing + - change: add/remove/new project file won't save all openned project files. + - fix: save all project files shouldn't trigger syntax check in inactive editors Red Panda C++ Version 1.4 diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index b3bb62bb..af986408 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -265,6 +265,7 @@ bool Editor::save(bool force, bool doReparse) { // tr("File %1 is not writable!").arg(mFilename)); // return false; // } +// qDebug()<<"saving "<fileSystemWatcher()->addPath(mFilename); setModified(false); @@ -279,12 +280,11 @@ bool Editor::save(bool force, bool doReparse) { return false; } - if (doReparse && mParser) { + if (doReparse && isVisible()) { reparse(false); - } - if (doReparse && pSettings->editor().syntaxCheckWhenSave()) checkSyntaxInBack(); - reparseTodo(); + reparseTodo(); + } return true; } @@ -1302,7 +1302,11 @@ void Editor::showEvent(QShowEvent */*event*/) // && !inProject()) { // reparse(); // } - reparseTodo(); + if (!pMainWindow->isClosingAll() + && !pMainWindow->isQuitting()) { + checkSyntaxInBack(); + reparseTodo(); + } setHideTime(QDateTime()); } @@ -1553,16 +1557,16 @@ void Editor::onStatusChanged(QSynedit::StatusChanges changes) && !changes.testFlag(QSynedit::StatusChange::scReadOnly) && changes.testFlag(QSynedit::StatusChange::scCaretY))) { mCurrentLineModified = false; - if (!changes.testFlag(QSynedit::StatusChange::scOpenFile)) + if (!changes.testFlag(QSynedit::StatusChange::scOpenFile)) { reparse(false); + checkSyntaxInBack(); + reparseTodo(); + } // if (pSettings->codeCompletion().clearWhenEditorHidden() // && changes.testFlag(SynStatusChange::scOpenFile)) { // } else{ // reparse(); // } - if (pSettings->editor().syntaxCheckWhenLineChanged()) - checkSyntaxInBack(); - reparseTodo(); } mLineCount = document()->count(); if (changes.testFlag(QSynedit::scModifyChanged)) { diff --git a/RedPandaIDE/editorlist.cpp b/RedPandaIDE/editorlist.cpp index 2afcf621..a50d9a54 100644 --- a/RedPandaIDE/editorlist.cpp +++ b/RedPandaIDE/editorlist.cpp @@ -214,6 +214,48 @@ bool EditorList::swapEditor(Editor *editor) return true; } +void EditorList::saveAll() +{ + for (int i=0;imodified()) + e->save(); + } +} + +bool EditorList::saveAllForProject() +{ + for (int i=0;imodified() && e->inProject()) { + if (!e->save()) + return false; + } + } + return true; +} + +bool EditorList::projectEditorsModified() +{ + for (int i=0;imodified() && e->inProject()) { + return true; + } + } + return false; +} + +void EditorList::clearProjectEditorsModified() +{ + for (int i=0;iinProject()) { + e->setModified(false); + } + } +} + void EditorList::beginUpdate() { if (mUpdateCount==0) { mPanel->setUpdatesEnabled(false); diff --git a/RedPandaIDE/editorlist.h b/RedPandaIDE/editorlist.h index 4e9aded3..d0e7f5d1 100644 --- a/RedPandaIDE/editorlist.h +++ b/RedPandaIDE/editorlist.h @@ -49,6 +49,12 @@ public: bool swapEditor(Editor* editor); + void saveAll(); + bool saveAllForProject(); + + bool projectEditorsModified(); + void clearProjectEditorsModified(); + bool closeAll(bool force = false); void forceCloseEditor(Editor* editor); diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 1f6f7fc3..4914eca3 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -1685,8 +1685,10 @@ bool MainWindow::compile(bool rebuild) mCompilerManager->stopPausing(); CompileTarget target =getCompileTarget(); if (target == CompileTarget::Project) { - if (mProject->modified()) + if (mProject->modified()) { mProject->saveAll(); + } + mEditorList->saveAll(); clearIssues(); // Increment build number automagically @@ -1813,7 +1815,7 @@ void MainWindow::runExecutable(RunType runType) tr("Rebuild Project"), tr("Project has been modified, do you want to rebuild it?") ) == QMessageBox::Yes) { - mProject->saveAll(); + //mProject->saveAll(); mCompileSuccessionTask=std::make_shared(); mCompileSuccessionTask->type = CompileSuccessionTaskType::RunNormal; mCompileSuccessionTask->execName=mProject->executable(); @@ -4397,8 +4399,11 @@ void MainWindow::closeProject(bool refreshEditor) auto action = finally([&,this]{ mFileSystemWatcher.blockSignals(oldBlock); }); + + //save all files + // TODO: should we save watches? - if (mProject->modified()) { + if (mEditorList->projectEditorsModified()) { QString s; if (mProject->name().isEmpty()) { s = mProject->filename(); @@ -4407,6 +4412,7 @@ void MainWindow::closeProject(bool refreshEditor) } if (mSystemTurnedOff) { mProject->saveAll(); + mEditorList->saveAllForProject(); } else { int answer = QMessageBox::question( this, @@ -4419,8 +4425,10 @@ void MainWindow::closeProject(bool refreshEditor) switch (answer) { case QMessageBox::Yes: mProject->saveAll(); + mEditorList->saveAllForProject(); break; case QMessageBox::No: + mEditorList->clearProjectEditorsModified(); mProject->setModified(false); mProject->saveLayout(); break; @@ -4880,6 +4888,11 @@ void MainWindow::clearToolsOutput() ui->txtToolsOutput->clear(); } +void MainWindow::clearTodos() +{ + mTodoModel.clear(); +} + void MainWindow::onCompileStarted() { //do nothing @@ -6085,13 +6098,7 @@ void MainWindow::on_actionSaveAll_triggered() } // Make changes to files - for (int i=0;ipageCount();i++) { - Editor * e= (*mEditorList)[i]; - if (e->modified() && !e->inProject()) { - if (!e->save()) - break; - } - } + mEditorList->saveAll(); updateAppTitle(); } @@ -6435,6 +6442,9 @@ void MainWindow::newProjectUnitFile() QMessageBox::critical(this,tr("File Already Exists!"), tr("File '%1' already exists!").arg(newFileName)); return; + } else { + //create an empty file + createFile(newFileName); } newUnit = mProject->newUnit( pNode,newFileName); @@ -7756,7 +7766,9 @@ void MainWindow::on_actionGit_Create_Repository_triggered() vcsManager.add(mProject->folder(),extractRelativePath(mProject->folder(),pUnit->fileName()),output); } //update project view - mProject->addUnit(includeTrailingPathDelimiter(mProject->folder())+".gitignore", mProject->rootNode()); + QString ignoreFile=includeTrailingPathDelimiter(mProject->folder())+".gitignore"; + mProject->addUnit(ignoreFile, mProject->rootNode()); + createFile(ignoreFile); mProject->saveAll(); if (mProject->folder() == mFileSystemModel.rootPath() || mFileSystemModel.rootPath().startsWith(includeTrailingPathDelimiter(mProject->folder()), PATH_SENSITIVITY)) { diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 44878335..21b3123c 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -208,6 +208,7 @@ public slots: void logToolsOutput(const QString& msg); void onCompileIssue(PCompileIssue issue); void clearToolsOutput(); + void clearTodos(); void onCompileStarted(); void onCompileFinished(bool isCheckSyntax); void onCompileErrorOccured(const QString& reason); diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp index ff89e2b4..baa5913a 100644 --- a/RedPandaIDE/project.cpp +++ b/RedPandaIDE/project.cpp @@ -158,17 +158,18 @@ QString Project::makeFileName() bool Project::modified() const { + return mModified; // Project file modified? Done - if (mModified) - return true;// quick exit avoids loop over all units +// if (mModified) +// return true;// quick exit avoids loop over all units - // Otherwise, check all units - foreach (const PProjectUnit& unit, mUnits){ - if (unit->modified()) { - return true; - } - } - return false; +// // Otherwise, check all units +// foreach (const PProjectUnit& unit, mUnits){ +// if (unit->modified()) { +// return true; +// } +// } +// return false; } void Project::open() @@ -224,7 +225,6 @@ void Project::open() if (QTextCodec::codecForName(newUnit->encoding())==nullptr) { newUnit->setEncoding(ENCODING_AUTO_DETECT); } - newUnit->setNew(false); PProjectModelNode parentNode; if (mOptions.modelType==ProjectModelType::FileSystem) { parentNode = getParentFileSystemFolderNode(newUnit->fileName()); @@ -341,7 +341,6 @@ PProjectUnit Project::newUnit(PProjectModelNode parentNode, const QString& custo // Set all properties newUnit->setFileName(s); - newUnit->setNew(true); newUnit->setFolder(getNodePath(parentNode)); PProjectModelNode node = makeNewFileNode(newUnit,newUnit->priority(),parentNode); newUnit->setNode(node); @@ -372,7 +371,6 @@ PProjectUnit Project::newUnit(PProjectModelNode parentNode, const QString& custo newUnit->setPriority(1000); newUnit->setOverrideBuildCmd(false); newUnit->setBuildCmd(""); - newUnit->setModified(true); newUnit->setEncoding(toByteArray(mOptions.encoding)); return newUnit; } @@ -394,7 +392,7 @@ Editor* Project::openUnit(PProjectUnit& unit, bool forceOpen) { } QByteArray encoding; encoding = unit->encoding(); - editor = mEditorList->newEditor(unit->fileName(), encoding, this, unit->isNew()); + editor = mEditorList->newEditor(unit->fileName(), encoding, this, false); if (editor) { //editor->setProject(this); //unit->setEncoding(encoding); @@ -421,7 +419,7 @@ Editor *Project::openUnit(PProjectUnit &unit, const PProjectEditorLayout &layout } QByteArray encoding; encoding = unit->encoding(); - editor = mEditorList->newEditor(unit->fileName(), encoding, this, unit->isNew()); + editor = mEditorList->newEditor(unit->fileName(), encoding, this, false); if (editor) { //editor->setInProject(true); editor->setCaretY(layout->caretY); @@ -678,16 +676,14 @@ void Project::renameUnit(PProjectUnit& unit, const QString &sFileName) if (sFileName.compare(unit->fileName(),PATH_SENSITIVITY)==0) return; - if (fileExists(unit->fileName())) { - unit->setNew(false); - } - Editor * editor=unitEditor(unit); if (editor) { //prevent recurse editor->saveAs(sFileName,true); + } else { + copyFile(unit->fileName(),sFileName,true); } - removeUnit(unit,false,false); + removeUnit(unit,false,true); PProjectModelNode parentNode = unit->node()->parent.lock(); unit = addUnit(sFileName,parentNode); setModified(true); @@ -706,23 +702,23 @@ bool Project::saveUnits() foreach (const PProjectUnit& unit, mUnits) { i++; QByteArray groupName = toByteArray(QString("Unit%1").arg(i)); - if (!unit->FileMissing()) { - bool rd_only = false; - if (unit->modified() && fileExists(unit->fileName()) - && isReadOnly(unit->fileName())) { - // file is read-only - QMessageBox::critical(nullptr, - tr("Can't save file"), - tr("Can't save file '%1'").arg(unit->fileName()), - QMessageBox::Ok - ); - rd_only = true; - } - if (!rd_only) { - if (!unit->save() && unit->isNew()) - return false; - } - } +// if (!unit->FileMissing()) { +// bool rd_only = false; +// if (unit->modified() && fileExists(unit->fileName()) +// && isReadOnly(unit->fileName())) { +// // file is read-only +// QMessageBox::critical(nullptr, +// tr("Can't save file"), +// tr("Can't save file '%1'").arg(unit->fileName()), +// QMessageBox::Ok +// ); +// rd_only = true; +// } +// if (!rd_only) { +// if (!unit->save() && unit->isNew()) +// return false; +// } +// } // saved new file or an existing file add to project file ini.SetValue( @@ -745,7 +741,6 @@ bool Project::saveUnits() default: break; } - unit->setNew(false); ini.SetValue(groupName,"Folder", toByteArray(unit->folder())); ini.SetLongValue(groupName,"Compile", unit->compile()); ini.SetLongValue(groupName,"Link", unit->link()); @@ -1187,7 +1182,6 @@ PProjectUnit Project::addUnit(const QString &inFileName, PProjectModelNode paren // Set all properties newUnit->setFileName(QDir(directory()).filePath(inFileName)); - newUnit->setNew(false); Editor * e= unitEditor(newUnit); if (e) { newUnit->setEncoding(e->fileEncoding()); @@ -2261,6 +2255,7 @@ ProjectUnit::ProjectUnit(Project* parent) mParent = parent; mFileMissing = false; mPriority=0; + mNew = true; } Project *ProjectUnit::parent() const @@ -2284,11 +2279,6 @@ void ProjectUnit::setFileName(QString newFileName) } } -bool ProjectUnit::isNew() const -{ - return mNew; -} - void ProjectUnit::setNew(bool newNew) { mNew = newNew; @@ -2384,51 +2374,6 @@ void ProjectUnit::setEncoding(const QByteArray &newEncoding) } } -bool ProjectUnit::modified() const -{ - Editor * editor=mParent->unitEditor(this); - if (editor) { - return editor->modified(); - } else { - return false; - } -} - -void ProjectUnit::setModified(bool value) -{ - Editor * editor=mParent->unitEditor(this); - // Mark the change in the coupled editor - if (editor) { - return editor->setModified(value); - } - - // If modified is set to true, mark project as modified too - if (value) { - mParent->setModified(true); - } -} - -bool ProjectUnit::save() -{ - bool previous=mParent->fileSystemWatcher()->blockSignals(true); - auto action = finally([&previous,this](){ - mParent->fileSystemWatcher()->blockSignals(previous); - }); - bool result=true; - Editor * editor=mParent->unitEditor(this); - if (!editor && !fileExists(mFileName)) { - // file is neither open, nor saved - QStringList temp; - stringsToFile(temp,mFileName); - } else if (editor && editor->modified()) { - result = editor->save(); - } - if (mNode) { - mNode->text = extractFileName(mFileName); - } - return result; -} - PProjectModelNode &ProjectUnit::node() { return mNode; diff --git a/RedPandaIDE/project.h b/RedPandaIDE/project.h index 0dbaed27..1100969d 100644 --- a/RedPandaIDE/project.h +++ b/RedPandaIDE/project.h @@ -79,8 +79,6 @@ public: Project* parent() const; const QString &fileName() const; void setFileName(QString newFileName); - bool isNew() const; - void setNew(bool newNew); const QString &folder() const; void setFolder(const QString &newFolder); bool compile() const; @@ -97,9 +95,6 @@ public: void setPriority(int newPriority); const QByteArray &encoding() const; void setEncoding(const QByteArray &newEncoding); - bool modified() const; - void setModified(bool value); - bool save(); PProjectModelNode &node(); void setNode(const PProjectModelNode &newNode); @@ -107,11 +102,13 @@ public: bool FileMissing() const; void setFileMissing(bool newDontSave); + void setNew(bool newNew); + private: Project* mParent; QString mFileName; - bool mNew; QString mFolder; + bool mNew; bool mCompile; bool mCompileCpp; bool mOverrideBuildCmd; diff --git a/libs/redpanda_qt_utils/qt_utils/utils.cpp b/libs/redpanda_qt_utils/qt_utils/utils.cpp index 8a3a3040..175f73e7 100644 --- a/libs/redpanda_qt_utils/qt_utils/utils.cpp +++ b/libs/redpanda_qt_utils/qt_utils/utils.cpp @@ -656,3 +656,8 @@ bool isInFolder(const QString &folderpath, const QString &filepath) QFileInfo fileInfo(filepath); return fileInfo.absoluteFilePath().startsWith(includeTrailingPathDelimiter(folder.absolutePath())); } + +void createFile(const QString &fileName) +{ + stringToFile("",fileName); +} diff --git a/libs/redpanda_qt_utils/qt_utils/utils.h b/libs/redpanda_qt_utils/qt_utils/utils.h index f2b5ce2b..8106d479 100644 --- a/libs/redpanda_qt_utils/qt_utils/utils.h +++ b/libs/redpanda_qt_utils/qt_utils/utils.h @@ -106,6 +106,7 @@ QByteArray readFileToByteArray(const QString& fileName); void stringsToFile(const QStringList& list, const QString& fileName); void stringToFile(const QString& str, const QString& fileName); +void createFile(const QString& fileName); /* File I/O utils */ bool fileExists(const QString& file);