okular/generators/comicbook/document.cpp
Martin T. H. Sandsmark 2b473fedbd generators: Fix build without implicit cast to/from ascii
See previous commit for details.
2016-07-11 21:59:14 +02:00

233 lines
6.4 KiB
C++

/***************************************************************************
* 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 "document.h"
#include <QtCore/QScopedPointer>
#include <QtGui/QImage>
#include <QtGui/QImageReader>
#include <KLocalizedString>
#include <QMimeType>
#include <QMimeDatabase>
#include <kzip.h>
#include <ktar.h>
#include <memory>
#include <core/page.h>
#include "debug_comicbook.h"
#include "directory.h"
#include "qnatsort.h"
#include "unrar.h"
using namespace ComicBook;
static void imagesInArchive( const QString &prefix, const KArchiveDirectory* dir, QStringList *entries )
{
Q_FOREACH ( const QString &entry, dir->entries() ) {
const KArchiveEntry *e = dir->entry( entry );
if ( e->isDirectory() ) {
imagesInArchive( prefix + entry + QLatin1Char('/'), static_cast<const KArchiveDirectory*>( e ), entries );
} else if ( e->isFile() ) {
entries->append( prefix + entry );
}
}
}
Document::Document()
: mDirectory( 0 ), mUnrar( 0 ), mArchive( 0 )
{
}
Document::~Document()
{
}
bool Document::open( const QString &fileName )
{
close();
QMimeDatabase db;
const QMimeType mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchContent);
/**
* We have a zip archive
*/
if ( mime.inherits(QStringLiteral("application/x-cbz") ) || mime.inherits( QStringLiteral("application/zip") ) ) {
mArchive = new KZip( fileName );
if ( !processArchive() ) {
return false;
}
/**
* We have a TAR archive
*/
} else if ( mime.inherits( QStringLiteral("application/x-cbt") ) || mime.inherits( QStringLiteral("application/x-gzip") ) ||
mime.inherits( QStringLiteral("application/x-tar") ) || mime.inherits( QStringLiteral("application/x-bzip") ) ) {
mArchive = new KTar( fileName );
if ( !processArchive() ) {
return false;
}
} else if ( mime.inherits( QStringLiteral("application/x-cbr") ) || mime.inherits( QStringLiteral("application/x-rar") ) ) {
if ( !Unrar::isAvailable() ) {
mLastErrorString = i18n( "Cannot open document, unrar was not found." );
return false;
}
if ( !Unrar::isSuitableVersionAvailable() ) {
mLastErrorString = i18n( "The version of unrar on your system is not suitable for opening comicbooks." );
return false;
}
/**
* We have a rar archive
*/
mUnrar = new Unrar();
if ( !mUnrar->open( fileName ) ) {
delete mUnrar;
mUnrar = 0;
return false;
}
mEntries = mUnrar->list();
} else if ( mime.inherits( QStringLiteral("inode/directory") ) ) {
mDirectory = new Directory();
if ( !mDirectory->open( fileName ) ) {
delete mDirectory;
mDirectory = 0;
return false;
}
mEntries = mDirectory->list();
} else {
mLastErrorString = i18n( "Unknown ComicBook format." );
return false;
}
return true;
}
void Document::close()
{
mLastErrorString.clear();
if ( !( mArchive || mUnrar || mDirectory ) )
return;
delete mArchive;
mArchive = 0;
delete mDirectory;
mDirectory = 0;
delete mUnrar;
mUnrar = 0;
mPageMap.clear();
mEntries.clear();
}
bool Document::processArchive() {
if ( !mArchive->open( QIODevice::ReadOnly ) ) {
delete mArchive;
mArchive = 0;
return false;
}
const KArchiveDirectory *directory = mArchive->directory();
if ( !directory ) {
delete mArchive;
mArchive = 0;
return false;
}
mArchiveDir = const_cast<KArchiveDirectory*>( directory );
imagesInArchive( QString(), mArchiveDir, &mEntries );
return true;
}
void Document::pages( QVector<Okular::Page*> * pagesVector )
{
qSort( mEntries.begin(), mEntries.end(), caseSensitiveNaturalOrderLessThen );
QScopedPointer< QIODevice > dev;
int count = 0;
pagesVector->clear();
pagesVector->resize( mEntries.size() );
QImageReader reader;
foreach(const QString &file, mEntries) {
if ( mArchive ) {
const KArchiveFile *entry = static_cast<const KArchiveFile*>( mArchiveDir->entry( file ) );
if ( entry ) {
dev.reset( entry->createDevice() );
}
} else if ( mDirectory ) {
dev.reset( mDirectory->createDevice( file ) );
} else {
dev.reset( mUnrar->createDevice( file ) );
}
if ( ! dev.isNull() ) {
reader.setDevice( dev.data() );
if ( reader.canRead() )
{
QSize pageSize = reader.size();
if ( !pageSize.isValid() ) {
const QImage i = reader.read();
if ( !i.isNull() )
pageSize = i.size();
}
if ( pageSize.isValid() ) {
pagesVector->replace( count, new Okular::Page( count, pageSize.width(), pageSize.height(), Okular::Rotation0 ) );
mPageMap.append(file);
count++;
} else {
qCDebug(OkularComicbookDebug) << "Ignoring" << file << "doesn't seem to be an image even if QImageReader::canRead returned true";
}
}
}
}
pagesVector->resize( count );
}
QStringList Document::pageTitles() const
{
return QStringList();
}
QImage Document::pageImage( int page ) const
{
if ( mArchive ) {
const KArchiveFile *entry = static_cast<const KArchiveFile*>( mArchiveDir->entry( mPageMap[ page ] ) );
if ( entry )
return QImage::fromData( entry->data() );
} else if ( mDirectory ) {
return QImage( mPageMap[ page ] );
} else {
return QImage::fromData( mUnrar->contentOf( mPageMap[ page ] ) );
}
return QImage();
}
QString Document::lastErrorString() const
{
return mLastErrorString;
}