emit signal when starting and finishing to save a document

This commit is contained in:
wmayer
2018-10-08 14:03:00 +02:00
parent addb742b3c
commit bf4dd7920e
7 changed files with 99 additions and 4 deletions

View File

@@ -431,6 +431,8 @@ Document* Application::newDocument(const char * Name, const char * UserName)
_pActiveDoc->signalOpenTransaction.connect(boost::bind(&App::Application::slotOpenTransaction, this, _1, _2));
_pActiveDoc->signalCommitTransaction.connect(boost::bind(&App::Application::slotCommitTransaction, this, _1));
_pActiveDoc->signalAbortTransaction.connect(boost::bind(&App::Application::slotAbortTransaction, this, _1));
_pActiveDoc->signalStartSave.connect(boost::bind(&App::Application::slotStartSaveDocument, this, _1, _2));
_pActiveDoc->signalFinishSave.connect(boost::bind(&App::Application::slotFinishSaveDocument, this, _1, _2));
// make sure that the active document is set in case no GUI is up
{
@@ -1055,6 +1057,16 @@ void Application::slotAbortTransaction(const Document& d)
this->signalAbortTransaction(d);
}
void Application::slotStartSaveDocument(const App::Document& doc, const std::string& filename)
{
this->signalStartSaveDocument(doc, filename);
}
void Application::slotFinishSaveDocument(const App::Document& doc, const std::string& filename)
{
this->signalFinishSaveDocument(doc, filename);
}
//**************************************************************************
// Init, Destruct and singleton

View File

@@ -116,6 +116,10 @@ public:
boost::signal<void (const Document&)> signalStartRestoreDocument;
/// signal on restoring Document
boost::signal<void (const Document&)> signalFinishRestoreDocument;
/// signal on starting to save Document
boost::signal<void (const Document&, const std::string&)> signalStartSaveDocument;
/// signal on saved Document
boost::signal<void (const Document&, const std::string&)> signalFinishSaveDocument;
/// signal on undo in document
boost::signal<void (const Document&)> signalUndoDocument;
/// signal on redo in document
@@ -295,6 +299,8 @@ protected:
void slotOpenTransaction(const App::Document&, std::string);
void slotCommitTransaction(const App::Document&);
void slotAbortTransaction(const App::Document&);
void slotStartSaveDocument(const App::Document&, const std::string&);
void slotFinishSaveDocument(const App::Document&, const std::string&);
//@}
private:

View File

@@ -1661,6 +1661,8 @@ bool Document::save (void)
bool Document::saveToFile(const char* filename) const
{
signalStartSave(*this, filename);
auto hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document");
int compression = hGrp->GetInt("CompressionLevel",3);
compression = Base::clamp<int>(compression, Z_NO_COMPRESSION, Z_BEST_COMPRESSION);
@@ -1758,6 +1760,8 @@ bool Document::saveToFile(const char* filename) const
Base::Console().Warning("Cannot rename file from '%s' to '%s'\n",
fn.c_str(), filename);
signalFinishSave(*this, filename);
return true;
}

View File

@@ -152,6 +152,10 @@ public:
Base::XMLReader&)> signalImportObjects;
boost::signal<void (const std::vector<App::DocumentObject*>&, Base::Reader&,
const std::map<std::string, std::string>&)> signalImportViewObjects;
//signal starting a save action to a file
boost::signal<void (const App::Document&, const std::string&)> signalStartSave;
//signal finishing a save action to a file
boost::signal<void (const App::Document&, const std::string&)> signalFinishSave;
boost::signal<void (const App::Document&)> signalRecomputed;
boost::signal<void (const App::DocumentObject&)> signalRecomputedObject;
//signal a new opened transaction

View File

