1 /***************************************************************************
2 qgslayoutshapewidget.cpp
3 --------------------------
4 begin : November 2009
5 copyright : (C) 2009 by Marco Hugentobler
6 email : marco@hugis.net
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 "qgslayoutshapewidget.h"
19 #include "qgsstyle.h"
20 #include "qgslayoutitemshape.h"
21 #include "qgslayout.h"
22 #include "qgslayoutundostack.h"
23 #include "qgsvectorlayer.h"
24
QgsLayoutShapeWidget(QgsLayoutItemShape * shape)25 QgsLayoutShapeWidget::QgsLayoutShapeWidget( QgsLayoutItemShape *shape )
26 : QgsLayoutItemBaseWidget( nullptr, shape )
27 , mShape( shape )
28 {
29 Q_ASSERT( mShape );
30
31 setupUi( this );
32 connect( mShapeComboBox, &QComboBox::currentTextChanged, this, &QgsLayoutShapeWidget::mShapeComboBox_currentIndexChanged );
33 connect( mCornerRadiusSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutShapeWidget::mCornerRadiusSpinBox_valueChanged );
34 setPanelTitle( tr( "Shape Properties" ) );
35
36 //add widget for general composer item properties
37 mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, shape );
38 //shapes don't use background or frame, since the symbol style is set through a QgsSymbolSelectorWidget
39 mItemPropertiesWidget->showBackgroundGroup( false );
40 mItemPropertiesWidget->showFrameGroup( false );
41 mainLayout->addWidget( mItemPropertiesWidget );
42
43 blockAllSignals( true );
44
45 //shape types
46 mShapeComboBox->addItem( tr( "Rectangle" ), QgsLayoutItemShape::Rectangle );
47 mShapeComboBox->addItem( tr( "Ellipse" ), QgsLayoutItemShape::Ellipse );
48 mShapeComboBox->addItem( tr( "Triangle" ), QgsLayoutItemShape::Triangle );
49
50 mShapeStyleButton->setSymbolType( QgsSymbol::Fill );
51 mRadiusUnitsComboBox->linkToWidget( mCornerRadiusSpinBox );
52 mRadiusUnitsComboBox->setConverter( &mShape->layout()->renderContext().measurementConverter() );
53
54 setGuiElementValues();
55
56 blockAllSignals( false );
57
58 connect( mShape, &QgsLayoutObject::changed, this, &QgsLayoutShapeWidget::setGuiElementValues );
59 mShapeStyleButton->registerExpressionContextGenerator( mShape );
60
61 connect( mShapeStyleButton, &QgsSymbolButton::changed, this, &QgsLayoutShapeWidget::symbolChanged );
62 connect( mRadiusUnitsComboBox, &QgsLayoutUnitsComboBox::changed, this, &QgsLayoutShapeWidget::radiusUnitsChanged );
63
64 mShapeStyleButton->setLayer( coverageLayer() );
65 if ( mShape->layout() )
66 {
67 connect( &mShape->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, mShapeStyleButton, &QgsSymbolButton::setLayer );
68 }
69 }
70
setMasterLayout(QgsMasterLayoutInterface * masterLayout)71 void QgsLayoutShapeWidget::setMasterLayout( QgsMasterLayoutInterface *masterLayout )
72 {
73 if ( mItemPropertiesWidget )
74 mItemPropertiesWidget->setMasterLayout( masterLayout );
75 }
76
setNewItem(QgsLayoutItem * item)77 bool QgsLayoutShapeWidget::setNewItem( QgsLayoutItem *item )
78 {
79 if ( item->type() != QgsLayoutItemRegistry::LayoutShape )
80 return false;
81
82 if ( mShape )
83 {
84 disconnect( mShape, &QgsLayoutObject::changed, this, &QgsLayoutShapeWidget::setGuiElementValues );
85 }
86
87 mShape = qobject_cast< QgsLayoutItemShape * >( item );
88 mItemPropertiesWidget->setItem( mShape );
89
90 if ( mShape )
91 {
92 connect( mShape, &QgsLayoutObject::changed, this, &QgsLayoutShapeWidget::setGuiElementValues );
93 mShapeStyleButton->registerExpressionContextGenerator( mShape );
94 }
95
96 setGuiElementValues();
97
98 return true;
99 }
100
blockAllSignals(bool block)101 void QgsLayoutShapeWidget::blockAllSignals( bool block )
102 {
103 mShapeComboBox->blockSignals( block );
104 mCornerRadiusSpinBox->blockSignals( block );
105 mRadiusUnitsComboBox->blockSignals( block );
106 mShapeStyleButton->blockSignals( block );
107 }
108
setGuiElementValues()109 void QgsLayoutShapeWidget::setGuiElementValues()
110 {
111 if ( !mShape )
112 {
113 return;
114 }
115
116 blockAllSignals( true );
117
118 mShapeStyleButton->setSymbol( mShape->symbol()->clone() );
119
120 mCornerRadiusSpinBox->setValue( mShape->cornerRadius().length() );
121 mRadiusUnitsComboBox->setUnit( mShape->cornerRadius().units() );
122
123 mShapeComboBox->setCurrentIndex( mShapeComboBox->findData( mShape->shapeType() ) );
124 toggleRadiusSpin( mShape->shapeType() );
125
126 blockAllSignals( false );
127 }
128
symbolChanged()129 void QgsLayoutShapeWidget::symbolChanged()
130 {
131 if ( !mShape )
132 return;
133
134 mShape->layout()->undoStack()->beginCommand( mShape, tr( "Change Shape Style" ), QgsLayoutItem::UndoShapeStyle );
135 mShape->setSymbol( mShapeStyleButton->clonedSymbol<QgsFillSymbol>() );
136 mShape->layout()->undoStack()->endCommand();
137 }
138
mCornerRadiusSpinBox_valueChanged(double val)139 void QgsLayoutShapeWidget::mCornerRadiusSpinBox_valueChanged( double val )
140 {
141 if ( !mShape )
142 return;
143
144 mShape->layout()->undoStack()->beginCommand( mShape, tr( "Change Shape Radius" ), QgsLayoutItem::UndoShapeCornerRadius );
145 mShape->setCornerRadius( QgsLayoutMeasurement( val, mRadiusUnitsComboBox->unit() ) );
146 mShape->layout()->undoStack()->endCommand();
147 mShape->update();
148 }
149
radiusUnitsChanged()150 void QgsLayoutShapeWidget::radiusUnitsChanged()
151 {
152 if ( !mShape )
153 return;
154
155 mShape->layout()->undoStack()->beginCommand( mShape, tr( "Change Shape Radius" ), QgsLayoutItem::UndoShapeCornerRadius );
156 mShape->setCornerRadius( QgsLayoutMeasurement( mCornerRadiusSpinBox->value(), mRadiusUnitsComboBox->unit() ) );
157 mShape->layout()->undoStack()->endCommand();
158 mShape->update();
159 }
160
mShapeComboBox_currentIndexChanged(const QString &)161 void QgsLayoutShapeWidget::mShapeComboBox_currentIndexChanged( const QString & )
162 {
163 if ( !mShape )
164 {
165 return;
166 }
167
168 mShape->layout()->undoStack()->beginCommand( mShape, tr( "Change Shape Type" ) );
169 QgsLayoutItemShape::Shape shape = static_cast< QgsLayoutItemShape::Shape >( mShapeComboBox->currentData().toInt() );
170 mShape->setShapeType( shape );
171 toggleRadiusSpin( shape );
172 mShape->update();
173 mShape->layout()->undoStack()->endCommand();
174 }
175
toggleRadiusSpin(QgsLayoutItemShape::Shape shape)176 void QgsLayoutShapeWidget::toggleRadiusSpin( QgsLayoutItemShape::Shape shape )
177 {
178 switch ( shape )
179 {
180 case QgsLayoutItemShape::Ellipse:
181 case QgsLayoutItemShape::Triangle:
182 {
183 mCornerRadiusSpinBox->setEnabled( false );
184 break;
185 }
186 case QgsLayoutItemShape::Rectangle:
187 {
188 mCornerRadiusSpinBox->setEnabled( true );
189 break;
190 }
191 }
192 }
193