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