QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsstylemanagerdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsstylemanagerdialog.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 
16 #include "qgsstylemanagerdialog.h"
17 #include "qgsstylesavedialog.h"
18 
19 #include "qgssymbol.h"
20 #include "qgssymbollayerutils.h"
21 #include "qgscolorramp.h"
22 
31 #include "qgssettings.h"
32 #include "qgsstylemodel.h"
33 #include "qgsmessagebar.h"
34 #include "qgstextformatwidget.h"
35 #include "qgslabelinggui.h"
37 #include <QAction>
38 #include <QFile>
39 #include <QFileDialog>
40 #include <QInputDialog>
41 #include <QMessageBox>
42 #include <QPushButton>
43 #include <QStandardItemModel>
44 #include <QMenu>
45 #include <QClipboard>
46 
47 #include "qgsapplication.h"
48 #include "qgslogger.h"
49 
50 //
51 // QgsCheckableStyleModel
52 //
53 
55 QgsCheckableStyleModel::QgsCheckableStyleModel( QgsStyleModel *sourceModel, QObject *parent, bool readOnly )
56  : QgsStyleProxyModel( sourceModel, parent )
57  , mStyle( sourceModel->style() )
58  , mReadOnly( readOnly )
59 {
60 
61 }
62 
63 QgsCheckableStyleModel::QgsCheckableStyleModel( QgsStyle *style, QObject *parent, bool readOnly )
64  : QgsStyleProxyModel( style, parent )
65  , mStyle( style )
66  , mReadOnly( readOnly )
67 {
68 }
69 
70 void QgsCheckableStyleModel::setCheckable( bool checkable )
71 {
72  if ( checkable == mCheckable )
73  return;
74 
75  mCheckable = checkable;
76  emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ), QVector< int >() << Qt::CheckStateRole );
77 }
78 
79 void QgsCheckableStyleModel::setCheckTag( const QString &tag )
80 {
81  if ( tag == mCheckTag )
82  return;
83 
84  mCheckTag = tag;
85  emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ), QVector< int >() << Qt::CheckStateRole );
86 }
87 
88 Qt::ItemFlags QgsCheckableStyleModel::flags( const QModelIndex &index ) const
89 {
90  Qt::ItemFlags f = QgsStyleProxyModel::flags( index );
91  if ( !mReadOnly && mCheckable && index.column() == 0 )
92  f |= Qt::ItemIsUserCheckable;
93 
94  if ( mReadOnly )
95  f &= ~Qt::ItemIsEditable;
96 
97  return f;
98 }
99 
100 QVariant QgsCheckableStyleModel::data( const QModelIndex &index, int role ) const
101 {
102  switch ( role )
103  {
104  case Qt::FontRole:
105  {
106  // drop font size to get reasonable amount of item name shown
107  QFont f = QgsStyleProxyModel::data( index, role ).value< QFont >();
108  f.setPointSize( 9 );
109  return f;
110  }
111 
112  case Qt::CheckStateRole:
113  {
114  if ( !mCheckable || index.column() != 0 )
115  return QVariant();
116 
117  const QStringList tags = data( index, QgsStyleModel::TagRole ).toStringList();
118  return tags.contains( mCheckTag ) ? Qt::Checked : Qt::Unchecked;
119  }
120 
121  default:
122  break;
123 
124  }
125  return QgsStyleProxyModel::data( index, role );
126 }
127 
128 bool QgsCheckableStyleModel::setData( const QModelIndex &i, const QVariant &value, int role )
129 {
130  if ( i.row() < 0 || i.row() >= rowCount( QModelIndex() ) ||
131  ( role != Qt::EditRole && role != Qt::CheckStateRole ) )
132  return false;
133 
134  if ( mReadOnly )
135  return false;
136 
137  if ( role == Qt::CheckStateRole )
138  {
139  if ( !mCheckable || mCheckTag.isEmpty() )
140  return false;
141 
142  const QString name = data( index( i.row(), QgsStyleModel::Name ), Qt::DisplayRole ).toString();
143  const QgsStyle::StyleEntity entity = static_cast< QgsStyle::StyleEntity >( data( i, QgsStyleModel::TypeRole ).toInt() );
144 
145  if ( value.toInt() == Qt::Checked )
146  return mStyle->tagSymbol( entity, name, QStringList() << mCheckTag );
147  else
148  return mStyle->detagSymbol( entity, name, QStringList() << mCheckTag );
149  }
150  return QgsStyleProxyModel::setData( i, value, role );
151 }
153 
154 //
155 // QgsStyleManagerDialog
156 //
157 
158 #include "qgsgui.h"
159 
160 QgsStyleManagerDialog::QgsStyleManagerDialog( QgsStyle *style, QWidget *parent, Qt::WindowFlags flags, bool readOnly )
161  : QDialog( parent, flags )
162  , mStyle( style )
163  , mReadOnly( readOnly )
164 {
165  setupUi( this );
167  connect( tabItemType, &QTabWidget::currentChanged, this, &QgsStyleManagerDialog::tabItemType_currentChanged );
168  connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsStyleManagerDialog::showHelp );
169  connect( buttonBox, &QDialogButtonBox::rejected, this, &QgsStyleManagerDialog::onClose );
170 
171  mMessageBar = new QgsMessageBar();
172  mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
173  mVerticalLayout->insertWidget( 0, mMessageBar );
174 
175 #ifdef Q_OS_MAC
176  setWindowModality( Qt::WindowModal );
177 #endif
178 
179  QgsSettings settings;
180 
181  mSplitter->setSizes( QList<int>() << 170 << 540 );
182  mSplitter->restoreState( settings.value( QStringLiteral( "Windows/StyleV2Manager/splitter" ) ).toByteArray() );
183 
184  tabItemType->setDocumentMode( true );
185  searchBox->setShowSearchIcon( true );
186  searchBox->setPlaceholderText( tr( "Filter symbols…" ) );
187 
188  connect( this, &QDialog::finished, this, &QgsStyleManagerDialog::onFinished );
189  connect( listItems, &QAbstractItemView::doubleClicked, this, &QgsStyleManagerDialog::editItem );
190  connect( btnEditItem, &QPushButton::clicked, this, [ = ]( bool ) { editItem(); }
191  );
192  connect( actnEditItem, &QAction::triggered, this, [ = ]( bool ) { editItem(); }
193  );
194 
195  if ( !mReadOnly )
196  {
197  connect( btnAddItem, &QPushButton::clicked, this, [ = ]( bool ) { addItem(); }
198  );
199 
200  connect( btnRemoveItem, &QPushButton::clicked, this, [ = ]( bool ) { removeItem(); }
201  );
202  connect( actnRemoveItem, &QAction::triggered, this, [ = ]( bool ) { removeItem(); }
203  );
204  }
205  else
206  {
207  btnAddTag->setEnabled( false );
208  btnAddSmartgroup->setEnabled( false );
209  }
210 
211  QMenu *shareMenu = new QMenu( tr( "Share Menu" ), this );
212  QAction *exportAction = new QAction( tr( "Export Item(s)…" ), this );
213  exportAction->setIcon( QIcon( QgsApplication::iconPath( "mActionFileSave.svg" ) ) );
214  shareMenu->addAction( exportAction );
215  if ( !mReadOnly )
216  {
217  QAction *importAction = new QAction( tr( "Import Item(s)…" ), this );
218  importAction->setIcon( QIcon( QgsApplication::iconPath( "mActionFileOpen.svg" ) ) );
219  shareMenu->addAction( importAction );
220  connect( importAction, &QAction::triggered, this, &QgsStyleManagerDialog::importItems );
221  }
222  if ( mStyle != QgsStyle::defaultStyle() )
223  {
224  mActionCopyToDefault = new QAction( tr( "Copy Selection to Default Style…" ), this );
225  shareMenu->addAction( mActionCopyToDefault );
226  connect( mActionCopyToDefault, &QAction::triggered, this, &QgsStyleManagerDialog::copyItemsToDefault );
227  connect( mCopyToDefaultButton, &QPushButton::clicked, this, &QgsStyleManagerDialog::copyItemsToDefault );
228  }
229  else
230  {
231  mCopyToDefaultButton->hide();
232  }
233 
234  mActionCopyItem = new QAction( tr( "Copy Item" ), this );
235  connect( mActionCopyItem, &QAction::triggered, this, &QgsStyleManagerDialog::copyItem );
236  mActionPasteItem = new QAction( tr( "Paste Item…" ), this );
237  connect( mActionPasteItem, &QAction::triggered, this, &QgsStyleManagerDialog::pasteItem );
238 
239  shareMenu->addSeparator();
240  shareMenu->addAction( actnExportAsPNG );
241  shareMenu->addAction( actnExportAsSVG );
242 
243  connect( actnExportAsPNG, &QAction::triggered, this, &QgsStyleManagerDialog::exportItemsPNG );
244  connect( actnExportAsSVG, &QAction::triggered, this, &QgsStyleManagerDialog::exportItemsSVG );
245  connect( exportAction, &QAction::triggered, this, &QgsStyleManagerDialog::exportItems );
246  btnShare->setMenu( shareMenu );
247 
248 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
249  double iconSize = Qgis::UI_SCALE_FACTOR * fontMetrics().width( 'X' ) * 10;
250 #else
251  double iconSize = Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 10;
252 #endif
253  listItems->setIconSize( QSize( static_cast< int >( iconSize ), static_cast< int >( iconSize * 0.9 ) ) ); // ~100, 90 on low dpi
254 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
255  double treeIconSize = Qgis::UI_SCALE_FACTOR * fontMetrics().width( 'X' ) * 2;
256 #else
257  double treeIconSize = Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 2;
258 #endif
259  mSymbolTreeView->setIconSize( QSize( static_cast< int >( treeIconSize ), static_cast< int >( treeIconSize ) ) );
260 
261  mModel = mStyle == QgsStyle::defaultStyle() ? new QgsCheckableStyleModel( QgsApplication::defaultStyleModel(), this, mReadOnly )
262  : new QgsCheckableStyleModel( mStyle, this, mReadOnly );
263  mModel->addDesiredIconSize( listItems->iconSize() );
264  mModel->addDesiredIconSize( mSymbolTreeView->iconSize() );
265  listItems->setModel( mModel );
266  mSymbolTreeView->setModel( mModel );
267 
268  listItems->setSelectionBehavior( QAbstractItemView::SelectRows );
269  listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
270  mSymbolTreeView->setSelectionModel( listItems->selectionModel() );
271  mSymbolTreeView->setSelectionMode( listItems->selectionMode() );
272 
273  connect( listItems->selectionModel(), &QItemSelectionModel::currentChanged,
275  connect( listItems->selectionModel(), &QItemSelectionModel::selectionChanged,
277 
278  QStandardItemModel *groupModel = new QStandardItemModel( groupTree );
279  groupTree->setModel( groupModel );
280  groupTree->setHeaderHidden( true );
281  populateGroups();
282  groupTree->setCurrentIndex( groupTree->model()->index( 0, 0 ) );
283 
284  connect( groupTree->selectionModel(), &QItemSelectionModel::currentChanged,
286  if ( !mReadOnly )
287  {
288  connect( groupModel, &QStandardItemModel::itemChanged,
290  }
291 
292  if ( !mReadOnly )
293  {
294  QMenu *groupMenu = new QMenu( tr( "Group Actions" ), this );
295  connect( actnTagSymbols, &QAction::triggered, this, &QgsStyleManagerDialog::tagSymbolsAction );
296  groupMenu->addAction( actnTagSymbols );
297  connect( actnFinishTagging, &QAction::triggered, this, &QgsStyleManagerDialog::tagSymbolsAction );
298  actnFinishTagging->setVisible( false );
299  groupMenu->addAction( actnFinishTagging );
300  groupMenu->addAction( actnEditSmartGroup );
301  btnManageGroups->setMenu( groupMenu );
302  }
303  else
304  {
305  btnManageGroups->setEnabled( false );
306  }
307 
308  connect( searchBox, &QLineEdit::textChanged, this, &QgsStyleManagerDialog::filterSymbols );
309 
310  // Context menu for groupTree
311  groupTree->setContextMenuPolicy( Qt::CustomContextMenu );
312  connect( groupTree, &QWidget::customContextMenuRequested,
314 
315  // Context menu for listItems
316  listItems->setContextMenuPolicy( Qt::CustomContextMenu );
317  connect( listItems, &QWidget::customContextMenuRequested,
319  mSymbolTreeView->setContextMenuPolicy( Qt::CustomContextMenu );
320  connect( mSymbolTreeView, &QWidget::customContextMenuRequested,
322 
323  if ( !mReadOnly )
324  {
325  // Menu for the "Add item" toolbutton when in colorramp mode
326  QStringList rampTypes;
327  rampTypes << tr( "Gradient…" ) << tr( "Color presets…" ) << tr( "Random…" ) << tr( "Catalog: cpt-city…" );
328  rampTypes << tr( "Catalog: ColorBrewer…" );
329 
330  mMenuBtnAddItemAll = new QMenu( this );
331  mMenuBtnAddItemColorRamp = new QMenu( this );
332  mMenuBtnAddItemLabelSettings = new QMenu( this );
333  mMenuBtnAddItemLegendPatchShape = new QMenu( this );
334 
335  QAction *item = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "mIconPointLayer.svg" ) ), tr( "Marker…" ), this );
336  connect( item, &QAction::triggered, this, [ = ]( bool ) { addSymbol( QgsSymbol::Marker ); } );
337  mMenuBtnAddItemAll->addAction( item );
338  item = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "mIconLineLayer.svg" ) ), tr( "Line…" ), this );
339  connect( item, &QAction::triggered, this, [ = ]( bool ) { addSymbol( QgsSymbol::Line ); } );
340  mMenuBtnAddItemAll->addAction( item );
341  item = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "mIconPolygonLayer.svg" ) ), tr( "Fill…" ), this );
342  connect( item, &QAction::triggered, this, [ = ]( bool ) { addSymbol( QgsSymbol::Fill ); } );
343  mMenuBtnAddItemAll->addAction( item );
344  mMenuBtnAddItemAll->addSeparator();
345  for ( const QString &rampType : qgis::as_const( rampTypes ) )
346  {
347  item = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "styleicons/color.svg" ) ), rampType, this );
348  connect( item, &QAction::triggered, this, [ = ]( bool ) { addColorRamp( item ); } );
349  mMenuBtnAddItemAll->addAction( item );
350  mMenuBtnAddItemColorRamp->addAction( new QAction( rampType, this ) );
351  }
352  mMenuBtnAddItemAll->addSeparator();
353  item = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "mIconFieldText.svg" ) ), tr( "Text Format…" ), this );
354  connect( item, &QAction::triggered, this, [ = ]( bool ) { addTextFormat(); } );
355  mMenuBtnAddItemAll->addAction( item );
356  mMenuBtnAddItemAll->addSeparator();
357  item = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "labelingSingle.svg" ) ), tr( "Point Label Settings…" ), this );
358  connect( item, &QAction::triggered, this, [ = ]( bool ) { addLabelSettings( QgsWkbTypes::PointGeometry ); } );
359  mMenuBtnAddItemAll->addAction( item );
360  mMenuBtnAddItemLabelSettings->addAction( item );
361  item = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "labelingSingle.svg" ) ), tr( "Line Label Settings…" ), this );
362  connect( item, &QAction::triggered, this, [ = ]( bool ) { addLabelSettings( QgsWkbTypes::LineGeometry ); } );
363  mMenuBtnAddItemAll->addAction( item );
364  mMenuBtnAddItemLabelSettings->addAction( item );
365  item = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "labelingSingle.svg" ) ), tr( "Polygon Label Settings…" ), this );
366  connect( item, &QAction::triggered, this, [ = ]( bool ) { addLabelSettings( QgsWkbTypes::PolygonGeometry ); } );
367  mMenuBtnAddItemAll->addAction( item );
368  mMenuBtnAddItemLabelSettings->addAction( item );
369 
370  mMenuBtnAddItemAll->addSeparator();
371  item = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "legend.svg" ) ), tr( "Marker Legend Patch Shape…" ), this );
372  connect( item, &QAction::triggered, this, [ = ]( bool ) { addLegendPatchShape( QgsSymbol::Marker ); } );
373  mMenuBtnAddItemAll->addAction( item );
374  mMenuBtnAddItemLegendPatchShape->addAction( item );
375  item = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "legend.svg" ) ), tr( "Line Legend Patch Shape…" ), this );
376  connect( item, &QAction::triggered, this, [ = ]( bool ) { addLegendPatchShape( QgsSymbol::Line ); } );
377  mMenuBtnAddItemAll->addAction( item );
378  mMenuBtnAddItemLegendPatchShape->addAction( item );
379  item = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "legend.svg" ) ), tr( "Fill Legend Patch Shape…" ), this );
380  connect( item, &QAction::triggered, this, [ = ]( bool ) { addLegendPatchShape( QgsSymbol::Fill ); } );
381  mMenuBtnAddItemAll->addAction( item );
382  mMenuBtnAddItemLegendPatchShape->addAction( item );
383 
384  connect( mMenuBtnAddItemColorRamp, &QMenu::triggered,
385  this, static_cast<bool ( QgsStyleManagerDialog::* )( QAction * )>( &QgsStyleManagerDialog::addColorRamp ) );
386  }
387 
388  // Context menu for symbols/colorramps. The menu entries for every group are created when displaying the menu.
389  mGroupMenu = new QMenu( this );
390  mGroupListMenu = new QMenu( mGroupMenu );
391  mGroupListMenu->setTitle( tr( "Add to Tag" ) );
392  mGroupListMenu->setEnabled( false );
393  if ( !mReadOnly )
394  {
395  connect( actnAddFavorite, &QAction::triggered, this, &QgsStyleManagerDialog::addFavoriteSelectedSymbols );
396  mGroupMenu->addAction( actnAddFavorite );
397  connect( actnRemoveFavorite, &QAction::triggered, this, &QgsStyleManagerDialog::removeFavoriteSelectedSymbols );
398  mGroupMenu->addAction( actnRemoveFavorite );
399  mGroupMenu->addSeparator()->setParent( this );
400  mGroupMenu->addMenu( mGroupListMenu );
401  actnDetag->setData( 0 );
402  connect( actnDetag, &QAction::triggered, this, &QgsStyleManagerDialog::detagSelectedSymbols );
403  mGroupMenu->addAction( actnDetag );
404  mGroupMenu->addSeparator()->setParent( this );
405  mGroupMenu->addAction( actnRemoveItem );
406  mGroupMenu->addAction( actnEditItem );
407  mGroupMenu->addAction( mActionCopyItem );
408  mGroupMenu->addAction( mActionPasteItem );
409  mGroupMenu->addSeparator()->setParent( this );
410  }
411  else
412  {
413  btnAddItem->setVisible( false );
414  btnRemoveItem->setVisible( false );
415  btnEditItem->setVisible( false );
416  btnAddSmartgroup->setVisible( false );
417  btnAddTag->setVisible( false );
418  btnManageGroups->setVisible( false );
419 
420  mGroupMenu->addAction( mActionCopyItem );
421  }
422  if ( mActionCopyToDefault )
423  {
424  mGroupMenu->addAction( mActionCopyToDefault );
425  }
426  mGroupMenu->addAction( actnExportAsPNG );
427  mGroupMenu->addAction( actnExportAsSVG );
428 
429  // Context menu for the group tree
430  mGroupTreeContextMenu = new QMenu( this );
431  if ( !mReadOnly )
432  {
433  connect( actnEditSmartGroup, &QAction::triggered, this, &QgsStyleManagerDialog::editSmartgroupAction );
434  mGroupTreeContextMenu->addAction( actnEditSmartGroup );
435  connect( actnAddTag, &QAction::triggered, this, [ = ]( bool ) { addTag(); }
436  );
437  mGroupTreeContextMenu->addAction( actnAddTag );
438  connect( actnAddSmartgroup, &QAction::triggered, this, [ = ]( bool ) { addSmartgroup(); }
439  );
440  mGroupTreeContextMenu->addAction( actnAddSmartgroup );
441  connect( actnRemoveGroup, &QAction::triggered, this, &QgsStyleManagerDialog::removeGroup );
442  mGroupTreeContextMenu->addAction( actnRemoveGroup );
443  }
444 
445  tabItemType_currentChanged( 0 );
446 
449 
450  connect( mButtonIconView, &QToolButton::toggled, this, [ = ]( bool active )
451  {
452  if ( active )
453  {
454  mSymbolViewStackedWidget->setCurrentIndex( 0 );
455  // note -- we have to save state here and not in destructor, as new symbol list widgets are created before the previous ones are destroyed
456  QgsSettings().setValue( QStringLiteral( "Windows/StyleV2Manager/lastIconView" ), 0, QgsSettings::Gui );
457  }
458  } );
459  connect( mButtonListView, &QToolButton::toggled, this, [ = ]( bool active )
460  {
461  if ( active )
462  {
463  QgsSettings().setValue( QStringLiteral( "Windows/StyleV2Manager/lastIconView" ), 1, QgsSettings::Gui );
464  mSymbolViewStackedWidget->setCurrentIndex( 1 );
465  }
466  } );
467  // restore previous view
468  const int currentView = settings.value( QStringLiteral( "Windows/StyleV2Manager/lastIconView" ), 0, QgsSettings::Gui ).toInt();
469  if ( currentView == 0 )
470  mButtonIconView->setChecked( true );
471  else
472  mButtonListView->setChecked( true );
473 
474  mSymbolTreeView->header()->restoreState( settings.value( QStringLiteral( "Windows/StyleV2Manager/treeState" ), QByteArray(), QgsSettings::Gui ).toByteArray() );
475  connect( mSymbolTreeView->header(), &QHeaderView::sectionResized, this, [this]
476  {
477  // note -- we have to save state here and not in destructor, as new symbol list widgets are created before the previous ones are destroyed
478  QgsSettings().setValue( QStringLiteral( "Windows/StyleV2Manager/treeState" ), mSymbolTreeView->header()->saveState(), QgsSettings::Gui );
479  } );
480 
481  // set initial disabled state for actions requiring a selection
482  selectedSymbolsChanged( QItemSelection(), QItemSelection() );
483 }
484 
486 {
487  if ( mModified && !mReadOnly )
488  {
489  mStyle->save();
490  }
491 
492  QgsSettings settings;
493  settings.setValue( QStringLiteral( "Windows/StyleV2Manager/splitter" ), mSplitter->saveState() );
494 }
495 
497 {
498 }
499 
500 void QgsStyleManagerDialog::tabItemType_currentChanged( int )
501 {
502  // when in Color Ramp tab, add menu to add item button and hide "Export symbols as PNG/SVG"
503  const bool isSymbol = currentItemType() != 3 && currentItemType() != 4 && currentItemType() != 5 && currentItemType() != 6;
504  const bool isColorRamp = currentItemType() == 3;
505  const bool isTextFormat = currentItemType() == 4;
506  const bool isLabelSettings = currentItemType() == 5;
507  searchBox->setPlaceholderText( isSymbol ? tr( "Filter symbols…" ) :
508  isColorRamp ? tr( "Filter color ramps…" ) :
509  isTextFormat ? tr( "Filter text symbols…" ) :
510  isLabelSettings ? tr( "Filter label settings…" ) : tr( "Filter legend patch shapes…" ) );
511 
512  if ( !mReadOnly && isColorRamp ) // color ramp tab
513  {
514  btnAddItem->setMenu( mMenuBtnAddItemColorRamp );
515  }
516  if ( !mReadOnly && !isSymbol && !isColorRamp && !isTextFormat && !isLabelSettings ) // legend patch shape tab
517  {
518  btnAddItem->setMenu( mMenuBtnAddItemLegendPatchShape );
519  }
520  else if ( !mReadOnly && isLabelSettings ) // label settings tab
521  {
522  btnAddItem->setMenu( mMenuBtnAddItemLabelSettings );
523  }
524  else if ( !mReadOnly && !isSymbol && !isColorRamp ) // text format tab
525  {
526  btnAddItem->setMenu( nullptr );
527  }
528  else if ( !mReadOnly && tabItemType->currentIndex() == 0 ) // all symbols tab
529  {
530  btnAddItem->setMenu( mMenuBtnAddItemAll );
531  }
532  else
533  {
534  btnAddItem->setMenu( nullptr );
535  }
536 
537  actnExportAsPNG->setVisible( isSymbol );
538  actnExportAsSVG->setVisible( isSymbol );
539 
540  mModel->setEntityFilter( isSymbol ? QgsStyle::SymbolEntity : ( isColorRamp ? QgsStyle::ColorrampEntity : isTextFormat ? QgsStyle::TextFormatEntity : isLabelSettings ? QgsStyle::LabelSettingsEntity : QgsStyle::LegendPatchShapeEntity ) );
541  mModel->setEntityFilterEnabled( !allTypesSelected() );
542  mModel->setSymbolTypeFilterEnabled( isSymbol && !allTypesSelected() );
543  if ( isSymbol && !allTypesSelected() )
544  mModel->setSymbolType( static_cast< QgsSymbol::SymbolType >( currentItemType() ) );
545 
546  populateList();
547 }
548 
549 void QgsStyleManagerDialog::copyItemsToDefault()
550 {
551  const QList< ItemDetails > items = selectedItems();
552  if ( !items.empty() )
553  {
554  bool ok = false;
555  QStringList options;
556  if ( !mBaseName.isEmpty() )
557  options.append( mBaseName );
558 
559  QStringList defaultTags = QgsStyle::defaultStyle()->tags();
560  defaultTags.sort( Qt::CaseInsensitive );
561  options.append( defaultTags );
562  const QString tags = QInputDialog::getItem( this, tr( "Import Items" ),
563  tr( "Additional tags to add (comma separated)" ), options, mBaseName.isEmpty() ? -1 : 0, true, &ok );
564  if ( !ok )
565  return;
566 
567  const QStringList parts = tags.split( ',', QString::SkipEmptyParts );
568  QStringList additionalTags;
569  additionalTags.reserve( parts.count() );
570  for ( const QString &tag : parts )
571  additionalTags << tag.trimmed();
572 
573  auto cursorOverride = qgis::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
574  const int count = copyItems( items, mStyle, QgsStyle::defaultStyle(), this, cursorOverride, true, additionalTags, false, false );
575  cursorOverride.reset();
576  if ( count > 0 )
577  {
578  mMessageBar->pushSuccess( tr( "Import Items" ), count > 1 ? tr( "Successfully imported %1 items." ).arg( count ) : tr( "Successfully imported item." ) );
579  }
580  }
581 }
582 
583 void QgsStyleManagerDialog::copyItem()
584 {
585  const QList< ItemDetails > items = selectedItems();
586  if ( items.empty() )
587  return;
588 
589  ItemDetails details = items.at( 0 );
590  switch ( details.entityType )
591  {
593  {
594  std::unique_ptr< QgsSymbol > symbol( mStyle->symbol( details.name ) );
595  if ( !symbol )
596  return;
597  QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::symbolToMimeData( symbol.get() ) );
598  break;
599  }
600 
602  {
603  const QgsTextFormat format( mStyle->textFormat( details.name ) );
604  QApplication::clipboard()->setMimeData( format.toMimeData() );
605  break;
606  }
607 
609  {
610  const QgsTextFormat format( mStyle->labelSettings( details.name ).format() );
611  QApplication::clipboard()->setMimeData( format.toMimeData() );
612  break;
613  }
614 
617  case QgsStyle::TagEntity:
619  return;
620 
621  }
622 }
623 
624 void QgsStyleManagerDialog::pasteItem()
625 {
626  const QString defaultTag = groupTree->currentIndex().isValid() ? groupTree->currentIndex().data().toString() : QString();
627  std::unique_ptr< QgsSymbol > tempSymbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
628  if ( tempSymbol )
629  {
630  QgsStyleSaveDialog saveDlg( this );
631  saveDlg.setWindowTitle( tr( "Paste Symbol" ) );
632  saveDlg.setDefaultTags( defaultTag );
633  if ( !saveDlg.exec() || saveDlg.name().isEmpty() )
634  return;
635 
636  if ( mStyle->symbolNames().contains( saveDlg.name() ) )
637  {
638  int res = QMessageBox::warning( this, tr( "Paste Symbol" ),
639  tr( "A symbol with the name '%1' already exists. Overwrite?" )
640  .arg( saveDlg.name() ),
641  QMessageBox::Yes | QMessageBox::No );
642  if ( res != QMessageBox::Yes )
643  {
644  return;
645  }
646  mStyle->removeSymbol( saveDlg.name() );
647  }
648 
649  QStringList symbolTags = saveDlg.tags().split( ',' );
650  mStyle->addSymbol( saveDlg.name(), tempSymbol->clone() );
651  // make sure the symbol is stored
652  mStyle->saveSymbol( saveDlg.name(), tempSymbol->clone(), saveDlg.isFavorite(), symbolTags );
653  return;
654  }
655 
656  bool ok = false;
657  const QgsTextFormat format = QgsTextFormat::fromMimeData( QApplication::clipboard()->mimeData(), &ok );
658  if ( ok )
659  {
660  QgsStyleSaveDialog saveDlg( this, QgsStyle::TextFormatEntity );
661  saveDlg.setDefaultTags( defaultTag );
662  saveDlg.setWindowTitle( tr( "Paste Text Format" ) );
663  if ( !saveDlg.exec() || saveDlg.name().isEmpty() )
664  return;
665 
666  if ( mStyle->textFormatNames().contains( saveDlg.name() ) )
667  {
668  int res = QMessageBox::warning( this, tr( "Paste Text Format" ),
669  tr( "A format with the name '%1' already exists. Overwrite?" )
670  .arg( saveDlg.name() ),
671  QMessageBox::Yes | QMessageBox::No );
672  if ( res != QMessageBox::Yes )
673  {
674  return;
675  }
676  mStyle->removeTextFormat( saveDlg.name() );
677  }
678 
679  QStringList symbolTags = saveDlg.tags().split( ',' );
680  mStyle->addTextFormat( saveDlg.name(), format );
681  // make sure the foprmatis stored
682  mStyle->saveTextFormat( saveDlg.name(), format, saveDlg.isFavorite(), symbolTags );
683  return;
684  }
685 }
686 
687 int QgsStyleManagerDialog::selectedItemType()
688 {
689  QModelIndex index = listItems->selectionModel()->currentIndex();
690  if ( !index.isValid() )
691  return 0;
692 
693  const QgsStyle::StyleEntity entity = static_cast< QgsStyle::StyleEntity >( mModel->data( index, QgsStyleModel::TypeRole ).toInt() );
694  if ( entity == QgsStyle::ColorrampEntity )
695  return 3;
696  else if ( entity == QgsStyle::TextFormatEntity )
697  return 4;
698  else if ( entity == QgsStyle::LabelSettingsEntity )
699  return 5;
700  else if ( entity == QgsStyle::LegendPatchShapeEntity )
701  return 6;
702 
703  return mModel->data( index, QgsStyleModel::SymbolTypeRole ).toInt();
704 }
705 
706 bool QgsStyleManagerDialog::allTypesSelected() const
707 {
708  return tabItemType->currentIndex() == 0;
709 }
710 
711 QList< QgsStyleManagerDialog::ItemDetails > QgsStyleManagerDialog::selectedItems()
712 {
713  QList<QgsStyleManagerDialog::ItemDetails > res;
714  QModelIndexList indices = listItems->selectionModel()->selectedRows();
715  for ( const QModelIndex &index : indices )
716  {
717  if ( !index.isValid() )
718  continue;
719 
720  ItemDetails details;
721  details.entityType = static_cast< QgsStyle::StyleEntity >( mModel->data( index, QgsStyleModel::TypeRole ).toInt() );
722  if ( details.entityType == QgsStyle::SymbolEntity )
723  details.symbolType = static_cast< QgsSymbol::SymbolType >( mModel->data( index, QgsStyleModel::SymbolTypeRole ).toInt() );
724  details.name = mModel->data( mModel->index( index.row(), QgsStyleModel::Name, index.parent() ), Qt::DisplayRole ).toString();
725 
726  res << details;
727  }
728  return res;
729 }
730 
731 int QgsStyleManagerDialog::copyItems( const QList<QgsStyleManagerDialog::ItemDetails> &items, QgsStyle *src, QgsStyle *dst, QWidget *parentWidget,
732  std::unique_ptr< QgsTemporaryCursorOverride > &cursorOverride, bool isImport, const QStringList &importTags, bool addToFavorites, bool ignoreSourceTags )
733 {
734  bool prompt = true;
735  bool overwriteAll = true;
736  int count = 0;
737 
738  const QStringList favoriteSymbols = src->symbolsOfFavorite( QgsStyle::SymbolEntity );
739  const QStringList favoriteColorramps = src->symbolsOfFavorite( QgsStyle::ColorrampEntity );
740  const QStringList favoriteTextFormats = src->symbolsOfFavorite( QgsStyle::TextFormatEntity );
741  const QStringList favoriteLabelSettings = src->symbolsOfFavorite( QgsStyle::LabelSettingsEntity );
742  const QStringList favoriteLegendPatchShapes = src->symbolsOfFavorite( QgsStyle::LegendPatchShapeEntity );
743 
744  for ( auto &details : items )
745  {
746  QStringList symbolTags;
747  if ( !ignoreSourceTags )
748  {
749  symbolTags = src->tagsOfSymbol( details.entityType, details.name );
750  }
751 
752  bool addItemToFavorites = false;
753  if ( isImport )
754  {
755  symbolTags << importTags;
756  addItemToFavorites = addToFavorites;
757  }
758 
759  switch ( details.entityType )
760  {
762  {
763  std::unique_ptr< QgsSymbol > symbol( src->symbol( details.name ) );
764  if ( !symbol )
765  continue;
766 
767  const bool hasDuplicateName = dst->symbolNames().contains( details.name );
768  bool overwriteThis = false;
769  if ( isImport )
770  addItemToFavorites = favoriteSymbols.contains( details.name );
771 
772  if ( hasDuplicateName && prompt )
773  {
774  cursorOverride.reset();
775  int res = QMessageBox::warning( parentWidget, isImport ? tr( "Import Symbol" ) : tr( "Export Symbol" ),
776  tr( "A symbol with the name “%1” already exists.\nOverwrite?" )
777  .arg( details.name ),
778  QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
779  cursorOverride = qgis::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
780  switch ( res )
781  {
782  case QMessageBox::Cancel:
783  return count;
784 
785  case QMessageBox::No:
786  continue;
787 
788  case QMessageBox::Yes:
789  overwriteThis = true;
790  break;
791 
792  case QMessageBox::YesToAll:
793  prompt = false;
794  overwriteAll = true;
795  break;
796 
797  case QMessageBox::NoToAll:
798  prompt = false;
799  overwriteAll = false;
800  break;
801  }
802  }
803 
804  if ( !hasDuplicateName || overwriteAll || overwriteThis )
805  {
806  QgsSymbol *newSymbol = symbol.get();
807  dst->addSymbol( details.name, symbol.release() );
808  dst->saveSymbol( details.name, newSymbol, addItemToFavorites, symbolTags );
809  count++;
810  }
811  break;
812  }
813 
815  {
816  std::unique_ptr< QgsColorRamp > ramp( src->colorRamp( details.name ) );
817  if ( !ramp )
818  continue;
819 
820  const bool hasDuplicateName = dst->colorRampNames().contains( details.name );
821  bool overwriteThis = false;
822  if ( isImport )
823  addItemToFavorites = favoriteColorramps.contains( details.name );
824 
825  if ( hasDuplicateName && prompt )
826  {
827  cursorOverride.reset();
828  int res = QMessageBox::warning( parentWidget, isImport ? tr( "Import Color Ramp" ) : tr( "Export Color Ramp" ),
829  tr( "A color ramp with the name “%1” already exists.\nOverwrite?" )
830  .arg( details.name ),
831  QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
832  cursorOverride = qgis::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
833  switch ( res )
834  {
835  case QMessageBox::Cancel:
836  return count;
837 
838  case QMessageBox::No:
839  continue;
840 
841  case QMessageBox::Yes:
842  overwriteThis = true;
843  break;
844 
845  case QMessageBox::YesToAll:
846  prompt = false;
847  overwriteAll = true;
848  break;
849 
850  case QMessageBox::NoToAll:
851  prompt = false;
852  overwriteAll = false;
853  break;
854  }
855  }
856 
857  if ( !hasDuplicateName || overwriteAll || overwriteThis )
858  {
859  QgsColorRamp *newRamp = ramp.get();
860  dst->addColorRamp( details.name, ramp.release() );
861  dst->saveColorRamp( details.name, newRamp, addItemToFavorites, symbolTags );
862  count++;
863  }
864  break;
865  }
866 
868  {
869  const QgsTextFormat format( src->textFormat( details.name ) );
870 
871  const bool hasDuplicateName = dst->textFormatNames().contains( details.name );
872  bool overwriteThis = false;
873  if ( isImport )
874  addItemToFavorites = favoriteTextFormats.contains( details.name );
875 
876  if ( hasDuplicateName && prompt )
877  {
878  cursorOverride.reset();
879  int res = QMessageBox::warning( parentWidget, isImport ? tr( "Import Text Format" ) : tr( "Export Text Format" ),
880  tr( "A text format with the name “%1” already exists.\nOverwrite?" )
881  .arg( details.name ),
882  QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
883  cursorOverride = qgis::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
884  switch ( res )
885  {
886  case QMessageBox::Cancel:
887  return count;
888 
889  case QMessageBox::No:
890  continue;
891 
892  case QMessageBox::Yes:
893  overwriteThis = true;
894  break;
895 
896  case QMessageBox::YesToAll:
897  prompt = false;
898  overwriteAll = true;
899  break;
900 
901  case QMessageBox::NoToAll:
902  prompt = false;
903  overwriteAll = false;
904  break;
905  }
906  }
907 
908  if ( !hasDuplicateName || overwriteAll || overwriteThis )
909  {
910  dst->addTextFormat( details.name, format );
911  dst->saveTextFormat( details.name, format, addItemToFavorites, symbolTags );
912  count++;
913  }
914  break;
915  }
916 
918  {
919  const QgsPalLayerSettings settings( src->labelSettings( details.name ) );
920 
921  const bool hasDuplicateName = dst->labelSettingsNames().contains( details.name );
922  bool overwriteThis = false;
923  if ( isImport )
924  addItemToFavorites = favoriteLabelSettings.contains( details.name );
925 
926  if ( hasDuplicateName && prompt )
927  {
928  cursorOverride.reset();
929  int res = QMessageBox::warning( parentWidget, isImport ? tr( "Import Label Settings" ) : tr( "Export Label Settings" ),
930  tr( "Label settings with the name “%1” already exist.\nOverwrite?" )
931  .arg( details.name ),
932  QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
933  cursorOverride = qgis::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
934  switch ( res )
935  {
936  case QMessageBox::Cancel:
937  return count;
938 
939  case QMessageBox::No:
940  continue;
941 
942  case QMessageBox::Yes:
943  overwriteThis = true;
944  break;
945 
946  case QMessageBox::YesToAll:
947  prompt = false;
948  overwriteAll = true;
949  break;
950 
951  case QMessageBox::NoToAll:
952  prompt = false;
953  overwriteAll = false;
954  break;
955  }
956  }
957 
958  if ( !hasDuplicateName || overwriteAll || overwriteThis )
959  {
960  dst->addLabelSettings( details.name, settings );
961  dst->saveLabelSettings( details.name, settings, addItemToFavorites, symbolTags );
962  count++;
963  }
964  break;
965  }
966 
968  {
969  const QgsLegendPatchShape shape( src->legendPatchShape( details.name ) );
970 
971  const bool hasDuplicateName = dst->legendPatchShapeNames().contains( details.name );
972  bool overwriteThis = false;
973  if ( isImport )
974  addItemToFavorites = favoriteLegendPatchShapes.contains( details.name );
975 
976  if ( hasDuplicateName && prompt )
977  {
978  cursorOverride.reset();
979  int res = QMessageBox::warning( parentWidget, isImport ? tr( "Import Legend Patch Shape" ) : tr( "Export Legend Patch Shape" ),
980  tr( "Legend patch shape with the name “%1” already exist.\nOverwrite?" )
981  .arg( details.name ),
982  QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
983  cursorOverride = qgis::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
984  switch ( res )
985  {
986  case QMessageBox::Cancel:
987  return count;
988 
989  case QMessageBox::No:
990  continue;
991 
992  case QMessageBox::Yes:
993  overwriteThis = true;
994  break;
995 
996  case QMessageBox::YesToAll:
997  prompt = false;
998  overwriteAll = true;
999  break;
1000 
1001  case QMessageBox::NoToAll:
1002  prompt = false;
1003  overwriteAll = false;
1004  break;
1005  }
1006  }
1007 
1008  if ( !hasDuplicateName || overwriteAll || overwriteThis )
1009  {
1010  dst->addLegendPatchShape( details.name, shape );
1011  dst->saveLegendPatchShape( details.name, shape, addItemToFavorites, symbolTags );
1012  count++;
1013  }
1014  break;
1015  }
1016 
1017  case QgsStyle::TagEntity:
1019  break;
1020 
1021  }
1022  }
1023  return count;
1024 }
1025 
1026 bool QgsStyleManagerDialog::addTextFormat()
1027 {
1028  QgsTextFormat format;
1029  QgsTextFormatDialog formatDlg( format, nullptr, this );
1030  if ( !formatDlg.exec() )
1031  return false;
1032  format = formatDlg.format();
1033 
1034  QgsStyleSaveDialog saveDlg( this, QgsStyle::TextFormatEntity );
1035  if ( !saveDlg.exec() )
1036  return false;
1037  QString name = saveDlg.name();
1038 
1039  // request valid/unique name
1040  bool nameInvalid = true;
1041  while ( nameInvalid )
1042  {
1043  // validate name
1044  if ( name.isEmpty() )
1045  {
1046  QMessageBox::warning( this, tr( "Save Text Format" ),
1047  tr( "Cannot save text format without name. Enter a name." ) );
1048  }
1049  else if ( mStyle->textFormatNames().contains( name ) )
1050  {
1051  int res = QMessageBox::warning( this, tr( "Save Text Format" ),
1052  tr( "Text format with name '%1' already exists. Overwrite?" )
1053  .arg( name ),
1054  QMessageBox::Yes | QMessageBox::No );
1055  if ( res == QMessageBox::Yes )
1056  {
1057  mStyle->removeTextFormat( name );
1058  nameInvalid = false;
1059  }
1060  }
1061  else
1062  {
1063  // valid name
1064  nameInvalid = false;
1065  }
1066  if ( nameInvalid )
1067  {
1068  bool ok;
1069  name = QInputDialog::getText( this, tr( "Text Format Name" ),
1070  tr( "Please enter a name for new text format:" ),
1071  QLineEdit::Normal, name, &ok );
1072  if ( !ok )
1073  {
1074  return false;
1075  }
1076  }
1077  }
1078 
1079  QStringList symbolTags = saveDlg.tags().split( ',' );
1080 
1081  // add new format to style and re-populate the list
1082  mStyle->addTextFormat( name, format );
1083  mStyle->saveTextFormat( name, format, saveDlg.isFavorite(), symbolTags );
1084 
1085  mModified = true;
1086  return true;
1087 }
1088 
1090 {
1091  groupChanged( groupTree->selectionModel()->currentIndex() );
1092 }
1093 
1094 void QgsStyleManagerDialog::populateSymbols( const QStringList &, bool )
1095 {
1096 }
1097 
1098 void QgsStyleManagerDialog::populateColorRamps( const QStringList &, bool )
1099 {
1100 }
1101 
1103 {
1104  switch ( tabItemType->currentIndex() )
1105  {
1106  case 1:
1107  return QgsSymbol::Marker;
1108  case 2:
1109  return QgsSymbol::Line;
1110  case 3:
1111  return QgsSymbol::Fill;
1112  case 4:
1113  return 3;
1114  case 5:
1115  return 4;
1116  case 6:
1117  return 5;
1118  case 7:
1119  return 6;
1120  default:
1121  return 0;
1122  }
1123 }
1124 
1126 {
1127  QModelIndex index = listItems->selectionModel()->currentIndex();
1128  if ( !index.isValid() )
1129  return QString();
1130 
1131  return mModel->data( mModel->index( index.row(), QgsStyleModel::Name, index.parent() ), Qt::DisplayRole ).toString();
1132 }
1133 
1135 {
1136  bool changed = false;
1137  if ( currentItemType() < 3 )
1138  {
1139  changed = addSymbol();
1140  }
1141  else if ( currentItemType() == 3 )
1142  {
1143  changed = addColorRamp();
1144  }
1145  else if ( currentItemType() == 4 )
1146  {
1147  changed = addTextFormat();
1148  }
1149  else if ( currentItemType() == 5 )
1150  {
1151  // actually never hit, because we present a submenu when adding label settings
1152  // changed = addLabelSettings();
1153  }
1154  else if ( currentItemType() == 6 )
1155  {
1156  // actually never hit, because we present a submenu when adding legend patches
1157  // changed = addLegendPatchShape();
1158  }
1159  else
1160  {
1161  Q_ASSERT( false && "not implemented" );
1162  }
1163 
1164  if ( changed )
1165  {
1166  populateList();
1167  }
1168 }
1169 
1170 bool QgsStyleManagerDialog::addSymbol( int symbolType )
1171 {
1172  // create new symbol with current type
1173  QgsSymbol *symbol = nullptr;
1174  QString name = tr( "new symbol" );
1175  switch ( symbolType == -1 ? currentItemType() : symbolType )
1176  {
1177  case QgsSymbol::Marker:
1178  symbol = new QgsMarkerSymbol();
1179  name = tr( "new marker" );
1180  break;
1181  case QgsSymbol::Line:
1182  symbol = new QgsLineSymbol();
1183  name = tr( "new line" );
1184  break;
1185  case QgsSymbol::Fill:
1186  symbol = new QgsFillSymbol();
1187  name = tr( "new fill symbol" );
1188  break;
1189  default:
1190  Q_ASSERT( false && "unknown symbol type" );
1191  return false;
1192  }
1193 
1194  // get symbol design
1195  // NOTE : Set the parent widget as "this" to notify the Symbol selector
1196  // that, it is being called by Style Manager, so recursive calling
1197  // of style manager and symbol selector can be arrested
1198  // See also: editSymbol()
1199  QgsSymbolSelectorDialog dlg( symbol, mStyle, nullptr, this );
1200  if ( dlg.exec() == 0 )
1201  {
1202  delete symbol;
1203  return false;
1204  }
1205 
1206  QgsStyleSaveDialog saveDlg( this );
1207  if ( !saveDlg.exec() )
1208  {
1209  delete symbol;
1210  return false;
1211  }
1212 
1213  name = saveDlg.name();
1214 
1215  // request valid/unique name
1216  bool nameInvalid = true;
1217  while ( nameInvalid )
1218  {
1219  // validate name
1220  if ( name.isEmpty() )
1221  {
1222  QMessageBox::warning( this, tr( "Save Symbol" ),
1223  tr( "Cannot save symbol without name. Enter a name." ) );
1224  }
1225  else if ( mStyle->symbolNames().contains( name ) )
1226  {
1227  int res = QMessageBox::warning( this, tr( "Save Symbol" ),
1228  tr( "Symbol with name '%1' already exists. Overwrite?" )
1229  .arg( name ),
1230  QMessageBox::Yes | QMessageBox::No );
1231  if ( res == QMessageBox::Yes )
1232  {
1233  mStyle->removeSymbol( name );
1234  nameInvalid = false;
1235  }
1236  }
1237  else
1238  {
1239  // valid name
1240  nameInvalid = false;
1241  }
1242  if ( nameInvalid )
1243  {
1244  bool ok;
1245  name = QInputDialog::getText( this, tr( "Symbol Name" ),
1246  tr( "Please enter a name for new symbol:" ),
1247  QLineEdit::Normal, name, &ok );
1248  if ( !ok )
1249  {
1250  delete symbol;
1251  return false;
1252  }
1253  }
1254  }
1255 
1256  QStringList symbolTags = saveDlg.tags().split( ',' );
1257 
1258  // add new symbol to style and re-populate the list
1259  mStyle->addSymbol( name, symbol );
1260  mStyle->saveSymbol( name, symbol, saveDlg.isFavorite(), symbolTags );
1261 
1262  mModified = true;
1263  return true;
1264 }
1265 
1266 
1267 QString QgsStyleManagerDialog::addColorRampStatic( QWidget *parent, QgsStyle *style, QString rampType )
1268 {
1269  // let the user choose the color ramp type if rampType is not given
1270  bool ok = true;
1271  if ( rampType.isEmpty() )
1272  {
1273  QStringList rampTypes;
1274  rampTypes << tr( "Gradient" ) << tr( "Color presets" ) << tr( "Random" ) << tr( "Catalog: cpt-city" );
1275  rampTypes << tr( "Catalog: ColorBrewer" );
1276  rampType = QInputDialog::getItem( parent, tr( "Color Ramp Type" ),
1277  tr( "Please select color ramp type:" ), rampTypes, 0, false, &ok );
1278  }
1279  if ( !ok || rampType.isEmpty() )
1280  return QString();
1281 
1282  QString name = tr( "new ramp" );
1283 
1284  std::unique_ptr< QgsColorRamp > ramp;
1285  if ( rampType == tr( "Gradient" ) )
1286  {
1288  if ( !dlg.exec() )
1289  {
1290  return QString();
1291  }
1292  ramp.reset( dlg.ramp().clone() );
1293  name = tr( "new gradient ramp" );
1294  }
1295  else if ( rampType == tr( "Random" ) )
1296  {
1298  if ( !dlg.exec() )
1299  {
1300  return QString();
1301  }
1302  ramp.reset( dlg.ramp().clone() );
1303  name = tr( "new random ramp" );
1304  }
1305  else if ( rampType == tr( "Catalog: ColorBrewer" ) )
1306  {
1308  if ( !dlg.exec() )
1309  {
1310  return QString();
1311  }
1312  ramp.reset( dlg.ramp().clone() );
1313  name = dlg.ramp().schemeName() + QString::number( dlg.ramp().colors() );
1314  }
1315  else if ( rampType == tr( "Color presets" ) )
1316  {
1318  if ( !dlg.exec() )
1319  {
1320  return QString();
1321  }
1322  ramp.reset( dlg.ramp().clone() );
1323  name = tr( "new preset ramp" );
1324  }
1325  else if ( rampType == tr( "Catalog: cpt-city" ) )
1326  {
1327  QgsCptCityColorRampDialog dlg( QgsCptCityColorRamp( QString(), QString() ), parent );
1328  if ( !dlg.exec() )
1329  {
1330  return QString();
1331  }
1332  // name = dlg.selectedName();
1333  name = QFileInfo( dlg.ramp().schemeName() ).baseName() + dlg.ramp().variantName();
1334  if ( dlg.saveAsGradientRamp() )
1335  {
1336  ramp.reset( dlg.ramp().cloneGradientRamp() );
1337  }
1338  else
1339  {
1340  ramp.reset( dlg.ramp().clone() );
1341  }
1342  }
1343  else
1344  {
1345  // Q_ASSERT( 0 && "invalid ramp type" );
1346  // bailing out is rather harsh!
1347  QgsDebugMsg( QStringLiteral( "invalid ramp type %1" ).arg( rampType ) );
1348  return QString();
1349  }
1350 
1351  QgsStyleSaveDialog saveDlg( parent, QgsStyle::ColorrampEntity );
1352  if ( !saveDlg.exec() )
1353  {
1354  return QString();
1355  }
1356 
1357  name = saveDlg.name();
1358 
1359  // get valid/unique name
1360  bool nameInvalid = true;
1361  while ( nameInvalid )
1362  {
1363  // validate name
1364  if ( name.isEmpty() )
1365  {
1366  QMessageBox::warning( parent, tr( "Save Color Ramp" ),
1367  tr( "Cannot save color ramp without name. Enter a name." ) );
1368  }
1369  else if ( style->colorRampNames().contains( name ) )
1370  {
1371  int res = QMessageBox::warning( parent, tr( "Save Color Ramp" ),
1372  tr( "Color ramp with name '%1' already exists. Overwrite?" )
1373  .arg( name ),
1374  QMessageBox::Yes | QMessageBox::No );
1375  if ( res == QMessageBox::Yes )
1376  {
1377  nameInvalid = false;
1378  }
1379  }
1380  else
1381  {
1382  // valid name
1383  nameInvalid = false;
1384  }
1385  if ( nameInvalid )
1386  {
1387  bool ok;
1388  name = QInputDialog::getText( parent, tr( "Color Ramp Name" ),
1389  tr( "Please enter a name for new color ramp:" ),
1390  QLineEdit::Normal, name, &ok );
1391  if ( !ok )
1392  {
1393  return QString();
1394  }
1395  }
1396  }
1397 
1398  QStringList colorRampTags = saveDlg.tags().split( ',' );
1399  QgsColorRamp *r = ramp.release();
1400 
1401  // add new symbol to style and re-populate the list
1402  style->addColorRamp( name, r );
1403  style->saveColorRamp( name, r, saveDlg.isFavorite(), colorRampTags );
1404 
1405  return name;
1406 }
1407 
1409 {
1410  mFavoritesGroupVisible = show;
1411  populateGroups();
1412 }
1413 
1415 {
1416  mSmartGroupVisible = show;
1417  populateGroups();
1418 }
1419 
1420 void QgsStyleManagerDialog::setBaseStyleName( const QString &name )
1421 {
1422  mBaseName = name;
1423 }
1424 
1426 {
1427  raise();
1428  setWindowState( windowState() & ~Qt::WindowMinimized );
1429  activateWindow();
1430 }
1431 
1433 {
1434  return addColorRamp( nullptr );
1435 }
1436 
1438 {
1439  // pass the action text, which is the color ramp type
1440  QString rampName = addColorRampStatic( this, mStyle,
1441  action ? action->text() : QString() );
1442  if ( !rampName.isEmpty() )
1443  {
1444  mModified = true;
1445  populateList();
1446  return true;
1447  }
1448 
1449  return false;
1450 }
1451 
1453 {
1454  if ( selectedItemType() < 3 )
1455  {
1456  editSymbol();
1457  }
1458  else if ( selectedItemType() == 3 )
1459  {
1460  editColorRamp();
1461  }
1462  else if ( selectedItemType() == 4 )
1463  {
1464  editTextFormat();
1465  }
1466  else if ( selectedItemType() == 5 )
1467  {
1468  editLabelSettings();
1469  }
1470  else if ( selectedItemType() == 6 )
1471  {
1472  editLegendPatchShape();
1473  }
1474  else
1475  {
1476  Q_ASSERT( false && "not implemented" );
1477  }
1478 }
1479 
1481 {
1482  QString symbolName = currentItemName();
1483  if ( symbolName.isEmpty() )
1484  return false;
1485 
1486  std::unique_ptr< QgsSymbol > symbol( mStyle->symbol( symbolName ) );
1487 
1488  // let the user edit the symbol and update list when done
1489  QgsSymbolSelectorDialog dlg( symbol.get(), mStyle, nullptr, this );
1490  if ( mReadOnly )
1491  dlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( false );
1492 
1493  if ( !dlg.exec() )
1494  return false;
1495 
1496  // by adding symbol to style with the same name the old effectively gets overwritten
1497  mStyle->addSymbol( symbolName, symbol.release(), true );
1498  mModified = true;
1499  return true;
1500 }
1501 
1503 {
1504  QString name = currentItemName();
1505  if ( name.isEmpty() )
1506  return false;
1507 
1508  std::unique_ptr< QgsColorRamp > ramp( mStyle->colorRamp( name ) );
1509 
1510  if ( ramp->type() == QLatin1String( "gradient" ) )
1511  {
1512  QgsGradientColorRamp *gradRamp = static_cast<QgsGradientColorRamp *>( ramp.get() );
1513  QgsGradientColorRampDialog dlg( *gradRamp, this );
1514  if ( mReadOnly )
1515  dlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( false );
1516 
1517  if ( !dlg.exec() )
1518  {
1519  return false;
1520  }
1521  ramp.reset( dlg.ramp().clone() );
1522  }
1523  else if ( ramp->type() == QLatin1String( "random" ) )
1524  {
1525  QgsLimitedRandomColorRamp *randRamp = static_cast<QgsLimitedRandomColorRamp *>( ramp.get() );
1526  QgsLimitedRandomColorRampDialog dlg( *randRamp, this );
1527  if ( mReadOnly )
1528  dlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( false );
1529 
1530  if ( !dlg.exec() )
1531  {
1532  return false;
1533  }
1534  ramp.reset( dlg.ramp().clone() );
1535  }
1536  else if ( ramp->type() == QLatin1String( "colorbrewer" ) )
1537  {
1538  QgsColorBrewerColorRamp *brewerRamp = static_cast<QgsColorBrewerColorRamp *>( ramp.get() );
1539  QgsColorBrewerColorRampDialog dlg( *brewerRamp, this );
1540  if ( mReadOnly )
1541  dlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( false );
1542 
1543  if ( !dlg.exec() )
1544  {
1545  return false;
1546  }
1547  ramp.reset( dlg.ramp().clone() );
1548  }
1549  else if ( ramp->type() == QLatin1String( "preset" ) )
1550  {
1551  QgsPresetSchemeColorRamp *presetRamp = static_cast<QgsPresetSchemeColorRamp *>( ramp.get() );
1552  QgsPresetColorRampDialog dlg( *presetRamp, this );
1553  if ( mReadOnly )
1554  dlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( false );
1555 
1556  if ( !dlg.exec() )
1557  {
1558  return false;
1559  }
1560  ramp.reset( dlg.ramp().clone() );
1561  }
1562  else if ( ramp->type() == QLatin1String( "cpt-city" ) )
1563  {
1564  QgsCptCityColorRamp *cptCityRamp = static_cast<QgsCptCityColorRamp *>( ramp.get() );
1565  QgsCptCityColorRampDialog dlg( *cptCityRamp, this );
1566  if ( mReadOnly )
1567  dlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( false );
1568 
1569  if ( !dlg.exec() )
1570  {
1571  return false;
1572  }
1573  if ( dlg.saveAsGradientRamp() )
1574  {
1575  ramp.reset( dlg.ramp().cloneGradientRamp() );
1576  }
1577  else
1578  {
1579  ramp.reset( dlg.ramp().clone() );
1580  }
1581  }
1582  else
1583  {
1584  Q_ASSERT( false && "invalid ramp type" );
1585  }
1586 
1587  mStyle->addColorRamp( name, ramp.release(), true );
1588  mModified = true;
1589  return true;
1590 }
1591 
1592 bool QgsStyleManagerDialog::editTextFormat()
1593 {
1594  const QString formatName = currentItemName();
1595  if ( formatName.isEmpty() )
1596  return false;
1597 
1598  QgsTextFormat format = mStyle->textFormat( formatName );
1599 
1600  // let the user edit the format and update list when done
1601  QgsTextFormatDialog dlg( format, nullptr, this );
1602  if ( mReadOnly )
1603  dlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( false );
1604 
1605  if ( !dlg.exec() )
1606  return false;
1607 
1608  // by adding format to style with the same name the old effectively gets overwritten
1609  mStyle->addTextFormat( formatName, dlg.format(), true );
1610  mModified = true;
1611  return true;
1612 }
1613 
1614 bool QgsStyleManagerDialog::addLabelSettings( QgsWkbTypes::GeometryType type )
1615 {
1616  QgsPalLayerSettings settings;
1617  QgsLabelSettingsDialog settingsDlg( settings, nullptr, nullptr, this, type );
1618  if ( mReadOnly )
1619  settingsDlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( false );
1620 
1621  if ( !settingsDlg.exec() )
1622  return false;
1623 
1624  settings = settingsDlg.settings();
1625  settings.layerType = type;
1626 
1627  QgsStyleSaveDialog saveDlg( this, QgsStyle::LabelSettingsEntity );
1628  if ( !saveDlg.exec() )
1629  return false;
1630  QString name = saveDlg.name();
1631 
1632  // request valid/unique name
1633  bool nameInvalid = true;
1634  while ( nameInvalid )
1635  {
1636  // validate name
1637  if ( name.isEmpty() )
1638  {
1639  QMessageBox::warning( this, tr( "Save Label Settings" ),
1640  tr( "Cannot save label settings without a name. Enter a name." ) );
1641  }
1642  else if ( mStyle->labelSettingsNames().contains( name ) )
1643  {
1644  int res = QMessageBox::warning( this, tr( "Save Label Settings" ),
1645  tr( "Label settings with the name '%1' already exist. Overwrite?" )
1646  .arg( name ),
1647  QMessageBox::Yes | QMessageBox::No );
1648  if ( res == QMessageBox::Yes )
1649  {
1650  mStyle->removeLabelSettings( name );
1651  nameInvalid = false;
1652  }
1653  }
1654  else
1655  {
1656  // valid name
1657  nameInvalid = false;
1658  }
1659  if ( nameInvalid )
1660  {
1661  bool ok;
1662  name = QInputDialog::getText( this, tr( "Label Settings Name" ),
1663  tr( "Please enter a name for the new label settings:" ),
1664  QLineEdit::Normal, name, &ok );
1665  if ( !ok )
1666  {
1667  return false;
1668  }
1669  }
1670  }
1671 
1672  QStringList symbolTags = saveDlg.tags().split( ',' );
1673 
1674  // add new format to style and re-populate the list
1675  mStyle->addLabelSettings( name, settings );
1676  mStyle->saveLabelSettings( name, settings, saveDlg.isFavorite(), symbolTags );
1677 
1678  mModified = true;
1679  return true;
1680 }
1681 
1682 bool QgsStyleManagerDialog::editLabelSettings()
1683 {
1684  const QString formatName = currentItemName();
1685  if ( formatName.isEmpty() )
1686  return false;
1687 
1688  QgsPalLayerSettings settings = mStyle->labelSettings( formatName );
1689  QgsWkbTypes::GeometryType geomType = settings.layerType;
1690 
1691  // let the user edit the settings and update list when done
1692  QgsLabelSettingsDialog dlg( settings, nullptr, nullptr, this, geomType );
1693  if ( !dlg.exec() )
1694  return false;
1695 
1696  settings = dlg.settings();
1697  settings.layerType = geomType;
1698 
1699  // by adding format to style with the same name the old effectively gets overwritten
1700  mStyle->addLabelSettings( formatName, settings, true );
1701  mModified = true;
1702  return true;
1703 }
1704 
1705 bool QgsStyleManagerDialog::addLegendPatchShape( QgsSymbol::SymbolType type )
1706 {
1707  QgsLegendPatchShape shape = mStyle->defaultPatch( type, QSizeF( 10, 5 ) );
1708  QgsLegendPatchShapeDialog dialog( shape, this );
1709  if ( mReadOnly )
1710  dialog.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( false );
1711 
1712  if ( !dialog.exec() )
1713  return false;
1714 
1715  shape = dialog.shape();
1716 
1717  QgsStyleSaveDialog saveDlg( this, QgsStyle::LegendPatchShapeEntity );
1718  if ( !saveDlg.exec() )
1719  return false;
1720  QString name = saveDlg.name();
1721 
1722  // request valid/unique name
1723  bool nameInvalid = true;
1724  while ( nameInvalid )
1725  {
1726  // validate name
1727  if ( name.isEmpty() )
1728  {
1729  QMessageBox::warning( this, tr( "Save Legend Patch Shape" ),
1730  tr( "Cannot save legend patch shapes without a name. Enter a name." ) );
1731  }
1732  else if ( mStyle->legendPatchShapeNames().contains( name ) )
1733  {
1734  int res = QMessageBox::warning( this, tr( "Save Legend Patch Shape" ),
1735  tr( "A legend patch shape with the name '%1' already exists. Overwrite?" )
1736  .arg( name ),
1737  QMessageBox::Yes | QMessageBox::No );
1738  if ( res == QMessageBox::Yes )
1739  {
1741  nameInvalid = false;
1742  }
1743  }
1744  else
1745  {
1746  // valid name
1747  nameInvalid = false;
1748  }
1749  if ( nameInvalid )
1750  {
1751  bool ok;
1752  name = QInputDialog::getText( this, tr( "Legend Patch Shape Name" ),
1753  tr( "Please enter a name for the new legend patch shape:" ),
1754  QLineEdit::Normal, name, &ok );
1755  if ( !ok )
1756  {
1757  return false;
1758  }
1759  }
1760  }
1761 
1762  QStringList symbolTags = saveDlg.tags().split( ',' );
1763 
1764  // add new shape to style and re-populate the list
1765  mStyle->addLegendPatchShape( name, shape );
1766  mStyle->saveLegendPatchShape( name, shape, saveDlg.isFavorite(), symbolTags );
1767 
1768  mModified = true;
1769  return true;
1770 }
1771 
1772 bool QgsStyleManagerDialog::editLegendPatchShape()
1773 {
1774  const QString shapeName = currentItemName();
1775  if ( shapeName.isEmpty() )
1776  return false;
1777 
1778  QgsLegendPatchShape shape = mStyle->legendPatchShape( shapeName );
1779  if ( shape.isNull() )
1780  return false;
1781 
1782  // let the user edit the shape and update list when done
1783  QgsLegendPatchShapeDialog dlg( shape, this );
1784  if ( !dlg.exec() )
1785  return false;
1786 
1787  shape = dlg.shape();
1788 
1789  // by adding shape to style with the same name the old effectively gets overwritten
1790  mStyle->addLegendPatchShape( shapeName, shape, true );
1791  mModified = true;
1792  return true;
1793 }
1794 
1796 {
1797  const QList< ItemDetails > items = selectedItems();
1798 
1799  if ( allTypesSelected() )
1800  {
1801  if ( QMessageBox::Yes != QMessageBox::question( this, tr( "Remove Items" ),
1802  QString( tr( "Do you really want to remove %n item(s)?", nullptr, items.count() ) ),
1803  QMessageBox::Yes,
1804  QMessageBox::No ) )
1805  return;
1806  }
1807  else
1808  {
1809  if ( currentItemType() < 3 )
1810  {
1811  if ( QMessageBox::Yes != QMessageBox::question( this, tr( "Remove Symbol" ),
1812  QString( tr( "Do you really want to remove %n symbol(s)?", nullptr, items.count() ) ),
1813  QMessageBox::Yes,
1814  QMessageBox::No ) )
1815  return;
1816  }
1817  else if ( currentItemType() == 3 )
1818  {
1819  if ( QMessageBox::Yes != QMessageBox::question( this, tr( "Remove Color Ramp" ),
1820  QString( tr( "Do you really want to remove %n ramp(s)?", nullptr, items.count() ) ),
1821  QMessageBox::Yes,
1822  QMessageBox::No ) )
1823  return;
1824  }
1825  else if ( currentItemType() == 4 )
1826  {
1827  if ( QMessageBox::Yes != QMessageBox::question( this, tr( "Remove Text Formats" ),
1828  QString( tr( "Do you really want to remove %n text format(s)?", nullptr, items.count() ) ),
1829  QMessageBox::Yes,
1830  QMessageBox::No ) )
1831  return;
1832  }
1833  else if ( currentItemType() == 5 )
1834  {
1835  if ( QMessageBox::Yes != QMessageBox::question( this, tr( "Remove Label Settings" ),
1836  QString( tr( "Do you really want to remove %n label settings?", nullptr, items.count() ) ),
1837  QMessageBox::Yes,
1838  QMessageBox::No ) )
1839  return;
1840  }
1841  else if ( currentItemType() == 6 )
1842  {
1843  if ( QMessageBox::Yes != QMessageBox::question( this, tr( "Remove Legend Patch Shapes" ),
1844  QString( tr( "Do you really want to remove %n legend patch shapes?", nullptr, items.count() ) ),
1845  QMessageBox::Yes,
1846  QMessageBox::No ) )
1847  return;
1848  }
1849  }
1850 
1851  QgsTemporaryCursorOverride override( Qt::WaitCursor );
1852 
1853  for ( const ItemDetails &details : items )
1854  {
1855  if ( details.name.isEmpty() )
1856  continue;
1857 
1858  mStyle->removeEntityByName( details.entityType, details.name );
1859  }
1860 
1861  mModified = true;
1862 }
1863 
1865 {
1866  return false;
1867 }
1868 
1870 {
1871  return false;
1872 }
1873 
1874 void QgsStyleManagerDialog::itemChanged( QStandardItem * )
1875 {
1876 }
1877 
1879 {
1880  QString dir = QFileDialog::getExistingDirectory( this, tr( "Export Selected Symbols as PNG" ),
1881  QDir::home().absolutePath(),
1882  QFileDialog::ShowDirsOnly
1883  | QFileDialog::DontResolveSymlinks );
1884  exportSelectedItemsImages( dir, QStringLiteral( "png" ), QSize( 32, 32 ) );
1885 }
1886 
1888 {
1889  QString dir = QFileDialog::getExistingDirectory( this, tr( "Export Selected Symbols as SVG" ),
1890  QDir::home().absolutePath(),
1891  QFileDialog::ShowDirsOnly
1892  | QFileDialog::DontResolveSymlinks );
1893  exportSelectedItemsImages( dir, QStringLiteral( "svg" ), QSize( 32, 32 ) );
1894 }
1895 
1896 
1897 void QgsStyleManagerDialog::exportSelectedItemsImages( const QString &dir, const QString &format, QSize size )
1898 {
1899  if ( dir.isEmpty() )
1900  return;
1901 
1902  const QList< ItemDetails > items = selectedItems();
1903  for ( const ItemDetails &details : items )
1904  {
1905  if ( details.entityType != QgsStyle::SymbolEntity )
1906  continue;
1907 
1908  QString path = dir + '/' + details.name + '.' + format;
1909  std::unique_ptr< QgsSymbol > sym( mStyle->symbol( details.name ) );
1910  if ( sym )
1911  sym->exportImage( path, format, size );
1912  }
1913 }
1914 
1916 {
1918  dlg.exec();
1919 }
1920 
1922 {
1924  dlg.exec();
1925  populateList();
1926  populateGroups();
1927 }
1928 
1929 void QgsStyleManagerDialog::setBold( QStandardItem *item )
1930 {
1931  QFont font = item->font();
1932  font.setBold( true );
1933  item->setFont( font );
1934 }
1935 
1937 {
1938  if ( mBlockGroupUpdates )
1939  return;
1940 
1941  QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
1942  model->clear();
1943 
1944  if ( mFavoritesGroupVisible )
1945  {
1946  QStandardItem *favoriteSymbols = new QStandardItem( tr( "Favorites" ) );
1947  favoriteSymbols->setData( "favorite" );
1948  favoriteSymbols->setEditable( false );
1949  setBold( favoriteSymbols );
1950  model->appendRow( favoriteSymbols );
1951  }
1952 
1953  QStandardItem *allSymbols = new QStandardItem( tr( "All" ) );
1954  allSymbols->setData( "all" );
1955  allSymbols->setEditable( false );
1956  setBold( allSymbols );
1957  model->appendRow( allSymbols );
1958 
1959  QStandardItem *taggroup = new QStandardItem( QString() ); //require empty name to get first order groups
1960  taggroup->setData( "tags" );
1961  taggroup->setEditable( false );
1962  QStringList tags = mStyle->tags();
1963  tags.sort();
1964  for ( const QString &tag : qgis::as_const( tags ) )
1965  {
1966  QStandardItem *item = new QStandardItem( tag );
1967  item->setData( mStyle->tagId( tag ) );
1968  item->setEditable( !mReadOnly );
1969  taggroup->appendRow( item );
1970  }
1971  taggroup->setText( tr( "Tags" ) );//set title later
1972  setBold( taggroup );
1973  model->appendRow( taggroup );
1974 
1975  if ( mSmartGroupVisible )
1976  {
1977  QStandardItem *smart = new QStandardItem( tr( "Smart Groups" ) );
1978  smart->setData( "smartgroups" );
1979  smart->setEditable( false );
1980  setBold( smart );
1981  QgsSymbolGroupMap sgMap = mStyle->smartgroupsListMap();
1982  QgsSymbolGroupMap::const_iterator i = sgMap.constBegin();
1983  while ( i != sgMap.constEnd() )
1984  {
1985  QStandardItem *item = new QStandardItem( i.value() );
1986  item->setData( i.key() );
1987  item->setEditable( !mReadOnly );
1988  smart->appendRow( item );
1989  ++i;
1990  }
1991  model->appendRow( smart );
1992  }
1993 
1994  // expand things in the group tree
1995  int rows = model->rowCount( model->indexFromItem( model->invisibleRootItem() ) );
1996  for ( int i = 0; i < rows; i++ )
1997  {
1998  groupTree->setExpanded( model->indexFromItem( model->item( i ) ), true );
1999  }
2000 }
2001 
2002 void QgsStyleManagerDialog::groupChanged( const QModelIndex &index )
2003 {
2004  QStringList groupSymbols;
2005 
2006  const QString category = index.data( Qt::UserRole + 1 ).toString();
2007  if ( mGroupingMode )
2008  {
2009  mModel->setTagId( -1 );
2010  mModel->setSmartGroupId( -1 );
2011  mModel->setFavoritesOnly( false );
2012  mModel->setCheckTag( index.data( Qt::DisplayRole ).toString() );
2013  }
2014  else if ( category == QLatin1String( "all" ) || category == QLatin1String( "tags" ) || category == QLatin1String( "smartgroups" ) )
2015  {
2016  enableGroupInputs( false );
2017  if ( category == QLatin1String( "tags" ) )
2018  {
2019  actnAddTag->setEnabled( !mReadOnly );
2020  actnAddSmartgroup->setEnabled( false );
2021  }
2022  else if ( category == QLatin1String( "smartgroups" ) )
2023  {
2024  actnAddTag->setEnabled( false );
2025  actnAddSmartgroup->setEnabled( !mReadOnly );
2026  }
2027 
2028  mModel->setTagId( -1 );
2029  mModel->setSmartGroupId( -1 );
2030  mModel->setFavoritesOnly( false );
2031  }
2032  else if ( category == QLatin1String( "favorite" ) )
2033  {
2034  enableGroupInputs( false );
2035  mModel->setTagId( -1 );
2036  mModel->setSmartGroupId( -1 );
2037  mModel->setFavoritesOnly( true );
2038  }
2039  else if ( index.parent().data( Qt::UserRole + 1 ) == "smartgroups" )
2040  {
2041  actnRemoveGroup->setEnabled( !mReadOnly );
2042  btnManageGroups->setEnabled( !mReadOnly );
2043  const int groupId = index.data( Qt::UserRole + 1 ).toInt();
2044  mModel->setTagId( -1 );
2045  mModel->setSmartGroupId( groupId );
2046  mModel->setFavoritesOnly( false );
2047  }
2048  else // tags
2049  {
2050  enableGroupInputs( true );
2051  int tagId = index.data( Qt::UserRole + 1 ).toInt();
2052  mModel->setTagId( tagId );
2053  mModel->setSmartGroupId( -1 );
2054  mModel->setFavoritesOnly( false );
2055  }
2056 
2057  actnEditSmartGroup->setVisible( false );
2058  actnAddTag->setVisible( false );
2059  actnAddSmartgroup->setVisible( false );
2060  actnRemoveGroup->setVisible( false );
2061  actnTagSymbols->setVisible( false );
2062  actnFinishTagging->setVisible( false );
2063 
2064  if ( index.parent().isValid() )
2065  {
2066  if ( index.parent().data( Qt::UserRole + 1 ).toString() == QLatin1String( "smartgroups" ) )
2067  {
2068  actnEditSmartGroup->setVisible( !mGroupingMode && !mReadOnly );
2069  }
2070  else if ( index.parent().data( Qt::UserRole + 1 ).toString() == QLatin1String( "tags" ) )
2071  {
2072  actnAddTag->setVisible( !mGroupingMode && !mReadOnly );
2073  actnTagSymbols->setVisible( !mGroupingMode && !mReadOnly );
2074  actnFinishTagging->setVisible( mGroupingMode && !mReadOnly );
2075  }
2076  actnRemoveGroup->setVisible( !mReadOnly );
2077  }
2078  else if ( index.data( Qt::UserRole + 1 ) == "smartgroups" )
2079  {
2080  actnAddSmartgroup->setVisible( !mGroupingMode && !mReadOnly );
2081  }
2082  else if ( index.data( Qt::UserRole + 1 ) == "tags" )
2083  {
2084  actnAddTag->setVisible( !mGroupingMode && !mReadOnly );
2085  }
2086 }
2087 
2089 {
2090  QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
2091  QModelIndex index;
2092  for ( int i = 0; i < groupTree->model()->rowCount(); i++ )
2093  {
2094  index = groupTree->model()->index( i, 0 );
2095  QString data = index.data( Qt::UserRole + 1 ).toString();
2096  if ( data == QLatin1String( "tags" ) )
2097  {
2098  break;
2099  }
2100  }
2101 
2102  QString itemName;
2103  int id;
2104  bool ok;
2105  itemName = QInputDialog::getText( this, tr( "Add Tag" ),
2106  tr( "Please enter name for the new tag:" ), QLineEdit::Normal, tr( "New tag" ), &ok ).trimmed();
2107  if ( !ok || itemName.isEmpty() )
2108  return 0;
2109 
2110  int check = mStyle->tagId( itemName );
2111  if ( check > 0 )
2112  {
2113  mMessageBar->pushCritical( tr( "Add Tag" ), tr( "The tag “%1” already exists." ).arg( itemName ) );
2114  return 0;
2115  }
2116 
2117  // block the auto-repopulation of groups when the style emits groupsModified
2118  // instead, we manually update the model items for better state retention
2119  mBlockGroupUpdates++;
2120  id = mStyle->addTag( itemName );
2121  mBlockGroupUpdates--;
2122 
2123  if ( !id )
2124  {
2125  mMessageBar->pushCritical( tr( "Add Tag" ), tr( "New tag could not be created — There was a problem with the symbol database." ) );
2126  return 0;
2127  }
2128 
2129  QStandardItem *parentItem = model->itemFromIndex( index );
2130  QStandardItem *childItem = new QStandardItem( itemName );
2131  childItem->setData( id );
2132  parentItem->appendRow( childItem );
2133 
2134  return id;
2135 }
2136 
2138 {
2139  QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
2140  QModelIndex index;
2141  for ( int i = 0; i < groupTree->model()->rowCount(); i++ )
2142  {
2143  index = groupTree->model()->index( i, 0 );
2144  QString data = index.data( Qt::UserRole + 1 ).toString();
2145  if ( data == QLatin1String( "smartgroups" ) )
2146  {
2147  break;
2148  }
2149  }
2150 
2151  QString itemName;
2152  int id;
2153  QgsSmartGroupEditorDialog dlg( mStyle, this );
2154  if ( dlg.exec() == QDialog::Rejected )
2155  return 0;
2156 
2157  // block the auto-repopulation of groups when the style emits groupsModified
2158  // instead, we manually update the model items for better state retention
2159  mBlockGroupUpdates++;
2160  id = mStyle->addSmartgroup( dlg.smartgroupName(), dlg.conditionOperator(), dlg.conditionMap() );
2161  mBlockGroupUpdates--;
2162 
2163  if ( !id )
2164  return 0;
2165  itemName = dlg.smartgroupName();
2166 
2167  QStandardItem *parentItem = model->itemFromIndex( index );
2168  QStandardItem *childItem = new QStandardItem( itemName );
2169  childItem->setData( id );
2170  parentItem->appendRow( childItem );
2171 
2172  return id;
2173 }
2174 
2176 {
2177  QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
2178  QModelIndex index = groupTree->currentIndex();
2179 
2180  // do not allow removal of system-defined groupings
2181  QString data = index.data( Qt::UserRole + 1 ).toString();
2182  if ( data == QLatin1String( "all" ) || data == QLatin1String( "favorite" ) || data == QLatin1String( "tags" ) || index.data() == "smartgroups" )
2183  {
2184  // should never appear -- blocked by GUI
2185  int err = QMessageBox::critical( this, tr( "Remove Group" ),
2186  tr( "Invalid selection. Cannot delete system defined categories.\n"
2187  "Kindly select a group or smart group you might want to delete." ) );
2188  if ( err )
2189  return;
2190  }
2191 
2192  QStandardItem *parentItem = model->itemFromIndex( index.parent() );
2193 
2194  // block the auto-repopulation of groups when the style emits groupsModified
2195  // instead, we manually update the model items for better state retention
2196  mBlockGroupUpdates++;
2197 
2198  if ( parentItem->data( Qt::UserRole + 1 ).toString() == QLatin1String( "smartgroups" ) )
2199  {
2200  mStyle->remove( QgsStyle::SmartgroupEntity, index.data( Qt::UserRole + 1 ).toInt() );
2201  }
2202  else
2203  {
2204  mStyle->remove( QgsStyle::TagEntity, index.data( Qt::UserRole + 1 ).toInt() );
2205  }
2206 
2207  mBlockGroupUpdates--;
2208  parentItem->removeRow( index.row() );
2209 }
2210 
2211 void QgsStyleManagerDialog::groupRenamed( QStandardItem *item )
2212 {
2213  QgsDebugMsg( QStringLiteral( "Symbol group edited: data=%1 text=%2" ).arg( item->data( Qt::UserRole + 1 ).toString(), item->text() ) );
2214  int id = item->data( Qt::UserRole + 1 ).toInt();
2215  QString name = item->text();
2216  mBlockGroupUpdates++;
2217  if ( item->parent()->data( Qt::UserRole + 1 ) == "smartgroups" )
2218  {
2219  mStyle->rename( QgsStyle::SmartgroupEntity, id, name );
2220  }
2221  else
2222  {
2223  mStyle->rename( QgsStyle::TagEntity, id, name );
2224  }
2225  mBlockGroupUpdates--;
2226 }
2227 
2229 {
2230  QStandardItemModel *treeModel = qobject_cast<QStandardItemModel *>( groupTree->model() );
2231 
2232  if ( mGroupingMode )
2233  {
2234  mGroupingMode = false;
2235  mModel->setCheckable( false );
2236  actnTagSymbols->setVisible( true );
2237  actnFinishTagging->setVisible( false );
2238  // disconnect slot which handles regrouping
2239 
2240  // disable all items except groups in groupTree
2242  groupChanged( groupTree->currentIndex() );
2243 
2244  // Finally: Reconnect all Symbol editing functionalities
2245  connect( treeModel, &QStandardItemModel::itemChanged,
2247 
2248  // Reset the selection mode
2249  listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
2250  mSymbolTreeView->setSelectionMode( QAbstractItemView::ExtendedSelection );
2251  }
2252  else
2253  {
2254  bool validGroup = false;
2255  // determine whether it is a valid group
2256  QModelIndex present = groupTree->currentIndex();
2257  while ( present.parent().isValid() )
2258  {
2259  if ( present.parent().data() == "Tags" )
2260  {
2261  validGroup = true;
2262  break;
2263  }
2264  present = present.parent();
2265  }
2266  if ( !validGroup )
2267  return;
2268 
2269  mGroupingMode = true;
2270  // Change visibility of actions
2271  actnTagSymbols->setVisible( false );
2272  actnFinishTagging->setVisible( true );
2273  // Remove all Symbol editing functionalities
2274  disconnect( treeModel, &QStandardItemModel::itemChanged,
2276 
2277  // disable all items except groups in groupTree
2278  enableItemsForGroupingMode( false );
2279  groupChanged( groupTree->currentIndex() );
2280  btnManageGroups->setEnabled( true );
2281 
2282  mModel->setCheckable( true );
2283 
2284  // No selection should be possible
2285  listItems->setSelectionMode( QAbstractItemView::NoSelection );
2286  mSymbolTreeView->setSelectionMode( QAbstractItemView::NoSelection );
2287  }
2288 }
2289 
2290 void QgsStyleManagerDialog::regrouped( QStandardItem * )
2291 {
2292 }
2293 
2294 void QgsStyleManagerDialog::setSymbolsChecked( const QStringList & )
2295 {
2296 }
2297 
2298 void QgsStyleManagerDialog::filterSymbols( const QString &qword )
2299 {
2300  mModel->setFilterString( qword );
2301 }
2302 
2303 void QgsStyleManagerDialog::symbolSelected( const QModelIndex &index )
2304 {
2305  actnEditItem->setEnabled( index.isValid() && !mGroupingMode && !mReadOnly );
2306 }
2307 
2308 void QgsStyleManagerDialog::selectedSymbolsChanged( const QItemSelection &selected, const QItemSelection &deselected )
2309 {
2310  Q_UNUSED( selected )
2311  Q_UNUSED( deselected )
2312  bool nothingSelected = listItems->selectionModel()->selectedIndexes().empty();
2313  actnRemoveItem->setDisabled( nothingSelected || mReadOnly );
2314  actnAddFavorite->setDisabled( nothingSelected || mReadOnly );
2315  actnRemoveFavorite->setDisabled( nothingSelected || mReadOnly );
2316  mGroupListMenu->setDisabled( nothingSelected || mReadOnly );
2317  actnDetag->setDisabled( nothingSelected || mReadOnly );
2318  actnExportAsPNG->setDisabled( nothingSelected );
2319  actnExportAsSVG->setDisabled( nothingSelected );
2320  if ( mActionCopyToDefault )
2321  mActionCopyToDefault->setDisabled( nothingSelected );
2322  mCopyToDefaultButton->setDisabled( nothingSelected );
2323  actnEditItem->setDisabled( nothingSelected || mReadOnly );
2324 }
2325 
2327 {
2328  groupTree->setEnabled( enable );
2329  btnAddTag->setEnabled( enable && !mReadOnly );
2330  btnAddSmartgroup->setEnabled( enable && !mReadOnly );
2331  actnAddTag->setEnabled( enable && !mReadOnly );
2332  actnAddSmartgroup->setEnabled( enable && !mReadOnly );
2333  actnRemoveGroup->setEnabled( enable && !mReadOnly );
2334  btnManageGroups->setEnabled( !mReadOnly && ( enable || mGroupingMode ) ); // always enabled in grouping mode, as it is the only way to leave grouping mode
2335  searchBox->setEnabled( enable );
2336 }
2337 
2339 {
2340  actnRemoveGroup->setEnabled( enable && !mReadOnly );
2341  btnManageGroups->setEnabled( !mReadOnly && ( enable || mGroupingMode ) ); // always enabled in grouping mode, as it is the only way to leave grouping mode
2342 }
2343 
2345 {
2346  QStandardItemModel *treeModel = qobject_cast<QStandardItemModel *>( groupTree->model() );
2347  for ( int i = 0; i < treeModel->rowCount(); i++ )
2348  {
2349  treeModel->item( i )->setEnabled( enable );
2350 
2351  if ( treeModel->item( i )->data() == "smartgroups" )
2352  {
2353  for ( int j = 0; j < treeModel->item( i )->rowCount(); j++ )
2354  {
2355  treeModel->item( i )->child( j )->setEnabled( enable );
2356  }
2357  }
2358  }
2359 
2360  // The buttons
2361  // NOTE: if you ever change the layout name in the .ui file edit here too
2362  for ( int i = 0; i < symbolBtnsLayout->count(); i++ )
2363  {
2364  QWidget *w = symbolBtnsLayout->itemAt( i )->widget();
2365  if ( w )
2366  w->setEnabled( enable );
2367  }
2368 
2369  // The actions
2370  actnRemoveItem->setEnabled( enable );
2371  actnEditItem->setEnabled( enable );
2372  mActionCopyItem->setEnabled( enable );
2373  mActionPasteItem->setEnabled( enable );
2374 }
2375 
2377 {
2378  QPoint globalPos = groupTree->viewport()->mapToGlobal( point );
2379 
2380  QModelIndex index = groupTree->indexAt( point );
2381  if ( index.isValid() && !mGroupingMode )
2382  mGroupTreeContextMenu->popup( globalPos );
2383 }
2384 
2386 {
2387  QPoint globalPos = mSymbolViewStackedWidget->currentIndex() == 0
2388  ? listItems->viewport()->mapToGlobal( point )
2389  : mSymbolTreeView->viewport()->mapToGlobal( point );
2390 
2391  // Clear all actions and create new actions for every group
2392  mGroupListMenu->clear();
2393 
2394  const QModelIndexList indices = listItems->selectionModel()->selectedRows();
2395 
2396  if ( !mReadOnly )
2397  {
2398  const QStringList currentTags = indices.count() == 1 ? indices.at( 0 ).data( QgsStyleModel::TagRole ).toStringList() : QStringList();
2399  QAction *a = nullptr;
2400  QStringList tags = mStyle->tags();
2401  tags.sort();
2402  for ( const QString &tag : qgis::as_const( tags ) )
2403  {
2404  a = new QAction( tag, mGroupListMenu );
2405  a->setData( tag );
2406  if ( indices.count() == 1 )
2407  {
2408  a->setCheckable( true );
2409  a->setChecked( currentTags.contains( tag ) );
2410  }
2411  connect( a, &QAction::triggered, this, [ = ]( bool ) { tagSelectedSymbols(); }
2412  );
2413  mGroupListMenu->addAction( a );
2414  }
2415 
2416  if ( tags.count() > 0 )
2417  {
2418  mGroupListMenu->addSeparator();
2419  }
2420  a = new QAction( tr( "Create New Tag…" ), mGroupListMenu );
2421  connect( a, &QAction::triggered, this, [ = ]( bool ) { tagSelectedSymbols( true ); }
2422  );
2423  mGroupListMenu->addAction( a );
2424  }
2425 
2426  const QList< ItemDetails > items = selectedItems();
2427  mActionCopyItem->setEnabled( !items.isEmpty() && ( items.at( 0 ).entityType != QgsStyle::ColorrampEntity ) );
2428 
2429  bool enablePaste = false;
2430  std::unique_ptr< QgsSymbol > tempSymbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
2431  if ( tempSymbol )
2432  enablePaste = true;
2433  else
2434  {
2435  ( void )QgsTextFormat::fromMimeData( QApplication::clipboard()->mimeData(), &enablePaste );
2436  }
2437  mActionPasteItem->setEnabled( enablePaste );
2438 
2439  mGroupMenu->popup( globalPos );
2440 }
2441 
2443 {
2444  const QList< ItemDetails > items = selectedItems();
2445  for ( const ItemDetails &details : items )
2446  {
2447  mStyle->addFavorite( details.entityType, details.name );
2448  }
2449 }
2450 
2452 {
2453  const QList< ItemDetails > items = selectedItems();
2454  for ( const ItemDetails &details : items )
2455  {
2456  mStyle->removeFavorite( details.entityType, details.name );
2457  }
2458 }
2459 
2461 {
2462  QAction *selectedItem = qobject_cast<QAction *>( sender() );
2463  if ( selectedItem )
2464  {
2465  const QList< ItemDetails > items = selectedItems();
2466  QString tag;
2467  if ( newTag )
2468  {
2469  int id = addTag();
2470  if ( id == 0 )
2471  {
2472  return;
2473  }
2474 
2475  tag = mStyle->tag( id );
2476  }
2477  else
2478  {
2479  tag = selectedItem->data().toString();
2480  }
2481 
2482  for ( const ItemDetails &details : items )
2483  {
2484  mStyle->tagSymbol( details.entityType, details.name, QStringList( tag ) );
2485  }
2486  }
2487 }
2488 
2490 {
2491  QAction *selectedItem = qobject_cast<QAction *>( sender() );
2492 
2493  if ( selectedItem )
2494  {
2495  const QList< ItemDetails > items = selectedItems();
2496  for ( const ItemDetails &details : items )
2497  {
2498  mStyle->detagSymbol( details.entityType, details.name );
2499  }
2500  }
2501 }
2502 
2504 {
2505  QStandardItemModel *treeModel = qobject_cast<QStandardItemModel *>( groupTree->model() );
2506 
2507  // determine whether it is a valid group
2508  QModelIndex present = groupTree->currentIndex();
2509  if ( present.parent().data( Qt::UserRole + 1 ) != "smartgroups" )
2510  {
2511  // should never appear - blocked by GUI logic
2512  QMessageBox::critical( this, tr( "Edit Smart Group" ),
2513  tr( "You have not selected a Smart Group. Kindly select a Smart Group to edit." ) );
2514  return;
2515  }
2516  QStandardItem *item = treeModel->itemFromIndex( present );
2517 
2518  QgsSmartGroupEditorDialog dlg( mStyle, this );
2519  QgsSmartConditionMap map = mStyle->smartgroup( present.data( Qt::UserRole + 1 ).toInt() );
2520  dlg.setSmartgroupName( item->text() );
2521  dlg.setOperator( mStyle->smartgroupOperator( item->data().toInt() ) );
2522  dlg.setConditionMap( map );
2523 
2524  if ( dlg.exec() == QDialog::Rejected )
2525  return;
2526 
2527  mBlockGroupUpdates++;
2528  mStyle->remove( QgsStyle::SmartgroupEntity, item->data().toInt() );
2529  int id = mStyle->addSmartgroup( dlg.smartgroupName(), dlg.conditionOperator(), dlg.conditionMap() );
2530  mBlockGroupUpdates--;
2531  if ( !id )
2532  {
2533  mMessageBar->pushCritical( tr( "Edit Smart Group" ), tr( "There was an error while editing the smart group." ) );
2534  return;
2535  }
2536  item->setText( dlg.smartgroupName() );
2537  item->setData( id );
2538 
2539  groupChanged( present );
2540 }
2541 
2543 {
2544  reject();
2545 }
2546 
2548 {
2549  QgsHelp::openHelp( QStringLiteral( "style_library/style_manager.html" ) );
2550 }
2551 
QgsSymbolSelectorDialog
Definition: qgssymbolselectordialog.h:263
QgsPresetColorRampDialog::buttonBox
QDialogButtonBox * buttonBox() const
Returns a reference to the dialog's button box.
Definition: qgspresetcolorrampdialog.cpp:125
QgsStyle::saveTextFormat
bool saveTextFormat(const QString &name, const QgsTextFormat &format, bool favorite, const QStringList &tags)
Adds a text format to the database.
Definition: qgsstyle.cpp:820
QgsColorRamp
Abstract base class for color ramps.
Definition: qgscolorramp.h:31
QgsStyleManagerDialog::currentItemName
QString currentItemName()
Definition: qgsstylemanagerdialog.cpp:1125
QgsPresetSchemeColorRamp::clone
QgsPresetSchemeColorRamp * clone() const override
Creates a clone of the color ramp.
Definition: qgscolorramp.cpp:892
QgsColorBrewerColorRampDialog::ramp
QgsColorBrewerColorRamp ramp
Definition: qgscolorbrewercolorrampdialog.h:89
QgsSymbolSelectorDialog::buttonBox
QDialogButtonBox * buttonBox() const
Returns a reference to the dialog's button box.
Definition: qgssymbolselectordialog.cpp:933
QgsPresetColorRampDialog
Definition: qgspresetcolorrampdialog.h:86
QgsStyle::ColorrampEntity
@ ColorrampEntity
Color ramps.
Definition: qgsstyle.h:182
QgsGradientColorRamp
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
Definition: qgscolorramp.h:139
QgsColorBrewerColorRamp::clone
QgsColorBrewerColorRamp * clone() const override
Creates a clone of the color ramp.
Definition: qgscolorramp.cpp:570
QgsStyle::tagSymbol
bool tagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Tags the symbol with the tags in the list.
Definition: qgsstyle.cpp:1530
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Definition: qgsapplication.cpp:605
QgsStyleModel
Definition: qgsstylemodel.h:45
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:174
QgsStyleManagerDialog::removeSymbol
Q_DECL_DEPRECATED bool removeSymbol() SIP_DEPRECATED
Definition: qgsstylemanagerdialog.cpp:1864
QgsLimitedRandomColorRampDialog::ramp
QgsLimitedRandomColorRamp ramp
Definition: qgslimitedrandomcolorrampdialog.h:101
QgsStyle::removeEntityByName
bool removeEntityByName(StyleEntity type, const QString &name)
Removes the entry of the specified type with matching name from the database.
Definition: qgsstyle.cpp:1286
QgsMessageBar::pushCritical
void pushCritical(const QString &title, const QString &message)
Pushes a critical warning message with default timeout to the message bar.
Definition: qgsmessagebar.cpp:209
QgsCptCityColorRampDialog::saveAsGradientRamp
bool saveAsGradientRamp() const
Returns true if the ramp should be converted to a QgsGradientColorRamp.
Definition: qgscptcitycolorrampdialog.cpp:501
QgsStyle::textFormat
QgsTextFormat textFormat(const QString &name) const
Returns the text format with the specified name.
Definition: qgsstyle.cpp:1895
QgsPalLayerSettings
Definition: qgspallabeling.h:205
qgsstylemanagerdialog.h
QgsStyle::symbolsOfFavorite
QStringList symbolsOfFavorite(StyleEntity type) const
Returns the symbol names which are flagged as favorite.
Definition: qgsstyle.cpp:1085
QgsSymbolLayerUtils::symbolFromMimeData
static QgsSymbol * symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
Definition: qgssymbollayerutils.cpp:3060
qgsgui.h
QgsStyle::labelSettingsNames
QStringList labelSettingsNames() const
Returns a list of names of label settings in the style.
Definition: qgsstyle.cpp:1951
QgsPresetSchemeColorRamp
A scheme based color ramp consisting of a list of predefined colors.
Definition: qgscolorramp.h:471
QgsLegendPatchShapeDialog
A dialog for configuring a custom legend patch shape.
Definition: qgslegendpatchshapewidget.h:79
qgssymbollayerutils.h
QgsStyleManagerDialog::enableItemsForGroupingMode
void enableItemsForGroupingMode(bool)
Enables or disables the groupTree items for grouping mode.
Definition: qgsstylemanagerdialog.cpp:2344
QgsGradientColorRampDialog
Definition: qgsgradientcolorrampdialog.h:38
QgsStyleManagerDialog::exportSelectedItemsImages
void exportSelectedItemsImages(const QString &dir, const QString &format, QSize size)
Triggers the dialog to export selected items as images of the specified format and size.
Definition: qgsstylemanagerdialog.cpp:1897
QgsCptCityColorRampDialog::ramp
QgsCptCityColorRamp ramp
Definition: qgscptcitycolorrampdialog.h:45
QgsGradientColorRamp::clone
QgsGradientColorRamp * clone() const override
Creates a clone of the color ramp.
Definition: qgscolorramp.cpp:190
QgsTextFormatDialog
Definition: qgstextformatwidget.h:323
QgsStyleManagerDialog::QgsStyleManagerDialog
QgsStyleManagerDialog(QgsStyle *style, QWidget *parent SIP_TRANSFERTHIS=nullptr, Qt::WindowFlags flags=Qt::WindowFlags(), bool readOnly=false)
Constructor for QgsStyleManagerDialog, with the specified parent widget and window flags.
Definition: qgsstylemanagerdialog.cpp:160
QgsStyle::addFavorite
bool addFavorite(StyleEntity type, const QString &name)
Adds the specified symbol to favorites.
Definition: qgsstyle.cpp:1401
QgsStyleManagerDialog::groupRenamed
void groupRenamed(QStandardItem *item)
Triggered when a group item is renamed.
Definition: qgsstylemanagerdialog.cpp:2211
QgsSettings
Definition: qgssettings.h:61
QgsStyleManagerDialog
Definition: qgsstylemanagerdialog.h:67
QgsStyleManagerDialog::addColorRampStatic
static QString addColorRampStatic(QWidget *parent, QgsStyle *style, QString RampType=QString())
Opens the add color ramp dialog, returning the new color ramp's name if the ramp has been added.
Definition: qgsstylemanagerdialog.cpp:1267
QgsCptCityColorRamp::variantName
QString variantName() const
Definition: qgscolorramp.h:667
QgsStyleManagerDialog::activate
void activate()
Raises, unminimizes and activates this window.
Definition: qgsstylemanagerdialog.cpp:1425
QgsStyleManagerDialog::editSymbol
bool editSymbol()
Definition: qgsstylemanagerdialog.cpp:1480
QgsSymbol
Definition: qgssymbol.h:63
QgsStyle::LegendPatchShapeEntity
@ LegendPatchShapeEntity
Legend patch shape (since QGIS 3.14)
Definition: qgsstyle.h:186
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsApplication::iconPath
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
Definition: qgsapplication.cpp:594
QgsStyle::saveColorRamp
bool saveColorRamp(const QString &name, QgsColorRamp *ramp, bool favorite, const QStringList &tags)
Adds the colorramp to the database.
Definition: qgsstyle.cpp:357
QgsStyleManagerDialog::setBaseStyleName
void setBaseStyleName(const QString &name)
Sets the base name for the style, which is used by the dialog to reflect the original style/XML file ...
Definition: qgsstylemanagerdialog.cpp:1420
QgsStyleManagerDialog::removeItem
void removeItem()
Removes the current selected item.
Definition: qgsstylemanagerdialog.cpp:1795
QgsStyle::defaultPatch
QgsLegendPatchShape defaultPatch(QgsSymbol::SymbolType type, QSizeF size) const
Returns the default legend patch shape for the given symbol type.
Definition: qgsstyle.cpp:1030
QgsLimitedRandomColorRamp
Constrained random color ramp, which returns random colors based on preset parameters.
Definition: qgscolorramp.h:283
QgsStyleManagerDialog::removeFavoriteSelectedSymbols
void removeFavoriteSelectedSymbols()
Remove selected symbols from favorites.
Definition: qgsstylemanagerdialog.cpp:2451
qgsstylesavedialog.h
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:143
QgsColorBrewerColorRamp
Color ramp utilising "Color Brewer" preset color schemes.
Definition: qgscolorramp.h:535
QgsStyle::symbol
QgsSymbol * symbol(const QString &name)
Returns a NEW copy of symbol.
Definition: qgsstyle.cpp:248
QgsCptCityColorRamp::cloneGradientRamp
QgsGradientColorRamp * cloneGradientRamp() const
Definition: qgscolorramp.cpp:662
QgsLegendPatchShape
Definition: qgslegendpatchshape.h:30
QgsStyle::SymbolEntity
@ SymbolEntity
Symbols.
Definition: qgsstyle.h:180
QgsStyleManagerDialog::groupChanged
void groupChanged(const QModelIndex &)
Triggered when the current group (or tag) is changed.
Definition: qgsstylemanagerdialog.cpp:2002
QgsCptCityColorRampDialog::buttonBox
QDialogButtonBox * buttonBox() const
Returns a reference to the dialog's button box.
Definition: qgscptcitycolorrampdialog.cpp:508
QgsStyle::addColorRamp
bool addColorRamp(const QString &name, QgsColorRamp *colorRamp, bool update=false)
Adds a color ramp to the style.
Definition: qgsstyle.cpp:270
QgsStyle::TagEntity
@ TagEntity
Tags.
Definition: qgsstyle.h:181
QgsGuiUtils::iconSize
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
Definition: qgsguiutils.cpp:264
QgsLimitedRandomColorRampDialog::buttonBox
QDialogButtonBox * buttonBox() const
Returns a reference to the dialog's button box.
Definition: qgslimitedrandomcolorrampdialog.cpp:135
QgsColorBrewerColorRampDialog::buttonBox
QDialogButtonBox * buttonBox() const
Returns a reference to the dialog's button box.
Definition: qgscolorbrewercolorrampdialog.cpp:141
QgsStyle::LabelSettingsEntity
@ LabelSettingsEntity
Label settings.
Definition: qgsstyle.h:185
QgsStyle::defaultStyle
static QgsStyle * defaultStyle()
Returns default application-wide style.
Definition: qgsstyle.cpp:111
QgsSymbolLayerUtils::symbolToMimeData
static QMimeData * symbolToMimeData(const QgsSymbol *symbol)
Creates new mime data from a symbol.
Definition: qgssymbollayerutils.cpp:3042
qgsapplication.h
QgsSmartGroupEditorDialog::setSmartgroupName
void setSmartgroupName(const QString &)
sets the smart group Name
Definition: qgssmartgroupeditordialog.cpp:196
QgsStyleManagerDialog::removeColorRamp
Q_DECL_DEPRECATED bool removeColorRamp() SIP_DEPRECATED
Definition: qgsstylemanagerdialog.cpp:1869
QgsStyleModel::TypeRole
@ TypeRole
Style entity type, see QgsStyle::StyleEntity.
Definition: qgsstylemodel.h:61
QgsStyleManagerDialog::exportItems
void exportItems()
Triggers the dialog to export items.
Definition: qgsstylemanagerdialog.cpp:1915
QgsStyle::detagSymbol
bool detagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Detags the symbol with the given list.
Definition: qgsstyle.cpp:1593
QgsGui::enableAutoGeometryRestore
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition: qgsgui.cpp:133
QgsStyleManagerDialog::addColorRamp
bool addColorRamp()
add a new color ramp to style
Definition: qgsstylemanagerdialog.cpp:1432
QgsStyleManagerDialog::populateTypes
Q_DECL_DEPRECATED void populateTypes() SIP_DEPRECATED
Populate combo box with known style items (symbols, color ramps).
Definition: qgsstylemanagerdialog.cpp:496
QgsStyleManagerDialog::onClose
void onClose()
Closes the dialog.
Definition: qgsstylemanagerdialog.cpp:2542
QgsTextFormat
Definition: qgstextformat.h:38
qgscolorbrewercolorrampdialog.h
QgsStyle::addSmartgroup
int addSmartgroup(const QString &name, const QString &op, const QgsSmartConditionMap &conditions)
Adds a new smartgroup to the database and returns the id.
Definition: qgsstyle.cpp:2023
QgsColorBrewerColorRampDialog
Definition: qgscolorbrewercolorrampdialog.h:86
QgsStyleManagerDialog::addSmartgroup
int addSmartgroup()
Triggers the dialog to add a new smart group.
Definition: qgsstylemanagerdialog.cpp:2137
QgsLimitedRandomColorRamp::clone
QgsLimitedRandomColorRamp * clone() const override
Creates a clone of the color ramp.
Definition: qgscolorramp.cpp:357
qgstextformatwidget.h
QgsStyle::addSymbol
bool addSymbol(const QString &name, QgsSymbol *symbol, bool update=false)
Adds a symbol to style and takes symbol's ownership.
Definition: qgsstyle.cpp:159
QgsStyle::addLegendPatchShape
bool addLegendPatchShape(const QString &name, const QgsLegendPatchShape &shape, bool update=false)
Adds a legend patch shape with the specified name to the style.
Definition: qgsstyle.cpp:336
QgsStyleManagerDialog::grouptreeContextMenu
void grouptreeContextMenu(QPoint)
Context menu for the groupTree.
Definition: qgsstylemanagerdialog.cpp:2376
QgsCptCityColorRampDialog
Definition: qgscptcitycolorrampdialog.h:42
QgsColorBrewerColorRamp::colors
int colors() const
Returns the number of colors in the ramp.
Definition: qgscolorramp.h:575
QgsTextFormat::fromMimeData
static QgsTextFormat fromMimeData(const QMimeData *data, bool *ok=nullptr)
Attempts to parse the provided mime data as a QgsTextFormat.
Definition: qgstextformat.cpp:524
qgscolorramp.h
QgsMarkerSymbol
Definition: qgssymbol.h:917
QgsStyle::removeFavorite
bool removeFavorite(StyleEntity type, const QString &name)
Removes the specified symbol from favorites.
Definition: qgsstyle.cpp:1437
QgsStyleExportImportDialog::Import
@ Import
Import xml file mode.
Definition: qgsstyleexportimportdialog.h:50
QgsStyleModel::TagRole
@ TagRole
String list of tags.
Definition: qgsstylemodel.h:62
QgsStyleManagerDialog::editItem
void editItem()
Triggers the dialog for editing the current item.
Definition: qgsstylemanagerdialog.cpp:1452
QgsStyle::tag
QString tag(int id) const
Returns the tag name for the given id.
Definition: qgsstyle.cpp:1815
QgsStyleManagerDialog::detagSelectedSymbols
void detagSelectedSymbols()
Remove all tags from selected symbols.
Definition: qgsstylemanagerdialog.cpp:2489
QgsCptCityColorRamp::schemeName
QString schemeName() const
Definition: qgscolorramp.h:666
QgsPalLayerSettings::format
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc.
Definition: qgspallabeling.h:1015
QgsStyleManagerDialog::enableGroupInputs
void enableGroupInputs(bool)
Enables or disables the groupTree specific inputs.
Definition: qgsstylemanagerdialog.cpp:2338
QgsCptCityColorRamp::clone
QgsCptCityColorRamp * clone() const override
Creates a clone of the color ramp.
Definition: qgscolorramp.cpp:640
QgsApplication::defaultStyleModel
static QgsStyleModel * defaultStyleModel()
Returns a shared QgsStyleModel containing the default style library (see QgsStyle::defaultStyle()).
Definition: qgsapplication.cpp:2184
QgsColorBrewerColorRamp::schemeName
QString schemeName() const
Returns the name of the color brewer color scheme.
Definition: qgscolorramp.h:569
QgsStyleManagerDialog::importItems
void importItems()
Triggers the dialog to import items.
Definition: qgsstylemanagerdialog.cpp:1921
QgsStyle::tags
QStringList tags() const
Returns a list of all tags in the style database.
Definition: qgsstyle.cpp:1185
QgsStyleManagerDialog::enableSymbolInputs
void enableSymbolInputs(bool)
Enables or disbables the symbol specific inputs.
Definition: qgsstylemanagerdialog.cpp:2326
QgsMessageBar
Definition: qgsmessagebar.h:60
QgsLineSymbol
Definition: qgssymbol.h:1117
qgssmartgroupeditordialog.h
QgsStyleManagerDialog::setBold
void setBold(QStandardItem *)
sets the text of the item with bold font
Definition: qgsstylemanagerdialog.cpp:1929
QgsStyleManagerDialog::setFavoritesGroupVisible
void setFavoritesGroupVisible(bool show)
Sets whether the favorites group should be shown.
Definition: qgsstylemanagerdialog.cpp:1408
QgsStyle::SmartgroupEntity
@ SmartgroupEntity
Smart groups.
Definition: qgsstyle.h:183
Qgis::UI_SCALE_FACTOR
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition: qgis.h:195
QgsStyleManagerDialog::editSmartgroupAction
void editSmartgroupAction()
Triggers the dialog for editing the selected smart group.
Definition: qgsstylemanagerdialog.cpp:2503
QgsStyleManagerDialog::addFavoriteSelectedSymbols
void addFavoriteSelectedSymbols()
Add selected symbols to favorites.
Definition: qgsstylemanagerdialog.cpp:2442
QgsStyle::smartgroupsListMap
QgsSymbolGroupMap smartgroupsListMap()
Returns the smart groups map with id as key and name as value.
Definition: qgsstyle.cpp:2075
QgsLimitedRandomColorRampDialog
Definition: qgslimitedrandomcolorrampdialog.h:98
QgsStyleManagerDialog::editColorRamp
bool editColorRamp()
Definition: qgsstylemanagerdialog.cpp:1502
qgsmessagebar.h
qgsstylemodel.h
QgsStyle::groupsModified
void groupsModified()
Emitted every time a tag or smartgroup has been added, removed, or renamed.
QgsSymbol::Fill
@ Fill
Fill symbol.
Definition: qgssymbol.h:89
QgsSmartGroupEditorDialog::setOperator
void setOperator(const QString &)
sets the operator AND/OR
Definition: qgssmartgroupeditordialog.cpp:191
QgsSettings::setValue
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Definition: qgssettings.cpp:289
QgsStyle::removeLabelSettings
bool removeLabelSettings(const QString &name)
Removes label settings from the style.
Definition: qgsstyle.cpp:928
QgsStyleManagerDialog::symbolSelected
void symbolSelected(const QModelIndex &)
Perform symbol specific tasks when selected.
Definition: qgsstylemanagerdialog.cpp:2303
QgsSmartGroupEditorDialog::setConditionMap
void setConditionMap(const QgsSmartConditionMap &)
sets up the GUI for the given conditionmap
Definition: qgssmartgroupeditordialog.cpp:160
QgsStyleManagerDialog::onFinished
void onFinished()
Called when the dialog is going to be closed.
Definition: qgsstylemanagerdialog.cpp:485
qgssymbolselectordialog.h
QgsStyleManagerDialog::tagSelectedSymbols
void tagSelectedSymbols(bool newTag=false)
Tag selected symbols using menu item selection.
Definition: qgsstylemanagerdialog.cpp:2460
qgsstyleexportimportdialog.h
QgsStyle::symbolNames
QStringList symbolNames() const
Returns a list of names of symbols.
Definition: qgsstyle.cpp:264
QgsStyleModel::SymbolTypeRole
@ SymbolTypeRole
Symbol type (for symbol or legend patch shape entities)
Definition: qgsstylemodel.h:63
QgsSmartGroupEditorDialog::conditionOperator
QString conditionOperator()
returns the AND/OR condition
Definition: qgssmartgroupeditordialog.cpp:155
QgsStyleManagerDialog::populateList
void populateList()
Refreshes the list of items.
Definition: qgsstylemanagerdialog.cpp:1089
QgsStyleManagerDialog::removeGroup
void removeGroup()
Removes the selected tag or smartgroup.
Definition: qgsstylemanagerdialog.cpp:2175
QgsStyle::smartgroup
QgsSmartConditionMap smartgroup(int id)
Returns the QgsSmartConditionMap for the given id.
Definition: qgsstyle.cpp:2216
QgsStyle::removeSymbol
bool removeSymbol(const QString &name)
Removes symbol from style (and delete it)
Definition: qgsstyle.cpp:217
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:142
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:141
QgsStyleManagerDialog::listitemsContextMenu
void listitemsContextMenu(QPoint)
Context menu for the listItems ( symbols list )
Definition: qgsstylemanagerdialog.cpp:2385
QgsStyle::legendPatchShape
QgsLegendPatchShape legendPatchShape(const QString &name) const
Returns the legend patch shape with the specified name.
Definition: qgsstyle.cpp:1920
QgsStyleManagerDialog::populateGroups
void populateGroups()
populate the groups
Definition: qgsstylemanagerdialog.cpp:1936
QgsStyle::textFormatNames
QStringList textFormatNames() const
Returns a list of names of text formats in the style.
Definition: qgsstyle.cpp:1905
QgsGradientColorRampDialog::ramp
QgsGradientColorRamp ramp
Definition: qgsgradientcolorrampdialog.h:41
QgsStyleManagerDialog::setSymbolsChecked
Q_DECL_DEPRECATED void setSymbolsChecked(const QStringList &) SIP_DEPRECATED
Definition: qgsstylemanagerdialog.cpp:2294
QgsStyleExportImportDialog::Export
@ Export
Export existing symbols mode.
Definition: qgsstyleexportimportdialog.h:49
QgsGui::instance
static QgsGui * instance()
Returns a pointer to the singleton instance.
Definition: qgsgui.cpp:62
QgsStyleManagerDialog::tagSymbolsAction
void tagSymbolsAction()
Toggles the interactive item tagging mode.
Definition: qgsstylemanagerdialog.cpp:2228
QgsWkbTypes::GeometryType
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:139
QgsMessageBar::pushSuccess
void pushSuccess(const QString &title, const QString &message)
Pushes a success message with default timeout to the message bar.
Definition: qgsmessagebar.cpp:194
QgsStyleManagerDialog::filterSymbols
void filterSymbols(const QString &filter)
Sets the filter string to filter symbols by.
Definition: qgsstylemanagerdialog.cpp:2298
QgsStyle::rename
bool rename(StyleEntity type, int id, const QString &newName)
Renames the given entity with the specified id.
Definition: qgsstyle.cpp:1205
QgsStyle
Definition: qgsstyle.h:159
QgsStyle::TextFormatEntity
@ TextFormatEntity
Text formats.
Definition: qgsstyle.h:184
QgsHelp::openHelp
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
QgsStyleManagerDialog::exportItemsSVG
void exportItemsSVG()
Triggers the dialog to export selected items as SVG files.
Definition: qgsstylemanagerdialog.cpp:1887
QgsSymbolGroupMap
QMap< int, QString > QgsSymbolGroupMap
Definition: qgsstyle.h:42
QgsStyleManagerDialog::setSmartGroupsVisible
void setSmartGroupsVisible(bool show)
Sets whether smart groups should be shown.
Definition: qgsstylemanagerdialog.cpp:1414
QgsStyleManagerDialog::addTag
int addTag()
Triggers the dialog to add a new tag.
Definition: qgsstylemanagerdialog.cpp:2088
QgsStyle::symbolSaved
void symbolSaved(const QString &name, QgsSymbol *symbol)
Emitted every time a new symbol has been added to the database.
qgssettings.h
qgslimitedrandomcolorrampdialog.h
QgsStyle::smartgroupOperator
QString smartgroupOperator(int id)
Returns the operator for the smartgroup.
Definition: qgsstyle.cpp:2256
QgsFillSymbol
Definition: qgssymbol.h:1212
QgsStyleManagerDialog::itemChanged
Q_DECL_DEPRECATED void itemChanged(QStandardItem *item) SIP_DEPRECATED
Definition: qgsstylemanagerdialog.cpp:1874
QgsStyleManagerDialog::showHelp
void showHelp()
Opens the associated help.
Definition: qgsstylemanagerdialog.cpp:2547
QgsSymbol::Line
@ Line
Line symbol.
Definition: qgssymbol.h:88
QgsStyleManagerDialog::addItem
void addItem()
Triggers the dialog for adding a new item, based on the currently selected item type tab.
Definition: qgsstylemanagerdialog.cpp:1134
QgsSmartGroupEditorDialog::smartgroupName
QString smartgroupName()
returns the value from mNameLineEdit
Definition: qgssmartgroupeditordialog.cpp:98
QgsSymbol::Marker
@ Marker
Marker symbol.
Definition: qgssymbol.h:87
qgsgradientcolorrampdialog.h
QgsStyle::addLabelSettings
bool addLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool update=false)
Adds label settings with the specified name to the style.
Definition: qgsstyle.cpp:315
QgsStyle::saveSymbol
bool saveSymbol(const QString &name, QgsSymbol *symbol, bool favorite, const QStringList &tags)
Adds the symbol to the database with tags.
Definition: qgsstyle.cpp:183
QgsStyle::colorRampNames
QStringList colorRampNames() const
Returns a list of names of color ramps.
Definition: qgsstyle.cpp:412
QgsSmartGroupEditorDialog::conditionMap
QgsSmartConditionMap conditionMap()
returns the condition map
Definition: qgssmartgroupeditordialog.cpp:142
QgsStyleManagerDialog::selectedSymbolsChanged
void selectedSymbolsChanged(const QItemSelection &selected, const QItemSelection &deselected)
Perform tasks when the selected symbols change.
Definition: qgsstylemanagerdialog.cpp:2308
QgsCptCityColorRamp
Definition: qgscolorramp.h:626
QgsSymbol::SymbolType
SymbolType
Type of the symbol.
Definition: qgssymbol.h:85
QgsStyle::remove
bool remove(StyleEntity type, int id)
Removes the specified entity from the database.
Definition: qgsstyle.cpp:1240
QgsGradientColorRampDialog::buttonBox
QDialogButtonBox * buttonBox() const
Returns a reference to the dialog's button box.
Definition: qgsgradientcolorrampdialog.cpp:182
qgslogger.h
QgsStyle::saveLegendPatchShape
bool saveLegendPatchShape(const QString &name, const QgsLegendPatchShape &shape, bool favorite, const QStringList &tags)
Adds a legend patch shape to the database.
Definition: qgsstyle.cpp:968
QgsStyle::legendPatchShapeNames
QStringList legendPatchShapeNames() const
Returns a list of names of legend patch shapes in the style.
Definition: qgsstyle.cpp:1961
qgscptcitycolorrampdialog.h
QgsStyle::tagsOfSymbol
QStringList tagsOfSymbol(StyleEntity type, const QString &symbol)
Returns the tags associated with the symbol.
Definition: qgsstyle.cpp:1686
QgsStyle::removeTextFormat
bool removeTextFormat(const QString &name)
Removes a text format from the style.
Definition: qgsstyle.cpp:854
qgspresetcolorrampdialog.h
QgsStyle::addTextFormat
bool addTextFormat(const QString &name, const QgsTextFormat &format, bool update=false)
Adds a text format with the specified name to the style.
Definition: qgsstyle.cpp:294
QgsStyleManagerDialog::addSymbol
bool addSymbol(int symbolType=-1)
add a new symbol to style
Definition: qgsstylemanagerdialog.cpp:1170
QgsStyleProxyModel
Definition: qgsstylemodel.h:137
QgsStyle::labelSettings
QgsPalLayerSettings labelSettings(const QString &name) const
Returns the label settings with the specified name.
Definition: qgsstyle.cpp:1915
QgsSmartConditionMap
QMultiMap< QString, QString > QgsSmartConditionMap
Definition: qgsstyle.h:79
QgsPalLayerSettings::layerType
QgsWkbTypes::GeometryType layerType
Geometry type of layers associated with these settings.
Definition: qgspallabeling.h:940
qgssymbol.h
QgsStyleExportImportDialog
Definition: qgsstyleexportimportdialog.h:40
QgsStyle::saveLabelSettings
bool saveLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool favorite, const QStringList &tags)
Adds label settings to the database.
Definition: qgsstyle.cpp:894
QgsStyleManagerDialog::currentItemType
int currentItemType()
Definition: qgsstylemanagerdialog.cpp:1102
qgslabelinggui.h
QgsStyle::save
bool save(QString filename=QString())
Saves style into a file (will use current filename if empty string is passed)
Definition: qgsstyle.cpp:699
QgsStyle::colorRamp
QgsColorRamp * colorRamp(const QString &name) const
Returns a new copy of the specified color ramp.
Definition: qgsstyle.cpp:396
QgsStyleManagerDialog::populateSymbols
Q_DECL_DEPRECATED void populateSymbols(const QStringList &symbolNames, bool checkable=false) SIP_DEPRECATED
Populates the list view with symbols of the current type with the given names.
Definition: qgsstylemanagerdialog.cpp:1094
QgsSmartGroupEditorDialog
Definition: qgssmartgroupeditordialog.h:71
QgsStyleManagerDialog::exportItemsPNG
void exportItemsPNG()
Triggers the dialog to export selected items as PNG files.
Definition: qgsstylemanagerdialog.cpp:1878
QgsTemporaryCursorOverride
Temporarily sets a cursor override for the QApplication for the lifetime of the object.
Definition: qgsguiutils.h:203
QgsStyleManagerDialog::regrouped
Q_DECL_DEPRECATED void regrouped(QStandardItem *) SIP_DEPRECATED
Definition: qgsstylemanagerdialog.cpp:2290
QgsPresetColorRampDialog::ramp
QgsPresetSchemeColorRamp ramp
Definition: qgspresetcolorrampdialog.h:89
QgsSettings::Gui
@ Gui
Definition: qgssettings.h:71
QgsStyle::tagId
int tagId(const QString &tag)
Returns the database id for the given tag name.
Definition: qgsstyle.cpp:1985
QgsStyleModel::Name
@ Name
Name column.
Definition: qgsstylemodel.h:54
QgsStyleManagerDialog::populateColorRamps
Q_DECL_DEPRECATED void populateColorRamps(const QStringList &colorRamps, bool checkable=false) SIP_DEPRECATED
Populates the list view with color ramps of the current type with the given names.
Definition: qgsstylemanagerdialog.cpp:1098
QgsStyle::StyleEntity
StyleEntity
Enum for Entities involved in a style.
Definition: qgsstyle.h:178
qgslegendpatchshapewidget.h
QgsLegendPatchShape::isNull
bool isNull() const
Returns true if the patch shape is a null QgsLegendPatchShape, which indicates that the default legen...
Definition: qgslegendpatchshape.cpp:32
QgsStyle::addTag
int addTag(const QString &tagName)
Adds a new tag and returns the tag's id.
Definition: qgsstyle.cpp:1165