QGIS API Documentation  2.3.0-Master
 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->pos().y() / ( 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->pos().y() - page * ( mComposition->paperHeight() + mComposition->spaceBetweenPages() );
128  }
129  QgsComposerFrame* newFrame = new QgsComposerFrame( mComposition, this, currentItem->pos().x(),
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->pos().y() / ( 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->pos().y() / ( 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->pos().x(),
197  lastFrame->pos().y() + 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 }
static unsigned index
void setNumPages(int pages)
Note: added in version 1.9.
A item that forms part of a map composition.
void removeComposerItem(QgsComposerItem *item, bool createCommand=true)
Remove item from the graphics scene.
QgsComposition * mComposition
virtual QSizeF totalSize() const =0
double spaceBetweenPages() const
int numPages() const
Note: added in version 1.9.
bool _readXML(const QDomElement &itemElem, const QDomDocument &doc, bool ignoreFrames=false)
virtual void addFrame(QgsComposerFrame *frame, bool recalcFrameSizes=true)=0
QList< QgsComposerFrame * > mFrameItems
bool _writeXML(QDomElement &elem, QDomDocument &doc, bool ignoreFrames=false) const
Graphics scene for map printing.
void handlePageChange()
Adapts to changed number of pages if resize type is RepeatOnEveryPage.
Frame for html, table, text which can be divided onto several frames.
void deleteFrames()
Removes and deletes all frames from mComposition.
void setResizeMode(ResizeMode mode)
bool readXML(const QDomElement &itemElem, const QDomDocument &doc)
sets state from Dom document
double paperHeight() const
Returns height of paper item.
QgsComposerFrame * frame(int i) const
void setContentSection(const QRectF &section)
Sets the part of this frame (relative to the total multiframe extent in mm)
double size
Definition: qgssvgcache.cpp:77
void addMultiFrame(QgsComposerMultiFrame *multiFrame)
Adds multiframe.
void handleFrameRemoval(QgsComposerItem *item)
Called before a frame is going to be removed (update frame list)