mirror of
https://invent.kde.org/graphics/okular
synced 2024-09-19 16:01:41 +00:00
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
This commit is contained in:
parent
70423d2f95
commit
a5795e2726
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue