Move the EPub backend to kdegraphics.

svn path=/trunk/KDE/kdegraphics/okular/; revision=793009
This commit is contained in:
Pino Toscano 2008-04-02 20:43:31 +00:00
commit 433f78d7f1
13 changed files with 539 additions and 0 deletions

View file

@ -0,0 +1,36 @@
find_package(KDE4 REQUIRED)
include(KDE4Defaults)
find_package(Okular REQUIRED)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
find_package(EPub REQUIRED)
add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories(
${KDE4_INCLUDES}
${OKULAR_INCLUDE_DIR}
${EPUB_INCLUDE_DIR}
)
########### next target ###############
set(okularGenerator_epub_PART_SRCS
converter.cpp
epubdocument.cpp
generator_epub.cpp
)
kde4_add_plugin(okularGenerator_epub ${okularGenerator_epub_PART_SRCS})
target_link_libraries(okularGenerator_epub ${OKULAR_LIBRARIES} ${EPUB_LIBRARIES} ${KDE4_KDECORE_LIBS} ${QT_QTGUI_LIBRARY})
install(TARGETS okularGenerator_epub DESTINATION ${PLUGIN_INSTALL_DIR})
########### install files ###############
install( FILES libokularGenerator_epub.desktop okularEPub.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
install( FILES okularApplication_epub.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} )

2
generators/epub/Messages.sh Executable file
View file

@ -0,0 +1,2 @@
#!/bin/sh
$XGETTEXT $(find . -name "*.cpp") -o $podir/okular_epub.pot

10
generators/epub/README Normal file
View file

@ -0,0 +1,10 @@
This is a libepub based backend to watch epub books using okular
The epub library can be obtained using:
svn co https://ebook-tools.svn.sourceforge.net/svnroot/ebook-tools/trunk ebook-tools
The library uses standard cmake (ccmake .;make install)
The epub standard specs can be found in:
http://www.idpf.org/specs.htm

View file

@ -0,0 +1,35 @@
# - Find EPub
# Find the EPub library.
#
# This module defines
# EPUB_FOUND - whether the EPub library was found
# EPUB_LIBRARIES - the EPub library
# EPUB_INCLUDE_DIR - the include path of the EPub library
# Copyright (c) 2008, Pino Toscano, <pino@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if (EPUB_INCLUDE_DIR AND EPUB_LIBRARIES)
# Already in cache
set (EPUB_FOUND TRUE)
else (EPUB_INCLUDE_DIR AND EPUB_LIBRARIES)
find_library (EPUB_LIBRARIES
NAMES epub
)
find_path (EPUB_INCLUDE_DIR
NAMES epub.h
)
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (EPub DEFAULT_MSG EPUB_LIBRARIES EPUB_INCLUDE_DIR)
endif (EPUB_INCLUDE_DIR AND EPUB_LIBRARIES)
mark_as_advanced(EPUB_INCLUDE_DIR EPUB_LIBRARIES)

View file

