51#include <QStandardItem>
52#include <QStandardItemModel>
56#include "moc_qgscategorizedsymbolrendererwidget.cpp"
58using namespace Qt::StringLiterals;
62QgsCategorizedSymbolRendererModel::QgsCategorizedSymbolRendererModel( QObject *parent, QScreen *screen )
66Qt::ItemFlags QgsCategorizedSymbolRendererModel::extraFlags(
const QModelIndex &index )
const
69 return index.column() == 2 ? Qt::ItemFlags( Qt::ItemIsEditable ) : Qt::NoItemFlags;
78bool QgsCategorizedSymbolRendererModel::setExtraData(
const QModelIndex &index,
const QVariant &value )
80 if ( index.column() == 2 )
82 mRenderer->updateCategoryLabel( index.row(), value.toString() );
83 emit dataChanged( index, index );
90QVariant QgsCategorizedSymbolRendererModel::extraData(
const QModelIndex &index,
int role )
const
92 if ( index.column() == 2 && ( role == Qt::DisplayRole || role == Qt::ToolTipRole || role == Qt::EditRole ) )
95 return category.
label();
101QVariant QgsCategorizedSymbolRendererModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
103 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
106 lst << tr(
"Symbol" ) << tr(
"Value" ) << tr(
"Legend" );
107 return lst.value( section );
112int QgsCategorizedSymbolRendererModel::columnCount(
const QModelIndex &index )
const
118void QgsCategorizedSymbolRendererModel::sort(
int column, Qt::SortOrder order )
120 if ( column == symbolColumn() )
124 if ( column == valueColumn() )
126 mRenderer->sortByValue( order );
128 else if ( column == 2 )
130 mRenderer->sortByLabel( order );
132 emit dataChanged( createIndex( 0, 0 ), createIndex(
static_cast<int>( mRenderer->categories().size() ), 0 ) );
135void QgsCategorizedSymbolRendererModel::onRowsMoved()
141QgsCategorizedSymbolRendererViewStyle::QgsCategorizedSymbolRendererViewStyle( QWidget *parent )
145void QgsCategorizedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget )
const
147 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
149 QStyleOption opt( *option );
150 opt.rect.setLeft( 0 );
152 opt.rect.setHeight( 0 );
154 opt.rect.setRight( widget->width() );
155 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
158 QProxyStyle::drawPrimitive( element, option, painter, widget );
162QgsCategorizedRendererViewItemDelegate::QgsCategorizedRendererViewItemDelegate(
QgsFieldExpressionWidget *expressionWidget, QObject *parent )
163 : QStyledItemDelegate( parent )
164 , mFieldExpressionWidget( expressionWidget )
167QWidget *QgsCategorizedRendererViewItemDelegate::createEditor( QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index )
const
176 const QString fieldName { mFieldExpressionWidget->currentField( &isExpression, &isValid ) };
177 if ( !fieldName.isEmpty() && mFieldExpressionWidget->layer() && mFieldExpressionWidget->layer()->fields().lookupField( fieldName ) != -1 )
179 userType = mFieldExpressionWidget->layer()->fields().field( fieldName ).type();
181 else if ( isExpression && isValid )
185 if ( mFieldExpressionWidget->layer()->getFeatures().nextFeature( feat ) )
190 expressionContext.
appendScope( mFieldExpressionWidget->layer()->createExpressionContextScope() );
193 const QVariant value = exp.
evaluate( &expressionContext );
196 userType =
static_cast<QMetaType::Type
>( value.userType() );
205 case QMetaType::Type::Double:
211 if ( value.toDouble( &ok ); ok )
213 const QString strVal { value.toString() };
214 const int dotPosition( strVal.indexOf(
'.' ) );
215 if ( dotPosition >= 0 )
217 decimals = std::max<int>( 2, strVal.length() - dotPosition - 1 );
220 editor->setDecimals( decimals );
222 editor->setMaximum( std::numeric_limits<double>::max() );
223 editor->setMinimum( std::numeric_limits<double>::lowest() );
226 case QMetaType::Type::Int:
229 editor->setDecimals( 0 );
231 editor->setMaximum( std::numeric_limits<int>::max() );
232 editor->setMinimum( std::numeric_limits<int>::min() );
235 case QMetaType::Type::QChar:
238 editor->setDecimals( 0 );
240 editor->setMaximum( std::numeric_limits<char>::max() );
241 editor->setMinimum( std::numeric_limits<char>::min() );
244 case QMetaType::Type::UInt:
247 editor->setDecimals( 0 );
249 editor->setMaximum( std::numeric_limits<unsigned int>::max() );
250 editor->setMinimum( 0 );
253 case QMetaType::Type::LongLong:
256 editor->setDecimals( 0 );
258 editor->setMaximum(
static_cast<double>( std::numeric_limits<qlonglong>::max() ) );
259 editor->setMinimum( std::numeric_limits<qlonglong>::min() );
262 case QMetaType::Type::ULongLong:
265 editor->setDecimals( 0 );
267 editor->setMaximum(
static_cast<double>( std::numeric_limits<unsigned long long>::max() ) );
268 editor->setMinimum( 0 );
274 return editor ? editor : QStyledItemDelegate::createEditor( parent, option, index );
287 , mContextMenu( new QMenu( this ) )
302 const QString attrName =
mRenderer->classAttribute();
303 mOldClassificationAttribute = attrName;
307 layout()->setContentsMargins( 0, 0, 0, 0 );
309 mExpressionWidget->setLayer(
mLayer );
310 btnChangeCategorizedSymbol->setLayer(
mLayer );
311 btnChangeCategorizedSymbol->registerExpressionContextGenerator(
this );
314 btnColorRamp->setShowRandomColorRamp(
true );
317 std::unique_ptr<QgsColorRamp> colorRamp(
QgsProject::instance()->styleSettings()->defaultColorRamp() );
320 btnColorRamp->setColorRamp( colorRamp.get() );
324 btnColorRamp->setRandomColorRamp();
334 mModel =
new QgsCategorizedSymbolRendererModel(
this, screen() );
340 viewCategories->setModel(
mModel );
341 viewCategories->resizeColumnToContents( 0 );
342 viewCategories->resizeColumnToContents( 1 );
343 viewCategories->resizeColumnToContents( 2 );
344 viewCategories->setItemDelegateForColumn( 1,
new QgsCategorizedRendererViewItemDelegate( mExpressionWidget, viewCategories ) );
346 viewCategories->setStyle(
new QgsCategorizedSymbolRendererViewStyle( viewCategories ) );
347 connect( viewCategories->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsCategorizedSymbolRendererWidget::selectionChanged );
355 connect( viewCategories, &QTreeView::customContextMenuRequested,
this, &QgsCategorizedSymbolRendererWidget::showContextMenu );
357 connect( btnChangeCategorizedSymbol, &
QgsSymbolButton::changed,
this, &QgsCategorizedSymbolRendererWidget::updateSymbolsFromButton );
368 QMenu *advMenu =
new QMenu;
375 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
377 connect( actionDdsLegend, &QAction::triggered,
this, &QgsCategorizedSymbolRendererWidget::dataDefinedSizeLegend );
380 btnAdvanced->setMenu( advMenu );
382 mExpressionWidget->registerExpressionContextGenerator(
this );
384 mMergeCategoriesAction =
new QAction( tr(
"Merge Categories" ),
this );
385 connect( mMergeCategoriesAction, &QAction::triggered,
this, &QgsCategorizedSymbolRendererWidget::mergeSelectedCategories );
386 mUnmergeCategoriesAction =
new QAction( tr(
"Unmerge Categories" ),
this );
387 connect( mUnmergeCategoriesAction, &QAction::triggered,
this, &QgsCategorizedSymbolRendererWidget::unmergeSelectedCategories );
389 connect( mContextMenu, &QMenu::aboutToShow,
this, [
this] {
409 const QString attrName =
mRenderer->classAttribute();
410 mExpressionWidget->setField( attrName );
422 btnColorRamp->setColorRamp(
mRenderer->sourceColorRamp() );
434 btnChangeCategorizedSymbol->setMapCanvas(
context.mapCanvas() );
435 btnChangeCategorizedSymbol->setMessageBar(
context.messageBar() );
440 delete mActionLevels;
441 mActionLevels =
nullptr;
448 if ( !selectedCats.isEmpty() )
459 const auto constSelectedCats = selectedCats;
460 for (
const int idx : constSelectedCats )
466 mRenderer->updateCategorySymbol( idx, newCatSymbol );
486 if ( !dlg.exec() || !newSymbol )
508 if ( idx.isValid() && idx.column() ==
mModel->symbolColumn() )
516 std::unique_ptr<QgsSymbol> symbol;
518 if (
auto *lSymbol = category.
symbol() )
520 symbol.reset( lSymbol->clone() );
540 if ( !dlg.exec() || !symbol )
553 const QString attrName = mExpressionWidget->currentField();
554 bool valuesRetrieved;
556 if ( !valuesRetrieved )
558 QgsDebugMsgLevel( u
"Unable to retrieve values from layer %1 with expression %2"_s.arg(
mLayer->name() ).arg( attrName ), 2 );
563 if ( uniqueValues.size() >= 1000 )
565 const int res = QMessageBox::
566 warning(
nullptr, tr(
"Classify Categories" ), tr(
"High number of classes. Classification would yield %n entries which might not be expected. Continue?",
nullptr, uniqueValues.size() ), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel );
567 if ( res == QMessageBox::Cancel )
574 DlgAddCategories dlg(
mStyle, createDefaultSymbol(), unique_vals,
this );
580 bool deleteExisting =
false;
582 if ( !mOldClassificationAttribute.isEmpty() && attrName != mOldClassificationAttribute && !
mRenderer->categories().isEmpty() )
584 const int res = QMessageBox::question(
586 tr(
"Delete Classification" ),
588 "The classification field was changed from '%1' to '%2'.\n"
589 "Should the existing classes be deleted before classification?"
591 .arg( mOldClassificationAttribute, attrName ),
592 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel
594 if ( res == QMessageBox::Cancel )
599 deleteExisting = ( res == QMessageBox::Yes );
603 bool keepExistingColors =
false;
604 if ( !deleteExisting )
607 keepExistingColors = !prevCats.isEmpty();
609 if ( keepExistingColors && btnColorRamp->isRandomColorRamp() )
611 for (
int i = 0; i < cats.size(); ++i )
613 bool contains =
false;
614 const QVariant value = cats.at( i ).value();
615 for (
int j = 0; j < prevCats.size() && !contains; ++j )
617 const QVariant prevCatValue = prevCats.at( j ).value();
618 if ( prevCatValue.userType() == QMetaType::Type::QVariantList )
620 const QVariantList list = prevCatValue.toList();
621 for (
const QVariant &v : list )
632 if ( prevCats.at( j ).value() == value )
643 if ( keepExistingColors && btnColorRamp->isRandomColorRamp() )
646 cats.at( i ).symbol()->setColor( randomColors.
color( i ) );
648 prevCats.append( cats.at( i ) );
654 mOldClassificationAttribute = attrName;
671 auto r = std::make_unique<QgsCategorizedSymbolRenderer>( attrName, cats );
673 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
675 r->setSourceColorRamp( ramp->clone() );
679 mModel->setRenderer( r.get() );
682 if ( !keepExistingColors && ramp )
689 if ( !btnColorRamp->isNull() )
691 mRenderer->updateColorRamp( btnColorRamp->colorRamp() );
693 mModel->updateSymbology();
698 const QModelIndex idx = viewCategories->selectionModel()->currentIndex();
699 if ( !idx.isValid() )
707 const QModelIndexList selectedRows = viewCategories->selectionModel()->selectedRows();
709 const auto constSelectedRows = selectedRows;
710 for (
const QModelIndex &r : constSelectedRows )
714 rows.append( r.row() );
723 mModel->deleteRows( categoryIndexes );
737 const QString attrName = mExpressionWidget->currentField();
738 bool valuesRetrieved;
740 if ( !valuesRetrieved )
742 QgsDebugMsgLevel( u
"Unable to retrieve values from layer %1 with expression %2"_s.arg(
mLayer->name() ).arg( attrName ), 2 );
747 QList<int> unusedIndexes;
749 for (
int i = 0; i < catList.size(); ++i )
752 if ( !uniqueValues.contains( cat.
value() ) )
754 unusedIndexes.append( i );
757 mModel->deleteRows( unusedIndexes );
763 bool valuesRetrieved;
765 if ( !valuesRetrieved )
767 QgsDebugMsgLevel( u
"Unable to retrieve values from layer %1 with expression %2"_s.arg(
mLayer->name() ).arg( attrName ), 2 );
778 mModel->addCategory( cat );
786 QItemSelectionModel *m = viewCategories->selectionModel();
787 const QModelIndexList selectedIndexes = m->selectedRows( 1 );
789 if ( !selectedIndexes.isEmpty() )
792 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
793 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
795 const int row = ( *indexIt ).row();
810 QItemSelectionModel *m = viewCategories->selectionModel();
811 const QModelIndexList selectedIndexes = m->selectedRows( 1 );
813 if ( !selectedIndexes.isEmpty() )
815 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
816 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
818 cl.append(
mModel->category( *indexIt ) );
837 viewCategories->selectionModel()->clear();
845 QMessageBox::information(
this, tr(
"Matched Symbols" ), tr(
"Matched %n categories to symbols.",
nullptr, matched ) );
849 QMessageBox::warning(
this, tr(
"Matched Symbols" ), tr(
"No categories could be matched to symbols in library." ) );
862 QVariantList unmatchedCategories;
863 QStringList unmatchedSymbols;
864 const int matched =
mRenderer->matchToSymbols( style, type, unmatchedCategories, unmatchedSymbols );
866 mModel->updateSymbology();
873 const QString openFileDir = settings.
value( u
"UI/lastMatchToSymbolsDir"_s, QDir::homePath() ).toString();
875 const QString fileName = QFileDialog::getOpenFileName(
this, tr(
"Match to Symbols from File" ), openFileDir, tr(
"XML files (*.xml *.XML)" ) );
876 if ( fileName.isEmpty() )
881 const QFileInfo openFileInfo( fileName );
882 settings.
setValue( u
"UI/lastMatchToSymbolsDir"_s, openFileInfo.absolutePath() );
885 if ( !importedStyle.
importXml( fileName ) )
887 QMessageBox::warning(
this, tr(
"Match to Symbols from File" ), tr(
"An error occurred while reading file:\n%1" ).arg( importedStyle.
errorString() ) );
894 QMessageBox::information(
this, tr(
"Match to Symbols from File" ), tr(
"Matched %n categories to symbols from file.",
nullptr, matched ) );
898 QMessageBox::warning(
this, tr(
"Match to Symbols from File" ), tr(
"No categories could be matched to symbols in file." ) );
909 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
912 mRenderer->setUsingSymbolLevels( enabled );
913 mModel->updateSymbology();
924 if ( !selectedCats.isEmpty() )
926 for (
const int idx : selectedCats )
928 if (
mRenderer->categories().at( idx ).symbol()->type() != tempSymbol->type() )
931 std::unique_ptr<QgsSymbol> newCatSymbol( tempSymbol->clone() );
932 if ( selectedCats.count() > 1 )
935 newCatSymbol->setColor(
mRenderer->categories().at( idx ).symbol()->color() );
937 mRenderer->updateCategorySymbol( idx, newCatSymbol.release() );
950void QgsCategorizedSymbolRendererWidget::updateSymbolsFromButton()
960 QItemSelectionModel *m = viewCategories->selectionModel();
961 const QModelIndexList i = m->selectedRows();
967 if ( !selectedCats.isEmpty() )
969 const auto constSelectedCats = selectedCats;
970 for (
const int idx : constSelectedCats )
973 if ( selectedCats.count() > 1 )
978 mRenderer->updateCategorySymbol( idx, newCatSymbol );
987 mModel->updateSymbology();
998 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1000 mCopyBuffer.clear();
1003 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1005 QgsCategoryList::iterator rIt = mCopyBuffer.begin();
1006 for ( ; rIt != mCopyBuffer.end(); ++rIt )
1008 rIt->mUuid = QUuid::createUuid().toString();
1009 mModel->addCategory( *rIt );
1017 if (
auto *lMapCanvas =
mContext.mapCanvas() )
1019 expContext = lMapCanvas->createExpressionContext();
1034 const auto constAdditionalExpressionContextScopes =
mContext.additionalExpressionContextScopes();
1043void QgsCategorizedSymbolRendererWidget::dataDefinedSizeLegend()
1057void QgsCategorizedSymbolRendererWidget::mergeSelectedCategories()
1062 QList<int> categoryIndexes;
1065 for (
const int i : selectedCategoryIndexes )
1067 const QVariant v = categories.at( i ).value();
1069 if ( !v.isValid() || v ==
"" )
1074 categoryIndexes.append( i );
1077 if ( categoryIndexes.count() < 2 )
1081 QVariantList values;
1082 values.reserve( categoryIndexes.count() );
1083 labels.reserve( categoryIndexes.count() );
1084 for (
const int i : categoryIndexes )
1086 const QVariant v = categories.at( i ).value();
1088 if ( v.userType() == QMetaType::Type::QVariantList )
1090 values.append( v.toList() );
1095 labels << categories.at( i ).label();
1099 mRenderer->updateCategoryLabel( categoryIndexes.at( 0 ), labels.join(
',' ) );
1100 mRenderer->updateCategoryValue( categoryIndexes.at( 0 ), values );
1102 categoryIndexes.pop_front();
1103 mModel->deleteRows( categoryIndexes );
1108void QgsCategorizedSymbolRendererWidget::unmergeSelectedCategories()
1111 if ( categoryIndexes.isEmpty() )
1115 for (
const int i : categoryIndexes )
1117 const QVariant v = categories.at( i ).value();
1118 if ( v.userType() != QMetaType::Type::QVariantList )
1121 const QVariantList list = v.toList();
1122 for (
int j = 1; j < list.count(); ++j )
1124 mModel->addCategory( QgsRendererCategory( list.at( j ), categories.at( i ).symbol()->clone(), list.at( j ).toString(), categories.at( i ).renderState() ) );
1126 mRenderer->updateCategoryValue( i, list.at( 0 ) );
1127 mRenderer->updateCategoryLabel( i, list.at( 0 ).toString() );
1133void QgsCategorizedSymbolRendererWidget::showContextMenu( QPoint )
1135 mContextMenu->clear();
1136 const QList<QAction *> actions =
contextMenu->actions();
1137 for ( QAction *act : actions )
1139 mContextMenu->addAction( act );
1142 mContextMenu->addSeparator();
1144 if ( viewCategories->selectionModel()->selectedRows().count() > 1 )
1146 mContextMenu->addAction( mMergeCategoriesAction );
1148 if ( viewCategories->selectionModel()->selectedRows().count() == 1 )
1152 const QVariant v = categories.at( categoryIndexes.at( 0 ) ).value();
1153 if ( v.userType() == QMetaType::Type::QVariantList )
1154 mContextMenu->addAction( mUnmergeCategoriesAction );
1156 else if ( viewCategories->selectionModel()->selectedRows().count() > 1 )
1158 mContextMenu->addAction( mUnmergeCategoriesAction );
1161 mContextMenu->exec( QCursor::pos() );
1164void QgsCategorizedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1167 if ( !selectedCats.isEmpty() )
1169 whileBlocking( btnChangeCategorizedSymbol )->setSymbol(
mRenderer->categories().at( selectedCats.at( 0 ) ).symbol()->clone() );
1175 btnChangeCategorizedSymbol->setDialogTitle( selectedCats.size() == 1 ?
mRenderer->categories().at( selectedCats.at( 0 ) ).label() : tr(
"Symbol Settings" ) );
A feature renderer which represents features using a list of renderer categories.
QgsRendererCategory Category
static QgsCategorizedSymbolRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer, QgsVectorLayer *layer=nullptr)
Creates a new QgsCategorizedSymbolRenderer from an existing renderer.
static QgsCategoryList createCategories(const QVariantList &values, const QgsSymbol *symbol, QgsVectorLayer *layer=nullptr, const QString &fieldName=QString())
Create categories for a list of values.
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
void setClearValue(double customValue, const QString &clearValueText=QString())
Defines the clear value as a custom value and will automatically set the clear value mode to CustomVa...
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Handles parsing and evaluation of expressions (formerly called "search strings").
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
QVariant evaluate()
Evaluate the feature and return the result.
Abstract base class for all 2D vector feature renderers.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Stores information about one class/rule of a vector layer renderer in a unified way that can be used ...
Contains configuration for rendering maps.
A marker symbol type, for rendering Point and MultiPoint geometries.
static QgsProject * instance()
Returns the QgsProject singleton instance.
A QProxyStyle subclass which correctly sets the base style to match the QGIS application style,...
A color ramp consisting of random colors, constrained within component ranges.
virtual void setTotalColorCount(int colorCount)
Sets the desired total number of unique colors for the resultant ramp.
QColor color(double value) const override
Returns the color corresponding to a specified value.
Represents an individual category (class) from a QgsCategorizedSymbolRenderer.
QgsSymbol * symbol() const
Returns the symbol which will be used to render this category.
QVariant value() const
Returns the value corresponding to this category.
QString label() const
Returns the label for this category, which is used to represent the category within legends and the l...
Stores properties relating to a screen.
Stores settings for use within QGIS.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
A database of saved style entities, including symbols, color ramps, text formats and others.
QString errorString() const
Returns the last error from a load() operation.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
bool importXml(const QString &filename)
Imports the symbols and colorramps into the default style database from the given XML file.
static std::unique_ptr< QgsSymbol > symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Returns an icon preview for a color ramp.
A dialog that can be used to select and build a symbol.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
Abstract base class for all rendered symbols.
void setColor(const QColor &color) const
Sets the color for the symbol.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
static QgsSymbol * defaultSymbol(Qgis::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QList< QVariant > uniqueValues(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly=false, int limit=-1, QgsFeedback *feedback=nullptr)
Fetches all unique values from a specified field name or expression.
Represents a vector layer which manages a vector based dataset.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
QList< QgsRendererCategory > QgsCategoryList
QList< QgsLegendSymbolItem > QgsLegendSymbolList
#define QgsDebugMsgLevel(str, level)