Skip to content

Commit c5f6e6f

Browse files
author
wonder
committedDec 8, 2009
Symbology-NG: support for additional SVG paths - fix for #2157
git-svn-id: http://svn.osgeo.org/qgis/trunk@12365 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 3b477fd commit c5f6e6f

File tree

3 files changed

+146
-49
lines changed

3 files changed

+146
-49
lines changed
 

‎src/core/symbology-ng/qgsmarkersymbollayerv2.cpp

Lines changed: 108 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
#include "qgsrendercontext.h"
66
#include "qgsapplication.h"
77
#include "qgslogger.h"
8+
#include "qgsproject.h"
89

910
#include <QPainter>
1011
#include <QSvgRenderer>
12+
#include <QFileInfo>
13+
#include <QDir>
1114

1215
#include <cmath>
1316

@@ -105,11 +108,11 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsRenderContext& context )
105108
<< QPointF( -half, -sixth )
106109
<< QPointF( -sixth, 0 )
107110
<< QPointF( -half, half )
108-
<< QPointF( 0, +sixth )
111+
<< QPointF( 0, + sixth )
109112
<< QPointF( half, half )
110-
<< QPointF( +sixth, 0 )
113+
<< QPointF( + sixth, 0 )
111114
<< QPointF( half, -sixth )
112-
<< QPointF( +sixth, -sixth );
115+
<< QPointF( + sixth, -sixth );
113116
}
114117
else if ( mName == "regular_star" )
115118
{
@@ -248,7 +251,7 @@ void QgsSimpleMarkerSymbolLayerV2::drawMarker( QPainter* p )
248251

249252
QgsSvgMarkerSymbolLayerV2::QgsSvgMarkerSymbolLayerV2( QString name, double size, double angle )
250253
{
251-
mName = name;
254+
mPath = symbolNameToPath( name );
252255
mSize = size;
253256
mAngle = angle;
254257
mOffset = QPointF( 0, 0 );
@@ -282,11 +285,8 @@ QString QgsSvgMarkerSymbolLayerV2::layerType() const
282285

283286
void QgsSvgMarkerSymbolLayerV2::startRender( QgsRenderContext& context )
284287
{
285-
QString svgPath = QgsApplication::svgPath();
286-
QString file = svgPath + "/" + mName;
287-
288288
QRectF rect( QPointF( -mSize / 2.0, -mSize / 2.0 ), QSizeF( mSize, mSize ) );
289-
QSvgRenderer renderer( file );
289+
QSvgRenderer renderer( mPath );
290290
QPainter painter( &mPicture );
291291
renderer.render( &painter, rect );
292292
}
@@ -317,7 +317,7 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsRenderCont
317317
QgsStringMap QgsSvgMarkerSymbolLayerV2::properties() const
318318
{
319319
QgsStringMap map;
320-
map["name"] = mName;
320+
map["name"] = symbolPathToName( mPath );
321321
map["size"] = QString::number( mSize );
322322
map["angle"] = QString::number( mAngle );
323323
map["offset"] = QgsSymbolLayerV2Utils::encodePoint( mOffset );
@@ -326,7 +326,105 @@ QgsStringMap QgsSvgMarkerSymbolLayerV2::properties() const
326326

327327
QgsSymbolLayerV2* QgsSvgMarkerSymbolLayerV2::clone() const
328328
{
329-
QgsSvgMarkerSymbolLayerV2* m = new QgsSvgMarkerSymbolLayerV2( mName, mSize, mAngle );
329+
QgsSvgMarkerSymbolLayerV2* m = new QgsSvgMarkerSymbolLayerV2( mPath, mSize, mAngle );
330330
m->setOffset( mOffset );
331331
return m;
332332
}
333+
334+
335+
QStringList QgsSvgMarkerSymbolLayerV2::listSvgFiles()
336+
{
337+
// copied from QgsMarkerCatalogue - TODO: unify
338+
QStringList list;
339+
QStringList svgPaths = QgsApplication::svgPaths();
340+
341+
for ( int i = 0; i < svgPaths.size(); i++ )
342+
{
343+
QDir dir( svgPaths[i] );
344+
foreach( QString item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
345+
{
346+
svgPaths.insert( i + 1, dir.path() + "/" + item );
347+
}
348+
349+
foreach( QString item, dir.entryList( QStringList( "*.svg" ), QDir::Files ) )
350+
{
351+
// TODO test if it is correct SVG
352+
list.append( dir.path() + "/" + item );
353+
}
354+
}
355+
return list;
356+
}
357+
358+
QString QgsSvgMarkerSymbolLayerV2::symbolNameToPath( QString name )
359+
{
360+
// copied from QgsSymbol::setNamedPointSymbol - TODO: unify
361+
362+
// we might have a full path...
363+
if ( QFile( name ).exists() )
364+
return QFileInfo( name ).canonicalFilePath();
365+
366+
// SVG symbol not found - probably a relative path was used
367+
368+
QStringList svgPaths = QgsApplication::svgPaths();
369+
for ( int i = 0; i < svgPaths.size(); i++ )
370+
{
371+
QgsDebugMsg( "SvgPath: " + svgPaths[i] );
372+
QFileInfo myInfo( name );
373+
QString myFileName = myInfo.fileName(); // foo.svg
374+
QString myLowestDir = myInfo.dir().dirName();
375+
QString myLocalPath = svgPaths[i] + "/" + myLowestDir + "/" + myFileName;
376+
377+
QgsDebugMsg( "Alternative svg path: " + myLocalPath );
378+
if ( QFile( myLocalPath ).exists() )
379+
{
380+
QgsDebugMsg( "Svg found in alternative path" );
381+
return QFileInfo( myLocalPath ).canonicalFilePath();
382+
}
383+
else if ( myInfo.isRelative() )
384+
{
385+
QFileInfo pfi( QgsProject::instance()->fileName() );
386+
QString alternatePath = pfi.canonicalPath() + QDir::separator() + name;
387+
if ( pfi.exists() && QFile( alternatePath ).exists() )
388+
{
389+
QgsDebugMsg( "Svg found in alternative path" );
390+
return QFileInfo( alternatePath ).canonicalFilePath();
391+
}
392+
else
393+
{
394+
QgsDebugMsg( "Svg not found in project path" );
395+
}
396+
}
397+
else
398+
{
399+
//couldnt find the file, no happy ending :-(
400+
QgsDebugMsg( "Computed alternate path but no svg there either" );
401+
}
402+
}
403+
return QString();
404+
}
405+
406+
QString QgsSvgMarkerSymbolLayerV2::symbolPathToName( QString path )
407+
{
408+
// copied from QgsSymbol::writeXML
409+
410+
QFileInfo fi( path );
411+
if ( !fi.exists() )
412+
return path;
413+
414+
path = fi.canonicalFilePath();
415+
416+
QStringList svgPaths = QgsApplication::svgPaths();
417+
418+
for ( int i = 0; i < svgPaths.size(); i++ )
419+
{
420+
QString dir = QFileInfo( svgPaths[i] ).canonicalFilePath();
421+
422+
if ( !dir.isEmpty() && path.startsWith( dir ) )
423+
{
424+
path = path.mid( dir.size() );
425+
break;
426+
}
427+
}
428+
429+
return path;
430+
}

‎src/core/symbology-ng/qgsmarkersymbollayerv2.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
6262

6363
//////////
6464

65-
#define DEFAULT_SVGMARKER_NAME "symbol/Star1.svg"
65+
#define DEFAULT_SVGMARKER_NAME "/symbol/Star1.svg"
6666
#define DEFAULT_SVGMARKER_SIZE 9
6767
#define DEFAULT_SVGMARKER_ANGLE 0
6868

@@ -77,6 +77,15 @@ class CORE_EXPORT QgsSvgMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
7777

7878
static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() );
7979

80+
//! Return a list of all available svg files
81+
static QStringList listSvgFiles();
82+
83+
//! Get symbol's path from its name
84+
static QString symbolNameToPath( QString name );
85+
86+
//! Get symbols's name from its path
87+
static QString symbolPathToName( QString path );
88+
8089
// implemented from base classes
8190

8291
QString layerType() const;
@@ -91,14 +100,14 @@ class CORE_EXPORT QgsSvgMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
91100

92101
QgsSymbolLayerV2* clone() const;
93102

94-
QString name() const { return mName; }
95-
void setName( QString name ) { mName = name; }
103+
QString path() const { return mPath; }
104+
void setPath( QString path ) { mPath = path; }
96105

97106
protected:
98107

99108
void loadSvg();
100109

101-
QString mName;
110+
QString mPath;
102111
QPicture mPicture;
103112
};
104113

‎src/gui/symbology-ng/qgssymbollayerv2widget.cpp

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -372,43 +372,29 @@ void QgsSvgMarkerSymbolLayerV2Widget::populateList()
372372
QStandardItemModel* m = new QStandardItemModel( viewImages );
373373
viewImages->setModel( m );
374374

375-
QString svgPath = QgsApplication::svgPath();
376375
QSvgRenderer renderer;
377376
QPainter painter;
378377

379-
QDir dir( svgPath );
380-
381-
QStringList dl = dir.entryList( QDir::Dirs );
382-
383-
for ( QStringList::iterator it = dl.begin(); it != dl.end(); ++it )
378+
foreach( QString entry, QgsSvgMarkerSymbolLayerV2::listSvgFiles() )
384379
{
385-
if ( *it == "." || *it == ".." ) continue;
386-
387-
QDir dir2( svgPath + *it );
388-
389-
QStringList dl2 = dir2.entryList( QStringList( "*.svg" ), QDir::Files );
390-
391-
for ( QStringList::iterator it2 = dl2.begin(); it2 != dl2.end(); ++it2 )
392-
{
393-
// TODO test if it is correct SVG
394-
QString entry = *it2;
395-
396-
// render SVG file
397-
renderer.load( dir2.filePath( *it2 ) );
398-
QPixmap pixmap( renderer.defaultSize() );
399-
pixmap.fill();
400-
painter.begin( &pixmap );
401-
renderer.render( &painter );
402-
painter.end();
403-
404-
// add item
405-
QStandardItem* item = new QStandardItem( QIcon( pixmap ), *it + "/" + entry );
406-
m->appendRow( item );
407-
}
380+
// render SVG file
381+
renderer.load( entry );
382+
QPixmap pixmap( renderer.defaultSize() );
383+
pixmap.fill();
384+
painter.begin( &pixmap );
385+
renderer.render( &painter );
386+
painter.end();
387+
388+
// add item
389+
QStandardItem* item = new QStandardItem( QIcon( pixmap ), QString() );
390+
item->setData( entry, Qt::UserRole );
391+
item->setToolTip( entry );
392+
m->appendRow( item );
408393
}
409394

410395
}
411396

397+
412398
void QgsSvgMarkerSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
413399
{
414400
if ( layer->layerType() != "SvgMarker" )
@@ -420,13 +406,18 @@ void QgsSvgMarkerSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
420406
// set values
421407

422408
QStandardItemModel* m = static_cast<QStandardItemModel*>( viewImages->model() );
423-
QList<QStandardItem*> items = m->findItems( mLayer->name() );
424-
if ( items.count() > 0 )
409+
for ( int i = 0; i < m->rowCount(); i++ )
425410
{
426-
QModelIndex idx = items[0]->index();
427-
viewImages->selectionModel()->select( idx, QItemSelectionModel::SelectCurrent );
411+
QStandardItem* item = m->item( i, 0 );
412+
if ( item->data( Qt::UserRole ).toString() == mLayer->path() )
413+
{
414+
viewImages->selectionModel()->select( item->index(), QItemSelectionModel::SelectCurrent );
415+
viewImages->selectionModel()->setCurrentIndex( item->index(), QItemSelectionModel::SelectCurrent );
416+
break;
417+
}
428418
}
429419

420+
430421
spinSize->setValue( mLayer->size() );
431422
spinAngle->setValue( mLayer->angle() );
432423

@@ -446,9 +437,8 @@ QgsSymbolLayerV2* QgsSvgMarkerSymbolLayerV2Widget::symbolLayer()
446437

447438
void QgsSvgMarkerSymbolLayerV2Widget::setName( const QModelIndex& idx )
448439
{
449-
mLayer->setName( idx.data().toString() );
440+
mLayer->setPath( idx.data( Qt::UserRole ).toString() );
450441

451-
//mLayer->setName(lstNames->currentItem()->data(Qt::UserRole).toString());
452442
emit changed();
453443
}
454444

0 commit comments

Comments
 (0)
Please sign in to comment.