Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 72cffb78 authored by Thorsten Zachmann's avatar Thorsten Zachmann

o Optimize drawing of pages in the dockument docker. Cache pixmaps of

  the pages so they don't need to be redrawn every time we need them.

  Added a pixmap cache to cache pixmaps in different sizes. It is
  possible to invalidate all pixmaps of different sizes at the same
  time.


svn path=/trunk/koffice/; revision=996734
parent 6ce35837
......@@ -147,9 +147,3 @@ bool KoChildrenData::isChildLocked(const KoShape *child) const
void KoChildrenData::containerChanged(KoShapeContainer *)
{
}
void KoChildrenData::childChanged(KoShape *child, KoShape::ChangeType type)
{
Q_UNUSED(child);
Q_UNUSED(type);
}
......@@ -58,9 +58,6 @@ public:
/// reimplemented
virtual void containerChanged(KoShapeContainer *);
/// reimplemented
virtual void childChanged(KoShape *child, KoShape::ChangeType type);
private:
class Private;
Private * const d;
......
......@@ -120,7 +120,9 @@ public:
BorderChanged, ///< the shapes border has changed
BackgroundChanged, ///< the shapes background has changed
ShadowChanged, ///< the shapes shadow has changed
ParameterChanged ///< the shapes parameter has changed (KoParameterShape only)
ParameterChanged, ///< the shapes parameter has changed (KoParameterShape only)
ContentChanged, ///< the content of the shape changed e.g. a new image inside a pixmap/text change inside a textshape
ChildChanged ///< a child of a container was changed/removed. This is propagated to all parents
};
/**
......
......@@ -83,6 +83,11 @@ void KoShapeContainer::removeChild(KoShape *shape)
d->children->remove(shape);
shape->setParent(0);
childCountChanged();
KoShapeContainer * grandparent = parent();
if (grandparent) {
grandparent->model()->childChanged(this, KoShape::ChildChanged);
}
}
int KoShapeContainer::childCount() const
......
......@@ -19,6 +19,8 @@
#include "KoShapeContainerModel.h"
#include "KoShapeContainer.h"
KoShapeContainerModel::KoShapeContainerModel()
{
}
......@@ -27,3 +29,20 @@ KoShapeContainerModel::~KoShapeContainerModel()
{
}
void KoShapeContainerModel::proposeMove(KoShape *child, QPointF &move)
{
Q_UNUSED(child);
Q_UNUSED(move);
}
void KoShapeContainerModel::childChanged(KoShape *child, KoShape::ChangeType type)
{
Q_UNUSED( type );
KoShapeContainer * parent = child->parent();
Q_ASSERT(parent);
// propagate the change up the hierarchy
KoShapeContainer * grandparent = parent->parent();
if (grandparent) {
grandparent->model()->childChanged(parent, KoShape::ChildChanged);
}
}
......@@ -111,19 +111,21 @@ public:
* @param child the child of this container that the user is trying to move.
* @param move the distance that the user proposes to move child from the current position.
*/
virtual void proposeMove(KoShape *child, QPointF &move) {
Q_UNUSED(child); Q_UNUSED(move);
}
virtual void proposeMove(KoShape *child, QPointF &move);
/**
* This method is called when one of the child shapes has been modified.
* When a child shape is rotated, moved or scaled/skewed this method will be called
* to inform the container of such a change. The change has already happened at the
* time this method is called.
* The base implementation notifies the grand parent of the child that there was a
* change in a child. A reimplentation if this function should call this method when
* overwriding the function.
*
* @param child the child that has been changed
* @param type this enum shows which change the child has had.
*/
virtual void childChanged(KoShape *child, KoShape::ChangeType type) = 0;
virtual void childChanged(KoShape *child, KoShape::ChangeType type);
};
#endif
......@@ -46,7 +46,6 @@ public:
return QList<KoShape*>(m_members);
}
void containerChanged(KoShapeContainer *) { }
void childChanged(KoShape *, KoShape::ChangeType) { }
bool isChildLocked(const KoShape *child) const {
Q_ASSERT(child->parent());
return child->isGeometryProtected() || child->parent()->isGeometryProtected();
......
......@@ -21,9 +21,11 @@ set( kopageapp_LIB_SRCS
KoPAView.cpp
KoPACanvas.cpp
KoPASavingContext.cpp
KoPAPixmapCache.cpp
KoPAPageBase.cpp
KoPAMasterPage.cpp
KoPAPage.cpp
KoPAPageContainerModel.cpp
KoPAViewMode.cpp
KoPAViewModeNormal.cpp
KoPALoadingContext.cpp
......
......@@ -33,6 +33,7 @@
#include "KoPASavingContext.h"
#include "KoPALoadingContext.h"
#include "KoPAUtil.h"
#include "KoPAPixmapCache.h"
KoPAMasterPage::KoPAMasterPage()
: KoPAPageBase()
......@@ -117,6 +118,13 @@ void KoPAMasterPage::setDisplayMasterBackground( bool display )
Q_UNUSED( display );
}
void KoPAMasterPage::pageUpdated()
{
KoPAPageBase::pageUpdated();
// TODO that is not the best way as it removes to much from the cache
KoPAPixmapCache::instance()->clear( false );
}
QPixmap KoPAMasterPage::generateThumbnail( const QSize& size )
{
// don't paint null pixmap
......
......@@ -54,6 +54,10 @@ public:
/// reimplemented
virtual void setDisplayMasterBackground( bool display );
/// reimplemented
virtual void pageUpdated();
/// reimplemented
virtual void paintPage( QPainter & painter, KoZoomHandler & zoomHandler );
protected:
......
......@@ -20,6 +20,8 @@
#include "KoPAPageBase.h"
#include "KoPASavingContext.h"
#include "KoPALoadingContext.h"
#include "KoPAPixmapCache.h"
#include "KoPAPageContainerModel.h"
#include <QPainter>
......@@ -40,7 +42,7 @@
#include <KoShapeBackground.h>
KoPAPageBase::KoPAPageBase()
: KoShapeContainer()
: KoShapeContainer( new KoPAPageContainerModel() )
{
// Add a default layer
KoShapeLayer* layer = new KoShapeLayer;
......@@ -216,7 +218,33 @@ KoPageApp::PageType KoPAPageBase::pageType() const
QPixmap KoPAPageBase::thumbnail( const QSize& size )
{
#ifdef CACHE_PAGE_THUMBNAILS
QString key = thumbnailKey();
QPixmap pm;
if ( !KoPAPixmapCache::instance()->find( key, size, pm ) ) {
pm = generateThumbnail( size );
KoPAPixmapCache::instance()->insert( key, pm );
kDebug(30010) << "create thumbnail" << this;
}
else {
kDebug(30010) << "thumbnail in cache " << this;
}
return pm;
#else
return generateThumbnail( size );
#endif
}
void KoPAPageBase::pageUpdated()
{
KoPAPixmapCache::instance()->remove( thumbnailKey() );
}
QString KoPAPageBase::thumbnailKey() const
{
QString key;
key.sprintf( "%p", static_cast<const void *>( this ) );
return key;
}
KoShapeManagerPaintingStrategy * KoPAPageBase::getPaintingStrategy() const
......
......@@ -20,7 +20,6 @@
#ifndef KOPAPAGEBASE_H
#define KOPAPAGEBASE_H
#include <QList>
#include <QString>
#include <QPixmap>
......@@ -32,6 +31,8 @@
#include "KoPASavingContext.h"
#include "kopageapp_export.h"
#define CACHE_PAGE_THUMBNAILS
struct KoPageLayout;
class KoOdfLoadingContext;
class KoGenStyle;
......@@ -109,6 +110,13 @@ public:
QPixmap thumbnail( const QSize& size = QSize( 512, 512 ) );
/**
* This function is called when the content of the page changes
*
* It invalidates the pages thumbnail cache.
*/
virtual void pageUpdated();
/// reimplemented
virtual QSizeF size() const;
......@@ -222,6 +230,11 @@ protected:
*/
virtual QPixmap generateThumbnail( const QSize& size = QSize( 512, 512 ) ) = 0;
/**
* Get the key used for for caching the tumbnail pixmap
*/
QString thumbnailKey() const;
/**
* Get the painting strategy used for generating thumbnails
*
......
/* This file is part of the KDE project
Copyright (C) 2009 Thorsten Zachmann <zachmann@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "KoPAPixmapCache.h"
#include <QPixmapCache>
#include <KGlobal>
class KoPAPixmapCache::Singleton
{
public:
KoPAPixmapCache q;
};
K_GLOBAL_STATIC( KoPAPixmapCache::Singleton, singleton )
KoPAPixmapCache * KoPAPixmapCache::instance()
{
return &( singleton->q );
}
KoPAPixmapCache::KoPAPixmapCache()
{
}
KoPAPixmapCache::~KoPAPixmapCache()
{
}
int KoPAPixmapCache::cacheLimit()
{
return QPixmapCache::cacheLimit();
}
void KoPAPixmapCache::clear( bool all )
{
if ( all ) {
QPixmapCache::clear();
}
else {
QMap<QString, QList<QSize> >::iterator it( m_keySize.begin() );
for ( ; it != m_keySize.end(); ++it ) {
foreach( QSize size, it.value() ) {
QString k = generateKey( it.key(), size );
QPixmapCache::remove( k );
}
}
m_keySize.clear();
}
}
bool KoPAPixmapCache::find( const QString & key, const QSize & size, QPixmap & pm )
{
QString k = generateKey( key, size );
return QPixmapCache::find( k, pm );
}
bool KoPAPixmapCache::insert( const QString & key, const QPixmap & pm )
{
QString k = generateKey( key, pm.size() );
m_keySize[key].append( pm.size() );
return QPixmapCache::insert( k, pm );
}
void KoPAPixmapCache::remove( const QString & key )
{
QMap<QString, QList<QSize> >::iterator it( m_keySize.find( key ) );
if ( it != m_keySize.end() ) {
foreach( QSize size, it.value() ) {
QString k = generateKey( key, size );
QPixmapCache::remove( k );
}
m_keySize.erase( it );
}
}
void KoPAPixmapCache::setCacheLimit( int n )
{
QPixmapCache::setCacheLimit( n );
}
QString KoPAPixmapCache::generateKey( const QString &key, const QSize & size )
{
return QString( "%1-%2-%3" ).arg( key ).arg( size.width() ).arg( size.height() );
}
/* This file is part of the KDE project
Copyright (C) 2009 Thorsten Zachmann <zachmann@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KOPAPIXMAPCACHE_H
#define KOPAPIXMAPCACHE_H
#include <QMap>
class QString;
class QSize;
class QPixmap;
/**
* This class is a cache for pixmaps which will be cached for different sizes
* of the same pixmap If a key is removed from the cache all cached sizes will
* be removed from the cache.
*
* The API is similar to QPixmpaCache. The only addition is that you need to
* specify the size of the pixmap when you search it.
*
* The implementation uses QPixmpaCache.
*
* This class is a singleton.
*/
class KoPAPixmapCache
{
public:
class Singleton;
/**
* Get the pixmap cache singleton
*/
static KoPAPixmapCache * instance();
~KoPAPixmapCache();
/**
* Returns the cache limit (in kilobytes)
*/
int cacheLimit();
/**
* Removes all pixmaps from the cache.
*
* @param all If true QPixmpaCache::clear will be called.
* If false only the pixmaps which were added via this object
* will be removed
*/
void clear( bool all = true );
/**
* Looks for a cached pixmap associated with the key in the cache.
*
* If the pixmap is found, the function sets pm to that pixmap and returns true;
* otherwise it leaves pm alone and returns false.
*
* @param key the key of the pixmap
* @param size the size you want to have the pixmap
* @param pm the pixmap
*/
bool find( const QString & key, const QSize & size, QPixmap & pm );
/**
* Insert a copy of the pixmap into the cache.
*
* The size is taken from the pixmap.
*/
bool insert( const QString & key, const QPixmap & pm );
/**
* Remove all pixmaps associated with key from the cache
*/
void remove( const QString & key );
/**
* Sets the cache limit to n kilobytes
*/
void setCacheLimit( int n );
private:
KoPAPixmapCache();
KoPAPixmapCache( const KoPAPixmapCache & );
KoPAPixmapCache operator=( const KoPAPixmapCache & );
QString generateKey( const QString &key, const QSize & size );
QMap<QString, QList<QSize> > m_keySize;
};
#endif /* KOPAPIXMAPCACHE_H */
......@@ -123,6 +123,7 @@ void KoTextShapeContainerModel::childChanged(KoShape *child, KoShape::ChangeType
lay->interruptLayout();
data->fireResizeEvent();
}
KoShapeContainerModel::childChanged( child, type );
}
void KoTextShapeContainerModel::addAnchor(KoTextAnchor *anchor)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment