0000175: Auto save function (first step)

This commit is contained in:
wmayer 2013-05-17 13:29:11 +02:00
parent 1939e61c57
commit 37d1696e16
3 changed files with 82 additions and 0 deletions

View File

@ -41,8 +41,11 @@
# include <QGLFramebufferObject> # include <QGLFramebufferObject>
#endif #endif
# include <QSessionManager> # include <QSessionManager>
# include <QTextStream>
#endif #endif
#include <boost/interprocess/sync/file_lock.hpp>
// FreeCAD Base header // FreeCAD Base header
#include <Base/Console.h> #include <Base/Console.h>
@ -1748,9 +1751,24 @@ void Application::runApplication(void)
Base::Console().Log("Init: Entering event loop\n"); Base::Console().Log("Init: Entering event loop\n");
try { try {
std::stringstream s;
s << Base::FileInfo::getTempPath() << App::GetApplication().getExecutableName()
<< "_" << QCoreApplication::applicationPid() << ".lock";
// open a lock file with the PID
Base::FileInfo fi(s.str());
Base::ofstream lock(fi);
boost::interprocess::file_lock flock(s.str().c_str());
flock.lock();
int ret = mainApp.exec(); int ret = mainApp.exec();
if (ret == systemExit) if (ret == systemExit)
throw Base::SystemExitException(); throw Base::SystemExitException();
// close the lock file, in case of a crash we can see the existing lock file
// on the next restart and try to repair the documents, if needed.
flock.unlock();
lock.close();
fi.deleteFile();
} }
catch (const Base::SystemExitException&) { catch (const Base::SystemExitException&) {
Base::Console().Message("System exit\n"); Base::Console().Message("System exit\n");
@ -1765,3 +1783,64 @@ void Application::runApplication(void)
Base::Console().Log("Finish: Event loop left\n"); Base::Console().Log("Finish: Event loop left\n");
} }
void Application::checkForPreviousCrashes()
{
QDir tmp = QDir::temp();
tmp.setNameFilters(QStringList() << QString::fromAscii("*.lock"));
tmp.setFilter(QDir::Files);
QList<QFileInfo> restoreDocFiles;
QString exeName = QString::fromAscii(App::GetApplication().getExecutableName());
QList<QFileInfo> locks = tmp.entryInfoList();
for (QList<QFileInfo>::iterator it = locks.begin(); it != locks.end(); ++it) {
QString bn = it->baseName();
if (bn.startsWith(exeName)) {
QString fn = it->absoluteFilePath();
boost::interprocess::file_lock flock((const char*)fn.toLocal8Bit());
if (flock.try_lock()) {
// OK, this file is a leftover from a previous crash
QString crashed_pid = bn.mid(exeName.length()+1);
// search for transient directories with this PID
QString filter;
QTextStream str(&filter);
str << exeName << "_Doc_*_" << crashed_pid;
tmp.setNameFilters(QStringList() << filter);
tmp.setFilter(QDir::Dirs);
QList<QFileInfo> dirs = tmp.entryInfoList();
if (dirs.isEmpty()) {
// delete the lock file immediately if not transient directories are related
tmp.remove(fn);
}
else {
int countDeletedDocs = 0;
for (QList<QFileInfo>::iterator it = dirs.begin(); it != dirs.end(); ++it) {
QDir doc_dir(it->absoluteFilePath());
doc_dir.setFilter(QDir::NoDotAndDotDot|QDir::AllEntries);
uint entries = doc_dir.entryList().count();
if (entries == 0) {
// in this case we can delete the transient directory because
// we cannot do anything
if (tmp.rmdir(it->filePath()))
countDeletedDocs++;
}
else {
// store the transient directory in case it's not empty
restoreDocFiles << *it;
}
}
// all directories corresponding to the lock file have been deleted
// so delete the lock file, too
if (countDeletedDocs == dirs.size()) {
tmp.remove(fn);
}
}
}
}
}
if (!restoreDocFiles.isEmpty()) {
//TODO:
}
}

View File

@ -157,6 +157,7 @@ public:
/// true when the application shuting down /// true when the application shuting down
bool isClosing(void); bool isClosing(void);
void checkForPreviousCrashes();
/** @name workbench handling */ /** @name workbench handling */
//@{ //@{

View File

@ -1174,6 +1174,8 @@ void MainWindow::delayedStartup()
if (hGrp->GetBool("CreateNewDoc", false)) { if (hGrp->GetBool("CreateNewDoc", false)) {
App::GetApplication().newDocument(); App::GetApplication().newDocument();
} }
Application::Instance->checkForPreviousCrashes();
} }
void MainWindow::appendRecentFile(const QString& filename) void MainWindow::appendRecentFile(const QString& filename)