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 );
271 #if 0 // this is too expensive to do for many providers. TODO revisit when support for connection timeouts is complete across all providers
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 );
315 mBlockModified =
true;
318 mBlockModified =
false;
327 mBlockModified =
true;
330 mBlockModified =
false;
337 mBlockModified =
true;
340 mBlockModified =
false;
346 if ( !mAdvancedMenu )
348 mAdvancedMenu =
new QMenu(
this );
352 return mAdvancedMenu;
361 mPreviewExpressionContext = *lExpressionContext;
365 mPreviewExpressionContext.
setFeature( mPreviewFeature );
368 QWidget *widget = stackedWidget->currentWidget();
395 parent =
static_cast<SymbolLayerItem *
>( model->invisibleRootItem() );
398 SymbolLayerItem *symbolItem =
new SymbolLayerItem(
symbol );
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 );
420 void QgsSymbolSelectorWidget::reloadSymbol()
423 loadSymbol( mSymbol,
static_cast<SymbolLayerItem *
>( model->invisibleRootItem() ) );
426 void QgsSymbolSelectorWidget::updateUi()
428 QModelIndex currentIdx = layersTree->currentIndex();
429 if ( !currentIdx.isValid() )
432 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>( model->itemFromIndex( currentIdx ) );
433 if ( !item->isLayer() )
435 btnUp->setEnabled(
false );
436 btnDown->setEnabled(
false );
437 btnRemoveLayer->setEnabled(
false );
438 btnLock->setEnabled(
false );
439 btnDuplicate->setEnabled(
false );
443 int rowCount = item->parent()->rowCount();
444 int currentRow = item->row();
446 btnUp->setEnabled( currentRow > 0 );
447 btnDown->setEnabled( currentRow < rowCount - 1 );
448 btnRemoveLayer->setEnabled( rowCount > 1 );
449 btnLock->setEnabled(
true );
450 btnDuplicate->setEnabled(
true );
458 std::unique_ptr< QgsSymbol > symbolClone( mSymbol->
clone() );
459 QImage preview = symbolClone->bigSymbolPreviewImage( &mPreviewExpressionContext );
460 lblPreview->setPixmap( QPixmap::fromImage( preview ) );
462 if ( !mBlockModified )
469 SymbolLayerItem *item = currentLayerItem();
471 item->updatePreview();
476 SymbolLayerItem *QgsSymbolSelectorWidget::currentLayerItem()
478 QModelIndex idx = layersTree->currentIndex();
479 if ( !idx.isValid() )
482 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>( model->itemFromIndex( idx ) );
483 if ( !item->isLayer() )
491 QModelIndex idx = layersTree->currentIndex();
492 if ( !idx.isValid() )
495 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>( model->itemFromIndex( idx ) );
496 if ( item->isLayer() )
497 return item->layer();
506 SymbolLayerItem *currentItem =
static_cast<SymbolLayerItem *
>( model->itemFromIndex( layersTree->currentIndex() ) );
510 if ( currentItem->isLayer() )
512 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( currentItem->parent() );
513 mDataDefineRestorer.reset(
new DataDefinedRestorer( parent->symbol(), currentItem->layer() ) );
517 setWidget( layerProp );
527 mDataDefineRestorer.reset();
530 currentItem->symbol()->setLayer( mVectorLayer );
534 symbolsList->setContext( mContext );
536 setWidget( symbolsList );
544 SymbolLayerItem *currentItem =
static_cast<SymbolLayerItem *
>( model->itemFromIndex( layersTree->currentIndex() ) );
545 if ( !currentItem || currentItem->isLayer() )
549 if ( currentItem->parent() )
553 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( currentItem->parent() );
554 parent->removeRow( 0 );
556 layersTree->setCurrentIndex( parent->child( 0 )->index() );
557 parent->updatePreview();
563 QModelIndex newIndex = layersTree->model()->index( 0, 0 );
564 layersTree->setCurrentIndex( newIndex );
571 void QgsSymbolSelectorWidget::setWidget( QWidget *widget )
573 int index = stackedWidget->addWidget( widget );
574 stackedWidget->setCurrentIndex( index );
575 if ( mPresentWidget )
576 mPresentWidget->deleteLater();
577 mPresentWidget = widget;
580 void QgsSymbolSelectorWidget::updateLockButton()
585 btnLock->setChecked( layer->
isLocked() );
590 QModelIndex idx = layersTree->currentIndex();
591 if ( !idx.isValid() )
595 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>( model->itemFromIndex( idx ) );
596 if ( item->isLayer() )
598 insertIdx = item->row();
599 item =
static_cast<SymbolLayerItem *
>( item->parent() );
602 QgsSymbol *parentSymbol = item->symbol();
616 if ( insertIdx == -1 )
623 static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedSize( ddSize );
625 static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedAngle( ddAngle );
627 static_cast<QgsLineSymbol *
>( parentSymbol )->setDataDefinedWidth( ddWidth );
629 SymbolLayerItem *newLayerItem =
new SymbolLayerItem( newLayer );
630 item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
631 item->updatePreview();
633 layersTree->setCurrentIndex( model->indexFromItem( newLayerItem ) );
640 SymbolLayerItem *item = currentLayerItem();
641 int row = item->row();
642 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( item->parent() );
644 int layerIdx = parent->rowCount() - row - 1;
645 QgsSymbol *parentSymbol = parent->symbol();
648 parent->removeRow( row );
649 parent->updatePreview();
651 QModelIndex newIdx = parent->child( 0 )->index();
652 layersTree->setCurrentIndex( newIdx );
662 moveLayerByOffset( + 1 );
667 moveLayerByOffset( -1 );
670 void QgsSymbolSelectorWidget::moveLayerByOffset(
int offset )
672 SymbolLayerItem *item = currentLayerItem();
675 int row = item->row();
677 SymbolLayerItem *parent =
static_cast<SymbolLayerItem *
>( item->parent() );
678 QgsSymbol *parentSymbol = parent->symbol();
680 int layerIdx = parent->rowCount() - row - 1;
685 QList<QStandardItem *> rowItems = parent->takeRow( row );
686 parent->insertRows( row + offset, rowItems );
687 parent->updatePreview();
689 QModelIndex newIdx = rowItems[ 0 ]->index();
690 layersTree->setCurrentIndex( newIdx );
701 layer->
setLocked( btnLock->isChecked() );
707 QModelIndex idx = layersTree->currentIndex();
708 if ( !idx.isValid() )
711 SymbolLayerItem *item =
static_cast<SymbolLayerItem *
>( model->itemFromIndex( idx ) );
712 if ( !item->isLayer() )
717 int insertIdx = item->row();
718 item =
static_cast<SymbolLayerItem *
>( item->parent() );
720 QgsSymbol *parentSymbol = item->symbol();
723 if ( insertIdx == -1 )
728 SymbolLayerItem *newLayerItem =
new SymbolLayerItem( newLayer );
729 item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
733 layersTree->setExpanded( newLayerItem->index(),
true );
735 item->updatePreview();
737 layersTree->setCurrentIndex( model->indexFromItem( newLayerItem ) );
744 SymbolLayerItem *item = currentLayerItem();
749 item->removeRow( 0 );
752 item->setLayer( newLayer );
757 layersTree->setExpanded( item->index(),
true );
762 int layerIdx = item->parent()->rowCount() - item->row() - 1;
765 item->updatePreview();
774 setLayout(
new QVBoxLayout() );
777 mButtonBox =
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
779 connect( mButtonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
780 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
781 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsSymbolSelectorDialog::showHelp );
783 layout()->addWidget( mSelectorWidget );
784 layout()->addWidget( mButtonBox );
788 mSelectorWidget->setMinimumSize( 460, 560 );
789 setObjectName( QStringLiteral(
"SymbolSelectorDialog" ) );
796 layout()->setContentsMargins( 0, 0, 0, 0 );
800 setWindowTitle( tr(
"Symbol Selector" ) );
822 return mSelectorWidget->
symbol();
828 if ( !isWindow() && e->key() == Qt::Key_Escape )
834 QDialog::keyPressEvent( e );
838 void QgsSymbolSelectorDialog::reloadSymbol()
840 mSelectorWidget->reloadSymbol();
848 void QgsSymbolSelectorDialog::updateUi()
850 mSelectorWidget->updateUi();
853 void QgsSymbolSelectorDialog::updateLockButton()
855 mSelectorWidget->updateLockButton();
858 SymbolLayerItem *QgsSymbolSelectorDialog::currentLayerItem()
860 return mSelectorWidget->currentLayerItem();
865 return mSelectorWidget->currentLayer();
868 void QgsSymbolSelectorDialog::moveLayerByOffset(
int offset )
870 mSelectorWidget->moveLayerByOffset( offset );
873 void QgsSymbolSelectorDialog::setWidget( QWidget *widget )
875 mSelectorWidget->setWidget( widget );
938 void QgsSymbolSelectorDialog::showHelp()