void QgsDecorationCopyright::projectRead() { QgsDecorationItem::projectRead(); mLabelText = QgsProject::instance()->readEntry( mNameConfig, QStringLiteral( "/Label" ), QString() ); mMarginHorizontal = QgsProject::instance()->readNumEntry( mNameConfig, QStringLiteral( "/MarginH" ), 0 ); mMarginVertical = QgsProject::instance()->readNumEntry( mNameConfig, QStringLiteral( "/MarginV" ), 0 ); QDomDocument doc; QDomElement elem; QString textXml = QgsProject::instance()->readEntry( mNameConfig, QStringLiteral( "/Font" ) ); if ( !textXml.isEmpty() ) { doc.setContent( textXml ); elem = doc.documentElement(); QgsReadWriteContext rwContext; rwContext.setPathResolver( QgsProject::instance()->pathResolver() ); mTextFormat.readXml( elem, rwContext ); } // Migratation for pre QGIS 3.2 settings QColor oldColor = QgsSymbolLayerUtils::decodeColor( QgsProject::instance()->readEntry( mNameConfig, QStringLiteral( "/Color" ) ) ); if ( oldColor.isValid() ) { mTextFormat.setColor( oldColor ); QgsProject::instance()->removeEntry( mNameConfig, QStringLiteral( "/Color" ) ); } }
QDomElement QgsLayoutManager::writeXml( QDomDocument &doc ) const { QDomElement layoutsElem = doc.createElement( QStringLiteral( "Layouts" ) ); QgsReadWriteContext context; context.setPathResolver( mProject->pathResolver() ); for ( QgsMasterLayoutInterface *l : mLayouts ) { QDomElement layoutElem = l->writeLayoutXml( doc, context ); layoutsElem.appendChild( layoutElem ); } return layoutsElem; }
QgsLayerTreeNode *QgsLayerTreeNode::readXml( QDomElement &element, const QgsProject *project ) { QgsReadWriteContext context; QgsPathResolver resolver; if ( project ) resolver = project->pathResolver(); context.setPathResolver( resolver ); context.setProjectTranslator( const_cast<QgsProject *>( project ) ); QgsLayerTreeNode *node = readXml( element, context ); if ( node ) node->resolveReferences( project ); return node; }
void QgsDecorationCopyright::saveToProject() { QgsDecorationItem::saveToProject(); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/Label" ), mLabelText ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/MarginH" ), mMarginHorizontal ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/MarginV" ), mMarginVertical ); QDomDocument textDoc; QgsReadWriteContext rwContext; rwContext.setPathResolver( QgsProject::instance()->pathResolver() ); QDomElement textElem = mTextFormat.writeXml( textDoc, rwContext ); textDoc.appendChild( textElem ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/Font" ), textDoc.toString() ); }
bool QgsLayoutItemPicture::writePropertiesToElement( QDomElement &elem, QDomDocument &, const QgsReadWriteContext &context ) const { QString imagePath = mSourcePath; // convert from absolute path to relative. For SVG we also need to consider system SVG paths QgsPathResolver pathResolver = context.pathResolver(); if ( imagePath.endsWith( QLatin1String( ".svg" ), Qt::CaseInsensitive ) ) imagePath = QgsSymbolLayerUtils::svgSymbolPathToName( imagePath, pathResolver ); else imagePath = pathResolver.writePath( imagePath ); elem.setAttribute( QStringLiteral( "file" ), imagePath ); elem.setAttribute( QStringLiteral( "pictureWidth" ), QString::number( mPictureWidth ) ); elem.setAttribute( QStringLiteral( "pictureHeight" ), QString::number( mPictureHeight ) ); elem.setAttribute( QStringLiteral( "resizeMode" ), QString::number( static_cast< int >( mResizeMode ) ) ); elem.setAttribute( QStringLiteral( "anchorPoint" ), QString::number( static_cast< int >( mPictureAnchor ) ) ); elem.setAttribute( QStringLiteral( "svgFillColor" ), QgsSymbolLayerUtils::encodeColor( mSvgFillColor ) ); elem.setAttribute( QStringLiteral( "svgBorderColor" ), QgsSymbolLayerUtils::encodeColor( mSvgStrokeColor ) ); elem.setAttribute( QStringLiteral( "svgBorderWidth" ), QString::number( mSvgStrokeWidth ) ); //rotation elem.setAttribute( QStringLiteral( "pictureRotation" ), QString::number( mPictureRotation ) ); if ( !mRotationMap ) { elem.setAttribute( QStringLiteral( "mapUuid" ), QString() ); } else { elem.setAttribute( QStringLiteral( "mapUuid" ), mRotationMap->uuid() ); } elem.setAttribute( QStringLiteral( "northMode" ), mNorthMode ); elem.setAttribute( QStringLiteral( "northOffset" ), mNorthOffset ); return true; }
QString QgsMeshLayer::encodedSource( const QString &source, const QgsReadWriteContext &context ) const { QString src( source ); if ( providerType() == QLatin1String( "mdal" ) ) { src = context.pathResolver().writePath( src ); } return src; }
virtual bool readProject( const QString &uri, QIODevice *ioDevice, QgsReadWriteContext &context ) override { QgsReadWriteContextCategoryPopper popper( context.enterCategory( "memory storage" ) ); QStringList lst = uri.split( ":" ); Q_ASSERT( lst.count() == 2 ); QString projectName = lst[1]; if ( !mProjects.contains( projectName ) ) { context.pushMessage( "project not found", Qgis::Critical ); return false; } QByteArray content = mProjects[projectName]; ioDevice->write( content ); ioDevice->seek( 0 ); return true; }
bool QgsLayoutItemPolyline::readPropertiesFromElement( const QDomElement &elmt, const QDomDocument &doc, const QgsReadWriteContext &context ) { mArrowHeadWidth = elmt.attribute( QStringLiteral( "arrowHeadWidth" ), QStringLiteral( "2.0" ) ).toDouble(); mArrowHeadFillColor = QgsSymbolLayerUtils::decodeColor( elmt.attribute( QStringLiteral( "arrowHeadFillColor" ), QStringLiteral( "0,0,0,255" ) ) ); mArrowHeadStrokeColor = QgsSymbolLayerUtils::decodeColor( elmt.attribute( QStringLiteral( "arrowHeadOutlineColor" ), QStringLiteral( "0,0,0,255" ) ) ); mArrowHeadStrokeWidth = elmt.attribute( QStringLiteral( "outlineWidth" ), QStringLiteral( "1.0" ) ).toDouble(); // relative paths to absolute QString startMarkerPath = elmt.attribute( QStringLiteral( "startMarkerFile" ), QString() ); QString endMarkerPath = elmt.attribute( QStringLiteral( "endMarkerFile" ), QString() ); setStartSvgMarkerPath( QgsSymbolLayerUtils::svgSymbolNameToPath( startMarkerPath, context.pathResolver() ) ); setEndSvgMarkerPath( QgsSymbolLayerUtils::svgSymbolNameToPath( endMarkerPath, context.pathResolver() ) ); mEndMarker = static_cast< QgsLayoutItemPolyline::MarkerMode >( elmt.attribute( QStringLiteral( "markerMode" ), QStringLiteral( "0" ) ).toInt() ); mStartMarker = static_cast< QgsLayoutItemPolyline::MarkerMode >( elmt.attribute( QStringLiteral( "startMarkerMode" ), QStringLiteral( "0" ) ).toInt() ); QgsLayoutNodesItem::readPropertiesFromElement( elmt, doc, context ); updateBoundingRect(); return true; }
void QgsDecorationGrid::saveToProject() { QgsDecorationItem::saveToProject(); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/Enabled" ), mEnabled ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/MapUnits" ), static_cast< int >( mMapUnits ) ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/Style" ), static_cast< int >( mGridStyle ) ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/IntervalX" ), mGridIntervalX ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/IntervalY" ), mGridIntervalY ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/OffsetX" ), mGridOffsetX ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/OffsetY" ), mGridOffsetY ); // QgsProject::instance()->writeEntry( mNameConfig, "/CrossLength", mCrossLength ); // missing mGridPen, but should use styles anyway QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/ShowAnnotation" ), mShowGridAnnotation ); // QgsProject::instance()->writeEntry( mNameConfig, "/AnnotationPosition", ( int ) mGridAnnotationPosition ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/AnnotationDirection" ), static_cast< int >( mGridAnnotationDirection ) ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/AnnotationFont" ), mGridAnnotationFont.toString() ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/AnnotationFrameDistance" ), mAnnotationFrameDistance ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/AnnotationPrecision" ), mGridAnnotationPrecision ); // write symbol info to xml QDomDocument doc; QDomElement elem; QgsReadWriteContext rwContext; rwContext.setPathResolver( QgsProject::instance()->pathResolver() ); if ( mLineSymbol ) { elem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "line symbol" ), mLineSymbol, doc, rwContext ); doc.appendChild( elem ); // FIXME this works, but XML will not be valid as < is replaced by < QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/LineSymbol" ), doc.toString() ); } if ( mMarkerSymbol ) { doc.setContent( QString() ); elem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "marker symbol" ), mMarkerSymbol, doc, rwContext ); doc.appendChild( elem ); QgsProject::instance()->writeEntry( mNameConfig, QStringLiteral( "/MarkerSymbol" ), doc.toString() ); } }
void QgsDecorationTitle::projectRead() { QgsDecorationItem::projectRead(); mLabelText = QgsProject::instance()->readEntry( mNameConfig, QStringLiteral( "/Label" ), QString() ); mBackgroundColor = QgsSymbolLayerUtils::decodeColor( QgsProject::instance()->readEntry( mNameConfig, QStringLiteral( "/BackgroundColor" ), QStringLiteral( "0,0,0,99" ) ) ); mMarginHorizontal = QgsProject::instance()->readNumEntry( mNameConfig, QStringLiteral( "/MarginH" ), 0 ); mMarginVertical = QgsProject::instance()->readNumEntry( mNameConfig, QStringLiteral( "/MarginV" ), 0 ); QDomDocument doc; QDomElement elem; QString textXml = QgsProject::instance()->readEntry( mNameConfig, QStringLiteral( "/Font" ) ); if ( !textXml.isEmpty() ) { doc.setContent( textXml ); elem = doc.documentElement(); QgsReadWriteContext rwContext; rwContext.setPathResolver( QgsProject::instance()->pathResolver() ); mTextFormat.readXml( elem, rwContext ); } }
bool QgsMeshLayer::readXml( const QDomNode &layer_node, QgsReadWriteContext &context ) { QgsDebugMsgLevel( QStringLiteral( "Datasource in QgsMeshLayer::readXml: %1" ).arg( mDataSource.toLocal8Bit().data() ), 3 ); //process provider key QDomNode pkeyNode = layer_node.namedItem( QStringLiteral( "provider" ) ); if ( pkeyNode.isNull() ) { mProviderKey.clear(); } else { QDomElement pkeyElt = pkeyNode.toElement(); mProviderKey = pkeyElt.text(); } QgsDataProvider::ProviderOptions providerOptions; if ( !setDataProvider( mProviderKey, providerOptions ) ) { return false; } QDomElement elemExtraDatasets = layer_node.firstChildElement( QStringLiteral( "extra-datasets" ) ); if ( !elemExtraDatasets.isNull() ) { QDomElement elemUri = elemExtraDatasets.firstChildElement( QStringLiteral( "uri" ) ); while ( !elemUri.isNull() ) { QString uri = context.pathResolver().readPath( elemUri.text() ); bool res = mDataProvider->addDataset( uri ); #ifdef QGISDEBUG QgsDebugMsg( QStringLiteral( "extra dataset (res %1): %2" ).arg( res ).arg( uri ) ); #else ( void )res; // avoid unused warning in release builds #endif elemUri = elemUri.nextSiblingElement( QStringLiteral( "uri" ) ); } } QString errorMsg; readSymbology( layer_node, errorMsg, context ); return mValid; // should be true if read successfully }
bool QgsLayoutItemPolyline::writePropertiesToElement( QDomElement &elmt, QDomDocument &doc, const QgsReadWriteContext &context ) const { QgsLayoutNodesItem::writePropertiesToElement( elmt, doc, context ); // absolute paths to relative QString startMarkerPath = QgsSymbolLayerUtils::svgSymbolPathToName( mStartMarkerFile, context.pathResolver() ); QString endMarkerPath = QgsSymbolLayerUtils::svgSymbolPathToName( mEndMarkerFile, context.pathResolver() ); elmt.setAttribute( QStringLiteral( "arrowHeadWidth" ), QString::number( mArrowHeadWidth ) ); elmt.setAttribute( QStringLiteral( "arrowHeadFillColor" ), QgsSymbolLayerUtils::encodeColor( mArrowHeadFillColor ) ); elmt.setAttribute( QStringLiteral( "arrowHeadOutlineColor" ), QgsSymbolLayerUtils::encodeColor( mArrowHeadStrokeColor ) ); elmt.setAttribute( QStringLiteral( "outlineWidth" ), QString::number( mArrowHeadStrokeWidth ) ); elmt.setAttribute( QStringLiteral( "markerMode" ), mEndMarker ); elmt.setAttribute( QStringLiteral( "startMarkerMode" ), mStartMarker ); elmt.setAttribute( QStringLiteral( "startMarkerFile" ), startMarkerPath ); elmt.setAttribute( QStringLiteral( "endMarkerFile" ), endMarkerPath ); return true; }
bool QgsMeshLayer::writeXml( QDomNode &layer_node, QDomDocument &document, const QgsReadWriteContext &context ) const { // first get the layer element so that we can append the type attribute QDomElement mapLayerNode = layer_node.toElement(); if ( mapLayerNode.isNull() || ( QLatin1String( "maplayer" ) != mapLayerNode.nodeName() ) ) { QgsDebugMsgLevel( QStringLiteral( "can't find <maplayer>" ), 2 ); return false; } mapLayerNode.setAttribute( QStringLiteral( "type" ), QStringLiteral( "mesh" ) ); // add provider node if ( mDataProvider ) { QDomElement provider = document.createElement( QStringLiteral( "provider" ) ); QDomText providerText = document.createTextNode( providerType() ); provider.appendChild( providerText ); layer_node.appendChild( provider ); const QStringList extraDatasetUris = mDataProvider->extraDatasets(); QDomElement elemExtraDatasets = document.createElement( QStringLiteral( "extra-datasets" ) ); for ( const QString &uri : extraDatasetUris ) { QString path = context.pathResolver().writePath( uri ); QDomElement elemUri = document.createElement( QStringLiteral( "uri" ) ); elemUri.appendChild( document.createTextNode( path ) ); elemExtraDatasets.appendChild( elemUri ); } layer_node.appendChild( elemExtraDatasets ); } // renderer specific settings QString errorMsg; return writeSymbology( layer_node, document, errorMsg, context ); }
bool QgsLayoutItemPicture::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &, const QgsReadWriteContext &context ) { mPictureWidth = itemElem.attribute( QStringLiteral( "pictureWidth" ), QStringLiteral( "10" ) ).toDouble(); mPictureHeight = itemElem.attribute( QStringLiteral( "pictureHeight" ), QStringLiteral( "10" ) ).toDouble(); mResizeMode = QgsLayoutItemPicture::ResizeMode( itemElem.attribute( QStringLiteral( "resizeMode" ), QStringLiteral( "0" ) ).toInt() ); //when loading from xml, default to anchor point of middle to match pre 2.4 behavior mPictureAnchor = static_cast< QgsLayoutItem::ReferencePoint >( itemElem.attribute( QStringLiteral( "anchorPoint" ), QString::number( QgsLayoutItem::Middle ) ).toInt() ); mSvgFillColor = QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "svgFillColor" ), QgsSymbolLayerUtils::encodeColor( QColor( 255, 255, 255 ) ) ) ); mSvgStrokeColor = QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "svgBorderColor" ), QgsSymbolLayerUtils::encodeColor( QColor( 0, 0, 0 ) ) ) ); mSvgStrokeWidth = itemElem.attribute( QStringLiteral( "svgBorderWidth" ), QStringLiteral( "0.2" ) ).toDouble(); QDomNodeList composerItemList = itemElem.elementsByTagName( QStringLiteral( "ComposerItem" ) ); if ( !composerItemList.isEmpty() ) { QDomElement composerItemElem = composerItemList.at( 0 ).toElement(); if ( !qgsDoubleNear( composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble(), 0.0 ) ) { //in versions prior to 2.1 picture rotation was stored in the rotation attribute mPictureRotation = composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble(); } } mDefaultSvgSize = QSize( 0, 0 ); if ( itemElem.hasAttribute( QStringLiteral( "sourceExpression" ) ) ) { //update pre 2.5 picture expression to use data defined expression QString sourceExpression = itemElem.attribute( QStringLiteral( "sourceExpression" ), QLatin1String( "" ) ); QString useExpression = itemElem.attribute( QStringLiteral( "useExpression" ) ); bool expressionActive; expressionActive = ( useExpression.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 ); mDataDefinedProperties.setProperty( QgsLayoutObject::PictureSource, QgsProperty::fromExpression( sourceExpression, expressionActive ) ); } QString imagePath = itemElem.attribute( QStringLiteral( "file" ) ); // convert from relative path to absolute. For SVG we also need to consider system SVG paths QgsPathResolver pathResolver = context.pathResolver(); if ( imagePath.endsWith( QLatin1String( ".svg" ), Qt::CaseInsensitive ) ) imagePath = QgsSymbolLayerUtils::svgSymbolNameToPath( imagePath, pathResolver ); else imagePath = pathResolver.readPath( imagePath ); mSourcePath = imagePath; //picture rotation if ( !qgsDoubleNear( itemElem.attribute( QStringLiteral( "pictureRotation" ), QStringLiteral( "0" ) ).toDouble(), 0.0 ) ) { mPictureRotation = itemElem.attribute( QStringLiteral( "pictureRotation" ), QStringLiteral( "0" ) ).toDouble(); } //rotation map mNorthMode = static_cast< NorthMode >( itemElem.attribute( QStringLiteral( "northMode" ), QStringLiteral( "0" ) ).toInt() ); mNorthOffset = itemElem.attribute( QStringLiteral( "northOffset" ), QStringLiteral( "0" ) ).toDouble(); mRotationMap = nullptr; mRotationMapId = -1; mRotationMapUuid.clear(); mRotationMapId = itemElem.attribute( QStringLiteral( "mapId" ), QStringLiteral( "-1" ) ).toInt(); mRotationMapUuid = itemElem.attribute( QStringLiteral( "mapUuid" ) ); return true; }
void QgsDecorationGrid::projectRead() { QgsDecorationItem::projectRead(); mEnabled = QgsProject::instance()->readBoolEntry( mNameConfig, QStringLiteral( "/Enabled" ), false ); mMapUnits = static_cast< QgsUnitTypes::DistanceUnit >( QgsProject::instance()->readNumEntry( mNameConfig, QStringLiteral( "/MapUnits" ), QgsUnitTypes::DistanceUnknownUnit ) ); mGridStyle = static_cast< GridStyle >( QgsProject::instance()->readNumEntry( mNameConfig, QStringLiteral( "/Style" ), QgsDecorationGrid::Line ) ); mGridIntervalX = QgsProject::instance()->readDoubleEntry( mNameConfig, QStringLiteral( "/IntervalX" ), 10 ); mGridIntervalY = QgsProject::instance()->readDoubleEntry( mNameConfig, QStringLiteral( "/IntervalY" ), 10 ); mGridOffsetX = QgsProject::instance()->readDoubleEntry( mNameConfig, QStringLiteral( "/OffsetX" ), 0 ); mGridOffsetY = QgsProject::instance()->readDoubleEntry( mNameConfig, QStringLiteral( "/OffsetY" ), 0 ); // mCrossLength = QgsProject::instance()->readDoubleEntry( mNameConfig, "/CrossLength", 3 ); mShowGridAnnotation = QgsProject::instance()->readBoolEntry( mNameConfig, QStringLiteral( "/ShowAnnotation" ), false ); // mGridAnnotationPosition = ( GridAnnotationPosition ) QgsProject::instance()->readNumEntry( mNameConfig, // "/AnnotationPosition", 0 ); mGridAnnotationPosition = InsideMapFrame; // don't allow outside frame, doesn't make sense mGridAnnotationDirection = static_cast< GridAnnotationDirection >( QgsProject::instance()->readNumEntry( mNameConfig, QStringLiteral( "/AnnotationDirection" ), 0 ) ); QString fontStr = QgsProject::instance()->readEntry( mNameConfig, QStringLiteral( "/AnnotationFont" ), QString() ); if ( !fontStr.isEmpty() ) { mGridAnnotationFont.fromString( fontStr ); } else { mGridAnnotationFont = QFont(); // TODO fix font scaling problem - put a slightly large font for now mGridAnnotationFont.setPointSize( 16 ); } mAnnotationFrameDistance = QgsProject::instance()->readDoubleEntry( mNameConfig, QStringLiteral( "/AnnotationFrameDistance" ), 0 ); mGridAnnotationPrecision = QgsProject::instance()->readNumEntry( mNameConfig, QStringLiteral( "/AnnotationPrecision" ), 0 ); // read symbol info from xml QDomDocument doc; QDomElement elem; QString xml; QgsReadWriteContext rwContext; rwContext.setPathResolver( QgsProject::instance()->pathResolver() ); if ( mLineSymbol ) setLineSymbol( nullptr ); xml = QgsProject::instance()->readEntry( mNameConfig, QStringLiteral( "/LineSymbol" ) ); if ( !xml.isEmpty() ) { doc.setContent( xml ); elem = doc.documentElement(); mLineSymbol = QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( elem, rwContext ); } if ( ! mLineSymbol ) mLineSymbol = new QgsLineSymbol(); if ( mMarkerSymbol ) setMarkerSymbol( nullptr ); xml = QgsProject::instance()->readEntry( mNameConfig, QStringLiteral( "/MarkerSymbol" ) ); if ( !xml.isEmpty() ) { doc.setContent( xml ); elem = doc.documentElement(); mMarkerSymbol = QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( elem, rwContext ); } if ( ! mMarkerSymbol ) { // set default symbol : cross with width=3 QgsSymbolLayerList symbolList; symbolList << new QgsSimpleMarkerSymbolLayer( QgsSimpleMarkerSymbolLayerBase::Cross, 3, 0 ); mMarkerSymbol = new QgsMarkerSymbol( symbolList ); // mMarkerSymbol = new QgsMarkerSymbol(); } }
bool QgsLayoutManager::readXml( const QDomElement &element, const QDomDocument &doc ) { clear(); QDomElement layoutsElem = element; if ( element.tagName() != QStringLiteral( "Layouts" ) ) { layoutsElem = element.firstChildElement( QStringLiteral( "Layouts" ) ); } if ( layoutsElem.isNull() ) { // handle legacy projects layoutsElem = doc.documentElement(); } //restore each composer bool result = true; QDomNodeList composerNodes = element.elementsByTagName( QStringLiteral( "Composer" ) ); for ( int i = 0; i < composerNodes.size(); ++i ) { // This legacy title is the Composer "title" (that can be overridden by the Composition "name") QString legacyTitle = composerNodes.at( i ).toElement().attribute( QStringLiteral( "title" ) ); // Convert compositions to layouts QDomNodeList compositionNodes = composerNodes.at( i ).toElement().elementsByTagName( QStringLiteral( "Composition" ) ); for ( int j = 0; j < compositionNodes.size(); ++j ) { std::unique_ptr< QgsPrintLayout > l( QgsCompositionConverter::createLayoutFromCompositionXml( compositionNodes.at( j ).toElement(), mProject ) ); if ( l ) { if ( l->name().isEmpty() ) l->setName( legacyTitle ); // some 2.x projects could end in a state where they had duplicated layout names. This is strictly forbidden in 3.x // so check for duplicate name in layouts already added int id = 2; bool isDuplicateName = false; QString originalName = l->name(); do { isDuplicateName = false; for ( QgsMasterLayoutInterface *layout : qgis::as_const( mLayouts ) ) { if ( l->name() == layout->name() ) { isDuplicateName = true; break; } } if ( isDuplicateName ) { l->setName( QStringLiteral( "%1 %2" ).arg( originalName ).arg( id ) ); id++; } } while ( isDuplicateName ); bool added = addLayout( l.release() ); result = added && result; } } } QgsReadWriteContext context; context.setPathResolver( mProject->pathResolver() ); // restore layouts const QDomNodeList layoutNodes = layoutsElem.childNodes(); for ( int i = 0; i < layoutNodes.size(); ++i ) { if ( layoutNodes.at( i ).nodeName() != QStringLiteral( "Layout" ) ) continue; std::unique_ptr< QgsPrintLayout > l = qgis::make_unique< QgsPrintLayout >( mProject ); l->undoStack()->blockCommands( true ); if ( !l->readLayoutXml( layoutNodes.at( i ).toElement(), doc, context ) ) { result = false; continue; } l->undoStack()->blockCommands( false ); if ( addLayout( l.get() ) ) { ( void )l.release(); // ownership was transferred successfully } else { result = false; } } //reports const QDomNodeList reportNodes = element.elementsByTagName( QStringLiteral( "Report" ) ); for ( int i = 0; i < reportNodes.size(); ++i ) { std::unique_ptr< QgsReport > r = qgis::make_unique< QgsReport >( mProject ); if ( !r->readLayoutXml( reportNodes.at( i ).toElement(), doc, context ) ) { result = false; continue; } if ( addLayout( r.get() ) ) { ( void )r.release(); // ownership was transferred successfully } else { result = false; } } return result; }
QgsRelation QgsRelation::createFromXml( const QDomNode &node, QgsReadWriteContext &context ) { QDomElement elem = node.toElement(); if ( elem.tagName() != QLatin1String( "relation" ) ) { QgsLogger::warning( QApplication::translate( "QgsRelation", "Cannot create relation. Unexpected tag '%1'" ).arg( elem.tagName() ) ); } QgsRelation relation; QString referencingLayerId = elem.attribute( QStringLiteral( "referencingLayer" ) ); QString referencedLayerId = elem.attribute( QStringLiteral( "referencedLayer" ) ); QString id = elem.attribute( QStringLiteral( "id" ) ); QString name = context.projectTranslator()->translate( QStringLiteral( "project:relations" ), elem.attribute( QStringLiteral( "name" ) ) ); QString strength = elem.attribute( QStringLiteral( "strength" ) ); const QMap<QString, QgsMapLayer *> &mapLayers = QgsProject::instance()->mapLayers(); QgsMapLayer *referencingLayer = mapLayers[referencingLayerId]; QgsMapLayer *referencedLayer = mapLayers[referencedLayerId]; if ( !referencingLayer ) { QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which does not exist." ).arg( referencingLayerId ) ); } else if ( QgsMapLayer::VectorLayer != referencingLayer->type() ) { QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencingLayerId ) ); } if ( !referencedLayer ) { QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which does not exist." ).arg( referencedLayerId ) ); } else if ( QgsMapLayer::VectorLayer != referencedLayer->type() ) { QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencedLayerId ) ); } relation.d->mReferencingLayerId = referencingLayerId; relation.d->mReferencingLayer = qobject_cast<QgsVectorLayer *>( referencingLayer ); relation.d->mReferencedLayerId = referencedLayerId; relation.d->mReferencedLayer = qobject_cast<QgsVectorLayer *>( referencedLayer ); relation.d->mRelationId = id; relation.d->mRelationName = name; if ( strength == QLatin1String( "Composition" ) ) { relation.d->mRelationStrength = RelationStrength::Composition; } else { relation.d->mRelationStrength = RelationStrength::Association; } QDomNodeList references = elem.elementsByTagName( QStringLiteral( "fieldRef" ) ); for ( int i = 0; i < references.size(); ++i ) { QDomElement refEl = references.at( i ).toElement(); QString referencingField = refEl.attribute( QStringLiteral( "referencingField" ) ); QString referencedField = refEl.attribute( QStringLiteral( "referencedField" ) ); relation.addFieldPair( referencingField, referencedField ); } relation.updateRelationStatus(); return relation; }