QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgscomposeritemgroup.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposeritemgroup.cpp
3  ------------------------
4  begin : 2nd June 2008
5  copyright : (C) 2008 by Marco Hugentobler
6  email : marco dot hugentobler at karto dot baug dot ethz dot ch
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 "qgscomposeritemgroup.h"
19 #include "qgscomposition.h"
20 #include "qgscomposerutils.h"
21 #include "qgslogger.h"
22 #include "qgscomposermodel.h"
23 
24 #include <QPen>
25 #include <QPainter>
26 
28  : QgsComposerItem( c )
29 {
30  setZValue( 90 );
31  show();
32 }
33 
35 {
36  //loop through group members and remove them from the scene
37  Q_FOREACH ( QgsComposerItem* item, mItems )
38  {
39  if ( !item || item->isRemoved() )
40  continue;
41 
42  //inform model that we are about to remove an item from the scene
44  mComposition->removeItem( item );
45  item->setIsGroupMember( false );
46  }
47 }
48 
50 {
51  if ( !item )
52  {
53  return;
54  }
55 
56  if ( mItems.contains( item ) )
57  {
58  return;
59  }
60 
61  connect( item, SIGNAL( destroyed() ), this, SLOT( itemDestroyed() ) );
62 
63  mItems.insert( item );
64  item->setSelected( false );
65  item->setIsGroupMember( true );
66 
67  //update extent
68  if ( mBoundingRectangle.isEmpty() ) //we add the first item
69  {
70  mBoundingRectangle = QRectF( 0, 0, item->rect().width(), item->rect().height() );
71  //call method of superclass to avoid repositioning of items
72  QgsComposerItem::setSceneRect( QRectF( item->pos().x(), item->pos().y(), item->rect().width(), item->rect().height() ) );
73 
74  if ( !qgsDoubleNear( item->itemRotation(), 0.0 ) )
75  {
76  setItemRotation( item->itemRotation() );
77  }
78  }
79  else
80  {
81  if ( !qgsDoubleNear( item->itemRotation(), itemRotation() ) )
82  {
83  //items have mixed rotation, so reset rotation of group
84  mBoundingRectangle = mapRectToScene( mBoundingRectangle );
85  setItemRotation( 0 );
86  mBoundingRectangle = mBoundingRectangle.united( item->mapRectToScene( item->rect() ) );
87  //call method of superclass to avoid repositioning of items
88  QgsComposerItem::setSceneRect( mBoundingRectangle );
89  }
90  else
91  {
92  //items have same rotation, so keep rotation of group
93  mBoundingRectangle = mBoundingRectangle.united( mapRectFromItem( item, item->rect() ) );
94  QPointF newPos = mapToScene( mBoundingRectangle.topLeft().x(), mBoundingRectangle.topLeft().y() );
95  mBoundingRectangle = QRectF( 0, 0, mBoundingRectangle.width(), mBoundingRectangle.height() );
96  QgsComposerItem::setSceneRect( QRectF( newPos.x(), newPos.y(), mBoundingRectangle.width(), mBoundingRectangle.height() ) );
97  }
98  }
99 
100 }
101 
103 {
104  Q_FOREACH ( QgsComposerItem* item, mItems )
105  {
106  item->setIsGroupMember( false );
107  item->setSelected( true );
108  }
109  mItems.clear();
110 }
111 
113 {
114  mItems.remove( static_cast<QgsComposerItem*>( sender() ) );
115 }
116 
117 void QgsComposerItemGroup::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
118 {
119  Q_UNUSED( option );
120  Q_UNUSED( widget );
121  drawFrame( painter );
122  if ( isSelected() )
123  {
124  drawSelectionBoxes( painter );
125  }
126 }
127 
129 {
130  //resize all items in this group
131  //first calculate new group rectangle in current group coordsys
132  QPointF newOrigin = mapFromScene( rectangle.topLeft() );
133  QRectF newRect = QRectF( newOrigin.x(), newOrigin.y(), rectangle.width(), rectangle.height() );
134 
135  Q_FOREACH ( QgsComposerItem* item, mItems )
136  {
137  //each item needs to be scaled relatively to the final size of the group
138  QRectF itemRect = mapRectFromItem( item, item->rect() );
139  QgsComposerUtils::relativeResizeRect( itemRect, rect(), newRect );
140 
141  QPointF newPos = mapToScene( itemRect.topLeft() );
142  item->setSceneRect( QRectF( newPos.x(), newPos.y(), itemRect.width(), itemRect.height() ) );
143  }
144  //lastly, set new rect for group
145  QgsComposerItem::setSceneRect( rectangle );
146 }
147 
148 void QgsComposerItemGroup::setVisibility( const bool visible )
149 {
150  //also set visibility for all items within the group
151  Q_FOREACH ( QgsComposerItem* item, mItems )
152  {
153  item->setVisibility( visible );
154  }
155  //lastly set visibility for group item itself
157 }
158 
160 {
161  if ( !mComposition )
162  {
163  return;
164  }
165 
167  {
168  QPen newPen( pen() );
169  newPen.setStyle( Qt::DashLine );
170  newPen.setColor( QColor( 128, 128, 128, 128 ) );
171  p->setPen( newPen );
172  p->setRenderHint( QPainter::Antialiasing, true );
173  p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
174  }
175 }
176 
178 {
179  QDomElement group = doc.createElement( "ComposerItemGroup" );
180 
182  for ( ; itemIt != mItems.end(); ++itemIt )
183  {
184  QDomElement item = doc.createElement( "ComposerItemGroupElement" );
185  item.setAttribute( "uuid", ( *itemIt )->uuid() );
186  group.appendChild( item );
187  }
188 
189  elem.appendChild( group );
190 
191  return _writeXML( group, doc );
192 }
193 
194 bool QgsComposerItemGroup::readXML( const QDomElement& itemElem, const QDomDocument& doc )
195 {
196  //restore general composer item properties
197  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
198  if ( !composerItemList.isEmpty() )
199  {
200  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
201  _readXML( composerItemElem, doc );
202  }
203 
205 
206  QDomNodeList elementNodes = itemElem.elementsByTagName( "ComposerItemGroupElement" );
207  for ( int i = 0; i < elementNodes.count(); ++i )
208  {
209  QDomNode elementNode = elementNodes.at( i );
210  if ( !elementNode.isElement() )
211  continue;
212 
213  QString uuid = elementNode.toElement().attribute( "uuid" );
214 
215  for ( QList<QGraphicsItem *>::iterator it = items.begin(); it != items.end(); ++it )
216  {
217  QgsComposerItem *item = dynamic_cast<QgsComposerItem *>( *it );
218  if ( item && ( item->mUuid == uuid || item->mTemplateUuid == uuid ) )
219  {
220  addItem( item );
221  break;
222  }
223  }
224  }
225 
226  return true;
227 }
QRectF mapRectFromItem(const QGraphicsItem *item, const QRectF &rect) const
static void relativeResizeRect(QRectF &rectToResize, const QRectF &boundsBefore, const QRectF &boundsAfter)
Resizes a QRectF relative to a resized bounding rectangle.
QDomNodeList elementsByTagName(const QString &tagname) const
void setStyle(Qt::PenStyle style)
void setRenderHint(RenderHint hint, bool on)
QDomNode appendChild(const QDomNode &newChild)
QString attribute(const QString &name, const QString &defValue) const
QgsComposerModel * itemsModel()
Returns the items model attached to the composition.
QList< QGraphicsItem * > items() const
QObject * sender() const
void removeItems() override
Removes the items but does not delete them.
bool isElement() const
A item that forms part of a map composition.
void drawFrame(QPainter *p) override
Draw black frame around item.
virtual void setSelected(bool s)
Set selected, selected item should be highlighted.
double itemRotation(const QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue) const
Returns the current rotation for the composer item.
const_iterator insert(const T &value)
QRectF mapRectToScene(const QRectF &rect) const
bool _writeXML(QDomElement &itemElem, QDomDocument &doc) const
Writes parameter that are not subclass specific in document.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:353
QgsComposition::PlotStyle plotStyle() const
QSet< QgsComposerItem * > items()
bool _readXML(const QDomElement &itemElem, const QDomDocument &doc)
Reads parameter that are not subclass specific in document.
QgsComposerItemGroup(QgsComposition *c)
QDomElement toElement() const
bool isEmpty() const
void drawRect(const QRectF &rectangle)
QPointF pos() const
QGraphicsItemGroup * group() const
int count() const
qreal x() const
qreal y() const
virtual void setVisibility(const bool visible) override
Sets visibility for item.
void removeItem(QGraphicsItem *item)
virtual void drawSelectionBoxes(QPainter *p)
Draws additional graphics on selected items.
void setPen(const QColor &color)
bool mFrame
True if item fram needs to be painted.
void setAttribute(const QString &name, const QString &value)
bool isSelected() const
void addItem(QgsComposerItem *item) override
Adds an item to the group.
QPointF topLeft() const
QPointF mapFromScene(const QPointF &point) const
QString uuid() const
Get item identification name.
QRectF united(const QRectF &rectangle) const
void setColor(const QColor &color)
Graphics scene for map printing.
iterator end()
iterator begin()
bool isEmpty() const
virtual bool isRemoved() const
Returns whether this item has been removed from the composition.
bool contains(const T &value) const
QgsComposition * mComposition
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=nullptr) override
Draw outline and ev.
QPointF mapToScene(const QPointF &point) const
qreal width() const
bool remove(const T &value)
bool readXML(const QDomElement &itemElem, const QDomDocument &doc) override
Sets state from Dom document.
virtual void setItemRotation(const double r, const bool adjustPosition=false)
Sets the item rotation.
iterator end()
void setSceneRect(const QRectF &rectangle) override
Sets this items bound in scene coordinates such that 1 item size units corresponds to 1 scene size un...
virtual void setSceneRect(const QRectF &rectangle)
Sets this items bound in scene coordinates such that 1 item size units corresponds to 1 scene size un...
bool writeXML(QDomElement &elem, QDomDocument &doc) const override
Stores state in Dom node.
void setIsGroupMember(const bool isGroupMember)
Sets whether this item is part of a group.
qreal height() const
void setItemRemoved(QgsComposerItem *item)
Marks an item as removed from the composition.
QDomElement createElement(const QString &tagName)
void clear()
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setZValue(qreal z)
virtual void setVisibility(const bool visible)
Sets visibility for item.
iterator begin()
void destroyed(QObject *obj)
QDomNode at(int index) const
QRectF rect() const