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
18 #include "qgslayoutattributetablewidget.h"
19 #include "qgslayoutatlas.h"
20 #include "qgslayout.h"
21 #include "qgslayoutframe.h"
22 #include "qgslayoutattributeselectiondialog.h"
23 #include "qgslayoutitemwidget.h"
24 #include "qgslayoutitemattributetable.h"
25 #include "qgslayouttablecolumn.h"
26 #include "qgslayoutitemmap.h"
27 #include "qgsvectorlayer.h"
28 #include "qgsexpressionbuilderdialog.h"
29 #include "qgsproject.h"
30 #include "qgsrelationmanager.h"
31 #include "qgsguiutils.h"
32 #include "qgslayouttablebackgroundcolorsdialog.h"
33
QgsLayoutAttributeTableWidget(QgsLayoutFrame * frame)34 QgsLayoutAttributeTableWidget::QgsLayoutAttributeTableWidget( QgsLayoutFrame *frame )
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
145 registerDataDefinedButton( mLayerSourceDDBtn, QgsLayoutObject::AttributeTableSourceLayer );
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
setReportTypeString(const QString & string)159 void QgsLayoutAttributeTableWidget::setReportTypeString( const QString &string )
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
setMasterLayout(QgsMasterLayoutInterface * masterLayout)169 void QgsLayoutAttributeTableWidget::setMasterLayout( QgsMasterLayoutInterface *masterLayout )
170 {
171 if ( mItemPropertiesWidget )
172 mItemPropertiesWidget->setMasterLayout( masterLayout );
173 }
174
createExpressionContext() const175 QgsExpressionContext QgsLayoutAttributeTableWidget::createExpressionContext() const
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
setNewItem(QgsLayoutItem * item)196 bool QgsLayoutAttributeTableWidget::setNewItem( QgsLayoutItem *item )
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
mRefreshPushButton_clicked()229 void QgsLayoutAttributeTableWidget::mRefreshPushButton_clicked()
230 {
231 if ( !mTable )
232 {
233 return;
234 }
235
236 mTable->refreshAttributes();
237 }
238
mAttributesPushButton_clicked()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
composerMapChanged(QgsLayoutItem * item)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
mMaximumRowsSpinBox_valueChanged(int i)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
mMarginSpinBox_valueChanged(double d)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
headerFontChanged()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
contentFontChanged()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
mGridStrokeWidthSpinBox_valueChanged(double d)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
mGridColorButton_colorChanged(const QColor & newColor)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
mDrawHorizontalGrid_toggled(bool state)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
mDrawVerticalGrid_toggled(bool state)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
mShowGridGroupCheckBox_toggled(bool state)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
mBackgroundColorButton_colorChanged(const QColor & newColor)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
updateGuiElements()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
atlasToggled()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
updateRelationsCombo()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
toggleAtlasSpecificControls(const bool atlasEnabled)551 void QgsLayoutAttributeTableWidget::toggleAtlasSpecificControls( const bool atlasEnabled )
552 {
553 if ( !atlasEnabled )
554 {
555 if ( mTable->source() == QgsLayoutItemAttributeTable::AtlasFeature )
556 {
557 mTable->setSource( QgsLayoutItemAttributeTable::LayerAttributes );
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
blockAllSignals(bool b)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
setMaximumNumberOfFeatures(int n)620 void QgsLayoutAttributeTableWidget::setMaximumNumberOfFeatures( int n )
621 {
622 whileBlocking( mMaximumRowsSpinBox )->setValue( n );
623 }
624
mShowOnlyVisibleFeaturesCheckBox_stateChanged(int state)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
mUniqueOnlyCheckBox_stateChanged(int state)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
mEmptyFrameCheckBox_toggled(bool checked)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
mHideEmptyBgCheckBox_toggled(bool checked)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
mIntersectAtlasCheckBox_stateChanged(int state)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
mFeatureFilterCheckBox_stateChanged(int state)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
mFeatureFilterEdit_editingFinished()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
mFeatureFilterButton_clicked()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
mHeaderHAlignmentComboBox_currentIndexChanged(int)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
mHeaderModeComboBox_currentIndexChanged(int)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
mWrapStringLineEdit_editingFinished()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
changeLayer(QgsMapLayer * layer)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
812 if ( vl->geometryType() == QgsWkbTypes::NullGeometry )
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
mAddFramePushButton_clicked()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
mResizeModeComboBox_currentIndexChanged(int index)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
mSourceComboBox_currentIndexChanged(int index)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
mRelationsComboBox_currentIndexChanged(int index)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
mEmptyModeComboBox_currentIndexChanged(int index)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
mWrapBehaviorComboBox_currentIndexChanged(int index)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
mAdvancedCustomizationButton_clicked()918 void QgsLayoutAttributeTableWidget::mAdvancedCustomizationButton_clicked()
919 {
920 if ( !mTable )
921 {
922 return;
923 }
924
925 QgsLayoutTableBackgroundColorsDialog d( mTable, this );
926 d.exec();
927 }
928
useConditionalStylingChanged(bool checked)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
mDrawEmptyCheckBox_toggled(bool checked)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
mEmptyMessageLineEdit_editingFinished()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
toggleSourceControls()966 void QgsLayoutAttributeTableWidget::toggleSourceControls()
967 {
968 switch ( mTable->source() )
969 {
970 case QgsLayoutItemAttributeTable::LayerAttributes:
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;
987 case QgsLayoutItemAttributeTable::AtlasFeature:
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;
1003 case QgsLayoutItemAttributeTable::RelationChildren:
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 }
1021