diff --git a/src/Base/Writer.cpp b/src/Base/Writer.cpp
index 9d0d048c6e..1955bf883b 100644
--- a/src/Base/Writer.cpp
+++ b/src/Base/Writer.cpp
@@ -264,7 +264,7 @@ void FileWriter::putNextEntry(const char* file)
this->FileStream.open(fileName.c_str(), std::ios::out);
}
-bool FileWriter::shouldWrite(const Base::Persistence *) const
+bool FileWriter::shouldWrite(const std::string& , const Base::Persistence *) const
{
return true;
}
@@ -278,7 +278,7 @@ void FileWriter::writeFiles(void)
while (index < FileList.size()) {
FileEntry entry = FileList.begin()[index];
- if (shouldWrite(entry.Object)) {
+ if (shouldWrite(entry.FileName, entry.Object)) {
std::string filePath = entry.FileName;
std::string::size_type pos = 0;
while ((pos = filePath.find("/", pos)) != std::string::npos) {
diff --git a/src/Base/Writer.h b/src/Base/Writer.h
index fa867d06f1..53f86e3836 100644
--- a/src/Base/Writer.h
+++ b/src/Base/Writer.h
@@ -165,7 +165,7 @@ private:
std::stringstream StrStream;
};
-/*! The FileWriter class
+/*! The FileWriter class
This class writes out the data into files into a given directory name.
\see Base::Persistence
\author Werner Mayer
@@ -185,7 +185,7 @@ public:
to write out certain objects. The default implementation
always returns true.
*/
- virtual bool shouldWrite(const Base::Persistence *Object) const;
+ virtual bool shouldWrite(const std::string& name, const Base::Persistence *Object) const;
private:
std::string DirName;
diff --git a/src/Gui/AutoSaver.cpp b/src/Gui/AutoSaver.cpp
index c645a3acb9..16ad020ec9 100644
--- a/src/Gui/AutoSaver.cpp
+++ b/src/Gui/AutoSaver.cpp
@@ -33,11 +33,13 @@
#include "AutoSaver.h"
#include
+#include
#include
#include
#include
#include
#include
+#include
#include "Document.h"
#include "WaitCursor.h"
@@ -86,6 +88,11 @@ void AutoSaver::slotCreateDocument(const App::Document& Doc)
int id = timeout > 0 ? startTimer(timeout) : 0;
AutoSaveProperty* as = new AutoSaveProperty(&Doc);
as->timerId = id;
+ std::string dirName = Doc.TransientDir.getValue();
+ dirName += "/fc_recovery_files";
+ Base::FileInfo fi(dirName);
+ fi.createDirectory();
+ as->dirName = dirName;
saverMap.insert(std::make_pair(name, as));
}
@@ -101,7 +108,7 @@ void AutoSaver::slotDeleteDocument(const App::Document& Doc)
}
}
-void AutoSaver::saveDocument(const std::string& name, const std::set& data)
+void AutoSaver::saveDocument(const std::string& name, AutoSaveProperty& saver)
{
Gui::WaitCursor wc;
App::Document* doc = App::GetApplication().getDocument(name.c_str());
@@ -145,6 +152,7 @@ void AutoSaver::saveDocument(const std::string& name, const std::setGetBool("SaveBinaryBrep", true))
writer.setMode("BinaryBrep");
@@ -177,8 +185,8 @@ void AutoSaver::timerEvent(QTimerEvent * event)
for (std::map::iterator it = saverMap.begin(); it != saverMap.end(); ++it) {
if (it->second->timerId == id) {
try {
- saveDocument(it->first, it->second->objects);
- it->second->objects.clear();
+ saveDocument(it->first, *it->second);
+ it->second->touched.clear();
break;
}
catch (...) {
@@ -192,13 +200,28 @@ void AutoSaver::timerEvent(QTimerEvent * event)
AutoSaveProperty::AutoSaveProperty(const App::Document* doc) : timerId(-1)
{
- document = const_cast(doc)->signalChangedObject.connect
+ documentNew = const_cast(doc)->signalNewObject.connect
+ (boost::bind(&AutoSaveProperty::slotNewObject, this, _1));
+ documentMod = const_cast(doc)->signalChangedObject.connect
(boost::bind(&AutoSaveProperty::slotChangePropertyData, this, _2));
}
AutoSaveProperty::~AutoSaveProperty()
{
- document.disconnect();
+ documentNew.disconnect();
+ documentMod.disconnect();
+}
+
+void AutoSaveProperty::slotNewObject(const App::DocumentObject& obj)
+{
+ std::vector props;
+ obj.getPropertyList(props);
+
+ // if an object was deleted and then restored by an undo then add all properties
+ // because this might be the data files which we may want to re-write
+ for (std::vector::iterator it = props.begin(); it != props.end(); ++it) {
+ slotChangePropertyData(*(*it));
+ }
}
void AutoSaveProperty::slotChangePropertyData(const App::Property& prop)
@@ -206,13 +229,13 @@ void AutoSaveProperty::slotChangePropertyData(const App::Property& prop)
std::stringstream str;
str << static_cast(&prop) << std::ends;
std::string address = str.str();
- this->objects.insert(address);
+ this->touched.insert(address);
}
// ----------------------------------------------------------------------------
-RecoveryWriter::RecoveryWriter(const char* DirName)
- : Base::FileWriter(DirName)
+RecoveryWriter::RecoveryWriter(AutoSaveProperty& saver)
+ : Base::FileWriter(saver.dirName.c_str()), saver(saver)
{
}
@@ -220,12 +243,17 @@ RecoveryWriter::~RecoveryWriter()
{
}
-void RecoveryWriter::setModifiedData(const std::set& m)
+void RecoveryWriter::setLevel(int)
{
- data = m;
+ // not implemented
}
-bool RecoveryWriter::shouldWrite(const Base::Persistence *object) const
+void RecoveryWriter::setComment(const char*)
+{
+ // not implemented
+}
+
+bool RecoveryWriter::shouldWrite(const std::string& name, const Base::Persistence *object) const
{
// Property files of a view provider can always be written because
// these are rather small files.
@@ -244,8 +272,16 @@ bool RecoveryWriter::shouldWrite(const Base::Persistence *object) const
str << static_cast(object) << std::ends;
std::string address = str.str();
- std::set::const_iterator it = data.find(address);
- return (it != data.end());
+ // Check if the property will be exported to the same file. If the file has changed or if the property hasn't been
+ // yet exported then (re-)write the file.
+ std::map::iterator it = saver.fileMap.find(address);
+ if (it == saver.fileMap.end() || it->second != name) {
+ saver.fileMap[address] = name;
+ return true;
+ }
+
+ std::set::const_iterator jt = saver.touched.find(address);
+ return (jt != saver.touched.end());
}
diff --git a/src/Gui/AutoSaver.h b/src/Gui/AutoSaver.h
index b97f8da700..3cd5c445a1 100644
--- a/src/Gui/AutoSaver.h
+++ b/src/Gui/AutoSaver.h
@@ -33,6 +33,7 @@
namespace App {
class Document;
+class DocumentObject;
class Property;
}
@@ -45,12 +46,16 @@ public:
AutoSaveProperty(const App::Document* doc);
~AutoSaveProperty();
int timerId;
- std::set objects;
+ std::set touched;
+ std::string dirName;
+ std::map fileMap;
private:
+ void slotNewObject(const App::DocumentObject&);
void slotChangePropertyData(const App::Property&);
typedef boost::BOOST_SIGNALS_NAMESPACE::connection Connection;
- Connection document;
+ Connection documentNew;
+ Connection documentMod;
};
/*!
@@ -77,7 +82,7 @@ protected:
void slotCreateDocument(const App::Document& Doc);
void slotDeleteDocument(const App::Document& Doc);
void timerEvent(QTimerEvent * event);
- void saveDocument(const std::string&, const std::set&);
+ void saveDocument(const std::string&, AutoSaveProperty&);
private:
int timeout; /*!< Timeout in milliseconds */
@@ -87,19 +92,21 @@ private:
class RecoveryWriter : public Base::FileWriter
{
public:
- RecoveryWriter(const char* DirName);
+ RecoveryWriter(AutoSaveProperty&);
virtual ~RecoveryWriter();
- void setModifiedData(const std::set &);
+
+ void setLevel(int);
+ void setComment(const char*);
/*!
This method can be re-implemented in sub-classes to avoid
to write out certain objects. The default implementation
always returns true.
*/
- virtual bool shouldWrite(const Base::Persistence *) const;
+ virtual bool shouldWrite(const std::string&, const Base::Persistence *) const;
private:
- std::set data;
+ AutoSaveProperty& saver;
};
} //namespace Gui