26 #include <QDomDocument>
27 #include <QDomElement>
28 #include <QDomImplementation>
29 #include <QTextStream>
47 mTransparencyLevel( 255 ),
49 mDataSource( source ),
63 QDateTime dt = QDateTime::currentDateTime();
64 mID = lyrname + dt.toString(
"yyyyMMddhhmmsszzz" );
71 mID.replace( QRegExp(
"[\\W]" ),
"_" );
151 QDomElement element = layer_node.toElement();
158 mnl = layer_node.namedItem(
"provider" );
159 mne = mnl.toElement();
160 provider = mne.text();
163 mnl = layer_node.namedItem(
"datasource" );
164 mne = mnl.toElement();
167 if ( provider ==
"spatialite" )
173 else if ( provider ==
"ogr" )
175 QStringList theURIParts =
mDataSource.split(
"|" );
179 else if ( provider ==
"delimitedtext" )
181 QUrl urlSource = QUrl::fromEncoded(
mDataSource.toAscii() );
186 urlSource.setScheme(
"file" );
187 urlSource.setPath( file.path() );
190 QUrl urlDest = QUrl::fromLocalFile(
QgsProject::instance()->readPath( urlSource.toLocalFile() ) );
191 urlDest.setQueryItems( urlSource.queryItems() );
192 mDataSource = QString::fromAscii( urlDest.toEncoded() );
203 mnl = layer_node.namedItem(
"layername" );
204 mne = mnl.toElement();
206 QDomNode srsNode = layer_node.namedItem(
"srs" );
218 layerError = !
readXml( layer_node );
237 mnl = layer_node.namedItem(
"id" );
238 if ( ! mnl.isNull() )
240 mne = mnl.toElement();
241 if ( ! mne.isNull() && mne.text().length() > 10 )
253 mnl = layer_node.namedItem(
"layername" );
254 mne = mnl.toElement();
258 QDomNode transparencyNode = layer_node.namedItem(
"transparencyLevelInt" );
259 if ( ! transparencyNode.isNull() )
263 QDomElement myElement = transparencyNode.toElement();
285 QDomElement maplayer = document.createElement(
"maplayer" );
289 maplayer.setAttribute(
"minimumScale",
minimumScale() );
290 maplayer.setAttribute(
"maximumScale",
maximumScale() );
293 QDomElement layerId = document.createElement(
"id" );
294 QDomText layerIdText = document.createTextNode(
id() );
295 layerId.appendChild( layerIdText );
297 maplayer.appendChild( layerId );
300 QDomElement dataSource = document.createElement(
"datasource" );
314 QStringList theURIParts = src.split(
"|" );
316 src = theURIParts.join(
"|" );
318 else if ( vlayer && vlayer->
providerType() ==
"delimitedtext" )
320 QUrl urlSource = QUrl::fromEncoded( src.toAscii() );
321 QUrl urlDest = QUrl::fromLocalFile(
QgsProject::instance()->writePath( urlSource.toLocalFile() ) );
322 urlDest.setQueryItems( urlSource.queryItems() );
323 src = QString::fromAscii( urlDest.toEncoded() );
330 QDomText dataSourceText = document.createTextNode( src );
331 dataSource.appendChild( dataSourceText );
333 maplayer.appendChild( dataSource );
337 QDomElement layerName = document.createElement(
"layername" );
338 QDomText layerNameText = document.createTextNode(
name() );
339 layerName.appendChild( layerNameText );
341 maplayer.appendChild( layerName );
346 QDomElement stamp = document.createElement(
"timestamp" );
347 QDomText stampText = document.createTextNode(
timestamp().toString( Qt::ISODate ) );
348 stamp.appendChild( stampText );
349 maplayer.appendChild( stamp );
352 maplayer.appendChild( layerName );
359 QDomElement mySrsElement = document.createElement(
"srs" );
361 maplayer.appendChild( mySrsElement );
364 QDomElement transparencyLevelIntElement = document.createElement(
"transparencyLevelInt" );
365 QDomText transparencyLevelIntText = document.createTextNode( QString::number(
getTransparency() ) );
366 transparencyLevelIntElement.appendChild( transparencyLevelIntText );
367 maplayer.appendChild( transparencyLevelIntElement );
370 layer_node.appendChild( maplayer );
374 return writeXml( maplayer, document );
454 return QStringList();
501 settings.value(
"qgis/capitaliseLayerName", QVariant(
false ) ).toBool();
503 QString layerName( name );
505 if ( capitaliseLayerName )
506 layerName = layerName.left( 1 ).toUpper() + layerName.mid( 1 );
514 QFileInfo myFileInfo( myURI );
516 if ( myFileInfo.exists() )
519 key = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() +
".qml";
530 bool theResultFlag =
false;
534 sqlite3_stmt *myPreparedStatement;
538 QgsDebugMsg( QString(
"Trying to load style for \"%1\" from \"%2\"" ).arg( theURI ).arg( db ) );
540 if ( !QFile( db ).exists() )
543 myResult = sqlite3_open( db.toUtf8().data(), &myDatabase );
544 if ( myResult != SQLITE_OK )
549 QString mySql =
"select qml from tbl_styles where style=?";
550 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8().data(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
551 if ( myResult == SQLITE_OK )
553 QByteArray param = theURI.toUtf8();
555 if ( sqlite3_bind_text( myPreparedStatement, 1, param.data(), param.length(), SQLITE_STATIC ) == SQLITE_OK &&
556 sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
558 qml = QString::fromUtf8((
char * )sqlite3_column_text( myPreparedStatement, 0 ) );
559 theResultFlag =
true;
562 sqlite3_finalize( myPreparedStatement );
565 sqlite3_close( myDatabase );
567 return theResultFlag;
572 theResultFlag =
false;
574 QDomDocument myDocument(
"qgis" );
578 QString myErrorMessage;
580 QFile myFile( theURI );
581 if ( myFile.open( QFile::ReadOnly ) )
584 theResultFlag = myDocument.setContent( &myFile, &myErrorMessage, &line, &column );
585 if ( !theResultFlag )
586 myErrorMessage = tr(
"%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
592 QgsDebugMsg( QString(
"project fileName: %1" ).arg( project.absoluteFilePath() ) );
596 ( project.exists() &&
loadNamedStyleFromDb( project.absoluteDir().absoluteFilePath( project.baseName() +
".qmldb" ), theURI, qml ) ) ||
599 theResultFlag = myDocument.setContent( qml, &myErrorMessage, &line, &column );
600 if ( !theResultFlag )
602 myErrorMessage = tr(
"%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
607 myErrorMessage = tr(
"style not found in database" );
611 if ( !theResultFlag )
613 return myErrorMessage;
618 QDomElement myRoot = myDocument.firstChildElement(
"qgis" );
619 if ( myRoot.isNull() )
621 myErrorMessage = tr(
"Error: qgis element could not be found in %1" ).arg( theURI );
622 theResultFlag =
false;
623 return myErrorMessage;
632 QDomNode transparencyNode = myRoot.namedItem(
"transparencyLevelInt" );
633 if ( ! transparencyNode.isNull() )
637 QDomElement myElement = transparencyNode.toElement();
643 if ( !theResultFlag )
645 myErrorMessage = tr(
"Loading style file %1 failed because:\n%2" ).arg( theURI ).arg( errorMsg );
646 return myErrorMessage;
659 QString myErrorMessage;
661 QDomImplementation DomImplementation;
662 QDomDocumentType documentType =
663 DomImplementation.createDocumentType(
664 "qgis",
"http://mrcc.com/qgis.dtd",
"SYSTEM" );
665 QDomDocument myDocument( documentType );
666 QDomElement myRootNode = myDocument.createElement(
"qgis" );
668 myDocument.appendChild( myRootNode );
672 myRootNode.setAttribute(
"minimumScale",
minimumScale() );
673 myRootNode.setAttribute(
"maximumScale",
maximumScale() );
676 QDomElement transparencyLevelIntElement = myDocument.createElement(
"transparencyLevelInt" );
677 QDomText transparencyLevelIntText = myDocument.createTextNode( QString::number(
getTransparency() ) );
678 transparencyLevelIntElement.appendChild( transparencyLevelIntText );
679 myRootNode.appendChild( transparencyLevelIntElement );
685 return tr(
"Could not save symbology because:\n%1" ).arg( errorMsg );
696 QStringList theURIParts = theURI.split(
"|" );
697 filename = theURIParts[0];
699 else if ( vlayer && vlayer->
providerType() ==
"delimitedtext" )
701 filename = QUrl::fromEncoded( theURI.toAscii() ).toLocalFile();
708 QFileInfo myFileInfo( filename );
709 if ( myFileInfo.exists() || filename.endsWith(
".qml", Qt::CaseInsensitive ) )
711 QFileInfo myDirInfo( myFileInfo.path() );
712 if ( !myDirInfo.isWritable() )
714 return tr(
"The directory containing your dataset needs to be writeable!" );
718 QString myFileName = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() +
".qml";
720 QFile myFile( myFileName );
721 if ( myFile.open( QFile::WriteOnly | QFile::Truncate ) )
723 QTextStream myFileStream( &myFile );
725 myDocument.save( myFileStream, 2 );
727 theResultFlag =
true;
728 return tr(
"Created default style file as %1" ).arg( myFileName );
732 theResultFlag =
false;
733 return tr(
"ERROR: Failed to created default style file as %1. Check file permissions and retry." ).arg( myFileName );
738 QString qml = myDocument.toString();
742 sqlite3_stmt *myPreparedStatement;
747 if ( myResult != SQLITE_OK )
749 return tr(
"User database could not be opened." );
752 QByteArray param0 = theURI.toUtf8();
753 QByteArray param1 = qml.toUtf8();
755 QString mySql =
"create table if not exists tbl_styles(style varchar primary key,qml varchar)";
756 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8().data(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
757 if ( myResult == SQLITE_OK )
759 if ( sqlite3_step( myPreparedStatement ) != SQLITE_DONE )
761 sqlite3_finalize( myPreparedStatement );
762 sqlite3_close( myDatabase );
763 theResultFlag =
false;
764 return tr(
"The style table could not be created." );
768 sqlite3_finalize( myPreparedStatement );
770 mySql =
"insert into tbl_styles(style,qml) values (?,?)";
771 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8().data(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
772 if ( myResult == SQLITE_OK )
774 if ( sqlite3_bind_text( myPreparedStatement, 1, param0.data(), param0.length(), SQLITE_STATIC ) == SQLITE_OK &&
775 sqlite3_bind_text( myPreparedStatement, 2, param1.data(), param1.length(), SQLITE_STATIC ) == SQLITE_OK &&
776 sqlite3_step( myPreparedStatement ) == SQLITE_DONE )
778 theResultFlag =
true;
779 myErrorMessage = tr(
"The style %1 was saved to database" ).arg( theURI );
783 sqlite3_finalize( myPreparedStatement );
785 if ( !theResultFlag )
787 QString mySql =
"update tbl_styles set qml=? where style=?";
788 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8().data(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
789 if ( myResult == SQLITE_OK )
791 if ( sqlite3_bind_text( myPreparedStatement, 2, param0.data(), param0.length(), SQLITE_STATIC ) == SQLITE_OK &&
792 sqlite3_bind_text( myPreparedStatement, 1, param1.data(), param1.length(), SQLITE_STATIC ) == SQLITE_OK &&
793 sqlite3_step( myPreparedStatement ) == SQLITE_DONE )
795 theResultFlag =
true;
796 myErrorMessage = tr(
"The style %1 was updated in the database." ).arg( theURI );
800 theResultFlag =
false;
801 myErrorMessage = tr(
"The style %1 could not be updated in the database." ).arg( theURI );
806 theResultFlag =
false;
807 myErrorMessage = tr(
"The style %1 could not be inserted into database." ).arg( theURI );
810 sqlite3_finalize( myPreparedStatement );
813 sqlite3_close( myDatabase );
816 return myErrorMessage;
845 QDomNode propsNode = layerNode.namedItem(
"customproperties" );
846 if ( propsNode.isNull() )
849 if ( !keyStartsWith.isEmpty() )
852 QStringList keysToRemove;
856 if ( pIt.key().startsWith( keyStartsWith ) )
858 keysToRemove.push_back( pIt.key() );
862 QStringList::const_iterator sIt = keysToRemove.constBegin();
863 for ( ; sIt != keysToRemove.constEnd(); ++sIt )
873 QDomNodeList nodes = propsNode.childNodes();
875 for (
int i = 0; i < nodes.size(); i++ )
877 QDomNode propNode = nodes.at( i );
878 if ( propNode.isNull() || propNode.nodeName() !=
"property" )
880 QDomElement propElement = propNode.toElement();
882 QString key = propElement.attribute(
"key" );
883 if ( key.isEmpty() || key.startsWith( keyStartsWith ) )
885 QString value = propElement.attribute(
"value" );
895 QDomNodeList propertyList = layerNode.toElement().elementsByTagName(
"customproperties" );
896 for (
int i = 0; i < propertyList.size(); ++i )
898 layerNode.removeChild( propertyList.at( i ) );
901 QDomElement propsElement = doc.createElement(
"customproperties" );
905 QDomElement propElement = doc.createElement(
"property" );
906 propElement.setAttribute(
"key", it.key() );
907 propElement.setAttribute(
"value", it.value().toString() );
908 propsElement.appendChild( propElement );
911 layerNode.appendChild( propsElement );