[FEATURE] Reworked symbol selector/properties dialog, greatly improved style manager

This is merge of Arun's GSoC 2012 work.

Merge remote-tracking branch 'arun/gsoc'

Conflicts:
	src/gui/symbology-ng/qgssymbolv2selectordialog.cpp
This commit is contained in:
Martin Dobias 2012-08-14 21:45:32 +02:00
commit 21253f99e9
53 changed files with 5129 additions and 2032 deletions

View File

@ -1265,7 +1265,7 @@ class QgsSymbolLayerV2Utils
static QgsSymbolV2* loadSymbol( QDomElement& element ) /Factory/;
static QgsSymbolLayerV2* loadSymbolLayer( QDomElement& element ) /Factory/;
static QDomElement saveSymbol( QString name, QgsSymbolV2* symbol, QDomDocument& doc, QgsSymbolV2Map* subSymbols = NULL );
static QDomElement saveSymbol( QString name, QgsSymbolV2* symbol, QDomDocument& doc );
static QgsStringMap parseProperties( QDomElement& element );
static void saveProperties( QgsStringMap props, QDomDocument& doc, QDomElement& element );

View File

@ -1,31 +1,4 @@
class QgsSymbolV2PropertiesDialog : QDialog //, private Ui::DlgSymbolV2Properties
{
%TypeHeaderCode
#include <qgssymbolv2propertiesdialog.h>
%End
public:
QgsSymbolV2PropertiesDialog(QgsSymbolV2* symbol, const QgsVectorLayer* vl, QWidget* parent = NULL);
public slots:
void moveLayerDown();
void moveLayerUp();
void addLayer();
void removeLayer();
void lockLayer();
void layerTypeChanged();
void layerChanged();
};
class QgsRendererV2PropertiesDialog : QDialog //, private Ui::QgsRendererV2PropsDialogBase
{
%TypeHeaderCode
@ -71,27 +44,33 @@ class QgsSymbolV2SelectorDialog : QDialog //, private Ui::QgsSymbolV2SelectorDia
%TypeHeaderCode
#include <qgssymbolv2selectordialog.h>
%End
public:
QgsSymbolV2SelectorDialog( QgsSymbolV2* symbol, QgsStyleV2* style, const QgsVectorLayer* vl, QWidget* parent = NULL, bool embedded = false );
public:
QgsSymbolV2SelectorDialog(QgsSymbolV2* symbol, QgsStyleV2* style, const QgsVectorLayer* vl, QWidget* parent = NULL, bool embedded = false);
protected:
void populateSymbolView();
void updateSymbolPreview();
void updateSymbolColor();
void updateSymbolInfo();
QMenu* advancedMenu();
public slots:
void changeSymbolProperties();
void setSymbolFromStyle(const QModelIndex & index);
void setSymbolColor();
void setMarkerAngle(double angle);
void setMarkerSize(double size);
void setLineWidth(double width);
protected:
void keyPressEvent( QKeyEvent * event );
signals:
void symbolModified();
void loadSymbol();
void updateUi();
void updateLockButton();
QgsSymbolLayerV2* currentLayer();
void moveLayerByOffset( int offset );
void setWidget( QWidget* widget );
signals:
void symbolModified();
public slots:
void moveLayerDown();
void moveLayerUp();
void addLayer();
void removeLayer();
void lockLayer();
void layerChanged();
void updateLayerPreview();
void updatePreview();
};

View File

