QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgssymbolbutton.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssymbolbutton.h
3  -----------------
4  Date : July 2017
5  Copyright : (C) 2017 by Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgssymbolbutton.h"
17 #include "qgspanelwidget.h"
18 #include "qgsexpressioncontext.h"
20 #include "qgsvectorlayer.h"
22 #include "qgsstyle.h"
23 #include "qgscolorwidgets.h"
24 #include "qgscolorschemeregistry.h"
25 #include "qgscolorswatchgrid.h"
26 #include "qgssymbollayerutils.h"
27 #include "qgsapplication.h"
28 #include "qgsguiutils.h"
30 #include "qgsgui.h"
31 #include "qgscolordialog.h"
32 #include "qgsfillsymbol.h"
33 #include "qgslinesymbol.h"
34 #include "qgsmarkersymbol.h"
35 
36 #include <QMenu>
37 #include <QClipboard>
38 #include <QDrag>
39 #include <QBuffer>
40 
41 QgsSymbolButton::QgsSymbolButton( QWidget *parent, const QString &dialogTitle )
42  : QToolButton( parent )
43  , mDialogTitle( dialogTitle.isEmpty() ? tr( "Symbol Settings" ) : dialogTitle )
44 {
45  mSymbol.reset( QgsFillSymbol::createSimple( QVariantMap() ) );
46 
47  setAcceptDrops( true );
48  connect( this, &QAbstractButton::clicked, this, &QgsSymbolButton::showSettingsDialog );
49 
50  //setup dropdown menu
51  mMenu = new QMenu( this );
52  connect( mMenu, &QMenu::aboutToShow, this, &QgsSymbolButton::prepareMenu );
53  setMenu( mMenu );
54  setPopupMode( QToolButton::MenuButtonPopup );
55 
56  //make sure height of button looks good under different platforms
57  const QSize size = QToolButton::minimumSizeHint();
58  const int fontHeight = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.4 );
59  mSizeHint = QSize( size.width(), std::max( size.height(), fontHeight ) );
60 }
61 
63 
65 {
66 
67  return mSizeHint;
68 }
69 
71 {
72  return mSizeHint;
73 }
74 
76 {
77  if ( type != mType )
78  {
79  switch ( type )
80  {
82  mSymbol.reset( QgsMarkerSymbol::createSimple( QVariantMap() ) );
83  break;
84 
86  mSymbol.reset( QgsLineSymbol::createSimple( QVariantMap() ) );
87  break;
88 
90  mSymbol.reset( QgsFillSymbol::createSimple( QVariantMap() ) );
91  break;
92 
94  break;
95  }
96  }
97  updatePreview();
98  mType = type;
99 }
100 
101 void QgsSymbolButton::showSettingsDialog()
102 {
103  QgsExpressionContext context;
104  if ( mExpressionContextGenerator )
105  context = mExpressionContextGenerator->createExpressionContext();
106  else
107  {
109  }
110 
111  QgsSymbol *newSymbol = nullptr;
112  if ( mSymbol )
113  {
114  newSymbol = mSymbol->clone();
115  }
116  else
117  {
118  switch ( mType )
119  {
122  break;
125  break;
128  break;
130  break;
131  }
132  }
133 
134  QgsSymbolWidgetContext symbolContext;
135  symbolContext.setExpressionContext( &context );
136  symbolContext.setMapCanvas( mMapCanvas );
137  symbolContext.setMessageBar( mMessageBar );
138 
140  if ( panel && panel->dockMode() )
141  {
142  QgsSymbolSelectorWidget *d = new QgsSymbolSelectorWidget( newSymbol, QgsStyle::defaultStyle(), mLayer, panel );
143  d->setPanelTitle( mDialogTitle );
144  d->setContext( symbolContext );
145  connect( d, &QgsPanelWidget::widgetChanged, this, &QgsSymbolButton::updateSymbolFromWidget );
146  connect( d, &QgsPanelWidget::panelAccepted, this, &QgsSymbolButton::cleanUpSymbolSelector );
147  panel->openPanel( d );
148  }
149  else
150  {
151  QgsSymbolSelectorDialog dialog( newSymbol, QgsStyle::defaultStyle(), mLayer, this );
152  dialog.setWindowTitle( mDialogTitle );
153  dialog.setContext( symbolContext );
154  if ( dialog.exec() )
155  {
156  setSymbol( newSymbol );
157  }
158  else
159  {
160  delete newSymbol;
161  }
162 
163  // reactivate button's window
164  activateWindow();
165  }
166 }
167 
168 void QgsSymbolButton::updateSymbolFromWidget()
169 {
170  if ( QgsSymbolSelectorWidget *w = qobject_cast<QgsSymbolSelectorWidget *>( sender() ) )
171  setSymbol( w->symbol()->clone() );
172 }
173 
174 void QgsSymbolButton::cleanUpSymbolSelector( QgsPanelWidget *container )
175 {
176  QgsSymbolSelectorWidget *w = qobject_cast<QgsSymbolSelectorWidget *>( container );
177  if ( !w )
178  return;
179 
180  delete w->symbol();
181 }
182 
184 {
185  return mMapCanvas;
186 }
187 
189 {
190  mMapCanvas = mapCanvas;
191 }
192 
194 {
195  mMessageBar = bar;
196 }
197 
199 {
200  return mMessageBar;
201 }
202 
204 {
205  return mLayer;
206 }
207 
209 {
210  mLayer = layer;
211 }
212 
214 {
215  mExpressionContextGenerator = generator;
216 }
217 
219 {
220  mSymbol.reset( symbol );
221  updatePreview();
222  emit changed();
223 }
224 
225 void QgsSymbolButton::setColor( const QColor &color )
226 {
227  if ( !mSymbol )
228  return;
229 
230  QColor opaque = color;
231  opaque.setAlphaF( 1.0 );
232 
233  if ( opaque == mSymbol->color() )
234  return;
235 
236  mSymbol->setColor( opaque );
237  updatePreview();
238  emit changed();
239 }
240 
242 {
243  QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::symbolToMimeData( mSymbol.get() ) );
244 }
245 
247 {
248  std::unique_ptr< QgsSymbol > symbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
249  if ( symbol && symbol->type() == mType )
250  setSymbol( symbol.release() );
251 }
252 
254 {
255  QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mSymbol->color() ) );
256 }
257 
259 {
260  QColor clipColor;
261  bool hasAlpha = false;
262  if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
263  {
264  //paste color
265  setColor( clipColor );
267  }
268 }
269 
270 void QgsSymbolButton::mousePressEvent( QMouseEvent *e )
271 {
272  if ( mPickingColor )
273  {
274  //don't show dialog if in color picker mode
275  e->accept();
276  return;
277  }
278 
279  if ( e->button() == Qt::RightButton )
280  {
281  QToolButton::showMenu();
282  return;
283  }
284  else if ( e->button() == Qt::LeftButton )
285  {
286  mDragStartPosition = e->pos();
287  }
288  QToolButton::mousePressEvent( e );
289 }
290 
291 void QgsSymbolButton::mouseMoveEvent( QMouseEvent *e )
292 {
293  if ( mPickingColor )
294  {
295  updatePreview( QgsGui::sampleColor( e->globalPos() ) );
296  e->accept();
297  return;
298  }
299 
300  //handle dragging colors/symbols from button
301 
302  if ( !( e->buttons() & Qt::LeftButton ) )
303  {
304  //left button not depressed, so not a drag
305  QToolButton::mouseMoveEvent( e );
306  return;
307  }
308 
309  if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
310  {
311  //mouse not moved, so not a drag
312  QToolButton::mouseMoveEvent( e );
313  return;
314  }
315 
316  //user is dragging
317  QDrag *drag = new QDrag( this );
318  drag->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mSymbol->color() ) );
319  drag->setPixmap( QgsColorWidget::createDragIcon( mSymbol->color() ) );
320  drag->exec( Qt::CopyAction );
321  setDown( false );
322 }
323 
325 {
326  if ( mPickingColor )
327  {
328  //end color picking operation by sampling the color under cursor
329  stopPicking( e->globalPos() );
330  e->accept();
331  return;
332  }
333 
334  QToolButton::mouseReleaseEvent( e );
335 }
336 
337 void QgsSymbolButton::keyPressEvent( QKeyEvent *e )
338 {
339  if ( !mPickingColor )
340  {
341  //if not picking a color, use default tool button behavior
342  QToolButton::keyPressEvent( e );
343  return;
344  }
345 
346  //cancel picking, sampling the color if space was pressed
347  stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
348 }
349 
350 void QgsSymbolButton::dragEnterEvent( QDragEnterEvent *e )
351 {
352  //is dragged data valid color data?
353  QColor mimeColor;
354  bool hasAlpha = false;
355 
356  if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
357  {
358  //if so, we accept the drag, and temporarily change the button's color
359  //to match the dragged color. This gives immediate feedback to the user
360  //that colors can be dropped here
361  e->acceptProposedAction();
362  updatePreview( mimeColor );
363  }
364 }
365 
366 void QgsSymbolButton::dragLeaveEvent( QDragLeaveEvent *e )
367 {
368  Q_UNUSED( e )
369  //reset button color
370  updatePreview();
371 }
372 
373 void QgsSymbolButton::dropEvent( QDropEvent *e )
374 {
375  //is dropped data valid format data?
376  QColor mimeColor;
377  bool hasAlpha = false;
378  if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
379  {
380  //accept drop and set new color
381  e->acceptProposedAction();
382  mimeColor.setAlphaF( 1.0 );
383  mSymbol->setColor( mimeColor );
385  updatePreview();
386  emit changed();
387  }
388  updatePreview();
389 }
390 
391 void QgsSymbolButton::wheelEvent( QWheelEvent *event )
392 {
393  if ( isEnabled() && mSymbol )
394  {
395  bool symbolChanged = false;
396  const double increment = ( ( event->modifiers() & Qt::ControlModifier ) ? 0.1 : 1 ) *
397  ( event->angleDelta().y() > 0 ? 1 : -1 );
398  switch ( mSymbol->type() )
399  {
401  {
402  QgsMarkerSymbol *marker = qgis::down_cast<QgsMarkerSymbol *>( mSymbol.get() );
403  if ( marker )
404  {
405  const double size = std::max( 0.0, marker->size() + increment );
406  marker->setSize( size );
407  symbolChanged = true;
408  }
409  break;
410  }
411 
413  {
414  QgsLineSymbol *line = qgis::down_cast<QgsLineSymbol *>( mSymbol.get() );
415  if ( line )
416  {
417  const double width = std::max( 0.0, line->width() + increment );
418  line->setWidth( width );
419  symbolChanged = true;
420  }
421  break;
422  }
423 
426  break;
427  }
428 
429  if ( symbolChanged )
430  {
431  updatePreview();
432  emit changed();
433  }
434 
435  event->accept();
436  }
437  else
438  {
439  QToolButton::wheelEvent( event );
440  }
441 }
442 
443 void QgsSymbolButton::prepareMenu()
444 {
445  //we need to tear down and rebuild this menu every time it is shown. Otherwise the space allocated to any
446  //QgsColorSwatchGridAction is not recalculated by Qt and the swatch grid may not be the correct size
447  //for the number of colors shown in the grid. Note that we MUST refresh color swatch grids every time this
448  //menu is opened, otherwise color schemes like the recent color scheme grid are meaningless
449  mMenu->clear();
450 
451  QAction *configureAction = new QAction( tr( "Configure Symbol…" ), this );
452  mMenu->addAction( configureAction );
453  connect( configureAction, &QAction::triggered, this, &QgsSymbolButton::showSettingsDialog );
454 
455  QAction *copySymbolAction = new QAction( tr( "Copy Symbol" ), this );
456  copySymbolAction->setEnabled( !isNull() );
457  mMenu->addAction( copySymbolAction );
458  connect( copySymbolAction, &QAction::triggered, this, &QgsSymbolButton::copySymbol );
459 
460  QAction *pasteSymbolAction = new QAction( tr( "Paste Symbol" ), this );
461  //enable or disable paste action based on current clipboard contents. We always show the paste
462  //action, even if it's disabled, to give hint to the user that pasting symbols is possible
463  std::unique_ptr< QgsSymbol > tempSymbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
464  if ( tempSymbol && tempSymbol->type() == mType )
465  {
466  const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
467  pasteSymbolAction->setIcon( QgsSymbolLayerUtils::symbolPreviewIcon( tempSymbol.get(), QSize( iconSize, iconSize ), 1 ) );
468  }
469  else
470  {
471  pasteSymbolAction->setEnabled( false );
472  }
473  mMenu->addAction( pasteSymbolAction );
474  connect( pasteSymbolAction, &QAction::triggered, this, &QgsSymbolButton::pasteSymbol );
475 
476  if ( mShowNull )
477  {
478  QAction *nullAction = new QAction( tr( "Clear Current Symbol" ), this );
479  nullAction->setEnabled( !isNull() );
480  mMenu->addAction( nullAction );
481  connect( nullAction, &QAction::triggered, this, &QgsSymbolButton::setToNull );
482  }
483 
484  if ( mSymbol )
485  {
486  mMenu->addSeparator();
487 
488  QgsColorWheel *colorWheel = new QgsColorWheel( mMenu );
489  colorWheel->setColor( mSymbol->color() );
490  QgsColorWidgetAction *colorAction = new QgsColorWidgetAction( colorWheel, mMenu, mMenu );
491  colorAction->setDismissOnColorSelection( false );
492  connect( colorAction, &QgsColorWidgetAction::colorChanged, this, &QgsSymbolButton::setColor );
493  mMenu->addAction( colorAction );
494 
496  QColor alphaColor = mSymbol->color();
497  alphaColor.setAlphaF( mSymbol->opacity() );
498  alphaRamp->setColor( alphaColor );
499  QgsColorWidgetAction *alphaAction = new QgsColorWidgetAction( alphaRamp, mMenu, mMenu );
500  alphaAction->setDismissOnColorSelection( false );
501  connect( alphaAction, &QgsColorWidgetAction::colorChanged, this, [ = ]( const QColor & color )
502  {
503  const double opacity = color.alphaF();
504  mSymbol->setOpacity( opacity );
505  updatePreview();
506  emit changed();
507  } );
508  connect( colorAction, &QgsColorWidgetAction::colorChanged, alphaRamp, [alphaRamp]( const QColor & color ) { alphaRamp->setColor( color, false ); }
509  );
510  mMenu->addAction( alphaAction );
511 
512  //get schemes with ShowInColorButtonMenu flag set
513  QList< QgsColorScheme * > schemeList = QgsApplication::colorSchemeRegistry()->schemes( QgsColorScheme::ShowInColorButtonMenu );
514  QList< QgsColorScheme * >::iterator it = schemeList.begin();
515  for ( ; it != schemeList.end(); ++it )
516  {
517  QgsColorSwatchGridAction *colorAction = new QgsColorSwatchGridAction( *it, mMenu, QStringLiteral( "symbology" ), this );
518  colorAction->setBaseColor( mSymbol->color() );
519  mMenu->addAction( colorAction );
520  connect( colorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsSymbolButton::setColor );
521  connect( colorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsSymbolButton::addRecentColor );
522  }
523 
524  mMenu->addSeparator();
525 
526  QAction *copyColorAction = new QAction( tr( "Copy Color" ), this );
527  mMenu->addAction( copyColorAction );
528  connect( copyColorAction, &QAction::triggered, this, &QgsSymbolButton::copyColor );
529 
530  QAction *pasteColorAction = new QAction( tr( "Paste Color" ), this );
531  //enable or disable paste action based on current clipboard contents. We always show the paste
532  //action, even if it's disabled, to give hint to the user that pasting colors is possible
533  QColor clipColor;
534  bool hasAlpha = false;
535  if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
536  {
537  pasteColorAction->setIcon( createColorIcon( clipColor ) );
538  }
539  else
540  {
541  pasteColorAction->setEnabled( false );
542  }
543  mMenu->addAction( pasteColorAction );
544  connect( pasteColorAction, &QAction::triggered, this, &QgsSymbolButton::pasteColor );
545 
546  QAction *pickColorAction = new QAction( tr( "Pick Color" ), this );
547  mMenu->addAction( pickColorAction );
548  connect( pickColorAction, &QAction::triggered, this, &QgsSymbolButton::activatePicker );
549 
550  QAction *chooseColorAction = new QAction( tr( "Choose Color…" ), this );
551  mMenu->addAction( chooseColorAction );
552  connect( chooseColorAction, &QAction::triggered, this, &QgsSymbolButton::showColorDialog );
553  }
554 }
555 
556 void QgsSymbolButton::addRecentColor( const QColor &color )
557 {
559 }
560 
561 void QgsSymbolButton::activatePicker()
562 {
563  //activate picker color
564  QApplication::setOverrideCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Sampler ) );
565  grabMouse();
566  grabKeyboard();
567  mPickingColor = true;
568  setMouseTracking( true );
569 }
570 
571 
573 {
574  if ( e->type() == QEvent::EnabledChange )
575  {
576  updatePreview();
577  }
578  QToolButton::changeEvent( e );
579 }
580 
581 void QgsSymbolButton::showEvent( QShowEvent *e )
582 {
583  updatePreview();
584  QToolButton::showEvent( e );
585 }
586 
587 void QgsSymbolButton::resizeEvent( QResizeEvent *event )
588 {
589  QToolButton::resizeEvent( event );
590  //recalculate icon size and redraw icon
591  mIconSize = QSize();
592  updatePreview();
593 }
594 
595 void QgsSymbolButton::updatePreview( const QColor &color, QgsSymbol *tempSymbol )
596 {
597  QSize currentIconSize;
598  //icon size is button size with a small margin
599  if ( menu() )
600  {
601  if ( !mIconSize.isValid() )
602  {
603  //calculate size of push button part of widget (ie, without the menu dropdown button part)
604  QStyleOptionToolButton opt;
605  initStyleOption( &opt );
606  const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
607  this );
608  //make sure height of icon looks good under different platforms
609 #ifdef Q_OS_WIN
610  mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
611 #else
612  mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
613 #endif
614  }
615  currentIconSize = mIconSize;
616  }
617  else
618  {
619  //no menu
620 #ifdef Q_OS_WIN
621  currentIconSize = QSize( width() - 10, height() - 6 );
622 #else
623  currentIconSize = QSize( width() - 10, height() - 12 );
624 #endif
625  }
626 
627  if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
628  {
629  return;
630  }
631 
632  std::unique_ptr< QgsSymbol > previewSymbol;
633 
634  if ( tempSymbol )
635  {
636  previewSymbol.reset( tempSymbol->clone() );
637  }
638  else if ( mSymbol )
639  {
640  previewSymbol.reset( mSymbol->clone() );
641  }
642  else
643  {
644  setIconSize( currentIconSize );
645  setIcon( QIcon() );
646  setToolTip( QString( ) );
647  return;
648  }
649 
650  if ( color.isValid() )
651  previewSymbol->setColor( color );
652 
653  //create an icon pixmap
654  const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize );
655  setIconSize( currentIconSize );
656  setIcon( icon );
657 
658  // set tooltip
659  // create very large preview image
660  const int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 23 );
661  const int height = static_cast< int >( width / 1.61803398875 ); // golden ratio
662 
663  const QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20 );
664  QByteArray data;
665  QBuffer buffer( &data );
666  pm.save( &buffer, "PNG", 100 );
667  setToolTip( QStringLiteral( "<img src='data:image/png;base64, %3'>" ).arg( QString( data.toBase64() ) ) );
668 }
669 
670 bool QgsSymbolButton::colorFromMimeData( const QMimeData *mimeData, QColor &resultColor, bool &hasAlpha )
671 {
672  hasAlpha = false;
673  const QColor mimeColor = QgsSymbolLayerUtils::colorFromMimeData( mimeData, hasAlpha );
674 
675  if ( mimeColor.isValid() )
676  {
677  resultColor = mimeColor;
678  return true;
679  }
680 
681  //could not get color from mime data
682  return false;
683 }
684 
685 QPixmap QgsSymbolButton::createColorIcon( const QColor &color ) const
686 {
687  //create an icon pixmap
688  const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
689  QPixmap pixmap( iconSize, iconSize );
690  pixmap.fill( Qt::transparent );
691 
692  QPainter p;
693  p.begin( &pixmap );
694 
695  //draw color over pattern
696  p.setBrush( QBrush( color ) );
697 
698  //draw border
699  p.setPen( QColor( 197, 197, 197 ) );
700  p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
701  p.end();
702  return pixmap;
703 }
704 
705 void QgsSymbolButton::stopPicking( QPoint eventPos, bool samplingColor )
706 {
707  //release mouse and keyboard, and reset cursor
708  releaseMouse();
709  releaseKeyboard();
710  QgsApplication::restoreOverrideCursor();
711  setMouseTracking( false );
712  mPickingColor = false;
713 
714  if ( !samplingColor )
715  {
716  //not sampling color, restore old icon
717  updatePreview();
718  return;
719  }
720 
721  const QColor newColor = QgsGui::sampleColor( eventPos );
722  setColor( newColor );
723  addRecentColor( newColor );
724 }
725 
726 void QgsSymbolButton::showColorDialog()
727 {
728  if ( !mSymbol )
729  return;
730 
732  if ( panel && panel->dockMode() )
733  {
734  const QColor currentColor = mSymbol->color();
736  colorWidget->setPanelTitle( tr( "Symbol Color" ) );
737  colorWidget->setAllowOpacity( true );
738 
739  if ( currentColor.isValid() )
740  {
741  colorWidget->setPreviousColor( currentColor );
742  }
743 
744  connect( colorWidget, &QgsCompoundColorWidget::currentColorChanged, this, [ = ]( const QColor & newColor )
745  {
746  if ( newColor.isValid() )
747  {
748  setColor( newColor );
749  }
750  } );
751  panel->openPanel( colorWidget );
752  return;
753  }
754 
755  QgsColorDialog dialog( this, Qt::WindowFlags(), mSymbol->color() );
756  dialog.setTitle( tr( "Symbol Color" ) );
757  dialog.setAllowOpacity( true );
758 
759  if ( dialog.exec() && dialog.color().isValid() )
760  {
761  setColor( dialog.color() );
762  }
763 
764  // reactivate button's window
765  activateWindow();
766 }
767 
768 void QgsSymbolButton::setDialogTitle( const QString &title )
769 {
770  mDialogTitle = title;
771 }
772 
773 QString QgsSymbolButton::dialogTitle() const
774 {
775  return mDialogTitle;
776 }
777 
779 {
780  return mSymbol.get();
781 }
782 
783 void QgsSymbolButton::setShowNull( bool showNull )
784 {
785  mShowNull = showNull;
786 }
787 
789 {
790  return mShowNull;
791 }
792 
794 {
795  return !mSymbol;
796 }
797 
799 {
800  setSymbol( nullptr );
801 }
QgsSymbolSelectorDialog
Definition: qgssymbolselectordialog.h:276
QgsSymbolButton::setDialogTitle
void setDialogTitle(const QString &title)
Sets the title for the symbol settings dialog window.
Definition: qgssymbolbutton.cpp:768
QgsCompoundColorWidget::setAllowOpacity
void setAllowOpacity(bool allowOpacity)
Sets whether opacity modification (transparency) is permitted for the color dialog.
Definition: qgscompoundcolorwidget.cpp:303
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:406
QgsSymbolButton::wheelEvent
void wheelEvent(QWheelEvent *event) override
Definition: qgssymbolbutton.cpp:391
qgsexpressioncontextutils.h
QgsExpressionContext::appendScopes
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
Definition: qgsexpressioncontext.cpp:499
QgsSymbolButton::changed
void changed()
Emitted when the symbol's settings are changed.
QgsSymbolLayerUtils::colorToMimeData
static QMimeData * colorToMimeData(const QColor &color)
Creates mime data from a color.
Definition: qgssymbollayerutils.cpp:3497
QgsColorRampWidget::Horizontal
@ Horizontal
Horizontal ramp.
Definition: qgscolorwidgets.h:495
Qgis::SymbolType::Fill
@ Fill
Fill symbol.
QgsGui::sampleColor
static QColor sampleColor(QPoint point)
Samples the color on screen at the specified global point (pixel).
Definition: qgsgui.cpp:237
Qgis::SymbolType::Line
@ Line
Line symbol.
QgsSymbol::defaultSymbol
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Definition: qgssymbol.cpp:673
QgsMarkerSymbol::size
double size() const
Returns the estimated size for the whole symbol, which is the maximum size of all marker symbol layer...
Definition: qgsmarkersymbol.cpp:197
QgsPanelWidget::findParentPanel
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
Definition: qgspanelwidget.cpp:54
QgsColorSwatchGridAction
A color swatch grid which can be embedded into a menu.
Definition: qgscolorswatchgrid.h:189
QgsSymbolLayerUtils::symbolFromMimeData
static QgsSymbol * symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
Definition: qgssymbollayerutils.cpp:3305
qgscolorswatchgrid.h
qgsgui.h
QgsColorSwatchGridAction::setBaseColor
void setBaseColor(const QColor &baseColor)
Sets the base color for the color grid.
Definition: qgscolorswatchgrid.cpp:413
QgsLineSymbol::width
double width() const
Returns the estimated width for the whole symbol, which is the maximum width of all marker symbol lay...
Definition: qgslinesymbol.cpp:96
QgsApplication::getThemeCursor
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
Definition: qgsapplication.cpp:762
QgsSymbolButton::isNull
bool isNull() const
Returns true if the current symbol is null.
Definition: qgssymbolbutton.cpp:793
QgsSymbolSelectorWidget::symbol
QgsSymbol * symbol()
Returns the symbol that is currently active in the widget.
Definition: qgssymbolselectordialog.h:129
qgssymbollayerutils.h
QgsSymbolWidgetContext
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
Definition: qgssymbolwidgetcontext.h:35
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
QgsPanelWidget::openPanel
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
Definition: qgspanelwidget.cpp:84
QgsSymbolButton::resizeEvent
void resizeEvent(QResizeEvent *event) override
Definition: qgssymbolbutton.cpp:587
QgsApplication::colorSchemeRegistry
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes.
Definition: qgsapplication.cpp:2310
QgsExpressionContextUtils::globalProjectLayerScopes
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Definition: qgsexpressioncontextutils.cpp:377
QgsSymbolButton::changeEvent
void changeEvent(QEvent *e) override
Definition: qgssymbolbutton.cpp:572
QgsColorDialog
A custom QGIS dialog for selecting a color. Has many improvements over the standard Qt color picker d...
Definition: qgscolordialog.h:36
QgsSymbolButton::copySymbol
void copySymbol()
Copies the current symbol to the clipboard.
Definition: qgssymbolbutton.cpp:241
qgscolorwidgets.h
QgsColorRampWidget
A color ramp widget. This widget consists of an interactive box filled with a color which varies alon...
Definition: qgscolorwidgets.h:484
QgsSymbolSelectorWidget
Symbol selector widget that can be used to select and build a symbol.
Definition: qgssymbolselectordialog.h:87
QgsSymbol
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:92
QgsSymbolSelectorWidget::setContext
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
Definition: qgssymbolselectordialog.cpp:355
QgsSymbolButton::mouseMoveEvent
void mouseMoveEvent(QMouseEvent *e) override
Definition: qgssymbolbutton.cpp:291
QgsSymbolButton::layer
QgsVectorLayer * layer() const
Returns the layer associated with the widget.
Definition: qgssymbolbutton.cpp:203
QgsSymbolLayerUtils::colorFromMimeData
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
Definition: qgssymbollayerutils.cpp:3507
QgsPanelWidget::dockMode
bool dockMode()
Returns the dock mode state.
Definition: qgspanelwidget.h:93
QgsCompoundColorWidget::setPreviousColor
void setPreviousColor(const QColor &color)
Sets the color to show in an optional "previous color" section.
Definition: qgscompoundcolorwidget.cpp:732
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsLineSymbol::createSimple
static QgsLineSymbol * createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
Definition: qgslinesymbol.cpp:22
QgsGuiUtils::iconSize
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
Definition: qgsguiutils.cpp:264
QgsSymbolButton::setColor
void setColor(const QColor &color)
Sets the current color for the symbol.
Definition: qgssymbolbutton.cpp:225
QgsSymbolButton::setToNull
void setToNull()
Sets symbol to to null.
Definition: qgssymbolbutton.cpp:798
QgsSymbolWidgetContext::setMapCanvas
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
Definition: qgssymbolwidgetcontext.cpp:49
QgsColorScheme::ShowInColorButtonMenu
@ ShowInColorButtonMenu
Show scheme in color button drop-down menu.
Definition: qgscolorscheme.h:74
QgsStyle::defaultStyle
static QgsStyle * defaultStyle()
Returns default application-wide style.
Definition: qgsstyle.cpp:145
QgsSymbolButton::dragEnterEvent
void dragEnterEvent(QDragEnterEvent *e) override
Definition: qgssymbolbutton.cpp:350
QgsSymbolLayerUtils::symbolToMimeData
static QMimeData * symbolToMimeData(const QgsSymbol *symbol)
Creates new mime data from a symbol.
Definition: qgssymbollayerutils.cpp:3287
qgsapplication.h
QgsCompoundColorWidget
A custom QGIS widget for selecting a color, including options for selecting colors via hue wheel,...
Definition: qgscompoundcolorwidget.h:33
QgsCompoundColorWidget::LayoutVertical
@ LayoutVertical
Use a narrower, vertically stacked layout.
Definition: qgscompoundcolorwidget.h:44
QgsSymbolLayerUtils::symbolPreviewIcon
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr)
Returns an icon preview for a color ramp.
Definition: qgssymbollayerutils.cpp:871
QgsSymbolWidgetContext::setMessageBar
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
Definition: qgssymbolwidgetcontext.cpp:59
QgsCompoundColorWidget::currentColorChanged
void currentColorChanged(const QColor &color)
Emitted when the dialog's color changes.
qgsexpressioncontext.h
QgsColorWidget::setColor
virtual void setColor(const QColor &color, bool emitSignals=false)
Sets the color for the widget.
Definition: qgscolorwidgets.cpp:347
QgsSymbolButton::setSymbol
void setSymbol(QgsSymbol *symbol)
Sets the symbol for the button.
Definition: qgssymbolbutton.cpp:218
QgsPanelWidget
Base class for any widget that can be shown as a inline panel.
Definition: qgspanelwidget.h:29
QgsSymbolLayerUtils::symbolPreviewPixmap
static QPixmap symbolPreviewPixmap(const QgsSymbol *symbol, QSize size, int padding=0, QgsRenderContext *customContext=nullptr, bool selected=false, const QgsExpressionContext *expressionContext=nullptr, const QgsLegendPatchShape *shape=nullptr)
Returns a pixmap preview for a color ramp.
Definition: qgssymbollayerutils.cpp:876
QgsColorWidgetAction::setDismissOnColorSelection
void setDismissOnColorSelection(bool dismiss)
Sets whether the parent menu should be dismissed and closed when a color is selected from the action'...
Definition: qgscolorwidgets.h:240
QgsSymbolButton::setShowNull
void setShowNull(bool showNull)
Sets whether a set to null (clear) option is shown in the button's drop-down menu.
Definition: qgssymbolbutton.cpp:783
Qgis::SymbolType
SymbolType
Symbol types.
Definition: qgis.h:205
QgsSymbolButton::setMapCanvas
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas to associate with the widget.
Definition: qgssymbolbutton.cpp:188
QgsSymbolButton::minimumSizeHint
QSize minimumSizeHint() const override
Definition: qgssymbolbutton.cpp:64
QgsSymbol::type
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:152
QgsSymbolButton::pasteSymbol
void pasteSymbol()
Pastes a symbol from the clipboard.
Definition: qgssymbolbutton.cpp:246
QgsMarkerSymbol
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgsmarkersymbol.h:30
QgsPanelWidget::panelAccepted
void panelAccepted(QgsPanelWidget *panel)
Emitted when the panel is accepted by the user.
QgsSymbolButton::pasteColor
void pasteColor()
Pastes a color from the clipboard to the symbol.
Definition: qgssymbolbutton.cpp:258
QgsColorWheel
A color wheel widget. This widget consists of an outer ring which allows for hue selection,...
Definition: qgscolorwidgets.h:289
QgsColorWidget::Alpha
@ Alpha
Alpha component (opacity) of color.
Definition: qgscolorwidgets.h:57
QgsSymbolButton::showNull
bool showNull() const
Returns whether the set to null (clear) option is shown in the button's drop-down menu.
Definition: qgssymbolbutton.cpp:788
QgsMessageBar
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:60
QgsPanelWidget::widgetChanged
void widgetChanged()
Emitted when the widget state changes.
QgsLineSymbol
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:29
QgsColorWidgetAction
An action containing a color widget, which can be embedded into a menu.
Definition: qgscolorwidgets.h:213
QgsExpressionContextGenerator::createExpressionContext
virtual QgsExpressionContext createExpressionContext() const =0
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QgsColorWheel::setColor
void setColor(const QColor &color, bool emitSignals=false) override
Definition: qgscolorwidgets.cpp:483
Qgis::UI_SCALE_FACTOR
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition: qgis.h:2043
QgsSymbolButton::setSymbolType
void setSymbolType(Qgis::SymbolType type)
Sets the symbol type which the button requires.
Definition: qgssymbolbutton.cpp:75
QgsSymbolButton::setMessageBar
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
Definition: qgssymbolbutton.cpp:193
QgsSymbolButton::~QgsSymbolButton
~QgsSymbolButton()
QgsSymbolButton::sizeHint
QSize sizeHint() const override
Definition: qgssymbolbutton.cpp:70
QgsSymbolButton::showEvent
void showEvent(QShowEvent *e) override
Definition: qgssymbolbutton.cpp:581
QgsFillSymbol::createSimple
static QgsFillSymbol * createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
Definition: qgsfillsymbol.cpp:20
QgsPanelWidget::setPanelTitle
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
Definition: qgspanelwidget.h:44
qgssymbolselectordialog.h
qgsstyle.h
qgsexpressioncontextgenerator.h
qgsvectorlayer.h
qgscolordialog.h
Qgis::SymbolType::Hybrid
@ Hybrid
Hybrid symbol.
QgsSymbol::clone
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:143
QgsSymbolButton::mapCanvas
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
Definition: qgssymbolbutton.cpp:183
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:142
QgsSymbolButton::copyColor
void copyColor()
Copies the current symbol color to the clipboard.
Definition: qgssymbolbutton.cpp:253
QgsSymbolButton::dropEvent
void dropEvent(QDropEvent *e) override
Definition: qgssymbolbutton.cpp:373
QgsSymbolButton::setLayer
void setLayer(QgsVectorLayer *layer)
Sets a layer to associate with the widget.
Definition: qgssymbolbutton.cpp:208
QgsColorSchemeRegistry::schemes
QList< QgsColorScheme * > schemes() const
Returns all color schemes in the registry.
Definition: qgscolorschemeregistry.cpp:88
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsRecentColorScheme::addRecentColor
static void addRecentColor(const QColor &color)
Adds a color to the list of recent colors.
Definition: qgscolorscheme.cpp:68
qgsmarkersymbol.h
QgsColorSwatchGridAction::colorChanged
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget.
QgsSymbolButton::symbol
QgsSymbol * symbol()
Returns the current symbol defined by the button.
Definition: qgssymbolbutton.cpp:778
QgsLineSymbol::setWidth
void setWidth(double width) const
Sets the width for the whole line symbol.
Definition: qgslinesymbol.cpp:40
QgsMarkerSymbol::setSize
void setSize(double size) const
Sets the size for the whole symbol.
Definition: qgsmarkersymbol.cpp:153
qgscolorschemeregistry.h
QgsColorWidgetAction::colorChanged
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget.
QgsSymbolButton::registerExpressionContextGenerator
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
Definition: qgssymbolbutton.cpp:213
QgsSymbolButton::dialogTitle
QString dialogTitle
Definition: qgssymbolbutton.h:48
QgsSymbolWidgetContext::setExpressionContext
void setExpressionContext(QgsExpressionContext *context)
Sets the optional expression context used for the widget.
Definition: qgssymbolwidgetcontext.cpp:69
QgsSymbolButton::keyPressEvent
void keyPressEvent(QKeyEvent *e) override
Definition: qgssymbolbutton.cpp:337
qgsguiutils.h
QgsSymbolButton::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *e) override
Definition: qgssymbolbutton.cpp:324
QgsGuiUtils::scaleIconSize
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
Definition: qgsguiutils.cpp:259
qgspanelwidget.h
QgsSymbolButton::messageBar
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
Definition: qgssymbolbutton.cpp:198
QgsSymbolButton::QgsSymbolButton
QgsSymbolButton(QWidget *parent=nullptr, const QString &dialogTitle=QString())
Construct a new symbol button.
Definition: qgssymbolbutton.cpp:41
QgsSymbolButton::mousePressEvent
void mousePressEvent(QMouseEvent *e) override
Definition: qgssymbolbutton.cpp:270
QgsExpressionContextGenerator
Abstract interface for generating an expression context.
Definition: qgsexpressioncontextgenerator.h:36
QgsMarkerSymbol::createSimple
static QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
Definition: qgsmarkersymbol.cpp:22
qgsfillsymbol.h
qgssymbolbutton.h
Qgis::SymbolType::Marker
@ Marker
Marker symbol.
QgsSymbolButton::dragLeaveEvent
void dragLeaveEvent(QDragLeaveEvent *e) override
Definition: qgssymbolbutton.cpp:366
qgslinesymbol.h
QgsColorWidget::createDragIcon
static QPixmap createDragIcon(const QColor &color)
Create an icon for dragging colors.
Definition: qgscolorwidgets.cpp:61