43 #include <QColorDialog> 
   45 #include <QStandardItemModel> 
   46 #include <QInputDialog> 
   47 #include <QMessageBox> 
   53 #include <QStandardItem> 
   57 static const int SYMBOL_LAYER_ITEM_TYPE = QStandardItem::UserType + 1;
 
   67     mDDSize = mMarker->dataDefinedSize();
 
   68     mDDAngle = mMarker->dataDefinedAngle();
 
   70     if ( !mDDSize && !mDDAngle )
 
   77     mDDWidth = mLine->dataDefinedWidth();
 
   85 void DataDefinedRestorer::save()
 
   89     mSize = mMarkerSymbolLayer->size();
 
   90     mAngle = mMarkerSymbolLayer->angle();
 
   91     mMarkerOffset = mMarkerSymbolLayer->offset();
 
   95     mWidth = mLineSymbolLayer->width();
 
   96     mLineOffset = mLineSymbolLayer->offset();
 
  100 void DataDefinedRestorer::restore()
 
  105          ( mSize != mMarkerSymbolLayer->size() || mMarkerOffset != mMarkerSymbolLayer->offset() ) )
 
  106       mMarker->setDataDefinedSize( mDDSize );
 
  108          mAngle != mMarkerSymbolLayer->angle() )
 
  109       mMarker->setDataDefinedAngle( mDDAngle );
 
  114          ( mWidth != mLineSymbolLayer->width() || mLineOffset != mLineSymbolLayer->offset() ) )
 
  115       mLine->setDataDefinedWidth( mDDWidth );
 
  122 class SymbolLayerItem : 
public QStandardItem
 
  130     explicit SymbolLayerItem( 
QgsSymbol *symbol )
 
  153       if ( !mSize.isValid() )
 
  156         mSize = QSize( size, size );
 
  165       if ( 
auto *lParent = parent() )
 
  166         static_cast<SymbolLayerItem *
>( lParent )->updatePreview();
 
  169     int type()
 const override { 
return SYMBOL_LAYER_ITEM_TYPE; }
 
  170     bool isLayer() { 
return mIsLayer; }
 
  183     QVariant data( 
int role )
 const override 
  185       if ( role == Qt::DisplayRole || role == Qt::EditRole )
 
  191           switch ( mSymbol->type() )
 
  194               return QCoreApplication::translate( 
"SymbolLayerItem", 
"Marker" );
 
  196               return QCoreApplication::translate( 
"SymbolLayerItem", 
"Fill" );
 
  198               return QCoreApplication::translate( 
"SymbolLayerItem", 
"Line" );
 
  204       else if ( role == Qt::ForegroundRole && mIsLayer )
 
  206         QBrush brush( Qt::black, Qt::SolidPattern );
 
  207         if ( !mLayer->enabled() )
 
  209           brush.setColor( Qt::lightGray );
 
  216       if ( role == Qt::CheckStateRole )
 
  218       return QStandardItem::data( role );
 
  237   setWindowModality( Qt::WindowModal );
 
  241   mPresentWidget = 
nullptr;
 
  244   this->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  246   layersTree->setMaximumHeight( 
static_cast< int >( 
Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 7 ) );
 
  247   layersTree->setMinimumHeight( layersTree->maximumHeight() );
 
  248   lblPreview->setMaximumWidth( layersTree->maximumHeight() );
 
  256   iconLock.addFile( 
QgsApplication::iconPath( QStringLiteral( 
"unlocked.svg" ) ), QSize(), QIcon::Normal, QIcon::Off );
 
  257   iconLock.addFile( 
QgsApplication::iconPath( QStringLiteral( 
"unlocked.svg" ) ), QSize(), QIcon::Active, QIcon::Off );
 
  258   btnLock->setIcon( iconLock );
 
  263   model = 
new QStandardItemModel( layersTree );
 
  265   layersTree->setModel( model );
 
  266   layersTree->setHeaderHidden( 
true );
 
  278     mPreviewExpressionContext.
