void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value) { GOwnPtr<gchar> originalName(JSStringCopyUTF8CString(key)); GOwnPtr<gchar> valueAsString(JSStringCopyUTF8CString(value)); WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); ASSERT(view); // This transformation could be handled by a hash table (and it once was), but // having it prominent, makes it easier for people from other ports to keep the // list up to date. const gchar* propertyName = 0; if (g_str_equal(originalName.get(), "WebKitJavaScriptEnabled")) propertyName = "enable-scripts"; else if (g_str_equal(originalName.get(), "WebKitDefaultFontSize")) propertyName = "default-font-size"; else if (g_str_equal(originalName.get(), "WebKitEnableCaretBrowsing")) propertyName = "enable-caret-browsing"; else if (g_str_equal(originalName.get(), "WebKitUsesPageCachePreferenceKey")) propertyName = "enable-page-cache"; else if (g_str_equal(originalName.get(), "WebKitPluginsEnabled")) propertyName = "enable-plugins"; else if (g_str_equal(originalName.get(), "WebKitHyperlinkAuditingEnabled")) propertyName = "enable-hyperlink-auditing"; else if (g_str_equal(originalName.get(), "WebKitWebGLEnabled")) propertyName = "enable-webgl"; else if (g_str_equal(originalName.get(), "WebKitWebAudioEnabled")) propertyName = "enable-webaudio"; else if (g_str_equal(originalName.get(), "WebKitTabToLinksPreferenceKey")) { DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(!g_ascii_strcasecmp(valueAsString.get(), "true") || !g_ascii_strcasecmp(valueAsString.get(), "1")); return; } else if (g_str_equal(originalName.get(), "WebKitHixie76WebSocketProtocolEnabled")) { DumpRenderTreeSupportGtk::setHixie76WebSocketProtocolEnabled(webkit_web_frame_get_web_view(mainFrame), !g_ascii_strcasecmp(valueAsString.get(), "true") || !g_ascii_strcasecmp(valueAsString.get(), "1")); return; } else { fprintf(stderr, "LayoutTestController::overridePreference tried to override " "unknown preference '%s'.\n", originalName.get()); return; } WebKitWebSettings* settings = webkit_web_view_get_settings(view); GParamSpec* pspec = g_object_class_find_property(G_OBJECT_CLASS( WEBKIT_WEB_SETTINGS_GET_CLASS(settings)), propertyName); GValue currentPropertyValue = { 0, { { 0 } } }; g_value_init(¤tPropertyValue, pspec->value_type); if (G_VALUE_HOLDS_STRING(¤tPropertyValue)) g_object_set(settings, propertyName, valueAsString.get(), NULL); else if (G_VALUE_HOLDS_BOOLEAN(¤tPropertyValue)) g_object_set(G_OBJECT(settings), propertyName, !g_ascii_strcasecmp(valueAsString.get(), "true") || !g_ascii_strcasecmp(valueAsString.get(), "1"), NULL); else if (G_VALUE_HOLDS_INT(¤tPropertyValue)) g_object_set(G_OBJECT(settings), propertyName, atoi(valueAsString.get()), NULL); else if (G_VALUE_HOLDS_FLOAT(¤tPropertyValue)) { gfloat newValue = g_ascii_strtod(valueAsString.get(), 0); g_object_set(G_OBJECT(settings), propertyName, newValue, NULL); } else fprintf(stderr, "LayoutTestController::overridePreference failed to override " "preference '%s'.\n", originalName.get()); }
void Forge::SetBasicDescs(OBJ_DATA & obj, const char * shortDesc, bool addComma) { std::string originalName(obj.name); // Set up the name and long based on the short; strip any quotes or commas from the name std::string name; for (size_t i(0); shortDesc[i] != '\0'; ++i) { switch (shortDesc[i]) { case '"': case ',': break; default: name += shortDesc[i]; break; } } name += " obj_forgeweapon"; std::string longDesc(shortDesc); if (addComma) longDesc += ','; longDesc += " lies here."; longDesc[0] = UPPER(longDesc[0]); // Now actually set the values setName(obj, name.c_str()); copy_string(obj.short_descr, shortDesc); copy_string(obj.description, longDesc.c_str()); // Now seek any extra descs based on the original name for (EXTRA_DESCR_DATA * ed(obj.extra_descr); ed != NULL; ed = ed->next) { if (originalName == ed->keyword) copy_string(ed->keyword, obj.name); } }
CC_FILE_ERROR BinFilter::LoadFileV2(QFile& in, ccHObject& container, int flags) { assert(in.isOpen()); uint32_t binVersion = 20; if (in.read((char*)&binVersion,4) < 0) return CC_FERR_READING; if (binVersion < 20) //should be superior to 2.0! return CC_FERR_MALFORMED_FILE; QString coordsFormat = ( (flags & ccSerializableObject::DF_POINT_COORDS_64_BITS) ? "double" : "float"); QString scalarFormat = ( (flags & ccSerializableObject::DF_SCALAR_VAL_32_BITS) ? "float" : "double"); ccLog::Print(QString("[BIN] Version %1.%2 (coords: %3 / scalar: %4)").arg(binVersion/10).arg(binVersion%10).arg(coordsFormat).arg(scalarFormat)); //we keep track of the last unique ID before load unsigned lastUniqueIDBeforeLoad = ccObject::GetLastUniqueID(); //we read first entity type CC_CLASS_ENUM classID = ccObject::ReadClassIDFromFile(in, static_cast<short>(binVersion)); if (classID == CC_TYPES::OBJECT) return CC_FERR_CONSOLE_ERROR; ccHObject* root = ccHObject::New(classID); if (!root) return CC_FERR_MALFORMED_FILE; if (classID == CC_TYPES::CUSTOM_H_OBJECT) { // store seeking position size_t original_pos = in.pos(); // we need to load it as plain ccCustomHobject root->fromFileNoChildren(in, static_cast<short>(binVersion), flags); // this will load it in.seek(original_pos); // reseek back the file QString classId = root->getMetaData("class_name").toString(); QString pluginId = root->getMetaData("plugin_name").toString(); // try to get a new object from external factories ccHObject* new_child = ccHObject::New(pluginId, classId); if (new_child) // found a plugin that can deserialize it root = new_child; else return CC_FERR_FILE_WAS_WRITTEN_BY_UNKNOWN_PLUGIN; } if (!root->fromFile(in,static_cast<short>(binVersion),flags)) { //DGM: can't delete it, too dangerous (bad pointers ;) //delete root; return CC_FERR_CONSOLE_ERROR; } CC_FILE_ERROR result = CC_FERR_NO_ERROR; //re-link objects (and check errors) bool checkErrors = true; ccHObject* orphans = new ccHObject("Orphans (CORRUPTED FILE)");; ccHObject::Container toCheck; toCheck.push_back(root); while (!toCheck.empty()) { ccHObject* currentObject = toCheck.back(); toCheck.pop_back(); assert(currentObject); //we check objects that have links to other entities (meshes, polylines, etc.) if (currentObject->isKindOf(CC_TYPES::MESH)) { //specific case: mesh groups are deprecated! if (currentObject->isA(CC_TYPES::MESH_GROUP)) { //TODO ccLog::Warning(QString("[BIN] Mesh groups are deprecated! Entity %1 should be ignored...").arg(currentObject->getName())); } else if (currentObject->isA(CC_TYPES::SUB_MESH)) { ccSubMesh* subMesh = ccHObjectCaster::ToSubMesh(currentObject); //normally, the associated mesh should be the sub-mesh's parent! //however we have its ID so we will look for it just to be sure intptr_t meshID = (intptr_t)subMesh->getAssociatedMesh(); if (meshID > 0) { ccHObject* mesh = FindRobust(root,subMesh,static_cast<unsigned>(meshID),CC_TYPES::MESH); if (mesh) { subMesh->setAssociatedMesh(ccHObjectCaster::ToMesh(mesh),false); //'false' because previous mesh is not null (= real mesh ID)!!! } else { //we have a problem here ;) //normally, the associated mesh should be the sub-mesh's parent! if (subMesh->getParent() && subMesh->getParent()->isA(CC_TYPES::MESH)) { subMesh->setAssociatedMesh(ccHObjectCaster::ToMesh(subMesh->getParent()),false); //'false' because previous mesh is not null (= real mesh ID)!!! } else { subMesh->setAssociatedMesh(0,false); //'false' because previous mesh is not null (= real mesh ID)!!! //DGM: can't delete it, too dangerous (bad pointers ;) //delete subMesh; ccLog::Warning(QString("[BIN] Couldn't find associated mesh (ID=%1) for sub-mesh '%2' in the file!").arg(meshID).arg(subMesh->getName())); return CC_FERR_MALFORMED_FILE; } } } } else if (currentObject->isA(CC_TYPES::MESH) || currentObject->isKindOf(CC_TYPES::PRIMITIVE)) //CC_TYPES::MESH or CC_TYPES::PRIMITIVE! { ccMesh* mesh = ccHObjectCaster::ToMesh(currentObject); assert(mesh); //vertices intptr_t cloudID = (intptr_t)mesh->getAssociatedCloud(); if (cloudID > 0) { ccHObject* cloud = FindRobust(root,mesh,static_cast<unsigned>(cloudID),CC_TYPES::POINT_CLOUD); if (cloud) { mesh->setAssociatedCloud(ccHObjectCaster::ToGenericPointCloud(cloud)); } else { //we have a problem here ;) mesh->setAssociatedCloud(0); if (mesh->getMaterialSet()) mesh->setMaterialSet(0,false); //DGM: can't delete it, too dangerous (bad pointers ;) //delete mesh; if (mesh->getParent()) { mesh->getParent()->removeDependencyWith(mesh); mesh->getParent()->removeChild(mesh); } ccLog::Warning(QString("[BIN] Couldn't find vertices (ID=%1) for mesh '%2' in the file!").arg(cloudID).arg(mesh->getName())); mesh = 0; //return CC_FERR_MALFORMED_FILE; } } if (mesh) { //materials ccHObject* materials = 0; intptr_t matSetID = (intptr_t)mesh->getMaterialSet(); if (matSetID > 0) { materials = FindRobust(root,mesh,static_cast<unsigned>(matSetID),CC_TYPES::MATERIAL_SET); if (materials) { mesh->setMaterialSet(static_cast<ccMaterialSet*>(materials),false); } else { //we have a (less severe) problem here ;) mesh->setMaterialSet(0,false); mesh->showMaterials(false); ccLog::Warning(QString("[BIN] Couldn't find shared materials set (ID=%1) for mesh '%2' in the file!").arg(matSetID).arg(mesh->getName())); result = CC_FERR_BROKEN_DEPENDENCY_ERROR; //add it to the 'orphans' set if (materials) orphans->addChild(materials); materials = 0; } } //per-triangle normals ccHObject* triNormsTable = 0; intptr_t triNormsTableID = (intptr_t)mesh->getTriNormsTable(); if (triNormsTableID > 0) { triNormsTable = FindRobust(root,mesh,static_cast<unsigned>(triNormsTableID),CC_TYPES::NORMAL_INDEXES_ARRAY); if (triNormsTable) { mesh->setTriNormsTable(static_cast<NormsIndexesTableType*>(triNormsTable),false); } else { //we have a (less severe) problem here ;) mesh->setTriNormsTable(0,false); mesh->showTriNorms(false); ccLog::Warning(QString("[BIN] Couldn't find shared normals (ID=%1) for mesh '%2' in the file!").arg(triNormsTableID).arg(mesh->getName())); result = CC_FERR_BROKEN_DEPENDENCY_ERROR; //add it to the 'orphans' set if (triNormsTable) orphans->addChild(triNormsTable); triNormsTable = 0; } } //per-triangle texture coordinates ccHObject* texCoordsTable = 0; intptr_t texCoordArrayID = (intptr_t)mesh->getTexCoordinatesTable(); if (texCoordArrayID > 0) { texCoordsTable = FindRobust(root,mesh,static_cast<unsigned>(texCoordArrayID),CC_TYPES::TEX_COORDS_ARRAY); if (texCoordsTable) { mesh->setTexCoordinatesTable(static_cast<TextureCoordsContainer*>(texCoordsTable),false); } else { //we have a (less severe) problem here ;) mesh->setTexCoordinatesTable(0,false); ccLog::Warning(QString("[BIN] Couldn't find shared texture coordinates (ID=%1) for mesh '%2' in the file!").arg(texCoordArrayID).arg(mesh->getName())); result = CC_FERR_BROKEN_DEPENDENCY_ERROR; //add it to the 'orphans' set if (texCoordsTable) orphans->addChild(texCoordsTable); texCoordsTable = 0; } } if (checkErrors) { ccGenericPointCloud* pc = mesh->getAssociatedCloud(); unsigned faceCount = mesh->size(); unsigned vertCount = pc->size(); for (unsigned i=0; i<faceCount; ++i) { const CCLib::VerticesIndexes* tri = mesh->getTriangleVertIndexes(i); if ( tri->i1 >= vertCount || tri->i2 >= vertCount || tri->i3 >= vertCount ) { ccLog::Warning(QString("[BIN] File is corrupted: missing vertices for mesh '%1'!").arg(mesh->getName())); //add cloud to the 'orphans' set pc->setName(mesh->getName() + QString(".") + pc->getName()); orphans->addChild(pc); if (texCoordsTable) { texCoordsTable->setName(mesh->getName() + QString(".") + texCoordsTable->getName()); orphans->addChild(texCoordsTable); } if (triNormsTable) { triNormsTable->setName(mesh->getName() + QString(".") + triNormsTable->getName()); orphans->addChild(triNormsTable); } if (materials) { materials->setName(mesh->getName() + QString(".") + materials->getName()); orphans->addChild(materials); } //delete corrupted mesh mesh->setMaterialSet(0,false); mesh->setTriNormsTable(0,false); mesh->setTexCoordinatesTable(0,false); if (mesh->getParent()) mesh->getParent()->removeChild(mesh); mesh = 0; break; } } } } } } else if (currentObject->isKindOf(CC_TYPES::POLY_LINE)) { ccPolyline* poly = ccHObjectCaster::ToPolyline(currentObject); intptr_t cloudID = (intptr_t)poly->getAssociatedCloud(); ccHObject* cloud = FindRobust(root,poly,static_cast<unsigned>(cloudID),CC_TYPES::POINT_CLOUD); if (cloud) { poly->setAssociatedCloud(ccHObjectCaster::ToGenericPointCloud(cloud)); } else { //we have a problem here ;) poly->setAssociatedCloud(0); //DGM: can't delete it, too dangerous (bad pointers ;) //delete root; ccLog::Warning(QString("[BIN] Couldn't find vertices (ID=%1) for polyline '%2' in the file!").arg(cloudID).arg(poly->getName())); return CC_FERR_MALFORMED_FILE; } } else if (currentObject->isKindOf(CC_TYPES::SENSOR)) { ccSensor* sensor = ccHObjectCaster::ToSensor(currentObject); intptr_t bufferID = (intptr_t)sensor->getPositions(); if (bufferID > 0) { ccHObject* buffer = FindRobust(root,sensor,static_cast<unsigned>(bufferID),CC_TYPES::TRANS_BUFFER); if (buffer) { sensor->setPositions(ccHObjectCaster::ToTransBuffer(buffer)); } else { //we have a problem here ;) sensor->setPositions(0); //DGM: can't delete it, too dangerous (bad pointers ;) //delete root; ccLog::Warning(QString("[BIN] Couldn't find trans. buffer (ID=%1) for sensor '%2' in the file!").arg(bufferID).arg(sensor->getName())); //positions are optional, so we can simply set them to NULL and go ahead, we do not need to return. //return CC_FERR_MALFORMED_FILE; } } } else if (currentObject->isA(CC_TYPES::LABEL_2D)) { cc2DLabel* label = ccHObjectCaster::To2DLabel(currentObject); std::vector<cc2DLabel::PickedPoint> correctedPickedPoints; //we must check all label 'points'! for (unsigned i=0; i<label->size(); ++i) { const cc2DLabel::PickedPoint& pp = label->getPoint(i); intptr_t cloudID = (intptr_t)pp.cloud; ccHObject* cloud = FindRobust(root,label,static_cast<unsigned>(cloudID),CC_TYPES::POINT_CLOUD); if (cloud) { ccGenericPointCloud* genCloud = ccHObjectCaster::ToGenericPointCloud(cloud); assert(genCloud->size()>pp.index); correctedPickedPoints.push_back(cc2DLabel::PickedPoint(genCloud,pp.index)); } else { //we have a problem here ;) ccLog::Warning(QString("[BIN] Couldn't find cloud (ID=%1) associated to label '%2' in the file!").arg(cloudID).arg(label->getName())); if (label->getParent()) label->getParent()->removeChild(label); //DGM: can't delete it, too dangerous (bad pointers ;) //delete label; label = 0; break; } } if (label) //correct label data { assert(correctedPickedPoints.size() == label->size()); bool visible = label->isVisible(); QString originalName(label->getRawName()); label->clear(true); for (unsigned i=0; i<correctedPickedPoints.size(); ++i) label->addPoint(correctedPickedPoints[i].cloud,correctedPickedPoints[i].index); label->setVisible(visible); label->setName(originalName); } } else if (currentObject->isA(CC_TYPES::FACET)) { ccFacet* facet = ccHObjectCaster::ToFacet(currentObject); //origin points { intptr_t cloudID = (intptr_t)facet->getOriginPoints(); if (cloudID > 0) { ccHObject* cloud = FindRobust(root,facet,static_cast<unsigned>(cloudID),CC_TYPES::POINT_CLOUD); if (cloud && cloud->isA(CC_TYPES::POINT_CLOUD)) { facet->setOriginPoints(ccHObjectCaster::ToPointCloud(cloud)); } else { //we have a problem here ;) facet->setOriginPoints(0); ccLog::Warning(QString("[BIN] Couldn't find origin points (ID=%1) for facet '%2' in the file!").arg(cloudID).arg(facet->getName())); } } } //contour points { intptr_t cloudID = (intptr_t)facet->getContourVertices(); if (cloudID > 0) { ccHObject* cloud = FindRobust(root,facet,static_cast<unsigned>(cloudID),CC_TYPES::POINT_CLOUD); if (cloud) { facet->setContourVertices(ccHObjectCaster::ToPointCloud(cloud)); } else { //we have a problem here ;) facet->setContourVertices(0); ccLog::Warning(QString("[BIN] Couldn't find contour points (ID=%1) for facet '%2' in the file!").arg(cloudID).arg(facet->getName())); } } } //contour polyline { intptr_t polyID = (intptr_t)facet->getContour(); if (polyID > 0) { ccHObject* poly = FindRobust(root,facet,static_cast<unsigned>(polyID),CC_TYPES::POLY_LINE); if (poly) { facet->setContour(ccHObjectCaster::ToPolyline(poly)); } else { //we have a problem here ;) facet->setContourVertices(0); ccLog::Warning(QString("[BIN] Couldn't find contour polyline (ID=%1) for facet '%2' in the file!").arg(polyID).arg(facet->getName())); } } } //polygon mesh { intptr_t polyID = (intptr_t)facet->getPolygon(); if (polyID > 0) { ccHObject* poly = FindRobust(root,facet,static_cast<unsigned>(polyID),CC_TYPES::MESH); if (poly) { facet->setPolygon(ccHObjectCaster::ToMesh(poly)); } else { //we have a problem here ;) facet->setPolygon(0); ccLog::Warning(QString("[BIN] Couldn't find polygon mesh (ID=%1) for facet '%2' in the file!").arg(polyID).arg(facet->getName())); } } } } else if (currentObject->isKindOf(CC_TYPES::IMAGE)) { ccImage* image = ccHObjectCaster::ToImage(currentObject); intptr_t sensorID = (intptr_t)image->getAssociatedSensor(); if (sensorID > 0) { ccHObject* sensor = FindRobust(root,image,static_cast<unsigned>(sensorID),CC_TYPES::CAMERA_SENSOR); if (sensor) { image->setAssociatedSensor(ccHObjectCaster::ToCameraSensor(sensor)); } else { //we have a problem here ;) image->setAssociatedSensor(0); //DGM: can't delete it, too dangerous (bad pointers ;) //delete root; ccLog::Warning(QString("[BIN] Couldn't find camera sensor (ID=%1) for image '%2' in the file!").arg(sensorID).arg(image->getName())); //return CC_FERR_MALFORMED_FILE; } } } if (currentObject) for (unsigned i=0; i<currentObject->getChildrenNumber() ;++i) toCheck.push_back(currentObject->getChild(i)); } //check for unique IDs duplicate (yes it happens :-( ) { std::unordered_set<unsigned> uniqueIDs; unsigned maxUniqueID = root->findMaxUniqueID_recursive(); assert(toCheck.empty()); toCheck.push_back(root); while (!toCheck.empty()) { ccHObject* currentObject = toCheck.back(); toCheck.pop_back(); assert(currentObject); //check that the ID is not already used (strangely it happens!) unsigned uniqueID = currentObject->getUniqueID(); if (uniqueIDs.find(uniqueID) != uniqueIDs.end()) { ccLog::Warning(QString("[BIN] Duplicate 'unique ID' found! (ID = %1)").arg(uniqueID)); currentObject->setUniqueID(++maxUniqueID); } else { uniqueIDs.insert(uniqueID); } for (unsigned i=0; i<currentObject->getChildrenNumber() ;++i) { toCheck.push_back(currentObject->getChild(i)); } } } //update 'unique IDs' toCheck.push_back(root); while (!toCheck.empty()) { ccHObject* currentObject = toCheck.back(); toCheck.pop_back(); currentObject->setUniqueID(lastUniqueIDBeforeLoad+currentObject->getUniqueID()); for (unsigned i=0; i<currentObject->getChildrenNumber(); ++i) toCheck.push_back(currentObject->getChild(i)); } if (root->isA(CC_TYPES::HIERARCHY_OBJECT)) { //transfer children to container root->transferChildren(container,true); delete root; root = 0; } else { container.addChild(root); } //orphans if (orphans) { if (orphans->getChildrenNumber() != 0) { orphans->setEnabled(false); container.addChild(orphans); } else { delete orphans; orphans = 0; } } return result; }
CC_FILE_ERROR BinFilter::loadFileV2(QFile& in, ccHObject& container) { assert(in.isOpen()); uint32_t binVersion = 20; if (in.read((char*)&binVersion,4)<0) return CC_FERR_READING; if (binVersion<20) //should be superior to 2.0! return CC_FERR_MALFORMED_FILE; ccLog::Print(QString("[BIN] Version %1.%2").arg(binVersion/10).arg(binVersion%10)); ccProgressDialog pdlg(true); pdlg.setMethodTitle(qPrintable(QString("Open Bin file (V%1.%2)").arg(binVersion/10).arg(binVersion%10))); //we keep track of the last unique ID before load unsigned lastUniqueIDBeforeLoad = ccObject::GetLastUniqueID(); //we read first entity type unsigned classID=0; if (!ccObject::ReadClassIDFromFile(classID, in, binVersion)) return CC_FERR_CONSOLE_ERROR; ccHObject* root = ccHObject::New(classID); if (!root) return CC_FERR_MALFORMED_FILE; if (!root->fromFile(in,binVersion)) { //DGM: can't delete it, too dangerous (bad pointers ;) //delete root; return CC_FERR_CONSOLE_ERROR; } CC_FILE_ERROR result = CC_FERR_NO_ERROR; //re-link objects ccHObject::Container toCheck; toCheck.push_back(root); while (!toCheck.empty()) { ccHObject* currentObject = toCheck.back(); toCheck.pop_back(); assert(currentObject); //we check objects that have links to other entities (meshes, polylines, etc.) if (currentObject->isKindOf(CC_MESH)) { ccGenericMesh* mesh = static_cast<ccGenericMesh*>(currentObject); //vertices //special case: if the parent is a mesh group, then the job has already be done once and for all! if (!mesh->getParent() || !mesh->getParent()->isA(CC_MESH_GROUP)) { intptr_t cloudID = (intptr_t)mesh->getAssociatedCloud(); if (cloudID>0) { ccHObject* cloud = root->find(cloudID); if (cloud && cloud->isKindOf(CC_POINT_CLOUD)) mesh->setAssociatedCloud(static_cast<ccGenericPointCloud*>(cloud)); else { //we have a problem here ;) mesh->setAssociatedCloud(0); if (mesh->getMaterialSet()) mesh->setMaterialSet(0,false); //DGM: can't delete it, too dangerous (bad pointers ;) //delete root; ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find vertices (ID=%1) for mesh '%2' in the file!").arg(cloudID).arg(mesh->getName())); return CC_FERR_MALFORMED_FILE; } } } //materials intptr_t matSetID = (intptr_t)mesh->getMaterialSet(); if (matSetID>0) { ccHObject* materials = root->find(matSetID); if (materials && materials->isA(CC_MATERIAL_SET)) mesh->setMaterialSet(static_cast<ccMaterialSet*>(materials),false); else { //we have a (less severe) problem here ;) mesh->setMaterialSet(0,false); mesh->showMaterials(false); ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find shared materials set (ID=%1) for mesh '%2' in the file!").arg(matSetID).arg(mesh->getName())); result = CC_FERR_BROKEN_DEPENDENCY_ERROR; } } //per-triangle normals intptr_t triNormsTableID = (intptr_t)mesh->getTriNormsTable(); if (triNormsTableID>0) { ccHObject* triNormsTable = root->find(triNormsTableID); if (triNormsTable && triNormsTable->isA(CC_NORMAL_INDEXES_ARRAY)) mesh->setTriNormsTable(static_cast<NormsIndexesTableType*>(triNormsTable),false); else { //we have a (less severe) problem here ;) mesh->setTriNormsTable(0,false); mesh->showTriNorms(false); ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find shared normals (ID=%1) for mesh '%2' in the file!").arg(matSetID).arg(mesh->getName())); result = CC_FERR_BROKEN_DEPENDENCY_ERROR; } } //per-triangle texture coordinates intptr_t texCoordArrayID = (intptr_t)mesh->getTexCoordinatesTable(); if (texCoordArrayID>0) { ccHObject* texCoordsTable = root->find(texCoordArrayID); if (texCoordsTable && texCoordsTable->isA(CC_TEX_COORDS_ARRAY)) mesh->setTexCoordinatesTable(static_cast<TextureCoordsContainer*>(texCoordsTable),false); else { //we have a (less severe) problem here ;) mesh->setTexCoordinatesTable(0,false); ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find shared texture coordinates (ID=%1) for mesh '%2' in the file!").arg(matSetID).arg(mesh->getName())); result = CC_FERR_BROKEN_DEPENDENCY_ERROR; } } } else if (currentObject->isKindOf(CC_POLY_LINE)) { ccPolyline* poly = static_cast<ccPolyline*>(currentObject); intptr_t cloudID = (intptr_t)poly->getAssociatedCloud(); ccHObject* cloud = root->find(cloudID); if (cloud && cloud->isKindOf(CC_POINT_CLOUD)) poly->setAssociatedCloud(static_cast<ccGenericPointCloud*>(cloud)); else { //we have a problem here ;) poly->setAssociatedCloud(0); //DGM: can't delete it, too dangerous (bad pointers ;) //delete root; ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find vertices (ID=%1) for polyline '%2' in the file!").arg(cloudID).arg(poly->getName())); return CC_FERR_MALFORMED_FILE; } } else if (currentObject->isA(CC_2D_LABEL)) { cc2DLabel* label = static_cast<cc2DLabel*>(currentObject); std::vector<cc2DLabel::PickedPoint> correctedPickedPoints; //we must check all label 'points'! for (unsigned i=0;i<label->size();++i) { const cc2DLabel::PickedPoint& pp = label->getPoint(i); intptr_t cloudID = (intptr_t)pp.cloud; ccHObject* cloud = root->find(cloudID); if (cloud && cloud->isKindOf(CC_POINT_CLOUD)) { ccGenericPointCloud* genCloud = static_cast<ccGenericPointCloud*>(cloud); assert(genCloud->size()>pp.index); correctedPickedPoints.push_back(cc2DLabel::PickedPoint(genCloud,pp.index)); } else { //we have a problem here ;) ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find cloud (ID=%1) associated to label '%2' in the file!").arg(cloudID).arg(label->getName())); if (label->getParent()) label->getParent()->removeChild(label); if (!label->getFlagState(CC_FATHER_DEPENDANT)) { //DGM: can't delete it, too dangerous (bad pointers ;) //delete label; } label=0; break; } } if (label) //correct label data { assert(correctedPickedPoints.size() == label->size()); bool visible = label->isVisible(); QString originalName(label->getRawName()); label->clear(); for (unsigned i=0;i<correctedPickedPoints.size();++i) label->addPoint(correctedPickedPoints[i].cloud,correctedPickedPoints[i].index); label->setVisible(visible); label->setName(originalName); } } for (unsigned i=0;i<currentObject->getChildrenNumber();++i) toCheck.push_back(currentObject->getChild(i)); } //update 'unique IDs' toCheck.push_back(root); while (!toCheck.empty()) { ccHObject* currentObject = toCheck.back(); toCheck.pop_back(); currentObject->setUniqueID(lastUniqueIDBeforeLoad+currentObject->getUniqueID()); for (unsigned i=0;i<currentObject->getChildrenNumber();++i) toCheck.push_back(currentObject->getChild(i)); } if (root->isA(CC_HIERARCHY_OBJECT)) { //transfer children to container root->transferChildren(container,true); } else { container.addChild(root); } return result; }
std::string NamedAndIndexed::internalName() const { std::stringstream ss; ss << originalName() << "_" << index(); return ss.str(); }
bool QgsMapLayer::writeLayerXML( QDomElement& layerElement, QDomDocument& document ) { // use scale dependent visibility flag layerElement.setAttribute( "hasScaleBasedVisibilityFlag", hasScaleBasedVisibility() ? 1 : 0 ); layerElement.setAttribute( "minimumScale", QString::number( minimumScale() ) ); layerElement.setAttribute( "maximumScale", QString::number( maximumScale() ) ); // ID QDomElement layerId = document.createElement( "id" ); QDomText layerIdText = document.createTextNode( id() ); layerId.appendChild( layerIdText ); layerElement.appendChild( layerId ); // data source QDomElement dataSource = document.createElement( "datasource" ); QString src = source(); QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( this ); // TODO: what about postgres, mysql and others, they should not go through writePath() if ( vlayer && vlayer->providerType() == "spatialite" ) { QgsDataSourceURI uri( src ); QString database = QgsProject::instance()->writePath( uri.database() ); uri.setConnection( uri.host(), uri.port(), database, uri.username(), uri.password() ); src = uri.uri(); } else if ( vlayer && vlayer->providerType() == "ogr" ) { QStringList theURIParts = src.split( "|" ); theURIParts[0] = QgsProject::instance()->writePath( theURIParts[0] ); src = theURIParts.join( "|" ); } else if ( vlayer && vlayer->providerType() == "delimitedtext" ) { QUrl urlSource = QUrl::fromEncoded( src.toAscii() ); QUrl urlDest = QUrl::fromLocalFile( QgsProject::instance()->writePath( urlSource.toLocalFile() ) ); urlDest.setQueryItems( urlSource.queryItems() ); src = QString::fromAscii( urlDest.toEncoded() ); } else { src = QgsProject::instance()->writePath( src ); } QDomText dataSourceText = document.createTextNode( src ); dataSource.appendChild( dataSourceText ); layerElement.appendChild( dataSource ); // layer name QDomElement layerName = document.createElement( "layername" ); QDomText layerNameText = document.createTextNode( originalName() ); layerName.appendChild( layerNameText ); // layer title QDomElement layerTitle = document.createElement( "title" ) ; QDomText layerTitleText = document.createTextNode( title() ); layerTitle.appendChild( layerTitleText ); // layer abstract QDomElement layerAbstract = document.createElement( "abstract" ); QDomText layerAbstractText = document.createTextNode( abstract() ); layerAbstract.appendChild( layerAbstractText ); layerElement.appendChild( layerName ); layerElement.appendChild( layerTitle ); layerElement.appendChild( layerAbstract ); // layer keyword list QStringList keywordStringList = keywordList().split( "," ); if ( keywordStringList.size() > 0 ) { QDomElement layerKeywordList = document.createElement( "keywordList" ); for ( int i = 0; i < keywordStringList.size(); ++i ) { QDomElement layerKeywordValue = document.createElement( "value" ); QDomText layerKeywordText = document.createTextNode( keywordStringList.at( i ).trimmed() ); layerKeywordValue.appendChild( layerKeywordText ); layerKeywordList.appendChild( layerKeywordValue ); } layerElement.appendChild( layerKeywordList ); } // layer metadataUrl QString aDataUrl = dataUrl(); if ( !aDataUrl.isEmpty() ) { QDomElement layerDataUrl = document.createElement( "dataUrl" ) ; QDomText layerDataUrlText = document.createTextNode( aDataUrl ); layerDataUrl.appendChild( layerDataUrlText ); layerDataUrl.setAttribute( "format", dataUrlFormat() ); layerElement.appendChild( layerDataUrl ); } // layer attribution QString aAttribution = attribution(); if ( !aAttribution.isEmpty() ) { QDomElement layerAttribution = document.createElement( "attribution" ) ; QDomText layerAttributionText = document.createTextNode( aAttribution ); layerAttribution.appendChild( layerAttributionText ); layerAttribution.setAttribute( "href", attributionUrl() ); layerElement.appendChild( layerAttribution ); } // layer metadataUrl QString aMetadataUrl = metadataUrl(); if ( !aMetadataUrl.isEmpty() ) { QDomElement layerMetadataUrl = document.createElement( "metadataUrl" ) ; QDomText layerMetadataUrlText = document.createTextNode( aMetadataUrl ); layerMetadataUrl.appendChild( layerMetadataUrlText ); layerMetadataUrl.setAttribute( "type", metadataUrlType() ); layerMetadataUrl.setAttribute( "format", metadataUrlFormat() ); layerElement.appendChild( layerMetadataUrl ); } // timestamp if supported if ( timestamp() > QDateTime() ) { QDomElement stamp = document.createElement( "timestamp" ); QDomText stampText = document.createTextNode( timestamp().toString( Qt::ISODate ) ); stamp.appendChild( stampText ); layerElement.appendChild( stamp ); } layerElement.appendChild( layerName ); // zorder // This is no longer stored in the project file. It is superfluous since the layers // are written and read in the proper order. // spatial reference system id QDomElement mySrsElement = document.createElement( "srs" ); mCRS->writeXML( mySrsElement, document ); layerElement.appendChild( mySrsElement ); #if 0 // <transparencyLevelInt> QDomElement transparencyLevelIntElement = document.createElement( "transparencyLevelInt" ); QDomText transparencyLevelIntText = document.createTextNode( QString::number( getTransparency() ) ); transparencyLevelIntElement.appendChild( transparencyLevelIntText ); maplayer.appendChild( transparencyLevelIntElement ); #endif // now append layer node to map layer node writeCustomProperties( layerElement, document ); return writeXml( layerElement, document ); } // bool QgsMapLayer::writeXML
CC_FILE_ERROR BinFilter::LoadFileV2(QFile& in, ccHObject& container, int flags) { assert(in.isOpen()); uint32_t binVersion = 20; if (in.read((char*)&binVersion,4) < 0) return CC_FERR_READING; if (binVersion < 20) //should be superior to 2.0! return CC_FERR_MALFORMED_FILE; QString coordsFormat = (flags & ccSerializableObject::DF_POINT_COORDS_64_BITS ? "double" : "float"); QString scalarFormat = (flags & ccSerializableObject::DF_SCALAR_VAL_32_BITS ? "float" : "double"); ccLog::Print(QString("[BIN] Version %1.%2 (coords: %3 / scalar: %4)").arg(binVersion/10).arg(binVersion%10).arg(coordsFormat).arg(scalarFormat)); //we keep track of the last unique ID before load unsigned lastUniqueIDBeforeLoad = ccObject::GetLastUniqueID(); //we read first entity type unsigned classID = 0; if (!ccObject::ReadClassIDFromFile(classID, in, static_cast<short>(binVersion))) return CC_FERR_CONSOLE_ERROR; ccHObject* root = ccHObject::New(classID); if (!root) return CC_FERR_MALFORMED_FILE; if (!root->fromFile(in,static_cast<short>(binVersion),flags)) { //DGM: can't delete it, too dangerous (bad pointers ;) //delete root; return CC_FERR_CONSOLE_ERROR; } CC_FILE_ERROR result = CC_FERR_NO_ERROR; //re-link objects (and check errors) bool checkErrors = true; ccHObject* orphans = new ccHObject("Orphans (CORRUPTED FILE)");; ccHObject::Container toCheck; toCheck.push_back(root); while (!toCheck.empty()) { ccHObject* currentObject = toCheck.back(); toCheck.pop_back(); assert(currentObject); //we check objects that have links to other entities (meshes, polylines, etc.) if (currentObject->isKindOf(CC_MESH)) { //specific case: mesh groups are deprecated! if (currentObject->isA(CC_MESH_GROUP)) { //TODO ccLog::Warning(QString("Mesh groups are deprecated! Entity %1 should be ignored...").arg(currentObject->getName())); } else if (currentObject->isA(CC_SUB_MESH)) { ccSubMesh* subMesh = ccHObjectCaster::ToSubMesh(currentObject); //normally, the associated mesh should be the sub-mesh's parent! //however we have its ID so we will look for it just to be sure intptr_t meshID = (intptr_t)subMesh->getAssociatedMesh(); if (meshID > 0) { ccHObject* mesh = root->find(static_cast<int>(meshID)); if (mesh && mesh->isA(CC_MESH)) { subMesh->setAssociatedMesh(ccHObjectCaster::ToMesh(mesh)); } else { //we have a problem here ;) //normally, the associated mesh should be the sub-mesh's parent! if (subMesh->getParent() && subMesh->getParent()->isA(CC_MESH)) { subMesh->setAssociatedMesh(ccHObjectCaster::ToMesh(subMesh->getParent())); } else { subMesh->setAssociatedMesh(0); //DGM: can't delete it, too dangerous (bad pointers ;) //delete subMesh; ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find associated mesh (ID=%1) for sub-mesh '%2' in the file!").arg(meshID).arg(subMesh->getName())); return CC_FERR_MALFORMED_FILE; } } } } else if (currentObject->isA(CC_MESH) || currentObject->isKindOf(CC_PRIMITIVE)) //CC_MESH or CC_PRIMITIVE! { ccMesh* mesh = ccHObjectCaster::ToMesh(currentObject); assert(mesh); //vertices intptr_t cloudID = (intptr_t)mesh->getAssociatedCloud(); if (cloudID > 0) { ccHObject* cloud = root->find(static_cast<int>(cloudID)); if (cloud && cloud->isKindOf(CC_POINT_CLOUD)) { mesh->setAssociatedCloud(ccHObjectCaster::ToGenericPointCloud(cloud)); } else { //we have a problem here ;) mesh->setAssociatedCloud(0); if (mesh->getMaterialSet()) mesh->setMaterialSet(0,false); //DGM: can't delete it, too dangerous (bad pointers ;) //delete mesh; ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find vertices (ID=%1) for mesh '%2' in the file!").arg(cloudID).arg(mesh->getName())); return CC_FERR_MALFORMED_FILE; } } //materials ccHObject* materials = 0; intptr_t matSetID = (intptr_t)mesh->getMaterialSet(); if (matSetID > 0) { materials = root->find(static_cast<int>(matSetID)); if (materials && materials->isA(CC_MATERIAL_SET)) mesh->setMaterialSet(static_cast<ccMaterialSet*>(materials),false); else { //we have a (less severe) problem here ;) mesh->setMaterialSet(0,false); mesh->showMaterials(false); ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find shared materials set (ID=%1) for mesh '%2' in the file!").arg(matSetID).arg(mesh->getName())); result = CC_FERR_BROKEN_DEPENDENCY_ERROR; //add it to the 'orphans' set if (materials) orphans->addChild(materials); materials = 0; } } //per-triangle normals ccHObject* triNormsTable = 0; intptr_t triNormsTableID = (intptr_t)mesh->getTriNormsTable(); if (triNormsTableID > 0) { triNormsTable = root->find(static_cast<int>(triNormsTableID)); if (triNormsTable && triNormsTable->isA(CC_NORMAL_INDEXES_ARRAY)) { mesh->setTriNormsTable(static_cast<NormsIndexesTableType*>(triNormsTable),false); } else { //we have a (less severe) problem here ;) mesh->setTriNormsTable(0,false); mesh->showTriNorms(false); ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find shared normals (ID=%1) for mesh '%2' in the file!").arg(triNormsTableID).arg(mesh->getName())); result = CC_FERR_BROKEN_DEPENDENCY_ERROR; //add it to the 'orphans' set if (triNormsTable) orphans->addChild(triNormsTable); triNormsTable = 0; } } //per-triangle texture coordinates ccHObject* texCoordsTable = 0; intptr_t texCoordArrayID = (intptr_t)mesh->getTexCoordinatesTable(); if (texCoordArrayID > 0) { texCoordsTable = root->find(static_cast<int>(texCoordArrayID)); if (texCoordsTable && texCoordsTable->isA(CC_TEX_COORDS_ARRAY)) mesh->setTexCoordinatesTable(static_cast<TextureCoordsContainer*>(texCoordsTable),false); else { //we have a (less severe) problem here ;) mesh->setTexCoordinatesTable(0,false); ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find shared texture coordinates (ID=%1) for mesh '%2' in the file!").arg(texCoordArrayID).arg(mesh->getName())); result = CC_FERR_BROKEN_DEPENDENCY_ERROR; //add it to the 'orphans' set if (texCoordsTable) orphans->addChild(texCoordsTable); texCoordsTable = 0; } } if (checkErrors) { ccGenericPointCloud* pc = mesh->getAssociatedCloud(); unsigned faceCount = mesh->size(); unsigned vertCount = pc->size(); for (unsigned i=0; i<faceCount; ++i) { const CCLib::TriangleSummitsIndexes* tri = mesh->getTriangleIndexes(i); if ( tri->i1 >= vertCount || tri->i2 >= vertCount || tri->i3 >= vertCount ) { ccLog::Warning(QString("[BinFilter::loadFileV2] File is corrupted: missing vertices for mesh '%1'!").arg(mesh->getName())); //add cloud to the 'orphans' set pc->setName(mesh->getName() + QString(".") + pc->getName()); orphans->addChild(pc); if (texCoordsTable) { texCoordsTable->setName(mesh->getName() + QString(".") + texCoordsTable->getName()); orphans->addChild(texCoordsTable); } if (triNormsTable) { triNormsTable->setName(mesh->getName() + QString(".") + triNormsTable->getName()); orphans->addChild(triNormsTable); } if (materials) { materials->setName(mesh->getName() + QString(".") + materials->getName()); orphans->addChild(materials); } //delete corrupted mesh mesh->setMaterialSet(0,false); mesh->setTriNormsTable(0,false); mesh->setTexCoordinatesTable(0,false); if (mesh->getParent()) mesh->getParent()->removeChild(mesh); mesh = 0; break; } } } } } else if (currentObject->isKindOf(CC_POLY_LINE)) { ccPolyline* poly = static_cast<ccPolyline*>(currentObject); intptr_t cloudID = (intptr_t)poly->getAssociatedCloud(); ccHObject* cloud = root->find(static_cast<int>(cloudID)); if (cloud && cloud->isKindOf(CC_POINT_CLOUD)) poly->setAssociatedCloud(ccHObjectCaster::ToGenericPointCloud(cloud)); else { //we have a problem here ;) poly->setAssociatedCloud(0); //DGM: can't delete it, too dangerous (bad pointers ;) //delete root; ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find vertices (ID=%1) for polyline '%2' in the file!").arg(cloudID).arg(poly->getName())); return CC_FERR_MALFORMED_FILE; } } else if (currentObject->isA(CC_2D_LABEL)) { cc2DLabel* label = static_cast<cc2DLabel*>(currentObject); std::vector<cc2DLabel::PickedPoint> correctedPickedPoints; //we must check all label 'points'! for (unsigned i=0;i<label->size();++i) { const cc2DLabel::PickedPoint& pp = label->getPoint(i); intptr_t cloudID = (intptr_t)pp.cloud; ccHObject* cloud = root->find(static_cast<int>(cloudID)); if (cloud && cloud->isKindOf(CC_POINT_CLOUD)) { ccGenericPointCloud* genCloud = ccHObjectCaster::ToGenericPointCloud(cloud); assert(genCloud->size()>pp.index); correctedPickedPoints.push_back(cc2DLabel::PickedPoint(genCloud,pp.index)); } else { //we have a problem here ;) ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find cloud (ID=%1) associated to label '%2' in the file!").arg(cloudID).arg(label->getName())); if (label->getParent()) label->getParent()->removeChild(label); if (!label->getFlagState(CC_FATHER_DEPENDENT)) { //DGM: can't delete it, too dangerous (bad pointers ;) //delete label; } label=0; break; } } if (label) //correct label data { assert(correctedPickedPoints.size() == label->size()); bool visible = label->isVisible(); QString originalName(label->getRawName()); label->clear(); for (unsigned i=0;i<correctedPickedPoints.size();++i) label->addPoint(correctedPickedPoints[i].cloud,correctedPickedPoints[i].index); label->setVisible(visible); label->setName(originalName); } } else if (currentObject->isA(CC_FACET)) { ccFacet* facet = ccHObjectCaster::ToFacet(currentObject); //origin points { intptr_t cloudID = (intptr_t)facet->getOriginPoints(); if (cloudID > 0) { ccHObject* cloud = root->find(static_cast<int>(cloudID)); if (cloud && cloud->isA(CC_POINT_CLOUD)) facet->setOriginPoints(ccHObjectCaster::ToPointCloud(cloud)); else { //we have a problem here ;) facet->setOriginPoints(0); ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find origin points (ID=%1) for facet '%2' in the file!").arg(cloudID).arg(facet->getName())); } } } //contour points { intptr_t cloudID = (intptr_t)facet->getContourVertices(); if (cloudID > 0) { ccHObject* cloud = root->find(static_cast<int>(cloudID)); if (cloud && cloud->isA(CC_POINT_CLOUD)) facet->setContourVertices(ccHObjectCaster::ToPointCloud(cloud)); else { //we have a problem here ;) facet->setContourVertices(0); ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find contour points (ID=%1) for facet '%2' in the file!").arg(cloudID).arg(facet->getName())); } } } //contour polyline { intptr_t polyID = (intptr_t)facet->getContour(); if (polyID > 0) { ccHObject* poly = root->find(static_cast<int>(polyID)); if (poly && poly->isA(CC_POLY_LINE)) facet->setContour(ccHObjectCaster::ToPolyline(poly)); else { //we have a problem here ;) facet->setContourVertices(0); ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find contour polyline (ID=%1) for facet '%2' in the file!").arg(polyID).arg(facet->getName())); } } } //polygon mesh { intptr_t polyID = (intptr_t)facet->getPolygon(); if (polyID > 0) { ccHObject* poly = root->find(static_cast<int>(polyID)); if (poly && poly->isA(CC_MESH)) { facet->setPolygon(ccHObjectCaster::ToMesh(poly)); } else { //we have a problem here ;) facet->setContourVertices(0); ccLog::Warning(QString("[BinFilter::loadFileV2] Couldn't find polygon mesh (ID=%1) for facet '%2' in the file!").arg(polyID).arg(facet->getName())); } } } } if (currentObject) for (unsigned i=0;i<currentObject->getChildrenNumber();++i) toCheck.push_back(currentObject->getChild(i)); } //update 'unique IDs' toCheck.push_back(root); while (!toCheck.empty()) { ccHObject* currentObject = toCheck.back(); toCheck.pop_back(); currentObject->setUniqueID(lastUniqueIDBeforeLoad+currentObject->getUniqueID()); for (unsigned i=0;i<currentObject->getChildrenNumber();++i) toCheck.push_back(currentObject->getChild(i)); } if (root->isA(CC_HIERARCHY_OBJECT)) { //transfer children to container root->transferChildren(container,true); } else { container.addChild(root); } //orphans if (orphans) { if (orphans->getChildrenNumber() != 0) { orphans->setEnabled(false); container.addChild(orphans); } else { delete orphans; orphans = 0; } } return result; }
bool QgsMapLayer::writeLayerXML( QDomElement& layerElement, QDomDocument& document, const QString& relativeBasePath ) { // use scale dependent visibility flag layerElement.setAttribute( "hasScaleBasedVisibilityFlag", hasScaleBasedVisibility() ? 1 : 0 ); layerElement.setAttribute( "minimumScale", QString::number( minimumScale() ) ); layerElement.setAttribute( "maximumScale", QString::number( maximumScale() ) ); // ID QDomElement layerId = document.createElement( "id" ); QDomText layerIdText = document.createTextNode( id() ); layerId.appendChild( layerIdText ); layerElement.appendChild( layerId ); // data source QDomElement dataSource = document.createElement( "datasource" ); QString src = source(); QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( this ); // TODO: what about postgres, mysql and others, they should not go through writePath() if ( vlayer && vlayer->providerType() == "spatialite" ) { QgsDataSourceURI uri( src ); QString database = QgsProject::instance()->writePath( uri.database(), relativeBasePath ); uri.setConnection( uri.host(), uri.port(), database, uri.username(), uri.password() ); src = uri.uri(); } else if ( vlayer && vlayer->providerType() == "ogr" ) { QStringList theURIParts = src.split( "|" ); theURIParts[0] = QgsProject::instance()->writePath( theURIParts[0], relativeBasePath ); src = theURIParts.join( "|" ); } else if ( vlayer && vlayer->providerType() == "gpx" ) { QStringList theURIParts = src.split( "?" ); theURIParts[0] = QgsProject::instance()->writePath( theURIParts[0], relativeBasePath ); src = theURIParts.join( "?" ); } else if ( vlayer && vlayer->providerType() == "delimitedtext" ) { QUrl urlSource = QUrl::fromEncoded( src.toAscii() ); QUrl urlDest = QUrl::fromLocalFile( QgsProject::instance()->writePath( urlSource.toLocalFile(), relativeBasePath ) ); urlDest.setQueryItems( urlSource.queryItems() ); src = QString::fromAscii( urlDest.toEncoded() ); } else { bool handled = false; if ( !vlayer ) { QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>( this ); // Update path for subdataset if ( rlayer && rlayer->providerType() == "gdal" ) { if ( src.startsWith( "NETCDF:" ) ) { // NETCDF:filename:variable // filename can be quoted with " as it can contain colons QRegExp r( "NETCDF:(.+):([^:]+)" ); if ( r.exactMatch( src ) ) { QString filename = r.cap( 1 ); if ( filename.startsWith( '"' ) && filename.endsWith( '"' ) ) filename = filename.mid( 1, filename.length() - 2 ); src = "NETCDF:\"" + QgsProject::instance()->writePath( filename, relativeBasePath ) + "\":" + r.cap( 2 ); handled = true; } } else if ( src.startsWith( "HDF4_SDS:" ) ) { // HDF4_SDS:subdataset_type:file_name:subdataset_index // filename can be quoted with " as it can contain colons QRegExp r( "HDF4_SDS:([^:]+):(.+):([^:]+)" ); if ( r.exactMatch( src ) ) { QString filename = r.cap( 2 ); if ( filename.startsWith( '"' ) && filename.endsWith( '"' ) ) filename = filename.mid( 1, filename.length() - 2 ); src = "HDF4_SDS:" + r.cap( 1 ) + ":\"" + QgsProject::instance()->writePath( filename, relativeBasePath ) + "\":" + r.cap( 3 ); handled = true; } } else if ( src.startsWith( "HDF5:" ) ) { // HDF5:file_name:subdataset // filename can be quoted with " as it can contain colons QRegExp r( "HDF5:(.+):([^:]+)" ); if ( r.exactMatch( src ) ) { QString filename = r.cap( 1 ); if ( filename.startsWith( '"' ) && filename.endsWith( '"' ) ) filename = filename.mid( 1, filename.length() - 2 ); src = "HDF5:\"" + QgsProject::instance()->writePath( filename, relativeBasePath ) + "\":" + r.cap( 2 ); handled = true; } } else if ( src.contains( QRegExp( "^(NITF_IM|RADARSAT_2_CALIB):" ) ) ) { // NITF_IM:0:filename // RADARSAT_2_CALIB:?:filename QRegExp r( "([^:]+):([^:]+):(.+)" ); if ( r.exactMatch( src ) ) { src = r.cap( 1 ) + ":" + r.cap( 2 ) + ":" + QgsProject::instance()->writePath( r.cap( 3 ), relativeBasePath ); handled = true; } } } } if ( !handled ) src = QgsProject::instance()->writePath( src, relativeBasePath ); } QDomText dataSourceText = document.createTextNode( src ); dataSource.appendChild( dataSourceText ); layerElement.appendChild( dataSource ); // layer name QDomElement layerName = document.createElement( "layername" ); QDomText layerNameText = document.createTextNode( originalName() ); layerName.appendChild( layerNameText ); // layer title QDomElement layerTitle = document.createElement( "title" ); QDomText layerTitleText = document.createTextNode( title() ); layerTitle.appendChild( layerTitleText ); // layer abstract QDomElement layerAbstract = document.createElement( "abstract" ); QDomText layerAbstractText = document.createTextNode( abstract() ); layerAbstract.appendChild( layerAbstractText ); layerElement.appendChild( layerName ); layerElement.appendChild( layerTitle ); layerElement.appendChild( layerAbstract ); // layer keyword list QStringList keywordStringList = keywordList().split( "," ); if ( keywordStringList.size() > 0 ) { QDomElement layerKeywordList = document.createElement( "keywordList" ); for ( int i = 0; i < keywordStringList.size(); ++i ) { QDomElement layerKeywordValue = document.createElement( "value" ); QDomText layerKeywordText = document.createTextNode( keywordStringList.at( i ).trimmed() ); layerKeywordValue.appendChild( layerKeywordText ); layerKeywordList.appendChild( layerKeywordValue ); } layerElement.appendChild( layerKeywordList ); } // layer metadataUrl QString aDataUrl = dataUrl(); if ( !aDataUrl.isEmpty() ) { QDomElement layerDataUrl = document.createElement( "dataUrl" ); QDomText layerDataUrlText = document.createTextNode( aDataUrl ); layerDataUrl.appendChild( layerDataUrlText ); layerDataUrl.setAttribute( "format", dataUrlFormat() ); layerElement.appendChild( layerDataUrl ); } // layer legendUrl QString aLegendUrl = legendUrl(); if ( !aLegendUrl.isEmpty() ) { QDomElement layerLegendUrl = document.createElement( "legendUrl" ); QDomText layerLegendUrlText = document.createTextNode( aLegendUrl ); layerLegendUrl.appendChild( layerLegendUrlText ); layerLegendUrl.setAttribute( "format", legendUrlFormat() ); layerElement.appendChild( layerLegendUrl ); } // layer attribution QString aAttribution = attribution(); if ( !aAttribution.isEmpty() ) { QDomElement layerAttribution = document.createElement( "attribution" ); QDomText layerAttributionText = document.createTextNode( aAttribution ); layerAttribution.appendChild( layerAttributionText ); layerAttribution.setAttribute( "href", attributionUrl() ); layerElement.appendChild( layerAttribution ); } // layer metadataUrl QString aMetadataUrl = metadataUrl(); if ( !aMetadataUrl.isEmpty() ) { QDomElement layerMetadataUrl = document.createElement( "metadataUrl" ); QDomText layerMetadataUrlText = document.createTextNode( aMetadataUrl ); layerMetadataUrl.appendChild( layerMetadataUrlText ); layerMetadataUrl.setAttribute( "type", metadataUrlType() ); layerMetadataUrl.setAttribute( "format", metadataUrlFormat() ); layerElement.appendChild( layerMetadataUrl ); } // timestamp if supported if ( timestamp() > QDateTime() ) { QDomElement stamp = document.createElement( "timestamp" ); QDomText stampText = document.createTextNode( timestamp().toString( Qt::ISODate ) ); stamp.appendChild( stampText ); layerElement.appendChild( stamp ); } layerElement.appendChild( layerName ); // zorder // This is no longer stored in the project file. It is superfluous since the layers // are written and read in the proper order. // spatial reference system id QDomElement mySrsElement = document.createElement( "srs" ); mCRS->writeXML( mySrsElement, document ); layerElement.appendChild( mySrsElement ); #if 0 // <transparencyLevelInt> QDomElement transparencyLevelIntElement = document.createElement( "transparencyLevelInt" ); QDomText transparencyLevelIntText = document.createTextNode( QString::number( getTransparency() ) ); transparencyLevelIntElement.appendChild( transparencyLevelIntText ); maplayer.appendChild( transparencyLevelIntElement ); #endif // now append layer node to map layer node writeCustomProperties( layerElement, document ); return writeXml( layerElement, document ); } // bool QgsMapLayer::writeXML