- fix: Crash when a project is removed from the disk while it is openned in RedPanda-C++.

This commit is contained in:
Roy Qu 2023-03-19 20:51:12 +08:00
parent 56cd6c4d76
commit b951ac6636
10 changed files with 516 additions and 439 deletions

View File

@ -2,6 +2,7 @@ Red Panda C++ Version 2.19
- fix: Crash when directive line ends with '\' and at the last line.
- fix: The option "Minimal indent for a continuous conditional beloning to a conditional header:" for formatter is not correct.
- fix: Crash when a project is removed from the disk while it is openned in RedPanda-C++.
Red Panda C++ Version 2.18

View File

@ -1430,10 +1430,11 @@ void Editor::hideEvent(QHideEvent */*event*/)
this,
&Editor::onEndParsing);
}
pMainWindow->updateForEncodingInfo(nullptr);
pMainWindow->updateStatusbarForLineCol(nullptr);
pMainWindow->updateForStatusbarModeInfo(nullptr);
if (!pMainWindow->isQuitting()) {
pMainWindow->updateForEncodingInfo(nullptr);
pMainWindow->updateStatusbarForLineCol(nullptr);
pMainWindow->updateForStatusbarModeInfo(nullptr);
}
setHideTime(QDateTime::currentDateTime());
}

View File

