QGIS API Documentation  master-6164ace
src/gui/symbology-ng/qgsstylev2managerdialog.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002     qgsstylev2managerdialog.cpp
00003     ---------------------
00004     begin                : November 2009
00005     copyright            : (C) 2009 by Martin Dobias
00006     email                : wonder dot sk at gmail dot 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 #include "qgsstylev2managerdialog.h"
00017 
00018 #include "qgsstylev2.h"
00019 #include "qgssymbolv2.h"
00020 #include "qgssymbollayerv2utils.h"
00021 #include "qgsvectorcolorrampv2.h"
00022 
00023 #include "qgssymbolv2selectordialog.h"
00024 #include "qgsvectorgradientcolorrampv2dialog.h"
00025 #include "qgsvectorrandomcolorrampv2dialog.h"
00026 #include "qgsvectorcolorbrewercolorrampv2dialog.h"
00027 #include "qgscptcitycolorrampv2dialog.h"
00028 #include "qgsstylev2exportimportdialog.h"
00029 #include "qgssmartgroupeditordialog.h"
00030 
00031 #include <QFile>
00032 #include <QFileDialog>
00033 #include <QInputDialog>
00034 #include <QMessageBox>
00035 #include <QSettings>
00036 #include <QStandardItemModel>
00037 #include <QAction>
00038 #include <QMenu>
00039 
00040 #include "qgsapplication.h"
00041 #include "qgslogger.h"
00042 
00043 
00044 QgsStyleV2ManagerDialog::QgsStyleV2ManagerDialog( QgsStyleV2* style, QWidget* parent )
00045     : QDialog( parent ), mStyle( style ), mModified( false )
00046 {
00047   setupUi( this );
00048 #ifdef Q_WS_MAC
00049   setWindowModality( Qt::WindowModal );
00050 #endif
00051 
00052   QSettings settings;
00053   restoreGeometry( settings.value( "/Windows/StyleV2Manager/geometry" ).toByteArray() );
00054   mSplitter->setSizes( QList<int>() << 170 << 540 );
00055   mSplitter->restoreState( settings.value( "/Windows/StyleV2Manager/splitter" ).toByteArray() );
00056 
00057 #if QT_VERSION >= 0x40500
00058   tabItemType->setDocumentMode( true );
00059 #endif
00060 #if QT_VERSION >= 0x40700
00061   searchBox->setPlaceholderText( tr( "Type here to filter symbols ..." ) );
00062 #else
00063   searchBox->setToolTip( tr( "Type here to filter symbols ..." ) );
00064 #endif
00065 
00066   // setup icons
00067   btnAddItem->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.png" ) ) );
00068   btnEditItem->setIcon( QIcon( QgsApplication::iconPath( "symbologyEdit.png" ) ) );
00069   btnRemoveItem->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.png" ) ) );
00070   btnShare->setIcon( QIcon( QgsApplication::iconPath( "user.png" ) ) );
00071 
00072   connect( this, SIGNAL( finished( int ) ), this, SLOT( onFinished() ) );
00073 
00074   connect( listItems, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( editItem() ) );
00075 
00076   connect( btnAddItem, SIGNAL( clicked() ), this, SLOT( addItem() ) );
00077   connect( btnEditItem, SIGNAL( clicked() ), this, SLOT( editItem() ) );
00078   connect( btnRemoveItem, SIGNAL( clicked() ), this, SLOT( removeItem() ) );
00079 
00080   QMenu *shareMenu = new QMenu( "Share Menu", this );
00081   QAction *exportAction = shareMenu->addAction( "Export" );
00082   QAction *importAction = shareMenu->addAction( "Import" );
00083   connect( exportAction, SIGNAL( triggered() ), this, SLOT( exportItems() ) );
00084   connect( importAction, SIGNAL( triggered() ), this, SLOT( importItems() ) );
00085   btnShare->setMenu( shareMenu );
00086 
00087   // Set editing mode off by default
00088   mGrouppingMode = false;
00089 
00090   QStandardItemModel* model = new QStandardItemModel( listItems );
00091   listItems->setModel( model );
00092   listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
00093 
00094   connect( model, SIGNAL( itemChanged( QStandardItem* ) ), this, SLOT( itemChanged( QStandardItem* ) ) );
00095   connect( listItems->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00096            this, SLOT( symbolSelected( const QModelIndex& ) ) );
00097 
00098   populateTypes();
00099 
00100   QStandardItemModel* groupModel = new QStandardItemModel( groupTree );
00101   groupTree->setModel( groupModel );
00102   groupTree->setHeaderHidden( true );
00103   populateGroups();
00104   connect( groupTree->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00105            this, SLOT( groupChanged( const QModelIndex& ) ) );
00106   connect( groupModel, SIGNAL( itemChanged( QStandardItem* ) ),
00107            this, SLOT( groupRenamed( QStandardItem* ) ) );
00108 
00109   QMenu *groupMenu = new QMenu( "Group Actions", this );
00110   QAction *groupSymbols = groupMenu->addAction( "Group Symbols" );
00111   QAction *editSmartgroup = groupMenu->addAction( "Edit Smart Group" );
00112   btnManageGroups->setMenu( groupMenu );
00113   connect( groupSymbols, SIGNAL( triggered() ), this, SLOT( groupSymbolsAction() ) );
00114   connect( editSmartgroup, SIGNAL( triggered() ), this, SLOT( editSmartgroupAction() ) );
00115 
00116   connect( btnAddGroup, SIGNAL( clicked() ), this, SLOT( addGroup() ) );
00117   connect( btnRemoveGroup, SIGNAL( clicked() ), this, SLOT( removeGroup() ) );
00118 
00119   on_tabItemType_currentChanged( 0 );
00120 
00121   connect( searchBox, SIGNAL( textChanged( QString ) ), this, SLOT( filterSymbols( QString ) ) );
00122   tagsLineEdit->installEventFilter( this );
00123 
00124   // Context menu for groupTree
00125   groupTree->setContextMenuPolicy( Qt::CustomContextMenu );
00126   connect( groupTree, SIGNAL( customContextMenuRequested( const QPoint& ) ),
00127            this, SLOT( grouptreeContextMenu( const QPoint& ) ) );
00128 
00129   // Context menu for listItems
00130   listItems->setContextMenuPolicy( Qt::CustomContextMenu );
00131   connect( listItems, SIGNAL( customContextMenuRequested( const QPoint& ) ),
00132            this, SLOT( listitemsContextMenu( const QPoint& ) ) );
00133 
00134 }
00135 
00136 void QgsStyleV2ManagerDialog::onFinished()
00137 {
00138   if ( mModified )
00139   {
00140     mStyle->save();
00141   }
00142 
00143   QSettings settings;
00144   settings.setValue( "/Windows/StyleV2Manager/geometry", saveGeometry() );
00145   settings.setValue( "/Windows/StyleV2Manager/splitter", mSplitter->saveState() );
00146 }
00147 
00148 void QgsStyleV2ManagerDialog::populateTypes()
00149 {
00150 #if 0
00151   // save current selection index in types combo
00152   int current = ( tabItemType->count() > 0 ? tabItemType->currentIndex() : 0 );
00153 
00154 // no counting of style items
00155   int markerCount = 0, lineCount = 0, fillCount = 0;
00156 
00157   QStringList symbolNames = mStyle->symbolNames();
00158   for ( int i = 0; i < symbolNames.count(); ++i )
00159   {
00160     switch ( mStyle->symbolRef( symbolNames[i] )->type() )
00161     {
00162       case QgsSymbolV2::Marker:
00163         markerCount++;
00164         break;
00165       case QgsSymbolV2::Line:
00166         lineCount++;
00167         break;
00168       case QgsSymbolV2::Fill:
00169         fillCount++;
00170         break;
00171       default: Q_ASSERT( 0 && "unknown symbol type" );
00172         break;
00173     }
00174   }
00175 
00176   cboItemType->clear();
00177   cboItemType->addItem( tr( "Marker symbol (%1)" ).arg( markerCount ), QVariant( QgsSymbolV2::Marker ) );
00178   cboItemType->addItem( tr( "Line symbol (%1)" ).arg( lineCount ), QVariant( QgsSymbolV2::Line ) );
00179   cboItemType->addItem( tr( "Fill symbol (%1)" ).arg( fillCount ), QVariant( QgsSymbolV2::Fill ) );
00180 
00181   cboItemType->addItem( tr( "Color ramp (%1)" ).arg( mStyle->colorRampCount() ), QVariant( 3 ) );
00182 
00183   // update current index to previous selection
00184   cboItemType->setCurrentIndex( current );
00185 #endif
00186 }
00187 
00188 void QgsStyleV2ManagerDialog::on_tabItemType_currentChanged( int )
00189 {
00190   // when in Color Ramp tab, add menu to add item button
00191   if ( currentItemType() == 3 )
00192   {
00193     QStringList rampTypes;
00194     rampTypes << tr( "Gradient" ) << tr( "Random" ) << tr( "ColorBrewer" );
00195     rampTypes << tr( "cpt-city" ); // todo, only for rasters?
00196     QMenu* menu = new QMenu( btnAddItem );
00197     foreach ( QString rampType, rampTypes )
00198     {
00199       menu->addAction( rampType );
00200     }
00201     btnAddItem->setMenu( menu );
00202     connect( menu, SIGNAL( triggered( QAction* ) ),
00203              this, SLOT( addColorRamp( QAction* ) ) );
00204   }
00205   else
00206   {
00207     if ( btnAddItem->menu() )
00208     {
00209       disconnect( btnAddItem->menu(), SIGNAL( triggered( QAction* ) ),
00210                   this, SLOT( addColorRamp( QAction* ) ) );
00211       btnAddItem->setMenu( 0 );
00212     }
00213   }
00214 
00215   // set icon and grid size, depending on type
00216   if ( currentItemType() == 1 || currentItemType() == 3 )
00217   {
00218     listItems->setIconSize( QSize( 75, 50 ) );
00219     listItems->setGridSize( QSize( 100, 80 ) );
00220   }
00221   else
00222   {
00223     listItems->setIconSize( QSize( 50, 50 ) );
00224     listItems->setGridSize( QSize( 75, 80 ) );
00225   }
00226 
00227   populateList();
00228 }
00229 
00230 void QgsStyleV2ManagerDialog::populateList()
00231 {
00232   if ( currentItemType() > 3 )
00233   {
00234     Q_ASSERT( 0 && "not implemented" );
00235     return;
00236   }
00237   groupChanged( groupTree->selectionModel()->currentIndex() );
00238 }
00239 
00240 void QgsStyleV2ManagerDialog::populateSymbols( QStringList symbolNames, bool check )
00241 {
00242   QStandardItemModel* model = qobject_cast<QStandardItemModel*>( listItems->model() );
00243   model->clear();
00244 
00245   int type = currentItemType();
00246 
00247   for ( int i = 0; i < symbolNames.count(); ++i )
00248   {
00249     QString name = symbolNames[i];
00250     QgsSymbolV2* symbol = mStyle->symbol( name );
00251     if ( symbol->type() == type )
00252     {
00253       QStandardItem* item = new QStandardItem( name );
00254       QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( symbol, listItems->iconSize() );
00255       item->setIcon( icon );
00256       item->setData( name ); // used to find out original name when user edited the name
00257       item->setCheckable( check );
00258       item->setToolTip( name );
00259       // add to model
00260       model->appendRow( item );
00261     }
00262     delete symbol;
00263   }
00264 }
00265 
00266 
00267 void QgsStyleV2ManagerDialog::populateColorRamps( QStringList colorRamps, bool check )
00268 {
00269   QStandardItemModel* model = qobject_cast<QStandardItemModel*>( listItems->model() );
00270   model->clear();
00271 
00272   for ( int i = 0; i < colorRamps.count(); ++i )
00273   {
00274     QString name = colorRamps[i];
00275     QgsVectorColorRampV2* ramp = mStyle->colorRamp( name );
00276 
00277     QStandardItem* item = new QStandardItem( name );
00278     QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( ramp, listItems->iconSize() );
00279     item->setIcon( icon );
00280     item->setData( name ); // used to find out original name when user edited the name
00281     item->setCheckable( check );
00282     item->setToolTip( name );
00283     model->appendRow( item );
00284     delete ramp;
00285   }
00286 }
00287 
00288 int QgsStyleV2ManagerDialog::currentItemType()
00289 {
00290   switch ( tabItemType->currentIndex() )
00291   {
00292     case 0: return QgsSymbolV2::Marker;
00293     case 1: return QgsSymbolV2::Line;
00294     case 2: return QgsSymbolV2::Fill;
00295     case 3: return 3;
00296     default: return 0;
00297   }
00298 }
00299 
00300 QString QgsStyleV2ManagerDialog::currentItemName()
00301 {
00302   QModelIndex index = listItems->selectionModel()->currentIndex();
00303   if ( !index.isValid() )
00304     return QString();
00305   return index.model()->data( index, 0 ).toString();
00306 }
00307 
00308 void QgsStyleV2ManagerDialog::addItem()
00309 {
00310   bool changed = false;
00311   if ( currentItemType() < 3 )
00312   {
00313     changed = addSymbol();
00314   }
00315   else if ( currentItemType() == 3 )
00316   {
00317     changed = addColorRamp();
00318   }
00319   else
00320   {
00321     Q_ASSERT( 0 && "not implemented" );
00322   }
00323 
00324   if ( changed )
00325   {
00326     populateList();
00327     populateTypes();
00328   }
00329 }
00330 
00331 bool QgsStyleV2ManagerDialog::addSymbol()
00332 {
00333   // create new symbol with current type
00334   QgsSymbolV2* symbol;
00335   QString name = tr( "new symbol" );
00336   switch ( currentItemType() )
00337   {
00338     case QgsSymbolV2::Marker:
00339       symbol = new QgsMarkerSymbolV2();
00340       name = tr( "new marker" );
00341       break;
00342     case QgsSymbolV2::Line:
00343       symbol = new QgsLineSymbolV2();
00344       name = tr( "new line" );
00345       break;
00346     case QgsSymbolV2::Fill:
00347       symbol = new QgsFillSymbolV2();
00348       name = tr( "new fill symbol" );
00349       break;
00350     default:
00351       Q_ASSERT( 0 && "unknown symbol type" );
00352       return false;
00353   }
00354 
00355   // get symbol design
00356   // NOTE : Set the parent widget as "this" to notify the Symbol selector
00357   //        that, it is being called by Style Manager, so recursive calling
00358   //        of style manager and symbol selector can be arrested
00359   //        See also: editSymbol()
00360   QgsSymbolV2SelectorDialog dlg( symbol, mStyle, NULL, this );
00361   if ( dlg.exec() == 0 )
00362   {
00363     delete symbol;
00364     return false;
00365   }
00366 
00367   // get unique name
00368   bool nameInvalid = true;
00369 
00370   while ( nameInvalid )
00371   {
00372     bool ok;
00373     name = QInputDialog::getText( this, tr( "Symbol Name" ),
00374                                   tr( "Please enter a name for new symbol:" ),
00375                                   QLineEdit::Normal, name, &ok );
00376     if ( !ok )
00377     {
00378       delete symbol;
00379       return false;
00380     }
00381     // validate name
00382     if ( name.isEmpty() )
00383     {
00384       QMessageBox::warning( this, tr( "Save symbol" ),
00385                             tr( "Cannot save symbol without name. Enter a name." ) );
00386     }
00387     else if ( mStyle->symbolNames().contains( name ) )
00388     {
00389       int res = QMessageBox::warning( this, tr( "Save symbol" ),
00390                                       tr( "Symbol with name '%1' already exists. Overwrite?" )
00391                                       .arg( name ),
00392                                       QMessageBox::Yes | QMessageBox::No );
00393       if ( res == QMessageBox::Yes )
00394       {
00395         nameInvalid = false;
00396       }
00397     }
00398     else
00399     {
00400       // valid name
00401       nameInvalid = false;
00402     }
00403   }
00404 
00405   // add new symbol to style and re-populate the list
00406   mStyle->addSymbol( name, symbol, true );
00407   // TODO groups and tags
00408   mModified = true;
00409   return true;
00410 }
00411 
00412 
00413 QString QgsStyleV2ManagerDialog::addColorRampStatic( QWidget* parent, QgsStyleV2* style, QString rampType )
00414 {
00415   // let the user choose the color ramp type if rampType is not given
00416   bool ok = true;
00417   if ( rampType.isEmpty() )
00418   {
00419     QStringList rampTypes;
00420     rampTypes << tr( "Gradient" ) << tr( "Random" ) << tr( "ColorBrewer" );
00421     rampTypes << tr( "cpt-city" ); // todo, only for rasters?
00422     rampType = QInputDialog::getItem( parent, tr( "Color ramp type" ),
00423                                       tr( "Please select color ramp type:" ), rampTypes, 0, false, &ok );
00424   }
00425   if ( !ok || rampType.isEmpty() )
00426     return QString();
00427 
00428   QString name = tr( "new ramp" );
00429 
00430   QgsVectorColorRampV2 *ramp = NULL;
00431   if ( rampType == tr( "Gradient" ) )
00432   {
00433     QgsVectorGradientColorRampV2* gradRamp = new QgsVectorGradientColorRampV2();
00434     QgsVectorGradientColorRampV2Dialog dlg( gradRamp, parent );
00435     if ( !dlg.exec() )
00436     {
00437       delete gradRamp;
00438       return QString();
00439     }
00440     ramp = gradRamp;
00441     name = tr( "new gradient ramp" );
00442   }
00443   else if ( rampType == tr( "Random" ) )
00444   {
00445     QgsVectorRandomColorRampV2* randRamp = new QgsVectorRandomColorRampV2();
00446     QgsVectorRandomColorRampV2Dialog dlg( randRamp, parent );
00447     if ( !dlg.exec() )
00448     {
00449       delete randRamp;
00450       return QString();
00451     }
00452     ramp = randRamp;
00453     name = tr( "new random ramp" );
00454   }
00455   else if ( rampType == tr( "ColorBrewer" ) )
00456   {
00457     QgsVectorColorBrewerColorRampV2* brewerRamp = new QgsVectorColorBrewerColorRampV2();
00458     QgsVectorColorBrewerColorRampV2Dialog dlg( brewerRamp, parent );
00459     if ( !dlg.exec() )
00460     {
00461       delete brewerRamp;
00462       return QString();
00463     }
00464     ramp = brewerRamp;
00465     name = brewerRamp->schemeName() + QString::number( brewerRamp->colors() );
00466   }
00467   else if ( rampType == tr( "cpt-city" ) )
00468   {
00469     QgsCptCityColorRampV2* cptCityRamp = new QgsCptCityColorRampV2( "", "" );
00470     QgsCptCityColorRampV2Dialog dlg( cptCityRamp, parent );
00471     if ( !dlg.exec() )
00472     {
00473       delete cptCityRamp;
00474       return QString();
00475     }
00476     // name = dlg.selectedName();
00477     name = QFileInfo( cptCityRamp->schemeName() ).baseName() + cptCityRamp->variantName();
00478     if ( dlg.saveAsGradientRamp() )
00479     {
00480       ramp = cptCityRamp->cloneGradientRamp();
00481       delete cptCityRamp;
00482     }
00483     else
00484     {
00485       ramp = cptCityRamp;
00486     }
00487   }
00488   else
00489   {
00490     // Q_ASSERT( 0 && "invalid ramp type" );
00491     // bailing out is rather harsh!
00492     QgsDebugMsg( "invalid ramp type " + rampType );
00493     return QString();
00494   }
00495 
00496   // get unique name
00497   bool nameInvalid = true;
00498 
00499   while ( nameInvalid )
00500   {
00501     bool ok;
00502     name = QInputDialog::getText( parent, tr( "Color Ramp Name" ),
00503                                   tr( "Please enter a name for new color ramp:" ),
00504                                   QLineEdit::Normal, name, &ok );
00505     if ( !ok )
00506     {
00507       delete ramp;
00508       return QString();
00509     }
00510     // validate name
00511     if ( name.isEmpty() )
00512     {
00513       QMessageBox::warning( parent, tr( "Save Color Ramp" ),
00514                             tr( "Cannot save color ramp without name. Enter a name." ) );
00515     }
00516     else if ( style->colorRampNames().contains( name ) )
00517     {
00518       int res = QMessageBox::warning( parent, tr( "Save color ramp" ),
00519                                       tr( "Color ramp with name '%1' already exists. Overwrite?" )
00520                                       .arg( name ),
00521                                       QMessageBox::Yes | QMessageBox::No );
00522       if ( res == QMessageBox::Yes )
00523       {
00524         nameInvalid = false;
00525       }
00526     }
00527     else
00528     {
00529       // valid name
00530       nameInvalid = false;
00531     }
00532   }
00533 
00534   // add new symbol to style and re-populate the list
00535   style->addColorRamp( name, ramp, true );
00536   // TODO groups and tags, using saveColorRamp
00537   return name;
00538 }
00539 
00540 
00541 bool QgsStyleV2ManagerDialog::addColorRamp()
00542 {
00543   return addColorRamp( 0 );
00544 }
00545 
00546 bool QgsStyleV2ManagerDialog::addColorRamp( QAction* action )
00547 {
00548   // pass the action text, which is the color ramp type
00549   QString rampName = addColorRampStatic( this , mStyle,
00550                                          action ? action->text() : QString() );
00551   if ( !rampName.isEmpty() )
00552   {
00553     mModified = true;
00554     populateList();
00555     return true;
00556   }
00557 
00558   return false;
00559 }
00560 
00561 void QgsStyleV2ManagerDialog::editItem()
00562 {
00563   bool changed = false;
00564   if ( currentItemType() < 3 )
00565   {
00566     changed = editSymbol();
00567   }
00568   else if ( currentItemType() == 3 )
00569   {
00570     changed = editColorRamp();
00571   }
00572   else
00573   {
00574     Q_ASSERT( 0 && "not implemented" );
00575   }
00576 
00577   if ( changed )
00578     populateList();
00579 }
00580 
00581 bool QgsStyleV2ManagerDialog::editSymbol()
00582 {
00583   QString symbolName = currentItemName();
00584   if ( symbolName.isEmpty() )
00585     return false;
00586 
00587   QgsSymbolV2* symbol = mStyle->symbol( symbolName );
00588 
00589   // let the user edit the symbol and update list when done
00590   QgsSymbolV2SelectorDialog dlg( symbol, mStyle, NULL , this );
00591   if ( dlg.exec() == 0 )
00592   {
00593     delete symbol;
00594     return false;
00595   }
00596 
00597   // by adding symbol to style with the same name the old effectively gets overwritten
00598   mStyle->addSymbol( symbolName, symbol, true );
00599   mModified = true;
00600   return true;
00601 }
00602 
00603 bool QgsStyleV2ManagerDialog::editColorRamp()
00604 {
00605   QString name = currentItemName();
00606   if ( name.isEmpty() )
00607     return false;
00608 
00609   QgsVectorColorRampV2* ramp = mStyle->colorRamp( name );
00610 
00611   if ( ramp->type() == "gradient" )
00612   {
00613     QgsVectorGradientColorRampV2* gradRamp = static_cast<QgsVectorGradientColorRampV2*>( ramp );
00614     QgsVectorGradientColorRampV2Dialog dlg( gradRamp, this );
00615     if ( !dlg.exec() )
00616     {
00617       delete ramp;
00618       return false;
00619     }
00620   }
00621   else if ( ramp->type() == "random" )
00622   {
00623     QgsVectorRandomColorRampV2* randRamp = static_cast<QgsVectorRandomColorRampV2*>( ramp );
00624     QgsVectorRandomColorRampV2Dialog dlg( randRamp, this );
00625     if ( !dlg.exec() )
00626     {
00627       delete ramp;
00628       return false;
00629     }
00630   }
00631   else if ( ramp->type() == "colorbrewer" )
00632   {
00633     QgsVectorColorBrewerColorRampV2* brewerRamp = static_cast<QgsVectorColorBrewerColorRampV2*>( ramp );
00634     QgsVectorColorBrewerColorRampV2Dialog dlg( brewerRamp, this );
00635     if ( !dlg.exec() )
00636     {
00637       delete ramp;
00638       return false;
00639     }
00640   }
00641   else if ( ramp->type() == "cpt-city" )
00642   {
00643     QgsCptCityColorRampV2* cptCityRamp = static_cast<QgsCptCityColorRampV2*>( ramp );
00644     QgsCptCityColorRampV2Dialog dlg( cptCityRamp, this );
00645     if ( !dlg.exec() )
00646     {
00647       delete ramp;
00648       return false;
00649     }
00650     if ( dlg.saveAsGradientRamp() )
00651     {
00652       ramp = cptCityRamp->cloneGradientRamp();
00653       delete cptCityRamp;
00654     }
00655   }
00656   else
00657   {
00658     Q_ASSERT( 0 && "invalid ramp type" );
00659   }
00660 
00661   mStyle->addColorRamp( name, ramp, true );
00662   mModified = true;
00663   return true;
00664 }
00665 
00666 
00667 void QgsStyleV2ManagerDialog::removeItem()
00668 {
00669   bool changed = false;
00670   if ( currentItemType() < 3 )
00671   {
00672     changed = removeSymbol();
00673   }
00674   else if ( currentItemType() == 3 )
00675   {
00676     changed = removeColorRamp();
00677   }
00678   else
00679   {
00680     Q_ASSERT( 0 && "not implemented" );
00681   }
00682 
00683   if ( changed )
00684   {
00685     populateList();
00686     populateTypes();
00687   }
00688 }
00689 
00690 bool QgsStyleV2ManagerDialog::removeSymbol()
00691 {
00692   QModelIndexList indexes = listItems->selectionModel()->selectedIndexes();
00693   foreach ( QModelIndex index, indexes )
00694   {
00695     QString symbolName = index.data().toString();
00696     // delete from style and update list
00697     if ( !symbolName.isEmpty() )
00698       mStyle->removeSymbol( symbolName );
00699   }
00700   mModified = true;
00701   return true;
00702 }
00703 
00704 bool QgsStyleV2ManagerDialog::removeColorRamp()
00705 {
00706   QString rampName = currentItemName();
00707   if ( rampName.isEmpty() )
00708     return false;
00709 
00710   mStyle->removeColorRamp( rampName );
00711   mModified = true;
00712   return true;
00713 }
00714 
00715 void QgsStyleV2ManagerDialog::itemChanged( QStandardItem* item )
00716 {
00717   // an item has been edited
00718   QString oldName = item->data().toString();
00719 
00720   bool changed = false;
00721   if ( currentItemType() < 3 )
00722   {
00723     changed = mStyle->renameSymbol( oldName, item->text() );
00724   }
00725   else if ( currentItemType() == 3 )
00726   {
00727     changed = mStyle->renameColorRamp( oldName, item->text() );
00728   }
00729 
00730   if ( changed )
00731   {
00732     populateList();
00733     mModified = true;
00734   }
00735 
00736 }
00737 
00738 void QgsStyleV2ManagerDialog::exportItems()
00739 {
00740   QgsStyleV2ExportImportDialog dlg( mStyle, this, QgsStyleV2ExportImportDialog::Export );
00741   dlg.exec();
00742 }
00743 
00744 void QgsStyleV2ManagerDialog::importItems()
00745 {
00746   QgsStyleV2ExportImportDialog dlg( mStyle, this, QgsStyleV2ExportImportDialog::Import );
00747   dlg.exec();
00748   populateList();
00749   populateGroups();
00750 }
00751 
00752 void QgsStyleV2ManagerDialog::setBold( QStandardItem* item )
00753 {
00754   QFont font = item->font();
00755   font.setBold( true );
00756   item->setFont( font );
00757 }
00758 
00759 void QgsStyleV2ManagerDialog::populateGroups()
00760 {
00761   QStandardItemModel *model = qobject_cast<QStandardItemModel*>( groupTree->model() );
00762   model->clear();
00763 
00764   QStandardItem *allSymbols = new QStandardItem( "All Symbols" );
00765   allSymbols->setData( "all" );
00766   allSymbols->setEditable( false );
00767   setBold( allSymbols );
00768   model->appendRow( allSymbols );
00769 
00770   QStandardItem *group = new QStandardItem( "" ); //require empty name to get first order groups
00771   group->setData( "groups" );
00772   group->setEditable( false );
00773   buildGroupTree( group );
00774   group->setText( "Groups" );//set title later
00775   QStandardItem *ungrouped = new QStandardItem( "Ungrouped" );
00776   ungrouped->setData( 0 );
00777   setBold( ungrouped );
00778   setBold( group );
00779   group->appendRow( ungrouped );
00780   model->appendRow( group );
00781 
00782   QStandardItem *tag = new QStandardItem( "Smart Groups" );
00783   tag->setData( "smartgroups" );
00784   tag->setEditable( false );
00785   setBold( tag );
00786   QgsSymbolGroupMap sgMap = mStyle->smartgroupsListMap();
00787   QgsSymbolGroupMap::const_iterator i = sgMap.constBegin();
00788   while ( i != sgMap.constEnd() )
00789   {
00790     QStandardItem *item = new QStandardItem( i.value() );
00791     item->setData( i.key() );
00792     tag->appendRow( item );
00793     ++i;
00794   }
00795   model->appendRow( tag );
00796 
00797   // expand things in the grouo tree
00798   int rows = model->rowCount( model->indexFromItem( model->invisibleRootItem() ) );
00799   for ( int i = 0; i < rows; i++ )
00800   {
00801     groupTree->setExpanded( model->indexFromItem( model->item( i ) ), true );
00802   }
00803 }
00804 
00805 void QgsStyleV2ManagerDialog::buildGroupTree( QStandardItem* &parent )
00806 {
00807   QgsSymbolGroupMap groups = mStyle->childGroupNames( parent->text() );
00808   QgsSymbolGroupMap::const_iterator i = groups.constBegin();
00809   while ( i != groups.constEnd() )
00810   {
00811     QStandardItem *item = new QStandardItem( i.value() );
00812     item->setData( i.key() );
00813     parent->appendRow( item );
00814     buildGroupTree( item );
00815     ++i;
00816   }
00817 }
00818 
00819 void QgsStyleV2ManagerDialog::groupChanged( const QModelIndex& index )
00820 {
00821   QStringList symbolNames;
00822   QStringList groupSymbols;
00823 
00824   QgsStyleV2::StyleEntity type = currentItemType() < 3 ? QgsStyleV2::SymbolEntity : QgsStyleV2::ColorrampEntity;
00825   if ( currentItemType() > 3 )
00826   {
00827     QgsDebugMsg( "Entity not implemented" );
00828     return;
00829   }
00830 
00831   QString category = index.data( Qt::UserRole + 1 ).toString();
00832   if ( category == "all" || category == "groups" || category == "smartgroups" )
00833   {
00834     enableGroupInputs( false );
00835     if ( category == "groups" || category == "smartgroups" )
00836     {
00837       btnAddGroup->setEnabled( true );
00838     }
00839     symbolNames = currentItemType() < 3 ? mStyle->symbolNames() : mStyle->colorRampNames();
00840   }
00841   else
00842   {
00843     //determine groups and tags
00844     if ( index.parent().data( Qt::UserRole + 1 ) == "smartgroups" )
00845     {
00846       btnAddGroup->setEnabled( false );
00847       btnRemoveGroup->setEnabled( true );
00848       btnManageGroups->setEnabled( true );
00849       int groupId = index.data( Qt::UserRole + 1 ).toInt();
00850       symbolNames = mStyle->symbolsOfSmartgroup( type, groupId );
00851     }
00852     else // then it must be a group
00853     {
00854       if (( !index.data( Qt::UserRole + 1 ).toInt() && ( index.data() == "Ungrouped" ) ) || mGrouppingMode )
00855         enableGroupInputs( false );
00856       else
00857         enableGroupInputs( true );
00858       int groupId = index.data( Qt::UserRole + 1 ).toInt();
00859       symbolNames = mStyle->symbolsOfGroup( type, groupId );
00860       if ( mGrouppingMode && groupId )
00861       {
00862         groupSymbols = symbolNames;
00863         symbolNames += mStyle->symbolsOfGroup( type, 0 );
00864       }
00865     }
00866   }
00867 
00868   if ( currentItemType() < 3 )
00869   {
00870     populateSymbols( symbolNames, mGrouppingMode );
00871   }
00872   else if ( currentItemType() == 3 )
00873   {
00874     populateColorRamps( symbolNames, mGrouppingMode );
00875   }
00876   if ( mGrouppingMode )
00877     setSymbolsChecked( groupSymbols );
00878 }
00879 
00880 void QgsStyleV2ManagerDialog::addGroup()
00881 {
00882   QStandardItemModel *model = qobject_cast<QStandardItemModel*>( groupTree->model() );
00883   QModelIndex parentIndex = groupTree->currentIndex();
00884 
00885   // Violation 1: Creating sub-groups of system defined groups
00886   QString parentData = parentIndex.data( Qt::UserRole + 1 ).toString();
00887   if ( parentData == "all" || ( parentIndex.data() == "Ungrouped" && parentData == "0" ) )
00888   {
00889     int err = QMessageBox::critical( this, tr( "Invalid Selection" ),
00890                                      tr( "The parent group you have selected is not user editable.\n"
00891                                          "Kindly select a user defined group." ) );
00892     if ( err )
00893       return;
00894   }
00895 
00896   // Violation 2: Creating a nested tag
00897   if ( parentIndex.parent().data( Qt::UserRole + 1 ).toString() == "smartgroups" )
00898   {
00899     int err = QMessageBox::critical( this, tr( "Operation Not Allowed" ),
00900                                      tr( "Creation of nested smart groups are not allowed\n"
00901                                          "Select the 'Smart Group' to create a new group." ) );
00902     if ( err )
00903       return;
00904   }
00905 
00906   QString itemName;
00907   QVariant itemData;
00908   bool isGroup = true;
00909 
00910   // create a smart group if that is selected
00911   if ( parentIndex.data( Qt::UserRole + 1 ).toString() == "smartgroups" )
00912   {
00913     QgsSmartGroupEditorDialog dlg( mStyle, this );
00914     if ( dlg.exec() == QDialog::Rejected )
00915       return;
00916     int id = mStyle->addSmartgroup( dlg.smartgroupName(), dlg.conditionOperator(), dlg.conditionMap() );
00917     if ( !id )
00918       return;
00919     itemData = QVariant( id );
00920     itemName = dlg.smartgroupName();
00921     isGroup = false;
00922   }
00923   else
00924   {
00925     itemName = QString( "New Group" );
00926     itemData = QVariant( "newgroup" );
00927   }
00928 
00929   // Else create a simple child-group to the selected
00930   QStandardItem *parentItem = model->itemFromIndex( parentIndex );
00931   QStandardItem *childItem = new QStandardItem( itemName );
00932   childItem->setData( itemData );
00933   parentItem->appendRow( childItem );
00934 
00935   groupTree->setCurrentIndex( childItem->index() );
00936   if ( isGroup )
00937   {
00938     groupTree->edit( childItem->index() );
00939   }
00940 }
00941 
00942 void QgsStyleV2ManagerDialog::removeGroup()
00943 {
00944   QStandardItemModel *model = qobject_cast<QStandardItemModel*>( groupTree->model() );
00945   QModelIndex index = groupTree->currentIndex();
00946 
00947   // Violation: removing system groups
00948   QString data = index.data( Qt::UserRole + 1 ).toString();
00949   if ( data == "all" || data == "groups" || data == "smartgroups" || index.data() == "Ungrouped" )
00950   {
00951     int err = QMessageBox::critical( this, tr( "Invalid selection" ),
00952                                      tr( "Cannot delete system defined categories.\n"
00953                                          "Kindly select a group or smart group you might want to delete." ) );
00954     if ( err )
00955       return;
00956   }
00957 
00958   QStandardItem *parentItem = model->itemFromIndex( index.parent() );
00959   if ( parentItem->data( Qt::UserRole + 1 ).toString() == "smartgroups" )
00960   {
00961     mStyle->remove( QgsStyleV2::SmartgroupEntity, index.data( Qt::UserRole + 1 ).toInt() );
00962   }
00963   else
00964   {
00965     mStyle->remove( QgsStyleV2::GroupEntity, index.data( Qt::UserRole + 1 ).toInt() );
00966     QStandardItem *item = model->itemFromIndex( index );
00967     if ( item->hasChildren() )
00968     {
00969       QStandardItem *parent = item->parent();
00970       for ( int i = 0; i < item->rowCount(); i++ )
00971       {
00972         parent->appendRow( item->takeChild( i ) );
00973       }
00974     }
00975   }
00976   parentItem->removeRow( index.row() );
00977 }
00978 
00979 void QgsStyleV2ManagerDialog::groupRenamed( QStandardItem * item )
00980 {
00981   QString data = item->data( Qt::UserRole + 1 ).toString();
00982   QgsDebugMsg( "Symbol group edited: data=" + data + " text=" + item->text() );
00983   if ( data == "newgroup" )
00984   {
00985     int id;
00986     if ( item->parent()->data( Qt::UserRole + 1 ).toString() == "groups" )
00987     {
00988       id = mStyle->addGroup( item->text() );
00989     }
00990     else
00991     {
00992       int parentid = item->parent()->data( Qt::UserRole + 1 ).toInt();
00993       id = mStyle->addGroup( item->text(), parentid );
00994     }
00995     if ( !id )
00996     {
00997       QMessageBox::critical( this, tr( "Error!" ),
00998                              tr( "New group could not be created.\n"
00999                                  "There was a problem with your symbol database." ) );
01000       item->parent()->removeRow( item->row() );
01001       return;
01002     }
01003     else
01004     {
01005       item->setData( id );
01006     }
01007   }
01008   else
01009   {
01010     int id = item->data( Qt::UserRole + 1 ).toInt();
01011     QString name = item->text();
01012     if ( item->parent()->data( Qt::UserRole + 1 ) == "smartgroups" )
01013     {
01014       mStyle->rename( QgsStyleV2::SmartgroupEntity, id, name );
01015     }
01016     else
01017     {
01018       mStyle->rename( QgsStyleV2::GroupEntity, id, name );
01019     }
01020   }
01021 }
01022 
01023 void QgsStyleV2ManagerDialog::groupSymbolsAction()
01024 {
01025 
01026   QStandardItemModel *treeModel = qobject_cast<QStandardItemModel*>( groupTree->model() );
01027   QStandardItemModel *model = qobject_cast<QStandardItemModel*>( listItems->model() );
01028   QAction *senderAction = qobject_cast<QAction*>( sender() );
01029 
01030   if ( mGrouppingMode )
01031   {
01032     mGrouppingMode = false;
01033     senderAction->setText( "Group Symbols" );
01034     // disconnect slot which handles regrouping
01035     disconnect( model, SIGNAL( itemChanged( QStandardItem* ) ),
01036                 this, SLOT( regrouped( QStandardItem* ) ) );
01037 
01038     // disabel all items except groups in groupTree
01039     enableItemsForGroupingMode( true );
01040     groupChanged( groupTree->currentIndex() );
01041 
01042     // Finally: Reconnect all Symbol editing functionalities
01043     connect( treeModel, SIGNAL( itemChanged( QStandardItem* ) ),
01044              this, SLOT( groupRenamed( QStandardItem* ) ) );
01045     connect( model, SIGNAL( itemChanged( QStandardItem* ) ),
01046              this, SLOT( itemChanged( QStandardItem* ) ) );
01047     // Reset the selection mode
01048     listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
01049   }
01050   else
01051   {
01052     bool validGroup = false;
01053     // determine whether it is a valid group
01054     QModelIndex present = groupTree->currentIndex();
01055     while ( present.parent().isValid() )
01056     {
01057       if ( present.parent().data() == "Groups" )
01058       {
01059         validGroup = true;
01060         break;
01061       }
01062       else
01063         present = present.parent();
01064     }
01065     if ( !validGroup )
01066       return;
01067 
01068     mGrouppingMode = true;
01069     // Change the text menu
01070     senderAction->setText( "Finish Grouping" );
01071     // Remove all Symbol editing functionalities
01072     disconnect( treeModel, SIGNAL( itemChanged( QStandardItem* ) ),
01073                 this, SLOT( groupRenamed( QStandardItem* ) ) );
01074     disconnect( model, SIGNAL( itemChanged( QStandardItem* ) ),
01075                 this, SLOT( itemChanged( QStandardItem* ) ) );
01076 
01077     // disabel all items except groups in groupTree
01078     enableItemsForGroupingMode( false );
01079     groupChanged( groupTree->currentIndex() );
01080     btnManageGroups->setEnabled( true );
01081 
01082 
01083     // Connect to slot which handles regrouping
01084     connect( model, SIGNAL( itemChanged( QStandardItem* ) ),
01085              this, SLOT( regrouped( QStandardItem* ) ) );
01086 
01087     // No selection should be possible
01088     listItems->setSelectionMode( QAbstractItemView::NoSelection );
01089   }
01090 }
01091 
01092 void QgsStyleV2ManagerDialog::regrouped( QStandardItem *item )
01093 {
01094   QgsStyleV2::StyleEntity type = ( currentItemType() < 3 ) ? QgsStyleV2::SymbolEntity : QgsStyleV2::ColorrampEntity;
01095   if ( currentItemType() > 3 )
01096   {
01097     QgsDebugMsg( "Unknown style entity" );
01098     return;
01099   }
01100   int groupid = groupTree->currentIndex().data( Qt::UserRole + 1 ).toInt();
01101   QString symbolName = item->text();
01102   bool regrouped;
01103   if ( item->checkState() == Qt::Checked )
01104     regrouped = mStyle->group( type, symbolName, groupid );
01105   else
01106     regrouped = mStyle->group( type, symbolName, 0 );
01107   if ( !regrouped )
01108   {
01109     int er = QMessageBox::critical( this, tr( "Database Error" ),
01110                                     tr( "There was a problem with the Symbols database while regrouping." ) );
01111     // call the slot again to get back to normal
01112     if ( er )
01113       groupSymbolsAction();
01114   }
01115 }
01116 
01117 void QgsStyleV2ManagerDialog::setSymbolsChecked( QStringList symbols )
01118 {
01119   QStandardItemModel *model = qobject_cast<QStandardItemModel*>( listItems->model() );
01120   foreach ( const QString symbol, symbols )
01121   {
01122     QList<QStandardItem*> items = model->findItems( symbol );
01123     foreach ( QStandardItem* item, items )
01124       item->setCheckState( Qt::Checked );
01125   }
01126 }
01127 
01128 void QgsStyleV2ManagerDialog::filterSymbols( QString qword )
01129 {
01130   QStringList symbols = mStyle->findSymbols( qword );
01131   populateSymbols( symbols );
01132 }
01133 
01134 void QgsStyleV2ManagerDialog::tagsChanged()
01135 {
01136   QModelIndexList indexes =  listItems->selectionModel()->selection().indexes();
01137   QStringList addtags;
01138   QStringList removetags;
01139 
01140   QStringList oldtags = mTagList;
01141   QStringList newtags = tagsLineEdit->text().split( ",", QString::SkipEmptyParts );
01142 
01143   QgsStyleV2::StyleEntity type;
01144   if ( currentItemType() < 3 )
01145   {
01146     type = QgsStyleV2::SymbolEntity;
01147   }
01148   else if ( currentItemType() == 3 )
01149   {
01150     type = QgsStyleV2::ColorrampEntity;
01151   }
01152   else
01153   {
01154     QgsDebugMsg( "Unknown Style Entity!" );
01155     return;
01156   }
01157   // compare old with new to find removed tags
01158   foreach ( const QString &tag, oldtags )
01159   {
01160     if ( !newtags.contains( tag ) )
01161       removetags.append( tag );
01162   }
01163   if ( removetags.size() > 0 )
01164   {
01165     foreach ( QModelIndex index, indexes )
01166     {
01167       mStyle->detagSymbol( type, index.data().toString(), removetags );
01168     }
01169   }
01170   // compare new with old to find added tags
01171   foreach ( const QString &tag, newtags )
01172   {
01173     if ( !oldtags.contains( tag ) )
01174       addtags.append( tag );
01175   }
01176   if ( addtags.size() > 0 )
01177   {
01178     foreach ( QModelIndex index, indexes )
01179     {
01180       mStyle->tagSymbol( type, index.data().toString(), addtags );
01181     }
01182   }
01183 }
01184 
01185 void QgsStyleV2ManagerDialog::symbolSelected( const QModelIndex& index )
01186 {
01187   // Populate the tags for the symbol
01188   tagsLineEdit->clear();
01189   QStandardItem *item = static_cast<QStandardItemModel*>( listItems->model() )->itemFromIndex( index );
01190   QgsStyleV2::StyleEntity type = ( currentItemType() < 3 ) ? QgsStyleV2::SymbolEntity : QgsStyleV2::ColorrampEntity;
01191   mTagList = mStyle->tagsOfSymbol( type, item->data().toString() );
01192   tagsLineEdit->setText( mTagList.join( "," ) );
01193 }
01194 
01195 void QgsStyleV2ManagerDialog::enableSymbolInputs( bool enable )
01196 {
01197   groupTree->setEnabled( enable );
01198   btnAddGroup->setEnabled( enable );
01199   btnRemoveGroup->setEnabled( enable );
01200   btnManageGroups->setEnabled( enable );
01201   searchBox->setEnabled( enable );
01202   tagsLineEdit->setEnabled( enable );
01203 }
01204 
01205 void QgsStyleV2ManagerDialog::enableGroupInputs( bool enable )
01206 {
01207   btnAddGroup->setEnabled( enable );
01208   btnRemoveGroup->setEnabled( enable );
01209   btnManageGroups->setEnabled( enable );
01210 }
01211 
01212 void QgsStyleV2ManagerDialog::enableItemsForGroupingMode( bool enable )
01213 {
01214   QStandardItemModel *treeModel = qobject_cast<QStandardItemModel*>( groupTree->model() );
01215   for ( int i = 0; i < treeModel->rowCount(); i++ )
01216   {
01217     if ( treeModel->item( i )->data() != "groups" )
01218     {
01219       treeModel->item( i )->setEnabled( enable );
01220     }
01221     if ( treeModel->item( i )->data() == "groups" )
01222     {
01223       treeModel->item( i )->setEnabled( enable );
01224       for ( int k = 0; k < treeModel->item( i )->rowCount(); k++ )
01225       {
01226         if ( !treeModel->item( i )->child( k )->data().toInt() )
01227           treeModel->item( i )->child( k )->setEnabled( enable );
01228       }
01229     }
01230     if ( treeModel->item( i )->data() == "smartgroups" )
01231     {
01232       for ( int j = 0; j < treeModel->item( i )->rowCount(); j++ )
01233       {
01234         treeModel->item( i )->child( j )->setEnabled( enable );
01235       }
01236     }
01237   }
01238 
01239   // The buttons
01240   // NOTE: if you ever change the layout name in the .ui file edit here too
01241   for ( int i = 0; i < symbolBtnsLayout->count(); i++ )
01242   {
01243     symbolBtnsLayout->itemAt( i )->widget()->setEnabled( enable );
01244   }
01245 
01246 }
01247 
01248 void QgsStyleV2ManagerDialog::grouptreeContextMenu( const QPoint& point )
01249 {
01250   QPoint globalPos = groupTree->viewport()->mapToGlobal( point );
01251 
01252   QModelIndex index = groupTree->indexAt( point );
01253   QgsDebugMsg( "Now you clicked : " + index.data().toString() );
01254 
01255   QMenu groupMenu;
01256 
01257   if ( index.parent().isValid() && ( index.data().toString() != "Ungrouped" ) )
01258   {
01259     if ( index.parent().data( Qt::UserRole + 1 ).toString() == "smartgroups" )
01260     {
01261       groupMenu.addAction( "Edit Group" );
01262     }
01263     else
01264     {
01265       groupMenu.addAction( "Add Group" );
01266     }
01267     groupMenu.addAction( "Remove Group" );
01268   }
01269   else if ( index.data( Qt::UserRole + 1 ) == "groups" || index.data( Qt::UserRole + 1 ) == "smartgroups" )
01270   {
01271     groupMenu.addAction( "Add Group" );
01272   }
01273 
01274 
01275   QAction* selectedItem = groupMenu.exec( globalPos );
01276 
01277   if ( selectedItem )
01278   {
01279     if ( selectedItem->text() == "Add Group" )
01280       addGroup();
01281     else if ( selectedItem->text() == "Remove Group" )
01282       removeGroup();
01283     else if ( selectedItem->text() == "Edit Group" )
01284       editSmartgroupAction();
01285   }
01286 }
01287 
01288 void QgsStyleV2ManagerDialog::listitemsContextMenu( const QPoint& point )
01289 {
01290   QPoint globalPos = listItems->viewport()->mapToGlobal( point );
01291 
01292   QMenu *groupMenu = new QMenu( this );
01293   QMenu *groupList = new QMenu( this );
01294   groupList->setTitle( "Apply Group" );
01295 
01296   QStringList groups = mStyle->groupNames();
01297   foreach ( QString group, groups )
01298   {
01299     groupList->addAction( group );
01300   }
01301   groupMenu->addMenu( groupList );
01302   groupMenu->addAction( "Un-group" );
01303 
01304   QAction* selectedItem = groupMenu->exec( globalPos );
01305 
01306   if ( selectedItem )
01307   {
01308     QgsStyleV2::StyleEntity type = ( currentItemType() < 3 ) ? QgsStyleV2::SymbolEntity : QgsStyleV2::ColorrampEntity;
01309     if ( currentItemType() > 3 )
01310     {
01311       QgsDebugMsg( "unknow entity type" );
01312       return;
01313     }
01314     int groupId = 0;
01315     if ( selectedItem->text() != "Un-group" )
01316     {
01317       groupId = mStyle->groupId( selectedItem->text() );
01318     }
01319     QModelIndexList indexes =  listItems->selectionModel()->selectedIndexes();
01320     foreach ( QModelIndex index, indexes )
01321     {
01322       mStyle->group( type, index.data().toString(), groupId );
01323     }
01324     populateList();
01325 
01326     QgsDebugMsg( "Selected Action: " + selectedItem->text() );
01327   }
01328 }
01329 
01330 void QgsStyleV2ManagerDialog::editSmartgroupAction()
01331 {
01332   QStandardItemModel *treeModel = qobject_cast<QStandardItemModel*>( groupTree->model() );
01333 
01334   // determine whether it is a valid group
01335   QModelIndex present = groupTree->currentIndex();
01336   if ( present.parent().data( Qt::UserRole + 1 ) != "smartgroups" )
01337   {
01338     QMessageBox::critical( this, tr( "Invalid Selection" ),
01339                            tr( "You have not selected a Smart Group. Kindly select a Smart Group to edit." ) );
01340     return;
01341   }
01342   QStandardItem* item = treeModel->itemFromIndex( present );
01343 
01344   QgsSmartGroupEditorDialog dlg( mStyle, this );
01345   QgsSmartConditionMap map = mStyle->smartgroup( present.data( Qt::UserRole + 1 ).toInt() );
01346   dlg.setSmartgroupName( item->text() );
01347   dlg.setOperator( mStyle->smartgroupOperator( item->data().toInt() ) );
01348   dlg.setConditionMap( map );
01349 
01350   if ( dlg.exec() == QDialog::Rejected )
01351     return;
01352 
01353   mStyle->remove( QgsStyleV2::SmartgroupEntity, item->data().toInt() );
01354   int id = mStyle->addSmartgroup( dlg.smartgroupName(), dlg.conditionOperator(), dlg.conditionMap() );
01355   if ( !id )
01356   {
01357     QMessageBox::critical( this, tr( "Database Error!" ),
01358                            tr( "There was some error while editing the smart group." ) );
01359     return;
01360   }
01361   item->setText( dlg.smartgroupName() );
01362   item->setData( id );
01363 
01364   groupChanged( present );
01365 }
01366 
01367 bool QgsStyleV2ManagerDialog::eventFilter( QObject *obj, QEvent *event )
01368 {
01369 
01370   if (( obj == tagsLineEdit ) && ( event->type() == QEvent::FocusOut ) )
01371   {
01372     tagsChanged();
01373     return true;
01374   }
01375   return false;
01376 }
01377 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines