Skip to content

Commit

Permalink
fix .qml file loading in /vsigzip and /vsizip items
Browse files Browse the repository at this point in the history
  • Loading branch information
etiennesky committed Apr 25, 2012
1 parent 66e3fcb commit 2bd054c
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 98 deletions.
25 changes: 17 additions & 8 deletions python/core/qgsmaplayer.sip
Expand Up @@ -181,7 +181,7 @@ public:
void removeCustomProperty( const QString& key );

/** Read the symbology for the current layer from the Dom node supplied.
* @param QDomNode node that will contain the symbology definition for this layer.
* @param node node that will contain the symbology definition for this layer.
* @param errorMessage reference to string that will be updated with any error messages
* @return true in case of success.
*/
Expand Down Expand Up @@ -244,10 +244,19 @@ public:
/** A convenience function to capitalise the layer name */
static QString capitaliseLayerName(const QString name);

/** Retrieve the default style for this layer if one
/** Retrieve the style URI for this layer
* (either as a .qml file on disk or as a
* record in the users style table in their personal qgis.db)
* @return a QString withe the style file name
* @see also loadNamedStyle () and saveNamedStyle ();
* @note This method was added in QGIS 1.8
*/
virtual QString styleURI( );

/** Retrieve the default style for this layer if one
* exists (either as a .qml file on disk or as a
* record in the users style table in their personal qgis.db)
* @param a reference to a flag that will be set to false if
* @param theResultFlag a reference to a flag that will be set to false if
* we did not manage to load the default style.
* @return a QString with any status messages
* @see also loadNamedStyle ();
Expand All @@ -257,12 +266,12 @@ public:
/** Retrieve a named style for this layer if one
* exists (either as a .qml file on disk or as a
* record in the users style table in their personal qgis.db)
* @param QString theURI - the file name or other URI for the
* @param theURI - the file name or other URI for the
* style file. First an attempt will be made to see if this
* is a file and load that, if that fails the qgis.db styles
* table will be consulted to see if there is a style who's
* key matches the URI.
* @param a reference to a flag that will be set to false if
* @param theResultFlag a reference to a flag that will be set to false if
* we did not manage to load the default style.
* @return a QString with any status messages
* @see also loadDefaultStyle ();
Expand All @@ -274,7 +283,7 @@ public:
/** Save the properties of this layer as the default style
* (either as a .qml file on disk or as a
* record in the users style table in their personal qgis.db)
* @param a reference to a flag that will be set to false if
* @param theResultFlag a reference to a flag that will be set to false if
* we did not manage to save the default style.
* @return a QString with any status messages
* @see also loadNamedStyle () and saveNamedStyle()
Expand All @@ -284,12 +293,12 @@ public:
/** Save the properties of this layer as a named style
* (either as a .qml file on disk or as a
* record in the users style table in their personal qgis.db)
* @param QString theURI - the file name or other URI for the
* @param theURI - the file name or other URI for the
* style file. First an attempt will be made to see if this
* is a file and save to that, if that fails the qgis.db styles
* table will be used to create a style entry who's
* key matches the URI.
* @param a reference to a flag that will be set to false if
* @param theResultFlag a reference to a flag that will be set to false if
* we did not manage to save the default style.
* @return a QString with any status messages
* @see also saveDefaultStyle ();
Expand Down
43 changes: 27 additions & 16 deletions src/core/qgsdataitem.cpp
Expand Up @@ -469,8 +469,7 @@ QVector<QgsDataItem*> QgsDirectoryItem::createChildren( )
QString path = dir.absoluteFilePath( name );
QFileInfo fileInfo( path );

// vsizip support was added to GDAL/OGR 1.6 but this symbol not available here
// #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1600
// vsizip support was added to GDAL/OGR 1.6 but GDAL_VERSION_NUM not available here
if ( fileInfo.suffix() == "zip" && scanZip )
{
QgsDataItem * item = QgsZipItem::itemFromPath( this, path, name );
Expand All @@ -480,7 +479,6 @@ QVector<QgsDataItem*> QgsDirectoryItem::createChildren( )
continue;
}
}
// #endif

foreach( QLibrary *library, mLibraries )
{
Expand Down Expand Up @@ -780,13 +778,14 @@ QgsZipItem::~QgsZipItem()
QVector<QgsDataItem*> QgsZipItem::createChildren( )
{
QVector<QgsDataItem*> children;
QStringList zipFileList;
QString tmpPath;
QString childPath;

QSettings settings;
int scanZipSetting = settings.value( "/qgis/scanZipInBrowser", 1 ).toInt();

mZipFileList.clear();

QgsDebugMsg( QString( "path = %1 name= %2 scanZipSetting= %3" ).arg( path() ).arg( name() ).arg( scanZipSetting ) );

// if scanZipBrowser == 0 (No): skip to the next file
Expand All @@ -804,7 +803,7 @@ QVector<QgsDataItem*> QgsZipItem::createChildren( )
}
#endif

// if scanZipBrowser == 1 (Passthru): do not scan zip and allow to open directly with /vsigzip/
// if scanZipBrowser == 1 (Passthru): do not scan zip and allow to open directly with /vsizip/
if ( scanZipSetting == 1 )
{
mPath = "/vsizip/" + path(); // should check for extension
Expand All @@ -827,10 +826,10 @@ QVector<QgsDataItem*> QgsZipItem::createChildren( )
tmpPath = zip.getCurrentFileName();
// skip directories (files ending with /)
if ( tmpPath.right( 1 ) != "/" )
zipFileList << tmpPath;
mZipFileList << tmpPath;
}
zip.close();
}
zip.close();
if ( zip.getZipError() != UNZ_OK )
{
QgsDebugMsg( QString( "Zip error: %1" ).arg( zip.getZipError() ) );
Expand All @@ -840,7 +839,7 @@ QVector<QgsDataItem*> QgsZipItem::createChildren( )
#endif

// loop over files inside zip
foreach( QString fileName, zipFileList )
foreach( QString fileName, mZipFileList )
{
QFileInfo info( fileName );
tmpPath = "/vsizip/" + path() + "/" + fileName;
Expand All @@ -854,7 +853,7 @@ QVector<QgsDataItem*> QgsZipItem::createChildren( )
{
if ( info.suffix() == "dbf" )
{
if ( zipFileList.indexOf( fileName.left( fileName.count() - 4 ) + ".shp" ) != -1 )
if ( mZipFileList.indexOf( fileName.left( fileName.count() - 4 ) + ".shp" ) != -1 )
continue;
}
if ( info.completeSuffix().toLower() == "shp.xml" )
Expand Down Expand Up @@ -901,8 +900,9 @@ QgsDataItem* QgsZipItem::itemFromPath( QgsDataItem* parent, QString path, QStrin

QSettings settings;
int scanZipSetting = settings.value( "/qgis/scanZipInBrowser", 1 ).toInt();
QString vsizipPath = path;
int zipFileCount = 0;
QFileInfo fileInfo( path );
QString tmpPath = path;
QgsZipItem * zipItem = 0;

QgsDebugMsg( QString( "path = %1 name= %2 scanZipSetting= %3" ).arg( path ).arg( name ).arg( scanZipSetting ) );
Expand All @@ -912,10 +912,10 @@ QgsDataItem* QgsZipItem::itemFromPath( QgsDataItem* parent, QString path, QStrin
{
return 0;
}
// if scanZipBrowser == 1 (Passthru): do not scan zip and allow to open directly with /vsigzip/
// if scanZipBrowser == 1 (Passthru): do not scan zip and allow to open directly with /vsizip/
else if ( scanZipSetting == 1 )
{
tmpPath = "/vsizip/" + path;
vsizipPath = "/vsizip/" + path;
zipItem = 0;
}
else
Expand All @@ -937,24 +937,35 @@ QgsDataItem* QgsZipItem::itemFromPath( QgsDataItem* parent, QString path, QStrin
QgsDebugMsg( "returning zipItem" );
return zipItem;
}
// if 1 or 0 child found, create a data item using the full path given by QgsZipItem
// if 1 or 0 child found, create a single data item using the normal path or the full path given by QgsZipItem
else
{
if ( zipItem )
{
tmpPath = zipItem->path();
vsizipPath = zipItem->path();
zipFileCount = zipItem->getZipFileList().count();
delete zipItem;
}

QgsDebugMsg( QString( "will try to create a normal dataItem from path= %2" ).arg( tmpPath ) );
QgsDebugMsg( QString( "will try to create a normal dataItem from path= %2 or %3" ).arg( path ).arg( vsizipPath ) );

// try to open using registered providers (gdal and ogr)
for ( int i = 0; i < mProviderNames.size(); i++ )
{
dataItem_t *dataItem = mDataItemPtr[i];
if ( dataItem )
{
QgsDataItem *item = dataItem( tmpPath, parent );
QgsDataItem *item = 0;
// try first with normal path (Passthru)
// this is to simplify .qml handling, and without this some tests will fail
// (e.g. testZipItemVectorTransparency(), second test)
if (( scanZipSetting == 1 ) ||
( mProviderNames[i] == "ogr" ) ||
( mProviderNames[i] == "gdal" && zipFileCount == 1 ) )
item = dataItem( path, parent );
// try with /vsizip/
if ( ! item )
item = dataItem( vsizipPath, parent );
if ( item )
return item;
}
Expand Down
7 changes: 7 additions & 0 deletions src/core/qgsdataitem.h
Expand Up @@ -289,6 +289,10 @@ class CORE_EXPORT QgsFavouritesItem : public QgsDataCollectionItem
class CORE_EXPORT QgsZipItem : public QgsDataCollectionItem
{
Q_OBJECT

protected:
QStringList mZipFileList;

public:
QgsZipItem( QgsDataItem* parent, QString name, QString path );
~QgsZipItem();
Expand All @@ -302,6 +306,9 @@ class CORE_EXPORT QgsZipItem : public QgsDataCollectionItem
static QgsDataItem* itemFromPath( QgsDataItem* parent, QString path, QString name );

static const QIcon &iconZip();

const QStringList & getZipFileList() const { return mZipFileList; }

};

#endif // QGSDATAITEM_H
Expand Down
42 changes: 38 additions & 4 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -549,25 +549,57 @@ QString QgsMapLayer::capitaliseLayerName( const QString name )
return layerName;
}

QString QgsMapLayer::loadDefaultStyle( bool & theResultFlag )
QString QgsMapLayer::styleURI( )
{
QString myURI = publicSource();

// if file is using the /vsizip/ or /vsigzip/ mechanism, cleanup the name
if ( myURI.left( 9 ) == "/vsigzip/" )
{
myURI.remove( 1, 9 );
}
else if ( myURI.left( 8 ) == "/vsizip/" && myURI.right( 4 ) == ".zip" )
{
// ideally we should look for .qml file inside zip file
myURI.remove( 1, 8 );
}

QFileInfo myFileInfo( myURI );
QString key;

if ( myFileInfo.exists() )
{
// if file is using the /vsizip/ or /vsigzip/ mechanism, cleanup the name
if ( myURI.right( 3 ) == ".gz" )
{
myURI.chop( 3 );
myFileInfo.setFile( myURI );
}
else if ( myURI.right( 4 ) == ".zip" )
{
myURI.chop( 4 );
myFileInfo.setFile( myURI );
}
// get the file name for our .qml style file
key = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() + ".qml";
}
else
{
key = myURI;
key = publicSource();
}
return loadNamedStyle( key, theResultFlag );

return key;
}

QString QgsMapLayer::loadDefaultStyle( bool & theResultFlag )
{
return loadNamedStyle( styleURI(), theResultFlag );
}

bool QgsMapLayer::loadNamedStyleFromDb( const QString db, const QString theURI, QString &qml )
{
QgsDebugMsg( QString( "db = %1 uri = %2" ).arg( db ).arg( theURI ) );

bool theResultFlag = false;

// read from database
Expand Down Expand Up @@ -610,6 +642,8 @@ bool QgsMapLayer::loadNamedStyleFromDb( const QString db, const QString theURI,

QString QgsMapLayer::loadNamedStyle( const QString theURI, bool &theResultFlag )
{
QgsDebugMsg( QString( "uri = %1 myURI = %2" ).arg( theURI ).arg( publicSource() ) );

theResultFlag = false;

QDomDocument myDocument( "qgis" );
Expand Down Expand Up @@ -692,7 +726,7 @@ QString QgsMapLayer::loadNamedStyle( const QString theURI, bool &theResultFlag )

QString QgsMapLayer::saveDefaultStyle( bool & theResultFlag )
{
return saveNamedStyle( publicSource(), theResultFlag );
return saveNamedStyle( styleURI(), theResultFlag );
}

QString QgsMapLayer::saveNamedStyle( const QString theURI, bool & theResultFlag )
Expand Down
9 changes: 9 additions & 0 deletions src/core/qgsmaplayer.h
Expand Up @@ -237,6 +237,15 @@ class CORE_EXPORT QgsMapLayer : public QObject
/** A convenience function to capitalise the layer name */
static QString capitaliseLayerName( const QString name );