@ -185,8 +185,12 @@ bool EditorList::closeEditor(Editor* editor, bool transferFocus, bool force) {
// }
if (editor->inProject() && pMainWindow->project()) {
PProjectUnit unit = pMainWindow->project()->findUnit(editor);
pMainWindow->project()->closeUnit(unit);
if (fileExists(pMainWindow->project()->directory())) {
PProjectUnit unit = pMainWindow->project()->findUnit(editor);
pMainWindow->project()->closeUnit(unit);
} else {
editor->setProject(nullptr);
}
} else {
if (!editor->isNew() && pMainWindow->visitHistoryManager()->addFile(editor->filename())) {
pMainWindow->rebuildOpenedFileHisotryMenu();

View File

@ -402,6 +402,8 @@ MainWindow::MainWindow(QWidget *parent)
connect(&mFileSystemWatcher,&QFileSystemWatcher::fileChanged,
this, &MainWindow::onFileChanged);
connect(&mFileSystemWatcher,&QFileSystemWatcher::directoryChanged,
this, &MainWindow::onDirChanged);
mStatementColors = std::make_shared<QHash<StatementKind, PColorSchemeItem> >();
mCompletionPopup = std::make_shared<CodeCompletionPopup>();
@ -463,6 +465,8 @@ MainWindow::MainWindow(QWidget *parent)
MainWindow::~MainWindow()
{
mQuitting=true;
if (mProject)
mProject=nullptr;
delete mProjectProxyModel;
delete mEditorList;
delete ui;
@ -5106,51 +5110,56 @@ void MainWindow::closeProject(bool refreshEditor)
//save all files
// TODO: should we save watches?
if (mEditorList->projectEditorsModified()) {
QString s;
if (mProject->name().isEmpty()) {
s = mProject->filename();
} else {
s = mProject->name();
}
if (mSystemTurnedOff) {
mProject->saveAll();
mEditorList->saveAllForProject();
} else {
int answer = QMessageBox::question(
this,
tr("Save project"),
tr("The project '%1' has modifications.").arg(s)
+ "<br />"
+ tr("Do you want to save it?"),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
QMessageBox::Yes);
switch (answer) {
case QMessageBox::Yes:
if (fileExists(mProject->directory())){
if (mEditorList->projectEditorsModified()) {
QString s;
if (mProject->name().isEmpty()) {
s = mProject->filename();
} else {
s = mProject->name();
}
if (mSystemTurnedOff) {
mProject->saveAll();
mEditorList->saveAllForProject();
break;
case QMessageBox::No:
mEditorList->clearProjectEditorsModified();
mProject->setModified(false);
mProject->saveLayout();
break;
case QMessageBox::Cancel:
mProject->saveLayout();
return;
} else {
int answer = QMessageBox::question(
this,
tr("Save project"),
tr("The project '%1' has modifications.").arg(s)
+ "<br />"
+ tr("Do you want to save it?"),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
QMessageBox::Yes);
switch (answer) {
case QMessageBox::Yes:
mProject->saveAll();
mEditorList->saveAllForProject();
break;
case QMessageBox::No:
mEditorList->clearProjectEditorsModified();
mProject->setModified(false);
mProject->saveLayout();
break;
case QMessageBox::Cancel:
mProject->saveLayout();
return;
}
}
}
} else
mProject->saveAll(); // always save layout, but not when SaveAll has been called
} else
mProject->saveAll(); // always save layout, but not when SaveAll has been called
}
mClosingProject=true;
mBookmarkModel->saveProjectBookmarks(
changeFileExt(mProject->filename(), PROJECT_BOOKMARKS_EXT),
mProject->directory());
mDebugger->saveForProject(
changeFileExt(mProject->filename(), PROJECT_DEBUG_EXT),
mProject->directory());
if (fileExists(mProject->directory())){
mBookmarkModel->saveProjectBookmarks(
changeFileExt(mProject->filename(), PROJECT_BOOKMARKS_EXT),
mProject->directory());
mDebugger->saveForProject(
changeFileExt(mProject->filename(), PROJECT_DEBUG_EXT),
mProject->directory());
}
mClassBrowserModel.beginUpdate();
// Remember it
@ -5251,6 +5260,22 @@ void MainWindow::onFileChanged(const QString &path)
mFilesChangedNotifying.remove(path);
}
void MainWindow::onDirChanged(const QString &path)
{
if (mFilesChangedNotifying.contains(path))
return;
mFilesChangedNotifying.insert(path);
if (mProject && QString::compare(mProject->directory(),path,PATH_SENSITIVITY)==0
&& !fileExists(path)) {
QMessageBox::information(this,tr("Project folder removed."),
tr("Folder for project '%1' was removed.").arg(path)
+"<BR /><BR />"
+ tr("It will be closed."));
closeProject(false);
}
mFilesChangedNotifying.remove(path);
}
void MainWindow::onFilesViewPathChanged()
{
QString filesPath = ui->cbFilesPath->currentText();

View File

@ -340,6 +340,7 @@ private slots:
void onEditorRenamed(const QString &oldFilename, const QString &newFilename, bool firstSave);
void onAutoSaveTimeout();
void onFileChanged(const QString &path);
void onDirChanged(const QString &path);
void onFilesViewPathChanged();
void onWatchViewContextMenu(const QPoint& pos);
void onBookmarkContextMenu(const QPoint& pos);

View File

@ -61,6 +61,7 @@ Project::Project(const QString &filename, const QString &name,
std::bind(
&EditorList::getContentFromOpenedEditor,mEditorList,
std::placeholders::_1, std::placeholders::_2));
mFileSystemWatcher->addPath(directory());
}
std::shared_ptr<Project> Project::load(const QString &filename, EditorList *editorList, QFileSystemWatcher *fileSystemWatcher, QObject *parent)
@ -103,12 +104,14 @@ std::shared_ptr<Project> Project::create(
Project::~Project()
{
mFileSystemWatcher->removePath(directory());
mEditorList->beginUpdate();
foreach (const PProjectUnit& unit, mUnits) {
Editor * editor = unitEditor(unit);
if (editor) {
editor->setProject(nullptr);
mEditorList->forceCloseEditor(editor);
if (fileExists(directory()))
mEditorList->forceCloseEditor(editor);
}
}
mEditorList->endUpdate();
@ -259,15 +262,15 @@ void Project::open()
}
}
void Project::setFileName(QString value)
{
value = QFileInfo(value).absoluteFilePath();
if (mFilename!=value) {
QFile::rename(mFilename,value);
mFilename = value;
setModified(true);
}
}
//void Project::setFileName(QString value)
//{
// value = QFileInfo(value).absoluteFilePath();
// if (mFilename!=value) {
// QFile::rename(mFilename,value);
// mFilename = value;
// setModified(true);
// }
//}
void Project::setModified(bool value)
{
@ -611,6 +614,9 @@ void Project::saveAll()
void Project::saveLayout()
{
if (!fileExists(directory()))
return;
QHash<QString, PProjectEditorLayout> oldLayouts = loadLayout();
QHash<QString,int> editorOrderSet;
@ -669,9 +675,6 @@ void Project::saveLayout()
QJsonDocument doc(jsonLayouts);
file.write(doc.toJson(QJsonDocument::Indented));
file.close();
} else {
throw FileError(QObject::tr("Can't open file '%1' for write.")
.arg(jsonFilename));
}
}
@ -711,6 +714,8 @@ void Project::renameUnit(PProjectUnit& unit, const QString &newFileName)
bool Project::saveUnits()
{
if (!fileExists(directory()))
return false;
int count = 0;
SimpleIni ini;
SI_Error error = ini.LoadFile(mFilename.toLocal8Bit());
@ -1140,6 +1145,8 @@ void Project::setEncoding(const QByteArray &encoding)
void Project::saveOptions()
{
if (!fileExists(directory()))
return;
SimpleIni ini;
ini.LoadFile(mFilename.toLocal8Bit());
ini.SetValue("Project","FileName", toByteArray(extractRelativePath(directory(), mFilename)));

View File

@ -218,7 +218,7 @@ public:
bool unitsModifiedSince(const QDateTime& time);
bool modified() const;
bool modifiedSince(const QDateTime& time);
void setFileName(QString value);
// void setFileName(QString value);
void setModified(bool value);
PProjectModelNode addFolder(PProjectModelNode parentFolder, const QString& s);

View File

@ -5187,6 +5187,18 @@
<source>Save settings failed!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Project folder removed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Folder for project &apos;%1&apos; was removed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>It will be closed.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MemoryModel</name>

File diff suppressed because it is too large Load Diff

View File

@ -4920,6 +4920,18 @@
<source>F11</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Project folder removed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Folder for project &apos;%1&apos; was removed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>It will be closed.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MemoryModel</name>