diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 3ab7c2caeb..abea1441bf 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -579,34 +579,7 @@ void Document::Save (Base::Writer &writer) const PropertyContainer::Save(writer); // writing the features types - writer.incInd(); // indention for 'Objects count' - writer.Stream() << writer.ind() << "objectArray.size() <<"\">" << endl; - - writer.incInd(); // indention for 'Object type' - std::vector::const_iterator it; - for (it = d->objectArray.begin(); it != d->objectArray.end(); ++it) { - writer.Stream() << writer.ind() << "getTypeId().getName() << "\" " - << "name=\"" << (*it)->getNameInDocument() << "\" " - << "/>" << endl; - } - - writer.decInd(); // indention for 'Object type' - writer.Stream() << writer.ind() << "" << endl; - - // writing the features itself - writer.Stream() << writer.ind() << "objectArray.size() <<"\">" << endl; - - writer.incInd(); // indention for 'Object name' - for (it = d->objectArray.begin(); it != d->objectArray.end(); ++it) { - writer.Stream() << writer.ind() << "getNameInDocument() << "\">" << endl; - (*it)->Save(writer); - writer.Stream() << writer.ind() << "" << endl; - } - - writer.decInd(); // indention for 'Object name' - writer.Stream() << writer.ind() << "" << endl; - writer.decInd(); // indention for 'Objects count' + writeObjects(d->objectArray, writer); writer.Stream() << "" << endl; } @@ -685,37 +658,7 @@ void Document::Restore(Base::XMLReader &reader) } // SchemeVersion "3" or higher else if ( scheme >= 3 ) { // read the feature types - reader.readElement("Objects"); - Cnt = reader.getAttributeAsInteger("Count"); - for (i=0 ;iStatusBits.set(4); - pObj->Restore(reader); - pObj->StatusBits.reset(4); - } - reader.readEndElement("Object"); - } - reader.readEndElement("ObjectData"); + readObjects(reader); } reader.readEndElement("Document"); @@ -732,6 +675,20 @@ void Document::exportObjects(const std::vector& obj, writer.Stream() << "" << endl; writer.Stream() << "" << endl; + // writing the object types + writeObjects(obj, writer); + writer.Stream() << "" << endl; + + // Hook for others to add further data. + signalExportObjects(obj, writer); + + // write additional files + writer.writeFiles(); +} + +void Document::writeObjects(const std::vector& obj, + Base::Writer &writer) const +{ // writing the features types writer.incInd(); // indention for 'Objects count' writer.Stream() << writer.ind() << "" << endl; @@ -741,7 +698,7 @@ void Document::exportObjects(const std::vector& obj, for (it = obj.begin(); it != obj.end(); ++it) { writer.Stream() << writer.ind() << "getTypeId().getName() << "\" " - << "name=\"" << (*it)->getNameInDocument() << "\" " + << "name=\"" << (*it)->getNameInDocument() << "\" " << "/>" << endl; } @@ -761,42 +718,31 @@ void Document::exportObjects(const std::vector& obj, writer.decInd(); // indention for 'Object name' writer.Stream() << writer.ind() << "" << endl; writer.decInd(); // indention for 'Objects count' - writer.Stream() << "" << endl; - - // Hook for others to add further data. - signalExportObjects(obj, writer); - - // write additional files - writer.writeFiles(); } std::vector -Document::importObjects(std::istream& input) +Document::readObjects(Base::XMLReader& reader) { std::vector objs; - zipios::ZipInputStream zipstream(input); - Base::XMLReader reader("", zipstream); - - int i,Cnt; - reader.readElement("Document"); - long scheme = reader.getAttributeAsInteger("SchemaVersion"); - reader.DocumentSchema = scheme; // read the object types - std::map nameMap; reader.readElement("Objects"); - Cnt = reader.getAttributeAsInteger("Count"); - for (i=0 ;igetNameInDocument(); + reader.addName(name.c_str(), o->getNameInDocument()); } catch (Base::Exception&) { Base::Console().Message("Cannot create object '%s'\n", name.c_str()); @@ -807,9 +753,9 @@ Document::importObjects(std::istream& input) // read the features itself reader.readElement("ObjectData"); Cnt = reader.getAttributeAsInteger("Count"); - for (i=0 ;iStatusBits.set(4); @@ -820,12 +766,26 @@ Document::importObjects(std::istream& input) } reader.readEndElement("ObjectData"); + return objs; +} + +std::vector +Document::importObjects(Base::XMLReader& reader) +{ + reader.readElement("Document"); + long scheme = reader.getAttributeAsInteger("SchemaVersion"); + reader.DocumentSchema = scheme; + + std::vector objs = readObjects(reader); + reader.readEndElement("Document"); signalImportObjects(objs, reader); - reader.readFiles(zipstream); + // reset all touched - for (std::vector::iterator it= objs.begin();it!=objs.end();++it) + for (std::vector::iterator it= objs.begin();it!=objs.end();++it) { + (*it)->onDocumentRestored(); (*it)->purgeTouched(); + } return objs; } diff --git a/src/App/Document.h b/src/App/Document.h index 9b705e8c9d..c8dd9d830e 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -115,7 +115,7 @@ public: void restore (void); void exportObjects(const std::vector&, std::ostream&); void exportGraphviz(std::ostream&); - std::vector importObjects(std::istream&); + std::vector importObjects(Base::XMLReader& reader); /// Opens the document from its file name //void open (void); /// Is the document already saved to a file @@ -266,6 +266,8 @@ protected: /// checks if a valid transaction is open void _checkTransaction(void); void breakDependency(DocumentObject* pcObject, bool clear); + std::vector readObjects(Base::XMLReader& reader); + void writeObjects(const std::vector&, Base::Writer &writer) const; void onChanged(const Property* prop); /// callback from the Document objects before property will be changed diff --git a/src/Base/Reader.cpp b/src/Base/Reader.cpp index 6791b99f62..496f583da8 100644 --- a/src/Base/Reader.cpp +++ b/src/Base/Reader.cpp @@ -360,6 +360,15 @@ bool Base::XMLReader::isRegistered(Base::Persistence *Object) const return false; } +void Base::XMLReader::addName(const char*, const char*) +{ +} + +const char* Base::XMLReader::getName(const char* name) const +{ + return name; +} + // --------------------------------------------------------------------------- // Base::XMLReader: Implementation of the SAX DocumentHandler interface // --------------------------------------------------------------------------- diff --git a/src/Base/Reader.h b/src/Base/Reader.h index 7e55575d42..f35ff379d7 100644 --- a/src/Base/Reader.h +++ b/src/Base/Reader.h @@ -159,6 +159,8 @@ public: /// get all registered file names const std::vector& getFilenames() const; bool isRegistered(Base::Persistence *Object) const; + virtual void addName(const char*, const char*); + virtual const char* getName(const char*) const; //@} /// Schema Version of the document diff --git a/src/Gui/Action.cpp b/src/Gui/Action.cpp index 5e39c8a518..5cdc6d4127 100644 --- a/src/Gui/Action.cpp +++ b/src/Gui/Action.cpp @@ -31,6 +31,7 @@ # include # include # include +# include # include # include #endif @@ -55,13 +56,21 @@ using namespace Gui::Dialog; * Constructs an action called \a name with parent \a parent. It also stores a pointer * to the command object. */ -Action::Action (Command* pcCmd,QObject * parent) +Action::Action (Command* pcCmd, QObject * parent) : QObject(parent), _action(new QAction( this )), _pcCmd(pcCmd) { _action->setObjectName(QString::fromAscii(_pcCmd->getName())); connect(_action, SIGNAL(triggered(bool)), this, SLOT(onActivated())); } +Action::Action (Command* pcCmd, QAction* action, QObject * parent) + : QObject(parent), _action(action), _pcCmd(pcCmd) +{ + _action->setParent(this); + _action->setObjectName(QString::fromAscii(_pcCmd->getName())); + connect(_action, SIGNAL(triggered(bool)), this, SLOT(onActivated())); +} + Action::~Action() { delete _action; @@ -257,6 +266,14 @@ void ActionGroup::setVisible( bool b ) _group->setVisible(b); } +QAction* ActionGroup::addAction(QAction* action) +{ + int index = _group->actions().size(); + action = _group->addAction(action); + action->setData(QVariant(index)); + return action; +} + QAction* ActionGroup::addAction(const QString& text) { int index = _group->actions().size(); @@ -289,6 +306,14 @@ void ActionGroup::onActivated () _pcCmd->invoke(this->property("defaultAction").toInt()); } +/** + * Activates the command. + */ +void ActionGroup::onActivated (int index) +{ + _pcCmd->invoke(index); +} + /** * Activates the command. */ @@ -410,6 +435,8 @@ void WorkbenchComboBox::onActivated(int i) int index = itemData(i).toInt(); WorkbenchActionEvent* ev = new WorkbenchActionEvent(this->actions()[index]); QApplication::postEvent(this->group, ev); + // TODO: Test if we can use this instead + //QTimer::singleShot(20, this->actions()[i], SLOT(trigger())); } void WorkbenchComboBox::onActivated(QAction* action) diff --git a/src/Gui/Action.h b/src/Gui/Action.h index 0b33f57ece..34ce2dd525 100644 --- a/src/Gui/Action.h +++ b/src/Gui/Action.h @@ -45,6 +45,8 @@ class GuiExport Action : public QObject public: Action (Command* pcCmd, QObject * parent = 0); + /// Action takes ownership of the 'action' object. + Action (Command* pcCmd, QAction* action, QObject * parent); virtual ~Action(); virtual void addTo (QWidget * w); @@ -100,6 +102,7 @@ public: void setVisible (bool); void setDropDownMenu(bool b) { _dropDown = b; } + QAction* addAction(QAction*); QAction* addAction(const QString&); QList actions() const; int checkedAction() const; @@ -107,6 +110,7 @@ public: public Q_SLOTS: void onActivated (); + void onActivated (int); void onActivated (QAction*); protected: diff --git a/src/Gui/MergeDocuments.cpp b/src/Gui/MergeDocuments.cpp index 52713fa474..9b53d960cb 100644 --- a/src/Gui/MergeDocuments.cpp +++ b/src/Gui/MergeDocuments.cpp @@ -42,10 +42,22 @@ namespace Gui { class XMLMergeReader : public Base::XMLReader { public: - XMLMergeReader(const std::map& name, const char* FileName, std::istream& str) + XMLMergeReader(std::map& name, const char* FileName, std::istream& str) : Base::XMLReader(FileName, str), nameMap(name) {} + void addName(const char* s1, const char* s2) + { + nameMap[s1] = s2; + } + const char* getName(const char* name) const + { + std::map::const_iterator it = nameMap.find(name); + if (it != nameMap.end()) + return it->second.c_str(); + else + return name; + } protected: void startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, @@ -75,7 +87,7 @@ protected: } private: - const std::map& nameMap; + std::map& nameMap; typedef std::pair PropertyTag; std::stack propertyStack; }; @@ -104,64 +116,14 @@ unsigned int MergeDocuments::getMemSize (void) const std::vector MergeDocuments::importObjects(std::istream& input) { - //std::map nameMap; - std::vector objs; - zipios::ZipInputStream zipstream(input); - XMLMergeReader reader(nameMap,"", zipstream); + this->nameMap.clear(); + this->stream = new zipios::ZipInputStream(input); + XMLMergeReader reader(this->nameMap,"", *stream); + std::vector objs = appdoc->importObjects(reader); - int i,Cnt; - reader.readElement("Document"); - long scheme = reader.getAttributeAsInteger("SchemaVersion"); - reader.DocumentSchema = scheme; + delete this->stream; + this->stream = 0; - // read the object types - nameMap.clear(); - reader.readElement("Objects"); - Cnt = reader.getAttributeAsInteger("Count"); - for (i=0 ;iaddObject(type.c_str(),name.c_str()); - objs.push_back(o); - // use this name for the later access because an object with - // the given name may already exist - nameMap[name] = o->getNameInDocument(); - } - catch (Base::Exception&) { - Base::Console().Message("Cannot create object '%s'\n", name.c_str()); - } - } - reader.readEndElement("Objects"); - - // read the features itself - reader.readElement("ObjectData"); - Cnt = reader.getAttributeAsInteger("Count"); - for (i=0 ;igetObject(name.c_str()); - if (pObj) { // check if this feature has been registered -// pObj->StatusBits.set(4); - pObj->Restore(reader); -// pObj->StatusBits.reset(4); - } - reader.readEndElement("Object"); - } - reader.readEndElement("ObjectData"); - - reader.readEndElement("Document"); - appdoc->signalImportObjects(objs, reader); - reader.readFiles(zipstream); - // reset all touched - for (std::vector::iterator it= objs.begin();it!=objs.end();++it) - (*it)->purgeTouched(); return objs; } @@ -173,6 +135,8 @@ void MergeDocuments::importObject(const std::vector& o, Ba if (vp) vp->hide(); } Restore(r); + + r.readFiles(*this->stream); } void MergeDocuments::exportObject(const std::vector& o, Base::Writer & w) diff --git a/src/Gui/MergeDocuments.h b/src/Gui/MergeDocuments.h index 817ae91193..42bc252e02 100644 --- a/src/Gui/MergeDocuments.h +++ b/src/Gui/MergeDocuments.h @@ -27,6 +27,9 @@ #include #include +namespace zipios { +class ZipInputStream; +} namespace App { class Document; class DocumentObject; @@ -49,6 +52,7 @@ public: void RestoreDocFile(Base::Reader & r); private: + zipios::ZipInputStream* stream; App::Document* appdoc; Gui::Document* document; std::vector objects; diff --git a/src/Gui/ViewProviderPythonFeature.cpp b/src/Gui/ViewProviderPythonFeature.cpp index 144d158159..b008fd04ac 100644 --- a/src/Gui/ViewProviderPythonFeature.cpp +++ b/src/Gui/ViewProviderPythonFeature.cpp @@ -25,6 +25,8 @@ #ifndef _PreComp_ # include +# include +# include # include # include # include @@ -68,7 +70,19 @@ using namespace Gui; namespace Gui { -class ViewProviderPythonFeatureObserver +class PropertyEvent : public QEvent +{ +public: + PropertyEvent(App::Property* p1, App::Property* p2) + : QEvent(QEvent::Type(QEvent::User)), p1(p1), p2(p2) + { + } + + App::Property* p1; + App::Property* p2; +}; + +class ViewProviderPythonFeatureObserver : public QObject { public: /// The one and only instance. @@ -80,13 +94,19 @@ public: void slotDeleteDocument(const Gui::Document&); private: + void customEvent(QEvent* e) + { + PropertyEvent* pe = static_cast(e); + pe->p1->Paste(*pe->p2); + delete pe->p2; + } static ViewProviderPythonFeatureObserver* _singleton; ViewProviderPythonFeatureObserver(); ~ViewProviderPythonFeatureObserver(); typedef std::map< const App::DocumentObject*, - std::string + App::Property* > ObjectProxy; std::map proxyMap; @@ -133,8 +153,8 @@ void ViewProviderPythonFeatureObserver::slotAppendObject(const Gui::ViewProvider try { App::Property* prop = vp.getPropertyByName("Proxy"); if (prop && prop->isDerivedFrom(App::PropertyPythonObject::getClassTypeId())) { - static_cast(prop)->fromString(jt->second); - static_cast(prop)->touch(); + // make this delayed so that the corresponding item in the tree view is accessible + QApplication::postEvent(this, new PropertyEvent(prop, jt->second)); it->second.erase(jt); } } @@ -162,8 +182,7 @@ void ViewProviderPythonFeatureObserver::slotDeleteObject(const Gui::ViewProvider try { App::Property* prop = vp.getPropertyByName("Proxy"); if (prop && prop->isDerivedFrom(App::PropertyPythonObject::getClassTypeId())) { - std::string proxy = static_cast(prop)->toString(); - proxyMap[doc][docobj] = proxy; + proxyMap[doc][docobj] = prop->Copy(); } } catch (Py::Exception& e) {