Skip to content

Commit b007b88

Browse files
author
mhugent
committedNov 19, 2009
Add a new composer item to draw basic shapes (atm ellipse, rectangle, triangle), fix some composer related bugs and bring rotation to composer item level
git-svn-id: http://svn.osgeo.org/qgis/trunk@12183 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 649eb01 commit b007b88

31 files changed

+982
-165
lines changed
 
974 Bytes
Loading

‎python/core/qgscomposeritem.sip

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** \ingroup MapComposer
22
* A item that forms part of a map composition.
33
*/
4-
class QgsComposerItem: QGraphicsRectItem
4+
class QgsComposerItem: public QObject, public QGraphicsRectItem
55
{
66
%TypeHeaderCode
77
#include <qgscomposeritem.h>
@@ -130,6 +130,23 @@ class QgsComposerItem: QGraphicsRectItem
130130
/**Returns a font where size is in pixel and font size is upscaled with FONT_WORKAROUND_SCALE*/
131131
QFont scaledFontPixelSize( const QFont& font ) const;
132132

133+
/**Locks / unlocks the item position for mouse drags
134+
@note this method was added in version 1.2*/
135+
void setPositionLock( bool lock );
136+
137+
/**Returns position lock for mouse drags (true means locked)
138+
@note this method was added in version 1.2*/
139+
bool positionLock() const;
140+
141+
/**Update mouse cursor at (item) position
142+
@note this method was added in version 1.2*/
143+
void updateCursor( const QPointF& itemPos );
144+
145+
double rotation() const;
146+
147+
public slots:
148+
void setRotation( double r);
149+
133150
protected:
134151

135152
//event handlers
@@ -163,4 +180,28 @@ class QgsComposerItem: QGraphicsRectItem
163180

164181
/**Draw background*/
165182
virtual void drawBackground( QPainter* p );
166-
};
183+
184+
/**Returns the current (zoom level dependent) tolerance to decide if mouse position is close enough to the \
185+
item border for resizing*/
186+
double rectHandlerBorderTolerance() const;
187+
188+
/**Returns the size of the lock symbol depending on the composer zoom level and the item size
189+
@note: this function was introduced in version 1.2*/
190+
double lockSymbolSize() const;
191+
192+
/**Returns the zoom factor of the graphics view.
193+
@return the factor or -1 in case of error (e.g. graphic view does not exist)
194+
@note: this function was introduced in version 1.2*/
195+
double horizontalViewScaleFactor() const;
196+
197+
/**Calculates width and hight of the picture (in mm) such that it fits into the item frame with the given rotation*/
198+
bool imageSizeConsideringRotation( double& width, double& height ) const;
199+
/**Calculates corner point after rotation and scaling*/
200+
bool cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const;
201+
/**Returns a point on the line from startPoint to directionPoint that is a certain distance away from the starting point*/
202+
QPointF pointOnLineWithDistance( const QPointF& startPoint, const QPointF& directionPoint, double distance ) const;
203+
204+
signals:
205+
/**Is emitted on rotation change to notify north arrow pictures*/
206+
void rotationChanged( double newRotation );
207+
};

‎python/core/qgscomposerlegend.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** \ingroup MapComposer
22
* A legend that can be placed onto a map composition
33
*/
4-
class QgsComposerLegend: QObject, QgsComposerItem
4+
class QgsComposerLegend: QgsComposerItem
55
{
66
%TypeHeaderCode
77
#include <qgscomposerlegend.h>

‎python/core/qgscomposermap.sip

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* \brief Object representing map window.
44
*/
55
// NOTE: QgsComposerMapBase must be first, otherwise does not compile
6-
class QgsComposerMap : QObject, QgsComposerItem
6+
class QgsComposerMap : QgsComposerItem
77
{
88
%TypeHeaderCode
99
#include <qgscomposermap.h>
@@ -211,11 +211,6 @@ class QgsComposerMap : QObject, QgsComposerItem
211211
@note this function was added in version 1.4*/
212212
void updateBoundingRect();
213213

214-
/**Sets the rotation of the map content
215-
@note this function was added in version 1.4*/
216-
void setRotation(double r);
217-
double rotation() const;
218-
219214
/**Sets length of the cros segments (if grid style is cross)
220215
@note this function was added in version 1.4*/
221216
void setCrossLength(double l);
@@ -231,6 +226,4 @@ class QgsComposerMap : QObject, QgsComposerItem
231226
signals:
232227
/**Is emitted when width/height is changed as a result of user interaction*/
233228
void extentChanged();
234-
/**Is emitted on rotation change to notify north arrow pictures*/
235-
void rotationChanged( double newRotation );
236229
};

‎python/core/qgscomposerpicture.sip

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** \ingroup MapComposer
22
* A composer class that displays svg files or raster format (jpg, png, ...)
33
* */
4-
class QgsComposerPicture: QObject, QgsComposerItem
4+
class QgsComposerPicture: QgsComposerItem
55
{
66

77
%TypeHeaderCode
@@ -23,10 +23,6 @@ class QgsComposerPicture: QObject, QgsComposerItem
2323
corresponds to 1 scene size unit*/
2424
void setSceneRect( const QRectF& rectangle );
2525

26-
void setRotation( double rotation );
27-
28-
double rotation() const;
29-
3026
/** stores state in Dom node
3127
* @param node is Dom node corresponding to 'Composer' tag
3228
* @param temp write template file

‎python/core/qgscomposerscalebar.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* A scale bar item that can be added to a map composition.
33
*/
44

5-
class QgsComposerScaleBar: QObject, QgsComposerItem
5+
class QgsComposerScaleBar: QgsComposerItem
66
{
77
%TypeHeaderCode
88
#include "qgscomposerscalebar.h"

‎python/core/qgscomposershape.sip

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**A composer items that draws common shapes (ellipse, triangle, rectangle)*/
2+
class QgsComposerShape: public QgsComposerItem
3+
{
4+
%TypeHeaderCode
5+
#include "qgscomposershape.h"
6+
%End
7+
public:
8+
9+
enum Shape
10+
{
11+
Ellipse,
12+
Rectangle,
13+
Triangle
14+
};
15+
16+
QgsComposerShape( QgsComposition* composition /TransferThis/);
17+
QgsComposerShape( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition );
18+
~QgsComposerShape();
19+
20+
/** \brief Reimplementation of QCanvasItem::paint - draw on canvas */
21+
void paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget );
22+
23+
/** stores state in Dom node
24+
* @param node is Dom node corresponding to 'Composer' tag
25+
* @param temp write template file
26+
*/
27+
bool writeXML( QDomElement& elem, QDomDocument & doc ) const;
28+
29+
/** sets state from Dom document
30+
* @param itemElem is Dom node corresponding to item tag
31+
*/
32+
bool readXML( const QDomElement& itemElem, const QDomDocument& doc );
33+
34+
//setters and getters
35+
void setLineWidth( double width );
36+
double lineWidth() const;
37+
void setOutlineColor( const QColor& color );
38+
QColor outlineColor() const;
39+
void setFillColor( const QColor& color );
40+
QColor fillColor() const;
41+
QgsComposerShape::Shape shapeType() const;
42+
void setShapeType( QgsComposerShape::Shape s );
43+
};

‎src/app/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ SET(QGIS_APP_SRCS
8080
composer/qgscomposermanager.cpp
8181
composer/qgscomposermapwidget.cpp
8282
composer/qgscomposerscalebarwidget.cpp
83+
composer/qgscomposershapewidget.cpp
8384
composer/qgscomposerlegenditemdialog.cpp
8485
composer/qgscomposerlegendwidget.cpp
8586
composer/qgscompositionwidget.cpp
@@ -179,6 +180,7 @@ SET (QGIS_APP_MOC_HDRS
179180
composer/qgscomposermapwidget.h
180181
composer/qgscomposerpicturewidget.h
181182
composer/qgscomposerscalebarwidget.h
183+
composer/qgscomposershapewidget.h
182184
composer/qgscompositionwidget.h
183185
composer/qgsitempositiondialog.h
184186

‎src/app/composer/qgscomposer.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include "qgscomposerpicturewidget.h"
3232
#include "qgscomposerscalebar.h"
3333
#include "qgscomposerscalebarwidget.h"
34+
#include "qgscomposershape.h"
35+
#include "qgscomposershapewidget.h"
3436
#include "qgsexception.h"
3537
#include "qgsproject.h"
3638
#include "qgsmapcanvas.h"
@@ -106,6 +108,7 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title ): QMainWindow(),
106108
toggleActionGroup->addAction( mActionAddNewScalebar );
107109
toggleActionGroup->addAction( mActionAddImage );
108110
toggleActionGroup->addAction( mActionSelectMoveItem );
111+
toggleActionGroup->addAction( mActionAddBasicShape );
109112
toggleActionGroup->setExclusive( true );
110113

111114
mActionAddNewMap->setCheckable( true );
@@ -115,6 +118,7 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title ): QMainWindow(),
115118
mActionAddNewScalebar->setCheckable( true );
116119
mActionAddImage->setCheckable( true );
117120
mActionMoveItemContent->setCheckable( true );
121+
mActionAddBasicShape->setCheckable( true );
118122

119123
#ifdef Q_WS_MAC
120124
QMenu *appMenu = menuBar()->addMenu( tr( "QGIS" ) );
@@ -150,6 +154,7 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title ): QMainWindow(),
150154
layoutMenu->addAction( mActionAddImage );
151155
layoutMenu->addAction( mActionSelectMoveItem );
152156
layoutMenu->addAction( mActionMoveItemContent );
157+
layoutMenu->addAction( mActionAddBasicShape );
153158
layoutMenu->addSeparator();
154159
layoutMenu->addAction( mActionGroupItems );
155160
layoutMenu->addAction( mActionUngroupItems );
@@ -243,6 +248,7 @@ void QgsComposer::setupTheme()
243248
mActionAddNewLabel->setIcon( QgisApp::getThemeIcon( "/mActionLabel.png" ) );
244249
mActionAddNewLegend->setIcon( QgisApp::getThemeIcon( "/mActionAddLegend.png" ) );
245250
mActionAddNewScalebar->setIcon( QgisApp::getThemeIcon( "/mActionScaleBar.png" ) );
251+
mActionAddBasicShape->setIcon( QgisApp::getThemeIcon( "/mActionAddBasicShape.png" ) );
246252
mActionSelectMoveItem->setIcon( QgisApp::getThemeIcon( "/mActionSelectPan.png" ) );
247253
mActionMoveItemContent->setIcon( QgisApp::getThemeIcon( "/mActionMoveItemContent.png" ) );
248254
mActionGroupItems->setIcon( QgisApp::getThemeIcon( "/mActionGroupItems.png" ) );
@@ -268,6 +274,7 @@ void QgsComposer::connectSlots()
268274
connect( mView, SIGNAL( composerScaleBarAdded( QgsComposerScaleBar* ) ), this, SLOT( addComposerScaleBar( QgsComposerScaleBar* ) ) );
269275
connect( mView, SIGNAL( composerLegendAdded( QgsComposerLegend* ) ), this, SLOT( addComposerLegend( QgsComposerLegend* ) ) );
270276
connect( mView, SIGNAL( composerPictureAdded( QgsComposerPicture* ) ), this, SLOT( addComposerPicture( QgsComposerPicture* ) ) );
277+
connect( mView, SIGNAL( composerShapeAdded( QgsComposerShape* ) ), this, SLOT( addComposerShape( QgsComposerShape* ) ) );
271278
connect( mView, SIGNAL( actionFinished() ), this, SLOT( setSelectionTool() ) );
272279
}
273280