@ -1,4 +1,4 @@
INSTALL(FILES srs.db qgis.db qgis_help.db symbology-ng-style.xml spatialite.db customization.xml
INSTALL(FILES srs.db qgis.db qgis_help.db symbology-ng-style.db spatialite.db customization.xml
DESTINATION ${QGIS_DATA_DIR}/resources)
ADD_SUBDIRECTORY(context_help)

Binary file not shown.

105
scripts/symbol_xml2db.py Normal file
View File

@ -0,0 +1,105 @@
#!/usr/bin/python
"""
/***************************************************************************
symbol_xml2db.py
-------------------
begin : 26-5-2012
copyright : (C) 2012 by Arunmozhi
email : aruntheguy at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
The script creates a sqlite3 Db for storing the symbols which will be
shipped with QGIS by default. It then converts symbols and colorramps
in the symbology_ng_style.xml to the database table entries.
"""
import sqlite3
from xml.dom.minidom import parse, parseString
xmlfile = "../resources/symbology-ng-style.xml"
dbfile = "../resources/symbology-ng-style.db"
_symbol = "CREATE TABLE symbol("\
"id INTEGER PRIMARY KEY,"\
"name TEXT UNIQUE,"\
"xml TEXT,"\
"groupid INTEGER)"
_colorramp = "CREATE TABLE colorramp("\
"id INTEGER PRIMARY KEY,"\
"name TEXT,"\
"xml TEXT,"\
"groupid INTEGER)"
_tag = "CREATE TABLE tag("\
"id INTEGER PRIMARY KEY,"\
"name TEXT)"
_tagmap = "CREATE TABLE tagmap("\
"tag_id INTEGER NOT NULL,"\
"symbol_id INTEGER)"
_symgroup = "CREATE TABLE symgroup("\
"id INTEGER PRIMARY KEY,"\
"name TEXT,"\
"parent INTEGER)"
_smartgroup = "CREATE TABLE smartgroup("\
"id INTEGER PRIMARY KEY,"\
"name TEXT,"\
"xml TEXT)"
_ctagmap = "CREATE TABLE ctagmap("\
"tag_id INTEGER NOT NULL,"\
"colorramp_id INTEGER)"
create_tables = [ _symbol, _colorramp, _tag, _tagmap, _ctagmap, _symgroup, _smartgroup ]
# Create the DB with required Schema
conn = sqlite3.connect( dbfile )
c = conn.cursor()
print "Creating tables in the Database\n"
for table in create_tables:
try:
c.execute( table )
print table
except sqlite3.OperationalError as e:
pass
conn.commit()
# parse the XML file & write symbol into DB
dom = parse( xmlfile )
symbols = dom.getElementsByTagName( "symbol" )
for symbol in symbols:
symbol_name = symbol.getAttribute( "name" )
if '@' in symbol_name:
parts = symbol_name.split('@')
parent_name = parts[1]
layerno = int(parts[2])
c.execute( "SELECT xml FROM symbol WHERE name=(?)", (parent_name,) )
symdom = parseString( c.fetchone()[0] ).getElementsByTagName( 'symbol' )[0]
symdom.getElementsByTagName( "layer" )[ layerno ].appendChild( symbol )
c.execute( "UPDATE symbol SET xml=? WHERE name=?", ( symdom.toxml(), parent_name ))
else:
c.execute( "INSERT INTO symbol VALUES (?,?,?,?)", ( None, symbol_name, symbol.toxml(), None ) )
conn.commit()
# ColorRamps
colorramps = dom.getElementsByTagName( "colorramp" )
for ramp in colorramps:
ramp_name = ramp.getAttribute( "name" )
c.execute( "INSERT INTO colorramp VALUES (?,?,?,?)", ( None, ramp_name, ramp.toxml(), None ) )
conn.commit()
# Finally close the sqlite cursor
c.close()

View File

@ -24,7 +24,6 @@
#include "qgsstylev2.h"
#include "qgssymbolv2.h"
#include "qgssymbolv2selectordialog.h"
#include "qgssymbolv2propertiesdialog.h"
#include "qgisapp.h"
#include <QFontDialog>
@ -212,7 +211,7 @@ void QgsDecorationGridDialog::on_mLineSymbolButton_clicked()
return;
QgsLineSymbolV2* lineSymbol = dynamic_cast<QgsLineSymbolV2*>( mLineSymbol->clone() );
QgsSymbolV2PropertiesDialog dlg( lineSymbol, 0, this );
QgsSymbolV2SelectorDialog dlg( lineSymbol, QgsStyleV2::defaultStyle(), 0, this );
if ( dlg.exec() == QDialog::Rejected )
{
delete lineSymbol;
@ -235,7 +234,7 @@ void QgsDecorationGridDialog::on_mMarkerSymbolButton_clicked()
return;
QgsMarkerSymbolV2* markerSymbol = dynamic_cast<QgsMarkerSymbolV2*>( mMarkerSymbol->clone() );
QgsSymbolV2PropertiesDialog dlg( markerSymbol, 0, this );
QgsSymbolV2SelectorDialog dlg( markerSymbol, QgsStyleV2::defaultStyle(), 0, this );
if ( dlg.exec() == QDialog::Rejected )
{
delete markerSymbol;

View File

@ -557,12 +557,12 @@ const QString QgsApplication::svgPath()
const QString QgsApplication::userStyleV2Path()
{
return qgisSettingsDirPath() + QString( "symbology-ng-style.xml" );
return qgisSettingsDirPath() + QString( "symbology-ng-style.db" );
}
const QString QgsApplication::defaultStyleV2Path()
{
return ABISYM( mPkgDataPath ) + QString( "/resources/symbology-ng-style.xml" );
return ABISYM( mPkgDataPath ) + QString( "/resources/symbology-ng-style.db" );
}
const QString QgsApplication::libraryPath()

View File

@ -794,6 +794,32 @@ QStringList QgsSvgMarkerSymbolLayerV2::listSvgFiles()
return list;
}
// Stripped down version of listSvgFiles() for specified directory
QStringList QgsSvgMarkerSymbolLayerV2::listSvgFilesAt( QString directory )
{
// TODO anything that applies for the listSvgFiles() applies this also
QStringList list;
QStringList svgPaths;
svgPaths.append( directory );
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 ) )
{
list.append( dir.path() + "/" + item );
}
}
return list;
}
QString QgsSvgMarkerSymbolLayerV2::symbolNameToPath( QString name )
{
// copied from QgsSymbol::setNamedPointSymbol - TODO: unify

View File

@ -109,6 +109,9 @@ class CORE_EXPORT QgsSvgMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
//! Return a list of all available svg files
static QStringList listSvgFiles();
//! Return a list of svg files at the specified directory
static QStringList listSvgFilesAt( QString directory );
//! Get symbol's path from its name
static QString symbolNameToPath( QString name );

File diff suppressed because it is too large Load Diff

View File

@ -17,8 +17,11 @@
#define QGSSTYLEV2_H
#include <QMap>
#include <QMultiMap>
#include <QString>
#include <sqlite3.h>
#include "qgssymbollayerv2utils.h" // QgsStringMap
class QgsSymbolV2;
@ -29,6 +32,19 @@ class QDomDocument;
class QDomElement;
typedef QMap<QString, QgsVectorColorRampV2* > QgsVectorColorRampV2Map;
typedef QMap<int, QString> QgsSymbolGroupMap;
typedef QMultiMap<QString, QString> QgsSmartConditionMap;
// Enumeraters representing sqlite DB columns
enum SymbolTable { SymbolId, SymbolName, SymbolXML, SymbolGroupId };
enum SymgroupTable { SymgroupId, SymgroupName, SymgroupParent };
enum TagTable { TagId, TagName };
enum TagmapTable { TagmapTagId, TagmapSymbolId };
enum ColorrampTable { ColorrampId, ColorrampName, ColorrampXML, ColorrampGroupId };
enum SmartgroupTable { SmartgroupId, SmartgroupName, SmartgroupXML };
// Enums for types
enum StyleEntity { SymbolEntity, GroupEntity, TagEntity, ColorrampEntity, SmartgroupEntity };
class CORE_EXPORT QgsStyleV2
{
@ -65,6 +81,43 @@ class CORE_EXPORT QgsStyleV2
//! return a list of names of symbols
QStringList symbolNames();
//! return the id in the style database for the given symbol name
//! returns 0 if not found
int symbolId( QString name );
int colorrampId( QString name );
//! return the id in the style database for the given group name
int groupId( QString group );
int tagId( QString tag );
int smartgroupId( QString smartgroup );
//! return the all the groups in the style
QStringList groupNames();
//! return a map of groupid and names for the given parent
QgsSymbolGroupMap childGroupNames( QString parent = "" );
//! returns the symbolnames of a given groupid
QStringList symbolsOfGroup( StyleEntity type, int groupid );
//! returns the symbol names with which have the given tag
QStringList symbolsWithTag( StyleEntity type, int tagid );
//! adds a new group and returns the group's id
int addGroup( QString groupName, int parent = 0 );
//! adds a new tag and returns the tag's id
int addTag( QString tagName );
//! applies the specifed group to the symbol or colorramp specified by StyleEntity
bool group( StyleEntity type, QString name, int groupid );
//! rename the given entity with the specified id
void rename( StyleEntity type, int id, QString newName );
//! remove the specified entity from the db
void remove( StyleEntity type, int id );
//! add the symbol to the DB with the tags
bool saveSymbol( QString name, QgsSymbolV2* symbol, int groupid, QStringList tags );
//! add the colorramp to the DB
bool saveColorRamp( QString name, QgsVectorColorRampV2* ramp, int groupid, QStringList tags );
//! add color ramp to style. takes ramp's ownership
bool addColorRamp( QString name, QgsVectorColorRampV2* colorRamp );
@ -101,6 +154,43 @@ class CORE_EXPORT QgsStyleV2
//! return current file name of the style
QString fileName() { return mFileName; }
//! return the names of the symbols which have a matching 'substring' in its defintion
QStringList findSymbols( QString qword );
//! tags the symbol with the tags in the list, the remove flag DE-TAGS
bool tagSymbol( StyleEntity type, QString symbol, QStringList tags );
//! detags the symbol with the given list
bool detagSymbol( StyleEntity type, QString symbol, QStringList tags );
//! return the tags associated with the symbol
QStringList tagsOfSymbol( StyleEntity type, QString symbol );
//! adds the smartgroup to the database and returns the id
int addSmartgroup( QString name, QString op, QgsSmartConditionMap conditions );
//! returns the smart groups map
QgsSymbolGroupMap smartgroupsListMap();
//! returns the smart groups list
QStringList smartgroupNames();
//! returns the QgsSmartConditionMap for the given id
QgsSmartConditionMap smartgroup( int id );
//! returns the operator for the smartgroup
//! @note: clumsy implementation TODO create a class for smartgroups
QString smartgroupOperator( int id );
//! returns the symbols for the smartgroup
QStringList symbolsOfSmartgroup( StyleEntity type, int id );
//! Exports the style as a XML file
bool exportXML( QString filename );
//! Imports the symbols and colorramps into the default style database from the given XML file
bool importXML( QString filename );
protected:
QgsSymbolV2Map mSymbols;
@ -109,7 +199,19 @@ class CORE_EXPORT QgsStyleV2
QString mErrorString;
QString mFileName;
sqlite3* mCurrentDB;
static QgsStyleV2* mDefaultStyle;
//! Convinence function to open the DB and return a sqlite3 object
bool openDB( QString filename );
//! Convinence function that would run queries which donot generate return values
//! it returns sucess result
bool runEmptyQuery( char* query );
//! prepares the complex query for removing a group,so that the children are not abandoned
char* getGroupRemoveQuery( int id );
//! gets the id from the table for the given name from the database, 0 if not found
int getId( QString table, QString name );
};

View File

@ -638,8 +638,20 @@ QgsSymbolV2* QgsSymbolLayerV2Utils::loadSymbol( QDomElement& element )
else
{
QgsSymbolLayerV2* layer = loadSymbolLayer( e );
if ( layer != NULL )
{
// Dealing with sub-symbols nested into a layer
QDomElement s = e.firstChildElement( "symbol" );
if ( !s.isNull() )
{
QgsSymbolV2* subSymbol = loadSymbol( s );
bool res = layer->setSubSymbol( subSymbol );
if ( !res )
QgsDebugMsg( "symbol layer refused subsymbol: " + s.attribute( "name" ) );
}
layers.append( layer );
}
}
}
layerNode = layerNode.nextSibling();
@ -707,16 +719,16 @@ static QString _nameForSymbolType( QgsSymbolV2::SymbolType type )
}
}
QDomElement QgsSymbolLayerV2Utils::saveSymbol( QString name, QgsSymbolV2* symbol, QDomDocument& doc, QgsSymbolV2Map* subSymbols )
QDomElement QgsSymbolLayerV2Utils::saveSymbol( QString name, QgsSymbolV2* symbol, QDomDocument& doc )
{
Q_ASSERT( symbol );
QDomElement symEl = doc.createElement( "symbol" );
symEl.setAttribute( "type", _nameForSymbolType( symbol->type() ) );
symEl.setAttribute( "name", name );
symEl.setAttribute( "outputUnit", encodeOutputUnit( symbol->outputUnit() ) );
symEl.setAttribute( "alpha", QString::number( symbol->alpha() ) );
QgsDebugMsg( "num layers " + QString::number( symbol->symbolLayerCount() ) );
for ( int i = 0; i < symbol->symbolLayerCount(); i++ )
{
QgsSymbolLayerV2* layer = symbol->symbolLayer( i );
@ -725,14 +737,13 @@ QDomElement QgsSymbolLayerV2Utils::saveSymbol( QString name, QgsSymbolV2* symbol
layerEl.setAttribute( "class", layer->layerType() );
layerEl.setAttribute( "locked", layer->isLocked() );
layerEl.setAttribute( "pass", layer->renderingPass() );
if ( subSymbols != NULL && layer->subSymbol() != NULL )
saveProperties( layer->properties(), doc, layerEl );
if ( layer->subSymbol() != NULL )
{
QString subname = QString( "@%1@%2" ).arg( name ).arg( i );
subSymbols->insert( subname, layer->subSymbol() );
QDomElement subEl = saveSymbol( subname, layer->subSymbol(), doc );
layerEl.appendChild( subEl );
}
saveProperties( layer->properties(), doc, layerEl );
symEl.appendChild( layerEl );
}
@ -2177,6 +2188,7 @@ void QgsSymbolLayerV2Utils::saveProperties( QgsStringMap props, QDomDocument& do
}
}
// XXX Not used by QgStyleV2 anymore, But renderers use it still
QgsSymbolV2Map QgsSymbolLayerV2Utils::loadSymbols( QDomElement& element )
{
// go through symbols one-by-one and load them
@ -2259,22 +2271,13 @@ QDomElement QgsSymbolLayerV2Utils::saveSymbols( QgsSymbolV2Map& symbols, QString
{
QDomElement symbolsElem = doc.createElement( tagName );
QMap<QString, QgsSymbolV2*> subSymbols;
// save symbols
for ( QMap<QString, QgsSymbolV2*>::iterator its = symbols.begin(); its != symbols.end(); ++its )
{
QDomElement symEl = saveSymbol( its.key(), its.value(), doc, &subSymbols );
QDomElement symEl = saveSymbol( its.key(), its.value(), doc );
symbolsElem.appendChild( symEl );
}
// add subsymbols, don't allow subsymbols for them (to keep things simple)
for ( QMap<QString, QgsSymbolV2*>::iterator itsub = subSymbols.begin(); itsub != subSymbols.end(); ++itsub )
{
QDomElement subsymEl = saveSymbol( itsub.key(), itsub.value(), doc );
symbolsElem.appendChild( subsymEl );
}
return symbolsElem;
}

View File

@ -99,7 +99,7 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
static QgsSymbolV2* loadSymbol( QDomElement& element );
static QgsSymbolLayerV2* loadSymbolLayer( QDomElement& element );
static QDomElement saveSymbol( QString name, QgsSymbolV2* symbol, QDomDocument& doc, QgsSymbolV2Map* subSymbols = NULL );
static QDomElement saveSymbol( QString symbolName, QgsSymbolV2* symbol, QDomDocument& doc );
static bool createSymbolLayerV2ListFromSld( QDomElement& element, QGis::GeometryType geomType, QgsSymbolLayerV2List &layers );

View File

@ -14,7 +14,6 @@ symbology-ng/qgscolorrampcombobox.cpp
symbology-ng/qgsdashspacedialog.cpp
symbology-ng/qgspenstylecombobox.cpp
symbology-ng/qgssymbollayerv2widget.cpp
symbology-ng/qgssymbolv2propertiesdialog.cpp
symbology-ng/qgsrendererv2widget.cpp
symbology-ng/qgssinglesymbolrendererv2widget.cpp
symbology-ng/qgscategorizedsymbolrendererv2widget.cpp
@ -33,6 +32,9 @@ symbology-ng/qgsstylev2exportimportdialog.cpp
symbology-ng/qgsellipsesymbollayerv2widget.cpp
symbology-ng/qgspointdisplacementrendererwidget.cpp
symbology-ng/qgsvectorfieldsymbollayerwidget.cpp
symbology-ng/qgssymbolslistwidget.cpp
symbology-ng/qgslayerpropertieswidget.cpp
symbology-ng/qgssmartgroupeditordialog.cpp
attributetable/qgsattributetablemodel.cpp
attributetable/qgsattributetablememorymodel.cpp
@ -111,7 +113,6 @@ raster/qgsrasterhistogramwidget.h
symbology-ng/qgsdashspacedialog.h
symbology-ng/qgssymbollayerv2widget.h
symbology-ng/qgssymbolv2propertiesdialog.h
symbology-ng/qgssinglesymbolrendererv2widget.h
symbology-ng/qgscategorizedsymbolrendererv2widget.h
symbology-ng/qgsgraduatedsymbolrendererv2widget.h
@ -133,6 +134,9 @@ symbology-ng/qgsstylev2exportimportdialog.h
symbology-ng/qgsellipsesymbollayerv2widget.h
symbology-ng/qgspointdisplacementrendererwidget.h
symbology-ng/qgsvectorfieldsymbollayerwidget.h
symbology-ng/qgssymbolslistwidget.h
symbology-ng/qgslayerpropertieswidget.h
symbology-ng/qgssmartgroupeditordialog.h
attributetable/qgsattributetableview.h
attributetable/qgsattributetablemodel.h

View File

@ -0,0 +1,189 @@
/***************************************************************************
qgslayerpropertieswidget.cpp
----------------------------
begin : June 2012
copyright : (C) 2012 by Arunmozhi
email : aruntheguy at gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgslayerpropertieswidget.h"
#include <QFile>
#include <QStandardItem>
#include <QKeyEvent>
#include <QMessageBox>
#include "qgssymbollayerv2.h"
#include "qgssymbollayerv2registry.h"
#include "qgsapplication.h"
#include "qgslogger.h"
#include "qgssymbollayerv2widget.h"
#include "qgsellipsesymbollayerv2widget.h"
#include "qgsvectorfieldsymbollayerwidget.h"
#include "qgssymbolv2.h" //for the unit
static bool _initWidgetFunction( QString name, QgsSymbolLayerV2WidgetFunc f )
{
QgsSymbolLayerV2Registry* reg = QgsSymbolLayerV2Registry::instance();
QgsSymbolLayerV2AbstractMetadata* abstractMetadata = reg->symbolLayerMetadata( name );
if ( abstractMetadata == NULL )
{
QgsDebugMsg( "Failed to find symbol layer's entry in registry: " + name );
return false;
}
QgsSymbolLayerV2Metadata* metadata = dynamic_cast<QgsSymbolLayerV2Metadata*>( abstractMetadata );
if ( metadata == NULL )
{
QgsDebugMsg( "Failed to cast symbol layer's metadata: " + name );
return false;
}
metadata->setWidgetFunction( f );
return true;
}
static void _initWidgetFunctions()
{
static bool initialized = false;
if ( initialized )
return;
_initWidgetFunction( "SimpleLine", QgsSimpleLineSymbolLayerV2Widget::create );
_initWidgetFunction( "MarkerLine", QgsMarkerLineSymbolLayerV2Widget::create );
_initWidgetFunction( "LineDecoration", QgsLineDecorationSymbolLayerV2Widget::create );
_initWidgetFunction( "SimpleMarker", QgsSimpleMarkerSymbolLayerV2Widget::create );
_initWidgetFunction( "SvgMarker", QgsSvgMarkerSymbolLayerV2Widget::create );
_initWidgetFunction( "FontMarker", QgsFontMarkerSymbolLayerV2Widget::create );
_initWidgetFunction( "EllipseMarker", QgsEllipseSymbolLayerV2Widget::create );
_initWidgetFunction( "VectorField", QgsVectorFieldSymbolLayerWidget::create );
_initWidgetFunction( "SimpleFill", QgsSimpleFillSymbolLayerV2Widget::create );
_initWidgetFunction( "SVGFill", QgsSVGFillSymbolLayerWidget::create );
_initWidgetFunction( "CentroidFill", QgsCentroidFillSymbolLayerV2Widget::create );
_initWidgetFunction( "LinePatternFill", QgsLinePatternFillSymbolLayerWidget::create );
_initWidgetFunction( "PointPatternFill", QgsPointPatternFillSymbolLayerWidget::create );
initialized = true;
}
QgsLayerPropertiesWidget::QgsLayerPropertiesWidget( QgsSymbolLayerV2* layer, const QgsSymbolV2* symbol, const QgsVectorLayer* vl, QWidget* parent )
: QWidget( parent )
{
mLayer = layer;
mSymbol = symbol;
mVectorLayer = vl;
setupUi( this );
// initalize the sub-widgets
// XXX Should this thing be here this way? Initalize all th widgets just for the sake of one layer?
// TODO Make this on demand creation
_initWidgetFunctions();
// TODO Algorithm
//
// 3. populate the combo box with the supported layer type
// 4. set the present layer type
// 5. create the widget for the present layer type and set inn stacked widget
// 6. connect comboBox type changed to two things
// 1. emit signal that type has beed changed
// 2. remove the widget and place the new widget corresponding to the changed layer type
//
populateLayerTypes();
// update layer type combo box
int idx = cboLayerType->findData( mLayer->layerType() );
cboLayerType->setCurrentIndex( idx );
// set the corresponding widget
updateSymbolLayerWidget( layer );
connect( cboLayerType, SIGNAL( currentIndexChanged( int ) ), this, SLOT( layerTypeChanged() ) );
}
void QgsLayerPropertiesWidget::populateLayerTypes()
{
QStringList types = QgsSymbolLayerV2Registry::instance()->symbolLayersForType( mSymbol->type() );
for ( int i = 0; i < types.count(); i++ )
cboLayerType->addItem( QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( types[i] )->visibleName(), types[i] );
if ( mSymbol->type() == QgsSymbolV2::Fill )
{
QStringList typesLine = QgsSymbolLayerV2Registry::instance()->symbolLayersForType( QgsSymbolV2::Line );
for ( int i = 0; i < typesLine.count(); i++ )
{
QString visibleName = QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( typesLine[i] )->visibleName();
QString name = QString( tr( "Outline: %1" ) ).arg( visibleName );
cboLayerType->addItem( name, typesLine[i] );
}
}
}
void QgsLayerPropertiesWidget::updateSymbolLayerWidget( QgsSymbolLayerV2* layer )
{
if ( stackedWidget->currentWidget() != pageDummy )
{
// stop updating from the original widget
disconnect( stackedWidget->currentWidget(), SIGNAL( changed() ), this, SLOT( emitSignalChanged() ) );
stackedWidget->removeWidget( stackedWidget->currentWidget() );
}
QgsSymbolLayerV2Registry* pReg = QgsSymbolLayerV2Registry::instance();
QString layerType = layer->layerType();
QgsSymbolLayerV2AbstractMetadata* am = pReg->symbolLayerMetadata( layerType );
if ( am )
{
QgsSymbolLayerV2Widget* w = am->createSymbolLayerWidget( mVectorLayer );
if ( w )
{
w->setSymbolLayer( layer );
stackedWidget->addWidget( w );
stackedWidget->setCurrentWidget( w );
// start recieving updates from widget
connect( w , SIGNAL( changed() ), this, SLOT( emitSignalChanged() ) );
return;
}
}
// When anything is not right
stackedWidget->setCurrentWidget( pageDummy );
}
void QgsLayerPropertiesWidget::layerTypeChanged()
{
QgsSymbolLayerV2* layer = mLayer;
if ( !layer )
return;
QString newLayerType = cboLayerType->itemData( cboLayerType->currentIndex() ).toString();
if ( layer->layerType() == newLayerType )
return;
// get creation function for new layer from registry
QgsSymbolLayerV2Registry* pReg = QgsSymbolLayerV2Registry::instance();
QgsSymbolLayerV2AbstractMetadata* am = pReg->symbolLayerMetadata( newLayerType );
if ( am == NULL ) // check whether the metadata is assigned
return;
// change layer to a new (with different type)
QgsSymbolLayerV2* newLayer = am->createSymbolLayer( QgsStringMap() );
if ( newLayer == NULL )
return;
updateSymbolLayerWidget( newLayer );
emit changeLayer( newLayer );
}
void QgsLayerPropertiesWidget::emitSignalChanged()
{
emit changed();
}

View File

@ -0,0 +1,59 @@
/***************************************************************************
qgslayerpropertieswidget.h
---------------------
begin : June 2012
copyright : (C) 2012 by Martin Dobias
email : aruntheguy at gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSLAYERPROPERTIESWIDGET_H
#define QGSLAYERPROPERTIESWIDGET_H
#include "ui_widget_layerproperties.h"
class QgsSymbolV2;
class QgsSymbolLayerV2;
class QgsSymbolLayerV2Widget;
class QgsVectorLayer;
class SymbolLayerItem;
#include <QMap>
#include <QStandardItemModel>
class GUI_EXPORT QgsLayerPropertiesWidget : public QWidget, private Ui::LayerPropertiesWidget
{
Q_OBJECT
public:
QgsLayerPropertiesWidget( QgsSymbolLayerV2* layer, const QgsSymbolV2* symbol, const QgsVectorLayer* vl, QWidget* parent = NULL );
public slots:
void layerTypeChanged();
void emitSignalChanged();
signals:
void changed();
void changeLayer( QgsSymbolLayerV2* );
protected:
void populateLayerTypes();
void updateSymbolLayerWidget( QgsSymbolLayerV2* layer );
protected: // data
QgsSymbolLayerV2* mLayer;
const QgsSymbolV2* mSymbol;
const QgsVectorLayer* mVectorLayer;
};
#endif //QGSLAYERPROPERTIESWIDGET_H

View File

@ -0,0 +1,208 @@
/***************************************************************************
qgssmartgroupeditordialog.cpp
-----------------------------
begin : July 2012
copyright : (C) 2012 by Arunmozhi
email : aruntheguy at gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgssmartgroupeditordialog.h"
#include "qgsstylev2.h"
#include "qgsapplication.h"
#include <QVariant>
#include <QMessageBox>
// -------------------------- //
// Condition Widget functions //
// -------------------------- //
QgsSmartGroupCondition::QgsSmartGroupCondition( int id, QWidget* parent ) : QWidget( parent )
{
setupUi( this );
mConditionId = id;
mCondCombo->addItem( "has the tag", QVariant( "tag" ) );
mCondCombo->addItem( "is a member of group", QVariant( "group" ) );
mCondCombo->addItem( "has a part of name matching", QVariant( "name" ) );
mCondCombo->addItem( "does NOT have the tag", QVariant( "!tag" ) );
mCondCombo->addItem( "is NOT a member of group", QVariant( "!group" ) );
mCondCombo->addItem( "has NO part of name matching", QVariant( "!name" ) );
mRemoveBtn->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.png" ) ) );
connect( mRemoveBtn, SIGNAL( clicked() ), this, SLOT( destruct() ) );
}
void QgsSmartGroupCondition::destruct()
{
emit removed( mConditionId );
}
QString QgsSmartGroupCondition::constraint()
{
return mCondCombo->itemData( mCondCombo->currentIndex() ).toString();
}
QString QgsSmartGroupCondition::parameter()
{
return mCondLineEdit->text();
}
void QgsSmartGroupCondition::setConstraint( QString constraint )
{
mCondCombo->setCurrentIndex( mCondCombo->findData( QVariant( constraint ) ) );
}
void QgsSmartGroupCondition::setParameter( QString param )
{
mCondLineEdit->setText( param );
}
void QgsSmartGroupCondition::hideRemoveButton( bool hide )
{
mRemoveBtn->setVisible( !hide );
}
// ------------------------ //
// Editor Dialog Functions //
// ------------------------ //
QgsSmartGroupEditorDialog::QgsSmartGroupEditorDialog( QgsStyleV2* style, QWidget* parent )
: QDialog( parent ), mStyle( style )
{
setupUi( this );
mCondCount = 0;
mAndOrCombo->addItem( "ALL the constraints", QVariant( "AND" ) );
mAndOrCombo->addItem( "any ONE of the constraints", QVariant( "OR" ) );
mLayout = new QGridLayout( mConditionsBox );
addCondition();
connect( mAddConditionBtn, SIGNAL( clicked() ), this, SLOT( addCondition() ) );
}
QgsSmartGroupEditorDialog::~QgsSmartGroupEditorDialog()
{
}
QString QgsSmartGroupEditorDialog::smartgroupName()
{
return mNameLineEdit->text();
}
void QgsSmartGroupEditorDialog::addCondition()
{
// enable the remove buttons when 2nd condition is added
if ( mConditionMap.count() == 1 )
{
foreach ( QgsSmartGroupCondition *condition, mConditionMap.values() )
{
condition->hideRemoveButton( false );
}
}
QgsSmartGroupCondition *cond = new QgsSmartGroupCondition( mCondCount, this );
mLayout->addWidget( cond, mCondCount, 0, 1, 1 );
connect( cond, SIGNAL( removed( int ) ), this, SLOT( removeCondition( int ) ) );
if ( mConditionMap.count() == 0 )
{
cond->hideRemoveButton( true );
}
mConditionMap.insert( mCondCount, cond );
++mCondCount;
}
void QgsSmartGroupEditorDialog::removeCondition( int id )
{
// hide the remove button of the last condition when 2nd last is removed
if ( mConditionMap.count() == 2 )
{
foreach( QgsSmartGroupCondition* condition, mConditionMap.values() )
{
condition->hideRemoveButton( true );
}
}
QgsSmartGroupCondition *cond = mConditionMap.take( id );
delete cond;
}
QgsSmartConditionMap QgsSmartGroupEditorDialog::conditionMap()
{
QgsSmartConditionMap conditions;
foreach( QgsSmartGroupCondition* condition, mConditionMap.values() )
{
conditions.insert( condition->constraint(), condition->parameter() );
}
return conditions;
}
QString QgsSmartGroupEditorDialog::conditionOperator()
{
return mAndOrCombo->itemData( mAndOrCombo->currentIndex() ).toString();
}
void QgsSmartGroupEditorDialog::setConditionMap( QgsSmartConditionMap map )
{
QStringList constraints;
constraints << "tag" << "group" << "name" << "!tag" << "!group" << "!name" ;
// clear any defaults
foreach( int id, mConditionMap.keys() )
{
QgsSmartGroupCondition *cond = mConditionMap.take( id );
delete cond;
}
//set the constraints
foreach ( const QString &constr, constraints )
{
QStringList params = map.values( constr );
foreach ( const QString &param, params )
{
QgsSmartGroupCondition *cond = new QgsSmartGroupCondition( mCondCount, this );
mLayout->addWidget( cond, mCondCount, 0, 1, 1 );
cond->setConstraint( constr );
cond->setParameter( param );
connect( cond, SIGNAL( removed( int ) ), this, SLOT( removeCondition( int ) ) );
mConditionMap.insert( mCondCount, cond );
++mCondCount;
}
}
}
void QgsSmartGroupEditorDialog::setOperator( QString op )
{
mAndOrCombo->setCurrentIndex( mAndOrCombo->findData( QVariant( op ) ) );
}
void QgsSmartGroupEditorDialog::setSmartgroupName( QString name )
{
mNameLineEdit->setText( name );
}
void QgsSmartGroupEditorDialog::on_buttonBox_accepted()
{
if ( mNameLineEdit->text().isEmpty() )
{
QMessageBox::critical( this, tr( "Invalid name" ), tr( "The smart group name field is empty. Kindly provide a name" ) );
return;
}
accept();
}

View File

@ -0,0 +1,114 @@
/***************************************************************************
qgssmartgroupeditordialog.h
---------------------------
begin : July 2012
copyright : (C) 2012 by Arunmozhi
email : aruntheguy at gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSSMARTGROUPCONDITION_H
#define QGSSMARTGROUPCONDITION_H
#include "ui_qgssmartgroupconditionwidget.h"
class GUI_EXPORT QgsSmartGroupCondition : public QWidget, private Ui::QgsSmartGroupConditionWidget
{
Q_OBJECT
public:
QgsSmartGroupCondition( int id, QWidget *parent = NULL );
//! returns the constraint key
QString constraint();
//! returns the parameter
QString parameter();
//! sets the given constraint
void setConstraint( QString constraint );
//! sets the given param
void setParameter( QString param );
//! sets the remove button hidden state to 'hide'
void hideRemoveButton( bool hide );
public slots:
void destruct();
signals:
void removed( int );
protected:
int mConditionId;
};
#endif //QGSSMARTGROUPCONDITION
#ifndef QGSSMARTGROUPEDITORDIALOG_H
#define QGSSMARTGROUPEDITORDIALOG_H
#include <QDialog>
#include "ui_qgssmartgroupeditordialogbase.h"
//#include "qgscontexthelp.h"
#include "qgsstylev2.h" //for QgsSmartConditionMap
class GUI_EXPORT QgsSmartGroupEditorDialog : public QDialog, private Ui::QgsSmartGroupEditorDialogBase
{
Q_OBJECT
public:
QgsSmartGroupEditorDialog( QgsStyleV2* style, QWidget* parent = NULL );
~QgsSmartGroupEditorDialog();
//! returns the value from mNameLineEdit
QString smartgroupName();
//! returns the condition map
QgsSmartConditionMap conditionMap();
//! returns the AND/OR condition
QString conditionOperator();
//! sets up the GUI for the given conditionmap
void setConditionMap( QgsSmartConditionMap );
//! sets the operator AND/OR
void setOperator( QString );
//! sets the smart group Name
void setSmartgroupName( QString );
public slots:
//! function to create a new ConditionBox and update UI
void addCondition();
//! slot to remove the condition with id int
void removeCondition( int );
void on_buttonBox_accepted();
protected:
QgsStyleV2* mStyle;
// layout of the mConditionsBox
QGridLayout *mLayout;
// counter for the number of conditions
int mCondCount;
// map tracking the condition widget and the ids
QMap<int,QgsSmartGroupCondition*> mConditionMap;
};
#endif // QGSSMARTGROUPEDITORDIALOG_H

View File

@ -13,24 +13,23 @@
* (at your option) any later version. *
* *
***************************************************************************/
#include <QCloseEvent>
#include <QFileDialog>
#include <QMessageBox>
#include <QPushButton>
#include <QStandardItemModel>
#include "qgsstylev2exportimportdialog.h"
#include "qgsstylev2.h"
#include "qgssymbolv2.h"
#include "qgssymbollayerv2utils.h"
#include "qgsvectorcolorrampv2.h"
#include "qgslogger.h"
QgsStyleV2ExportImportDialog::QgsStyleV2ExportImportDialog( QgsStyleV2* style, QWidget *parent, Mode mode, QString fileName )
#include <QInputDialog>
#include <QCloseEvent>
#include <QFileDialog>
#include <QMessageBox>
#include <QPushButton>
#include <QStandardItemModel>
QgsStyleV2ExportImportDialog::QgsStyleV2ExportImportDialog( QgsStyleV2* style, QWidget *parent, Mode mode )
: QDialog( parent )
, mFileName( fileName )
, mDialogMode( mode )
, mQgisStyle( style )
{
@ -50,18 +49,45 @@ QgsStyleV2ExportImportDialog::QgsStyleV2ExportImportDialog( QgsStyleV2* style, Q
listItems->setModel( model );
mTempStyle = new QgsStyleV2();
// TODO validate
mFileName = "";
mProgressDlg = NULL;
mTempFile = NULL;
mNetManager = new QNetworkAccessManager( this );
mNetReply = NULL;
if ( mDialogMode == Import )
{
// populate the import types
importTypeCombo->addItem( "file specified below", QVariant( "file" ) );
// importTypeCombo->addItem( "official QGIS repo online", QVariant( "official" ) );
importTypeCombo->addItem( "URL specified below", QVariant( "url" ) );
connect( importTypeCombo, SIGNAL( currentIndexChanged( int ) ), this, SLOT( importTypeChanged( int ) ) );
QStringList groups = mQgisStyle->groupNames();
groupCombo->addItem( "imported", QVariant( "new" ) );
foreach ( QString gName, groups )
{
groupCombo->addItem( gName );
}
btnBrowse->setText( "Browse" );
connect( btnBrowse, SIGNAL( clicked() ), this, SLOT( browse() ) );
label->setText( tr( "Select symbols to import" ) );
buttonBox->button( QDialogButtonBox::Ok )->setText( tr( "Import" ) );
if ( !populateStyles( mTempStyle ) )
{
QApplication::postEvent( this, new QCloseEvent() );
}
}
else
{
// hide import specific controls when exporting
btnBrowse->setHidden( true );
fromLabel->setHidden( true );
importTypeCombo->setHidden( true );
locationLabel->setHidden( true );
locationLineEdit->setHidden( true );
groupLabel->setHidden( true );
groupCombo->setHidden( true );
buttonBox->button( QDialogButtonBox::Ok )->setText( tr( "Export" ) );
if ( !populateStyles( mQgisStyle ) )
{
@ -102,7 +128,7 @@ void QgsStyleV2ExportImportDialog::doExportImport()
mFileName = fileName;
moveStyles( &selection, mQgisStyle, mTempStyle );
if ( !mTempStyle->save( mFileName ) )
if ( !mTempStyle->exportXML( mFileName ) )
{
QMessageBox::warning( this, tr( "Export/import error" ),
tr( "Error when saving selected symbols to file:\n%1" )
@ -113,7 +139,6 @@ void QgsStyleV2ExportImportDialog::doExportImport()
else // import
{
moveStyles( &selection, mTempStyle, mQgisStyle );
mQgisStyle->save();
// clear model
QStandardItemModel* model = qobject_cast<QStandardItemModel*>( listItems->model() );
@ -130,10 +155,11 @@ bool QgsStyleV2ExportImportDialog::populateStyles( QgsStyleV2* style )
// load symbols and color ramps from file
if ( mDialogMode == Import )
{
if ( !mTempStyle->load( mFileName ) )
// NOTE mTempStyle is style here
if ( !style->importXML( mFileName ) )
{
QMessageBox::warning( this, tr( "Import error" ),
tr( "An error occured during import:\n%1" ).arg( mTempStyle->errorString() ) );
tr( "An error occured during import:\n%1" ).arg( style->errorString() ) );
return false;
}
}
@ -182,6 +208,54 @@ void QgsStyleV2ExportImportDialog::moveStyles( QModelIndexList* selection, QgsSt
bool isSymbol = true;
bool prompt = true;
bool overwrite = true;
int groupid = 0;
// get the groupid when going for import
if ( mDialogMode == Import )
{
int index = groupCombo->currentIndex();
QString name = groupCombo->itemText( index );
if ( name.isEmpty() )
{
// get name of the group
bool nameInvalid = true;
while ( nameInvalid )
{
bool ok;
name = QInputDialog::getText( this, tr( "Group Name"),
tr( "Please enter a name for new group:" ),
QLineEdit::Normal,
tr( "imported" ),
&ok );
if ( !ok )
{
QMessageBox::warning( this, tr( "New Group"),
tr( "New group cannot be without a name. Kindly enter a name." ) );
continue;
}
// validate name
if ( name.isEmpty() )
{
QMessageBox::warning( this, tr( "New group" ),
tr( "Cannot create a group without name. Enter a name." ) );
}
else
{
// valid name
nameInvalid = false;
}
}
groupid = dst->addGroup( name );
}
else if ( dst->groupNames().contains( name ) )
{
groupid = dst->groupId( name );
}
else
{
groupid = dst->addGroup( name );
}
}
for ( int i = 0; i < selection->size(); ++i )
{
@ -210,6 +284,8 @@ void QgsStyleV2ExportImportDialog::moveStyles( QModelIndexList* selection, QgsSt
continue;
case QMessageBox::Yes:
dst->addSymbol( symbolName, symbol );
if ( mDialogMode == Import )
dst->saveSymbol( symbolName, symbol, groupid, QStringList() );
continue;
case QMessageBox::YesToAll:
prompt = false;
@ -225,6 +301,8 @@ void QgsStyleV2ExportImportDialog::moveStyles( QModelIndexList* selection, QgsSt
if ( dst->symbolNames().contains( symbolName ) && overwrite )
{
dst->addSymbol( symbolName, symbol );
if ( mDialogMode == Import )
dst->saveSymbol( symbolName, symbol, groupid, QStringList() );
}
else if ( dst->symbolNames().contains( symbolName ) && !overwrite )
{
@ -233,6 +311,8 @@ void QgsStyleV2ExportImportDialog::moveStyles( QModelIndexList* selection, QgsSt
else
{
dst->addSymbol( symbolName, symbol );
if ( mDialogMode == Import )
dst->saveSymbol( symbolName, symbol, groupid, QStringList() );
}
}
else
@ -251,6 +331,8 @@ void QgsStyleV2ExportImportDialog::moveStyles( QModelIndexList* selection, QgsSt
continue;
case QMessageBox::Yes:
dst->addColorRamp( symbolName, ramp );
if ( mDialogMode == Import )
dst->saveColorRamp( symbolName, ramp, groupid, QStringList() );
continue;
case QMessageBox::YesToAll:
prompt = false;
@ -265,6 +347,8 @@ void QgsStyleV2ExportImportDialog::moveStyles( QModelIndexList* selection, QgsSt
if ( dst->colorRampNames().contains( symbolName ) && overwrite )
{
dst->addColorRamp( symbolName, ramp );
if ( mDialogMode == Import )
dst->saveColorRamp( symbolName, ramp, groupid, QStringList() );
}
else if ( dst->colorRampNames().contains( symbolName ) && !overwrite )
{
@ -273,6 +357,8 @@ void QgsStyleV2ExportImportDialog::moveStyles( QModelIndexList* selection, QgsSt
else
{
dst->addColorRamp( symbolName, ramp );
if ( mDialogMode == Import )
dst->saveColorRamp( symbolName, ramp, groupid, QStringList() );
}
}
}
@ -280,6 +366,7 @@ void QgsStyleV2ExportImportDialog::moveStyles( QModelIndexList* selection, QgsSt
QgsStyleV2ExportImportDialog::~QgsStyleV2ExportImportDialog()
{
delete mTempFile;
delete mTempStyle;
}
@ -292,3 +379,129 @@ void QgsStyleV2ExportImportDialog::clearSelection()
{
listItems->clearSelection();
}
void QgsStyleV2ExportImportDialog::importTypeChanged( int index )
{
QString type = importTypeCombo->itemData( index ).toString();
locationLineEdit->setText( "" );
if ( type == "file" )
{
locationLineEdit->setEnabled( true );
btnBrowse->setText( "Browse" );
}
else if ( type == "official" )
{
btnBrowse->setText( "Fetch Symbols" );
locationLineEdit->setEnabled( false );
}
else
{
btnBrowse->setText( "Fetch Symbols" );
locationLineEdit->setEnabled( true );
}
}
void QgsStyleV2ExportImportDialog::browse()
{
QString type = importTypeCombo->itemData( importTypeCombo->currentIndex() ).toString();
if ( type == "file" )
{
mFileName = QFileDialog::getOpenFileName( this, tr( "Load styles" ), ".",
tr( "XML files (*.xml *XML)" ) );
if ( mFileName.isEmpty() )
{
return;
}
QFileInfo pathInfo( mFileName );
QString groupName = pathInfo.fileName().replace( ".xml", "" );
groupCombo->setItemText( 0, groupName );
locationLineEdit->setText( mFileName );
populateStyles( mTempStyle );
}
else if ( type == "official" )
{
// TODO set URL
// downloadStyleXML( QUrl( "http://...." ) );
}
else
{
downloadStyleXML( QUrl( locationLineEdit->text() ) );
}
}
void QgsStyleV2ExportImportDialog::downloadStyleXML( QUrl url )
{
// XXX Try to move this code to some core Network interface,
// HTTP downloading is a generic functionality that might be used elsewhere
mTempFile = new QTemporaryFile();
if ( mTempFile->open() )
{
mFileName = mTempFile->fileName();
if ( mProgressDlg )
{
QProgressDialog *dummy = mProgressDlg;
mProgressDlg = NULL;
delete dummy;
}
mProgressDlg = new QProgressDialog();
mProgressDlg->setLabelText( tr( "Downloading style ... " ) );
mProgressDlg->setAutoClose( true );
connect( mProgressDlg, SIGNAL( canceled() ), this, SLOT( downloadCanceled() ) );
// open the network connection and connect the respective slots
if ( mNetReply )
{
QNetworkReply *dummyReply = mNetReply;
mNetReply = NULL;
delete dummyReply;
}
mNetReply = mNetManager->get( QNetworkRequest( url ) );
connect( mNetReply, SIGNAL( finished() ), this, SLOT( httpFinished() ) );
connect( mNetReply, SIGNAL( readyRead() ), this, SLOT( fileReadyRead() ) );
connect( mNetReply, SIGNAL( downloadProgress( qint64, qint64 ) ), this, SLOT( updateProgress( qint64, qint64 ) ) );
}
}
void QgsStyleV2ExportImportDialog::httpFinished()
{
if ( mNetReply->error() )
{
mTempFile->remove();
mFileName = "";
mProgressDlg->hide();
QMessageBox::information( this, tr( "HTTP Error!" ),
tr( "Download failed: %1." ).arg( mNetReply->errorString() ) );
return;
}
else
{
mTempFile->flush();
mTempFile->close();
populateStyles( mTempStyle );
}
}
void QgsStyleV2ExportImportDialog::fileReadyRead()
{
mTempFile->write( mNetReply->readAll() );
}
void QgsStyleV2ExportImportDialog::updateProgress( qint64 bytesRead, qint64 bytesTotal )
{
mProgressDlg->setMaximum( bytesTotal );
mProgressDlg->setValue( bytesRead );
}
void QgsStyleV2ExportImportDialog::downloadCanceled()
{
mNetReply->abort();
mTempFile->remove();
mFileName = "";
}

View File

@ -19,6 +19,11 @@
#define QGSSTYLEV2EXPORTIMPORTDIALOG_H
#include <QDialog>
#include <QUrl>
#include <QProgressDialog>
#include <QTemporaryFile>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include "ui_qgsstylev2exportimportdialogbase.h"
@ -37,7 +42,7 @@ class QgsStyleV2ExportImportDialog : public QDialog, private Ui::QgsStyleV2Expor
// constructor
// mode argument must be 0 for saving and 1 for loading
QgsStyleV2ExportImportDialog( QgsStyleV2* style, QWidget *parent = NULL, Mode mode = Export, QString fileName = "" );
QgsStyleV2ExportImportDialog( QgsStyleV2* style, QWidget *parent = NULL, Mode mode = Export );
~QgsStyleV2ExportImportDialog();
public slots:
@ -45,10 +50,25 @@ class QgsStyleV2ExportImportDialog : public QDialog, private Ui::QgsStyleV2Expor
void selectAll();
void clearSelection();
void importTypeChanged( int );
void browse();
private slots:
void httpFinished();
void fileReadyRead();
void updateProgress( qint64, qint64 );
void downloadCanceled();
private:
void downloadStyleXML( QUrl url );
bool populateStyles( QgsStyleV2* style );
void moveStyles( QModelIndexList* selection, QgsStyleV2* src, QgsStyleV2* dst );
QProgressDialog *mProgressDlg;
QTemporaryFile *mTempFile;
QNetworkAccessManager *mNetManager;
QNetworkReply *mNetReply;
QString mFileName;
Mode mDialogMode;

View File

@ -20,12 +20,13 @@
#include "qgssymbollayerv2utils.h"
#include "qgsvectorcolorrampv2.h"
#include "qgssymbolv2propertiesdialog.h"
#include "qgssymbolv2selectordialog.h"
#include "qgsvectorgradientcolorrampv2dialog.h"
#include "qgsvectorrandomcolorrampv2dialog.h"
#include "qgsvectorcolorbrewercolorrampv2dialog.h"
#include "qgscptcitycolorrampv2dialog.h"
#include "qgsstylev2exportimportdialog.h"
#include "qgssmartgroupeditordialog.h"
#include <QFile>
#include <QFileDialog>
@ -33,6 +34,8 @@
#include <QMessageBox>
#include <QSettings>
#include <QStandardItemModel>
#include <QAction>
#include <QMenu>
#include "qgsapplication.h"
#include "qgslogger.h"
@ -42,7 +45,6 @@
QgsStyleV2ManagerDialog::QgsStyleV2ManagerDialog( QgsStyleV2* style, QWidget* parent )
: QDialog( parent ), mStyle( style ), mModified( false )
{
setupUi( this );
QSettings settings;
@ -64,20 +66,63 @@ QgsStyleV2ManagerDialog::QgsStyleV2ManagerDialog( QgsStyleV2* style, QWidget* pa
connect( btnAddItem, SIGNAL( clicked() ), this, SLOT( addItem() ) );
connect( btnEditItem, SIGNAL( clicked() ), this, SLOT( editItem() ) );
connect( btnRemoveItem, SIGNAL( clicked() ), this, SLOT( removeItem() ) );
connect( btnExportItems, SIGNAL( clicked() ), this, SLOT( exportItems() ) );
connect( btnImportItems, SIGNAL( clicked() ), this, SLOT( importItems() ) );
QMenu *shareMenu = new QMenu( "Share Menu", this );
QAction *exportAction = shareMenu->addAction( "Export" );
QAction *importAction = shareMenu->addAction( "Import" );
connect( exportAction, SIGNAL( triggered() ), this, SLOT( exportItems() ) );
connect( importAction, SIGNAL( triggered() ), this, SLOT( importItems() ) );
btnShare->setMenu( shareMenu );
// Set editing mode off by default
mGrouppingMode = false;
QStandardItemModel* model = new QStandardItemModel( listItems );
listItems->setModel( model );
listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
connect( model, SIGNAL( itemChanged( QStandardItem* ) ), this, SLOT( itemChanged( QStandardItem* ) ) );
connect( listItems->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
this, SLOT( symbolSelected( const QModelIndex& ) ) );
populateTypes();
connect( tabItemType, SIGNAL( currentChanged( int ) ), this, SLOT( populateList() ) );
QStandardItemModel* groupModel = new QStandardItemModel( groupTree );
groupTree->setModel( groupModel );
groupTree->setHeaderHidden( true );
populateGroups();
connect( groupTree->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
this, SLOT( groupChanged( const QModelIndex& ) ) );
connect( groupModel, SIGNAL( itemChanged( QStandardItem* ) ),
this, SLOT( groupRenamed( QStandardItem* ) ) );
QMenu *groupMenu = new QMenu( "Group Actions", this );
QAction *groupSymbols = groupMenu->addAction( "Group Symbols" );
QAction *editSmartgroup = groupMenu->addAction( "Edit Smart Group" );
btnManageGroups->setMenu( groupMenu );
connect( groupSymbols, SIGNAL( triggered() ), this, SLOT( groupSymbolsAction() ) );
connect( editSmartgroup, SIGNAL( triggered() ), this, SLOT( editSmartgroupAction() ) );
connect( btnAddGroup, SIGNAL( clicked() ), this, SLOT( addGroup() ) );
connect( btnRemoveGroup, SIGNAL( clicked() ), this, SLOT( removeGroup() ) );
connect( tabItemType, SIGNAL( currentChanged( int ) ), this, SLOT( populateList() ) );
populateList();
connect( searchBox, SIGNAL( textChanged( QString ) ), this, SLOT( filterSymbols( QString ) ) );
tagsLineEdit->installEventFilter( this );
// Context menu for groupTree
groupTree->setContextMenuPolicy( Qt::CustomContextMenu );
connect( groupTree, SIGNAL( customContextMenuRequested( const QPoint& ) ),
this, SLOT( grouptreeContextMenu( const QPoint& ) ) );
// Context menu for listItems
listItems->setContextMenuPolicy( Qt::CustomContextMenu );
connect( listItems, SIGNAL( customContextMenuRequested( const QPoint& ) ),
this, SLOT( listitemsContextMenu( const QPoint& ) ) );
}
void QgsStyleV2ManagerDialog::onFinished()
@ -133,29 +178,20 @@ void QgsStyleV2ManagerDialog::populateTypes()
void QgsStyleV2ManagerDialog::populateList()
{
// get current symbol type
int itemType = currentItemType();
if ( itemType < 3 )
{
populateSymbols( itemType );
}
else if ( itemType == 3 )
{
populateColorRamps();
}
else
if ( currentItemType() > 3 )
{
Q_ASSERT( 0 && "not implemented" );
return;
}
groupChanged( groupTree->selectionModel()->currentIndex() );
}
void QgsStyleV2ManagerDialog::populateSymbols( int type )
void QgsStyleV2ManagerDialog::populateSymbols( QStringList symbolNames, bool check )
{
QStandardItemModel* model = qobject_cast<QStandardItemModel*>( listItems->model() );
model->clear();
QStringList symbolNames = mStyle->symbolNames();
int type = currentItemType();
for ( int i = 0; i < symbolNames.count(); ++i )
{
@ -167,21 +203,21 @@ void QgsStyleV2ManagerDialog::populateSymbols( int type )
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( symbol, listItems->iconSize() );
item->setIcon( icon );
item->setData( name ); // used to find out original name when user edited the name
item->setCheckable( check );
item->setToolTip( name );
// add to model
model->appendRow( item );
}
delete symbol;
}
}
void QgsStyleV2ManagerDialog::populateColorRamps()
void QgsStyleV2ManagerDialog::populateColorRamps( QStringList colorRamps, bool check )
{
QStandardItemModel* model = qobject_cast<QStandardItemModel*>( listItems->model() );
model->clear();
QStringList colorRamps = mStyle->colorRampNames();
for ( int i = 0; i < colorRamps.count(); ++i )
{
QString name = colorRamps[i];
@ -191,6 +227,7 @@ void QgsStyleV2ManagerDialog::populateColorRamps()
QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( ramp, listItems->iconSize() );
item->setIcon( icon );
item->setData( name ); // used to find out original name when user edited the name
item->setCheckable( check );
model->appendRow( item );
delete ramp;
}
@ -260,7 +297,7 @@ bool QgsStyleV2ManagerDialog::addSymbol()
}
// get symbol design
QgsSymbolV2PropertiesDialog dlg( symbol, 0, this );
QgsSymbolV2SelectorDialog dlg( symbol, mStyle, NULL, this );
if ( dlg.exec() == 0 )
{
delete symbol;
@ -268,31 +305,50 @@ bool QgsStyleV2ManagerDialog::addSymbol()
}
// get name
bool ok;
QString name = QInputDialog::getText( this, tr( "Symbol name" ),
tr( "Please enter name for new symbol:" ), QLineEdit::Normal, tr( "new symbol" ), &ok );
if ( !ok || name.isEmpty() )
{
delete symbol;
return false;
}
bool nameInvalid = true;
QString name;
// check if there is no symbol with same name
if ( mStyle->symbolNames().contains( name ) )
while ( nameInvalid )
{
int res = QMessageBox::warning( this, tr( "Save symbol" ),
tr( "Symbol with name '%1' already exists. Overwrite?" )
.arg( name ),
QMessageBox::Yes | QMessageBox::No );
if ( res != QMessageBox::Yes )
bool ok;
name = QInputDialog::getText( this, tr( "Symbol Name"),
tr( "Please enter a name for new symbol:" ),
QLineEdit::Normal,
tr( "new symbol" ),
&ok );
if ( !ok )
{
delete symbol;
return false;
}
// validate name
if ( name.isEmpty() )
{
QMessageBox::warning( this, tr( "Save symbol" ),
tr( "Cannot save symbol without name. Enter a name." ) );
}
else if ( mStyle->symbolNames().contains( name ) )
{
int res = QMessageBox::warning( this, tr( "Save symbol" ),
tr( "Symbol with name '%1' already exists. Overwrite?" )
.arg( name ),
QMessageBox::Yes | QMessageBox::No );
if ( res == QMessageBox::Yes )
{
nameInvalid = false;
}
}
else
{
// valid name
nameInvalid = false;
}
}
// add new symbol to style and re-populate the list
mStyle->addSymbol( name, symbol );
// TODO groups and tags
mStyle->saveSymbol( name, symbol, 0, QStringList() );
mModified = true;
return true;
}
@ -421,7 +477,7 @@ bool QgsStyleV2ManagerDialog::editSymbol()
QgsSymbolV2* symbol = mStyle->symbol( symbolName );
// let the user edit the symbol and update list when done
QgsSymbolV2PropertiesDialog dlg( symbol, 0, this );
QgsSymbolV2SelectorDialog dlg( symbol, mStyle, NULL , this );
if ( dlg.exec() == 0 )
{
delete symbol;
@ -559,6 +615,7 @@ void QgsStyleV2ManagerDialog::itemChanged( QStandardItem* item )
populateList();
mModified = true;
}
}
void QgsStyleV2ManagerDialog::exportItems()
@ -569,14 +626,635 @@ void QgsStyleV2ManagerDialog::exportItems()
void QgsStyleV2ManagerDialog::importItems()
{
QString fileName = QFileDialog::getOpenFileName( this, tr( "Load styles" ), ".",
tr( "XML files (*.xml *XML)" ) );
if ( fileName.isEmpty() )
QgsStyleV2ExportImportDialog dlg( mStyle, this, QgsStyleV2ExportImportDialog::Import );
dlg.exec();
populateList();
populateGroups();
}
void QgsStyleV2ManagerDialog::setBold( QStandardItem* item )
{
QFont font = item->font();
font.setBold( true );
item->setFont( font );
}
void QgsStyleV2ManagerDialog::populateGroups()
{
QStandardItemModel *model = qobject_cast<QStandardItemModel*>( groupTree->model() );
model->clear();
QStandardItem *allSymbols = new QStandardItem( "All Symbols" );
allSymbols->setData( "all" );
allSymbols->setEditable( false );
setBold( allSymbols );
model->appendRow( allSymbols );
QStandardItem *group = new QStandardItem( "" ); //require empty name to get first order groups
group->setData( "groups" );
group->setEditable( false );
buildGroupTree( group );
group->setText( "Groups" );//set title later
QStandardItem *ungrouped = new QStandardItem( "Ungrouped" );
ungrouped->setData( 0 );
setBold( ungrouped );
setBold( group );
group->appendRow( ungrouped );
model->appendRow( group );
QStandardItem *tag = new QStandardItem( "Smart Groups" );
tag->setData( "smartgroups" );
tag->setEditable( false );
setBold( tag );
QgsSymbolGroupMap sgMap = mStyle->smartgroupsListMap();
QgsSymbolGroupMap::const_iterator i = sgMap.constBegin();
while ( i != sgMap.constEnd() )
{
QStandardItem *item = new QStandardItem( i.value() );
item->setData( i.key() );
tag->appendRow( item );
++i;
}
model->appendRow( tag );
// expand things in the grouo tree
int rows = model->rowCount( model->indexFromItem( model->invisibleRootItem() ) );
for ( int i = 0; i < rows; i++ )
{
groupTree->setExpanded( model->indexFromItem( model->item( i ) ), true );
}
}
void QgsStyleV2ManagerDialog::buildGroupTree( QStandardItem* &parent )
{
QgsSymbolGroupMap groups = mStyle->childGroupNames( parent->text() );
QgsSymbolGroupMap::const_iterator i = groups.constBegin();
while ( i != groups.constEnd() )
{
QStandardItem *item = new QStandardItem( i.value() );
item->setData( i.key() );
parent->appendRow( item );
buildGroupTree( item );
++i;
}
}
void QgsStyleV2ManagerDialog::groupChanged( const QModelIndex& index )
{
QStringList symbolNames;
QStringList groupSymbols;
StyleEntity type = currentItemType() < 3 ? SymbolEntity : ColorrampEntity;
if ( currentItemType() > 3 )
{
QgsDebugMsg( "Entity not implemented" );
return;
}
QgsStyleV2ExportImportDialog dlg( mStyle, this, QgsStyleV2ExportImportDialog::Import, fileName );
dlg.exec();
populateList();
QString category = index.data( Qt::UserRole + 1 ).toString();
if ( category == "all" || category == "groups" || category == "smartgroups" )
{
enableGroupInputs( false );
if ( category == "groups" || category == "smartgroups" )
{
btnAddGroup->setEnabled( true );
}
symbolNames = currentItemType() < 3 ? mStyle->symbolNames() : mStyle->colorRampNames();
}
else
{
//determine groups and tags
if ( index.parent().data( Qt::UserRole + 1 ) == "smartgroups" )
{
btnAddGroup->setEnabled( false );
btnRemoveGroup->setEnabled( true );
btnManageGroups->setEnabled( true );
int groupId = index.data( Qt::UserRole + 1 ).toInt();
symbolNames = mStyle->symbolsOfSmartgroup( type, groupId );
}
else // then it must be a group
{
if ( ( !index.data( Qt::UserRole + 1 ).toInt() && ( index.data() == "Ungrouped" ) ) || mGrouppingMode )
enableGroupInputs( false );
else
enableGroupInputs( true );
int groupId = index.data( Qt::UserRole + 1 ).toInt();
symbolNames = mStyle->symbolsOfGroup( type, groupId );
if ( mGrouppingMode && groupId )
{
groupSymbols = symbolNames;
symbolNames += mStyle->symbolsOfGroup( type, 0 );
}
}
}
if ( currentItemType() < 3 )
{
populateSymbols( symbolNames, mGrouppingMode );
}
else if ( currentItemType() == 3 )
{
populateColorRamps( symbolNames, mGrouppingMode );
}
if( mGrouppingMode )
setSymbolsChecked( groupSymbols );
}
void QgsStyleV2ManagerDialog::addGroup()
{
QStandardItemModel *model = qobject_cast<QStandardItemModel*>( groupTree->model() );
QModelIndex parentIndex = groupTree->currentIndex();
// Violation 1: Creating sub-groups of system defined groups
QString parentData = parentIndex.data( Qt::UserRole + 1 ).toString();
if ( parentData == "all" || ( parentIndex.data() == "Ungrouped" && parentData == "0" ) )
{
int err = QMessageBox::critical( this, tr( "Invalid Selection" ),
tr( "The parent group you have selected is not user editable.\n"
"Kindly select a user defined Group."));
if ( err )
return;
}
// Violation 2: Creating a nested tag
if ( parentIndex.parent().data( Qt::UserRole + 1 ).toString() == "smartgroups" )
{
int err = QMessageBox::critical( this, tr( "Operation Not Allowed" ),
tr( "Creation of nested Smart Groups are not allowed\n"
"Select the 'Smart Group' to create a new group." ) );
if ( err )
return;
}
QString itemName;
QVariant itemData;
bool isGroup = true;
// create a smart group if that is selected
if ( parentIndex.data( Qt::UserRole + 1 ).toString() == "smartgroups" )
{
QgsSmartGroupEditorDialog dlg( mStyle, this );
if ( dlg.exec() == QDialog::Rejected )
return;
int id = mStyle->addSmartgroup( dlg.smartgroupName(), dlg.conditionOperator(), dlg.conditionMap() );
if ( !id )
return;
itemData = QVariant( id );
itemName = dlg.smartgroupName();
isGroup = false;
}
else
{
itemName = QString( "New Group" );
itemData = QVariant( "newgroup" );
}
// Else create a simple child-group to the selected
QStandardItem *parentItem = model->itemFromIndex( parentIndex );
QStandardItem *childItem = new QStandardItem( itemName );
childItem->setData( itemData );
parentItem->appendRow( childItem );
groupTree->setCurrentIndex( childItem->index() );
if ( isGroup )
{
groupTree->edit( childItem->index() );
}
}
void QgsStyleV2ManagerDialog::removeGroup()
{
QStandardItemModel *model = qobject_cast<QStandardItemModel*>( groupTree->model() );
QModelIndex index = groupTree->currentIndex();
// Violation: removing system groups
QString data = index.data( Qt::UserRole + 1 ).toString();
if ( data == "all" || data == "groups" || data == "smartgroups" || index.data() == "Ungrouped" )
{
int err = QMessageBox::critical( this, tr( "Invalid slection" ),
tr( "Cannot delete system defined categories.\n"
"Kindly select a group or smart group you might want to delete."));
if ( err )
return;
}
QStandardItem *parentItem = model->itemFromIndex( index.parent() );
if ( parentItem->data( Qt::UserRole + 1 ).toString() == "smartgroups" )
{
mStyle->remove( SmartgroupEntity, index.data( Qt::UserRole + 1 ).toInt() );
}
else
{
mStyle->remove( GroupEntity, index.data( Qt::UserRole + 1 ).toInt() );
QStandardItem *item = model->itemFromIndex( index );
if ( item->hasChildren() )
{
QStandardItem *parent = item->parent();
for( int i = 0; i < item->rowCount(); i++ )
{
parent->appendRow( item->takeChild( i ) );
}
}
}
parentItem->removeRow( index.row() );
}
void QgsStyleV2ManagerDialog::groupRenamed( QStandardItem * item )
{
QString data = item->data( Qt::UserRole + 1 ).toString();
QgsDebugMsg( "Symbol group edited: data=" + data + " text=" + item->text() );
if ( data == "newgroup" )
{
int id;
if ( item->parent()->data( Qt::UserRole + 1 ).toString() == "groups" )
{
id = mStyle->addGroup( item->text() );
}
else
{
int parentid = item->parent()->data( Qt::UserRole + 1 ).toInt();
id = mStyle->addGroup( item->text(), parentid );
}
if ( !id )
{
QMessageBox::critical( this, tr( "Error!" ),
tr( "New group could not be created.\n"
"There was a problem with your symbol database." ) );
item->parent()->removeRow( item->row() );
return;
}
else
{
item->setData( id );
}
}
else
{
int id = item->data( Qt::UserRole + 1 ).toInt();
QString name = item->text();
if ( item->parent()->data( Qt::UserRole + 1 ) == "smartgroups" )
{
mStyle->rename( SmartgroupEntity, id, name );
}
else
{
mStyle->rename( GroupEntity, id, name );
}
}
}
void QgsStyleV2ManagerDialog::groupSymbolsAction()
{
QStandardItemModel *treeModel = qobject_cast<QStandardItemModel*>( groupTree->model() );
QStandardItemModel *model = qobject_cast<QStandardItemModel*>( listItems->model() );
QAction *senderAction = qobject_cast<QAction*>( sender() );
if ( mGrouppingMode )
{
mGrouppingMode = false;
senderAction->setText( "Group Symbols" );
// disconnect slot which handles regrouping
disconnect( model, SIGNAL( itemChanged( QStandardItem* )),
this, SLOT( regrouped( QStandardItem* ) ) );
// disabel all items except groups in groupTree
enableItemsForGroupingMode( true );
groupChanged( groupTree->currentIndex() );
// Finally: Reconnect all Symbol editing functionalities
connect( treeModel, SIGNAL( itemChanged( QStandardItem* ) ),
this, SLOT( groupRenamed( QStandardItem* ) ) );
connect( model, SIGNAL( itemChanged( QStandardItem* ) ),
this, SLOT( itemChanged( QStandardItem* ) ) );
// Reset the selection mode
listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
}
else
{
bool validGroup = false;
// determine whether it is a valid group
QModelIndex present = groupTree->currentIndex();
while( present.parent().isValid() )
{
if ( present.parent().data() == "Groups" )
{
validGroup = true;
break;
}
else
present = present.parent();
}
if ( !validGroup )
return;
mGrouppingMode = true;
// Change the text menu
senderAction->setText( "Finish Grouping" );
// Remove all Symbol editing functionalities
disconnect( treeModel, SIGNAL( itemChanged( QStandardItem* ) ),
this, SLOT( groupRenamed( QStandardItem* ) ) );
disconnect( model, SIGNAL( itemChanged( QStandardItem* ) ),
this, SLOT( itemChanged( QStandardItem* ) ) );
// disabel all items except groups in groupTree
enableItemsForGroupingMode( false );
groupChanged( groupTree->currentIndex() );
btnManageGroups->setEnabled( true );
// Connect to slot which handles regrouping
connect( model, SIGNAL( itemChanged( QStandardItem* )),
this, SLOT( regrouped( QStandardItem* ) ) );
// No selection should be possible
listItems->setSelectionMode( QAbstractItemView::NoSelection );
}
}
void QgsStyleV2ManagerDialog::regrouped( QStandardItem *item )
{
StyleEntity type = ( currentItemType() < 3 ) ? SymbolEntity : ColorrampEntity;
if ( currentItemType() > 3 )
{
QgsDebugMsg( "Unknown style entity" );
return;
}
int groupid = groupTree->currentIndex().data( Qt::UserRole + 1 ).toInt();
QString symbolName = item->text();
bool regrouped;
if ( item->checkState() == Qt::Checked )
regrouped = mStyle->group( type, symbolName, groupid );
else
regrouped = mStyle->group( type, symbolName, 0 );
if ( !regrouped )
{
int er = QMessageBox::critical( this, tr( "Database Error"),
tr( "There was a problem with the Symbols database while regrouping." ) );
// call the slot again to get back to normal
if ( er )
groupSymbolsAction();
}
}
void QgsStyleV2ManagerDialog::setSymbolsChecked( QStringList symbols )
{
QStandardItemModel *model = qobject_cast<QStandardItemModel*>( listItems->model() );
foreach( const QString symbol, symbols )
{
QList<QStandardItem*> items = model->findItems( symbol );
foreach( QStandardItem* item, items )
item->setCheckState( Qt::Checked );
}
}
void QgsStyleV2ManagerDialog::filterSymbols( QString qword )
{
QStringList symbols = mStyle->findSymbols( qword );
populateSymbols( symbols );
}
void QgsStyleV2ManagerDialog::tagsChanged()
{
QModelIndexList indexes = listItems->selectionModel()->selection().indexes();
QStringList addtags;
QStringList removetags;
QStringList oldtags = mTagList;
QStringList newtags = tagsLineEdit->text().split( ",", QString::SkipEmptyParts );
StyleEntity type;
if ( currentItemType() < 3 )
{
type = SymbolEntity;
}
else if ( currentItemType() == 3 )
{
type = ColorrampEntity;
}
else
{
QgsDebugMsg( "Unknown Style Entity!" );
return;
}
// compare old with new to find removed tags
foreach( const QString &tag, oldtags )
{
if ( !newtags.contains( tag ) )
removetags.append( tag );
}
if ( removetags.size() > 0 )
{
foreach( QModelIndex index, indexes )
{
mStyle->detagSymbol( type, index.data().toString(), removetags );
}
}
// compare new with old to find added tags
foreach( const QString &tag, newtags )
{
if( !oldtags.contains( tag ) )
addtags.append( tag );
}
if ( addtags.size() > 0 )
{
foreach( QModelIndex index, indexes )
{
mStyle->tagSymbol( type, index.data().toString(), addtags );
}
}
}
void QgsStyleV2ManagerDialog::symbolSelected( const QModelIndex& index )
{
// Populate the tags for the symbol
tagsLineEdit->clear();
QStandardItem *item = static_cast<QStandardItemModel*>( listItems->model() )->itemFromIndex( index );
StyleEntity type = ( currentItemType() < 3 ) ? SymbolEntity : ColorrampEntity;
mTagList = mStyle->tagsOfSymbol( type, item->data().toString() );
tagsLineEdit->setText( mTagList.join( "," ) );
}
void QgsStyleV2ManagerDialog::enableSymbolInputs( bool enable )
{
groupTree->setEnabled( enable );
btnAddGroup->setEnabled( enable );
btnRemoveGroup->setEnabled( enable );
btnManageGroups->setEnabled( enable );
searchBox->setEnabled( enable );
tagsLineEdit->setEnabled( enable );
}
void QgsStyleV2ManagerDialog::enableGroupInputs( bool enable )
{
btnAddGroup->setEnabled( enable );
btnRemoveGroup->setEnabled( enable );
btnManageGroups->setEnabled( enable );
}
void QgsStyleV2ManagerDialog::enableItemsForGroupingMode( bool enable )
{
QStandardItemModel *treeModel = qobject_cast<QStandardItemModel*>( groupTree->model() );
for( int i = 0; i < treeModel->rowCount(); i++ )
{
if ( treeModel->item( i )->data() != "groups" )
{
treeModel->item( i )->setEnabled( enable );
}
if ( treeModel->item( i )->data() == "groups" )
{
treeModel->item( i )->setEnabled( enable );
for ( int k = 0; k < treeModel->item( i )->rowCount(); k++ )
{
if ( !treeModel->item( i )->child( k )->data().toInt() )
treeModel->item( i )->child( k )->setEnabled( enable );
}
}
if( treeModel->item( i )->data() == "smartgroups" )
{
for( int j = 0; j < treeModel->item( i )->rowCount(); j++ )
{
treeModel->item( i )->child( j )->setEnabled( enable );
}
}
}
// The buttons
// NOTE: if you ever change the layout name in the .ui file edit here too
for ( int i = 0; i < symbolBtnsLayout->count(); i++ )
{
symbolBtnsLayout->itemAt( i )->widget()->setEnabled( enable );
}
}
void QgsStyleV2ManagerDialog::grouptreeContextMenu( const QPoint& point )
{
QPoint globalPos = groupTree->viewport()->mapToGlobal( point );
QModelIndex index = groupTree->indexAt( point );
QgsDebugMsg( "Now you clicked : " + index.data().toString() );
QMenu groupMenu;
if ( index.parent().isValid() && ( index.data().toString() != "Ungrouped" ) )
{
if ( index.parent().data( Qt::UserRole + 1 ).toString() == "smartgroups" )
{
groupMenu.addAction( "Edit Group" );
}
else
{
groupMenu.addAction( "Add Group" );
}
groupMenu.addAction( "Remove Group" );
}
else if ( index.data( Qt::UserRole + 1 ) == "groups" || index.data( Qt::UserRole + 1 ) == "smartgroups" )
{
groupMenu.addAction( "Add Group" );
}
QAction* selectedItem = groupMenu.exec( globalPos );
if ( selectedItem )
{
if ( selectedItem->text() == "Add Group" )
addGroup();
else if ( selectedItem->text() == "Remove Group" )
removeGroup();
else if ( selectedItem->text() == "Edit Group" )
editSmartgroupAction();
}
}
void QgsStyleV2ManagerDialog::listitemsContextMenu( const QPoint& point )
{
QPoint globalPos = listItems->viewport()->mapToGlobal( point );
QMenu *groupMenu = new QMenu( this );
QMenu *groupList = new QMenu( this );
groupList->setTitle( "Apply Group" );
QStringList groups = mStyle->groupNames();
foreach( QString group, groups )
{
groupList->addAction( group );
}
groupMenu->addMenu( groupList );
groupMenu->addAction( "Un-group" );
QAction* selectedItem = groupMenu->exec( globalPos );
if ( selectedItem )
{
StyleEntity type = ( currentItemType() < 3 ) ? SymbolEntity : ColorrampEntity;
if ( currentItemType() > 3 )
{
QgsDebugMsg( "unknow entity type" );
return;
}
int groupId = 0;
if ( selectedItem->text() != "Un-group" )
{
groupId = mStyle->groupId( selectedItem->text() );
}
QModelIndexList indexes = listItems->selectionModel()->selection().indexes();
foreach( QModelIndex index, indexes )
{
mStyle->group( type, index.data().toString(), groupId );
}
populateList();
QgsDebugMsg( "Selected Action: " + selectedItem->text() );
}
}
void QgsStyleV2ManagerDialog::editSmartgroupAction()
{
QStandardItemModel *treeModel = qobject_cast<QStandardItemModel*>( groupTree->model() );
// determine whether it is a valid group
QModelIndex present = groupTree->currentIndex();
if ( present.parent().data( Qt::UserRole + 1 ) != "smartgroups" )
{
QMessageBox::critical( this, tr( "Invalid Selection" ),
tr( "You have not selected a Smart Group. Kindly select a Smart Group to edit." ) );
return;
}
QStandardItem* item = treeModel->itemFromIndex( present );
QgsSmartGroupEditorDialog dlg( mStyle, this );
QgsSmartConditionMap map = mStyle->smartgroup( present.data( Qt::UserRole + 1 ).toInt() );
dlg.setSmartgroupName( item->text() );
dlg.setOperator( mStyle->smartgroupOperator( item->data().toInt() ) );
dlg.setConditionMap( map );
if ( dlg.exec() == QDialog::Rejected )
return;
mStyle->remove( SmartgroupEntity, item->data().toInt() );
int id = mStyle->addSmartgroup( dlg.smartgroupName(), dlg.conditionOperator(), dlg.conditionMap() );
if ( !id )
{
QMessageBox::critical( this, tr( "Database Error!"),
tr( "There was some error in editing the smart group." ) );
return;
}
item->setText( dlg.smartgroupName() );
item->setData( id );
groupChanged( present );
}
bool QgsStyleV2ManagerDialog::eventFilter( QObject *obj, QEvent *event )
{
if ( ( obj == tagsLineEdit ) && ( event->type() == QEvent::FocusOut ) )
{
tagsChanged();
return true;
}
return false;
}

View File

@ -18,6 +18,8 @@
#include <QDialog>
#include <QStandardItem>
#include <QAction>
#include <QMenu>
#include "ui_qgsstylev2managerdialogbase.h"
#include "qgscontexthelp.h"
@ -40,6 +42,7 @@ class GUI_EXPORT QgsStyleV2ManagerDialog : public QDialog, private Ui::QgsStyleV
void removeItem();
void exportItems();
void importItems();
//! adds symbols of some type to list
void populateList();
@ -50,15 +53,53 @@ class GUI_EXPORT QgsStyleV2ManagerDialog : public QDialog, private Ui::QgsStyleV
void itemChanged( QStandardItem* item );
void groupChanged( const QModelIndex& );
void groupRenamed( QStandardItem * );
void addGroup();
void removeGroup();
//! carryout symbol grouping using check boxes
void groupSymbolsAction();
//! edit the selected smart group
void editSmartgroupAction();
//! symbol changed from one group
void regrouped( QStandardItem* );
//! filter the symbols based on input search term
void filterSymbols( QString );
//! Listen to tag changes
void tagsChanged();
//! Perform symbol specific tasks when selected
void symbolSelected( const QModelIndex& );
//! Context menu for the groupTree
void grouptreeContextMenu( const QPoint& );
//! Context menu for the listItems ( symbols list )
void listitemsContextMenu( const QPoint& );
protected:
//! populate combo box with known style items (symbols, color ramps)
void populateTypes();
//! populate list view with symbols of specified type
void populateSymbols( int type );
//! populate the groups
void populateGroups();
//! build the groups tree
void buildGroupTree( QStandardItem* &parent );
//! to set symbols checked when in editing mode
void setSymbolsChecked( QStringList );
//! populate list view with symbols of the current type with the given names
void populateSymbols( QStringList symbolNames, bool checkable = false );
//! populate list view with color ramps
void populateColorRamps();
void populateColorRamps( QStringList colorRamps, bool check );
int currentItemType();
QString currentItemName();
@ -74,11 +115,30 @@ class GUI_EXPORT QgsStyleV2ManagerDialog : public QDialog, private Ui::QgsStyleV
bool removeSymbol();
bool removeColorRamp();
//! Enables or disbables the symbol specific inputs
void enableSymbolInputs( bool );
//! Enables or disables the groupTree specific inputs
void enableGroupInputs( bool );
//! Enables or diables the groupTree items for grouping mode
void enableItemsForGroupingMode( bool );
//! Event filter to capture tagsLineEdit out of focus
bool eventFilter( QObject* , QEvent* );
//! sets the text of the item with bold font
void setBold( QStandardItem* );
QgsStyleV2* mStyle;
QString mStyleFilename;
bool mModified;
//! Mode to display the symbol list
bool mGrouppingMode;
//! space to store symbol tags
QStringList mTagList;
};
#endif

View File

@ -22,11 +22,15 @@
#include "characterwidget.h"
#include "qgsdashspacedialog.h"
#include "qgssymbolv2propertiesdialog.h"
#include "qgssymbolv2selectordialog.h"
#include "qgssvgcache.h"
#include "qgsstylev2.h" //for symbol selector dialog
#include "qgsapplication.h"
#include "qgslogger.h"
#include <QAbstractButton>
#include <QColorDialog>
#include <QDir>
@ -415,7 +419,6 @@ QgsMarkerLineSymbolLayerV2Widget::QgsMarkerLineSymbolLayerV2Widget( const QgsVec
setupUi( this );
connect( spinInterval, SIGNAL( valueChanged( double ) ), this, SLOT( setInterval( double ) ) );
connect( btnChangeMarker, SIGNAL( clicked() ), this, SLOT( setMarker() ) );
connect( chkRotateMarker, SIGNAL( clicked() ), this, SLOT( setRotate() ) );
connect( spinOffset, SIGNAL( valueChanged( double ) ), this, SLOT( setOffset() ) );
connect( radInterval, SIGNAL( clicked() ), this, SLOT( setPlacement() ) );
@ -447,7 +450,6 @@ void QgsMarkerLineSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
radCentralPoint->setChecked( true );
else
radVertexFirst->setChecked( true );
updateMarker();
setPlacement(); // update gui
}
@ -462,16 +464,6 @@ void QgsMarkerLineSymbolLayerV2Widget::setInterval( double val )
emit changed();
}
void QgsMarkerLineSymbolLayerV2Widget::setMarker()
{
QgsSymbolV2PropertiesDialog dlg( mLayer->subSymbol(), mVectorLayer, this );
if ( dlg.exec() == 0 )
return;
updateMarker();
emit changed();
}
void QgsMarkerLineSymbolLayerV2Widget::setRotate()
{
mLayer->setRotateMarker( chkRotateMarker->isChecked() );
@ -484,13 +476,6 @@ void QgsMarkerLineSymbolLayerV2Widget::setOffset()
emit changed();
}
void QgsMarkerLineSymbolLayerV2Widget::updateMarker()
{
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mLayer->subSymbol(), btnChangeMarker->iconSize() );
btnChangeMarker->setIcon( icon );
}
void QgsMarkerLineSymbolLayerV2Widget::setPlacement()
{
bool interval = radInterval->isChecked();
@ -519,10 +504,12 @@ QgsSvgMarkerSymbolLayerV2Widget::QgsSvgMarkerSymbolLayerV2Widget( const QgsVecto
mLayer = NULL;
setupUi( this );
viewGroups->setHeaderHidden( true );
populateList();
connect( viewImages->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( setName( const QModelIndex& ) ) );
connect( viewGroups->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( populateIcons( const QModelIndex& ) ) );
connect( spinSize, SIGNAL( valueChanged( double ) ), this, SLOT( setSize() ) );
connect( spinAngle, SIGNAL( valueChanged( double ) ), this, SLOT( setAngle() ) );
connect( spinOffsetX, SIGNAL( valueChanged( double ) ), this, SLOT( setOffset() ) );
@ -532,6 +519,7 @@ QgsSvgMarkerSymbolLayerV2Widget::QgsSvgMarkerSymbolLayerV2Widget( const QgsVecto
#include <QTime>
#include <QAbstractListModel>
#include <QPixmapCache>
#include <QStyle>
class QgsSvgListModel : public QAbstractListModel
{
@ -541,6 +529,12 @@ class QgsSvgListModel : public QAbstractListModel
mSvgFiles = QgsSvgMarkerSymbolLayerV2::listSvgFiles();
}
// Constructor to create model for icons in a specific path
QgsSvgListModel( QObject* parent, QString path ) : QAbstractListModel( parent )
{
mSvgFiles = QgsSvgMarkerSymbolLayerV2::listSvgFilesAt( path );
}
int rowCount( const QModelIndex & parent = QModelIndex() ) const
{
Q_UNUSED( parent );
@ -581,13 +575,86 @@ class QgsSvgListModel : public QAbstractListModel
QStringList mSvgFiles;
};
class QgsSvgGroupsModel : public QStandardItemModel
{
public:
QgsSvgGroupsModel( QObject* parent ) : QStandardItemModel( parent )
{
QStringList svgPaths = QgsApplication::svgPaths();
QStandardItem *parentItem = invisibleRootItem();
for ( int i = 0; i < svgPaths.size(); i++ )
{
QDir dir( svgPaths[i] );
QStandardItem *baseGroup;
if ( dir.path().contains( QgsApplication::pkgDataPath() ) )
{
baseGroup = new QStandardItem( QString( "App Symbols" ) );
}
else if ( dir.path().contains( QgsApplication::qgisSettingsDirPath() ) )
{
baseGroup = new QStandardItem( QString( "User Symbols" ) );
}
else
{
baseGroup = new QStandardItem( dir.dirName() );
}
baseGroup->setData( QVariant( svgPaths[i] ) );
baseGroup->setEditable( false );
baseGroup->setCheckable( false );
baseGroup->setIcon( QgsApplication::style()->standardIcon( QStyle::SP_DirIcon ) );
baseGroup->setToolTip( dir.path() );
parentItem->appendRow( baseGroup );
createTree( baseGroup );
QgsDebugMsg( QString( "SVG base path %1: %2" ).arg( i ).arg( baseGroup->data().toString() ) );
}
}
private:
void createTree( QStandardItem* &parentGroup )
{
QDir parentDir( parentGroup->data().toString() );
foreach( QString item, parentDir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
{
QStandardItem* group = new QStandardItem( item );
group->setData( QVariant( parentDir.path() + "/" + item ) );
group->setEditable( false );
group->setCheckable( false );
group->setToolTip( parentDir.path() + "/" + item );
group->setIcon( QgsApplication::style()->standardIcon( QStyle::SP_DirIcon ) );
parentGroup->appendRow( group );
createTree( group );
}
}
};
void QgsSvgMarkerSymbolLayerV2Widget::populateList()
{
QgsSvgListModel* m = new QgsSvgListModel( viewImages );
QgsSvgGroupsModel* g = new QgsSvgGroupsModel( viewGroups );
viewGroups->setModel( g );
// Set the tree expanded at the first level
int rows = g->rowCount( g->indexFromItem( g->invisibleRootItem() ) );
for ( int i = 0; i < rows; i++ )
{
viewGroups->setExpanded( g->indexFromItem( g->item( i ) ), true );
}
// Initally load the icons in the List view without any grouping
QgsSvgListModel* m = new QgsSvgListModel( viewImages );
viewImages->setModel( m );
}
void QgsSvgMarkerSymbolLayerV2Widget::populateIcons( const QModelIndex& idx )
{
QString path = idx.data( Qt::UserRole + 1 ).toString();
QgsSvgListModel* m = new QgsSvgListModel( viewImages, path );
viewImages->setModel( m );
connect( viewImages->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( setName( const QModelIndex& ) ) );
emit changed();
}
void QgsSvgMarkerSymbolLayerV2Widget::setGuiForSvg( const QgsSvgMarkerSymbolLayerV2* layer )
{
if ( !layer )
@ -611,6 +678,7 @@ void QgsSvgMarkerSymbolLayerV2Widget::setGuiForSvg( const QgsSvgMarkerSymbolLaye
mBorderWidthSpinBox->blockSignals( true );
mBorderWidthSpinBox->setValue( layer->outlineWidth() );
mBorderWidthSpinBox->blockSignals( false );
}
@ -816,10 +884,12 @@ QgsSVGFillSymbolLayerWidget::QgsSVGFillSymbolLayerWidget( const QgsVectorLayer*
{
mLayer = 0;
setupUi( this );
mSvgTreeView->setHeaderHidden( true );
insertIcons();
updateOutlineIcon();
connect( mSvgListView->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( setFile( const QModelIndex& ) ) );
connect( mSvgTreeView->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( populateIcons( const QModelIndex& ) ) );
}
void QgsSVGFillSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* layer )
@ -895,13 +965,33 @@ void QgsSVGFillSymbolLayerWidget::setFile( const QModelIndex& item )
void QgsSVGFillSymbolLayerWidget::insertIcons()
{
QgsSvgGroupsModel* g = new QgsSvgGroupsModel( mSvgTreeView );
mSvgTreeView->setModel( g );
// Set the tree expanded at the first level
int rows = g->rowCount( g->indexFromItem( g->invisibleRootItem() ) );
for ( int i = 0; i < rows; i++ )
{
mSvgTreeView->setExpanded( g->indexFromItem( g->item( i ) ), true );
}
QgsSvgListModel* m = new QgsSvgListModel( mSvgListView );
mSvgListView->setModel( m );
}
void QgsSVGFillSymbolLayerWidget::populateIcons( const QModelIndex& idx )
{
QString path = idx.data( Qt::UserRole + 1 ).toString();
QgsSvgListModel* m = new QgsSvgListModel( mSvgListView, path );
mSvgListView->setModel( m );
connect( mSvgListView->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( setFile( const QModelIndex& ) ) );
emit changed();
}
void QgsSVGFillSymbolLayerWidget::on_mChangeOutlinePushButton_clicked()
{
QgsSymbolV2PropertiesDialog dlg( mLayer->subSymbol(), mVectorLayer, this );
QgsSymbolV2SelectorDialog dlg( mLayer->subSymbol(), QgsStyleV2::defaultStyle(), mVectorLayer, this );
if ( dlg.exec() == QDialog::Rejected )
{
return;
@ -1062,7 +1152,7 @@ void QgsLinePatternFillSymbolLayerWidget::on_mOutlinePushButton_clicked()
{
if ( mLayer )
{
QgsSymbolV2PropertiesDialog dlg( mLayer->subSymbol(), mVectorLayer, this );
QgsSymbolV2SelectorDialog dlg( mLayer->subSymbol(), QgsStyleV2::defaultStyle(), mVectorLayer, this );
if ( dlg.exec() == QDialog::Rejected )
{
return;
@ -1079,7 +1169,6 @@ QgsPointPatternFillSymbolLayerWidget::QgsPointPatternFillSymbolLayerWidget( cons
QgsSymbolLayerV2Widget( parent, vl ), mLayer( 0 )
{
setupUi( this );
updateMarkerIcon();
}
@ -1095,7 +1184,6 @@ void QgsPointPatternFillSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* lay
mVerticalDistanceSpinBox->setValue( mLayer->distanceY() );
mHorizontalDisplacementSpinBox->setValue( mLayer->displacementX() );
mVerticalDisplacementSpinBox->setValue( mLayer->displacementY() );
updateMarkerIcon();
}
QgsSymbolLayerV2* QgsPointPatternFillSymbolLayerWidget::symbolLayer()
@ -1103,15 +1191,6 @@ QgsSymbolLayerV2* QgsPointPatternFillSymbolLayerWidget::symbolLayer()
return mLayer;
}
void QgsPointPatternFillSymbolLayerWidget::updateMarkerIcon()
{
if ( mLayer )
{
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mLayer->subSymbol(), mChangeMarkerButton->iconSize() );
mChangeMarkerButton->setIcon( icon );
}
}
void QgsPointPatternFillSymbolLayerWidget::on_mHorizontalDistanceSpinBox_valueChanged( double d )
{
if ( mLayer )
@ -1148,23 +1227,6 @@ void QgsPointPatternFillSymbolLayerWidget::on_mVerticalDisplacementSpinBox_value
}
}
void QgsPointPatternFillSymbolLayerWidget::on_mChangeMarkerButton_clicked()
{
if ( !mLayer )
{
return;
}
QgsSymbolV2PropertiesDialog dlg( mLayer->subSymbol(), mVectorLayer, this );
if ( dlg.exec() == QDialog::Rejected )
{
return;
}
updateMarkerIcon();
emit changed();
}
/////////////
QgsFontMarkerSymbolLayerV2Widget::QgsFontMarkerSymbolLayerV2Widget( const QgsVectorLayer* vl, QWidget* parent )
@ -1274,8 +1336,6 @@ QgsCentroidFillSymbolLayerV2Widget::QgsCentroidFillSymbolLayerV2Widget( const Qg
mLayer = NULL;
setupUi( this );
connect( btnChangeMarker, SIGNAL( clicked() ), this, SLOT( setMarker() ) );
}
void QgsCentroidFillSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
@ -1285,9 +1345,6 @@ void QgsCentroidFillSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer
// layer type is correct, we can do the cast
mLayer = static_cast<QgsCentroidFillSymbolLayerV2*>( layer );
// set values
updateMarker();
}
QgsSymbolLayerV2* QgsCentroidFillSymbolLayerV2Widget::symbolLayer()
@ -1295,18 +1352,3 @@ QgsSymbolLayerV2* QgsCentroidFillSymbolLayerV2Widget::symbolLayer()
return mLayer;
}
void QgsCentroidFillSymbolLayerV2Widget::setMarker()
{
QgsSymbolV2PropertiesDialog dlg( mLayer->subSymbol(), mVectorLayer, this );
if ( dlg.exec() == 0 )
return;
updateMarker();
emit changed();
}
void QgsCentroidFillSymbolLayerV2Widget::updateMarker()
{
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mLayer->subSymbol(), btnChangeMarker->iconSize() );
btnChangeMarker->setIcon( icon );
}

View File

@ -161,15 +161,12 @@ class GUI_EXPORT QgsMarkerLineSymbolLayerV2Widget : public QgsSymbolLayerV2Widge
public slots:
void setInterval( double val );
void setMarker();
void setRotate();
void setOffset();
void setPlacement();
protected:
void updateMarker();
QgsMarkerLineSymbolLayerV2* mLayer;
};
@ -195,6 +192,7 @@ class GUI_EXPORT QgsSvgMarkerSymbolLayerV2Widget : public QgsSymbolLayerV2Widget
public slots:
void setName( const QModelIndex& idx );
void populateIcons( const QModelIndex& idx );
void setSize();
void setAngle();
void setOffset();
@ -273,6 +271,7 @@ class GUI_EXPORT QgsSVGFillSymbolLayerWidget : public QgsSymbolLayerV2Widget, pr
void on_mTextureWidthSpinBox_valueChanged( double d );
void on_mSVGLineEdit_textChanged( const QString & text );
void setFile( const QModelIndex& item );
void populateIcons( const QModelIndex& item );
void on_mChangeOutlinePushButton_clicked();
void on_mRotationSpinBox_valueChanged( double d );
void on_mChangeColorButton_clicked();
@ -329,14 +328,12 @@ class GUI_EXPORT QgsPointPatternFillSymbolLayerWidget: public QgsSymbolLayerV2Wi
protected:
QgsPointPatternFillSymbolLayer* mLayer;
void updateMarkerIcon();
private slots:
void on_mHorizontalDistanceSpinBox_valueChanged( double d );
void on_mVerticalDistanceSpinBox_valueChanged( double d );
void on_mHorizontalDisplacementSpinBox_valueChanged( double d );
void on_mVerticalDisplacementSpinBox_valueChanged( double d );
void on_mChangeMarkerButton_clicked();
};
/////////
@ -392,12 +389,7 @@ class GUI_EXPORT QgsCentroidFillSymbolLayerV2Widget : public QgsSymbolLayerV2Wid
virtual void setSymbolLayer( QgsSymbolLayerV2* layer );
virtual QgsSymbolLayerV2* symbolLayer();
public slots:
void setMarker();
protected:
void updateMarker();
QgsCentroidFillSymbolLayerV2* mLayer;
};

View File

@ -0,0 +1,350 @@
/***************************************************************************
qgssymbolslist.cpp
---------------------
begin : June 2012
copyright : (C) 2012 by Arunmozhi
email : aruntheguy at gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgssymbolslistwidget.h"
#include "qgsstylev2managerdialog.h"
#include "qgssymbolv2.h"
#include "qgsstylev2.h"
#include "qgssymbollayerv2utils.h"
#include "qgsapplication.h"
#include <QString>
#include <QStringList>
#include <QPainter>
#include <QIcon>
#include <QStandardItemModel>
#include <QColorDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QMenu>
QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbolV2* symbol, QgsStyleV2* style, QMenu* menu, QWidget* parent ) : QWidget( parent )
{
mSymbol = symbol;
mStyle = style;
setupUi( this );
btnAdvanced->hide(); // advanced button is hidden by default
if ( menu ) // show it if there is a menu pointer
{
btnAdvanced->setMenu( menu );
btnAdvanced->show();
}
// populate the groups
groupsCombo->addItem( "" );
populateGroups();
QStringList groups = style->smartgroupNames();
foreach ( QString group, groups )
{
groupsCombo->addItem( group, QVariant( "smart" ) );
}
QStandardItemModel* model = new QStandardItemModel( viewSymbols );
viewSymbols->setModel( model );
connect( viewSymbols->selectionModel(), SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ), this, SLOT( setSymbolFromStyle( const QModelIndex & ) ) );
// Set the Style Menu under btnStyle
QMenu *styleMenu = new QMenu( btnStyle );
QAction *styleMgrAction = new QAction( "Style Manager", styleMenu );
styleMenu->addAction( styleMgrAction );
QAction *saveStyle = new QAction( "Save as style", styleMenu );
styleMenu->addAction( saveStyle );
connect( styleMgrAction, SIGNAL( triggered() ), this, SLOT( openStyleManager() ) );
connect( saveStyle, SIGNAL( triggered() ), this, SLOT( addSymbolToStyle() ) );
btnStyle->setMenu( styleMenu );
lblSymbolName->setText( "" );
populateSymbolView();
if ( mSymbol )
{
// output unit
mSymbolUnitComboBox->blockSignals( true );
mSymbolUnitComboBox->setCurrentIndex( mSymbol->outputUnit() );
mSymbolUnitComboBox->blockSignals( false );
mTransparencySlider->blockSignals( true );
double transparency = 1 - symbol->alpha();
mTransparencySlider->setValue( transparency * 255 );
displayTransparency( symbol->alpha() );
mTransparencySlider->blockSignals( false );
}
// select correct page in stacked widget
// there's a correspondence between symbol type number and page numbering => exploit it!
stackedWidget->setCurrentIndex( symbol->type() );
connect( btnColor, SIGNAL( clicked() ), this, SLOT( setSymbolColor() ) );
connect( spinAngle, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerAngle( double ) ) );
connect( spinSize, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerSize( double ) ) );
connect( spinWidth, SIGNAL( valueChanged( double ) ), this, SLOT( setLineWidth( double ) ) );
// Set symbol color in btnColor
updateSymbolColor();
}
void QgsSymbolsListWidget::populateGroups( QString parent, QString prepend )
{
QgsSymbolGroupMap groups = mStyle->childGroupNames( parent );
QgsSymbolGroupMap::const_iterator i = groups.constBegin();
while ( i != groups.constEnd() )
{
QString text;
if ( !prepend.isEmpty() )
{
text = prepend + "/" + i.value();
}
else
{
text = i.value();
}
groupsCombo->addItem( text, QVariant( i.key() ) );
populateGroups( i.value(), text );
++i;
}
}
void QgsSymbolsListWidget::populateSymbolView()
{
populateSymbols( mStyle->symbolNames() );
}
void QgsSymbolsListWidget::populateSymbols( QStringList names )
{
QSize previewSize = viewSymbols->iconSize();
QPixmap p( previewSize );
QPainter painter;
QStandardItemModel* model = qobject_cast<QStandardItemModel*>( viewSymbols->model() );
if ( !model )
{
return;
}
model->clear();
for ( int i = 0; i < names.count(); i++ )
{
QgsSymbolV2* s = mStyle->symbol( names[i] );
if ( s->type() != mSymbol->type() )
{
delete s;
continue;
}
QStandardItem* item = new QStandardItem( names[i] );
item->setData( names[i], Qt::UserRole ); //so we can show a label when it is clicked
item->setText( "" ); //set the text to nothing and show in label when clicked rather
item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
// create preview icon
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( s, previewSize );
item->setIcon( icon );
// add to model
model->appendRow( item );
delete s;
}
}
void QgsSymbolsListWidget::openStyleManager()
{
QgsStyleV2ManagerDialog dlg( mStyle, this );
dlg.exec();
populateSymbolView();
}
void QgsSymbolsListWidget::setSymbolColor()
{
#if defined(Q_WS_MAC) && QT_VERSION >= 0x040500 && defined(QT_MAC_USE_COCOA)
// Native Mac dialog works only for Qt Carbon
// Qt bug: http://bugreports.qt.nokia.com/browse/QTBUG-14889
// FIXME need to also check max QT_VERSION when Qt bug fixed
QColor color = QColorDialog::getColor( mSymbol->color(), this, "", QColorDialog::DontUseNativeDialog );
#else
QColor color = QColorDialog::getColor( mSymbol->color(), this );
#endif
if ( !color.isValid() )
return;
mSymbol->setColor( color );
updateSymbolColor();
emit changed();
}
void QgsSymbolsListWidget::setMarkerAngle( double angle )
{
QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
if ( markerSymbol->angle() == angle )
return;
markerSymbol->setAngle( angle );
emit changed();
}
void QgsSymbolsListWidget::setMarkerSize( double size )
{
QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
if ( markerSymbol->size() == size )
return;
markerSymbol->setSize( size );
emit changed();
}
void QgsSymbolsListWidget::setLineWidth( double width )
{
QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mSymbol );
if ( lineSymbol->width() == width )
return;
lineSymbol->setWidth( width );
emit changed();
}
void QgsSymbolsListWidget::addSymbolToStyle()
{
bool ok;
QString name = QInputDialog::getText( this, tr( "Symbol name" ),
tr( "Please enter name for the symbol:" ) , QLineEdit::Normal, tr( "New symbol" ), &ok );
if ( !ok || name.isEmpty() )
return;
// check if there is no symbol with same name
if ( mStyle->symbolNames().contains( name ) )
{
int res = QMessageBox::warning( this, tr( "Save symbol" ),
tr( "Symbol with name '%1' already exists. Overwrite?" )
.arg( name ),
QMessageBox::Yes | QMessageBox::No );
if ( res != QMessageBox::Yes )
{
return;
}
}
// add new symbol to style and re-populate the list
mStyle->addSymbol( name, mSymbol->clone() );
// make sure the symbol is stored
mStyle->saveSymbol( name, mSymbol->clone(), 0, QStringList() );
populateSymbolView();
}
void QgsSymbolsListWidget::on_mSymbolUnitComboBox_currentIndexChanged( const QString & text )
{
Q_UNUSED( text );
if ( mSymbol )
{
mSymbol->setOutputUnit(( QgsSymbolV2::OutputUnit ) mSymbolUnitComboBox->currentIndex() );
emit changed();
}
}
void QgsSymbolsListWidget::on_mTransparencySlider_valueChanged( int value )
{
if ( mSymbol )
{
double alpha = 1 - ( value / 255.0 );
mSymbol->setAlpha( alpha );
displayTransparency( alpha );
emit changed();
}
}
void QgsSymbolsListWidget::displayTransparency( double alpha )
{
double transparencyPercent = ( 1 - alpha ) * 100;
mTransparencyLabel->setText( tr( "Transparency %1%" ).arg(( int ) transparencyPercent ) );
}
void QgsSymbolsListWidget::updateSymbolColor()
{
btnColor->setColor( mSymbol->color() );
}
void QgsSymbolsListWidget::updateSymbolInfo()
{
updateSymbolColor();
if ( mSymbol->type() == QgsSymbolV2::Marker )
{
QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
spinSize->setValue( markerSymbol->size() );
spinAngle->setValue( markerSymbol->angle() );
}
else if ( mSymbol->type() == QgsSymbolV2::Line )
{
QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mSymbol );
spinWidth->setValue( lineSymbol->width() );
}
}
void QgsSymbolsListWidget::setSymbolFromStyle( const QModelIndex & index )
{
QString symbolName = index.data( Qt::UserRole ).toString();
lblSymbolName->setText( symbolName );
// get new instance of symbol from style
QgsSymbolV2* s = mStyle->symbol( symbolName );
// remove all symbol layers from original symbol
while ( mSymbol->symbolLayerCount() )
mSymbol->deleteSymbolLayer( 0 );
// move all symbol layers to our symbol
while ( s->symbolLayerCount() )
{
QgsSymbolLayerV2* sl = s->takeSymbolLayer( 0 );
mSymbol->appendSymbolLayer( sl );
}
// delete the temporary symbol
delete s;
updateSymbolInfo();
emit changed();
}
void QgsSymbolsListWidget::on_groupsCombo_currentIndexChanged( int index )
{
QStringList symbols;
QString text = groupsCombo->itemText( index );
// List all symbols when empty list item is selected
if ( text.isEmpty() )
{
symbols = mStyle->symbolNames();
}
else
{
int groupid;
if ( groupsCombo->itemData( index ).toString() == "smart" )
{
groupid = mStyle->smartgroupId( text );
symbols = mStyle->symbolsOfSmartgroup( SymbolEntity, groupid );
}
else
{
groupid = groupsCombo->itemData( index ).toInt();
symbols = mStyle->symbolsOfGroup( SymbolEntity, groupid );
}
}
populateSymbols( symbols );
}
void QgsSymbolsListWidget::on_groupsCombo_editTextChanged( const QString &text )
{
QStringList symbols = mStyle->findSymbols( text );
populateSymbols( symbols );
}

View File

@ -0,0 +1,70 @@
/***************************************************************************
qgssymbolslistwidget.h
---------------------
begin : June 2012
copyright : (C) 2012 by Arunmozhi
email : aruntheguy at gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSSYMBOLSLISTWIDGET_H
#define QGSSYMBOLSLISTWIDGET_H
#include "ui_widget_symbolslist.h"
#include <QWidget>
class QgsSymbolV2;
class QgsStyleV2;
class QMenu;
class GUI_EXPORT QgsSymbolsListWidget : public QWidget, private Ui::SymbolsListWidget
{
Q_OBJECT
public:
QgsSymbolsListWidget( QgsSymbolV2* symbol, QgsStyleV2* style, QMenu* menu, QWidget* parent = NULL );
public slots:
void setSymbolFromStyle( const QModelIndex & index );
void setSymbolColor();
void setMarkerAngle( double angle );
void setMarkerSize( double size );
void setLineWidth( double width );
void addSymbolToStyle();
void on_mSymbolUnitComboBox_currentIndexChanged( const QString & text );
void on_mTransparencySlider_valueChanged( int value );
void on_groupsCombo_currentIndexChanged( int index );
void on_groupsCombo_editTextChanged( const QString &text );
void openStyleManager();
signals:
void changed();
protected:
QgsSymbolV2* mSymbol;
QgsStyleV2* mStyle;
void populateSymbolView();
void populateSymbols( QStringList symbols );
void updateSymbolColor();
void updateSymbolInfo();
private:
/**Displays alpha value as transparency in mTransparencyLabel*/
void displayTransparency( double alpha );
/** Recursive function to create the group tree in the widget */
void populateGroups( QString parent = "", QString prepend = "" );
};
#endif //QGSSYMBOLSLISTWIDGET_H

View File

@ -1,458 +0,0 @@
/***************************************************************************
qgssymbolv2propertiesdialog.cpp
---------------------
begin : November 2009
copyright : (C) 2009 by Martin Dobias
email : wonder.sk at gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgssymbolv2propertiesdialog.h"
#include <QFile>
#include <QStandardItem>
#include <QKeyEvent>
#include "qgssymbollayerv2.h"
#include "qgssymbollayerv2registry.h"
#include "qgsapplication.h"
#include "qgslogger.h"
#include "qgssymbollayerv2widget.h"
#include "qgsellipsesymbollayerv2widget.h"
#include "qgsvectorfieldsymbollayerwidget.h"
#include "qgssymbolv2.h" //for the unit
static const int SymbolLayerItemType = QStandardItem::UserType + 1;
class SymbolLayerItem : public QStandardItem
{
public:
SymbolLayerItem( QgsSymbolLayerV2* layer )
{
setLayer( layer );
}
void setLayer( QgsSymbolLayerV2* layer )
{
mLayer = layer;
updatePreview();
}
void updatePreview()
{
QIcon icon = QgsSymbolLayerV2Utils::symbolLayerPreviewIcon( mLayer, QgsSymbolV2::MM, QSize( 16, 16 ) ); //todo: make unit a parameter
setIcon( icon );
}
int type() const { return SymbolLayerItemType; }
QVariant data( int role ) const
{
if ( role == Qt::DisplayRole )
return QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( mLayer->layerType() )->visibleName();
if ( role == Qt::SizeHintRole )
return QVariant( QSize( 32, 32 ) );
if ( role == Qt::CheckStateRole )
return QVariant(); // could be true/false
return QStandardItem::data( role );
}
protected:
QgsSymbolLayerV2* mLayer;
};
//////////
static bool _initWidgetFunction( QString name, QgsSymbolLayerV2WidgetFunc f )
{
QgsSymbolLayerV2Registry* reg = QgsSymbolLayerV2Registry::instance();
QgsSymbolLayerV2AbstractMetadata* abstractMetadata = reg->symbolLayerMetadata( name );
if ( abstractMetadata == NULL )
{
QgsDebugMsg( "Failed to find symbol layer's entry in registry: " + name );
return false;
}
QgsSymbolLayerV2Metadata* metadata = dynamic_cast<QgsSymbolLayerV2Metadata*>( abstractMetadata );
if ( metadata == NULL )
{
QgsDebugMsg( "Failed to cast symbol layer's metadata: " + name );
return false;
}
metadata->setWidgetFunction( f );
return true;
}
static void _initWidgetFunctions()
{
static bool initialized = false;
if ( initialized )
return;
_initWidgetFunction( "SimpleLine", QgsSimpleLineSymbolLayerV2Widget::create );
_initWidgetFunction( "MarkerLine", QgsMarkerLineSymbolLayerV2Widget::create );
_initWidgetFunction( "LineDecoration", QgsLineDecorationSymbolLayerV2Widget::create );
_initWidgetFunction( "SimpleMarker", QgsSimpleMarkerSymbolLayerV2Widget::create );
_initWidgetFunction( "SvgMarker", QgsSvgMarkerSymbolLayerV2Widget::create );
_initWidgetFunction( "FontMarker", QgsFontMarkerSymbolLayerV2Widget::create );
_initWidgetFunction( "EllipseMarker", QgsEllipseSymbolLayerV2Widget::create );
_initWidgetFunction( "VectorField", QgsVectorFieldSymbolLayerWidget::create );
_initWidgetFunction( "SimpleFill", QgsSimpleFillSymbolLayerV2Widget::create );
_initWidgetFunction( "SVGFill", QgsSVGFillSymbolLayerWidget::create );
_initWidgetFunction( "CentroidFill", QgsCentroidFillSymbolLayerV2Widget::create );
_initWidgetFunction( "LinePatternFill", QgsLinePatternFillSymbolLayerWidget::create );
_initWidgetFunction( "PointPatternFill", QgsPointPatternFillSymbolLayerWidget::create );
initialized = true;
}
//////////
QgsSymbolV2PropertiesDialog::QgsSymbolV2PropertiesDialog( QgsSymbolV2* symbol, const QgsVectorLayer* vl, QWidget* parent )
: QDialog( parent ), mSymbol( symbol ), mVectorLayer( vl )
{
setupUi( this );
// setup icons
btnAddLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.png" ) ) );
btnRemoveLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.png" ) ) );
QIcon iconLock;
iconLock.addFile( QgsApplication::iconPath( "locked.png" ), QSize(), QIcon::Normal, QIcon::On );
iconLock.addFile( QgsApplication::iconPath( "unlocked.png" ), QSize(), QIcon::Normal, QIcon::Off );
btnLock->setIcon( iconLock );
btnUp->setIcon( QIcon( QgsApplication::iconPath( "symbologyUp.png" ) ) );
btnDown->setIcon( QIcon( QgsApplication::iconPath( "symbologyDown.png" ) ) );
// set widget functions
// (should be probably moved somewhere else)
_initWidgetFunctions();
loadSymbol();
connect( btnUp, SIGNAL( clicked() ), this, SLOT( moveLayerUp() ) );
connect( btnDown, SIGNAL( clicked() ), this, SLOT( moveLayerDown() ) );
connect( btnAddLayer, SIGNAL( clicked() ), this, SLOT( addLayer() ) );
connect( btnRemoveLayer, SIGNAL( clicked() ), this, SLOT( removeLayer() ) );
connect( btnLock, SIGNAL( clicked() ), this, SLOT( lockLayer() ) );
populateLayerTypes();
connect( cboLayerType, SIGNAL( currentIndexChanged( int ) ), this, SLOT( layerTypeChanged() ) );
loadPropertyWidgets();
updateUi();
// set first layer as active
QModelIndex newIndex = listLayers->model()->index( 0, 0 );
listLayers->setCurrentIndex( newIndex );
}
void QgsSymbolV2PropertiesDialog::loadSymbol()
{
QStandardItemModel* model = new QStandardItemModel( this );
listLayers->setModel( model );
QItemSelectionModel* selModel = listLayers->selectionModel();
connect( selModel, SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( layerChanged() ) );
int count = mSymbol->symbolLayerCount();
for ( int i = count - 1; i >= 0; i-- )
{
model->appendRow( new SymbolLayerItem( mSymbol->symbolLayer( i ) ) );
}
updatePreview();
}
void QgsSymbolV2PropertiesDialog::populateLayerTypes()
{
QStringList types = QgsSymbolLayerV2Registry::instance()->symbolLayersForType( mSymbol->type() );
cboLayerType->clear();
for ( int i = 0; i < types.count(); i++ )
cboLayerType->addItem( QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( types[i] )->visibleName(), types[i] );
if ( mSymbol->type() == QgsSymbolV2::Fill )
{
QStringList typesLine = QgsSymbolLayerV2Registry::instance()->symbolLayersForType( QgsSymbolV2::Line );
for ( int i = 0; i < typesLine.count(); i++ )
{
QString visibleName = QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( typesLine[i] )->visibleName();
QString name = QString( tr( "Outline: %1" ) ).arg( visibleName );
cboLayerType->addItem( name, typesLine[i] );
}
}
}
void QgsSymbolV2PropertiesDialog::updateUi()
{
int row = currentRowIndex();
int count = listLayers->model()->rowCount();
btnUp->setEnabled( row > 0 );
btnDown->setEnabled( row < count - 1 && row != -1 );
btnRemoveLayer->setEnabled( count > 1 && row != -1 );
}
void QgsSymbolV2PropertiesDialog::updatePreview()
{
QImage preview = mSymbol->bigSymbolPreviewImage();
lblPreview->setPixmap( QPixmap::fromImage( preview ) );
}
void QgsSymbolV2PropertiesDialog::updateLayerPreview()
{
// get current layer item and update its icon
SymbolLayerItem* item = currentLayerItem();
if ( item )
item->updatePreview();
// update also preview of the whole symbol
updatePreview();
}
void QgsSymbolV2PropertiesDialog::updateSymbolLayerWidget( QgsSymbolLayerV2* layer )
{
QString layerType = layer->layerType();
// stop updating from the original widget
if ( stackedWidget->currentWidget() != pageDummy )
disconnect( stackedWidget->currentWidget(), SIGNAL( changed() ), this, SLOT( updateLayerPreview() ) );
// update active properties widget
if ( mWidgets.contains( layerType ) )
{
stackedWidget->setCurrentWidget( mWidgets[layerType] );
mWidgets[layerType]->setSymbolLayer( layer );
// start recieving updates from widget
connect( mWidgets[layerType], SIGNAL( changed() ), this, SLOT( updateLayerPreview() ) );
}
else
{
// use dummy widget instead
stackedWidget->setCurrentWidget( pageDummy );
}
}
void QgsSymbolV2PropertiesDialog::loadPropertyWidgets()
{
QgsSymbolLayerV2Registry* pReg = QgsSymbolLayerV2Registry::instance();
QStringList layerTypes = pReg->symbolLayersForType( mSymbol->type() );
// also load line symbol layers for fill symbols
if ( mSymbol->type() == QgsSymbolV2::Fill )
layerTypes += pReg->symbolLayersForType( QgsSymbolV2::Line );
for ( int i = 0; i < layerTypes.count(); i++ )
{
QString layerType = layerTypes[i];
QgsSymbolLayerV2AbstractMetadata* am = pReg->symbolLayerMetadata( layerType );
if ( am == NULL ) // check whether the metadata is assigned
continue;
QgsSymbolLayerV2Widget* w = am->createSymbolLayerWidget( mVectorLayer );
if ( w == NULL ) // check whether the function returns correct widget
continue;
mWidgets[layerType] = w;
stackedWidget->addWidget( w );
}
}
int QgsSymbolV2PropertiesDialog::currentRowIndex()
{
QModelIndex idx = listLayers->selectionModel()->currentIndex();
if ( !idx.isValid() )
return -1;
return idx.row();
}
int QgsSymbolV2PropertiesDialog::currentLayerIndex()
{
return listLayers->model()->rowCount() - currentRowIndex() - 1;
}
SymbolLayerItem* QgsSymbolV2PropertiesDialog::currentLayerItem()
{
int index = currentRowIndex();
if ( index < 0 )
return NULL;
QStandardItemModel* model = qobject_cast<QStandardItemModel*>( listLayers->model() );
if ( model == NULL )
return NULL;
QStandardItem* item = model->item( index );
if ( item->type() != SymbolLayerItemType )
return NULL;
return static_cast<SymbolLayerItem*>( item );
}
QgsSymbolLayerV2* QgsSymbolV2PropertiesDialog::currentLayer()
{
int idx = currentLayerIndex();
if ( idx < 0 )
return NULL;
return mSymbol->symbolLayer( idx );
}
void QgsSymbolV2PropertiesDialog::layerChanged()
{
updateUi();
// get layer info
QgsSymbolLayerV2* layer = currentLayer();
if ( !layer )
return;
// update layer type combo box
int idx = cboLayerType->findData( layer->layerType() );
cboLayerType->setCurrentIndex( idx );
updateSymbolLayerWidget( layer );
updateLockButton();
}
void QgsSymbolV2PropertiesDialog::updateLockButton()
{
QgsSymbolLayerV2* layer = currentLayer();
if ( !layer )
return;
btnLock->setChecked( layer->isLocked() );
}
void QgsSymbolV2PropertiesDialog::layerTypeChanged()
{
QgsSymbolLayerV2* layer = currentLayer();
if ( !layer )
return;
QString newLayerType = cboLayerType->itemData( cboLayerType->currentIndex() ).toString();
if ( layer->layerType() == newLayerType )
return;
// get creation function for new layer from registry
QgsSymbolLayerV2Registry* pReg = QgsSymbolLayerV2Registry::instance();
QgsSymbolLayerV2AbstractMetadata* am = pReg->symbolLayerMetadata( newLayerType );
if ( am == NULL ) // check whether the metadata is assigned
return;
// change layer to a new (with different type)
QgsSymbolLayerV2* newLayer = am->createSymbolLayer( QgsStringMap() );
if ( newLayer == NULL )
return;
mSymbol->changeSymbolLayer( currentLayerIndex(), newLayer );
updateSymbolLayerWidget( newLayer );
// update symbol layer item
SymbolLayerItem* item = currentLayerItem();
item->setLayer( newLayer );
item->updatePreview();
updatePreview();
}
void QgsSymbolV2PropertiesDialog::addLayer()
{
QgsSymbolLayerV2* newLayer = QgsSymbolLayerV2Registry::instance()->defaultSymbolLayer( mSymbol->type() );
mSymbol->appendSymbolLayer( newLayer );
loadSymbol();
QModelIndex newIndex = listLayers->model()->index( 0, 0 );
listLayers->setCurrentIndex( newIndex );
updateUi();
}
void QgsSymbolV2PropertiesDialog::removeLayer()
{
int idx = currentLayerIndex();
if ( idx < 0 )
return;
int row = currentRowIndex();
mSymbol->deleteSymbolLayer( idx );
loadSymbol();
updateUi();
// set previous layer as active
QModelIndex newIndex = listLayers->model()->index( qMin( row, mSymbol->symbolLayerCount() - 1 ), 0 );
listLayers->setCurrentIndex( newIndex );
}
void QgsSymbolV2PropertiesDialog::moveLayerDown()
{
moveLayerByOffset( + 1 );
}
void QgsSymbolV2PropertiesDialog::moveLayerUp()
{
moveLayerByOffset( -1 );
}
void QgsSymbolV2PropertiesDialog::moveLayerByOffset( int offset )
{
int rowIdx = currentRowIndex();
int layerIdx = currentLayerIndex();
// switch layers
QgsSymbolLayerV2* tmpLayer = mSymbol->takeSymbolLayer( layerIdx );
mSymbol->insertSymbolLayer( layerIdx - offset, tmpLayer );
loadSymbol();
QModelIndex newIndex = listLayers->model()->index( rowIdx + offset, 0 );
listLayers->setCurrentIndex( newIndex );
updateUi();
}
void QgsSymbolV2PropertiesDialog::lockLayer()
{
QgsSymbolLayerV2* layer = currentLayer();
if ( !layer )
return;
layer->setLocked( btnLock->isChecked() );
}
void QgsSymbolV2PropertiesDialog::keyPressEvent( QKeyEvent * e )
{
// Ignore the ESC key to avoid close the dialog without the properties window
if ( !isWindow() && e->key() == Qt::Key_Escape )
{
e->ignore();
}
else
{
QDialog::keyPressEvent( e );
}
}

View File

@ -1,86 +0,0 @@
/***************************************************************************
qgssymbolv2propertiesdialog.h
---------------------
begin : November 2009
copyright : (C) 2009 by Martin Dobias
email : wonder.sk at gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSSYMBOLV2PROPERTIESDIALOG_H
#define QGSSYMBOLV2PROPERTIESDIALOG_H
#include "ui_qgssymbolv2propertiesdialogbase.h"
class QgsSymbolV2;
class QgsSymbolLayerV2;
class QgsSymbolLayerV2Widget;
class QgsVectorLayer;
class SymbolLayerItem;
#include <QMap>
class GUI_EXPORT QgsSymbolV2PropertiesDialog : public QDialog, private Ui::DlgSymbolV2Properties
{
Q_OBJECT
public:
QgsSymbolV2PropertiesDialog( QgsSymbolV2* symbol, const QgsVectorLayer* vl, QWidget* parent = NULL );
public slots:
void moveLayerDown();
void moveLayerUp();
void addLayer();
void removeLayer();
void lockLayer();
void layerTypeChanged();
void layerChanged();
void updateLayerPreview();
void updatePreview();
protected:
//! Reimplements dialog keyPress event so we can ignore it
void keyPressEvent( QKeyEvent * event );
void loadSymbol();
void populateLayerTypes();
void updateUi();
void loadPropertyWidgets();
void updateSymbolLayerWidget( QgsSymbolLayerV2* layer );
void updateLockButton();
int currentRowIndex();
int currentLayerIndex();
SymbolLayerItem* currentLayerItem();
QgsSymbolLayerV2* currentLayer();
void moveLayerByOffset( int offset );
protected: // data
QgsSymbolV2* mSymbol;
QMap<QString, QgsSymbolLayerV2Widget*> mWidgets;
const QgsVectorLayer* mVectorLayer;
};
#endif

View File

@ -15,13 +15,20 @@
#include "qgssymbolv2selectordialog.h"
#include "qgssymbolv2propertiesdialog.h"
#include "qgsstylev2managerdialog.h"
#include "qgssymbolv2.h"
#include "qgssymbollayerv2utils.h"
#include "qgsstylev2.h"
#include "qgssymbolv2.h"
#include "qgssymbollayerv2.h"
#include "qgssymbollayerv2utils.h"
#include "qgssymbollayerv2registry.h"
// the widgets
#include "qgssymbolslistwidget.h"
#include "qgslayerpropertieswidget.h"
#include "qgssymbollayerv2widget.h"
#include "qgsellipsesymbollayerv2widget.h"
#include "qgsvectorfieldsymbollayerwidget.h"
#include "qgslogger.h"
#include "qgsapplication.h"
#include <QColorDialog>
@ -32,240 +39,152 @@
#include <QKeyEvent>
#include <QMenu>
#include <QWidget>
#include <QFile>
#include <QStandardItem>
static const int SymbolLayerItemType = QStandardItem::UserType + 1;
// Hybrid item which may represent a symbol or a layer
// Check using item->isLayer()
class SymbolLayerItem : public QStandardItem
{
public:
SymbolLayerItem( QgsSymbolLayerV2* layer )
{
setLayer( layer );
}
SymbolLayerItem( QgsSymbolV2* symbol )
{
setSymbol( symbol );
}
void setLayer( QgsSymbolLayerV2* layer )
{
mLayer = layer;
mIsLayer = true;
mSymbol = NULL;
updatePreview();
}
void setSymbol( QgsSymbolV2* symbol )
{
mSymbol = symbol;
mIsLayer = false;
mLayer = NULL;
updatePreview();
}
void updatePreview()
{
QIcon icon;
if ( mIsLayer )
icon = QgsSymbolLayerV2Utils::symbolLayerPreviewIcon( mLayer, QgsSymbolV2::MM, QSize( 16, 16 ) ); //todo: make unit a parameter
else
icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mSymbol, QSize( 16, 16 ) );
setIcon( icon );
if ( parent() )
static_cast<SymbolLayerItem*>( parent() )->updatePreview();
}
int type() const { return SymbolLayerItemType; }
bool isLayer() { return mIsLayer; }
// returns the symbol pointer; helpful in determining a layer's parent symbol
QgsSymbolV2* symbol()
{
if ( mIsLayer )
return NULL;
return mSymbol;
}
QgsSymbolLayerV2* layer()
{
if ( mIsLayer )
return mLayer;
return NULL;
}
QVariant data( int role ) const
{
if ( role == Qt::DisplayRole || role == Qt::EditRole )
{
if ( mIsLayer )
return QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( mLayer->layerType() )->visibleName();
else
{
switch( mSymbol->type() )
{
case QgsSymbolV2::Marker : return "Symbol: Marker";
case QgsSymbolV2::Fill : return "Symbol: Fill";
case QgsSymbolV2::Line : return "Symbol: Line";
default: return "Symbol";
}
}
}
if ( role == Qt::SizeHintRole )
return QVariant( QSize( 32, 32 ) );
if ( role == Qt::CheckStateRole )
return QVariant(); // could be true/false
return QStandardItem::data( role );
}
protected:
QgsSymbolLayerV2* mLayer;
QgsSymbolV2* mSymbol;
bool mIsLayer;
};
//////////
QgsSymbolV2SelectorDialog::QgsSymbolV2SelectorDialog( QgsSymbolV2* symbol, QgsStyleV2* style, const QgsVectorLayer* vl, QWidget* parent, bool embedded )
: QDialog( parent ), mAdvancedMenu( NULL ), mVectorLayer( vl )
{
mStyle = style;
mSymbol = symbol;
mPresentWidget = NULL;
setupUi( this );
btnAdvanced->hide(); // advanced button is hidden by default
// can be embedded in renderer properties dialog
if ( embedded )
{
buttonBox->hide();
layout()->setContentsMargins( 0, 0, 0, 0 );
}
// setup icons
btnAddLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.png" ) ) );
btnRemoveLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.png" ) ) );
QIcon iconLock;
iconLock.addFile( QgsApplication::iconPath( "locked.png" ), QSize(), QIcon::Normal, QIcon::On );
iconLock.addFile( QgsApplication::iconPath( "unlocked.png" ), QSize(), QIcon::Normal, QIcon::Off );
btnLock->setIcon( iconLock );
btnUp->setIcon( QIcon( QgsApplication::iconPath( "symbologyUp.png" ) ) );
btnDown->setIcon( QIcon( QgsApplication::iconPath( "symbologyDown.png" ) ) );
connect( btnSymbolProperties, SIGNAL( clicked() ), this, SLOT( changeSymbolProperties() ) );
connect( btnStyleManager, SIGNAL( clicked() ), SLOT( openStyleManager() ) );
model = new QStandardItemModel();
// Set the symbol
layersTree->setModel( model );
layersTree->setHeaderHidden( true );
QStandardItemModel* model = new QStandardItemModel( viewSymbols );
viewSymbols->setModel( model );
connect( viewSymbols, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( setSymbolFromStyle( const QModelIndex & ) ) );
lblSymbolName->setText( "" );
populateSymbolView();
updateSymbolPreview();
updateSymbolInfo();
QItemSelectionModel* selModel = layersTree->selectionModel();
connect( selModel, SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( layerChanged() ) );
if ( mSymbol )
{
// output unit
mSymbolUnitComboBox->blockSignals( true );
mSymbolUnitComboBox->setCurrentIndex( mSymbol->outputUnit() );
mSymbolUnitComboBox->blockSignals( false );
loadSymbol( symbol, static_cast<SymbolLayerItem*>( model->invisibleRootItem() ) );
updatePreview();
mTransparencySlider->blockSignals( true );
double transparency = 1 - symbol->alpha();
mTransparencySlider->setValue( transparency * 255 );
displayTransparency( symbol->alpha() );
mTransparencySlider->blockSignals( false );
}
connect( btnUp, SIGNAL( clicked() ), this, SLOT( moveLayerUp() ) );
connect( btnDown, SIGNAL( clicked() ), this, SLOT( moveLayerDown() ) );
connect( btnAddLayer, SIGNAL( clicked() ), this, SLOT( addLayer() ) );
connect( btnRemoveLayer, SIGNAL( clicked() ), this, SLOT( removeLayer() ) );
connect( btnLock, SIGNAL( clicked() ), this, SLOT( lockLayer() ) );
// select correct page in stacked widget
// there's a correspondence between symbol type number and page numbering => exploit it!
stackedWidget->setCurrentIndex( symbol->type() );
updateUi();
connect( btnColor, SIGNAL( clicked() ), this, SLOT( setSymbolColor() ) );
connect( spinAngle, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerAngle( double ) ) );
connect( spinSize, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerSize( double ) ) );
connect( spinWidth, SIGNAL( valueChanged( double ) ), this, SLOT( setLineWidth( double ) ) );
connect( btnAddToStyle, SIGNAL( clicked() ), this, SLOT( addSymbolToStyle() ) );
btnSymbolProperties->setIcon( QIcon( QgsApplication::defaultThemePath() + "mActionOptions.png" ) );
btnAddToStyle->setIcon( QIcon( QgsApplication::defaultThemePath() + "symbologyAdd.png" ) );
}
void QgsSymbolV2SelectorDialog::populateSymbolView()
{
QSize previewSize = viewSymbols->iconSize();
QPixmap p( previewSize );
QPainter painter;
QStandardItemModel* model = qobject_cast<QStandardItemModel*>( viewSymbols->model() );
if ( !model )
{
return;
}
model->clear();
if ( mStyle )
{
QStringList names = mStyle->symbolNames();
for ( int i = 0; i < names.count(); i++ )
{
QgsSymbolV2* s = mStyle->symbol( names[i] );
if ( s->type() != mSymbol->type() )
{
delete s;
continue;
}
QStandardItem* item = new QStandardItem( names[i] );
item->setData( names[i], Qt::UserRole ); //so we can show a label when it is clicked
item->setText( "" ); //set the text to nothing and show in label when clicked rather
item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
// create preview icon
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( s, previewSize );
item->setIcon( icon );
// add to model
model->appendRow( item );
delete s;
}
}
}
void QgsSymbolV2SelectorDialog::setSymbolFromStyle( const QModelIndex & index )
{
QString symbolName = index.data( Qt::UserRole ).toString();
lblSymbolName->setText( symbolName );
// get new instance of symbol from style
QgsSymbolV2* s = mStyle->symbol( symbolName );
// remove all symbol layers from original symbol
while ( mSymbol->symbolLayerCount() )
mSymbol->deleteSymbolLayer( 0 );
// move all symbol layers to our symbol
while ( s->symbolLayerCount() )
{
QgsSymbolLayerV2* sl = s->takeSymbolLayer( 0 );
mSymbol->appendSymbolLayer( sl );
}
// delete the temporary symbol
delete s;
updateSymbolPreview();
updateSymbolInfo();
emit symbolModified();
}
void QgsSymbolV2SelectorDialog::updateSymbolPreview()
{
QImage preview = mSymbol->bigSymbolPreviewImage();
lblPreview->setPixmap( QPixmap::fromImage( preview ) );
}
void QgsSymbolV2SelectorDialog::updateSymbolColor()
{
btnColor->setColor( mSymbol->color() );
}
void QgsSymbolV2SelectorDialog::updateSymbolInfo()
{
updateSymbolColor();
if ( mSymbol->type() == QgsSymbolV2::Marker )
{
QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
spinSize->setValue( markerSymbol->size() );
spinAngle->setValue( markerSymbol->angle() );
}
else if ( mSymbol->type() == QgsSymbolV2::Line )
{
QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mSymbol );
spinWidth->setValue( lineSymbol->width() );
}
}
void QgsSymbolV2SelectorDialog::changeSymbolProperties()
{
QgsSymbolV2PropertiesDialog dlg( mSymbol, mVectorLayer, this );
if ( !dlg.exec() )
return;
updateSymbolPreview();
updateSymbolInfo();
emit symbolModified();
}
void QgsSymbolV2SelectorDialog::setSymbolColor()
{
#if defined(Q_WS_MAC) && QT_VERSION >= 0x040500 && defined(QT_MAC_USE_COCOA)
// Native Mac dialog works only for Qt Carbon
// Qt bug: http://bugreports.qt.nokia.com/browse/QTBUG-14889
// FIXME need to also check max QT_VERSION when Qt bug fixed
QColor color = QColorDialog::getColor( mSymbol->color(), this, "", QColorDialog::DontUseNativeDialog );
#else
QColor color = QColorDialog::getColor( mSymbol->color(), this );
#endif
if ( !color.isValid() )
return;
mSymbol->setColor( color );
updateSymbolColor();
updateSymbolPreview();
emit symbolModified();
}
void QgsSymbolV2SelectorDialog::setMarkerAngle( double angle )
{
QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
if ( markerSymbol->angle() == angle )
return;
markerSymbol->setAngle( angle );
updateSymbolPreview();
emit symbolModified();
}
void QgsSymbolV2SelectorDialog::setMarkerSize( double size )
{
QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
if ( markerSymbol->size() == size )
return;
markerSymbol->setSize( size );
updateSymbolPreview();
emit symbolModified();
}
void QgsSymbolV2SelectorDialog::setLineWidth( double width )
{
QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mSymbol );
if ( lineSymbol->width() == width )
return;
lineSymbol->setWidth( width );
updateSymbolPreview();
emit symbolModified();
}
void QgsSymbolV2SelectorDialog::addSymbolToStyle()
{
bool ok;
QString name = QInputDialog::getText( this, tr( "Symbol name" ),
tr( "Please enter name for the symbol:" ) , QLineEdit::Normal, tr( "New symbol" ), &ok );
if ( !ok || name.isEmpty() )
return;
// check if there is no symbol with same name
if ( mStyle->symbolNames().contains( name ) )
{
int res = QMessageBox::warning( this, tr( "Save symbol" ),
tr( "Symbol with name '%1' already exists. Overwrite?" )
.arg( name ),
QMessageBox::Yes | QMessageBox::No );
if ( res != QMessageBox::Yes )
{
return;
}
}
// add new symbol to style and re-populate the list
mStyle->addSymbol( name, mSymbol->clone() );
// make sure the symbol is stored
mStyle->save();
populateSymbolView();
// set symbol as active item in the tree
QModelIndex newIndex = layersTree->model()->index( 0, 0 );
layersTree->setCurrentIndex( newIndex );
}
void QgsSymbolV2SelectorDialog::keyPressEvent( QKeyEvent * e )
@ -281,51 +200,312 @@ void QgsSymbolV2SelectorDialog::keyPressEvent( QKeyEvent * e )
}
}
void QgsSymbolV2SelectorDialog::on_mSymbolUnitComboBox_currentIndexChanged( const QString & text )
{
Q_UNUSED( text );
if ( mSymbol )
{
mSymbol->setOutputUnit(( QgsSymbolV2::OutputUnit ) mSymbolUnitComboBox->currentIndex() );
updateSymbolPreview();
emit symbolModified();
}
}
void QgsSymbolV2SelectorDialog::on_mTransparencySlider_valueChanged( int value )
{
if ( mSymbol )
{
double alpha = 1 - ( value / 255.0 );
mSymbol->setAlpha( alpha );
displayTransparency( alpha );
updateSymbolPreview();
emit symbolModified();
}
}
void QgsSymbolV2SelectorDialog::displayTransparency( double alpha )
{
double transparencyPercent = ( 1 - alpha ) * 100;
mTransparencyLabel->setText( tr( "Transparency %1%" ).arg(( int ) transparencyPercent ) );
}
QMenu* QgsSymbolV2SelectorDialog::advancedMenu()
{
if ( mAdvancedMenu == NULL )
{
mAdvancedMenu = new QMenu;
btnAdvanced->setMenu( mAdvancedMenu );
btnAdvanced->show();
// Brute force method to activate the Advanced menu
layerChanged();
}
return mAdvancedMenu;
}
void QgsSymbolV2SelectorDialog::openStyleManager()
void QgsSymbolV2SelectorDialog::loadSymbol( QgsSymbolV2* symbol, SymbolLayerItem* parent )
{
QgsStyleV2ManagerDialog dlg( mStyle, this );
dlg.exec();
SymbolLayerItem* symbolItem = new SymbolLayerItem( symbol );
QFont boldFont = symbolItem->font();
boldFont.setBold( true );
symbolItem->setFont( boldFont );
parent->appendRow( symbolItem );
populateSymbolView();
int count = symbol->symbolLayerCount();
for ( int i = count - 1; i >= 0; i-- )
{
SymbolLayerItem *layerItem = new SymbolLayerItem( symbol->symbolLayer( i ) );
layerItem->setEditable( false );
symbolItem->appendRow( layerItem );
if ( symbol->symbolLayer( i )->subSymbol() )
{
loadSymbol( symbol->symbolLayer( i )->subSymbol(), layerItem );
}
}
layersTree->setExpanded( symbolItem->index(), true);
}
void QgsSymbolV2SelectorDialog::loadSymbol()
{
model->clear();
loadSymbol( mSymbol, static_cast<SymbolLayerItem*>( model->invisibleRootItem() ) );
}
void QgsSymbolV2SelectorDialog::updateUi()
{
QModelIndex currentIdx = layersTree->currentIndex();
if ( !currentIdx.isValid() )
return;
SymbolLayerItem *item = static_cast<SymbolLayerItem*>( model->itemFromIndex( currentIdx ) );
if ( !item->isLayer() )
{
btnUp->setEnabled( false );
btnDown->setEnabled( false );
btnRemoveLayer->setEnabled( false );
btnLock->setEnabled( false );
btnAddLayer->setEnabled( true );
return;
}
int rowCount = item->parent()->rowCount();
int currentRow = item->row();
btnUp->setEnabled( currentRow > 0 );
btnDown->setEnabled( currentRow < rowCount - 1 );
btnRemoveLayer->setEnabled( rowCount > 1 );
btnLock->setEnabled( true );
btnAddLayer->setEnabled( false );
}
void QgsSymbolV2SelectorDialog::updatePreview()
{
QImage preview = mSymbol->bigSymbolPreviewImage();
lblPreview->setPixmap( QPixmap::fromImage( preview ) );
// Hope this is a appropriate place
emit symbolModified();
}
void QgsSymbolV2SelectorDialog::updateLayerPreview()
{
// get current layer item and update its icon
SymbolLayerItem* item = currentLayerItem();
if ( item )
item->updatePreview();
// update also preview of the whole symbol
updatePreview();
}
SymbolLayerItem* QgsSymbolV2SelectorDialog::currentLayerItem()
{
QModelIndex idx = layersTree->currentIndex();
if ( !idx.isValid() )
return NULL;
SymbolLayerItem *item = static_cast<SymbolLayerItem*>( model->itemFromIndex( idx ) );
if ( !item->isLayer() )
return NULL;
return item;
}
QgsSymbolLayerV2* QgsSymbolV2SelectorDialog::currentLayer()
{
QModelIndex idx = layersTree->currentIndex();
if ( !idx.isValid() )
return NULL;
SymbolLayerItem *item = static_cast<SymbolLayerItem*>( model->itemFromIndex( idx ) );
if ( item->isLayer() )
return item->layer();
return NULL;
}
void QgsSymbolV2SelectorDialog::layerChanged()
{
updateUi();
SymbolLayerItem *currentItem = static_cast<SymbolLayerItem*>( model->itemFromIndex( layersTree->currentIndex() ) );
if ( currentItem == NULL )
return;
if ( currentItem->isLayer() )
{
SymbolLayerItem *parent = static_cast<SymbolLayerItem*>( currentItem->parent() );
QWidget *layerProp = new QgsLayerPropertiesWidget( currentItem->layer(), parent->symbol(), mVectorLayer);
setWidget( layerProp );
connect( layerProp, SIGNAL( changed() ), this, SLOT( updateLayerPreview() ) );
// This connection when layer type is changed
connect( layerProp, SIGNAL( changeLayer( QgsSymbolLayerV2* ) ), this, SLOT( changeLayer( QgsSymbolLayerV2* ) ) );
}
else
{
// then it must be a symbol
// Now populate symbols of that type using the symbols list widget:
QWidget *symbolsList = new QgsSymbolsListWidget( currentItem->symbol(), mStyle, mAdvancedMenu );
setWidget( symbolsList );
connect( symbolsList, SIGNAL( changed() ), this, SLOT( symbolChanged() ) );
}
updateLockButton();
}
void QgsSymbolV2SelectorDialog::symbolChanged()
{
SymbolLayerItem *currentItem = static_cast<SymbolLayerItem*>( model->itemFromIndex( layersTree->currentIndex() ) );
if ( currentItem == NULL || currentItem->isLayer() )
return;
// disconnect to avoid recreating widget
disconnect( layersTree->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( layerChanged() ) );
if ( currentItem->parent() )
{
// it is a sub-symbol
QgsSymbolV2* symbol = currentItem->symbol();
SymbolLayerItem *parent = static_cast<SymbolLayerItem*>( currentItem->parent() );
parent->removeRow( 0 );
loadSymbol( symbol, parent );
layersTree->setCurrentIndex( parent->child( 0 )->index() );
parent->updatePreview();
}
else
{
//it is the symbol itself
loadSymbol();
QModelIndex newIndex = layersTree->model()->index( 0, 0 );
layersTree->setCurrentIndex( newIndex );
}
updatePreview();
// connect it back once things are set
connect( layersTree->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( layerChanged() ) );
}
void QgsSymbolV2SelectorDialog::setWidget( QWidget* widget )
{
int index = stackedWidget->addWidget( widget );
stackedWidget->setCurrentIndex( index );
if ( mPresentWidget )
{
stackedWidget->removeWidget( mPresentWidget );
QWidget *dummy = mPresentWidget;
mPresentWidget = widget;
delete dummy; // auto disconnects all signals
}
}
void QgsSymbolV2SelectorDialog::updateLockButton()
{
QgsSymbolLayerV2* layer = currentLayer();
if ( !layer )
return;
btnLock->setChecked( layer->isLocked() );
}
void QgsSymbolV2SelectorDialog::addLayer()
{
QModelIndex idx = layersTree->currentIndex();
if ( !idx.isValid() )
return;
SymbolLayerItem *item = static_cast<SymbolLayerItem*>( model->itemFromIndex( idx ) );
if ( item->isLayer() )
{
QMessageBox::critical( this, tr( "Invalid Selection!" ), tr( "Kindly select a symbol to add layer.") );
return;
}
QgsSymbolV2* parentSymbol = item->symbol();
QgsSymbolLayerV2* newLayer = QgsSymbolLayerV2Registry::instance()->defaultSymbolLayer( parentSymbol->type() );
parentSymbol->appendSymbolLayer( newLayer );
// XXX Insane behaviour of the appendSymbolLayer, it actually "pushes" into the list
SymbolLayerItem *newLayerItem = new SymbolLayerItem( newLayer );
item->insertRow( 0, newLayerItem );
item->updatePreview();
layersTree->setCurrentIndex( model->indexFromItem( newLayerItem ) );
updateUi();
updatePreview();
}
void QgsSymbolV2SelectorDialog::removeLayer()
{
SymbolLayerItem *item = currentLayerItem();
int row = item->row();
SymbolLayerItem *parent = static_cast<SymbolLayerItem*>( item->parent() );
int layerIdx = parent->rowCount() - row - 1; // IMPORTANT
QgsSymbolV2* parentSymbol = parent->symbol();
QgsSymbolLayerV2 *tmpLayer = parentSymbol->takeSymbolLayer( layerIdx );
parent->removeRow( row );
parent->updatePreview();
QModelIndex newIdx = parent->child( 0 )->index();
layersTree->setCurrentIndex( newIdx );
updateUi();
updatePreview();
//finally delete the removed layer pointer
delete tmpLayer;
}
void QgsSymbolV2SelectorDialog::moveLayerDown()
{
moveLayerByOffset( + 1 );
}
void QgsSymbolV2SelectorDialog::moveLayerUp()
{
moveLayerByOffset( -1 );
}
void QgsSymbolV2SelectorDialog::moveLayerByOffset( int offset )
{
SymbolLayerItem *item = currentLayerItem();
if( item == NULL )
return;
int row = item->row();
SymbolLayerItem *parent = static_cast<SymbolLayerItem*>( item->parent() );
QgsSymbolV2* parentSymbol = parent->symbol();
int layerIdx = parent->rowCount() - row - 1;
// switch layers
QgsSymbolLayerV2* tmpLayer = parentSymbol->takeSymbolLayer( layerIdx );
parentSymbol->insertSymbolLayer( layerIdx - offset, tmpLayer );
QList<QStandardItem*> rowItems = parent->takeRow( row );
parent->insertRows( row + offset, rowItems );
parent->updatePreview();
QModelIndex newIdx = rowItems[ 0 ]->index();
layersTree->setCurrentIndex( newIdx );
updatePreview();
updateUi();
}
void QgsSymbolV2SelectorDialog::lockLayer()
{
QgsSymbolLayerV2* layer = currentLayer();
if ( !layer )
return;
layer->setLocked( btnLock->isChecked() );
}
void QgsSymbolV2SelectorDialog::changeLayer( QgsSymbolLayerV2* newLayer )
{
SymbolLayerItem *item = currentLayerItem();
QgsSymbolLayerV2* layer = item->layer();
if ( layer->subSymbol() )
{
item->removeRow( 0 );
}
// update symbol layer item
item->setLayer( newLayer );
// When it is a marker symbol
if ( newLayer->subSymbol() )
{
loadSymbol( newLayer->subSymbol(), item );
layersTree->setExpanded( item->index(), true );
}
// Change the symbol at last to avoid deleting item's layer
QgsSymbolV2* symbol = static_cast<SymbolLayerItem*>( item->parent() )->symbol();
int layerIdx = item->parent()->rowCount() - item->row() - 1;
symbol->changeSymbolLayer( layerIdx, newLayer );
item->updatePreview();
updatePreview();
// Important: This lets the layer to have its own layer properties widget
layerChanged();
}

View File

@ -20,11 +20,17 @@
#include "ui_qgssymbolv2selectordialogbase.h"
#include <QStandardItemModel>
class QgsStyleV2;
class QgsSymbolV2;
class QgsSymbolLayerV2;
class QgsVectorLayer;
class QMenu;
class QWidget;
class SymbolLayerItem;
class GUI_EXPORT QgsSymbolV2SelectorDialog : public QDialog, private Ui::QgsSymbolV2SelectorDialogBase
{
@ -37,39 +43,57 @@ class GUI_EXPORT QgsSymbolV2SelectorDialog : public QDialog, private Ui::QgsSymb
QMenu* advancedMenu();
protected:
void populateSymbolView();
void updateSymbolPreview();
void updateSymbolColor();
void updateSymbolInfo();
//! Reimplements dialog keyPress event so we can ignore it
void keyPressEvent( QKeyEvent * event );
private:
/**Displays alpha value as transparency in mTransparencyLabel*/
void displayTransparency( double alpha );
void loadSymbol();
void loadSymbol( QgsSymbolV2* symbol, SymbolLayerItem* parent );
public slots:
void changeSymbolProperties();
void setSymbolFromStyle( const QModelIndex & index );
void setSymbolColor();
void setMarkerAngle( double angle );
void setMarkerSize( double size );
void setLineWidth( double width );
void addSymbolToStyle();
void on_mSymbolUnitComboBox_currentIndexChanged( const QString & text );
void on_mTransparencySlider_valueChanged( int value );
void populateLayerTypes( QgsSymbolV2* symbol );
void openStyleManager();
void updateUi();
void updateLockButton();
SymbolLayerItem* currentLayerItem();
QgsSymbolLayerV2* currentLayer();
void moveLayerByOffset( int offset );
void setWidget( QWidget* widget );
signals:
void symbolModified();
protected:
public slots:
void moveLayerDown();
void moveLayerUp();
void addLayer();
void removeLayer();
void lockLayer();
void layerChanged();
void updateLayerPreview();
void updatePreview();
//! Slot to update tree when a new symbol from style
void symbolChanged();
//! alters tree and sets proper widget when Layer Type is changed
//! @note: The layer is recieved from the LayerPropertiesWidget
void changeLayer( QgsSymbolLayerV2* layer );
protected: // data
QgsStyleV2* mStyle;
QgsSymbolV2* mSymbol;
QMenu* mAdvancedMenu;
const QgsVectorLayer* mVectorLayer;
QStandardItemModel* model;
QWidget *mPresentWidget;
};
#endif

View File

@ -13,7 +13,6 @@
* *
***************************************************************************/
#include "qgsvectorfieldsymbollayerwidget.h"
#include "qgssymbolv2propertiesdialog.h"
#include "qgsvectorfieldsymbollayer.h"
#include "qgsvectorlayer.h"
@ -88,7 +87,7 @@ void QgsVectorFieldSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* layer )
{
mRadiansRadioButton->setChecked( true );
}
updateMarkerIcon();
emit changed();
}
QgsSymbolLayerV2* QgsVectorFieldSymbolLayerWidget::symbolLayer()
@ -123,32 +122,6 @@ void QgsVectorFieldSymbolLayerWidget::on_mYAttributeComboBox_currentIndexChanged
}
}
void QgsVectorFieldSymbolLayerWidget::on_mLineStylePushButton_clicked()
{
if ( !mLayer )
{
return;
}
QgsSymbolV2PropertiesDialog dlg( mLayer->subSymbol(), mVectorLayer, this );
if ( dlg.exec() == QDialog::Rejected )
{
return;
}
updateMarkerIcon();
emit changed();
}
void QgsVectorFieldSymbolLayerWidget::updateMarkerIcon()
{
if ( mLayer )
{
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mLayer->subSymbol(), mLineStylePushButton->iconSize() );
mLineStylePushButton->setIcon( icon );
}
}
void QgsVectorFieldSymbolLayerWidget::on_mCartesianRadioButton_toggled( bool checked )
{
if ( mLayer && checked )

View File

@ -35,13 +35,11 @@ class GUI_EXPORT QgsVectorFieldSymbolLayerWidget: public QgsSymbolLayerV2Widget,
protected:
QgsVectorFieldSymbolLayer* mLayer;
void updateMarkerIcon();
private slots:
void on_mScaleSpinBox_valueChanged( double d );
void on_mXAttributeComboBox_currentIndexChanged( int index );
void on_mYAttributeComboBox_currentIndexChanged( int index );
void on_mLineStylePushButton_clicked();
void on_mCartesianRadioButton_toggled( bool checked );
void on_mPolarRadioButton_toggled( bool checked );
void on_mHeightRadioButton_toggled( bool checked );

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsSmartGroupConditionWidget</class>
<widget class="QWidget" name="QgsSmartGroupConditionWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>494</width>
<height>29</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>The Symbol</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mCondCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mCondLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mRemoveBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsSmartGroupEditorDialogBase</class>
<widget class="QDialog" name="QgsSmartGroupEditorDialogBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>141</height>
</rect>
</property>
<property name="windowTitle">
<string>Smart Group Editor</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Smart Group Name</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="mNameLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Condition matches</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="mAndOrCombo"/>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="mAddConditionBtn">
<property name="text">
<string>Add Condition</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QGroupBox" name="mConditionsBox">
<property name="title">
<string>Conditions</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsSmartGroupEditorDialogBase</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -7,21 +7,66 @@
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<height>379</height>
</rect>
</property>
<property name="windowTitle">
<string>Styles import/export</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="fromLabel">
<property name="text">
<string>Import from</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="importTypeCombo"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="locationLabel">
<property name="text">
<string>Location</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="locationLineEdit"/>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="btnBrowse">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="groupLabel">
<property name="text">
<string>Save to group</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QComboBox" name="groupCombo">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Select symbols to export</string>
</property>
</widget>
</item>
<item>
<item row="2" column="0">
<widget class="QListView" name="listItems">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@ -55,7 +100,7 @@
</property>
</widget>
</item>
<item>
<item row="3" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>

View File

@ -6,15 +6,103 @@
<rect>
<x>0</x>
<y>0</y>
<width>625</width>
<width>717</width>
<height>395</height>
</rect>
</property>
<property name="windowTitle">
<string>Style Manager</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="5">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="3">
<widget class="QTreeView" name="groupTree">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::DoubleClicked</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="btnAddGroup">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyAdd.png</normaloff>:/images/themes/default/symbologyAdd.png</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="btnRemoveGroup">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyRemove.png</normaloff>:/images/themes/default/symbologyRemove.png</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="btnManageGroups">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionChangeLabelProperties.png</normaloff>:/images/themes/default/mActionChangeLabelProperties.png</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>222</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="searchBox">
<property name="text">
<string/>
</property>
<property name="placeholderText">
<string>Type here to filter symbols ...</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QTabWidget" name="tabItemType">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@ -27,8 +115,8 @@
</property>
<property name="iconSize">
<size>
<width>22</width>
<height>22</height>
<width>20</width>
<height>20</height>
</size>
</property>
<widget class="QWidget" name="tabMarker">
@ -93,7 +181,7 @@
</widget>
</widget>
</item>
<item>
<item row="2" column="1" colspan="2">
<widget class="QListView" name="listItems">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@ -119,81 +207,94 @@
<property name="spacing">
<number>5</number>
</property>
<property name="gridSize">
<size>
<width>75</width>
<height>83</height>
</size>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item row="4" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="btnAddItem">
<property name="toolTip">
<string>Add item</string>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
<layout class="QHBoxLayout" name="symbolBtnsLayout">
<item>
<widget class="QPushButton" name="btnAddItem">
<property name="toolTip">
<string>Add item</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnEditItem">
<property name="toolTip">
<string>Edit item</string>
</property>
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnRemoveItem">
<property name="toolTip">
<string>Remove item</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnShare">
<property name="text">
<string>Share</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="btnEditItem">
<property name="toolTip">
<string>Edit item</string>
</property>
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnRemoveItem">
<property name="toolTip">
<string>Remove item</string>
</property>
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<spacer>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnExportItems">
<property name="text">
<string>Export...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnImportItems">
<property name="text">
<string>Import...</string>
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
</property>
</widget>
<item row="3" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Tags</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="tagsLineEdit"/>
</item>
</layout>
</item>
</layout>
</widget>

View File

@ -1,278 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DlgSymbolV2Properties</class>
<widget class="QDialog" name="DlgSymbolV2Properties">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>674</width>
<height>396</height>
</rect>
</property>
<property name="windowTitle">
<string>Symbol properties</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Symbol layers</string>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="5">
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Symbol layer type</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboLayerType"/>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Symbol layer properties</string>
</property>
<layout class="QGridLayout">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="pageDummy">
<layout class="QVBoxLayout">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>This symbol layer doesn't have GUI for settings.</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QListView" name="listLayers">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout">
<item>
<widget class="QPushButton" name="btnAddLayer">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Add symbol layer</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnRemoveLayer">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Remove symbol layer</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnLock">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Lock layer's color</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnUp">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Move up</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnDown">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Move down</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Symbol preview</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="lblPreview">
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>listLayers</tabstop>
<tabstop>btnAddLayer</tabstop>
<tabstop>btnRemoveLayer</tabstop>
<tabstop>btnLock</tabstop>
<tabstop>btnUp</tabstop>
<tabstop>btnDown</tabstop>
<tabstop>cboLayerType</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DlgSymbolV2Properties</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>386</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DlgSymbolV2Properties</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>325</x>
<y>386</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -6,20 +6,20 @@
<rect>
<x>0</x>
<y>0</y>
<width>489</width>
<width>619</width>
<height>416</height>
</rect>
</property>
<property name="windowTitle">
<string>Symbol selector</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="lblPreview">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -45,326 +45,105 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSymbolProperties">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Change...</string>
<string>Symbol layers</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="mSymbolUnitLabel">
<property name="text">
<string>Unit</string>
</property>
<property name="buddy">
<cstring>mSymbolUnitComboBox</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mSymbolUnitComboBox">
<item>
<property name="text">
<string>Millimeter</string>
</property>
</item>
<item>
<property name="text">
<string>Map unit</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mTransparencyLabel">
<property name="text">
<string>Opacity</string>
</property>
<property name="buddy">
<cstring>mTransparencySlider</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="mTransparencySlider">
<item>
<widget class="QTreeView" name="layersTree">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QPushButton" name="btnAddLayer">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>255</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
<property name="toolTip">
<string>Add symbol layer</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Color</string>
<item>
<widget class="QPushButton" name="btnRemoveLayer">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="buddy">
<cstring>btnColor</cstring>
<property name="toolTip">
<string>Remove symbol layer</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QgsColorButtonV2" name="btnColor">
<property name="text">
<string>Change</string>
<item>
<widget class="QPushButton" name="btnLock">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Lock layer's color</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnUp">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Move up</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnDown">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Move down</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="2" colspan="2">
<widget class="QStackedWidget" name="stackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>2</number>
</property>
<widget class="QWidget" name="pageMarker">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Size</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="spinSize">
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Rotation</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="spinAngle">
<property name="suffix">
<string>°</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>5.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>178</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="pageLine">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Width</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QDoubleSpinBox" name="spinWidth">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>37</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>37</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="pageFill">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="margin">
<number>0</number>
</property>
</layout>
</widget>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1" colspan="2">
<widget class="QPushButton" name="btnAdvanced">
<property name="text">
<string>Advanced</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="btnAddToStyle">
<property name="text">
<string>Save as style</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<item row="0" column="1">
<widget class="QStackedWidget" name="stackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<widget class="QWidget" name="page_2"/>
</widget>
</item>
<item row="2" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Saved styles</string>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="btnStyleManager">
<property name="text">
<string>Style manager...</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QListView" name="viewSymbols">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>2</verstretch>
</sizepolicy>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="flow">
<enum>QListView::LeftToRight</enum>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="spacing">
<number>5</number>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lblSymbolName">
<property name="text">
<string>Symbol Name</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="1" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -376,27 +155,6 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsColorButtonV2</class>
<extends>QPushButton</extends>
<header>qgscolorbutton.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>btnSymbolProperties</tabstop>
<tabstop>mSymbolUnitComboBox</tabstop>
<tabstop>mTransparencySlider</tabstop>
<tabstop>btnColor</tabstop>
<tabstop>spinWidth</tabstop>
<tabstop>spinSize</tabstop>
<tabstop>spinAngle</tabstop>
<tabstop>btnAdvanced</tabstop>
<tabstop>btnAddToStyle</tabstop>
<tabstop>btnStyleManager</tabstop>
<tabstop>viewSymbols</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>366</width>
<width>368</width>
<height>242</height>
</rect>
</property>
@ -16,26 +16,6 @@
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Marker</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnChangeMarker">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Change</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
@ -69,9 +49,6 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>btnChangeMarker</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -7,13 +7,16 @@
<x>0</x>
<y>0</y>
<width>336</width>
<height>326</height>
<height>336</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
@ -106,7 +109,7 @@
<item row="6" column="0" colspan="2">
<widget class="QListWidget" name="mShapeListWidget">
<property name="dragDropMode">
<enum>QAbstractItemView::DropOnly</enum>
<enum>QAbstractItemView::NoDragDrop</enum>
</property>
<property name="iconSize">
<size>

View File

@ -14,6 +14,9 @@
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>1</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout">
<property name="sizeConstraint">

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LayerPropertiesWidget</class>
<widget class="QWidget" name="LayerPropertiesWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>318</width>
<height>439</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="verticalSpacing">
<number>3</number>
</property>
<property name="margin">
<number>1</number>
</property>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Symbol layer type</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboLayerType">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QStackedWidget" name="stackedWidget">
<widget class="QWidget" name="pageDummy">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string> This layer doesn't have any editbale properties</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>366</width>
<width>368</width>
<height>242</height>
</rect>
</property>
@ -14,6 +14,9 @@
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>1</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">

View File

@ -6,14 +6,17 @@
<rect>
<x>0</x>
<y>0</y>
<width>236</width>
<height>151</height>
<width>201</width>
<height>202</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="mAngleLabel">
<property name="text">

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>352</width>
<width>263</width>
<height>281</height>
</rect>
</property>
@ -14,44 +14,17 @@
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Marker</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="btnChangeMarker">
<property name="text">
<string>Change</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>109</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="2">
<property name="margin">
<number>1</number>
</property>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Marker placement</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QRadioButton" name="radInterval">
<property name="text">
<string>with interval</string>
@ -61,7 +34,7 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="spinInterval">
<property name="decimals">
<number>2</number>
@ -74,42 +47,42 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<item row="2" column="0" colspan="2">
<widget class="QRadioButton" name="radVertex">
<property name="text">
<string>on every vertex</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<item row="3" column="0" colspan="2">
<widget class="QRadioButton" name="radVertexLast">
<property name="text">
<string>on last vertex only</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<item row="4" column="0" colspan="2">
<widget class="QRadioButton" name="radVertexFirst">
<property name="text">
<string>on first vertex only</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<item row="7" column="0" colspan="2">
<widget class="QCheckBox" name="chkRotateMarker">
<property name="text">
<string>Rotate marker</string>
</property>
</widget>
</item>
<item row="9" column="0">
<item row="8" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Line offset</string>
</property>
</widget>
</item>
<item row="9" column="1">
<item row="8" column="1">
<widget class="QDoubleSpinBox" name="spinOffset">
<property name="decimals">
<number>5</number>
@ -122,7 +95,7 @@
</property>
</widget>
</item>
<item row="10" column="0" colspan="3">
<item row="9" column="0" colspan="3">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -135,14 +108,14 @@
</property>
</spacer>
</item>
<item row="7" column="0" colspan="3">
<item row="6" column="0" colspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="0">
<item row="5" column="0">
<widget class="QRadioButton" name="radCentralPoint">
<property name="text">
<string>on central point</string>
@ -152,7 +125,6 @@
</layout>
</widget>
<tabstops>
<tabstop>btnChangeMarker</tabstop>
<tabstop>radInterval</tabstop>
<tabstop>spinInterval</tabstop>
<tabstop>radVertex</tabstop>

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>243</width>
<width>283</width>
<height>152</height>
</rect>
</property>
@ -14,31 +14,10 @@
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="mMarkerLabel">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="text">
<string>Marker</string>
</property>
</widget>
</item>
<property name="margin">
<number>1</number>
</property>
<item row="0" column="1">
<widget class="QPushButton" name="mChangeMarkerButton">
<property name="text">
<string>Change</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mHorizontalDistanceLabel">
<property name="text">
<string>Horizontal distance</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="mHorizontalDistanceSpinBox">
<property name="decimals">
<number>5</number>
@ -48,48 +27,7 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="mVerticalDistanceLabel">
<property name="text">
<string>Vertical distance</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="mVerticalDistanceSpinBox">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>999999999.990000009536743</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="mHorizontalDisplacementLabel">
<property name="text">
<string>Horizontal displacement</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="mHorizontalDisplacementSpinBox">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>9999999.990000000223517</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="mVerticalDisplacementLabel">
<property name="text">
<string>Vertical displacement</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="mVerticalDisplacementSpinBox">
<property name="decimals">
<number>5</number>
@ -99,6 +37,54 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="mVerticalDistanceSpinBox">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>999999999.990000009536743</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="mHorizontalDisplacementLabel">
<property name="text">
<string>Horizontal displacement</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="mHorizontalDistanceLabel">
<property name="text">
<string>Horizontal distance</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mVerticalDistanceLabel">
<property name="text">
<string>Vertical distance</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="mHorizontalDisplacementSpinBox">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>9999999.990000000223517</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="mVerticalDisplacementLabel">
<property name="text">
<string>Vertical displacement</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>

View File

@ -7,13 +7,16 @@
<x>0</x>
<y>0</y>
<width>335</width>
<height>206</height>
<height>212</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>1</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>358</width>
<width>368</width>
<height>296</height>
</rect>
</property>
@ -14,6 +14,9 @@
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>1</number>
</property>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">

View File

@ -14,6 +14,9 @@
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>1</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">

View File

@ -6,14 +6,17 @@
<rect>
<x>0</x>
<y>0</y>
<width>236</width>
<height>310</height>
<width>239</width>
<height>346</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<layout class="QGridLayout" name="gridLayout_3">
<property name="margin">
<number>1</number>
</property>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
@ -106,20 +109,41 @@
</layout>
</item>
<item row="1" column="0">
<widget class="QListView" name="mSvgListView">
<property name="flow">
<enum>QListView::LeftToRight</enum>
</property>
<property name="layoutMode">
<enum>QListView::Batched</enum>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
</widget>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="mSymbolGroupLabel">
<property name="text">
<string>SVG Groups</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="mSymbolListLabel">
<property name="text">
<string>SVG Symbols</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTreeView" name="mSvgTreeView"/>
</item>
<item row="1" column="1">
<widget class="QListView" name="mSvgListView">
<property name="flow">
<enum>QListView::LeftToRight</enum>
</property>
<property name="layoutMode">
<enum>QListView::Batched</enum>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">

View File

@ -6,15 +6,18 @@
<rect>
<x>0</x>
<y>0</y>
<width>302</width>
<height>337</height>
<width>364</width>
<height>361</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<property name="margin">
<number>1</number>
</property>
<item row="0" column="0" colspan="2">
<layout class="QGridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
@ -163,6 +166,13 @@
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>SVG Groups</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>SVG Image</string>
@ -170,6 +180,9 @@
</widget>
</item>
<item row="2" column="0">
<widget class="QTreeView" name="viewGroups"/>
</item>
<item row="2" column="1">
<widget class="QListView" name="viewImages">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
@ -209,7 +222,7 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="mFileLineEdit"/>

View File

@ -0,0 +1,360 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SymbolsListWidget</class>
<widget class="QWidget" name="SymbolsListWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>344</width>
<height>441</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="verticalSpacing">
<number>4</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="mSymbolUnitLabel">
<property name="text">
<string>Unit</string>
</property>
<property name="buddy">
<cstring>mSymbolUnitComboBox</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mSymbolUnitComboBox">
<item>
<property name="text">
<string>Millimeter</string>
</property>
</item>
<item>
<property name="text">
<string>Map unit</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mTransparencyLabel">
<property name="text">
<string>Opacity</string>
</property>
<property name="buddy">
<cstring>mTransparencySlider</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="mTransparencySlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>255</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Color</string>
</property>
<property name="buddy">
<cstring>btnColor</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QgsColorButtonV2" name="btnColor">
<property name="text">
<string>Change</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>2</number>
</property>
<widget class="QWidget" name="pageMarker">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Size</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="spinSize">
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Rotation</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="spinAngle">
<property name="suffix">
<string>°</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>5.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>178</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="pageLine">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Width</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QDoubleSpinBox" name="spinWidth">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>37</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>37</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="pageFill">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="margin">
<number>0</number>
</property>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Saved styles</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>194</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QComboBox" name="groupsCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QListView" name="viewSymbols">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>2</verstretch>
</sizepolicy>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="flow">
<enum>QListView::LeftToRight</enum>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="spacing">
<number>5</number>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="topMargin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="lblSymbolName">
<property name="text">
<string>Symbol Name</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnStyle">
<property name="text">
<string>Style</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnAdvanced">
<property name="text">
<string>Advanced</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsColorButtonV2</class>
<extends>QPushButton</extends>
<header>qgscolorbutton.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -6,14 +6,17 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>291</height>
<width>315</width>
<height>320</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="margin">
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="mXAttributeLabel">
<property name="text">
@ -21,7 +24,7 @@
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<item row="0" column="1">
<widget class="QComboBox" name="mXAttributeComboBox"/>
</item>
<item row="1" column="0">
@ -31,7 +34,7 @@
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<item row="1" column="1">
<widget class="QComboBox" name="mYAttributeComboBox"/>
</item>
<item row="2" column="0">
@ -41,98 +44,102 @@
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="mScaleSpinBox"/>
</item>
<item row="4" column="0" rowspan="2" colspan="2">
<widget class="QGroupBox" name="mFieldTypeGroupBox">
<property name="title">
<string>Vector field type</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QRadioButton" name="mCartesianRadioButton">
<property name="text">
<string>Cartesian</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="mPolarRadioButton">
<property name="text">
<string>Polar</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="mHeightRadioButton">
<property name="text">
<string>Height only</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="2" colspan="2">
<widget class="QGroupBox" name="mAngleUnitsGroupBox">
<property name="title">
<string>Angle units</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QRadioButton" name="mDegreesRadioButton">
<property name="text">
<string>Degrees</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="mRadiansRadioButton">
<property name="text">
<string>Radians</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="2" colspan="2">
<widget class="QGroupBox" name="mAngleOrientationGroupBox">
<property name="title">
<string>Angle orientation</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<item row="3" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGroupBox" name="mFieldTypeGroupBox">
<property name="title">
<string>Vector field type</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QRadioButton" name="mHeightRadioButton">
<property name="text">
<string>Height only</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="mPolarRadioButton">
<property name="text">
<string>Polar</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="mCartesianRadioButton">
<property name="text">
<string>Cartesian</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="mAngleUnitsGroupBox">
<property name="title">
<string>Angle units</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QRadioButton" name="mDegreesRadioButton">
<property name="text">
<string>Degrees</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="mRadiansRadioButton">
<property name="text">
<string>Radians</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="mAngleOrientationGroupBox">
<property name="title">
<string>Angle orientation</string>
</property>
<widget class="QRadioButton" name="mCounterclockwiseFromEastRadioButton">
<property name="geometry">
<rect>
<x>17</x>
<y>52</y>
<width>183</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Counterclockwise from east</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="mClockwiseFromNorthRadioButton">
<property name="geometry">
<rect>
<x>17</x>
<y>25</y>
<width>146</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Clockwise from north</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="mLineStyleLabel">
<property name="text">
<string>LineStyle</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QPushButton" name="mLineStylePushButton">
<property name="text">
<string>change</string>
</property>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</widget>