/************************************************************************** ** ** This file is part of Qt SDK** ** ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).* ** ** Contact: Nokia Corporation qt-info@nokia.com** ** ** GNU Lesser General Public License Usage ** ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this file. ** Please review the following information to ensure the GNU Lesser General ** Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception version ** 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you are unsure which license is appropriate for your use, please contact ** (qt-info@nokia.com). ** **************************************************************************/ #ifndef EXTRACTARCHIVEOPERATION_P_H #define EXTRACTARCHIVEOPERATION_P_H #include "extractarchiveoperation.h" #include "lib7z_facade.h" #include "qinstaller.h" #include #include #include #include #include #include namespace QInstaller { class WorkerThread : public QThread { Q_OBJECT public: WorkerThread( ExtractArchiveOperation *op, const QStringList &files, QObject* parent = NULL ); void run(); Q_SIGNALS: void outputTextChanged( const QString& filename ); void progressChanged( int progress ); private: QStringList m_files; ExtractArchiveOperation* m_op; }; class ExtractArchiveOperation::Callback : public QObject, public Lib7z::ExtractCallback { Q_OBJECT public: int lastProgress; HRESULT state; bool createBackups; QVector > backupFiles; explicit Callback() : lastProgress( -1 ), state( S_OK ), createBackups( true ) { } Q_SIGNALS: void progressChanged( const QString& filename ); void progressChanged( int ); public Q_SLOTS: void statusChanged( QInstaller::Installer::Status status ) { switch( status ) { case Installer::Canceled: state = E_ABORT; break; case Installer::Failure: state = E_FAIL; break; case Installer::Unfinished: // fall through case Installer::Success: case Installer::Running: //state = S_OK; break; } } protected: /* reimp */ void setCurrentFile( const QString& filename ) { emit progressChanged( QDir::toNativeSeparators( filename ) ); } static QString generateBackupName( const QString& fn ) { const QString bfn = fn + QLatin1String(".tmpUpdate" ); QString res = bfn; int i = 0; while ( QFile::exists( res ) ) res = bfn + QString::fromLatin1(".%1").arg( i++ ); return res; } /* reimp */ bool prepareForFile( const QString& filename ) { if ( !createBackups ) return true; if ( !QFile::exists( filename ) ) return true; const QString backup = generateBackupName( filename ); QFile f( filename ); const bool renamed = f.rename( backup ); if ( f.exists() && !renamed ) { qCritical("Could not rename %s to %s: %s", qPrintable(filename), qPrintable(backup), qPrintable(f.errorString()) ); return false; } backupFiles.push_back( qMakePair( filename, backup ) ); return true; } /* reimp */ HRESULT setCompleted( quint64 completed, quint64 total ) { assert( total != 0 ); const int progress = ( 100 * completed ) / total; if( progress != lastProgress ) emit progressChanged( progress ); lastProgress = progress; return state; } }; class ExtractArchiveOperation::Runnable : public QObject, public QRunnable { Q_OBJECT public: Runnable( const QString& archivePath_, const QString& targetDir_, ExtractArchiveOperation::Callback* callback_ ) : QObject(), QRunnable(), archivePath( archivePath_ ), targetDir( targetDir_ ), callback( callback_ ) { } /* reimp */ void run() { QFile archive( archivePath ); if ( !archive.open( QIODevice::ReadOnly ) ) { emit finished( false, tr("Could not open %1 for reading: %2.").arg( archivePath, archive.errorString() ) ); return; } try { Lib7z::extractArchive( &archive, targetDir, callback ); emit finished( true, QString() ); } catch ( const Lib7z::SevenZipException& e ) { #ifdef Q_WS_WIN emit finished( false, tr("Error while extracting %1: %2. (Maybe the target dir(%3) is blocked by another process.)").arg( archivePath, e.message(), targetDir ) ); #else emit finished( false, tr("Error while extracting %1: %2.").arg( archivePath, e.message() ) ); #endif } catch ( ... ) { emit finished( false, tr("Unknown exception caught while extracting %1.").arg( archivePath ) ); } } Q_SIGNALS: void finished( bool success, const QString& errorString ); private: const QString archivePath; const QString targetDir; ExtractArchiveOperation::Callback* const callback; }; class ExtractArchiveOperation::Receiver : public QObject { Q_OBJECT public: explicit Receiver( QObject* parent=0 ) : QObject( parent ), success( false ) {} public Q_SLOTS: void runnableFinished( bool ok, const QString& msg ) { success = ok; errorString = msg; emit finished(); } Q_SIGNALS: void finished(); public: bool success; QString errorString; }; } #endif // EXTRACTARCHIVEOPERATION_P_H