From 82dfbaca5176515decbccd96ca7bd92635d4b419 Mon Sep 17 00:00:00 2001 From: Arunmozhi Date: Fri, 22 Jun 2012 23:29:10 +0530 Subject: [PATCH] Midway commit; implements symbols listing/changing in symbol selector --- python/gui/symbology-ng-gui.sip | 43 +- src/gui/symbology-ng/qgssymbolslistwidget.cpp | 13 +- src/gui/symbology-ng/qgssymbolslistwidget.h | 2 - .../qgssymbolv2selectordialog.cpp | 715 ++++++++++++------ .../symbology-ng/qgssymbolv2selectordialog.h | 66 +- src/ui/qgssymbolv2propertiesdialogbase.ui | 56 +- src/ui/qgssymbolv2selectordialogbase.ui | 394 ++-------- 7 files changed, 649 insertions(+), 640 deletions(-) diff --git a/python/gui/symbology-ng-gui.sip b/python/gui/symbology-ng-gui.sip index 5b4861fe30f..a1c1d2af121 100644 --- a/python/gui/symbology-ng-gui.sip +++ b/python/gui/symbology-ng-gui.sip @@ -71,27 +71,34 @@ class QgsSymbolV2SelectorDialog : QDialog //, private Ui::QgsSymbolV2SelectorDia %TypeHeaderCode #include %End + public: + QgsSymbolV2SelectorDialog( QgsSymbolV2* symbol, QgsStyleV2* style, const QgsVectorLayer* vl, QWidget* parent = NULL, bool embedded = false ); -public: - QgsSymbolV2SelectorDialog(QgsSymbolV2* symbol, QgsStyleV2* style, const QgsVectorLayer* vl, QWidget* parent = NULL, bool embedded = false); - -protected: - void populateSymbolView(); - void updateSymbolPreview(); - void updateSymbolColor(); - void updateSymbolInfo(); - + QMenu* advancedMenu(); -public slots: - void changeSymbolProperties(); - void setSymbolFromStyle(const QModelIndex & index); - void setSymbolColor(); - void setMarkerAngle(double angle); - void setMarkerSize(double size); - void setLineWidth(double width); + protected: + void keyPressEvent( QKeyEvent * event ); -signals: - void symbolModified(); + void loadSymbol(); + void updateUi(); + void updateLockButton(); + QgsSymbolLayerV2* currentLayer(); + void moveLayerByOffset( int offset ); + void setWidget( QWidget* widget ); + + signals: + void symbolModified(); + + public slots: + void moveLayerDown(); + void moveLayerUp(); + void addLayer(); + void removeLayer(); + void lockLayer(); + void layerTypeChanged(); + void layerChanged(); + void updateLayerPreview(); + void updatePreview(); }; diff --git a/src/gui/symbology-ng/qgssymbolslistwidget.cpp b/src/gui/symbology-ng/qgssymbolslistwidget.cpp index ce1dc1b7e8e..757a1a0f076 100644 --- a/src/gui/symbology-ng/qgssymbolslistwidget.cpp +++ b/src/gui/symbology-ng/qgssymbolslistwidget.cpp @@ -46,7 +46,7 @@ QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbolV2* symbol, QgsStyleV2* sty QStandardItemModel* model = new QStandardItemModel( viewSymbols ); viewSymbols->setModel( model ); - //connect( viewSymbols, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( setSymbolFromStyle( const QModelIndex & ) ) ); + connect( viewSymbols, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( setSymbolFromStyle( const QModelIndex & ) ) ); connect( btnStyleManager, SIGNAL( clicked() ), SLOT( openStyleManager() ) ); lblSymbolName->setText( "" ); @@ -270,7 +270,16 @@ void QgsSymbolsListWidget::setSymbolFromStyle( const QModelIndex & index ) emit changed(); } - +QMenu* QgsSymbolsListWidget::advancedMenu() +{ + if ( mAdvancedMenu == NULL ) + { + mAdvancedMenu = new QMenu; + btnAdvanced->setMenu( mAdvancedMenu ); + btnAdvanced->show(); + } + return mAdvancedMenu; +} diff --git a/src/gui/symbology-ng/qgssymbolslistwidget.h b/src/gui/symbology-ng/qgssymbolslistwidget.h index d5b1712839f..ddeb040aa13 100644 --- a/src/gui/symbology-ng/qgssymbolslistwidget.h +++ b/src/gui/symbology-ng/qgssymbolslistwidget.h @@ -22,7 +22,6 @@ class QgsSymbolV2; class QgsStyleV2; -class QgsVectorLayer; class QMenu; @@ -57,7 +56,6 @@ class GUI_EXPORT QgsSymbolsListWidget : public QWidget, private Ui::WidgetSymbol QgsSymbolV2* mSymbol; QgsStyleV2* mStyle; QMenu* mAdvancedMenu; - const QgsVectorLayer* mVectorLayer; void populateSymbolView(); void updateSymbolColor(); diff --git a/src/gui/symbology-ng/qgssymbolv2selectordialog.cpp b/src/gui/symbology-ng/qgssymbolv2selectordialog.cpp index 57b12b3a1c4..78b6956ce4c 100644 --- a/src/gui/symbology-ng/qgssymbolv2selectordialog.cpp +++ b/src/gui/symbology-ng/qgssymbolv2selectordialog.cpp @@ -15,13 +15,20 @@ #include "qgssymbolv2selectordialog.h" -#include "qgssymbolv2propertiesdialog.h" -#include "qgsstylev2managerdialog.h" - -#include "qgssymbolv2.h" -#include "qgssymbollayerv2utils.h" #include "qgsstylev2.h" +#include "qgssymbolv2.h" +#include "qgssymbollayerv2.h" +#include "qgssymbollayerv2utils.h" +#include "qgssymbollayerv2registry.h" +// the widgets +#include "qgssymbolslistwidget.h" +//#include "qgslayerpropertieswidget.h" +#include "qgssymbollayerv2widget.h" +#include "qgsellipsesymbollayerv2widget.h" +#include "qgsvectorfieldsymbollayerwidget.h" + +#include "qgslogger.h" #include "qgsapplication.h" #include @@ -32,237 +39,153 @@ #include #include +#include +#include +#include + +static const int SymbolLayerItemType = QStandardItem::UserType + 1; + +// Hybrid item which may represent a symbol or a layer +// Check using item->isLayer() +class SymbolLayerItem : public QStandardItem +{ + public: + SymbolLayerItem( QgsSymbolLayerV2* layer ) + { + setLayer( layer ); + } + + SymbolLayerItem( QgsSymbolV2* symbol ) + { + setSymbol( symbol ); + } + + void setLayer( QgsSymbolLayerV2* layer ) + { + mLayer = layer; + mIsLayer = true; + mSymbol = NULL; + updatePreview(); + } + + void setSymbol( QgsSymbolV2* symbol ) + { + mSymbol = symbol; + mIsLayer = false; + mLayer = NULL; + updatePreview(); + } + + void updatePreview() + { + QIcon icon; + if ( mIsLayer ) + icon = QgsSymbolLayerV2Utils::symbolLayerPreviewIcon( mLayer, QgsSymbolV2::MM, QSize( 16, 16 ) ); //todo: make unit a parameter + else + icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mSymbol, QSize( 16, 16 ) ); + setIcon( icon ); + + if ( parent() ) + static_cast( parent() )->updatePreview(); + } + + int type() const { return SymbolLayerItemType; } + bool isLayer() { return mIsLayer; } + + // returns the symbol pointer; helpful in determining a layer's parent symbol + QgsSymbolV2* symbol() + { + if ( mIsLayer ) + return NULL; + return mSymbol; + } + + QgsSymbolLayerV2* layer() + { + if ( mIsLayer ) + return mLayer; + return NULL; + } + + QVariant data( int role ) const + { + if ( role == Qt::DisplayRole ) + { + if ( mIsLayer ) + return QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( mLayer->layerType() )->visibleName(); + else + { + switch( mSymbol->type() ) + { + case QgsSymbolV2::Marker : return "Symbol: Marker"; + case QgsSymbolV2::Fill : return "Symbol: Fill"; + case QgsSymbolV2::Line : return "Symbol: Line"; + default: return "Symbol"; + } + } + } + if ( role == Qt::SizeHintRole ) + return QVariant( QSize( 32, 32 ) ); + if ( role == Qt::CheckStateRole ) + return QVariant(); // could be true/false + return QStandardItem::data( role ); + } + + protected: + QgsSymbolLayerV2* mLayer; + QgsSymbolV2* mSymbol; + bool mIsLayer; +}; + +////////// + QgsSymbolV2SelectorDialog::QgsSymbolV2SelectorDialog( QgsSymbolV2* symbol, QgsStyleV2* style, const QgsVectorLayer* vl, QWidget* parent, bool embedded ) : QDialog( parent ), mAdvancedMenu( NULL ), mVectorLayer( vl ) { mStyle = style; mSymbol = symbol; + mPresentWidget = NULL; setupUi( this ); - - btnAdvanced->hide(); // advanced button is hidden by default - // can be embedded in renderer properties dialog if ( embedded ) { buttonBox->hide(); layout()->setContentsMargins( 0, 0, 0, 0 ); } + // setup icons + btnAddLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.png" ) ) ); + btnRemoveLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.png" ) ) ); + QIcon iconLock; + iconLock.addFile( QgsApplication::iconPath( "locked.png" ), QSize(), QIcon::Normal, QIcon::On ); + iconLock.addFile( QgsApplication::iconPath( "unlocked.png" ), QSize(), QIcon::Normal, QIcon::Off ); + btnLock->setIcon( iconLock ); + btnUp->setIcon( QIcon( QgsApplication::iconPath( "symbologyUp.png" ) ) ); + btnDown->setIcon( QIcon( QgsApplication::iconPath( "symbologyDown.png" ) ) ); - connect( btnSymbolProperties, SIGNAL( clicked() ), this, SLOT( changeSymbolProperties() ) ); - connect( btnStyleManager, SIGNAL( clicked() ), SLOT( openStyleManager() ) ); + model = new QStandardItemModel(); + // Set the symbol + layersTree->setModel( model ); + layersTree->setHeaderHidden( true ); - QStandardItemModel* model = new QStandardItemModel( viewSymbols ); - viewSymbols->setModel( model ); - connect( viewSymbols, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( setSymbolFromStyle( const QModelIndex & ) ) ); - lblSymbolName->setText( "" ); - populateSymbolView(); - updateSymbolPreview(); - updateSymbolInfo(); + QItemSelectionModel* selModel = layersTree->selectionModel(); + connect( selModel, SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( layerChanged() ) ); - if ( mSymbol ) - { - // output unit - mSymbolUnitComboBox->blockSignals( true ); - mSymbolUnitComboBox->setCurrentIndex( mSymbol->outputUnit() ); - mSymbolUnitComboBox->blockSignals( false ); + loadSymbol( symbol, static_cast( model->invisibleRootItem() ) ); + updatePreview(); - mTransparencySlider->blockSignals( true ); - double transparency = 1 - symbol->alpha(); - mTransparencySlider->setValue( transparency * 255 ); - displayTransparency( symbol->alpha() ); - mTransparencySlider->blockSignals( false ); - } + connect( btnUp, SIGNAL( clicked() ), this, SLOT( moveLayerUp() ) ); + connect( btnDown, SIGNAL( clicked() ), this, SLOT( moveLayerDown() ) ); + connect( btnAddLayer, SIGNAL( clicked() ), this, SLOT( addLayer() ) ); + connect( btnRemoveLayer, SIGNAL( clicked() ), this, SLOT( removeLayer() ) ); + connect( btnLock, SIGNAL( clicked() ), this, SLOT( lockLayer() ) ); - // select correct page in stacked widget - // there's a correspondence between symbol type number and page numbering => exploit it! - stackedWidget->setCurrentIndex( symbol->type() ); + updateUi(); - connect( btnColor, SIGNAL( clicked() ), this, SLOT( setSymbolColor() ) ); - connect( spinAngle, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerAngle( double ) ) ); - connect( spinSize, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerSize( double ) ) ); - connect( spinWidth, SIGNAL( valueChanged( double ) ), this, SLOT( setLineWidth( double ) ) ); + // set symbol as active item in the tree + QModelIndex newIndex = layersTree->model()->index( 0, 0 ); + layersTree->setCurrentIndex( newIndex ); - connect( btnAddToStyle, SIGNAL( clicked() ), this, SLOT( addSymbolToStyle() ) ); - btnSymbolProperties->setIcon( QIcon( QgsApplication::defaultThemePath() + "mActionOptions.png" ) ); - btnAddToStyle->setIcon( QIcon( QgsApplication::defaultThemePath() + "symbologyAdd.png" ) ); -} - -void QgsSymbolV2SelectorDialog::populateSymbolView() -{ - QSize previewSize = viewSymbols->iconSize(); - QPixmap p( previewSize ); - QPainter painter; - - QStandardItemModel* model = qobject_cast( viewSymbols->model() ); - if ( !model ) - { - return; - } - model->clear(); - - QStringList names = mStyle->symbolNames(); - for ( int i = 0; i < names.count(); i++ ) - { - QgsSymbolV2* s = mStyle->symbol( names[i] ); - if ( s->type() != mSymbol->type() ) - { - delete s; - continue; - } - QStandardItem* item = new QStandardItem( names[i] ); - item->setData( names[i], Qt::UserRole ); //so we can show a label when it is clicked - item->setText( "" ); //set the text to nothing and show in label when clicked rather - item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable ); - // create preview icon - QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( s, previewSize ); - item->setIcon( icon ); - // add to model - model->appendRow( item ); - delete s; - } -} - -void QgsSymbolV2SelectorDialog::setSymbolFromStyle( const QModelIndex & index ) -{ - QString symbolName = index.data( Qt::UserRole ).toString(); - lblSymbolName->setText( symbolName ); - // get new instance of symbol from style - QgsSymbolV2* s = mStyle->symbol( symbolName ); - // remove all symbol layers from original symbol - while ( mSymbol->symbolLayerCount() ) - mSymbol->deleteSymbolLayer( 0 ); - // move all symbol layers to our symbol - while ( s->symbolLayerCount() ) - { - QgsSymbolLayerV2* sl = s->takeSymbolLayer( 0 ); - mSymbol->appendSymbolLayer( sl ); - } - // delete the temporary symbol - delete s; - - updateSymbolPreview(); - updateSymbolInfo(); - emit symbolModified(); -} - -void QgsSymbolV2SelectorDialog::updateSymbolPreview() -{ - QImage preview = mSymbol->bigSymbolPreviewImage(); - lblPreview->setPixmap( QPixmap::fromImage( preview ) ); -} - -void QgsSymbolV2SelectorDialog::updateSymbolColor() -{ - btnColor->setColor( mSymbol->color() ); -} - -void QgsSymbolV2SelectorDialog::updateSymbolInfo() -{ - updateSymbolColor(); - - if ( mSymbol->type() == QgsSymbolV2::Marker ) - { - QgsMarkerSymbolV2* markerSymbol = static_cast( mSymbol ); - spinSize->setValue( markerSymbol->size() ); - spinAngle->setValue( markerSymbol->angle() ); - } - else if ( mSymbol->type() == QgsSymbolV2::Line ) - { - QgsLineSymbolV2* lineSymbol = static_cast( mSymbol ); - spinWidth->setValue( lineSymbol->width() ); - } -} - -void QgsSymbolV2SelectorDialog::changeSymbolProperties() -{ - QgsSymbolV2PropertiesDialog dlg( mSymbol, mVectorLayer, this ); - if ( !dlg.exec() ) - return; - - updateSymbolPreview(); - updateSymbolInfo(); - emit symbolModified(); -} - - -void QgsSymbolV2SelectorDialog::setSymbolColor() -{ -#if defined(Q_WS_MAC) && QT_VERSION >= 0x040500 && defined(QT_MAC_USE_COCOA) - // Native Mac dialog works only for Qt Carbon - // Qt bug: http://bugreports.qt.nokia.com/browse/QTBUG-14889 - // FIXME need to also check max QT_VERSION when Qt bug fixed - QColor color = QColorDialog::getColor( mSymbol->color(), this, "", QColorDialog::DontUseNativeDialog ); -#else - QColor color = QColorDialog::getColor( mSymbol->color(), this ); -#endif - if ( !color.isValid() ) - return; - - mSymbol->setColor( color ); - updateSymbolColor(); - updateSymbolPreview(); - emit symbolModified(); -} - -void QgsSymbolV2SelectorDialog::setMarkerAngle( double angle ) -{ - QgsMarkerSymbolV2* markerSymbol = static_cast( mSymbol ); - if ( markerSymbol->angle() == angle ) - return; - markerSymbol->setAngle( angle ); - updateSymbolPreview(); - emit symbolModified(); -} - -void QgsSymbolV2SelectorDialog::setMarkerSize( double size ) -{ - QgsMarkerSymbolV2* markerSymbol = static_cast( mSymbol ); - if ( markerSymbol->size() == size ) - return; - markerSymbol->setSize( size ); - updateSymbolPreview(); - emit symbolModified(); -} - -void QgsSymbolV2SelectorDialog::setLineWidth( double width ) -{ - QgsLineSymbolV2* lineSymbol = static_cast( mSymbol ); - if ( lineSymbol->width() == width ) - return; - lineSymbol->setWidth( width ); - updateSymbolPreview(); - emit symbolModified(); -} - -void QgsSymbolV2SelectorDialog::addSymbolToStyle() -{ - bool ok; - QString name = QInputDialog::getText( this, tr( "Symbol name" ), - tr( "Please enter name for the symbol:" ) , QLineEdit::Normal, tr( "New symbol" ), &ok ); - if ( !ok || name.isEmpty() ) - return; - - // check if there is no symbol with same name - if ( mStyle->symbolNames().contains( name ) ) - { - int res = QMessageBox::warning( this, tr( "Save symbol" ), - tr( "Symbol with name '%1' already exists. Overwrite?" ) - .arg( name ), - QMessageBox::Yes | QMessageBox::No ); - if ( res != QMessageBox::Yes ) - { - return; - } - } - - // add new symbol to style and re-populate the list - mStyle->addSymbol( name, mSymbol->clone() ); - - // make sure the symbol is stored - mStyle->save(); - - populateSymbolView(); } void QgsSymbolV2SelectorDialog::keyPressEvent( QKeyEvent * e ) @@ -278,51 +201,339 @@ void QgsSymbolV2SelectorDialog::keyPressEvent( QKeyEvent * e ) } } -void QgsSymbolV2SelectorDialog::on_mSymbolUnitComboBox_currentIndexChanged( const QString & text ) -{ - Q_UNUSED( text ); - if ( mSymbol ) - { - mSymbol->setOutputUnit(( QgsSymbolV2::OutputUnit ) mSymbolUnitComboBox->currentIndex() ); - - updateSymbolPreview(); - emit symbolModified(); - } -} - -void QgsSymbolV2SelectorDialog::on_mTransparencySlider_valueChanged( int value ) -{ - if ( mSymbol ) - { - double alpha = 1 - ( value / 255.0 ); - mSymbol->setAlpha( alpha ); - displayTransparency( alpha ); - updateSymbolPreview(); - emit symbolModified(); - } -} - -void QgsSymbolV2SelectorDialog::displayTransparency( double alpha ) -{ - double transparencyPercent = ( 1 - alpha ) * 100; - mTransparencyLabel->setText( tr( "Transparency %1%" ).arg(( int ) transparencyPercent ) ); -} - QMenu* QgsSymbolV2SelectorDialog::advancedMenu() { if ( mAdvancedMenu == NULL ) { mAdvancedMenu = new QMenu; - btnAdvanced->setMenu( mAdvancedMenu ); - btnAdvanced->show(); + //btnAdvanced->setMenu( mAdvancedMenu ); + //btnAdvanced->show(); + // TODO + // Send the menu to symbols list widget } return mAdvancedMenu; } -void QgsSymbolV2SelectorDialog::openStyleManager() +void QgsSymbolV2SelectorDialog::loadSymbol( QgsSymbolV2* symbol, SymbolLayerItem* parent ) { - QgsStyleV2ManagerDialog dlg( mStyle, this ); - dlg.exec(); + SymbolLayerItem* symbolItem = new SymbolLayerItem( symbol ); + parent->appendRow( symbolItem ); - populateSymbolView(); + int count = symbol->symbolLayerCount(); + for ( int i = count - 1; i >= 0; i-- ) + { + SymbolLayerItem *layerItem = new SymbolLayerItem( symbol->symbolLayer( i ) ); + layerItem->setEditable( false ); + symbolItem->appendRow( layerItem ); + if ( symbol->symbolLayer( i )->subSymbol() ) + { + loadSymbol( symbol->symbolLayer( i )->subSymbol(), layerItem ); + } + } + layersTree->setExpanded( symbolItem->index(), true); } + + +void QgsSymbolV2SelectorDialog::loadSymbol() +{ + model->clear(); + loadSymbol( mSymbol, static_cast( model->invisibleRootItem() ) ); +} + +void QgsSymbolV2SelectorDialog::updateUi() +{ + QModelIndex currentIdx = layersTree->currentIndex(); + if ( !currentIdx.isValid() ) + return; + + SymbolLayerItem *item = static_cast( model->itemFromIndex( currentIdx ) ); + if ( !item->isLayer() ) + { + btnUp->setEnabled( false ); + btnDown->setEnabled( false ); + btnRemoveLayer->setEnabled( false ); + btnLock->setEnabled( false ); + return; + } + + int rowCount = item->parent()->rowCount(); + int currentRow = item->row(); + + btnUp->setEnabled( currentRow > 0 ); + btnDown->setEnabled( currentRow < rowCount - 1 ); + btnRemoveLayer->setEnabled( rowCount > 1 ); + btnLock->setEnabled( true ); +} + +void QgsSymbolV2SelectorDialog::updatePreview() +{ + QImage preview = mSymbol->bigSymbolPreviewImage(); + lblPreview->setPixmap( QPixmap::fromImage( preview ) ); + // Hope this is a appropriate place + emit symbolModified(); +} + +void QgsSymbolV2SelectorDialog::updateLayerPreview() +{ + // get current layer item and update its icon + SymbolLayerItem* item = currentLayerItem(); + if ( item ) + item->updatePreview(); + // update also preview of the whole symbol + updatePreview(); +} + +// A similar function would be needed to update the stacked widget +// void QgsSymbolV2SelectorDialog::updateSymbolLayerWidget( QgsSymbolLayerV2* layer ) + +SymbolLayerItem* QgsSymbolV2SelectorDialog::currentLayerItem() +{ + QModelIndex idx = layersTree->currentIndex(); + if ( !idx.isValid() ) + return NULL; + + SymbolLayerItem *item = static_cast( model->itemFromIndex( idx ) ); + if ( !item->isLayer() ) + return NULL; + + return item; +} + +QgsSymbolLayerV2* QgsSymbolV2SelectorDialog::currentLayer() +{ + QModelIndex idx = layersTree->currentIndex(); + if ( !idx.isValid() ) + return NULL; + + SymbolLayerItem *item = static_cast( model->itemFromIndex( idx ) ); + if ( item->isLayer() ) + return item->layer(); + + return NULL; +} + + +void QgsSymbolV2SelectorDialog::layerChanged() +{ + // We donot want slot to fire while we load compatible layertypes + // disconnect( cboLayerType, SIGNAL( currentIndexChanged( int ) ), this, SLOT( layerTypeChanged() ) ); + updateUi(); + + SymbolLayerItem *currentItem = static_cast( model->itemFromIndex( layersTree->currentIndex() ) ); + if ( currentItem == NULL ) + return; + + // TODO Entire thing below is a TODO + if ( currentItem->isLayer() ) + { + // add layerproperties widget to the stacked widget and update + // build the widget based on layer type and set it + } + else + { + // then it must be a symbol + // Now populate symbols of that type using the symbols list widget: + QWidget *symbolsList = new QgsSymbolsListWidget( currentItem->symbol(), mStyle, this ); + setWidget( symbolsList ); + connect( symbolsList, SIGNAL( changed() ), this, SLOT( symbolChanged() ) ); + } + updateLockButton(); +} + +void QgsSymbolV2SelectorDialog::symbolChanged() +{ + SymbolLayerItem *currentItem = static_cast( model->itemFromIndex( layersTree->currentIndex() ) ); + if ( currentItem == NULL || currentItem->isLayer() ) + return; + // disconnect to avoid recreating widget + disconnect( layersTree->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( layerChanged() ) ); + if ( currentItem->parent() ) + { + // it is a sub-symbol + QgsSymbolV2* symbol = currentItem->symbol(); + SymbolLayerItem *parent = static_cast( currentItem->parent() ); + parent->removeRow( 0 ); + loadSymbol( symbol, parent ); + layersTree->setCurrentIndex( parent->child( 0 )->index() ); + } + else + { + //it is the symbol itself + loadSymbol(); + QModelIndex newIndex = layersTree->model()->index( 0, 0 ); + layersTree->setCurrentIndex( newIndex ); + } + updatePreview(); + // connect it back once things are set + connect( layersTree->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( layerChanged() ) ); +} + +void QgsSymbolV2SelectorDialog::setWidget( QWidget* widget ) +{ + int index = stackedWidget->addWidget( widget ); + stackedWidget->setCurrentIndex( index ); + if ( mPresentWidget ) + { + stackedWidget->removeWidget( mPresentWidget ); + QWidget *dummy = mPresentWidget; + mPresentWidget = widget; + delete dummy; // auto disconnects all signals + } +} + + +void QgsSymbolV2SelectorDialog::updateLockButton() +{ + QgsSymbolLayerV2* layer = currentLayer(); + if ( !layer ) + return; + btnLock->setChecked( layer->isLocked() ); +} + + +void QgsSymbolV2SelectorDialog::layerTypeChanged() +{ + QgsSymbolLayerV2* layer = currentLayer(); + if ( !layer ) + return; + // FIXME + /* + QString newLayerType = cboLayerType->itemData( cboLayerType->currentIndex() ).toString(); + if ( layer->layerType() == newLayerType ) + return; + */ + + QString newLayerType = "Simple Line"; + + // 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; + + SymbolLayerItem *item = currentLayerItem(); + // remove previos childs if any + if ( layer->subSymbol() ) + { + item->removeRow( 0 ); + } + // update symbol layer item + item->setLayer( newLayer ); + // When it is a marker symbol + if ( newLayer->subSymbol() ) + { + SymbolLayerItem *subsymbol = new SymbolLayerItem( newLayer->subSymbol() ); + SymbolLayerItem *sublayer = new SymbolLayerItem( newLayer->subSymbol()->symbolLayer( 0 ) ); + subsymbol->appendRow( sublayer ); + item->appendRow( subsymbol ); + } + + // Change the symbol at last to avoid deleting item's layer + QgsSymbolV2* symbol = static_cast( item->parent() )->symbol(); + int layerIdx = item->parent()->rowCount() - item->row() - 1; + symbol->changeSymbolLayer( layerIdx, newLayer ); + + //updateSymbolLayerWidget( newLayer ); + + item->updatePreview(); + updatePreview(); +} + + +void QgsSymbolV2SelectorDialog::addLayer() +{ + QModelIndex idx = layersTree->currentIndex(); + if ( !idx.isValid() ) + return; + + SymbolLayerItem *item = static_cast( model->itemFromIndex( idx ) ); + if ( item->isLayer() ) + { + QMessageBox::critical( this, tr( "Invalid Selection!" ), tr( "Kindly select a symbol to add layer.") ); + return; + } + + QgsSymbolV2* parentSymbol = item->symbol(); + QgsSymbolLayerV2* newLayer = QgsSymbolLayerV2Registry::instance()->defaultSymbolLayer( parentSymbol->type() ); + parentSymbol->appendSymbolLayer( newLayer ); + // XXX Insane behaviour of the appendSymbolLayer, it actually "pushes" into the list + SymbolLayerItem *newLayerItem = new SymbolLayerItem( newLayer ); + item->insertRow( 0, newLayerItem ); + item->updatePreview(); + + layersTree->setCurrentIndex( model->indexFromItem( newLayerItem ) ); + updateUi(); + updatePreview(); +} + +void QgsSymbolV2SelectorDialog::removeLayer() +{ + SymbolLayerItem *item = currentLayerItem(); + int row = item->row(); + SymbolLayerItem *parent = static_cast( item->parent() ); + + int layerIdx = parent->rowCount() - row - 1; // IMPORTANT + QgsSymbolV2* parentSymbol = parent->symbol(); + QgsSymbolLayerV2 *tmpLayer = parentSymbol->takeSymbolLayer( layerIdx ); + + parent->removeRow( row ); + parent->updatePreview(); + + QModelIndex newIdx = parent->child( 0 )->index(); + layersTree->setCurrentIndex( newIdx ); + + updateUi(); + updatePreview(); + //finally delete the removed layer pointer + delete tmpLayer; +} + +void QgsSymbolV2SelectorDialog::moveLayerDown() +{ + moveLayerByOffset( + 1 ); +} + +void QgsSymbolV2SelectorDialog::moveLayerUp() +{ + moveLayerByOffset( -1 ); +} + +void QgsSymbolV2SelectorDialog::moveLayerByOffset( int offset ) +{ + SymbolLayerItem *item = currentLayerItem(); + if( item == NULL ) + return; + int row = item->row(); + + SymbolLayerItem *parent = static_cast( item->parent() ); + QgsSymbolV2* parentSymbol = parent->symbol(); + + int layerIdx = parent->rowCount() - row - 1; + // switch layers + QgsSymbolLayerV2* tmpLayer = parentSymbol->takeSymbolLayer( layerIdx ); + parentSymbol->insertSymbolLayer( layerIdx - offset, tmpLayer ); + + QList rowItems = parent->takeRow( row ); + parent->insertRows( row + offset, rowItems ); + parent->updatePreview(); + + QModelIndex newIdx = rowItems[ 0 ]->index(); + layersTree->setCurrentIndex( newIdx ); + + updatePreview(); + updateUi(); +} + +void QgsSymbolV2SelectorDialog::lockLayer() +{ + QgsSymbolLayerV2* layer = currentLayer(); + if ( !layer ) + return; + layer->setLocked( btnLock->isChecked() ); +} + diff --git a/src/gui/symbology-ng/qgssymbolv2selectordialog.h b/src/gui/symbology-ng/qgssymbolv2selectordialog.h index a2e4661ce29..a7ab88a866c 100644 --- a/src/gui/symbology-ng/qgssymbolv2selectordialog.h +++ b/src/gui/symbology-ng/qgssymbolv2selectordialog.h @@ -20,11 +20,17 @@ #include "ui_qgssymbolv2selectordialogbase.h" +#include + class QgsStyleV2; class QgsSymbolV2; +class QgsSymbolLayerV2; class QgsVectorLayer; class QMenu; +class QWidget; + +class SymbolLayerItem; class GUI_EXPORT QgsSymbolV2SelectorDialog : public QDialog, private Ui::QgsSymbolV2SelectorDialogBase { @@ -37,39 +43,59 @@ class GUI_EXPORT QgsSymbolV2SelectorDialog : public QDialog, private Ui::QgsSymb QMenu* advancedMenu(); protected: - void populateSymbolView(); - void updateSymbolPreview(); - void updateSymbolColor(); - void updateSymbolInfo(); - //! Reimplements dialog keyPress event so we can ignore it void keyPressEvent( QKeyEvent * event ); - private: - /**Displays alpha value as transparency in mTransparencyLabel*/ - void displayTransparency( double alpha ); + void loadSymbol(); + void loadSymbol( QgsSymbolV2* symbol, SymbolLayerItem* parent ); - public slots: - void changeSymbolProperties(); - void setSymbolFromStyle( const QModelIndex & index ); - void setSymbolColor(); - void setMarkerAngle( double angle ); - void setMarkerSize( double size ); - void setLineWidth( double width ); - void addSymbolToStyle(); - void on_mSymbolUnitComboBox_currentIndexChanged( const QString & text ); - void on_mTransparencySlider_valueChanged( int value ); + void populateLayerTypes( QgsSymbolV2* symbol ); - void openStyleManager(); + void updateUi(); + + //void loadPropertyWidgets(); + + //void updateSymbolLayerWidget( QgsSymbolLayerV2* layer ); + 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 layerTypeChanged(); + + void layerChanged(); + + void updateLayerPreview(); + void updatePreview(); + + void symbolChanged(); + + + protected: // data QgsStyleV2* mStyle; QgsSymbolV2* mSymbol; QMenu* mAdvancedMenu; const QgsVectorLayer* mVectorLayer; + + QStandardItemModel* model; + QWidget *mPresentWidget; + }; #endif diff --git a/src/ui/qgssymbolv2propertiesdialogbase.ui b/src/ui/qgssymbolv2propertiesdialogbase.ui index d09520d466e..a7bb8e0cc5c 100644 --- a/src/ui/qgssymbolv2propertiesdialogbase.ui +++ b/src/ui/qgssymbolv2propertiesdialogbase.ui @@ -6,7 +6,7 @@ 0 0 - 674 + 597 396 @@ -68,10 +68,13 @@ - - - - Symbol layers + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -205,13 +208,10 @@ - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + Symbol layers @@ -235,22 +235,6 @@ - - buttonBox - accepted() - DlgSymbolV2Properties - accept() - - - 257 - 386 - - - 157 - 274 - - - buttonBox rejected() @@ -267,5 +251,21 @@ + + buttonBox + accepted() + DlgSymbolV2Properties + accept() + + + 257 + 386 + + + 157 + 274 + + + diff --git a/src/ui/qgssymbolv2selectordialogbase.ui b/src/ui/qgssymbolv2selectordialogbase.ui index e61a7309915..bcd48e5219d 100644 --- a/src/ui/qgssymbolv2selectordialogbase.ui +++ b/src/ui/qgssymbolv2selectordialogbase.ui @@ -6,20 +6,20 @@ 0 0 - 489 + 619 416 Symbol selector - + - + 0 0 @@ -45,326 +45,105 @@ - + - Change... + Symbol layers - - - - - - - - - - Unit - - - mSymbolUnitComboBox - - - - - - - - Millimeter - - - - - Map unit - - - - - - - - Opacity - - - mTransparencySlider - - - - - + + + + QAbstractItemView::NoEditTriggers + + + + + + + - + 0 0 - - 255 - - - Qt::Horizontal + + Add symbol layer - - - - Color + + + + + 0 + 0 + - - btnColor + + Remove symbol layer - - - - Change + + + + + 0 + 0 + + + + Lock layer's color + + + true + + + + + + + + 0 + 0 + + + + Move up + + + + + + + + 0 + 0 + + + + Move down - - - - - 0 - 0 - - - - 2 - - - - - - - Size - - - - - - - 2 - - - 99999.000000000000000 - - - 1.000000000000000 - - - - - - - Rotation - - - - - - - ° - - - 1 - - - 360.000000000000000 - - - 5.000000000000000 - - - - - - - Qt::Horizontal - - - - 178 - 20 - - - - - - - - - - - - Width - - - - - - - 5 - - - 99999.000000000000000 - - - 1.000000000000000 - - - - - - - Qt::Horizontal - - - - 37 - 20 - - - - - - - - Qt::Horizontal - - - - 37 - 20 - - - - - - - - - - 0 - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Advanced - - - - - - - Save as style - - - - - - - Qt::Horizontal + + + + + 2 + 0 + + - - - - - - Saved styles - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Style manager... - - - - - - - - 0 - 2 - - - - - 48 - 48 - - - - QListView::LeftToRight - - - QListView::Adjust - - - 5 - - - QListView::IconMode - - - true - - - true - - - - - - - - - Symbol Name - - - - + Qt::Horizontal @@ -376,27 +155,6 @@ - - - QgsColorButtonV2 - QPushButton -
qgscolorbutton.h
-
-
- - btnSymbolProperties - mSymbolUnitComboBox - mTransparencySlider - btnColor - spinWidth - spinSize - spinAngle - btnAdvanced - btnAddToStyle - btnStyleManager - viewSymbols - buttonBox -