@ -0,0 +1,221 @@
/***************************************************************************
* Copyright (C) 2008 by Ely Levy <elylevy@cs.huji.ac.il> *
* *
* 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. *
***************************************************************************/
#include "converter.h"
#include <QtGui/QAbstractTextDocumentLayout>
#include <QtGui/QTextDocument>
#include <QtGui/QTextFrame>
#include <QTextDocumentFragment>
#include <QtCore/QDebug>
#include <klocale.h>
#include <okular/core/action.h>
using namespace Epub;
Converter::Converter() : mTextDocument(NULL)
{
}
Converter::~Converter()
{
}
// join the char * array into one QString
QString _strPack(char **str, int size)
{
QString res;
res = QString::fromUtf8(str[0]);
for (int i=1;i<size;i++) {
res += ", ";
res += QString::fromUtf8(str[i]);
}
return res;
}
// emit data wrap function that map between epub metadata to okular's
void Converter::_emitData(Okular::DocumentInfo::Key key,
enum epub_metadata type)
{
int size;
unsigned char **data;
data = epub_get_metadata(mTextDocument->getEpub(), type, &size);
if (data) {
emit addMetaData(key, _strPack((char **)data, size));
for (int i=0;i<size;i++)
free(data[i]);
free(data);
}
}
// Got over the blocks from start and add them to hashes use name as the
// prefix for local links
void Converter::_handle_anchors(const QTextBlock &start, const QString &name) {
for (QTextBlock bit = start; bit != mTextDocument->end(); bit = bit.next()) {
for (QTextBlock::iterator fit = bit.begin(); !(fit.atEnd()); ++fit) {
QTextFragment frag = fit.fragment();
if (frag.isValid() && frag.charFormat().isAnchor()) {
QUrl href(frag.charFormat().anchorHref());
if (href.isValid() && ! href.isEmpty())
if (href.isRelative()) { // Inside document link
mLocalLinks.insert(href.toString(),
QPair<int, int>(frag.position(),
frag.position()+frag.length()));
} else { // Outside document link
Okular::BrowseAction *action =
new Okular::BrowseAction(href.toString());
emit addAction(action, frag.position(),
frag.position() + frag.length());
}
const QStringList &names = frag.charFormat().anchorNames();
if (!names.empty()) {
for (QStringList::const_iterator lit = names.constBegin();
lit != names.constEnd(); ++lit) {
mSectionMap.insert(name + "#" + *lit, bit);
}
}
} // end anchor case
}
}
}
QTextDocument* Converter::convert( const QString &fileName )
{
EpubDocument *newDocument = new EpubDocument(fileName);
if (!newDocument->isValid()) {
emit error(i18n("Error while opening the EPub document."), -1);
delete newDocument;
return NULL;
}
mTextDocument = newDocument;
mTextDocument->setPageSize(QSizeF(600, 800));
QTextCursor *_cursor = new QTextCursor( mTextDocument );
QTextFrameFormat frameFormat;
frameFormat.setMargin( 20 );
QTextFrame *rootFrame = mTextDocument->rootFrame();
rootFrame->setFrameFormat( frameFormat );
mLocalLinks.clear();
mSectionMap.clear();
// Emit the document meta data
_emitData(Okular::DocumentInfo::Title, EPUB_TITLE);
_emitData(Okular::DocumentInfo::Author, EPUB_CREATOR);
_emitData(Okular::DocumentInfo::Subject, EPUB_SUBJECT);
_emitData(Okular::DocumentInfo::Creator, EPUB_PUBLISHER);
_emitData(Okular::DocumentInfo::Description, EPUB_DESCRIPTION);
_emitData(Okular::DocumentInfo::CreationDate, EPUB_DATE);
_emitData(Okular::DocumentInfo::Category, EPUB_TYPE);
_emitData(Okular::DocumentInfo::Copyright, EPUB_RIGHTS);
emit addMetaData( Okular::DocumentInfo::MimeType, "application/epub+zip");
struct eiterator *it;
// iterate over the book
it = epub_get_iterator(mTextDocument->getEpub(), EITERATOR_SPINE, 0);
do {
if (epub_it_get_curr(it)) {
// insert block for links
_cursor->insertBlock();
QString link(epub_it_get_curr_url(it));
// Pass on all the anchor since last block
const QTextBlock &before = _cursor->block();
mSectionMap.insert(link, before);
_cursor->insertHtml(epub_it_get_curr(it));
// Add anchors to hashes
_handle_anchors(before, link);
// Start new file in a new page
int page = mTextDocument->pageCount();
while(mTextDocument->pageCount() == page)
_cursor->insertText("\n");
}
} while (epub_it_get_next(it));
epub_free_iterator(it);
// adding link actions
QHashIterator<QString, QPair<int, int> > hit(mLocalLinks);
while (hit.hasNext()) {
hit.next();
const QTextBlock &block = mSectionMap[hit.key()];
if (block.isValid()) { // be sure we actually got a block
Okular::DocumentViewport viewport =
calculateViewport(mTextDocument, block);
Okular::GotoAction *action = new Okular::GotoAction(QString(), viewport);
emit addAction(action, hit.value().first, hit.value().second);
} else {
qDebug() << "Error: no block found for "<< hit.key() << "\n";
}
}
struct titerator *tit;
tit = epub_get_titerator(mTextDocument->getEpub(), TITERATOR_NAVMAP, 0);
if (! tit)
tit = epub_get_titerator(mTextDocument->getEpub(), TITERATOR_GUIDE, 0);
if (tit) {
do {
if (epub_tit_curr_valid(tit)) {
char *link = epub_tit_get_curr_link(tit);
const QTextBlock &block = mSectionMap[link];
if (link)
free(link);
if (block.isValid()) { // be sure we actually got a block
char *label = epub_tit_get_curr_label(tit);
emit addTitle(epub_tit_get_curr_depth(tit),
label,
block);
if (label)
free(label);
} else {
qDebug() << "Error: no block found for "<< hit.key() << "\n";
}
}
} while (epub_tit_next(tit));
epub_free_titerator(tit);
}
delete _cursor;
return mTextDocument;
}

View file

