39#include <QColorDialog> 
   41#include <QStandardItemModel> 
   42#include <QInputDialog> 
   49#include <QStandardItem> 
   53static const int SYMBOL_LAYER_ITEM_TYPE = QStandardItem::UserType + 1;
 
   63    mDDSize = mMarker->dataDefinedSize();
 
   64    mDDAngle = mMarker->dataDefinedAngle();
 
   66    if ( !mDDSize && !mDDAngle )
 
   73    mDDWidth = mLine->dataDefinedWidth();
 
   81void DataDefinedRestorer::save()
 
   85    mSize = mMarkerSymbolLayer->size();
 
   86    mAngle = mMarkerSymbolLayer->angle();
 
   87    mMarkerOffset = mMarkerSymbolLayer->offset();
 
   91    mWidth = mLineSymbolLayer->width();
 
   92    mLineOffset = mLineSymbolLayer->offset();
 
   96void DataDefinedRestorer::restore()
 
  101         ( mSize != mMarkerSymbolLayer->size() || mMarkerOffset != mMarkerSymbolLayer->offset() ) )
 
  102      mMarker->setDataDefinedSize( mDDSize );
 
  104         mAngle != mMarkerSymbolLayer->angle() )
 
  105      mMarker->setDataDefinedAngle( mDDAngle );
 
  110         ( mWidth != mLineSymbolLayer->width() || mLineOffset != mLineSymbolLayer->offset() ) )
 
  111      mLine->setDataDefinedWidth( mDDWidth );
 
  118class SymbolLayerItem : 
public QStandardItem
 
  122      : mVectorLayer( vectorLayer )
 
  125      setLayer( layer, symbolType );
 
  129      : mVectorLayer( vectorLayer )
 
  140      mSymbolType = symbolType;
 
  154      if ( !mSize.isValid() )
 
  157        mSize = QSize( size, size );
 
  170      if ( 
auto *lParent = parent() )
 
  171        static_cast<SymbolLayerItem *
>( lParent )->updatePreview();
 
  174    int type()
 const override { 
return SYMBOL_LAYER_ITEM_TYPE; }
 
  175    bool isLayer() { 
return mIsLayer; }
 
  188    QVariant data( 
int role )
 const override 
  190      if ( role == Qt::DisplayRole || role == Qt::EditRole )
 
  202          switch ( mSymbol->type() )
 
  205              return QCoreApplication::translate( 
"SymbolLayerItem", 
"Marker" );
 
  207              return QCoreApplication::translate( 
"SymbolLayerItem", 
"Fill" );
 
  209              return QCoreApplication::translate( 
"SymbolLayerItem", 
"Line" );
 
  215      else if ( role == Qt::ForegroundRole && mIsLayer )
 
  217        if ( !mLayer->enabled() )
 
  219          QPalette 
pal = qApp->palette();
 
  220          QBrush brush = QStandardItem::data( role ).value< QBrush >();
 
  221          brush.setColor( 
pal.color( QPalette::Disabled, QPalette::WindowText ) );
 
  232      if ( role == Qt::CheckStateRole )
 
  234      return QStandardItem::data( role );
 
  240    QPointer< QgsVectorLayer > mVectorLayer;
 
  241    bool mIsLayer = 
false;
 
  244    QPointer< QScreen > mScreen;
 
  258  setWindowModality( Qt::WindowModal );
 
  262  this->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  264  layersTree->setMaximumHeight( 
static_cast< int >( 
Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 7 ) );
 
  265  layersTree->setMinimumHeight( layersTree->maximumHeight() );
 
  266  lblPreview->setMaximumWidth( layersTree->maximumHeight() );
 
  274  iconLock.addFile( 
QgsApplication::iconPath( QStringLiteral( 
"unlocked.svg" ) ), QSize(), QIcon::Normal, QIcon::Off );
 
  275  iconLock.addFile( 
QgsApplication::iconPath( QStringLiteral( 
"unlocked.svg" ) ), QSize(), QIcon::Active, QIcon::Off );
 
  276  btnLock->setIcon( iconLock );
 
  281  mSymbolLayersModel = 
