40 #include <QApplication> 44 #include <QTextStream> 60 QStringList keyTokens = QStringList( scope );
61 keyTokens += key.split(
'/', QString::SkipEmptyParts );
64 keyTokens.push_front(
"properties" );
91 while ( !keySequence.isEmpty() )
95 if ( keySequence.first() == currentProperty->
name() )
98 keySequence.pop_front();
100 if ( 1 == keySequence.count() )
103 return currentProperty->
find( keySequence.front() );
105 else if ( keySequence.isEmpty() )
110 return currentProperty;
112 else if (( nextProperty = currentProperty->
find( keySequence.first() ) ) )
114 if ( nextProperty->
isKey() )
118 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
124 return currentProperty;
170 while ( ! keySequence.isEmpty() )
174 if ( keySequence.first() == currentProperty->
name() )
177 keySequence.pop_front();
181 if ( 1 == keySequence.count() )
183 currentProperty->
setValue( keySequence.front(), value );
184 return currentProperty;
188 else if ( keySequence.isEmpty() )
192 return currentProperty;
194 else if (( nextProperty = currentProperty->
find( keySequence.first() ) ) )
198 if ( currentProperty )
209 if (( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
211 currentProperty = newPropertyKey;
240 while ( ! keySequence.isEmpty() )
244 if ( keySequence.first() == currentProperty->
name() )
247 keySequence.pop_front();
251 if ( 1 == keySequence.count() )
253 currentProperty->
removeKey( keySequence.front() );
258 else if ( keySequence.isEmpty() )
260 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
262 else if (( nextProperty = currentProperty->
find( keySequence.first() ) ) )
264 previousQgsPropertyKey = currentProperty;
267 if ( currentProperty )
304 properties_.
name() =
"properties";
313 file.setFileName( QString() );
323 QgsProject::QgsProject()
342 delete mBadLayerHandler;
343 delete mRelationManager;
399 imp_->file.setFileName( name );
408 return imp_->file.fileName();
414 mEmbeddedLayers.clear();
415 mRelationManager->clear();
417 mRootGroup->removeAllChildren();
421 writeEntry(
"PositionPrecision",
"/Automatic",
true );
422 writeEntry(
"PositionPrecision",
"/DecimalPlaces", 2 );
432 topQgsPropertyKey.
dump();
470 QDomNodeList properties = doc.elementsByTagName(
"properties" );
472 if ( properties.count() > 1 )
474 QgsDebugMsg(
"there appears to be more than one ``properties'' XML tag ... bailing" );
477 else if ( properties.count() < 1 )
483 QDomNodeList scopes = properties.item( 0 ).childNodes();
485 if ( scopes.count() < 1 )
487 QgsDebugMsg(
"empty ``properties'' XML tag ... bailing" );
491 QDomNode propertyNode = properties.item( 0 );
493 if ( ! project_properties.
readXML( propertyNode ) )
495 QgsDebugMsg(
"Project_properties.readXML() failed" );
515 QDomNodeList nl = doc.elementsByTagName(
"title" );
525 QDomNode titleNode = nl.item( 0 );
527 if ( !titleNode.hasChildNodes() )
533 QDomNode titleTextNode = titleNode.firstChild();
535 if ( !titleTextNode.isText() )
541 QDomText titleText = titleTextNode.toText();
543 title = titleText.data();
554 QDomNodeList nl = doc.elementsByTagName(
"qgis" );
558 QgsDebugMsg(
" unable to find qgis element in project file" );
562 QDomNode qgisNode = nl.item( 0 );
564 QDomElement qgisElement = qgisNode.toElement();
566 return projectVersion;
618 QPair< bool, QList<QDomNode> > QgsProject::_getMapLayers( QDomDocument
const &doc )
623 QDomNodeList nl = doc.elementsByTagName(
"maplayer" );
625 QList<QDomNode> brokenNodes;
632 if ( 0 == nl.count() )
634 return qMakePair(
true, brokenNodes );
642 bool returnStatus =
true;
648 QList< QPair< QgsVectorLayer*, QDomElement > > vLayerList;
650 for (
int i = 0; i < nl.count(); i++ )
652 QDomNode node = nl.item( i );
653 QDomElement element = node.toElement();
655 QString name = node.namedItem(
"layername" ).toElement().text();
656 if ( !name.isNull() )
659 if ( element.attribute(
"embedded" ) ==
"1" )
666 if ( !
addLayer( element, brokenNodes, vLayerList ) )
668 returnStatus =
false;
676 QList< QPair< QgsVectorLayer*, QDomElement > >::iterator vIt = vLayerList.begin();
677 for ( ; vIt != vLayerList.end(); ++vIt )
679 vIt->first->createJoinCaches();
680 vIt->first->updateFields();
683 QSet<QgsVectorLayer *> notified;
684 for ( vIt = vLayerList.begin(); vIt != vLayerList.end(); ++vIt )
686 if ( notified.contains( vIt->first ) )
689 notified << vIt->first;
695 return qMakePair( returnStatus, brokenNodes );
698 bool QgsProject::addLayer(
const QDomElement &layerElem, QList<QDomNode> &brokenNodes, QList< QPair< QgsVectorLayer*, QDomElement > > &vectorLayerList )
700 QString type = layerElem.attribute(
"type" );
704 if ( type ==
"vector" )
708 else if ( type ==
"raster" )
712 else if ( type ==
"plugin" )
714 QString typeName = layerElem.attribute(
"name" );
725 Q_CHECK_PTR( mapLayer );
732 if ( !vLayer || vLayer->
vectorJoins().size() == 0 )
735 vectorLayerList.push_back( qMakePair( vLayer, layerElem ) );
737 QList<QgsMapLayer *> myLayers;
738 myLayers << mapLayer;
747 QgsDebugMsg(
"Unable to load " + type +
" layer" );
748 brokenNodes.push_back( layerElem );
759 imp_->file.setFileName( file.filePath() );
773 QScopedPointer<QDomDocument> doc(
new QDomDocument(
"qgis" ) );
775 if ( !imp_->file.open( QIODevice::ReadOnly | QIODevice::Text ) )
779 setError(
tr(
"Unable to open %1" ).arg( imp_->file.fileName() ) );
788 if ( !doc->setContent( &imp_->file, &errorMsg, &line, &column ) )
792 QMessageBox::critical( 0,
tr(
"Project File Read Error" ),
793 tr(
"%1 at line %2 column %3" ).arg( errorMsg ).arg( line ).arg( column ) );
796 QString errorString =
tr(
"Project file read error: %1 at line %2 column %3" )
797 .arg( errorMsg ).arg( line ).arg( column );
803 setError(
tr(
"%1 for file %2" ).arg( errorString ).arg( imp_->file.fileName() ) );
811 QgsDebugMsg(
"Opened document " + imp_->file.fileName() );
818 if ( thisVersion > fileVersion )
821 "version of qgis (saved in " + fileVersion.
text() +
823 "). Problems may occur." );
829 QgsDebugMsg(
"Emitting oldProjectVersionWarning(oldVersion)." );
831 projectFile.updateRevision( thisVersion );
835 QString
fileName = imp_->file.fileName();
837 imp_->file.setFileName( fileName );
842 QgsDebugMsg( QString::number( imp_->properties_.count() ) +
" properties read" );
844 dump_( imp_->properties_ );
851 mRootGroup->setCustomProperty(
"loading", 1 );
853 QDomElement layerTreeElem = doc->documentElement().firstChildElement(
"layer-tree-group" );
854 if ( !layerTreeElem.isNull() )
856 mRootGroup->readChildrenFromXML( layerTreeElem );
863 QgsDebugMsg(
"Loaded layer tree:\n " + mRootGroup->dump() );
865 mLayerTreeRegistryBridge->setEnabled(
false );
868 QPair< bool, QList<QDomNode> > getMapLayersResults = _getMapLayers( *doc );
871 bool clean = getMapLayersResults.first;
875 QgsDebugMsg(
"Unable to get map layers from project file." );
877 if ( ! getMapLayersResults.second.isEmpty() )
879 QgsDebugMsg(
"there are " + QString::number( getMapLayersResults.second.size() ) +
" broken layers" );
884 mBadLayerHandler->handleBadLayers( getMapLayersResults.second, *doc );
887 mLayerTreeRegistryBridge->setEnabled(
true );
895 mRootGroup->removeCustomProperty(
"loading" );
925 QList<QgsLayerTreeNode*> clonedChildren;
927 clonedChildren << newGroupChild->
clone();
942 QList<QDomNode> brokenNodes;
943 QList< QPair< QgsVectorLayer*, QDomElement > > vectorLayerList;
954 QList<QDomNode> brokenNodes;
955 QList< QPair< QgsVectorLayer*, QDomElement > > vectorLayerList;
956 return addLayer( layerNode.toElement(), brokenNodes, vectorLayerList );
963 imp_->file.setFileName( file.filePath() );
977 if ( QFile::exists( backup ) )
978 QFile::remove( backup );
979 QFile::rename(
fileName(), backup );
985 if ( !imp_->file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
990 setError(
tr(
"Unable to save to file %1" ).arg( imp_->file.fileName() ) );
993 QFileInfo myFileInfo( imp_->file );
994 if ( !myFileInfo.isWritable() )
999 setError(
tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
1000 .arg( imp_->file.fileName() ) );
1006 QDomImplementation DomImplementation;
1007 DomImplementation.setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
1009 QDomDocumentType documentType =
1010 DomImplementation.createDocumentType(
"qgis",
"http://mrcc.com/qgis.dtd",
1012 QScopedPointer<QDomDocument> doc(
new QDomDocument( documentType ) );
1014 QDomElement qgisNode = doc->createElement(
"qgis" );
1015 qgisNode.setAttribute(
"projectname",
title() );
1018 doc->appendChild( qgisNode );
1021 QDomElement titleNode = doc->createElement(
"title" );
1022 qgisNode.appendChild( titleNode );
1024 QDomText titleText = doc->createTextNode(
title() );
1025 titleNode.appendChild( titleText );
1042 QDomElement projectLayersNode = doc->createElement(
"projectlayers" );
1043 projectLayersNode.setAttribute(
"layercount", qulonglong( layers.size() ) );
1045 QMap<QString, QgsMapLayer*>::ConstIterator li = layers.constBegin();
1046 while ( li != layers.end() )
1053 QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.find( ml->
id() );
1054 if ( emIt == mEmbeddedLayers.constEnd() )
1057 QDomElement maplayerElem = doc->createElement(
"maplayer" );
1063 projectLayersNode.appendChild( maplayerElem );
1069 if ( emIt.value().second )
1071 QDomElement mapLayerElem = doc->createElement(
"maplayer" );
1072 mapLayerElem.setAttribute(
"embedded", 1 );
1073 mapLayerElem.setAttribute(
"project",
writePath( emIt.value().first ) );
1074 mapLayerElem.setAttribute(
"id", ml->
id() );
1075 projectLayersNode.appendChild( mapLayerElem );
1082 qgisNode.appendChild( projectLayersNode );
1086 dump_( imp_->properties_ );
1088 QgsDebugMsg( QString(
"there are %1 property scopes" ).arg( static_cast<int>( imp_->properties_.count() ) ) );
1090 if ( !imp_->properties_.isEmpty() )
1093 imp_->properties_.writeXML(
"properties", qgisNode, *doc );
1099 QTextStream projectFileStream( &imp_->file );
1101 doc->save( projectFileStream, 2 );
1107 if ( projectFileStream.pos() == -1 || imp_->file.error() != QFile::NoError )
1109 setError(
tr(
"Unable to save to file %1. Your project " 1110 "may be corrupted on disk. Try clearing some space on the volume and " 1111 "check file permissions before pressing save again." )
1112 .arg( imp_->file.fileName() ) );
1139 return addKey_( scope, key, &imp_->properties_, value );
1149 return addKey_( scope, key, &imp_->properties_, value );
1158 return addKey_( scope, key, &imp_->properties_, value );
1164 const QString &value )
1168 return addKey_( scope, key, &imp_->properties_, value );
1174 const QStringList &value )
1178 return addKey_( scope, key, &imp_->properties_, value );
1193 value =
property->value();
1195 bool valid = QVariant::StringList == value.type();
1201 return value.toStringList();
1221 value =
property->value();
1223 bool valid = value.canConvert( QVariant::String );
1228 return value.toString();
1245 value =
property->value();
1248 bool valid = value.canConvert( QVariant::String );
1257 return value.toInt();
1272 QVariant value =
property->value();
1274 bool valid = value.canConvert( QVariant::Double );
1279 return value.toDouble();
1294 QVariant value =
property->value();
1296 bool valid = value.canConvert( QVariant::Bool );
1301 return value.toBool();
1314 return !
findKey_( scope, key, imp_->properties_ );
1323 QStringList entries;
1325 if ( foundProperty )
1341 QStringList entries;
1343 if ( foundProperty )
1359 dump_( imp_->properties_ );
1373 if ( ! vsiPrefix.isEmpty() )
1377 if ( src.startsWith(
"/vsi", Qt::CaseInsensitive ) )
1378 src.remove( 0, vsiPrefix.size() );
1384 if ( !src.startsWith(
"./" ) && !src.startsWith(
"../" ) )
1386 #if defined(Q_OS_WIN) 1387 if ( src.startsWith(
"\\\\" ) ||
1388 src.startsWith(
"//" ) ||
1389 ( src[0].isLetter() && src[1] ==
':' ) )
1392 return vsiPrefix + src;
1395 if ( src[0] ==
'/' )
1398 return vsiPrefix + src;
1407 if ( home.isNull() )
1408 return vsiPrefix + src;
1410 QFileInfo fi( home +
"/" + src );
1414 return vsiPrefix + src;
1418 return vsiPrefix + fi.canonicalFilePath();
1422 QString srcPath = src;
1425 if ( projPath.isEmpty() )
1427 return vsiPrefix + src;
1430 #if defined(Q_OS_WIN) 1431 srcPath.replace(
"\\",
"/" );
1432 projPath.replace(
"\\",
"/" );
1434 bool uncPath = projPath.startsWith(
"//" );
1437 QStringList srcElems = srcPath.split(
"/", QString::SkipEmptyParts );
1438 QStringList projElems = projPath.split(
"/", QString::SkipEmptyParts );
1440 #if defined(Q_OS_WIN) 1443 projElems.insert( 0,
"" );
1444 projElems.insert( 0,
"" );
1449 projElems.removeLast();
1452 projElems << srcElems;
1453 projElems.removeAll(
"." );
1457 while (( pos = projElems.indexOf(
".." ) ) > 0 )
1460 projElems.removeAt( pos - 1 );
1461 projElems.removeAt( pos - 1 );
1464 #if !defined(Q_OS_WIN) 1466 projElems.prepend(
"" );
1469 return vsiPrefix + projElems.join(
"/" );
1475 if (
readBoolEntry(
"Paths",
"/Absolute",
false ) || src.isEmpty() )
1480 QFileInfo srcFileInfo( src );
1481 QFileInfo projFileInfo(
fileName() );
1482 QString srcPath = srcFileInfo.exists() ? srcFileInfo.canonicalFilePath() : src;
1483 QString projPath = projFileInfo.canonicalFilePath();
1485 if ( !relativeBasePath.isNull() )
1487 projPath = relativeBasePath;
1490 if ( projPath.isEmpty() )
1497 if ( ! vsiPrefix.isEmpty() )
1499 srcPath.remove( 0, vsiPrefix.size() );
1502 #if defined( Q_OS_WIN ) 1503 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
1505 srcPath.replace(
"\\",
"/" );
1507 if ( srcPath.startsWith(
"//" ) )
1510 srcPath =
"\\\\" + srcPath.mid( 2 );
1513 projPath.replace(
"\\",
"/" );
1514 if ( projPath.startsWith(
"//" ) )
1517 projPath =
"\\\\" + projPath.mid( 2 );
1520 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
1523 QStringList projElems = projPath.split(
"/", QString::SkipEmptyParts );
1524 QStringList srcElems = srcPath.split(
"/", QString::SkipEmptyParts );
1527 projElems.removeLast();
1529 projElems.removeAll(
"." );
1530 srcElems.removeAll(
"." );
1534 while ( srcElems.size() > 0 &&
1535 projElems.size() > 0 &&
1536 srcElems[0].compare( projElems[0], cs ) == 0 )
1538 srcElems.removeFirst();
1539 projElems.removeFirst();
1549 if ( projElems.size() > 0 )
1552 for (
int i = 0; i < projElems.size(); i++ )
1554 srcElems.insert( 0,
".." );
1561 srcElems.insert( 0,
"." );
1564 return vsiPrefix + srcElems.join(
"/" );
1569 mErrorMessage = errorMessage;
1574 return mErrorMessage;
1584 delete mBadLayerHandler;
1585 mBadLayerHandler = handler;
1590 QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
1591 if ( it == mEmbeddedLayers.constEnd() )
1595 return it.value().first;
1599 QList< QPair< QgsVectorLayer*, QDomElement > > &vectorLayerList,
bool saveFlag )
1603 static QString prevProjectFilePath;
1604 static QDomDocument projectDocument;
1606 if ( projectFilePath != prevProjectFilePath )
1608 prevProjectFilePath.clear();
1610 QFile projectFile( projectFilePath );
1611 if ( !projectFile.open( QIODevice::ReadOnly ) )
1616 if ( !projectDocument.setContent( &projectFile ) )
1621 prevProjectFilePath = projectFilePath;
1625 bool useAbsolutePathes =
true;
1627 QDomElement propertiesElem = projectDocument.documentElement().firstChildElement(
"properties" );
1628 if ( !propertiesElem.isNull() )
1630 QDomElement absElem = propertiesElem.firstChildElement(
"Paths" ).firstChildElement(
"Absolute" );
1631 if ( !absElem.isNull() )
1633 useAbsolutePathes = absElem.text().compare(
"true", Qt::CaseInsensitive ) == 0;
1637 QDomElement projectLayersElem = projectDocument.documentElement().firstChildElement(
"projectlayers" );
1638 if ( projectLayersElem.isNull() )
1643 QDomNodeList mapLayerNodes = projectLayersElem.elementsByTagName(
"maplayer" );
1644 for (
int i = 0; i < mapLayerNodes.size(); ++i )
1647 QDomElement mapLayerElem = mapLayerNodes.at( i ).toElement();
1648 QString
id = mapLayerElem.firstChildElement(
"id" ).text();
1649 if (
id == layerId )
1652 if ( mapLayerElem.attribute(
"embedded" ) ==
"1" )
1657 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
1660 if ( !useAbsolutePathes )
1662 QDomElement provider = mapLayerElem.firstChildElement(
"provider" );
1663 if ( provider.text() ==
"spatialite" )
1665 QDomElement dsElem = mapLayerElem.firstChildElement(
"datasource" );
1669 QFileInfo absoluteDs( QFileInfo( projectFilePath ).absolutePath() +
"/" + uri.database() );
1670 if ( absoluteDs.exists() )
1673 dsElem.removeChild( dsElem.childNodes().at( 0 ) );
1674 dsElem.appendChild( projectDocument.createTextNode( uri.uri() ) );
1679 QDomElement dsElem = mapLayerElem.firstChildElement(
"datasource" );
1680 QString debug( QFileInfo( projectFilePath ).absolutePath() +
"/" + dsElem.text() );
1681 QFileInfo absoluteDs( QFileInfo( projectFilePath ).absolutePath() +
"/" + dsElem.text() );
1682 if ( absoluteDs.exists() )
1684 dsElem.removeChild( dsElem.childNodes().at( 0 ) );
1685 dsElem.appendChild( projectDocument.createTextNode( absoluteDs.absoluteFilePath() ) );
1690 if (
addLayer( mapLayerElem, brokenNodes, vectorLayerList ) )
1696 mEmbeddedLayers.remove( layerId );
1709 QFile projectFile( projectFilePath );
1710 if ( !projectFile.open( QIODevice::ReadOnly ) )
1715 QDomDocument projectDocument;
1716 if ( !projectDocument.setContent( &projectFile ) )
1722 QSet<QString> embeddedIdentifyDisabledLayers;
1723 QDomElement disabledLayersElem = projectDocument.documentElement().firstChildElement(
"properties" ).firstChildElement(
"Identify" ).firstChildElement(
"disabledLayers" );
1724 if ( !disabledLayersElem.isNull() )
1726 QDomNodeList valueList = disabledLayersElem.elementsByTagName(
"value" );
1727 for (
int i = 0; i < valueList.size(); ++i )
1729 embeddedIdentifyDisabledLayers.insert( valueList.at( i ).toElement().text() );
1735 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement(
"layer-tree-group" );
1736 if ( !layerTreeElem.isNull() )
1746 if ( !group || group->customProperty(
"embedded" ).toBool() )
1762 mLayerTreeRegistryBridge->setEnabled(
false );
1764 mLayerTreeRegistryBridge->setEnabled(
true );
1769 if ( embeddedIdentifyDisabledLayers.contains( layerId ) )
1772 thisProjectIdentifyDisabledLayers.append( layerId );
1779 layer->
setVisible( invisibleLayers.contains( layerId ) ? Qt::Unchecked : Qt::Checked );
1800 QList<QDomNode> brokenNodes;
1801 QList< QPair< QgsVectorLayer*, QDomElement > > vectorLayerList;
1809 QStringList layerIdList, enabledList, snapTypeList, toleranceUnitList, toleranceList, avoidIntersectionList;
1810 snapSettings( layerIdList, enabledList, snapTypeList, toleranceUnitList, toleranceList, avoidIntersectionList );
1811 int idx = layerIdList.indexOf( layerId );
1814 layerIdList.removeAt( idx );
1815 enabledList.removeAt( idx );
1816 snapTypeList.removeAt( idx );
1817 toleranceUnitList.removeAt( idx );
1818 toleranceList.removeAt( idx );
1819 avoidIntersectionList.removeOne( layerId );
1822 layerIdList.append( layerId );
1825 enabledList.append( enabled ?
"enabled" :
"disabled" );
1831 typeString =
"to_segment";
1835 typeString =
"to_vertex_and_segment";
1839 typeString =
"to_vertex";
1841 snapTypeList.append( typeString );
1844 toleranceUnitList.append( QString::number( unit ) );
1847 toleranceList.append( QString::number( tolerance ) );
1850 if ( avoidIntersection )
1852 avoidIntersectionList.append( layerId );
1855 writeEntry(
"Digitizing",
"/LayerSnappingList", layerIdList );
1856 writeEntry(
"Digitizing",
"/LayerSnappingEnabledList", enabledList );
1857 writeEntry(
"Digitizing",
"/LayerSnappingToleranceList", toleranceList );
1858 writeEntry(
"Digitizing",
"/LayerSnappingToleranceUnitList", toleranceUnitList );
1859 writeEntry(
"Digitizing",
"/LayerSnapToList", snapTypeList );
1860 writeEntry(
"Digitizing",
"/AvoidIntersectionsList", avoidIntersectionList );
1865 bool &avoidIntersection )
const 1867 QStringList layerIdList, enabledList, snapTypeList, toleranceUnitList, toleranceList, avoidIntersectionList;
1868 snapSettings( layerIdList, enabledList, snapTypeList, toleranceUnitList, toleranceList, avoidIntersectionList );
1869 int idx = layerIdList.indexOf( layerId );
1876 int minListEntries = idx + 1;
1877 if ( layerIdList.size() < minListEntries || enabledList.size() < minListEntries || snapTypeList.size() < minListEntries ||
1878 toleranceUnitList.size() < minListEntries || toleranceList.size() < minListEntries )
1884 enabled = enabledList.at( idx ) ==
"enabled";
1887 QString snapType = snapTypeList.at( idx );
1888 if ( snapType ==
"to_segment" )
1892 else if ( snapType ==
"to_vertex_and_segment" )
1902 if ( toleranceUnitList.at( idx ) ==
"1" )
1906 else if ( toleranceUnitList.at( idx ) ==
"2" )
1916 tolerance = toleranceList.at( idx ).toDouble();
1919 avoidIntersection = ( avoidIntersectionList.indexOf( layerId ) != -1 );
1924 void QgsProject::snapSettings( QStringList &layerIdList, QStringList &enabledList, QStringList &snapTypeList, QStringList &toleranceUnitList, QStringList &toleranceList,
1925 QStringList &avoidIntersectionList )
const 1927 layerIdList =
readListEntry(
"Digitizing",
"/LayerSnappingList" );
1928 enabledList =
readListEntry(
"Digitizing",
"/LayerSnappingEnabledList" );
1929 toleranceList =
readListEntry(
"Digitizing",
"/LayerSnappingToleranceList" );
1930 toleranceUnitList =
readListEntry(
"Digitizing",
"/LayerSnappingToleranceUnitList" );
1931 snapTypeList =
readListEntry(
"Digitizing",
"/LayerSnapToList" );
1932 avoidIntersectionList =
readListEntry(
"Digitizing",
"/AvoidIntersectionsList" );
1954 if ( !pfi.exists() )
1955 return QString::null;
1957 return pfi.canonicalPath();
1962 return mRelationManager;
virtual void handleBadLayers(QList< QDomNode > layers, QDomDocument projectDom) override
static const char * QGIS_VERSION
Layer tree group node serves as a container for layers and further groups.
bool topologicalEditing() const
Convenience function to query topological editing status.
static QgsProperty * findKey_(QString const &scope, QString const &key, QgsPropertyKey &rootProperty)
return the property that matches the given key sequence, if any
Base class for all map layer types.
static void removeInvalidLayers(QgsLayerTreeGroup *group)
Remove layer nodes that refer to invalid layers.
const QList< QgsVectorJoinInfo > vectorJoins() const
QString writePath(QString filename, QString relativeBasePath=QString::null) const
prepare a filename to save it to the project file
QgsPluginLayer * createLayer(QString typeName)
return new layer if corresponding plugin has been found, else return NULL
void readChildrenFromXML(QDomElement &element)
Read children from XML and append them to the group.
QgsPropertyKey properties_
QgsPropertyKey * addKey(const QString &keyName)
add the given property key
void setTopologicalEditing(bool enabled)
Convenience function to set topological editing.
bool writeLayerXML(QDomElement &layerElement, QDomDocument &document, QString relativeBasePath=QString::null)
stores state in Dom node
bool snapSettingsForLayer(const QString &layerId, bool &enabled, QgsSnapper::SnappingType &type, QgsTolerance::UnitType &units, double &tolerance, bool &avoidIntersection) const
Convenience function to query snap settings of a layer.
void entryList(QStringList &entries) const
return keys that do not contain other keys
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
static void _getProperties(QDomDocument const &doc, QgsPropertyKey &project_properties)
Restore any optional properties found in "doc" to "properties".
QgsPropertyValue * setValue(const QString &name, const QVariant &value)
set the value associated with this key
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
virtual QgsLayerTreeNode * clone() const =0
Create a copy of the node. Returns new instance.
static QgsProperty * addKey_(QString const &scope, QString const &key, QgsPropertyKey *rootProperty, QVariant value)
add the given key and value
static void warning(const QString &msg)
Goes to qWarning.
void oldProjectVersionWarning(QString)
emitted when an old project file is read.
void setDatabase(const QString &database)
Set database.
static QgsMapLayerRegistry * instance()
static bool readOldLegend(QgsLayerTreeGroup *root, const QDomElement &legendElem)
Try to load layer tree from.
void setFileName(const QString &name)
Every project has an associated file that contains its XML.
UnitType
Type of unit of tolerance value from settings.
QString qgsVsiPrefix(QString path)
QString layerIsEmbedded(const QString &id) const
Returns project file path if layer is embedded from other project file.
void setSnapSettingsForLayer(const QString &layerId, bool enabled, QgsSnapper::SnappingType type, QgsTolerance::UnitType unit, double tolerance, bool avoidIntersection)
Convenience function to set snap settings per layer.
QString homePath() const
Return project's home path.
void clear()
clear project properties when a new project is started
static void _getTitle(QDomDocument const &doc, QString &title)
Get the project title.
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=0) const
void insertChildNodes(int index, QList< QgsLayerTreeNode * > nodes)
Insert existing nodes at specified position. The nodes must not have a parent yet. The nodes will be owned by this group.
void setDirty(bool b)
Set project as dirty (modified).
void projectSaved()
emitted when the project file has been written and closed
void loadEmbeddedNodes(QgsLayerTreeGroup *group)
QString readPath(QString filename) const
turn filename read from the project file to an absolute path
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=0) const
virtual void writeXML(QDomElement &parentElement)=0
Write layer tree to XML.
QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is ...
SnappingType
Snap to vertex, to segment or both.
bool writeEntry(const QString &scope, const QString &key, bool value)
QStringList readListEntry(const QString &scope, const QString &key, QStringList def=QStringList(), bool *ok=0) const
key value accessors
bool createEmbeddedLayer(const QString &layerId, const QString &projectFilePath, QList< QDomNode > &brokenNodes, QList< QPair< QgsVectorLayer *, QDomElement > > &vectorLayerList, bool saveFlag=true)
Creates a maplayer instance defined in an arbitrary project file.
bool read()
presuming that the caller has already reset the map canvas, map registry, and legend ...
static QgsProjectVersion _getVersion(QDomDocument const &doc)
return the version string found in the given Dom document
void removeKey(const QString &keyName)
remove the given key
QStringList subkeyList(const QString &scope, const QString &key) const
return keys with keys – do not return keys that contain only values
void initializeEmbeddedSubtree(const QString &projectFilePath, QgsLayerTreeGroup *group)
Pixels unit of tolerance.
QList< QgsMapLayer * > addMapLayers(QList< QgsMapLayer * > theMapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
virtual void clearKeys()
delete any sub-nodes
A class to describe the version of a project.
void setBadLayerHandler(QgsProjectBadLayerHandler *handler)
Change handler for missing layers.
void readProject(const QDomDocument &)
emitted when project is being read
Listens to the updates in map layer registry and does changes in layer tree.
static void replaceChildrenOfEmbeddedGroups(QgsLayerTreeGroup *group)
Remove subtree of embedded groups and replaces it with a custom property embedded-visible-layers.
void layerLoaded(int i, int n)
emitted when a layer from a projects was read
QString fileName() const
returns file name
This class is a base class for nodes in a layer tree.
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
bool removeEntry(const QString &scope, const QString &key)
remove the given key
static void updateEmbeddedGroupsProjectPath(QgsLayerTreeGroup *group)
Reads and writes project states.
void setVisible(Qt::CheckState visible)
void writeMapLayer(QgsMapLayer *mapLayer, QDomElement &layerElem, QDomDocument &doc)
Emitted, when a layer is being saved.
QString error() const
Return error message from previous read/write.
QString name() const
Get group's name.
QList< QgsLayerTreeNode * > children()
Get list of children of the node. Children are owned by the parent.
bool isLayer(QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
An Abstract Base Class for QGIS project property hierarchies.
double readDoubleEntry(const QString &scope, const QString &key, double def=0, bool *ok=0) const
QgsProperty * find(QString &propertyName)
Class for storing the component parts of a PostgreSQL/RDBMS datasource URI.
void subkeyList(QStringList &entries) const
return keys that contain other keys
QgsLayerTreeGroup * createEmbeddedGroup(const QString &groupName, const QString &projectFilePath, const QStringList &invisibleLayers)
Create layer group instance defined in an arbitrary project file.
void clearError()
Clear error message.
void setError(QString errorMessage)
Set error message from read/write operation.
bool isDirty() const
the dirty flag is true if the project has been modified since the last write()
bool addLayer(const QDomElement &layerElem, QList< QDomNode > &brokenNodes, QList< QPair< QgsVectorLayer *, QDomElement > > &vectorLayerList)
void writeProject(QDomDocument &)
emitted when project is being written
QString readEntry(const QString &scope, const QString &key, const QString &def=QString::null, bool *ok=0) const
QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is ...
This class manages a set of relations between layers.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes. Searches recursively the whole sub-tree.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name. Searches recursively the whole sub-tree.
static QgsProject * instance()
access to canonical QgsProject instance
static void removeKey_(QString const &scope, QString const &key, QgsPropertyKey &rootProperty)
void setTitle(const QString &title)
Set project title.
void loadingLayer(QString)
const QMap< QString, QgsMapLayer * > & mapLayers()
Retrieve the mapLayers collection (mainly intended for use by projection)
bool readXML(QDomNode &keyNode) override
restores property hierarchy to given Dom node
QStringList entryList(const QString &scope, const QString &key) const
return keys with values – do not return keys that contain other keys
QgsLayerTreeLayer * findLayer(const QString &layerId) const
Find layer node representing the map layer specified by its ID. Searches recursively the whole sub-tr...
bool readLayerXML(const QDomElement &layerElement)
sets state from Dom document
const QString & title() const
returns title
void dumpProperties() const
dump out current project properties to stderr
void clearProperties()
removes all project properties
static QgsPluginLayerRegistry * instance()
means of accessing canonical single instance
static QStringList makeKeyTokens_(QString const &scope, QString const &key)
Take the given scope and key and convert them to a string list of key tokens that will be used to nav...
const QString & name() const
every key has a name
void readMapLayer(QgsMapLayer *mapLayer, const QDomElement &layerNode)
Emitted, after the basic initialisation of a layer from the project file is done. ...
QgsLayerTreeGroup * layerTreeRoot() const
Return pointer to the root (invisible) node of the project's layer tree.
Default bad layer handler which ignores any missing layers.
virtual bool isKey() const =0
returns true if is a QgsPropertyKey
Represents a vector layer which manages a vector based data sets.
QgsRelationManager * relationManager() const
bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
virtual bool isValue() const =0
returns true if is a QgsPropertyValue
static void dump_(QgsPropertyKey const &topQgsPropertyKey)
void clear()
Clear the project.
Interface for classes that handle missing layer files when reading project file.
Layer tree node points to a map layer.
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the node.
void dump(int tabs=0) const override
dumps out the keys and values
void snapSettingsChanged()