|
QGIS API Documentation
master-28efcda
|
00001 /*************************************************************************** 00002 qgscomposermultiframe.cpp 00003 ------------------------------------------------------------ 00004 begin : July 2012 00005 copyright : (C) 2012 by Marco Hugentobler 00006 email : marco dot hugentobler at sourcepole dot ch 00007 *************************************************************************** 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 ***************************************************************************/ 00015 00016 #include "qgscomposermultiframe.h" 00017 #include "qgscomposerframe.h" 00018 #include "qgscomposition.h" 00019 00020 QgsComposerMultiFrame::QgsComposerMultiFrame( QgsComposition* c, bool createUndoCommands ): mComposition( c ), mResizeMode( UseExistingFrames ), mCreateUndoCommands( createUndoCommands ) 00021 { 00022 mComposition->addMultiFrame( this ); 00023 connect( mComposition, SIGNAL( nPagesChanged() ), this, SLOT( handlePageChange() ) ); 00024 } 00025 00026 QgsComposerMultiFrame::QgsComposerMultiFrame(): mComposition( 0 ), mResizeMode( UseExistingFrames ) 00027 { 00028 } 00029 00030 QgsComposerMultiFrame::~QgsComposerMultiFrame() 00031 { 00032 deleteFrames(); 00033 } 00034 00035 void QgsComposerMultiFrame::setResizeMode( ResizeMode mode ) 00036 { 00037 if ( mode != mResizeMode ) 00038 { 00039 mResizeMode = mode; 00040 recalculateFrameSizes(); 00041 emit changed(); 00042 } 00043 } 00044 00045 void QgsComposerMultiFrame::recalculateFrameSizes() 00046 { 00047 if ( mFrameItems.size() < 1 ) 00048 { 00049 return; 00050 } 00051 00052 QSizeF size = totalSize(); 00053 double totalHeight = size.height(); 00054 00055 if ( totalHeight < 1 ) 00056 { 00057 return; 00058 } 00059 00060 double currentY = 0; 00061 double currentHeight = 0; 00062 QgsComposerFrame* currentItem = 0; 00063 00064 for ( int i = 0; i < mFrameItems.size(); ++i ) 00065 { 00066 if ( mResizeMode != RepeatOnEveryPage && currentY >= totalHeight ) 00067 { 00068 if ( mResizeMode == RepeatUntilFinished || mResizeMode == ExtendToNextPage ) //remove unneeded frames in extent mode 00069 { 00070 for ( int j = mFrameItems.size(); j > i; --j ) 00071 { 00072 removeFrame( j - 1 ); 00073 } 00074 } 00075 return; 00076 } 00077 00078 currentItem = mFrameItems.value( i ); 00079 currentHeight = currentItem->rect().height(); 00080 if ( mResizeMode == RepeatOnEveryPage ) 00081 { 00082 currentItem->setContentSection( QRectF( 0, 0, currentItem->rect().width(), currentHeight ) ); 00083 } 00084 else 00085 { 00086 currentItem->setContentSection( QRectF( 0, currentY, currentItem->rect().width(), currentHeight ) ); 00087 } 00088 currentItem->update(); 00089 currentY += currentHeight; 00090 } 00091 00092 //at end of frames but there is still content left. Add other pages if ResizeMode == 00093 if ( mResizeMode != UseExistingFrames ) 00094 { 00095 while (( mResizeMode == RepeatOnEveryPage ) || currentY < totalHeight ) 00096 { 00097 //find out on which page the lower left point of the last frame is 00098 int page = currentItem->transform().dy() / ( mComposition->paperHeight() + mComposition->spaceBetweenPages() ); 00099 if ( mResizeMode == RepeatOnEveryPage ) 00100 { 00101 if ( page > mComposition->numPages() - 2 ) 00102 { 00103 break; 00104 } 00105 } 00106 else 00107 { 00108 if ( mComposition->numPages() < ( page + 2 ) ) 00109 { 00110 mComposition->setNumPages( page + 2 ); 00111 } 00112 } 00113 00114 double frameHeight = 0; 00115 if ( mResizeMode == RepeatUntilFinished || mResizeMode == RepeatOnEveryPage ) 00116 { 00117 frameHeight = currentItem->rect().height(); 00118 } 00119 else //mResizeMode == ExtendToNextPage 00120 { 00121 frameHeight = ( currentY + mComposition->paperHeight() ) > totalHeight ? totalHeight - currentY : mComposition->paperHeight(); 00122 } 00123 00124 double newFrameY = ( page + 1 ) * ( mComposition->paperHeight() + mComposition->spaceBetweenPages() ); 00125 if ( mResizeMode == RepeatUntilFinished || mResizeMode == RepeatOnEveryPage ) 00126 { 00127 newFrameY += currentItem->transform().dy() - page * ( mComposition->paperHeight() + mComposition->spaceBetweenPages() ); 00128 } 00129 QgsComposerFrame* newFrame = new QgsComposerFrame( mComposition, this, currentItem->transform().dx(), 00130 newFrameY, 00131 currentItem->rect().width(), frameHeight ); 00132 if ( mResizeMode == RepeatOnEveryPage ) 00133 { 00134 newFrame->setContentSection( QRectF( 0, 0, newFrame->rect().width(), newFrame->rect().height() ) ); 00135 } 00136 else 00137 { 00138 newFrame->setContentSection( QRectF( 0, currentY, newFrame->rect().width(), newFrame->rect().height() ) ); 00139 } 00140 currentY += frameHeight; 00141 currentItem = newFrame; 00142 addFrame( newFrame, false ); 00143 } 00144 } 00145 } 00146 00147 void QgsComposerMultiFrame::handleFrameRemoval( QgsComposerItem* item ) 00148 { 00149 QgsComposerFrame* frame = dynamic_cast<QgsComposerFrame*>( item ); 00150 if ( !frame ) 00151 { 00152 return; 00153 } 00154 int index = mFrameItems.indexOf( frame ); 00155 if ( index == -1 ) 00156 { 00157 return; 00158 } 00159 mFrameItems.removeAt( index ); 00160 if ( mFrameItems.size() > 0 ) 00161 { 00162 recalculateFrameSizes(); 00163 } 00164 } 00165 00166 void QgsComposerMultiFrame::handlePageChange() 00167 { 00168 if ( mComposition->numPages() < 1 ) 00169 { 00170 return; 00171 } 00172 00173 if ( mResizeMode != RepeatOnEveryPage ) 00174 { 00175 return; 00176 } 00177 00178 //remove items beginning on non-existing pages 00179 for ( int i = mFrameItems.size() - 1; i >= 0; --i ) 00180 { 00181 QgsComposerFrame* frame = mFrameItems[i]; 00182 int page = frame->transform().dy() / ( mComposition->paperHeight() + mComposition->spaceBetweenPages() ); 00183 if ( page > ( mComposition->numPages() - 1 ) ) 00184 { 00185 removeFrame( i ); 00186 } 00187 } 00188 00189 //page number of the last item 00190 QgsComposerFrame* lastFrame = mFrameItems.last(); 00191 int lastItemPage = lastFrame->transform().dy() / ( mComposition->paperHeight() + mComposition->spaceBetweenPages() ); 00192 00193 for ( int i = lastItemPage + 1; i < mComposition->numPages(); ++i ) 00194 { 00195 //copy last frame to current page 00196 QgsComposerFrame* newFrame = new QgsComposerFrame( mComposition, this, lastFrame->transform().dx(), 00197 lastFrame->transform().dy() + mComposition->paperHeight() + mComposition->spaceBetweenPages(), 00198 lastFrame->rect().width(), lastFrame->rect().height() ); 00199 addFrame( newFrame, false ); 00200 lastFrame = newFrame; 00201 } 00202 00203 recalculateFrameSizes(); 00204 update(); 00205 } 00206 00207 void QgsComposerMultiFrame::removeFrame( int i ) 00208 { 00209 QgsComposerFrame* frameItem = mFrameItems[i]; 00210 if ( mComposition ) 00211 { 00212 mComposition->removeComposerItem( frameItem ); 00213 } 00214 mFrameItems.removeAt( i ); 00215 } 00216 00217 void QgsComposerMultiFrame::update() 00218 { 00219 QList<QgsComposerFrame*>::iterator frameIt = mFrameItems.begin(); 00220 for ( ; frameIt != mFrameItems.end(); ++frameIt ) 00221 { 00222 ( *frameIt )->update(); 00223 } 00224 } 00225 00226 void QgsComposerMultiFrame::deleteFrames() 00227 { 00228 ResizeMode bkResizeMode = mResizeMode; 00229 mResizeMode = UseExistingFrames; 00230 QObject::disconnect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( handleFrameRemoval( QgsComposerItem* ) ) ); 00231 QList<QgsComposerFrame*>::iterator frameIt = mFrameItems.begin(); 00232 for ( ; frameIt != mFrameItems.end(); ++frameIt ) 00233 { 00234 mComposition->removeComposerItem( *frameIt, false ); 00235 delete *frameIt; 00236 } 00237 QObject::connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( handleFrameRemoval( QgsComposerItem* ) ) ); 00238 mFrameItems.clear(); 00239 mResizeMode = bkResizeMode; 00240 } 00241 00242 QgsComposerFrame* QgsComposerMultiFrame::frame( int i ) const 00243 { 00244 if ( i >= mFrameItems.size() ) 00245 { 00246 return 0; 00247 } 00248 return mFrameItems.at( i ); 00249 } 00250 00251 bool QgsComposerMultiFrame::_writeXML( QDomElement& elem, QDomDocument& doc, bool ignoreFrames ) const 00252 { 00253 elem.setAttribute( "resizeMode", mResizeMode ); 00254 if ( !ignoreFrames ) 00255 { 00256 QList<QgsComposerFrame*>::const_iterator frameIt = mFrameItems.constBegin(); 00257 for ( ; frameIt != mFrameItems.constEnd(); ++frameIt ) 00258 { 00259 ( *frameIt )->writeXML( elem, doc ); 00260 } 00261 } 00262 return true; 00263 } 00264 00265 bool QgsComposerMultiFrame::_readXML( const QDomElement& itemElem, const QDomDocument& doc, bool ignoreFrames ) 00266 { 00267 mResizeMode = ( ResizeMode )itemElem.attribute( "resizeMode", "0" ).toInt(); 00268 if ( !ignoreFrames ) 00269 { 00270 QDomNodeList frameList = itemElem.elementsByTagName( "ComposerFrame" ); 00271 for ( int i = 0; i < frameList.size(); ++i ) 00272 { 00273 QDomElement frameElem = frameList.at( i ).toElement(); 00274 QgsComposerFrame* newFrame = new QgsComposerFrame( mComposition, this, 0, 0, 0, 0 ); 00275 newFrame->readXML( frameElem, doc ); 00276 addFrame( newFrame ); 00277 } 00278 } 00279 return true; 00280 }