QGIS API Documentation  2.0.1-Dufour
 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 
21 #include <QPen>
22 #include <QPainter>
23 
25  : QgsComposerItem( c )
26 {
27  setZValue( 90 );
28  show();
29 }
30 
32 {
33  QSet<QgsComposerItem*>::iterator itemIt = mItems.begin();
34  for ( ; itemIt != mItems.end(); ++itemIt )
35  {
36  if ( *itemIt )
37  {
38  mComposition->removeItem( *itemIt );
39  ( *itemIt )->setFlag( QGraphicsItem::ItemIsSelectable, true );
40  }
41  }
42 }
43 
45 {
46  if ( !item )
47  {
48  return;
49  }
50 
51  if ( mItems.contains( item ) )
52  {
53  return;
54  }
55 
56  connect( item, SIGNAL( destroyed() ), this, SLOT( itemDestroyed() ) );
57 
58  mItems.insert( item );
59  item->setSelected( false );
60  item->setFlag( QGraphicsItem::ItemIsSelectable, false ); //item in groups cannot be selected
61 
62  //update extent (which is in scene coordinates)
63  double minXItem = item->transform().dx();
64  double minYItem = item->transform().dy();
65  double maxXItem = minXItem + item->rect().width();
66  double maxYItem = minYItem + item->rect().height();
67 
68  if ( mSceneBoundingRectangle.isEmpty() ) //we add the first item
69  {
70  mSceneBoundingRectangle.setLeft( minXItem );
71  mSceneBoundingRectangle.setTop( minYItem );
72  mSceneBoundingRectangle.setRight( maxXItem );
73  mSceneBoundingRectangle.setBottom( maxYItem );
74  }
75  else
76  {
77  if ( minXItem < mSceneBoundingRectangle.left() )
78  {
79  mSceneBoundingRectangle.setLeft( minXItem );
80  }
81  if ( minYItem < mSceneBoundingRectangle.top() )
82  {
83  mSceneBoundingRectangle.setTop( minYItem );
84  }
85  if ( maxXItem > mSceneBoundingRectangle.right() )
86  {
87  mSceneBoundingRectangle.setRight( maxXItem );
88  }
89  if ( maxYItem > mSceneBoundingRectangle.bottom() )
90  {
91  mSceneBoundingRectangle.setBottom( maxYItem );
92  }
93  }
94 
95  QgsComposerItem::setSceneRect( mSceneBoundingRectangle ); //call method of superclass to avoid repositioning of items
96 }
97 
99 {
100  QSet<QgsComposerItem*>::iterator item_it = mItems.begin();
101  for ( ; item_it != mItems.end(); ++item_it )
102  {
103  ( *item_it )->setFlag( QGraphicsItem::ItemIsSelectable, true ); //enable item selection again
104  ( *item_it )->setSelected( true );
105  }
106  mItems.clear();
107 }
108 
110 {
111  mItems.remove( static_cast<QgsComposerItem*>( sender() ) );
112 }
113 
114 void QgsComposerItemGroup::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
115 {
116  Q_UNUSED( option );
117  Q_UNUSED( widget );
118  drawFrame( painter );
119  if ( isSelected() )
120  {
121  drawSelectionBoxes( painter );
122  }
123 }
124 
125 void QgsComposerItemGroup::setSceneRect( const QRectF& rectangle )
126 {
127  //calculate values between 0 and 1 for boundaries of all contained items, depending on their positions in the item group rectangle.
128  //then position the item boundaries in the new item group rect such that these values are the same
129  double xLeftCurrent = transform().dx();
130  double xRightCurrent = xLeftCurrent + rect().width();
131  double yTopCurrent = transform().dy();
132  double yBottomCurrent = yTopCurrent + rect().height();
133 
134  double xItemLeft, xItemRight, yItemTop, yItemBottom;
135  double xItemLeftNew, xItemRightNew, yItemTopNew, yItemBottomNew;
136  double xParamLeft, xParamRight, yParamTop, yParamBottom;
137 
138 
139  QSet<QgsComposerItem*>::iterator item_it = mItems.begin();
140  for ( ; item_it != mItems.end(); ++item_it )
141  {
142  xItemLeft = ( *item_it )->transform().dx();
143  xItemRight = xItemLeft + ( *item_it )->rect().width();
144  yItemTop = ( *item_it )->transform().dy();
145  yItemBottom = yItemTop + ( *item_it )->rect().height();
146 
147  xParamLeft = ( xItemLeft - xLeftCurrent ) / ( xRightCurrent - xLeftCurrent );
148  xParamRight = ( xItemRight - xLeftCurrent ) / ( xRightCurrent - xLeftCurrent );
149  yParamTop = ( yItemTop - yTopCurrent ) / ( yBottomCurrent - yTopCurrent );
150  yParamBottom = ( yItemBottom - yTopCurrent ) / ( yBottomCurrent - yTopCurrent );
151 
152  xItemLeftNew = xParamLeft * rectangle.right() + ( 1 - xParamLeft ) * rectangle.left();
153  xItemRightNew = xParamRight * rectangle.right() + ( 1 - xParamRight ) * rectangle.left();
154  yItemTopNew = yParamTop * rectangle.bottom() + ( 1 - yParamTop ) * rectangle.top();
155  yItemBottomNew = yParamBottom * rectangle.bottom() + ( 1 - yParamBottom ) * rectangle.top();
156 
157  ( *item_it )->setSceneRect( QRectF( xItemLeftNew, yItemTopNew, xItemRightNew - xItemLeftNew, yItemBottomNew - yItemTopNew ) );
158  }
159  QgsComposerItem::setSceneRect( rectangle );
160 }
161 
163 {
164  if ( !mComposition )
165  {
166  return;
167  }
168 
170  {
171  QPen newPen( pen() );
172  newPen.setStyle( Qt::DashLine );
173  newPen.setColor( QColor( 128, 128, 128, 128 ) );
174  p->setPen( newPen );
175  p->setRenderHint( QPainter::Antialiasing, true );
176  p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
177  }
178 }
179 
180 bool QgsComposerItemGroup::writeXML( QDomElement& elem, QDomDocument & doc ) const
181 {
182  QDomElement group = doc.createElement( "ComposerItemGroup" );
183 
184  QSet<QgsComposerItem*>::const_iterator itemIt = mItems.begin();
185  for ( ; itemIt != mItems.end(); ++itemIt )
186  {
187  QDomElement item = doc.createElement( "ComposerItemGroupElement" );
188  item.setAttribute( "uuid", ( *itemIt )->uuid() );
189  group.appendChild( item );
190  }
191 
192  elem.appendChild( group );
193 
194  return _writeXML( group, doc );
195 }
196 
197 bool QgsComposerItemGroup::readXML( const QDomElement& itemElem, const QDomDocument& doc )
198 {
199  //restore general composer item properties
200  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
201  if ( composerItemList.size() > 0 )
202  {
203  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
204  _readXML( composerItemElem, doc );
205  }
206 
207  QList<QGraphicsItem *> items = mComposition->items();
208 
209  QDomNodeList elementNodes = itemElem.elementsByTagName( "ComposerItemGroupElement" );
210  for ( int i = 0; i < elementNodes.count(); ++i )
211  {
212  QDomNode elementNode = elementNodes.at( i );
213  if ( !elementNode.isElement() )
214  continue;
215 
216  QString uuid = elementNode.toElement().attribute( "uuid" );
217 
218  for ( QList<QGraphicsItem *>::iterator it = items.begin(); it != items.end(); ++it )
219  {
220  QgsComposerItem *item = dynamic_cast<QgsComposerItem *>( *it );
221  if ( item && ( item->mUuid == uuid || item->mTemplateUuid == uuid ) )
222  {
223  addItem( item );
224  break;
225  }
226  }
227  }
228 
229  return true;
230 }