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
core/misc.cpp
core/observer.cpp
core/page.cpp
core/pagesize.cpp
core/pagetransition.cpp
core/rotationjob.cpp
core/sound.cpp
......@@ -57,6 +58,7 @@ install( FILES
core/link.h
core/observer.h
core/page.h
core/pagesize.h
core/pagetransition.h
core/sound.h
core/sourcereference.h
......
......@@ -141,6 +141,11 @@ class Document::Private
// the rotation applied to the document
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
BookmarkManager *m_bookmarkManager;
......@@ -839,6 +844,8 @@ void Document::closeDocument()
d->m_viewportHistory.append( DocumentViewport() );
d->m_viewportIterator = d->m_viewportHistory.begin();
d->m_allocatedPixmapsTotalMemory = 0;
d->m_pageSize = PageSize();
d->m_pageSizes.clear();
}
void Document::addObserver( DocumentObserver * pObserver )
......@@ -1023,14 +1030,20 @@ bool Document::supportsSearching() const
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
......@@ -2033,14 +2046,32 @@ void Document::slotRotation( int r )
kDebug() << "Rotated: " << r << endl;
}
void Document::slotPaperSizes( int newsize )
void Document::slotPageSizes( int newsize )
{
if (d->m_generator->supportsPaperSizes())
{
d->m_generator->setPaperSize(d->m_pagesVector,newsize);
foreachObserver( notifySetup( d->m_pagesVector, true ) );
kDebug() << "PaperSize no: " << newsize << endl;
}
if ( !d->m_generator->supportsPageSizes() || newsize < 0 || newsize >= d->m_pageSizes.count() )
return;
const PageSize& ps = d->m_pageSizes.at( newsize );
// 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 **/
......
......@@ -14,6 +14,7 @@
#include <okular/core/okular_export.h>
#include <okular/core/area.h>
#include <okular/core/global.h>
#include <okular/core/pagesize.h>
#include <QtCore/QHash>
#include <QtCore/QObject>
......@@ -191,16 +192,16 @@ class OKULAR_EXPORT Document : public QObject
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.
* @see supportsPaperSizes
* @see supportsPageSizes()
*/
QStringList paperSizes() const;
PageSize::List pageSizes() const;
/**
* Returns whether the document supports the export to ASCII text.
......@@ -447,10 +448,10 @@ class OKULAR_EXPORT Document : public QObject
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.
*/
void slotPaperSizes( int size );
void slotPageSizes( int size );
Q_SIGNALS:
/**
......
......@@ -84,17 +84,17 @@ void Generator::rotationChanged( Rotation, Rotation )
{
}
bool Generator::supportsPaperSizes () const
bool Generator::supportsPageSizes() const
{
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 @@
#include <okular/core/okular_export.h>
#include <okular/core/global.h>
#include <core/pagesize.h>
#include <QtCore/QList>
#include <QtCore/QObject>
......@@ -251,20 +252,19 @@ class OKULAR_EXPORT Generator : public QObject
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
* to the given @p paperSize.
* This method is called when the page size has been changed by the user.
*/
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.
......
......@@ -21,6 +21,7 @@
#include "area.h"
#include "link.h"
#include "page.h"
#include "pagesize.h"
#include "pagetransition.h"
#include "rotationjob.h"
#include "textpage.h"
......@@ -309,6 +310,21 @@ void Page::rotateAt( Rotation orientation )
(*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
{
QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
......
......@@ -26,6 +26,7 @@ class PagePainter;
namespace Okular {
class Annotation;
class PageSize;
class PageTransition;
class SourceReference;
class TextPage;
......@@ -190,6 +191,13 @@ class OKULAR_EXPORT Page : public QObject
*/
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.
*/
......
/***************************************************************************
* 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 @@
OKULAR_EXPORT_PLUGIN(GSGenerator)
static Okular::PageSize buildPageSizeFromCDSCMEDIA( const CDSCMEDIA & media )
{
return Okular::PageSize( media.width, media.height, QString::fromAscii( media.name ) );
}
GSGenerator::GSGenerator() :
Okular::Generator(),
m_converted(false)
......@@ -55,6 +60,11 @@ GSGenerator::GSGenerator() :
}
else
m_logWindow = 0;
for ( int i = 0; i < CDSC_KNOWN_MEDIA; ++i )
{
m_pageSizes.append( buildPageSizeFromCDSCMEDIA( dsc_known_media[i] ) );
}
}
GSGenerator::~GSGenerator()
......@@ -252,25 +262,27 @@ void GSGenerator::slotAsyncPixmapGenerated(QPixmap * pix)
docLock.unlock();
}
bool GSGenerator::supportsPaperSizes() const
bool GSGenerator::supportsPageSizes() const
{
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));
loadPages(pagesVector);
/**
FIXME: is it needed to notify the observers? doesn't the document do that already?
Okular::NotifyRequest r(Okular::DocumentObserver::Setup, false);
document()->notifyObservers( &r );
*/
for ( int i = 0; i < m_pageSizes.count(); ++i )
{
if ( size == m_pageSizes.at(i) )
{
internalDoc->setMedia( size.name() );
kDebug() << "New Page size:" << size.name() << ":" << internalDoc->computePageSize( internalDoc->pageMedia() ) << endl;
break;
}
}
}
QString GSGenerator::xmlFile() const
......@@ -366,6 +378,7 @@ bool GSGenerator::loadDocumentWithDSC( const QString & name, QVector< Okular::Pa
internalDoc = new GSInternalDocument (name, ps ? GSInternalDocument::PS : GSInternalDocument::PDF);
pagesVector.resize( internalDoc->dsc()->page_count() );
kDebug() << "Page count: " << internalDoc->dsc()->page_count() << endl;
kDebug() << "Page size: " << internalDoc->computePageSize( internalDoc->pageMedia() ) << endl;
return loadPages (pagesVector);
}
......
......@@ -42,10 +42,10 @@ class GSGenerator : public Okular::Generator, public Okular::ConfigInterface, pu
bool canGeneratePixmap( bool async ) const;
void generatePixmap( Okular::PixmapRequest * request ) ;
// paper size management
bool supportsPaperSizes() const;
QStringList paperSizes() const;
void setPaperSize( QVector<Okular::Page*> & pagesVector, int newsize );
// page size management
bool supportsPageSizes() const;
Okular::PageSize::List pageSizes() const;
void pageSizeChanged( const Okular::PageSize &, const Okular::PageSize & );
QString xmlFile() const;
void setupGui( KActionCollection *, QToolBox * );
......@@ -97,6 +97,8 @@ class GSGenerator : public Okular::Generator, public Okular::ConfigInterface, pu
GSLogWindow * m_logWindow ;
KActionCollection* m_actionCollection;
QToolBox * m_box;
Okular::PageSize::List m_pageSizes;
};
#endif
......@@ -30,7 +30,7 @@
<Action name="view_render_mode"/>
<Separator/>
<Action name="view_orientation"/>
<Action name="view_papersizes"/>
<Action name="view_pagesizes"/>
</Menu>
<Menu name="go"><text>&amp;Go</text>
<Action name="previous_page"/>
......
......@@ -135,7 +135,7 @@ public:
// actions
KSelectAction * aOrientation;
KSelectAction * aPaperSizes;
KSelectAction * aPageSizes;
KAction * aMouseNormal;
KAction * aMouseSelect;
KAction * aMouseTextSelect;
......@@ -272,7 +272,7 @@ PageView::PageView( QWidget *parent, Okular::Document *document )
d->blockPixmapsRequest = false;
d->messageWindow = new PageViewMessage(this);
d->aPrevAction = 0;
d->aPaperSizes=0;
d->aPageSizes=0;
d->setting_renderMode = Okular::Settings::renderMode();
d->setting_renderCols = Okular::Settings::viewColumns();
......@@ -324,7 +324,7 @@ void PageView::setupActions( KActionCollection * ac )
d->actionCollection = ac;
d->aOrientation=new KSelectAction( i18n( "&Orientation" ), ac, "view_orientation" );
d->aPaperSizes=new KSelectAction( i18n( "&Paper Size" ), ac, "view_papersizes" );
d->aPageSizes=new KSelectAction( i18n( "&Page Size" ), ac, "view_pagesizes" );
QStringList rotations;
rotations.append( i18n( "Default" ) );
rotations.append( i18n( "Rotated 90 Degrees" ) );
......@@ -334,13 +334,18 @@ void PageView::setupActions( KActionCollection * ac )
connect( d->aOrientation , SIGNAL( triggered( int ) ),
d->document , SLOT( slotRotation( int ) ) );
connect( d->aPaperSizes , SIGNAL( triggered( int ) ),
d->document , SLOT( slotPaperSizes( int ) ) );
connect( d->aPageSizes , SIGNAL( triggered( int ) ),
d->document , SLOT( slotPageSizes( int ) ) );
bool paperSizes=d->document->supportsPaperSizes();
d->aPaperSizes->setEnabled(paperSizes);
if (paperSizes)
d->aPaperSizes->setItems(d->document->paperSizes());
bool pageSizes = d->document->supportsPageSizes();
d->aPageSizes->setEnabled( pageSizes );
if ( pageSizes )
{
QStringList items;
foreach ( const Okular::PageSize &p, d->document->pageSizes() )
items.append( p.name() );
d->aPageSizes->setItems( items );
}
// Zoom actions ( higher scales takes lots of memory! )
d->aZoom = new KSelectAction( KIcon( "viewmag" ), i18n( "Zoom" ), ac, "zoom_to" );
......@@ -617,13 +622,18 @@ void PageView::notifySetup( const QVector< Okular::Page * > & pageSet, bool docu
pageSet.count() ),
PageViewMessage::Info, 4000 );
bool paperSizes=d->document->supportsPaperSizes();
d->aPaperSizes->setEnabled(paperSizes);
// set the new paper sizes:
bool pageSizes = d->document->supportsPageSizes();
d->aPageSizes->setEnabled( pageSizes );
// set the new page sizes:
// - if the generator supports them
// - if the document changed
if (paperSizes && documentChanged)
d->aPaperSizes->setItems(d->document->paperSizes());
if ( pageSizes && documentChanged )
{
QStringList items;
foreach ( const Okular::PageSize &p, d->document->pageSizes() )
items.append( p.name() );
d->aPageSizes->setItems( items );
}
}
void PageView::notifyViewportChanged( bool smoothMove )
......
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