new QStandardItemModel( layersTree );
 
  283  layersTree->setModel( mSymbolLayersModel );
 
  284  layersTree->setHeaderHidden( 
true );
 
  296    mPreviewExpressionContext.
setFeature( mPreviewFeature );
 
  304  QItemSelectionModel *selModel = layersTree->selectionModel();
 
  307  loadSymbol( mSymbol, 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->invisibleRootItem() ) );
 
  321  const QModelIndex newIndex = layersTree->model()->index( 0, 0 );
 
  322  layersTree->setCurrentIndex( newIndex );
 
  349  if ( !mAdvancedMenu )
 
  351    mAdvancedMenu = 
new QMenu( 
this );
 
  355  return mAdvancedMenu;
 
  364    mPreviewExpressionContext = *lExpressionContext;
 
  368    mPreviewExpressionContext.
setFeature( mPreviewFeature );
 
  371  QWidget *widget = stackedWidget->currentWidget();
 
  373    layerProp->setContext( 
context );
 
  375    listWidget->setContext( 
context );
 
  394    mSymbolLayersModel->clear();
 
  395    parent = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->invisibleRootItem() );
 
  398  SymbolLayerItem *symbolItem = 
new SymbolLayerItem( 
symbol, mVectorLayer, screen() );
 
  399  QFont boldFont = symbolItem->font();
 
  400  boldFont.setBold( 
true );
 
  401  symbolItem->setFont( boldFont );
 
  402  parent->appendRow( symbolItem );
 
  405  for ( 
int i = count - 1; i >= 0; i-- )
 
  408    layerItem->setEditable( 
false );
 
  409    symbolItem->appendRow( layerItem );
 
  414    layersTree->setExpanded( layerItem->index(), 
true );
 
  416  layersTree->setExpanded( symbolItem->index(), 
true );
 
  418  if ( mSymbol == 
symbol && !layersTree->currentIndex().isValid() )
 
  421    layersTree->setCurrentIndex( symbolItem->index() );
 
  425void QgsSymbolSelectorWidget::reloadSymbol()
 
  427  mSymbolLayersModel->clear();
 
  428  loadSymbol( mSymbol, 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->invisibleRootItem() ) );
 
  431void QgsSymbolSelectorWidget::updateUi()
 
  433  const QModelIndex currentIdx = layersTree->currentIndex();
 
  434  if ( !currentIdx.isValid() )
 
  437  SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( currentIdx ) );
 
  438  if ( !item->isLayer() )
 
  440    btnUp->setEnabled( 
false );
 
  441    btnDown->setEnabled( 
false );
 
  442    btnRemoveLayer->setEnabled( 
false );
 
  443    btnLock->setEnabled( 
false );
 
  444    btnDuplicate->setEnabled( 
false );
 
  448  const int rowCount = item->parent()->rowCount();
 
  449  const int currentRow = item->row();
 
  451  btnUp->setEnabled( currentRow > 0 );
 
  452  btnDown->setEnabled( currentRow < rowCount - 1 );
 
  453  btnRemoveLayer->setEnabled( rowCount > 1 );
 
  454  btnLock->setEnabled( 
true );
 
  455  btnDuplicate->setEnabled( 
true );
 
  463  std::unique_ptr< QgsSymbol > symbolClone( mSymbol->
clone() );
 
  465  lblPreview->setPixmap( QPixmap::fromImage( preview ) );
 
  467  if ( !mBlockModified )
 
  474  SymbolLayerItem *item = currentLayerItem();
 
  476    item->updatePreview();
 
  481SymbolLayerItem *QgsSymbolSelectorWidget::currentLayerItem()
 
  483  const QModelIndex idx = layersTree->currentIndex();
 
  484  if ( !idx.isValid() )
 
  487  SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( idx ) );
 
  488  if ( !item->isLayer() )
 
  496  const QModelIndex idx = layersTree->currentIndex();
 
  497  if ( !idx.isValid() )
 
  500  SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( idx ) );
 
  501  if ( item->isLayer() )
 
  502    return item->layer();
 
  511  SymbolLayerItem *currentItem = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( layersTree->currentIndex() ) );
 
  515  if ( currentItem->isLayer() )
 
  517    SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( currentItem->parent() );
 
  518    mDataDefineRestorer.reset( 
new DataDefinedRestorer( parent->symbol(), currentItem->layer() ) );
 
  522    setWidget( layerProp );
 
  533    mDataDefineRestorer.reset();
 
  535    currentItem->symbol()->setLayer( mVectorLayer );
 
  539    symbolsList->setContext( mContext );
 
  541    setWidget( symbolsList );
 
  549  SymbolLayerItem *currentItem = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( layersTree->currentIndex() ) );
 
  550  if ( !currentItem || currentItem->isLayer() )
 
  554  if ( currentItem->parent() )
 
  558    SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( currentItem->parent() );
 
  559    parent->removeRow( 0 );
 
  561    layersTree->setCurrentIndex( parent->child( 0 )->index() );
 
  562    parent->updatePreview();
 
  568    const QModelIndex newIndex = layersTree->model()->index( 0, 0 );
 
  569    layersTree->setCurrentIndex( newIndex );
 
  576void QgsSymbolSelectorWidget::setWidget( QWidget *widget )
 
  578  const int index = stackedWidget->addWidget( widget );
 
  579  stackedWidget->setCurrentIndex( index );
 
  580  if ( mPresentWidget )
 
  581    mPresentWidget->deleteLater();
 
  582  mPresentWidget = widget;
 
  585void QgsSymbolSelectorWidget::updateLockButton()
 
  590  btnLock->setChecked( layer->
isLocked() );
 
  595  const QModelIndex idx = layersTree->currentIndex();
 
  596  if ( !idx.isValid() )
 
  600  SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( idx ) );
 
  601  if ( item->isLayer() )
 
  603    insertIdx = item->row();
 
  604    item = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  607  QgsSymbol *parentSymbol = item->symbol();
 
  621  if ( insertIdx == -1 )
 
  628    static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedSize( ddSize );
 
  630    static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedAngle( ddAngle );
 
  632    static_cast<QgsLineSymbol *
