Skip to content

Commit 2ec31d8

Browse files
committedNov 7, 2017
Add configuration widget for shapes
1 parent 7674bd7 commit 2ec31d8

File tree

7 files changed

+427
-3
lines changed

7 files changed

+427
-3
lines changed
 

‎python/core/layout/qgslayoutitem.sip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
6060
UndoOpacity,
6161
UndoSetId,
6262
UndoRotation,
63+
UndoShapeStyle,
64+
UndoShapeCornerRadius,
6365
};
6466

6567
explicit QgsLayoutItem( QgsLayout *layout, bool manageZValue = true );

‎src/app/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ SET(QGIS_APP_SRCS
182182
layout/qgslayoutmapwidget.cpp
183183
layout/qgslayoutpagepropertieswidget.cpp
184184
layout/qgslayoutpropertieswidget.cpp
185+
layout/qgslayoutshapewidget.cpp
185186

186187
locator/qgsinbuiltlocatorfilters.cpp
187188
locator/qgslocatoroptionswidget.cpp
@@ -379,6 +380,7 @@ SET (QGIS_APP_MOC_HDRS
379380
layout/qgslayoutmapwidget.h
380381
layout/qgslayoutpagepropertieswidget.h
381382
layout/qgslayoutpropertieswidget.h
383+
layout/qgslayoutshapewidget.h
382384

383385
locator/qgsinbuiltlocatorfilters.h
384386
locator/qgslocatoroptionswidget.h

‎src/app/layout/qgslayoutapputils.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "qgslayoutviewrubberband.h"
2121
#include "qgslayoutitemshape.h"
2222
#include "qgslayoutmapwidget.h"
23+
#include "qgslayoutshapewidget.h"
2324
#include "qgslayoutitemmap.h"
2425

2526
void QgsLayoutAppUtils::registerGuiForKnownItemTypes()
@@ -49,19 +50,25 @@ void QgsLayoutAppUtils::registerGuiForKnownItemTypes()
4950
return new QgsLayoutMapWidget( qobject_cast< QgsLayoutItemMap * >( item ) );
5051
}, createRubberBand ) );
5152

