Skip to content

Commit b1291c1

Browse files
Files rewriting with backup
1 parent d2a5c56 commit b1291c1

3 files changed

Lines changed: 87 additions & 33 deletions

File tree

src/cegui/CEGUIProject.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include "src/cegui/CEGUIProject.h"
22
#include "src/cegui/CEGUIProjectItem.h"
3+
#include "src/Application.h"
34
#include "qfile.h"
45
#include "qdir.h"
56
#include "qdom.h"
67
#include "qtextstream.h"
8+
#include <qmessagebox.h>
79

810
const QString CEGUIProject::EditorEmbeddedCEGUIVersion("1.0");
911
const QStringList CEGUIProject::CEGUIVersions = { "0.6", "0.7", "0.8", "1.0" };
@@ -128,18 +130,43 @@ bool CEGUIProject::save(const QString& newFilePath)
128130
xmlRoot.appendChild(xmlItems);
129131
doc.appendChild(xmlRoot);
130132

131-
// Save to file
133+
// If the file already exists, rename it to avoid data losing due to save error
134+
const bool tmpUsed = QFileInfo(filePath).exists();
135+
if (tmpUsed)
136+
{
137+
QFile prevFile(filePath);
138+
if (!prevFile.rename(filePath + ".bak"))
139+
{
140+
QMessageBox::critical(qobject_cast<Application*>(qApp)->getMainWindow(),
141+
"Error saving project!",
142+
"CEED encountered an error trying to save the project file " + filePath);
143+
return false;
144+
}
145+
}
132146

147+
// Save to file
133148
QFile file(filePath);
134-
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
149+
if (file.open(QIODevice::WriteOnly | QIODevice::Text))
135150
{
136-
qDebug(QString("CEGUIProject::save() > can't open the file for writing: %1").arg(filePath).toLocal8Bit().data());
137-
return false;
151+
QTextStream stream(&file);
152+
doc.save(stream, 4);
153+
file.close();
154+
if (tmpUsed) QFile(filePath + ".bak").remove();
155+
return true;
138156
}
139157

140-
QTextStream stream(&file);
141-
doc.save(stream, 4);
142-
return true;
158+
// Something went wrong, show error and restore backup
159+
QMessageBox::critical(qobject_cast<Application*>(qApp)->getMainWindow(),
160+
"Error saving project!",
161+
"CEED encountered an error trying to save the project file " + filePath);
162+
163+
if (tmpUsed)
164+
{
165+
QFile(filePath).remove();
166+
QFile(filePath + ".bak").rename(filePath);
167+
}
168+
169+
return false;
143170
}
144171

145172
void CEGUIProject::unload()

src/editors/EditorBase.cpp

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -274,39 +274,67 @@ bool EditorBase::saveAs(const QString& targetPath)
274274
// watching it, so re-enabling monitor is necessary.
275275
enableFileMonitoring(false);
276276

277-
QFile file(actualPath);
278-
if (!file.open(QIODevice::WriteOnly))
277+
// If the file already exists, rename it to avoid data losing due to save error
278+
const bool tmpUsed = QFileInfo(actualPath).exists();
279+
if (tmpUsed)
279280
{
280-
QMessageBox::critical(qobject_cast<Application*>(qApp)->getMainWindow(),
281-
"Error saving file!",
282-
"CEED encountered an error trying to save the file " + actualPath);
283-
enableFileMonitoring(true);
284-
return false;
281+
QFile prevFile(actualPath);
282+
if (!prevFile.rename(actualPath + ".bak"))
283+
{
284+
QMessageBox::critical(qobject_cast<Application*>(qApp)->getMainWindow(),
285+
"Error saving file!",
286+
"CEED encountered an error trying to save the file " + actualPath);
287+
return false;
288+
}
285289
}
286290

287-
// Do it before obtaining raw data since it may contain relative pathes.
288-
// For example imageset XML contains a relative path to underlying image.
289-
_filePath = actualPath;
291+
QFile file(actualPath);
292+
if (file.open(QIODevice::WriteOnly))
293+
{
294+
// Do it before obtaining raw data since it may contain relative pathes.
295+
// For example imageset XML contains a relative path to underlying image.
296+
_filePath = actualPath;
290297

291-
QByteArray rawData;
292-
getRawData(rawData);
293-
/*
294-
if self.compatibilityManager is not None:
295-
outputData = self.compatibilityManager.transform(self.compatibilityManager.EditorNativeType, self.desiredSavingDataType, self.nativeData)
296-
*/
297-
file.write(rawData);
298-
file.close();
298+
QByteArray rawData;
299+
getRawData(rawData);
300+
/*
301+
if self.compatibilityManager is not None:
302+
outputData = self.compatibilityManager.transform(self.compatibilityManager.EditorNativeType, self.desiredSavingDataType, self.nativeData)
303+
*/
299304

300-
enableFileMonitoring(true);
301-
markAsUnchanged();
305+
const auto written = file.write(rawData);
306+
file.close();
307+
308+
if (written == rawData.size())
309+
{
310+
if (tmpUsed) QFile(actualPath + ".bak").remove();
311+
enableFileMonitoring(true);
312+
313+
markAsUnchanged();
314+
315+
if (prevFilePath != _filePath)
316+
{
317+
_labelText = QFileInfo(_filePath).fileName();
318+
emit filePathChanged(prevFilePath, _filePath);
319+
}
302320

303-
if (prevFilePath != _filePath)
321+
return true;
322+
}
323+
}
324+
325+
// Something went wrong, show error and restore backup
326+
QMessageBox::critical(qobject_cast<Application*>(qApp)->getMainWindow(),
327+
"Error saving file!",
328+
"CEED encountered an error trying to save the file " + actualPath);
329+
330+
if (tmpUsed)
304331
{
305-
_labelText = QFileInfo(_filePath).fileName();
306-
emit filePathChanged(prevFilePath, _filePath);
332+
QFile(actualPath).remove();
333+
QFile(actualPath + ".bak").rename(actualPath);
307334
}
335+
enableFileMonitoring(true);
308336

309-
return true;
337+
return false;
310338
}
311339

312340
// Either reload file from disk or confirm desynchronization

src/ui/MainWindow.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ void MainWindow::on_tabs_currentChanged(int index)
660660
const bool hasEditor = (currentEditor != nullptr);
661661
fsBrowser->activeFileDirectoryButton()->setEnabled(hasEditor);
662662
ui->actionRevert->setEnabled(hasEditor);
663-
ui->actionSave->setEnabled(hasEditor);
663+
ui->actionSave->setEnabled(hasEditor && currentEditor->hasChanges());
664664
ui->actionSaveAs->setEnabled(hasEditor);
665665
ui->actionCloseTab->setEnabled(hasEditor);
666666
ui->actionCloseOtherTabs->setEnabled(hasEditor);
@@ -680,7 +680,6 @@ void MainWindow::on_tabs_currentChanged(int index)
680680
{
681681
undoViewer->setUndoStack(undoStack);
682682

683-
ui->actionSave->setEnabled(undoStack->isClean());
684683
ui->actionUndo->setEnabled(undoStack->canUndo());
685684
ui->actionRedo->setEnabled(undoStack->canRedo());
686685
ui->actionUndo->setText("Undo " + undoStack->undoText());

0 commit comments

Comments
 (0)