Skip to content

Commit

Permalink
Symbology-NG: support for additional SVG paths - fix for #2157
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12365 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder committed Dec 8, 2009
1 parent 906f86a commit 88def1e
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 49 deletions.
118 changes: 108 additions & 10 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
Expand Up @@ -5,9 +5,12 @@
#include "qgsrendercontext.h"
#include "qgsapplication.h"
#include "qgslogger.h"
#include "qgsproject.h"

#include <QPainter>
#include <QSvgRenderer>
#include <QFileInfo>
#include <QDir>

#include <cmath>

Expand Down Expand Up @@ -105,11 +108,11 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsRenderContext& context )
<< QPointF( -half, -sixth )
<< QPointF( -sixth, 0 )
<< QPointF( -half, half )
<< QPointF( 0, +sixth )
<< QPointF( 0, + sixth )
<< QPointF( half, half )
<< QPointF( +sixth, 0 )
<< QPointF( + sixth, 0 )
<< QPointF( half, -sixth )
<< QPointF( +sixth, -sixth );
<< QPointF( + sixth, -sixth );
}
else if ( mName == "regular_star" )
{
Expand Down Expand Up @@ -248,7 +251,7 @@ void QgsSimpleMarkerSymbolLayerV2::drawMarker( QPainter* p )

QgsSvgMarkerSymbolLayerV2::QgsSvgMarkerSymbolLayerV2( QString name, double size, double angle )
{
mName = name;
mPath = symbolNameToPath( name );
mSize = size;
mAngle = angle;
mOffset = QPointF( 0, 0 );
Expand Down Expand Up @@ -282,11 +285,8 @@ QString QgsSvgMarkerSymbolLayerV2::layerType() const

void QgsSvgMarkerSymbolLayerV2::startRender( QgsRenderContext& context )
{
QString svgPath = QgsApplication::svgPath();
QString file = svgPath + "/" + mName;

QRectF rect( QPointF( -mSize / 2.0, -mSize / 2.0 ), QSizeF( mSize, mSize ) );
QSvgRenderer renderer( file );
QSvgRenderer renderer( mPath );
QPainter painter( &mPicture );
renderer.render( &painter, rect );
}
Expand Down Expand Up @@ -317,7 +317,7 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsRenderCont
QgsStringMap QgsSvgMarkerSymbolLayerV2::properties() const
{
QgsStringMap map;
map["name"] = mName;
map["name"] = symbolPathToName( mPath );
map["size"] = QString::number( mSize );
map["angle"] = QString::number( mAngle );
map["offset"] = QgsSymbolLayerV2Utils::encodePoint( mOffset );
Expand All @@ -326,7 +326,105 @@ QgsStringMap QgsSvgMarkerSymbolLayerV2::properties() const

QgsSymbolLayerV2* QgsSvgMarkerSymbolLayerV2::clone() const
{
QgsSvgMarkerSymbolLayerV2* m = new QgsSvgMarkerSymbolLayerV2( mName, mSize, mAngle );
QgsSvgMarkerSymbolLayerV2* m = new QgsSvgMarkerSymbolLayerV2( mPath, mSize, mAngle );
m->setOffset( mOffset );
return m;
}


QStringList QgsSvgMarkerSymbolLayerV2::listSvgFiles()
{
// copied from QgsMarkerCatalogue - TODO: unify
QStringList list;
QStringList svgPaths = QgsApplication::svgPaths();

for ( int i = 0; i < svgPaths.size(); i++ )
{
QDir dir( svgPaths[i] );
foreach( QString item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
{
svgPaths.insert( i + 1, dir.path() + "/" + item );
}

foreach( QString item, dir.entryList( QStringList( "*.svg" ), QDir::Files ) )
{
// TODO test if it is correct SVG
list.append( dir.path() + "/" + item );
}
}
return list;
}

QString QgsSvgMarkerSymbolLayerV2::symbolNameToPath( QString name )
{
// copied from QgsSymbol::setNamedPointSymbol - TODO: unify

// we might have a full path...
if ( QFile( name ).exists() )
return QFileInfo( name ).canonicalFilePath();

// SVG symbol not found - probably a relative path was used

QStringList svgPaths = QgsApplication::svgPaths();
for ( int i = 0; i < svgPaths.size(); i++ )
{
QgsDebugMsg( "SvgPath: " + svgPaths[i] );
QFileInfo myInfo( name );
QString myFileName = myInfo.fileName(); // foo.svg
QString myLowestDir = myInfo.dir().dirName();
QString myLocalPath = svgPaths[i] + "/" + myLowestDir + "/" + myFileName;

QgsDebugMsg( "Alternative svg path: " + myLocalPath );
if ( QFile( myLocalPath ).exists() )
{
QgsDebugMsg( "Svg found in alternative path" );
return QFileInfo( myLocalPath ).canonicalFilePath();
}
else if ( myInfo.isRelative() )
{
QFileInfo pfi( QgsProject::instance()->fileName() );
QString alternatePath = pfi.canonicalPath() + QDir::separator() + name;
if ( pfi.exists() && QFile( alternatePath ).exists() )
{
QgsDebugMsg( "Svg found in alternative path" );
return QFileInfo( alternatePath ).canonicalFilePath();
}
else
{
QgsDebugMsg( "Svg not found in project path" );
}
}
else
{
//couldnt find the file, no happy ending :-(
QgsDebugMsg( "Computed alternate path but no svg there either" );
}
}
return QString();
}

QString QgsSvgMarkerSymbolLayerV2::symbolPathToName( QString path )
{
// copied from QgsSymbol::writeXML

QFileInfo fi( path );
if ( !fi.exists() )
return path;

path = fi.canonicalFilePath();

QStringList svgPaths = QgsApplication::svgPaths();

for ( int i = 0; i < svgPaths.size(); i++ )
{
QString dir = QFileInfo( svgPaths[i] ).canonicalFilePath();

if ( !dir.isEmpty() && path.startsWith( dir ) )
{
path = path.mid( dir.size() );
break;
}
}

return path;
}
17 changes: 13 additions & 4 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.h
Expand Up @@ -62,7 +62,7 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2

//////////

#define DEFAULT_SVGMARKER_NAME "symbol/Star1.svg"
#define DEFAULT_SVGMARKER_NAME "/symbol/Star1.svg"
#define DEFAULT_SVGMARKER_SIZE 9
#define DEFAULT_SVGMARKER_ANGLE 0

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

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

//! Return a list of all available svg files
static QStringList listSvgFiles();

//! Get symbol's path from its name
static QString symbolNameToPath( QString name );

//! Get symbols's name from its path
static QString symbolPathToName( QString path );

// implemented from base classes

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

QgsSymbolLayerV2* clone() const;

QString name() const { return mName; }
void setName( QString name ) { mName = name; }
QString path() const { return mPath; }
void setPath( QString path ) { mPath = path; }

protected:

void loadSvg();

QString mName;
QString mPath;
QPicture mPicture;
};

Expand Down
60 changes: 25 additions & 35 deletions src/gui/symbology-ng/qgssymbollayerv2widget.cpp
Expand Up @@ -372,43 +372,29 @@ void QgsSvgMarkerSymbolLayerV2Widget::populateList()
QStandardItemModel* m = new QStandardItemModel( viewImages );
viewImages->setModel( m );

QString svgPath = QgsApplication::svgPath();
QSvgRenderer renderer;
QPainter painter;

QDir dir( svgPath );

QStringList dl = dir.entryList( QDir::Dirs );

for ( QStringList::iterator it = dl.begin(); it != dl.end(); ++it )
foreach( QString entry, QgsSvgMarkerSymbolLayerV2::listSvgFiles() )
{
if ( *it == "." || *it == ".." ) continue;

QDir dir2( svgPath + *it );

QStringList dl2 = dir2.entryList( QStringList( "*.svg" ), QDir::Files );

for ( QStringList::iterator it2 = dl2.begin(); it2 != dl2.end(); ++it2 )
{
// TODO test if it is correct SVG
QString entry = *it2;

// render SVG file
renderer.load( dir2.filePath( *it2 ) );
QPixmap pixmap( renderer.defaultSize() );
pixmap.fill();
painter.begin( &pixmap );
renderer.render( &painter );
painter.end();

// add item
QStandardItem* item = new QStandardItem( QIcon( pixmap ), *it + "/" + entry );
m->appendRow( item );
}
// render SVG file
renderer.load( entry );
QPixmap pixmap( renderer.defaultSize() );
pixmap.fill();
painter.begin( &pixmap );
renderer.render( &painter );
painter.end();

// add item
QStandardItem* item = new QStandardItem( QIcon( pixmap ), QString() );
item->setData( entry, Qt::UserRole );
item->setToolTip( entry );
m->appendRow( item );
}

}


void QgsSvgMarkerSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
{
if ( layer->layerType() != "SvgMarker" )
Expand All @@ -420,13 +406,18 @@ void QgsSvgMarkerSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
// set values

QStandardItemModel* m = static_cast<QStandardItemModel*>( viewImages->model() );
QList<QStandardItem*> items = m->findItems( mLayer->name() );
if ( items.count() > 0 )
for ( int i = 0; i < m->rowCount(); i++ )
{
QModelIndex idx = items[0]->index();
viewImages->selectionModel()->select( idx, QItemSelectionModel::SelectCurrent );
QStandardItem* item = m->item( i, 0 );
if ( item->data( Qt::UserRole ).toString() == mLayer->path() )
{
viewImages->selectionModel()->select( item->index(), QItemSelectionModel::SelectCurrent );
viewImages->selectionModel()->setCurrentIndex( item->index(), QItemSelectionModel::SelectCurrent );
break;
}
}


spinSize->setValue( mLayer->size() );
spinAngle->setValue( mLayer->angle() );

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

void QgsSvgMarkerSymbolLayerV2Widget::setName( const QModelIndex& idx )
{
mLayer->setName( idx.data().toString() );
mLayer->setPath( idx.data( Qt::UserRole ).toString() );

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

Expand Down

0 comments on commit 88def1e

Please sign in to comment.