50 #include <QFileDialog> 
   51 #include <QInputDialog> 
   52 #include <QMessageBox> 
   53 #include <QPushButton> 
   54 #include <QStandardItemModel> 
   57 #include <QDesktopServices> 
   69 QgsCheckableStyleModel::QgsCheckableStyleModel( 
QgsStyleModel *sourceModel, QObject *parent, 
bool readOnly )
 
   71   , mStyle( sourceModel->style() )
 
   72   , mReadOnly( readOnly )
 
   77 QgsCheckableStyleModel::QgsCheckableStyleModel( 
QgsStyle *style, QObject *parent, 
bool readOnly )
 
   80   , mReadOnly( readOnly )
 
   84 void QgsCheckableStyleModel::setCheckable( 
bool checkable )
 
   86   if ( checkable == mCheckable )
 
   89   mCheckable = checkable;
 
   90   emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ), QVector< int >() << Qt::CheckStateRole );
 
   93 void QgsCheckableStyleModel::setCheckTag( 
const QString &tag )
 
   95   if ( tag == mCheckTag )
 
   99   emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ), QVector< int >() << Qt::CheckStateRole );
 
  102 Qt::ItemFlags QgsCheckableStyleModel::flags( 
const QModelIndex &index )
 const 
  104   Qt::ItemFlags f = QgsStyleProxyModel::flags( index );
 
  105   if ( !mReadOnly && mCheckable && index.column() == 0 )
 
  106     f |= Qt::ItemIsUserCheckable;
 
  109     f &= ~Qt::ItemIsEditable;
 
  114 QVariant QgsCheckableStyleModel::data( 
const QModelIndex &index, 
int role )
 const 
  121       QFont f = QgsStyleProxyModel::data( index, role ).value< QFont >();
 
  126     case Qt::CheckStateRole:
 
  128       if ( !mCheckable || index.column() != 0 )
 
  132       return tags.contains( mCheckTag ) ? Qt::Checked : Qt::Unchecked;
 
  139   return QgsStyleProxyModel::data( index, role );
 
  142 bool QgsCheckableStyleModel::setData( 
const QModelIndex &i, 
const QVariant &value, 
int role )
 
  144   if ( i.row() < 0 || i.row() >= rowCount( QModelIndex() ) ||
 
  145        ( role != Qt::EditRole && role != Qt::CheckStateRole ) )
 
  151   if ( role == Qt::CheckStateRole )
 
  153     if ( !mCheckable || mCheckTag.isEmpty() )
 
  156     const QString name = data( index( i.row(), 
QgsStyleModel::Name ), Qt::DisplayRole ).toString();
 
  159     if ( value.toInt() == Qt::Checked )
 
  160       return mStyle->tagSymbol( entity, name, QStringList() << mCheckTag );
 
  162       return mStyle->detagSymbol( entity, name, QStringList() << mCheckTag );
 
  164   return QgsStyleProxyModel::setData( i, value, role );
 
  174 QString QgsStyleManagerDialog::sPreviousTag;
 
  177   : QDialog( parent, flags )
 
  178   , mReadOnly( readOnly )
 
  181   setCurrentStyle( style );
 
  182   mStyleDatabaseWidget->hide();
 
  186   : QDialog( parent, flags )
 
  192   mComboBoxStyleDatabase->setModel( mProjectStyleModel );
 
  196   connect( mComboBoxStyleDatabase, qOverload< int >( &QComboBox::currentIndexChanged ), 
this, [ = ]()
 
  198     if ( mBlockStyleDatabaseChanges )
 
  201     const QModelIndex index = mProjectStyleModel->index( mComboBoxStyleDatabase->currentIndex(), 0, QModelIndex() );
 
  205   connect( mButtonAddStyleDatabase, &QAbstractButton::clicked, 
this, [ = ] { addStyleDatabase( 
false ); } );
 
  206   connect( mButtonNewStyleDatabase, &QAbstractButton::clicked, 
this, [ = ] { addStyleDatabase( 
true ); } );
 
  208 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0) 
  210   mStyleDatabaseWidget->hide();
 
  214 void QgsStyleManagerDialog::init()
 
  218   connect( tabItemType, &QTabWidget::currentChanged, 
this, &QgsStyleManagerDialog::tabItemType_currentChanged );
 
  222   QPushButton *downloadButton = buttonBox->addButton( tr( 
"Browse Online Styles" ), QDialogButtonBox::ResetRole );
 
  223   downloadButton->setToolTip( tr( 
"Download new styles from the online QGIS style repository" ) );
 
  225   connect( downloadButton, &QPushButton::clicked, 
this, [ = ]
 
  227     QDesktopServices::openUrl( QUrl( QStringLiteral( 
"https://plugins.qgis.org/styles" ) ) );
 
  231   mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
 
  232   mVerticalLayout->insertWidget( 0,  mMessageBar );
 
  235   setWindowModality( Qt::WindowModal );
 
  240   mSplitter->setSizes( QList<int>() << 170 << 540 );
 
  241   mSplitter->restoreState( settings.
value( QStringLiteral( 
"Windows/StyleV2Manager/splitter" ) ).toByteArray() );
 
  243   tabItemType->setDocumentMode( 
true );
 
  244   searchBox->setShowSearchIcon( 
true );
 
  245   searchBox->setPlaceholderText( tr( 
"Filter symbols…" ) );
 
  249   connect( btnEditItem, &QPushButton::clicked, 
this, [ = ]( 
bool ) { 
editItem(); }
 
  251   connect( actnEditItem, &QAction::triggered, 
this, [ = ]( 
bool ) { 
editItem(); }
 
  255   connect( btnAddItem, &QPushButton::clicked, 
this, [ = ]( 
bool )
 
  258     if ( !btnAddItem->menu() )
 
  265   connect( btnRemoveItem, &QPushButton::clicked, 
this, [ = ]( 
bool ) { 
removeItem(); }
 
  267   connect( actnRemoveItem, &QAction::triggered, 
this, [ = ]( 
bool ) { 
removeItem(); }
 
  270   mShareMenu = 
new QMenu( tr( 
"Share Menu" ), 
this );
 
  271   mExportAction = 
new QAction( tr( 
"Export Item(s)…" ), 
this );
 
  273   mShareMenu->addAction( mExportAction );
 
  275   connect( mCopyToDefaultButton, &QPushButton::clicked, 
this, &QgsStyleManagerDialog::copyItemsToDefault );
 
  277   mActionCopyItem = 
new QAction( tr( 
"Copy Item" ), 
this );
 
  278   connect( mActionCopyItem, &QAction::triggered, 
this, &QgsStyleManagerDialog::copyItem );
 
  279   mActionPasteItem = 
new QAction( tr( 
"Paste Item…" ), 
this );
 
  280   connect( mActionPasteItem, &QAction::triggered, 
this, &QgsStyleManagerDialog::pasteItem );
 
  282   QShortcut *copyShortcut = 
new QShortcut( QKeySequence( QKeySequence::StandardKey::Copy ), 
this );
 
  283   connect( copyShortcut, &QShortcut::activated, 
this, &QgsStyleManagerDialog::copyItem );
 
  284   QShortcut *pasteShortcut = 
new QShortcut( QKeySequence( QKeySequence::StandardKey::Paste ), 
this );
 
  285   connect( pasteShortcut, &QShortcut::activated, 
this, &QgsStyleManagerDialog::pasteItem );
 
  286   QShortcut *removeShortcut = 
new QShortcut( QKeySequence( QKeySequence::StandardKey::Delete ), 
this );
 
  288   QShortcut *editShortcut = 
new QShortcut( QKeySequence( Qt::Key_Return ), 
this );
 
  291   mShareMenu->addSeparator();
 
  292   mShareMenu->addAction( actnExportAsPNG );
 
  293   mShareMenu->addAction( actnExportAsSVG );
 
  298   btnShare->setMenu( mShareMenu );
 
  300   listItems->setTextElideMode( Qt::TextElideMode::ElideRight );
 
  302   mSymbolTreeView->setIconSize( QSize( 
static_cast< int >( treeIconSize ), 
static_cast< int >( treeIconSize ) ) );
 
  304   listItems->setSelectionBehavior( QAbstractItemView::SelectRows );
 
  305   listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
 
  306   mSymbolTreeView->setSelectionMode( listItems->selectionMode() );
 
  308   QStandardItemModel *groupModel = 
new QStandardItemModel( groupTree );
 
  309   groupTree->setModel( groupModel );
 
  310   groupTree->setHeaderHidden( 
true );
 
  312   connect( groupTree->selectionModel(), &QItemSelectionModel::currentChanged,
 
  316   QMenu *groupMenu = 
new QMenu( tr( 
"Group Actions" ), 
this );
 
  318   groupMenu->addAction( actnTagSymbols );
 
  320   actnFinishTagging->setVisible( 
false );
 
  321   groupMenu->addAction( actnFinishTagging );
 
  322   groupMenu->addAction( actnEditSmartGroup );
 
  323   btnManageGroups->setMenu( groupMenu );
 
  328   groupTree->setContextMenuPolicy( Qt::CustomContextMenu );
 
  329   connect( groupTree, &QWidget::customContextMenuRequested,
 
  333   listItems->setContextMenuPolicy( Qt::CustomContextMenu );
 
  334   connect( listItems, &QWidget::customContextMenuRequested,
 
  336   mSymbolTreeView->setContextMenuPolicy( Qt::CustomContextMenu );
 
  337   connect( mSymbolTreeView, &QWidget::customContextMenuRequested,
 
  340   mMenuBtnAddItemAll = 
new QMenu( 
this );
 
  341   mMenuBtnAddItemColorRamp = 
new QMenu( 
this );
 
  342   mMenuBtnAddItemLabelSettings = 
new QMenu( 
this );
 
  343   mMenuBtnAddItemLegendPatchShape = 
new QMenu( 
this );
 
  344   mMenuBtnAddItemSymbol3D = 
new QMenu( 
this );
 
  348   mMenuBtnAddItemAll->addAction( item );
 
  351   mMenuBtnAddItemAll->addAction( item );
 
  354   mMenuBtnAddItemAll->addAction( item );
 
  355   mMenuBtnAddItemAll->addSeparator();
 
  358   for ( 
const QPair< QString, QString > &rampType : rampTypes )
 
  360     item = 
new QAction( 
QgsApplication::getThemeIcon( QStringLiteral( 
"styleicons/color.svg" ) ), tr( 
"%1…" ).arg( rampType.second ), 
this );
 
  361     connect( item, &QAction::triggered, 
this, [ = ]( 
bool ) { 
addColorRamp( rampType.first ); } );
 
  362     mMenuBtnAddItemAll->addAction( item );
 
  363     mMenuBtnAddItemColorRamp->addAction( item );
 
  365   mMenuBtnAddItemAll->addSeparator();
 
  367   connect( item, &QAction::triggered, 
this, [ = ]( 
bool ) { addTextFormat(); } );
 
  368   mMenuBtnAddItemAll->addAction( item );
 
  369   mMenuBtnAddItemAll->addSeparator();
 
  372   mMenuBtnAddItemAll->addAction( item );
 
  373   mMenuBtnAddItemLabelSettings->addAction( item );
 
  376   mMenuBtnAddItemAll->addAction( item );
 
  377   mMenuBtnAddItemLabelSettings->addAction( item );
 
  380   mMenuBtnAddItemAll->addAction( item );
 
  381   mMenuBtnAddItemLabelSettings->addAction( item );
 
  383   mMenuBtnAddItemAll->addSeparator();
 
  386   mMenuBtnAddItemAll->addAction( item );
 
  387   mMenuBtnAddItemLegendPatchShape->addAction( item );
 
  389   connect( item, &QAction::triggered, 
this, [ = ]( 
bool ) {  addLegendPatchShape( 
Qgis::SymbolType::Line ); } );
 
  390   mMenuBtnAddItemAll->addAction( item );
 
  391   mMenuBtnAddItemLegendPatchShape->addAction( item );
 
  393   connect( item, &QAction::triggered, 
this, [ = ]( 
bool ) {  addLegendPatchShape( 
Qgis::SymbolType::Fill ); } );
 
  394   mMenuBtnAddItemAll->addAction( item );
 
  395   mMenuBtnAddItemLegendPatchShape->addAction( item );
 
  397   mMenuBtnAddItemAll->addSeparator();
 
  399   connect( item, &QAction::triggered, 
this, [ = ]( 
bool ) { addSymbol3D( QStringLiteral( 
"point" ) ); } );
 
  400   mMenuBtnAddItemAll->addAction( item );
 
  401   mMenuBtnAddItemSymbol3D->addAction( item );
 
  403   connect( item, &QAction::triggered, 
this, [ = ]( 
bool ) {  addSymbol3D( QStringLiteral( 
"line" ) ); } );
 
  404   mMenuBtnAddItemAll->addAction( item );
 
  405   mMenuBtnAddItemSymbol3D->addAction( item );
 
  407   connect( item, &QAction::triggered, 
this, [ = ]( 
bool ) {  addSymbol3D( QStringLiteral( 
"polygon" ) ); } );
 
  408   mMenuBtnAddItemAll->addAction( item );
 
  409   mMenuBtnAddItemSymbol3D->addAction( item );
 
  412   mGroupMenu = 
new QMenu( 
this );
 
  413   mGroupListMenu = 
new QMenu( mGroupMenu );
 
  414   mGroupListMenu->setTitle( tr( 
"Add to Tag" ) );
 
  415   mGroupListMenu->setEnabled( 
false );
 
  422   mGroupTreeContextMenu = 
new QMenu( 
this );
 
  424   connect( actnAddTag, &QAction::triggered, 
this, [ = ]( 
bool ) { 
addTag(); } );
 
  425   connect( actnAddSmartgroup, &QAction::triggered, 
this, [ = ]( 
bool ) { 
addSmartgroup(); } );
 
  428   tabItemType_currentChanged( 0 );
 
  430   connect( mButtonIconView, &QToolButton::toggled, 
this, [ = ]( 
bool active )
 
  434       mSymbolViewStackedWidget->setCurrentIndex( 0 );
 
  439   connect( mButtonListView, &QToolButton::toggled, 
this, [ = ]( 
bool active )
 
  444       mSymbolViewStackedWidget->setCurrentIndex( 1 );
 
  448   const int currentView = settings.
value( QStringLiteral( 
"Windows/StyleV2Manager/lastIconView" ), 0, 
QgsSettings::Gui ).toInt();
 
  449   if ( currentView == 0 )
 
  450     mButtonIconView->setChecked( 
true );
 
  452     mButtonListView->setChecked( 
true );
 
  454   mSymbolTreeView->header()->restoreState( settings.
value( QStringLiteral( 
"Windows/StyleV2Manager/treeState" ), QByteArray(), 
QgsSettings::Gui ).toByteArray() );
 
  455   connect( mSymbolTreeView->header(), &QHeaderView::sectionResized, 
this, [
this]
 
  458     QgsSettings().setValue( QStringLiteral( 
"Windows/StyleV2Manager/treeState" ), mSymbolTreeView->header()->saveState(), QgsSettings::Gui );
 
  461   const int thumbnailSize = settings.
value( QStringLiteral( 
"Windows/StyleV2Manager/thumbnailSize" ), 0, 
QgsSettings::Gui ).toInt();
 
  462   mSliderIconSize->setValue( thumbnailSize );
 
  463   connect( mSliderIconSize, &QSlider::valueChanged, 
this, &QgsStyleManagerDialog::setThumbnailSize );
 
  464   setThumbnailSize( thumbnailSize );
 
  467 void QgsStyleManagerDialog::setCurrentStyle( 
QgsStyle *style )
 
  469   if ( mStyle == style )
 
  479   QgsCheckableStyleModel *oldModel = mModel;
 
  482   const bool readOnly = isReadOnly();
 
  485     if ( !mActionCopyToDefault )
 
  487       mActionCopyToDefault = 
new QAction( tr( 
"Copy Selection to Default Style…" ), 
this );
 
  488       mShareMenu->insertAction( mActionCopyItem, mActionCopyToDefault );
 
  489       connect( mActionCopyToDefault, &QAction::triggered, 
this, &QgsStyleManagerDialog::copyItemsToDefault );
 
  491     mCopyToDefaultButton->show();
 
  492     mModel = 
new QgsCheckableStyleModel( mStyle, 
this, readOnly );
 
  496     mCopyToDefaultButton->hide();
 
  497     if ( mActionCopyToDefault )
 
  499       mActionCopyToDefault->deleteLater();
 
  500       mActionCopyToDefault = 
nullptr;
 
  504   mModel->addDesiredIconSize( mSymbolTreeView->iconSize() );
 
  505   mModel->addDesiredIconSize( listItems->iconSize() );
 
  506   mModel->setFilterString( searchBox->text() );
 
  508   listItems->setModel( mModel );
 
  509   mSymbolTreeView->setModel( mModel );
 
  511   mSymbolTreeView->setSelectionModel( listItems->selectionModel() );
 
  513   connect( listItems->selectionModel(), &QItemSelectionModel::currentChanged,
 
  515   connect( listItems->selectionModel(), &QItemSelectionModel::selectionChanged,
 
  520     oldModel->deleteLater();
 
  528   if ( mProjectStyleModel )
 
  530     const QModelIndex styleIndex = mProjectStyleModel->
indexFromStyle( mStyle );
 
  531     mBlockStyleDatabaseChanges++;
 
  532     mComboBoxStyleDatabase->setCurrentIndex( styleIndex.row() );
 
  533     mBlockStyleDatabaseChanges--;
 
  538     btnAddTag->setEnabled( 
false );
 
  539     btnAddSmartgroup->setEnabled( 
false );
 
  540     btnManageGroups->setEnabled( 
false );
 
  542     btnAddItem->setVisible( 
false );
 
  543     btnRemoveItem->setVisible( 
false );
 
  544     btnEditItem->setVisible( 
false );
 
  545     btnAddSmartgroup->setVisible( 
false );
 
  546     btnAddTag->setVisible( 
false );
 
  547     btnManageGroups->setVisible( 
false );
 
  549     delete mImportAction;
 
  550     mImportAction = 
nullptr;
 
  552     mGroupTreeContextMenu->clear();
 
  554     mGroupMenu->addAction( mActionCopyItem );
 
  558     btnAddTag->setEnabled( 
true );
 
  559     btnAddSmartgroup->setEnabled( 
true );
 
  560     btnManageGroups->setEnabled( 
true );
 
  562     btnAddItem->setVisible( 
true );
 
  563     btnRemoveItem->setVisible( 
true );
 
  564     btnEditItem->setVisible( 
true );
 
  565     btnAddSmartgroup->setVisible( 
true );
 
  566     btnAddTag->setVisible( 
true );
 
  567     btnManageGroups->setVisible( 
true );
 
  569     if ( !mImportAction )
 
  571       mImportAction = 
new QAction( tr( 
"Import Item(s)…" ), 
this );
 
  573       mShareMenu->insertAction( mShareMenu->actions().at( mShareMenu->actions().indexOf( mExportAction ) + 1 ), mImportAction );
 
  577     mGroupTreeContextMenu->clear();
 
  578     mGroupTreeContextMenu->addAction( actnEditSmartGroup );
 
  579     mGroupTreeContextMenu->addAction( actnAddTag );
 
  580     mGroupTreeContextMenu->addAction( actnAddSmartgroup );
 
  581     mGroupTreeContextMenu->addAction( actnRemoveGroup );
 
  584     mGroupMenu->addAction( actnAddFavorite );
 
  585     mGroupMenu->addAction( actnRemoveFavorite );
 
  586     mGroupMenu->addSeparator()->setParent( 
this );
 
  587     mGroupMenu->addMenu( mGroupListMenu );
 
  588     mGroupMenu->addAction( actnDetag );
 
  589     mGroupMenu->addSeparator()->setParent( 
this );
 
  590     mGroupMenu->addAction( actnRemoveItem );
 
  591     mGroupMenu->addAction( actnEditItem );
 
  592     mGroupMenu->addAction( mActionCopyItem );
 
  593     mGroupMenu->addAction( mActionPasteItem );
 
  594     mGroupMenu->addSeparator()->setParent( 
this );
 
  597   if ( mActionCopyToDefault )
 
  599     mGroupMenu->addAction( mActionCopyToDefault );
 
  601   mGroupMenu->addAction( actnExportAsPNG );
 
  602   mGroupMenu->addAction( actnExportAsSVG );
 
  605   const QModelIndexList prevIndex = groupTree->model()->match( groupTree->model()->index( 0, 0 ), Qt::UserRole + 1, sPreviousTag, 1, Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive );
 
  606   groupTree->setCurrentIndex( !prevIndex.empty() ? prevIndex.at( 0 ) : groupTree->model()->index( 0, 0 ) );
 
  609   tabItemType_currentChanged( tabItemType->currentIndex() );
 
  615 void QgsStyleManagerDialog::currentStyleAboutToBeDestroyed()
 
  626   settings.
setValue( QStringLiteral( 
"Windows/StyleV2Manager/splitter" ), mSplitter->saveState() );
 
  633 void QgsStyleManagerDialog::tabItemType_currentChanged( 
int )
 
  642   searchBox->setPlaceholderText( isSymbol ? tr( 
"Filter symbols…" ) :
 
  643                                  isColorRamp ? tr( 
"Filter color ramps…" ) :
 
  644                                  isTextFormat ? tr( 
"Filter text symbols…" ) :
 
  645                                  isLabelSettings ? tr( 
"Filter label settings…" ) :
 
  646                                  isLegendPatchShape ? tr( 
"Filter legend patch shapes…" ) : tr( 
"Filter 3D symbols…" ) );
 
  648   const bool readOnly = isReadOnly();
 
  649   if ( !readOnly && isColorRamp ) 
 
  651     btnAddItem->setMenu( mMenuBtnAddItemColorRamp );
 
  653   else if ( !readOnly && isLegendPatchShape ) 
 
  655     btnAddItem->setMenu( mMenuBtnAddItemLegendPatchShape );
 
  657   else if ( !readOnly && isSymbol3D ) 
 
  659     btnAddItem->setMenu( mMenuBtnAddItemSymbol3D );
 
  661   else if ( !readOnly && isLabelSettings ) 
 
  663     btnAddItem->setMenu( mMenuBtnAddItemLabelSettings );
 
  665   else if ( !readOnly && !isSymbol && !isColorRamp ) 
 
  667     btnAddItem->setMenu( 
nullptr );
 
  669   else if ( !readOnly && tabItemType->currentIndex() == 0 ) 
 
  671     btnAddItem->setMenu( mMenuBtnAddItemAll );
 
  675     btnAddItem->setMenu( 
nullptr );
 
  678   actnExportAsPNG->setVisible( isSymbol );
 
  679   actnExportAsSVG->setVisible( isSymbol );
 
  684     mModel->setEntityFilterEnabled( !allTypesSelected() );
 
  685     mModel->setSymbolTypeFilterEnabled( isSymbol && !allTypesSelected() );
 
  686     if ( isSymbol && !allTypesSelected() )
 
  693 void QgsStyleManagerDialog::copyItemsToDefault()
 
  695   const QList< ItemDetails > items = selectedItems();
 
  696   if ( !items.empty() )
 
  700     if ( !mBaseName.isEmpty() )
 
  701       options.append( mBaseName );
 
  704     defaultTags.sort( Qt::CaseInsensitive );
 
  705     options.append( defaultTags );
 
  706     const QString tags = QInputDialog::getItem( 
this, tr( 
"Import Items" ),
 
  707                          tr( 
"Additional tags to add (comma separated)" ), options, mBaseName.isEmpty() ? -1 : 0, 
true, &ok );
 
  711 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 
  712     const QStringList parts = tags.split( 
',', QString::SkipEmptyParts );
 
  714     const QStringList parts = tags.split( 
',', Qt::SkipEmptyParts );
 
  716     QStringList additionalTags;
 
  717     additionalTags.reserve( parts.count() );
 
  718     for ( 
const QString &tag : parts )
 
  719       additionalTags << tag.trimmed();
 
  721     auto cursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
 
  722     const int count = copyItems( items, mStyle, 
QgsStyle::defaultStyle(), 
this, cursorOverride, 
true, additionalTags, 
false, 
false );
 
  723     cursorOverride.reset();
 
  726       mMessageBar->pushSuccess( tr( 
"Import Items" ), count > 1 ? tr( 
"Successfully imported %n item(s).", 
nullptr, count ) : tr( 
"Successfully imported item." ) );
 
  731 void QgsStyleManagerDialog::copyItem()
 
  733   const QList< ItemDetails > items = selectedItems();
 
  737   ItemDetails details = items.at( 0 );
 
  738   switch ( details.entityType )
 
  742       std::unique_ptr< QgsSymbol > symbol( mStyle->
symbol( details.name ) );
 
  752       QApplication::clipboard()->setMimeData( format.toMimeData() );
 
  759       QApplication::clipboard()->setMimeData( format.toMimeData() );
 
  773 void QgsStyleManagerDialog::pasteItem()
 
  775   const QString defaultTag = groupTree->currentIndex().isValid() ? groupTree->currentIndex().data( 
GroupModelRoles::TagName ).toString() : QString();
 
  779     QgsStyleSaveDialog saveDlg( 
this );
 
  780     saveDlg.setWindowTitle( tr( 
"Paste Symbol" ) );
 
  781     saveDlg.setDefaultTags( defaultTag );
 
  782     if ( !saveDlg.exec() || saveDlg.name().isEmpty() )
 
  785     if ( mStyle->
symbolNames().contains( saveDlg.name() ) )
 
  787       int res = QMessageBox::warning( 
this, tr( 
"Paste Symbol" ),
 
  788                                       tr( 
"A symbol with the name '%1' already exists. Overwrite?" )
 
  789                                       .arg( saveDlg.name() ),
 
  790                                       QMessageBox::Yes | QMessageBox::No );
 
  791       if ( res != QMessageBox::Yes )
 
  798     QStringList symbolTags = saveDlg.tags().split( 
',' );
 
  800     mStyle->
addSymbol( saveDlg.name(), tempSymbol.release() );
 
  802     mStyle->
saveSymbol( saveDlg.name(), newSymbol, saveDlg.isFavorite(), symbolTags );
 
  811     saveDlg.setDefaultTags( defaultTag );
 
  812     saveDlg.setWindowTitle( tr( 
"Paste Text Format" ) );
 
  813     if ( !saveDlg.exec() || saveDlg.name().isEmpty() )
 
  818       int res = QMessageBox::warning( 
this, tr( 
"Paste Text Format" ),
 
  819                                       tr( 
"A format with the name '%1' already exists. Overwrite?" )
 
  820                                       .arg( saveDlg.name() ),
 
  821                                       QMessageBox::Yes | QMessageBox::No );
 
  822       if ( res != QMessageBox::Yes )
 
  829     QStringList symbolTags = saveDlg.tags().split( 
',' );
 
  832     mStyle->
saveTextFormat( saveDlg.name(), format, saveDlg.isFavorite(), symbolTags );
 
  837 void QgsStyleManagerDialog::setThumbnailSize( 
int value )
 
  842   const double spacing = 
Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 
'X' ) * ( value * 2.2 + 14 );
 
  845   listItems->setIconSize( QSize( 
static_cast< int >( 
iconSize ), 
static_cast< int >( 
iconSize * 0.9 ) ) );
 
  846   listItems->setGridSize( QSize( 
static_cast< int >( spacing ), 
static_cast< int >( verticalSpacing ) ) );
 
  849     mModel->addDesiredIconSize( listItems->iconSize() );
 
  855 int QgsStyleManagerDialog::selectedItemType()
 
  857   QModelIndex index = listItems->selectionModel()->currentIndex();
 
  858   if ( !index.isValid() )
 
  876 bool QgsStyleManagerDialog::allTypesSelected()
 const 
  878   return tabItemType->currentIndex() == 0;
 
  881 bool QgsStyleManagerDialog::isReadOnly()
 const 
  883   return mReadOnly || ( mStyle && mStyle->
isReadOnly() );
 
  886 QList< QgsStyleManagerDialog::ItemDetails > QgsStyleManagerDialog::selectedItems()
 
  888   QList<QgsStyleManagerDialog::ItemDetails > res;
 
  889   QModelIndexList indices = listItems->selectionModel()->selectedRows();
 
  890   for ( 
const QModelIndex &index : indices )
 
  892     if ( !index.isValid() )
 
  899     details.name = mModel->data( mModel->index( index.row(), 
QgsStyleModel::Name, index.parent() ), Qt::DisplayRole ).toString();
 
  906 int QgsStyleManagerDialog::copyItems( 
const QList<QgsStyleManagerDialog::ItemDetails> &items, 
QgsStyle *src, 
QgsStyle *dst, QWidget *parentWidget,
 
  907                                       std::unique_ptr< QgsTemporaryCursorOverride > &cursorOverride, 
bool isImport, 
const QStringList &importTags, 
bool addToFavorites, 
bool ignoreSourceTags )
 
  910   bool overwriteAll = 
true;
 
  920   for ( 
auto &details : items )
 
  922     QStringList symbolTags;
 
  923     if ( !ignoreSourceTags )
 
  925       symbolTags = src->
tagsOfSymbol( details.entityType, details.name );
 
  928     bool addItemToFavorites = 
false;
 
  931       symbolTags << importTags;
 
  932       addItemToFavorites = addToFavorites;
 
  935     switch ( details.entityType )
 
  939         std::unique_ptr< QgsSymbol > symbol( src->
symbol( details.name ) );
 
  943         const bool hasDuplicateName = dst->
symbolNames().contains( details.name );
 
  944         bool overwriteThis = 
false;
 
  946           addItemToFavorites = favoriteSymbols.contains( details.name );
 
  948         if ( hasDuplicateName && prompt )
 
  950           cursorOverride.reset();
 
  951           int res = QMessageBox::warning( parentWidget, isImport ? tr( 
"Import Symbol" ) : tr( 
"Export Symbol" ),
 
  952                                           tr( 
"A symbol with the name “%1” already exists.\nOverwrite?" )
 
  953                                           .arg( details.name ),
 
  954                                           QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
 
  955           cursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
 
  958             case QMessageBox::Cancel:
 
  961             case QMessageBox::No:
 
  964             case QMessageBox::Yes:
 
  965               overwriteThis = 
true;
 
  968             case QMessageBox::YesToAll:
 
  973             case QMessageBox::NoToAll:
 
  975               overwriteAll = 
false;
 
  980         if ( !hasDuplicateName || overwriteAll || overwriteThis )
 
  983           dst->
addSymbol( details.name, symbol.release() );
 
  984           dst->
saveSymbol( details.name, newSymbol, addItemToFavorites, symbolTags );
 
  992         std::unique_ptr< QgsColorRamp > ramp( src->
colorRamp( details.name ) );
 
  996         const bool hasDuplicateName = dst->
colorRampNames().contains( details.name );
 
  997         bool overwriteThis = 
false;
 
  999           addItemToFavorites = favoriteColorramps.contains( details.name );
 
 1001         if ( hasDuplicateName && prompt )
 
 1003           cursorOverride.reset();
 
 1004           int res = QMessageBox::warning( parentWidget, isImport ? tr( 
"Import Color Ramp" ) : tr( 
"Export Color Ramp" ),
 
 1005                                           tr( 
"A color ramp with the name “%1” already exists.\nOverwrite?" )
 
 1006                                           .arg( details.name ),
 
 1007                                           QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
 
 1008           cursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
 
 1011             case QMessageBox::Cancel:
 
 1014             case QMessageBox::No:
 
 1017             case QMessageBox::Yes:
 
 1018               overwriteThis = 
true;
 
 1021             case QMessageBox::YesToAll:
 
 1023               overwriteAll = 
true;
 
 1026             case QMessageBox::NoToAll:
 
 1028               overwriteAll = 
false;
 
 1033         if ( !hasDuplicateName || overwriteAll || overwriteThis )
 
 1037           dst->
saveColorRamp( details.name, newRamp, addItemToFavorites, symbolTags );
 
 1047         const bool hasDuplicateName = dst->
textFormatNames().contains( details.name );
 
 1048         bool overwriteThis = 
false;
 
 1050           addItemToFavorites = favoriteTextFormats.contains( details.name );
 
 1052         if ( hasDuplicateName && prompt )
 
 1054           cursorOverride.reset();
 
 1055           int res = QMessageBox::warning( parentWidget, isImport ? tr( 
"Import Text Format" ) : tr( 
"Export Text Format" ),
 
 1056                                           tr( 
"A text format with the name “%1” already exists.\nOverwrite?" )
 
 1057                                           .arg( details.name ),
 
 1058                                           QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
 
 1059           cursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
 
 1062             case QMessageBox::Cancel:
 
 1065             case QMessageBox::No:
 
 1068             case QMessageBox::Yes:
 
 1069               overwriteThis = 
true;
 
 1072             case QMessageBox::YesToAll:
 
 1074               overwriteAll = 
true;
 
 1077             case QMessageBox::NoToAll:
 
 1079               overwriteAll = 
false;
 
 1084         if ( !hasDuplicateName || overwriteAll || overwriteThis )
 
 1087           dst->
saveTextFormat( details.name, format, addItemToFavorites, symbolTags );
 
 1098         bool overwriteThis = 
false;
 
 1100           addItemToFavorites = favoriteLabelSettings.contains( details.name );
 
 1102         if ( hasDuplicateName && prompt )
 
 1104           cursorOverride.reset();
 
 1105           int res = QMessageBox::warning( parentWidget, isImport ? tr( 
"Import Label Settings" ) : tr( 
"Export Label Settings" ),
 
 1106                                           tr( 
"Label settings with the name “%1” already exist.\nOverwrite?" )
 
 1107                                           .arg( details.name ),
 
 1108                                           QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
 
 1109           cursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
 
 1112             case QMessageBox::Cancel:
 
 1115             case QMessageBox::No:
 
 1118             case QMessageBox::Yes:
 
 1119               overwriteThis = 
true;
 
 1122             case QMessageBox::YesToAll:
 
 1124               overwriteAll = 
true;
 
 1127             case QMessageBox::NoToAll:
 
 1129               overwriteAll = 
false;
 
 1134         if ( !hasDuplicateName || overwriteAll || overwriteThis )
 
 1137           dst->
saveLabelSettings( details.name, settings, addItemToFavorites, symbolTags );
 
 1148         bool overwriteThis = 
false;
 
 1150           addItemToFavorites = favoriteLegendPatchShapes.contains( details.name );
 
 1152         if ( hasDuplicateName && prompt )
 
 1154           cursorOverride.reset();
 
 1155           int res = QMessageBox::warning( parentWidget, isImport ? tr( 
"Import Legend Patch Shape" ) : tr( 
"Export Legend Patch Shape" ),
 
 1156                                           tr( 
"Legend patch shape with the name “%1” already exist.\nOverwrite?" )
 
 1157                                           .arg( details.name ),
 
 1158                                           QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
 
 1159           cursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
 
 1162             case QMessageBox::Cancel:
 
 1165             case QMessageBox::No:
 
 1168             case QMessageBox::Yes:
 
 1169               overwriteThis = 
true;
 
 1172             case QMessageBox::YesToAll:
 
 1174               overwriteAll = 
true;
 
 1177             case QMessageBox::NoToAll:
 
 1179               overwriteAll = 
false;
 
 1184         if ( !hasDuplicateName || overwriteAll || overwriteThis )
 
 1195         std::unique_ptr< QgsAbstract3DSymbol > symbol( src->
symbol3D( details.name ) );
 
 1199         const bool hasDuplicateName = dst->
symbol3DNames().contains( details.name );
 
 1200         bool overwriteThis = 
false;
 
 1202           addItemToFavorites = favorite3dSymbols.contains( details.name );
 
 1204         if ( hasDuplicateName && prompt )
 
 1206           cursorOverride.reset();
 
 1207           int res = QMessageBox::warning( parentWidget, isImport ? tr( 
"Import 3D Symbol" ) : tr( 
"Export 3D Symbol" ),
 
 1208                                           tr( 
"A 3D symbol with the name “%1” already exists.\nOverwrite?" )
 
 1209                                           .arg( details.name ),
 
 1210                                           QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
 
 1211           cursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
 
 1214             case QMessageBox::Cancel:
 
 1217             case QMessageBox::No:
 
 1220             case QMessageBox::Yes:
 
 1221               overwriteThis = 
true;
 
 1224             case QMessageBox::YesToAll:
 
 1226               overwriteAll = 
true;
 
 1229             case QMessageBox::NoToAll:
 
 1231               overwriteAll = 
false;
 
 1236         if ( !hasDuplicateName || overwriteAll || overwriteThis )
 
 1239           dst->
addSymbol3D( details.name, symbol.release() );
 
 1240           dst->
saveSymbol3D( details.name, newSymbol, addItemToFavorites, symbolTags );
 
 1255 bool QgsStyleManagerDialog::addTextFormat()
 
 1259   formatDlg.setWindowTitle( tr( 
"New Text Format" ) );
 
 1260   if ( !formatDlg.exec() )
 
 1262   format = formatDlg.format();
 
 1265   const QString defaultTag = groupTree->currentIndex().isValid() ? groupTree->currentIndex().data( 
GroupModelRoles::TagName ).toString() : QString();
 
 1266   saveDlg.setDefaultTags( defaultTag );
 
 1267   if ( !saveDlg.exec() )
 
 1269   QString name = saveDlg.name();
 
 1272   bool nameInvalid = 
true;
 
 1273   while ( nameInvalid )
 
 1276     if ( name.isEmpty() )
 
 1278       QMessageBox::warning( 
this, tr( 
"Save Text Format" ),
 
 1279                             tr( 
"Cannot save text format without name. Enter a name." ) );
 
 1283       int res = QMessageBox::warning( 
this, tr( 
"Save Text Format" ),
 
 1284                                       tr( 
"Text format with name '%1' already exists. Overwrite?" )
 
 1286                                       QMessageBox::Yes | QMessageBox::No );
 
 1287       if ( res == QMessageBox::Yes )
 
 1290         nameInvalid = 
false;
 
 1296       nameInvalid = 
false;
 
 1301       name = QInputDialog::getText( 
this, tr( 
"Text Format Name" ),
 
 1302                                     tr( 
"Please enter a name for new text format:" ),
 
 1303                                     QLineEdit::Normal, name, &ok );
 
 1311   QStringList symbolTags = saveDlg.tags().split( 
',' );
 
 1315   mStyle->
saveTextFormat( name, format, saveDlg.isFavorite(), symbolTags );
 
 1323   groupChanged( groupTree->selectionModel()->currentIndex() );
 
 1336   switch ( tabItemType->currentIndex() )
 
 1361   QModelIndex index = listItems->selectionModel()->currentIndex();
 
 1362   if ( !index.isValid() )
 
 1365   return mModel->data( mModel->index( index.row(), 
QgsStyleModel::Name, index.parent() ), Qt::DisplayRole ).toString();
 
 1370   bool changed = 
false;
 
 1381     changed = addTextFormat();
 
 1400     Q_ASSERT( 
false && 
"not implemented" );
 
 1413   QString name = tr( 
"new symbol" );
 
 1414   QString dialogTitle;
 
 1419       name = tr( 
"new marker" );
 
 1420       dialogTitle = tr( 
"New Marker Symbol" );
 
 1424       name = tr( 
"new line" );
 
 1425       dialogTitle = tr( 
"New Line Symbol" );
 
 1429       name = tr( 
"new fill symbol" );
 
 1430       dialogTitle = tr( 
"New Fill Symbol" );
 
 1433       Q_ASSERT( 
false && 
"unknown symbol type" );
 
 1443   dlg.setWindowTitle( dialogTitle );
 
 1444   if ( dlg.exec() == 0 )
 
 1450   QgsStyleSaveDialog saveDlg( 
this );
 
 1451   const QString defaultTag = groupTree->currentIndex().isValid() ? groupTree->currentIndex().data( 
GroupModelRoles::TagName ).toString() : QString();
 
 1452   saveDlg.setDefaultTags( defaultTag );
 
 1453   if ( !saveDlg.exec() )
 
 1459   name = saveDlg.name();
 
 1462   bool nameInvalid = 
true;
 
 1463   while ( nameInvalid )
 
 1466     if ( name.isEmpty() )
 
 1468       QMessageBox::warning( 
this, tr( 
"Save Symbol" ),
 
 1469                             tr( 
"Cannot save symbol without name. Enter a name." ) );
 
 1471     else if ( mStyle->
symbolNames().contains( name ) )
 
 1473       int res = QMessageBox::warning( 
this, tr( 
"Save Symbol" ),
 
 1474                                       tr( 
"Symbol with name '%1' already exists. Overwrite?" )
 
 1476                                       QMessageBox::Yes | QMessageBox::No );
 
 1477       if ( res == QMessageBox::Yes )
 
 1480         nameInvalid = 
false;
 
 1486       nameInvalid = 
false;
 
 1491       name = QInputDialog::getText( 
this, tr( 
"Symbol Name" ),
 
 1492                                     tr( 
"Please enter a name for new symbol:" ),
 
 1493                                     QLineEdit::Normal, name, &ok );
 
 1502   QStringList symbolTags = saveDlg.tags().split( 
',' );
 
 1506   mStyle->
saveSymbol( name, symbol, saveDlg.isFavorite(), symbolTags );
 
 1515   QString rampType = type;
 
 1517   if ( rampType.isEmpty() )
 
 1522     QStringList rampTypeNames;
 
 1523     rampTypeNames.reserve( rampTypes.size() );
 
 1524     for ( 
const QPair< QString, QString > &type : rampTypes )
 
 1525       rampTypeNames << type.second;
 
 1526     const QString selectedRampTypeName = QInputDialog::getItem( parent, tr( 
"Color Ramp Type" ),
 
 1527                                          tr( 
"Please select color ramp type:" ), rampTypeNames, 0, 
false, &ok );
 
 1528     if ( !ok || selectedRampTypeName.isEmpty() )
 
 1531     rampType = rampTypes.value( rampTypeNames.indexOf( selectedRampTypeName ) ).first;
 
 1534   QString name = tr( 
"new ramp" );
 
 1536   std::unique_ptr< QgsColorRamp  > ramp;
 
 1540     dlg.setWindowTitle( tr( 
"New Gradient Color Ramp" ) );
 
 1546     name = tr( 
"new gradient ramp" );
 
 1551     dlg.setWindowTitle( tr( 
"New Random Color Ramp" ) );
 
 1557     name = tr( 
"new random ramp" );
 
 1562     dlg.setWindowTitle( tr( 
"New ColorBrewer Ramp" ) );
 
 1573     dlg.setWindowTitle( tr( 
"New Preset Color Ramp" ) );
 
 1579     name = tr( 
"new preset ramp" );
 
 1584     dlg.setWindowTitle( tr( 
"New cpt-city Color Ramp" ) );
 
 1604     QgsDebugMsg( QStringLiteral( 
"invalid ramp type %1" ).arg( rampType ) );
 
 1609   if ( !saveDlg.exec() )
 
 1614   name = saveDlg.name();
 
 1617   bool nameInvalid = 
true;
 
 1618   while ( nameInvalid )
 
 1621     if ( name.isEmpty() )
 
 1623       QMessageBox::warning( parent, tr( 
"Save Color Ramp" ),
 
 1624                             tr( 
"Cannot save color ramp without name. Enter a name." ) );
 
 1628       int res = QMessageBox::warning( parent, tr( 
"Save Color Ramp" ),
 
 1629                                       tr( 
"Color ramp with name '%1' already exists. Overwrite?" )
 
 1631                                       QMessageBox::Yes | QMessageBox::No );
 
 1632       if ( res == QMessageBox::Yes )
 
 1634         nameInvalid = 
false;
 
 1640       nameInvalid = 
false;
 
 1645       name = QInputDialog::getText( parent, tr( 
"Color Ramp Name" ),
 
 1646                                     tr( 
"Please enter a name for new color ramp:" ),
 
 1647                                     QLineEdit::Normal, name, &ok );
 
 1655   QStringList colorRampTags = saveDlg.tags().split( 
',' );
 
 1660   style->
saveColorRamp( name, r, saveDlg.isFavorite(), colorRampTags );
 
 1667   mFavoritesGroupVisible = show;
 
 1673   mSmartGroupVisible = show;
 
 1685   setWindowState( windowState() & ~Qt::WindowMinimized );
 
 1693   if ( !rampName.isEmpty() )
 
 1705   if ( selectedItemType() < 3 )
 
 1709   else if ( selectedItemType() == 3 )
 
 1713   else if ( selectedItemType() == 4 )
 
 1717   else if ( selectedItemType() == 5 )
 
 1719     editLabelSettings();
 
 1721   else if ( selectedItemType() == 6 )
 
 1723     editLegendPatchShape();
 
 1725   else if ( selectedItemType() == 7 )
 
 1731     Q_ASSERT( 
false && 
"not implemented" );
 
 1738   if ( symbolName.isEmpty() )
 
 1741   std::unique_ptr< QgsSymbol > symbol( mStyle->
symbol( symbolName ) );
 
 1745   dlg.setWindowTitle( symbolName );
 
 1747     dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
 1753   mStyle->
addSymbol( symbolName, symbol.release(), 
true );
 
 1761   if ( name.isEmpty() )
 
 1764   std::unique_ptr< QgsColorRamp > ramp( mStyle->
colorRamp( name ) );
 
 1770     dlg.setWindowTitle( name );
 
 1772       dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
 1784     dlg.setWindowTitle( name );
 
 1786       dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
 1798     dlg.setWindowTitle( name );
 
 1800       dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
 1812     dlg.setWindowTitle( name );
 
 1814       dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
 1826     dlg.setWindowTitle( name );
 
 1828       dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
 1845     Q_ASSERT( 
false && 
"invalid ramp type" );
 
 1853 bool QgsStyleManagerDialog::editTextFormat()
 
 1856   if ( formatName.isEmpty() )
 
 1863   dlg.setWindowTitle( formatName );
 
 1865     dlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
 1879   QgsLabelSettingsDialog settingsDlg( settings, 
nullptr, 
nullptr, 
this, type );
 
 1880   settingsDlg.setWindowTitle( tr( 
"New Label Settings" ) );
 
 1882     settingsDlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
 1884   if ( !settingsDlg.exec() )
 
 1887   settings = settingsDlg.settings();
 
 1891   const QString defaultTag = groupTree->currentIndex().isValid() ? groupTree->currentIndex().data( 
GroupModelRoles::TagName ).toString() : QString();
 
 1892   saveDlg.setDefaultTags( defaultTag );
 
 1893   if ( !saveDlg.exec() )
 
 1895   QString name = saveDlg.name();
 
 1898   bool nameInvalid = 
true;
 
 1899   while ( nameInvalid )
 
 1902     if ( name.isEmpty() )
 
 1904       QMessageBox::warning( 
this, tr( 
"Save Label Settings" ),
 
 1905                             tr( 
"Cannot save label settings without a name. Enter a name." ) );
 
 1909       int res = QMessageBox::warning( 
this, tr( 
"Save Label Settings" ),
 
 1910                                       tr( 
"Label settings with the name '%1' already exist. Overwrite?" )
 
 1912                                       QMessageBox::Yes | QMessageBox::No );
 
 1913       if ( res == QMessageBox::Yes )
 
 1916         nameInvalid = 
false;
 
 1922       nameInvalid = 
false;
 
 1927       name = QInputDialog::getText( 
this, tr( 
"Label Settings Name" ),
 
 1928                                     tr( 
"Please enter a name for the new label settings:" ),
 
 1929                                     QLineEdit::Normal, name, &ok );
 
 1937   QStringList symbolTags = saveDlg.tags().split( 
',' );
 
 1947 bool QgsStyleManagerDialog::editLabelSettings()
 
 1950   if ( formatName.isEmpty() )
 
 1957   QgsLabelSettingsDialog dlg( settings, 
nullptr, 
nullptr, 
this, geomType );
 
 1958   dlg.setWindowTitle( formatName );
 
 1962   settings = dlg.settings();
 
 1975   dialog.setWindowTitle( tr( 
"New Legend Patch Shape" ) );
 
 1977     dialog.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
 1979   if ( !dialog.exec() )
 
 1982   shape = dialog.shape();
 
 1985   const QString defaultTag = groupTree->currentIndex().isValid() ? groupTree->currentIndex().data( 
GroupModelRoles::TagName ).toString() : QString();
 
 1986   saveDlg.setDefaultTags( defaultTag );
 
 1987   if ( !saveDlg.exec() )
 
 1989   QString name = saveDlg.name();
 
 1992   bool nameInvalid = 
true;
 
 1993   while ( nameInvalid )
 
 1996     if ( name.isEmpty() )
 
 1998       QMessageBox::warning( 
this, tr( 
"Save Legend Patch Shape" ),
 
 1999                             tr( 
"Cannot save legend patch shapes without a name. Enter a name." ) );
 
 2003       int res = QMessageBox::warning( 
this, tr( 
"Save Legend Patch Shape" ),
 
 2004                                       tr( 
"A legend patch shape with the name '%1' already exists. Overwrite?" )
 
 2006                                       QMessageBox::Yes | QMessageBox::No );
 
 2007       if ( res == QMessageBox::Yes )
 
 2010         nameInvalid = 
false;
 
 2016       nameInvalid = 
false;
 
 2021       name = QInputDialog::getText( 
this, tr( 
"Legend Patch Shape Name" ),
 
 2022                                     tr( 
"Please enter a name for the new legend patch shape:" ),
 
 2023                                     QLineEdit::Normal, name, &ok );
 
 2031   QStringList symbolTags = saveDlg.tags().split( 
',' );
 
 2041 bool QgsStyleManagerDialog::editLegendPatchShape()
 
 2044   if ( shapeName.isEmpty() )
 
 2053   dlg.setWindowTitle( shapeName );
 
 2057   shape = dlg.shape();
 
 2065 bool QgsStyleManagerDialog::addSymbol3D( 
const QString &type )
 
 2072   dialog.setWindowTitle( tr( 
"New 3D Symbol" ) );
 
 2074     dialog.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
 2076   if ( !dialog.exec() )
 
 2079   symbol.reset( dialog.symbol() );
 
 2084   const QString defaultTag = groupTree->currentIndex().isValid() ? groupTree->currentIndex().data( 
GroupModelRoles::TagName ).toString() : QString();
 
 2085   saveDlg.setDefaultTags( defaultTag );
 
 2086   if ( !saveDlg.exec() )
 
 2088   QString name = saveDlg.name();
 
 2091   bool nameInvalid = 
true;
 
 2092   while ( nameInvalid )
 
 2095     if ( name.isEmpty() )
 
 2097       QMessageBox::warning( 
this, tr( 
"Save 3D Symbol" ),
 
 2098                             tr( 
"Cannot save 3D symbols without a name. Enter a name." ) );
 
 2102       int res = QMessageBox::warning( 
this, tr( 
"Save 3D Symbol" ),
 
 2103                                       tr( 
"A 3D symbol with the name '%1' already exists. Overwrite?" )
 
 2105                                       QMessageBox::Yes | QMessageBox::No );
 
 2106       if ( res == QMessageBox::Yes )
 
 2109         nameInvalid = 
false;
 
 2115       nameInvalid = 
false;
 
 2120       name = QInputDialog::getText( 
this, tr( 
"3D Symbol Name" ),
 
 2121                                     tr( 
"Please enter a name for the new 3D symbol:" ),
 
 2122                                     QLineEdit::Normal, name, &ok );
 
 2130   QStringList symbolTags = saveDlg.tags().split( 
',' );
 
 2135   mStyle->
saveSymbol3D( name, newSymbol, saveDlg.isFavorite(), symbolTags );
 
 2141 bool QgsStyleManagerDialog::editSymbol3D()
 
 2144   if ( symbolName.isEmpty() )
 
 2147   std::unique_ptr< QgsAbstract3DSymbol > symbol( mStyle->
symbol3D( symbolName ) );
 
 2153   dlg.setWindowTitle( symbolName );
 
 2157   symbol.reset( dlg.symbol() );
 
 2162   mStyle->
addSymbol3D( symbolName, symbol.release(), 
true );
 
 2167 void QgsStyleManagerDialog::addStyleDatabase( 
bool createNew )
 
 2170   if ( initialFolder.isEmpty() )
 
 2171     initialFolder = QDir::homePath();
 
 2173   QString databasePath = createNew
 
 2174                          ? QFileDialog::getSaveFileName(
 
 2176                            tr( 
"Create Style Database" ),
 
 2178                            tr( 
"Style databases" ) + 
" (*.db)" )
 
 2179                          : QFileDialog::getOpenFileName(
 
 2181                            tr( 
"Add Style Database" ),
 
 2183                            tr( 
"Style databases" ) + 
" (*.db *.xml)" );
 
 2184   if ( ! databasePath.isEmpty() )
 
 2191       if ( QFile::exists( databasePath ) )
 
 2193         QFile::remove( databasePath );
 
 2198         QMessageBox::warning( 
this, tr( 
"Create Style Database" ), tr( 
"The style database could not be created" ) );
 
 2210   const QList< ItemDetails > items = selectedItems();
 
 2212   if ( allTypesSelected() )
 
 2214     if ( QMessageBox::Yes != QMessageBox::question( 
this, tr( 
"Remove Items" ),
 
 2215          QString( tr( 
"Do you really want to remove %n item(s)?", 
nullptr, items.count() ) ),
 
 2224       if ( QMessageBox::Yes != QMessageBox::question( 
this, tr( 
"Remove Symbol" ),
 
 2225            QString( tr( 
"Do you really want to remove %n symbol(s)?", 
nullptr, items.count() ) ),
 
 2232       if ( QMessageBox::Yes != QMessageBox::question( 
this, tr( 
"Remove Color Ramp" ),
 
 2233            QString( tr( 
"Do you really want to remove %n ramp(s)?", 
nullptr, items.count() ) ),
 
 2240       if ( QMessageBox::Yes != QMessageBox::question( 
this, tr( 
"Remove Text Formats" ),
 
 2241            QString( tr( 
"Do you really want to remove %n text format(s)?", 
nullptr, items.count() ) ),
 
 2248       if ( QMessageBox::Yes != QMessageBox::question( 
this, tr( 
"Remove Label Settings" ),
 
 2249            QString( tr( 
"Do you really want to remove %n label setting(s)?", 
nullptr, items.count() ) ),
 
 2256       if ( QMessageBox::Yes != QMessageBox::question( 
this, tr( 
"Remove Legend Patch Shapes" ),
 
 2257            QString( tr( 
"Do you really want to remove %n legend patch shape(s)?", 
nullptr, items.count() ) ),
 
 2264       if ( QMessageBox::Yes != QMessageBox::question( 
this, tr( 
"Remove 3D Symbols" ),
 
 2265            QString( tr( 
"Do you really want to remove %n 3D symbol(s)?", 
nullptr, items.count() ) ),
 
 2274   for ( 
const ItemDetails &details : items )
 
 2276     if ( details.name.isEmpty() )
 
 2301   QString dir = QFileDialog::getExistingDirectory( 
this, tr( 
"Export Selected Symbols as PNG" ),
 
 2302                 QDir::home().absolutePath(),
 
 2303                 QFileDialog::DontResolveSymlinks );
 
 2309   QString dir = QFileDialog::getExistingDirectory( 
this, tr( 
"Export Selected Symbols as SVG" ),
 
 2310                 QDir::home().absolutePath(),
 
 2311                 QFileDialog::DontResolveSymlinks );
 
 2318   if ( dir.isEmpty() )
 
 2321   const QList< ItemDetails > items = selectedItems();
 
 2322   for ( 
const ItemDetails &details : items )
 
 2327     QString path = dir + 
'/' + details.name + 
'.' + format;
 
 2328     std::unique_ptr< QgsSymbol > sym( mStyle->
symbol( details.name ) );
 
 2330       sym->exportImage( path, format, size );
 
 2350   QFont font = item->font();
 
 2351   font.setBold( 
true );
 
 2352   item->setFont( font );
 
 2357   if ( mBlockGroupUpdates )
 
 2360   QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
 
 2363   const bool readOnly = isReadOnly();
 
 2365   if ( mFavoritesGroupVisible )
 
 2367     QStandardItem *favoriteSymbols = 
new QStandardItem( tr( 
"Favorites" ) );
 
 2368     favoriteSymbols->setData( 
"favorite" );
 
 2369     favoriteSymbols->setEditable( 
false );
 
 2371     model->appendRow( favoriteSymbols );
 
 2374   QStandardItem *allSymbols = 
new QStandardItem( tr( 
"All" ) );
 
 2375   allSymbols->setData( 
"all" );
 
 2376   allSymbols->setEditable( 
false );
 
 2378   model->appendRow( allSymbols );
 
 2380   QStandardItem *taggroup = 
new QStandardItem( QString() ); 
 
 2381   taggroup->setData( 
"tags" );
 
 2382   taggroup->setEditable( 
false );
 
 2383   QStringList tags = mStyle->
tags();
 
 2385   for ( 
const QString &tag : std::as_const( tags ) )
 
 2387     QStandardItem *item = 
new QStandardItem( tag );
 
 2388     item->setData( mStyle->
tagId( tag ) );
 
 2390     item->setEditable( !readOnly );
 
 2391     taggroup->appendRow( item );
 
 2393   taggroup->setText( tr( 
"Tags" ) );
 
 2395   model->appendRow( taggroup );
 
 2397   if ( mSmartGroupVisible )
 
 2399     QStandardItem *smart = 
new QStandardItem( tr( 
"Smart Groups" ) );
 
 2400     smart->setData( 
"smartgroups" );
 
 2401     smart->setEditable( 
false );
 
 2404     QgsSymbolGroupMap::const_iterator i = sgMap.constBegin();
 
 2405     while ( i != sgMap.constEnd() )
 
 2407       QStandardItem *item = 
new QStandardItem( i.value() );
 
 2408       item->setData( i.key() );
 
 2409       item->setEditable( !readOnly );
 
 2410       smart->appendRow( item );
 
 2413     model->appendRow( smart );
 
 2417   int rows = model->rowCount( model->indexFromItem( model->invisibleRootItem() ) );
 
 2418   for ( 
int i = 0; i < rows; i++ )
 
 2420     groupTree->setExpanded( model->indexFromItem( model->item( i ) ), 
true );
 
 2426   QStringList groupSymbols;
 
 2428   const QString category = index.data( Qt::UserRole + 1 ).toString();
 
 2429   sPreviousTag = category;
 
 2431   const bool readOnly = isReadOnly();
 
 2433   if ( mGroupingMode && mModel )
 
 2435     mModel->setTagId( -1 );
 
 2436     mModel->setSmartGroupId( -1 );
 
 2437     mModel->setFavoritesOnly( 
false );
 
 2438     mModel->setCheckTag( index.data( Qt::DisplayRole ).toString() );
 
 2440   else if ( category == QLatin1String( 
"all" ) || category == QLatin1String( 
"tags" ) || category == QLatin1String( 
"smartgroups" ) )
 
 2443     if ( category == QLatin1String( 
"tags" ) )
 
 2445       actnAddTag->setEnabled( !readOnly );
 
 2446       actnAddSmartgroup->setEnabled( 
false );
 
 2448     else if ( category == QLatin1String( 
"smartgroups" ) )
 
 2450       actnAddTag->setEnabled( 
false );
 
 2451       actnAddSmartgroup->setEnabled( !readOnly );
 
 2456       mModel->setTagId( -1 );
 
 2457       mModel->setSmartGroupId( -1 );
 
 2458       mModel->setFavoritesOnly( 
false );
 
 2461   else if ( category == QLatin1String( 
"favorite" ) )
 
 2464     mModel->setTagId( -1 );
 
 2465     mModel->setSmartGroupId( -1 );
 
 2466     mModel->setFavoritesOnly( 
true );
 
 2468   else if ( index.parent().data( Qt::UserRole + 1 ) == 
"smartgroups" )
 
 2470     actnRemoveGroup->setEnabled( !readOnly );
 
 2471     btnManageGroups->setEnabled( !readOnly );
 
 2472     const int groupId = index.data( Qt::UserRole + 1 ).toInt();
 
 2475       mModel->setTagId( -1 );
 
 2476       mModel->setSmartGroupId( groupId );
 
 2477       mModel->setFavoritesOnly( 
false );
 
 2483     int tagId = index.data( Qt::UserRole + 1 ).toInt();
 
 2486       mModel->setTagId( tagId );
 
 2487       mModel->setSmartGroupId( -1 );
 
 2488       mModel->setFavoritesOnly( 
false );
 
 2492   actnEditSmartGroup->setVisible( 
false );
 
 2493   actnAddTag->setVisible( 
false );
 
 2494   actnAddSmartgroup->setVisible( 
false );
 
 2495   actnRemoveGroup->setVisible( 
false );
 
 2496   actnTagSymbols->setVisible( 
false );
 
 2497   actnFinishTagging->setVisible( 
false );
 
 2499   if ( index.parent().isValid() )
 
 2501     if ( index.parent().data( Qt::UserRole + 1 ).toString() == QLatin1String( 
"smartgroups" ) )
 
 2503       actnEditSmartGroup->setVisible( !mGroupingMode && !readOnly );
 
 2505     else if ( index.parent().data( Qt::UserRole + 1 ).toString() == QLatin1String( 
"tags" ) )
 
 2507       actnAddTag->setVisible( !mGroupingMode && !readOnly );
 
 2508       actnTagSymbols->setVisible( !mGroupingMode && !readOnly );
 
 2509       actnFinishTagging->setVisible( mGroupingMode && !readOnly );
 
 2511     actnRemoveGroup->setVisible( !readOnly );
 
 2513   else if ( index.data( Qt::UserRole + 1 ) == 
"smartgroups" )
 
 2515     actnAddSmartgroup->setVisible( !mGroupingMode && !readOnly );
 
 2517   else if ( index.data( Qt::UserRole + 1 ) == 
"tags" )
 
 2519     actnAddTag->setVisible( !mGroupingMode && !readOnly );
 
 2528   QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
 
 2530   for ( 
int i = 0; i < groupTree->model()->rowCount(); i++ )
 
 2532     index = groupTree->model()->index( i, 0 );
 
 2533     QString data = index.data( Qt::UserRole + 1 ).toString();
 
 2534     if ( data == QLatin1String( 
"tags" ) )
 
 2543   itemName = QInputDialog::getText( 
this, tr( 
"Add Tag" ),
 
 2544                                     tr( 
"Please enter name for the new tag:" ), QLineEdit::Normal, tr( 
"New tag" ), &ok ).trimmed();
 
 2545   if ( !ok || itemName.isEmpty() )
 
 2548   int check = mStyle->
tagId( itemName );
 
 2551     mMessageBar->pushCritical( tr( 
"Add Tag" ), tr( 
"The tag “%1” already exists." ).arg( itemName ) );
 
 2557   mBlockGroupUpdates++;
 
 2558   id = mStyle->
addTag( itemName );
 
 2559   mBlockGroupUpdates--;
 
 2563     mMessageBar->pushCritical( tr( 
"Add Tag" ),  tr( 
"New tag could not be created — There was a problem with the symbol database." ) );
 
 2567   QStandardItem *parentItem = model->itemFromIndex( index );
 
 2568   QStandardItem *childItem = 
new QStandardItem( itemName );
 
 2569   childItem->setData( 
id );
 
 2571   parentItem->appendRow( childItem );
 
 2581   QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
 
 2583   for ( 
int i = 0; i < groupTree->model()->rowCount(); i++ )
 
 2585     index = groupTree->model()->index( i, 0 );
 
 2586     QString data = index.data( Qt::UserRole + 1 ).toString();
 
 2587     if ( data == QLatin1String( 
"smartgroups" ) )
 
 2596   if ( dlg.exec() == QDialog::Rejected )
 
 2601   mBlockGroupUpdates++;
 
 2603   mBlockGroupUpdates--;
 
 2609   QStandardItem *parentItem = model->itemFromIndex( index );
 
 2610   QStandardItem *childItem = 
new QStandardItem( itemName );
 
 2611   childItem->setData( 
id );
 
 2612   parentItem->appendRow( childItem );
 
 2622   QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
 
 2623   QModelIndex index = groupTree->currentIndex();
 
 2626   QString data = index.data( Qt::UserRole + 1 ).toString();
 
 2627   if ( data == QLatin1String( 
"all" ) || data == QLatin1String( 
"favorite" ) || data == QLatin1String( 
"tags" ) || index.data() == 
"smartgroups" )
 
 2630     int err = QMessageBox::critical( 
this, tr( 
"Remove Group" ),
 
 2631                                      tr( 
"Invalid selection. Cannot delete system defined categories.\n" 
 2632                                          "Kindly select a group or smart group you might want to delete." ) );
 
 2637   QStandardItem *parentItem = model->itemFromIndex( index.parent() );
 
 2641   mBlockGroupUpdates++;
 
 2643   if ( parentItem->data( Qt::UserRole + 1 ).toString() == QLatin1String( 
"smartgroups" ) )
 
 2652   mBlockGroupUpdates--;
 
 2653   parentItem->removeRow( index.row() );
 
 2661   QgsDebugMsg( QStringLiteral( 
"Symbol group edited: data=%1 text=%2" ).arg( item->data( Qt::UserRole + 1 ).toString(), item->text() ) );
 
 2662   int id = item->data( Qt::UserRole + 1 ).toInt();
 
 2663   QString name = item->text();
 
 2664   mBlockGroupUpdates++;
 
 2665   if ( item->parent()->data( Qt::UserRole + 1 ) == 
"smartgroups" )
 
 2673   mBlockGroupUpdates--;
 
 2681   QStandardItemModel *treeModel = qobject_cast<QStandardItemModel *>( groupTree->model() );
 
 2683   if ( mGroupingMode )
 
 2685     mGroupingMode = 
false;
 
 2686     mModel->setCheckable( 
false );
 
 2687     actnTagSymbols->setVisible( 
true );
 
 2688     actnFinishTagging->setVisible( 
false );
 
 2696     connect( treeModel, &QStandardItemModel::itemChanged,
 
 2700     listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
 
 2701     mSymbolTreeView->setSelectionMode( QAbstractItemView::ExtendedSelection );
 
 2705     bool validGroup = 
false;
 
 2707     QModelIndex present = groupTree->currentIndex();
 
 2708     while ( present.parent().isValid() )
 
 2710       if ( present.parent().data() == 
"Tags" )
 
 2715       present = present.parent();
 
 2720     mGroupingMode = 
true;
 
 2722     actnTagSymbols->setVisible( 
false );
 
 2723     actnFinishTagging->setVisible( 
true );
 
 2725     disconnect( treeModel, &QStandardItemModel::itemChanged,
 
 2731     btnManageGroups->setEnabled( 
true );
 
 2733     mModel->setCheckable( 
true );
 
 2736     listItems->setSelectionMode( QAbstractItemView::NoSelection );
 
 2737     mSymbolTreeView->setSelectionMode( QAbstractItemView::NoSelection );
 
 2751   mModel->setFilterString( qword );
 
 2756   actnEditItem->setEnabled( index.isValid() && !mGroupingMode && !isReadOnly() );
 
 2761   Q_UNUSED( selected )
 
 2762   Q_UNUSED( deselected )
 
 2763   const bool nothingSelected = listItems->selectionModel()->selectedIndexes().empty();
 
 2764   const bool readOnly = isReadOnly();
 
 2765   actnRemoveItem->setDisabled( nothingSelected || readOnly );
 
 2766   actnAddFavorite->setDisabled( nothingSelected || readOnly );
 
 2767   actnRemoveFavorite->setDisabled( nothingSelected || readOnly );
 
 2768   mGroupListMenu->setDisabled( nothingSelected || readOnly );
 
 2769   actnDetag->setDisabled( nothingSelected || readOnly );
 
 2770   actnExportAsPNG->setDisabled( nothingSelected );
 
 2771   actnExportAsSVG->setDisabled( nothingSelected );
 
 2772   if ( mActionCopyToDefault )
 
 2773     mActionCopyToDefault->setDisabled( nothingSelected );
 
 2774   mCopyToDefaultButton->setDisabled( nothingSelected );
 
 2775   actnEditItem->setDisabled( nothingSelected || readOnly );
 
 2780   const bool readOnly = isReadOnly();
 
 2781   groupTree->setEnabled( enable );
 
 2782   btnAddTag->setEnabled( enable && !readOnly );
 
 2783   btnAddSmartgroup->setEnabled( enable && !readOnly );
 
 2784   actnAddTag->setEnabled( enable && !readOnly );
 
 2785   actnAddSmartgroup->setEnabled( enable && !readOnly );
 
 2786   actnRemoveGroup->setEnabled( enable && !readOnly );
 
 2787   btnManageGroups->setEnabled( !readOnly && ( enable || mGroupingMode ) ); 
 
 2788   searchBox->setEnabled( enable );
 
 2793   const bool readOnly = isReadOnly();
 
 2794   actnRemoveGroup->setEnabled( enable && !readOnly );
 
 2795   btnManageGroups->setEnabled( !readOnly && ( enable || mGroupingMode ) ); 
 
 2800   QStandardItemModel *treeModel = qobject_cast<QStandardItemModel *>( groupTree->model() );
 
 2801   for ( 
int i = 0; i < treeModel->rowCount(); i++ )
 
 2803     treeModel->item( i )->setEnabled( enable );
 
 2805     if ( treeModel->item( i )->data() == 
"smartgroups" )
 
 2807       for ( 
int j = 0; j < treeModel->item( i )->rowCount(); j++ )
 
 2809         treeModel->item( i )->child( j )->setEnabled( enable );
 
 2816   for ( 
int i = 0; i < symbolBtnsLayout->count(); i++ )
 
 2818     QWidget *w = symbolBtnsLayout->itemAt( i )->widget();
 
 2820       w->setEnabled( enable );
 
 2824   actnRemoveItem->setEnabled( enable );
 
 2825   actnEditItem->setEnabled( enable );
 
 2826   mActionCopyItem->setEnabled( enable );
 
 2827   mActionPasteItem->setEnabled( enable );
 
 2832   QPoint globalPos = groupTree->viewport()->mapToGlobal( point );
 
 2834   QModelIndex index = groupTree->indexAt( point );
 
 2835   if ( index.isValid() && !mGroupingMode )
 
 2836     mGroupTreeContextMenu->popup( globalPos );
 
 2841   QPoint globalPos = mSymbolViewStackedWidget->currentIndex() == 0
 
 2842                      ? listItems->viewport()->mapToGlobal( point )
 
 2843                      : mSymbolTreeView->viewport()->mapToGlobal( point );
 
 2846   mGroupListMenu->clear();
 
 2848   const QModelIndexList indices = listItems->selectionModel()->selectedRows();
 
 2850   if ( !isReadOnly() )
 
 2852     const QStringList currentTags = indices.count() == 1 ? indices.at( 0 ).data( 
QgsStyleModel::TagRole ).toStringList() : QStringList();
 
 2853     QAction *a = 
nullptr;
 
 2854     QStringList tags = mStyle->
tags();
 
 2856     for ( 
const QString &tag : std::as_const( tags ) )
 
 2858       a = 
new QAction( tag, mGroupListMenu );
 
 2860       if ( indices.count() == 1 )
 
 2862         a->setCheckable( 
true );
 
 2863         a->setChecked( currentTags.contains( tag ) );
 
 2867       mGroupListMenu->addAction( a );
 
 2870     if ( tags.count() > 0 )
 
 2872       mGroupListMenu->addSeparator();
 
 2874     a = 
new QAction( tr( 
"Create New Tag…" ), mGroupListMenu );
 
 2877     mGroupListMenu->addAction( a );
 
 2880   const QList< ItemDetails > items = selectedItems();
 
 2883   bool enablePaste = 
false;
 
 2891   mActionPasteItem->setEnabled( enablePaste );
 
 2893   mGroupMenu->popup( globalPos );
 
 2901   const QList< ItemDetails > items = selectedItems();
 
 2902   for ( 
const ItemDetails &details : items )
 
 2904     mStyle->
addFavorite( details.entityType, details.name );
 
 2913   const QList< ItemDetails > items = selectedItems();
 
 2914   for ( 
const ItemDetails &details : items )
 
 2922   QAction *selectedItem = qobject_cast<QAction *>( sender() );
 
 2925     const QList< ItemDetails > items = selectedItems();
 
 2935       tag = mStyle->
tag( 
id );
 
 2939       tag = selectedItem->data().toString();
 
 2942     for ( 
const ItemDetails &details : items )
 
 2944       mStyle->
tagSymbol( details.entityType, details.name, QStringList( tag ) );
 
 2954   QAction *selectedItem = qobject_cast<QAction *>( sender() );
 
 2958     const QList< ItemDetails > items = selectedItems();
 
 2959     for ( 
const ItemDetails &details : items )
 
 2961       mStyle->
detagSymbol( details.entityType, details.name );
 
 2971   QStandardItemModel *treeModel = qobject_cast<QStandardItemModel *>( groupTree->model() );
 
 2974   QModelIndex present = groupTree->currentIndex();
 
 2975   if ( present.parent().data( Qt::UserRole + 1 ) != 
"smartgroups" )
 
 2978     QMessageBox::critical( 
this, tr( 
"Edit Smart Group" ),
 
 2979                            tr( 
"You have not selected a Smart Group. Kindly select a Smart Group to edit." ) );
 
 2982   QStandardItem *item = treeModel->itemFromIndex( present );
 
 2990   if ( dlg.exec() == QDialog::Rejected )
 
 2993   mBlockGroupUpdates++;
 
 2996   mBlockGroupUpdates--;
 
 2999     mMessageBar->pushCritical( tr( 
"Edit Smart Group" ), tr( 
"There was an error while editing the smart group." ) );
 
 3003   item->setData( 
id );