19#include "moc_qgslayoutlabelwidget.cpp"
29#include <QColorDialog>
42 connect( mHtmlCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutLabelWidget::mHtmlCheckBox_stateChanged );
43 connect( mTextEdit, &QPlainTextEdit::textChanged,
this, &QgsLayoutLabelWidget::mTextEdit_textChanged );
44 connect( mInsertExpressionButton, &QPushButton::clicked,
this, &QgsLayoutLabelWidget::mInsertExpressionButton_clicked );
45 connect( mMarginXDoubleSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLabelWidget::mMarginXDoubleSpinBox_valueChanged );
46 connect( mMarginYDoubleSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLabelWidget::mMarginYDoubleSpinBox_valueChanged );
48 mHAlignmentComboBox->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight | Qt::AlignJustify );
49 mVAlignmentComboBox->setAvailableAlignments( Qt::AlignTop | Qt::AlignVCenter | Qt::AlignBottom );
57 mFontButton->setDialogTitle( tr(
"Label Font" ) );
58 mFontButton->registerExpressionContextGenerator(
this );
62 mainLayout->addWidget( mItemPropertiesWidget );
64 mMarginXDoubleSpinBox->setClearValue( 0.0 );
65 mMarginYDoubleSpinBox->setClearValue( 0.0 );
67 setGuiElementValues();
72 mDynamicTextMenu =
new QMenu(
this );
73 mDynamicTextButton->setMenu( mDynamicTextMenu );
75 connect( mDynamicTextMenu, &QMenu::aboutToShow,
this, [ = ]
77 mDynamicTextMenu->clear();
78 if ( mLabel->layout() )
81 buildInsertDynamicTextMenu( mLabel->layout(), mDynamicTextMenu, [ = ]( const QString & expression )
83 mLabel->beginCommand( tr(
"Insert dynamic text" ) );
84 mTextEdit->insertPlainText(
"[%" + expression.trimmed() +
"%]" );
90 QMenu *expressionMenu =
new QMenu(
this );
91 QAction *convertToStaticAction =
new QAction( tr(
"Convert to Static Text" ),
this );
92 expressionMenu->addAction( convertToStaticAction );
94 mInsertExpressionButton->setMenu( expressionMenu );
96 mFontButton->setLayer( coverageLayer() );
97 if ( mLabel->layout() )
105 if ( mItemPropertiesWidget )
111 return mLabel->createExpressionContext();
117 auto addExpression = [&callback]( QMenu * menu,
const QString & name,
const QString & expression )
119 QAction *action =
new QAction( name, menu );
120 connect( action, &QAction::triggered, action, [callback, expression]
122 callback( expression );
124 menu->addAction( action );
127 QMenu *dateMenu =
new QMenu( tr(
"Current Date" ), menu );
128 for (
const std::pair< QString, QString > &expression :
130 std::make_pair( tr(
"ISO Format (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral(
"yyyy-MM-dd" ) ) ), QStringLiteral(
"format_date(now(), 'yyyy-MM-dd')" ) ),
131 std::make_pair( tr(
"Day/Month/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral(
"dd/MM/yyyy" ) ) ), QStringLiteral(
"format_date(now(), 'dd/MM/yyyy')" ) ),
132 std::make_pair( tr(
"Month/Day/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral(
"MM/dd/yyyy" ) ) ), QStringLiteral(
"format_date(now(), 'MM/dd/yyyy')" ) ),
135 addExpression( dateMenu, expression.first, expression.second );
137 menu->addMenu( dateMenu );
139 QMenu *mapsMenu =
new QMenu( tr(
"Map Properties" ), menu );
140 QList< QgsLayoutItemMap * > maps;
145 if ( map->id().isEmpty() )
148 QMenu *mapMenu =
new QMenu( map->displayName(), mapsMenu );
149 for (
const std::pair< QString, QString > &expression :
151 std::make_pair( tr(
"Scale (%1)" ).arg( map->scale() ), QStringLiteral(
"format_number(item_variables('%1')['map_scale'], places:=6, omit_group_separators:=true, trim_trailing_zeroes:=true)" ).arg( map->id() ) ),
152 std::make_pair( tr(
"Rotation (%1)" ).arg( map->rotation() ), QStringLiteral(
"item_variables('%1')['map_rotation']" ).arg( map->id() ) ),
155 addExpression( mapMenu, expression.first, expression.second );
157 mapMenu->addSeparator();
158 for (
const std::pair< QString, QString > &expression :
160 std::make_pair( tr(
"CRS Identifier (%1)" ).arg( map->crs().authid() ), QStringLiteral(
"item_variables('%1')['map_crs']" ).arg( map->id() ) ),
161 std::make_pair( tr(
"CRS Name (%1)" ).arg( map->crs().description() ), QStringLiteral(
"item_variables('%1')['map_crs_description']" ).arg( map->id() ) ),
162 std::make_pair( tr(
"Ellipsoid Name (%1)" ).arg( map->crs().ellipsoidAcronym() ), QStringLiteral(
"item_variables('%1')['map_crs_ellipsoid']" ).arg( map->id() ) ),
163 std::make_pair( tr(
"Units (%1)" ).arg(
QgsUnitTypes::toString( map->crs().mapUnits() ) ), QStringLiteral(
"item_variables('%1')['map_units']" ).arg( map->id() ) ),
164 std::make_pair( tr(
"Projection (%1)" ).arg( map->crs().operation().description() ), QStringLiteral(
"item_variables('%1')['map_crs_projection']" ).arg( map->id() ) ),
167 addExpression( mapMenu, expression.first, expression.second );
169 mapMenu->addSeparator();
173 for (
const std::pair< QString, QString > &expression :
175 std::make_pair( tr(
"Center (X) (%1)" ).arg( center.
x() ), QStringLiteral(
"x(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ),
176 std::make_pair( tr(
"Center (Y) (%1)" ).arg( center.
y() ), QStringLiteral(
"y(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ),
177 std::make_pair( tr(
"X Minimum (%1)" ).arg( mapExtent.
xMinimum() ), QStringLiteral(
"x_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ),
178 std::make_pair( tr(
"Y Minimum (%1)" ).arg( mapExtent.
yMinimum() ), QStringLiteral(
"y_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ),
179 std::make_pair( tr(
"X Maximum (%1)" ).arg( mapExtent.
xMaximum() ), QStringLiteral(
"x_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ),
180 std::make_pair( tr(
"Y Maximum (%1)" ).arg( mapExtent.
yMaximum() ), QStringLiteral(
"y_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ),
183 addExpression( mapMenu, expression.first, expression.second );
185 mapMenu->addSeparator();
186 for (
const std::pair< QString, QString > &expression :
188 std::make_pair( tr(
"Layer Credits" ), QStringLiteral(
"array_to_string(map_credits('%1'))" ).arg( map->id() ) ),
191 addExpression( mapMenu, expression.first, expression.second );
193 mapsMenu->addMenu( mapMenu );
195 menu->addMenu( mapsMenu );
196 menu->addSeparator();
202 QMenu *fieldsMenu =
new QMenu( tr(
"Field" ), menu );
203 for (
const QgsField &field : fields )
205 addExpression( fieldsMenu, field.displayName(), QStringLiteral(
"\"%1\"" ).arg( field.name() ) );
208 menu->addMenu( fieldsMenu );
209 menu->addSeparator();
212 for (
const std::pair< QString, QString > &expression :
214 std::make_pair( tr(
"Layout Name" ), QStringLiteral(
"@layout_name" ) ),
215 std::make_pair( tr(
"Layout Page Number" ), QStringLiteral(
"@layout_page" ) ),
216 std::make_pair( tr(
"Layout Page Count" ), QStringLiteral(
"@layout_numpages" ) ),
217 std::make_pair( tr(
"Layer Credits" ), QStringLiteral(
"array_to_string(map_credits())" ) )
220 addExpression( menu, expression.first, expression.second );
222 menu->addSeparator();
223 for (
const std::pair< QString, QString > &expression :
225 std::make_pair( tr(
"Project Author" ), QStringLiteral(
"@project_author" ) ),
226 std::make_pair( tr(
"Project Title" ), QStringLiteral(
"@project_title" ) ),
227 std::make_pair( tr(
"Project Path" ), QStringLiteral(
"@project_path" ) )
230 addExpression( menu, expression.first, expression.second );
232 menu->addSeparator();
233 for (
const std::pair< QString, QString > &expression :
235 std::make_pair( tr(
"Current User Name" ), QStringLiteral(
"@user_full_name" ) ),
236 std::make_pair( tr(
"Current User Account" ), QStringLiteral(
"@user_account_name" ) )
239 addExpression( menu, expression.first, expression.second );
253 mLabel = qobject_cast< QgsLayoutItemLabel * >( item );
254 mItemPropertiesWidget->
setItem( mLabel );
261 setGuiElementValues();
266void QgsLayoutLabelWidget::mHtmlCheckBox_stateChanged(
int state )
270 mVerticalAlignementLabel->setDisabled( state );
271 mVAlignmentComboBox->setDisabled( state );
273 mLabel->beginCommand( tr(
"Change Label Mode" ) );
274 mLabel->blockSignals(
true );
276 mLabel->setText( mTextEdit->toPlainText() );
278 mLabel->blockSignals(
false );
279 mLabel->endCommand();
283void QgsLayoutLabelWidget::mTextEdit_textChanged()
288 mLabel->blockSignals(
true );
289 mLabel->setText( mTextEdit->toPlainText() );
291 mLabel->blockSignals(
false );
292 mLabel->endCommand();
296void QgsLayoutLabelWidget::fontChanged()
301 mLabel->setTextFormat( mFontButton->textFormat() );
303 mLabel->endCommand();
307void QgsLayoutLabelWidget::mMarginXDoubleSpinBox_valueChanged(
double d )
312 mLabel->setMarginX( d );
314 mLabel->endCommand();
318void QgsLayoutLabelWidget::mMarginYDoubleSpinBox_valueChanged(
double d )
323 mLabel->setMarginY( d );
325 mLabel->endCommand();
329void QgsLayoutLabelWidget::mInsertExpressionButton_clicked()
344 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
345 if ( exprDlg.exec() == QDialog::Accepted )
347 expression = exprDlg.expressionText();
348 if ( !expression.isEmpty() )
350 mLabel->beginCommand( tr(
"Insert expression" ) );
351 mTextEdit->insertPlainText(
"[%" + expression.trimmed() +
"%]" );
352 mLabel->endCommand();
357void QgsLayoutLabelWidget::horizontalAlignmentChanged()
361 mLabel->beginCommand( tr(
"Change Label Alignment" ) );
362 mLabel->setHAlign(
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mHAlignmentComboBox->currentAlignment() ) ) );
364 mLabel->endCommand();
368void QgsLayoutLabelWidget::verticalAlignmentChanged()
372 mLabel->beginCommand( tr(
"Change Label Alignment" ) );
373 mLabel->setVAlign(
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mVAlignmentComboBox->currentAlignment() ) ) );
375 mLabel->endCommand();
379void QgsLayoutLabelWidget::setGuiElementValues()
381 blockAllSignals(
true );
382 mTextEdit->setPlainText( mLabel->text() );
383 mTextEdit->moveCursor( QTextCursor::End, QTextCursor::MoveAnchor );
384 mMarginXDoubleSpinBox->setValue( mLabel->marginX() );
385 mMarginYDoubleSpinBox->setValue( mLabel->marginY() );
388 mHAlignmentComboBox->setCurrentAlignment( mLabel->hAlign() );
389 mVAlignmentComboBox->setCurrentAlignment( mLabel->vAlign() );
391 mFontButton->setTextFormat( mLabel->textFormat() );
395 blockAllSignals(
false );
398void QgsLayoutLabelWidget::blockAllSignals(
bool block )
400 mTextEdit->blockSignals( block );
401 mHtmlCheckBox->blockSignals( block );
402 mMarginXDoubleSpinBox->blockSignals( block );
403 mMarginYDoubleSpinBox->blockSignals( block );
404 mHAlignmentComboBox->blockSignals( block );
405 mVAlignmentComboBox->blockSignals( block );
406 mFontButton->blockSignals( block );
void changed()
Emitted when the alignment is changed.
A generic dialog for building expression strings.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static QString findAndSelectActiveExpression(QgsCodeEditor *editor, const QString &pattern=QString())
Find the expression under the cursor in the given editor and select it.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
A layout item subclass for text labels.
void convertToStaticText()
Converts the label's text() to a static string, by evaluating any expressions included in the text an...
@ ModeHtml
Label displays rendered HTML content.
Layout graphical items for displaying a map.
Base class for graphical items within a QgsLayout.
@ UndoLabelMargin
Label margin.
@ UndoLabelFont
Label font.
@ UndoLabelText
Label text.
int type() const override
Returns a unique graphics item type identifier.
void changed()
Emitted when the object's properties change.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
QgsVectorLayer * layer() const
Returns the vector layer associated with the layout's context.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
QgsLayoutReportContext & reportContext()
Returns a reference to the layout's report context, which stores information relating to the current ...
Interface for master layout type objects, such as print layouts and reports.
A class to represent a 2D point.
A rectangle specified with double values.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
QgsPointXY center() const
Returns the center point of the rectangle.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
Represents a vector layer which manages a vector based data sets.