QGIS API Documentation  3.21.0-Master (5b68dc587e)
qgslayoutattributetablewidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutattributetablewidget.cpp
3  ---------------------------------
4  begin : November 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 
19 #include "qgslayoutatlas.h"
20 #include "qgslayout.h"
21 #include "qgslayoutframe.h"
23 #include "qgslayoutitemwidget.h"
25 #include "qgslayouttablecolumn.h"
26 #include "qgslayoutitemmap.h"
27 #include "qgsvectorlayer.h"
29 #include "qgsproject.h"
30 #include "qgsrelationmanager.h"
31 #include "qgsguiutils.h"
33 
35  : QgsLayoutItemBaseWidget( nullptr, frame ? qobject_cast< QgsLayoutItemAttributeTable* >( frame->multiFrame() ) : nullptr )
36  , mTable( frame ? qobject_cast< QgsLayoutItemAttributeTable* >( frame->multiFrame() ) : nullptr )
37  , mFrame( frame )
38 {
39  setupUi( this );
40  connect( mRefreshPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeTableWidget::mRefreshPushButton_clicked );
41  connect( mAttributesPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeTableWidget::mAttributesPushButton_clicked );
42  connect( mMaximumRowsSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsLayoutAttributeTableWidget::mMaximumRowsSpinBox_valueChanged );
43  connect( mMarginSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutAttributeTableWidget::mMarginSpinBox_valueChanged );
44  connect( mGridStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutAttributeTableWidget::mGridStrokeWidthSpinBox_valueChanged );
45  connect( mGridColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutAttributeTableWidget::mGridColorButton_colorChanged );
46  connect( mBackgroundColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutAttributeTableWidget::mBackgroundColorButton_colorChanged );
47  connect( mDrawHorizontalGrid, &QCheckBox::toggled, this, &QgsLayoutAttributeTableWidget::mDrawHorizontalGrid_toggled );
48  connect( mDrawVerticalGrid, &QCheckBox::toggled, this, &QgsLayoutAttributeTableWidget::mDrawVerticalGrid_toggled );
49  connect( mShowGridGroupCheckBox, &QgsCollapsibleGroupBoxBasic::toggled, this, &QgsLayoutAttributeTableWidget::mShowGridGroupCheckBox_toggled );
50  connect( mShowOnlyVisibleFeaturesCheckBox, &QCheckBox::stateChanged, this, &QgsLayoutAttributeTableWidget::mShowOnlyVisibleFeaturesCheckBox_stateChanged );
51  connect( mFeatureFilterCheckBox, &QCheckBox::stateChanged, this, &QgsLayoutAttributeTableWidget::mFeatureFilterCheckBox_stateChanged );
52  connect( mFeatureFilterEdit, &QLineEdit::editingFinished, this, &QgsLayoutAttributeTableWidget::mFeatureFilterEdit_editingFinished );
53  connect( mFeatureFilterButton, &QToolButton::clicked, this, &QgsLayoutAttributeTableWidget::mFeatureFilterButton_clicked );
54  connect( mHeaderHAlignmentComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutAttributeTableWidget::mHeaderHAlignmentComboBox_currentIndexChanged );
55  connect( mHeaderModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutAttributeTableWidget::mHeaderModeComboBox_currentIndexChanged );
56  connect( mWrapStringLineEdit, &QLineEdit::editingFinished, this, &QgsLayoutAttributeTableWidget::mWrapStringLineEdit_editingFinished );
57  connect( mAddFramePushButton, &QPushButton::clicked, this, &QgsLayoutAttributeTableWidget::mAddFramePushButton_clicked );
58  connect( mResizeModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutAttributeTableWidget::mResizeModeComboBox_currentIndexChanged );
59  connect( mSourceComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutAttributeTableWidget::mSourceComboBox_currentIndexChanged );
60  connect( mRelationsComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutAttributeTableWidget::mRelationsComboBox_currentIndexChanged );
61  connect( mEmptyModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutAttributeTableWidget::mEmptyModeComboBox_currentIndexChanged );
62  connect( mDrawEmptyCheckBox, &QCheckBox::toggled, this, &QgsLayoutAttributeTableWidget::mDrawEmptyCheckBox_toggled );
63  connect( mEmptyMessageLineEdit, &QLineEdit::editingFinished, this, &QgsLayoutAttributeTableWidget::mEmptyMessageLineEdit_editingFinished );
64  connect( mIntersectAtlasCheckBox, &QCheckBox::stateChanged, this, &QgsLayoutAttributeTableWidget::mIntersectAtlasCheckBox_stateChanged );
65  connect( mUniqueOnlyCheckBox, &QCheckBox::stateChanged, this, &QgsLayoutAttributeTableWidget::mUniqueOnlyCheckBox_stateChanged );
66  connect( mEmptyFrameCheckBox, &QCheckBox::toggled, this, &QgsLayoutAttributeTableWidget::mEmptyFrameCheckBox_toggled );
67  connect( mHideEmptyBgCheckBox, &QCheckBox::toggled, this, &QgsLayoutAttributeTableWidget::mHideEmptyBgCheckBox_toggled );
68  connect( mWrapBehaviorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutAttributeTableWidget::mWrapBehaviorComboBox_currentIndexChanged );
69  connect( mAdvancedCustomizationButton, &QPushButton::clicked, this, &QgsLayoutAttributeTableWidget::mAdvancedCustomizationButton_clicked );
70  connect( mUseConditionalStylingCheckBox, &QCheckBox::stateChanged, this, &QgsLayoutAttributeTableWidget::useConditionalStylingChanged );
71  setPanelTitle( tr( "Table Properties" ) );
72 
73  mContentFontToolButton->setMode( QgsFontButton::ModeTextRenderer );
74  mHeaderFontToolButton->setMode( QgsFontButton::ModeTextRenderer );
75 
76  mContentFontToolButton->registerExpressionContextGenerator( this );
77  mHeaderFontToolButton->registerExpressionContextGenerator( this );
78 
79  blockAllSignals( true );
80 
81  mResizeModeComboBox->addItem( tr( "Use Existing Frames" ), QgsLayoutMultiFrame::UseExistingFrames );
82  mResizeModeComboBox->addItem( tr( "Extend to Next Page" ), QgsLayoutMultiFrame::ExtendToNextPage );
83  mResizeModeComboBox->addItem( tr( "Repeat Until Finished" ), QgsLayoutMultiFrame::RepeatUntilFinished );
84 
85  mEmptyModeComboBox->addItem( tr( "Draw Headers Only" ), QgsLayoutTable::HeadersOnly );
86  mEmptyModeComboBox->addItem( tr( "Hide Entire Table" ), QgsLayoutTable::HideTable );
87  mEmptyModeComboBox->addItem( tr( "Show Set Message" ), QgsLayoutTable::ShowMessage );
88 
89  mWrapBehaviorComboBox->addItem( tr( "Truncate Text" ), QgsLayoutTable::TruncateText );
90  mWrapBehaviorComboBox->addItem( tr( "Wrap Text" ), QgsLayoutTable::WrapText );
91 
92  mHeaderModeComboBox->addItem( tr( "On First Frame" ), QgsLayoutTable::FirstFrame );
93  mHeaderModeComboBox->addItem( tr( "On All Frames" ), QgsLayoutTable::AllFrames );
94  mHeaderModeComboBox->addItem( tr( "No Header" ), QgsLayoutTable::NoHeaders );
95 
96  mHeaderHAlignmentComboBox->addItem( tr( "Follow Column Alignment" ), QgsLayoutTable::FollowColumn );
97  mHeaderHAlignmentComboBox->addItem( tr( "Left" ), QgsLayoutTable::HeaderLeft );
98  mHeaderHAlignmentComboBox->addItem( tr( "Center" ), QgsLayoutTable::HeaderCenter );
99  mHeaderHAlignmentComboBox->addItem( tr( "Right" ), QgsLayoutTable::HeaderRight );
100 
101  mSourceComboBox->addItem( tr( "Layer Features" ), QgsLayoutItemAttributeTable::LayerAttributes );
102  toggleAtlasSpecificControls( static_cast< bool >( coverageLayer() ) );
103 
104  //update relations combo when relations modified in project
105  connect( QgsProject::instance()->relationManager(), &QgsRelationManager::changed, this, &QgsLayoutAttributeTableWidget::updateRelationsCombo );
106 
107  mLayerComboBox->setFilters( QgsMapLayerProxyModel::VectorLayer );
108  connect( mLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsLayoutAttributeTableWidget::changeLayer );
109 
110  mComposerMapComboBox->setCurrentLayout( mTable->layout() );
111  mComposerMapComboBox->setItemType( QgsLayoutItemRegistry::LayoutMap );
112  connect( mComposerMapComboBox, &QgsLayoutItemComboBox::itemChanged, this, &QgsLayoutAttributeTableWidget::composerMapChanged );
113 
114  mGridColorButton->setColorDialogTitle( tr( "Select Grid Color" ) );
115  mGridColorButton->setAllowOpacity( true );
116  mGridColorButton->setContext( QStringLiteral( "composer" ) );
117  mGridColorButton->setDefaultColor( Qt::black );
118  mBackgroundColorButton->setColorDialogTitle( tr( "Select Background Color" ) );
119  mBackgroundColorButton->setAllowOpacity( true );
120  mBackgroundColorButton->setContext( QStringLiteral( "composer" ) );
121  mBackgroundColorButton->setShowNoColor( true );
122  mBackgroundColorButton->setNoColorString( tr( "No Background" ) );
123 
124  updateGuiElements();
125 
126  if ( mTable )
127  {
128  connect( mTable, &QgsLayoutMultiFrame::changed, this, &QgsLayoutAttributeTableWidget::updateGuiElements );
129 
130  // repopulate relations combo box if atlas layer changes
131  connect( &mTable->layout()->reportContext(), &QgsLayoutReportContext::layerChanged,
132  this, &QgsLayoutAttributeTableWidget::atlasToggled );
133 
134  if ( QgsLayoutAtlas *atlas = layoutAtlas() )
135  {
136  connect( atlas, &QgsLayoutAtlas::toggled, this, &QgsLayoutAttributeTableWidget::atlasToggled );
137  atlasToggled();
138  }
139 
140  mLayerSourceDDBtn->registerExpressionContextGenerator( mTable );
141  }
142 
144 
145  //embed widget for general options
146  if ( mFrame )
147  {
148  //add widget for general composer item properties
149  mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, mFrame );
150  mainLayout->addWidget( mItemPropertiesWidget );
151  }
152 
153  connect( mHeaderFontToolButton, &QgsFontButton::changed, this, &QgsLayoutAttributeTableWidget::headerFontChanged );
154  connect( mContentFontToolButton, &QgsFontButton::changed, this, &QgsLayoutAttributeTableWidget::contentFontChanged );
155 }
156 
158 {
159  mIntersectAtlasCheckBox->setText( tr( "Show only features intersecting %1 feature" ).arg( string ) );
160  const int atlasFeatureIndex = mSourceComboBox->findData( QgsLayoutItemAttributeTable::AtlasFeature );
161  if ( atlasFeatureIndex != -1 )
162  {
163  mSourceComboBox->setItemText( atlasFeatureIndex, tr( "Current %1 Feature" ).arg( string ) );
164  }
165 }
166 
168 {
169  if ( mItemPropertiesWidget )
170  mItemPropertiesWidget->setMasterLayout( masterLayout );
171 }
172 
174 {
175  QgsExpressionContext context;
176 
177  // frames include their parent multiframe's context, so prefer that if possible
178  if ( mFrame )
179  context = mFrame->createExpressionContext();
180  else if ( mTable )
181  context = mTable->createExpressionContext();
182 
183  std::unique_ptr< QgsExpressionContextScope > cellScope = std::make_unique< QgsExpressionContextScope >();
184  cellScope->setVariable( QStringLiteral( "row_number" ), 1, true );
185  cellScope->setVariable( QStringLiteral( "column_number" ), 1, true );
186  context.appendScope( cellScope.release() );
187 
188  context.setHighlightedVariables( { QStringLiteral( "row_number" ),
189  QStringLiteral( "column_number" )} );
190 
191  return context;
192 }
193 
195 {
196  QgsLayoutFrame *frame = qobject_cast< QgsLayoutFrame * >( item );
197  if ( !frame )
198  return false;
199 
200  QgsLayoutMultiFrame *multiFrame = frame->multiFrame();
201  if ( !multiFrame )
202  return false;
203 
204  if ( multiFrame->type() != QgsLayoutItemRegistry::LayoutAttributeTable )
205  return false;
206 
207  if ( mTable )
208  {
209  disconnect( mTable, &QgsLayoutObject::changed, this, &QgsLayoutAttributeTableWidget::updateGuiElements );
210  }
211 
212  mTable = qobject_cast< QgsLayoutItemAttributeTable * >( multiFrame );
213  mFrame = frame;
214  mItemPropertiesWidget->setItem( frame );
215 
216  if ( mTable )
217  {
218  connect( mTable, &QgsLayoutObject::changed, this, &QgsLayoutAttributeTableWidget::updateGuiElements );
219  }
220 
221  updateGuiElements();
222 
223  return true;
224 }
225 
226 
227 void QgsLayoutAttributeTableWidget::mRefreshPushButton_clicked()
228 {
229  if ( !mTable )
230  {
231  return;
232  }
233 
234  mTable->refreshAttributes();
235 }
236 
237 void QgsLayoutAttributeTableWidget::mAttributesPushButton_clicked()
238 {
239  if ( !mTable )
240  {
241  return;
242  }
243 
244  //make deep copy of current columns, so we can restore them in case of cancellation
245  QVector<QgsLayoutTableColumn> currentColumns = mTable->columns();
246  QVector<QgsLayoutTableColumn> currentSortColumns = mTable->sortColumns();
247 
248  mTable->beginCommand( tr( "Change Table Attributes" ) );
249 
250  //temporarily block updates for the window, to stop table trying to repaint under windows (#11462)
251  window()->setUpdatesEnabled( false );
252 
253  QgsLayoutAttributeSelectionDialog d( mTable, mTable->sourceLayer(), this );
254  if ( d.exec() == QDialog::Accepted )
255  {
256  mTable->refreshAttributes();
257  //safe to unblock updates
258  window()->setUpdatesEnabled( true );
259  mTable->update();
260  mTable->endCommand();
261 
262  //clear currentColumns to free memory
263  currentColumns.clear();
264  currentSortColumns.clear();
265  }
266  else
267  {
268  //undo changes
269  mTable->setColumns( currentColumns );
270  mTable->setSortColumns( currentSortColumns );
271  window()->setUpdatesEnabled( true );
272  mTable->cancelCommand();
273  }
274 }
275 
276 void QgsLayoutAttributeTableWidget::composerMapChanged( QgsLayoutItem *item )
277 {
278  if ( !mTable )
279  {
280  return;
281  }
282 
283  mTable->beginCommand( tr( "Change Table Map" ) );
284  mTable->setMap( qobject_cast< QgsLayoutItemMap * >( item ) );
285  mTable->update();
286  mTable->endCommand();
287 }
288 
289 void QgsLayoutAttributeTableWidget::mMaximumRowsSpinBox_valueChanged( int i )
290 {
291  if ( !mTable )
292  {
293  return;
294  }
295 
296  mTable->beginCommand( tr( "Change Table Rows" ), QgsLayoutMultiFrame::UndoTableMaximumFeatures );
297  mTable->setMaximumNumberOfFeatures( i );
298  mTable->update();
299  mTable->endCommand();
300 }
301 
302 void QgsLayoutAttributeTableWidget::mMarginSpinBox_valueChanged( double d )
303 {
304  if ( !mTable )
305  {
306  return;
307  }
308 
309  mTable->beginCommand( tr( "Change Table Margin" ), QgsLayoutMultiFrame::UndoTableMargin );
310  mTable->setCellMargin( d );
311  mTable->endCommand();
312 }
313 
314 void QgsLayoutAttributeTableWidget::headerFontChanged()
315 {
316  if ( !mTable )
317  return;
318 
319  mTable->beginCommand( tr( "Change Table Text Format" ) );
320  mTable->setHeaderTextFormat( mHeaderFontToolButton->textFormat() );
321  mTable->endCommand();
322 }
323 
324 void QgsLayoutAttributeTableWidget::contentFontChanged()
325 {
326  if ( !mTable )
327  {
328  return;
329  }
330 
331  mTable->beginCommand( tr( "Change Table Text Format" ) );
332  mTable->setContentTextFormat( mContentFontToolButton->textFormat() );
333  mTable->endCommand();
334 }
335 
336 void QgsLayoutAttributeTableWidget::mGridStrokeWidthSpinBox_valueChanged( double d )
337 {
338  if ( !mTable )
339  {
340  return;
341  }
342 
343  mTable->beginCommand( tr( "Change Table Line Width" ), QgsLayoutMultiFrame::UndoTableGridStrokeWidth );
344  mTable->setGridStrokeWidth( d );
345  mTable->endCommand();
346 }
347 
348 void QgsLayoutAttributeTableWidget::mGridColorButton_colorChanged( const QColor &newColor )
349 {
350  if ( !mTable )
351  {
352  return;
353  }
354 
355  mTable->beginCommand( tr( "Change Table Grid Color" ), QgsLayoutMultiFrame::UndoTableGridColor );
356  mTable->setGridColor( newColor );
357  mTable->endCommand();
358 }
359 
360 void QgsLayoutAttributeTableWidget::mDrawHorizontalGrid_toggled( bool state )
361 {
362  if ( !mTable )
363  {
364  return;
365  }
366 
367  mTable->beginCommand( tr( "Toggle Table Grid" ) );
368  mTable->setHorizontalGrid( state );
369  mTable->endCommand();
370 }
371 
372 void QgsLayoutAttributeTableWidget::mDrawVerticalGrid_toggled( bool state )
373 {
374  if ( !mTable )
375  {
376  return;
377  }
378 
379  mTable->beginCommand( tr( "Toggled Table Grid" ) );
380  mTable->setVerticalGrid( state );
381  mTable->endCommand();
382 }
383 
384 void QgsLayoutAttributeTableWidget::mShowGridGroupCheckBox_toggled( bool state )
385 {
386  if ( !mTable )
387  {
388  return;
389  }
390 
391  mTable->beginCommand( tr( "Toggle Table Grid" ) );
392  mTable->setShowGrid( state );
393  mTable->endCommand();
394 }
395 
396 void QgsLayoutAttributeTableWidget::mBackgroundColorButton_colorChanged( const QColor &newColor )
397 {
398  if ( !mTable )
399  {
400  return;
401  }
402 
403  mTable->beginCommand( tr( "Change Table Color" ), QgsLayoutMultiFrame::UndoTableBackgroundColor );
404  mTable->setBackgroundColor( newColor );
405  mTable->endCommand();
406 }
407 
408 void QgsLayoutAttributeTableWidget::updateGuiElements()
409 {
410  if ( !mTable || !mFrame )
411  {
412  return;
413  }
414 
415  blockAllSignals( true );
416 
417  mSourceComboBox->setCurrentIndex( mSourceComboBox->findData( mTable->source() ) );
418  mRelationsComboBox->setCurrentIndex( mRelationsComboBox->findData( mTable->relationId() ) );
419 
420  //layer combo box
421  if ( mTable->vectorLayer() )
422  {
423  mLayerComboBox->setLayer( mTable->vectorLayer() );
424  if ( mTable->vectorLayer()->geometryType() == QgsWkbTypes::NullGeometry )
425  {
426  //layer has no geometry, so uncheck & disable controls which require geometry
427  mShowOnlyVisibleFeaturesCheckBox->setChecked( false );
428  mShowOnlyVisibleFeaturesCheckBox->setEnabled( false );
429  mComposerMapComboBox->setEnabled( false );
430  mComposerMapLabel->setEnabled( false );
431  mIntersectAtlasCheckBox->setEnabled( false );
432  }
433  else
434  {
435  mShowOnlyVisibleFeaturesCheckBox->setEnabled( true );
436  mComposerMapComboBox->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
437  mComposerMapLabel->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
438  mIntersectAtlasCheckBox->setEnabled( mSourceComboBox->findData( QgsLayoutItemAttributeTable::AtlasFeature ) != -1 && mTable->layout()->reportContext().layer() && mTable->layout()->reportContext().layer()->geometryType() != QgsWkbTypes::NullGeometry );
439  }
440  }
441 
442  mComposerMapComboBox->setItem( mTable->map() );
443  mMaximumRowsSpinBox->setValue( mTable->maximumNumberOfFeatures() );
444  mMarginSpinBox->setValue( mTable->cellMargin() );
445  mGridStrokeWidthSpinBox->setValue( mTable->gridStrokeWidth() );
446  mGridColorButton->setColor( mTable->gridColor() );
447  mDrawHorizontalGrid->setChecked( mTable->horizontalGrid() );
448  mDrawVerticalGrid->setChecked( mTable->verticalGrid() );
449  if ( mTable->showGrid() )
450  {
451  mShowGridGroupCheckBox->setChecked( true );
452  }
453  else
454  {
455  mShowGridGroupCheckBox->setChecked( false );
456  }
457  mBackgroundColorButton->setColor( mTable->backgroundColor() );
458 
459  mHeaderFontToolButton->setTextFormat( mTable->headerTextFormat() );
460  mContentFontToolButton->setTextFormat( mTable->contentTextFormat() );
461 
462  if ( mTable->displayOnlyVisibleFeatures() && mShowOnlyVisibleFeaturesCheckBox->isEnabled() )
463  {
464  mShowOnlyVisibleFeaturesCheckBox->setCheckState( Qt::Checked );
465  mComposerMapComboBox->setEnabled( true );
466  mComposerMapLabel->setEnabled( true );
467  }
468  else
469  {
470  mShowOnlyVisibleFeaturesCheckBox->setCheckState( Qt::Unchecked );
471  mComposerMapComboBox->setEnabled( false );
472  mComposerMapLabel->setEnabled( false );
473  }
474 
475  mUniqueOnlyCheckBox->setChecked( mTable->uniqueRowsOnly() );
476  mIntersectAtlasCheckBox->setChecked( mTable->filterToAtlasFeature() );
477  mFeatureFilterEdit->setText( mTable->featureFilter() );
478  mFeatureFilterCheckBox->setCheckState( mTable->filterFeatures() ? Qt::Checked : Qt::Unchecked );
479  mFeatureFilterEdit->setEnabled( mTable->filterFeatures() );
480  mFeatureFilterButton->setEnabled( mTable->filterFeatures() );
481  mUseConditionalStylingCheckBox->setChecked( mTable->useConditionalStyling() );
482 
483  mHeaderHAlignmentComboBox->setCurrentIndex( mHeaderHAlignmentComboBox->findData( mTable->headerHAlignment() ) );
484  mHeaderModeComboBox->setCurrentIndex( mHeaderModeComboBox->findData( mTable->headerMode() ) );
485 
486  mEmptyModeComboBox->setCurrentIndex( mEmptyModeComboBox->findData( mTable->emptyTableBehavior() ) );
487  mEmptyMessageLineEdit->setText( mTable->emptyTableMessage() );
488  mEmptyMessageLineEdit->setEnabled( mTable->emptyTableBehavior() == QgsLayoutTable::ShowMessage );
489  mEmptyMessageLabel->setEnabled( mTable->emptyTableBehavior() == QgsLayoutTable::ShowMessage );
490  mDrawEmptyCheckBox->setChecked( mTable->showEmptyRows() );
491  mWrapStringLineEdit->setText( mTable->wrapString() );
492  mWrapBehaviorComboBox->setCurrentIndex( mWrapBehaviorComboBox->findData( mTable->wrapBehavior() ) );
493 
494  mResizeModeComboBox->setCurrentIndex( mResizeModeComboBox->findData( mTable->resizeMode() ) );
495  mAddFramePushButton->setEnabled( mTable->resizeMode() == QgsLayoutMultiFrame::UseExistingFrames );
496 
497  mEmptyFrameCheckBox->setChecked( mFrame->hidePageIfEmpty() );
498  mHideEmptyBgCheckBox->setChecked( mFrame->hideBackgroundIfEmpty() );
499 
500  updateDataDefinedButton( mLayerSourceDDBtn );
501 
502  toggleSourceControls();
503 
504  blockAllSignals( false );
505 }
506 
507 void QgsLayoutAttributeTableWidget::atlasToggled()
508 {
509  // display/hide atlas options in source combobox depending on atlas status
510  // if there's no atlas but there IS a coverageLayer, it's a report export and we should enable the controls
511  const bool atlasEnabled = ( layoutAtlas() && layoutAtlas()->enabled() ) || ( !layoutAtlas() && coverageLayer() );
512 
513 
514  toggleAtlasSpecificControls( atlasEnabled );
515 
516  if ( !mTable )
517  return;
518 
519  whileBlocking( mSourceComboBox )->setCurrentIndex( mSourceComboBox->findData( mTable->source() ) );
520 
521  if ( !atlasEnabled && mTable->filterToAtlasFeature() )
522  {
523  mTable->setFilterToAtlasFeature( false );
524  }
525 }
526 
527 void QgsLayoutAttributeTableWidget::updateRelationsCombo()
528 {
529  mRelationsComboBox->blockSignals( true );
530  mRelationsComboBox->clear();
531 
532  QgsVectorLayer *atlasLayer = coverageLayer();
533  if ( atlasLayer )
534  {
535  const QList<QgsRelation> relations = QgsProject::instance()->relationManager()->referencedRelations( atlasLayer );
536  for ( const QgsRelation &relation : relations )
537  {
538  mRelationsComboBox->addItem( relation.name(), relation.id() );
539  }
540  if ( mTable )
541  {
542  mRelationsComboBox->setCurrentIndex( mRelationsComboBox->findData( mTable->relationId() ) );
543  }
544  }
545 
546  mRelationsComboBox->blockSignals( false );
547 }
548 
549 void QgsLayoutAttributeTableWidget::toggleAtlasSpecificControls( const bool atlasEnabled )
550 {
551  if ( !atlasEnabled )
552  {
553  if ( mTable->source() == QgsLayoutItemAttributeTable::AtlasFeature )
554  {
556  }
557  mSourceComboBox->removeItem( mSourceComboBox->findData( QgsLayoutItemAttributeTable::AtlasFeature ) );
558  mSourceComboBox->removeItem( mSourceComboBox->findData( QgsLayoutItemAttributeTable::RelationChildren ) );
559  mRelationsComboBox->blockSignals( true );
560  mRelationsComboBox->setEnabled( false );
561  mRelationsComboBox->clear();
562  mRelationsComboBox->blockSignals( false );
563  mIntersectAtlasCheckBox->setEnabled( false );
564  }
565  else
566  {
567  if ( mSourceComboBox->findData( QgsLayoutItemAttributeTable::AtlasFeature ) == -1 )
568  {
569  //add missing atlasfeature option to combobox
570  mSourceComboBox->addItem( tr( "Current Atlas Feature" ), QgsLayoutItemAttributeTable::AtlasFeature );
571  }
572  if ( mSourceComboBox->findData( QgsLayoutItemAttributeTable::RelationChildren ) == -1 )
573  {
574  //add missing relation children option to combobox
575  mSourceComboBox->addItem( tr( "Relation Children" ), QgsLayoutItemAttributeTable::RelationChildren );
576  }
577 
578  //add relations for coverage layer
579  updateRelationsCombo();
580  mRelationsComboBox->setEnabled( true );
581  mIntersectAtlasCheckBox->setEnabled( mTable->layout()->reportContext().layer() && mTable->layout()->reportContext().layer()->geometryType() != QgsWkbTypes::NullGeometry );
582  }
583 }
584 
585 void QgsLayoutAttributeTableWidget::blockAllSignals( bool b )
586 {
587  mSourceComboBox->blockSignals( b );
588  mLayerComboBox->blockSignals( b );
589  mComposerMapComboBox->blockSignals( b );
590  mMaximumRowsSpinBox->blockSignals( b );
591  mMarginSpinBox->blockSignals( b );
592  mGridColorButton->blockSignals( b );
593  mGridStrokeWidthSpinBox->blockSignals( b );
594  mBackgroundColorButton->blockSignals( b );
595  mDrawHorizontalGrid->blockSignals( b );
596  mDrawVerticalGrid->blockSignals( b );
597  mShowGridGroupCheckBox->blockSignals( b );
598  mShowOnlyVisibleFeaturesCheckBox->blockSignals( b );
599  mUniqueOnlyCheckBox->blockSignals( b );
600  mIntersectAtlasCheckBox->blockSignals( b );
601  mFeatureFilterEdit->blockSignals( b );
602  mFeatureFilterCheckBox->blockSignals( b );
603  mHeaderHAlignmentComboBox->blockSignals( b );
604  mHeaderModeComboBox->blockSignals( b );
605  mResizeModeComboBox->blockSignals( b );
606  mRelationsComboBox->blockSignals( b );
607  mEmptyModeComboBox->blockSignals( b );
608  mEmptyMessageLineEdit->blockSignals( b );
609  mEmptyFrameCheckBox->blockSignals( b );
610  mHideEmptyBgCheckBox->blockSignals( b );
611  mDrawEmptyCheckBox->blockSignals( b );
612  mWrapStringLineEdit->blockSignals( b );
613  mWrapBehaviorComboBox->blockSignals( b );
614  mContentFontToolButton->blockSignals( b );
615  mHeaderFontToolButton->blockSignals( b );
616 }
617 
618 void QgsLayoutAttributeTableWidget::setMaximumNumberOfFeatures( int n )
619 {
620  whileBlocking( mMaximumRowsSpinBox )->setValue( n );
621 }
622 
623 void QgsLayoutAttributeTableWidget::mShowOnlyVisibleFeaturesCheckBox_stateChanged( int state )
624 {
625  if ( !mTable )
626  {
627  return;
628  }
629 
630  mTable->beginCommand( tr( "Toggle Visible Features Only" ) );
631  const bool showOnlyVisibleFeatures = ( state == Qt::Checked );
632  mTable->setDisplayOnlyVisibleFeatures( showOnlyVisibleFeatures );
633  mTable->update();
634  mTable->endCommand();
635 
636  //enable/disable map combobox based on state of checkbox
637  mComposerMapComboBox->setEnabled( state == Qt::Checked );
638  mComposerMapLabel->setEnabled( state == Qt::Checked );
639 }
640 
641 void QgsLayoutAttributeTableWidget::mUniqueOnlyCheckBox_stateChanged( int state )
642 {
643  if ( !mTable )
644  {
645  return;
646  }
647 
648  mTable->beginCommand( tr( "Toggle Table Filter Duplicates" ) );
649  mTable->setUniqueRowsOnly( state == Qt::Checked );
650  mTable->update();
651  mTable->endCommand();
652 }
653 
654 void QgsLayoutAttributeTableWidget::mEmptyFrameCheckBox_toggled( bool checked )
655 {
656  if ( !mFrame )
657  {
658  return;
659  }
660 
661  mFrame->beginCommand( tr( "Toggle Empty Frame Mode" ) );
662  mFrame->setHidePageIfEmpty( checked );
663  mFrame->endCommand();
664 }
665 
666 void QgsLayoutAttributeTableWidget::mHideEmptyBgCheckBox_toggled( bool checked )
667 {
668  if ( !mFrame )
669  {
670  return;
671  }
672 
673  mFrame->beginCommand( tr( "Toggle Background Display" ) );
674  mFrame->setHideBackgroundIfEmpty( checked );
675  mFrame->endCommand();
676 }
677 
678 void QgsLayoutAttributeTableWidget::mIntersectAtlasCheckBox_stateChanged( int state )
679 {
680  if ( !mTable )
681  {
682  return;
683  }
684 
685  mTable->beginCommand( tr( "Toggle Table Atlas Filter" ) );
686  const bool filterToAtlas = ( state == Qt::Checked );
687  mTable->setFilterToAtlasFeature( filterToAtlas );
688  mTable->update();
689  mTable->endCommand();
690 }
691 
692 void QgsLayoutAttributeTableWidget::mFeatureFilterCheckBox_stateChanged( int state )
693 {
694  if ( !mTable )
695  {
696  return;
697  }
698 
699  if ( state == Qt::Checked )
700  {
701  mFeatureFilterEdit->setEnabled( true );
702  mFeatureFilterButton->setEnabled( true );
703  }
704  else
705  {
706  mFeatureFilterEdit->setEnabled( false );
707  mFeatureFilterButton->setEnabled( false );
708  }
709 
710  mTable->beginCommand( tr( "Toggle Table Feature Filter" ) );
711  mTable->setFilterFeatures( state == Qt::Checked );
712  mTable->update();
713  mTable->endCommand();
714 }
715 
716 void QgsLayoutAttributeTableWidget::mFeatureFilterEdit_editingFinished()
717 {
718  if ( !mTable )
719  {
720  return;
721  }
722 
723  mTable->beginCommand( tr( "Change Table Feature Filter" ) );
724  mTable->setFeatureFilter( mFeatureFilterEdit->text() );
725  mTable->update();
726  mTable->endCommand();
727 }
728 
729 void QgsLayoutAttributeTableWidget::mFeatureFilterButton_clicked()
730 {
731  if ( !mTable )
732  {
733  return;
734  }
735 
736  const QgsExpressionContext context = mTable->createExpressionContext();
737  QgsExpressionBuilderDialog exprDlg( mTable->sourceLayer(), mFeatureFilterEdit->text(), this, QStringLiteral( "generic" ), context );
738  exprDlg.setWindowTitle( tr( "Expression Based Filter" ) );
739  if ( exprDlg.exec() == QDialog::Accepted )
740  {
741  const QString expression = exprDlg.expressionText();
742  if ( !expression.isEmpty() )
743  {
744  mFeatureFilterEdit->setText( expression );
745  mTable->beginCommand( tr( "Change Table Feature Filter" ) );
746  mTable->setFeatureFilter( mFeatureFilterEdit->text() );
747  mTable->update();
748  mTable->endCommand();
749  }
750  }
751 }
752 
753 void QgsLayoutAttributeTableWidget::mHeaderHAlignmentComboBox_currentIndexChanged( int )
754 {
755  if ( !mTable )
756  {
757  return;
758  }
759 
760  mTable->beginCommand( tr( "Change Table Alignment" ) );
761  mTable->setHeaderHAlignment( static_cast< QgsLayoutTable::HeaderHAlignment >( mHeaderHAlignmentComboBox->currentData().toInt() ) );
762  mTable->endCommand();
763 }
764 
765 void QgsLayoutAttributeTableWidget::mHeaderModeComboBox_currentIndexChanged( int )
766 {
767  if ( !mTable )
768  {
769  return;
770  }
771 
772  mTable->beginCommand( tr( "Change Table Header Mode" ) );
773  mTable->setHeaderMode( static_cast< QgsLayoutTable::HeaderMode >( mHeaderModeComboBox->currentData().toInt() ) );
774  mTable->endCommand();
775 }
776 
777 void QgsLayoutAttributeTableWidget::mWrapStringLineEdit_editingFinished()
778 {
779  if ( !mTable )
780  {
781  return;
782  }
783 
784  mTable->beginCommand( tr( "Change Table Wrap String" ) );
785  mTable->setWrapString( mWrapStringLineEdit->text() );
786  mTable->endCommand();
787 }
788 
789 void QgsLayoutAttributeTableWidget::changeLayer( QgsMapLayer *layer )
790 {
791  if ( !mTable )
792  {
793  return;
794  }
795 
796  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
797  if ( !vl )
798  {
799  return;
800  }
801 
802  mTable->beginCommand( tr( "Change Table Layer" ) );
803  mTable->setVectorLayer( vl );
804  mTable->update();
805  mTable->endCommand();
806 
808  {
809  //layer has no geometry, so uncheck & disable controls which require geometry
810  mShowOnlyVisibleFeaturesCheckBox->setChecked( false );
811  mShowOnlyVisibleFeaturesCheckBox->setEnabled( false );
812  mComposerMapComboBox->setEnabled( false );
813  mComposerMapLabel->setEnabled( false );
814  mIntersectAtlasCheckBox->setEnabled( false );
815  }
816  else
817  {
818  mShowOnlyVisibleFeaturesCheckBox->setEnabled( true );
819  mComposerMapComboBox->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
820  mComposerMapLabel->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
821  mIntersectAtlasCheckBox->setEnabled( mSourceComboBox->findData( QgsLayoutItemAttributeTable::AtlasFeature ) != -1 && mTable->layout()->reportContext().layer() && mTable->layout()->reportContext().layer()->geometryType() != QgsWkbTypes::NullGeometry );
822  }
823 }
824 
825 void QgsLayoutAttributeTableWidget::mAddFramePushButton_clicked()
826 {
827  if ( !mTable || !mFrame )
828  {
829  return;
830  }
831 
832  //create a new frame based on the current frame
833  QPointF pos = mFrame->pos();
834  //shift new frame so that it sits 10 units below current frame
835  pos.ry() += mFrame->rect().height() + 10;
836 
837  QgsLayoutFrame *newFrame = mTable->createNewFrame( mFrame, pos, mFrame->rect().size() );
838  mTable->recalculateFrameSizes();
839 
840  //set new frame as selection
841  if ( QgsLayout *layout = mTable->layout() )
842  {
843  layout->setSelectedItem( newFrame );
844  }
845 }
846 
847 void QgsLayoutAttributeTableWidget::mResizeModeComboBox_currentIndexChanged( int index )
848 {
849  if ( !mTable )
850  {
851  return;
852  }
853 
854  mTable->beginCommand( tr( "Change Resize Mode" ) );
855  mTable->setResizeMode( static_cast< QgsLayoutMultiFrame::ResizeMode >( mResizeModeComboBox->itemData( index ).toInt() ) );
856  mTable->endCommand();
857 
858  mAddFramePushButton->setEnabled( mTable->resizeMode() == QgsLayoutMultiFrame::UseExistingFrames );
859 }
860 
861 void QgsLayoutAttributeTableWidget::mSourceComboBox_currentIndexChanged( int index )
862 {
863  if ( !mTable )
864  {
865  return;
866  }
867 
868  mTable->beginCommand( tr( "Change Table Source" ) );
869  mTable->setSource( static_cast< QgsLayoutItemAttributeTable::ContentSource >( mSourceComboBox->itemData( index ).toInt() ) );
870  mTable->endCommand();
871 
872  toggleSourceControls();
873 }
874 
875 void QgsLayoutAttributeTableWidget::mRelationsComboBox_currentIndexChanged( int index )
876 {
877  if ( !mTable )
878  {
879  return;
880  }
881 
882  mTable->beginCommand( tr( "Change Table Source Relation" ) );
883  mTable->setRelationId( mRelationsComboBox->itemData( index ).toString() );
884  mTable->endCommand();
885 }
886 
887 void QgsLayoutAttributeTableWidget::mEmptyModeComboBox_currentIndexChanged( int index )
888 {
889  if ( !mTable )
890  {
891  return;
892  }
893 
894  mTable->beginCommand( tr( "Change Empty Table Behavior" ) );
895  mTable->setEmptyTableBehavior( static_cast< QgsLayoutTable::EmptyTableMode >( mEmptyModeComboBox->itemData( index ).toInt() ) );
896  mTable->endCommand();
897  mEmptyMessageLineEdit->setEnabled( mTable->emptyTableBehavior() == QgsLayoutTable::ShowMessage );
898  mEmptyMessageLabel->setEnabled( mTable->emptyTableBehavior() == QgsLayoutTable::ShowMessage );
899 }
900 
901 void QgsLayoutAttributeTableWidget::mWrapBehaviorComboBox_currentIndexChanged( int index )
902 {
903  if ( !mTable )
904  {
905  return;
906  }
907 
908  mTable->beginCommand( tr( "Change Table Wrap Mode" ) );
909  mTable->setWrapBehavior( static_cast< QgsLayoutTable::WrapBehavior >( mWrapBehaviorComboBox->itemData( index ).toInt() ) );
910  mTable->endCommand();
911 }
912 
913 void QgsLayoutAttributeTableWidget::mAdvancedCustomizationButton_clicked()
914 {
915  if ( !mTable )
916  {
917  return;
918  }
919 
920  QgsLayoutTableBackgroundColorsDialog d( mTable, this );
921  d.exec();
922 }
923 
924 void QgsLayoutAttributeTableWidget::useConditionalStylingChanged( bool checked )
925 {
926  if ( !mTable )
927  {
928  return;
929  }
930 
931  mTable->beginCommand( tr( "Toggle Table Conditional Styling" ) );
932  mTable->setUseConditionalStyling( checked );
933  mTable->update();
934  mTable->endCommand();
935 }
936 
937 void QgsLayoutAttributeTableWidget::mDrawEmptyCheckBox_toggled( bool checked )
938 {
939  if ( !mTable )
940  {
941  return;
942  }
943 
944  mTable->beginCommand( tr( "Change Show Empty Rows" ) );
945  mTable->setShowEmptyRows( checked );
946  mTable->endCommand();
947 }
948 
949 void QgsLayoutAttributeTableWidget::mEmptyMessageLineEdit_editingFinished()
950 {
951  if ( !mTable )
952  {
953  return;
954  }
955 
956  mTable->beginCommand( tr( "Change Empty Table Message" ) );
957  mTable->setEmptyTableMessage( mEmptyMessageLineEdit->text() );
958  mTable->endCommand();
959 }
960 
961 void QgsLayoutAttributeTableWidget::toggleSourceControls()
962 {
963  switch ( mTable->source() )
964  {
966  mLayerComboBox->setEnabled( true );
967  mLayerComboBox->setVisible( true );
968  mLayerSourceDDBtn->setVisible( true );
969  mLayerLabel->setVisible( true );
970  mRelationsComboBox->setEnabled( false );
971  mRelationsComboBox->setVisible( false );
972  mRelationLabel->setVisible( false );
973  mMaximumRowsSpinBox->setEnabled( true );
974  mMaxNumFeaturesLabel->setEnabled( true );
975  mShowOnlyVisibleFeaturesCheckBox->setEnabled( mTable->vectorLayer() && mTable->vectorLayer()->geometryType() != QgsWkbTypes::NullGeometry );
976  mShowOnlyVisibleFeaturesCheckBox->setChecked( mTable->vectorLayer() && mTable->vectorLayer()->geometryType() != QgsWkbTypes::NullGeometry && mTable->displayOnlyVisibleFeatures() );
977  mComposerMapComboBox->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
978  mComposerMapLabel->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
979  mIntersectAtlasCheckBox->setEnabled( mTable->vectorLayer() && mTable->vectorLayer()->geometryType() != QgsWkbTypes::NullGeometry
980  && mSourceComboBox->findData( QgsLayoutItemAttributeTable::AtlasFeature ) != -1 && mTable->layout()->reportContext().layer() && mTable->layout()->reportContext().layer()->geometryType() != QgsWkbTypes::NullGeometry );
981  break;
983  mLayerComboBox->setEnabled( false );
984  mLayerComboBox->setVisible( false );
985  mLayerSourceDDBtn->setVisible( false );
986  mLayerLabel->setVisible( false );
987  mRelationsComboBox->setEnabled( false );
988  mRelationsComboBox->setVisible( false );
989  mRelationLabel->setVisible( false );
990  mMaximumRowsSpinBox->setEnabled( false );
991  mMaxNumFeaturesLabel->setEnabled( false );
992  mShowOnlyVisibleFeaturesCheckBox->setEnabled( mTable->sourceLayer() && mTable->sourceLayer()->geometryType() != QgsWkbTypes::NullGeometry );
993  mShowOnlyVisibleFeaturesCheckBox->setChecked( mTable->sourceLayer() && mTable->sourceLayer()->geometryType() != QgsWkbTypes::NullGeometry && mTable->displayOnlyVisibleFeatures() );
994  mComposerMapComboBox->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
995  mComposerMapLabel->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
996  mIntersectAtlasCheckBox->setEnabled( false );
997  break;
999  mLayerComboBox->setEnabled( false );
1000  mLayerComboBox->setVisible( false );
1001  mLayerLabel->setVisible( false );
1002  mLayerSourceDDBtn->setVisible( false );
1003  mRelationsComboBox->setEnabled( true );
1004  mRelationsComboBox->setVisible( true );
1005  mRelationLabel->setVisible( true );
1006  mMaximumRowsSpinBox->setEnabled( true );
1007  mMaxNumFeaturesLabel->setEnabled( true );
1008  //it's missing the check for null geometry of the referencing layer
1009  mShowOnlyVisibleFeaturesCheckBox->setEnabled( true );
1010  mComposerMapComboBox->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
1011  mComposerMapLabel->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
1012  mIntersectAtlasCheckBox->setEnabled( mSourceComboBox->findData( QgsLayoutItemAttributeTable::AtlasFeature ) != -1 && mTable->layout()->reportContext().layer() && mTable->layout()->reportContext().layer()->geometryType() != QgsWkbTypes::NullGeometry );
1013  break;
1014  }
1015 }
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
A generic dialog for building expression strings.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
@ ModeTextRenderer
Configure font settings for use with QgsTextRenderer.
Definition: qgsfontbutton.h:61
void changed()
Emitted when the widget's text format settings are changed.
Class used to render QgsLayout as an atlas, by iterating over the features from an associated vector ...
void toggled(bool)
Emitted when atlas is enabled or disabled.
bool enabled() const
Returns whether the atlas generation is enabled.
A dialog to select what attributes to display (in the table item), set the column properties and spec...
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void setReportTypeString(const QString &string) override
Sets the string to use to describe the current report type (e.g.
QgsLayoutAttributeTableWidget(QgsLayoutFrame *frame)
constructor
bool setNewItem(QgsLayoutItem *item) override
Attempts to update the widget to show the properties for the specified item.
void setMasterLayout(QgsMasterLayoutInterface *masterLayout) override
Sets the master layout associated with the item.
Base class for frame items, which form a layout multiframe item.
QgsLayoutMultiFrame * multiFrame() const
Returns the parent multiframe for the frame.
A layout table subclass that displays attributes from a vector layer.
ContentSource
Specifies the content source for the attribute table.
@ AtlasFeature
Table shows attributes from the current atlas feature.
@ RelationChildren
Table shows attributes from related child features.
@ LayerAttributes
Table shows attributes from features in a vector layer.
A base class for property widgets for layout items.
void updateDataDefinedButton(QgsPropertyOverrideButton *button)
Updates a previously registered data defined button to reflect the item's current properties.
QgsVectorLayer * coverageLayer() const
Returns the current layout context coverage layer (if set).
void registerDataDefinedButton(QgsPropertyOverrideButton *button, QgsLayoutObject::DataDefinedProperty property)
Registers a data defined button, setting up its initial value, connections and description.
QgsLayoutAtlas * layoutAtlas() const
Returns the atlas for the layout (if available)
void itemChanged(QgsLayoutItem *item)
Emitted whenever the currently selected item changes.
A widget for controlling the common properties of layout items (e.g.
void setMasterLayout(QgsMasterLayoutInterface *masterLayout)
Sets the master layout associated with the item.
void setItem(QgsLayoutItem *item)
Sets the layout item.
@ LayoutAttributeTable
Attribute table.
Base class for graphical items within a QgsLayout.
Abstract base class for layout items with the ability to distribute the content to several frames (Qg...
virtual int type() const =0
Returns unique multiframe type id.
ResizeMode
Specifies the behavior for creating new frames to fit the multiframe's content.
@ UseExistingFrames
Don't automatically create new frames, just use existing frames.
@ ExtendToNextPage
Creates new full page frames on the following page(s) until the entire multiframe content is visible.
@ UndoTableMaximumFeatures
Maximum features in table.
@ UndoTableBackgroundColor
Table background color.
@ UndoTableGridStrokeWidth
Table grid stroke width.
@ UndoTableGridColor
Table grid color.
@ UndoTableMargin
Table margins.
void changed()
Emitted when the object's properties change.
@ AttributeTableSourceLayer
Attribute table source layer.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
A dialog for customization of the cell background colors for a QgsLayoutTable.
HeaderMode
Controls where headers are shown in the table.
@ FirstFrame
Header shown on first frame only.
@ AllFrames
Headers shown on all frames.
@ NoHeaders
No headers shown for table.
WrapBehavior
Controls how long strings in the table are handled.
@ WrapText
Text which doesn't fit inside the cell is wrapped. Note that this only applies to text in columns wit...
@ TruncateText
Text which doesn't fit inside the cell is truncated.
HeaderHAlignment
Controls how headers are horizontally aligned in a table.
@ HeaderRight
Align headers right.
@ HeaderLeft
Align headers left.
@ HeaderCenter
Align headers to center.
@ FollowColumn
Header uses the same alignment as the column.
EmptyTableMode
Controls how empty tables are displayed.
@ HideTable
Hides entire table if empty.
@ ShowMessage
Shows preset message instead of table contents.
@ HeadersOnly
Show header rows only.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:51
void layerChanged(QgsMapLayer *layer)
Emitted whenever the currently selected layer changes.
Base class for all map layer types.
Definition: qgsmaplayer.h:73
Interface for master layout type objects, such as print layouts and reports.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
QgsRelationManager * relationManager
Definition: qgsproject.h:111
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:467
QList< QgsRelation > referencedRelations(const QgsVectorLayer *layer=nullptr) const
Gets all relations where this layer is the referenced part (i.e.
void changed()
Emitted when relations are added or removed to the manager.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:1173