QGIS API Documentation  2.12.0-Lyon
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  QSet<QgsComposerItem*>::iterator itemIt = mItems.begin();
38  for ( ; itemIt != mItems.end(); ++itemIt )
39  {
40  if ( *itemIt )
41  {
42  //inform model that we are about to remove an item from the scene
43  mComposition->itemsModel()->setItemRemoved( *itemIt );
44  mComposition->removeItem( *itemIt );
45  ( *itemIt )->setIsGroupMember( false );
46  }
47  }
48 }
49 
51 {
52  if ( !item )
53  {
54  return;
55  }
56 
57  if ( mItems.contains( item ) )
58  {
59  return;
60  }
61 
62  connect( item, SIGNAL( destroyed() ), this, SLOT( itemDestroyed() ) );
63 
64  mItems.insert( item );
65  item->setSelected( false );
66  item->setIsGroupMember( true );
67 
68  //update extent
69  if ( mBoundingRectangle.isEmpty() ) //we add the first item
70  {
71  mBoundingRectangle = QRectF( 0, 0, item->rect().width(), item->rect().height() );
72  //call method of superclass to avoid repositioning of items
73  QgsComposerItem::setSceneRect( QRectF( item->pos().x(), item->pos().y(), item->rect().width(), item->rect().height() ) );
74 
75  if ( item->itemRotation() != 0 )
76  {
77  setItemRotation( item->itemRotation() );
78  }
79  }
80  else
81  {
82  if ( item->itemRotation() != itemRotation() )
83  {
84  //items have mixed rotation, so reset rotation of group
85  mBoundingRectangle = mapRectToScene( mBoundingRectangle );
86  setItemRotation( 0 );
87  mBoundingRectangle = mBoundingRectangle.united( item->mapRectToScene( item->rect() ) );
88  //call method of superclass to avoid repositioning of items
89  QgsComposerItem::setSceneRect( mBoundingRectangle );
90  }
91  else
92  {
93  //items have same rotation, so keep rotation of group
94  mBoundingRectangle = mBoundingRectangle.united( mapRectFromItem( item, item->rect() ) );
95  QPointF newPos = mapToScene( mBoundingRectangle.topLeft().x(), mBoundingRectangle.topLeft().y() );
96  mBoundingRectangle = QRectF( 0, 0, mBoundingRectangle.width(), mBoundingRectangle.height() );
97  QgsComposerItem::setSceneRect( QRectF( newPos.x(), newPos.y(), mBoundingRectangle.width(), mBoundingRectangle.height() ) );
98  }
99  }
100 
101 }
102 
104 {
105  QSet<QgsComposerItem*>::iterator item_it = mItems.begin();
106  for ( ; item_it != mItems.end(); ++item_it )
107  {
108  ( *item_it )->setIsGroupMember( false );
109  ( *item_it )->setSelected( true );
110  }
111  mItems.clear();
112 }
113 
115 {
116  mItems.remove( static_cast<QgsComposerItem*>( sender() ) );
117 }
118 
119 void QgsComposerItemGroup::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
120 {
121  Q_UNUSED( option );
122  Q_UNUSED( widget );
123  drawFrame( painter );
124  if ( isSelected() )
125  {
126  drawSelectionBoxes( painter );
127  }
128 }
129 
131 {
132  //resize all items in this group
133  //first calculate new group rectangle in current group coordsys
134  QPointF newOrigin = mapFromScene( rectangle.topLeft() );
135  QRectF newRect = QRectF( newOrigin.x(), newOrigin.y(), rectangle.width(), rectangle.height() );
136 
137  QSet<QgsComposerItem*>::iterator item_it = mItems.begin();
138  for ( ; item_it != mItems.end(); ++item_it )
139  {
140  //each item needs to be scaled relatively to the final size of the group
141  QRectF itemRect = mapRectFromItem(( *item_it ), ( *item_it )->rect() );
142  QgsComposerUtils::relativeResizeRect( itemRect, rect(), newRect );
143 
144  QPointF newPos = mapToScene( itemRect.topLeft() );
145  ( *item_it )->setSceneRect( QRectF( newPos.x(), newPos.y(), itemRect.width(), itemRect.height() ) );
146  }
147  //lastly, set new rect for group
148  QgsComposerItem::setSceneRect( rectangle );
149 }
150 
151 void QgsComposerItemGroup::setVisibility( const bool visible )
152 {
153  //also set visibility for all items within the group
154  QSet<QgsComposerItem*>::iterator item_it = mItems.begin();
155  for ( ; item_it != mItems.end(); ++item_it )
156  {
157  ( *item_it )->setVisibility( visible );
158  }
159  //lastly set visibility for group item itself
161 }
162 
164 {
165  if ( !mComposition )
166  {
167  return;
168  }
169 
171  {
172  QPen newPen( pen() );
173  newPen.setStyle( Qt::DashLine );
174  newPen.setColor( QColor( 128, 128, 128, 128 ) );
175  p->setPen( newPen );
176  p->setRenderHint( QPainter::Antialiasing, true );
177  p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
178  }
179 }
180 
182 {
183  QDomElement group = doc.createElement( "ComposerItemGroup" );
184 
186  for ( ; itemIt != mItems.end(); ++itemIt )
187  {
188  QDomElement item = doc.createElement( "ComposerItemGroupElement" );
189  item.setAttribute( "uuid", ( *itemIt )->uuid() );
190  group.appendChild( item );
191  }
192 
193  elem.appendChild( group );
194 
195  return _writeXML( group, doc );
196 }
197 
198 bool QgsComposerItemGroup::readXML( const QDomElement& itemElem, const QDomDocument& doc )
199 {
200  //restore general composer item properties
201  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
202  if ( composerItemList.size() > 0 )
203  {
204  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
205  _readXML( composerItemElem, doc );
206  }
207 
209 
210  QDomNodeList elementNodes = itemElem.elementsByTagName( "ComposerItemGroupElement" );
211  for ( int i = 0; i < elementNodes.count(); ++i )
212  {
213  QDomNode elementNode = elementNodes.at( i );
214  if ( !elementNode.isElement() )
215  continue;
216 
217  QString uuid = elementNode.toElement().attribute( "uuid" );
218 
219  for ( QList<QGraphicsItem *>::iterator it = items.begin(); it != items.end(); ++it )
220  {
221  QgsComposerItem *item = dynamic_cast<QgsComposerItem *>( *it );
222  if ( item && ( item->mUuid == uuid || item->mTemplateUuid == uuid ) )
223  {
224  addItem( item );
225  break;
226  }
227  }
228  }
229 
230  return true;
231 }
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.
const_iterator insert(const T &value)
QRectF mapRectToScene(const QRectF &rect) const
double itemRotation(const QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue) const
Returns the current rotation for the composer item.
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
void drawRect(const QRectF &rectangle)
QString uuid() const
Get item identification name.
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
QRectF united(const QRectF &rectangle) const
void setColor(const QColor &color)
Graphics scene for map printing.
iterator end()
iterator begin()
bool isEmpty() const
bool contains(const T &value) const
QgsComposition * mComposition
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.
bool _writeXML(QDomElement &itemElem, QDomDocument &doc) const
Writes parameter that are not subclass specific in 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.
int size() const
QDomElement createElement(const QString &tagName)
void clear()
QgsComposition::PlotStyle plotStyle() const
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)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0) override
Draw outline and ev.
QDomNode at(int index) const
QRectF rect() const