39 #include <QFileDialog>
40 #include <QInputDialog>
41 #include <QMessageBox>
42 #include <QPushButton>
43 #include <QStandardItemModel>
55 QgsCheckableStyleModel::QgsCheckableStyleModel(
QgsStyleModel *sourceModel, QObject *parent,
bool readOnly )
57 , mStyle( sourceModel->style() )
58 , mReadOnly( readOnly )
63 QgsCheckableStyleModel::QgsCheckableStyleModel(
QgsStyle *style, QObject *parent,
bool readOnly )
66 , mReadOnly( readOnly )
70 void QgsCheckableStyleModel::setCheckable(
bool checkable )
72 if ( checkable == mCheckable )
75 mCheckable = checkable;
76 emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ), QVector< int >() << Qt::CheckStateRole );
79 void QgsCheckableStyleModel::setCheckTag(
const QString &tag )
81 if ( tag == mCheckTag )
85 emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ), QVector< int >() << Qt::CheckStateRole );
88 Qt::ItemFlags QgsCheckableStyleModel::flags(
const QModelIndex &index )
const
90 Qt::ItemFlags f = QgsStyleProxyModel::flags( index );
91 if ( !mReadOnly && mCheckable && index.column() == 0 )
92 f |= Qt::ItemIsUserCheckable;
95 f &= ~Qt::ItemIsEditable;
100 QVariant QgsCheckableStyleModel::data(
const QModelIndex &index,
int role )
const
107 QFont f = QgsStyleProxyModel::data( index, role ).value< QFont >();
112 case Qt::CheckStateRole:
114 if ( !mCheckable || index.column() != 0 )
118 return tags.contains( mCheckTag ) ? Qt::Checked : Qt::Unchecked;
125 return QgsStyleProxyModel::data( index, role );
128 bool QgsCheckableStyleModel::setData(
const QModelIndex &i,
const QVariant &value,
int role )
130 if ( i.row() < 0 || i.row() >= rowCount( QModelIndex() ) ||
131 ( role != Qt::EditRole && role != Qt::CheckStateRole ) )
137 if ( role == Qt::CheckStateRole )
139 if ( !mCheckable || mCheckTag.isEmpty() )
142 const QString name = data( index( i.row(),
QgsStyleModel::Name ), Qt::DisplayRole ).toString();
145 if ( value.toInt() == Qt::Checked )
146 return mStyle->tagSymbol( entity, name, QStringList() << mCheckTag );
148 return mStyle->detagSymbol( entity, name, QStringList() << mCheckTag );
150 return QgsStyleProxyModel::setData( i, value, role );
161 : QDialog( parent, flags )
163 , mReadOnly( readOnly )
167 connect( tabItemType, &QTabWidget::currentChanged,
this, &QgsStyleManagerDialog::tabItemType_currentChanged );
172 mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
173 mVerticalLayout->insertWidget( 0, mMessageBar );
176 setWindowModality( Qt::WindowModal );
181 mSplitter->setSizes( QList<int>() << 170 << 540 );
182 mSplitter->restoreState( settings.
value( QStringLiteral(
"Windows/StyleV2Manager/splitter" ) ).toByteArray() );
184 tabItemType->setDocumentMode(
true );
185 searchBox->setShowSearchIcon(
true );
186 searchBox->setPlaceholderText( tr(
"Filter symbols…" ) );
190 connect( btnEditItem, &QPushButton::clicked,
this, [ = ](
bool ) {
editItem(); }
192 connect( actnEditItem, &QAction::triggered,
this, [ = ](
bool ) {
editItem(); }
197 connect( btnAddItem, &QPushButton::clicked,
this, [ = ](
bool ) {
addItem(); }
200 connect( btnRemoveItem, &QPushButton::clicked,
this, [ = ](
bool ) {
removeItem(); }
202 connect( actnRemoveItem, &QAction::triggered,
this, [ = ](
bool ) {
removeItem(); }
207 btnAddTag->setEnabled(
false );
208 btnAddSmartgroup->setEnabled(
false );
211 QMenu *shareMenu =
new QMenu( tr(
"Share Menu" ),
this );
212 QAction *exportAction =
new QAction( tr(
"Export Item(s)…" ),
this );
214 shareMenu->addAction( exportAction );
217 QAction *importAction =
new QAction( tr(
"Import Item(s)…" ),
this );
219 shareMenu->addAction( importAction );
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 );
231 mCopyToDefaultButton->hide();
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 );
239 shareMenu->addSeparator();
240 shareMenu->addAction( actnExportAsPNG );
241 shareMenu->addAction( actnExportAsSVG );
246 btnShare->setMenu( shareMenu );
248 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
253 listItems->setIconSize( QSize(
static_cast< int >(
iconSize ),
static_cast< int >(
iconSize * 0.9 ) ) );
254 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
259 mSymbolTreeView->setIconSize( QSize(
static_cast< int >( treeIconSize ),
static_cast< int >( treeIconSize ) ) );
262 :
new QgsCheckableStyleModel( mStyle,
this, mReadOnly );
263 mModel->addDesiredIconSize( listItems->iconSize() );
264 mModel->addDesiredIconSize( mSymbolTreeView->iconSize() );
265 listItems->setModel( mModel );
266 mSymbolTreeView->setModel( mModel );
268 listItems->setSelectionBehavior( QAbstractItemView::SelectRows );
269 listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
270 mSymbolTreeView->setSelectionModel( listItems->selectionModel() );
271 mSymbolTreeView->setSelectionMode( listItems->selectionMode() );
273 connect( listItems->selectionModel(), &QItemSelectionModel::currentChanged,
275 connect( listItems->selectionModel(), &QItemSelectionModel::selectionChanged,
278 QStandardItemModel *groupModel =
new QStandardItemModel( groupTree );
279 groupTree->setModel( groupModel );
280 groupTree->setHeaderHidden(
true );
282 groupTree->setCurrentIndex( groupTree->model()->index( 0, 0 ) );
284 connect( groupTree->selectionModel(), &QItemSelectionModel::currentChanged,
288 connect( groupModel, &QStandardItemModel::itemChanged,
294 QMenu *groupMenu =
new QMenu( tr(
"Group Actions" ),
this );
296 groupMenu->addAction( actnTagSymbols );
298 actnFinishTagging->setVisible(
false );
299 groupMenu->addAction( actnFinishTagging );
300 groupMenu->addAction( actnEditSmartGroup );
301 btnManageGroups->setMenu( groupMenu );
305 btnManageGroups->setEnabled(
false );
311 groupTree->setContextMenuPolicy( Qt::CustomContextMenu );
312 connect( groupTree, &QWidget::customContextMenuRequested,
316 listItems->setContextMenuPolicy( Qt::CustomContextMenu );
317 connect( listItems, &QWidget::customContextMenuRequested,
319 mSymbolTreeView->setContextMenuPolicy( Qt::CustomContextMenu );
320 connect( mSymbolTreeView, &QWidget::customContextMenuRequested,
326 QStringList rampTypes;
327 rampTypes << tr(
"Gradient…" ) << tr(
"Color presets…" ) << tr(
"Random…" ) << tr(
"Catalog: cpt-city…" );
328 rampTypes << tr(
"Catalog: ColorBrewer…" );
330 mMenuBtnAddItemAll =
new QMenu(
this );
331 mMenuBtnAddItemColorRamp =
new QMenu(
this );
332 mMenuBtnAddItemLabelSettings =
new QMenu(
this );
333 mMenuBtnAddItemLegendPatchShape =
new QMenu(
this );
337 mMenuBtnAddItemAll->addAction( item );
340 mMenuBtnAddItemAll->addAction( item );
343 mMenuBtnAddItemAll->addAction( item );
344 mMenuBtnAddItemAll->addSeparator();
345 for (
const QString &rampType : qgis::as_const( rampTypes ) )
348 connect( item, &QAction::triggered,
this, [ = ](
bool ) {
addColorRamp( item ); } );
349 mMenuBtnAddItemAll->addAction( item );
350 mMenuBtnAddItemColorRamp->addAction(
new QAction( rampType,
this ) );
352 mMenuBtnAddItemAll->addSeparator();
354 connect( item, &QAction::triggered,
this, [ = ](
bool ) { addTextFormat(); } );
355 mMenuBtnAddItemAll->addAction( item );
356 mMenuBtnAddItemAll->addSeparator();
359 mMenuBtnAddItemAll->addAction( item );
360 mMenuBtnAddItemLabelSettings->addAction( item );
363 mMenuBtnAddItemAll->addAction( item );
364 mMenuBtnAddItemLabelSettings->addAction( item );
367 mMenuBtnAddItemAll->addAction( item );
368 mMenuBtnAddItemLabelSettings->addAction( item );
370 mMenuBtnAddItemAll->addSeparator();
372 connect( item, &QAction::triggered,
this, [ = ](
bool ) { addLegendPatchShape(
QgsSymbol::Marker ); } );
373 mMenuBtnAddItemAll->addAction( item );
374 mMenuBtnAddItemLegendPatchShape->addAction( item );
376 connect( item, &QAction::triggered,
this, [ = ](
bool ) { addLegendPatchShape(
QgsSymbol::Line ); } );
377 mMenuBtnAddItemAll->addAction( item );
378 mMenuBtnAddItemLegendPatchShape->addAction( item );
380 connect( item, &QAction::triggered,
this, [ = ](
bool ) { addLegendPatchShape(
QgsSymbol::Fill ); } );
381 mMenuBtnAddItemAll->addAction( item );
382 mMenuBtnAddItemLegendPatchShape->addAction( item );
384 connect( mMenuBtnAddItemColorRamp, &QMenu::triggered,
389 mGroupMenu =
new QMenu(
this );
390 mGroupListMenu =
new QMenu( mGroupMenu );
391 mGroupListMenu->setTitle( tr(
"Add to Tag" ) );
392 mGroupListMenu->setEnabled(
false );
396 mGroupMenu->addAction( actnAddFavorite );
398 mGroupMenu->addAction( actnRemoveFavorite );
399 mGroupMenu->addSeparator()->setParent(
this );
400 mGroupMenu->addMenu( mGroupListMenu );
401 actnDetag->setData( 0 );
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 );
413 btnAddItem->setVisible(
false );
414 btnRemoveItem->setVisible(
false );
415 btnEditItem->setVisible(
false );
416 btnAddSmartgroup->setVisible(
false );
417 btnAddTag->setVisible(
false );
418 btnManageGroups->setVisible(
false );
420 mGroupMenu->addAction( mActionCopyItem );
422 if ( mActionCopyToDefault )
424 mGroupMenu->addAction( mActionCopyToDefault );
426 mGroupMenu->addAction( actnExportAsPNG );
427 mGroupMenu->addAction( actnExportAsSVG );
430 mGroupTreeContextMenu =
new QMenu(
this );
434 mGroupTreeContextMenu->addAction( actnEditSmartGroup );
435 connect( actnAddTag, &QAction::triggered,
this, [ = ](
bool ) {
addTag(); }
437 mGroupTreeContextMenu->addAction( actnAddTag );
438 connect( actnAddSmartgroup, &QAction::triggered,
this, [ = ](
bool ) {
addSmartgroup(); }
440 mGroupTreeContextMenu->addAction( actnAddSmartgroup );
442 mGroupTreeContextMenu->addAction( actnRemoveGroup );
445 tabItemType_currentChanged( 0 );
450 connect( mButtonIconView, &QToolButton::toggled,
this, [ = ](
bool active )
454 mSymbolViewStackedWidget->setCurrentIndex( 0 );
459 connect( mButtonListView, &QToolButton::toggled,
this, [ = ](
bool active )
464 mSymbolViewStackedWidget->setCurrentIndex( 1 );
468 const int currentView = settings.
value( QStringLiteral(
"Windows/StyleV2Manager/lastIconView" ), 0,
QgsSettings::Gui ).toInt();
469 if ( currentView == 0 )
470 mButtonIconView->setChecked(
true );
472 mButtonListView->setChecked(
true );
474 mSymbolTreeView->header()->restoreState( settings.
value( QStringLiteral(
"Windows/StyleV2Manager/treeState" ), QByteArray(),
QgsSettings::Gui ).toByteArray() );
475 connect( mSymbolTreeView->header(), &QHeaderView::sectionResized,
this, [
this]
478 QgsSettings().setValue( QStringLiteral(
"Windows/StyleV2Manager/treeState" ), mSymbolTreeView->header()->saveState(), QgsSettings::Gui );
487 if ( mModified && !mReadOnly )
493 settings.
setValue( QStringLiteral(
"Windows/StyleV2Manager/splitter" ), mSplitter->saveState() );
500 void QgsStyleManagerDialog::tabItemType_currentChanged(
int )
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…" ) );
512 if ( !mReadOnly && isColorRamp )
514 btnAddItem->setMenu( mMenuBtnAddItemColorRamp );
516 if ( !mReadOnly && !isSymbol && !isColorRamp && !isTextFormat && !isLabelSettings )
518 btnAddItem->setMenu( mMenuBtnAddItemLegendPatchShape );
520 else if ( !mReadOnly && isLabelSettings )
522 btnAddItem->setMenu( mMenuBtnAddItemLabelSettings );
524 else if ( !mReadOnly && !isSymbol && !isColorRamp )
526 btnAddItem->setMenu(
nullptr );
528 else if ( !mReadOnly && tabItemType->currentIndex() == 0 )
530 btnAddItem->setMenu( mMenuBtnAddItemAll );
534 btnAddItem->setMenu(
nullptr );
537 actnExportAsPNG->setVisible( isSymbol );
538 actnExportAsSVG->setVisible( isSymbol );
541 mModel->setEntityFilterEnabled( !allTypesSelected() );
542 mModel->setSymbolTypeFilterEnabled( isSymbol && !allTypesSelected() );
543 if ( isSymbol && !allTypesSelected() )
549 void QgsStyleManagerDialog::copyItemsToDefault()
551 const QList< ItemDetails > items = selectedItems();
552 if ( !items.empty() )
556 if ( !mBaseName.isEmpty() )
557 options.append( mBaseName );
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 );
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();
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();
578 mMessageBar->
pushSuccess( tr(
"Import Items" ), count > 1 ? tr(
"Successfully imported %1 items." ).arg( count ) : tr(
"Successfully imported item." ) );
583 void QgsStyleManagerDialog::copyItem()
585 const QList< ItemDetails > items = selectedItems();
589 ItemDetails details = items.at( 0 );
590 switch ( details.entityType )
594 std::unique_ptr< QgsSymbol > symbol( mStyle->
symbol( details.name ) );
604 QApplication::clipboard()->setMimeData( format.toMimeData() );
611 QApplication::clipboard()->setMimeData( format.toMimeData() );
624 void QgsStyleManagerDialog::pasteItem()
626 const QString defaultTag = groupTree->currentIndex().isValid() ? groupTree->currentIndex().data().toString() : QString();
630 QgsStyleSaveDialog saveDlg(
this );
631 saveDlg.setWindowTitle( tr(
"Paste Symbol" ) );
632 saveDlg.setDefaultTags( defaultTag );
633 if ( !saveDlg.exec() || saveDlg.name().isEmpty() )
636 if ( mStyle->
symbolNames().contains( saveDlg.name() ) )
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 )
649 QStringList symbolTags = saveDlg.tags().split(
',' );
650 mStyle->
addSymbol( saveDlg.name(), tempSymbol->clone() );
652 mStyle->
saveSymbol( saveDlg.name(), tempSymbol->clone(), saveDlg.isFavorite(), symbolTags );
661 saveDlg.setDefaultTags( defaultTag );
662 saveDlg.setWindowTitle( tr(
"Paste Text Format" ) );
663 if ( !saveDlg.exec() || saveDlg.name().isEmpty() )
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 )
679 QStringList symbolTags = saveDlg.tags().split(
',' );
682 mStyle->
saveTextFormat( saveDlg.name(), format, saveDlg.isFavorite(), symbolTags );
687 int QgsStyleManagerDialog::selectedItemType()
689 QModelIndex index = listItems->selectionModel()->currentIndex();
690 if ( !index.isValid() )
706 bool QgsStyleManagerDialog::allTypesSelected()
const
708 return tabItemType->currentIndex() == 0;
711 QList< QgsStyleManagerDialog::ItemDetails > QgsStyleManagerDialog::selectedItems()
713 QList<QgsStyleManagerDialog::ItemDetails > res;
714 QModelIndexList indices = listItems->selectionModel()->selectedRows();
715 for (
const QModelIndex &index : indices )
717 if ( !index.isValid() )
724 details.name = mModel->data( mModel->index( index.row(),
QgsStyleModel::Name, index.parent() ), Qt::DisplayRole ).toString();
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 )
735 bool overwriteAll =
true;
744 for (
auto &details : items )
746 QStringList symbolTags;
747 if ( !ignoreSourceTags )
749 symbolTags = src->
tagsOfSymbol( details.entityType, details.name );
752 bool addItemToFavorites =
false;
755 symbolTags << importTags;
756 addItemToFavorites = addToFavorites;
759 switch ( details.entityType )
763 std::unique_ptr< QgsSymbol > symbol( src->
symbol( details.name ) );
767 const bool hasDuplicateName = dst->
symbolNames().contains( details.name );
768 bool overwriteThis =
false;
770 addItemToFavorites = favoriteSymbols.contains( details.name );
772 if ( hasDuplicateName && prompt )
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 );
782 case QMessageBox::Cancel:
785 case QMessageBox::No:
788 case QMessageBox::Yes:
789 overwriteThis =
true;
792 case QMessageBox::YesToAll:
797 case QMessageBox::NoToAll:
799 overwriteAll =
false;
804 if ( !hasDuplicateName || overwriteAll || overwriteThis )
807 dst->
addSymbol( details.name, symbol.release() );
808 dst->
saveSymbol( details.name, newSymbol, addItemToFavorites, symbolTags );
816 std::unique_ptr< QgsColorRamp > ramp( src->
colorRamp( details.name ) );
820 const bool hasDuplicateName = dst->
colorRampNames().contains( details.name );
821 bool overwriteThis =
false;
823 addItemToFavorites = favoriteColorramps.contains( details.name );
825 if ( hasDuplicateName && prompt )
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 );
835 case QMessageBox::Cancel:
838 case QMessageBox::No:
841 case QMessageBox::Yes:
842 overwriteThis =
true;
845 case QMessageBox::YesToAll:
850 case QMessageBox::NoToAll:
852 overwriteAll =
false;
857 if ( !hasDuplicateName || overwriteAll || overwriteThis )
861 dst->
saveColorRamp( details.name, newRamp, addItemToFavorites, symbolTags );
871 const bool hasDuplicateName = dst->
textFormatNames().contains( details.name );
872 bool overwriteThis =
false;
874 addItemToFavorites = favoriteTextFormats.contains( details.name );
876 if ( hasDuplicateName && prompt )
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 );
886 case QMessageBox::Cancel:
889 case QMessageBox::No:
892 case QMessageBox::Yes:
893 overwriteThis =
true;
896 case QMessageBox::YesToAll:
901 case QMessageBox::NoToAll:
903 overwriteAll =
false;
908 if ( !hasDuplicateName || overwriteAll || overwriteThis )
911 dst->
saveTextFormat( details.name, format, addItemToFavorites, symbolTags );
922 bool overwriteThis =
false;
924 addItemToFavorites = favoriteLabelSettings.contains( details.name );
926 if ( hasDuplicateName && prompt )
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 );
936 case QMessageBox::Cancel:
939 case QMessageBox::No:
942 case QMessageBox::Yes:
943 overwriteThis =
true;
946 case QMessageBox::YesToAll:
951 case QMessageBox::NoToAll:
953 overwriteAll =
false;
958 if ( !hasDuplicateName || overwriteAll || overwriteThis )
961 dst->
saveLabelSettings( details.name, settings, addItemToFavorites, symbolTags );
972 bool overwriteThis =
false;
974 addItemToFavorites = favoriteLegendPatchShapes.contains( details.name );
976 if ( hasDuplicateName && prompt )
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 );
986 case QMessageBox::Cancel:
989 case QMessageBox::No:
992 case QMessageBox::Yes:
993 overwriteThis =
true;
996 case QMessageBox::YesToAll:
1001 case QMessageBox::NoToAll:
1003 overwriteAll =
false;
1008 if ( !hasDuplicateName || overwriteAll || overwriteThis )
1026 bool QgsStyleManagerDialog::addTextFormat()
1030 if ( !formatDlg.exec() )
1032 format = formatDlg.format();
1035 if ( !saveDlg.exec() )
1037 QString name = saveDlg.name();
1040 bool nameInvalid =
true;
1041 while ( nameInvalid )
1044 if ( name.isEmpty() )
1046 QMessageBox::warning(
this, tr(
"Save Text Format" ),
1047 tr(
"Cannot save text format without name. Enter a name." ) );
1051 int res = QMessageBox::warning(
this, tr(
"Save Text Format" ),
1052 tr(
"Text format with name '%1' already exists. Overwrite?" )
1054 QMessageBox::Yes | QMessageBox::No );
1055 if ( res == QMessageBox::Yes )
1058 nameInvalid =
false;
1064 nameInvalid =
false;
1069 name = QInputDialog::getText(
this, tr(
"Text Format Name" ),
1070 tr(
"Please enter a name for new text format:" ),
1071 QLineEdit::Normal, name, &ok );
1079 QStringList symbolTags = saveDlg.tags().split(
',' );
1083 mStyle->
saveTextFormat( name, format, saveDlg.isFavorite(), symbolTags );
1091 groupChanged( groupTree->selectionModel()->currentIndex() );
1104 switch ( tabItemType->currentIndex() )
1127 QModelIndex index = listItems->selectionModel()->currentIndex();
1128 if ( !index.isValid() )
1131 return mModel->data( mModel->index( index.row(),
QgsStyleModel::Name, index.parent() ), Qt::DisplayRole ).toString();
1136 bool changed =
false;
1147 changed = addTextFormat();
1161 Q_ASSERT(
false &&
"not implemented" );
1174 QString name = tr(
"new symbol" );
1179 name = tr(
"new marker" );
1183 name = tr(
"new line" );
1187 name = tr(
"new fill symbol" );
1190 Q_ASSERT(
false &&
"unknown symbol type" );
1200 if ( dlg.exec() == 0 )
1206 QgsStyleSaveDialog saveDlg(
this );
1207 if ( !saveDlg.exec() )
1213 name = saveDlg.name();
1216 bool nameInvalid =
true;
1217 while ( nameInvalid )
1220 if ( name.isEmpty() )
1222 QMessageBox::warning(
this, tr(
"Save Symbol" ),
1223 tr(
"Cannot save symbol without name. Enter a name." ) );
1225 else if ( mStyle->
symbolNames().contains( name ) )
1227 int res = QMessageBox::warning(
this, tr(
"Save Symbol" ),
1228 tr(
"Symbol with name '%1' already exists. Overwrite?" )
1230 QMessageBox::Yes | QMessageBox::No );
1231 if ( res == QMessageBox::Yes )
1234 nameInvalid =
false;
1240 nameInvalid =
false;
1245 name = QInputDialog::getText(
this, tr(
"Symbol Name" ),
1246 tr(
"Please enter a name for new symbol:" ),
1247 QLineEdit::Normal, name, &ok );
1256 QStringList symbolTags = saveDlg.tags().split(
',' );
1260 mStyle->
saveSymbol( name, symbol, saveDlg.isFavorite(), symbolTags );
1271 if ( rampType.isEmpty() )
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 );
1279 if ( !ok || rampType.isEmpty() )
1282 QString name = tr(
"new ramp" );
1284 std::unique_ptr< QgsColorRamp > ramp;
1285 if ( rampType == tr(
"Gradient" ) )
1293 name = tr(
"new gradient ramp" );
1295 else if ( rampType == tr(
"Random" ) )
1303 name = tr(
"new random ramp" );
1305 else if ( rampType == tr(
"Catalog: ColorBrewer" ) )
1315 else if ( rampType == tr(
"Color presets" ) )
1323 name = tr(
"new preset ramp" );
1325 else if ( rampType == tr(
"Catalog: cpt-city" ) )
1347 QgsDebugMsg( QStringLiteral(
"invalid ramp type %1" ).arg( rampType ) );
1352 if ( !saveDlg.exec() )
1357 name = saveDlg.name();
1360 bool nameInvalid =
true;
1361 while ( nameInvalid )
1364 if ( name.isEmpty() )
1366 QMessageBox::warning( parent, tr(
"Save Color Ramp" ),
1367 tr(
"Cannot save color ramp without name. Enter a name." ) );
1371 int res = QMessageBox::warning( parent, tr(
"Save Color Ramp" ),
1372 tr(
"Color ramp with name '%1' already exists. Overwrite?" )
1374 QMessageBox::Yes | QMessageBox::No );
1375 if ( res == QMessageBox::Yes )
1377 nameInvalid =
false;
1383 nameInvalid =
false;
1388 name = QInputDialog::getText( parent, tr(
"Color Ramp Name" ),
1389 tr(
"Please enter a name for new color ramp:" ),
1390 QLineEdit::Normal, name, &ok );
1398 QStringList colorRampTags = saveDlg.tags().split(
',' );
1403 style->
saveColorRamp( name, r, saveDlg.isFavorite(), colorRampTags );
1410 mFavoritesGroupVisible = show;
1416 mSmartGroupVisible = show;
1428 setWindowState( windowState() & ~Qt::WindowMinimized );
1441 action ? action->text() : QString() );
1442 if ( !rampName.isEmpty() )
1454 if ( selectedItemType() < 3 )
1458 else if ( selectedItemType() == 3 )
1462 else if ( selectedItemType() == 4 )
1466 else if ( selectedItemType() == 5 )
1468 editLabelSettings();
1470 else if ( selectedItemType() == 6 )
1472 editLegendPatchShape();
1476 Q_ASSERT(
false &&
"not implemented" );
1483 if ( symbolName.isEmpty() )
1486 std::unique_ptr< QgsSymbol > symbol( mStyle->
symbol( symbolName ) );
1491 dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled(
false );
1497 mStyle->
addSymbol( symbolName, symbol.release(),
true );
1505 if ( name.isEmpty() )
1508 std::unique_ptr< QgsColorRamp > ramp( mStyle->
colorRamp( name ) );
1510 if ( ramp->type() == QLatin1String(
"gradient" ) )
1515 dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled(
false );
1523 else if ( ramp->type() == QLatin1String(
"random" ) )
1528 dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled(
false );
1536 else if ( ramp->type() == QLatin1String(
"colorbrewer" ) )
1541 dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled(
false );
1549 else if ( ramp->type() == QLatin1String(
"preset" ) )
1554 dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled(
false );
1562 else if ( ramp->type() == QLatin1String(
"cpt-city" ) )
1567 dlg.
buttonBox()->button( QDialogButtonBox::Ok )->setEnabled(
false );
1584 Q_ASSERT(
false &&
"invalid ramp type" );
1592 bool QgsStyleManagerDialog::editTextFormat()
1595 if ( formatName.isEmpty() )
1603 dlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled(
false );
1617 QgsLabelSettingsDialog settingsDlg( settings,
nullptr,
nullptr,
this, type );
1619 settingsDlg.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled(
false );
1621 if ( !settingsDlg.exec() )
1624 settings = settingsDlg.settings();
1628 if ( !saveDlg.exec() )
1630 QString name = saveDlg.name();
1633 bool nameInvalid =
true;
1634 while ( nameInvalid )
1637 if ( name.isEmpty() )
1639 QMessageBox::warning(
this, tr(
"Save Label Settings" ),
1640 tr(
"Cannot save label settings without a name. Enter a name." ) );
1644 int res = QMessageBox::warning(
this, tr(
"Save Label Settings" ),
1645 tr(
"Label settings with the name '%1' already exist. Overwrite?" )
1647 QMessageBox::Yes | QMessageBox::No );
1648 if ( res == QMessageBox::Yes )
1651 nameInvalid =
false;
1657 nameInvalid =
false;
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 );
1672 QStringList symbolTags = saveDlg.tags().split(
',' );
1682 bool QgsStyleManagerDialog::editLabelSettings()
1685 if ( formatName.isEmpty() )
1692 QgsLabelSettingsDialog dlg( settings,
nullptr,
nullptr,
this, geomType );
1696 settings = dlg.settings();
1710 dialog.buttonBox()->button( QDialogButtonBox::Ok )->setEnabled(
false );
1712 if ( !dialog.exec() )
1715 shape = dialog.shape();
1718 if ( !saveDlg.exec() )
1720 QString name = saveDlg.name();
1723 bool nameInvalid =
true;
1724 while ( nameInvalid )
1727 if ( name.isEmpty() )
1729 QMessageBox::warning(
this, tr(
"Save Legend Patch Shape" ),
1730 tr(
"Cannot save legend patch shapes without a name. Enter a name." ) );
1734 int res = QMessageBox::warning(
this, tr(
"Save Legend Patch Shape" ),
1735 tr(
"A legend patch shape with the name '%1' already exists. Overwrite?" )
1737 QMessageBox::Yes | QMessageBox::No );
1738 if ( res == QMessageBox::Yes )
1741 nameInvalid =
false;
1747 nameInvalid =
false;
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 );
1762 QStringList symbolTags = saveDlg.tags().split(
',' );
1772 bool QgsStyleManagerDialog::editLegendPatchShape()
1775 if ( shapeName.isEmpty() )
1787 shape = dlg.shape();
1797 const QList< ItemDetails > items = selectedItems();
1799 if ( allTypesSelected() )
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() ) ),
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() ) ),
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() ) ),
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() ) ),
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() ) ),
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() ) ),
1853 for (
const ItemDetails &details : items )
1855 if ( details.name.isEmpty() )
1880 QString dir = QFileDialog::getExistingDirectory(
this, tr(
"Export Selected Symbols as PNG" ),
1881 QDir::home().absolutePath(),
1882 QFileDialog::ShowDirsOnly
1883 | QFileDialog::DontResolveSymlinks );
1889 QString dir = QFileDialog::getExistingDirectory(
this, tr(
"Export Selected Symbols as SVG" ),
1890 QDir::home().absolutePath(),
1891 QFileDialog::ShowDirsOnly
1892 | QFileDialog::DontResolveSymlinks );
1899 if ( dir.isEmpty() )
1902 const QList< ItemDetails > items = selectedItems();
1903 for (
const ItemDetails &details : items )
1908 QString path = dir +
'/' + details.name +
'.' + format;
1909 std::unique_ptr< QgsSymbol > sym( mStyle->
symbol( details.name ) );
1911 sym->exportImage( path, format, size );
1931 QFont font = item->font();
1932 font.setBold(
true );
1933 item->setFont( font );
1938 if ( mBlockGroupUpdates )
1941 QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
1944 if ( mFavoritesGroupVisible )
1946 QStandardItem *favoriteSymbols =
new QStandardItem( tr(
"Favorites" ) );
1947 favoriteSymbols->setData(
"favorite" );
1948 favoriteSymbols->setEditable(
false );
1950 model->appendRow( favoriteSymbols );
1953 QStandardItem *allSymbols =
new QStandardItem( tr(
"All" ) );
1954 allSymbols->setData(
"all" );
1955 allSymbols->setEditable(
false );
1957 model->appendRow( allSymbols );
1959 QStandardItem *taggroup =
new QStandardItem( QString() );
1960 taggroup->setData(
"tags" );
1961 taggroup->setEditable(
false );
1962 QStringList tags = mStyle->
tags();
1964 for (
const QString &tag : qgis::as_const( tags ) )
1966 QStandardItem *item =
new QStandardItem( tag );
1967 item->setData( mStyle->
tagId( tag ) );
1968 item->setEditable( !mReadOnly );
1969 taggroup->appendRow( item );
1971 taggroup->setText( tr(
"Tags" ) );
1973 model->appendRow( taggroup );
1975 if ( mSmartGroupVisible )
1977 QStandardItem *smart =
new QStandardItem( tr(
"Smart Groups" ) );
1978 smart->setData(
"smartgroups" );
1979 smart->setEditable(
false );
1982 QgsSymbolGroupMap::const_iterator i = sgMap.constBegin();
1983 while ( i != sgMap.constEnd() )
1985 QStandardItem *item =
new QStandardItem( i.value() );
1986 item->setData( i.key() );
1987 item->setEditable( !mReadOnly );
1988 smart->appendRow( item );
1991 model->appendRow( smart );
1995 int rows = model->rowCount( model->indexFromItem( model->invisibleRootItem() ) );
1996 for (
int i = 0; i < rows; i++ )
1998 groupTree->setExpanded( model->indexFromItem( model->item( i ) ),
true );
2004 QStringList groupSymbols;
2006 const QString category = index.data( Qt::UserRole + 1 ).toString();
2007 if ( mGroupingMode )
2009 mModel->setTagId( -1 );
2010 mModel->setSmartGroupId( -1 );
2011 mModel->setFavoritesOnly(
false );
2012 mModel->setCheckTag( index.data( Qt::DisplayRole ).toString() );
2014 else if ( category == QLatin1String(
"all" ) || category == QLatin1String(
"tags" ) || category == QLatin1String(
"smartgroups" ) )
2017 if ( category == QLatin1String(
"tags" ) )
2019 actnAddTag->setEnabled( !mReadOnly );
2020 actnAddSmartgroup->setEnabled(
false );
2022 else if ( category == QLatin1String(
"smartgroups" ) )
2024 actnAddTag->setEnabled(
false );
2025 actnAddSmartgroup->setEnabled( !mReadOnly );
2028 mModel->setTagId( -1 );
2029 mModel->setSmartGroupId( -1 );
2030 mModel->setFavoritesOnly(
false );
2032 else if ( category == QLatin1String(
"favorite" ) )
2035 mModel->setTagId( -1 );
2036 mModel->setSmartGroupId( -1 );
2037 mModel->setFavoritesOnly(
true );
2039 else if ( index.parent().data( Qt::UserRole + 1 ) ==
"smartgroups" )
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 );
2051 int tagId = index.data( Qt::UserRole + 1 ).toInt();
2052 mModel->setTagId( tagId );
2053 mModel->setSmartGroupId( -1 );
2054 mModel->setFavoritesOnly(
false );
2057 actnEditSmartGroup->setVisible(
false );
2058 actnAddTag->setVisible(
false );
2059 actnAddSmartgroup->setVisible(
false );
2060 actnRemoveGroup->setVisible(
false );
2061 actnTagSymbols->setVisible(
false );
2062 actnFinishTagging->setVisible(
false );
2064 if ( index.parent().isValid() )
2066 if ( index.parent().data( Qt::UserRole + 1 ).toString() == QLatin1String(
"smartgroups" ) )
2068 actnEditSmartGroup->setVisible( !mGroupingMode && !mReadOnly );
2070 else if ( index.parent().data( Qt::UserRole + 1 ).toString() == QLatin1String(
"tags" ) )
2072 actnAddTag->setVisible( !mGroupingMode && !mReadOnly );
2073 actnTagSymbols->setVisible( !mGroupingMode && !mReadOnly );
2074 actnFinishTagging->setVisible( mGroupingMode && !mReadOnly );
2076 actnRemoveGroup->setVisible( !mReadOnly );
2078 else if ( index.data( Qt::UserRole + 1 ) ==
"smartgroups" )
2080 actnAddSmartgroup->setVisible( !mGroupingMode && !mReadOnly );
2082 else if ( index.data( Qt::UserRole + 1 ) ==
"tags" )
2084 actnAddTag->setVisible( !mGroupingMode && !mReadOnly );
2090 QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
2092 for (
int i = 0; i < groupTree->model()->rowCount(); i++ )
2094 index = groupTree->model()->index( i, 0 );
2095 QString data = index.data( Qt::UserRole + 1 ).toString();
2096 if ( data == QLatin1String(
"tags" ) )
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() )
2110 int check = mStyle->
tagId( itemName );
2113 mMessageBar->
pushCritical( tr(
"Add Tag" ), tr(
"The tag “%1” already exists." ).arg( itemName ) );
2119 mBlockGroupUpdates++;
2120 id = mStyle->
addTag( itemName );
2121 mBlockGroupUpdates--;
2125 mMessageBar->
pushCritical( tr(
"Add Tag" ), tr(
"New tag could not be created — There was a problem with the symbol database." ) );
2129 QStandardItem *parentItem = model->itemFromIndex( index );
2130 QStandardItem *childItem =
new QStandardItem( itemName );
2131 childItem->setData(
id );
2132 parentItem->appendRow( childItem );
2139 QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
2141 for (
int i = 0; i < groupTree->model()->rowCount(); i++ )
2143 index = groupTree->model()->index( i, 0 );
2144 QString data = index.data( Qt::UserRole + 1 ).toString();
2145 if ( data == QLatin1String(
"smartgroups" ) )
2154 if ( dlg.exec() == QDialog::Rejected )
2159 mBlockGroupUpdates++;
2161 mBlockGroupUpdates--;
2167 QStandardItem *parentItem = model->itemFromIndex( index );
2168 QStandardItem *childItem =
new QStandardItem( itemName );
2169 childItem->setData(
id );
2170 parentItem->appendRow( childItem );
2177 QStandardItemModel *model = qobject_cast<QStandardItemModel *>( groupTree->model() );
2178 QModelIndex index = groupTree->currentIndex();
2181 QString data = index.data( Qt::UserRole + 1 ).toString();
2182 if ( data == QLatin1String(
"all" ) || data == QLatin1String(
"favorite" ) || data == QLatin1String(
"tags" ) || index.data() ==
"smartgroups" )
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." ) );
2192 QStandardItem *parentItem = model->itemFromIndex( index.parent() );
2196 mBlockGroupUpdates++;
2198 if ( parentItem->data( Qt::UserRole + 1 ).toString() == QLatin1String(
"smartgroups" ) )
2207 mBlockGroupUpdates--;
2208 parentItem->removeRow( index.row() );
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" )
2225 mBlockGroupUpdates--;
2230 QStandardItemModel *treeModel = qobject_cast<QStandardItemModel *>( groupTree->model() );
2232 if ( mGroupingMode )
2234 mGroupingMode =
false;
2235 mModel->setCheckable(
false );
2236 actnTagSymbols->setVisible(
true );
2237 actnFinishTagging->setVisible(
false );
2245 connect( treeModel, &QStandardItemModel::itemChanged,
2249 listItems->setSelectionMode( QAbstractItemView::ExtendedSelection );
2250 mSymbolTreeView->setSelectionMode( QAbstractItemView::ExtendedSelection );
2254 bool validGroup =
false;
2256 QModelIndex present = groupTree->currentIndex();
2257 while ( present.parent().isValid() )
2259 if ( present.parent().data() ==
"Tags" )
2264 present = present.parent();
2269 mGroupingMode =
true;
2271 actnTagSymbols->setVisible(
false );
2272 actnFinishTagging->setVisible(
true );
2274 disconnect( treeModel, &QStandardItemModel::itemChanged,
2280 btnManageGroups->setEnabled(
true );
2282 mModel->setCheckable(
true );
2285 listItems->setSelectionMode( QAbstractItemView::NoSelection );
2286 mSymbolTreeView->setSelectionMode( QAbstractItemView::NoSelection );
2300 mModel->setFilterString( qword );
2305 actnEditItem->setEnabled( index.isValid() && !mGroupingMode && !mReadOnly );
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 );
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 ) );
2335 searchBox->setEnabled( enable );
2340 actnRemoveGroup->setEnabled( enable && !mReadOnly );
2341 btnManageGroups->setEnabled( !mReadOnly && ( enable || mGroupingMode ) );
2346 QStandardItemModel *treeModel = qobject_cast<QStandardItemModel *>( groupTree->model() );
2347 for (
int i = 0; i < treeModel->rowCount(); i++ )
2349 treeModel->item( i )->setEnabled( enable );
2351 if ( treeModel->item( i )->data() ==
"smartgroups" )
2353 for (
int j = 0; j < treeModel->item( i )->rowCount(); j++ )
2355 treeModel->item( i )->child( j )->setEnabled( enable );
2362 for (
int i = 0; i < symbolBtnsLayout->count(); i++ )
2364 QWidget *w = symbolBtnsLayout->itemAt( i )->widget();
2366 w->setEnabled( enable );
2370 actnRemoveItem->setEnabled( enable );
2371 actnEditItem->setEnabled( enable );
2372 mActionCopyItem->setEnabled( enable );
2373 mActionPasteItem->setEnabled( enable );
2378 QPoint globalPos = groupTree->viewport()->mapToGlobal( point );
2380 QModelIndex index = groupTree->indexAt( point );
2381 if ( index.isValid() && !mGroupingMode )
2382 mGroupTreeContextMenu->popup( globalPos );
2387 QPoint globalPos = mSymbolViewStackedWidget->currentIndex() == 0
2388 ? listItems->viewport()->mapToGlobal( point )
2389 : mSymbolTreeView->viewport()->mapToGlobal( point );
2392 mGroupListMenu->clear();
2394 const QModelIndexList indices = listItems->selectionModel()->selectedRows();
2398 const QStringList currentTags = indices.count() == 1 ? indices.at( 0 ).data(
QgsStyleModel::TagRole ).toStringList() : QStringList();
2399 QAction *a =
nullptr;
2400 QStringList tags = mStyle->
tags();
2402 for (
const QString &tag : qgis::as_const( tags ) )
2404 a =
new QAction( tag, mGroupListMenu );
2406 if ( indices.count() == 1 )
2408 a->setCheckable(
true );
2409 a->setChecked( currentTags.contains( tag ) );
2413 mGroupListMenu->addAction( a );
2416 if ( tags.count() > 0 )
2418 mGroupListMenu->addSeparator();
2420 a =
new QAction( tr(
"Create New Tag…" ), mGroupListMenu );
2423 mGroupListMenu->addAction( a );
2426 const QList< ItemDetails > items = selectedItems();
2429 bool enablePaste =
false;
2437 mActionPasteItem->setEnabled( enablePaste );
2439 mGroupMenu->popup( globalPos );
2444 const QList< ItemDetails > items = selectedItems();
2445 for (
const ItemDetails &details : items )
2447 mStyle->
addFavorite( details.entityType, details.name );
2453 const QList< ItemDetails > items = selectedItems();
2454 for (
const ItemDetails &details : items )
2462 QAction *selectedItem = qobject_cast<QAction *>( sender() );
2465 const QList< ItemDetails > items = selectedItems();
2475 tag = mStyle->
tag(
id );
2479 tag = selectedItem->data().toString();
2482 for (
const ItemDetails &details : items )
2484 mStyle->
tagSymbol( details.entityType, details.name, QStringList( tag ) );
2491 QAction *selectedItem = qobject_cast<QAction *>( sender() );
2495 const QList< ItemDetails > items = selectedItems();
2496 for (
const ItemDetails &details : items )
2498 mStyle->
detagSymbol( details.entityType, details.name );
2505 QStandardItemModel *treeModel = qobject_cast<QStandardItemModel *>( groupTree->model() );
2508 QModelIndex present = groupTree->currentIndex();
2509 if ( present.parent().data( Qt::UserRole + 1 ) !=
"smartgroups" )
2512 QMessageBox::critical(
this, tr(
"Edit Smart Group" ),
2513 tr(
"You have not selected a Smart Group. Kindly select a Smart Group to edit." ) );
2516 QStandardItem *item = treeModel->itemFromIndex( present );
2524 if ( dlg.exec() == QDialog::Rejected )
2527 mBlockGroupUpdates++;
2530 mBlockGroupUpdates--;
2533 mMessageBar->
pushCritical( tr(
"Edit Smart Group" ), tr(
"There was an error while editing the smart group." ) );
2537 item->setData(
id );