emit signal when starting and finishing to save a document
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user