1,132 changes: 1,087 additions & 45 deletions src/core/symbology-ng/qgsstylev2.cpp

Large diffs are not rendered by default.

102 changes: 102 additions & 0 deletions src/core/symbology-ng/qgsstylev2.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
#define QGSSTYLEV2_H

#include <QMap>
#include <QMultiMap>
#include <QString>

#include <sqlite3.h>

#include "qgssymbollayerv2utils.h" // QgsStringMap

class QgsSymbolV2;
Expand All @@ -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
{
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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;
Expand All @@ -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 );
};


Expand Down
37 changes: 20 additions & 17 deletions src/core/symbology-ng/qgssymbollayerv2utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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 );
Expand All @@ -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 );
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgssymbollayerv2utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 );

Expand Down
8 changes: 6 additions & 2 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
189 changes: 189 additions & 0 deletions src/gui/symbology-ng/qgslayerpropertieswidget.cpp
Original file line number Diff line number Diff line change
@@ -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();
}
59 changes: 59 additions & 0 deletions src/gui/symbology-ng/qgslayerpropertieswidget.h
Original file line number Diff line number Diff line change
@@ -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
208 changes: 208 additions & 0 deletions src/gui/symbology-ng/qgssmartgroupeditordialog.cpp
Original file line number Diff line number Diff line change
@@ -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();
}
114 changes: 114 additions & 0 deletions src/gui/symbology-ng/qgssmartgroupeditordialog.h
Original file line number Diff line number Diff line change
@@ -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

247 changes: 230 additions & 17 deletions src/gui/symbology-ng/qgsstylev2exportimportdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,23 @@
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsstylev2exportimportdialog.h"

#include "qgsstylev2.h"
#include "qgssymbolv2.h"
#include "qgssymbollayerv2utils.h"
#include "qgsvectorcolorrampv2.h"
#include "qgslogger.h"

#include <QInputDialog>
#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"

QgsStyleV2ExportImportDialog::QgsStyleV2ExportImportDialog( QgsStyleV2* style, QWidget *parent, Mode mode, QString fileName )
QgsStyleV2ExportImportDialog::QgsStyleV2ExportImportDialog( QgsStyleV2* style, QWidget *parent, Mode mode )
: QDialog( parent )
, mFileName( fileName )
, mDialogMode( mode )
, mQgisStyle( style )
{
Expand All @@ -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 )
{
label->setText( tr( "Select symbols to import" ) );
buttonBox->button( QDialogButtonBox::Ok )->setText( tr( "Import" ) );
if ( !populateStyles( mTempStyle ) )
// 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 )
{
QApplication::postEvent( this, new QCloseEvent() );
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" ) );
}
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 ) )
{
Expand Down Expand Up @@ -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" )
Expand All @@ -113,7 +139,6 @@ void QgsStyleV2ExportImportDialog::doExportImport()
else // import
{
moveStyles( &selection, mTempStyle, mQgisStyle );
mQgisStyle->save();

// clear model
QStandardItemModel* model = qobject_cast<QStandardItemModel*>( listItems->model() );
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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 )
{
Expand Down Expand Up @@ -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;
Expand All @@ -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 )
{
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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 )
{
Expand All @@ -273,13 +357,16 @@ void QgsStyleV2ExportImportDialog::moveStyles( QModelIndexList* selection, QgsSt
else
{
dst->addColorRamp( symbolName, ramp );
if ( mDialogMode == Import )
dst->saveColorRamp( symbolName, ramp, groupid, QStringList() );
}
}
}
}

QgsStyleV2ExportImportDialog::~QgsStyleV2ExportImportDialog()
{
delete mTempFile;
delete mTempStyle;
}

Expand All @@ -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 = "";
}
22 changes: 21 additions & 1 deletion src/gui/symbology-ng/qgsstylev2exportimportdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
#define QGSSTYLEV2EXPORTIMPORTDIALOG_H

#include <QDialog>
#include <QUrl>
#include <QProgressDialog>
#include <QTemporaryFile>
#include <QNetworkAccessManager>
#include <QNetworkReply>

#include "ui_qgsstylev2exportimportdialogbase.h"

Expand All @@ -37,18 +42,33 @@ 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:
void doExportImport();
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;

Expand Down
768 changes: 723 additions & 45 deletions src/gui/symbology-ng/qgsstylev2managerdialog.cpp

Large diffs are not rendered by default.

66 changes: 63 additions & 3 deletions src/gui/symbology-ng/qgsstylev2managerdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include <QDialog>
#include <QStandardItem>
#include <QAction>
#include <QMenu>

#include "ui_qgsstylev2managerdialogbase.h"
#include "qgscontexthelp.h"
Expand All @@ -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();

Expand All @@ -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();
Expand All @@ -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
182 changes: 112 additions & 70 deletions src/gui/symbology-ng/qgssymbollayerv2widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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() ) );
Expand Down Expand Up @@ -447,7 +450,6 @@ void QgsMarkerLineSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
radCentralPoint->setChecked( true );
else
radVertexFirst->setChecked( true );
updateMarker();
setPlacement(); // update gui
}

