- 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
This commit is contained in:
Roy Qu 2022-10-21 12:43:02 +08:00
parent 5d5f7027af
commit 1301168135
10 changed files with 129 additions and 114 deletions

View File

@ -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: 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: index out of range in cpp highlighter
- fix: memory leak in code folding processing - 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 Red Panda C++ Version 1.4

View File

@ -265,6 +265,7 @@ bool Editor::save(bool force, bool doReparse) {
// tr("File %1 is not writable!").arg(mFilename)); // tr("File %1 is not writable!").arg(mFilename));
// return false; // return false;
// } // }
// qDebug()<<"saving "<<mFilename;
saveFile(mFilename); saveFile(mFilename);
pMainWindow->fileSystemWatcher()->addPath(mFilename); pMainWindow->fileSystemWatcher()->addPath(mFilename);
setModified(false); setModified(false);
@ -279,12 +280,11 @@ bool Editor::save(bool force, bool doReparse) {
return false; return false;
} }
if (doReparse && mParser) { if (doReparse && isVisible()) {
reparse(false); reparse(false);
}
if (doReparse && pSettings->editor().syntaxCheckWhenSave())
checkSyntaxInBack(); checkSyntaxInBack();
reparseTodo(); reparseTodo();
}
return true; return true;
} }
@ -1302,7 +1302,11 @@ void Editor::showEvent(QShowEvent */*event*/)
// && !inProject()) { // && !inProject()) {
// reparse(); // reparse();
// } // }
reparseTodo(); if (!pMainWindow->isClosingAll()
&& !pMainWindow->isQuitting()) {
checkSyntaxInBack();
reparseTodo();
}
setHideTime(QDateTime()); setHideTime(QDateTime());
} }
@ -1553,16 +1557,16 @@ void Editor::onStatusChanged(QSynedit::StatusChanges changes)
&& !changes.testFlag(QSynedit::StatusChange::scReadOnly) && !changes.testFlag(QSynedit::StatusChange::scReadOnly)
&& changes.testFlag(QSynedit::StatusChange::scCaretY))) { && changes.testFlag(QSynedit::StatusChange::scCaretY))) {
mCurrentLineModified = false; mCurrentLineModified = false;
if (!changes.testFlag(QSynedit::StatusChange::scOpenFile)) if (!changes.testFlag(QSynedit::StatusChange::scOpenFile)) {
reparse(false); reparse(false);
checkSyntaxInBack();
reparseTodo();
}
// if (pSettings->codeCompletion().clearWhenEditorHidden() // if (pSettings->codeCompletion().clearWhenEditorHidden()
// && changes.testFlag(SynStatusChange::scOpenFile)) { // && changes.testFlag(SynStatusChange::scOpenFile)) {
// } else{ // } else{
// reparse(); // reparse();
// } // }
if (pSettings->editor().syntaxCheckWhenLineChanged())
checkSyntaxInBack();
reparseTodo();
} }
mLineCount = document()->count(); mLineCount = document()->count();
if (changes.testFlag(QSynedit::scModifyChanged)) { if (changes.testFlag(QSynedit::scModifyChanged)) {

View File

@ -214,6 +214,48 @@ bool EditorList::swapEditor(Editor *editor)
return true; return true;
} }
void EditorList::saveAll()
{
for (int i=0;i<pageCount();i++) {
Editor * e= (*this)[i];
if (e->modified())
e->save();
}
}
bool EditorList::saveAllForProject()
{
for (int i=0;i<pageCount();i++) {
Editor * e= (*this)[i];
if (e->modified() && e->inProject()) {
if (!e->save())
return false;
}
}
return true;
}
bool EditorList::projectEditorsModified()
{
for (int i=0;i<pageCount();i++) {
Editor * e= (*this)[i];
if (e->modified() && e->inProject()) {
return true;
}
}
return false;
}
void EditorList::clearProjectEditorsModified()
{
for (int i=0;i<pageCount();i++) {
Editor * e= (*this)[i];
if (e->inProject()) {
e->setModified(false);
}
}
}
void EditorList::beginUpdate() { void EditorList::beginUpdate() {
if (mUpdateCount==0) { if (mUpdateCount==0) {
mPanel->setUpdatesEnabled(false); mPanel->setUpdatesEnabled(false);

View File

@ -49,6 +49,12 @@ public:
bool swapEditor(Editor* editor); bool swapEditor(Editor* editor);
void saveAll();
bool saveAllForProject();
bool projectEditorsModified();
void clearProjectEditorsModified();
bool closeAll(bool force = false); bool closeAll(bool force = false);
void forceCloseEditor(Editor* editor); void forceCloseEditor(Editor* editor);

View File

@ -1685,8 +1685,10 @@ bool MainWindow::compile(bool rebuild)
mCompilerManager->stopPausing(); mCompilerManager->stopPausing();
CompileTarget target =getCompileTarget(); CompileTarget target =getCompileTarget();
if (target == CompileTarget::Project) { if (target == CompileTarget::Project) {
if (mProject->modified()) if (mProject->modified()) {
mProject->saveAll(); mProject->saveAll();
}
mEditorList->saveAll();
clearIssues(); clearIssues();
// Increment build number automagically // Increment build number automagically
@ -1813,7 +1815,7 @@ void MainWindow::runExecutable(RunType runType)
tr("Rebuild Project"), tr("Rebuild Project"),
tr("Project has been modified, do you want to rebuild it?") tr("Project has been modified, do you want to rebuild it?")
) == QMessageBox::Yes) { ) == QMessageBox::Yes) {
mProject->saveAll(); //mProject->saveAll();
mCompileSuccessionTask=std::make_shared<CompileSuccessionTask>(); mCompileSuccessionTask=std::make_shared<CompileSuccessionTask>();
mCompileSuccessionTask->type = CompileSuccessionTaskType::RunNormal; mCompileSuccessionTask->type = CompileSuccessionTaskType::RunNormal;
mCompileSuccessionTask->execName=mProject->executable(); mCompileSuccessionTask->execName=mProject->executable();
@ -4397,8 +4399,11 @@ void MainWindow::closeProject(bool refreshEditor)
auto action = finally([&,this]{ auto action = finally([&,this]{
mFileSystemWatcher.blockSignals(oldBlock); mFileSystemWatcher.blockSignals(oldBlock);
}); });
//save all files
// TODO: should we save watches? // TODO: should we save watches?
if (mProject->modified()) { if (mEditorList->projectEditorsModified()) {
QString s; QString s;
if (mProject->name().isEmpty()) { if (mProject->name().isEmpty()) {
s = mProject->filename(); s = mProject->filename();
@ -4407,6 +4412,7 @@ void MainWindow::closeProject(bool refreshEditor)
} }
if (mSystemTurnedOff) { if (mSystemTurnedOff) {
mProject->saveAll(); mProject->saveAll();
mEditorList->saveAllForProject();
} else { } else {
int answer = QMessageBox::question( int answer = QMessageBox::question(
this, this,
@ -4419,8 +4425,10 @@ void MainWindow::closeProject(bool refreshEditor)
switch (answer) { switch (answer) {
case QMessageBox::Yes: case QMessageBox::Yes:
mProject->saveAll(); mProject->saveAll();
mEditorList->saveAllForProject();
break; break;
case QMessageBox::No: case QMessageBox::No:
mEditorList->clearProjectEditorsModified();
mProject->setModified(false); mProject->setModified(false);
mProject->saveLayout(); mProject->saveLayout();
break; break;
@ -4880,6 +4888,11 @@ void MainWindow::clearToolsOutput()
ui->txtToolsOutput->clear(); ui->txtToolsOutput->clear();
} }
void MainWindow::clearTodos()
{
mTodoModel.clear();
}
void MainWindow::onCompileStarted() void MainWindow::onCompileStarted()
{ {
//do nothing //do nothing
@ -6085,13 +6098,7 @@ void MainWindow::on_actionSaveAll_triggered()
} }
// Make changes to files // Make changes to files
for (int i=0;i<mEditorList->pageCount();i++) { mEditorList->saveAll();
Editor * e= (*mEditorList)[i];
if (e->modified() && !e->inProject()) {
if (!e->save())
break;
}
}
updateAppTitle(); updateAppTitle();
} }
@ -6435,6 +6442,9 @@ void MainWindow::newProjectUnitFile()
QMessageBox::critical(this,tr("File Already Exists!"), QMessageBox::critical(this,tr("File Already Exists!"),
tr("File '%1' already exists!").arg(newFileName)); tr("File '%1' already exists!").arg(newFileName));
return; return;
} else {
//create an empty file
createFile(newFileName);
} }
newUnit = mProject->newUnit( newUnit = mProject->newUnit(
pNode,newFileName); pNode,newFileName);
@ -7756,7 +7766,9 @@ void MainWindow::on_actionGit_Create_Repository_triggered()
vcsManager.add(mProject->folder(),extractRelativePath(mProject->folder(),pUnit->fileName()),output); vcsManager.add(mProject->folder(),extractRelativePath(mProject->folder(),pUnit->fileName()),output);
} }
//update project view //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(); mProject->saveAll();
if (mProject->folder() == mFileSystemModel.rootPath() if (mProject->folder() == mFileSystemModel.rootPath()
|| mFileSystemModel.rootPath().startsWith(includeTrailingPathDelimiter(mProject->folder()), PATH_SENSITIVITY)) { || mFileSystemModel.rootPath().startsWith(includeTrailingPathDelimiter(mProject->folder()), PATH_SENSITIVITY)) {

View File

@ -208,6 +208,7 @@ public slots:
void logToolsOutput(const QString& msg); void logToolsOutput(const QString& msg);
void onCompileIssue(PCompileIssue issue); void onCompileIssue(PCompileIssue issue);
void clearToolsOutput(); void clearToolsOutput();
void clearTodos();
void onCompileStarted(); void onCompileStarted();
void onCompileFinished(bool isCheckSyntax); void onCompileFinished(bool isCheckSyntax);
void onCompileErrorOccured(const QString& reason); void onCompileErrorOccured(const QString& reason);

View File

@ -158,17 +158,18 @@ QString Project::makeFileName()
bool Project::modified() const bool Project::modified() const
{ {
return mModified;
// Project file modified? Done // Project file modified? Done
if (mModified) // if (mModified)
return true;// quick exit avoids loop over all units // return true;// quick exit avoids loop over all units
// Otherwise, check all units // // Otherwise, check all units
foreach (const PProjectUnit& unit, mUnits){ // foreach (const PProjectUnit& unit, mUnits){
if (unit->modified()) { // if (unit->modified()) {
return true; // return true;
} // }
} // }
return false; // return false;
} }
void Project::open() void Project::open()
@ -224,7 +225,6 @@ void Project::open()
if (QTextCodec::codecForName(newUnit->encoding())==nullptr) { if (QTextCodec::codecForName(newUnit->encoding())==nullptr) {
newUnit->setEncoding(ENCODING_AUTO_DETECT); newUnit->setEncoding(ENCODING_AUTO_DETECT);
} }
newUnit->setNew(false);
PProjectModelNode parentNode; PProjectModelNode parentNode;
if (mOptions.modelType==ProjectModelType::FileSystem) { if (mOptions.modelType==ProjectModelType::FileSystem) {
parentNode = getParentFileSystemFolderNode(newUnit->fileName()); parentNode = getParentFileSystemFolderNode(newUnit->fileName());
@ -341,7 +341,6 @@ PProjectUnit Project::newUnit(PProjectModelNode parentNode, const QString& custo
// Set all properties // Set all properties
newUnit->setFileName(s); newUnit->setFileName(s);
newUnit->setNew(true);
newUnit->setFolder(getNodePath(parentNode)); newUnit->setFolder(getNodePath(parentNode));
PProjectModelNode node = makeNewFileNode(newUnit,newUnit->priority(),parentNode); PProjectModelNode node = makeNewFileNode(newUnit,newUnit->priority(),parentNode);
newUnit->setNode(node); newUnit->setNode(node);
@ -372,7 +371,6 @@ PProjectUnit Project::newUnit(PProjectModelNode parentNode, const QString& custo
newUnit->setPriority(1000); newUnit->setPriority(1000);
newUnit->setOverrideBuildCmd(false); newUnit->setOverrideBuildCmd(false);
newUnit->setBuildCmd(""); newUnit->setBuildCmd("");
newUnit->setModified(true);
newUnit->setEncoding(toByteArray(mOptions.encoding)); newUnit->setEncoding(toByteArray(mOptions.encoding));
return newUnit; return newUnit;
} }
@ -394,7 +392,7 @@ Editor* Project::openUnit(PProjectUnit& unit, bool forceOpen) {
} }
QByteArray encoding; QByteArray encoding;
encoding = unit->encoding(); encoding = unit->encoding();
editor = mEditorList->newEditor(unit->fileName(), encoding, this, unit->isNew()); editor = mEditorList->newEditor(unit->fileName(), encoding, this, false);
if (editor) { if (editor) {
//editor->setProject(this); //editor->setProject(this);
//unit->setEncoding(encoding); //unit->setEncoding(encoding);
@ -421,7 +419,7 @@ Editor *Project::openUnit(PProjectUnit &unit, const PProjectEditorLayout &layout
} }
QByteArray encoding; QByteArray encoding;
encoding = unit->encoding(); encoding = unit->encoding();
editor = mEditorList->newEditor(unit->fileName(), encoding, this, unit->isNew()); editor = mEditorList->newEditor(unit->fileName(), encoding, this, false);
if (editor) { if (editor) {
//editor->setInProject(true); //editor->setInProject(true);
editor->setCaretY(layout->caretY); editor->setCaretY(layout->caretY);
@ -678,16 +676,14 @@ void Project::renameUnit(PProjectUnit& unit, const QString &sFileName)
if (sFileName.compare(unit->fileName(),PATH_SENSITIVITY)==0) if (sFileName.compare(unit->fileName(),PATH_SENSITIVITY)==0)
return; return;
if (fileExists(unit->fileName())) {
unit->setNew(false);
}
Editor * editor=unitEditor(unit); Editor * editor=unitEditor(unit);
if (editor) { if (editor) {
//prevent recurse //prevent recurse
editor->saveAs(sFileName,true); editor->saveAs(sFileName,true);
} else {
copyFile(unit->fileName(),sFileName,true);
} }
removeUnit(unit,false,false); removeUnit(unit,false,true);
PProjectModelNode parentNode = unit->node()->parent.lock(); PProjectModelNode parentNode = unit->node()->parent.lock();
unit = addUnit(sFileName,parentNode); unit = addUnit(sFileName,parentNode);
setModified(true); setModified(true);
@ -706,23 +702,23 @@ bool Project::saveUnits()
foreach (const PProjectUnit& unit, mUnits) { foreach (const PProjectUnit& unit, mUnits) {
i++; i++;
QByteArray groupName = toByteArray(QString("Unit%1").arg(i)); QByteArray groupName = toByteArray(QString("Unit%1").arg(i));
if (!unit->FileMissing()) { // if (!unit->FileMissing()) {
bool rd_only = false; // bool rd_only = false;
if (unit->modified() && fileExists(unit->fileName()) // if (unit->modified() && fileExists(unit->fileName())
&& isReadOnly(unit->fileName())) { // && isReadOnly(unit->fileName())) {
// file is read-only // // file is read-only
QMessageBox::critical(nullptr, // QMessageBox::critical(nullptr,
tr("Can't save file"), // tr("Can't save file"),
tr("Can't save file '%1'").arg(unit->fileName()), // tr("Can't save file '%1'").arg(unit->fileName()),
QMessageBox::Ok // QMessageBox::Ok
); // );
rd_only = true; // rd_only = true;
} // }
if (!rd_only) { // if (!rd_only) {
if (!unit->save() && unit->isNew()) // if (!unit->save() && unit->isNew())
return false; // return false;
} // }
} // }
// saved new file or an existing file add to project file // saved new file or an existing file add to project file
ini.SetValue( ini.SetValue(
@ -745,7 +741,6 @@ bool Project::saveUnits()
default: default:
break; break;
} }
unit->setNew(false);
ini.SetValue(groupName,"Folder", toByteArray(unit->folder())); ini.SetValue(groupName,"Folder", toByteArray(unit->folder()));
ini.SetLongValue(groupName,"Compile", unit->compile()); ini.SetLongValue(groupName,"Compile", unit->compile());
ini.SetLongValue(groupName,"Link", unit->link()); ini.SetLongValue(groupName,"Link", unit->link());
@ -1187,7 +1182,6 @@ PProjectUnit Project::addUnit(const QString &inFileName, PProjectModelNode paren
// Set all properties // Set all properties
newUnit->setFileName(QDir(directory()).filePath(inFileName)); newUnit->setFileName(QDir(directory()).filePath(inFileName));
newUnit->setNew(false);
Editor * e= unitEditor(newUnit); Editor * e= unitEditor(newUnit);
if (e) { if (e) {
newUnit->setEncoding(e->fileEncoding()); newUnit->setEncoding(e->fileEncoding());
@ -2261,6 +2255,7 @@ ProjectUnit::ProjectUnit(Project* parent)
mParent = parent; mParent = parent;
mFileMissing = false; mFileMissing = false;
mPriority=0; mPriority=0;
mNew = true;
} }
Project *ProjectUnit::parent() const Project *ProjectUnit::parent() const
@ -2284,11 +2279,6 @@ void ProjectUnit::setFileName(QString newFileName)
} }
} }
bool ProjectUnit::isNew() const
{
return mNew;
}
void ProjectUnit::setNew(bool newNew) void ProjectUnit::setNew(bool newNew)
{ {
mNew = 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() PProjectModelNode &ProjectUnit::node()
{ {
return mNode; return mNode;

View File

@ -79,8 +79,6 @@ public:
Project* parent() const; Project* parent() const;
const QString &fileName() const; const QString &fileName() const;
void setFileName(QString newFileName); void setFileName(QString newFileName);
bool isNew() const;
void setNew(bool newNew);
const QString &folder() const; const QString &folder() const;
void setFolder(const QString &newFolder); void setFolder(const QString &newFolder);
bool compile() const; bool compile() const;
@ -97,9 +95,6 @@ public:
void setPriority(int newPriority); void setPriority(int newPriority);
const QByteArray &encoding() const; const QByteArray &encoding() const;
void setEncoding(const QByteArray &newEncoding); void setEncoding(const QByteArray &newEncoding);
bool modified() const;
void setModified(bool value);
bool save();
PProjectModelNode &node(); PProjectModelNode &node();
void setNode(const PProjectModelNode &newNode); void setNode(const PProjectModelNode &newNode);
@ -107,11 +102,13 @@ public:
bool FileMissing() const; bool FileMissing() const;
void setFileMissing(bool newDontSave); void setFileMissing(bool newDontSave);
void setNew(bool newNew);
private: private:
Project* mParent; Project* mParent;
QString mFileName; QString mFileName;
bool mNew;
QString mFolder; QString mFolder;
bool mNew;
bool mCompile; bool mCompile;
bool mCompileCpp; bool mCompileCpp;
bool mOverrideBuildCmd; bool mOverrideBuildCmd;

View File

@ -656,3 +656,8 @@ bool isInFolder(const QString &folderpath, const QString &filepath)
QFileInfo fileInfo(filepath); QFileInfo fileInfo(filepath);
return fileInfo.absoluteFilePath().startsWith(includeTrailingPathDelimiter(folder.absolutePath())); return fileInfo.absoluteFilePath().startsWith(includeTrailingPathDelimiter(folder.absolutePath()));
} }
void createFile(const QString &fileName)
{
stringToFile("",fileName);
}

View File

@ -106,6 +106,7 @@ QByteArray readFileToByteArray(const QString& fileName);
void stringsToFile(const QStringList& list, const QString& fileName); void stringsToFile(const QStringList& list, const QString& fileName);
void stringToFile(const QString& str, const QString& fileName); void stringToFile(const QString& str, const QString& fileName);
void createFile(const QString& fileName);
/* File I/O utils */ /* File I/O utils */
bool fileExists(const QString& file); bool fileExists(const QString& file);