@@ -330,6 +337,10 @@ void QgsComposer::setTitle( const QString& title )
330337
{
331338
mTitle = title;
332339
setWindowTitle( mTitle );
340+
if ( mWindowAction )
341+
{
342+
mWindowAction->setText( title );
343+
}
333344
}
334345

335346
void QgsComposer::showCompositionOptions( QWidget *w )
@@ -786,6 +797,14 @@ void QgsComposer::on_mActionAddImage_triggered()
786797
}
787798
}
788799

800+
void QgsComposer::on_mActionAddBasicShape_triggered()
801+
{
802+
if ( mView )
803+
{
804+
mView->setCurrentTool( QgsComposerView::AddShape );
805+
}
806+
}
807+
789808
void QgsComposer::on_mActionSaveAsTemplate_triggered()
790809
{
791810
//show file dialog
@@ -1015,6 +1034,16 @@ void QgsComposer::writeXML( QDomNode& parentNode, QDomDocument& doc )
10151034
{
10161035
QDomElement composerElem = doc.createElement( "Composer" );
10171036
composerElem.setAttribute( "title", mTitle );
1037+
1038+
//store if composer is open or closed
1039+
if ( isVisible() )
1040+
{
1041+
composerElem.setAttribute( "visible", 1 );
1042+
}
1043+
else
1044+
{
1045+
composerElem.setAttribute( "visible", 0 );
1046+
}
10181047
parentNode.appendChild( composerElem );
10191048

10201049
//store composer items:
@@ -1173,6 +1202,21 @@ void QgsComposer::readXML( const QDomElement& composerElem, const QDomDocument&
11731202
showItemOptions( newPicture );
11741203
}
11751204

1205+
//composer shapes
1206+
QDomNodeList composerShapeList = composerElem.elementsByTagName( "ComposerShape" );
1207+
for ( int i = 0; i < composerShapeList.size(); ++i )
1208+
{
1209+
QDomElement currentShapeElem = composerShapeList.at( i ).toElement();
1210+
QgsComposerShape* newShape = new QgsComposerShape( mComposition );
1211+
newShape->readXML( currentShapeElem, doc );
1212+
addComposerShape( newShape );
1213+
mComposition->addItem( newShape );
1214+
mComposition->update();
1215+
mComposition->clearSelection();
1216+
newShape->setSelected( true );
1217+
showItemOptions( newShape );
1218+
}
1219+
11761220
mComposition->sortZList();
11771221
mView->setComposition( mComposition );
11781222

@@ -1247,6 +1291,16 @@ void QgsComposer::addComposerPicture( QgsComposerPicture* picture )
12471291
mItemWidgetMap.insert( picture, pWidget );
12481292
}
12491293

1294+
void QgsComposer::addComposerShape( QgsComposerShape* shape )
1295+
{
1296+
if ( !shape )
1297+
{
1298+
return;
1299+
}
1300+
QgsComposerShapeWidget* sWidget = new QgsComposerShapeWidget( shape );
1301+
mItemWidgetMap.insert( shape, sWidget );
1302+
}
1303+
12501304
void QgsComposer::deleteItem( QgsComposerItem* item )
12511305
{
12521306
QMap<QgsComposerItem*, QWidget*>::iterator it = mItemWidgetMap.find( item );

‎src/app/composer/qgscomposer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class QgsComposerLegend;
2727
class QgsComposerMap;
2828
class QgsComposerPicture;
2929
class QgsComposerScaleBar;
30+
class QgsComposerShape;
3031
class QgsComposerView;
3132
class QgsComposition;
3233
class QgsMapCanvas;
@@ -142,6 +143,9 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
142143
//! Add new picture
143144
void on_mActionAddImage_triggered();
144145

146+
//! Add ellipse shape item
147+
void on_mActionAddBasicShape_triggered();
148+
145149
//! Save composer as template
146150
void on_mActionSaveAsTemplate_triggered();
147151

@@ -204,6 +208,9 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
204208
/**Adds a composer picture to the item/widget map and creates a configuration widget*/
205209
void addComposerPicture( QgsComposerPicture* picture );
206210

211+
/**Adds a composer shape to the item/widget map and creates a configuration widget*/
212+
void addComposerShape( QgsComposerShape* shape );
213+
207214
/**Removes item from the item/widget map and deletes the configuration widget*/
208215
void deleteItem( QgsComposerItem* item );
209216

‎src/app/composer/qgscomposermapwidget.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ void QgsComposerMapWidget::on_mRotationSpinBox_valueChanged( int value )
162162
return;
163163
}
164164

165-
mComposerMap->setRotation( value );
165+
mComposerMap->setMapRotation( value );
166166
mComposerMap->cache();
167167
mComposerMap->update();
168168
}

‎src/app/composer/qgscomposerpicturewidget.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ QgsComposerPictureWidget::QgsComposerPictureWidget( QgsComposerPicture* picture
4646
//add preview icons
4747
addStandardDirectoriesToPreview();
4848
connect( mPicture, SIGNAL( settingsChanged() ), this, SLOT( setGuiElementValues() ) );
49+
connect( mPicture, SIGNAL( rotationChanged( double ) ), this, SLOT( setGuiElementValues() ) );
4950
}
5051

