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