QGIS API Documentation  2.0.1-Dufour
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgscomposermultiframe.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposermultiframe.cpp
3  ------------------------------------------------------------
4  begin : July 2012
5  copyright : (C) 2012 by Marco Hugentobler
6  email : marco dot hugentobler at sourcepole dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgscomposermultiframe.h"
17 #include "qgscomposerframe.h"
18 #include "qgscomposition.h"
19 
20 QgsComposerMultiFrame::QgsComposerMultiFrame( QgsComposition* c, bool createUndoCommands ): mComposition( c ), mResizeMode( UseExistingFrames ), mCreateUndoCommands( createUndoCommands )
21 {
22  mComposition->addMultiFrame( this );
23  connect( mComposition, SIGNAL( nPagesChanged() ), this, SLOT( handlePageChange() ) );
24 }
25 
26 QgsComposerMultiFrame::QgsComposerMultiFrame(): mComposition( 0 ), mResizeMode( UseExistingFrames )
27 {
28 }
29 
31 {
32  deleteFrames();
33 }
34 
36 {
37  if ( mode != mResizeMode )
38  {
39  mResizeMode = mode;
41  emit changed();
42  }
43 }
44 
46 {
47  if ( mFrameItems.size() < 1 )
48  {
49  return;
50  }
51 
52  QSizeF size = totalSize();
53  double totalHeight = size.height();
54 
55  if ( totalHeight < 1 )
56  {
57  return;
58  }
59 
60  double currentY = 0;
61  double currentHeight = 0;
62  QgsComposerFrame* currentItem = 0;
63 
64  for ( int i = 0; i < mFrameItems.size(); ++i )
65  {
66  if ( mResizeMode != RepeatOnEveryPage && currentY >= totalHeight )
67  {
68  if ( mResizeMode == RepeatUntilFinished || mResizeMode == ExtendToNextPage ) //remove unneeded frames in extent mode
69  {
70  for ( int j = mFrameItems.size(); j > i; --j )
71  {
72  removeFrame( j - 1 );
73  }
74  }
75  return;
76  }
77 
78  currentItem = mFrameItems.value( i );
79  currentHeight = currentItem->rect().height();
81  {
82  currentItem->setContentSection( QRectF( 0, 0, currentItem->rect().width(), currentHeight ) );
83  }
84  else
85  {
86  currentItem->setContentSection( QRectF( 0, currentY, currentItem->rect().width(), currentHeight ) );
87  }
88  currentItem->update();
89  currentY += currentHeight;
90  }
91 
92  //at end of frames but there is still content left. Add other pages if ResizeMode ==
94  {
95  while (( mResizeMode == RepeatOnEveryPage ) || currentY < totalHeight )
96  {
97  //find out on which page the lower left point of the last frame is
98  int page = currentItem->transform().dy() / ( mComposition->paperHeight() + mComposition->spaceBetweenPages() );
100  {
101  if ( page > mComposition->numPages() - 2 )
102  {
103  break;
104  }
105  }
106  else
107  {
108  if ( mComposition->numPages() < ( page + 2 ) )
109  {
110  mComposition->setNumPages( page + 2 );
111  }
112  }
113 
114  double frameHeight = 0;
116  {
117  frameHeight = currentItem->rect().height();
118  }
119  else //mResizeMode == ExtendToNextPage
120  {
121  frameHeight = ( currentY + mComposition->paperHeight() ) > totalHeight ? totalHeight - currentY : mComposition->paperHeight();
122  }
123 
124  double newFrameY = ( page + 1 ) * ( mComposition->paperHeight() + mComposition->spaceBetweenPages() );
126  {
127  newFrameY += currentItem->transform().dy() - page * ( mComposition->paperHeight() + mComposition->spaceBetweenPages() );
128  }
129  QgsComposerFrame* newFrame = new QgsComposerFrame( mComposition, this, currentItem->transform().dx(),
130  newFrameY,
131  currentItem->rect().width(), frameHeight );
133  {
134  newFrame->setContentSection( QRectF( 0, 0, newFrame->rect().width(), newFrame->rect().height() ) );
135  }
136  else
137  {
138  newFrame->setContentSection( QRectF( 0, currentY, newFrame->rect().width(), newFrame->rect().height() ) );
139  }
140  currentY += frameHeight;
141  currentItem = newFrame;
142  addFrame( newFrame, false );
143  }
144  }
145 }
146 
148 {
149  QgsComposerFrame* frame = dynamic_cast<QgsComposerFrame*>( item );
150  if ( !frame )
151  {
152  return;
153  }
154  int index = mFrameItems.indexOf( frame );
155  if ( index == -1 )
156  {
157  return;
158  }
159  mFrameItems.removeAt( index );
160  if ( mFrameItems.size() > 0 )
161  {
163  }
164 }
165 
167 {
168  if ( mComposition->numPages() < 1 )
169  {
170  return;
171  }
172 
174  {
175  return;
176  }
177 
178  //remove items beginning on non-existing pages
179  for ( int i = mFrameItems.size() - 1; i >= 0; --i )
180  {
182  int page = frame->transform().dy() / ( mComposition->paperHeight() + mComposition->spaceBetweenPages() );
183  if ( page > ( mComposition->numPages() - 1 ) )
184  {
185  removeFrame( i );
186  }
187  }
188 
189  //page number of the last item
190  QgsComposerFrame* lastFrame = mFrameItems.last();
191  int lastItemPage = lastFrame->transform().dy() / ( mComposition->paperHeight() + mComposition->spaceBetweenPages() );
192 
193  for ( int i = lastItemPage + 1; i < mComposition->numPages(); ++i )
194  {
195  //copy last frame to current page
196  QgsComposerFrame* newFrame = new QgsComposerFrame( mComposition, this, lastFrame->transform().dx(),
197  lastFrame->transform().dy() + mComposition->paperHeight() + mComposition->spaceBetweenPages(),
198  lastFrame->rect().width(), lastFrame->rect().height() );
199  addFrame( newFrame, false );
200  lastFrame = newFrame;
201  }
202 
204  update();
205 }
206 
208 {
209  QgsComposerFrame* frameItem = mFrameItems[i];
210  if ( mComposition )
211  {
212  mComposition->removeComposerItem( frameItem );
213  }
214  mFrameItems.removeAt( i );
215 }
216 
218 {
219  QList<QgsComposerFrame*>::iterator frameIt = mFrameItems.begin();
220  for ( ; frameIt != mFrameItems.end(); ++frameIt )
221  {
222  ( *frameIt )->update();
223  }
224 }
225 
227 {
228  ResizeMode bkResizeMode = mResizeMode;
230  QObject::disconnect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( handleFrameRemoval( QgsComposerItem* ) ) );
231  QList<QgsComposerFrame*>::iterator frameIt = mFrameItems.begin();
232  for ( ; frameIt != mFrameItems.end(); ++frameIt )
233  {
234  mComposition->removeComposerItem( *frameIt, false );
235  delete *frameIt;
236  }
237  QObject::connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( handleFrameRemoval( QgsComposerItem* ) ) );
238  mFrameItems.clear();
239  mResizeMode = bkResizeMode;
240 }
241 
243 {
244  if ( i >= mFrameItems.size() )
245  {
246  return 0;
247  }
248  return mFrameItems.at( i );
249 }
250 
251 bool QgsComposerMultiFrame::_writeXML( QDomElement& elem, QDomDocument& doc, bool ignoreFrames ) const
252 {
253  elem.setAttribute( "resizeMode", mResizeMode );
254  if ( !ignoreFrames )
255  {
256  QList<QgsComposerFrame*>::const_iterator frameIt = mFrameItems.constBegin();
257  for ( ; frameIt != mFrameItems.constEnd(); ++frameIt )
258  {
259  ( *frameIt )->writeXML( elem, doc );
260  }
261  }
262  return true;
263 }
264 
265 bool QgsComposerMultiFrame::_readXML( const QDomElement& itemElem, const QDomDocument& doc, bool ignoreFrames )
266 {
267  mResizeMode = ( ResizeMode )itemElem.attribute( "resizeMode", "0" ).toInt();
268  if ( !ignoreFrames )
269  {
270  QDomNodeList frameList = itemElem.elementsByTagName( "ComposerFrame" );
271  for ( int i = 0; i < frameList.size(); ++i )
272  {
273  QDomElement frameElem = frameList.at( i ).toElement();
274  QgsComposerFrame* newFrame = new QgsComposerFrame( mComposition, this, 0, 0, 0, 0 );
275  newFrame->readXML( frameElem, doc );
276  addFrame( newFrame );
277  }
278  }
279  return true;
280 }