40 #include <QColorDialog> 42 #include <QStandardItemModel> 43 #include <QInputDialog> 44 #include <QMessageBox> 50 #include <QStandardItem> 54 static const int SYMBOL_LAYER_ITEM_TYPE = QStandardItem::UserType + 1;
64 mDDSize = mMarker->dataDefinedSize();
65 mDDAngle = mMarker->dataDefinedAngle();
67 if ( !mDDSize && !mDDAngle )
74 mDDWidth = mLine->dataDefinedWidth();
82 void DataDefinedRestorer::save()
86 mSize = mMarkerSymbolLayer->size();
87 mAngle = mMarkerSymbolLayer->angle();
88 mMarkerOffset = mMarkerSymbolLayer->offset();
92 mWidth = mLineSymbolLayer->width();
93 mLineOffset = mLineSymbolLayer->offset();
97 void DataDefinedRestorer::restore()
102 ( mSize != mMarkerSymbolLayer->size() || mMarkerOffset != mMarkerSymbolLayer->offset() ) )
103 mMarker->setDataDefinedSize( mDDSize );
105 mAngle != mMarkerSymbolLayer->angle() )
106 mMarker->setDataDefinedAngle( mDDAngle );
111 ( mWidth != mLineSymbolLayer->width() || mLineOffset != mLineSymbolLayer->offset() ) )
112 mLine->setDataDefinedWidth( mDDWidth );
119 class SymbolLayerItem :
public QStandardItem
127 explicit SymbolLayerItem(
QgsSymbol *symbol )
150 if ( !mSize.isValid() )
153 mSize = QSize( size, size );
163 static_cast<SymbolLayerItem *
>( parent() )->updatePreview();
166 int type()
const override {
return SYMBOL_LAYER_ITEM_TYPE; }
167 bool isLayer() {
return mIsLayer; }
180 QVariant data(
int role )
const override 182 if ( role == Qt::DisplayRole || role == Qt::EditRole )
188 switch ( mSymbol->type() )
191 return QCoreApplication::translate(
"SymbolLayerItem",
"Marker",
nullptr, QCoreApplication::UnicodeUTF8 );
193 return QCoreApplication::translate(
"SymbolLayerItem",
"Fill",
nullptr, QCoreApplication::UnicodeUTF8 );
195 return QCoreApplication::translate(
"SymbolLayerItem",
"Line",
nullptr, QCoreApplication::UnicodeUTF8 );
201 else if ( role == Qt::ForegroundRole && mIsLayer )
203 QBrush brush( Qt::black, Qt::SolidPattern );
204 if ( !mLayer->enabled() )
206 brush.setColor( Qt::lightGray );
213 if ( role == Qt::CheckStateRole )
215 return QStandardItem::data( role );
234 setWindowModality( Qt::WindowModal );
241 this->layout()->setContentsMargins( 0, 0, 0, 0 );
243 layersTree->setMaximumHeight( static_cast< int >(
Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 7 ) );
244 layersTree->setMinimumHeight( layersTree->maximumHeight() );
252 iconLock.addFile(
QgsApplication::iconPath( QStringLiteral(
"unlocked.svg" ) ), QSize(), QIcon::Normal, QIcon::Off );
253 iconLock.addFile(
QgsApplication::iconPath( QStringLiteral(
"unlocked.svg" ) ), QSize(), QIcon::Active, QIcon::Off );
254 btnLock->setIcon( iconLock );
259 model =
new QStandardItemModel( layersTree );
261 layersTree->setModel(
model );
262 layersTree->setHeaderHidden(
true );
267 #if 0 // this is too expensive to do for many providers. TODO revisit when support for connection timeouts is complete across all providers 274 mPreviewExpressionContext.
setFeature( mPreviewFeature );
282 QItemSelectionModel *selModel = layersTree->selectionModel();
285 loadSymbol( symbol, static_cast<SymbolLayerItem *>(
model->invisibleRootItem() ) );
299 QModelIndex newIndex = layersTree->model()->index( 0, 0 );
300 layersTree->setCurrentIndex( newIndex );
337 mPreviewExpressionContext.
setFeature( mPreviewFeature );
340 QWidget *widget = stackedWidget->currentWidget();
364 parent =
static_cast<SymbolLayerItem *
>(
model->invisibleRootItem() );
367 SymbolLayerItem *symbolItem =
new SymbolLayerItem( symbol );
368 QFont boldFont = symbolItem->font();
369 boldFont.setBold(
true );
370 symbolItem->setFont( boldFont );
371 parent->appendRow( symbolItem );
374 for (
int i = count - 1; i >= 0; i-- )
376 SymbolLayerItem *layerItem =
new SymbolLayerItem( symbol->
symbolLayer( i ) );
377 layerItem->setEditable(
false );
378 symbolItem->appendRow( layerItem );
383 layersTree->setExpanded( layerItem->index(), true );
385 layersTree->setExpanded( symbolItem->index(), true );
397 QModelIndex currentIdx = layersTree->currentIndex();
398 if ( !currentIdx.isValid() )
401 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( currentIdx ) );
402 if ( !item->isLayer() )
404 btnUp->setEnabled(
false );
405 btnDown->setEnabled(
false );
406 btnRemoveLayer->setEnabled(
false );
407 btnLock->setEnabled(
false );
408 btnDuplicate->setEnabled(
false );
412 int rowCount = item->parent()->rowCount();
413 int currentRow = item->row();
415 btnUp->setEnabled( currentRow > 0 );
416 btnDown->setEnabled( currentRow < rowCount - 1 );
417 btnRemoveLayer->setEnabled( rowCount > 1 );
418 btnLock->setEnabled(
true );
419 btnDuplicate->setEnabled(
true );
425 lblPreview->setPixmap( QPixmap::fromImage( preview ) );
435 item->updatePreview();
442 QModelIndex idx = layersTree->currentIndex();
443 if ( !idx.isValid() )
446 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( idx ) );
447 if ( !item->isLayer() )
455 QModelIndex idx = layersTree->currentIndex();
456 if ( !idx.isValid() )
459 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( idx ) );
460 if ( item->isLayer() )
461 return item->layer();
470 SymbolLayerItem *currentItem =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( layersTree->currentIndex() ) );
474 if ( currentItem->isLayer() )
476 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( currentItem->parent() );
477 mDataDefineRestorer.reset(
new DataDefinedRestorer( parent->symbol(), currentItem->layer() ) );
491 mDataDefineRestorer.reset();
508 SymbolLayerItem *currentItem =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( layersTree->currentIndex() ) );
509 if ( !currentItem || currentItem->isLayer() )
513 if ( currentItem->parent() )
516 QgsSymbol *symbol = currentItem->symbol();
517 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( currentItem->parent() );
518 parent->removeRow( 0 );
520 layersTree->setCurrentIndex( parent->child( 0 )->index() );
521 parent->updatePreview();
527 QModelIndex newIndex = layersTree->model()->index( 0, 0 );
528 layersTree->setCurrentIndex( newIndex );
537 int index = stackedWidget->addWidget( widget );
538 stackedWidget->setCurrentIndex( index );
549 btnLock->setChecked( layer->
isLocked() );
554 QModelIndex idx = layersTree->currentIndex();
555 if ( !idx.isValid() )
559 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( idx ) );
560 if ( item->isLayer() )
562 insertIdx = item->row();
563 item =
static_cast<SymbolLayerItem *
>( item->parent() );
566 QgsSymbol *parentSymbol = item->symbol();
576 ?
static_cast<QgsLineSymbol *
>( parentSymbol )->dataDefinedWidth()
580 if ( insertIdx == -1 )
587 static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedSize( ddSize );
589 static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedAngle( ddAngle );
591 static_cast<QgsLineSymbol *
>( parentSymbol )->setDataDefinedWidth( ddWidth );
593 SymbolLayerItem *newLayerItem =
new SymbolLayerItem( newLayer );
594 item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
595 item->updatePreview();
597 layersTree->setCurrentIndex(
model->indexFromItem( newLayerItem ) );
605 int row = item->row();
606 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( item->parent() );
608 int layerIdx = parent->rowCount() - row - 1;
609 QgsSymbol *parentSymbol = parent->symbol();
612 parent->removeRow( row );
613 parent->updatePreview();
615 QModelIndex newIdx = parent->child( 0 )->index();
616 layersTree->setCurrentIndex( newIdx );
639 int row = item->row();
641 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( item->parent() );
642 QgsSymbol *parentSymbol = parent->symbol();
644 int layerIdx = parent->rowCount() - row - 1;
649 QList<QStandardItem *> rowItems = parent->takeRow( row );
650 parent->insertRows( row + offset, rowItems );
651 parent->updatePreview();
653 QModelIndex newIdx = rowItems[ 0 ]->index();
654 layersTree->setCurrentIndex( newIdx );
665 layer->
setLocked( btnLock->isChecked() );
671 QModelIndex idx = layersTree->currentIndex();
672 if ( !idx.isValid() )
675 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( idx ) );
676 if ( !item->isLayer() )
681 int insertIdx = item->row();
682 item =
static_cast<SymbolLayerItem *
>( item->parent() );
684 QgsSymbol *parentSymbol = item->symbol();
687 if ( insertIdx == -1 )
692 SymbolLayerItem *newLayerItem =
new SymbolLayerItem( newLayer );
693 item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
697 layersTree->setExpanded( newLayerItem->index(), true );
699 item->updatePreview();
701 layersTree->setCurrentIndex(
model->indexFromItem( newLayerItem ) );
713 item->removeRow( 0 );
716 item->setLayer( newLayer );
721 layersTree->setExpanded( item->index(), true );
725 QgsSymbol *symbol =
static_cast<SymbolLayerItem *
>( item->parent() )->
symbol();
726 int layerIdx = item->parent()->rowCount() - item->row() - 1;
729 item->updatePreview();
738 setLayout(
new QVBoxLayout() );
740 mButtonBox =
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
742 connect( mButtonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
743 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
744 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsSymbolSelectorDialog::showHelp );
746 layout()->addWidget( mSelectorWidget );
747 layout()->addWidget( mButtonBox );
749 mSelectorWidget->setMinimumSize( 460, 560 );
750 setObjectName( QStringLiteral(
"SymbolSelectorDialog" ) );
757 layout()->setContentsMargins( 0, 0, 0, 0 );
761 setWindowTitle( tr(
"Symbol Selector" ) );
783 return mSelectorWidget->
symbol();
789 if ( !isWindow() && e->key() == Qt::Key_Escape )
795 QDialog::keyPressEvent( e );
806 mSelectorWidget->
loadSymbol( symbol, parent );
894 void QgsSymbolSelectorDialog::showHelp()
896 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/style_library.html#the-symbol-selector" ) );
void duplicateLayer()
Duplicates the current symbol layer and places the duplicated layer above the current symbol layer...
bool insertSymbolLayer(int index, QgsSymbolLayer *layer)
Inserts a symbol layer to specified index.
static QgsSymbolLayerRegistry * symbolLayerRegistry()
Returns the application's symbol layer registry, used for managing symbol layers. ...
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
Wrapper for iterator of features from vector data provider or vector layer.
void setLocked(bool locked)
QgsSymbolLayer * currentLayer()
Abstract base class for all rendered symbols.
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
static const double UI_SCALE_FACTOR
UI scaling factor.
bool appendSymbolLayer(QgsSymbolLayer *layer)
Appends a symbol layer at the end of the current symbol layer list.
QgsSymbolSelectorDialog(QgsSymbol *symbol, QgsStyle *style, QgsVectorLayer *vl, QWidget *parent=nullptr, bool embedded=false)
Constructor for QgsSymbolSelectorDialog.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
static QgsSymbolLayer * defaultSymbolLayer(QgsSymbol::SymbolType type)
create a new instance of symbol layer for specified symbol type with default settings ...
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
#define Q_NOWARN_DEPRECATED_PUSH
static QgsGui * instance()
Returns a pointer to the singleton instance.
A marker symbol type, for rendering Point and MultiPoint geometries.
QgsSymbolLayerAbstractMetadata * symbolLayerMetadata(const QString &name) const
Returns metadata for specified symbol layer. Returns NULL if not found.
A line symbol type, for rendering LineString and MultiLineString geometries.
static QIcon symbolLayerPreviewIcon(QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to an icon.
void moveLayerByOffset(int offset)
static QIcon symbolPreviewIcon(QgsSymbol *symbol, QSize size, int padding=0)
Returns an icon preview for a color ramp.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown...
QgsSymbol::SymbolType type() const
void updateLayerPreview()
virtual QgsSymbolLayer * clone() const =0
Shall be reimplemented by subclasses to create a deep copy of the instance.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsExpressionContext * expressionContext() const
Returns the expression context used for the widget, if set.
void symbolChanged()
Slot to update tree when a new symbol from style.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
void setWidget(QWidget *widget)
A store for object properties.
QgsSymbolLayer * symbolLayer(int layer)
Returns a specific symbol layer contained in the symbol.
QMenu * advancedMenu()
Returns menu for "advanced" button - create it if doesn't exist and show the advanced button...
#define Q_NOWARN_DEPRECATED_POP
QgsSymbolWidgetContext context() const
Returns the context in which the symbol widget is shown, e.g., the associated map canvas and expressi...
SymbolLayerItem * currentLayerItem()
bool changeSymbolLayer(int index, QgsSymbolLayer *layer)
Deletes the current layer at the specified index and replaces it with layer.
Abstract base class for marker symbol layers.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void changeLayer(QgsSymbolLayer *layer)
alters tree and sets proper widget when Layer Type is changed
SymbolType type() const
Returns the symbol's type.
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.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query the layer for features specified in request.
QgsSymbolLayer * takeSymbolLayer(int index)
Removes a symbol layer from the list and returns a pointer to it.
void remoteSvgFetched(const QString &url)
Emitted when the cache has finished retrieving an SVG file from a remote url.
QgsSymbol * symbol()
Returns the symbol that is currently active in the widget.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
bool nextFeature(QgsFeature &f)
void keyPressEvent(QKeyEvent *e) override
QImage bigSymbolPreviewImage(QgsExpressionContext *expressionContext=nullptr)
Returns a large (roughly 100x100 pixel) preview image for the symbol.
Represents a vector layer which manages a vector based data sets.