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.