QGIS API Documentation 3.40.0-Bratislava (b56115d8743)
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 "qgslayoutatlas.h"
20#include "qgslayout.h"
21#include "qgslayoutframe.h"
23#include "qgslayoutitemwidget.h"
26#include "qgslayoutitemmap.h"
27#include "qgsvectorlayer.h"
29#include "qgsproject.h"
30#include "qgsrelationmanager.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( Qgis::LayerFilter::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
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
229void QgsLayoutAttributeTableWidget::mRefreshPushButton_clicked()
230{
231 if ( !mTable )
232 {
233 return;
234 }
235
236 mTable->refreshAttributes();
237}
238
239void 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
278void 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
291void 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
304void 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
316void 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
326void 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
338void 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
350void 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
362void 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
374void 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
386void 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
398void 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
410void 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() == Qgis::GeometryType::Null )
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() != Qgis::GeometryType::Null );
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
509void 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
529void 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
551void 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() != Qgis::GeometryType::Null );
584 }
585}
586
587void 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
620void QgsLayoutAttributeTableWidget::setMaximumNumberOfFeatures( int n )
621{
622 whileBlocking( mMaximumRowsSpinBox )->setValue( n );
623}
624
625void 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
643void 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
656void 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
668void 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
680void 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
694void 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
718void 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
731void 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
755void 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
767void 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
779void 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
791void 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() != Qgis::GeometryType::Null );
827 }
828}
829
830void 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
852void 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
866void 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
880void 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
892void 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
906void 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
918void QgsLayoutAttributeTableWidget::mAdvancedCustomizationButton_clicked()
919{
920 if ( !mTable )
921 {
922 return;
923 }
924
925 QgsLayoutTableBackgroundColorsDialog d( mTable, this );
926 d.exec();
927}
928
929void 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
942void 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
954void 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
966void 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() != Qgis::GeometryType::Null );
981 mShowOnlyVisibleFeaturesCheckBox->setChecked( mTable->vectorLayer() && mTable->vectorLayer()->geometryType() != Qgis::GeometryType::Null && mTable->displayOnlyVisibleFeatures() );
982 mComposerMapComboBox->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
983 mComposerMapLabel->setEnabled( mShowOnlyVisibleFeaturesCheckBox->isChecked() );
984 mIntersectAtlasCheckBox->setEnabled( mTable->vectorLayer() && mTable->vectorLayer()->geometryType() != Qgis::GeometryType::Null
985 && mSourceComboBox->findData( QgsLayoutItemAttributeTable::AtlasFeature ) != -1 && mTable->layout()->reportContext().layer() && mTable->layout()->reportContext().layer()->geometryType() != Qgis::GeometryType::Null );
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() != Qgis::GeometryType::Null );
998 mShowOnlyVisibleFeaturesCheckBox->setChecked( mTable->sourceLayer() && mTable->sourceLayer()->geometryType() != Qgis::GeometryType::Null && 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() != Qgis::GeometryType::Null );
1018 break;
1019 }
1020}
@ 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:5821