46 #include <QColorDialog> 
   48 #include <QStandardItemModel> 
   49 #include <QInputDialog> 
   50 #include <QMessageBox> 
   56 #include <QStandardItem> 
   60 static const int SYMBOL_LAYER_ITEM_TYPE = QStandardItem::UserType + 1;
 
   70     mDDSize = mMarker->dataDefinedSize();
 
   71     mDDAngle = mMarker->dataDefinedAngle();
 
   73     if ( !mDDSize && !mDDAngle )
 
   80     mDDWidth = mLine->dataDefinedWidth();
 
   88 void DataDefinedRestorer::save()
 
   92     mSize = mMarkerSymbolLayer->size();
 
   93     mAngle = mMarkerSymbolLayer->angle();
 
   94     mMarkerOffset = mMarkerSymbolLayer->offset();
 
   98     mWidth = mLineSymbolLayer->width();
 
   99     mLineOffset = mLineSymbolLayer->offset();
 
  103 void DataDefinedRestorer::restore()
 
  108          ( mSize != mMarkerSymbolLayer->size() || mMarkerOffset != mMarkerSymbolLayer->offset() ) )
 
  109       mMarker->setDataDefinedSize( mDDSize );
 
  111          mAngle != mMarkerSymbolLayer->angle() )
 
  112       mMarker->setDataDefinedAngle( mDDAngle );
 
  117          ( mWidth != mLineSymbolLayer->width() || mLineOffset != mLineSymbolLayer->offset() ) )
 
  118       mLine->setDataDefinedWidth( mDDWidth );
 
  125 class SymbolLayerItem : 
public QStandardItem
 
  130       setLayer( layer, symbolType );
 
  133     explicit SymbolLayerItem( 
QgsSymbol *symbol )
 
  143       mSymbolType = symbolType;
 
  157       if ( !mSize.isValid() )
 
  160         mSize = QSize( size, size );
 
  169       if ( 
auto *lParent = parent() )
 
  170         static_cast<SymbolLayerItem *
>( lParent )->updatePreview();
 
  173     int type()
 const override { 
return SYMBOL_LAYER_ITEM_TYPE; }
 
  174     bool isLayer() { 
return mIsLayer; }
 
  187     QVariant data( 
int role )
 const override 
  189       if ( role == Qt::DisplayRole || role == Qt::EditRole )
 
  201           switch ( mSymbol->type() )
 
  204               return QCoreApplication::translate( 
"SymbolLayerItem", 
"Marker" );
 
  206               return QCoreApplication::translate( 
"SymbolLayerItem", 
"Fill" );
 
  208               return QCoreApplication::translate( 
"SymbolLayerItem", 
"Line" );
 
  214       else if ( role == Qt::ForegroundRole && mIsLayer )
 
  216         if ( !mLayer->enabled() )
 
  218           QPalette 
pal = qApp->palette();
 
  219           QBrush brush = QStandardItem::data( role ).value< QBrush >();
 
  220           brush.setColor( 
pal.color( QPalette::Disabled, QPalette::WindowText ) );
 
  231       if ( role == Qt::CheckStateRole )
 
  233       return QStandardItem::data( role );
 
  255   setWindowModality( Qt::WindowModal );
 
  259   this->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  261   layersTree->setMaximumHeight( 
static_cast< int >( 
Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 7 ) );
 
  262   layersTree->setMinimumHeight( layersTree->maximumHeight() );
 
  263   lblPreview->setMaximumWidth( layersTree->maximumHeight() );
 
  271   iconLock.addFile( 
QgsApplication::iconPath( QStringLiteral( 
"unlocked.svg" ) ), QSize(), QIcon::Normal, QIcon::Off );
 
  272   iconLock.addFile( 
QgsApplication::iconPath( QStringLiteral( 
"unlocked.svg" ) ), QSize(), QIcon::Active, QIcon::Off );
 
  273   btnLock->setIcon( iconLock );
 
  278   mSymbolLayersModel = 