>( parentSymbol )->setDataDefinedWidth( ddWidth );
 
  634  SymbolLayerItem *newLayerItem = 
new SymbolLayerItem( newLayer, parentSymbol->
type(), mVectorLayer, screen() );
 
  635  item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
 
  636  item->updatePreview();
 
  638  layersTree->setCurrentIndex( mSymbolLayersModel->indexFromItem( newLayerItem ) );
 
  645  SymbolLayerItem *item = currentLayerItem();
 
  646  const int row = item->row();
 
  647  SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  649  const int layerIdx = parent->rowCount() - row - 1; 
 
  650  QgsSymbol *parentSymbol = parent->symbol();
 
  653  parent->removeRow( row );
 
  654  parent->updatePreview();
 
  656  const QModelIndex newIdx = parent->child( 0 )->index();
 
  657  layersTree->setCurrentIndex( newIdx );
 
  667  moveLayerByOffset( + 1 );
 
  672  moveLayerByOffset( -1 );
 
  675void QgsSymbolSelectorWidget::moveLayerByOffset( 
int offset )
 
  677  SymbolLayerItem *item = currentLayerItem();
 
  680  const int row = item->row();
 
  682  SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  683  QgsSymbol *parentSymbol = parent->symbol();
 
  685  const int layerIdx = parent->rowCount() - row - 1;
 
  690  QList<QStandardItem *> rowItems = parent->takeRow( row );
 
  691  parent->insertRows( row + offset, rowItems );
 
  692  parent->updatePreview();
 
  694  const QModelIndex newIdx = rowItems[ 0 ]->index();
 
  695  layersTree->setCurrentIndex( newIdx );
 
  706  layer->
setLocked( btnLock->isChecked() );
 
  712  const QModelIndex idx = layersTree->currentIndex();
 
  713  if ( !idx.isValid() )
 
  716  SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( idx ) );
 
  717  if ( !item->isLayer() )
 
  722  const int insertIdx = item->row();
 
  723  item = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  725  QgsSymbol *parentSymbol = item->symbol();
 
  729  if ( insertIdx == -1 )
 
  734  SymbolLayerItem *newLayerItem = 