@ -0,0 +1,40 @@
/***************************************************************************
* Copyright (C) 2008 by Ely Levy <elylevy@cs.huji.ac.il> *
* *
* 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 EPUB_CONVERTER_H
#define EPUB_CONVERTER_H
#include <okular/core/textdocumentgenerator.h>
#include <okular/core/document.h>
#include "epubdocument.h"
class QTextCursor;
namespace Epub {
class Converter : public Okular::TextDocumentConverter
{
public:
Converter();
~Converter();
virtual QTextDocument *convert( const QString &fileName );
private:
void _emitData(Okular::DocumentInfo::Key key, enum epub_metadata type);
void _handle_anchors(const QTextBlock &start, const QString &name);
EpubDocument *mTextDocument;
QHash<QString, QTextBlock> mSectionMap;
QHash<QString, QPair<int, int> > mLocalLinks;
};
}
#endif

View file

@ -0,0 +1,67 @@
/***************************************************************************
* Copyright (C) 2008 by Ely Levy <elylevy@cs.huji.ac.il> *
* *
* 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. *
***************************************************************************/
#include "epubdocument.h"
using namespace Epub;
EpubDocument::EpubDocument(const QString &fileName) : QTextDocument()
{
mEpub = epub_open(qPrintable(fileName), 3);
}
bool EpubDocument::isValid()
{
return (mEpub?true:false);
}
EpubDocument::~EpubDocument() {
if (mEpub)
epub_close(mEpub);
epub_cleanup();
}
struct epub *EpubDocument::getEpub()
{
return mEpub;
}
QVariant EpubDocument::loadResource(int type, const QUrl &name)
{
int size;
char *data;
// Get the data from the epub file
size = epub_get_data(mEpub, qPrintable(name.toString()), &data);
QVariant resource;
if (size > 0) {
switch(type) {
case QTextDocument::ImageResource:
resource.setValue(QImage::fromData((unsigned char *)data, size));
break;
default:
resource.setValue(QString(data));
break;
}
free(data);
}
// add to cache
addResource(type, name, resource);
return resource;
}

View file

@ -0,0 +1,37 @@
/***************************************************************************
* Copyright (C) 2008 by Ely Levy <elylevy@cs.huji.ac.il> *
* *
* 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 EPUB_DOCUMENT_H
#define EPUB_DOCUMENT_H
#include <QTextDocument>
#include <QUrl>
#include <QVariant>
#include <QImage>
#include <epub.h>
namespace Epub {
class EpubDocument : public QTextDocument {
public:
EpubDocument(const QString &fileName);
bool isValid();
~EpubDocument();
struct epub *getEpub();
protected:
virtual QVariant loadResource(int type, const QUrl &name);
private:
struct epub *mEpub;
};
}
#endif

View file

@ -0,0 +1,37 @@
/***************************************************************************
* Copyright (C) 2008 by Ely Levy <elylevy@cs.huji.ac.il> *
* *
* 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. *
***************************************************************************/
#include "generator_epub.h"
#include "converter.h"
#include <kaboutdata.h>
static KAboutData createAboutData()
{
KAboutData aboutData(
"okular_epub",
"okular_epub",
ki18n("EPUB Backend"),
"0.1",
ki18n("A EPUB backend"),
KAboutData::License_GPL,
ki18n("© 2008 Ely Levy")
);
aboutData.addAuthor(ki18n("Ely Levy"), KLocalizedString(),
"elylevy@cs.huji.ac.il");
return aboutData;
}
OKULAR_EXPORT_PLUGIN( EPubGenerator, createAboutData() )
EPubGenerator::EPubGenerator( QObject *parent, const QVariantList &args )
: Okular::TextDocumentGenerator( new Epub::Converter, parent, args )
{
}

View file

@ -0,0 +1,20 @@
/***************************************************************************
* Copyright (C) 2008 by Ely Levy <elylevy@cs.huji.ac.il> *
* *
* 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_GENERATOR_EPUB_H_
#define _OKULAR_GENERATOR_EPUB_H_
#include <okular/core/textdocumentgenerator.h>
class EPubGenerator : public Okular::TextDocumentGenerator
{
public:
EPubGenerator( QObject *parent, const QVariantList &args );
~EPubGenerator() {}
};
#endif

View file

@ -0,0 +1,14 @@
[Desktop Entry]
Type=Service
Name=EPub document
Name[et]=EPubi dokument
Name[sv]=Epub-dokument
Comment=Epub backend for Okular
Comment[et]=Okulari Epubi taustaprogramm
Comment[sv]=Epub-gränssnitt för Okular
X-KDE-ServiceTypes=okular/Generator
MimeType=application/epub+zip;
X-KDE-Library=okularGenerator_epub
X-KDE-Priority=1
X-KDE-okularAPIVersion=1
X-KDE-okularHasInternalSettings=false

View file

@ -0,0 +1,13 @@
[Desktop Entry]
MimeType=application/epub+zip;
Terminal=false
Name=Okular
GenericName=Document Viewer
GenericName[et]=Dokumentide näitaja
GenericName[sv]=Dokumentvisning
Exec=okular %U %i -caption "%c"
Icon=graphics-viewer-document
Type=Application
InitialPreference=1
Categories=Qt;KDE;Graphics;Viewer;
NoDisplay=true

View file

@ -0,0 +1,7 @@
[Desktop Entry]
Icon=graphics-viewer-document
Name=Okular
X-KDE-ServiceTypes=KParts/ReadOnlyPart
X-KDE-Library=okularpart
Type=Service
MimeType=application/epub+zip;