Quantum GIS API Documentation  master-693a1fe
src/gui/symbology-ng/qgssymbolslistwidget.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002     qgssymbolslist.cpp
00003     ---------------------
00004     begin                : June 2012
00005     copyright            : (C) 2012 by Arunmozhi
00006     email                : aruntheguy at gmail.com
00007  ***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 
00016 
00017 #include "qgssymbolslistwidget.h"
00018 
00019 #include "qgsstylev2managerdialog.h"
00020 
00021 #include "qgssymbolv2.h"
00022 #include "qgsstylev2.h"
00023 #include "qgssymbollayerv2utils.h"
00024 
00025 #include "qgsapplication.h"
00026 
00027 #include <QString>
00028 #include <QStringList>
00029 #include <QPainter>
00030 #include <QIcon>
00031 #include <QStandardItemModel>
00032 #include <QColorDialog>
00033 #include <QInputDialog>
00034 #include <QMessageBox>
00035 #include <QMenu>
00036 
00037 
00038 QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbolV2* symbol, QgsStyleV2* style, QMenu* menu, QWidget* parent ) : QWidget( parent )
00039 {
00040   mSymbol = symbol;
00041   mStyle = style;
00042 
00043   setupUi( this );
00044 
00045   btnAdvanced->hide(); // advanced button is hidden by default
00046   if ( menu ) // show it if there is a menu pointer
00047   {
00048     btnAdvanced->setMenu( menu );
00049     btnAdvanced->show();
00050   }
00051 
00052   // populate the groups
00053   groupsCombo->addItem( "" );
00054   populateGroups();
00055   QStringList groups = style->smartgroupNames();
00056   foreach ( QString group, groups )
00057   {
00058     groupsCombo->addItem( group, QVariant( "smart" ) );
00059   }
00060 
00061   QStandardItemModel* model = new QStandardItemModel( viewSymbols );
00062   viewSymbols->setModel( model );
00063   connect( viewSymbols->selectionModel(), SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ), this, SLOT( setSymbolFromStyle( const QModelIndex & ) ) );
00064 
00065   if ( parent )
00066   {
00067     if ( dynamic_cast<QgsStyleV2ManagerDialog*>( parent->parentWidget() ) )
00068     {
00069       btnStyle->setVisible( false );
00070     }
00071   }
00072   // Set the Style Menu under btnStyle
00073   QMenu *styleMenu = new QMenu( btnStyle );
00074   QAction *styleMgrAction = new QAction( "Style Manager", styleMenu );
00075   styleMenu->addAction( styleMgrAction );
00076   QAction *saveStyle = new QAction( "Save in symbol library...", styleMenu );
00077   styleMenu->addAction( saveStyle );
00078   connect( styleMgrAction, SIGNAL( triggered() ), this, SLOT( openStyleManager() ) );
00079   connect( saveStyle, SIGNAL( triggered() ), this, SLOT( addSymbolToStyle() ) );
00080   btnStyle->setMenu( styleMenu );
00081 
00082   lblSymbolName->setText( "" );
00083   populateSymbolView();
00084 
00085   if ( mSymbol )
00086   {
00087     // output unit
00088     mSymbolUnitComboBox->blockSignals( true );
00089     mSymbolUnitComboBox->setCurrentIndex( mSymbol->outputUnit() );
00090     mSymbolUnitComboBox->blockSignals( false );
00091 
00092     mTransparencySlider->blockSignals( true );
00093     double transparency = 1 - symbol->alpha();
00094     mTransparencySlider->setValue( transparency * 255 );
00095     displayTransparency( symbol->alpha() );
00096     mTransparencySlider->blockSignals( false );
00097   }
00098 
00099   // select correct page in stacked widget
00100   // there's a correspondence between symbol type number and page numbering => exploit it!
00101   stackedWidget->setCurrentIndex( symbol->type() );
00102   connect( btnColor, SIGNAL( colorChanged( const QColor& ) ), this, SLOT( setSymbolColor( const QColor& ) ) );
00103   connect( spinAngle, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerAngle( double ) ) );
00104   connect( spinSize, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerSize( double ) ) );
00105   connect( spinWidth, SIGNAL( valueChanged( double ) ), this, SLOT( setLineWidth( double ) ) );
00106 
00107   // Live color updates are not undoable to child symbol layers
00108   btnColor->setAcceptLiveUpdates( false );
00109   btnColor->setColorDialogOptions( QColorDialog::ShowAlphaChannel );
00110   // Set symbol color in btnColor
00111   updateSymbolColor();
00112 }
00113 
00114 void QgsSymbolsListWidget::populateGroups( QString parent, QString prepend )
00115 {
00116   QgsSymbolGroupMap groups = mStyle->childGroupNames( parent );
00117   QgsSymbolGroupMap::const_iterator i = groups.constBegin();
00118   while ( i != groups.constEnd() )
00119   {
00120     QString text;
00121     if ( !prepend.isEmpty() )
00122     {
00123       text = prepend + "/" + i.value();
00124     }
00125     else
00126     {
00127       text = i.value();
00128     }
00129     groupsCombo->addItem( text, QVariant( i.key() ) );
00130     populateGroups( i.value(), text );
00131     ++i;
00132   }
00133 }
00134 
00135 void QgsSymbolsListWidget::populateSymbolView()
00136 {
00137   populateSymbols( mStyle->symbolNames() );
00138 }
00139 
00140 void QgsSymbolsListWidget::populateSymbols( QStringList names )
00141 {
00142   QSize previewSize = viewSymbols->iconSize();
00143   QPixmap p( previewSize );
00144   QPainter painter;
00145 
00146   QStandardItemModel* model = qobject_cast<QStandardItemModel*>( viewSymbols->model() );
00147   if ( !model )
00148   {
00149     return;
00150   }
00151   model->clear();
00152 
00153   for ( int i = 0; i < names.count(); i++ )
00154   {
00155     QgsSymbolV2* s = mStyle->symbol( names[i] );
00156     if ( s->type() != mSymbol->type() )
00157     {
00158       delete s;
00159       continue;
00160     }
00161     QStandardItem* item = new QStandardItem( names[i] );
00162     item->setData( names[i], Qt::UserRole ); //so we can load symbol with that name
00163     item->setText( names[i] );
00164     item->setToolTip( names[i] );
00165     item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
00166     // Set font to 10points to show reasonable text
00167     QFont itemFont = item->font();
00168     itemFont.setPointSize( 10 );
00169     item->setFont( itemFont );
00170     // create preview icon
00171     QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( s, previewSize );
00172     item->setIcon( icon );
00173     // add to model
00174     model->appendRow( item );
00175     delete s;
00176   }
00177 }
00178 
00179 void QgsSymbolsListWidget::openStyleManager()
00180 {
00181   QgsStyleV2ManagerDialog dlg( mStyle, this );
00182   dlg.exec();
00183 
00184   populateSymbolView();
00185 }
00186 
00187 void QgsSymbolsListWidget::setSymbolColor( const QColor& color )
00188 {
00189   mSymbol->setColor( color );
00190   emit changed();
00191 }
00192 
00193 void QgsSymbolsListWidget::setMarkerAngle( double angle )
00194 {
00195   QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
00196   if ( markerSymbol->angle() == angle )
00197     return;
00198   markerSymbol->setAngle( angle );
00199   emit changed();
00200 }
00201 
00202 void QgsSymbolsListWidget::setMarkerSize( double size )
00203 {
00204   QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
00205   if ( markerSymbol->size() == size )
00206     return;
00207   markerSymbol->setSize( size );
00208   emit changed();
00209 }
00210 
00211 void QgsSymbolsListWidget::setLineWidth( double width )
00212 {
00213   QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mSymbol );
00214   if ( lineSymbol->width() == width )
00215     return;
00216   lineSymbol->setWidth( width );
00217   emit changed();
00218 }
00219 
00220 void QgsSymbolsListWidget::addSymbolToStyle()
00221 {
00222   bool ok;
00223   QString name = QInputDialog::getText( this, tr( "Symbol name" ),
00224                                         tr( "Please enter name for the symbol:" ) , QLineEdit::Normal, tr( "New symbol" ), &ok );
00225   if ( !ok || name.isEmpty() )
00226     return;
00227 
00228   // check if there is no symbol with same name
00229   if ( mStyle->symbolNames().contains( name ) )
00230   {
00231     int res = QMessageBox::warning( this, tr( "Save symbol" ),
00232                                     tr( "Symbol with name '%1' already exists. Overwrite?" )
00233                                     .arg( name ),
00234                                     QMessageBox::Yes | QMessageBox::No );
00235     if ( res != QMessageBox::Yes )
00236     {
00237       return;
00238     }
00239   }
00240 
00241   // add new symbol to style and re-populate the list
00242   mStyle->addSymbol( name, mSymbol->clone() );
00243 
00244   // make sure the symbol is stored
00245   mStyle->saveSymbol( name, mSymbol->clone(), 0, QStringList() );
00246 
00247   populateSymbolView();
00248 }
00249 
00250 void QgsSymbolsListWidget::on_mSymbolUnitComboBox_currentIndexChanged( const QString & text )
00251 {
00252   Q_UNUSED( text );
00253   if ( mSymbol )
00254   {
00255     mSymbol->setOutputUnit(( QgsSymbolV2::OutputUnit ) mSymbolUnitComboBox->currentIndex() );
00256 
00257     emit changed();
00258   }
00259 }
00260 
00261 void QgsSymbolsListWidget::on_mTransparencySlider_valueChanged( int value )
00262 {
00263   if ( mSymbol )
00264   {
00265     double alpha = 1 - ( value / 255.0 );
00266     mSymbol->setAlpha( alpha );
00267     displayTransparency( alpha );
00268     emit changed();
00269   }
00270 }
00271 
00272 void QgsSymbolsListWidget::displayTransparency( double alpha )
00273 {
00274   double transparencyPercent = ( 1 - alpha ) * 100;
00275   mTransparencyLabel->setText( tr( "Transparency %1%" ).arg(( int ) transparencyPercent ) );
00276 }
00277 
00278 void QgsSymbolsListWidget::updateSymbolColor()
00279 {
00280   btnColor->blockSignals( true );
00281   btnColor->setColor( mSymbol->color() );
00282   btnColor->blockSignals( false );
00283 }
00284 
00285 void QgsSymbolsListWidget::updateSymbolInfo()
00286 {
00287   updateSymbolColor();
00288 
00289   if ( mSymbol->type() == QgsSymbolV2::Marker )
00290   {
00291     QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
00292     spinSize->setValue( markerSymbol->size() );
00293     spinAngle->setValue( markerSymbol->angle() );
00294   }
00295   else if ( mSymbol->type() == QgsSymbolV2::Line )
00296   {
00297     QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mSymbol );
00298     spinWidth->setValue( lineSymbol->width() );
00299   }
00300 }
00301 
00302 void QgsSymbolsListWidget::setSymbolFromStyle( const QModelIndex & index )
00303 {
00304   QString symbolName = index.data( Qt::UserRole ).toString();
00305   lblSymbolName->setText( symbolName );
00306   // get new instance of symbol from style
00307   QgsSymbolV2* s = mStyle->symbol( symbolName );
00308   // remove all symbol layers from original symbol
00309   while ( mSymbol->symbolLayerCount() )
00310     mSymbol->deleteSymbolLayer( 0 );
00311   // move all symbol layers to our symbol
00312   while ( s->symbolLayerCount() )
00313   {
00314     QgsSymbolLayerV2* sl = s->takeSymbolLayer( 0 );
00315     mSymbol->appendSymbolLayer( sl );
00316   }
00317   // delete the temporary symbol
00318   delete s;
00319 
00320   updateSymbolInfo();
00321   emit changed();
00322 }
00323 
00324 void QgsSymbolsListWidget::on_groupsCombo_currentIndexChanged( int index )
00325 {
00326   QStringList symbols;
00327   QString text = groupsCombo->itemText( index );
00328   // List all symbols when empty list item is selected
00329   if ( text.isEmpty() )
00330   {
00331     symbols = mStyle->symbolNames();
00332   }
00333   else
00334   {
00335     int groupid;
00336     if ( groupsCombo->itemData( index ).toString() == "smart" )
00337     {
00338       groupid = mStyle->smartgroupId( text );
00339       symbols = mStyle->symbolsOfSmartgroup( QgsStyleV2::SymbolEntity, groupid );
00340     }
00341     else
00342     {
00343       groupid = groupsCombo->itemData( index ).toInt();
00344       symbols = mStyle->symbolsOfGroup( QgsStyleV2::SymbolEntity, groupid );
00345     }
00346   }
00347   populateSymbols( symbols );
00348 }
00349 
00350 void QgsSymbolsListWidget::on_groupsCombo_editTextChanged( const QString &text )
00351 {
00352   QStringList symbols = mStyle->findSymbols( text );
00353   populateSymbols( symbols );
00354 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines