Skip to content

Commit 2bd054c

Browse files
committedApr 25, 2012
fix .qml file loading in /vsigzip and /vsizip items
1 parent 66e3fcb commit 2bd054c

File tree

11 files changed

+204
-98
lines changed

11 files changed

+204
-98
lines changed
 

‎python/core/qgsmaplayer.sip

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public:
181181
void removeCustomProperty( const QString& key );
182182

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

247-
/** Retrieve the default style for this layer if one
247+
/** Retrieve the style URI for this layer
248+
* (either as a .qml file on disk or as a
249+
* record in the users style table in their personal qgis.db)
250+
* @return a QString withe the style file name
251+
* @see also loadNamedStyle () and saveNamedStyle ();
252+
* @note This method was added in QGIS 1.8
253+
*/
254+
virtual QString styleURI( );
255+
256+
/** Retrieve the default style for this layer if one
248257
* exists (either as a .qml file on disk or as a
249258
* record in the users style table in their personal qgis.db)
250-
* @param a reference to a flag that will be set to false if
259+
* @param theResultFlag a reference to a flag that will be set to false if
251260
* we did not manage to load the default style.
252261
* @return a QString with any status messages
253262
* @see also loadNamedStyle ();
@@ -257,12 +266,12 @@ public:
257266
/** Retrieve a named style for this layer if one
258267
* exists (either as a .qml file on disk or as a
259268
* record in the users style table in their personal qgis.db)
260-
* @param QString theURI - the file name or other URI for the
269+
* @param theURI - the file name or other URI for the
261270
* style file. First an attempt will be made to see if this
262271
* is a file and load that, if that fails the qgis.db styles
263272
* table will be consulted to see if there is a style who's
264273
* key matches the URI.
265-
* @param a reference to a flag that will be set to false if
274+
* @param theResultFlag a reference to a flag that will be set to false if
266275
* we did not manage to load the default style.
267276
* @return a QString with any status messages
268277
* @see also loadDefaultStyle ();
@@ -274,7 +283,7 @@ public:
274283
/** Save the properties of this layer as the default style
275284
* (either as a .qml file on disk or as a
276285
* record in the users style table in their personal qgis.db)
277-
* @param a reference to a flag that will be set to false if
286+
* @param theResultFlag a reference to a flag that will be set to false if
278287
* we did not manage to save the default style.
279288
* @return a QString with any status messages
280289
* @see also loadNamedStyle () and saveNamedStyle()
@@ -284,12 +293,12 @@ public:
284293
/** Save the properties of this layer as a named style
285294
* (either as a .qml file on disk or as a
286295
* record in the users style table in their personal qgis.db)
287-
* @param QString theURI - the file name or other URI for the
296+
* @param theURI - the file name or other URI for the
288297
* style file. First an attempt will be made to see if this
289298
* is a file and save to that, if that fails the qgis.db styles
290299
* table will be used to create a style entry who's
291300
* key matches the URI.
292-
* @param a reference to a flag that will be set to false if
301+
* @param theResultFlag a reference to a flag that will be set to false if
293302
* we did not manage to save the default style.
294303
* @return a QString with any status messages
295304
* @see also saveDefaultStyle ();

‎src/core/qgsdataitem.cpp

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,7 @@ QVector<QgsDataItem*> QgsDirectoryItem::createChildren( )
469469
QString path = dir.absoluteFilePath( name );
470470
QFileInfo fileInfo( path );
471471

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

485483
foreach( QLibrary *library, mLibraries )
486484
{
@@ -780,13 +778,14 @@ QgsZipItem::~QgsZipItem()
780778
QVector<QgsDataItem*> QgsZipItem::createChildren( )
781779
{
782780
QVector<QgsDataItem*> children;
783-
QStringList zipFileList;
784781
QString tmpPath;
785782
QString childPath;
786783

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

787+
mZipFileList.clear();
788+
790789
QgsDebugMsg( QString( "path = %1 name= %2 scanZipSetting= %3" ).arg( path() ).arg( name() ).arg( scanZipSetting ) );
791790

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

807-
// if scanZipBrowser == 1 (Passthru): do not scan zip and allow to open directly with /vsigzip/
806+
// if scanZipBrowser == 1 (Passthru): do not scan zip and allow to open directly with /vsizip/
808807
if ( scanZipSetting == 1 )
809808
{
810809
mPath = "/vsizip/" + path(); // should check for extension
@@ -827,10 +826,10 @@ QVector<QgsDataItem*> QgsZipItem::createChildren( )
827826
tmpPath = zip.getCurrentFileName();
828827
// skip directories (files ending with /)
829828
if ( tmpPath.right( 1 ) != "/" )
830-
zipFileList << tmpPath;
829+
mZipFileList << tmpPath;
831830
}
831+
zip.close();
832832
}
833-
zip.close();
834833
if ( zip.getZipError() != UNZ_OK )
835834
{
836835
QgsDebugMsg( QString( "Zip error: %1" ).arg( zip.getZipError() ) );
@@ -840,7 +839,7 @@ QVector<QgsDataItem*> QgsZipItem::createChildren( )
840839
#endif
841840

842841
// loop over files inside zip
843-
foreach( QString fileName, zipFileList )
842+
foreach( QString fileName, mZipFileList )
844843
{
845844
QFileInfo info( fileName );
846845
tmpPath = "/vsizip/" + path() + "/" + fileName;
@@ -854,7 +853,7 @@ QVector<QgsDataItem*> QgsZipItem::createChildren( )
854853
{
855854
if ( info.suffix() == "dbf" )
856855
{
857-
if ( zipFileList.indexOf( fileName.left( fileName.count() - 4 ) + ".shp" ) != -1 )
856+
if ( mZipFileList.indexOf( fileName.left( fileName.count() - 4 ) + ".shp" ) != -1 )
858857
continue;
859858
}
860859
if ( info.completeSuffix().toLower() == "shp.xml" )
@@ -901,8 +900,9 @@ QgsDataItem* QgsZipItem::itemFromPath( QgsDataItem* parent, QString path, QStrin
901900

902901
QSettings settings;
903902
int scanZipSetting = settings.value( "/qgis/scanZipInBrowser", 1 ).toInt();
903+
QString vsizipPath = path;
904+
int zipFileCount = 0;
904905
QFileInfo fileInfo( path );
905-
QString tmpPath = path;
906906
QgsZipItem * zipItem = 0;
907907

908908
QgsDebugMsg( QString( "path = %1 name= %2 scanZipSetting= %3" ).arg( path ).arg( name ).arg( scanZipSetting ) );
@@ -912,10 +912,10 @@ QgsDataItem* QgsZipItem::itemFromPath( QgsDataItem* parent, QString path, QStrin
912912
{
913913
return 0;
914914
}
915-
// if scanZipBrowser == 1 (Passthru): do not scan zip and allow to open directly with /vsigzip/
915+
// if scanZipBrowser == 1 (Passthru): do not scan zip and allow to open directly with /vsizip/
916916
else if ( scanZipSetting == 1 )
917917
{
918-
tmpPath = "/vsizip/" + path;
918+
vsizipPath = "/vsizip/" + path;
919919
zipItem = 0;
920920
}
921921
else
@@ -937,24 +937,35 @@ QgsDataItem* QgsZipItem::itemFromPath( QgsDataItem* parent, QString path, QStrin
937937
QgsDebugMsg( "returning zipItem" );
938938
return zipItem;
939939
}
940-
// if 1 or 0 child found, create a data item using the full path given by QgsZipItem
940+
// if 1 or 0 child found, create a single data item using the normal path or the full path given by QgsZipItem
941941
else
942942
{
943943
if ( zipItem )
944944
{
945-
tmpPath = zipItem->path();
945+
vsizipPath = zipItem->path();
946+
zipFileCount = zipItem->getZipFileList().count();
946947
delete zipItem;
947948
}
948949

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

951952
// try to open using registered providers (gdal and ogr)
952953
for ( int i = 0; i < mProviderNames.size(); i++ )
953954
{
954955
dataItem_t *dataItem = mDataItemPtr[i];
955956
if ( dataItem )
956957
{
957-
QgsDataItem *item = dataItem( tmpPath, parent );
958+
QgsDataItem *item = 0;
959+
// try first with normal path (Passthru)
960+
// this is to simplify .qml handling, and without this some tests will fail
961+
// (e.g. testZipItemVectorTransparency(), second test)
962+
if (( scanZipSetting == 1 ) ||
963+
( mProviderNames[i] == "ogr" ) ||
964+
( mProviderNames[i] == "gdal" && zipFileCount == 1 ) )
965+
item = dataItem( path, parent );
966+
// try with /vsizip/
967+
if ( ! item )
968+
item = dataItem( vsizipPath, parent );
958969
if ( item )
959970
return item;
960971
}

‎src/core/qgsdataitem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,10 @@ class CORE_EXPORT QgsFavouritesItem : public QgsDataCollectionItem
289289
class CORE_EXPORT QgsZipItem : public QgsDataCollectionItem
290290
{
291291
Q_OBJECT
292+
293+
protected:
294+
QStringList mZipFileList;
295+
292296
public:
293297
QgsZipItem( QgsDataItem* parent, QString name, QString path );
294298
~QgsZipItem();
@@ -302,6 +306,9 @@ class CORE_EXPORT QgsZipItem : public QgsDataCollectionItem
302306
static QgsDataItem* itemFromPath( QgsDataItem* parent, QString path, QString name );
303307

304308
static const QIcon &iconZip();
309+
310+
const QStringList & getZipFileList() const { return mZipFileList; }
311+
305312
};
306313

307314
#endif // QGSDATAITEM_H

‎src/core/qgsmaplayer.cpp

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -549,25 +549,57 @@ QString QgsMapLayer::capitaliseLayerName( const QString name )
549549
return layerName;
550550
}
551551

552-
QString QgsMapLayer::loadDefaultStyle( bool & theResultFlag )
552+
QString QgsMapLayer::styleURI( )
553553
{
554554
QString myURI = publicSource();
555+
556+
// if file is using the /vsizip/ or /vsigzip/ mechanism, cleanup the name
557+
if ( myURI.left( 9 ) == "/vsigzip/" )
558+
{
559+
myURI.remove( 1, 9 );
560+
}
561+
else if ( myURI.left( 8 ) == "/vsizip/" && myURI.right( 4 ) == ".zip" )
562+
{
563+
// ideally we should look for .qml file inside zip file
564+
myURI.remove( 1, 8 );
565+
}
566+
555567
QFileInfo myFileInfo( myURI );
556568
QString key;
569+
557570
if ( myFileInfo.exists() )
558571
{
572+
// if file is using the /vsizip/ or /vsigzip/ mechanism, cleanup the name
573+
if ( myURI.right( 3 ) == ".gz" )
574+
{
575+
myURI.chop( 3 );
576+
myFileInfo.setFile( myURI );
577+
}
578+
else if ( myURI.right( 4 ) == ".zip" )
579+
{
580+
myURI.chop( 4 );
581+
myFileInfo.setFile( myURI );
582+
}
559583
// get the file name for our .qml style file
560584
key = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() + ".qml";
561585
}
562586
else
563587
{
564-
key = myURI;
588+
key = publicSource();
565589
}
566-
return loadNamedStyle( key, theResultFlag );
590+
591+
return key;
592+
}
593+
594+
QString QgsMapLayer::loadDefaultStyle( bool & theResultFlag )
595+
{
596+
return loadNamedStyle( styleURI(), theResultFlag );
567597
}
568598

569599
bool QgsMapLayer::loadNamedStyleFromDb( const QString db, const QString theURI, QString &qml )
570600
{
601+
QgsDebugMsg( QString( "db = %1 uri = %2" ).arg( db ).arg( theURI ) );
602+
571603
bool theResultFlag = false;
572604

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

611643
QString QgsMapLayer::loadNamedStyle( const QString theURI, bool &theResultFlag )
612644
{
645+
QgsDebugMsg( QString( "uri = %1 myURI = %2" ).arg( theURI ).arg( publicSource() ) );
646+
613647
theResultFlag = false;
614648

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

693727
QString QgsMapLayer::saveDefaultStyle( bool & theResultFlag )
694728
{
695-
return saveNamedStyle( publicSource(), theResultFlag );
729+
return saveNamedStyle( styleURI(), theResultFlag );
696730
}
697731

698732
QString QgsMapLayer::saveNamedStyle( const QString theURI, bool & theResultFlag )

‎src/core/qgsmaplayer.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,15 @@ class CORE_EXPORT QgsMapLayer : public QObject
237237
/** A convenience function to capitalise the layer name */
238238
static QString capitaliseLayerName( const QString name );
239239

