Commit 13980c23 authored by Henrique Pinto's avatar Henrique Pinto
Browse files

* Start a rework of libkerfuffle to use KJob

svn path=/branches/work/libarchive-based-ark/ark/; revision=690340
parent 8c93c516
......@@ -5,9 +5,11 @@ ADD_DEFINITIONS(-D_LARGEFILE64_SOURCE)
########### next target ###############
set(kerfuffle_SRCS
arch.cpp
#arch.cpp
archive.cpp
archiveinterface.cpp
internaljobs.cpp
jobs.cpp
archivebase.cpp
)
......
/*
ark -- archiver for the KDE project
Copyright (C) 2002 Helio Chissini de Castro <helio@conectiva.com.br>
Copyright (C) 2001 Corel Corporation (author: Michael Jarrett <michaelj@corel.com>)
Copyright (C) 1999-2000 Corel Corporation (author: Emily Ezust <emilye@corel.com>)
Copyright (C) 1999 Francois-Xavier Duranceau <duranceau@kde.org>
Copyright (C) 1997-1999 Rob Palmbos <palm9744@kettering.edu>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
// ark includes
#include "arch.h"
#include "archivebase.h"
#include "archivefactory.h"
// C includes
#include <cstdlib>
// QT includes
#include <QApplication>
#include <QFile>
#include <QByteArray>
// KDE includes
#include <KDebug>
#include <KMessageBox>
#include <KMimeType>
#include <KMimeTypeTrader>
#include <KServiceTypeTrader>
#include <KLocale>
#include <KPasswordDialog>
#include <KStandardDirs>
#include <KLibLoader>
Arch::Arch( const QString &filename )
: QObject( 0 ), m_filename( filename ), m_readOnly( false )
{
}
Arch::~Arch()
{
}
void Arch::extractFile( const QVariant & fileName, const QString & destinationDir, bool preservePaths )
{
QList<QVariant> l;
l << fileName;
extractFiles( l, destinationDir, preservePaths );
}
static bool comparePlugins( const KService::Ptr &p1, const KService::Ptr &p2 )
{
return ( p1->property( "X-KDE-Priority" ).toInt() ) > ( p2->property( "X-KDE-Priority" ).toInt() );
}
Arch *Arch::factory( const QString & filename,
const QString & requestedMimeType )
{
qRegisterMetaType<ArchiveEntry>( "ArchiveEntry" );
QString mimeType = requestedMimeType.isEmpty()? KMimeType::findByPath( filename )->name() : requestedMimeType;
KService::List offers = KMimeTypeTrader::self()->query( mimeType, "Kerfuffle/Plugin", "(exist Library)" );
qSort( offers.begin(), offers.end(), comparePlugins );
if ( !offers.isEmpty() )
{
QString libraryName = offers[ 0 ]->library();
kDebug( 1601 ) << k_funcinfo << "Loading library " << libraryName << " for handling mimetype " << mimeType << endl;
KLibrary *lib = KLibLoader::self()->library( QFile::encodeName( libraryName ), QLibrary::ExportExternalSymbolsHint );
if ( lib )
{
ArchiveFactory *( *pluginFactory )() = ( ArchiveFactory *( * )() )lib->resolveFunction( "pluginFactory" );
if ( pluginFactory )
{
ArchiveFactory *factory = pluginFactory(); // TODO: cache these
Arch *arch = factory->createArchive( filename, 0 );
delete factory;
return arch;
}
}
}
kDebug( 1601 ) << k_funcinfo << "Couldn't find a library for mimetype " << mimeType << endl;
return 0;
}
QStringList Arch::supportedMimeTypes()
{
QStringList supported;
KService::List offers = KServiceTypeTrader::self()->query( "Kerfuffle/Plugin", "(exist Library)" );
kDebug( 1601 ) << k_funcinfo << "returned " << offers.count() << " offers" << endl;
foreach( KService::Ptr service, offers )
{
kDebug( 1601 ) << k_funcinfo << " Service " << service->name() << " has service types " << service->serviceTypes() << endl;
foreach( const QString& mimeType, service->serviceTypes() )
{
if ( !mimeType.contains( "Kerfuffle" ) )
{
supported << mimeType;
}
}
}
return supported;
}
#include "arch.moc"
/*
ark -- archiver for the KDE project
Copyright (C) 1997-1999 Rob Palmbos <palm9744@kettering.edu>
Copyright (C) 1999 Francois-Xavier Duranceau <duranceau@kde.org>
Copyright (C) 1999-2000 Corel Corporation (author: Emily Ezust <emilye@corel.com>)
Copyright (C) 2001 Corel Corporation (author: Michael Jarrett <michaelj@corel.com>)
Copyright (C) 2007 Henrique Pinto <henrique.pinto@kdemail.net>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef ARCH_H
#define ARCH_H
#include <QObject>
#include <QList>
#include <QStringList>
#include <QPair>
#include <QRegExp>
#include <QHash>
#include <QVariant>
#include <KUrl>
#include "kerfuffle_export.h"
class QStringList;
enum ArchType { UNKNOWN_FORMAT, ZIP_FORMAT, TAR_FORMAT, AA_FORMAT,
LHA_FORMAT, RAR_FORMAT, ZOO_FORMAT, COMPRESSED_FORMAT,
SEVENZIP_FORMAT, ACE_FORMAT };
enum EntryMetaDataType { FileName = 0, OriginalFileName = 1, Permissions = 2, Owner = 3,
Group = 4, Size = 5, CompressedSize = 6, Link = 7, Ratio = 8,
CRC = 9, Method = 10, Version = 11, Timestamp = 12, IsDirectory = 13, Custom = 1048576 };
typedef QHash<int, QVariant> ArchiveEntry;
/**
* Pure virtual base class for archives - provides a framework as well as
* useful common functionality.
*/
class KERFUFFLE_EXPORT Arch : public QObject
{
Q_OBJECT
protected:
/* Creates an object representing an archive for _fileName */
Arch( const QString & _fileName );
public:
virtual ~Arch();
/* Starts an open() operation.
* This should list all archive entries ( by emmiting newEntry() ) and then emit
* opened() so that the GUI can know that the operation is over.
*/
virtual void open() = 0;
virtual void create() = 0;
virtual void remove( const QStringList & ) = 0;
virtual void addFile( const QStringList & ) = 0;
virtual void addDir( const QString & ) = 0;
virtual void extractFile( const QVariant & fileName, const QString & destinationDir, bool preservePaths = false );
virtual void extractFiles( const QList<QVariant> & fileList, const QString & destinationDir, bool preservePaths = false ) = 0;
virtual bool passwordRequired() { return false; }
QString fileName() const { return m_filename; }
bool isReadOnly() { return m_readOnly; }
static Arch *factory( const QString & filename, const QString & requestedMimeType = QString() );
static QStringList supportedMimeTypes();
signals:
void opened( bool success );
void sigCreate( Arch *, bool, const QString &, int );
void sigDelete( bool );
void sigExtract( bool );
void sigAdd( bool );
void newEntry( const ArchiveEntry& entry );
void error( const QString& error, const QString& details );
protected:
void setReadOnly( bool readOnly ) { m_readOnly = readOnly; }
QString m_filename;
bool m_readOnly; // for readonly archives
};
#endif /* ARCH_H */
/*
* Copyright (c) 2007 Henrique Pinto <henrique.pinto@kdemail.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive.h"
#include "archivefactory.h"
#include <QFile>
#include <KDebug>
#include <KMimeType>
#include <KMimeTypeTrader>
#include <KServiceTypeTrader>
#include <KLibLoader>
static bool comparePlugins( const KService::Ptr &p1, const KService::Ptr &p2 )
{
return ( p1->property( "X-KDE-Priority" ).toInt() ) > ( p2->property( "X-KDE-Priority" ).toInt() );
}
namespace Kerfuffle
{
Archive *factory( const QString & filename, const QString & requestedMimeType )
{
qRegisterMetaType<ArchiveEntry>( "ArchiveEntry" );
QString mimeType = requestedMimeType.isEmpty()? KMimeType::findByPath( filename )->name() : requestedMimeType;
KService::List offers = KMimeTypeTrader::self()->query( mimeType, "Kerfuffle/Plugin", "(exist Library)" );
qSort( offers.begin(), offers.end(), comparePlugins );
if ( !offers.isEmpty() )
{
QString libraryName = offers[ 0 ]->library();
KLibrary *lib = KLibLoader::self()->library( QFile::encodeName( libraryName ), QLibrary::ExportExternalSymbolsHint );
if ( lib )
{
ArchiveFactory *( *pluginFactory )() = ( ArchiveFactory *( * )() )lib->resolveFunction( "pluginFactory" );
if ( pluginFactory )
{
ArchiveFactory *factory = pluginFactory(); // TODO: cache these
Archive *arch = factory->createArchive( filename, 0 );
delete factory;
return arch;
}
}
}
return 0;
}
QStringList supportedMimeTypes()
{
QStringList supported;
KService::List offers = KServiceTypeTrader::self()->query( "Kerfuffle/Plugin", "(exist Library)" );
foreach( KService::Ptr service, offers )
{
foreach( const QString& mimeType, service->serviceTypes() )
{
if ( !mimeType.contains( "Kerfuffle" ) )
{
supported << mimeType;
}
}
}
return supported;
}
} // namespace Kerfuffle
/*
* Copyright (c) 2007 Henrique Pinto <henrique.pinto@kdemail.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KERFUFFLE_ARCHIVE_H
#define KERFUFFLE_ARCHIVE_H
#include "kerfuffle_export.h"
#include <QString>
#include <QStringList>
#include <QHash>
#include <KUrl>
class KJob;
namespace Kerfuffle
{
class ListJob;
class ExtractJob;
enum EntryMetaDataType { FileName = 0, OriginalFileName = 1, Permissions = 2, Owner = 3,
Group = 4, Size = 5, CompressedSize = 6, Link = 7, Ratio = 8,
CRC = 9, Method = 10, Version = 11, Timestamp = 12, IsDirectory = 13, Custom = 1048576 };
typedef QHash<int, QVariant> ArchiveEntry;
class KERFUFFLE_EXPORT Archive
{
public:
virtual ~Archive() {}
virtual KJob* open() = 0;
virtual KJob* create() = 0;
virtual ListJob* list() = 0;
virtual KJob* deleteFiles( const QList<QVariant> & files ) = 0;
virtual KJob* addFiles( const QList<KUrl> & files ) = 0;
virtual ExtractJob* copyFiles( const QList<QVariant> & files, const QString & destinationDir, bool preservePaths = false ) = 0;
};
Archive* factory( const QString & filename, const QString & requestedMimeType = QString() ) KERFUFFLE_EXPORT;
QStringList supportedMimeTypes() KERFUFFLE_EXPORT;
} // namespace Kerfuffle
#endif // KERFUFFLE_ARCHIVE_H
......@@ -37,70 +37,70 @@
#include <QStringList>
#include <QDateTime>
ArchiveBase::ArchiveBase( ReadOnlyArchiveInterface *archive )
: Arch( archive->filename() ), m_iface( archive )
namespace Kerfuffle
{
Q_ASSERT( archive );
archive->setParent( this );
setReadOnly( archive->isReadOnly() );
}
ArchiveBase::~ArchiveBase()
{
delete m_iface;
m_iface = 0;
}
void ArchiveBase::open()
{
ListingJob *job = new ListingJob( m_iface, this );
connect( job, SIGNAL( done( ThreadWeaver::Job* ) ),
this, SLOT( listingDone( ThreadWeaver::Job * ) ) );
connect( job, SIGNAL( entry( const ArchiveEntry & ) ),
this, SIGNAL( newEntry( const ArchiveEntry & ) ) );
connect( job, SIGNAL( error( const QString&, const QString& ) ),
this, SIGNAL( error( const QString&, const QString& ) ) );
ThreadWeaver::Weaver::instance()->enqueue( job );
}
void ArchiveBase::listingDone( ThreadWeaver::Job *job )
{
emit opened( job->success() );
delete job;
}
void ArchiveBase::create()
{
}
void ArchiveBase::addFile( const QStringList & )
{
}
void ArchiveBase::addDir( const QString & )
{
}
void ArchiveBase::remove( const QStringList & )
{
}
void ArchiveBase::extractFiles( const QList<QVariant> & files, const QString& destinationDir, bool preservePaths )
{
ExtractionJob *job = new ExtractionJob( m_iface, files, destinationDir, preservePaths, this );
connect( job, SIGNAL( done( ThreadWeaver::Job* ) ),
this, SLOT( extractionDone( ThreadWeaver::Job * ) ) );
connect( job, SIGNAL( error( const QString&, const QString& ) ),
this, SIGNAL( error( const QString&, const QString& ) ) );
ThreadWeaver::Weaver::instance()->enqueue( job );
}
void ArchiveBase::extractionDone( ThreadWeaver::Job *job )
{
emit sigExtract( job->success() );
delete job;
}
ArchiveBase::ArchiveBase( ReadOnlyArchiveInterface *archive )
: QObject(), Archive(), m_iface( archive )
{
Q_ASSERT( archive );
archive->setParent( this );
//setReadOnly( archive->isReadOnly() );
}
ArchiveBase::~ArchiveBase()
{
delete m_iface;
m_iface = 0;
}
/*
void ArchiveBase::extractFiles( const QList<QVariant> & files, const QString& destinationDir, bool preservePaths )
{
ExtractionJob *job = new ExtractionJob( m_iface, files, destinationDir, preservePaths, this );
connect( job, SIGNAL( done( ThreadWeaver::Job* ) ),
this, SLOT( extractionDone( ThreadWeaver::Job * ) ) );
connect( job, SIGNAL( error( const QString&, const QString& ) ),
this, SIGNAL( error( const QString&, const QString& ) ) );
ThreadWeaver::Weaver::instance()->enqueue( job );
}
void ArchiveBase::extractionDone( ThreadWeaver::Job *job )
{
emit sigExtract( job->success() );
delete job;
}
*/
KJob* ArchiveBase::open()
{
return 0;
}
KJob* ArchiveBase::create()
{
return 0;
}
ListJob* ArchiveBase::list()
{
return new ListJob( m_iface, this );
}
KJob* ArchiveBase::deleteFiles( const QList<QVariant> & files )
{
return 0;
}
KJob* ArchiveBase::addFiles( const QList<KUrl> & files )
{
return 0;
}
ExtractJob* ArchiveBase::copyFiles( const QList<QVariant> & files, const QString & destinationDir, bool preservePaths )
{
return new ExtractJob( files, destinationDir, preservePaths, m_iface, this );
}
} // namespace Kerfuffle
#include "archivebase.moc"
......@@ -26,8 +26,9 @@
#ifndef ARCHIVEBASE_H
#define ARCHIVEBASE_H
#include "arch.h"
#include "archive.h"
#include "archiveinterface.h"
#include "jobs.h"
#include "kerfuffle_export.h"
namespace ThreadWeaver
......@@ -35,32 +36,30 @@ namespace ThreadWeaver
class Job;
} // namespace ThreadWeaver
class KERFUFFLE_EXPORT ArchiveBase: public Arch
namespace Kerfuffle
{
Q_OBJECT
public:
/*
* Creates an Arch to operate on the given interface.
* This takes ownership of the interface, which is deleted
* on the destructor.
*/
ArchiveBase( ReadOnlyArchiveInterface *archive );
virtual ~ArchiveBase();
class KERFUFFLE_EXPORT ArchiveBase: public QObject, public Archive
{
Q_OBJECT
public:
/*
* Creates an Arch to operate on the given interface.
* This takes ownership of the interface, which is deleted
* on the destructor.
*/
ArchiveBase( ReadOnlyArchiveInterface *archive );
virtual ~ArchiveBase();
virtual void open();
virtual void create();
virtual KJob* open();
virtual KJob* create();
virtual ListJob* list();
virtual KJob* deleteFiles( const QList<QVariant> & files );
virtual KJob* addFiles( const QList<KUrl> & files );
virtual ExtractJob* copyFiles( const QList<QVariant> & files, const QString & destinationDir, bool preservePaths = false );
virtual void addFile( const QStringList & );
virtual void addDir( const QString & );
virtual void remove( const QStringList & );
virtual void extractFiles( const QList<QVariant> & files, const QString& destinationDir, bool preservePaths );
private slots:
void listingDone( ThreadWeaver::Job* );
void extractionDone( ThreadWeaver::Job* );
private:
ReadOnlyArchiveInterface *m_iface;
};
private:
ReadOnlyArchiveInterface *m_iface;
};
} // namespace Kerfuffle
#endif // ARCHIVEBASE_H
......@@ -22,30 +22,33 @@
#define ARCHIVEFACTORY_H
#include "kerfuffle_export.h"
#include "arch.h"
#include "archive.h"
#include "archivebase.h"
#include <QString>
#include <QObject>
class ArchiveFactory
namespace Kerfuffle
{