52-
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Rectangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ), nullptr, createRubberBand, QStringLiteral( "shapes" ), 0, []( QgsLayout * layout )->QgsLayoutItem*
53+
auto createShapeWidget =
54+
[]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
55+
{
56+
return new QgsLayoutShapeWidget( qobject_cast< QgsLayoutItemShape * >( item ) );
57+
};
58+
59+
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Rectangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ), createShapeWidget, createRubberBand, QStringLiteral( "shapes" ), 0, []( QgsLayout * layout )->QgsLayoutItem*
5360
{
5461
std::unique_ptr< QgsLayoutItemShape > shape = qgis::make_unique< QgsLayoutItemShape >( layout );
5562
shape->setShapeType( QgsLayoutItemShape::Rectangle );
5663
return shape.release();
5764
} ) );
58-
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Ellipse" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicCircle.svg" ) ), nullptr, createEllipseBand, QStringLiteral( "shapes" ), 0, []( QgsLayout * layout )->QgsLayoutItem*
65+
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Ellipse" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicCircle.svg" ) ), createShapeWidget, createEllipseBand, QStringLiteral( "shapes" ), 0, []( QgsLayout * layout )->QgsLayoutItem*
5966
{
6067
std::unique_ptr< QgsLayoutItemShape > shape = qgis::make_unique< QgsLayoutItemShape >( layout );
6168
shape->setShapeType( QgsLayoutItemShape::Ellipse );
6269
return shape.release();
6370
} ) );
64-
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Triangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicTriangle.svg" ) ), nullptr, createTriangleBand, QStringLiteral( "shapes" ), 0, []( QgsLayout * layout )->QgsLayoutItem*
71+
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Triangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicTriangle.svg" ) ), createShapeWidget, createTriangleBand, QStringLiteral( "shapes" ), 0, []( QgsLayout * layout )->QgsLayoutItem*
6572
{
6673
std::unique_ptr< QgsLayoutItemShape > shape = qgis::make_unique< QgsLayoutItemShape >( layout );
6774
shape->setShapeType( QgsLayoutItemShape::Triangle );
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
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+
24+
QgsLayoutShapeWidget::QgsLayoutShapeWidget( QgsLayoutItemShape *shape )
25+
: QgsLayoutItemBaseWidget( nullptr, shape )
26+
, mShape( shape )
27+
{
28+
setupUi( this );
29+
connect( mShapeComboBox, static_cast<void ( QComboBox::* )( const QString & )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutShapeWidget::mShapeComboBox_currentIndexChanged );
30+
connect( mCornerRadiusSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutShapeWidget::mCornerRadiusSpinBox_valueChanged );
31+
setPanelTitle( tr( "Shape properties" ) );
32+
33+
//add widget for general composer item properties
34+
mItemPropertiesWidget = new QgsLayoutItemPropertiesWidget( this, shape );
35+
//shapes don't use background or frame, since the symbol style is set through a QgsSymbolSelectorWidget
36+
mItemPropertiesWidget->showBackgroundGroup( false );
37+
mItemPropertiesWidget->showFrameGroup( false );
38+
mainLayout->addWidget( mItemPropertiesWidget );
39+
40+
blockAllSignals( true );
41+
42+
//shape types
43+
mShapeComboBox->addItem( tr( "Rectangle" ), QgsLayoutItemShape::Rectangle );
44+
mShapeComboBox->addItem( tr( "Ellipse" ), QgsLayoutItemShape::Ellipse );
45+
mShapeComboBox->addItem( tr( "Triangle" ), QgsLayoutItemShape::Triangle );
46+
47+
mShapeStyleButton->setSymbolType( QgsSymbol::Fill );
48+
mRadiusUnitsComboBox->linkToWidget( mCornerRadiusSpinBox );
49+
mRadiusUnitsComboBox->setConverter( &mShape->layout()->context().measurementConverter() );
50+
51+
setGuiElementValues();
52+
53+
blockAllSignals( false );
54+
55+
if ( mShape )
56+
{
57+
connect( mShape, &QgsLayoutObject::changed, this, &QgsLayoutShapeWidget::setGuiElementValues );
58+
mShapeStyleButton->registerExpressionContextGenerator( mShape );
59+
}
60+
connect( mShapeStyleButton, &QgsSymbolButton::changed, this, &QgsLayoutShapeWidget::symbolChanged );
61+
connect( mRadiusUnitsComboBox, &QgsLayoutUnitsComboBox::changed, this, &QgsLayoutShapeWidget::radiusUnitsChanged );
62+
63+
#if 0 //TODO
64+
mShapeStyleButton->setLayer( atlasCoverageLayer() );
65+
#endif
66+
}
67+
68+
bool QgsLayoutShapeWidget::setNewItem( QgsLayoutItem *item )
69+
{
70+
if ( item->type() != QgsLayoutItemRegistry::LayoutShape )
71+
return false;
72+
73+
mShape = qobject_cast< QgsLayoutItemShape * >( item );
74+
mItemPropertiesWidget->setItem( mShape );
75+
76+
setGuiElementValues();
77+
78+
return true;
79+
}
80+
81+
void QgsLayoutShapeWidget::blockAllSignals( bool block )
82+
{
83+
mShapeComboBox->blockSignals( block );
84+
mCornerRadiusSpinBox->blockSignals( block );
85+
mRadiusUnitsComboBox->blockSignals( block );
86+
mShapeStyleButton->blockSignals( block );
87+
}
88+
89+
void QgsLayoutShapeWidget::setGuiElementValues()
90+
{
91+
if ( !mShape )
92+
{
93+
return;
94+
}
95+
96+
blockAllSignals( true );
97+
98+
mShapeStyleButton->setSymbol( mShape->symbol()->clone() );
99+
100+
mCornerRadiusSpinBox->setValue( mShape->cornerRadius().length() );
101+
mRadiusUnitsComboBox->setUnit( mShape->cornerRadius().units() );
102+
103+
mShapeComboBox->setCurrentIndex( mShapeComboBox->findData( mShape->shapeType() ) );
104+
toggleRadiusSpin( mShape->shapeType() );
105+
106+
blockAllSignals( false );
107+
}
108+
109+
void QgsLayoutShapeWidget::symbolChanged()
110+
{
111+
if ( !mShape )
112+
return;
113+
114+
mShape->layout()->undoStack()->beginCommand( mShape, tr( "Change Shape Style" ), QgsLayoutItem::UndoShapeStyle );
115+
mShape->setSymbol( mShapeStyleButton->clonedSymbol<QgsFillSymbol>() );
116+
mShape->layout()->undoStack()->endCommand();
117+
}
118+
119+
void QgsLayoutShapeWidget::mCornerRadiusSpinBox_valueChanged( double val )
120+
{
121+
if ( !mShape )
122+
return;
123+
124+
mShape->layout()->undoStack()->beginCommand( mShape, tr( "Change Shape Radius" ), QgsLayoutItem::UndoShapeCornerRadius );
125+
mShape->setCornerRadius( QgsLayoutMeasurement( val, mRadiusUnitsComboBox->unit() ) );
126+
mShape->layout()->undoStack()->endCommand();
127+
mShape->update();
128+
}
129+
130+
void QgsLayoutShapeWidget::radiusUnitsChanged()
131+
{
132+
if ( !mShape )
133+
return;
134+
135+
mShape->layout()->undoStack()->beginCommand( mShape, tr( "Change Shape Radius" ), QgsLayoutItem::UndoShapeCornerRadius );
136+
mShape->setCornerRadius( QgsLayoutMeasurement( mCornerRadiusSpinBox->value(), mRadiusUnitsComboBox->unit() ) );
137+
mShape->layout()->undoStack()->endCommand();
138+
mShape->update();
139+
}
140+
141+
void QgsLayoutShapeWidget::mShapeComboBox_currentIndexChanged( const QString & )
142+
{
143+
if ( !mShape )
144+
{
145+
return;
146+
}
147+
148+
mShape->layout()->undoStack()->beginCommand( mShape, tr( "Change Shape Type" ) );
149+
QgsLayoutItemShape::Shape shape = static_cast< QgsLayoutItemShape::Shape >( mShapeComboBox->currentData().toInt() );
150+
mShape->setShapeType( shape );
151+
toggleRadiusSpin( shape );
152+
mShape->update();
153+
mShape->layout()->undoStack()->endCommand();
154+
}
155+
156+
void QgsLayoutShapeWidget::toggleRadiusSpin( QgsLayoutItemShape::Shape shape )
157+
{
158+
switch ( shape )
159+
{
160+
case QgsLayoutItemShape::Ellipse:
161+
case QgsLayoutItemShape::Triangle:
162+
{
163+
mCornerRadiusSpinBox->setEnabled( false );
164+
break;
165+
}
166+
case QgsLayoutItemShape::Rectangle:
167+
{
168+
mCornerRadiusSpinBox->setEnabled( true );
169+
break;
170+
}
171+
}
172+
}

‎src/app/layout/qgslayoutshapewidget.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/***************************************************************************
2+
qgslayoutshapewidget.h
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+
#ifndef QGSLAYOUTSHAPEWIDGET_H
19+
#define QGSLAYOUTSHAPEWIDGET_H
20+
21+
#include "ui_qgslayoutshapewidgetbase.h"
22+
#include "qgslayoutitemwidget.h"
23+
#include "qgslayoutitemshape.h"
24+
25+
/**
26+
* \ingroup app
27+
* Input widget for the configuration of QgsLayoutItemShape
28+
*/
29+
class QgsLayoutShapeWidget: public QgsLayoutItemBaseWidget, private Ui::QgsLayoutShapeWidgetBase
30+
{
31+
Q_OBJECT
32+
public:
33+
explicit QgsLayoutShapeWidget( QgsLayoutItemShape *shape );
34+
35+
protected:
36+
37+
bool setNewItem( QgsLayoutItem *item ) override;
38+
39+
40+
private:
41+
QgsLayoutItemShape *mShape = nullptr;
42+
QgsLayoutItemPropertiesWidget *mItemPropertiesWidget = nullptr;
43+
44+
//! Blocks / unblocks the signal of all GUI elements
45+
void blockAllSignals( bool block );
46+
47+
private slots:
48+
void mShapeComboBox_currentIndexChanged( const QString &text );
49+
void mCornerRadiusSpinBox_valueChanged( double val );
50+
void radiusUnitsChanged();
51+
void symbolChanged();
52+
53+
//! Sets the GUI elements to the currentValues of mComposerShape
54+
void setGuiElementValues();
55+
56+
//! Enables or disables the rounded radius spin box based on shape type
57+
void toggleRadiusSpin( QgsLayoutItemShape::Shape shape );
58+
};
59+
60+
#endif // QGSLAYOUTSHAPEWIDGET_H

‎src/core/layout/qgslayoutitem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
9393
UndoOpacity, //!< Opacity adjustment
9494
UndoSetId, //!< Change item ID
9595
UndoRotation, //!< Rotation adjustment
96+
UndoShapeStyle, //!< Shape symbol style
97+
UndoShapeCornerRadius, //!< Shape corner radius
9698
};
9799