240+
/** Retrieve the style URI for this layer
241+
* (either as a .qml file on disk or as a
242+
* record in the users style table in their personal qgis.db)
243+
* @return a QString withe the style file name
244+
* @see also loadNamedStyle () and saveNamedStyle ();
245+
* @note This method was added in QGIS 1.8
246+
*/
247+
virtual QString styleURI( );
248+
240249
/** Retrieve the default style for this layer if one
241250
* exists (either as a .qml file on disk or as a
242251
* record in the users style table in their personal qgis.db)

‎src/core/qgsvectorlayer.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2844,6 +2844,13 @@ bool QgsVectorLayer::setDataProvider( QString const & provider )
28442844
// make sure that the "observer" has been removed from URI to avoid crashes
28452845
mDataSource = mDataProvider->dataSourceUri();
28462846
}
2847+
else if ( provider == "ogr" )
2848+
{
2849+
// make sure that the /vsigzip or /vsizip is added to uri, if applicable
2850+
mDataSource = mDataProvider->dataSourceUri();
2851+
if ( mDataSource.right( 10 ) == "|layerid=0" )
2852+
mDataSource.chop( 10 );
2853+
}
28472854

28482855
// label
28492856
mLabel = new QgsLabel( mDataProvider->fields() );

‎src/core/raster/qgsrasterlayer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2278,6 +2278,12 @@ void QgsRasterLayer::setDataProvider( QString const & provider,
22782278
return;
22792279
}
22802280

2281+
if ( provider == "gdal" )
2282+
{
2283+
// make sure that the /vsigzip or /vsizip is added to uri, if applicable
2284+
mDataSource = mDataProvider->dataSourceUri();
2285+
}
2286+
22812287
mDataProvider->addLayers( layers, styles );
22822288
mDataProvider->setImageEncoding( format );
22832289
mDataProvider->setImageCrs( theCrs );

0 commit comments

Comments
 (0)
Please sign in to comment.