mirror of
https://invent.kde.org/graphics/okular
synced 2024-10-12 10:53:09 +00:00
Say hello to the new ComicBook generator for okular.
Information about this format and testfiles can be found at http://en.wikipedia.org/wiki/CDisplay_RAR_Archived_Comic_Book_File svn path=/trunk/playground/graphics/okular/; revision=624702
This commit is contained in:
parent
169b752433
commit
deabbae3bf
|
@ -29,3 +29,5 @@ add_subdirectory(xps)
|
|||
add_subdirectory(ooo)
|
||||
|
||||
add_subdirectory(fictionbook)
|
||||
|
||||
add_subdirectory(comicbook)
|
||||
|
|
26
generators/comicbook/CMakeLists.txt
Normal file
26
generators/comicbook/CMakeLists.txt
Normal file
|
@ -0,0 +1,26 @@
|
|||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/okular
|
||||
)
|
||||
|
||||
|
||||
########### next target ###############
|
||||
|
||||
set( okularGenerator_comicbook_PART_SRCS
|
||||
document.cpp
|
||||
generator_comicbook.cpp
|
||||
unrar.cpp
|
||||
)
|
||||
|
||||
kde4_automoc(${okularGenerator_comicbook_PART_SRCS})
|
||||
|
||||
kde4_add_plugin(okularGenerator_comicbook WITH_PREFIX ${okularGenerator_comicbook_PART_SRCS})
|
||||
|
||||
target_link_libraries(okularGenerator_comicbook okularcore ${KDE4_KDEUI_LIBS} )
|
||||
|
||||
install(TARGETS okularGenerator_comicbook DESTINATION ${PLUGIN_INSTALL_DIR})
|
||||
|
||||
|
||||
########### install files ###############
|
||||
|
||||
install( FILES libokularGenerator_comicbook.desktop okularComicbook.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
|
||||
install( FILES x-cbz.desktop x-cbr.desktop DESTINATION ${MIME_INSTALL_DIR}/application )
|
127
generators/comicbook/document.cpp
Normal file
127
generators/comicbook/document.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Tobias Koenig <tokoe@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. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QtGui/QImage>
|
||||
|
||||
#include <kzip.h>
|
||||
|
||||
#include "document.h"
|
||||
#include "unrar.h"
|
||||
|
||||
using namespace ComicBook;
|
||||
|
||||
Document::Document()
|
||||
: mUnrar( 0 ), mZip( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
Document::~Document()
|
||||
{
|
||||
delete mUnrar;
|
||||
delete mZip;
|
||||
}
|
||||
|
||||
bool Document::open( const QString &fileName )
|
||||
{
|
||||
delete mZip;
|
||||
delete mUnrar;
|
||||
|
||||
/**
|
||||
* We have a zip archive
|
||||
*/
|
||||
if ( fileName.toLower().endsWith( ".cbz" ) ) {
|
||||
mZip = new KZip( fileName );
|
||||
|
||||
if ( !mZip->open( QIODevice::ReadOnly ) ) {
|
||||
delete mZip;
|
||||
mZip = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const KArchiveDirectory *directory = mZip->directory();
|
||||
if ( !directory ) {
|
||||
delete mZip;
|
||||
mZip = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
mZipDir = const_cast<KArchiveDirectory*>( directory );
|
||||
QStringList entries = directory->entries();
|
||||
if ( entries.count() == 1 ) {
|
||||
// seems to be a nested directory
|
||||
const KArchiveEntry *entry = directory->entry( entries[ 0 ] );
|
||||
if ( entry->isDirectory() ) {
|
||||
entries = static_cast<const KArchiveDirectory*>( entry )->entries();
|
||||
mZipDir = const_cast<KArchiveDirectory*>( static_cast<const KArchiveDirectory*>( entry ) );
|
||||
}
|
||||
}
|
||||
|
||||
extractImageFiles( entries );
|
||||
|
||||
} else {
|
||||
/**
|
||||
* We have a rar archive
|
||||
*/
|
||||
mUnrar = new Unrar();
|
||||
|
||||
if ( !mUnrar->open( fileName ) ) {
|
||||
delete mUnrar;
|
||||
mUnrar = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
extractImageFiles( mUnrar->list() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Document::extractImageFiles( const QStringList &list )
|
||||
{
|
||||
QStringList files( list );
|
||||
|
||||
qSort( files );
|
||||
|
||||
for ( int i = 0; i < files.count(); ++i ) {
|
||||
const QString lowerFile = files[ i ].toLower();
|
||||
|
||||
if ( lowerFile.endsWith( ".gif" ) ||
|
||||
lowerFile.endsWith( ".jpg" ) ||
|
||||
lowerFile.endsWith( ".jpeg" ) ||
|
||||
lowerFile.endsWith( ".png" ) )
|
||||
mPageMap.append( files[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
int Document::pages() const
|
||||
{
|
||||
return mPageMap.count();
|
||||
}
|
||||
|
||||
QStringList Document::pageTitles() const
|
||||
{
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QImage Document::pageImage( int page ) const
|
||||
{
|
||||
if ( mZip ) {
|
||||
const KArchiveFile *entry = static_cast<const KArchiveFile*>( mZipDir->entry( mPageMap[ page ] ) );
|
||||
if ( entry )
|
||||
return QImage::fromData( entry->data() );
|
||||
|
||||
} else {
|
||||
return QImage::fromData( mUnrar->contentOf( mPageMap[ page ] ) );
|
||||
}
|
||||
|
||||
return QImage();
|
||||
}
|
46
generators/comicbook/document.h
Normal file
46
generators/comicbook/document.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Tobias Koenig <tokoe@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 COMICBOOK_DOCUMENT_H
|
||||
#define COMICBOOK_DOCUMENT_H
|
||||
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
class KArchiveDirectory;
|
||||
class KZip;
|
||||
class QImage;
|
||||
class Unrar;
|
||||
|
||||
namespace ComicBook {
|
||||
|
||||
class Document
|
||||
{
|
||||
public:
|
||||
Document();
|
||||
~Document();
|
||||
|
||||
bool open( const QString &fileName );
|
||||
|
||||
int pages() const;
|
||||
QStringList pageTitles() const;
|
||||
|
||||
QImage pageImage( int page ) const;
|
||||
|
||||
private:
|
||||
void extractImageFiles( const QStringList& );
|
||||
|
||||
QStringList mPageMap;
|
||||
Unrar *mUnrar;
|
||||
KZip *mZip;
|
||||
KArchiveDirectory *mZipDir;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
89
generators/comicbook/generator_comicbook.cpp
Normal file
89
generators/comicbook/generator_comicbook.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Tobias Koenig <tokoe@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. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <qpainter.h>
|
||||
#include <kprinter.h>
|
||||
|
||||
#include <okular/core/page.h>
|
||||
|
||||
#include "generator_comicbook.h"
|
||||
|
||||
OKULAR_EXPORT_PLUGIN(ComicBookGenerator)
|
||||
|
||||
ComicBookGenerator::ComicBookGenerator()
|
||||
: Generator()
|
||||
{
|
||||
}
|
||||
|
||||
ComicBookGenerator::~ComicBookGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
bool ComicBookGenerator::loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector )
|
||||
{
|
||||
if ( !mDocument.open( fileName ) )
|
||||
return false;
|
||||
|
||||
int pages = mDocument.pages();
|
||||
pagesVector.resize( pages );
|
||||
|
||||
for ( int i = 0; i < pages; ++i ) {
|
||||
Okular::Page * page = new Okular::Page( i, 800, 600, Okular::Rotation0 );
|
||||
pagesVector[i] = page;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ComicBookGenerator::closeDocument()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ComicBookGenerator::canGeneratePixmap( bool ) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void ComicBookGenerator::generatePixmap( Okular::PixmapRequest * request )
|
||||
{
|
||||
int width = request->width();
|
||||
int height = request->height();
|
||||
|
||||
QImage image = mDocument.pageImage( request->pageNumber() );
|
||||
image = image.scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
|
||||
request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( image ) ) );
|
||||
|
||||
// signal that the request has been accomplished
|
||||
signalRequestDone(request);
|
||||
}
|
||||
|
||||
bool ComicBookGenerator::print( KPrinter& printer )
|
||||
{
|
||||
QPainter p( &printer );
|
||||
|
||||
for ( int i = 0; i < mDocument.pages(); ++i ) {
|
||||
const QImage image = mDocument.pageImage( i );
|
||||
|
||||
if ( i != 0 )
|
||||
printer.newPage();
|
||||
|
||||
p.drawImage( 0, 0, image );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ComicBookGenerator::hasFeature( GeneratorFeature ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#include "generator_comicbook.moc"
|
||||
|
42
generators/comicbook/generator_comicbook.h
Normal file
42
generators/comicbook/generator_comicbook.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Tobias Koenig <tokoe@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 GENERATOR_COMICBOOK_H
|
||||
#define GENERATOR_COMICBOOK_H
|
||||
|
||||
#include <okular/core/generator.h>
|
||||
|
||||
#include "document.h"
|
||||
|
||||
class ComicBookGenerator : public Okular::Generator
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ComicBookGenerator();
|
||||
virtual ~ComicBookGenerator();
|
||||
|
||||
// [INHERITED] load a document and fill up the pagesVector
|
||||
bool loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector );
|
||||
bool closeDocument();
|
||||
|
||||
// [INHERITED] perform actions on document / pages
|
||||
bool canGeneratePixmap( bool async ) const;
|
||||
void generatePixmap( Okular::PixmapRequest * request );
|
||||
|
||||
// [INHERITED] print document using already configured kprinter
|
||||
bool print( KPrinter& printer );
|
||||
|
||||
bool hasFeature( GeneratorFeature feature ) const;
|
||||
|
||||
private:
|
||||
ComicBook::Document mDocument;
|
||||
};
|
||||
|
||||
#endif
|
11
generators/comicbook/libokularGenerator_comicbook.desktop
Normal file
11
generators/comicbook/libokularGenerator_comicbook.desktop
Normal file
|
@ -0,0 +1,11 @@
|
|||
[Desktop Entry]
|
||||
Encoding=UTF-8
|
||||
Type=Service
|
||||
Name=Comic Book
|
||||
Comment=Comic book backend for okular
|
||||
ServiceTypes=okular/Generator
|
||||
MimeType=application/x-cbz;application/x-cbr;
|
||||
X-KDE-Library=libokularGenerator_comicbook
|
||||
X-KDE-Priority=1
|
||||
X-KDE-okularAPIVersion=1
|
||||
X-KDE-okularHasInternalSettings=false
|
8
generators/comicbook/okularComicbook.desktop
Normal file
8
generators/comicbook/okularComicbook.desktop
Normal file
|
@ -0,0 +1,8 @@
|
|||
[Desktop Entry]
|
||||
Encoding=UTF-8
|
||||
Icon=okular
|
||||
Name=okular
|
||||
ServiceTypes=KParts/ReadOnlyPart
|
||||
X-KDE-Library=libokularpart
|
||||
Type=Service
|
||||
MimeType=application/x-cbz;application/x-cbr;
|
113
generators/comicbook/unrar.cpp
Normal file
113
generators/comicbook/unrar.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Tobias Koenig <tokoe@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. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QProcess>
|
||||
|
||||
#include <ktempdir.h>
|
||||
|
||||
#include "unrar.h"
|
||||
|
||||
Unrar::Unrar()
|
||||
: QObject( 0 ), mTempDir( 0 ), mErrorOccured( false )
|
||||
{
|
||||
}
|
||||
|
||||
Unrar::~Unrar()
|
||||
{
|
||||
delete mTempDir;
|
||||
}
|
||||
|
||||
bool Unrar::open( const QString &fileName )
|
||||
{
|
||||
delete mTempDir;
|
||||
mTempDir = new KTempDir();
|
||||
|
||||
mFileName = fileName;
|
||||
|
||||
/**
|
||||
* Extract the archive to a temporary directory
|
||||
*/
|
||||
mStdOutData.clear();
|
||||
mStdErrData.clear();
|
||||
|
||||
mProcess = new QProcess( this );
|
||||
|
||||
connect( mProcess, SIGNAL( readyReadStandardOutput() ), SLOT( readFromStdout() ) );
|
||||
connect( mProcess, SIGNAL( readyReadStandardError() ), SLOT( readFromStderr() ) );
|
||||
connect( mProcess, SIGNAL( finished( int, QProcess::ExitStatus ) ), SLOT( processExited() ) );
|
||||
connect( mProcess, SIGNAL( error( QProcess::ProcessError ) ), SLOT( processExited() ) );
|
||||
|
||||
mProcess->start( "unrar", QStringList() << "e" << mFileName << mTempDir->name(), QIODevice::ReadOnly );
|
||||
|
||||
mEventLoop.exec();
|
||||
|
||||
delete mProcess;
|
||||
mProcess = 0;
|
||||
|
||||
if ( mErrorOccured ) {
|
||||
mErrorOccured = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList Unrar::list()
|
||||
{
|
||||
mStdOutData.clear();
|
||||
mStdErrData.clear();
|
||||
|
||||
mProcess = new QProcess( this );
|
||||
|
||||
connect( mProcess, SIGNAL( readyReadStandardOutput() ), SLOT( readFromStdout() ) );
|
||||
connect( mProcess, SIGNAL( readyReadStandardError() ), SLOT( readFromStderr() ) );
|
||||
connect( mProcess, SIGNAL( finished( int, QProcess::ExitStatus ) ), SLOT( processExited() ) );
|
||||
connect( mProcess, SIGNAL( error( QProcess::ProcessError ) ), SLOT( processError() ) );
|
||||
|
||||
mProcess->start( "unrar", QStringList() << "lb" << mFileName, QIODevice::ReadOnly );
|
||||
|
||||
mEventLoop.exec();
|
||||
|
||||
delete mProcess;
|
||||
mProcess = 0;
|
||||
|
||||
return QString::fromLocal8Bit( mStdOutData ).split( "\n", QString::SkipEmptyParts );
|
||||
}
|
||||
|
||||
QByteArray Unrar::contentOf( const QString &fileName ) const
|
||||
{
|
||||
QFile file( mTempDir->name() + fileName );
|
||||
if ( !file.open( QIODevice::ReadOnly ) )
|
||||
return QByteArray();
|
||||
|
||||
return file.readAll();
|
||||
}
|
||||
|
||||
void Unrar::readFromStdout()
|
||||
{
|
||||
mStdOutData += mProcess->readAllStandardOutput();
|
||||
}
|
||||
|
||||
void Unrar::readFromStderr()
|
||||
{
|
||||
mStdErrData += mProcess->readAllStandardError();
|
||||
}
|
||||
|
||||
void Unrar::processExited()
|
||||
{
|
||||
mEventLoop.exit();
|
||||
}
|
||||
|
||||
void Unrar::processError()
|
||||
{
|
||||
mErrorOccured = true;
|
||||
}
|
||||
|
||||
#include "unrar.moc"
|
67
generators/comicbook/unrar.h
Normal file
67
generators/comicbook/unrar.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Tobias Koenig <tokoe@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 UNRAR_H
|
||||
#define UNRAR_H
|
||||
|
||||
#include <QtCore/QEventLoop>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
class QProcess;
|
||||
class KTempDir;
|
||||
|
||||
class Unrar : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new unrar object.
|
||||
*/
|
||||
Unrar();
|
||||
|
||||
/**
|
||||
* Destroys the unrar object.
|
||||
*/
|
||||
~Unrar();
|
||||
|
||||
/**
|
||||
* Opens given rar archive.
|
||||
*/
|
||||
bool open( const QString &fileName );
|
||||
|
||||
/**
|
||||
* Returns the list of files from the archive.
|
||||
*/
|
||||
QStringList list();
|
||||
|
||||
/**
|
||||
* Returns the content of the file with the given name.
|
||||
*/
|
||||
QByteArray contentOf( const QString &fileName ) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void processExited();
|
||||
void processError();
|
||||
void readFromStdout();
|
||||
void readFromStderr();
|
||||
|
||||
private:
|
||||
QProcess *mProcess;
|
||||
QEventLoop mEventLoop;
|
||||
QString mFileName;
|
||||
QByteArray mStdOutData;
|
||||
QByteArray mStdErrData;
|
||||
KTempDir *mTempDir;
|
||||
bool mErrorOccured;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
8
generators/comicbook/x-cbr.desktop
Normal file
8
generators/comicbook/x-cbr.desktop
Normal file
|
@ -0,0 +1,8 @@
|
|||
[Desktop Entry]
|
||||
Type=MimeType
|
||||
Encoding=UTF-8
|
||||
MimeType=application/x-cbr
|
||||
Icon=package_toys
|
||||
Patterns=*.cbr;*.CBR;
|
||||
Comment=Comic Book
|
||||
Comment[x-test]=xxComic Bookxx
|
8
generators/comicbook/x-cbz.desktop
Normal file
8
generators/comicbook/x-cbz.desktop
Normal file
|
@ -0,0 +1,8 @@
|
|||
[Desktop Entry]
|
||||
Type=MimeType
|
||||
Encoding=UTF-8
|
||||
MimeType=application/x-cbz
|
||||
Icon=package_toys
|
||||
Patterns=*.cbz;*.CBZ;
|
||||
Comment=Comic Book
|
||||
Comment[x-test]=xxComic Bookxx
|
Loading…
Reference in a new issue