98100
/**
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>QgsLayoutShapeWidgetBase</class>
4+
<widget class="QWidget" name="QgsLayoutShapeWidgetBase">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>564</width>
10+
<height>322</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Form</string>
15+
</property>
16+
<layout class="QVBoxLayout" name="verticalLayout">
17+
<property name="spacing">
18+
<number>0</number>
19+
</property>
20+
<property name="leftMargin">
21+
<number>0</number>
22+
</property>
23+
<property name="topMargin">
24+
<number>0</number>
25+
</property>
26+
<property name="rightMargin">
27+
<number>0</number>
28+
</property>
29+
<property name="bottomMargin">
30+
<number>0</number>
31+
</property>
32+
<item>
33+
<widget class="QLabel" name="label_2">
34+
<property name="sizePolicy">
35+
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
36+
<horstretch>0</horstretch>
37+
<verstretch>0</verstretch>
38+
</sizepolicy>
39+
</property>
40+
<property name="styleSheet">
41+
<string notr="true">padding: 2px; font-weight: bold; background-color: rgb(200, 200, 200);</string>
42+
</property>
43+
<property name="text">
44+
<string>Shape</string>
45+
</property>
46+
</widget>
47+
</item>
48+
<item>
49+
<widget class="QgsScrollArea" name="scrollArea">
50+
<property name="widgetResizable">
51+
<bool>true</bool>
52+
</property>
53+
<widget class="QWidget" name="scrollAreaWidgetContents">
54+
<property name="geometry">
55+
<rect>
56+
<x>0</x>
57+
<y>0</y>
58+
<width>548</width>
59+
<height>285</height>
60+
</rect>
61+
</property>
62+
<layout class="QVBoxLayout" name="mainLayout">
63+
<item>
64+
<widget class="QgsCollapsibleGroupBoxBasic" name="groupBox">
65+
<property name="focusPolicy">
66+
<enum>Qt::StrongFocus</enum>
67+
</property>
68+
<property name="title">
69+
<string>Main properties</string>
70+
</property>
71+
<property name="syncGroup" stdset="0">
72+
<string notr="true">composeritem</string>
73+
</property>
74+
<property name="collapsed" stdset="0">
75+
<bool>false</bool>
76+
</property>
77+
<layout class="QGridLayout" name="gridLayout">
78+
<item row="1" column="0">
79+
<widget class="QLabel" name="label_3">
80+
<property name="text">
81+
<string>Corner radius</string>
82+
</property>
83+
</widget>
84+
</item>
85+
<item row="1" column="1">
86+
<layout class="QHBoxLayout" name="horizontalLayout">
87+
<item>
88+
<widget class="QgsDoubleSpinBox" name="mCornerRadiusSpinBox">
89+
<property name="sizePolicy">
90+
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
91+
<horstretch>0</horstretch>
92+
<verstretch>0</verstretch>
93+
</sizepolicy>
94+
</property>
95+
<property name="suffix">
96+
<string/>
97+
</property>
98+
<property name="maximum">
99+
<double>999.000000000000000</double>
100+
</property>
101+
</widget>
102+
</item>
103+
<item>
104+
<widget class="QgsLayoutUnitsComboBox" name="mRadiusUnitsComboBox"/>
105+
</item>
106+
</layout>
107+
</item>
108+
<item row="2" column="0">
109+
<widget class="QLabel" name="label">
110+
<property name="text">
111+
<string>Style</string>
112+
</property>
113+
</widget>
114+
</item>
115+
<item row="2" column="1">
116+
<widget class="QgsSymbolButton" name="mShapeStyleButton">
117+
<property name="sizePolicy">
118+
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
119+
<horstretch>0</horstretch>
120+
<verstretch>0</verstretch>
121+
</sizepolicy>
122+
</property>
123+
<property name="text">
124+
<string>Change...</string>
125+
</property>
126+
</widget>
127+
</item>
128+
<item row="0" column="0" colspan="2">
129+
<widget class="QComboBox" name="mShapeComboBox"/>
130+
</item>
131+
</layout>
132+
</widget>
133+
</item>
134+
</layout>
135+
</widget>
136+
</widget>
137+
</item>
138+
</layout>
139+
</widget>
140+
<customwidgets>
141+
<customwidget>
142+
<class>QgsDoubleSpinBox</class>
143+
<extends>QDoubleSpinBox</extends>
144+
<header>qgsdoublespinbox.h</header>
145+
</customwidget>
146+
<customwidget>
147+
<class>QgsScrollArea</class>
148+
<extends>QScrollArea</extends>
149+
<header>qgsscrollarea.h</header>
150+
<container>1</container>
151+
</customwidget>
152+
<customwidget>
153+
<class>QgsCollapsibleGroupBoxBasic</class>
154+
<extends>QGroupBox</extends>
155+
<header>qgscollapsiblegroupbox.h</header>
156+
<container>1</container>
157+
</customwidget>
158+
<customwidget>
159+
<class>QgsSymbolButton</class>
160+
<extends>QToolButton</extends>
161+
<header>qgssymbolbutton.h</header>
162+
</customwidget>
163+
<customwidget>
164+
<class>QgsLayoutUnitsComboBox</class>
165+
<extends>QComboBox</extends>
166+
<header>qgslayoutunitscombobox.h</header>
167+
</customwidget>
168+
</customwidgets>
169+
<tabstops>
170+
<tabstop>groupBox</tabstop>
171+
<tabstop>scrollArea</tabstop>
172+
<tabstop>mShapeComboBox</tabstop>
173+
<tabstop>mCornerRadiusSpinBox</tabstop>
174+
<tabstop>mRadiusUnitsComboBox</tabstop>
175+
<tabstop>mShapeStyleButton</tabstop>
176+
</tabstops>
177+
<resources/>
178+
<connections/>
179+
</ui>

0 commit comments

Comments
 (0)
Please sign in to comment.