new QStandardItemModel( layersTree );
 
  280   layersTree->setModel( mSymbolLayersModel );
 
  281   layersTree->setHeaderHidden( 
true );
 
  286 #if 0 // this is too expensive to do for many providers. TODO revisit when support for connection timeouts is complete across all providers 
  293     mPreviewExpressionContext.
setFeature( mPreviewFeature );
 
  301   QItemSelectionModel *selModel = layersTree->selectionModel();
 
  304   loadSymbol( mSymbol, 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->invisibleRootItem() ) );
 
  318   const QModelIndex newIndex = layersTree->model()->index( 0, 0 );
 
  319   layersTree->setCurrentIndex( newIndex );
 
  346   if ( !mAdvancedMenu )
 
  348     mAdvancedMenu = 
new QMenu( 
this );
 
  352   return mAdvancedMenu;
 
  361     mPreviewExpressionContext = *lExpressionContext;
 
  365     mPreviewExpressionContext.
setFeature( mPreviewFeature );
 
  368   QWidget *widget = stackedWidget->currentWidget();
 
  370     layerProp->setContext( 
context );
 
  372     listWidget->setContext( 
context );
 
  391     mSymbolLayersModel->clear();
 
  392     parent = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->invisibleRootItem() );
 
  395   SymbolLayerItem *symbolItem = 
new SymbolLayerItem( 
symbol );
 
  396   QFont boldFont = symbolItem->font();
 
  397   boldFont.setBold( 
true );
 
  398   symbolItem->setFont( boldFont );
 
  399   parent->appendRow( symbolItem );
 
  402   for ( 
int i = count - 1; i >= 0; i-- )
 
  405     layerItem->setEditable( 
false );
 
  406     symbolItem->appendRow( layerItem );
 
  411     layersTree->setExpanded( layerItem->index(), 
true );
 
  413   layersTree->setExpanded( symbolItem->index(), 
true );
 
  415   if ( mSymbol == 
symbol && !layersTree->currentIndex().isValid() )
 
  418     layersTree->setCurrentIndex( symbolItem->index() );
 
  422 void QgsSymbolSelectorWidget::reloadSymbol()
 
  424   mSymbolLayersModel->clear();
 
  425   loadSymbol( mSymbol, 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->invisibleRootItem() ) );
 
  428 void QgsSymbolSelectorWidget::updateUi()
 
  430   const QModelIndex currentIdx = layersTree->currentIndex();
 
  431   if ( !currentIdx.isValid() )
 
  434   SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( currentIdx ) );
 
  435   if ( !item->isLayer() )
 
  437     btnUp->setEnabled( 
false );
 
  438     btnDown->setEnabled( 
false );
 
  439     btnRemoveLayer->setEnabled( 
false );
 
  440     btnLock->setEnabled( 
false );
 
  441     btnDuplicate->setEnabled( 
false );
 
  445   const int rowCount = item->parent()->rowCount();
 
  446   const int currentRow = item->row();
 
  448   btnUp->setEnabled( currentRow > 0 );
 
  449   btnDown->setEnabled( currentRow < rowCount - 1 );
 
  450   btnRemoveLayer->setEnabled( rowCount > 1 );
 
  451   btnLock->setEnabled( 
true );
 
  452   btnDuplicate->setEnabled( 
true );
 
  460   std::unique_ptr< QgsSymbol > symbolClone( mSymbol->
clone() );
 
  461   const QImage preview = symbolClone->bigSymbolPreviewImage( &mPreviewExpressionContext, Qgis::SymbolPreviewFlags() );
 
  462   lblPreview->setPixmap( QPixmap::fromImage( preview ) );
 
  464   if ( !mBlockModified )
 
  471   SymbolLayerItem *item = currentLayerItem();
 
  473     item->updatePreview();
 
  478 SymbolLayerItem *QgsSymbolSelectorWidget::currentLayerItem()
 
  480   const QModelIndex idx = layersTree->currentIndex();
 
  481   if ( !idx.isValid() )
 
  484   SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( idx ) );
 
  485   if ( !item->isLayer() )
 
  493   const QModelIndex idx = layersTree->currentIndex();
 
  494   if ( !idx.isValid() )
 
  497   SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( idx ) );
 
  498   if ( item->isLayer() )
 
  499     return item->layer();
 
  508   SymbolLayerItem *currentItem = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( layersTree->currentIndex() ) );
 
  512   if ( currentItem->isLayer() )
 
  514     SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( currentItem->parent() );
 
  515     mDataDefineRestorer.reset( 
new DataDefinedRestorer( parent->symbol(), currentItem->layer() ) );
 
  519     setWidget( layerProp );
 
  530     mDataDefineRestorer.reset();
 
  532     currentItem->symbol()->setLayer( mVectorLayer );
 
  536     symbolsList->setContext( mContext );
 
  538     setWidget( symbolsList );
 
  546   SymbolLayerItem *currentItem = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( layersTree->currentIndex() ) );
 
  547   if ( !currentItem || currentItem->isLayer() )
 
  551   if ( currentItem->parent() )
 
  555     SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( currentItem->parent() );
 
  556     parent->removeRow( 0 );
 
  558     layersTree->setCurrentIndex( parent->child( 0 )->index() );
 
  559     parent->updatePreview();
 
  565     const QModelIndex newIndex = layersTree->model()->index( 0, 0 );
 
  566     layersTree->setCurrentIndex( newIndex );
 
  573 void QgsSymbolSelectorWidget::setWidget( QWidget *widget )
 
  575   const int index = stackedWidget->addWidget( widget );
 
  576   stackedWidget->setCurrentIndex( index );
 
  577   if ( mPresentWidget )
 
  578     mPresentWidget->deleteLater();
 
  579   mPresentWidget = widget;
 
  582 void QgsSymbolSelectorWidget::updateLockButton()
 
  587   btnLock->setChecked( layer->
isLocked() );
 
  592   const QModelIndex idx = layersTree->currentIndex();
 
  593   if ( !idx.isValid() )
 
  597   SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( idx ) );
 
  598   if ( item->isLayer() )
 
  600     insertIdx = item->row();
 
  601     item = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  604   QgsSymbol *parentSymbol = item->symbol();
 
  618   if ( insertIdx == -1 )
 
  625     static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedSize( ddSize );
 
  627     static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedAngle( ddAngle );
 
  629     static_cast<QgsLineSymbol *
