QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgslayoutlabelwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutlabelwidget.cpp
3  ------------------------
4  begin : October 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 
18 #include "qgslayoutlabelwidget.h"
19 #include "qgslayoutitemlabel.h"
20 #include "qgslayout.h"
22 #include "qgsguiutils.h"
23 
24 #include <QColorDialog>
25 #include <QFontDialog>
26 #include <QWidget>
27 
29  : QgsLayoutItemBaseWidget( nullptr, label )
30  , mLabel( label )
31 {
32  Q_ASSERT( mLabel );
33 
34  setupUi( this );
35  connect( mHtmlCheckBox, &QCheckBox::stateChanged, this, &QgsLayoutLabelWidget::mHtmlCheckBox_stateChanged );
36  connect( mTextEdit, &QPlainTextEdit::textChanged, this, &QgsLayoutLabelWidget::mTextEdit_textChanged );
37  connect( mInsertExpressionButton, &QPushButton::clicked, this, &QgsLayoutLabelWidget::mInsertExpressionButton_clicked );
38  connect( mMarginXDoubleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutLabelWidget::mMarginXDoubleSpinBox_valueChanged );
39  connect( mMarginYDoubleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutLabelWidget::mMarginYDoubleSpinBox_valueChanged );
40  connect( mFontColorButton, &QgsColorButton::colorChanged, this, &QgsLayoutLabelWidget::mFontColorButton_colorChanged );
41  connect( mCenterRadioButton, &QRadioButton::clicked, this, &QgsLayoutLabelWidget::mCenterRadioButton_clicked );
42  connect( mLeftRadioButton, &QRadioButton::clicked, this, &QgsLayoutLabelWidget::mLeftRadioButton_clicked );
43  connect( mRightRadioButton, &QRadioButton::clicked, this, &QgsLayoutLabelWidget::mRightRadioButton_clicked );
44  connect( mTopRadioButton, &QRadioButton::clicked, this, &QgsLayoutLabelWidget::mTopRadioButton_clicked );
45  connect( mBottomRadioButton, &QRadioButton::clicked, this, &QgsLayoutLabelWidget::mBottomRadioButton_clicked );
46  connect( mMiddleRadioButton, &QRadioButton::clicked, this, &QgsLayoutLabelWidget::mMiddleRadioButton_clicked );
47  setPanelTitle( tr( "Label Properties" ) );
48 
49  mFontButton->setMode( QgsFontButton::ModeQFont );
50 
51  //add widget for general composer item properties
52  mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, label );
53  mainLayout->addWidget( mItemPropertiesWidget );
54 
55  mFontColorButton->setColorDialogTitle( tr( "Select Font Color" ) );
56  mFontColorButton->setContext( QStringLiteral( "composer" ) );
57  mFontColorButton->setAllowOpacity( true );
58 
59  mMarginXDoubleSpinBox->setClearValue( 0.0 );
60  mMarginYDoubleSpinBox->setClearValue( 0.0 );
61 
62  setGuiElementValues();
63  connect( mLabel, &QgsLayoutObject::changed, this, &QgsLayoutLabelWidget::setGuiElementValues );
64 
65  connect( mFontButton, &QgsFontButton::changed, this, &QgsLayoutLabelWidget::fontChanged );
66  connect( mJustifyRadioButton, &QRadioButton::clicked, this, &QgsLayoutLabelWidget::justifyClicked );
67 }
68 
70 {
71  if ( mItemPropertiesWidget )
72  mItemPropertiesWidget->setMasterLayout( masterLayout );
73 }
74 
76 {
78  return false;
79 
80  if ( mLabel )
81  {
82  disconnect( mLabel, &QgsLayoutObject::changed, this, &QgsLayoutLabelWidget::setGuiElementValues );
83  }
84 
85  mLabel = qobject_cast< QgsLayoutItemLabel * >( item );
86  mItemPropertiesWidget->setItem( mLabel );
87 
88  if ( mLabel )
89  {
90  connect( mLabel, &QgsLayoutObject::changed, this, &QgsLayoutLabelWidget::setGuiElementValues );
91  }
92 
93  setGuiElementValues();
94 
95  return true;
96 }
97 
98 void QgsLayoutLabelWidget::mHtmlCheckBox_stateChanged( int state )
99 {
100  if ( mLabel )
101  {
102  mVerticalAlignementLabel->setDisabled( state );
103  mTopRadioButton->setDisabled( state );
104  mMiddleRadioButton->setDisabled( state );
105  mBottomRadioButton->setDisabled( state );
106 
107  mLabel->beginCommand( tr( "Change Label Mode" ) );
108  mLabel->blockSignals( true );
109  mLabel->setMode( state ? QgsLayoutItemLabel::ModeHtml : QgsLayoutItemLabel::ModeFont );
110  mLabel->setText( mTextEdit->toPlainText() );
111  mLabel->update();
112  mLabel->blockSignals( false );
113  mLabel->endCommand();
114  }
115 }
116 
117 void QgsLayoutLabelWidget::mTextEdit_textChanged()
118 {
119  if ( mLabel )
120  {
121  mLabel->beginCommand( tr( "Change Label Text" ), QgsLayoutItem::UndoLabelText );
122  mLabel->blockSignals( true );
123  mLabel->setText( mTextEdit->toPlainText() );
124  mLabel->update();
125  mLabel->blockSignals( false );
126  mLabel->endCommand();
127  }
128 }
129 
130 void QgsLayoutLabelWidget::fontChanged()
131 {
132  if ( mLabel )
133  {
134  QFont newFont = mFontButton->currentFont();
135  mLabel->beginCommand( tr( "Change Label Font" ), QgsLayoutItem::UndoLabelFont );
136  mLabel->setFont( newFont );
137  mLabel->update();
138  mLabel->endCommand();
139  }
140 }
141 
142 void QgsLayoutLabelWidget::justifyClicked()
143 {
144  if ( mLabel )
145  {
146  mLabel->beginCommand( tr( "Change Label Alignment" ) );
147  mLabel->setHAlign( Qt::AlignJustify );
148  mLabel->update();
149  mLabel->endCommand();
150  }
151 }
152 
153 void QgsLayoutLabelWidget::mMarginXDoubleSpinBox_valueChanged( double d )
154 {
155  if ( mLabel )
156  {
157  mLabel->beginCommand( tr( "Change Label Margin" ), QgsLayoutItem::UndoLabelMargin );
158  mLabel->setMarginX( d );
159  mLabel->update();
160  mLabel->endCommand();
161  }
162 }
163 
164 void QgsLayoutLabelWidget::mMarginYDoubleSpinBox_valueChanged( double d )
165 {
166  if ( mLabel )
167  {
168  mLabel->beginCommand( tr( "Change Label Margin" ), QgsLayoutItem::UndoLabelMargin );
169  mLabel->setMarginY( d );
170  mLabel->update();
171  mLabel->endCommand();
172  }
173 }
174 
175 void QgsLayoutLabelWidget::mFontColorButton_colorChanged( const QColor &newLabelColor )
176 {
177  if ( !mLabel )
178  {
179  return;
180  }
181 
182  mLabel->beginCommand( tr( "Change Label Color" ), QgsLayoutItem::UndoLabelFontColor );
183  mLabel->setFontColor( newLabelColor );
184  mLabel->update();
185  mLabel->endCommand();
186 }
187 
188 void QgsLayoutLabelWidget::mInsertExpressionButton_clicked()
189 {
190  if ( !mLabel )
191  {
192  return;
193  }
194 
195  QString selText = mTextEdit->textCursor().selectedText();
196 
197  // html editor replaces newlines with Paragraph Separator characters - see https://github.com/qgis/QGIS/issues/27568
198  selText = selText.replace( QChar( 0x2029 ), QChar( '\n' ) );
199 
200  // edit the selected expression if there's one
201  if ( selText.startsWith( QLatin1String( "[%" ) ) && selText.endsWith( QLatin1String( "%]" ) ) )
202  selText = selText.mid( 2, selText.size() - 4 );
203 
204  // use the atlas coverage layer, if any
205  QgsVectorLayer *layer = coverageLayer();
206 
207  QgsExpressionContext context = mLabel->createExpressionContext();
208  QgsExpressionBuilderDialog exprDlg( layer, selText, this, QStringLiteral( "generic" ), context );
209 
210  exprDlg.setWindowTitle( tr( "Insert Expression" ) );
211  if ( exprDlg.exec() == QDialog::Accepted )
212  {
213  QString expression = exprDlg.expressionText();
214  if ( !expression.isEmpty() )
215  {
216  mLabel->beginCommand( tr( "Insert expression" ) );
217  mTextEdit->insertPlainText( "[%" + expression + "%]" );
218  mLabel->endCommand();
219  }
220  }
221 }
222 
223 void QgsLayoutLabelWidget::mCenterRadioButton_clicked()
224 {
225  if ( mLabel )
226  {
227  mLabel->beginCommand( tr( "Change Label Alignment" ) );
228  mLabel->setHAlign( Qt::AlignHCenter );
229  mLabel->update();
230  mLabel->endCommand();
231  }
232 }
233 
234 void QgsLayoutLabelWidget::mRightRadioButton_clicked()
235 {
236  if ( mLabel )
237  {
238  mLabel->beginCommand( tr( "Change Label Alignment" ) );
239  mLabel->setHAlign( Qt::AlignRight );
240  mLabel->update();
241  mLabel->endCommand();
242  }
243 }
244 
245 void QgsLayoutLabelWidget::mLeftRadioButton_clicked()
246 {
247  if ( mLabel )
248  {
249  mLabel->beginCommand( tr( "Change Label Alignment" ) );
250  mLabel->setHAlign( Qt::AlignLeft );
251  mLabel->update();
252  mLabel->endCommand();
253  }
254 }
255 
256 void QgsLayoutLabelWidget::mTopRadioButton_clicked()
257 {
258  if ( mLabel )
259  {
260  mLabel->beginCommand( tr( "Change Label Alignment" ) );
261  mLabel->setVAlign( Qt::AlignTop );
262  mLabel->update();
263  mLabel->endCommand();
264  }
265 }
266 
267 void QgsLayoutLabelWidget::mBottomRadioButton_clicked()
268 {
269  if ( mLabel )
270  {
271  mLabel->beginCommand( tr( "Change Label Alignment" ) );
272  mLabel->setVAlign( Qt::AlignBottom );
273  mLabel->update();
274  mLabel->endCommand();
275  }
276 }
277 
278 void QgsLayoutLabelWidget::mMiddleRadioButton_clicked()
279 {
280  if ( mLabel )
281  {
282  mLabel->beginCommand( tr( "Change Label Alignment" ) );
283  mLabel->setVAlign( Qt::AlignVCenter );
284  mLabel->update();
285  mLabel->endCommand();
286  }
287 }
288 
289 void QgsLayoutLabelWidget::setGuiElementValues()
290 {
291  blockAllSignals( true );
292  mTextEdit->setPlainText( mLabel->text() );
293  mTextEdit->moveCursor( QTextCursor::End, QTextCursor::MoveAnchor );
294  mMarginXDoubleSpinBox->setValue( mLabel->marginX() );
295  mMarginYDoubleSpinBox->setValue( mLabel->marginY() );
296  mHtmlCheckBox->setChecked( mLabel->mode() == QgsLayoutItemLabel::ModeHtml );
297  mTopRadioButton->setChecked( mLabel->vAlign() == Qt::AlignTop );
298  mMiddleRadioButton->setChecked( mLabel->vAlign() == Qt::AlignVCenter );
299  mBottomRadioButton->setChecked( mLabel->vAlign() == Qt::AlignBottom );
300  mLeftRadioButton->setChecked( mLabel->hAlign() == Qt::AlignLeft );
301  mJustifyRadioButton->setChecked( mLabel->hAlign() == Qt::AlignJustify );
302  mCenterRadioButton->setChecked( mLabel->hAlign() == Qt::AlignHCenter );
303  mRightRadioButton->setChecked( mLabel->hAlign() == Qt::AlignRight );
304  mFontColorButton->setColor( mLabel->fontColor() );
305  mFontButton->setCurrentFont( mLabel->font() );
306  mVerticalAlignementLabel->setDisabled( mLabel->mode() == QgsLayoutItemLabel::ModeHtml );
307  mTopRadioButton->setDisabled( mLabel->mode() == QgsLayoutItemLabel::ModeHtml );
308  mMiddleRadioButton->setDisabled( mLabel->mode() == QgsLayoutItemLabel::ModeHtml );
309  mBottomRadioButton->setDisabled( mLabel->mode() == QgsLayoutItemLabel::ModeHtml );
310 
311  blockAllSignals( false );
312 }
313 
314 void QgsLayoutLabelWidget::blockAllSignals( bool block )
315 {
316  mTextEdit->blockSignals( block );
317  mHtmlCheckBox->blockSignals( block );
318  mMarginXDoubleSpinBox->blockSignals( block );
319  mMarginYDoubleSpinBox->blockSignals( block );
320  mTopRadioButton->blockSignals( block );
321  mMiddleRadioButton->blockSignals( block );
322  mBottomRadioButton->blockSignals( block );
323  mLeftRadioButton->blockSignals( block );
324  mCenterRadioButton->blockSignals( block );
325  mRightRadioButton->blockSignals( block );
326  mJustifyRadioButton->blockSignals( block );
327  mFontColorButton->blockSignals( block );
328  mFontButton->blockSignals( block );
329 }
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:370
QgsLayoutLabelWidget::setMasterLayout
void setMasterLayout(QgsMasterLayoutInterface *masterLayout) override
Sets the master layout associated with the item.
Definition: qgslayoutlabelwidget.cpp:69
qgslayoutlabelwidget.h
QgsLayoutItem::UndoLabelFontColor
@ UndoLabelFontColor
Label color.
Definition: qgslayoutitem.h:250
QgsLayoutItemLabel::ModeFont
@ ModeFont
Label displays text rendered using a single font.
Definition: qgslayoutitemlabel.h:43
qgslayoutitemlabel.h
QgsLayoutObject::changed
void changed()
Emitted when the object's properties change.
QgsLayoutItemPropertiesWidget
A widget for controlling the common properties of layout items (e.g.
Definition: qgslayoutitemwidget.h:219
QgsLayoutItemBaseWidget::coverageLayer
QgsVectorLayer * coverageLayer() const
Returns the current layout context coverage layer (if set).
Definition: qgslayoutitemwidget.cpp:217
QgsColorButton::colorChanged
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
QgsLayoutItemPropertiesWidget::setMasterLayout
void setMasterLayout(QgsMasterLayoutInterface *masterLayout)
Sets the master layout associated with the item.
Definition: qgslayoutitemwidget.cpp:381
QgsLayoutItem::type
int type() const override
Returns a unique graphics item type identifier.
Definition: qgslayoutitem.cpp:124
QgsLayoutItem::UndoLabelText
@ UndoLabelText
Label text.
Definition: qgslayoutitem.h:247
QgsExpressionBuilderDialog
A generic dialog for building expression strings.
Definition: qgsexpressionbuilderdialog.h:31
QgsLayoutItem::UndoLabelMargin
@ UndoLabelMargin
Label margin.
Definition: qgslayoutitem.h:249
QgsLayoutItem
Base class for graphical items within a QgsLayout.
Definition: qgslayoutitem.h:113
QgsLayoutLabelWidget::QgsLayoutLabelWidget
QgsLayoutLabelWidget(QgsLayoutItemLabel *label)
constructor
Definition: qgslayoutlabelwidget.cpp:28
QgsPanelWidget::setPanelTitle
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
Definition: qgspanelwidget.h:44
qgslayout.h
QgsLayoutItemBaseWidget
A base class for property widgets for layout items.
Definition: qgslayoutitemwidget.h:123
QgsLayoutItemLabel::ModeHtml
@ ModeHtml
Label displays rendered HTML content.
Definition: qgslayoutitemlabel.h:44
QgsFontButton::ModeQFont
@ ModeQFont
Configure font settings for use with QFont objects.
Definition: qgsfontbutton.h:61
QgsLayoutItemRegistry::LayoutLabel
@ LayoutLabel
Label item.
Definition: qgslayoutitemregistry.h:319
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsLayoutItem::UndoLabelFont
@ UndoLabelFont
Label font.
Definition: qgslayoutitem.h:248
QgsLayoutItemLabel
A layout item subclass for text labels.
Definition: qgslayoutitemlabel.h:35
QgsMasterLayoutInterface
Interface for master layout type objects, such as print layouts and reports.
Definition: qgsmasterlayoutinterface.h:43
qgsguiutils.h
QgsLayoutLabelWidget::setNewItem
bool setNewItem(QgsLayoutItem *item) override
Attempts to update the widget to show the properties for the specified item.
Definition: qgslayoutlabelwidget.cpp:75
QgsLayoutItemPropertiesWidget::setItem
void setItem(QgsLayoutItem *item)
Sets the layout item.
Definition: qgslayoutitemwidget.cpp:362
qgsexpressionbuilderdialog.h
QgsFontButton::changed
void changed()
Emitted when the widget's text format settings are changed.