new SymbolLayerItem( newLayer, parentSymbol->
type(), mVectorLayer, screen() );
 
  735  item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
 
  739    layersTree->setExpanded( newLayerItem->index(), 
true );
 
  741  item->updatePreview();
 
  743  layersTree->setCurrentIndex( mSymbolLayersModel->indexFromItem( newLayerItem ) );
 
  750  SymbolLayerItem *item = currentLayerItem();
 
  755    item->removeRow( 0 );
 
  765    layersTree->setExpanded( item->index(), 
true );
 
  769  const int layerIdx = item->parent()->rowCount() - item->row() - 1;
 
  772  item->updatePreview();
 
  781  setLayout( 
new QVBoxLayout() );
 
  784  mButtonBox = 
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
 
  786  connect( mButtonBox, &QDialogButtonBox::accepted, 
this, &QDialog::accept );
 
  787  connect( mButtonBox, &QDialogButtonBox::rejected, 
this, &QDialog::reject );
 
  788  connect( mButtonBox, &QDialogButtonBox::helpRequested, 
this, &QgsSymbolSelectorDialog::showHelp );
 
  790  layout()->addWidget( mSelectorWidget );
 
  791  layout()->addWidget( mButtonBox );
 
  795  mSelectorWidget->setMinimumSize( 460, 560 );
 
  796  setObjectName( QStringLiteral( 
"SymbolSelectorDialog" ) );
 
  803    layout()->setContentsMargins( 0, 0, 0, 0 );
 
  807    setWindowTitle( tr( 
"Symbol Selector" ) );
 
  829  return mSelectorWidget->
symbol();
 
  835  if ( !isWindow() && e->key() == Qt::Key_Escape )
 
  841    QDialog::keyPressEvent( e );
 
  845void QgsSymbolSelectorDialog::reloadSymbol()
 
  847  mSelectorWidget->reloadSymbol();
 
  855void QgsSymbolSelectorDialog::updateUi()
 
  857  mSelectorWidget->updateUi();
 
  860void QgsSymbolSelectorDialog::updateLockButton()
 
  862  mSelectorWidget->updateLockButton();
 
  865SymbolLayerItem *QgsSymbolSelectorDialog::currentLayerItem()
 
  867  return mSelectorWidget->currentLayerItem();
 
  872  return mSelectorWidget->currentLayer();
 
  875void QgsSymbolSelectorDialog::moveLayerByOffset( 
int offset )
 
  877  mSelectorWidget->moveLayerByOffset( offset );
 
  880void QgsSymbolSelectorDialog::setWidget( QWidget *widget )
 
  882  mSelectorWidget->setWidget( widget );
 
  945void QgsSymbolSelectorDialog::showHelp()
 
  950void QgsSymbolSelectorWidget::projectDataChanged()
 
  952  mBlockModified = 
true;
 
  955  mBlockModified = 
false;
 
  958void QgsSymbolSelectorWidget::layersAboutToBeRemoved( 
const QList<QgsMapLayer *> &layers )
 
  960  if ( mVectorLayer && layers.contains( mVectorLayer ) )
 
@ FlagIncludeCrosshairsForMarkerSymbols
Include a crosshairs reference image in the background of marker symbol previews.
 
SymbolType
Attribute editing capabilities which may be supported by vector data providers.
 
static const double UI_SCALE_FACTOR
UI scaling factor.
 
static QgsSymbolLayerRegistry * symbolLayerRegistry()
Returns the application's symbol layer registry, used for managing symbol layers.
 
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
 
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
 
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
 
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
 
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
 
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.
 
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
 
Wrapper for iterator of features from vector data provider or vector layer.
 
bool nextFeature(QgsFeature &f)
 
This class wraps a request for features to a vector layer (or directly its vector data provider).
 
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
 
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
 
void remoteImageFetched(const QString &url)
Emitted when the cache has finished retrieving an image file from a remote url.
 
A line symbol type, for rendering LineString and MultiLineString geometries.
 
QgsProperty dataDefinedWidth() const
Returns data defined width for whole symbol (including all symbol layers).
 
Struct for storing maximum and minimum scales for measurements in map units.
 