setFeature( mPreviewFeature );
 
  286   QItemSelectionModel *selModel = layersTree->selectionModel();
 
  289   loadSymbol( 
symbol, 
static_cast<SymbolLayerItem *
>( model->invisibleRootItem() ) );
 
  303   QModelIndex newIndex = layersTree->model()->index( 0, 0 );
 
  304   layersTree->setCurrentIndex( newIndex );
 
  331   if ( !mAdvancedMenu )
 
  333     mAdvancedMenu = 
new QMenu( 
this );
 
  337   return mAdvancedMenu;
 
  346     mPreviewExpressionContext = *lExpressionContext;
 
  350     mPreviewExpressionContext.
setFeature( mPreviewFeature );
 
  353   QWidget *widget = stackedWidget->currentWidget();
 
  380     parent = 
static_cast<SymbolLayerItem *
>( model->invisibleRootItem() );
 
  383   SymbolLayerItem *symbolItem = 
new SymbolLayerItem( 
symbol );
 
  384   QFont boldFont = symbolItem->font();
 
  385   boldFont.setBold( 
true );
 
  386   symbolItem->setFont( boldFont );
 
  387   parent->appendRow( symbolItem );
 
  390   for ( 
int i = count - 1; i >= 0; i-- )
 
  393     layerItem->setEditable( 
false );
 
  394     symbolItem->appendRow( layerItem );
 
  399     layersTree->setExpanded( layerItem->index(), 
true );
 
  401   layersTree->setExpanded( symbolItem->index(), 
true );
 
  405 void QgsSymbolSelectorWidget::reloadSymbol()
 
  408   loadSymbol( mSymbol, 
static_cast<SymbolLayerItem *
>( model->invisibleRootItem() ) );
 
  411 void QgsSymbolSelectorWidget::updateUi()
 
  413   QModelIndex currentIdx = layersTree->currentIndex();
 
  414   if ( !currentIdx.isValid() )
 
  417   SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( model->itemFromIndex( currentIdx ) );
 
  418   if ( !item->isLayer() )
 
  420     btnUp->setEnabled( 
false );
 
  421     btnDown->setEnabled( 
false );
 
  422     btnRemoveLayer->setEnabled( 
false );
 
  423     btnLock->setEnabled( 
false );
 
  424     btnDuplicate->setEnabled( 
false );
 
  428   int rowCount = item->parent()->rowCount();
 
  429   int currentRow = item->row();
 
  431   btnUp->setEnabled( currentRow > 0 );
 
  432   btnDown->setEnabled( currentRow < rowCount - 1 );
 
  433   btnRemoveLayer->setEnabled( rowCount > 1 );
 
  434   btnLock->setEnabled( 
true );
 
  435   btnDuplicate->setEnabled( 
true );
 
  443   std::unique_ptr< QgsSymbol > symbolClone( mSymbol->
clone() );
 
  444   QImage preview = symbolClone->bigSymbolPreviewImage( &mPreviewExpressionContext );
 
  445   lblPreview->setPixmap( QPixmap::fromImage( preview ) );
 
  447   if ( !mBlockModified )
 
  454   SymbolLayerItem *item = currentLayerItem();
 
  456     item->updatePreview();
 
  461 SymbolLayerItem *QgsSymbolSelectorWidget::currentLayerItem()
 
  463   QModelIndex idx = layersTree->currentIndex();
 
  464   if ( !idx.isValid() )
 
  467   SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( model->itemFromIndex( idx ) );
 
  468   if ( !item->isLayer() )
 
  476   QModelIndex idx = layersTree->currentIndex();
 
  477   if ( !idx.isValid() )
 
  480   SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( model->itemFromIndex( idx ) );
 
  481   if ( item->isLayer() )
 
  482     return item->layer();
 
  491   SymbolLayerItem *currentItem = 
