| 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(); | ||
| } |
| 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 |
| 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 ¶m, 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(); | ||
| } |
| 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 | ||
|
|
| 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 ); | ||
| } |
| 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 | ||
|
|
| 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> |
| 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> |