QGIS API Documentation  2.12.0-Lyon
qgsstylev2managerdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsstylev2managerdialog.cpp
3  ---------------------
4  begin : November 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 #include "qgsstylev2.h"
19 #include "qgssymbolv2.h"
20 #include "qgssymbollayerv2utils.h"
21 #include "qgsvectorcolorrampv2.h"
22 
30 
31 #include <QFile>
32 #include <QFileDialog>
33 #include <QInputDialog>
34 #include <QMessageBox>
35 #include <QSettings>
36 #include <QStandardItemModel>
37 #include <QAction>
38 #include <QMenu>
39 
40 #include "qgsapplication.h"
41 #include "qgslogger.h"
42 
44  : QDialog( parent ), mStyle( style ), mModified( false )
45 {
46  setupUi( this );
47 #ifdef Q_OS_MAC
48  setWindowModality( Qt::WindowModal );
49 #endif
50 
51  QSettings settings;
52  restoreGeometry( settings.value( "/Windows/StyleV2Manager/geometry" ).toByteArray() );
53  mSplitter->setSizes( QList<int>() << 170 << 540 );
54  mSplitter->restoreState( settings.value( "/Windows/StyleV2Manager/splitter" ).toByteArray() );
55 
56  tabItemType->setDocumentMode( true );
57  searchBox->setPlaceholderText( tr( "Type here to filter symbols..." ) );
58 
59  connect( this, SIGNAL( finished( int ) ), this, SLOT( onFinished() ) );
60 
61  connect( listItems, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( editItem() ) );
62 
63  connect( btnAddItem, SIGNAL( clicked() ), this, SLOT( addItem() ) );
64  connect( btnEditItem, SIGNAL( clicked() ), this, SLOT( editItem() ) );
65  connect( btnRemoveItem, SIGNAL( clicked() ), this, SLOT( removeItem() ) );
66 
67  QMenu *shareMenu = new QMenu( tr( "Share Menu" ), this );
68  QAction *exportAsPNGAction = shareMenu->addAction( tr( "Export as PNG" ) );
69  QAction *exportAsSVGAction = shareMenu->addAction( tr( "Export as SVG" ) );
70  QAction *exportAction = shareMenu->addAction( tr( "Export" ) );
71  QAction *importAction = shareMenu->addAction( tr( "Import" ) );
72  exportAsPNGAction->setIcon( QIcon( QgsApplication::iconPath( "mActionSharingExport.svg" ) ) );
73  exportAsSVGAction->setIcon( QIcon( QgsApplication::iconPath( "mActionSharingExport.svg" ) ) );
74  exportAction->setIcon( QIcon( QgsApplication::iconPath( "mActionSharingExport.svg" ) ) );
75  importAction->setIcon( QIcon( QgsApplication::iconPath( "mActionSharingImport.svg" ) ) );
76  connect( exportAsPNGAction, SIGNAL( triggered() ), this, SLOT( exportItemsPNG() ) );
77  connect( exportAsSVGAction, SIGNAL( triggered() ), this, SLOT( exportItemsSVG() ) );
78  connect( exportAction, SIGNAL( triggered() ), this, SLOT( exportItems() ) );
79  connect( importAction, SIGNAL( triggered() ), this, SLOT( importItems() ) );
80  btnShare->setMenu( shareMenu );
81 
82  // Set editing mode off by default
83  mGrouppingMode = false;
84 
85  QStandardItemModel* model = new QStandardItemModel( listItems );
86  listItems->setModel( model );
87  listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
88 
89  connect( model, SIGNAL( itemChanged( QStandardItem* ) ), this, SLOT( itemChanged( QStandardItem* ) ) );
90  connect( listItems->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
91  this, SLOT( symbolSelected( const QModelIndex& ) ) );
92 
93  populateTypes();
94 
95  QStandardItemModel* groupModel = new QStandardItemModel( groupTree );
96  groupTree->setModel( groupModel );
97  groupTree->setHeaderHidden( true );
99  connect( groupTree->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
100  this, SLOT( groupChanged( const QModelIndex& ) ) );
101  connect( groupModel, SIGNAL( itemChanged( QStandardItem* ) ),
102  this, SLOT( groupRenamed( QStandardItem* ) ) );
103 
104  QMenu *groupMenu = new QMenu( tr( "Group Actions" ), this );
105  QAction *groupSymbols = groupMenu->addAction( tr( "Group Symbols" ) );
106  QAction *editSmartgroup = groupMenu->addAction( tr( "Edit Smart Group" ) );
107  btnManageGroups->setMenu( groupMenu );
108  connect( groupSymbols, SIGNAL( triggered() ), this, SLOT( groupSymbolsAction() ) );
109  connect( editSmartgroup, SIGNAL( triggered() ), this, SLOT( editSmartgroupAction() ) );
110 
111  connect( btnAddGroup, SIGNAL( clicked() ), this, SLOT( addGroup() ) );
112  connect( btnRemoveGroup, SIGNAL( clicked() ), this, SLOT( removeGroup() ) );
113 
115 
116  connect( searchBox, SIGNAL( textChanged( QString ) ), this, SLOT( filterSymbols( QString ) ) );
117  tagsLineEdit->installEventFilter( this );
118 
119  // Context menu for groupTree
120  groupTree->setContextMenuPolicy( Qt::CustomContextMenu );
121  connect( groupTree, SIGNAL( customContextMenuRequested( const QPoint& ) ),
122  this, SLOT( grouptreeContextMenu( const QPoint& ) ) );
123 
124  // Context menu for listItems
125  listItems->setContextMenuPolicy( Qt::CustomContextMenu );
126  connect( listItems, SIGNAL( customContextMenuRequested( const QPoint& ) ),
127  this, SLOT( listitemsContextMenu( const QPoint& ) ) );
128 
129 }
130 
132 {
133  if ( mModified )
134  {
135  mStyle->save();
136  }
137 
138  QSettings settings;
139  settings.setValue( "/Windows/StyleV2Manager/geometry", saveGeometry() );
140  settings.setValue( "/Windows/StyleV2Manager/splitter", mSplitter->saveState() );
141 }
142 
144 {
145 #if 0
146  // save current selection index in types combo
147  int current = ( tabItemType->count() > 0 ? tabItemType->currentIndex() : 0 );
148 
149 // no counting of style items
150  int markerCount = 0, lineCount = 0, fillCount = 0;
151 
152  QStringList symbolNames = mStyle->symbolNames();
153  for ( int i = 0; i < symbolNames.count(); ++i )
154  {
155  switch ( mStyle->symbolRef( symbolNames[i] )->type() )
156  {
157  case QgsSymbolV2::Marker:
158  markerCount++;
159  break;
160  case QgsSymbolV2::Line:
161  lineCount++;
162  break;
163  case QgsSymbolV2::Fill:
164  fillCount++;
165  break;
166  default: Q_ASSERT( 0 && "unknown symbol type" );
167  break;
168  }
169  }
170 
171  cboItemType->clear();
172  cboItemType->addItem( tr( "Marker symbol (%1)" ).arg( markerCount ), QVariant( QgsSymbolV2::Marker ) );
173  cboItemType->addItem( tr( "Line symbol (%1)" ).arg( lineCount ), QVariant( QgsSymbolV2::Line ) );
174  cboItemType->addItem( tr( "Fill symbol (%1)" ).arg( fillCount ), QVariant( QgsSymbolV2::Fill ) );
175 
176  cboItemType->addItem( tr( "Color ramp (%1)" ).arg( mStyle->colorRampCount() ), QVariant( 3 ) );
177 
178  // update current index to previous selection
179  cboItemType->setCurrentIndex( current );
180 #endif
181 }
182 
184 {
185  // when in Color Ramp tab, add menu to add item button
186  if ( currentItemType() == 3 )
187  {
188  btnShare->menu()->actions().at( 0 )->setVisible( false );
189  btnShare->menu()->actions().at( 1 )->setVisible( false );
190 
191  QStringList rampTypes;
192  rampTypes << tr( "Gradient" ) << tr( "Random" ) << tr( "ColorBrewer" );
193  rampTypes << tr( "cpt-city" ); // todo, only for rasters?
194  QMenu* menu = new QMenu( btnAddItem );
195  Q_FOREACH ( const QString& rampType, rampTypes )
196  {
197  menu->addAction( rampType );
198  }
199  btnAddItem->setMenu( menu );
200  connect( menu, SIGNAL( triggered( QAction* ) ),
201  this, SLOT( addColorRamp( QAction* ) ) );
202  }
203  else
204  {
205  btnShare->menu()->actions().at( 0 )->setVisible( true );
206  btnShare->menu()->actions().at( 1 )->setVisible( true );
207 
208  if ( btnAddItem->menu() )
209  {
210  disconnect( btnAddItem->menu(), SIGNAL( triggered( QAction* ) ),
211  this, SLOT( addColorRamp( QAction* ) ) );
212  btnAddItem->setMenu( 0 );
213  }
214  }
215 
216  // set icon and grid size, depending on type
217  if ( currentItemType() == 1 || currentItemType() == 3 )
218  {
219  listItems->setIconSize( QSize( 75, 50 ) );
220  listItems->setGridSize( QSize( 100, 80 ) );
221  }
222  else
223  {
224  listItems->setIconSize( QSize( 50, 50 ) );
225  listItems->setGridSize( QSize( 75, 80 ) );
226  }
227 
228  populateList();
229 }
230 
232 {
233  if ( currentItemType() > 3 )
234  {
235  Q_ASSERT( 0 && "not implemented" );
236  return;
237  }
238  groupChanged( groupTree->selectionModel()->currentIndex() );
239 }
240 
241 void QgsStyleV2ManagerDialog::populateSymbols( const QStringList& symbolNames, bool check )
242 {
243  QStandardItemModel* model = qobject_cast<QStandardItemModel*>( listItems->model() );
244  model->clear();
245 
246  int type = currentItemType();
247 
248  for ( int i = 0; i < symbolNames.count(); ++i )
249  {
250  QString name = symbolNames[i];
251  QgsSymbolV2* symbol = mStyle->symbol( name );
252  if ( symbol && symbol->type() == type )
253  {
254  QStandardItem* item = new QStandardItem( name );
255  QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( symbol, listItems->iconSize() );
256  item->setIcon( icon );
257  item->setData( name ); // used to find out original name when user edited the name
258  item->setCheckable( check );
259  item->setToolTip( name );
260  // add to model
261  model->appendRow( item );
262  }
263  delete symbol;
264  }
265 }
266 
267 
268 void QgsStyleV2ManagerDialog::populateColorRamps( const QStringList& colorRamps, bool check )
269 {
270  QStandardItemModel* model = qobject_cast<QStandardItemModel*>( listItems->model() );
271  model->clear();
272 
273  for ( int i = 0; i < colorRamps.count(); ++i )
274  {
275  QString name = colorRamps[i];
276  QgsVectorColorRampV2* ramp = mStyle->colorRamp( name );
277 
278  QStandardItem* item = new QStandardItem( name );
279  QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( ramp, listItems->iconSize() );
280  item->setIcon( icon );
281  item->setData( name ); // used to find out original name when user edited the name
282  item->setCheckable( check );
283  item->setToolTip( name );
284  model->appendRow( item );
285  delete ramp;
286  }
287 }
288 
290 {
291  switch ( tabItemType->currentIndex() )
292  {
293  case 0: return QgsSymbolV2::Marker;
294  case 1: return QgsSymbolV2::Line;
295  case 2: return QgsSymbolV2::Fill;
296  case 3: return 3;
297  default: return 0;
298  }
299 }
300 
302 {
303  QModelIndex index = listItems->selectionModel()->currentIndex();
304  if ( !index.isValid() )
305  return QString();
306  return index.model()->data( index, 0 ).toString();
307 }
308 
310 {
311  bool changed = false;
312  if ( currentItemType() < 3 )
313  {
314  changed = addSymbol();
315  }
316  else if ( currentItemType() == 3 )
317  {
318  changed = addColorRamp();
319  }
320  else
321  {
322  Q_ASSERT( 0 && "not implemented" );
323  }
324 
325  if ( changed )
326  {
327  populateList();
328  populateTypes();
329  }
330 }
331 
333 {
334  // create new symbol with current type
335  QgsSymbolV2* symbol;
336  QString name = tr( "new symbol" );
337  switch ( currentItemType() )
338  {
339  case QgsSymbolV2::Marker:
340  symbol = new QgsMarkerSymbolV2();
341  name = tr( "new marker" );
342  break;
343  case QgsSymbolV2::Line:
344  symbol = new QgsLineSymbolV2();
345  name = tr( "new line" );
346  break;
347  case QgsSymbolV2::Fill:
348  symbol = new QgsFillSymbolV2();
349  name = tr( "new fill symbol" );
350  break;
351  default:
352  Q_ASSERT( 0 && "unknown symbol type" );
353  return false;
354  }
355 
356  // get symbol design
357  // NOTE : Set the parent widget as "this" to notify the Symbol selector
358  // that, it is being called by Style Manager, so recursive calling
359  // of style manager and symbol selector can be arrested
360  // See also: editSymbol()
361  QgsSymbolV2SelectorDialog dlg( symbol, mStyle, NULL, this );
362  if ( dlg.exec() == 0 )
363  {
364  delete symbol;
365  return false;
366  }
367 
368  // get unique name
369  bool nameInvalid = true;
370 
371  while ( nameInvalid )
372  {
373  bool ok;
374  name = QInputDialog::getText( this, tr( "Symbol Name" ),
375  tr( "Please enter a name for new symbol:" ),
376  QLineEdit::Normal, name, &ok );
377  if ( !ok )
378  {
379  delete symbol;
380  return false;
381  }
382  // validate name
383  if ( name.isEmpty() )
384  {
385  QMessageBox::warning( this, tr( "Save symbol" ),
386  tr( "Cannot save symbol without name. Enter a name." ) );
387  }
388  else if ( mStyle->symbolNames().contains( name ) )
389  {
390  int res = QMessageBox::warning( this, tr( "Save symbol" ),
391  tr( "Symbol with name '%1' already exists. Overwrite?" )
392  .arg( name ),
393  QMessageBox::Yes | QMessageBox::No );
394  if ( res == QMessageBox::Yes )
395  {
396  nameInvalid = false;
397  }
398  }
399  else
400  {
401  // valid name
402  nameInvalid = false;
403  }
404  }
405 
406  // add new symbol to style and re-populate the list
407  mStyle->addSymbol( name, symbol, true );
408  // TODO groups and tags
409  mModified = true;
410  return true;
411 }
412 
413 
415 {
416  // let the user choose the color ramp type if rampType is not given
417  bool ok = true;
418  if ( rampType.isEmpty() )
419  {
420  QStringList rampTypes;
421  rampTypes << tr( "Gradient" ) << tr( "Random" ) << tr( "ColorBrewer" );
422  rampTypes << tr( "cpt-city" ); // todo, only for rasters?
423  rampType = QInputDialog::getItem( parent, tr( "Color ramp type" ),
424  tr( "Please select color ramp type:" ), rampTypes, 0, false, &ok );
425  }
426  if ( !ok || rampType.isEmpty() )
427  return QString();
428 
429  QString name = tr( "new ramp" );
430 
431  QgsVectorColorRampV2 *ramp = NULL;
432  if ( rampType == tr( "Gradient" ) )
433  {
435  QgsVectorGradientColorRampV2Dialog dlg( gradRamp, parent );
436  if ( !dlg.exec() )
437  {
438  delete gradRamp;
439  return QString();
440  }
441  ramp = gradRamp;
442  name = tr( "new gradient ramp" );
443  }
444  else if ( rampType == tr( "Random" ) )
445  {
447  QgsVectorRandomColorRampV2Dialog dlg( randRamp, parent );
448  if ( !dlg.exec() )
449  {
450  delete randRamp;
451  return QString();
452  }
453  ramp = randRamp;
454  name = tr( "new random ramp" );
455  }
456  else if ( rampType == tr( "ColorBrewer" ) )
457  {
459  QgsVectorColorBrewerColorRampV2Dialog dlg( brewerRamp, parent );
460  if ( !dlg.exec() )
461  {
462  delete brewerRamp;
463  return QString();
464  }
465  ramp = brewerRamp;
466  name = brewerRamp->schemeName() + QString::number( brewerRamp->colors() );
467  }
468  else if ( rampType == tr( "cpt-city" ) )
469  {
470  QgsCptCityColorRampV2* cptCityRamp = new QgsCptCityColorRampV2( "", "" );
471  QgsCptCityColorRampV2Dialog dlg( cptCityRamp, parent );
472  if ( !dlg.exec() )
473  {
474  delete cptCityRamp;
475  return QString();
476  }
477  // name = dlg.selectedName();
478  name = QFileInfo( cptCityRamp->schemeName() ).baseName() + cptCityRamp->variantName();
479  if ( dlg.saveAsGradientRamp() )
480  {
481  ramp = cptCityRamp->cloneGradientRamp();
482  delete cptCityRamp;
483  }
484  else
485  {
486  ramp = cptCityRamp;
487  }
488  }
489  else
490  {
491  // Q_ASSERT( 0 && "invalid ramp type" );
492  // bailing out is rather harsh!
493  QgsDebugMsg( "invalid ramp type " + rampType );
494  return QString();
495  }
496 
497  // get unique name
498  bool nameInvalid = true;
499 
500  while ( nameInvalid )
501  {
502  bool ok;
503  name = QInputDialog::getText( parent, tr( "Color Ramp Name" ),
504  tr( "Please enter a name for new color ramp:" ),
505  QLineEdit::Normal, name, &ok );
506  if ( !ok )
507  {
508  delete ramp;
509  return QString();
510  }
511  // validate name
512  if ( name.isEmpty() )
513  {
514  QMessageBox::warning( parent, tr( "Save Color Ramp" ),
515  tr( "Cannot save color ramp without name. Enter a name." ) );
516  }
517  else if ( style->colorRampNames().contains( name ) )
518  {
519  int res = QMessageBox::warning( parent, tr( "Save color ramp" ),
520  tr( "Color ramp with name '%1' already exists. Overwrite?" )
521  .arg( name ),
522  QMessageBox::Yes | QMessageBox::No );
523  if ( res == QMessageBox::Yes )
524  {
525  nameInvalid = false;
526  }
527  }
528  else
529  {
530  // valid name
531  nameInvalid = false;
532  }
533  }
534 
535  // add new symbol to style and re-populate the list
536  style->addColorRamp( name, ramp, true );
537  // TODO groups and tags, using saveColorRamp
538  return name;
539 }
540 
541 
543 {
544  return addColorRamp( 0 );
545 }
546 
548 {
549  // pass the action text, which is the color ramp type
550  QString rampName = addColorRampStatic( this, mStyle,
551  action ? action->text() : QString() );
552  if ( !rampName.isEmpty() )
553  {
554  mModified = true;
555  populateList();
556  return true;
557  }
558 
559  return false;
560 }
561 
563 {
564  bool changed = false;
565  if ( currentItemType() < 3 )
566  {
567  changed = editSymbol();
568  }
569  else if ( currentItemType() == 3 )
570  {
571  changed = editColorRamp();
572  }
573  else
574  {
575  Q_ASSERT( 0 && "not implemented" );
576  }
577 
578  if ( changed )
579  populateList();
580 }
581 
583 {
584  QString symbolName = currentItemName();
585  if ( symbolName.isEmpty() )
586  return false;
587 
588  QgsSymbolV2* symbol = mStyle->symbol( symbolName );
589 
590  // let the user edit the symbol and update list when done
591  QgsSymbolV2SelectorDialog dlg( symbol, mStyle, NULL, this );
592  if ( dlg.exec() == 0 )
593  {
594  delete symbol;
595  return false;
596  }
597 
598  // by adding symbol to style with the same name the old effectively gets overwritten
599  mStyle->addSymbol( symbolName, symbol, true );
600  mModified = true;
601  return true;
602 }
603 
605 {
607  if ( name.isEmpty() )
608  return false;
609 
610  QgsVectorColorRampV2* ramp = mStyle->colorRamp( name );
611 
612  if ( ramp->type() == "gradient" )
613  {
614  QgsVectorGradientColorRampV2* gradRamp = static_cast<QgsVectorGradientColorRampV2*>( ramp );
615  QgsVectorGradientColorRampV2Dialog dlg( gradRamp, this );
616  if ( !dlg.exec() )
617  {
618  delete ramp;
619  return false;
620  }
621  }
622  else if ( ramp->type() == "random" )
623  {
624  QgsVectorRandomColorRampV2* randRamp = static_cast<QgsVectorRandomColorRampV2*>( ramp );
625  QgsVectorRandomColorRampV2Dialog dlg( randRamp, this );
626  if ( !dlg.exec() )
627  {
628  delete ramp;
629  return false;
630  }
631  }
632  else if ( ramp->type() == "colorbrewer" )
633  {
634  QgsVectorColorBrewerColorRampV2* brewerRamp = static_cast<QgsVectorColorBrewerColorRampV2*>( ramp );
635  QgsVectorColorBrewerColorRampV2Dialog dlg( brewerRamp, this );
636  if ( !dlg.exec() )
637  {
638  delete ramp;
639  return false;
640  }
641  }
642  else if ( ramp->type() == "cpt-city" )
643  {
644  QgsCptCityColorRampV2* cptCityRamp = static_cast<QgsCptCityColorRampV2*>( ramp );
645  QgsCptCityColorRampV2Dialog dlg( cptCityRamp, this );
646  if ( !dlg.exec() )
647  {
648  delete ramp;
649  return false;
650  }
651  if ( dlg.saveAsGradientRamp() )
652  {
653  ramp = cptCityRamp->cloneGradientRamp();
654  delete cptCityRamp;
655  }
656  }
657  else
658  {
659  Q_ASSERT( 0 && "invalid ramp type" );
660  }
661 
662  mStyle->addColorRamp( name, ramp, true );
663  mModified = true;
664  return true;
665 }
666 
667 
669 {
670  bool changed = false;
671  if ( currentItemType() < 3 )
672  {
673  changed = removeSymbol();
674  }
675  else if ( currentItemType() == 3 )
676  {
677  changed = removeColorRamp();
678  }
679  else
680  {
681  Q_ASSERT( 0 && "not implemented" );
682  }
683 
684  if ( changed )
685  {
686  populateList();
687  populateTypes();
688  }
689 }
690 
692 {
693  QModelIndexList indexes = listItems->selectionModel()->selectedIndexes();
694  Q_FOREACH ( const QModelIndex& index, indexes )
695  {
696  QString symbolName = index.data().toString();
697  // delete from style and update list
698  if ( !symbolName.isEmpty() )
699  mStyle->removeSymbol( symbolName );
700  }
701  mModified = true;
702  return true;
703 }
704 
706 {
707  QString rampName = currentItemName();
708  if ( rampName.isEmpty() )
709  return false;
710 
711  mStyle->removeColorRamp( rampName );
712  mModified = true;
713  return true;
714 }
715 
717 {
718  // an item has been edited
719  QString oldName = item->data().toString();
720 
721  bool changed = false;
722  if ( currentItemType() < 3 )
723  {
724  changed = mStyle->renameSymbol( oldName, item->text() );
725  }
726  else if ( currentItemType() == 3 )
727  {
728  changed = mStyle->renameColorRamp( oldName, item->text() );
729  }
730 
731  if ( changed )
732  {
733  populateList();
734  mModified = true;
735  }
736  else
737  {
738  QMessageBox::critical( this, tr( "Cannot rename item" ),
739  tr( "Name is already taken by another item. Choose a different name." ) );
740  item->setText( oldName );
741  }
742 }
743 
745 {
746  QString dir = QFileDialog::getExistingDirectory( this, tr( "Exported selected symbols as PNG" ),
747  QDir::home().absolutePath(),
748  QFileDialog::ShowDirsOnly
749  | QFileDialog::DontResolveSymlinks );
750  exportSelectedItemsImages( dir, "png", QSize( 32, 32 ) );
751 }
752 
754 {
755  QString dir = QFileDialog::getExistingDirectory( this, tr( "Exported selected symbols as SVG" ),
756  QDir::home().absolutePath(),
757  QFileDialog::ShowDirsOnly
758  | QFileDialog::DontResolveSymlinks );
759  exportSelectedItemsImages( dir, "svg", QSize( 32, 32 ) );
760 }
761 
762 
763 void QgsStyleV2ManagerDialog::exportSelectedItemsImages( const QString& dir, const QString& format, const QSize& size )
764 {
765  if ( dir.isEmpty() )
766  return;
767 
768  QModelIndexList indexes = listItems->selectionModel()->selection().indexes();
769  Q_FOREACH ( const QModelIndex& index, indexes )
770  {
771  QString name = index.data().toString();
772  QString path = dir + "/" + name + "." + format;
773  QgsSymbolV2 *sym = mStyle->symbol( name );
774  sym->exportImage( path, format, size );
775  }
776 }
777 
779 {
781  dlg.exec();
782 }
783 
785 {
787  dlg.exec();
788  populateList();
789  populateGroups();
790 }
791 
793 {
794  QFont font = item->font();
795  font.setBold( true );
796  item->setFont( font );
797 }
798 
800 {
801  QStandardItemModel *model = qobject_cast<QStandardItemModel*>( groupTree->model() );
802  model->clear();
803 
804  QStandardItem *allSymbols = new QStandardItem( tr( "All Symbols" ) );
805  allSymbols->setData( "all" );
806  allSymbols->setEditable( false );
807  setBold( allSymbols );
808  model->appendRow( allSymbols );
809 
810  QStandardItem *group = new QStandardItem( "" ); //require empty name to get first order groups
811  group->setData( "groups" );
812  group->setEditable( false );
813  buildGroupTree( group );
814  group->setText( tr( "Groups" ) );//set title later
815  QStandardItem *ungrouped = new QStandardItem( tr( "Ungrouped" ) );
816  ungrouped->setData( 0 );
817  setBold( ungrouped );
818  setBold( group );
819  group->appendRow( ungrouped );
820  model->appendRow( group );
821 
822  QStandardItem *tag = new QStandardItem( tr( "Smart Groups" ) );
823  tag->setData( "smartgroups" );
824  tag->setEditable( false );
825  setBold( tag );
828  while ( i != sgMap.constEnd() )
829  {
830  QStandardItem *item = new QStandardItem( i.value() );
831  item->setData( i.key() );
832  tag->appendRow( item );
833  ++i;
834  }
835  model->appendRow( tag );
836 
837  // expand things in the grouo tree
838  int rows = model->rowCount( model->indexFromItem( model->invisibleRootItem() ) );
839  for ( int i = 0; i < rows; i++ )
840  {
841  groupTree->setExpanded( model->indexFromItem( model->item( i ) ), true );
842  }
843 }
844 
846 {
847  QgsSymbolGroupMap groups = mStyle->childGroupNames( parent->text() );
849  while ( i != groups.constEnd() )
850  {
851  QStandardItem *item = new QStandardItem( i.value() );
852  item->setData( i.key() );
853  parent->appendRow( item );
854  buildGroupTree( item );
855  ++i;
856  }
857 }
858 
860 {
861  QStringList symbolNames;
862  QStringList groupSymbols;
863 
865  if ( currentItemType() > 3 )
866  {
867  QgsDebugMsg( "Entity not implemented" );
868  return;
869  }
870 
871  QString category = index.data( Qt::UserRole + 1 ).toString();
872  if ( category == "all" || category == "groups" || category == "smartgroups" )
873  {
874  enableGroupInputs( false );
875  if ( category == "groups" || category == "smartgroups" )
876  {
877  btnAddGroup->setEnabled( true );
878  }
879  symbolNames = currentItemType() < 3 ? mStyle->symbolNames() : mStyle->colorRampNames();
880  }
881  else
882  {
883  //determine groups and tags
884  if ( index.parent().data( Qt::UserRole + 1 ) == "smartgroups" )
885  {
886  btnAddGroup->setEnabled( false );
887  btnRemoveGroup->setEnabled( true );
888  btnManageGroups->setEnabled( true );
889  int groupId = index.data( Qt::UserRole + 1 ).toInt();
890  symbolNames = mStyle->symbolsOfSmartgroup( type, groupId );
891  }
892  else // then it must be a group
893  {
894  if (( !index.data( Qt::UserRole + 1 ).toInt() && ( index.data() == "Ungrouped" ) ) || mGrouppingMode )
895  enableGroupInputs( false );
896  else
897  enableGroupInputs( true );
898  int groupId = index.data( Qt::UserRole + 1 ).toInt();
899  symbolNames = mStyle->symbolsOfGroup( type, groupId );
900  if ( mGrouppingMode && groupId )
901  {
902  groupSymbols = symbolNames;
903  symbolNames += mStyle->symbolsOfGroup( type, 0 );
904  }
905  }
906  }
907 
908  if ( currentItemType() < 3 )
909  {
910  populateSymbols( symbolNames, mGrouppingMode );
911  }
912  else if ( currentItemType() == 3 )
913  {
914  populateColorRamps( symbolNames, mGrouppingMode );
915  }
916  if ( mGrouppingMode )
917  setSymbolsChecked( groupSymbols );
918 }
919 
921 {
922  QStandardItemModel *model = qobject_cast<QStandardItemModel*>( groupTree->model() );
923  QModelIndex parentIndex = groupTree->currentIndex();
924 
925  // Violation 1: Creating sub-groups of system defined groups
926  QString parentData = parentIndex.data( Qt::UserRole + 1 ).toString();
927  if ( parentData == "all" || ( parentIndex.data() == "Ungrouped" && parentData == "0" ) )
928  {
929  int err = QMessageBox::critical( this, tr( "Invalid Selection" ),
930  tr( "The parent group you have selected is not user editable.\n"
931  "Kindly select a user defined group." ) );
932  if ( err )
933  return;
934  }
935 
936  // Violation 2: Creating a nested tag
937  if ( parentIndex.parent().data( Qt::UserRole + 1 ).toString() == "smartgroups" )
938  {
939  int err = QMessageBox::critical( this, tr( "Operation Not Allowed" ),
940  tr( "Creation of nested smart groups are not allowed\n"
941  "Select the 'Smart Group' to create a new group." ) );
942  if ( err )
943  return;
944  }
945 
946  QString itemName;
947  QVariant itemData;
948  bool isGroup = true;
949 
950  // create a smart group if that is selected
951  if ( parentIndex.data( Qt::UserRole + 1 ).toString() == "smartgroups" )
952  {
953  QgsSmartGroupEditorDialog dlg( mStyle, this );
954  if ( dlg.exec() == QDialog::Rejected )
955  return;
956  int id = mStyle->addSmartgroup( dlg.smartgroupName(), dlg.conditionOperator(), dlg.conditionMap() );
957  if ( !id )
958  return;
959  itemData = QVariant( id );
960  itemName = dlg.smartgroupName();
961  isGroup = false;
962  }
963  else
964  {
965  itemName = QString( tr( "New Group" ) );
966  itemData = QVariant( "newgroup" );
967  }
968 
969  // Else create a simple child-group to the selected
970  QStandardItem *parentItem = model->itemFromIndex( parentIndex );
971  QStandardItem *childItem = new QStandardItem( itemName );
972  childItem->setData( itemData );
973  parentItem->appendRow( childItem );
974 
975  groupTree->setCurrentIndex( childItem->index() );
976  if ( isGroup )
977  {
978  groupTree->edit( childItem->index() );
979  }
980 }
981 
983 {
984  QStandardItemModel *model = qobject_cast<QStandardItemModel*>( groupTree->model() );
985  QModelIndex index = groupTree->currentIndex();
986 
987  // Violation: removing system groups
988  QString data = index.data( Qt::UserRole + 1 ).toString();
989  if ( data == "all" || data == "groups" || data == "smartgroups" || index.data() == "Ungrouped" )
990  {
991  int err = QMessageBox::critical( this, tr( "Invalid selection" ),
992  tr( "Cannot delete system defined categories.\n"
993  "Kindly select a group or smart group you might want to delete." ) );
994  if ( err )
995  return;
996  }
997 
998  QStandardItem *parentItem = model->itemFromIndex( index.parent() );
999  if ( parentItem->data( Qt::UserRole + 1 ).toString() == "smartgroups" )
1000  {
1001  mStyle->remove( QgsStyleV2::SmartgroupEntity, index.data( Qt::UserRole + 1 ).toInt() );
1002  }
1003  else
1004  {
1005  mStyle->remove( QgsStyleV2::GroupEntity, index.data( Qt::UserRole + 1 ).toInt() );
1006  QStandardItem *item = model->itemFromIndex( index );
1007  if ( item->hasChildren() )
1008  {
1009  QStandardItem *parent = item->parent();
1010  for ( int i = 0; i < item->rowCount(); i++ )
1011  {
1012  parent->appendRow( item->takeChild( i ) );
1013  }
1014  }
1015  }
1016  parentItem->removeRow( index.row() );
1017 }
1018 
1020 {
1021  QString data = item->data( Qt::UserRole + 1 ).toString();
1022  QgsDebugMsg( "Symbol group edited: data=" + data + " text=" + item->text() );
1023  if ( data == "newgroup" )
1024  {
1025  int id;
1026  if ( item->parent()->data( Qt::UserRole + 1 ).toString() == "groups" )
1027  {
1028  id = mStyle->addGroup( item->text() );
1029  }
1030  else
1031  {
1032  int parentid = item->parent()->data( Qt::UserRole + 1 ).toInt();
1033  id = mStyle->addGroup( item->text(), parentid );
1034  }
1035  if ( !id )
1036  {
1037  QMessageBox::critical( this, tr( "Error!" ),
1038  tr( "New group could not be created.\n"
1039  "There was a problem with your symbol database." ) );
1040  item->parent()->removeRow( item->row() );
1041  return;
1042  }
1043  else
1044  {
1045  item->setData( id );
1046  }
1047  }
1048  else
1049  {
1050  int id = item->data( Qt::UserRole + 1 ).toInt();
1051  QString name = item->text();
1052  if ( item->parent()->data( Qt::UserRole + 1 ) == "smartgroups" )
1053  {
1055  }
1056  else
1057  {
1058  mStyle->rename( QgsStyleV2::GroupEntity, id, name );
1059  }
1060  }
1061 }
1062 
1064 {
1065 
1066  QStandardItemModel *treeModel = qobject_cast<QStandardItemModel*>( groupTree->model() );
1067  QStandardItemModel *model = qobject_cast<QStandardItemModel*>( listItems->model() );
1068  QAction *senderAction = qobject_cast<QAction*>( sender() );
1069 
1070  if ( mGrouppingMode )
1071  {
1072  mGrouppingMode = false;
1073  senderAction->setText( tr( "Group Symbols" ) );
1074  // disconnect slot which handles regrouping
1075  disconnect( model, SIGNAL( itemChanged( QStandardItem* ) ),
1076  this, SLOT( regrouped( QStandardItem* ) ) );
1077 
1078  // disabel all items except groups in groupTree
1080  groupChanged( groupTree->currentIndex() );
1081 
1082  // Finally: Reconnect all Symbol editing functionalities
1083  connect( treeModel, SIGNAL( itemChanged( QStandardItem* ) ),
1084  this, SLOT( groupRenamed( QStandardItem* ) ) );
1085  connect( model, SIGNAL( itemChanged( QStandardItem* ) ),
1086  this, SLOT( itemChanged( QStandardItem* ) ) );
1087  // Reset the selection mode
1088  listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
1089  }
1090  else
1091  {
1092  bool validGroup = false;
1093  // determine whether it is a valid group
1094  QModelIndex present = groupTree->currentIndex();
1095  while ( present.parent().isValid() )
1096  {
1097  if ( present.parent().data() == "Groups" )
1098  {
1099  validGroup = true;
1100  break;
1101  }
1102  else
1103  present = present.parent();
1104  }
1105  if ( !validGroup )
1106  return;
1107 
1108  mGrouppingMode = true;
1109  // Change the text menu
1110  senderAction->setText( tr( "Finish Grouping" ) );
1111  // Remove all Symbol editing functionalities
1112  disconnect( treeModel, SIGNAL( itemChanged( QStandardItem* ) ),
1113  this, SLOT( groupRenamed( QStandardItem* ) ) );
1114  disconnect( model, SIGNAL( itemChanged( QStandardItem* ) ),
1115  this, SLOT( itemChanged( QStandardItem* ) ) );
1116 
1117  // disabel all items except groups in groupTree
1118  enableItemsForGroupingMode( false );
1119  groupChanged( groupTree->currentIndex() );
1120  btnManageGroups->setEnabled( true );
1121 
1122 
1123  // Connect to slot which handles regrouping
1124  connect( model, SIGNAL( itemChanged( QStandardItem* ) ),
1125  this, SLOT( regrouped( QStandardItem* ) ) );
1126 
1127  // No selection should be possible
1128  listItems->setSelectionMode( QAbstractItemView::NoSelection );
1129  }
1130 }
1131 
1133 {
1135  if ( currentItemType() > 3 )
1136  {
1137  QgsDebugMsg( "Unknown style entity" );
1138  return;
1139  }
1140  int groupid = groupTree->currentIndex().data( Qt::UserRole + 1 ).toInt();
1141  QString symbolName = item->text();
1142  bool regrouped;
1143  if ( item->checkState() == Qt::Checked )
1144  regrouped = mStyle->group( type, symbolName, groupid );
1145  else
1146  regrouped = mStyle->group( type, symbolName, 0 );
1147  if ( !regrouped )
1148  {
1149  int er = QMessageBox::critical( this, tr( "Database Error" ),
1150  tr( "There was a problem with the Symbols database while regrouping." ) );
1151  // call the slot again to get back to normal
1152  if ( er )
1154  }
1155 }
1156 
1158 {
1159  QStandardItemModel *model = qobject_cast<QStandardItemModel*>( listItems->model() );
1160  Q_FOREACH ( const QString& symbol, symbols )
1161  {
1162  QList<QStandardItem*> items = model->findItems( symbol );
1163  Q_FOREACH ( QStandardItem* item, items )
1164  item->setCheckState( Qt::Checked );
1165  }
1166 }
1167 
1169 {
1170  QStringList items;
1171  if ( currentItemType() == 3 )
1172  {
1173  items = mStyle->findSymbols( QgsStyleV2::ColorrampEntity, qword );
1174  populateColorRamps( items );
1175  }
1176  else
1177  {
1178  items = mStyle->findSymbols( QgsStyleV2::SymbolEntity, qword );
1179  populateSymbols( items );
1180  }
1181 }
1182 
1184 {
1185  QModelIndexList indexes = listItems->selectionModel()->selection().indexes();
1186  QStringList addtags;
1187  QStringList removetags;
1188 
1189  QStringList oldtags = mTagList;
1190  QStringList newtags = tagsLineEdit->text().split( ",", QString::SkipEmptyParts );
1191 
1193  if ( currentItemType() < 3 )
1194  {
1195  type = QgsStyleV2::SymbolEntity;
1196  }
1197  else if ( currentItemType() == 3 )
1198  {
1200  }
1201  else
1202  {
1203  QgsDebugMsg( "Unknown Style Entity!" );
1204  return;
1205  }
1206  // compare old with new to find removed tags
1207  Q_FOREACH ( const QString &tag, oldtags )
1208  {
1209  if ( !newtags.contains( tag ) )
1210  removetags.append( tag );
1211  }
1212  if ( removetags.size() > 0 )
1213  {
1214  Q_FOREACH ( const QModelIndex& index, indexes )
1215  {
1216  mStyle->detagSymbol( type, index.data().toString(), removetags );
1217  }
1218  }
1219  // compare new with old to find added tags
1220  Q_FOREACH ( const QString &tag, newtags )
1221  {
1222  if ( !oldtags.contains( tag ) )
1223  addtags.append( tag );
1224  }
1225  if ( addtags.size() > 0 )
1226  {
1227  Q_FOREACH ( const QModelIndex& index, indexes )
1228  {
1229  mStyle->tagSymbol( type, index.data().toString(), addtags );
1230  }
1231  }
1232 }
1233 
1235 {
1236  // Populate the tags for the symbol
1237  tagsLineEdit->clear();
1238  QStandardItem *item = static_cast<QStandardItemModel*>( listItems->model() )->itemFromIndex( index );
1240  mTagList = mStyle->tagsOfSymbol( type, item->data().toString() );
1241  tagsLineEdit->setText( mTagList.join( "," ) );
1242 }
1243 
1245 {
1246  groupTree->setEnabled( enable );
1247  btnAddGroup->setEnabled( enable );
1248  btnRemoveGroup->setEnabled( enable );
1249  btnManageGroups->setEnabled( enable );
1250  searchBox->setEnabled( enable );
1251  tagsLineEdit->setEnabled( enable );
1252 }
1253 
1255 {
1256  btnAddGroup->setEnabled( enable );
1257  btnRemoveGroup->setEnabled( enable );
1258  btnManageGroups->setEnabled( enable );
1259 }
1260 
1262 {
1263  QStandardItemModel *treeModel = qobject_cast<QStandardItemModel*>( groupTree->model() );
1264  for ( int i = 0; i < treeModel->rowCount(); i++ )
1265  {
1266  if ( treeModel->item( i )->data() != "groups" )
1267  {
1268  treeModel->item( i )->setEnabled( enable );
1269  }
1270  if ( treeModel->item( i )->data() == "groups" )
1271  {
1272  treeModel->item( i )->setEnabled( enable );
1273  for ( int k = 0; k < treeModel->item( i )->rowCount(); k++ )
1274  {
1275  if ( !treeModel->item( i )->child( k )->data().toInt() )
1276  treeModel->item( i )->child( k )->setEnabled( enable );
1277  }
1278  }
1279  if ( treeModel->item( i )->data() == "smartgroups" )
1280  {
1281  for ( int j = 0; j < treeModel->item( i )->rowCount(); j++ )
1282  {
1283  treeModel->item( i )->child( j )->setEnabled( enable );
1284  }
1285  }
1286  }
1287 
1288  // The buttons
1289  // NOTE: if you ever change the layout name in the .ui file edit here too
1290  for ( int i = 0; i < symbolBtnsLayout->count(); i++ )
1291  {
1292  QWidget *w = qobject_cast<QWidget*>( symbolBtnsLayout->itemAt( i )->widget() );
1293  if ( w )
1294  w->setEnabled( enable );
1295  }
1296 
1297 }
1298 
1300 {
1301  QPoint globalPos = groupTree->viewport()->mapToGlobal( point );
1302 
1303  QModelIndex index = groupTree->indexAt( point );
1304  QgsDebugMsg( "Now you clicked: " + index.data().toString() );
1305 
1306  QMenu groupMenu;
1307 
1308  if ( index.parent().isValid() && ( index.data().toString() != "Ungrouped" ) )
1309  {
1310  if ( index.parent().data( Qt::UserRole + 1 ).toString() == "smartgroups" )
1311  {
1312  groupMenu.addAction( tr( "Edit Group" ) );
1313  }
1314  else
1315  {
1316  groupMenu.addAction( tr( "Add Group" ) );
1317  }
1318  groupMenu.addAction( tr( "Remove Group" ) );
1319  }
1320  else if ( index.data( Qt::UserRole + 1 ) == "groups" || index.data( Qt::UserRole + 1 ) == "smartgroups" )
1321  {
1322  groupMenu.addAction( tr( "Add Group" ) );
1323  }
1324 
1325 
1326  QAction* selectedItem = groupMenu.exec( globalPos );
1327 
1328  if ( selectedItem )
1329  {
1330  if ( selectedItem->text() == tr( "Add Group" ) )
1331  addGroup();
1332  else if ( selectedItem->text() == tr( "Remove Group" ) )
1333  removeGroup();
1334  else if ( selectedItem->text() == tr( "Edit Group" ) )
1336  }
1337 }
1338 
1340 {
1341  QPoint globalPos = listItems->viewport()->mapToGlobal( point );
1342 
1343  QMenu *groupMenu = new QMenu( this );
1344  QMenu *groupList = new QMenu( this );
1345  groupList->setTitle( tr( "Apply Group" ) );
1346 
1347  QStringList groups = mStyle->groupNames();
1348  Q_FOREACH ( const QString& group, groups )
1349  {
1350  groupList->addAction( group );
1351  }
1352  groupMenu->addMenu( groupList );
1353  groupMenu->addAction( tr( "Un-group" ) );
1354 
1355  QAction* selectedItem = groupMenu->exec( globalPos );
1356 
1357  if ( selectedItem )
1358  {
1360  if ( currentItemType() > 3 )
1361  {
1362  QgsDebugMsg( "unknow entity type" );
1363  return;
1364  }
1365  int groupId = 0;
1366  if ( selectedItem->text() != tr( "Un-group" ) )
1367  {
1368  groupId = mStyle->groupId( selectedItem->text() );
1369  }
1370  QModelIndexList indexes = listItems->selectionModel()->selectedIndexes();
1371  Q_FOREACH ( const QModelIndex& index, indexes )
1372  {
1373  mStyle->group( type, index.data().toString(), groupId );
1374  }
1375  populateList();
1376 
1377  QgsDebugMsg( "Selected Action: " + selectedItem->text() );
1378  }
1379 }
1380 
1382 {
1383  QStandardItemModel *treeModel = qobject_cast<QStandardItemModel*>( groupTree->model() );
1384 
1385  // determine whether it is a valid group
1386  QModelIndex present = groupTree->currentIndex();
1387  if ( present.parent().data( Qt::UserRole + 1 ) != "smartgroups" )
1388  {
1389  QMessageBox::critical( this, tr( "Invalid Selection" ),
1390  tr( "You have not selected a Smart Group. Kindly select a Smart Group to edit." ) );
1391  return;
1392  }
1393  QStandardItem* item = treeModel->itemFromIndex( present );
1394 
1395  QgsSmartGroupEditorDialog dlg( mStyle, this );
1396  QgsSmartConditionMap map = mStyle->smartgroup( present.data( Qt::UserRole + 1 ).toInt() );
1397  dlg.setSmartgroupName( item->text() );
1398  dlg.setOperator( mStyle->smartgroupOperator( item->data().toInt() ) );
1399  dlg.setConditionMap( map );
1400 
1401  if ( dlg.exec() == QDialog::Rejected )
1402  return;
1403 
1405  int id = mStyle->addSmartgroup( dlg.smartgroupName(), dlg.conditionOperator(), dlg.conditionMap() );
1406  if ( !id )
1407  {
1408  QMessageBox::critical( this, tr( "Database Error!" ),
1409  tr( "There was some error while editing the smart group." ) );
1410  return;
1411  }
1412  item->setText( dlg.smartgroupName() );
1413  item->setData( id );
1414 
1415  groupChanged( present );
1416 }
1417 
1419 {
1420 
1421  if (( obj == tagsLineEdit ) && ( event->type() == QEvent::FocusOut ) )
1422  {
1423  tagsChanged();
1424  return true;
1425  }
1426  return false;
1427 }
1428 
void customContextMenuRequested(const QPoint &pos)
QStringList tagsOfSymbol(StyleEntity type, const QString &symbol)
return the tags associated with the symbol
Definition: qgsstylev2.cpp:895
QString smartgroupOperator(int id)
returns the operator for the smartgroup
void setToolTip(const QString &toolTip)
QByteArray toByteArray() const
static unsigned index
void remove(StyleEntity type, int id)
remove the specified entity from the db
Definition: qgsstylev2.cpp:691
QgsVectorColorRampV2 * colorRamp(const QString &name)
return a NEW copy of color ramp
Definition: qgsstylev2.cpp:260
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFlags< QFileDialog::Option > options)
Type type() const
void setupUi(QWidget *widget)
void setIcon(const QIcon &icon)
static QIcon colorRampPreviewIcon(QgsVectorColorRampV2 *ramp, QSize size)
virtual QString type() const =0
QString getItem(QWidget *parent, const QString &title, const QString &label, const QStringList &items, int current, bool editable, bool *ok, QFlags< Qt::WindowType > flags, QFlags< Qt::InputMethodHint > inputMethodHints)
bool tagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
tags the symbol with the tags in the list
Definition: qgsstylev2.cpp:790
bool group(StyleEntity type, const QString &name, int groupid)
applies the specified group to the symbol or colorramp specified by StyleEntity
Definition: qgsstylev2.cpp:743
QStandardItem * invisibleRootItem() const
SymbolType type() const
Definition: qgssymbolv2.h:95
bool addSymbol(const QString &name, QgsSymbolV2 *symbol, bool update=false)
add symbol to style. takes symbol's ownership
Definition: qgsstylev2.cpp:83
QgsSmartConditionMap conditionMap()
returns the condition map
void setWindowModality(Qt::WindowModality windowModality)
void itemChanged(QStandardItem *item)
void groupChanged(const QModelIndex &)
int groupId(const QString &group)
return the DB id for the given group name
Definition: qgsstylev2.cpp:962
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
void enableItemsForGroupingMode(bool)
Enables or diables the groupTree items for grouping mode.
QObject * sender() const
void tagsChanged()
Listen to tag changes.
const_iterator constBegin() const
void setIcon(const QIcon &icon)
QStringList symbolsOfGroup(StyleEntity type, int groupid)
returns the symbolnames of a given groupid
Definition: qgsstylev2.cpp:527
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
void addAction(QAction *action)
bool contains(const QString &str, Qt::CaseSensitivity cs) const
void removeRow(int row)
QgsStyleV2ManagerDialog(QgsStyleV2 *style, QWidget *parent=NULL)
void exportImage(const QString &path, const QString &format, const QSize &size)
export symbol as image format. PNG and SVG supported
int exec()
Line symbol.
Definition: qgssymbolv2.h:71
bool addColorRamp(const QString &name, QgsVectorColorRampV2 *colorRamp, bool update=false)
add color ramp to style. takes ramp's ownership
Definition: qgsstylev2.cpp:188
const QPixmap * icon() const
bool detagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
detags the symbol with the given list
Definition: qgsstylev2.cpp:842
QString join(const QString &separator) const
QString smartgroupName()
returns the value from mNameLineEdit
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QStringList colorRampNames()
return a list of names of color ramps
Definition: qgsstylev2.cpp:276
QString tr(const char *sourceText, const char *disambiguation, int n)
QString text() const
Qt::CheckState checkState() const
Marker symbol.
Definition: qgssymbolv2.h:70
int size() const
virtual void setData(const QVariant &value, int role)
void finished(int result)
bool save(QString filename=QString())
save style into a file (will use current filename if empty string is passed)
Definition: qgsstylev2.cpp:360
void setBold(bool enable)
void setValue(const QString &key, const QVariant &value)
const char * name() const
bool isValid() const
void setConditionMap(QgsSmartConditionMap)
sets up the GUI for the given conditionmap
QString variantName() const
void setEnabled(bool)
QString number(int n, int base)
static QIcon symbolPreviewIcon(QgsSymbolV2 *symbol, QSize size)
QgsSymbolGroupMap childGroupNames(const QString &parent="")
return a map of groupid and names for the given parent group
Definition: qgsstylev2.cpp:480
int count(const T &value) const
bool addSymbol()
add a new symbol to style
void append(const T &value)
bool renameColorRamp(const QString &oldName, const QString &newName)
change ramp's name
Definition: qgsstylev2.cpp:438
int toInt(bool *ok) const
int colorRampCount()
return count of color ramps
Definition: qgsstylev2.cpp:271
QModelIndex indexFromItem(const QStandardItem *item) const
const Key & key() const
void filterSymbols(const QString &)
filter the symbols based on input search term
void populateSymbols(const QStringList &symbolNames, bool checkable=false)
populate list view with symbols of the current type with the given names
bool restoreGeometry(const QByteArray &geometry)
void populateGroups()
populate the groups
void appendRow(const QList< QStandardItem * > &items)
bool hasChildren() const
QStringList mTagList
space to store symbol tags
const QgsSymbolV2 * symbolRef(const QString &name) const
return a const pointer to a symbol (doesn't create new instance)
Definition: qgsstylev2.cpp:172
bool isEmpty() const
QStandardItem * parent() const
const_iterator constEnd() const
void groupRenamed(QStandardItem *)
void rename(StyleEntity type, int id, const QString &newName)
rename the given entity with the specified id
Definition: qgsstylev2.cpp:645
void populateColorRamps(const QStringList &colorRamps, bool checkable=false)
populate list view with color ramps
QList< QStandardItem * > findItems(const QString &text, QFlags< Qt::MatchFlag > flags, int column) const
const T & value() const
void buildGroupTree(QStandardItem *&parent)
build the groups tree
QStringList symbolsOfSmartgroup(StyleEntity type, int id)
returns the symbols for the smartgroup
virtual QVariant data(const QModelIndex &index, int role) const =0
void setTitle(const QString &title)
void grouptreeContextMenu(const QPoint &)
Context menu for the groupTree.
void setSymbolsChecked(const QStringList &)
to set symbols checked when in editing mode
void populateTypes()
populate combo box with known style items (symbols, color ramps)
QModelIndex parent() const
QStringList symbolNames()
return a list of names of symbols
Definition: qgsstylev2.cpp:182
QAction * exec()
QgsSymbolGroupMap smartgroupsListMap()
returns the smart groups map with id as key and name as value
QStandardItem * child(int row, int column) const
void setFont(const QFont &font)
QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode, const QString &text, bool *ok, QFlags< Qt::WindowType > flags, QFlags< Qt::InputMethodHint > inputMethodHints)
void setEnabled(bool enabled)
QgsSymbolV2 * symbol(const QString &name)
return a NEW copy of symbol
Definition: qgsstylev2.cpp:166
QStandardItem * item(int row, int column) const
const QFont & font() const
bool eventFilter(QObject *, QEvent *) override
Event filter to capture tagsLineEdit out of focus.
bool mGrouppingMode
Mode to display the symbol list.
void setBold(QStandardItem *)
sets the text of the item with bold font
QgsVectorGradientColorRampV2 * cloneGradientRamp() const
void setText(const QString &text)
void exportSelectedItemsImages(const QString &dir, const QString &format, const QSize &size)
QFont font() const
QVariant value(const QString &key, const QVariant &defaultValue) const
void symbolSelected(const QModelIndex &)
Perform symbol specific tasks when selected.
const QAbstractItemModel * model() const
void groupSymbolsAction()
carryout symbol grouping using check boxes
bool renameSymbol(const QString &oldName, const QString &newName)
change symbol's name
Definition: qgsstylev2.cpp:406
QVariant data(int role) const
QByteArray saveGeometry() const
void setOperator(const QString &)
sets the operator AND/OR
QStandardItem * itemFromIndex(const QModelIndex &index) const
QAction * addMenu(QMenu *menu)
void listitemsContextMenu(const QPoint &)
Context menu for the listItems ( symbols list )
Fill symbol.
Definition: qgssymbolv2.h:72
StandardButton critical(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
virtual int rowCount(const QModelIndex &parent) const
QStringList split(const QString &sep, const QString &str, bool allowEmptyEntries)
QModelIndex index() const
int rowCount() const
void setSmartgroupName(const QString &)
sets the smart group Name
StandardButton warning(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
void editSmartgroupAction()
edit the selected smart group
bool removeColorRamp(const QString &name)
remove color ramp from style (and delete it)
Definition: qgsstylev2.cpp:242
static QString addColorRampStatic(QWidget *parent, QgsStyleV2 *style, QString RampType=QString())
open add color ramp dialog, return color ramp's name if the ramp has been added
void setCheckState(Qt::CheckState state)
void enableGroupInputs(bool)
Enables or disables the groupTree specific inputs.
void enableSymbolInputs(bool)
Enables or disbables the symbol specific inputs.
void onFinished()
called when the dialog is going to be closed
QStandardItem * takeChild(int row, int column)
StyleEntity
Enum for Entities involved in a style.
Definition: qgsstylev2.h:80
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const
QChar * data()
bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
Definition: qgslayertree.h:34
QString toString() const
QDir home()
void setCheckable(bool checkable)
int row() const
void appendRow(const QList< QStandardItem * > &items)
virtual QVariant data(int role) const
QStringList findSymbols(StyleEntity type, const QString &qword)
return the names of the symbols which have a matching 'substring' in its defintion ...
Definition: qgsstylev2.cpp:764
void setEditable(bool editable)
void regrouped(QStandardItem *)
symbol changed from one group
QStringList groupNames()
return the all the groups in the style
Definition: qgsstylev2.cpp:466
int addGroup(const QString &groupName, int parent=0)
adds a new group and returns the group's id
Definition: qgsstylev2.cpp:613
QgsSmartConditionMap smartgroup(int id)
returns the QgsSmartConditionMap for the given id
bool removeSymbol(const QString &name)
remove symbol from style (and delete it)
Definition: qgsstylev2.cpp:138
int addSmartgroup(const QString &name, const QString &op, const QgsSmartConditionMap &conditions)
adds new smartgroup to the database and returns the id
Definition: qgsstylev2.cpp:977
QString conditionOperator()
returns the AND/OR condition
bool addColorRamp()
add a new color ramp to style
void populateList()
adds symbols of some type to list