>( parentSymbol )->setDataDefinedWidth( ddWidth );
 
  631   SymbolLayerItem *newLayerItem = 
new SymbolLayerItem( newLayer, parentSymbol->
type() );
 
  632   item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
 
  633   item->updatePreview();
 
  635   layersTree->setCurrentIndex( mSymbolLayersModel->indexFromItem( newLayerItem ) );
 
  642   SymbolLayerItem *item = currentLayerItem();
 
  643   const int row = item->row();
 
  644   SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  646   const int layerIdx = parent->rowCount() - row - 1; 
 
  647   QgsSymbol *parentSymbol = parent->symbol();
 
  650   parent->removeRow( row );
 
  651   parent->updatePreview();
 
  653   const QModelIndex newIdx = parent->child( 0 )->index();
 
  654   layersTree->setCurrentIndex( newIdx );
 
  664   moveLayerByOffset( + 1 );
 
  669   moveLayerByOffset( -1 );
 
  672 void QgsSymbolSelectorWidget::moveLayerByOffset( 
int offset )
 
  674   SymbolLayerItem *item = currentLayerItem();
 
  677   const int row = item->row();
 
  679   SymbolLayerItem *parent = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  680   QgsSymbol *parentSymbol = parent->symbol();
 
  682   const int layerIdx = parent->rowCount() - row - 1;
 
  687   QList<QStandardItem *> rowItems = parent->takeRow( row );
 
  688   parent->insertRows( row + offset, rowItems );
 
  689   parent->updatePreview();
 
  691   const QModelIndex newIdx = rowItems[ 0 ]->index();
 
  692   layersTree->setCurrentIndex( newIdx );
 
  703   layer->
