[QGIS Commit] r8587 - trunk/qgis/src/core
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Wed Jun 4 11:01:25 EDT 2008
Author: jef
Date: 2008-06-04 11:01:25 -0400 (Wed, 04 Jun 2008)
New Revision: 8587
Modified:
trunk/qgis/src/core/qgsmaplayer.cpp
Log:
save qml of non-file datasources to qgis user database
Modified: trunk/qgis/src/core/qgsmaplayer.cpp
===================================================================
--- trunk/qgis/src/core/qgsmaplayer.cpp 2008-06-04 15:00:23 UTC (rev 8586)
+++ trunk/qgis/src/core/qgsmaplayer.cpp 2008-06-04 15:01:25 UTC (rev 8587)
@@ -30,14 +30,15 @@
#include <QDomImplementation>
#include <QTextStream>
+#include <sqlite3.h>
#include "qgslogger.h"
#include "qgsrect.h"
#include "qgssymbol.h"
#include "qgsmaplayer.h"
#include "qgsspatialrefsys.h"
+#include "qgsapplication.h"
-
QgsMapLayer::QgsMapLayer(int type,
QString lyrname,
QString source) :
@@ -409,104 +410,125 @@
{
QString myURI = publicSource();
QFileInfo myFileInfo ( myURI );
- //get the file name for our .qml style file
- QString myFileName = myFileInfo.path() + QDir::separator() +
- myFileInfo.completeBaseName () + ".qml";
- return loadNamedStyle ( myFileName, theResultFlag );
+ QString key;
+ if( myFileInfo.exists() ) {
+ // get the file name for our .qml style file
+ key = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName () + ".qml";
+ } else {
+ key = myURI;
+ }
+ return loadNamedStyle ( key, theResultFlag );
}
+
QString QgsMapLayer::loadNamedStyle ( const QString theURI , bool & theResultFlag )
{
theResultFlag = false;
- //first check if its a file - we will add support for
- //database etc uris later
- QFileInfo myFileInfo ( theURI );
- if ( !myFileInfo.isFile() )
- {
- return QObject::tr( "Currently only filebased datasets are supported" );
- }
- QFile myFile ( theURI );
- if ( !myFile.open(QFile::ReadOnly ) )
- {
- return QObject::tr( "File could not been opened." );
- }
QDomDocument myDocument ( "qgis" );
+
// location of problem associated with errorMsg
int line, column;
QString myErrorMessage;
- if ( !myDocument.setContent ( &myFile, &myErrorMessage, &line, &column ) )
- {
+
+ QFile myFile ( theURI );
+ if ( myFile.open(QFile::ReadOnly ) )
+ {
+ // read file
+ theResultFlag = myDocument.setContent ( &myFile, &myErrorMessage, &line, &column );
+ if(!theResultFlag)
+ myErrorMessage = tr("%1 at line %2 column %3").arg( myErrorMessage ).arg( line ).arg(column);
myFile.close();
- return myErrorMessage + " at line " + QString::number( line ) +
- " column " + QString::number( column );
}
- else //dom parsed in ok
+ else
{
- myFile.close();
-
- // now get the layer node out and pass it over to the layer
- // to deserialise...
- QDomElement myRoot = myDocument.firstChildElement("qgis");
- if (myRoot.isNull())
+ // read from database
+ sqlite3 *myDatabase;
+ sqlite3_stmt *myPreparedStatement;
+ const char *myTail;
+ int myResult;
+
+ myResult = sqlite3_open(QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase);
+ if (myResult)
{
- myErrorMessage = "Error: qgis element could not be found in " + theURI;
- return myErrorMessage;
+ return tr("could not open user database");
}
- QDomElement myLayer = myRoot.firstChildElement("maplayer");
- if (myLayer.isNull())
+ QString mySql = "select qml from tbl_styles where style=?";
+ myResult = sqlite3_prepare(myDatabase, mySql.toUtf8().data(), mySql.length(), &myPreparedStatement, &myTail);
+ if (myResult==SQLITE_OK)
{
- myErrorMessage = "Error: maplayer element could not be found in " + theURI;
- return myErrorMessage;
+ QByteArray param = theURI.toUtf8();
+
+ if( sqlite3_bind_text(myPreparedStatement, 1, param.data(), param.length(), SQLITE_STATIC)==SQLITE_OK &&
+ sqlite3_step(myPreparedStatement)==SQLITE_ROW )
+ {
+ QString qml = QString::fromUtf8( (char *)sqlite3_column_text(myPreparedStatement, 0) );
+ theResultFlag = myDocument.setContent ( qml, &myErrorMessage, &line, &column );
+ if(!theResultFlag)
+ myErrorMessage = tr("%1 at line %2 column %3").arg( myErrorMessage ).arg( line ).arg(column);
+ }
}
-
- //
- // we need to ensure the data source matches the layers
- // current datasource not the one specified in the qml
- //
- QDomElement myDataSource = myLayer.firstChildElement("datasource");
- if (myDataSource.isNull())
+ else
{
- myErrorMessage = "Error: datasource element could not be found in " + theURI;
- return myErrorMessage;
+ theResultFlag = false;
+ myErrorMessage = tr("style %1 not found in database").arg(theURI);
}
- QDomElement myNewDataSource = myDocument.createElement( "datasource" );
- QDomText myDataSourceText = myDocument.createTextNode( source() );
- myNewDataSource.appendChild( myDataSourceText );
- myLayer.replaceChild( myNewDataSource ,
- myLayer.firstChildElement("datasource") );
- //
- // Now go on to parse the xml (QDomElement inherits QDomNode
- // so we can just pass along the element to readXML)
- //
- theResultFlag = readXML ( myLayer );
+ sqlite3_finalize(myPreparedStatement);
+ sqlite3_close(myDatabase);
+ }
- return QObject::tr( "Loaded default style file from " ) + theURI;
+ if(!theResultFlag)
+ return myErrorMessage;
+
+ // now get the layer node out and pass it over to the layer
+ // to deserialise...
+ QDomElement myRoot = myDocument.firstChildElement("qgis");
+ if (myRoot.isNull())
+ {
+ myErrorMessage = "Error: qgis element could not be found in " + theURI;
+ return myErrorMessage;
}
+
+ QDomElement myLayer = myRoot.firstChildElement("maplayer");
+ if (myLayer.isNull())
+ {
+ myErrorMessage = "Error: maplayer element could not be found in " + theURI;
+ return myErrorMessage;
+ }
+
+ //
+ // we need to ensure the data source matches the layers
+ // current datasource not the one specified in the qml
+ //
+ QDomElement myDataSource = myLayer.firstChildElement("datasource");
+ if (myDataSource.isNull())
+ {
+ myErrorMessage = "Error: datasource element could not be found in " + theURI;
+ return myErrorMessage;
+ }
+ QDomElement myNewDataSource = myDocument.createElement( "datasource" );
+ QDomText myDataSourceText = myDocument.createTextNode( source() );
+ myNewDataSource.appendChild( myDataSourceText );
+ myLayer.replaceChild( myNewDataSource, myLayer.firstChildElement("datasource") );
+
+ //
+ // Now go on to parse the xml (QDomElement inherits QDomNode
+ // so we can just pass along the element to readXML)
+ //
+ theResultFlag = readXML ( myLayer );
+
+ return QObject::tr( "Loaded default style file from " ) + theURI;
}
+
QString QgsMapLayer::saveDefaultStyle ( bool & theResultFlag )
{
- QString myURI = publicSource();
- QFileInfo myFileInfo ( myURI );
- //get the file name for our .qml style file
- QString myFileName = myFileInfo.path() + QDir::separator() +
- myFileInfo.completeBaseName () + ".qml";
- return saveNamedStyle ( myFileName, theResultFlag );
+ return saveNamedStyle ( publicSource(), theResultFlag );
}
-QString QgsMapLayer::saveNamedStyle ( const QString theURI , bool & theResultFlag )
+
+QString QgsMapLayer::saveNamedStyle ( const QString theURI, bool & theResultFlag )
{
- QFileInfo myFileInfo ( theURI );
- //now check if we can write to the dir where the layer
- //exists...
- QFileInfo myDirInfo ( myFileInfo.path() ); //excludes filename
- if ( !myDirInfo.isWritable() )
- {
- return QObject::tr( "The directory containing your dataset needs to be writeable!" );
- }
- //now construct the file name for our .qml style file
- QString myFileName = myFileInfo.path() + QDir::separator() +
- myFileInfo.completeBaseName () + ".qml";
+ QString myErrorMessage;
QDomImplementation DOMImplementation;
QDomDocumentType documentType =
@@ -518,19 +540,114 @@
myDocument.appendChild( myRootNode );
writeXML( myRootNode, myDocument );
+ // check if the uri is a file or ends with .qml,
+ // which indicates that it should become one
+ // everything else goes to the database.
+ QFileInfo myFileInfo ( theURI );
+ if ( myFileInfo.exists() || theURI.endsWith(".qml", Qt::CaseInsensitive) )
+ {
+ QFileInfo myDirInfo ( myFileInfo.path() ); //excludes filename
+ if ( !myDirInfo.isWritable() )
+ {
+ return QObject::tr( "The directory containing your dataset needs to be writeable!" );
+ }
- QFile myFile ( myFileName );
- if ( myFile.open(QFile::WriteOnly | QFile::Truncate ) )
- {
- QTextStream myFileStream( &myFile );
- // save as utf-8 with 2 spaces for indents
- myDocument.save( myFileStream, 2 );
- myFile.close();
- return QObject::tr( "Created default style file as " ) + myFileName;
+ // now construct the file name for our .qml style file
+ QString myFileName = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName () + ".qml";
+
+ QFile myFile ( myFileName );
+ if ( myFile.open(QFile::WriteOnly | QFile::Truncate ) )
+ {
+ QTextStream myFileStream( &myFile );
+ // save as utf-8 with 2 spaces for indents
+ myDocument.save( myFileStream, 2 );
+ myFile.close();
+ return QObject::tr( "Created default style file as " ) + myFileName;
+ }
+ else
+ {
+ return QObject::tr( "ERROR: Failed to created default style file as %1 Check file permissions and retry." ).arg(myFileName);
+ }
}
else
{
- return QObject::tr( "ERROR: Failed to created default style file as " ) + myFileName +
- tr( " Check file permissions and retry." );
+ QString qml = myDocument.toString();
+
+ // read from database
+ sqlite3 *myDatabase;
+ sqlite3_stmt *myPreparedStatement;
+ const char *myTail;
+ int myResult;
+
+ myResult = sqlite3_open(QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase);
+ if (myResult)
+ {
+ return tr("User database could not be opened.");
+ }
+
+ QByteArray param0 = theURI.toUtf8();
+ QByteArray param1 = qml.toUtf8();
+
+ QString mySql = "create table if not exists tbl_styles(style varchar primary key,qml varchar)";
+ myResult = sqlite3_prepare(myDatabase, mySql.toUtf8().data(), mySql.length(), &myPreparedStatement, &myTail);
+ if (myResult==SQLITE_OK)
+ {
+ if( sqlite3_step(myPreparedStatement)!=SQLITE_DONE )
+ {
+ sqlite3_finalize(myPreparedStatement);
+ sqlite3_close(myDatabase);
+ return tr("The style table could not be created.");
+ }
+ }
+
+ sqlite3_finalize(myPreparedStatement);
+
+ mySql = "insert into tbl_styles(style,qml) values (?,?)";
+ myResult = sqlite3_prepare(myDatabase, mySql.toUtf8().data(), mySql.length(), &myPreparedStatement, &myTail);
+ if (myResult==SQLITE_OK)
+ {
+ if( sqlite3_bind_text(myPreparedStatement, 1, param0.data(), param0.length(), SQLITE_STATIC)==SQLITE_OK &&
+ sqlite3_bind_text(myPreparedStatement, 2, param1.data(), param1.length(), SQLITE_STATIC)==SQLITE_OK &&
+ sqlite3_step(myPreparedStatement)==SQLITE_DONE )
+ {
+ theResultFlag = true;
+ myErrorMessage = tr("The style %1 was saved to database").arg(theURI);
+ }
+ }
+
+ sqlite3_finalize(myPreparedStatement);
+
+ if(!theResultFlag)
+ {
+ QString mySql = "update tbl_styles set qml=? where style=?";
+ myResult = sqlite3_prepare(myDatabase, mySql.toUtf8().data(), mySql.length(), &myPreparedStatement, &myTail);
+ if (myResult==SQLITE_OK)
+ {
+ if( sqlite3_bind_text(myPreparedStatement, 2, param0.data(), param0.length(), SQLITE_STATIC)==SQLITE_OK &&
+ sqlite3_bind_text(myPreparedStatement, 1, param1.data(), param1.length(), SQLITE_STATIC)==SQLITE_OK &&
+ sqlite3_step(myPreparedStatement)==SQLITE_DONE )
+ {
+ theResultFlag = true;
+ myErrorMessage = tr("The style %1 was updated in the database.").arg(theURI);
+ }
+ else
+ {
+ theResultFlag = true;
+ myErrorMessage = tr("The style %1 could not be updated in the database.").arg(theURI);
+ }
+ }
+ else
+ {
+ // try an update
+ theResultFlag = false;
+ myErrorMessage = tr("The style %1 could not be inserted into database.").arg(theURI);
+ }
+
+ sqlite3_finalize(myPreparedStatement);
+ }
+
+ sqlite3_close(myDatabase);
}
+
+ return myErrorMessage;
}
More information about the QGIS-commit
mailing list