/** Retrieve the style URI for this layer
* (either as a .qml file on disk or as a
* record in the users style table in their personal qgis.db)
* @return a QString withe the style file name
* @see also loadNamedStyle () and saveNamedStyle ();
* @note This method was added in QGIS 1.8
*/
virtual QString styleURI( );

/** Retrieve the default style for this layer if one
* exists (either as a .qml file on disk or as a
* record in the users style table in their personal qgis.db)
Expand Down
7 changes: 7 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -2844,6 +2844,13 @@ bool QgsVectorLayer::setDataProvider( QString const & provider )
// make sure that the "observer" has been removed from URI to avoid crashes
mDataSource = mDataProvider->dataSourceUri();
}
else if ( provider == "ogr" )
{
// make sure that the /vsigzip or /vsizip is added to uri, if applicable
mDataSource = mDataProvider->dataSourceUri();
if ( mDataSource.right( 10 ) == "|layerid=0" )
mDataSource.chop( 10 );
}

// label
mLabel = new QgsLabel( mDataProvider->fields() );
Expand Down
6 changes: 6 additions & 0 deletions src/core/raster/qgsrasterlayer.cpp
Expand Up @@ -2278,6 +2278,12 @@ void QgsRasterLayer::setDataProvider( QString const & provider,
return;
}

if ( provider == "gdal" )
{
// make sure that the /vsigzip or /vsizip is added to uri, if applicable
mDataSource = mDataProvider->dataSourceUri();
}

mDataProvider->addLayers( layers, styles );
mDataProvider->setImageEncoding( format );
mDataProvider->setImageCrs( theCrs );
Expand Down

0 comments on commit 2bd054c

Please sign in to comment.