setLocked( btnLock->isChecked() );
 
  709   const QModelIndex idx = layersTree->currentIndex();
 
  710   if ( !idx.isValid() )
 
  713   SymbolLayerItem *item = 
static_cast<SymbolLayerItem *
>( mSymbolLayersModel->itemFromIndex( idx ) );
 
  714   if ( !item->isLayer() )
 
  719   const int insertIdx = item->row();
 
  720   item = 
static_cast<SymbolLayerItem *
>( item->parent() );
 
  722   QgsSymbol *parentSymbol = item->symbol();
 
  725   if ( insertIdx == -1 )
 
  730   SymbolLayerItem *newLayerItem = 
new SymbolLayerItem( newLayer, parentSymbol->
type() );
 
  731   item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
 
  735     layersTree->setExpanded( newLayerItem->index(), 
true );
 
  737   item->updatePreview();
 
  739   layersTree->setCurrentIndex( mSymbolLayersModel->indexFromItem( newLayerItem ) );
 
  746   SymbolLayerItem *item = currentLayerItem();
 
  751     item->removeRow( 0 );
 
  761     layersTree->setExpanded( item->index(), 
true );
 
  765   const int layerIdx = item->parent()->rowCount() - item->row() - 1;
 
  768   item->updatePreview();
 
  777   setLayout( 
new QVBoxLayout() );
 
  780   mButtonBox = 
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
 
  782   connect( mButtonBox, &QDialogButtonBox::accepted, 
this, &QDialog::accept );
 
  783   connect( mButtonBox, &QDialogButtonBox::rejected, 
this, &QDialog::reject );
 
  784   connect( mButtonBox, &QDialogButtonBox::helpRequested, 
this, &QgsSymbolSelectorDialog::showHelp );
 
  786   layout()->addWidget( mSelectorWidget );
 
  787   layout()->addWidget( mButtonBox );
 
  791   mSelectorWidget->setMinimumSize( 460, 560 );
 
  792   setObjectName( QStringLiteral( 
"SymbolSelectorDialog" ) );
 
  799     layout()->setContentsMargins( 0, 0, 0, 0 );
 
  803     setWindowTitle( tr( 
"Symbol Selector" ) );
 
  825   return mSelectorWidget->
symbol();
 
  831   if ( !isWindow() && e->key() == Qt::Key_Escape )
 
  837     QDialog::keyPressEvent( e );
 
  841 void QgsSymbolSelectorDialog::reloadSymbol()
 
  843   mSelectorWidget->reloadSymbol();
 
  851 void QgsSymbolSelectorDialog::updateUi()
 
  853   mSelectorWidget->updateUi();
 
  856 void QgsSymbolSelectorDialog::updateLockButton()
 
  858   mSelectorWidget->updateLockButton();
 
  861 SymbolLayerItem *QgsSymbolSelectorDialog::currentLayerItem()
 
  863   return mSelectorWidget->currentLayerItem();
 
  868   return mSelectorWidget->currentLayer();
 
  871 void QgsSymbolSelectorDialog::moveLayerByOffset( 
int offset )
 
  873   mSelectorWidget->moveLayerByOffset( offset );
 
  876 void QgsSymbolSelectorDialog::setWidget( QWidget *widget )
 
  878   mSelectorWidget->setWidget( widget );
 
  941 void QgsSymbolSelectorDialog::showHelp()
 
  946 void QgsSymbolSelectorWidget::projectDataChanged()
 
  948   mBlockModified = 
true;
 
  951   mBlockModified = 
false;
 
  954 void QgsSymbolSelectorWidget::layersAboutToBeRemoved( 
const QList<QgsMapLayer *> &layers )
 
  956   if ( mVectorLayer && layers.contains( mVectorLayer ) )