diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 77f0201e0..d3c60aab9 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -1075,6 +1075,10 @@ bool Document::save (void) // write additional files writer.writeFiles(); + if (writer.hasErrors()) { + throw Base::FileException("Failed to write all data to file", tmp); + } + GetApplication().signalSaveDocument(*this); } diff --git a/src/App/DocumentPyImp.cpp b/src/App/DocumentPyImp.cpp index 51b98fedc..da7b7d07a 100644 --- a/src/App/DocumentPyImp.cpp +++ b/src/App/DocumentPyImp.cpp @@ -52,11 +52,22 @@ std::string DocumentPy::representation(void) const PyObject* DocumentPy::save(PyObject * args) { - if (!PyArg_ParseTuple(args, "")) // convert args: Python->C - return NULL; // NULL triggers exception - if (!getDocumentPtr()->save()) { - PyErr_Format(PyExc_ValueError, "Object attribute 'FileName' is not set"); - return NULL; + if (!PyArg_ParseTuple(args, "")) // convert args: Python->C + return NULL; // NULL triggers exception + + try { + if (!getDocumentPtr()->save()) { + PyErr_SetString(PyExc_ValueError, "Object attribute 'FileName' is not set"); + return NULL; + } + } + catch (const Base::FileException& e) { + PyErr_SetString(PyExc_IOError, e.what()); + return 0; + } + catch (const Base::Exception& e) { + PyErr_SetString(PyExc_RuntimeError, e.what()); + return 0; } const char* filename = getDocumentPtr()->FileName.getValue(); @@ -72,11 +83,22 @@ PyObject* DocumentPy::save(PyObject * args) PyObject* DocumentPy::saveAs(PyObject * args) { char* fn; - if (!PyArg_ParseTuple(args, "s", &fn)) // convert args: Python->C - return NULL; // NULL triggers exception - if (!getDocumentPtr()->saveAs(fn)) { - PyErr_Format(PyExc_ValueError, "Object attribute 'FileName' is not set"); - return NULL; + if (!PyArg_ParseTuple(args, "s", &fn)) // convert args: Python->C + return NULL; // NULL triggers exception + + try { + if (!getDocumentPtr()->saveAs(fn)) { + PyErr_SetString(PyExc_ValueError, "Object attribute 'FileName' is not set"); + return NULL; + } + } + catch (const Base::FileException& e) { + PyErr_SetString(PyExc_IOError, e.what()); + return 0; + } + catch (const Base::Exception& e) { + PyErr_SetString(PyExc_RuntimeError, e.what()); + return 0; } Base::FileInfo fi(fn); diff --git a/src/Base/Writer.cpp b/src/Base/Writer.cpp index aa863a593..7bb02e1e8 100644 --- a/src/Base/Writer.cpp +++ b/src/Base/Writer.cpp @@ -141,6 +141,26 @@ void Writer::clearModes() Modes.clear(); } +void Writer::addError(const std::string& msg) +{ + Errors.push_back(msg); +} + +bool Writer::hasErrors() const +{ + return (!Errors.empty()); +} + +void Writer::clearErrors() +{ + Errors.clear(); +} + +std::vector Writer::getErrors() const +{ + return Errors; +} + std::string Writer::addFile(const char* Name,const Base::Persistence *Object) { // always check isForceXML() before requesting a file! diff --git a/src/Base/Writer.h b/src/Base/Writer.h index 7979ceb69..802793014 100644 --- a/src/Base/Writer.h +++ b/src/Base/Writer.h @@ -95,6 +95,14 @@ public: void clearModes(); //@} + /** @name Error handling */ + //@{ + void addError(const std::string&); + bool hasErrors() const; + void clearErrors(); + std::vector getErrors() const; + //@} + /** @name pretty formating for XML */ //@{ /// get the current indentation @@ -118,6 +126,7 @@ protected: }; std::vector FileList; std::vector FileNames; + std::vector Errors; std::set Modes; short indent; diff --git a/src/Gui/Document.cpp b/src/Gui/Document.cpp index d00965cb5..4d0608223 100644 --- a/src/Gui/Document.cpp +++ b/src/Gui/Document.cpp @@ -605,10 +605,16 @@ App::Document* Document::getDocument(void) const bool Document::save(void) { if (d->_pcDocument->isSaved()) { - Gui::WaitCursor wc; - Command::doCommand(Command::Doc,"App.getDocument(\"%s\").save()" - ,d->_pcDocument->getName()); - setModified(false); + try { + Gui::WaitCursor wc; + Command::doCommand(Command::Doc,"App.getDocument(\"%s\").save()" + ,d->_pcDocument->getName()); + setModified(false); + } + catch (const Base::Exception& e) { + QMessageBox::critical(getMainWindow(), QObject::tr("Saving document failed"), + QString::fromLatin1(e.what())); + } return true; } else { @@ -631,12 +637,17 @@ bool Document::saveAs(void) const char * DocName = App::GetApplication().getDocumentName(getDocument()); // save as new file name - Gui::WaitCursor wc; - Command::doCommand(Command::Doc,"App.getDocument(\"%s\").saveAs(\"%s\")" - , DocName, (const char*)fn.toUtf8()); - setModified(false); - - getMainWindow()->appendRecentFile(fi.filePath()); + try { + Gui::WaitCursor wc; + Command::doCommand(Command::Doc,"App.getDocument(\"%s\").saveAs(\"%s\")" + , DocName, (const char*)fn.toUtf8()); + setModified(false); + getMainWindow()->appendRecentFile(fi.filePath()); + } + catch (const Base::Exception& e) { + QMessageBox::critical(getMainWindow(), QObject::tr("Saving document failed"), + QString::fromLatin1(e.what())); + } return true; } else { diff --git a/src/Mod/Part/App/PropertyTopoShape.cpp b/src/Mod/Part/App/PropertyTopoShape.cpp index 8c3766f01..7ac5d84d1 100644 --- a/src/Mod/Part/App/PropertyTopoShape.cpp +++ b/src/Mod/Part/App/PropertyTopoShape.cpp @@ -294,6 +294,10 @@ void PropertyPartShape::SaveDocFile (Base::Writer &writer) const else { Base::Console().Error("Cannot save BRep file '%s'\n", fi.filePath().c_str()); } + + std::stringstream ss; + ss << "Cannot save BRep file '" << fi.filePath() << "'"; + writer.addError(ss.str()); } Base::ifstream file(fi, std::ios::in | std::ios::binary);