5152
QgsComposerPictureWidget::~QgsComposerPictureWidget()
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/***************************************************************************
2+
qgscomposershapewidget.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 "qgscomposershapewidget.h"
19+
#include "qgscomposershape.h"
20+
#include "qgscomposeritemwidget.h"
21+
#include <QColorDialog>
22+
23+
QgsComposerShapeWidget::QgsComposerShapeWidget( QgsComposerShape* composerShape ): QWidget( 0 ), mComposerShape( composerShape )
24+
{
25+
setupUi( this );
26+
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, composerShape );
27+
gridLayout->addWidget( itemPropertiesWidget, 6, 0, 1, 1 );
28+
29+
blockAllSignals( true );
30+
31+
//shape types
32+
mShapeComboBox->addItem( tr( "Ellipse" ) );
33+
mShapeComboBox->addItem( tr( "Rectangle" ) );
34+
mShapeComboBox->addItem( tr( "Triangle" ) );
35+
36+
setGuiElementValues();
37+
38+
blockAllSignals( false );
39+
}
40+
41+
QgsComposerShapeWidget::~QgsComposerShapeWidget()
42+
{
43+
44+
}
45+
46+
void QgsComposerShapeWidget::blockAllSignals( bool block )
47+
{
48+
mShapeComboBox->blockSignals( block );
49+
mOutlineColorButton->blockSignals( block );
50+
mOutlineWidthSpinBox->blockSignals( block );
51+
mFillColorButton->blockSignals( block );
52+
mRotationSpinBox->blockSignals( block );
53+
mTransparentCheckBox->blockSignals( block );
54+
}
55+
56+
void QgsComposerShapeWidget::setGuiElementValues()
57+
{
58+
if ( !mComposerShape )
59+
{
60+
return;
61+
}
62+
mOutlineWidthSpinBox->setValue( mComposerShape->lineWidth() );
63+
mRotationSpinBox->setValue( mComposerShape->rotation() );
64+
if ( mComposerShape->shapeType() == QgsComposerShape::Ellipse )
65+
{
66+
mShapeComboBox->setCurrentIndex( mShapeComboBox->findText( tr( "Ellipse" ) ) );
67+
}
68+
else if ( mComposerShape->shapeType() == QgsComposerShape::Rectangle )
69+
{
70+
mShapeComboBox->setCurrentIndex( mShapeComboBox->findText( tr( "Rectangle" ) ) );
71+
}
72+
else if ( mComposerShape->shapeType() == QgsComposerShape::Triangle )
73+
{
74+
mShapeComboBox->setCurrentIndex( mShapeComboBox->findText( tr( "Triangle" ) ) );
75+
}
76+
77+
if ( mComposerShape->transparentFill() )
78+
{
79+
mTransparentCheckBox->setCheckState( Qt::Checked );
80+
mFillColorButton->setEnabled( false );
81+
}
82+
else
83+
{
84+
mTransparentCheckBox->setCheckState( Qt::Unchecked );
85+
mFillColorButton->setEnabled( true );
86+
}
87+
}
88+
89+
void QgsComposerShapeWidget::on_mRotationSpinBox_valueChanged( int val )
90+
{
91+
if ( mComposerShape )
92+
{
93+
mComposerShape->setRotation( val );
94+
mComposerShape->update();
95+
}
96+
}
97+
98+
void QgsComposerShapeWidget::on_mShapeComboBox_currentIndexChanged( const QString& text )
99+
{
100+
if ( !mComposerShape )
101+
{
102+
return;
103+
}
104+
105+
if ( text == tr( "Ellipse" ) )
106+
{
107+
mComposerShape->setShapeType( QgsComposerShape::Ellipse );
108+
}
109+
else if ( text == tr( "Rectangle" ) )
110+
{
111+
mComposerShape->setShapeType( QgsComposerShape::Rectangle );
112+
}
113+
else if ( text == tr( "Triangle" ) )
114+
{
115+
mComposerShape->setShapeType( QgsComposerShape::Triangle );
116+
}
117+
mComposerShape->update();
118+
}
119+
120+
void QgsComposerShapeWidget::on_mOutlineColorButton_clicked()
121+
{
122+
if ( !mComposerShape )
123+
{
124+
return;
125+
}
126+
QColor existingColor = mComposerShape->outlineColor();
127+
QColor newColor = QColorDialog::getColor( existingColor, 0 );
128+
if ( newColor.isValid() )
129+
{
130+
mComposerShape->setOutlineColor( newColor );
131+
mComposerShape->update();
132+
}
133+
}
134+
135+
void QgsComposerShapeWidget::on_mOutlineWidthSpinBox_valueChanged( double d )
136+
{
137+
if ( !mComposerShape )
138+
{
139+
return;
140+
}
141+
mComposerShape->setLineWidth( d );
142+
mComposerShape->update();
143+
}
144+
145+
void QgsComposerShapeWidget::on_mTransparentCheckBox_stateChanged( int state )
146+
{
147+
if ( !mComposerShape )
148+
{
149+
return;
150+
}
151+
152+
if ( state == Qt::Checked )
153+
{
154+
mComposerShape->setTransparentFill( true );
155+
mFillColorButton->setEnabled( false );
156+
}
157+
else
158+
{
159+
mComposerShape->setTransparentFill( false );
160+
mFillColorButton->setEnabled( true );
161+
}
162+
mComposerShape->update();
163+
}
164+
165+
void QgsComposerShapeWidget::on_mFillColorButton_clicked()
166+
{
167+
if ( !mComposerShape )
168+
{
169+
return;
170+
}
171+
QColor existingColor = mComposerShape->fillColor();
172+
QColor newColor = QColorDialog::getColor( existingColor, 0 );
173+
if ( newColor.isValid() )
174+
{
175+
mComposerShape->setFillColor( newColor );
176+
mComposerShape->update();
177+
}
178+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/***************************************************************************
2+
qgscomposershapewidget.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 QGSCOMPOSERSHAPEWIDGET_H
19+
#define QGSCOMPOSERSHAPEWIDGET_H
20+
21+
#include "ui_qgscomposershapewidgetbase.h"
22+
23+
class QgsComposerShape;
24+
25+
/**Input widget for QgsComposerShape*/
26+
class QgsComposerShapeWidget: public QWidget, private Ui::QgsComposerShapeWidgetBase
27+
{
28+
Q_OBJECT
29+
public:
30+
QgsComposerShapeWidget( QgsComposerShape* composerShape );
31+
~QgsComposerShapeWidget();
32+
33+
private:
34+
QgsComposerShape* mComposerShape;
35+
36+
/**Blocks / unblocks the signal of all GUI elements*/
37+
void blockAllSignals( bool block );
38+
/**Sets the GUI elements to the currentValues of mComposerShape*/
39+
void setGuiElementValues();
40+
41+
private slots:
42+
void on_mShapeComboBox_currentIndexChanged( const QString& text );
43+
void on_mOutlineColorButton_clicked();
44+
void on_mOutlineWidthSpinBox_valueChanged( double d );
45+
void on_mTransparentCheckBox_stateChanged( int state );
46+
void on_mFillColorButton_clicked();
47+
void on_mRotationSpinBox_valueChanged( int val );
48+
};
49+
50+
#endif // QGSCOMPOSERSHAPEWIDGET_H

‎src/app/qgisapp.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4261,6 +4261,10 @@ bool QgisApp::loadComposersFromProject( const QString& projectFilePath )
42614261
composer->showMinimized();
42624262
#endif
42634263
composer->zoomFull();
4264+
if ( composerNodes.at( i ).toElement().attribute( "visible", "1" ).toInt() < 1 )
4265+
{
4266+
composer->close();
4267+
}
42644268
}
42654269
return true;
42664270
}

‎src/core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ SET(QGIS_CORE_SRCS
7676
composer/qgscomposerpicture.cpp
7777
composer/qgscomposermap.cpp
7878
composer/qgscomposerscalebar.cpp
79+
composer/qgscomposershape.cpp
7980
composer/qgslegendmodel.cpp
8081
composer/qgscomposerlegend.cpp
8182
composer/qgspaperitem.cpp
@@ -198,6 +199,7 @@ composer/qgscomposerlegend.h
198199
composer/qgscomposermap.h
199200
composer/qgscomposerpicture.h
200201
composer/qgscomposerscalebar.h
202+
composer/qgscomposeritem.h
201203
composer/qgscomposeritemgroup.h
202204
composer/qgscomposition.h
203205
composer/qgslegendmodel.h

‎src/core/composer/qgscomposeritem.cpp

Lines changed: 158 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,16 @@
3131
#include "qgsrectangle.h" //just for debugging
3232
#include "qgslogger.h"
3333

34+
#ifndef Q_OS_MACX
35+
#include <cmath>
36+
#else
37+
#include <math.h>
38+
#endif
39+
3440
#define FONT_WORKAROUND_SCALE 10 //scale factor for upscaling fontsize and downscaling painter
3541

36-
QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue ): QGraphicsRectItem( 0 ), mComposition( composition ), mBoundingResizeRectangle( 0 ), \
37-
mFrame( true ), mItemPositionLocked( false ), mLastValidViewScaleFactor( -1 )
42+
QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue ): QObject( 0 ), QGraphicsRectItem( 0 ), mComposition( composition ), mBoundingResizeRectangle( 0 ), \
43+
mFrame( true ), mItemPositionLocked( false ), mLastValidViewScaleFactor( -1 ), mRotation( 0 )
3844
{
3945
setFlag( QGraphicsItem::ItemIsSelectable, true );
4046
setAcceptsHoverEvents( true );
@@ -53,7 +59,8 @@ QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue
5359
}
5460