Abstract base class for marker symbol layers.
 
A marker symbol type, for rendering Point and MultiPoint geometries.
 
QgsProperty dataDefinedAngle() const
Returns data defined angle for whole symbol (including all symbol layers).
 
QgsProperty dataDefinedSize() const
Returns data defined size for whole symbol (including all symbol layers).
 
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
 
static QgsProject * instance()
Returns the QgsProject singleton instance.
 
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
 
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
 
A store for object properties.
 
Stores properties relating to a screen.
 
void remoteSvgFetched(const QString &url)
Emitted when the cache has finished retrieving an SVG file from a remote url.
 
QgsSymbolLayerAbstractMetadata * symbolLayerMetadata(const QString &name) const
Returns metadata for specified symbol layer. Returns nullptr if not found.
 
static QgsSymbolLayer * defaultSymbolLayer(Qgis::SymbolType type)
create a new instance of symbol layer for specified symbol type with default settings
 
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, Qgis::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::SymbolType parentSymbolType=Qgis::SymbolType::Hybrid, QgsMapLayer *mapLayer=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Draws a symbol layer preview to an icon.
 
static QPixmap symbolPreviewPixmap(const QgsSymbol *symbol, QSize size, int padding=0, QgsRenderContext *customContext=nullptr, bool selected=false, const QgsExpressionContext *expressionContext=nullptr, const QgsLegendPatchShape *shape=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Returns a pixmap preview for a color ramp.
 
static void resetSymbolLayerIds(QgsSymbol *symbol)
Regenerate recursively unique id from all symbol symbol layers.
 
virtual QgsSymbolLayer * clone() const =0
Shall be reimplemented by subclasses to create a deep copy of the instance.
 
Qgis::SymbolType type() const
 
bool isLocked() const
Returns true if the symbol layer colors are locked and the layer will ignore any symbol-level color c...
 
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
 
void setLocked(bool locked)
Sets whether the layer's colors are locked.
 
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
 
QgsSymbolSelectorDialog(QgsSymbol *symbol, QgsStyle *style, QgsVectorLayer *vl, QWidget *parent=nullptr, bool embedded=false)
Constructor for QgsSymbolSelectorDialog.
 
QgsSymbolWidgetContext context() const
Returns the context in which the symbol widget is shown, e.g., the associated map canvas and expressi...
 
QMenu * advancedMenu()
Returns menu for "advanced" button - create it if doesn't exist and show the advanced button.
 
void symbolChanged()
Slot to update tree when a new symbol from style.
 
QDialogButtonBox * buttonBox() const
Returns a reference to the dialog's button box.
 
QgsSymbol * symbol()
Returns the symbol that is currently active in the widget.
 
void keyPressEvent(QKeyEvent *e) override
 
void updateLayerPreview()
 
void duplicateLayer()
Duplicates the current symbol layer and places the duplicated layer above the current symbol layer.
 
void changeLayer(QgsSymbolLayer *layer)
alters tree and sets proper widget when Layer Type is changed
 
void loadSymbol(QgsSymbol *symbol, SymbolLayerItem *parent=nullptr)
Loads the given symbol into the widget.
 
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
 
QgsExpressionContext * expressionContext() const
Returns the expression context used for the widget, if set.
 
Abstract base class for all rendered symbols.
 
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
 
bool appendSymbolLayer(QgsSymbolLayer *layer)
Appends a symbol layer at the end of the current symbol layer list.
 
bool insertSymbolLayer(int index, QgsSymbolLayer *layer)
Inserts a symbol layer to specified index.
 
bool changeSymbolLayer(int index, QgsSymbolLayer *layer)
Deletes the current layer at the specified index and replaces it with layer.
 
QgsSymbolLayer * takeSymbolLayer(int index)
Removes a symbol layer from the list and returns a pointer to it.
 
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.
 
Qgis::SymbolType type() const
Returns the symbol's type.
 
Q_DECL_DEPRECATED void setLayer(const QgsVectorLayer *layer)
 
Represents a vector layer which manages a vector based data sets.
 
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
 
#define Q_NOWARN_DEPRECATED_POP
 
#define Q_NOWARN_DEPRECATED_PUSH