Commit a5795e27 authored by Pino Toscano's avatar Pino Toscano

Now the DjVu generator is able to extract the list of bookmarks (aka Table of...

Now the DjVu generator is able to extract the list of bookmarks (aka Table of Contents) from the DjVy document, if it has any.

svn path=/trunk/playground/graphics/okular/; revision=555320
parent 70423d2f
......@@ -9,16 +9,48 @@
#include "generator_djvu.h"
#include "kdjvu.h"
#include "core/document.h"
#include "core/page.h"
#include <qdom.h>
#include <qstring.h>
#include <kdebug.h>
#include <klocale.h>
static void recurseCreateTOC( QDomDocument &maindoc, QDomNode &parent, QDomNode &parentDestination )
{
QDomNode n = parent.firstChild();
while( !n.isNull() )
{
QDomElement el = n.toElement();
QDomElement newel = maindoc.createElement( el.attribute( "title" ) );
parentDestination.appendChild( newel );
if ( !el.attribute( "destination" ).isEmpty() )
{
bool ok = true;
int page = el.attribute( "destination" ).toInt( &ok );
if ( ok && ( page > 0 ) )
{
DocumentViewport vp;
vp.pageNumber = page - 1;
newel.setAttribute( "Viewport", vp.toString() );
}
}
if ( el.hasChildNodes() )
{
recurseCreateTOC( maindoc, n, newel );
}
n = n.nextSibling();
}
}
OKULAR_EXPORT_PLUGIN(DjVuGenerator)
DjVuGenerator::DjVuGenerator( KPDFDocument * doc ) : Generator ( doc ),
m_docInfo( 0 ), ready( false )
m_docInfo( 0 ), m_docSyn( 0 ), ready( false )
{
m_djvu = new KDjVu();
connect( m_djvu, SIGNAL( pixmapGenerated( int, const QPixmap & ) ), this, SLOT( djvuPixmapGenerated( int, const QPixmap & ) ) );
......@@ -28,6 +60,8 @@ bool DjVuGenerator::loadDocument( const QString & fileName, QVector< KPDFPage *
{
delete m_docInfo;
m_docInfo = 0;
delete m_docSyn;
m_docSyn = 0;
if ( !m_djvu->openFile( fileName ) )
return false;
......@@ -87,6 +121,21 @@ const DocumentInfo * DjVuGenerator::generateDocumentInfo()
return m_docInfo;
}
const DocumentSynopsis * DjVuGenerator::generateDocumentSynopsis()
{
if ( m_docSyn )
return m_docSyn;
const QDomDocument *doc = m_djvu->documentBookmarks();
if ( doc )
{
m_docSyn = new DocumentSynopsis();
recurseCreateTOC( *m_docSyn, *const_cast<QDomDocument*>( doc ), *m_docSyn );
}
return m_docSyn;
}
void DjVuGenerator::setOrientation( QVector<KPDFPage*> & pagesVector, int orientation )
{
loadPages( pagesVector, orientation );
......
......@@ -28,6 +28,7 @@ class DjVuGenerator : public Generator
// document information
const DocumentInfo * generateDocumentInfo();
const DocumentSynopsis * generateDocumentSynopsis();
// rotation handling
bool supportsRotation() { return true; };
......@@ -42,6 +43,7 @@ class DjVuGenerator : public Generator
KDjVu *m_djvu;
DocumentInfo *m_docInfo;
DocumentSynopsis *m_docSyn;
bool ready;
PixmapRequest *m_request;
......
......@@ -9,15 +9,18 @@
#include "kdjvu.h"
#include <qdom.h>
#include <qfile.h>
#include <qlist.h>
#include <qmap.h>
#include <qpainter.h>
#include <qstring.h>
#include <kdebug.h>
#include <klocale.h>
#include <libdjvu/ddjvuapi.h>
#include <libdjvu/miniexp.h>
kdbgstream &operator<<( kdbgstream & s, const ddjvu_rect_t &r )
{
......@@ -134,13 +137,17 @@ class KDjVu::Private
{
public:
Private()
: m_djvu_cxt( 0 ), m_djvu_document( 0 ), m_format( 0 )
: m_djvu_cxt( 0 ), m_djvu_document( 0 ), m_format( 0 ), m_docBookmarks( 0 )
{
}
QPixmap generatePixmapTile( ddjvu_page_t *djvupage, int& res,
int width, int row, int xdelta, int height, int col, int ydelta );
void readBookmarks();
void fillBookmarksRecurse( QDomDocument& maindoc, QDomNode& curnode,
miniexp_t exp, int offset = -1 );
ddjvu_context_t *m_djvu_cxt;
ddjvu_document_t *m_djvu_document;
ddjvu_format_t *m_format;
......@@ -151,6 +158,7 @@ class KDjVu::Private
QList<PixmapCacheItem*> mPixCache;
QMap<QString, QString> m_metaData;
QDomDocument * m_docBookmarks;
};
QPixmap KDjVu::Private::generatePixmapTile( ddjvu_page_t *djvupage, int& res,
......@@ -187,6 +195,57 @@ QPixmap KDjVu::Private::generatePixmapTile( ddjvu_page_t *djvupage, int& res,
return pix;
}
void KDjVu::Private::readBookmarks()
{
if ( !m_djvu_document )
return;
miniexp_t outline;
while ( ( outline = ddjvu_document_get_outline( m_djvu_document ) ) == miniexp_dummy )
handle_ddjvu_messages( m_djvu_cxt, true );
if ( miniexp_listp( outline ) &&
( miniexp_length( outline ) > 0 ) &&
miniexp_symbolp( miniexp_nth( 0, outline ) ) &&
( QString::fromUtf8( miniexp_to_name( miniexp_nth( 0, outline ) ) ) == QLatin1String( "bookmarks" ) ) )
{
m_docBookmarks = new QDomDocument( "KDjVuBookmarks" );
fillBookmarksRecurse( *m_docBookmarks, *m_docBookmarks, outline, 1 );
}
}
void KDjVu::Private::fillBookmarksRecurse( QDomDocument& maindoc, QDomNode& curnode,
miniexp_t exp, int offset )
{
if ( !miniexp_listp( exp ) )
return;
int l = miniexp_length( exp );
for ( int i = qMax( offset, 0 ); i < l; ++i )
{
miniexp_t cur = miniexp_nth( i, exp );
if ( miniexp_consp( cur ) && ( miniexp_length( cur ) > 0 ) &&
miniexp_stringp( miniexp_nth( 0, cur ) ) && miniexp_stringp( miniexp_nth( 1, cur ) ) )
{
QString title = QString::fromUtf8( miniexp_to_str( miniexp_nth( 0, cur ) ) );
QString dest = QString::fromUtf8( miniexp_to_str( miniexp_nth( 1, cur ) ) );
QDomElement el;
if ( dest.isEmpty() || ( ( dest.at( 0 ) == QLatin1Char( '#' ) ) && ( dest.remove( 0, 1 ) != title ) ) )
{
el = maindoc.createElement( "item" );
el.setAttribute( "title", title );
el.setAttribute( "destination", dest );
curnode.appendChild( el );
}
if ( !el.isNull() && ( miniexp_length( cur ) > 2 ) )
{
fillBookmarksRecurse( maindoc, el, cur, 2 );
}
}
}
}
KDjVu::KDjVu() : QObject(), d( new Private )
{
......@@ -288,6 +347,9 @@ bool KDjVu::openFile( const QString & fileName )
void KDjVu::closeFile()
{
// deleting the old TOC
delete d->m_docBookmarks;
d->m_docBookmarks = 0;
// deleting the pages
qDeleteAll( d->m_pages );
// releasing the djvu pages
......@@ -310,6 +372,13 @@ QString KDjVu::getMetaData( const QString & key ) const
return d->m_metaData.contains( key ) ? d->m_metaData[ key ] : QString();
}
const QDomDocument * KDjVu::documentBookmarks() const
{
if ( !d->m_docBookmarks )
d->readBookmarks();
return d->m_docBookmarks;
}
const QVector<KDjVu::Page*> &KDjVu::pages() const
{
return d->m_pages;
......
......@@ -14,6 +14,8 @@
#include <qpixmap.h>
#include <qvector.h>
class QDomDocument;
/**
* @brief Qt (KDE) encapsulation of the DjVuLibre
*/
......@@ -69,6 +71,8 @@ class KDjVu : public QObject
*/
QString getMetaData( const QString & key ) const;
const QDomDocument * documentBookmarks() const;
// pixmap handling
/**
* Check if the pixmap for the specified \p page with the specified
......@@ -85,7 +89,7 @@ class KDjVu : public QObject
signals:
void pixmapGenerated( int page, const QPixmap & pix );
private:
private:
class Private;
Private * const d;
};
......
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