27 #include <QColorDialog>
28 #include <QFontDialog>
40 connect( mHtmlCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutLabelWidget::mHtmlCheckBox_stateChanged );
41 connect( mTextEdit, &QPlainTextEdit::textChanged,
this, &QgsLayoutLabelWidget::mTextEdit_textChanged );
42 connect( mInsertExpressionButton, &QPushButton::clicked,
this, &QgsLayoutLabelWidget::mInsertExpressionButton_clicked );
43 connect( mMarginXDoubleSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLabelWidget::mMarginXDoubleSpinBox_valueChanged );
44 connect( mMarginYDoubleSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLabelWidget::mMarginYDoubleSpinBox_valueChanged );
46 connect( mCenterRadioButton, &QRadioButton::clicked,
this, &QgsLayoutLabelWidget::mCenterRadioButton_clicked );
47 connect( mLeftRadioButton, &QRadioButton::clicked,
this, &QgsLayoutLabelWidget::mLeftRadioButton_clicked );
48 connect( mRightRadioButton, &QRadioButton::clicked,
this, &QgsLayoutLabelWidget::mRightRadioButton_clicked );
49 connect( mTopRadioButton, &QRadioButton::clicked,
this, &QgsLayoutLabelWidget::mTopRadioButton_clicked );
50 connect( mBottomRadioButton, &QRadioButton::clicked,
this, &QgsLayoutLabelWidget::mBottomRadioButton_clicked );
51 connect( mMiddleRadioButton, &QRadioButton::clicked,
this, &QgsLayoutLabelWidget::mMiddleRadioButton_clicked );
58 mainLayout->addWidget( mItemPropertiesWidget );
60 mFontColorButton->setColorDialogTitle( tr(
"Select Font Color" ) );
61 mFontColorButton->setContext( QStringLiteral(
"composer" ) );
62 mFontColorButton->setAllowOpacity(
true );
64 mMarginXDoubleSpinBox->setClearValue( 0.0 );
65 mMarginYDoubleSpinBox->setClearValue( 0.0 );
67 setGuiElementValues();
71 connect( mJustifyRadioButton, &QRadioButton::clicked,
this, &QgsLayoutLabelWidget::justifyClicked );
73 mDynamicTextMenu =
new QMenu(
this );
74 mDynamicTextButton->setMenu( mDynamicTextMenu );
76 connect( mDynamicTextMenu, &QMenu::aboutToShow,
this, [ = ]
78 mDynamicTextMenu->clear();
79 if ( mLabel->layout() )
82 buildInsertDynamicTextMenu( mLabel->layout(), mDynamicTextMenu, [ = ]( const QString & expression )
84 mLabel->beginCommand( tr(
"Insert dynamic text" ) );
85 mTextEdit->insertPlainText(
"[%" + expression +
"%]" );
91 QMenu *expressionMenu =
new QMenu(
this );
92 QAction *convertToStaticAction =
new QAction( tr(
"Convert to Static Text" ),
this );
93 expressionMenu->addAction( convertToStaticAction );
95 mInsertExpressionButton->setMenu( expressionMenu );
100 if ( mItemPropertiesWidget )
107 auto addExpression = [&callback]( QMenu * menu,
const QString & name,
const QString & expression )
109 QAction *action =
new QAction( name, menu );
110 connect( action, &QAction::triggered, action, [callback, expression]
112 callback( expression );
114 menu->addAction( action );
117 QMenu *dateMenu =
new QMenu( tr(
"Current Date" ), menu );
118 for (
const std::pair< QString, QString > &expression :
120 std::make_pair( tr(
"ISO Format (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral(
"yyyy-MM-dd" ) ) ), QStringLiteral(
"format_date(now(), 'yyyy-MM-dd')" ) ),
121 std::make_pair( tr(
"Day/Month/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral(
"dd/MM/yyyy" ) ) ), QStringLiteral(
"format_date(now(), 'dd/MM/yyyy')" ) ),
122 std::make_pair( tr(
"Month/Day/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral(
"MM/dd/yyyy" ) ) ), QStringLiteral(
"format_date(now(), 'MM/dd/yyyy')" ) ),
125 addExpression( dateMenu, expression.first, expression.second );
127 menu->addMenu( dateMenu );
129 QMenu *mapsMenu =
new QMenu( tr(
"Map Properties" ), menu );
130 QList< QgsLayoutItemMap * > maps;
135 if ( map->id().isEmpty() )
138 QMenu *mapMenu =
new QMenu( map->displayName(), mapsMenu );
139 for (
const std::pair< QString, QString > &expression :
141 std::make_pair( tr(
"Scale (%1)" ).arg( map->scale() ), QStringLiteral(
"item_variables('%1')['map_scale']" ).arg( map->id() ) ),
142 std::make_pair( tr(
"Rotation (%1)" ).arg( map->rotation() ), QStringLiteral(
"item_variables('%1')['map_rotation']" ).arg( map->id() ) ),
145 addExpression( mapMenu, expression.first, expression.second );
147 mapMenu->addSeparator();
148 for (
const std::pair< QString, QString > &expression :
150 std::make_pair( tr(
"CRS Identifier (%1)" ).arg( map->crs().authid() ), QStringLiteral(
"item_variables('%1')['map_crs']" ).arg( map->id() ) ),
151 std::make_pair( tr(
"CRS Name (%1)" ).arg( map->crs().description() ), QStringLiteral(
"item_variables('%1')['map_crs_description']" ).arg( map->id() ) ),
152 std::make_pair( tr(
"Ellipsoid Name (%1)" ).arg( map->crs().ellipsoidAcronym() ), QStringLiteral(
"item_variables('%1')['map_crs_ellipsoid']" ).arg( map->id() ) ),
153 std::make_pair( tr(
"Units (%1)" ).arg(
QgsUnitTypes::toString( map->crs().mapUnits() ) ), QStringLiteral(
"item_variables('%1')['map_units']" ).arg( map->id() ) ),
154 std::make_pair( tr(
"Projection (%1)" ).arg( map->crs().operation().description() ), QStringLiteral(
"item_variables('%1')['map_crs_projection']" ).arg( map->id() ) ),
157 addExpression( mapMenu, expression.first, expression.second );
159 mapMenu->addSeparator();
163 for (
const std::pair< QString, QString > &expression :
165 std::make_pair( tr(
"Center (X) (%1)" ).arg( center.
x() ), QStringLiteral(
"x(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ),
166 std::make_pair( tr(
"Center (Y) (%1)" ).arg( center.
y() ), QStringLiteral(
"y(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ),
167 std::make_pair( tr(
"X Minimum (%1)" ).arg( mapExtent.
xMinimum() ), QStringLiteral(
"x_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ),
168 std::make_pair( tr(
"Y Minimum (%1)" ).arg( mapExtent.
yMinimum() ), QStringLiteral(
"y_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ),
169 std::make_pair( tr(
"X Maximum (%1)" ).arg( mapExtent.
xMaximum() ), QStringLiteral(
"x_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ),
170 std::make_pair( tr(
"Y Maximum (%1)" ).arg( mapExtent.
yMaximum() ), QStringLiteral(
"y_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ),
173 addExpression( mapMenu, expression.first, expression.second );
175 mapMenu->addSeparator();
176 for (
const std::pair< QString, QString > &expression :
178 std::make_pair( tr(
"Layer Credits" ), QStringLiteral(
"array_to_string(map_credits('%1'))" ).arg( map->id() ) ),
181 addExpression( mapMenu, expression.first, expression.second );
183 mapsMenu->addMenu( mapMenu );
185 menu->addMenu( mapsMenu );
186 menu->addSeparator();
192 QMenu *fieldsMenu =
new QMenu( tr(
"Field" ), menu );
198 menu->addMenu( fieldsMenu );
199 menu->addSeparator();
202 for (
const std::pair< QString, QString > &expression :
204 std::make_pair( tr(
"Layout Name" ), QStringLiteral(
"@layout_name" ) ),
205 std::make_pair( tr(
"Layout Page Number" ), QStringLiteral(
"@layout_page" ) ),
206 std::make_pair( tr(
"Layout Page Count" ), QStringLiteral(
"@layout_numpages" ) )
209 addExpression( menu, expression.first, expression.second );
211 menu->addSeparator();
212 for (
const std::pair< QString, QString > &expression :
214 std::make_pair( tr(
"Project Author" ), QStringLiteral(
"@project_author" ) ),
215 std::make_pair( tr(
"Project Title" ), QStringLiteral(
"@project_title" ) ),
216 std::make_pair( tr(
"Project Path" ), QStringLiteral(
"@project_path" ) )
219 addExpression( menu, expression.first, expression.second );
221 menu->addSeparator();
222 for (
const std::pair< QString, QString > &expression :
224 std::make_pair( tr(
"Current User Name" ), QStringLiteral(
"@user_full_name" ) ),
225 std::make_pair( tr(
"Current User Account" ), QStringLiteral(
"@user_account_name" ) )
228 addExpression( menu, expression.first, expression.second );
242 mLabel = qobject_cast< QgsLayoutItemLabel * >( item );
243 mItemPropertiesWidget->
setItem( mLabel );
250 setGuiElementValues();
255 void QgsLayoutLabelWidget::mHtmlCheckBox_stateChanged(
int state )
259 mVerticalAlignementLabel->setDisabled( state );
260 mTopRadioButton->setDisabled( state );
261 mMiddleRadioButton->setDisabled( state );
262 mBottomRadioButton->setDisabled( state );
264 mLabel->beginCommand( tr(
"Change Label Mode" ) );
265 mLabel->blockSignals(
true );
267 mLabel->setText( mTextEdit->toPlainText() );
269 mLabel->blockSignals(
false );
270 mLabel->endCommand();
274 void QgsLayoutLabelWidget::mTextEdit_textChanged()
279 mLabel->blockSignals(
true );
280 mLabel->setText( mTextEdit->toPlainText() );
282 mLabel->blockSignals(
false );
283 mLabel->endCommand();
287 void QgsLayoutLabelWidget::fontChanged()
291 QFont newFont = mFontButton->currentFont();
293 mLabel->setFont( newFont );
295 mLabel->endCommand();
299 void QgsLayoutLabelWidget::justifyClicked()
303 mLabel->beginCommand( tr(
"Change Label Alignment" ) );
304 mLabel->setHAlign( Qt::AlignJustify );
306 mLabel->endCommand();
310 void QgsLayoutLabelWidget::mMarginXDoubleSpinBox_valueChanged(
double d )
315 mLabel->setMarginX( d );
317 mLabel->endCommand();
321 void QgsLayoutLabelWidget::mMarginYDoubleSpinBox_valueChanged(
double d )
326 mLabel->setMarginY( d );
328 mLabel->endCommand();
332 void QgsLayoutLabelWidget::mFontColorButton_colorChanged(
const QColor &newLabelColor )
340 mLabel->setFontColor( newLabelColor );
342 mLabel->endCommand();
345 void QgsLayoutLabelWidget::mInsertExpressionButton_clicked()
352 QString selText = mTextEdit->textCursor().selectedText();
355 selText = selText.replace( QChar( 0x2029 ), QChar(
'\n' ) );
358 if ( selText.startsWith( QLatin1String(
"[%" ) ) && selText.endsWith( QLatin1String(
"%]" ) ) )
359 selText = selText.mid( 2, selText.size() - 4 );
367 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
368 if ( exprDlg.exec() == QDialog::Accepted )
370 QString expression = exprDlg.expressionText();
371 if ( !expression.isEmpty() )
373 mLabel->beginCommand( tr(
"Insert expression" ) );
374 mTextEdit->insertPlainText(
"[%" + expression +
"%]" );
375 mLabel->endCommand();
380 void QgsLayoutLabelWidget::mCenterRadioButton_clicked()
384 mLabel->beginCommand( tr(
"Change Label Alignment" ) );
385 mLabel->setHAlign( Qt::AlignHCenter );
387 mLabel->endCommand();
391 void QgsLayoutLabelWidget::mRightRadioButton_clicked()
395 mLabel->beginCommand( tr(
"Change Label Alignment" ) );
396 mLabel->setHAlign( Qt::AlignRight );
398 mLabel->endCommand();
402 void QgsLayoutLabelWidget::mLeftRadioButton_clicked()
406 mLabel->beginCommand( tr(
"Change Label Alignment" ) );
407 mLabel->setHAlign( Qt::AlignLeft );
409 mLabel->endCommand();
413 void QgsLayoutLabelWidget::mTopRadioButton_clicked()
417 mLabel->beginCommand( tr(
"Change Label Alignment" ) );
418 mLabel->setVAlign( Qt::AlignTop );
420 mLabel->endCommand();
424 void QgsLayoutLabelWidget::mBottomRadioButton_clicked()
428 mLabel->beginCommand( tr(
"Change Label Alignment" ) );
429 mLabel->setVAlign( Qt::AlignBottom );
431 mLabel->endCommand();
435 void QgsLayoutLabelWidget::mMiddleRadioButton_clicked()
439 mLabel->beginCommand( tr(
"Change Label Alignment" ) );
440 mLabel->setVAlign( Qt::AlignVCenter );
442 mLabel->endCommand();
446 void QgsLayoutLabelWidget::setGuiElementValues()
448 blockAllSignals(
true );
449 mTextEdit->setPlainText( mLabel->text() );
450 mTextEdit->moveCursor( QTextCursor::End, QTextCursor::MoveAnchor );
451 mMarginXDoubleSpinBox->setValue( mLabel->marginX() );
452 mMarginYDoubleSpinBox->setValue( mLabel->marginY() );
454 mTopRadioButton->setChecked( mLabel->vAlign() == Qt::AlignTop );
455 mMiddleRadioButton->setChecked( mLabel->vAlign() == Qt::AlignVCenter );
456 mBottomRadioButton->setChecked( mLabel->vAlign() == Qt::AlignBottom );
457 mLeftRadioButton->setChecked( mLabel->hAlign() == Qt::AlignLeft );
458 mJustifyRadioButton->setChecked( mLabel->hAlign() == Qt::AlignJustify );
459 mCenterRadioButton->setChecked( mLabel->hAlign() == Qt::AlignHCenter );
460 mRightRadioButton->setChecked( mLabel->hAlign() == Qt::AlignRight );
461 mFontColorButton->setColor( mLabel->fontColor() );
462 mFontButton->setCurrentFont( mLabel->font() );
468 blockAllSignals(
false );
471 void QgsLayoutLabelWidget::blockAllSignals(
bool block )
473 mTextEdit->blockSignals( block );
474 mHtmlCheckBox->blockSignals( block );
475 mMarginXDoubleSpinBox->blockSignals( block );
476 mMarginYDoubleSpinBox->blockSignals( block );
477 mTopRadioButton->blockSignals( block );
478 mMiddleRadioButton->blockSignals( block );
479 mBottomRadioButton->blockSignals( block );
480 mLeftRadioButton->blockSignals( block );
481 mCenterRadioButton->blockSignals( block );
482 mRightRadioButton->blockSignals( block );
483 mJustifyRadioButton->blockSignals( block );
484 mFontColorButton->blockSignals( block );
485 mFontButton->blockSignals( block );
A generic dialog for building expression strings.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Encapsulate a field in an attribute table or data source.
QString displayName() const
Returns the name to use when displaying this field.
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.
@ ModeFont
Label displays text rendered using a single font.
Layout graphical items for displaying a map.
Base class for graphical items within a QgsLayout.
@ UndoLabelFontColor
Label color.
@ 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.
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 yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
static Q_INVOKABLE QString toString(QgsUnitTypes::DistanceUnit unit)
Returns a translated string representing a distance unit.
Represents a vector layer which manages a vector based data sets.
QgsFields fields() const FINAL
Returns the list of fields of this layer.