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=624702remotes/origin/KDE/4.0
parent
169b752433
commit
deabbae3bf
12 changed files with 547 additions and 0 deletions
@ -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 ) |
||||
@ -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(); |
||||
} |
||||
@ -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 |
||||
@ -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" |
||||
|
||||
@ -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 |
||||
@ -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 |
||||
@ -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; |
||||
@ -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" |
||||
@ -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 |
||||
|
||||
@ -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 |
||||
@ -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 new issue