QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
23 #include <QPen>
24 #include <QPainter>
25 
27  : QgsComposerItem( c )
28 {
29  setZValue( 90 );
30  show();
31 }
32 
34 {
35  QSet<QgsComposerItem*>::iterator itemIt = mItems.begin();
36  for ( ; itemIt != mItems.end(); ++itemIt )
37  {
38  if ( *itemIt )
39  {
40  mComposition->removeItem( *itemIt );
41  ( *itemIt )->setIsGroupMember( false );
42  }
43  }
44 }
45 
47 {
48  if ( !item )
49  {
50  return;
51  }
52 
53  if ( mItems.contains( item ) )
54  {
55  return;
56  }
57 
58  connect( item, SIGNAL( destroyed() ), this, SLOT( itemDestroyed() ) );
59 
60  mItems.insert( item );
61  item->setSelected( false );
62  item->setIsGroupMember( true );
63 
64  //update extent
65  if ( mBoundingRectangle.isEmpty() ) //we add the first item
66  {
67  mBoundingRectangle = QRectF( 0, 0, item->rect().width(), item->rect().height() );
68  //call method of superclass to avoid repositioning of items
69  QgsComposerItem::setSceneRect( QRectF( item->pos().x(), item->pos().y(), item->rect().width(), item->rect().height() ) );
70 
71  if ( item->itemRotation() != 0 )
72  {
73  setItemRotation( item->itemRotation() );
74  }
75  }
76  else
77  {
78  if ( item->itemRotation() != itemRotation() )
79  {
80  //items have mixed rotation, so reset rotation of group
81  mBoundingRectangle = mapRectToScene( mBoundingRectangle );
82  setItemRotation( 0 );
83  mBoundingRectangle = mBoundingRectangle.united( item->mapRectToScene( item->rect() ) );
84  //call method of superclass to avoid repositioning of items
86  }
87  else
88  {
89  //items have same rotation, so keep rotation of group
90  mBoundingRectangle = mBoundingRectangle.united( mapRectFromItem( item, item->rect() ) );
91  QPointF newPos = mapToScene( mBoundingRectangle.topLeft().x(), mBoundingRectangle.topLeft().y() );
92  mBoundingRectangle = QRectF( 0, 0, mBoundingRectangle.width(), mBoundingRectangle.height() );
93  QgsComposerItem::setSceneRect( QRectF( newPos.x(), newPos.y(), mBoundingRectangle.width(), mBoundingRectangle.height() ) );
94  }
95  }
96 
97 }
98 
100 {
101  QSet<QgsComposerItem*>::iterator item_it = mItems.begin();
102  for ( ; item_it != mItems.end(); ++item_it )
103  {
104  ( *item_it )->setIsGroupMember( false );
105  ( *item_it )->setSelected( true );
106  }
107  mItems.clear();
108 }
109 
111 {
112  mItems.remove( static_cast<QgsComposerItem*>( sender() ) );
113 }
114 
115 void QgsComposerItemGroup::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
116 {
117  Q_UNUSED( option );
118  Q_UNUSED( widget );
119  drawFrame( painter );
120  if ( isSelected() )
121  {
122  drawSelectionBoxes( painter );
123  }
124 }
125 
126 void QgsComposerItemGroup::setSceneRect( const QRectF& rectangle )
127 {
128  //resize all items in this group
129  //first calculate new group rectangle in current group coordsys
130  QPointF newOrigin = mapFromScene( rectangle.topLeft() );
131  QRectF newRect = QRectF( newOrigin.x(), newOrigin.y(), rectangle.width(), rectangle.height() );
132 
133  QSet<QgsComposerItem*>::iterator item_it = mItems.begin();
134  for ( ; item_it != mItems.end(); ++item_it )
135  {
136  //each item needs to be scaled relatively to the final size of the group
137  QRectF itemRect = mapRectFromItem(( *item_it ), ( *item_it )->rect() );
138  QgsComposerUtils::relativeResizeRect( itemRect, rect(), newRect );
139 
140  QPointF newPos = mapToScene( itemRect.topLeft() );
141  ( *item_it )->setSceneRect( QRectF( newPos.x(), newPos.y(), itemRect.width(), itemRect.height() ) );
142  }
143  //lastly, set new rect for group
144  QgsComposerItem::setSceneRect( rectangle );
145 }
146 
148 {
149  if ( !mComposition )
150  {
151  return;
152  }
153 
155  {
156  QPen newPen( pen() );
157  newPen.setStyle( Qt::DashLine );
158  newPen.setColor( QColor( 128, 128, 128, 128 ) );
159  p->setPen( newPen );
160  p->setRenderHint( QPainter::Antialiasing, true );
161  p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
162  }
163 }
164 
165 bool QgsComposerItemGroup::writeXML( QDomElement& elem, QDomDocument & doc ) const
166 {
167  QDomElement group = doc.createElement( "ComposerItemGroup" );
168 
169  QSet<QgsComposerItem*>::const_iterator itemIt = mItems.begin();
170  for ( ; itemIt != mItems.end(); ++itemIt )
171  {
172  QDomElement item = doc.createElement( "ComposerItemGroupElement" );
173  item.setAttribute( "uuid", ( *itemIt )->uuid() );
174  group.appendChild( item );
175  }
176 
177  elem.appendChild( group );
178 
179  return _writeXML( group, doc );
180 }
181 
182 bool QgsComposerItemGroup::readXML( const QDomElement& itemElem, const QDomDocument& doc )
183 {
184  //restore general composer item properties
185  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
186  if ( composerItemList.size() > 0 )
187  {
188  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
189  _readXML( composerItemElem, doc );
190  }
191 
192  QList<QGraphicsItem *> items = mComposition->items();
193 
194  QDomNodeList elementNodes = itemElem.elementsByTagName( "ComposerItemGroupElement" );
195  for ( int i = 0; i < elementNodes.count(); ++i )
196  {
197  QDomNode elementNode = elementNodes.at( i );
198  if ( !elementNode.isElement() )
199  continue;
200 
201  QString uuid = elementNode.toElement().attribute( "uuid" );
202 
203  for ( QList<QGraphicsItem *>::iterator it = items.begin(); it != items.end(); ++it )
204  {
205  QgsComposerItem *item = dynamic_cast<QgsComposerItem *>( *it );
206  if ( item && ( item->mUuid == uuid || item->mTemplateUuid == uuid ) )
207  {
208  addItem( item );
209  break;
210  }
211  }
212  }
213 
214  return true;
215 }
static void relativeResizeRect(QRectF &rectToResize, const QRectF &boundsBefore, const QRectF &boundsAfter)
Resizes a QRectF relative to a resized bounding rectangle.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0)
Draw outline and ev.
void removeItems()
Removes the items but does not delete them.
bool readXML(const QDomElement &itemElem, const QDomDocument &doc)
sets state from Dom document
bool writeXML(QDomElement &elem, QDomDocument &doc) const
stores state in Dom node
A item that forms part of a map composition.
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.
void drawFrame(QPainter *p)
Draw black frame around item.
QSet< QgsComposerItem * > items()
bool _readXML(const QDomElement &itemElem, const QDomDocument &doc)
Reads parameter that are not subclass specific in document.
QgsComposerItemGroup(QgsComposition *c)
QString uuid() const
Get item identification name.
virtual void drawSelectionBoxes(QPainter *p)
Draw selection boxes around item.
bool mFrame
True if item fram needs to be painted.
Graphics scene for map printing.
void setSceneRect(const QRectF &rectangle)
Sets this items bound in scene coordinates such that 1 item size units corresponds to 1 scene size un...
QgsComposition * mComposition
void addItem(QgsComposerItem *item)
Adds an item to the group.
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.
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...
void setIsGroupMember(const bool isGroupMember)
Sets whether this item is part of a group.
QSet< QgsComposerItem * > mItems
QgsComposition::PlotStyle plotStyle() const