Commit 85239031 authored by Henrique Pinto's avatar Henrique Pinto
Browse files

* Add extraction support to the KArchive plugin. Preview now works for tar and zip archives.

svn path=/branches/work/libarchive-based-ark/ark/; revision=690254
parent f545bde1
......@@ -5,7 +5,7 @@ add_subdirectory( app )
add_subdirectory( pics )
add_subdirectory( plugins )
add_subdirectory( kerfuffle )
add_subdirectory( old )
#add_subdirectory( old )
......
......@@ -57,11 +57,16 @@ Arch::~Arch()
{
}
void Arch::extractFile( const QVariant & fileName, const QString & destinationDir )
void Arch::extractFile( const QVariant & fileName, const QString & destinationDir, bool preservePaths )
{
QList<QVariant> l;
l << fileName;
extractFiles( l, destinationDir );
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,
......@@ -71,6 +76,8 @@ Arch *Arch::factory( const QString & filename,
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();
......
......@@ -77,8 +77,8 @@ class KERFUFFLE_EXPORT Arch : public QObject
virtual void addFile( const QStringList & ) = 0;
virtual void addDir( const QString & ) = 0;
virtual void extractFile( const QVariant & fileName, const QString & destinationDir );
virtual void extractFiles( const QList<QVariant> & fileList, const QString & destinationDir ) = 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; }
......
......@@ -86,9 +86,9 @@ void ArchiveBase::remove( const QStringList & )
{
}
void ArchiveBase::extractFiles( const QList<QVariant> & files, const QString& destinationDir )
void ArchiveBase::extractFiles( const QList<QVariant> & files, const QString& destinationDir, bool preservePaths )
{
ExtractionJob *job = new ExtractionJob( m_iface, files, destinationDir, this );
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& ) ),
......
......@@ -53,7 +53,7 @@ class KERFUFFLE_EXPORT ArchiveBase: public Arch
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 );
virtual void extractFiles( const QList<QVariant> & files, const QString& destinationDir, bool preservePaths );
private slots:
void listingDone( ThreadWeaver::Job* );
......
......@@ -50,7 +50,7 @@ class KERFUFFLE_EXPORT ReadOnlyArchiveInterface: public QObject
virtual bool open() { return true; }
virtual bool list() = 0;
virtual bool copyFiles( const QList<QVariant> & files, const QString & destinationDirectory ) = 0;
virtual bool copyFiles( const QList<QVariant> & files, const QString & destinationDirectory, bool preservePaths ) = 0;
protected:
void error( const QString & message, const QString & details = QString() );
......
......@@ -50,9 +50,9 @@ void ListingJob::run()
m_success = m_helper->getTheListing();
}
ExtractionJob::ExtractionJob( ReadOnlyArchiveInterface *archive, const QList<QVariant> & files, const QString & destinationDirectory, QObject *parent )
ExtractionJob::ExtractionJob( ReadOnlyArchiveInterface *archive, const QList<QVariant> & files, const QString & destinationDirectory, bool preservePaths, QObject *parent )
: ThreadWeaver::Job( parent ), m_archive( archive ), m_files( files ), m_destinationDirectory( destinationDirectory ),
m_helper( 0 ), m_success( false )
m_helper( 0 ), m_success( false ), m_preservePaths( preservePaths )
{
}
......@@ -71,7 +71,7 @@ void ExtractionJob::run()
connect( m_helper, SIGNAL( error( const QString&, const QString& ) ),
this, SIGNAL( error( const QString&, const QString& ) ) );
m_archive->registerObserver( m_helper );
m_success = m_archive->copyFiles( m_files, m_destinationDirectory );
m_success = m_archive->copyFiles( m_files, m_destinationDirectory, m_preservePaths );
m_archive->removeObserver( m_helper );
}
......
......@@ -62,7 +62,7 @@ class ExtractionJob: public ThreadWeaver::Job
{
Q_OBJECT
public:
ExtractionJob( ReadOnlyArchiveInterface *archive, const QList<QVariant> & files, const QString & destinationDirectory, QObject *parent = 0 );
ExtractionJob( ReadOnlyArchiveInterface *archive, const QList<QVariant> & files, const QString & destinationDirectory, bool preservePaths = false, QObject *parent = 0 );
~ExtractionJob();
bool success() const { return m_success; }
......@@ -80,6 +80,7 @@ class ExtractionJob: public ThreadWeaver::Job
QString m_destinationDirectory;
ArchiveJobHelper *m_helper;
bool m_success;
bool m_preservePaths;
};
#endif // JOBS_H
......@@ -367,13 +367,13 @@ void ArchiveModel::setArchive( Arch *archive )
reset();
}
void ArchiveModel::extractFile( const QVariant& fileName, const QString & destinationDir )
void ArchiveModel::extractFile( const QVariant& fileName, const QString & destinationDir, bool preservePaths )
{
if ( !m_archive )
{
emit extractionFinished( false );
return;
}
m_archive->extractFile( fileName, destinationDir );
m_archive->extractFile( fileName, destinationDir, preservePaths );
}
void extractFile( const QVariant& fileName, const QString & destinationDir );
......@@ -49,7 +49,7 @@ class ArchiveModel: public QAbstractItemModel
ArchiveEntry entryForIndex( const QModelIndex &index );
void extractFile( const QVariant& fileName, const QString & destinationDir );
void extractFile( const QVariant& fileName, const QString & destinationDir, bool preservePaths = false );
signals:
void loadingStarted();
......
......@@ -163,7 +163,7 @@ void Part::slotPreview( const QModelIndex & index )
m_previewDir = new KTempDir();
connect( m_model, SIGNAL( extractionFinished( bool ) ),
this, SLOT( slotPreviewExtracted( bool ) ) );
m_model->extractFile( entry[ FileName ], m_previewDir->name() );
m_model->extractFile( entry[ FileName ], m_previewDir->name(), false );
}
}
......@@ -175,7 +175,8 @@ void Part::slotPreviewExtracted( bool success )
{
ArkViewer viewer( widget() );
const ArchiveEntry& entry = m_model->entryForIndex( m_view->selectionModel()->currentIndex() );
if ( !viewer.view( m_previewDir->name() + '/' + entry[ FileName ].toString() ) )
QString name = entry[ FileName ].toString().split( '/', QString::SkipEmptyParts ).last();
if ( !viewer.view( m_previewDir->name() + '/' + name ) )
{
KMessageBox::sorry( widget(), i18n( "The internal viewer cannot preview this file." ) );
}
......
......@@ -61,7 +61,7 @@ bool BKInterface::list()
return result;
}
bool BKInterface::copyFiles( const QList<QVariant> & files, const QString & destinationDirectory )
bool BKInterface::copyFiles( const QList<QVariant> & files, const QString & destinationDirectory, bool preservePaths )
{
error( "Not implemented yet" );
return false;
......
......@@ -35,7 +35,7 @@ class BKInterface: public ReadOnlyArchiveInterface
~BKInterface();
bool list();
bool copyFiles( const QList<QVariant> & files, const QString & destinationDirectory );
bool copyFiles( const QList<QVariant> & files, const QString & destinationDirectory, bool preservePaths );
private:
bool browse( BkFileBase* base, const QString& prefix = QString() );
......
......@@ -21,36 +21,80 @@
#include "karchiveplugin.h"
#include "kerfuffle/archivefactory.h"
#include <KZip>
#include <memory>
#include <KTar>
#include <KMimeType>
KArchiveInterface::KArchiveInterface( const QString & filename, QObject *parent )
: ReadOnlyArchiveInterface( filename, parent )
: ReadOnlyArchiveInterface( filename, parent ), m_archive( 0 )
{
}
KArchiveInterface::~KArchiveInterface()
{
delete m_archive;
m_archive = 0;
}
bool KArchiveInterface::list()
KArchive *KArchiveInterface::archive()
{
std::auto_ptr<KArchive> archive( new KZip( filename() ) );
if ( m_archive == 0 )
{
KMimeType::Ptr mimeType = KMimeType::findByPath( filename() );
if ( mimeType->is( "application/zip" ) )
{
m_archive = new KZip( filename() );
}
else
{
m_archive = new KTar( filename() );
}
if ( !archive->open( QIODevice::ReadOnly ) )
}
return m_archive;
}
bool KArchiveInterface::list()
{
if ( !archive()->open( QIODevice::ReadOnly ) )
{
error( QString( "Couldn't open the archive '%1' for reading" ).arg( filename() ) );
return false;
}
else
{
return browseArchive( archive.get() );
return browseArchive( archive() );
}
}
bool KArchiveInterface::copyFiles( const QList<QVariant> & files, const QString & destinationDirectory )
bool KArchiveInterface::copyFiles( const QList<QVariant> & files, const QString & destinationDirectory, bool preservePaths )
{
error( "Not implemented yet" );
return false;
if ( preservePaths )
{
error( "Extraction preserving paths is not implemented yet." );
return false;
}
foreach( const QVariant & file, files )
{
const KArchiveEntry *archiveEntry = archive()->directory()->entry( file.toString() );
if ( !archiveEntry )
{
error( QString( "File '%1' not found in the archive" ).arg( file.toString() ) );
return false;
}
// TODO: handle errors, copyTo fails silently
if ( archiveEntry->isDirectory() )
{
static_cast<const KArchiveDirectory*>( archiveEntry )->copyTo( destinationDirectory );
}
else
{
static_cast<const KArchiveFile*>( archiveEntry )->copyTo( destinationDirectory );
}
}
return true;
}
bool KArchiveInterface::browseArchive( KArchive *archive )
......
......@@ -34,7 +34,7 @@ class KArchiveInterface: public ReadOnlyArchiveInterface
~KArchiveInterface();
bool list();
bool copyFiles( const QList<QVariant> & files, const QString & destinationDirectory );
bool copyFiles( const QList<QVariant> & files, const QString & destinationDirectory, bool preservePaths );
private:
bool browseArchive( KArchive *archive );
......@@ -42,6 +42,10 @@ class KArchiveInterface: public ReadOnlyArchiveInterface
bool processDir( const KArchiveDirectory *dir, const QString & prefix = QString() );
void createEntryFor( const KArchiveEntry *aentry, const QString& prefix );
KArchive *archive();
KArchive *m_archive;
};
#endif // KARCHIVEPLUGIN_H
......@@ -13,4 +13,4 @@ X-KDE-Priority=117
X-KDE-Kerfuffle-APIRevision=1
Name=kerfuffle_karchive
Comment=KArchive plugin for Kerfuffle
MimeType=application/zip;application/x-zip-compressed;
MimeType=application/zip;application/x-zip-compressed;application/x-tar;application/x-compressed-tar;
......@@ -96,8 +96,14 @@ bool LibArchiveInterface::list()
return archive_read_finish( arch ) == ARCHIVE_OK;
}
bool LibArchiveInterface::copyFiles( const QList<QVariant> & files, const QString & destinationDirectory )
bool LibArchiveInterface::copyFiles( const QList<QVariant> & files, const QString & destinationDirectory, bool preservePaths )
{
if ( !preservePaths )
{
error( "Extraction discarding paths is not supported yet." );
return false;
}
QDir::setCurrent( destinationDirectory );
const bool extractAll = files.isEmpty();
......
......@@ -41,7 +41,7 @@ class LibArchiveInterface: public ReadOnlyArchiveInterface
~LibArchiveInterface();
bool list();
bool copyFiles( const QList<QVariant> & files, const QString & destinationDirectory );
bool copyFiles( const QList<QVariant> & files, const QString & destinationDirectory, bool preservePaths );
private:
int extractionFlags() const;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment