Warning, file /office/calligra/libs/pageapp/KoPAPageBase.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 Copyright (C) 2006-2010 Thorsten Zachmann <zachmann@kde.org> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "KoPAPageBase.h" 0021 0022 #include "KoPASavingContext.h" 0023 #include "KoPALoadingContext.h" 0024 #include "KoPAPixmapCache.h" 0025 #include "KoPAPageContainerModel.h" 0026 #include "KoPAUtil.h" 0027 0028 #include <KoXmlNS.h> 0029 #include <KoPageLayout.h> 0030 #include <KoStyleStack.h> 0031 #include <KoGenStyle.h> 0032 #include <KoGenStyles.h> 0033 #include <KoOdfLoadingContext.h> 0034 #include <KoViewConverter.h> 0035 #include <KoShapeLayer.h> 0036 #include <KoShapeRegistry.h> 0037 #include <KoShapeBackground.h> 0038 #include <KoZoomHandler.h> 0039 0040 #include <PageAppDebug.h> 0041 0042 #include <QPainter> 0043 #include <QPainterPath> 0044 0045 #include <algorithm> 0046 0047 KoPAPageBase::KoPAPageBase() 0048 : KoShapeContainer( new KoPAPageContainerModel() ) 0049 { 0050 // Add a default layer 0051 KoShapeLayer* layer = new KoShapeLayer; 0052 addShape(layer); 0053 } 0054 0055 KoPAPageBase::~KoPAPageBase() 0056 { 0057 } 0058 0059 void KoPAPageBase::paintComponent(QPainter& painter, const KoViewConverter& converter, KoShapePaintingContext &) 0060 { 0061 Q_UNUSED(painter); 0062 Q_UNUSED(converter); 0063 } 0064 0065 void KoPAPageBase::paintBackground( QPainter & painter, const KoViewConverter & converter, KoShapePaintingContext &paintContext ) 0066 { 0067 painter.save(); 0068 applyConversion( painter, converter ); 0069 KoPageLayout layout = pageLayout(); 0070 painter.setPen(QPen(Qt::black, 0)); 0071 0072 if (background()) { 0073 QPainterPath p; 0074 p.addRect( QRectF( 0.0, 0.0, layout.width, layout.height ) ); 0075 background()->paint( painter, converter, paintContext, p ); 0076 } 0077 else { 0078 painter.setBrush(Qt::white); 0079 painter.drawRect(QRectF(0.0, 0.0, layout.width, layout.height)); 0080 } 0081 0082 painter.restore(); 0083 } 0084 0085 void KoPAPageBase::saveOdfPageContent( KoPASavingContext & paContext ) const 0086 { 0087 saveOdfLayers(paContext); 0088 saveOdfShapes( paContext ); 0089 saveOdfAnimations( paContext ); 0090 saveOdfPresentationNotes( paContext ); 0091 } 0092 0093 void KoPAPageBase::saveOdfLayers(KoPASavingContext &paContext) const 0094 { 0095 QList<KoShape*> shapes(this->shapes()); 0096 std::sort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex); 0097 foreach(KoShape* shape, shapes) { 0098 KoShapeLayer *layer = dynamic_cast<KoShapeLayer*>(shape); 0099 if (layer) { 0100 paContext.addLayerForSaving(layer); 0101 } 0102 else { 0103 Q_ASSERT(layer); 0104 warnPageApp << "Page contains non layer where a layer is expected"; 0105 } 0106 } 0107 paContext.saveLayerSet(paContext.xmlWriter()); 0108 paContext.clearLayers(); 0109 } 0110 0111 void KoPAPageBase::saveOdfShapes( KoShapeSavingContext &context ) const 0112 { 0113 QList<KoShape*> shapes(this->shapes()); 0114 QList<KoShape*> tlshapes( shapes ); 0115 0116 std::sort( tlshapes.begin(), tlshapes.end(), KoShape::compareShapeZIndex ); 0117 0118 foreach( KoShape *shape, tlshapes ) { 0119 shape->saveOdf( context ); 0120 } 0121 } 0122 0123 QString KoPAPageBase::saveOdfPageStyle( KoPASavingContext &paContext ) const 0124 { 0125 KoGenStyle style( KoGenStyle::DrawingPageAutoStyle, "drawing-page" ); 0126 0127 if ( paContext.isSet( KoShapeSavingContext::AutoStyleInStyleXml ) ) { 0128 style.setAutoStyleInStylesDotXml( true ); 0129 } 0130 0131 saveOdfPageStyleData( style, paContext ); 0132 0133 return paContext.mainStyles().insert( style, "dp" ); 0134 } 0135 0136 void KoPAPageBase::saveOdfPageStyleData( KoGenStyle &style, KoPASavingContext &paContext ) const 0137 { 0138 QSharedPointer<KoShapeBackground> bg = background(); 0139 if( bg ) 0140 bg->fillStyle( style, paContext ); 0141 } 0142 0143 bool KoPAPageBase::saveOdfAnimations( KoPASavingContext & paContext ) const 0144 { 0145 Q_UNUSED( paContext ); 0146 return true; 0147 } 0148 0149 bool KoPAPageBase::saveOdfPresentationNotes(KoPASavingContext &paContext) const 0150 { 0151 Q_UNUSED( paContext ); 0152 return true; 0153 } 0154 0155 bool KoPAPageBase::loadOdf( const KoXmlElement &element, KoShapeLoadingContext & loadingContext ) 0156 { 0157 KoPALoadingContext &paContext = static_cast<KoPALoadingContext&>( loadingContext ); 0158 0159 KoStyleStack& styleStack = loadingContext.odfLoadingContext().styleStack(); 0160 styleStack.save(); 0161 loadingContext.odfLoadingContext().fillStyleStack( element, KoXmlNS::draw, "style-name", "drawing-page" ); 0162 styleStack.setTypeProperties( "drawing-page" ); 0163 0164 loadOdfPageTag(element, paContext); 0165 styleStack.restore(); 0166 0167 // load layers and shapes 0168 const KoXmlElement & pageLayerSet = KoXml::namedItemNS( element, KoXmlNS::draw, "layer-set" ); 0169 0170 const KoXmlElement & usedPageLayerSet = pageLayerSet.isNull() ? loadingContext.odfLoadingContext().stylesReader().layerSet(): pageLayerSet; 0171 0172 int layerZIndex = 0; 0173 bool first = true; 0174 KoXmlElement layerElement; 0175 forEachElement( layerElement, usedPageLayerSet ) { 0176 KoShapeLayer * layer = 0; 0177 if ( first ) { 0178 first = false; 0179 layer = dynamic_cast<KoShapeLayer *>( shapes().first() ); 0180 Q_ASSERT( layer ); 0181 } 0182 else { 0183 layer = new KoShapeLayer(); 0184 addShape( layer ); 0185 } 0186 if ( layer ) { 0187 layer->setZIndex( layerZIndex++ ); 0188 layer->loadOdf( layerElement, loadingContext ); 0189 } 0190 } 0191 0192 KoShapeLayer * layer = dynamic_cast<KoShapeLayer *>( shapes().first() ); 0193 if ( layer ) 0194 { 0195 KoXmlElement child; 0196 forEachElement( child, element ) 0197 { 0198 debugPageApp <<"loading shape" << child.localName(); 0199 0200 KoShape * shape = KoShapeRegistry::instance()->createShapeFromOdf( child, loadingContext ); 0201 if ( shape ) { 0202 if( ! shape->parent() ) { 0203 layer->addShape( shape ); 0204 } 0205 } 0206 } 0207 } 0208 0209 loadOdfPageExtra(element, paContext); 0210 0211 return true; 0212 } 0213 0214 void KoPAPageBase::loadOdfPageTag( const KoXmlElement &element, 0215 KoPALoadingContext &loadingContext ) 0216 { 0217 Q_UNUSED(element); 0218 KoStyleStack& styleStack = loadingContext.odfLoadingContext().styleStack(); 0219 0220 if ( styleStack.hasProperty( KoXmlNS::draw, "fill" ) ) { 0221 setBackground(loadOdfFill(loadingContext)); 0222 } 0223 } 0224 0225 void KoPAPageBase::loadOdfPageExtra( const KoXmlElement &element, KoPALoadingContext & loadingContext ) 0226 { 0227 Q_UNUSED( element ); 0228 Q_UNUSED( loadingContext ); 0229 } 0230 0231 QSizeF KoPAPageBase::size() const 0232 { 0233 const KoPageLayout layout = pageLayout(); 0234 return QSize( layout.width, layout.height ); 0235 } 0236 0237 QRectF KoPAPageBase::boundingRect() const 0238 { 0239 //return KoShapeContainer::boundingRect(); 0240 return contentRect().united(QRectF(QPointF(0, 0), size() )); 0241 } 0242 0243 QRectF KoPAPageBase::contentRect() const 0244 { 0245 QRectF bb; 0246 foreach (KoShape* layer, shapes()) { 0247 if (bb.isNull()) { 0248 bb = layer->boundingRect(); 0249 } 0250 else { 0251 bb = bb.united(layer->boundingRect()); 0252 } 0253 } 0254 0255 return bb; 0256 } 0257 0258 void KoPAPageBase::shapeAdded( KoShape * shape ) 0259 { 0260 Q_UNUSED( shape ); 0261 } 0262 0263 void KoPAPageBase::shapeRemoved( KoShape * shape ) 0264 { 0265 Q_UNUSED( shape ); 0266 } 0267 0268 KoPageApp::PageType KoPAPageBase::pageType() const 0269 { 0270 return KoPageApp::Page; 0271 } 0272 0273 QPixmap KoPAPageBase::thumbnail( const QSize& size ) 0274 { 0275 #ifdef CACHE_PAGE_THUMBNAILS 0276 QString key = thumbnailKey(); 0277 QPixmap pm; 0278 if ( !KoPAPixmapCache::instance()->find( key, size, pm ) ) { 0279 pm = generateThumbnail( size ); 0280 KoPAPixmapCache::instance()->insert( key, pm, size ); 0281 debugPageApp << "create thumbnail" << this << key << size; 0282 } 0283 else { 0284 //debugPageApp << "thumbnail in cache " << this; 0285 } 0286 return pm; 0287 #else 0288 return generateThumbnail( size ); 0289 #endif 0290 } 0291 0292 QPixmap KoPAPageBase::generateThumbnail(const QSize &size) 0293 { 0294 // don't paint null pixmap 0295 if ( size.isEmpty() ) // either width or height is <= 0 0296 return QPixmap(); 0297 0298 KoZoomHandler zoomHandler; 0299 QSize thumbnailSize(size); 0300 0301 KoPAUtil::setSizeAndZoom(pageLayout(), thumbnailSize, zoomHandler); 0302 0303 QPixmap pixmap(thumbnailSize); 0304 // paint white as default page background 0305 pixmap.fill(Qt::white); 0306 QPainter painter(&pixmap); 0307 painter.setClipRect(QRect(QPoint(0, 0), thumbnailSize)); 0308 painter.setRenderHint(QPainter::Antialiasing); 0309 0310 paintPage(painter, zoomHandler); 0311 0312 return pixmap; 0313 } 0314 0315 QImage KoPAPageBase::thumbImage(const QSize &size) 0316 { 0317 if (size.isEmpty()) { 0318 return QImage(); 0319 } 0320 0321 KoZoomHandler zoomHandler; 0322 QSize thumbnailSize(size); 0323 0324 KoPAUtil::setSizeAndZoom(pageLayout(), thumbnailSize, zoomHandler); 0325 0326 QImage image(thumbnailSize, QImage::Format_RGB32); 0327 // paint white as default page background 0328 image.fill(QColor(Qt::white).rgb()); 0329 QPainter painter(&image); 0330 painter.setClipRect(QRect(QPoint(0, 0), thumbnailSize)); 0331 painter.setRenderHint(QPainter::Antialiasing); 0332 0333 paintPage(painter, zoomHandler); 0334 0335 return image; 0336 } 0337 0338 void KoPAPageBase::pageUpdated() 0339 { 0340 KoPAPixmapCache::instance()->remove( thumbnailKey() ); 0341 } 0342 0343 QString KoPAPageBase::thumbnailKey() const 0344 { 0345 QString key; 0346 key.sprintf( "%p", static_cast<const void *>( this ) ); 0347 return key; 0348 } 0349 0350 KoShapeManagerPaintingStrategy * KoPAPageBase::getPaintingStrategy() const 0351 { 0352 return 0; 0353 }