MergeDocuments.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "PreCompiled.h"
00024 #ifndef _PreComp_
00025 # include <stack>
00026 # include <boost/bind.hpp>
00027 #endif
00028 #include "MergeDocuments.h"
00029 #include <Base/Console.h>
00030 #include <Base/Reader.h>
00031 #include <Base/Writer.h>
00032 #include <App/Document.h>
00033 #include <App/DocumentObject.h>
00034 #include <Gui/Application.h>
00035 #include <Gui/Document.h>
00036 #include <Gui/ViewProvider.h>
00037
00038 using namespace Gui;
00039
00040 namespace Gui {
00041
00042 class XMLMergeReader : public Base::XMLReader
00043 {
00044 public:
00045 XMLMergeReader(const std::map<std::string, std::string>& name, const char* FileName, std::istream& str)
00046 : Base::XMLReader(FileName, str), nameMap(name)
00047 {}
00048
00049 protected:
00050 void startElement(const XMLCh* const uri, const XMLCh* const localname,
00051 const XMLCh* const qname,
00052 const XERCES_CPP_NAMESPACE_QUALIFIER Attributes& attrs)
00053 {
00054 Base::XMLReader::startElement(uri, localname, qname, attrs);
00055 if (LocalName == "Property")
00056 propertyStack.push(std::make_pair(AttrMap["name"],AttrMap["type"]));
00057
00058 if (!propertyStack.empty()) {
00059
00060 if (LocalName == "Link" || (LocalName == "String" && propertyStack.top().first == "Label")) {
00061 for (std::map<std::string, std::string>::iterator it = AttrMap.begin(); it != AttrMap.end(); ++it) {
00062 std::map<std::string, std::string>::const_iterator jt = nameMap.find(it->second);
00063 if (jt != nameMap.end())
00064 it->second = jt->second;
00065 }
00066 }
00067 }
00068 }
00069
00070 void endElement(const XMLCh* const uri, const XMLCh *const localname, const XMLCh *const qname)
00071 {
00072 Base::XMLReader::endElement(uri, localname, qname);
00073 if (LocalName == "Property")
00074 propertyStack.pop();
00075 }
00076
00077 private:
00078 const std::map<std::string, std::string>& nameMap;
00079 typedef std::pair<std::string, std::string> PropertyTag;
00080 std::stack<PropertyTag> propertyStack;
00081 };
00082 }
00083
00084 MergeDocuments::MergeDocuments(App::Document* doc) : appdoc(doc)
00085 {
00086 connectExport = doc->signalExportObjects.connect
00087 (boost::bind(&MergeDocuments::exportObject, this, _1, _2));
00088 connectImport = doc->signalImportObjects.connect
00089 (boost::bind(&MergeDocuments::importObject, this, _1, _2));
00090 document = Gui::Application::Instance->getDocument(doc);
00091 }
00092
00093 MergeDocuments::~MergeDocuments()
00094 {
00095 connectExport.disconnect();
00096 connectImport.disconnect();
00097 }
00098
00099 unsigned int MergeDocuments::getMemSize (void) const
00100 {
00101 return 0;
00102 }
00103
00104 std::vector<App::DocumentObject*>
00105 MergeDocuments::importObjects(std::istream& input)
00106 {
00107
00108 std::vector<App::DocumentObject*> objs;
00109 zipios::ZipInputStream zipstream(input);
00110 XMLMergeReader reader(nameMap,"<memory>", zipstream);
00111
00112 int i,Cnt;
00113 reader.readElement("Document");
00114 long scheme = reader.getAttributeAsInteger("SchemaVersion");
00115 reader.DocumentSchema = scheme;
00116
00117
00118 nameMap.clear();
00119 reader.readElement("Objects");
00120 Cnt = reader.getAttributeAsInteger("Count");
00121 for (i=0 ;i<Cnt ;i++) {
00122 reader.readElement("Object");
00123 std::string type = reader.getAttribute("type");
00124 std::string name = reader.getAttribute("name");
00125 std::string docn = name;
00126
00127
00128 size_t lastpos = docn.length()-1;
00129 while (docn[lastpos] >= 48 && docn[lastpos] <= 57)
00130 lastpos--;
00131 docn = docn.substr(0, lastpos+1);
00132
00133 try {
00134 App::DocumentObject* o = appdoc->addObject(type.c_str(),docn.c_str());
00135 objs.push_back(o);
00136
00137
00138 nameMap[name] = o->getNameInDocument();
00139 }
00140 catch (Base::Exception&) {
00141 Base::Console().Message("Cannot create object '%s'\n", name.c_str());
00142 }
00143 }
00144 reader.readEndElement("Objects");
00145
00146
00147 reader.readElement("ObjectData");
00148 Cnt = reader.getAttributeAsInteger("Count");
00149 for (i=0 ;i<Cnt ;i++) {
00150 reader.readElement("Object");
00151 std::string name = nameMap[reader.getAttribute("name")];
00152 App::DocumentObject* pObj = appdoc->getObject(name.c_str());
00153 if (pObj) {
00154
00155 pObj->Restore(reader);
00156
00157 }
00158 reader.readEndElement("Object");
00159 }
00160 reader.readEndElement("ObjectData");
00161
00162 reader.readEndElement("Document");
00163 appdoc->signalImportObjects(objs, reader);
00164 reader.readFiles(zipstream);
00165
00166 for (std::vector<App::DocumentObject*>::iterator it= objs.begin();it!=objs.end();++it)
00167 (*it)->purgeTouched();
00168 return objs;
00169 }
00170
00171 void MergeDocuments::importObject(const std::vector<App::DocumentObject*>& o, Base::XMLReader & r)
00172 {
00173 objects = o;
00174 for (std::vector<App::DocumentObject*>::iterator it = objects.begin(); it != objects.end(); ++it) {
00175 Gui::ViewProvider* vp = document->getViewProvider(*it);
00176 if (vp) vp->hide();
00177 }
00178 Restore(r);
00179 }
00180
00181 void MergeDocuments::exportObject(const std::vector<App::DocumentObject*>& o, Base::Writer & w)
00182 {
00183 objects = o;
00184 Save(w);
00185 }
00186
00187 void MergeDocuments::Save (Base::Writer & w) const
00188 {
00189 w.addFile("GuiDocument.xml", this);
00190 }
00191
00192 void MergeDocuments::Restore(Base::XMLReader &r)
00193 {
00194 r.addFile("GuiDocument.xml", this);
00195 }
00196
00197 void MergeDocuments::SaveDocFile (Base::Writer & w) const
00198 {
00199 document->exportObjects(objects, w);
00200 }
00201
00202 void MergeDocuments::RestoreDocFile(Base::Reader & reader)
00203 {
00204 std::vector<App::DocumentObject*> obj = objects;
00205
00206 Base::XMLReader xmlReader("GuiDocument.xml", reader);
00207 xmlReader.readElement("Document");
00208 long scheme = xmlReader.getAttributeAsInteger("SchemaVersion");
00209
00210
00211
00212
00213
00214 if (scheme == 1) {
00215
00216 xmlReader.readElement("ViewProviderData");
00217 int Cnt = xmlReader.getAttributeAsInteger("Count");
00218 std::vector<App::DocumentObject*>::const_iterator it = obj.begin();
00219 for (int i=0;i<Cnt&&it!=obj.end();++i,++it) {
00220
00221
00222
00223 xmlReader.readElement("ViewProvider");
00224 std::string name = xmlReader.getAttribute("name");
00225 name = nameMap[name];
00226 Gui::ViewProvider* pObj = document->getViewProviderByName(name.c_str());
00227
00228 if (pObj)
00229 pObj->Restore(xmlReader);
00230 xmlReader.readEndElement("ViewProvider");
00231 if (it == obj.end())
00232 break;
00233 }
00234 xmlReader.readEndElement("ViewProviderData");
00235 }
00236
00237 xmlReader.readEndElement("Document");
00238 }