58 : QAbstractItemModel( parent )
65 mEntityNames.insert( entity, mStyle->
allNames( entity ) );
106 name = mEntityNames[ entityType ].value(
index.row() - offsetForEntity( entityType ) );
112 case Qt::DisplayRole:
113 case Qt::ToolTipRole:
116 switch (
index.column() )
120 const QStringList tags = mStyle->
tagsOfSymbol( entityType, name );
122 if ( role == Qt::ToolTipRole )
124 QString tooltip = QStringLiteral(
"<h3>%1</h3><p><i>%2</i>" ).arg( name,
125 tags.count() > 0 ? tags.join( QLatin1String(
", " ) ) : tr(
"Not tagged" ) );
127 switch ( entityType )
132 std::unique_ptr< QgsSymbol > symbol( mStyle->
symbol( name ) );
135 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
138 int width =
static_cast< int >(
Qgis::UI_SCALE_FACTOR * QFontMetrics(
data(
index, Qt::FontRole ).value< QFont >() ).horizontalAdvance(
'X' ) * 23 );
140 int height =
static_cast< int >( width / 1.61803398875 );
143 QBuffer buffer( &
data );
144 pm.save( &buffer,
"PNG", 100 );
145 tooltip += QStringLiteral(
"<p><img src='data:image/png;base64, %3'>" ).arg( QString(
data.toBase64() ) );
152 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
155 int width =
static_cast< int >(
Qgis::UI_SCALE_FACTOR * QFontMetrics(
data(
index, Qt::FontRole ).value< QFont >() ).horizontalAdvance(
'X' ) * 23 );
157 int height =
static_cast< int >( width / 1.61803398875 );
161 QBuffer buffer( &
data );
162 pm.save( &buffer,
"PNG", 100 );
163 tooltip += QStringLiteral(
"<p><img src='data:image/png;base64, %3'>" ).arg( QString(
data.toBase64() ) );
169 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
172 int width =
static_cast< int >(
Qgis::UI_SCALE_FACTOR * QFontMetrics(
data(
index, Qt::FontRole ).value< QFont >() ).horizontalAdvance(
'X' ) * 23 );
174 int height =
static_cast< int >( width / 1.61803398875 );
178 QBuffer buffer( &
data );
179 pm.save( &buffer,
"PNG", 100 );
180 tooltip += QStringLiteral(
"<p><img src='data:image/png;base64, %3'>" ).arg( QString(
data.toBase64() ) );
186 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
189 int width =
static_cast< int >(
Qgis::UI_SCALE_FACTOR * QFontMetrics(
data(
index, Qt::FontRole ).value< QFont >() ).horizontalAdvance(
'X' ) * 23 );
191 int height =
static_cast< int >( width / 1.61803398875 );
198 QBuffer buffer( &
data );
199 pm.save( &buffer,
"PNG", 100 );
200 tooltip += QStringLiteral(
"<p><img src='data:image/png;base64, %3'>" ).arg( QString(
data.toBase64() ) );
219 return mStyle->
tagsOfSymbol( entityType, name ).join( QLatin1String(
", " ) );
224 case Qt::DecorationRole:
229 if ( !mExpressionContext )
235 mExpressionContext = qgis::make_unique< QgsExpressionContext >();
239 switch (
index.column() )
242 switch ( entityType )
247 QIcon icon = mIconCache[ entityType ].value( name );
248 if ( !icon.isNull() )
251 std::unique_ptr< QgsSymbol > symbol( mStyle->
symbol( name ) );
254 if ( mAdditionalSizes.isEmpty() )
257 for (
const QSize &s : mAdditionalSizes )
263 mIconCache[ entityType ].insert( name, icon );
269 QIcon icon = mIconCache[ entityType ].value( name );
270 if ( !icon.isNull() )
273 std::unique_ptr< QgsColorRamp > ramp( mStyle->
colorRamp( name ) );
276 if ( mAdditionalSizes.isEmpty() )
278 for (
const QSize &s : mAdditionalSizes )
284 mIconCache[ entityType ].insert( name, icon );
291 QIcon icon = mIconCache[ entityType ].value( name );
292 if ( !icon.isNull() )
296 if ( mAdditionalSizes.isEmpty() )
298 for (
const QSize &s : mAdditionalSizes )
302 mIconCache[ entityType ].insert( name, icon );
309 QIcon icon = mIconCache[ entityType ].value( name );
310 if ( !icon.isNull() )
314 if ( mAdditionalSizes.isEmpty() )
316 for (
const QSize &s : mAdditionalSizes )
320 mIconCache[ entityType ].insert( name, icon );
327 QIcon icon = mIconCache[ entityType ].value( name );
328 if ( !icon.isNull() )
336 if ( mAdditionalSizes.isEmpty() )
339 for (
const QSize &s : mAdditionalSizes )
345 mIconCache[ entityType ].insert( name, icon );
355 QIcon icon = mIconCache[ entityType ].value( name );
356 if ( !icon.isNull() )
359 if ( sIconGenerator && !mPending3dSymbolIcons.contains( name ) )
361 mPending3dSymbolIcons.insert( name );
366 if ( mAdditionalSizes.isEmpty() )
368 for (
const QSize &s : mAdditionalSizes )
372 mIconCache[ entityType ].insert( name, icon );
395 return mStyle->
isFavorite( entityType, name );
399 switch ( entityType )
404 return symbol ? symbol->
type() : QVariant();
423 switch ( entityType )
442 switch ( entityType )
448 res.reserve( types.size() );
451 res << static_cast< int >( type );
471 #ifndef _MSC_VER // avoid warning
478 if (
index.row() < 0 ||
index.row() >=
rowCount( QModelIndex() ) || role != Qt::EditRole )
481 switch (
index.column() )
487 switch ( entityType )
494 name = mEntityNames[ entityType ].value(
index.row() - offsetForEntity( entityType ) );
498 const QString newName = value.toString();
499 return mStyle->
renameEntity( entityType, name, newName );
511 Qt::ItemFlags
flags = QAbstractItemModel::flags(
index );
514 return flags | Qt::ItemIsEditable;
524 if ( role == Qt::DisplayRole )
526 if ( orientation == Qt::Vertical )
528 return QVariant( section );
535 return QVariant( tr(
"Name" ) );
538 return QVariant( tr(
"Tags" ) );
553 if ( !hasIndex( row, column,
parent ) )
554 return QModelIndex();
558 return createIndex( row, column );
561 return QModelIndex();
567 return QModelIndex();
576 count += mEntityNames[ type ].size();
589 if ( mAdditionalSizes.contains( size ) )
592 mAdditionalSizes << size;
594 if ( sIconGenerator )
602 sIconGenerator = generator;
608 mIconCache[ type ].remove( name );
609 const QStringList oldSymbolNames = mEntityNames[ type ];
610 const QStringList newSymbolNames = mStyle->
allNames( type );
613 const int newNameIndex = newSymbolNames.indexOf( name );
614 if ( newNameIndex < 0 )
617 const int offset = offsetForEntity( type );
618 beginInsertRows( QModelIndex(), newNameIndex + offset, newNameIndex + offset );
619 mEntityNames[ type ] = newSymbolNames;
625 mIconCache[ type ].remove( name );
626 const QStringList oldSymbolNames = mEntityNames[ type ];
627 const QStringList newSymbolNames = mStyle->
allNames( type );
630 const int oldNameIndex = oldSymbolNames.indexOf( name );
631 if ( oldNameIndex < 0 )
634 const int offset = offsetForEntity( type );
635 beginRemoveRows( QModelIndex(), oldNameIndex + offset, oldNameIndex + offset );
636 mEntityNames[ type ] = newSymbolNames;
642 mIconCache[ type ].remove( name );
644 const int offset = offsetForEntity( type );
645 QModelIndex i =
index( offset + mEntityNames[ type ].indexOf( name ),
Tags );
646 emit dataChanged( i, i, QVector< int >() << Qt::DecorationRole );
649 void QgsStyleModel::onEntityRename(
QgsStyle::StyleEntity type,
const QString &oldName,
const QString &newName )
651 mIconCache[ type ].remove( oldName );
652 const QStringList oldSymbolNames = mEntityNames[ type ];
653 const QStringList newSymbolNames = mStyle->
allNames( type );
656 const int oldNameIndex = oldSymbolNames.indexOf( oldName );
657 if ( oldNameIndex < 0 )
661 const int newNameIndex = newSymbolNames.indexOf( newName );
662 if ( newNameIndex < 0 )
665 if ( newNameIndex == oldNameIndex )
667 mEntityNames[ type ] = newSymbolNames;
671 const int offset = offsetForEntity( type );
672 beginMoveRows( QModelIndex(), oldNameIndex + offset, oldNameIndex + offset, QModelIndex(), ( newNameIndex > oldNameIndex ? newNameIndex + 1 : newNameIndex ) + offset );
673 mEntityNames[ type ] = newSymbolNames;
677 void QgsStyleModel::onTagsChanged(
int entity,
const QString &name,
const QStringList & )
681 int row = mEntityNames[type].indexOf( name ) + offsetForEntity( type );
691 emit dataChanged( i, i );
694 void QgsStyleModel::rebuildSymbolIcons()
697 mExpressionContext.reset();
701 void QgsStyleModel::iconGenerated(
QgsStyle::StyleEntity type,
const QString &name,
const QIcon &icon )
703 int row = mEntityNames[type].indexOf( name ) + offsetForEntity( type );
708 mPending3dSymbolIcons.remove( name );
710 emit dataChanged(
index( row, 0 ),
index( row, 0 ) );
726 int maxRowForEntity = 0;
729 maxRowForEntity += mEntityNames[ type ].size();
730 if ( row < maxRowForEntity )
744 if ( type == entity )
747 offset += mEntityNames[ type ].size();
757 : QSortFilterProxyModel( parent )
764 void QgsStyleProxyModel::initialize()
766 setSortCaseSensitivity( Qt::CaseInsensitive );
768 setSourceModel( mModel );
769 setDynamicSortFilter(
true );
777 if ( mSmartGroupId >= 0 )
784 if ( mFavoritesOnly )
800 if ( mSmartGroupId >= 0 )
806 : QSortFilterProxyModel( parent )
808 , mStyle( model->style() )
815 if ( mFilterString.isEmpty() && !mEntityFilterEnabled && !mSymbolTypeFilterEnabled && mTagId < 0 && mSmartGroupId < 0 && !mFavoritesOnly )
818 QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
819 const QString name = sourceModel()->data( index ).toString();
823 if ( mEntityFilterEnabled && ( mEntityFilters.empty() || !mEntityFilters.contains( styleEntityType ) ) )
827 if ( mSymbolTypeFilterEnabled &&
symbolType != mSymbolType )
832 switch ( styleEntityType )
852 if ( !types.empty() && !types.contains( mLayerType ) )
859 if ( mTagId >= 0 && !mTaggedSymbolNames.contains( name ) )
862 if ( mSmartGroupId >= 0 && !mSmartGroupSymbolNames.contains( name ) )
868 if ( !mFilterString.isEmpty() )
872 const QStringList partsToMatch = mFilterString.trimmed().split(
' ' );
874 QStringList partsToSearch = name.split(
' ' );
875 for (
const QString &tag : tags )
877 partsToSearch.append( tag.split(
' ' ) );
880 for (
const QString &part : partsToMatch )
883 for (
const QString &partToSearch : qgis::as_const( partsToSearch ) )
885 if ( partToSearch.contains( part, Qt::CaseInsensitive ) )
901 mFilterString = filter;
908 return mFavoritesOnly;
924 return mSymbolTypeFilterEnabled;
948 mTaggedSymbolNames.clear();
952 mTaggedSymbolNames.append( mStyle->
symbolsWithTag( entity, mTagId ) );
967 mSmartGroupSymbolNames.clear();
968 if ( mSmartGroupId >= 0 )
978 return mSmartGroupId;
994 return mEntityFilterEnabled;
1010 mEntityFilters = QList< QgsStyle::StyleEntity >() <<
entityFilter;
1016 mEntityFilters = filters;