Commit 18fab3d1 authored by Pino Toscano's avatar Pino Toscano

Improve the way we deal with generators that give the possibility to change...

Improve the way we deal with generators that give the possibility to change the size of the pages: instead of let them destroy and recreate the pages (bad), ask them the sizes they support, then do the work ourselves and notify the generator when the work is done.
While I was at it, I changed from "paper size" to "page size", it should be better.

svn path=/trunk/playground/graphics/okular/; revision=620411
parent edecb5b1
...@@ -41,6 +41,7 @@ set(okularcore_SRCS ...@@ -41,6 +41,7 @@ set(okularcore_SRCS
core/misc.cpp core/misc.cpp
core/observer.cpp core/observer.cpp
core/page.cpp core/page.cpp
core/pagesize.cpp
core/pagetransition.cpp core/pagetransition.cpp
core/rotationjob.cpp core/rotationjob.cpp
core/sound.cpp core/sound.cpp
...@@ -57,6 +58,7 @@ install( FILES ...@@ -57,6 +58,7 @@ install( FILES
core/link.h core/link.h
core/observer.h core/observer.h
core/page.h core/page.h
core/pagesize.h
core/pagetransition.h core/pagetransition.h
core/sound.h core/sound.h
core/sourcereference.h core/sourcereference.h
......
...@@ -141,6 +141,11 @@ class Document::Private ...@@ -141,6 +141,11 @@ class Document::Private
// the rotation applied to the document // the rotation applied to the document
Rotation m_rotation; Rotation m_rotation;
// the current size of the pages (if available), and the cache of the
// available page sizes
PageSize m_pageSize;
PageSize::List m_pageSizes;
// our bookmark manager // our bookmark manager
BookmarkManager *m_bookmarkManager; BookmarkManager *m_bookmarkManager;
...@@ -839,6 +844,8 @@ void Document::closeDocument() ...@@ -839,6 +844,8 @@ void Document::closeDocument()
d->m_viewportHistory.append( DocumentViewport() ); d->m_viewportHistory.append( DocumentViewport() );
d->m_viewportIterator = d->m_viewportHistory.begin(); d->m_viewportIterator = d->m_viewportHistory.begin();
d->m_allocatedPixmapsTotalMemory = 0; d->m_allocatedPixmapsTotalMemory = 0;
d->m_pageSize = PageSize();
d->m_pageSizes.clear();
} }
void Document::addObserver( DocumentObserver * pObserver ) void Document::addObserver( DocumentObserver * pObserver )
...@@ -1023,14 +1030,20 @@ bool Document::supportsSearching() const ...@@ -1023,14 +1030,20 @@ bool Document::supportsSearching() const
return d->m_generator ? d->m_generator->supportsSearching() : false; return d->m_generator ? d->m_generator->supportsSearching() : false;
} }
bool Document::supportsPaperSizes() const bool Document::supportsPageSizes() const
{ {
return d->m_generator ? d->m_generator->supportsPaperSizes() : false; return d->m_generator ? d->m_generator->supportsPageSizes() : false;
} }
QStringList Document::paperSizes() const PageSize::List Document::pageSizes() const
{ {
return d->m_generator ? d->m_generator->paperSizes() : QStringList(); if ( d->m_generator )
{
if ( d->m_pageSizes.isEmpty() )
d->m_pageSizes = d->m_generator->pageSizes();
return d->m_pageSizes;
}
return PageSize::List();
} }
bool Document::canExportToText() const bool Document::canExportToText() const
...@@ -2033,14 +2046,32 @@ void Document::slotRotation( int r ) ...@@ -2033,14 +2046,32 @@ void Document::slotRotation( int r )
kDebug() << "Rotated: " << r << endl; kDebug() << "Rotated: " << r << endl;
} }
void Document::slotPaperSizes( int newsize ) void Document::slotPageSizes( int newsize )
{ {
if (d->m_generator->supportsPaperSizes()) if ( !d->m_generator->supportsPageSizes() || newsize < 0 || newsize >= d->m_pageSizes.count() )
{ return;
d->m_generator->setPaperSize(d->m_pagesVector,newsize);
foreachObserver( notifySetup( d->m_pagesVector, true ) ); const PageSize& ps = d->m_pageSizes.at( newsize );
kDebug() << "PaperSize no: " << newsize << endl; // tell the pages to change size
} QVector< Okular::Page * >::const_iterator pIt = d->m_pagesVector.begin();
QVector< Okular::Page * >::const_iterator pEnd = d->m_pagesVector.end();
for ( ; pIt != pEnd; ++pIt )
(*pIt)->changeSize( ps );
// clear 'memory allocation' descriptors
QLinkedList< AllocatedPixmap * >::const_iterator aIt = d->m_allocatedPixmapsFifo.begin();
QLinkedList< AllocatedPixmap * >::const_iterator aEnd = d->m_allocatedPixmapsFifo.end();
for ( ; aIt != aEnd; ++aIt )
delete *aIt;
d->m_allocatedPixmapsFifo.clear();
d->m_allocatedPixmapsTotalMemory = 0;
// notify the generator that the current page size has changed
d->m_generator->pageSizeChanged( ps, d->m_pageSize );
// set the new page size
d->m_pageSize = ps;
foreachObserver( notifySetup( d->m_pagesVector, true ) );
foreachObserver( notifyContentsCleared (DocumentObserver::Pixmap | DocumentObserver::Highlights | DocumentObserver::Annotations));
kDebug() << "PageSize no: " << newsize << endl;
} }
/** DocumentViewport **/ /** DocumentViewport **/
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <okular/core/okular_export.h> #include <okular/core/okular_export.h>
#include <okular/core/area.h> #include <okular/core/area.h>
#include <okular/core/global.h> #include <okular/core/global.h>
#include <okular/core/pagesize.h>
#include <QtCore/QHash> #include <QtCore/QHash>
#include <QtCore/QObject> #include <QtCore/QObject>
...@@ -191,16 +192,16 @@ class OKULAR_EXPORT Document : public QObject ...@@ -191,16 +192,16 @@ class OKULAR_EXPORT Document : public QObject
bool supportsSearching() const; bool supportsSearching() const;
/** /**
* Returns whether the document supports the listing of paper sizes. * Returns whether the document supports the listing of page sizes.
*/ */
bool supportsPaperSizes() const; bool supportsPageSizes() const;
/** /**
* Returns the list of supported paper sizes or an empty list if this * Returns the list of supported page sizes or an empty list if this
* feature is not available. * feature is not available.
* @see supportsPaperSizes * @see supportsPageSizes()
*/ */
QStringList paperSizes() const; PageSize::List pageSizes() const;
/** /**
* Returns whether the document supports the export to ASCII text. * Returns whether the document supports the export to ASCII text.
...@@ -447,10 +448,10 @@ class OKULAR_EXPORT Document : public QObject ...@@ -447,10 +448,10 @@ class OKULAR_EXPORT Document : public QObject
void slotRotation( int rotation ); void slotRotation( int rotation );
/** /**
* This slot is called whenever the user changes the paper @p size * This slot is called whenever the user changes the page @p size
* of the document. * of the document.
*/ */
void slotPaperSizes( int size ); void slotPageSizes( int size );
Q_SIGNALS: Q_SIGNALS:
/** /**
......
...@@ -84,17 +84,17 @@ void Generator::rotationChanged( Rotation, Rotation ) ...@@ -84,17 +84,17 @@ void Generator::rotationChanged( Rotation, Rotation )
{ {
} }
bool Generator::supportsPaperSizes () const bool Generator::supportsPageSizes() const
{ {
return false; return false;
} }
QStringList Generator::paperSizes () const PageSize::List Generator::pageSizes() const
{ {
return QStringList(); return PageSize::List();
} }
void Generator::setPaperSize( QVector<Page*>&, int ) void Generator::pageSizeChanged( const PageSize &, const PageSize & )
{ {
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <okular/core/okular_export.h> #include <okular/core/okular_export.h>
#include <okular/core/global.h> #include <okular/core/global.h>
#include <core/pagesize.h>
#include <QtCore/QList> #include <QtCore/QList>
#include <QtCore/QObject> #include <QtCore/QObject>
...@@ -251,20 +252,19 @@ class OKULAR_EXPORT Generator : public QObject ...@@ -251,20 +252,19 @@ class OKULAR_EXPORT Generator : public QObject
virtual void rotationChanged( Rotation orientation, Rotation oldOrientation ); virtual void rotationChanged( Rotation orientation, Rotation oldOrientation );
/** /**
* Returns whether the generator supports paper sizes. Default is false. * Returns whether the generator supports page sizes. Default is false.
*/ */
virtual bool supportsPaperSizes() const; virtual bool supportsPageSizes() const;
/** /**
* Returns the list of supported paper sizes. * Returns the list of supported page sizes.
*/ */
virtual QStringList paperSizes() const; virtual PageSize::List pageSizes() const;
/** /**
* This method is called to set the paper size of the given @p pages * This method is called when the page size has been changed by the user.
* to the given @p paperSize.
*/ */
virtual void setPaperSize( QVector<Page*> &pages, int paperSize ); virtual void pageSizeChanged( const PageSize &pageSize, const PageSize &oldPageSize );
/** /**
* This method is called to print the document to the given @p printer. * This method is called to print the document to the given @p printer.
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "area.h" #include "area.h"
#include "link.h" #include "link.h"
#include "page.h" #include "page.h"
#include "pagesize.h"
#include "pagetransition.h" #include "pagetransition.h"
#include "rotationjob.h" #include "rotationjob.h"
#include "textpage.h" #include "textpage.h"
...@@ -309,6 +310,21 @@ void Page::rotateAt( Rotation orientation ) ...@@ -309,6 +310,21 @@ void Page::rotateAt( Rotation orientation )
(*objectIt)->transform( matrix ); (*objectIt)->transform( matrix );
} }
void Page::changeSize( const PageSize &size )
{
if ( size.isNull() || ( size.width() == d->m_width && size.height() == d->m_height ) )
return;
deletePixmaps();
// deleteHighlights();
// deleteTextSelections();
d->m_width = size.width();
d->m_height = size.height();
if ( d->m_rotation % 2 )
qSwap( d->m_width, d->m_height );
}
const ObjectRect * Page::objectRect( ObjectRect::ObjectType type, double x, double y, double xScale, double yScale ) const const ObjectRect * Page::objectRect( ObjectRect::ObjectType type, double x, double y, double xScale, double yScale ) const
{ {
QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end(); QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
......
...@@ -26,6 +26,7 @@ class PagePainter; ...@@ -26,6 +26,7 @@ class PagePainter;
namespace Okular { namespace Okular {
class Annotation; class Annotation;
class PageSize;
class PageTransition; class PageTransition;
class SourceReference; class SourceReference;
class TextPage; class TextPage;
...@@ -190,6 +191,13 @@ class OKULAR_EXPORT Page : public QObject ...@@ -190,6 +191,13 @@ class OKULAR_EXPORT Page : public QObject
*/ */
void rotateAt( Rotation orientation ); void rotateAt( Rotation orientation );
/**
* Changes the size of the page to the given @p size.
*
* The @p size is meant to be referred to the page not rotated.
*/
void changeSize( const PageSize &size );
/** /**
* Sets the @p pixmap for the observer with the given @p id. * Sets the @p pixmap for the observer with the given @p id.
*/ */
......
/***************************************************************************
* Copyright (C) 2007 by Pino Toscano <pino@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
// local includes
#include "pagesize.h"
using namespace Okular;
class PageSize::Private
{
public:
Private()
: m_width( 0 ), m_height( 0 )
{
}
double m_width;
double m_height;
QString m_name;
};
PageSize::PageSize()
: d( new Private )
{
}
PageSize::PageSize( double width, double height, const QString &name )
: d( new Private )
{
d->m_width = width;
d->m_height = height;
d->m_name = name;
}
PageSize::PageSize( const PageSize &pageSize )
: d( new Private( *pageSize.d ) )
{
}
PageSize::~PageSize()
{
delete d;
}
double PageSize::width() const
{
return d->m_width;
}
double PageSize::height() const
{
return d->m_height;
}
QString PageSize::name() const
{
return d->m_name;
}
bool PageSize::isNull() const
{
return d->m_width == 0 && d->m_height == 0 && d->m_name.isEmpty();
}
bool PageSize::operator==( const PageSize &pageSize ) const
{
return d->m_width == pageSize.d->m_width &&
d->m_height == pageSize.d->m_height &&
d->m_name == pageSize.d->m_name;
}
PageSize& PageSize::operator=( const PageSize &pageSize )
{
if ( this == &pageSize )
return *this;
*d = *pageSize.d;
return *this;
}
/***************************************************************************
* Copyright (C) 2007 by Pino Toscano <pino@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef _OKULAR_PAGESIZE_H_
#define _OKULAR_PAGESIZE_H_
#include <QtCore/QList>
#include <QtCore/QString>
#include <core/okular_export.h>
namespace Okular {
/**
* @short A small class that represents the size of a page.
*/
class OKULAR_EXPORT PageSize
{
public:
typedef QList<PageSize> List;
/**
* Construct a null page size.
* @see isNull()
*/
PageSize();
/**
* Construct a page size with the specified @p width and @p height,
* having the ID @p name.
*/
PageSize( double width, double height, const QString &name );
/**
* Copy constructor.
*/
PageSize( const PageSize &pageSize );
~PageSize();
/**
* Returns the width of the page size.
*/
double width() const;
/**
* Returns the height of the page size.
*/
double height() const;
/**
* Returns the ID of the page size.
*/
QString name() const;
/**
* Whether the page size is null.
*/
bool isNull() const;
PageSize& operator=( const PageSize &pageSize );
/**
* Comparison operator.
*/
bool operator==( const PageSize &pageSize ) const;
private:
class Private;
Private * const d;
};
}
#endif
...@@ -38,6 +38,11 @@ ...@@ -38,6 +38,11 @@
OKULAR_EXPORT_PLUGIN(GSGenerator) OKULAR_EXPORT_PLUGIN(GSGenerator)
static Okular::PageSize buildPageSizeFromCDSCMEDIA( const CDSCMEDIA & media )
{
return Okular::PageSize( media.width, media.height, QString::fromAscii( media.name ) );
}
GSGenerator::GSGenerator() : GSGenerator::GSGenerator() :
Okular::Generator(), Okular::Generator(),
m_converted(false) m_converted(false)
...@@ -55,6 +60,11 @@ GSGenerator::GSGenerator() : ...@@ -55,6 +60,11 @@ GSGenerator::GSGenerator() :
} }
else else
m_logWindow = 0; m_logWindow = 0;
for ( int i = 0; i < CDSC_KNOWN_MEDIA; ++i )
{
m_pageSizes.append( buildPageSizeFromCDSCMEDIA( dsc_known_media[i] ) );
}
} }
GSGenerator::~GSGenerator() GSGenerator::~GSGenerator()
...@@ -252,25 +262,27 @@ void GSGenerator::slotAsyncPixmapGenerated(QPixmap * pix) ...@@ -252,25 +262,27 @@ void GSGenerator::slotAsyncPixmapGenerated(QPixmap * pix)
docLock.unlock(); docLock.unlock();
} }
bool GSGenerator::supportsPaperSizes() const bool GSGenerator::supportsPageSizes() const
{ {
return true; return true;
} }
QStringList GSGenerator::paperSizes() const Okular::PageSize::List GSGenerator::pageSizes() const
{ {
return GSInternalDocument::paperSizes(); return m_pageSizes;
} }
void GSGenerator::setPaperSize( QVector<Okular::Page*> & pagesVector, int newsize ) void GSGenerator::pageSizeChanged( const Okular::PageSize &size, const Okular::PageSize &/*oldSize*/ )
{ {
internalDoc->setMedia(paperSizes().at(newsize)); for ( int i = 0; i < m_pageSizes.count(); ++i )
loadPages(pagesVector); {
/** if ( size == m_pageSizes.at(i) )
FIXME: is it needed to notify the observers? doesn't the document do that already? {
Okular::NotifyRequest r(Okular::DocumentObserver::Setup, false); internalDoc->setMedia( size.name() );
document()->notifyObservers( &r ); kDebug() << "New Page size:" << size.name() << ":" << internalDoc->computePageSize( internalDoc->pageMedia() ) << endl;
*/ break;
}
}
} }
QString GSGenerator::xmlFile() const QString GSGenerator::xmlFile() const
...@@ -366,6 +378,7 @@ bool GSGenerator::loadDocumentWithDSC( const QString & name, QVector< Okular::Pa ...@@ -366,6 +378,7 @@ bool GSGenerator::loadDocumentWithDSC( const QString & name, QVector< Okular::Pa
internalDoc = new GSInternalDocument (name, ps ? GSInternalDocument::PS : GSInternalDocument::PDF); internalDoc = new GSInternalDocument (name, ps ? GSInternalDocument::PS : GSInternalDocument::PDF);
pagesVector.resize( internalDoc->dsc()->page_count() ); pagesVector.resize( internalDoc->dsc()->page_count() );
kDebug() << "Page count: " << internalDoc->dsc()->page_count() << endl; kDebug() << "Page count: " << internalDoc->dsc()->page_count() << endl;
kDebug() << "Page size: " << internalDoc->computePageSize( internalDoc->pageMedia() ) << endl;
return loadPages (pagesVector); return loadPages (pagesVector);
} }
......
...@@ -42,10 +42,10 @@ class GSGenerator : public Okular::Generator, public Okular::ConfigInterface, pu ...@@ -42,10 +42,10 @@ class GSGenerator : public Okular::Generator, public Okular::ConfigInterface, pu
bool canGeneratePixmap( bool async ) const; bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request ) ; void generatePixmap( Okular::PixmapRequest * request ) ;
// paper size management // page size management
bool supportsPaperSizes() const; bool supportsPageSizes() const;
QStringList paperSizes() const; Okular::PageSize::List pageSizes() const;
void setPaperSize( QVector<Okular::Page*> & pagesVector, int newsize ); void pageSizeChanged( const Okular::PageSize &, const Okular::PageSize & );
QString xmlFile() const; QString xmlFile() const;
void setupGui( KActionCollection *, QToolBox * ); void setupGui( KActionCollection *, QToolBox * );
...@@ -97,6 +97,8 @@ class GSGenerator : public Okular::Generator, public Okular::ConfigInterface, pu ...@@ -97,6 +97,8 @@ class GSGenerator : public Okular::Generator, public Okular::ConfigInterface, pu
GSLogWindow * m_logWindow ; GSLogWindow * m_logWindow ;
KActionCollection* m_actionCollection; KActionCollection* m_actionCollection;
QToolBox * m_box; QToolBox * m_box;
Okular::PageSize::List m_pageSizes;
}; };
#endif #endif
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
<Action name="view_render_mode"/> <Action name="view_render_mode"/>
<Separator/> <Separator/>
<Action name="view_orientation"/> <Action name="view_orientation"/>
<Action name="view_papersizes"/> <Action name="view_pagesizes"/>
</Menu> </Menu>
<Menu name="go"><text>&amp;Go</text> <Menu name="go"><text>&amp;Go</text>
<Action name="previous_page"/> <Action name="previ