@@ -97,6 +97,11 @@ DocumentObserverPython::DocumentObserverPython(const Py::Object& obj) : inst(obj
this->connectDocumentAbortTransaction = App::GetApplication().signalAbortTransaction.connect(boost::bind
(&DocumentObserverPython::slotAbortTransaction, this, _1));
this->connectDocumentStartSave = App::GetApplication().signalStartSaveDocument.connect(boost::bind
(&DocumentObserverPython::slotStartSaveDocument, this, _1, _2));
this->connectDocumentFinishSave = App::GetApplication().signalFinishSaveDocument.connect(boost::bind
(&DocumentObserverPython::slotFinishSaveDocument, this, _1, _2));
this->connectObjectAppendDynamicProperty = App::GetApplication().signalAppendDynamicProperty.connect(boost::bind
(&DocumentObserverPython::slotAppendDynamicProperty, this, _1));
this->connectObjectRemoveDynamicProperty = App::GetApplication().signalRemoveDynamicProperty.connect(boost::bind
@@ -125,7 +130,9 @@ DocumentObserverPython::~DocumentObserverPython()
this->connectDocumentOpenTransaction.disconnect();
this->connectDocumentCommitTransaction.disconnect();
this->connectDocumentAbortTransaction.disconnect();
this->connectDocumentStartSave.disconnect();
this->connectDocumentFinishSave.disconnect();
this->connectObjectAppendDynamicProperty.disconnect();
this->connectObjectRemoveDynamicProperty.disconnect();
this->connectObjectChangePropertyEditor.disconnect();
@@ -518,3 +525,39 @@ void DocumentObserverPython::slotChangePropertyEditor(const App::Property& Prop)
e.ReportException();
}
}
void DocumentObserverPython::slotStartSaveDocument(const App::Document& doc, const std::string& file)
{
Base::PyGILStateLocker lock;
try {
if (this->inst.hasAttr(std::string("slotStartSaveDocument"))) {
Py::Callable method(this->inst.getAttr(std::string("slotStartSaveDocument")));
Py::Tuple args(2);
args.setItem(0, Py::Object(const_cast<App::Document&>(doc).getPyObject(), true));
args.setItem(1, Py::String(file));
method.apply(args);
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
}
void DocumentObserverPython::slotFinishSaveDocument(const App::Document& doc, const std::string& file)
{
Base::PyGILStateLocker lock;
try {
if (this->inst.hasAttr(std::string("slotFinishSaveDocument"))) {
Py::Callable method(this->inst.getAttr(std::string("slotFinishSaveDocument")));
Py::Tuple args(2);
args.setItem(0, Py::Object(const_cast<App::Document&>(doc).getPyObject(), true));
args.setItem(1, Py::String(file));
method.apply(args);
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
}

View File

@@ -91,6 +91,10 @@ private:
void slotRemoveDynamicProperty(const App::Property& Prop);
/** Called when an object property gets a new editor relevant status like hidden or read only*/
void slotChangePropertyEditor(const App::Property& Prop);
/** Called when a document is about to be saved*/
void slotStartSaveDocument(const App::Document&, const std::string&);
/** Called when an document has been saved*/
void slotFinishSaveDocument(const App::Document&, const std::string&);
private:
Py::Object inst;
@@ -114,6 +118,8 @@ private:
Connection connectDocumentOpenTransaction;
Connection connectDocumentCommitTransaction;
Connection connectDocumentAbortTransaction;
Connection connectDocumentStartSave;
Connection connectDocumentFinishSave;
Connection connectObjectAppendDynamicProperty;
Connection connectObjectRemoveDynamicProperty;
Connection connectObjectChangePropertyEditor;

View File

@@ -1406,7 +1406,17 @@ class DocumentObserverCases(unittest.TestCase):
self.signal.append('ObjChangePropEdit');
self.parameter.append(obj)
self.parameter2.append(prop)
def slotStartSaveDocument(self, obj, name):
self.signal.append('DocStartSave')
self.parameter.append(obj)
self.parameter2.append(name)
def slotFinishSaveDocument(self, obj, name):
self.signal.append('DocFinishSave')
self.parameter.append(obj)
self.parameter2.append(name)
class GuiObserver():
signal = []
@@ -1458,6 +1468,16 @@ class DocumentObserverCases(unittest.TestCase):
self.Obs = self.Observer();
FreeCAD.addDocumentObserver(self.Obs);
def testSave(self):
TempPath = tempfile.gettempdir()
SaveName = TempPath + os.sep + "SaveRestoreTests.FCStd"
self.Doc1 = FreeCAD.newDocument("Observer1");
self.Doc1.saveAs(SaveName)
self.assertEqual(self.Obs.signal.pop(), 'DocFinishSave')
self.assertEqual(self.Obs.parameter2.pop(), self.Doc1.FileName)
self.assertEqual(self.Obs.signal.pop(), 'DocStartSave')
self.assertEqual(self.Obs.parameter2.pop(), self.Doc1.FileName)
def testDocument(self):
# testing document level signals
@@ -1577,13 +1597,13 @@ class DocumentObserverCases(unittest.TestCase):
self.failUnless(self.Obs.parameter2.pop(0) == "Label")
self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2)
obj.touch()
obj.enforceRecompute()
obj.recompute()
self.failUnless(self.Obs.signal.pop(0) == 'ObjRecomputed')
self.failUnless(self.Obs.parameter.pop(0) is obj)
self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2)
obj.touch()
obj.enforceRecompute()
self.Doc1.recompute()
self.failUnless(self.Obs.signal.pop(0) == 'ObjRecomputed')
self.failUnless(self.Obs.parameter.pop(0) is obj)