5561
QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition, bool manageZValue ): \
56-
QGraphicsRectItem( 0, 0, width, height, 0 ), mComposition( composition ), mBoundingResizeRectangle( 0 ), mFrame( true ), mItemPositionLocked( false ), mLastValidViewScaleFactor( -1 )
62+
QObject( 0 ), QGraphicsRectItem( 0, 0, width, height, 0 ), mComposition( composition ), mBoundingResizeRectangle( 0 ), mFrame( true ), \
63+
mItemPositionLocked( false ), mLastValidViewScaleFactor( -1 ), mRotation( 0 )
5764
{
5865
setFlag( QGraphicsItem::ItemIsSelectable, true );
5966
setAcceptsHoverEvents( true );
@@ -124,6 +131,7 @@ bool QgsComposerItem::_writeXML( QDomElement& itemElem, QDomDocument& doc ) cons
124131
composerItemElem.setAttribute( "height", rect().height() );
125132
composerItemElem.setAttribute( "zValue", QString::number( zValue() ) );
126133
composerItemElem.setAttribute( "outlineWidth", QString::number( pen().widthF() ) );
134+
composerItemElem.setAttribute( "rotation", mRotation );
127135

128136
//position lock for mouse moves/resizes
129137
if ( mItemPositionLocked )
@@ -168,6 +176,9 @@ bool QgsComposerItem::_readXML( const QDomElement& itemElem, const QDomDocument&
168176
return false;
169177
}
170178

179+
//rotation
180+
mRotation = itemElem.attribute( "rotation", "0" ).toDouble();
181+
171182
//frame
172183
QString frame = itemElem.attribute( "frame" );
173184
if ( frame.compare( "true", Qt::CaseInsensitive ) == 0 )
@@ -794,3 +805,147 @@ void QgsComposerItem::updateCursor( const QPointF& itemPos )
794805
{
795806
setCursor( cursorForPosition( itemPos ) );
796807
}
808+
809+
void QgsComposerItem::setRotation( double r )
810+
{
811+
if ( r > 360 )
812+
{
813+
mRotation = (( int )r ) % 360;
814+
}
815+
else
816+
{
817+
mRotation = r;
818+
}
819+
emit rotationChanged( r );
820+
update();
821+
}
822+
823+
bool QgsComposerItem::imageSizeConsideringRotation( double& width, double& height ) const
824+
{
825+
if ( abs( mRotation ) <= 0 ) //width and height stays the same if there is no rotation
826+
{
827+
return true;
828+
}
829+
830+
double x1 = 0;
831+
double y1 = 0;
832+
double x2 = width;
833+
double y2 = 0;
834+
double x3 = width;
835+
double y3 = height;
836+
double x4 = 0;
837+
double y4 = height;
838+
double midX = width / 2.0;
839+
double midY = height / 2.0;
840+
841+
if ( !cornerPointOnRotatedAndScaledRect( x1, y1, width, height ) )
842+
{
843+
return false;
844+
}
845+
if ( !cornerPointOnRotatedAndScaledRect( x2, y2, width, height ) )
846+
{
847+
return false;
848+
}
849+
if ( !cornerPointOnRotatedAndScaledRect( x3, y3, width, height ) )
850+
{
851+
return false;
852+
}
853+
if ( !cornerPointOnRotatedAndScaledRect( x4, y4, width, height ) )
854+
{
855+
return false;
856+
}
857+
858+
859+
//assume points 1 and 3 are on the rectangle boundaries. Calculate 2 and 4.
860+
double distM1 = sqrt(( x1 - midX ) * ( x1 - midX ) + ( y1 - midY ) * ( y1 - midY ) );
861+
QPointF p2 = pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x2, y2 ), distM1 );
862+
QPointF p4 = pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x4, y4 ), distM1 );
863+
864+
if ( p2.x() < width && p2.x() > 0 && p2.y() < height && p2.y() > 0 )
865+
{
866+
width = sqrt(( p2.x() - x1 ) * ( p2.x() - x1 ) + ( p2.y() - y1 ) * ( p2.y() - y1 ) );
867+
height = sqrt(( x3 - p2.x() ) * ( x3 - p2.x() ) + ( y3 - p2.y() ) * ( y3 - p2.y() ) );
868+
return true;
869+
}
870+
871+
//else assume that points 2 and 4 are on the rectangle boundaries. Calculate 1 and 3
872+
double distM2 = sqrt(( x2 - midX ) * ( x2 - midX ) + ( y2 - midY ) * ( y2 - midY ) );
873+
QPointF p1 = pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x1, y1 ), distM2 );
874+
QPointF p3 = pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x3, y3 ), distM2 );
875+
width = sqrt(( x2 - p1.x() ) * ( x2 - p1.x() ) + ( y2 - p1.y() ) * ( y2 - p1.y() ) );
876+
height = sqrt(( p3.x() - x2 ) * ( p3.x() - x2 ) + ( p3.y() - y2 ) * ( p3.y() - y2 ) );
877+
return true;
878+
879+
880+
#if 0
881+
double x1 = 0;
882+
double y1 = 0;
883+
double x2 = width;
884+
double y2 = 0;
885+
double x3 = width;
886+
double y3 = height;
887+
888+
if ( !cornerPointOnRotatedAndScaledRect( x1, y1, width, height ) )
889+
{
890+
return false;
891+
}
892+
if ( !cornerPointOnRotatedAndScaledRect( x2, y2, width, height ) )
893+
{
894+
return false;
895+
}
896+
if ( !cornerPointOnRotatedAndScaledRect( x3, y3, width, height ) )
897+
{
898+
return false;
899+
}
900+
901+
width = sqrt(( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) );
902+
height = sqrt(( x3 - x2 ) * ( x3 - x2 ) + ( y3 - y2 ) * ( y3 - y2 ) );
903+
return true;
904+
#endif //0
905+
}
906+
907+
bool QgsComposerItem::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
908+
{
909+
//first rotate point clockwise
910+
double rotToRad = mRotation * M_PI / 180.0;
911+
QPointF midpoint( width / 2.0, height / 2.0 );
912+
double xVector = x - midpoint.x();
913+
double yVector = y - midpoint.y();
914+
//double xRotated = cos(rotToRad) * xVector + sin(rotToRad) * yVector;
915+
//double yRotated = -sin(rotToRad) * xVector + cos(rotToRad) * yVector;
916+
double xRotated = cos( rotToRad ) * xVector - sin( rotToRad ) * yVector;
917+
double yRotated = sin( rotToRad ) * xVector + cos( rotToRad ) * yVector;
918+
919+
//create line from midpoint to rotated point
920+
QLineF line( midpoint.x(), midpoint.y(), midpoint.x() + xRotated, midpoint.y() + yRotated );
921+
922+
//intersect with all four borders and return result
923+
QList<QLineF> borders;
924+
borders << QLineF( 0, 0, width, 0 );
925+
borders << QLineF( width, 0, width, height );
926+
borders << QLineF( width, height, 0, height );
927+
borders << QLineF( 0, height, 0, 0 );
928+
929+
QList<QLineF>::const_iterator it = borders.constBegin();
930+
QPointF intersectionPoint;
931+
932+
for ( ; it != borders.constEnd(); ++it )
933+
{
934+
if ( line.intersect( *it, &intersectionPoint ) == QLineF::BoundedIntersection )
935+
{
936+
x = intersectionPoint.x();
937+
y = intersectionPoint.y();
938+
return true;
939+
}
940+
}
941+
return false;
942+
}
943+
944+
QPointF QgsComposerItem::pointOnLineWithDistance( const QPointF& startPoint, const QPointF& directionPoint, double distance ) const
945+
{
946+
double dx = directionPoint.x() - startPoint.x();
947+
double dy = directionPoint.y() - startPoint.y();
948+
double length = sqrt( dx * dx + dy * dy );
949+
double scaleFactor = distance / length;
950+
return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
951+
}

‎src/core/composer/qgscomposeritem.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "qgscomposition.h"
2121
#include <QGraphicsRectItem>
22+
#include <QObject>
2223

2324
class QWidget;
2425
class QDomDocument;
@@ -29,9 +30,9 @@ class QqsComposition;
2930
/** \ingroup MapComposer
3031
* A item that forms part of a map composition.
3132
*/
32-
class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem
33+
class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem
3334
{
34-
35+
Q_OBJECT
3536
public:
3637

3738
/**Describes the action (move or resize in different directon) to be done during mouse move*/
@@ -168,6 +169,11 @@ class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem
168169
@note this method was added in version 1.2*/
169170
void updateCursor( const QPointF& itemPos );
170171

172+
double rotation() const {return mRotation;}
173+
174+
public slots:
175+
void setRotation( double r );
176+
171177
protected:
172178

173179
QgsComposition* mComposition;
@@ -191,6 +197,9 @@ class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem
191197
/**Backup to restore item appearance if no view scale factor is available*/
192198
mutable double mLastValidViewScaleFactor;
193199

200+
/**Item rotation in degrees, clockwise*/
201+
double mRotation;
202+
194203
//event handlers
195204
virtual void mouseMoveEvent( QGraphicsSceneMouseEvent * event );
196205
virtual void mousePressEvent( QGraphicsSceneMouseEvent * event );
@@ -235,6 +244,17 @@ class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem
235244
@return the factor or -1 in case of error (e.g. graphic view does not exist)
236245
@note: this function was introduced in version 1.2*/
237246
double horizontalViewScaleFactor() const;
247+
248+
/**Calculates width and hight of the picture (in mm) such that it fits into the item frame with the given rotation*/
249+
bool imageSizeConsideringRotation( double& width, double& height ) const;
250+
/**Calculates corner point after rotation and scaling*/
251+
bool cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const;
252+
/**Returns a point on the line from startPoint to directionPoint that is a certain distance away from the starting point*/
253+
QPointF pointOnLineWithDistance( const QPointF& startPoint, const QPointF& directionPoint, double distance ) const;
254+
255+
signals:
256+
/**Is emitted on rotation change to notify north arrow pictures*/
257+
void rotationChanged( double newRotation );
238258
};
239259

