1 /***************************************************************************
2 qgslayoutmarkerwidget.cpp
3 --------------------------
4 begin : April 2020
5 copyright : (C) 2020 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 "qgslayoutmarkerwidget.h"
19 #include "qgsstyle.h"
20 #include "qgslayoutitemmarker.h"
21 #include "qgslayout.h"
22 #include "qgslayoutundostack.h"
23 #include "qgsvectorlayer.h"
24 #include "qgslayoutitemmap.h"
25 #include "qgsmarkersymbol.h"
26
QgsLayoutMarkerWidget(QgsLayoutItemMarker * marker)27 QgsLayoutMarkerWidget::QgsLayoutMarkerWidget( QgsLayoutItemMarker *marker )
28 : QgsLayoutItemBaseWidget( nullptr, marker )
29 , mMarker( marker )
30 {
31 Q_ASSERT( mMarker );
32
33 setupUi( this );
34 setPanelTitle( tr( "Marker Properties" ) );
35
36 //add widget for general composer item properties
37 mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, marker );
38 mItemPropertiesWidget->showFrameGroup( false );
39 mainLayout->addWidget( mItemPropertiesWidget );
40
41 blockAllSignals( true );
42
43 mShapeStyleButton->setSymbolType( Qgis::SymbolType::Marker );
44
45 blockAllSignals( false );
46
47 connect( mMarker, &QgsLayoutObject::changed, this, &QgsLayoutMarkerWidget::setGuiElementValues );
48 mShapeStyleButton->registerExpressionContextGenerator( mMarker );
49
50 connect( mShapeStyleButton, &QgsSymbolButton::changed, this, &QgsLayoutMarkerWidget::symbolChanged );
51
52 connect( mRotationFromMapCheckBox, &QCheckBox::stateChanged, this, &QgsLayoutMarkerWidget::rotationFromMapCheckBoxChanged );
53 connect( mNorthOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutMarkerWidget::northOffsetSpinBoxChanged );
54 connect( mNorthTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutMarkerWidget::northTypeComboBoxChanged );
55
56 mNorthTypeComboBox->blockSignals( true );
57 mNorthTypeComboBox->addItem( tr( "Grid North" ), QgsLayoutNorthArrowHandler::GridNorth );
58 mNorthTypeComboBox->addItem( tr( "True North" ), QgsLayoutNorthArrowHandler::TrueNorth );
59 mNorthTypeComboBox->blockSignals( false );
60 mNorthOffsetSpinBox->setClearValue( 0.0 );
61
62 mShapeStyleButton->setLayer( coverageLayer() );
63 if ( mMarker->layout() )
64 {
65 connect( &mMarker->layout()->reportContext(), &QgsLayoutReportContext::layerChanged, mShapeStyleButton, &QgsSymbolButton::setLayer );
66 mMapComboBox->setCurrentLayout( mMarker->layout() );
67 mMapComboBox->setItemType( QgsLayoutItemRegistry::LayoutMap );
68 connect( mMapComboBox, &QgsLayoutItemComboBox::itemChanged, this, &QgsLayoutMarkerWidget::mapChanged );
69 }
70
71 setGuiElementValues();
72 }
73
setMasterLayout(QgsMasterLayoutInterface * masterLayout)74 void QgsLayoutMarkerWidget::setMasterLayout( QgsMasterLayoutInterface *masterLayout )
75 {
76 if ( mItemPropertiesWidget )
77 mItemPropertiesWidget->setMasterLayout( masterLayout );
78 }
79
setNewItem(QgsLayoutItem * item)80 bool QgsLayoutMarkerWidget::setNewItem( QgsLayoutItem *item )
81 {
82 if ( item->type() != QgsLayoutItemRegistry::LayoutShape )
83 return false;
84
85 if ( mMarker )
86 {
87 disconnect( mMarker, &QgsLayoutObject::changed, this, &QgsLayoutMarkerWidget::setGuiElementValues );
88 }
89
90 mMarker = qobject_cast< QgsLayoutItemMarker * >( item );
91 mItemPropertiesWidget->setItem( mMarker );
92
93 if ( mMarker )
94 {
95 connect( mMarker, &QgsLayoutObject::changed, this, &QgsLayoutMarkerWidget::setGuiElementValues );
96 mShapeStyleButton->registerExpressionContextGenerator( mMarker );
97 }
98
99 setGuiElementValues();
100
101 return true;
102 }
103
blockAllSignals(bool block)104 void QgsLayoutMarkerWidget::blockAllSignals( bool block )
105 {
106 mShapeStyleButton->blockSignals( block );
107 mMapComboBox->blockSignals( block );
108 mRotationFromMapCheckBox->blockSignals( block );
109 mNorthTypeComboBox->blockSignals( block );
110 mNorthOffsetSpinBox->blockSignals( block );
111 }
112
setGuiElementValues()113 void QgsLayoutMarkerWidget::setGuiElementValues()
114 {
115 if ( !mMarker )
116 {
117 return;
118 }
119
120 blockAllSignals( true );
121
122 mShapeStyleButton->setSymbol( mMarker->symbol()->clone() );
123
124 mMapComboBox->setItem( mMarker->linkedMap() );
125 if ( mMarker->linkedMap() )
126 {
127 mRotationFromMapCheckBox->setCheckState( Qt::Checked );
128 mMapComboBox->setEnabled( true );
129 mNorthTypeComboBox->setEnabled( true );
130 mNorthOffsetSpinBox->setEnabled( true );
131 }
132 else
133 {
134 mRotationFromMapCheckBox->setCheckState( Qt::Unchecked );
135 mMapComboBox->setEnabled( false );
136 mNorthTypeComboBox->setEnabled( false );
137 mNorthOffsetSpinBox->setEnabled( false );
138 }
139 mNorthTypeComboBox->setCurrentIndex( mNorthTypeComboBox->findData( mMarker->northMode() ) );
140 mNorthOffsetSpinBox->setValue( mMarker->northOffset() );
141
142 blockAllSignals( false );
143 }
144
symbolChanged()145 void QgsLayoutMarkerWidget::symbolChanged()
146 {
147 if ( !mMarker )
148 return;
149
150 mMarker->layout()->undoStack()->beginCommand( mMarker, tr( "Change Marker Symbol" ), QgsLayoutItem::UndoShapeStyle );
151 mMarker->setSymbol( mShapeStyleButton->clonedSymbol<QgsMarkerSymbol>() );
152 mMarker->layout()->undoStack()->endCommand();
153 }
154
rotationFromMapCheckBoxChanged(int state)155 void QgsLayoutMarkerWidget::rotationFromMapCheckBoxChanged( int state )
156 {
157 if ( !mMarker )
158 {
159 return;
160 }
161
162 mMarker->beginCommand( tr( "Toggle Rotation Sync" ) );
163 if ( state == Qt::Unchecked )
164 {
165 mMarker->setLinkedMap( nullptr );
166 mMapComboBox->setEnabled( false );
167 mNorthTypeComboBox->setEnabled( false );
168 mNorthOffsetSpinBox->setEnabled( false );
169 }
170 else
171 {
172 QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap * >( mMapComboBox->currentItem() );
173 mMarker->setLinkedMap( map );
174 mNorthTypeComboBox->setEnabled( true );
175 mNorthOffsetSpinBox->setEnabled( true );
176 mMapComboBox->setEnabled( true );
177 }
178 mMarker->endCommand();
179 }
180
mapChanged(QgsLayoutItem * item)181 void QgsLayoutMarkerWidget::mapChanged( QgsLayoutItem *item )
182 {
183 if ( !mMarker )
184 {
185 return;
186 }
187
188 const QgsLayout *layout = mMarker->layout();
189 if ( !layout )
190 {
191 return;
192 }
193
194 QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap *>( item );
195 if ( !map )
196 {
197 return;
198 }
199
200 mMarker->beginCommand( tr( "Change Rotation Map" ) );
201 mMarker->setLinkedMap( map );
202 mMarker->update();
203 mMarker->endCommand();
204 }
205
northOffsetSpinBoxChanged(double d)206 void QgsLayoutMarkerWidget::northOffsetSpinBoxChanged( double d )
207 {
208 mMarker->beginCommand( tr( "Change Marker North Offset" ), QgsLayoutItem::UndoPictureNorthOffset );
209 mMarker->setNorthOffset( d );
210 mMarker->endCommand();
211 mMarker->update();
212 }
213
northTypeComboBoxChanged(int index)214 void QgsLayoutMarkerWidget::northTypeComboBoxChanged( int index )
215 {
216 mMarker->beginCommand( tr( "Change Marker North Mode" ) );
217 mMarker->setNorthMode( static_cast< QgsLayoutNorthArrowHandler::NorthMode >( mNorthTypeComboBox->itemData( index ).toInt() ) );
218 mMarker->endCommand();
219 mMarker->update();
220 }
221