Expand All @@ -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() );
Expand All @@ -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();
Expand Down Expand Up @@ -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() ) );
Expand All @@ -532,6 +519,7 @@ QgsSvgMarkerSymbolLayerV2Widget::QgsSvgMarkerSymbolLayerV2Widget( const QgsVecto
#include <QTime>
#include <QAbstractListModel>
#include <QPixmapCache>
#include <QStyle>

class QgsSvgListModel : public QAbstractListModel
{
Expand All @@ -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 );
Expand Down Expand Up @@ -581,11 +575,84 @@ 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()
{
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 )
Expand All @@ -611,6 +678,7 @@ void QgsSvgMarkerSymbolLayerV2Widget::setGuiForSvg( const QgsSvgMarkerSymbolLaye
mBorderWidthSpinBox->blockSignals( true );
mBorderWidthSpinBox->setValue( layer->outlineWidth() );
mBorderWidthSpinBox->blockSignals( false );

}


Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -1079,7 +1169,6 @@ QgsPointPatternFillSymbolLayerWidget::QgsPointPatternFillSymbolLayerWidget( cons
QgsSymbolLayerV2Widget( parent, vl ), mLayer( 0 )
{
setupUi( this );
updateMarkerIcon();
}


Expand All @@ -1095,23 +1184,13 @@ void QgsPointPatternFillSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* lay
mVerticalDistanceSpinBox->setValue( mLayer->distanceY() );
mHorizontalDisplacementSpinBox->setValue( mLayer->displacementX() );
mVerticalDisplacementSpinBox->setValue( mLayer->displacementY() );
updateMarkerIcon();
}

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 )
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -1274,8 +1336,6 @@ QgsCentroidFillSymbolLayerV2Widget::QgsCentroidFillSymbolLayerV2Widget( const Qg
mLayer = NULL;

setupUi( this );

connect( btnChangeMarker, SIGNAL( clicked() ), this, SLOT( setMarker() ) );
}

void QgsCentroidFillSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
Expand All @@ -1285,28 +1345,10 @@ 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()
{
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 );
}
12 changes: 2 additions & 10 deletions src/gui/symbology-ng/qgssymbollayerv2widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand All @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
};

/////////
Expand Down Expand Up @@ -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;
};

Expand Down
350 changes: 350 additions & 0 deletions src/gui/symbology-ng/qgssymbolslistwidget.cpp
Original file line number Diff line number Diff line change
@@ -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 );
}
70 changes: 70 additions & 0 deletions src/gui/symbology-ng/qgssymbolslistwidget.h
Original file line number Diff line number Diff line change
@@ -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

458 changes: 0 additions & 458 deletions src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp

This file was deleted.

86 changes: 0 additions & 86 deletions src/gui/symbology-ng/qgssymbolv2propertiesdialog.h

This file was deleted.

594 changes: 387 additions & 207 deletions src/gui/symbology-ng/qgssymbolv2selectordialog.cpp

Large diffs are not rendered by default.

66 changes: 45 additions & 21 deletions src/gui/symbology-ng/qgssymbolv2selectordialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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 openStyleManager();
void populateLayerTypes( QgsSymbolV2* symbol );

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
29 changes: 1 addition & 28 deletions src/gui/symbology-ng/qgsvectorfieldsymbollayerwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
* *
***************************************************************************/
#include "qgsvectorfieldsymbollayerwidget.h"
#include "qgssymbolv2propertiesdialog.h"
#include "qgsvectorfieldsymbollayer.h"
#include "qgsvectorlayer.h"

Expand Down Expand Up @@ -88,7 +87,7 @@ void QgsVectorFieldSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* layer )
{
mRadiansRadioButton->setChecked( true );
}
updateMarkerIcon();
emit changed();
}

QgsSymbolLayerV2* QgsVectorFieldSymbolLayerWidget::symbolLayer()
Expand Down Expand Up @@ -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 )
Expand Down
2 changes: 0 additions & 2 deletions src/gui/symbology-ng/qgsvectorfieldsymbollayerwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down
74 changes: 74 additions & 0 deletions src/ui/qgssmartgroupconditionwidget.ui
Original file line number Diff line number Diff line change
@@ -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>
82 changes: 82 additions & 0 deletions src/ui/qgssmartgroupeditordialogbase.ui
Original file line number Diff line number Diff line change
@@ -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>
55 changes: 50 additions & 5 deletions src/ui/qgsstylev2exportimportdialogbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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>
Expand Down
221 changes: 161 additions & 60 deletions src/ui/qgsstylev2managerdialogbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand All @@ -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">
Expand Down Expand Up @@ -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">
Expand All @@ -119,82 +207,95 @@
<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>
<widget class="QPushButton" name="btnAddItem">
<property name="toolTip">
<string>Add item</string>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<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>
<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>
<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 name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
</property>
</spacer>
</widget>
</item>
</layout>
</item>
<item row="3" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="btnExportItems">
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Export...</string>
<string>Tags</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnImportItems">
<property name="text">
<string>Import...</string>
</property>
</widget>
<widget class="QLineEdit" name="tagsLineEdit"/>
</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>
</layout>
</widget>
<tabstops>
Expand Down
Loading