240260
#endif

‎src/core/composer/qgscomposeritemgroup.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@
1616
***************************************************************************/
1717

1818
#include "qgscomposeritem.h"
19-
#include <QObject>
2019
#include <QSet>
2120

2221
/** \ingroup MapComposer
2322
* A container for grouping several QgsComposerItems
2423
*/
25-
class CORE_EXPORT QgsComposerItemGroup: public QObject, public QgsComposerItem
24+
class CORE_EXPORT QgsComposerItemGroup: public QgsComposerItem
2625
{
2726
Q_OBJECT
2827
public:

‎src/core/composer/qgscomposerlegend.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@
2020

2121
#include "qgscomposeritem.h"
2222
#include "qgslegendmodel.h"
23-
#include <QObject>
2423

2524
class QgsSymbol;
2625

2726
/** \ingroup MapComposer
2827
* A legend that can be placed onto a map composition
2928
*/
30-
class CORE_EXPORT QgsComposerLegend: public QObject, public QgsComposerItem
29+
class CORE_EXPORT QgsComposerLegend: public QgsComposerItem
3130
{
3231
Q_OBJECT
3332

‎src/core/composer/qgscomposermap.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@
4242
QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int width, int height )
4343
: QgsComposerItem( x, y, width, height, composition ), mKeepLayerSet( false ), mGridEnabled( false ), mGridStyle( Solid ), \
4444
mGridIntervalX( 0.0 ), mGridIntervalY( 0.0 ), mGridOffsetX( 0.0 ), mGridOffsetY( 0.0 ), mGridAnnotationPrecision( 3 ), mShowGridAnnotation( false ), \
45-
mGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 ), mGridAnnotationDirection( Horizontal ), \
46-
mRotation( 0 ), mCrossLength( 3 )
45+
mGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 ), mGridAnnotationDirection( Horizontal ), mCrossLength( 3 )
4746
{
4847
mComposition = composition;
4948
mId = mComposition->composerMapItems().size();
@@ -74,8 +73,7 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int w
7473
QgsComposerMap::QgsComposerMap( QgsComposition *composition )
7574
: QgsComposerItem( 0, 0, 10, 10, composition ), mKeepLayerSet( false ), mGridEnabled( false ), mGridStyle( Solid ), \
7675
mGridIntervalX( 0.0 ), mGridIntervalY( 0.0 ), mGridOffsetX( 0.0 ), mGridOffsetY( 0.0 ), mGridAnnotationPrecision( 3 ), mShowGridAnnotation( false ), \
77-
mGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 ), mGridAnnotationDirection( Horizontal ), \
78-
mRotation( 0 ), mCrossLength( 3 )
76+
mGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 ), mGridAnnotationDirection( Horizontal ), mCrossLength( 3 )
7977
{
8078
//Offset
8179
mXOffset = 0.0;
@@ -505,9 +503,9 @@ void QgsComposerMap::setOffset( double xOffset, double yOffset )
505503
mYOffset = yOffset;
506504
}
507505

508-
void QgsComposerMap::setRotation( double r )
506+
void QgsComposerMap::setMapRotation( double r )
509507
{
510-
mRotation = r;
508+
setRotation( r );
511509
emit rotationChanged( r );
512510
}
513511

@@ -588,8 +586,6 @@ bool QgsComposerMap::writeXML( QDomElement& elem, QDomDocument & doc ) const
588586
{
589587
composerMapElem.setAttribute( "keepLayerSet", "false" );
590588
}
591-
//rotation
592-
composerMapElem.setAttribute( "rotation", mRotation );
593589

594590
//extent
595591
QDomElement extentElem = doc.createElement( "Extent" );
@@ -670,9 +666,6 @@ bool QgsComposerMap::readXML( const QDomElement& itemElem, const QDomDocument& d
670666
mPreviewMode = Rectangle;
671667
}
672668

673-
//rotation
674-
mRotation = itemElem.attribute( "rotation", "0" ).toDouble();
675-
676669
//extent
677670
QDomNodeList extentNodeList = itemElem.elementsByTagName( "Extent" );
678671
if ( extentNodeList.size() > 0 )
@@ -1400,6 +1393,7 @@ void QgsComposerMap::rotate( double angle, double& x, double& y ) const
14001393
y = yRot;
14011394
}
14021395