static_cast<SymbolLayerItem *
>( model->itemFromIndex( layersTree->currentIndex() ) );
 
  495   if ( currentItem->isLayer() )
 
  497     SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( currentItem->parent() );
 
  498     mDataDefineRestorer.reset( 
new DataDefinedRestorer( parent->symbol(), currentItem->layer() ) );
 
  502     setWidget( layerProp );
 
  512     mDataDefineRestorer.reset();
 
  515     currentItem->symbol()->setLayer( mVectorLayer );
 
  519     symbolsList->setContext( mContext );
 
  521     setWidget( symbolsList );
 
  529   SymbolLayerItem *currentItem = 
static_cast<SymbolLayerItem *
>( model->itemFromIndex( layersTree->currentIndex() ) );
 
  530   if ( !currentItem || currentItem->isLayer() )
 
  534   if ( currentItem->parent() )
 
  538     SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( currentItem->parent() );
 
  539     parent->removeRow( 0 );
 
  541     layersTree->setCurrentIndex( parent->child( 0 )->index() );
 
  542     parent->updatePreview();
 
  548     QModelIndex newIndex = layersTree->model()->index( 0, 0 );
 
  549     layersTree->setCurrentIndex( newIndex );
 
  556 void QgsSymbolSelectorWidget::setWidget( QWidget *widget )
 
  558   int index = stackedWidget->addWidget( widget );
 
  559   stackedWidget->setCurrentIndex( index );
 
  560   if ( mPresentWidget )
 
  561     mPresentWidget->deleteLater();
 
  562   mPresentWidget = widget;
 
  565 void QgsSymbolSelectorWidget::updateLockButton()
 
  570   btnLock->setChecked( layer->
isLocked() );
 
  575   QModelIndex idx = layersTree->currentIndex();
 
  576   if ( !idx.isValid() )
 
  580   SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( model->itemFromIndex( idx ) );
 
  581   if ( item->isLayer() )
 
  583     insertIdx = item->row();
 
  584     item = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  587   QgsSymbol *parentSymbol = item->symbol();
 
  601   if ( insertIdx == -1 )
 
  608     static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedSize( ddSize );
 
  610     static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedAngle( ddAngle );
 
  612     static_cast<QgsLineSymbol *
>( parentSymbol )->setDataDefinedWidth( ddWidth );
 
  614   SymbolLayerItem *newLayerItem = 
new SymbolLayerItem( newLayer );
 
  615   item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
 
  616   item->updatePreview();
 
  618   layersTree->setCurrentIndex( model->indexFromItem( newLayerItem ) );
 
  625   SymbolLayerItem *item = currentLayerItem();
 
  626   int row = item->row();
 
  627   SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  629   int layerIdx = parent->rowCount() - row - 1; 
 
  630   QgsSymbol *parentSymbol = parent->symbol();
 
  633   parent->removeRow( row );
 
  634   parent->updatePreview();
 
  636   QModelIndex newIdx = parent->child( 0 )->index();
 
  637   layersTree->setCurrentIndex( newIdx );
 
  647   moveLayerByOffset( + 1 );
 
  652   moveLayerByOffset( -1 );
 
  655 void QgsSymbolSelectorWidget::moveLayerByOffset( 
int offset )
 
  657   SymbolLayerItem *item = currentLayerItem();
 
  660   int row = item->row();
 
  662   SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  663   QgsSymbol *parentSymbol = parent->symbol();
 
  665   int layerIdx = parent->rowCount() - row - 1;
 
  670   QList<QStandardItem *> rowItems = parent->takeRow( row );
 
  671   parent->insertRows( row + offset, rowItems );
 
  672   parent->updatePreview();
 
  674   QModelIndex newIdx = rowItems[ 0 ]->index();
 
  675   layersTree->setCurrentIndex( newIdx );
 
  686   layer->
setLocked( btnLock->isChecked() );
 
  692   QModelIndex idx = layersTree->currentIndex();
 
  693   if ( !idx.isValid() )
 
  696   SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( model->itemFromIndex( idx ) );
 
  697   if ( !item->isLayer() )
 
  702   int insertIdx = item->row();
 
  703   item = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  705   QgsSymbol *parentSymbol = item->symbol();
 
  708   if ( insertIdx == -1 )
 
  713   SymbolLayerItem *newLayerItem = 
