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