QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgslayoutpicturewidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutpicturewidget.cpp
3  --------------------------
4  begin : October 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgslayoutpicturewidget.h"
19 #include "qgsapplication.h"
20 #include "qgslayoutitemmap.h"
21 #include "qgslayoutitempicture.h"
22 #include "qgslayout.h"
24 #include "qgssvgcache.h"
25 #include "qgssettings.h"
26 #include "qgssvgselectorwidget.h"
27 
28 #include <QDoubleValidator>
29 #include <QFileDialog>
30 #include <QFileInfo>
31 #include <QImageReader>
32 #include <QMessageBox>
33 #include <QPainter>
34 #include <QProgressDialog>
35 #include <QSvgRenderer>
36 
38  : QgsLayoutItemBaseWidget( nullptr, picture )
39  , mPicture( picture )
40 {
41  setupUi( this );
42 
43  mResizeModeComboBox->addItem( tr( "Zoom" ), QgsLayoutItemPicture::Zoom );
44  mResizeModeComboBox->addItem( tr( "Stretch" ), QgsLayoutItemPicture::Stretch );
45  mResizeModeComboBox->addItem( tr( "Clip" ), QgsLayoutItemPicture::Clip );
46  mResizeModeComboBox->addItem( tr( "Zoom and Resize Frame" ), QgsLayoutItemPicture::ZoomResizeFrame );
47  mResizeModeComboBox->addItem( tr( "Resize Frame to Image Size" ), QgsLayoutItemPicture::FrameToImageSize );
48 
49  mAnchorPointComboBox->addItem( tr( "Top Left" ), QgsLayoutItem::UpperLeft );
50  mAnchorPointComboBox->addItem( tr( "Top Center" ), QgsLayoutItem::UpperMiddle );
51  mAnchorPointComboBox->addItem( tr( "Top Right" ), QgsLayoutItem::UpperRight );
52  mAnchorPointComboBox->addItem( tr( "Middle Left" ), QgsLayoutItem::MiddleLeft );
53  mAnchorPointComboBox->addItem( tr( "Middle" ), QgsLayoutItem::Middle );
54  mAnchorPointComboBox->addItem( tr( "Middle Right" ), QgsLayoutItem::MiddleRight );
55  mAnchorPointComboBox->addItem( tr( "Bottom Left" ), QgsLayoutItem::LowerLeft );
56  mAnchorPointComboBox->addItem( tr( "Bottom Center" ), QgsLayoutItem::LowerMiddle );
57  mAnchorPointComboBox->addItem( tr( "Bottom Right" ), QgsLayoutItem::LowerRight );
58 
59  connect( mPictureRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPictureWidget::mPictureRotationSpinBox_valueChanged );
60  connect( mRotationFromComposerMapCheckBox, &QCheckBox::stateChanged, this, &QgsLayoutPictureWidget::mRotationFromComposerMapCheckBox_stateChanged );
61  connect( mResizeModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutPictureWidget::mResizeModeComboBox_currentIndexChanged );
62  connect( mAnchorPointComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutPictureWidget::mAnchorPointComboBox_currentIndexChanged );
63  connect( mFillColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutPictureWidget::mFillColorButton_colorChanged );
64  connect( mStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutPictureWidget::mStrokeColorButton_colorChanged );
65  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPictureWidget::mStrokeWidthSpinBox_valueChanged );
66  connect( mPictureRotationOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPictureWidget::mPictureRotationOffsetSpinBox_valueChanged );
67  connect( mNorthTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutPictureWidget::mNorthTypeComboBox_currentIndexChanged );
68  connect( mRadioSVG, &QRadioButton::toggled, this, &QgsLayoutPictureWidget::modeChanged );
69  connect( mRadioRaster, &QRadioButton::toggled, this, &QgsLayoutPictureWidget::modeChanged );
70  connect( mSvgSourceLineEdit, &QgsSvgSourceLineEdit::sourceChanged, this, &QgsLayoutPictureWidget::svgSourceChanged );
71  connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsLayoutPictureWidget::rasterSourceChanged );
72 
73  mSvgSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastComposerPictureDir" ) );
74 
75  setPanelTitle( tr( "Picture Properties" ) );
76 
77  mFillColorButton->setAllowOpacity( true );
78  mFillColorButton->setColorDialogTitle( tr( "Select Fill Color" ) );
79  mFillColorButton->setContext( QStringLiteral( "composer" ) );
80  mStrokeColorButton->setAllowOpacity( true );
81  mStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
82  mStrokeColorButton->setContext( QStringLiteral( "composer" ) );
83 
84  mFillColorDDBtn->registerLinkedWidget( mFillColorButton );
85  mStrokeColorDDBtn->registerLinkedWidget( mStrokeColorButton );
86 
87  mNorthTypeComboBox->blockSignals( true );
88  mNorthTypeComboBox->addItem( tr( "Grid North" ), QgsLayoutItemPicture::GridNorth );
89  mNorthTypeComboBox->addItem( tr( "True North" ), QgsLayoutItemPicture::TrueNorth );
90  mNorthTypeComboBox->blockSignals( false );
91  mPictureRotationOffsetSpinBox->setClearValue( 0.0 );
92  mPictureRotationSpinBox->setClearValue( 0.0 );
93 
94  viewGroups->setHeaderHidden( true );
95 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
96  mIconSize = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().width( 'X' ) * 4 ) ) );
97 #else
98  mIconSize = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 4 ) ) );
99 #endif
100  viewImages->setGridSize( QSize( mIconSize * 1.2, mIconSize * 1.2 ) );
101  populateList();
102 
103  connect( viewImages->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsLayoutPictureWidget::setSvgName );
104  connect( viewGroups->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsLayoutPictureWidget::populateIcons );
105 
106 
107  //add widget for general composer item properties
108  mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, picture );
109  mainLayout->addWidget( mItemPropertiesWidget );
110 
111  if ( mPicture->layout() )
112  {
113  mComposerMapComboBox->setCurrentLayout( mPicture->layout() );
114  mComposerMapComboBox->setItemType( QgsLayoutItemRegistry::LayoutMap );
115  connect( mComposerMapComboBox, &QgsLayoutItemComboBox::itemChanged, this, &QgsLayoutPictureWidget::mapChanged );
116  }
117 
118  setGuiElementValues();
119 
120  connect( mPicture, &QgsLayoutObject::changed, this, &QgsLayoutPictureWidget::setGuiElementValues );
121  connect( mPicture, &QgsLayoutItemPicture::pictureRotationChanged, this, &QgsLayoutPictureWidget::setPicRotationSpinValue );
122 
123  //connections for data defined buttons
124  mSourceDDBtn->registerEnabledWidget( mImageSourceLineEdit, false );
125  mSourceDDBtn->registerEnabledWidget( mSvgSourceLineEdit, false );
126 
131 
132  updatePictureTypeWidgets();
133 }
134 
136 {
137  if ( mItemPropertiesWidget )
138  mItemPropertiesWidget->setMasterLayout( masterLayout );
139 }
140 
141 void QgsLayoutPictureWidget::mPictureRotationSpinBox_valueChanged( double d )
142 {
143  if ( mPicture )
144  {
145  mPicture->beginCommand( tr( "Change Picture Rotation" ), QgsLayoutItem::UndoPictureRotation );
146  mPicture->setPictureRotation( d );
147  mPicture->endCommand();
148  }
149 }
150 
151 void QgsLayoutPictureWidget::mResizeModeComboBox_currentIndexChanged( int )
152 {
153  if ( !mPicture )
154  {
155  return;
156  }
157 
158  mPicture->beginCommand( tr( "Change Resize Mode" ) );
159  mPicture->setResizeMode( static_cast< QgsLayoutItemPicture::ResizeMode >( mResizeModeComboBox->currentData().toInt() ) );
160  mPicture->endCommand();
161 
162  //disable picture rotation for non-zoom modes
163  mRotationGroupBox->setEnabled( mPicture->resizeMode() == QgsLayoutItemPicture::Zoom ||
164  mPicture->resizeMode() == QgsLayoutItemPicture::ZoomResizeFrame );
165 
166  //disable anchor point control for certain zoom modes
167  if ( mPicture->resizeMode() == QgsLayoutItemPicture::Zoom ||
168  mPicture->resizeMode() == QgsLayoutItemPicture::Clip )
169  {
170  mAnchorPointComboBox->setEnabled( true );
171  }
172  else
173  {
174  mAnchorPointComboBox->setEnabled( false );
175  }
176 }
177 
178 void QgsLayoutPictureWidget::mAnchorPointComboBox_currentIndexChanged( int )
179 {
180  if ( !mPicture )
181  {
182  return;
183  }
184 
185  mPicture->beginCommand( tr( "Change Placement" ) );
186  mPicture->setPictureAnchor( static_cast< QgsLayoutItem::ReferencePoint >( mAnchorPointComboBox->currentData().toInt() ) );
187  mPicture->endCommand();
188 }
189 
191 {
193  return false;
194 
195  if ( mPicture )
196  {
197  disconnect( mPicture, &QgsLayoutObject::changed, this, &QgsLayoutPictureWidget::setGuiElementValues );
198  disconnect( mPicture, &QgsLayoutItemPicture::pictureRotationChanged, this, &QgsLayoutPictureWidget::setPicRotationSpinValue );
199  }
200 
201  mPicture = qobject_cast< QgsLayoutItemPicture * >( item );
202  mItemPropertiesWidget->setItem( mPicture );
203 
204  if ( mPicture )
205  {
206  connect( mPicture, &QgsLayoutObject::changed, this, &QgsLayoutPictureWidget::setGuiElementValues );
207  connect( mPicture, &QgsLayoutItemPicture::pictureRotationChanged, this, &QgsLayoutPictureWidget::setPicRotationSpinValue );
208  }
209 
210  setGuiElementValues();
211 
212  return true;
213 }
214 
215 void QgsLayoutPictureWidget::mRotationFromComposerMapCheckBox_stateChanged( int state )
216 {
217  if ( !mPicture )
218  {
219  return;
220  }
221 
222  mPicture->beginCommand( tr( "Toggle Rotation Sync" ) );
223  if ( state == Qt::Unchecked )
224  {
225  mPicture->setLinkedMap( nullptr );
226  mPictureRotationSpinBox->setEnabled( true );
227  mComposerMapComboBox->setEnabled( false );
228  mNorthTypeComboBox->setEnabled( false );
229  mPictureRotationOffsetSpinBox->setEnabled( false );
230  mPicture->setPictureRotation( mPictureRotationSpinBox->value() );
231  }
232  else
233  {
234  QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap * >( mComposerMapComboBox->currentItem() );
235  mPicture->setLinkedMap( map );
236  mPictureRotationSpinBox->setEnabled( false );
237  mNorthTypeComboBox->setEnabled( true );
238  mPictureRotationOffsetSpinBox->setEnabled( true );
239  mComposerMapComboBox->setEnabled( true );
240  }
241  mPicture->endCommand();
242 }
243 
244 void QgsLayoutPictureWidget::mapChanged( QgsLayoutItem *item )
245 {
246  if ( !mPicture )
247  {
248  return;
249  }
250 
251  //get composition
252  const QgsLayout *layout = mPicture->layout();
253  if ( !layout )
254  {
255  return;
256  }
257 
258  QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap *>( item );
259  if ( !map )
260  {
261  return;
262  }
263 
264  mPicture->beginCommand( tr( "Change Rotation Map" ) );
265  mPicture->setLinkedMap( map );
266  mPicture->update();
267  mPicture->endCommand();
268 }
269 
270 void QgsLayoutPictureWidget::setPicRotationSpinValue( double r )
271 {
272  mPictureRotationSpinBox->blockSignals( true );
273  mPictureRotationSpinBox->setValue( r );
274  mPictureRotationSpinBox->blockSignals( false );
275 }
276 
277 void QgsLayoutPictureWidget::setGuiElementValues()
278 {
279  //set initial gui values
280  if ( mPicture )
281  {
282  mPictureRotationSpinBox->blockSignals( true );
283  mComposerMapComboBox->blockSignals( true );
284  mRotationFromComposerMapCheckBox->blockSignals( true );
285  mNorthTypeComboBox->blockSignals( true );
286  mPictureRotationOffsetSpinBox->blockSignals( true );
287  mResizeModeComboBox->blockSignals( true );
288  mAnchorPointComboBox->blockSignals( true );
289  mFillColorButton->blockSignals( true );
290  mStrokeColorButton->blockSignals( true );
291  mStrokeWidthSpinBox->blockSignals( true );
292 
293  mPictureRotationSpinBox->setValue( mPicture->pictureRotation() );
294 
295  mComposerMapComboBox->setItem( mPicture->linkedMap() );
296 
297  if ( mPicture->linkedMap() )
298  {
299  mRotationFromComposerMapCheckBox->setCheckState( Qt::Checked );
300  mPictureRotationSpinBox->setEnabled( false );
301  mComposerMapComboBox->setEnabled( true );
302  mNorthTypeComboBox->setEnabled( true );
303  mPictureRotationOffsetSpinBox->setEnabled( true );
304  }
305  else
306  {
307  mRotationFromComposerMapCheckBox->setCheckState( Qt::Unchecked );
308  mPictureRotationSpinBox->setEnabled( true );
309  mComposerMapComboBox->setEnabled( false );
310  mNorthTypeComboBox->setEnabled( false );
311  mPictureRotationOffsetSpinBox->setEnabled( false );
312  }
313  mNorthTypeComboBox->setCurrentIndex( mNorthTypeComboBox->findData( mPicture->northMode() ) );
314  mPictureRotationOffsetSpinBox->setValue( mPicture->northOffset() );
315 
316  mResizeModeComboBox->setCurrentIndex( mResizeModeComboBox->findData( mPicture->resizeMode() ) );
317  //disable picture rotation for non-zoom modes
318  mRotationGroupBox->setEnabled( mPicture->resizeMode() == QgsLayoutItemPicture::Zoom ||
319  mPicture->resizeMode() == QgsLayoutItemPicture::ZoomResizeFrame );
320 
321  mAnchorPointComboBox->setCurrentIndex( mAnchorPointComboBox->findData( mPicture->pictureAnchor() ) );
322  //disable anchor point control for certain zoom modes
323  if ( mPicture->resizeMode() == QgsLayoutItemPicture::Zoom ||
324  mPicture->resizeMode() == QgsLayoutItemPicture::Clip )
325  {
326  mAnchorPointComboBox->setEnabled( true );
327  }
328  else
329  {
330  mAnchorPointComboBox->setEnabled( false );
331  }
332 
333  whileBlocking( mRadioSVG )->setChecked( mPicture->mode() == QgsLayoutItemPicture::FormatSVG );
334  whileBlocking( mRadioRaster )->setChecked( mPicture->mode() == QgsLayoutItemPicture::FormatRaster );
335  updatePictureTypeWidgets();
336 
337  if ( mRadioSVG->isChecked() )
338  {
339  whileBlocking( mSvgSourceLineEdit )->setSource( mPicture->picturePath() );
340 
341  mBlockSvgModelChanges++;
342  QAbstractItemModel *m = viewImages->model();
343  QItemSelectionModel *selModel = viewImages->selectionModel();
344  for ( int i = 0; i < m->rowCount(); i++ )
345  {
346  QModelIndex idx( m->index( i, 0 ) );
347  if ( m->data( idx ).toString() == mPicture->picturePath() )
348  {
349  selModel->select( idx, QItemSelectionModel::SelectCurrent );
350  selModel->setCurrentIndex( idx, QItemSelectionModel::SelectCurrent );
351  break;
352  }
353  }
354  mBlockSvgModelChanges--;
355  }
356  else if ( mRadioRaster->isChecked() )
357  {
358  whileBlocking( mImageSourceLineEdit )->setSource( mPicture->picturePath() );
359  }
360 
361  updateSvgParamGui( false );
362  mFillColorButton->setColor( mPicture->svgFillColor() );
363  mStrokeColorButton->setColor( mPicture->svgStrokeColor() );
364  mStrokeWidthSpinBox->setValue( mPicture->svgStrokeWidth() );
365 
366  mRotationFromComposerMapCheckBox->blockSignals( false );
367  mPictureRotationSpinBox->blockSignals( false );
368  mComposerMapComboBox->blockSignals( false );
369  mNorthTypeComboBox->blockSignals( false );
370  mPictureRotationOffsetSpinBox->blockSignals( false );
371  mResizeModeComboBox->blockSignals( false );
372  mAnchorPointComboBox->blockSignals( false );
373  mFillColorButton->blockSignals( false );
374  mStrokeColorButton->blockSignals( false );
375  mStrokeWidthSpinBox->blockSignals( false );
376 
378  }
379 }
380 
381 void QgsLayoutPictureWidget::updateSvgParamGui( bool resetValues )
382 {
383  if ( !mPicture )
384  return;
385 
386  QString picturePath = mPicture->picturePath();
387 
388  //activate gui for svg parameters only if supported by the svg file
389  bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
390  QColor defaultFill, defaultStroke;
391  double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
392  bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
393  QgsApplication::svgCache()->containsParams( picturePath, hasFillParam, hasDefaultFillColor, defaultFill,
394  hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
395  hasStrokeParam, hasDefaultStrokeColor, defaultStroke,
396  hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
397  hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
398 
399  if ( resetValues )
400  {
401  QColor fill = mFillColorButton->color();
402  double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
403  if ( hasDefaultFillColor )
404  {
405  fill = defaultFill;
406  }
407  fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
408  mFillColorButton->setColor( fill );
409  }
410  mFillColorButton->setEnabled( hasFillParam );
411  mFillColorButton->setAllowOpacity( hasFillOpacityParam );
412  if ( resetValues )
413  {
414  QColor stroke = mStrokeColorButton->color();
415  double newOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
416  if ( hasDefaultStrokeColor )
417  {
418  stroke = defaultStroke;
419  }
420  stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : newOpacity );
421  mStrokeColorButton->setColor( stroke );
422  }
423  mStrokeColorButton->setEnabled( hasStrokeParam );
424  mStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
425  if ( hasDefaultStrokeWidth && resetValues )
426  {
427  mStrokeWidthSpinBox->setValue( defaultStrokeWidth );
428  }
429  mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
430 }
431 
432 void QgsLayoutPictureWidget::mFillColorButton_colorChanged( const QColor &color )
433 {
434  mPicture->beginCommand( tr( "Change Picture Fill Color" ), QgsLayoutItem::UndoPictureFillColor );
435  mPicture->setSvgFillColor( color );
436  mPicture->endCommand();
437  mPicture->update();
438 }
439 
440 void QgsLayoutPictureWidget::mStrokeColorButton_colorChanged( const QColor &color )
441 {
442  mPicture->beginCommand( tr( "Change Picture Stroke Color" ), QgsLayoutItem::UndoPictureStrokeColor );
443  mPicture->setSvgStrokeColor( color );
444  mPicture->endCommand();
445  mPicture->update();
446 }
447 
448 void QgsLayoutPictureWidget::mStrokeWidthSpinBox_valueChanged( double d )
449 {
450  mPicture->beginCommand( tr( "Change Picture Stroke Width" ), QgsLayoutItem::UndoPictureStrokeWidth );
451  mPicture->setSvgStrokeWidth( d );
452  mPicture->endCommand();
453  mPicture->update();
454 }
455 
456 void QgsLayoutPictureWidget::mPictureRotationOffsetSpinBox_valueChanged( double d )
457 {
458  mPicture->beginCommand( tr( "Change Picture North Offset" ), QgsLayoutItem::UndoPictureNorthOffset );
459  mPicture->setNorthOffset( d );
460  mPicture->endCommand();
461  mPicture->update();
462 }
463 
464 void QgsLayoutPictureWidget::mNorthTypeComboBox_currentIndexChanged( int index )
465 {
466  mPicture->beginCommand( tr( "Change Picture North Mode" ) );
467  mPicture->setNorthMode( static_cast< QgsLayoutItemPicture::NorthMode >( mNorthTypeComboBox->itemData( index ).toInt() ) );
468  mPicture->endCommand();
469  mPicture->update();
470 }
471 
472 void QgsLayoutPictureWidget::modeChanged()
473 {
475  if ( mPicture && mPicture->mode() != newFormat )
476  {
477  whileBlocking( mSvgSourceLineEdit )->setSource( QString() );
478  whileBlocking( mImageSourceLineEdit )->setSource( QString() );
479  mPicture->beginCommand( tr( "Change Picture Type" ) );
480  mPicture->setPicturePath( QString(), newFormat );
481  mPicture->endCommand();
482  }
483  updatePictureTypeWidgets();
484 }
485 
486 void QgsLayoutPictureWidget::updatePictureTypeWidgets()
487 {
488  mRasterFrame->setVisible( mRadioRaster->isChecked() );
489  mSVGFrame->setVisible( mRadioSVG->isChecked() );
490  mSVGParamsGroupBox->setVisible( mRadioSVG->isChecked() );
491 
492  // need to move the data defined button to the appropriate frame -- we can't have two buttons linked to the one property!
493  if ( mRadioSVG->isChecked() )
494  mSvgDDBtnFrame->layout()->addWidget( mSourceDDBtn );
495  else
496  mRasterDDBtnFrame->layout()->addWidget( mSourceDDBtn );
497 }
498 
499 void QgsLayoutPictureWidget::populateList()
500 {
501  QAbstractItemModel *oldModel = viewGroups->model();
503  viewGroups->setModel( g );
504  delete oldModel;
505 
506  // Set the tree expanded at the first level
507  int rows = g->rowCount( g->indexFromItem( g->invisibleRootItem() ) );
508  for ( int i = 0; i < rows; i++ )
509  {
510  viewGroups->setExpanded( g->indexFromItem( g->item( i ) ), true );
511  }
512 
513  // Initially load the icons in the List view without any grouping
514  oldModel = viewImages->model();
515  QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( viewImages, mIconSize );
516  viewImages->setModel( m );
517 
518  delete oldModel;
519 }
520 
521 void QgsLayoutPictureWidget::populateIcons( const QModelIndex &idx )
522 {
523  QString path = idx.data( Qt::UserRole + 1 ).toString();
524 
525  QAbstractItemModel *oldModel = viewImages->model();
526  QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( viewImages, path, mIconSize );
527  viewImages->setModel( m );
528  delete oldModel;
529 
530  connect( viewImages->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsLayoutPictureWidget::setSvgName );
531 }
532 
533 void QgsLayoutPictureWidget::setSvgName( const QModelIndex &idx )
534 {
535  if ( mBlockSvgModelChanges )
536  return;
537 
538  QString name = idx.data( Qt::UserRole ).toString();
539  whileBlocking( mSvgSourceLineEdit )->setSource( name );
540  svgSourceChanged( name );
541 }
542 
543 void QgsLayoutPictureWidget::svgSourceChanged( const QString &source )
544 {
545  if ( mPicture )
546  {
547  mPicture->beginCommand( tr( "Change Picture" ) );
548  mPicture->setPicturePath( source, QgsLayoutItemPicture::FormatSVG );
549  mPicture->update();
550  mPicture->endCommand();
551  updateSvgParamGui();
552  }
553 }
554 
555 void QgsLayoutPictureWidget::rasterSourceChanged( const QString &source )
556 {
557  if ( mPicture )
558  {
559  mPicture->beginCommand( tr( "Change Picture" ) );
560  mPicture->setPicturePath( source, QgsLayoutItemPicture::FormatRaster );
561  mPicture->update();
562  mPicture->endCommand();
563  }
564 }
565 
567 {
568  updateDataDefinedButton( mSourceDDBtn );
569  updateDataDefinedButton( mFillColorDDBtn );
570  updateDataDefinedButton( mStrokeColorDDBtn );
571  updateDataDefinedButton( mStrokeWidthDDBtn );
572 
573  //initial state of controls - disable related controls when dd buttons are active
574  mImageSourceLineEdit->setEnabled( !mSourceDDBtn->isActive() );
575  mSvgSourceLineEdit->setEnabled( !mSourceDDBtn->isActive() );
576 }
577 
QgsLayoutItemBaseWidget::updateDataDefinedButton
void updateDataDefinedButton(QgsPropertyOverrideButton *button)
Updates a previously registered data defined button to reflect the item's current properties.
Definition: qgslayoutitemwidget.cpp:212
QgsLayoutItemPicture::FrameToImageSize
@ FrameToImageSize
Sets size of frame to match original size of image without scaling.
Definition: qgslayoutitempicture.h:49
qgssvgcache.h
QgsLayoutItemPicture::pictureRotationChanged
void pictureRotationChanged(double newRotation)
Emitted on picture rotation change.
QgsLayoutPictureWidget::setNewItem
bool setNewItem(QgsLayoutItem *item) override
Attempts to update the widget to show the properties for the specified item.
Definition: qgslayoutpicturewidget.cpp:190
QgsLayoutItem::UndoPictureStrokeColor
@ UndoPictureStrokeColor
Picture stroke color.
Definition: qgslayoutitem.h:244
QgsLayoutItem::Middle
@ Middle
Center of item.
Definition: qgslayoutitem.h:207
QgsLayoutItem::MiddleRight
@ MiddleRight
Middle right of item.
Definition: qgslayoutitem.h:208
QgsLayoutItem::UndoPictureStrokeWidth
@ UndoPictureStrokeWidth
Picture stroke width.
Definition: qgslayoutitem.h:245
QgsLayoutItem::MiddleLeft
@ MiddleLeft
Middle left of item.
Definition: qgslayoutitem.h:206
QgsLayoutItemBaseWidget::registerDataDefinedButton
void registerDataDefinedButton(QgsPropertyOverrideButton *button, QgsLayoutObject::DataDefinedProperty property)
Registers a data defined button, setting up its initial value, connections and description.
Definition: qgslayoutitemwidget.cpp:207
QgsLayoutItemPicture::NorthMode
NorthMode
Method for syncing rotation to a map's North direction.
Definition: qgslayoutitempicture.h:64
QgsLayoutItemPicture::GridNorth
@ GridNorth
Align to grid north.
Definition: qgslayoutitempicture.h:65
QgsLayoutItem::UndoPictureNorthOffset
@ UndoPictureNorthOffset
Picture north offset.
Definition: qgslayoutitem.h:246
QgsLayoutPictureWidget::setMasterLayout
void setMasterLayout(QgsMasterLayoutInterface *masterLayout) override
Sets the master layout associated with the item.
Definition: qgslayoutpicturewidget.cpp:135
qgslayoutpicturewidget.h
QgsLayoutPictureWidget::populateDataDefinedButtons
void populateDataDefinedButtons()
Initializes data defined buttons to current atlas coverage layer.
Definition: qgslayoutpicturewidget.cpp:566
QgsLayoutObject::changed
void changed()
Emitted when the object's properties change.
QgsLayoutObject::PictureSvgStrokeColor
@ PictureSvgStrokeColor
SVG stroke color.
Definition: qgslayoutobject.h:188
QgsLayoutItem::ReferencePoint
ReferencePoint
Fixed position reference point.
Definition: qgslayoutitem.h:202
QgsLayoutItemPropertiesWidget
A widget for controlling the common properties of layout items (e.g.
Definition: qgslayoutitemwidget.h:219
QgsSvgCache::containsParams
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an svg file contains parameters for fill, stroke color, stroke width.
Definition: qgssvgcache.cpp:225
QgsLayoutObject::PictureSvgStrokeWidth
@ PictureSvgStrokeWidth
SVG stroke width.
Definition: qgslayoutobject.h:189
QgsColorButton::colorChanged
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
QgsLayoutItemPropertiesWidget::setMasterLayout
void setMasterLayout(QgsMasterLayoutInterface *masterLayout)
Sets the master layout associated with the item.
Definition: qgslayoutitemwidget.cpp:381
QgsLayoutItem::type
int type() const override
Returns a unique graphics item type identifier.
Definition: qgslayoutitem.cpp:124
qgsapplication.h
QgsLayoutItemPicture::Stretch
@ Stretch
Stretches image to fit frame, ignores aspect ratio.
Definition: qgslayoutitempicture.h:46
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:262
QgsLayoutItemPicture::ZoomResizeFrame
@ ZoomResizeFrame
Enlarges image to fit frame, then resizes frame to fit resultant image.
Definition: qgslayoutitempicture.h:48
QgsLayoutItemPicture::Format
Format
Format of source image.
Definition: qgslayoutitempicture.h:56
QgsLayoutItemPicture::Clip
@ Clip
Draws image at original size and clips any portion which falls outside frame.
Definition: qgslayoutitempicture.h:47
Qgis::UI_SCALE_FACTOR
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition: qgis.h:182
QgsLayoutItemPicture::ResizeMode
ResizeMode
Controls how pictures are scaled within the item's frame.
Definition: qgslayoutitempicture.h:44
QgsLayoutItem
Base class for graphical items within a QgsLayout.
Definition: qgslayoutitem.h:113
QgsSvgSelectorListModel
A model for displaying SVG files with a preview icon.
Definition: qgssvgselectorwidget.h:182
QgsLayoutPictureWidget::QgsLayoutPictureWidget
QgsLayoutPictureWidget(QgsLayoutItemPicture *picture)
constructor
Definition: qgslayoutpicturewidget.cpp:37
QgsLayoutItemPicture::FormatSVG
@ FormatSVG
SVG image.
Definition: qgslayoutitempicture.h:57
QgsPanelWidget::setPanelTitle
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
Definition: qgspanelwidget.h:44
qgslayout.h
QgsApplication::svgCache
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
Definition: qgsapplication.cpp:2178
QgsLayoutItemBaseWidget
A base class for property widgets for layout items.
Definition: qgslayoutitemwidget.h:123
QgsLayoutItem::LowerRight
@ LowerRight
Lower right corner of item.
Definition: qgslayoutitem.h:211
QgsLayoutItem::LowerLeft
@ LowerLeft
Lower left corner of item.
Definition: qgslayoutitem.h:209
QgsLayoutItemPicture
A layout item subclass that displays SVG files or raster format images (jpg, png, ....
Definition: qgslayoutitempicture.h:36
QgsLayoutItemMap
Layout graphical items for displaying a map.
Definition: qgslayoutitemmap.h:318
QgsLayoutItemPicture::Zoom
@ Zoom
Enlarges image to fit frame while maintaining aspect ratio of picture.
Definition: qgslayoutitempicture.h:45
QgsLayout
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:50
QgsLayoutItem::UndoPictureRotation
@ UndoPictureRotation
Picture rotation.
Definition: qgslayoutitem.h:242
QgsSvgSelectorGroupsModel
A model for displaying SVG search paths.
Definition: qgssvgselectorwidget.h:234
QgsLayoutItemRegistry::LayoutPicture
@ LayoutPicture
Picture item.
Definition: qgslayoutitemregistry.h:318
QgsSvgSourceLineEdit::sourceChanged
void sourceChanged(const QString &source)
Emitted whenever the SVG source is changed in the widget.
qgssettings.h
QgsLayoutItem::UpperRight
@ UpperRight
Upper right corner of item.
Definition: qgslayoutitem.h:205
QgsLayoutItemRegistry::LayoutMap
@ LayoutMap
Map item.
Definition: qgslayoutitemregistry.h:317
qgslayoutitempicture.h
QgsLayoutItemComboBox::itemChanged
void itemChanged(QgsLayoutItem *item)
Emitted whenever the currently selected item changes.
QgsLayoutItem::UpperMiddle
@ UpperMiddle
Upper center of item.
Definition: qgslayoutitem.h:204
QgsLayoutItemPicture::TrueNorth
@ TrueNorth
Align to true north.
Definition: qgslayoutitempicture.h:66
QgsMasterLayoutInterface
Interface for master layout type objects, such as print layouts and reports.
Definition: qgsmasterlayoutinterface.h:43
QgsLayoutItemPicture::FormatRaster
@ FormatRaster
Raster image.
Definition: qgslayoutitempicture.h:58
QgsLayoutItemPropertiesWidget::setItem
void setItem(QgsLayoutItem *item)
Sets the layout item.
Definition: qgslayoutitemwidget.cpp:362
qgssvgselectorwidget.h
QgsAbstractFileContentSourceLineEdit::sourceChanged
void sourceChanged(const QString &source)
Emitted whenever the file source is changed in the widget.
QgsLayoutItem::UpperLeft
@ UpperLeft
Upper left corner of item.
Definition: qgslayoutitem.h:203
QgsLayoutObject::PictureSvgBackgroundColor
@ PictureSvgBackgroundColor
SVG background color.
Definition: qgslayoutobject.h:187
QgsLayoutObject::PictureSource
@ PictureSource
Picture source url.
Definition: qgslayoutobject.h:186
qgslayoutitemmap.h
QgsLayoutItem::LowerMiddle
@ LowerMiddle
Lower center of item.
Definition: qgslayoutitem.h:210
qgsexpressionbuilderdialog.h
QgsLayoutItem::UndoPictureFillColor
@ UndoPictureFillColor
Picture fill color.
Definition: qgslayoutitem.h:243