new SymbolLayerItem( newLayer );
 
  714   item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
 
  718     layersTree->setExpanded( newLayerItem->index(), 
true );
 
  720   item->updatePreview();
 
  722   layersTree->setCurrentIndex( model->indexFromItem( newLayerItem ) );
 
  729   SymbolLayerItem *item = currentLayerItem();
 
  734     item->removeRow( 0 );
 
  737   item->setLayer( newLayer );
 
  742     layersTree->setExpanded( item->index(), 
true );
 
  747   int layerIdx = item->parent()->rowCount() - item->row() - 1;
 
  750   item->updatePreview();
 
  759   setLayout( 
new QVBoxLayout() );
 
  762   mButtonBox = 
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
 
  764   connect( mButtonBox, &QDialogButtonBox::accepted, 
this, &QDialog::accept );
 
  765   connect( mButtonBox, &QDialogButtonBox::rejected, 
this, &QDialog::reject );
 
  766   connect( mButtonBox, &QDialogButtonBox::helpRequested, 
this, &QgsSymbolSelectorDialog::showHelp );
 
  768   layout()->addWidget( mSelectorWidget );
 
  769   layout()->addWidget( mButtonBox );
 
  773   mSelectorWidget->setMinimumSize( 460, 560 );
 
  774   setObjectName( QStringLiteral( 
"SymbolSelectorDialog" ) );
 
  781     layout()->setContentsMargins( 0, 0, 0, 0 );
 
  785     setWindowTitle( tr( 
"Symbol Selector" ) );
 
  807   return mSelectorWidget->
symbol();
 
  813   if ( !isWindow() && e->key() == Qt::Key_Escape )
 
  819     QDialog::keyPressEvent( e );
 
  823 void QgsSymbolSelectorDialog::reloadSymbol()
 
  825   mSelectorWidget->reloadSymbol();
 
  833 void QgsSymbolSelectorDialog::updateUi()
 
  835   mSelectorWidget->updateUi();
 
  838 void QgsSymbolSelectorDialog::updateLockButton()
 
  840   mSelectorWidget->updateLockButton();
 
  843 SymbolLayerItem *QgsSymbolSelectorDialog::currentLayerItem()
 
  845   return mSelectorWidget->currentLayerItem();
 
  850   return mSelectorWidget->currentLayer();
 
  853 void QgsSymbolSelectorDialog::moveLayerByOffset( 
int offset )
 
  855   mSelectorWidget->moveLayerByOffset( offset );
 
  858 void QgsSymbolSelectorDialog::setWidget( QWidget *widget )
 
  860   mSelectorWidget->setWidget( widget );
 
  923 void QgsSymbolSelectorDialog::showHelp()
 
  928 void QgsSymbolSelectorWidget::projectDataChanged()
 
  930   mBlockModified = 
true;
 
  933   mBlockModified = 
false;
 
  936 void QgsSymbolSelectorWidget::layersAboutToBeRemoved( 
const QList<QgsMapLayer *> &layers )
 
  938   if ( mVectorLayer && layers.contains( mVectorLayer ) )
 
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.
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 QgsGui * instance()
Returns a pointer to the singleton instance.
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).
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.
void remoteSvgFetched(const QString &url)
Emitted when the cache has finished retrieving an SVG file from a remote url.
static QgsSymbolLayer * defaultSymbolLayer(QgsSymbol::SymbolType type)
create a new instance of symbol layer for specified symbol type with default settings
QgsSymbolLayerAbstractMetadata * symbolLayerMetadata(const QString &name) const
Returns metadata for specified symbol layer. Returns nullptr if not found.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr)
Returns an icon preview for a color ramp.
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to an icon.
virtual QgsSymbolLayer * clone() const =0
Shall be reimplemented by subclasses to create a deep copy of the instance.
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
QgsSymbol::SymbolType type() const
void setLocked(bool 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.
SymbolType type() const
Returns the symbol's type.
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.
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
@ RenderMillimeters
Millimeters.
Represents a vector layer which manages a vector based data sets.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
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