/**
 * Saves the properties of the view providers.
 */
void Document::SaveDocFile (Base::Writer &writer) const
{
    writer.Stream() << "<?xml version='1.0' encoding='utf-8'?>" << std::endl
                    << "<!--" << std::endl
                    << " FreeCAD Document, see http://free-cad.sourceforge.net for more information..."
                    << std::endl << "-->" << std::endl;

    writer.Stream() << "<Document SchemaVersion=\"1\">" << std::endl;

    std::map<const App::DocumentObject*,ViewProviderDocumentObject*>::const_iterator it;

    // writing the view provider names itself
    writer.incInd(); // indention for 'ViewProviderData Count'
    writer.Stream() << writer.ind() << "<ViewProviderData Count=\"" 
                    << d->_ViewProviderMap.size() <<"\">" << std::endl;

    bool xml = writer.isForceXML();
    //writer.setForceXML(true);
    writer.incInd(); // indention for 'ViewProvider name'
    for(it = d->_ViewProviderMap.begin(); it != d->_ViewProviderMap.end(); ++it) {
        const App::DocumentObject* doc = it->first;
        ViewProvider* obj = it->second;
        writer.Stream() << writer.ind() << "<ViewProvider name=\""
                        << doc->getNameInDocument() << "\" "
                        << "expanded=\"" << (doc->testStatus(App::Expand) ? 1:0)
                        << "\">" << std::endl;
        obj->Save(writer);
        writer.Stream() << writer.ind() << "</ViewProvider>" << std::endl;
    }
    writer.setForceXML(xml);

    writer.decInd(); // indention for 'ViewProvider name'
    writer.Stream() << writer.ind() << "</ViewProviderData>" << std::endl;
    writer.decInd();  // indention for 'ViewProviderData Count'

    // set camera settings
    QString viewPos;
    if (d->_pcAppWnd->sendHasMsgToActiveView("GetCamera")) {
        const char* ppReturn=0;
        d->_pcAppWnd->sendMsgToActiveView("GetCamera",&ppReturn);
  
        // remove the first line because it's a comment like '#Inventor V2.1 ascii'
        QStringList lines = QString(QString::fromAscii(ppReturn)).split(QLatin1String("\n"));
        if (lines.size() > 1) {
            lines.pop_front();
            viewPos = lines.join(QLatin1String(" "));
        }
    }

    writer.incInd(); // indention for camera settings
    writer.Stream() << writer.ind() << "<Camera settings=\"" 
                    << (const char*)viewPos.toAscii() <<"\"/>" << std::endl;
    writer.decInd(); // indention for camera settings
    writer.Stream() << "</Document>" << std::endl;
}
void Document::exportObjects(const std::vector<App::DocumentObject*>& obj, Base::Writer& writer)
{
    writer.Stream() << "<?xml version='1.0' encoding='utf-8'?>" << std::endl;
    writer.Stream() << "<Document SchemaVersion=\"1\">" << std::endl;

    std::map<const App::DocumentObject*,ViewProvider*> views;
    for (std::vector<App::DocumentObject*>::const_iterator it = obj.begin(); it != obj.end(); ++it) {
        Document* doc = Application::Instance->getDocument((*it)->getDocument());
        if (doc) {
            ViewProvider* vp = doc->getViewProvider(*it);
            if (vp) views[*it] = vp;
        }
    }

    // writing the view provider names itself
    writer.incInd(); // indention for 'ViewProviderData Count'
    writer.Stream() << writer.ind() << "<ViewProviderData Count=\"" 
                    << views.size() <<"\">" << std::endl;

    bool xml = writer.isForceXML();
    //writer.setForceXML(true);
    writer.incInd(); // indention for 'ViewProvider name'
    std::map<const App::DocumentObject*,ViewProvider*>::const_iterator jt;
    for (jt = views.begin(); jt != views.end(); ++jt) {
        const App::DocumentObject* doc = jt->first;
        ViewProvider* obj = jt->second;
        writer.Stream() << writer.ind() << "<ViewProvider name=\""
                        << doc->getNameInDocument() << "\" type=\""
                        << obj->getTypeId().getName()
                        << "\">" << std::endl;
        obj->Save(writer);
        writer.Stream() << writer.ind() << "</ViewProvider>" << std::endl;
    }
    writer.setForceXML(xml);

    writer.decInd(); // indention for 'ViewProvider name'
    writer.Stream() << writer.ind() << "</ViewProviderData>" << std::endl;
    writer.decInd();  // indention for 'ViewProviderData Count'
    writer.incInd(); // indention for camera settings
    writer.Stream() << writer.ind() << "<Camera settings=\"\"/>" << std::endl;
    writer.decInd(); // indention for camera settings
    writer.Stream() << "</Document>" << std::endl;
}