38 #include <QColorDialog> 40 #include <QStandardItemModel> 41 #include <QInputDialog> 42 #include <QMessageBox> 48 #include <QStandardItem> 52 static const int SYMBOL_LAYER_ITEM_TYPE = QStandardItem::UserType + 1;
62 mDDSize = mMarker->dataDefinedSize();
63 mDDAngle = mMarker->dataDefinedAngle();
65 if ( !mDDSize && !mDDAngle )
72 mDDWidth = mLine->dataDefinedWidth();
80 void DataDefinedRestorer::save()
84 mSize = mMarkerSymbolLayer->size();
85 mAngle = mMarkerSymbolLayer->angle();
86 mMarkerOffset = mMarkerSymbolLayer->offset();
90 mWidth = mLineSymbolLayer->width();
91 mLineOffset = mLineSymbolLayer->offset();
95 void DataDefinedRestorer::restore()
100 ( mSize != mMarkerSymbolLayer->size() || mMarkerOffset != mMarkerSymbolLayer->offset() ) )
101 mMarker->setDataDefinedSize( mDDSize );
103 mAngle != mMarkerSymbolLayer->angle() )
104 mMarker->setDataDefinedAngle( mDDAngle );
109 ( mWidth != mLineSymbolLayer->width() || mLineOffset != mLineSymbolLayer->offset() ) )
110 mLine->setDataDefinedWidth( mDDWidth );
117 class SymbolLayerItem :
public QStandardItem
125 explicit SymbolLayerItem(
QgsSymbol *symbol )
156 static_cast<SymbolLayerItem *
>( parent() )->updatePreview();
159 int type()
const override {
return SYMBOL_LAYER_ITEM_TYPE; }
160 bool isLayer() {
return mIsLayer; }
173 QVariant data(
int role )
const override 175 if ( role == Qt::DisplayRole || role == Qt::EditRole )
181 switch ( mSymbol->type() )
184 return QCoreApplication::translate(
"SymbolLayerItem",
"Marker",
nullptr, QCoreApplication::UnicodeUTF8 );
186 return QCoreApplication::translate(
"SymbolLayerItem",
"Fill",
nullptr, QCoreApplication::UnicodeUTF8 );
188 return QCoreApplication::translate(
"SymbolLayerItem",
"Line",
nullptr, QCoreApplication::UnicodeUTF8 );
194 else if ( role == Qt::ForegroundRole && mIsLayer )
196 QBrush brush( Qt::black, Qt::SolidPattern );
197 if ( !mLayer->enabled() )
199 brush.setColor( Qt::lightGray );
206 if ( role == Qt::CheckStateRole )
208 return QStandardItem::data( role );
226 setWindowModality( Qt::WindowModal );
233 this->layout()->setContentsMargins( 0, 0, 0, 0 );
241 iconLock.addFile(
QgsApplication::iconPath( QStringLiteral(
"unlocked.svg" ) ), QSize(), QIcon::Normal, QIcon::Off );
242 iconLock.addFile(
QgsApplication::iconPath( QStringLiteral(
"unlocked.svg" ) ), QSize(), QIcon::Active, QIcon::Off );
243 btnLock->setIcon( iconLock );
248 model =
new QStandardItemModel( layersTree );
250 layersTree->setModel(
model );
251 layersTree->setHeaderHidden(
true );
259 mPreviewExpressionContext.
setFeature( mPreviewFeature );
266 QItemSelectionModel *selModel = layersTree->selectionModel();
269 loadSymbol( symbol, static_cast<SymbolLayerItem *>(
model->invisibleRootItem() ) );
283 QModelIndex newIndex = layersTree->model()->index( 0, 0 );
284 layersTree->setCurrentIndex( newIndex );
321 mPreviewExpressionContext.
setFeature( mPreviewFeature );
324 QWidget *widget = stackedWidget->currentWidget();
344 SymbolLayerItem *symbolItem =
new SymbolLayerItem( symbol );
345 QFont boldFont = symbolItem->font();
346 boldFont.setBold(
true );
347 symbolItem->setFont( boldFont );
348 parent->appendRow( symbolItem );
351 for (
int i = count - 1; i >= 0; i-- )
353 SymbolLayerItem *layerItem =
new SymbolLayerItem( symbol->
symbolLayer( i ) );
354 layerItem->setEditable(
false );
355 symbolItem->appendRow( layerItem );
360 layersTree->setExpanded( layerItem->index(), true );
362 layersTree->setExpanded( symbolItem->index(), true );
374 QModelIndex currentIdx = layersTree->currentIndex();
375 if ( !currentIdx.isValid() )
378 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( currentIdx ) );
379 if ( !item->isLayer() )
381 btnUp->setEnabled(
false );
382 btnDown->setEnabled(
false );
383 btnRemoveLayer->setEnabled(
false );
384 btnLock->setEnabled(
false );
385 btnDuplicate->setEnabled(
false );
389 int rowCount = item->parent()->rowCount();
390 int currentRow = item->row();
392 btnUp->setEnabled( currentRow > 0 );
393 btnDown->setEnabled( currentRow < rowCount - 1 );
394 btnRemoveLayer->setEnabled( rowCount > 1 );
395 btnLock->setEnabled(
true );
396 btnDuplicate->setEnabled(
true );
402 lblPreview->setPixmap( QPixmap::fromImage( preview ) );
412 item->updatePreview();
419 QModelIndex idx = layersTree->currentIndex();
420 if ( !idx.isValid() )
423 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( idx ) );
424 if ( !item->isLayer() )
432 QModelIndex idx = layersTree->currentIndex();
433 if ( !idx.isValid() )
436 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( idx ) );
437 if ( item->isLayer() )
438 return item->layer();
447 SymbolLayerItem *currentItem =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( layersTree->currentIndex() ) );
451 if ( currentItem->isLayer() )
453 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( currentItem->parent() );
454 mDataDefineRestorer.reset(
new DataDefinedRestorer( parent->symbol(), currentItem->layer() ) );
468 mDataDefineRestorer.reset();
483 SymbolLayerItem *currentItem =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( layersTree->currentIndex() ) );
484 if ( !currentItem || currentItem->isLayer() )
488 if ( currentItem->parent() )
491 QgsSymbol *symbol = currentItem->symbol();
492 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( currentItem->parent() );
493 parent->removeRow( 0 );
495 layersTree->setCurrentIndex( parent->child( 0 )->index() );
496 parent->updatePreview();
502 QModelIndex newIndex = layersTree->model()->index( 0, 0 );
503 layersTree->setCurrentIndex( newIndex );
512 int index = stackedWidget->addWidget( widget );
513 stackedWidget->setCurrentIndex( index );
524 btnLock->setChecked( layer->
isLocked() );
529 QModelIndex idx = layersTree->currentIndex();
530 if ( !idx.isValid() )
534 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( idx ) );
535 if ( item->isLayer() )
537 insertIdx = item->row();
538 item =
static_cast<SymbolLayerItem *
>( item->parent() );
541 QgsSymbol *parentSymbol = item->symbol();
551 ?
static_cast<QgsLineSymbol *
>( parentSymbol )->dataDefinedWidth()
555 if ( insertIdx == -1 )
562 static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedSize( ddSize );
564 static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedAngle( ddAngle );
566 static_cast<QgsLineSymbol *
>( parentSymbol )->setDataDefinedWidth( ddWidth );
568 SymbolLayerItem *newLayerItem =
new SymbolLayerItem( newLayer );
569 item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
570 item->updatePreview();
572 layersTree->setCurrentIndex(
model->indexFromItem( newLayerItem ) );
580 int row = item->row();
581 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( item->parent() );
583 int layerIdx = parent->rowCount() - row - 1;
584 QgsSymbol *parentSymbol = parent->symbol();
587 parent->removeRow( row );
588 parent->updatePreview();
590 QModelIndex newIdx = parent->child( 0 )->index();
591 layersTree->setCurrentIndex( newIdx );
614 int row = item->row();
616 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( item->parent() );
617 QgsSymbol *parentSymbol = parent->symbol();
619 int layerIdx = parent->rowCount() - row - 1;
624 QList<QStandardItem *> rowItems = parent->takeRow( row );
625 parent->insertRows( row + offset, rowItems );
626 parent->updatePreview();
628 QModelIndex newIdx = rowItems[ 0 ]->index();
629 layersTree->setCurrentIndex( newIdx );
640 layer->
setLocked( btnLock->isChecked() );
646 QModelIndex idx = layersTree->currentIndex();
647 if ( !idx.isValid() )
650 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>(
model->itemFromIndex( idx ) );
651 if ( !item->isLayer() )
656 int insertIdx = item->row();
657 item =
static_cast<SymbolLayerItem *
>( item->parent() );
659 QgsSymbol *parentSymbol = item->symbol();
662 if ( insertIdx == -1 )
667 SymbolLayerItem *newLayerItem =
new SymbolLayerItem( newLayer );
668 item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
672 layersTree->setExpanded( newLayerItem->index(), true );
674 item->updatePreview();
676 layersTree->setCurrentIndex(
model->indexFromItem( newLayerItem ) );
688 item->removeRow( 0 );
691 item->setLayer( newLayer );
696 layersTree->setExpanded( item->index(), true );
700 QgsSymbol *symbol =
static_cast<SymbolLayerItem *
>( item->parent() )->
symbol();
701 int layerIdx = item->parent()->rowCount() - item->row() - 1;
704 item->updatePreview();
713 setLayout(
new QVBoxLayout() );
715 mButtonBox =
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
717 connect( mButtonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
718 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
719 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsSymbolSelectorDialog::showHelp );
721 layout()->addWidget( mSelectorWidget );
722 layout()->addWidget( mButtonBox );
725 restoreGeometry( settings.
value( QStringLiteral(
"Windows/SymbolSelectorWidget/geometry" ) ).toByteArray() );
731 layout()->setContentsMargins( 0, 0, 0, 0 );
735 setWindowTitle( tr(
"Symbol Selector" ) );
763 return mSelectorWidget->
symbol();
769 if ( !isWindow() && e->key() == Qt::Key_Escape )
775 QDialog::keyPressEvent( e );
786 mSelectorWidget->
loadSymbol( symbol, parent );
874 void QgsSymbolSelectorDialog::showHelp()
876 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)
Insert symbol layer to specified index Ownership will be transferred.
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()
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
This class is a composition of two QSettings instances:
bool appendSymbolLayer(QgsSymbolLayer *layer)
Append symbol layer at the end of the list Ownership will be transferred.
QgsSymbolSelectorDialog(QgsSymbol *symbol, QgsStyle *style, QgsVectorLayer *vl, QWidget *parent=nullptr, bool embedded=false)
Constructor for QgsSymbolSelectorDialog.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
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.
int symbolLayerCount() const
Returns total number of symbol layers contained in the symbol.
static QIcon symbolLayerPreviewIcon(QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to an icon.
void saveGeometry(QWidget *widget, const QString &keyName)
Save the wigget geometry into settings.
QgsSymbolWidgetContext context() const
Returns the context in which the symbol widget is shown, e.g., the associated map canvas and expressi...
bool restoreGeometry(QWidget *widget, const QString &keyName)
Restore the wigget geometry from settings.
void setValue(const QString &key, const QVariant &value, const QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
void moveLayerByOffset(int offset)
static QIcon symbolPreviewIcon(QgsSymbol *symbol, QSize size, int padding=0)
Returns an icon preview for a color ramp.
QgsSymbolLayerAbstractMetadata * symbolLayerMetadata(const QString &name) const
return metadata for specified symbol layer. Returns NULL if not found
Contains settings which reflect the context in which a symbol (or renderer) widget is shown...
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)...
void symbolChanged()
Slot to update tree when a new symbol from style.
QgsSymbol::SymbolType type() const
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 layers contained in the symbol.
QMenu * advancedMenu()
return menu for "advanced" button - create it if doesn't exist and show the advanced button ...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override
Query the layer for features specified in request.
SymbolLayerItem * currentLayerItem()
bool changeSymbolLayer(int index, QgsSymbolLayer *layer)
delete layer at specified index and set a new one
QgsExpressionContext * expressionContext() const
Returns the expression context used for the widget, if set.
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 ...
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), const Section section=NoSection) const
Returns the value for setting key.
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
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
QgsSymbolLayer * takeSymbolLayer(int index)
Remove symbol layer from the list and return pointer to it.
void remoteSvgFetched(const QString &url)
Emitted when the cache has finished retrieving an SVG file from a remote url.
void appendScopes(const QList< QgsExpressionContextScope *> &scopes)
Appends a list of scopes to the end of the context.
QgsSymbol * symbol()
Return 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.
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.
~QgsSymbolSelectorDialog() override
Represents a vector layer which manages a vector based data sets.