1396+
#if 0
14031397
QPointF QgsComposerMap::pointOnLineWithDistance( const QPointF& startPoint, const QPointF& directionPoint, double distance ) const
14041398
{
14051399
double dx = directionPoint.x() - startPoint.x();
@@ -1408,3 +1402,4 @@ QPointF QgsComposerMap::pointOnLineWithDistance( const QPointF& startPoint, cons
14081402
double scaleFactor = distance / length;
14091403
return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
14101404
}
1405+
#endif //0

‎src/core/composer/qgscomposermap.h

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "qgscomposeritem.h"
2222
#include "qgsrectangle.h"
2323
#include <QGraphicsRectItem>
24-
#include <QObject>
2524

2625
class QgsComposition;
2726
class QgsMapRenderer;
@@ -35,7 +34,7 @@ class QPainter;
3534
* \brief Object representing map window.
3635
*/
3736
// NOTE: QgsComposerMapBase must be first, otherwise does not compile
38-
class CORE_EXPORT QgsComposerMap : /*public QWidget, private Ui::QgsComposerMapBase,*/ public QObject, public QgsComposerItem
37+
class CORE_EXPORT QgsComposerMap : public QgsComposerItem
3938
{
4039
Q_OBJECT
4140

@@ -239,16 +238,13 @@ class CORE_EXPORT QgsComposerMap : /*public QWidget, private Ui::QgsComposerMapB
239238
@note this function was added in version 1.4*/
240239
void updateBoundingRect();
241240

242-
/**Sets the rotation of the map content
243-
@note this function was added in version 1.4*/
244-
void setRotation( double r );
245-
double rotation() const { return mRotation; }
246-
247241
/**Sets length of the cros segments (if grid style is cross)
248242
@note this function was added in version 1.4*/
249243
void setCrossLength( double l ) {mCrossLength = l;}
250244
double crossLength() {return mCrossLength;}
251245

246+
void setMapRotation( double r );
247+
252248
public slots:
253249

254250
/**Called if map canvas has changed*/
@@ -259,8 +255,6 @@ class CORE_EXPORT QgsComposerMap : /*public QWidget, private Ui::QgsComposerMapB
259255
signals:
260256
/**Is emitted when width/height is changed as a result of user interaction*/
261257
void extentChanged();
262-
/**Is emitted on rotation change to notify north arrow pictures*/
263-
void rotationChanged( double newRotation );
264258

265259
private:
266260

@@ -345,9 +339,6 @@ class CORE_EXPORT QgsComposerMap : /*public QWidget, private Ui::QgsComposerMapB
345339
GridAnnotationDirection mGridAnnotationDirection;
346340
/**Current bounding rectangle. This is used to check if notification to the graphics scene is necessary*/
347341
QRectF mCurrentRectangle;
348-
349-
/**Rotation of the map. Clockwise in degrees, north direction is 0*/
350-
double mRotation;
351342
/**The length of the cross sides for mGridStyle Cross*/
352343
double mCrossLength;
353344

@@ -395,8 +386,10 @@ class CORE_EXPORT QgsComposerMap : /*public QWidget, private Ui::QgsComposerMapB
395386
@param x in/out: x coordinate before / after the rotation
396387
@param y in/out: y cooreinate before / after the rotation*/
397388
void rotate( double angle, double& x, double& y ) const;
389+
#if 0
398390
/**Returns a point on the line from startPoint to directionPoint that is a certain distance away from the starting point*/
399391
QPointF pointOnLineWithDistance( const QPointF& startPoint, const QPointF& directionPoint, double distance ) const;
392+
#endif //0
400393
};
401394

402395
#endif

‎src/core/composer/qgscomposerpicture.cpp

Lines changed: 6 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,12 @@
2626
#include <QPainter>
2727
#include <QSvgRenderer>
2828

29-
#ifndef Q_OS_MACX
30-
#include <cmath>
31-
#else
32-
#include <math.h>
33-
#endif
34-
35-
QgsComposerPicture::QgsComposerPicture( QgsComposition *composition ): QObject( 0 ), QgsComposerItem( composition ), mRotation( 0.0 ), mMode( Unknown ), \
36-
mSvgCacheUpToDate( false ), mCachedDpi( 0 ), mRotationMap( 0 )
29+
QgsComposerPicture::QgsComposerPicture( QgsComposition *composition ): QgsComposerItem( composition ), mMode( Unknown ), \
30+
mSvgCacheUpToDate( false ), mCachedDpi( 0 ), mCachedRotation( 0 ), mRotationMap( 0 )
3731
{
3832
}
3933

40-
QgsComposerPicture::QgsComposerPicture(): QgsComposerItem( 0 ), mRotation( 0.0 ), mMode( Unknown ), mSvgCacheUpToDate( false ), mRotationMap( 0 )
34+
QgsComposerPicture::QgsComposerPicture(): QgsComposerItem( 0 ), mMode( Unknown ), mSvgCacheUpToDate( false ), mCachedRotation( 0 ), mRotationMap( 0 )
4135
{
4236

4337
}
@@ -57,7 +51,7 @@ void QgsComposerPicture::paint( QPainter* painter, const QStyleOptionGraphicsIte
5751
drawBackground( painter );
5852

5953
int newDpi = ( painter->device()->logicalDpiX() + painter->device()->logicalDpiY() ) / 2;
60-
if ( newDpi != mCachedDpi )
54+
if ( newDpi != mCachedDpi || mCachedRotation != mRotation )
6155
{
6256
mSvgCacheUpToDate = false;
6357
}
@@ -103,6 +97,7 @@ void QgsComposerPicture::paint( QPainter* painter, const QStyleOptionGraphicsIte
10397
}
10498

10599
mCachedDpi = newDpi;
100+
mCachedRotation = mRotation;
106101

107102
//frame and selection boxes
108103
drawFrame( painter );
@@ -204,79 +199,7 @@ void QgsComposerPicture::updateImageFromSvg()
204199
mSvgCacheUpToDate = true;
205200
}
206201

207-
bool QgsComposerPicture::imageSizeConsideringRotation( double& width, double& height ) const
208-
{
209-
double x1 = 0;
210-
double y1 = 0;
211-
double x2 = width;
212-
double y2 = 0;
213-
double x3 = width;
214-
double y3 = height;
215-
#if 0
216-
double x4 = 0;
217-
double y4 = height;
218-
#endif
219-
220-
if ( !cornerPointOnRotatedAndScaledRect( x1, y1, width, height ) )
221-
{
222-
return false;
223-
}
224-
if ( !cornerPointOnRotatedAndScaledRect( x2, y2, width, height ) )
225-
{
226-
return false;
227-
}
228-
if ( !cornerPointOnRotatedAndScaledRect( x3, y3, width, height ) )
229-
{
230-
return false;
231-
}
232-
#if 0
233-
if ( !cornerPointOnRotatedAndScaledRect( x4, y4, width, height ) )
234-
{
235-
return false;
236-
}
237-
#endif
238-
239-
width = sqrt(( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) );
240-
height = sqrt(( x3 - x2 ) * ( x3 - x2 ) + ( y3 - y2 ) * ( y3 - y2 ) );
241-
return true;
242-
}
243202

244-
bool QgsComposerPicture::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
245-
{
246-
//first rotate point clockwise
247-
double rotToRad = mRotation * M_PI / 180.0;
248-
QPointF midpoint( width / 2.0, height / 2.0 );
249-
double xVector = x - midpoint.x();
250-
double yVector = y - midpoint.y();
251-
//double xRotated = cos(rotToRad) * xVector + sin(rotToRad) * yVector;
252-
//double yRotated = -sin(rotToRad) * xVector + cos(rotToRad) * yVector;
253-
double xRotated = cos( rotToRad ) * xVector - sin( rotToRad ) * yVector;
254-
double yRotated = sin( rotToRad ) * xVector + cos( rotToRad ) * yVector;
255-
256-
//create line from midpoint to rotated point
257-
QLineF line( midpoint.x(), midpoint.y(), midpoint.x() + xRotated, midpoint.y() + yRotated );
258-
259-
//intersect with all four borders and return result
260-
QList<QLineF> borders;
261-
borders << QLineF( 0, 0, width, 0 );
262-
borders << QLineF( width, 0, width, height );
263-
borders << QLineF( width, height, 0, height );
264-
borders << QLineF( 0, height, 0, 0 );
265-
266-
QList<QLineF>::const_iterator it = borders.constBegin();
267-
QPointF intersectionPoint;
268-
269-
for ( ; it != borders.constEnd(); ++it )
270-
{
271-
if ( line.intersect( *it, &intersectionPoint ) == QLineF::BoundedIntersection )
272-
{
273-
x = intersectionPoint.x();
274-
y = intersectionPoint.y();
275-
return true;
276-
}
277-
}
278-
return false;
279-
}
280203

281204
void QgsComposerPicture::setSceneRect( const QRectF& rectangle )
282205
{
@@ -285,20 +208,6 @@ void QgsComposerPicture::setSceneRect( const QRectF& rectangle )
285208
emit settingsChanged();
286209
}
287210

288-
void QgsComposerPicture::setRotation( double rotation )
289-
{
290-
if ( rotation > 360 )
291-
{
292-
mRotation = (( int )rotation ) % 360;
293-
}
294-
else
295-
{
296-
mRotation = rotation;
297-
}
298-
emit settingsChanged();
299-
update();
300-
}
301-
302211
void QgsComposerPicture::setRotationMap( int composerMapId )
303212
{
304213
if ( !mComposition )
@@ -324,6 +233,7 @@ void QgsComposerPicture::setRotationMap( int composerMapId )
324233
mRotation = map->rotation();
325234
QObject::connect( map, SIGNAL( rotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
326235
mRotationMap = map;
236+
setRotation( map->rotation() );
327237
}
328238

329239
QString QgsComposerPicture::pictureFile() const
@@ -339,7 +249,6 @@ bool QgsComposerPicture::writeXML( QDomElement& elem, QDomDocument & doc ) const
339249
}
340250
QDomElement composerPictureElem = doc.createElement( "ComposerPicture" );
341251
composerPictureElem.setAttribute( "file", QgsProject::instance()->writePath( mSourceFile.fileName() ) );
342-
composerPictureElem.setAttribute( "rotation", QString::number( mRotation ) );
343252
if ( !mRotationMap )
344253
{
345254
composerPictureElem.setAttribute( "mapId", -1 );
@@ -375,8 +284,6 @@ bool QgsComposerPicture::readXML( const QDomElement& itemElem, const QDomDocumen
375284
QString fileName = QgsProject::instance()->readPath( itemElem.attribute( "file" ) );
376285
setPictureFile( fileName );
377286

378-
mRotation = itemElem.attribute( "rotation" ).toDouble();
379-
380287
//rotation map
381288
int rotationMapId = itemElem.attribute( "mapId", "-1" ).toInt();
382289
if ( rotationMapId == -1 )

‎src/core/composer/qgscomposerpicture.h

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@
2020
#include "qgscomposeritem.h"
2121
#include <QFile>
2222
#include <QImage>
23-
#include <QObject>
2423

2524
/** \ingroup MapComposer
2625
* A composer class that displays svg files or raster format (jpg, png, ...)
2726
* */
28-
class CORE_EXPORT QgsComposerPicture: public QObject, public QgsComposerItem
27+
class CORE_EXPORT QgsComposerPicture: public QgsComposerItem
2928
{
3029
Q_OBJECT
3130
public:
@@ -43,8 +42,6 @@ class CORE_EXPORT QgsComposerPicture: public QObject, public QgsComposerItem
4342
corresponds to 1 scene size unit*/
4443
void setSceneRect( const QRectF& rectangle );
4544

46-
double rotation() const {return mRotation;}
47-
4845
/** stores state in Dom node
4946
* @param node is Dom node corresponding to 'Composer' tag
5047
* @param temp write template file
@@ -63,10 +60,6 @@ class CORE_EXPORT QgsComposerPicture: public QObject, public QgsComposerItem
6360
/**True if the rotation is taken from a map item*/
6461
bool useRotationMap() const {return mRotationMap;}
6562

66-
public slots:
67-
68-
void setRotation( double rotation );
69-
7063
private:
7164

7265
enum Mode //SVG or raster graphic format
@@ -87,18 +80,15 @@ class CORE_EXPORT QgsComposerPicture: public QObject, public QgsComposerItem
8780
@param out: boundWidth width of mImage that is used by the svg renderer. May different from mImage.width() to preserve aspect ratio
8881
@param out: boundHeight height of mImage that is used by the svg renderer*/
8982
void updateImageFromSvg();
90-
/**Calculates width and hight of the picture (in mm) such that it fits into the item frame with the given rotation*/
91-
bool imageSizeConsideringRotation( double& width, double& height ) const;
92-
/**Calculates corner point after rotation and scaling*/
93-
bool cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const;
83+
9484

9585
QImage mImage;
96-
double mRotation;
9786
QFile mSourceFile;
9887
Mode mMode;
9988
/**False if image needs to be rendered from svg*/
10089
bool mSvgCacheUpToDate;
10190
int mCachedDpi; //store dpis for which the svg cache is valid
91+
double mCachedRotation; //store last rotation value to generate new pixmap from svg on change
10292
QSize mDefaultSvgSize;
10393
/**Map that sets the rotation (or 0 if this picture uses map independent rotation)*/
10494
const QgsComposerMap* mRotationMap;

‎src/core/composer/qgscomposerscalebar.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#define QGSCOMPOSERSCALEBAR_H
1818

1919
#include "qgscomposeritem.h"
20-
#include <QObject>
2120
#include <QPen>
2221

2322
class QgsComposerMap;
@@ -26,7 +25,7 @@ class QgsScaleBarStyle;
2625
* A scale bar item that can be added to a map composition.
2726
*/
2827

29-
class CORE_EXPORT QgsComposerScaleBar: public QObject, public QgsComposerItem
28+
class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem
3029
{
3130

3231
Q_OBJECT
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/***************************************************************************
2+
qgscomposershape.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 "qgscomposershape.h"
19+
#include <QPainter>
20+
21+
QgsComposerShape::QgsComposerShape( QgsComposition* composition ): QgsComposerItem( composition ), mShape( Ellipse )
22+
{
23+
initBrushAndPen();
24+
}
25+
26+
QgsComposerShape::QgsComposerShape( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition ): QgsComposerItem( x, y, width, height, composition ), mShape( Ellipse )
27+
{
28+
setSceneRect( QRectF( x, y, width, height ) );
29+
initBrushAndPen();
30+
}
31+
32+
QgsComposerShape::~QgsComposerShape()
33+
{
34+
35+
}
36+
37+
void QgsComposerShape::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
38+
{
39+
double width = rect().width();
40+
double height = rect().height();
41+
imageSizeConsideringRotation( width, height );
42+
43+
painter->save();
44+
painter->setRenderHint( QPainter::Antialiasing );
45+
painter->setPen( mPen );
46+
painter->setBrush( mBrush );
47+
48+
painter->translate( rect().width() / 2.0, rect().height() / 2.0 );
49+
painter->rotate( mRotation );
50+
painter->translate( -width / 2.0, -height / 2.0 );
51+
52+
double halfPenWidth = mPen.widthF() / 2.0;
53+
54+
switch ( mShape )
55+
{
56+
case Ellipse:
57+
painter->drawEllipse( QRectF( halfPenWidth, halfPenWidth , width - mPen.widthF(), height - mPen.widthF() ) );
58+
break;
59+
case Rectangle:
60+
painter->drawRect( QRectF( halfPenWidth, halfPenWidth , width - mPen.widthF(), height - mPen.widthF() ) );
61+
break;
62+
case Triangle:
63+
QPolygonF triangle;
64+
triangle << QPointF( halfPenWidth, height - halfPenWidth );
65+
triangle << QPointF( width - halfPenWidth, height - halfPenWidth );
66+
triangle << QPointF( width / 2.0, halfPenWidth );
67+
painter->drawPolygon( triangle );
68+
break;
69+
}
70+
71+
painter->restore();
72+
73+
drawFrame( painter );
74+
if ( isSelected() )
75+
{
76+
drawSelectionBoxes( painter );
77+
}
78+
}
79+
80+
bool QgsComposerShape::writeXML( QDomElement& elem, QDomDocument & doc ) const
81+
{
82+
QDomElement composerShapeElem = doc.createElement( "ComposerShape" );
83+
composerShapeElem.setAttribute( "shapeType", mShape );
84+
composerShapeElem.setAttribute( "outlineWidth", mPen.widthF() );
85+
composerShapeElem.setAttribute( "transparentFill", mBrush.style() == Qt::NoBrush );
86+
QDomElement outlineColorElem = doc.createElement( "OutlineColor" );
87+
outlineColorElem.setAttribute( "red", mPen.color().red() );
88+
outlineColorElem.setAttribute( "green", mPen.color().green() );
89+
outlineColorElem.setAttribute( "blue", mPen.color().blue() );
90+
composerShapeElem.appendChild( outlineColorElem );
91+
QDomElement fillColorElem = doc.createElement( "FillColor" );
92+
fillColorElem.setAttribute( "red", mBrush.color().red() );
93+
fillColorElem.setAttribute( "green", mBrush.color().green() );
94+
fillColorElem.setAttribute( "blue", mBrush.color().blue() );
95+
composerShapeElem.appendChild( fillColorElem );
96+
elem.appendChild( composerShapeElem );
97+
return _writeXML( composerShapeElem, doc );
98+
}
99+
100+
bool QgsComposerShape::readXML( const QDomElement& itemElem, const QDomDocument& doc )
101+
{
102+
mShape = QgsComposerShape::Shape( itemElem.attribute( "shapeType", "0" ).toInt() );
103+
mPen.setWidthF( itemElem.attribute( "outlineWidth", "0.4" ).toDouble() );
104+
105+
//transparent fill
106+
bool transparent = itemElem.attribute( "transparentFill", "1" ).toInt() == 1;
107+
if ( transparent )
108+
{
109+
mBrush.setStyle( Qt::NoBrush );
110+
}
111+
else
112+
{
113+
mBrush.setStyle( Qt::SolidPattern );
114+
}
115+
116+
//outline color
117+
QDomNodeList outlineColorList = itemElem.elementsByTagName( "OutlineColor" );
118+
if ( outlineColorList.size() > 0 )
119+
{
120+
QDomElement outlineColorElem = outlineColorList.at( 0 ).toElement();
121+
int penRed = outlineColorElem.attribute( "red", "0" ).toInt();
122+
int penGreen = outlineColorElem.attribute( "green", "0" ).toInt();
123+
int penBlue = outlineColorElem.attribute( "blue", "0" ).toInt();
124+
mPen.setColor( QColor( penRed, penGreen, penBlue ) );
125+
}
126+
127+
//fill color
128+
QDomNodeList fillNodeList = itemElem.elementsByTagName( "FillColor" );
129+
if ( fillNodeList.size() > 0 )
130+
{
131+
QDomElement fillColorElem = fillNodeList.at( 0 ).toElement();
132+
int brushRed = fillColorElem.attribute( "red", "0" ).toInt();
133+
int brushGreen = fillColorElem.attribute( "green", "0" ).toInt();
134+
int brushBlue = fillColorElem.attribute( "blue", "0" ).toInt();
135+
mBrush.setColor( QColor( brushRed, brushGreen, brushBlue ) );
136+
}
137+
138+
139+
//restore general composer item properties
140+
QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
141+
if ( composerItemList.size() > 0 )
142+
{
143+
QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
144+
_readXML( composerItemElem, doc );
145+
}
146+
return true;
147+
}
148+
149+
void QgsComposerShape::setLineWidth( double width )
150+
{
151+
mPen.setWidthF( width );
152+
}
153+
154+
double QgsComposerShape::lineWidth() const
155+
{
156+
return mPen.widthF();
157+
}
158+
159+
void QgsComposerShape::setOutlineColor( const QColor& color )
160+
{
161+
mPen.setColor( color );
162+
}
163+
164+
QColor QgsComposerShape::outlineColor() const
165+
{
166+
return mPen.color();
167+
}
168+
169+
void QgsComposerShape::setFillColor( const QColor& color )
170+
{
171+
mBrush.setColor( color );
172+
}
173+
174+
QColor QgsComposerShape::fillColor() const
175+
{
176+
return mBrush.color();
177+
}
178+
179+
bool QgsComposerShape::transparentFill() const
180+
{
181+
return mBrush.style() == Qt::NoBrush;
182+
}
183+
184+
void QgsComposerShape::setTransparentFill( bool transparent )
185+
{
186+
if ( transparent )
187+
{
188+
mBrush.setStyle( Qt::NoBrush );
189+
}
190+
else
191+
{
192+
mBrush.setStyle( Qt::SolidPattern );
193+
}
194+
}
195+
196+
void QgsComposerShape::initBrushAndPen()
197+
{
198+
mPen.setColor( QColor( 0, 0, 0 ) );
199+
mPen.setWidthF( 1 );
200+
mPen.setJoinStyle( Qt::RoundJoin );
201+
mBrush.setColor( QColor( 0, 0, 0 ) );
202+
mBrush.setStyle( Qt::NoBrush );
203+
}

‎src/core/composer/qgscomposershape.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/***************************************************************************
2+
qgscomposershape.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 QGSCOMPOSERSHAPE_H
19+
#define QGSCOMPOSERSHAPE_H
20+
21+
#include "qgscomposeritem.h"
22+
23+
/**A composer items that draws common shapes (ellipse, triangle, rectangle)*/
24+
class QgsComposerShape: public QgsComposerItem
25+
{
26+
public:
27+
28+
enum Shape
29+
{
30+
Ellipse,
31+
Rectangle,
32+
Triangle
33+
};
34+
35+
QgsComposerShape( QgsComposition* composition );
36+
QgsComposerShape( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition );
37+
~QgsComposerShape();
38+
39+
/** \brief Reimplementation of QCanvasItem::paint - draw on canvas */
40+
void paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget );
41+
42+
/** stores state in Dom node
43+
* @param node is Dom node corresponding to 'Composer' tag
44+
* @param temp write template file
45+
*/
46+
bool writeXML( QDomElement& elem, QDomDocument & doc ) const;
47+
48+
/** sets state from Dom document
49+
* @param itemElem is Dom node corresponding to item tag
50+
*/
51+
bool readXML( const QDomElement& itemElem, const QDomDocument& doc );
52+
53+
//setters and getters
54+
void setLineWidth( double width );
55+
double lineWidth() const;
56+
void setOutlineColor( const QColor& color );
57+
QColor outlineColor() const;
58+
void setFillColor( const QColor& color );
59+
QColor fillColor() const;
60+
QgsComposerShape::Shape shapeType() const {return mShape;}
61+
void setShapeType( QgsComposerShape::Shape s ) {mShape = s;}
62+
bool transparentFill() const;
63+
void setTransparentFill( bool transparent );
64+
65+
66+
private:
67+
/**Ellipse, rectangle or triangle*/
68+
Shape mShape;
69+
/**Shape outline*/
70+
QPen mPen;
71+
/**Shape fill*/
72+
QBrush mBrush;
73+
/**Apply default graphics settings*/
74+
void initBrushAndPen();
75+
76+
/**Returns a point on the line from startPoint to directionPoint that is a certain distance away from the starting point*/
77+
QPointF pointOnLineWithDistance( const QPointF& startPoint, const QPointF& directionPoint, double distance ) const;
78+
};
79+
80+
#endif // QGSCOMPOSERSHAPEITEM_H

‎src/gui/qgscomposerview.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "qgscomposeritemgroup.h"
2727
#include "qgscomposerpicture.h"
2828
#include "qgscomposerscalebar.h"
29+
#include "qgscomposershape.h"
2930

3031
QgsComposerView::QgsComposerView( QWidget* parent, const char* name, Qt::WFlags f ) :
3132
QGraphicsView( parent ), mShiftKeyPressed( false ), mRubberBandItem( 0 ), mMoveContentItem( 0 )
@@ -96,8 +97,9 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
9697
break;
9798
}
9899

99-
//create rubber band
100+
//create rubber band for map and ellipse items
100101
case AddMap:
102+
case AddShape:
101103
{
102104
QTransform t;
103105
mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 );
@@ -186,6 +188,23 @@ void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
186188
break;
187189
}
188190

191+
case AddShape:
192+
{
193+
if ( !mRubberBandItem || mRubberBandItem->rect().width() < 0.1 || mRubberBandItem->rect().width() < 0.1 )
194+
{
195+
scene()->removeItem( mRubberBandItem );
196+
delete mRubberBandItem;
197+
return;
198+
}
199+
200+
QgsComposerShape* composerShape = new QgsComposerShape( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height(), composition() );
201+
addComposerShape( composerShape );
202+
scene()->removeItem( mRubberBandItem );
203+
delete mRubberBandItem;
204+
emit actionFinished();
205+
break;
206+
}
207+
189208
case AddMap:
190209
{
191210
if ( !mRubberBandItem || mRubberBandItem->rect().width() < 0.1 || mRubberBandItem->rect().width() < 0.1 )
@@ -233,6 +252,7 @@ void QgsComposerView::mouseMoveEvent( QMouseEvent* e )
233252
break;
234253

235254
case AddMap:
255+
case AddShape:
236256
//adjust rubber band item
237257
{
238258
double x = 0;
@@ -446,6 +466,15 @@ void QgsComposerView::addComposerPicture( QgsComposerPicture* picture )
446466
emit selectedItemChanged( picture );
447467
}
448468

469+
void QgsComposerView::addComposerShape( QgsComposerShape* shape )
470+
{
471+
scene()->addItem( shape );
472+
emit composerShapeAdded( shape );
473+
scene()->clearSelection();
474+
shape->setSelected( true );
475+
emit selectedItemChanged( shape );
476+
}
477+
449478
void QgsComposerView::groupItems()
450479
{
451480
if ( !composition() )

‎src/gui/qgscomposerview.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class QgsComposerLegend;
3030
class QgsComposerMap;
3131
class QgsComposerPicture;
3232
class QgsComposerScaleBar;
33+
class QgsComposerShape;
3334

3435
/** \ingroup MapComposer
3536
* \ingroup gui
@@ -53,6 +54,7 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView
5354
AddLabel, // add label
5455
AddScalebar, // add scalebar
5556
AddPicture, // add raster/vector picture
57+
AddShape, //add shape item (ellipse, rectangle, triangle)
5658
MoveItemContent //move content of item (e.g. content of map)
5759
};
5860

@@ -82,6 +84,8 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView
8284
void addComposerLegend( QgsComposerLegend* legend );
8385
/**Adds picture to the graphics scene and advices composer to create a widget for it (through signal)*/
8486
void addComposerPicture( QgsComposerPicture* picture );
87+
/**Adds a composer shape to the graphics scene and acvices composer to create a widget for it (through signal)*/
88+
void addComposerShape( QgsComposerShape* shape );
8589

8690
/**Returns the composer main window*/
8791
QMainWindow* composerWindow();
@@ -127,6 +131,8 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView
127131
void composerLegendAdded( QgsComposerLegend* legend );
128132
/**Is emitted when a new composer picture has been added*/
129133
void composerPictureAdded( QgsComposerPicture* picture );
134+
/**Is emitted when a new composer shape has been added*/
135+
void composerShapeAdded( QgsComposerShape* shape );
130136
/**Is emitted when a composer item has been removed from the scene*/
131137
void itemRemoved( QgsComposerItem* );
132138
/**Current action (e.g. adding composer map) has been finished. The purpose of this signal is that

‎src/ui/qgscomposerbase.ui

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@
169169
<addaction name="mActionAddNewLabel"/>
170170
<addaction name="mActionAddNewLegend"/>
171171
<addaction name="mActionAddNewScalebar"/>
172+
<addaction name="mActionAddBasicShape"/>
172173
<addaction name="mActionSelectMoveItem"/>
173174
<addaction name="mActionMoveItemContent"/>
174175
<addaction name="mActionGroupItems"/>
@@ -443,6 +444,14 @@
443444
<string>Ctrl+Q</string>
444445
</property>
445446
</action>
447+
<action name="mActionAddBasicShape">
448+
<property name="checkable">
449+
<bool>true</bool>
450+
</property>
451+
<property name="text">
452+
<string>Add Basic Shape</string>
453+
</property>
454+
</action>
446455
</widget>
447456
<tabstops>
448457
<tabstop>mCompositionNameComboBox</tabstop>

‎src/ui/qgscomposershapewidgetbase.ui

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>QgsComposerShapeWidgetBase</class>
4+
<widget class="QWidget" name="QgsComposerShapeWidgetBase">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>162</width>
10+
<height>193</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Form</string>
15+
</property>
16+
<layout class="QGridLayout" name="gridLayout">
17+
<item row="0" column="0">
18+
<widget class="QComboBox" name="mShapeComboBox"/>
19+
</item>
20+
<item row="1" column="0">
21+
<widget class="QPushButton" name="mOutlineColorButton">
22+
<property name="text">
23+
<string>Shape outline color...</string>
24+
</property>
25+
</widget>
26+
</item>
27+
<item row="2" column="0">
28+
<widget class="QDoubleSpinBox" name="mOutlineWidthSpinBox">
29+
<property name="prefix">
30+
<string>Outline width </string>
31+
</property>
32+
</widget>
33+
</item>
34+
<item row="3" column="0">
35+
<widget class="QCheckBox" name="mTransparentCheckBox">
36+
<property name="text">
37+
<string>Transparent fill</string>
38+
</property>
39+
</widget>
40+
</item>
41+
<item row="4" column="0">
42+
<widget class="QPushButton" name="mFillColorButton">
43+
<property name="text">
44+
<string>Shape fill Color...</string>
45+
</property>
46+
</widget>
47+
</item>
48+
<item row="5" column="0">
49+
<widget class="QSpinBox" name="mRotationSpinBox">
50+
<property name="prefix">
51+
<string comment="Rotation" extracomment="Rotation">Rotation </string>
52+
</property>
53+
<property name="maximum">
54+
<number>359</number>
55+
</property>
56+
</widget>
57+
</item>
58+
</layout>
59+
</widget>
60+
<resources/>
61+
<connections/>
62+
</ui>

0 commit comments

Comments
 (0)
Please sign in to comment.