From b5b43f86d146742951cc5e745d94c1ff1bf2e456 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 26 Sep 2013 17:39:33 -0700 Subject: [PATCH] begin to remove fervor + quazip --- interface/CMakeLists.txt | 4 - interface/external/fervor/CMakeLists.txt | 35 - .../external/fervor/fvavailableupdate.cpp | 97 -- interface/external/fervor/fvavailableupdate.h | 51 - .../external/fervor/fvignoredversions.cpp | 74 -- interface/external/fervor/fvignoredversions.h | 19 - interface/external/fervor/fvplatform.cpp | 210 ---- interface/external/fervor/fvplatform.h | 18 - .../fervor/fvupdatedownloadprogress.cpp | 26 - .../fervor/fvupdatedownloadprogress.h | 23 - .../fervor/fvupdatedownloadprogress.ui | 94 -- interface/external/fervor/fvupdater.cpp | 908 ------------------ interface/external/fervor/fvupdater.h | 183 ---- interface/external/fervor/fvupdatewindow.cpp | 66 -- interface/external/fervor/fvupdatewindow.h | 37 - interface/external/fervor/fvupdatewindow.ui | 129 --- .../external/fervor/fvversioncomparator.cpp | 164 ---- .../external/fervor/fvversioncomparator.h | 36 - .../external/quazip/include/JlCompress.h | 114 --- interface/external/quazip/include/crypt.h | 135 --- interface/external/quazip/include/ioapi.h | 77 -- .../external/quazip/include/quaadler32.h | 29 - .../external/quazip/include/quachecksum32.h | 54 -- interface/external/quazip/include/quacrc32.h | 26 - .../external/quazip/include/quagzipfile.h | 84 -- .../external/quazip/include/quaziodevice.h | 74 -- interface/external/quazip/include/quazip.h | 419 -------- .../external/quazip/include/quazip_global.h | 55 -- interface/external/quazip/include/quazipdir.h | 171 ---- .../external/quazip/include/quazipfile.h | 442 --------- .../external/quazip/include/quazipfileinfo.h | 73 -- .../external/quazip/include/quazipnewinfo.h | 121 --- interface/external/quazip/include/unzip.h | 356 ------- interface/external/quazip/include/zip.h | 245 ----- .../external/quazip/lib/MacOS/libquazip.a | Bin 224800 -> 0 bytes 35 files changed, 4649 deletions(-) delete mode 100644 interface/external/fervor/CMakeLists.txt delete mode 100755 interface/external/fervor/fvavailableupdate.cpp delete mode 100755 interface/external/fervor/fvavailableupdate.h delete mode 100755 interface/external/fervor/fvignoredversions.cpp delete mode 100755 interface/external/fervor/fvignoredversions.h delete mode 100755 interface/external/fervor/fvplatform.cpp delete mode 100755 interface/external/fervor/fvplatform.h delete mode 100755 interface/external/fervor/fvupdatedownloadprogress.cpp delete mode 100755 interface/external/fervor/fvupdatedownloadprogress.h delete mode 100755 interface/external/fervor/fvupdatedownloadprogress.ui delete mode 100755 interface/external/fervor/fvupdater.cpp delete mode 100755 interface/external/fervor/fvupdater.h delete mode 100755 interface/external/fervor/fvupdatewindow.cpp delete mode 100755 interface/external/fervor/fvupdatewindow.h delete mode 100755 interface/external/fervor/fvupdatewindow.ui delete mode 100755 interface/external/fervor/fvversioncomparator.cpp delete mode 100755 interface/external/fervor/fvversioncomparator.h delete mode 100644 interface/external/quazip/include/JlCompress.h delete mode 100644 interface/external/quazip/include/crypt.h delete mode 100644 interface/external/quazip/include/ioapi.h delete mode 100644 interface/external/quazip/include/quaadler32.h delete mode 100644 interface/external/quazip/include/quachecksum32.h delete mode 100644 interface/external/quazip/include/quacrc32.h delete mode 100644 interface/external/quazip/include/quagzipfile.h delete mode 100644 interface/external/quazip/include/quaziodevice.h delete mode 100644 interface/external/quazip/include/quazip.h delete mode 100644 interface/external/quazip/include/quazip_global.h delete mode 100644 interface/external/quazip/include/quazipdir.h delete mode 100644 interface/external/quazip/include/quazipfile.h delete mode 100644 interface/external/quazip/include/quazipfileinfo.h delete mode 100644 interface/external/quazip/include/quazipnewinfo.h delete mode 100644 interface/external/quazip/include/unzip.h delete mode 100644 interface/external/quazip/include/zip.h delete mode 100644 interface/external/quazip/lib/MacOS/libquazip.a diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 08ae5816a5..f1f3aa2d3d 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -76,10 +76,6 @@ if (APPLE) endforeach() endif (APPLE) -set(QUAZIP_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/quazip) -add_subdirectory(external/fervor/) -include_directories(external/fervor/) - # create the executable, make it a bundle on OS X add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS}) diff --git a/interface/external/fervor/CMakeLists.txt b/interface/external/fervor/CMakeLists.txt deleted file mode 100644 index 9c11f0fb7a..0000000000 --- a/interface/external/fervor/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -cmake_minimum_required(VERSION 2.8) -project(Fervor) - -find_package(Qt5Core REQUIRED) -find_package(Qt5Network REQUIRED) -find_package(Qt5Widgets REQUIRED) -find_package(Qt5WebKitWidgets REQUIRED) - -add_definitions(-DFV_GUI) - -file(GLOB FERVOR_SOURCES *.cpp) -file(GLOB FERVOR_HEADERS *.h) - -file(GLOB FERVOR_UI *.ui) - -qt5_wrap_ui(FERVOR_WRAPPED_UI ${FERVOR_UI}) - -LIST(GET FERVOR_HEADERS 1 FIRST_HEADER) -GET_FILENAME_COMPONENT(HEADER_PATH ${FIRST_HEADER} PATH) -list(REMOVE_ITEM FERVOR_HEADERS ${HEADER_PATH}/fvversioncomparator.h) - -file(GLOB FERVOR_UI *.ui) - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") -find_package(Quazip REQUIRED) - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${QUAZIP_INCLUDE_DIRS} -) - -add_library(fervor ${FERVOR_SOURCES} ${FERVOR_HEADERS} ${FERVOR_MOC_SOURCES} ${FERVOR_WRAPPED_UI}) -target_link_libraries(fervor ${QUAZIP_LIBRARIES}) - -qt5_use_modules(fervor Core Network Widgets WebKitWidgets) \ No newline at end of file diff --git a/interface/external/fervor/fvavailableupdate.cpp b/interface/external/fervor/fvavailableupdate.cpp deleted file mode 100755 index f0f6cb91cd..0000000000 --- a/interface/external/fervor/fvavailableupdate.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "fvavailableupdate.h" - -FvAvailableUpdate::FvAvailableUpdate(QObject *parent) : - QObject(parent) -{ - // noop -} - -QString FvAvailableUpdate::GetTitle() -{ - return m_title; -} - -void FvAvailableUpdate::SetTitle(QString title) -{ - m_title = title; -} - -QUrl FvAvailableUpdate::GetReleaseNotesLink() -{ - return m_releaseNotesLink; -} - -void FvAvailableUpdate::SetReleaseNotesLink(QUrl releaseNotesLink) -{ - m_releaseNotesLink = releaseNotesLink; -} - -void FvAvailableUpdate::SetReleaseNotesLink(QString releaseNotesLink) -{ - SetReleaseNotesLink(QUrl(releaseNotesLink)); -} - -QString FvAvailableUpdate::GetPubDate() -{ - return m_pubDate; -} - -void FvAvailableUpdate::SetPubDate(QString pubDate) -{ - m_pubDate = pubDate; -} - -QUrl FvAvailableUpdate::GetEnclosureUrl() -{ - return m_enclosureUrl; -} - -void FvAvailableUpdate::SetEnclosureUrl(QUrl enclosureUrl) -{ - m_enclosureUrl = enclosureUrl; -} - -void FvAvailableUpdate::SetEnclosureUrl(QString enclosureUrl) -{ - SetEnclosureUrl(QUrl(enclosureUrl)); -} - -QString FvAvailableUpdate::GetEnclosureVersion() -{ - return m_enclosureVersion; -} - -void FvAvailableUpdate::SetEnclosureVersion(QString enclosureVersion) -{ - m_enclosureVersion = enclosureVersion; -} - -QString FvAvailableUpdate::GetEnclosurePlatform() -{ - return m_enclosurePlatform; -} - -void FvAvailableUpdate::SetEnclosurePlatform(QString enclosurePlatform) -{ - m_enclosurePlatform = enclosurePlatform; -} - -unsigned long FvAvailableUpdate::GetEnclosureLength() -{ - return m_enclosureLength; -} - -void FvAvailableUpdate::SetEnclosureLength(unsigned long enclosureLength) -{ - m_enclosureLength = enclosureLength; -} - -QString FvAvailableUpdate::GetEnclosureType() -{ - return m_enclosureType; -} - -void FvAvailableUpdate::SetEnclosureType(QString enclosureType) -{ - m_enclosureType = enclosureType; -} diff --git a/interface/external/fervor/fvavailableupdate.h b/interface/external/fervor/fvavailableupdate.h deleted file mode 100755 index 6bf3cf9c97..0000000000 --- a/interface/external/fervor/fvavailableupdate.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef FVAVAILABLEUPDATE_H -#define FVAVAILABLEUPDATE_H - -#include -#include - -class FvAvailableUpdate : public QObject -{ - Q_OBJECT -public: - explicit FvAvailableUpdate(QObject *parent = 0); - - QString GetTitle(); - void SetTitle(QString title); - - QUrl GetReleaseNotesLink(); - void SetReleaseNotesLink(QUrl releaseNotesLink); - void SetReleaseNotesLink(QString releaseNotesLink); - - QString GetPubDate(); - void SetPubDate(QString pubDate); - - QUrl GetEnclosureUrl(); - void SetEnclosureUrl(QUrl enclosureUrl); - void SetEnclosureUrl(QString enclosureUrl); - - QString GetEnclosureVersion(); - void SetEnclosureVersion(QString enclosureVersion); - - QString GetEnclosurePlatform(); - void SetEnclosurePlatform(QString enclosurePlatform); - - unsigned long GetEnclosureLength(); - void SetEnclosureLength(unsigned long enclosureLength); - - QString GetEnclosureType(); - void SetEnclosureType(QString enclosureType); - -private: - QString m_title; - QUrl m_releaseNotesLink; - QString m_pubDate; - QUrl m_enclosureUrl; - QString m_enclosureVersion; - QString m_enclosurePlatform; - unsigned long m_enclosureLength; - QString m_enclosureType; - -}; - -#endif // FVAVAILABLEUPDATE_H diff --git a/interface/external/fervor/fvignoredversions.cpp b/interface/external/fervor/fvignoredversions.cpp deleted file mode 100755 index c665f9cff7..0000000000 --- a/interface/external/fervor/fvignoredversions.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "fvignoredversions.h" -#include "fvversioncomparator.h" -#include -#include -#include - -// QSettings key for the latest skipped version -#define FV_IGNORED_VERSIONS_LATEST_SKIPPED_VERSION_KEY "FVLatestSkippedVersion" - - -FVIgnoredVersions::FVIgnoredVersions(QObject *parent) : -QObject(parent) -{ - // noop -} - -bool FVIgnoredVersions::VersionIsIgnored(QString version) -{ - // We assume that variable 'version' contains either: - // 1) The current version of the application (ignore) - // 2) The version that was skipped before and thus stored in QSettings (ignore) - // 3) A newer version (don't ignore) - // 'version' is not likely to contain an older version in any case. - - if (version == QCoreApplication::applicationVersion()) { - return true; - } - - QSettings settings(QSettings::NativeFormat, - QSettings::UserScope, - QCoreApplication::organizationDomain(), - QCoreApplication::applicationName()); - - //QSettings settings; - if (settings.contains(FV_IGNORED_VERSIONS_LATEST_SKIPPED_VERSION_KEY)) { - QString lastSkippedVersion = settings.value(FV_IGNORED_VERSIONS_LATEST_SKIPPED_VERSION_KEY).toString(); - if (version == lastSkippedVersion) { - // Implicitly skipped version - skip - return true; - } - } - - std::string currentAppVersion = QCoreApplication::applicationVersion().toStdString(); - std::string suggestedVersion = std::string(version.toStdString()); - if (FvVersionComparator::CompareVersions(currentAppVersion, suggestedVersion) == FvVersionComparator::kAscending) { - // Newer version - do not skip - return false; - } - - // Fallback - skip - return true; -} - -void FVIgnoredVersions::IgnoreVersion(QString version) -{ - if (version == QCoreApplication::applicationVersion()) { - // Don't ignore the current version - return; - } - - if (version.isEmpty()) { - return; - } - - QSettings settings(QSettings::NativeFormat, - QSettings::UserScope, - QCoreApplication::organizationDomain(), - QCoreApplication::applicationName()); - - - settings.setValue(FV_IGNORED_VERSIONS_LATEST_SKIPPED_VERSION_KEY, version); - - return; -} \ No newline at end of file diff --git a/interface/external/fervor/fvignoredversions.h b/interface/external/fervor/fvignoredversions.h deleted file mode 100755 index 4e85f1b565..0000000000 --- a/interface/external/fervor/fvignoredversions.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef FVIGNOREDVERSIONS_H -#define FVIGNOREDVERSIONS_H - -#include - -class FVIgnoredVersions : public QObject -{ - Q_OBJECT - -public: - static bool VersionIsIgnored(QString version); - static void IgnoreVersion(QString version); - -private: - explicit FVIgnoredVersions(QObject *parent = 0); - -}; - -#endif // FVIGNOREDVERSIONS_H diff --git a/interface/external/fervor/fvplatform.cpp b/interface/external/fervor/fvplatform.cpp deleted file mode 100755 index 1a90ab1dca..0000000000 --- a/interface/external/fervor/fvplatform.cpp +++ /dev/null @@ -1,210 +0,0 @@ -#include "fvplatform.h" -#include -#include - -FvPlatform::FvPlatform(QObject *parent) : - QObject(parent) -{ - // noop -} - -bool FvPlatform::CurrentlyRunningOnPlatform(QString platform) -{ - platform = platform.toUpper().trimmed(); - if (platform.isEmpty()) { - return false; - } - - // Defined on AIX. -#ifdef Q_OS_AIX - if (platform == "Q_OS_AIX") { - return true; - } -#endif - - // Q_OS_BSD4 ("Defined on Any BSD 4.4 system") intentionally skipped. - - // Defined on BSD/OS. -#ifdef Q_OS_BSDI - if (platform == "Q_OS_BSDI") { - return true; - } -#endif - - // Defined on Cygwin. -#ifdef Q_OS_CYGWIN - if (platform == "Q_OS_CYGWIN") { - return true; - } -#endif - - // Q_OS_DARWIN ("Defined on Darwin OS (synonym for Q_OS_MAC)") intentionally skipped. - - // Defined on DG/UX. -#ifdef Q_OS_DGUX - if (platform == "Q_OS_DGUX") { - return true; - } -#endif - - // Defined on DYNIX/ptx. -#ifdef Q_OS_DYNIX - if (platform == "Q_OS_DYNIX") { - return true; - } -#endif - - // Defined on FreeBSD. -#ifdef Q_OS_FREEBSD - if (platform == "Q_OS_FREEBSD") { - return true; - } -#endif - - // Defined on HP-UX. -#ifdef Q_OS_HPUX - if (platform == "Q_OS_HPUX") { - return true; - } -#endif - - // Defined on GNU Hurd. -#ifdef Q_OS_HURD - if (platform == "Q_OS_HURD") { - return true; - } -#endif - - // Defined on SGI Irix. -#ifdef Q_OS_IRIX - if (platform == "Q_OS_IRIX") { - return true; - } -#endif - - // Defined on Linux. -#ifdef Q_OS_LINUX - if (platform == "Q_OS_LINUX") { - return true; - } -#endif - - // Defined on LynxOS. -#ifdef Q_OS_LYNX - if (platform == "Q_OS_LYNX") { - return true; - } -#endif - - // Defined on MAC OS (synonym for Darwin). -#ifdef Q_OS_MAC - if (platform == "Q_OS_MAC") { - return true; - } -#endif - - // Q_OS_MSDOS ("Defined on MS-DOS and Windows") intentionally skipped. - - // Defined on NetBSD. -#ifdef Q_OS_NETBSD - if (platform == "Q_OS_NETBSD") { - return true; - } -#endif - - // Defined on OS/2. -#ifdef Q_OS_OS2 - if (platform == "Q_OS_OS2") { - return true; - } -#endif - - // Defined on OpenBSD. -#ifdef Q_OS_OPENBSD - if (platform == "Q_OS_OPENBSD") { - return true; - } -#endif - - // Defined on XFree86 on OS/2 (not PM). -#ifdef Q_OS_OS2EMX - if (platform == "Q_OS_OS2EMX") { - return true; - } -#endif - - // Defined on HP Tru64 UNIX. -#ifdef Q_OS_OSF - if (platform == "Q_OS_OSF") { - return true; - } -#endif - - // Defined on QNX Neutrino. -#ifdef Q_OS_QNX - if (platform == "Q_OS_QNX") { - return true; - } -#endif - - // Defined on Reliant UNIX. -#ifdef Q_OS_RELIANT - if (platform == "Q_OS_RELIANT") { - return true; - } -#endif - - // Defined on SCO OpenServer 5. -#ifdef Q_OS_SCO - if (platform == "Q_OS_SCO") { - return true; - } -#endif - - // Defined on Sun Solaris. -#ifdef Q_OS_SOLARIS - if (platform == "Q_OS_SOLARIS") { - return true; - } -#endif - - // Defined on Symbian. -#ifdef Q_OS_SYMBIAN - if (platform == "Q_OS_SYMBIAN") { - return true; - } -#endif - - // Defined on DEC Ultrix. -#ifdef Q_OS_ULTRIX - if (platform == "Q_OS_ULTRIX") { - return true; - } -#endif - - // Q_OS_UNIX ("Defined on Any UNIX BSD/SYSV system") intentionally skipped. - - // Defined on UnixWare 7, Open UNIX 8. -#ifdef Q_OS_UNIXWARE - if (platform == "Q_OS_UNIXWARE") { - return true; - } -#endif - - // Defined on Windows CE (note: goes before Q_OS_WIN32) -#ifdef Q_OS_WINCE - if (platform == "Q_OS_WINCE") { - return true; - } -#endif - - // Defined on all supported versions of Windows. -#ifdef Q_OS_WIN32 - if (platform == "Q_OS_WIN32") { - return true; - } -#endif - - // Fallback - return false; -} diff --git a/interface/external/fervor/fvplatform.h b/interface/external/fervor/fvplatform.h deleted file mode 100755 index a98f04a1ce..0000000000 --- a/interface/external/fervor/fvplatform.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FVPLATFORM_H -#define FVPLATFORM_H - -#include - -class FvPlatform : public QObject -{ - Q_OBJECT - -public: - static bool CurrentlyRunningOnPlatform(QString platform); - -private: - explicit FvPlatform(QObject *parent = 0); - -}; - -#endif // FVPLATFORM_H diff --git a/interface/external/fervor/fvupdatedownloadprogress.cpp b/interface/external/fervor/fvupdatedownloadprogress.cpp deleted file mode 100755 index 0b6e7934ad..0000000000 --- a/interface/external/fervor/fvupdatedownloadprogress.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "fvupdatedownloadprogress.h" - -FvUpdateDownloadProgress::FvUpdateDownloadProgress(QWidget *parent) - : QWidget(parent, Qt::SplashScreen) -{ - ui.setupUi(this); - - ui.progress->setValue(0); - -} - -FvUpdateDownloadProgress::~FvUpdateDownloadProgress() -{ - -} - -void FvUpdateDownloadProgress::downloadProgress ( qint64 bytesReceived, qint64 bytesTotal ) -{ - ui.progress->setValue( ((float)bytesReceived / (float)bytesTotal) * 100 ); -} - -void FvUpdateDownloadProgress::close() -{ - this->deleteLater(); - QWidget::close(); -} \ No newline at end of file diff --git a/interface/external/fervor/fvupdatedownloadprogress.h b/interface/external/fervor/fvupdatedownloadprogress.h deleted file mode 100755 index 1b6ab0d709..0000000000 --- a/interface/external/fervor/fvupdatedownloadprogress.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef FVUPDATEDOWNLOADPROGRESS_H -#define FVUPDATEDOWNLOADPROGRESS_H - -#include -#include "ui_fvupdatedownloadprogress.h" - -class FvUpdateDownloadProgress : public QWidget -{ - Q_OBJECT - -public: - FvUpdateDownloadProgress(QWidget *parent = 0); - ~FvUpdateDownloadProgress(); - -public slots: - void downloadProgress ( qint64 bytesReceived, qint64 bytesTotal ); - void close(); - -private: - Ui::FvUpdateDownloadProgress ui; -}; - -#endif // FVUPDATEDOWNLOADPROGRESS_H diff --git a/interface/external/fervor/fvupdatedownloadprogress.ui b/interface/external/fervor/fvupdatedownloadprogress.ui deleted file mode 100755 index 264e8c9728..0000000000 --- a/interface/external/fervor/fvupdatedownloadprogress.ui +++ /dev/null @@ -1,94 +0,0 @@ - - - FvUpdateDownloadProgress - - - Qt::ApplicationModal - - - - 0 - 0 - 558 - 70 - - - - - 0 - 0 - - - - FvUpdateDownloadProgress - - - - 0 - - - 0 - - - - - QFrame::WinPanel - - - QFrame::Raised - - - - 8 - - - - - - 12 - - - - Qt::LeftToRight - - - QFrame::NoFrame - - - QFrame::Plain - - - Downloading Update... - - - Qt::AlignCenter - - - - - - - - 8 - - - - 24 - - - false - - - false - - - - - - - - - - - - diff --git a/interface/external/fervor/fvupdater.cpp b/interface/external/fervor/fvupdater.cpp deleted file mode 100755 index b720b0a024..0000000000 --- a/interface/external/fervor/fvupdater.cpp +++ /dev/null @@ -1,908 +0,0 @@ -#include "fvupdater.h" -#include "fvplatform.h" -#include "fvignoredversions.h" -#include "fvavailableupdate.h" -#include -#include -#include -#include -#include "quazip.h" -#include "quazipfile.h" - -#ifdef Q_OS_MAC -#include "CoreFoundation/CoreFoundation.h" -#endif - -#ifdef FV_GUI -#include "fvupdatewindow.h" -#include "fvupdatedownloadprogress.h" -#include -#include -#else -// QSettings key for automatic update installation -#define FV_NEW_VERSION_POLICY_KEY "FVNewVersionPolicy" -#endif - -#ifdef FV_DEBUG - // Unit tests -# include "fvversioncomparatortest.h" -#endif - -extern QSettings* settings; - -FvUpdater* FvUpdater::m_Instance = 0; - - -FvUpdater* FvUpdater::sharedUpdater() -{ - static QMutex mutex; - if (! m_Instance) { - mutex.lock(); - - if (! m_Instance) { - m_Instance = new FvUpdater; - } - - mutex.unlock(); - } - - return m_Instance; -} - -void FvUpdater::drop() -{ - static QMutex mutex; - mutex.lock(); - delete m_Instance; - m_Instance = 0; - mutex.unlock(); -} - -FvUpdater::FvUpdater() : QObject(0) -{ - m_reply = 0; -#ifdef FV_GUI - m_updaterWindow = 0; -#endif - m_proposedUpdate = 0; - m_requiredSslFingerprint = ""; - htAuthUsername = ""; - htAuthPassword = ""; - skipVersionAllowed = true; - remindLaterAllowed = true; - - connect(&m_qnam, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)),this, SLOT(authenticationRequired(QNetworkReply*, QAuthenticator*))); - - // Translation mechanism - installTranslator(); - -#ifdef FV_DEBUG - // Unit tests - FvVersionComparatorTest* test = new FvVersionComparatorTest(); - test->runAll(); - delete test; -#endif - -} - -FvUpdater::~FvUpdater() -{ - if (m_proposedUpdate) { - delete m_proposedUpdate; - m_proposedUpdate = 0; - } - -#ifdef FV_GUI - hideUpdaterWindow(); -#endif -} - -void FvUpdater::installTranslator() -{ - QTranslator translator; - QString locale = QLocale::system().name(); - translator.load(QString("fervor_") + locale); - -#if QT_VERSION < 0x050000 - QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8")); -#endif - - qApp->installTranslator(&translator); -} - -#ifdef FV_GUI -void FvUpdater::showUpdaterWindowUpdatedWithCurrentUpdateProposal() -{ - // Destroy window if already exists - hideUpdaterWindow(); - - // Create a new window - m_updaterWindow = new FvUpdateWindow(NULL, skipVersionAllowed, remindLaterAllowed); - m_updaterWindow->UpdateWindowWithCurrentProposedUpdate(); - m_updaterWindow->show(); -} - -void FvUpdater::hideUpdaterWindow() -{ - if (m_updaterWindow) { - if (! m_updaterWindow->close()) { - qWarning() << "Update window didn't close, leaking memory from now on"; - } - - // not deleting because of Qt::WA_DeleteOnClose - - m_updaterWindow = 0; - } -} - -void FvUpdater::updaterWindowWasClosed() -{ - // (Re-)nullify a pointer to a destroyed QWidget or you're going to have a bad time. - m_updaterWindow = 0; -} -#endif - -void FvUpdater::SetFeedURL(QUrl feedURL) -{ - m_feedURL = feedURL; -} - -void FvUpdater::SetFeedURL(QString feedURL) -{ - SetFeedURL(QUrl(feedURL)); -} - -QString FvUpdater::GetFeedURL() -{ - return m_feedURL.toString(); -} - -FvAvailableUpdate* FvUpdater::GetProposedUpdate() -{ - return m_proposedUpdate; -} - - -void FvUpdater::InstallUpdate() -{ - if(m_proposedUpdate==NULL) - { - qWarning() << "Abort Update: No update prososed! This should not happen."; - return; - } - - // Prepare download - QUrl url = m_proposedUpdate->GetEnclosureUrl(); - - // Check SSL Fingerprint if required - if(url.scheme()=="https" && !m_requiredSslFingerprint.isEmpty()) - if( !checkSslFingerPrint(url) ) // check failed - { - qWarning() << "Update aborted."; - return; - } - - // Start Download - QNetworkReply* reply = m_qnam.get(QNetworkRequest(url)); - connect(reply, SIGNAL(finished()), this, SLOT(httpUpdateDownloadFinished())); - - // Maybe Check request 's return value - if (reply->error() != QNetworkReply::NoError) - { - qDebug()<<"Unable to download the update: "<errorString(); - return; - } - else - qDebug()<<"OK"; - - // Show download Window -#ifdef FV_GUI - FvUpdateDownloadProgress* dlwindow = new FvUpdateDownloadProgress(NULL); - connect(reply, SIGNAL(downloadProgress(qint64, qint64)), dlwindow, SLOT(downloadProgress(qint64, qint64) )); - connect(&m_qnam, SIGNAL(finished(QNetworkReply*)), dlwindow, SLOT(close())); - dlwindow->show(); -#endif - - emit (updatedFinishedSuccessfully()); - -#ifdef FV_GUI - hideUpdaterWindow(); -#endif -} - -void FvUpdater::httpUpdateDownloadFinished() -{ - QNetworkReply* reply = qobject_cast(sender()); - if(reply==NULL) - { - qWarning()<<"The slot httpUpdateDownloadFinished() should only be invoked by S&S."; - return; - } - - if(reply->error() == QNetworkReply::NoError) - { - int httpstatuscode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toUInt(); - - // no error received? - if (reply->error() == QNetworkReply::NoError) - { - if (reply->isReadable()) - { -#ifdef Q_OS_MAC - CFURLRef appURLRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - char path[PATH_MAX]; - if (!CFURLGetFileSystemRepresentation(appURLRef, TRUE, (UInt8 *)path, PATH_MAX)) { - // error! - } - - CFRelease(appURLRef); - QString filePath = QString(path); - QString rootDirectory = filePath.left(filePath.lastIndexOf("/")); -#else - QString rootDirectory = QCoreApplication::applicationDirPath() + "/"; -#endif - - // Write download into File - QFileInfo fileInfo=reply->url().path(); - QString fileName = rootDirectory + fileInfo.fileName(); - //qDebug()<<"Writing downloaded file into "<readAll()); - file.close(); - - // Retrieve List of updated files (Placed in an extra scope to avoid QuaZIP handles the archive permanently and thus avoids the deletion.) - { - QuaZip zip(fileName); - if (!zip.open(QuaZip::mdUnzip)) { - qWarning("testRead(): zip.open(): %d", zip.getZipError()); - return; - } - zip.setFileNameCodec("IBM866"); - QList updateFiles = zip.getFileInfoList(); - - // Rename all current files with available update. - for (int i=0;ideleteLater(); - } // If !reply->error END -} // httpUpdateDownloadFinished END - -bool FvUpdater::unzipUpdate(const QString & filePath, const QString & extDirPath, const QString & singleFileName ) -{ - QuaZip zip(filePath); - - if (!zip.open(QuaZip::mdUnzip)) { - qWarning()<GetEnclosureVersion()); - -#ifdef FV_GUI - hideUpdaterWindow(); -#endif -} - -void FvUpdater::RemindMeLater() -{ - //qDebug() << "Remind me later"; - -#ifdef FV_GUI - hideUpdaterWindow(); -#endif -} - -bool FvUpdater::CheckForUpdates(bool silentAsMuchAsItCouldGet) -{ - if (m_feedURL.isEmpty()) { - qCritical() << "Please set feed URL via setFeedURL() before calling CheckForUpdates()."; - return false; - } - - m_silentAsMuchAsItCouldGet = silentAsMuchAsItCouldGet; - - // Check if application's organization name and domain are set, fail otherwise - // (nowhere to store QSettings to) - if (QCoreApplication::organizationName().isEmpty()) { - qCritical() << "QCoreApplication::organizationName is not set. Please do that."; - return false; - } - if (QCoreApplication::organizationDomain().isEmpty()) { - qCritical() << "QCoreApplication::organizationDomain is not set. Please do that."; - return false; - } - - if(QCoreApplication::applicationName().isEmpty()) { - qCritical() << "QCoreApplication::applicationName is not set. Please do that."; - return false; - } - - // Set application version is not set yet - if (QCoreApplication::applicationVersion().isEmpty()) { - qCritical() << "QCoreApplication::applicationVersion is not set. Please do that."; - return false; - } - - cancelDownloadFeed(); - m_httpRequestAborted = false; - startDownloadFeed(m_feedURL); - - return true; -} - -bool FvUpdater::CheckForUpdatesSilent() -{ - return CheckForUpdates(true); -} - -bool FvUpdater::CheckForUpdatesNotSilent() -{ - return CheckForUpdates(false); -} - - -void FvUpdater::startDownloadFeed(QUrl url) -{ - m_xml.clear(); - - // Check SSL Fingerprint if required - if(url.scheme()=="https" && !m_requiredSslFingerprint.isEmpty()) - if( !checkSslFingerPrint(url) ) // check failed - { - qWarning() << "Update aborted."; - return; - } - - - m_reply = m_qnam.get(QNetworkRequest(url)); - - connect(m_reply, SIGNAL(readyRead()), this, SLOT(httpFeedReadyRead())); - connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(httpFeedUpdateDataReadProgress(qint64, qint64))); - connect(m_reply, SIGNAL(finished()), this, SLOT(httpFeedDownloadFinished())); -} - -void FvUpdater::cancelDownloadFeed() -{ - if (m_reply) { - m_httpRequestAborted = true; - m_reply->abort(); - } -} - -void FvUpdater::httpFeedReadyRead() -{ - // this slot gets called every time the QNetworkReply has new data. - // We read all of its new data and write it into the file. - // That way we use less RAM than when reading it at the finished() - // signal of the QNetworkReply - m_xml.addData(m_reply->readAll()); -} - -void FvUpdater::httpFeedUpdateDataReadProgress(qint64 bytesRead, - qint64 totalBytes) -{ - Q_UNUSED(bytesRead); - Q_UNUSED(totalBytes); - - if (m_httpRequestAborted) { - return; - } -} - -void FvUpdater::httpFeedDownloadFinished() -{ - if (m_httpRequestAborted) { - m_reply->deleteLater(); - return; - } - - QVariant redirectionTarget = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute); - if (m_reply->error()) { - - // Error. - showErrorDialog(tr("Feed download failed: %1.").arg(m_reply->errorString()), false); - - } else if (! redirectionTarget.isNull()) { - QUrl newUrl = m_feedURL.resolved(redirectionTarget.toUrl()); - - m_feedURL = newUrl; - m_reply->deleteLater(); - - startDownloadFeed(m_feedURL); - return; - - } else { - - // Done. - xmlParseFeed(); - - } - - m_reply->deleteLater(); - m_reply = 0; -} - -bool FvUpdater::xmlParseFeed() -{ - QString currentTag, currentQualifiedTag; - - QString xmlTitle, xmlLink, xmlReleaseNotesLink, xmlPubDate, xmlEnclosureUrl, - xmlEnclosureVersion, xmlEnclosurePlatform, xmlEnclosureType; - unsigned long xmlEnclosureLength; - - // Parse - while (! m_xml.atEnd()) { - - m_xml.readNext(); - - if (m_xml.isStartElement()) { - - currentTag = m_xml.name().toString(); - currentQualifiedTag = m_xml.qualifiedName().toString(); - - if (m_xml.name() == "item") { - - xmlTitle.clear(); - xmlLink.clear(); - xmlReleaseNotesLink.clear(); - xmlPubDate.clear(); - xmlEnclosureUrl.clear(); - xmlEnclosureVersion.clear(); - xmlEnclosurePlatform.clear(); - xmlEnclosureLength = 0; - xmlEnclosureType.clear(); - - } else if (m_xml.name() == "enclosure") { - - QXmlStreamAttributes attribs = m_xml.attributes(); - - if (attribs.hasAttribute("fervor:platform")) - { - xmlEnclosurePlatform = attribs.value("fervor:platform").toString().trimmed(); - - if (FvPlatform::CurrentlyRunningOnPlatform(xmlEnclosurePlatform)) - { - xmlEnclosureUrl = attribs.hasAttribute("url") ? attribs.value("url").toString().trimmed() : ""; - - xmlEnclosureVersion = ""; - if (attribs.hasAttribute("fervor:version")) - xmlEnclosureVersion = attribs.value("fervor:version").toString().trimmed(); - if (attribs.hasAttribute("sparkle:version")) - xmlEnclosureVersion = attribs.value("sparkle:version").toString().trimmed(); - - xmlEnclosureLength = attribs.hasAttribute("length") ? attribs.value("length").toString().toLong() : 0; - - xmlEnclosureType = attribs.hasAttribute("type") ? attribs.value("type").toString().trimmed() : ""; - } - - } // if hasAttribute flevor:platform END - - } // IF encosure END - - } else if (m_xml.isEndElement()) { - - if (m_xml.name() == "item") { - - // That's it - we have analyzed a single and we'll stop - // here (because the topmost is the most recent one, and thus - // the newest version. - - return searchDownloadedFeedForUpdates(xmlTitle, - xmlLink, - xmlReleaseNotesLink, - xmlPubDate, - xmlEnclosureUrl, - xmlEnclosureVersion, - xmlEnclosurePlatform, - xmlEnclosureLength, - xmlEnclosureType); - - } - - } else if (m_xml.isCharacters() && ! m_xml.isWhitespace()) { - - if (currentTag == "title") { - xmlTitle += m_xml.text().toString().trimmed(); - - } else if (currentTag == "link") { - xmlLink += m_xml.text().toString().trimmed(); - - } else if (currentQualifiedTag == "sparkle:releaseNotesLink") { - xmlReleaseNotesLink += m_xml.text().toString().trimmed(); - - } else if (currentTag == "pubDate") { - xmlPubDate += m_xml.text().toString().trimmed(); - - } - - } - - if (m_xml.error() && m_xml.error() != QXmlStreamReader::PrematureEndOfDocumentError) { - - showErrorDialog(tr("Feed parsing failed: %1 %2.").arg(QString::number(m_xml.lineNumber()), m_xml.errorString()), false); - return false; - - } - } - - return false; -} - - -bool FvUpdater::searchDownloadedFeedForUpdates(QString xmlTitle, - QString xmlLink, - QString xmlReleaseNotesLink, - QString xmlPubDate, - QString xmlEnclosureUrl, - QString xmlEnclosureVersion, - QString xmlEnclosurePlatform, - unsigned long xmlEnclosureLength, - QString xmlEnclosureType) -{ - Q_UNUSED(xmlTitle); - Q_UNUSED(xmlPubDate); - Q_UNUSED(xmlEnclosureLength); - Q_UNUSED(xmlEnclosureType); - - // Validate - if (xmlReleaseNotesLink.isEmpty()) { - if (xmlLink.isEmpty()) { - showErrorDialog(tr("Feed error: \"release notes\" link is empty"), false); - return false; - } else { - xmlReleaseNotesLink = xmlLink; - } - } else { - xmlLink = xmlReleaseNotesLink; - } - if (! (xmlLink.startsWith("http://") || xmlLink.startsWith("https://"))) { - showErrorDialog(tr("Feed error: invalid \"release notes\" link"), false); - return false; - } - if (xmlEnclosureUrl.isEmpty() || xmlEnclosureVersion.isEmpty() || xmlEnclosurePlatform.isEmpty()) { - showErrorDialog(tr("Feed error: invalid \"enclosure\" with the download link"), false); - return false; - } - - // Relevant version? - if (FVIgnoredVersions::VersionIsIgnored(xmlEnclosureVersion)) { - qDebug() << "Version '" << xmlEnclosureVersion << "' is ignored, too old or something like that."; - - showInformationDialog(tr("No updates were found."), false); - - return true; // Things have succeeded when you think of it. - } - - - // - // Success! At this point, we have found an update that can be proposed - // to the user. - // - - if (m_proposedUpdate) { - delete m_proposedUpdate; m_proposedUpdate = 0; - } - m_proposedUpdate = new FvAvailableUpdate(); - m_proposedUpdate->SetTitle(xmlTitle); - m_proposedUpdate->SetReleaseNotesLink(xmlReleaseNotesLink); - m_proposedUpdate->SetPubDate(xmlPubDate); - m_proposedUpdate->SetEnclosureUrl(xmlEnclosureUrl); - m_proposedUpdate->SetEnclosureVersion(xmlEnclosureVersion); - m_proposedUpdate->SetEnclosurePlatform(xmlEnclosurePlatform); - m_proposedUpdate->SetEnclosureLength(xmlEnclosureLength); - m_proposedUpdate->SetEnclosureType(xmlEnclosureType); - -#ifdef FV_GUI - // Show "look, there's an update" window - showUpdaterWindowUpdatedWithCurrentUpdateProposal(); -#else - // Decide ourselves what to do - decideWhatToDoWithCurrentUpdateProposal(); -#endif - - return true; -} - - -void FvUpdater::showErrorDialog(QString message, bool showEvenInSilentMode) -{ - if (m_silentAsMuchAsItCouldGet) { - if (! showEvenInSilentMode) { - // Don't show errors in the silent mode - return; - } - } - -#ifdef FV_GUI - QMessageBox dlFailedMsgBox; - dlFailedMsgBox.setIcon(QMessageBox::Critical); - dlFailedMsgBox.setText(tr("Error")); - dlFailedMsgBox.setInformativeText(message); - dlFailedMsgBox.exec(); -#else - qCritical() << message; -#endif -} - -void FvUpdater::showInformationDialog(QString message, bool showEvenInSilentMode) -{ - if (m_silentAsMuchAsItCouldGet) { - if (! showEvenInSilentMode) { - // Don't show information dialogs in the silent mode - return; - } - } - -#ifdef FV_GUI - QMessageBox dlInformationMsgBox; - dlInformationMsgBox.setIcon(QMessageBox::Information); - dlInformationMsgBox.setText(tr("Information")); - dlInformationMsgBox.setInformativeText(message); - dlInformationMsgBox.exec(); -#else - qDebug() << message; -#endif -} - -void FvUpdater::finishUpdate(QString pathToFinish) -{ - pathToFinish = pathToFinish.isEmpty() ? QCoreApplication::applicationDirPath() : pathToFinish; - QDir appDir(pathToFinish); - appDir.setFilter( QDir::Files | QDir::Dirs ); - - QFileInfoList dirEntries = appDir.entryInfoList(); - foreach (QFileInfo fi, dirEntries) - { - if ( fi.isDir() ) - { - QString dirname = fi.fileName(); - if ((dirname==".") || (dirname == "..")) - continue; - - // recursive clean up subdirectory - finishUpdate(fi.filePath()); - } - else - { - if(fi.suffix()=="oldversion") - if( !appDir.remove( fi.absoluteFilePath() ) ) - qDebug()<<"Error: Unable to clean up file: "<connectToHostEncrypted(urltoCheck.host(), 443); - if( !socket->waitForEncrypted(1000)) // waits until ssl emits encrypted(), max 1000msecs - { - qWarning()<<"SSL fingerprint check: Unable to connect SSL server: "<sslErrors(); - return false; - } - - QSslCertificate cert = socket->peerCertificate(); - - if(cert.isNull()) - { - qWarning()<<"SSL fingerprint check: Unable to retrieve SSL server certificate."; - return false; - } - - // COmpare digests - if(cert.digest().toHex() != m_requiredSslFingerprint) - { - qWarning()<<"SSL fingerprint check: FINGERPRINT MISMATCH! Server digest="<setUser(htAuthUsername); - authenticator->setPassword(htAuthPassword); -} - -void FvUpdater::setHtAuthCredentials(QString user, QString pass) -{ - htAuthUsername = user; - htAuthPassword = pass; -} - -void FvUpdater::setHtAuthUsername(QString user) -{ - htAuthUsername = user; -} - -void FvUpdater::setHtAuthPassword(QString pass) -{ - htAuthPassword = pass; -} - -void FvUpdater::setSkipVersionAllowed(bool allowed) -{ - skipVersionAllowed = allowed; -} - -void FvUpdater::setRemindLaterAllowed(bool allowed) -{ - remindLaterAllowed = allowed; -} - -bool FvUpdater::getSkipVersionAllowed() -{ - return skipVersionAllowed; -} - -bool FvUpdater::getRemindLaterAllowed() -{ - return remindLaterAllowed; -} - -#ifndef FV_GUI - -void FvUpdater::decideWhatToDoWithCurrentUpdateProposal() -{ - QString policy = settings->value(FV_NEW_VERSION_POLICY_KEY).toString(); - if(policy == "install") - InstallUpdate(); - else if(policy == "skip") - SkipUpdate(); - else - RemindMeLater(); -} - -#endif - diff --git a/interface/external/fervor/fvupdater.h b/interface/external/fervor/fvupdater.h deleted file mode 100755 index 48baf0c194..0000000000 --- a/interface/external/fervor/fvupdater.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef FVUPDATER_H -#define FVUPDATER_H - -#include -#include -#include -#include -#include -class QNetworkReply; -class FvUpdateWindow; -class FvUpdateConfirmDialog; -class FvAvailableUpdate; - - -class FvUpdater : public QObject -{ - Q_OBJECT - -public: - - // Singleton - static FvUpdater* sharedUpdater(); - static void drop(); - - // Set / get feed URL - void SetFeedURL(QUrl feedURL); - void SetFeedURL(QString feedURL); - QString GetFeedURL(); - void finishUpdate(QString pathToFinish = ""); - void setRequiredSslFingerPrint(QString md5); - QString getRequiredSslFingerPrint(); // returns md5! - // HTTP Authentuication - for security reasons no getters are provided, only a setter - void setHtAuthCredentials(QString user, QString pass); - void setHtAuthUsername(QString user); - void setHtAuthPassword(QString pass); - void setSkipVersionAllowed(bool allowed); - void setRemindLaterAllowed(bool allowed); - bool getSkipVersionAllowed(); - bool getRemindLaterAllowed(); - - -public slots: - - // Check for updates - bool CheckForUpdates(bool silentAsMuchAsItCouldGet = true); - - // Aliases - bool CheckForUpdatesSilent(); - bool CheckForUpdatesNotSilent(); - - - // - // --------------------------------------------------- - // --------------------------------------------------- - // --------------------------------------------------- - // --------------------------------------------------- - // - -protected: - - friend class FvUpdateWindow; // Uses GetProposedUpdate() and others - friend class FvUpdateConfirmDialog; // Uses GetProposedUpdate() and others - FvAvailableUpdate* GetProposedUpdate(); - - -protected slots: - - // Update window button slots - void InstallUpdate(); - void SkipUpdate(); - void RemindMeLater(); - -private: - - // - // Singleton business - // - // (we leave just the declarations, so the compiler will warn us if we try - // to use those two functions by accident) - FvUpdater(); // Hide main constructor - ~FvUpdater(); // Hide main destructor - FvUpdater(const FvUpdater&); // Hide copy constructor - FvUpdater& operator=(const FvUpdater&); // Hide assign op - - static FvUpdater* m_Instance; // Singleton instance - - - // - // Windows / dialogs - // -#ifdef FV_GUI - FvUpdateWindow* m_updaterWindow; // Updater window (NULL if not shown) - void showUpdaterWindowUpdatedWithCurrentUpdateProposal(); // Show updater window - void hideUpdaterWindow(); // Hide + destroy m_updaterWindow - void updaterWindowWasClosed(); // Sent by the updater window when it gets closed -#else - void decideWhatToDoWithCurrentUpdateProposal(); // Perform an action which is configured in settings -#endif - - // Available update (NULL if not fetched) - FvAvailableUpdate* m_proposedUpdate; - - // If true, don't show the error dialogs and the "no updates." dialog - // (silentAsMuchAsItCouldGet from CheckForUpdates() goes here) - // Useful for automatic update checking upon application startup. - bool m_silentAsMuchAsItCouldGet; - - // Dialogs (notifications) - bool skipVersionAllowed; - bool remindLaterAllowed; - - void showErrorDialog(QString message, bool showEvenInSilentMode = false); // Show an error message - void showInformationDialog(QString message, bool showEvenInSilentMode = false); // Show an informational message - - - // - // HTTP feed fetcher infrastructure - // - QUrl m_feedURL; // Feed URL that will be fetched - QNetworkAccessManager m_qnam; - QNetworkReply* m_reply; - int m_httpGetId; - bool m_httpRequestAborted; - - void startDownloadFeed(QUrl url); // Start downloading feed - void cancelDownloadFeed(); // Stop downloading the current feed - - // - // SSL Fingerprint Check infrastructure - // - QString m_requiredSslFingerprint; - - bool checkSslFingerPrint(QUrl urltoCheck); // true=ssl Fingerprint accepted, false= ssl Fingerprint NOT accepted - - // - // Htauth-Infrastructure - // - QString htAuthUsername; - QString htAuthPassword; - - - // - // XML parser - // - QXmlStreamReader m_xml; // XML data collector and parser - bool xmlParseFeed(); // Parse feed in m_xml - bool searchDownloadedFeedForUpdates(QString xmlTitle, - QString xmlLink, - QString xmlReleaseNotesLink, - QString xmlPubDate, - QString xmlEnclosureUrl, - QString xmlEnclosureVersion, - QString xmlEnclosurePlatform, - unsigned long xmlEnclosureLength, - QString xmlEnclosureType); - - - // - // Helpers - // - void installTranslator(); // Initialize translation mechanism - void restartApplication(); // Restarts application after update - -private slots: - - void authenticationRequired ( QNetworkReply * reply, QAuthenticator * authenticator ); - void httpFeedReadyRead(); - void httpFeedUpdateDataReadProgress(qint64 bytesRead, - qint64 totalBytes); - void httpFeedDownloadFinished(); - - // - // Download and install Update infrastructure - // - void httpUpdateDownloadFinished(); - bool unzipUpdate(const QString & filePath, const QString & extDirPath, const QString & singleFileName = QString("")); // returns true on success - -signals: - void updatedFinishedSuccessfully(); - -}; - -#endif // FVUPDATER_H diff --git a/interface/external/fervor/fvupdatewindow.cpp b/interface/external/fervor/fvupdatewindow.cpp deleted file mode 100755 index 75329a54f3..0000000000 --- a/interface/external/fervor/fvupdatewindow.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "fvupdatewindow.h" -#include "ui_fvupdatewindow.h" -#include "fvupdater.h" -#include "fvavailableupdate.h" -#include -#include -#include - - -FvUpdateWindow::FvUpdateWindow(QWidget *parent, bool skipVersionAllowed, bool remindLaterAllowed) : - QWidget(parent, Qt::CustomizeWindowHint), - m_ui(new Ui::FvUpdateWindow) -{ - m_ui->setupUi(this); - - m_appIconScene = 0; - - if(!skipVersionAllowed) - m_ui->skipThisVersionButton->hide(); - if(!remindLaterAllowed) - m_ui->remindMeLaterButton->hide(); - - // Delete on close - setAttribute(Qt::WA_DeleteOnClose, true); - - // Set the "new version is available" string - QString newVersString = m_ui->newVersionIsAvailableLabel->text().arg(QApplication::applicationName()); - m_ui->newVersionIsAvailableLabel->setText(newVersString); - - // Connect buttons - connect(m_ui->installUpdateButton, SIGNAL(clicked()), - FvUpdater::sharedUpdater(), SLOT(InstallUpdate())); - connect(m_ui->skipThisVersionButton, SIGNAL(clicked()), - FvUpdater::sharedUpdater(), SLOT(SkipUpdate())); - connect(m_ui->remindMeLaterButton, SIGNAL(clicked()), - FvUpdater::sharedUpdater(), SLOT(RemindMeLater())); -} - -FvUpdateWindow::~FvUpdateWindow() -{ - m_ui->releaseNotesWebView->stop(); - delete m_ui; -} - -bool FvUpdateWindow::UpdateWindowWithCurrentProposedUpdate() -{ - FvAvailableUpdate* proposedUpdate = FvUpdater::sharedUpdater()->GetProposedUpdate(); - if (! proposedUpdate) { - return false; - } - - QString downloadString = m_ui->wouldYouLikeToDownloadLabel->text() - .arg(QApplication::applicationName(), proposedUpdate->GetEnclosureVersion(), QApplication::applicationVersion()); - m_ui->wouldYouLikeToDownloadLabel->setText(downloadString); - - m_ui->releaseNotesWebView->stop(); - m_ui->releaseNotesWebView->load(proposedUpdate->GetReleaseNotesLink()); - - return true; -} - -void FvUpdateWindow::closeEvent(QCloseEvent* event) -{ - FvUpdater::sharedUpdater()->updaterWindowWasClosed(); - event->accept(); -} diff --git a/interface/external/fervor/fvupdatewindow.h b/interface/external/fervor/fvupdatewindow.h deleted file mode 100755 index b2e3feb443..0000000000 --- a/interface/external/fervor/fvupdatewindow.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef FVUPDATEWINDOW_H -#define FVUPDATEWINDOW_H - -#if QT_VERSION >= 0x050000 - #include -#else - #include -#endif - -class QGraphicsScene; - -namespace Ui { -class FvUpdateWindow; -} - -class FvUpdateWindow : public QWidget -{ - Q_OBJECT - -public: - explicit FvUpdateWindow(QWidget *parent, bool skipVersionAllowed, bool remindLaterAllowed); - ~FvUpdateWindow(); - - // Update the current update proposal from FvUpdater - bool UpdateWindowWithCurrentProposedUpdate(); - - void closeEvent(QCloseEvent* event); - -private: - Ui::FvUpdateWindow* m_ui; - QGraphicsScene* m_appIconScene; - -}; - -#endif // FVUPDATEWINDOW_H - - diff --git a/interface/external/fervor/fvupdatewindow.ui b/interface/external/fervor/fvupdatewindow.ui deleted file mode 100755 index c59646bde7..0000000000 --- a/interface/external/fervor/fvupdatewindow.ui +++ /dev/null @@ -1,129 +0,0 @@ - - - FvUpdateWindow - - - - 0 - 0 - 640 - 480 - - - - Software Update - - - - QLayout::SetFixedSize - - - - - - - - 75 - true - - - - A new version of %1 is available! - - - - - - - %1 %2 is now available - you have %3. Would you like to download it now? - - - - - - - - 75 - true - - - - Release Notes: - - - - - - - 160 - 80 - - - - - about:blank - - - - - - - - - - - - - Skip This Version - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Remind Me Later - - - - - - - Install Update - - - true - - - true - - - - - - - - - - - - QWebView - QWidget -
QtWebKit/QWebView
-
-
- - -
diff --git a/interface/external/fervor/fvversioncomparator.cpp b/interface/external/fervor/fvversioncomparator.cpp deleted file mode 100755 index dc4da8a086..0000000000 --- a/interface/external/fervor/fvversioncomparator.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include "fvversioncomparator.h" -#include -#include -#include - -// -// Clone of Sparkle's SUStandardVersionComparator.m, so here's original author's -// copyright too: -// -// Copyright 2007 Andy Matuschak. All rights reserved. -// -// Everything's the same except for TypeOfCharacter() -// (because who knows how Foundation does isdigit() and such.) -// - - -FvVersionComparator::FvVersionComparator() -{ - // noop -} - -FvVersionComparator::CharacterType FvVersionComparator::TypeOfCharacter(std::string character) -{ - if (character == ".") { - return kSeparatorType; - } else if (isdigit(character[0])) { - return kNumberType; - } else if (isspace(character[0])) { - return kSeparatorType; - } else if (ispunct(character[0])) { - return kSeparatorType; - } else { - return kStringType; - } - -} - -std::vector FvVersionComparator::SplitVersionString(std::string version) -{ - std::string character; - std::string s; - unsigned long i = 0, n = 0; - CharacterType oldType, newType; - std::vector parts; - - if (version.length() == 0) { - // Nothing to do here - return parts; - } - - s = version.substr(0, 1); - oldType = TypeOfCharacter(s); - n = version.length() - 1; - for (i = 1; i <= n; ++i) { - character = version.substr(i, 1)[0]; - newType = TypeOfCharacter(character); - if (oldType != newType || oldType == kSeparatorType) { - // We've reached a new segment - std::string aPart = s; - parts.push_back(aPart); - s = character; - } else { - // Add character to string and continue - s.append(character); - } - oldType = newType; - } - - // Add the last part onto the array - parts.push_back(s); - return parts; -} - - -FvVersionComparator::ComparatorResult FvVersionComparator::CompareVersions(std::string versionA, - std::string versionB) -{ - std::vector partsA = SplitVersionString(versionA); - std::vector partsB = SplitVersionString(versionB); - - std::string partA = std::string(""), partB = std::string(""); - unsigned long i = 0, n = 0; - int intA, intB; - CharacterType typeA, typeB; - - n = std::min(partsA.size(), partsB.size()); - for (i = 0; i < n; ++i) { - partA = partsA.at(i); - partB = partsB.at(i); - - typeA = TypeOfCharacter(partA); - typeB = TypeOfCharacter(partB); - - // Compare types - if (typeA == typeB) { - // Same type; we can compare - if (typeA == kNumberType) { - intA = atoi(partA.c_str()); - intB = atoi(partB.c_str()); - - if (intA > intB) { - return kDescending; - } else if (intA < intB) { - return kAscending; - } - } else if (typeA == kStringType) { - short result = partA.compare(partB); - switch (result) { - case -1: return kAscending; break; - case 1: return kDescending; break; - case 0: /* do nothing */ break; - }; - } - } else { - // Not the same type? Now we have to do some validity checking - if (typeA != kStringType && typeB == kStringType) { - // typeA wins - return kDescending; - } else if (typeA == kStringType && typeB != kStringType) { - // typeB wins - return kAscending; - } else { - // One is a number and the other is a period. The period is invalid - if (typeA == kNumberType) { - return kDescending; - } else { - return kAscending; - } - } - } - } - // The versions are equal up to the point where they both still have parts - // Lets check to see if one is larger than the other - if (partsA.size() != partsB.size()) { - // Yep. Lets get the next part of the larger - // n holds the index of the part we want. - std::string missingPart = std::string(""); - CharacterType missingType; - ComparatorResult shorterResult, largerResult; - - if (partsA.size() > partsB.size()) { - missingPart = partsA.at(n); - shorterResult = kAscending; - largerResult = kDescending; - } else { - missingPart = partsB.at(n); - shorterResult = kDescending; - largerResult = kAscending; - } - - missingType = TypeOfCharacter(missingPart); - // Check the type - if (missingType == kStringType) { - // It's a string. Shorter version wins - return shorterResult; - } else { - // It's a number/period. Larger version wins - return largerResult; - } - } - - // The 2 strings are identical - return kSame; -} diff --git a/interface/external/fervor/fvversioncomparator.h b/interface/external/fervor/fvversioncomparator.h deleted file mode 100755 index f083fdfe03..0000000000 --- a/interface/external/fervor/fvversioncomparator.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef FVVERSIONCOMPARATOR_H -#define FVVERSIONCOMPARATOR_H - -#include -#include - - -class FvVersionComparator -{ -public: - - typedef enum { - kSame = 0, - kDescending = 1, - kAscending = -1 - } ComparatorResult; - - static ComparatorResult CompareVersions(std::string versionA, - std::string versionB); - -private: - - FvVersionComparator(); - - typedef enum { - kNumberType, - kStringType, - kSeparatorType - } CharacterType; - - static CharacterType TypeOfCharacter(std::string character); - static std::vector SplitVersionString(std::string version); - -}; - -#endif // FVVERSIONCOMPARATOR_H diff --git a/interface/external/quazip/include/JlCompress.h b/interface/external/quazip/include/JlCompress.h deleted file mode 100644 index 968f7a89ad..0000000000 --- a/interface/external/quazip/include/JlCompress.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef JLCOMPRESSFOLDER_H_ -#define JLCOMPRESSFOLDER_H_ - -#include "quazip.h" -#include "quazipfile.h" -#include "quazipfileinfo.h" -#include -#include -#include -#include - -/// Utility class for typical operations. -/** - This class contains a number of useful static functions to perform - simple operations, such as mass ZIP packing or extraction. - */ -class QUAZIP_EXPORT JlCompress { -private: - /// Compress a single file. - /** - \param zip Opened zip to compress the file to. - \param fileName The full path to the source file. - \param fileDest The full name of the file inside the archive. - \return true if success, false otherwise. - */ - static bool compressFile(QuaZip* zip, QString fileName, QString fileDest); - /// Compress a subdirectory. - /** - \param parentZip Opened zip containing the parent directory. - \param dir The full path to the directory to pack. - \param parentDir The full path to the directory corresponding to - the root of the ZIP. - \param recursive Whether to pack sub-directories as well or only - files. - \return true if success, false otherwise. - */ - static bool compressSubDir(QuaZip* parentZip, QString dir, QString parentDir, bool recursive = true); - /// Extract a single file. - /** - \param zip The opened zip archive to extract from. - \param fileName The full name of the file to extract. - \param fileDest The full path to the destination file. - \return true if success, false otherwise. - */ - static bool extractFile(QuaZip* zip, QString fileName, QString fileDest); - /// Remove some files. - /** - \param listFile The list of files to remove. - \return true if success, false otherwise. - */ - static bool removeFile(QStringList listFile); - -public: - /// Compress a single file. - /** - \param fileCompressed The name of the archive. - \param file The file to compress. - \return true if success, false otherwise. - */ - static bool compressFile(QString fileCompressed, QString file); - /// Compress a list of files. - /** - \param fileCompressed The name of the archive. - \param files The file list to compress. - \return true if success, false otherwise. - */ - static bool compressFiles(QString fileCompressed, QStringList files); - /// Compress a whole directory. - /** - \param fileCompressed The name of the archive. - \param dir The directory to compress. - \param recursive Whether to pack the subdirectories as well, or - just regular files. - \return true if success, false otherwise. - */ - static bool compressDir(QString fileCompressed, QString dir = QString(), bool recursive = true); - -public: - /// Extract a single file. - /** - \param fileCompressed The name of the archive. - \param fileName The file to extract. - \param fileDest The destination file, assumed to be identical to - \a file if left empty. - \return The list of the full paths of the files extracted, empty on failure. - */ - static QString extractFile(QString fileCompressed, QString fileName, QString fileDest = QString()); - /// Extract a list of files. - /** - \param fileCompressed The name of the archive. - \param files The file list to extract. - \param dir The directory to put the files to, the current - directory if left empty. - \return The list of the full paths of the files extracted, empty on failure. - */ - static QStringList extractFiles(QString fileCompressed, QStringList files, QString dir = QString()); - /// Extract a whole archive. - /** - \param fileCompressed The name of the archive. - \param dir The directory to extract to, the current directory if - left empty. - \return The list of the full paths of the files extracted, empty on failure. - */ - static QStringList extractDir(QString fileCompressed, QString dir = QString()); - /// Get the file list. - /** - \return The list of the files in the archive, or, more precisely, the - list of the entries, including both files and directories if they - are present separately. - */ - static QStringList getFileList(QString fileCompressed); -}; - -#endif /* JLCOMPRESSFOLDER_H_ */ diff --git a/interface/external/quazip/include/crypt.h b/interface/external/quazip/include/crypt.h deleted file mode 100644 index 1d6da628f3..0000000000 --- a/interface/external/quazip/include/crypt.h +++ /dev/null @@ -1,135 +0,0 @@ -/* crypt.h -- base code for crypt/uncrypt ZIPfile - - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This code is a modified version of crypting code in Infozip distribution - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - - If you don't need crypting in your application, just define symbols - NOCRYPT and NOUNCRYPT. - - This code support the "Traditional PKWARE Encryption". - - The new AES encryption added on Zip format by Winzip (see the page - http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong - Encryption is not supported. -*/ - -#include "quazip_global.h" - -#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) - -/*********************************************************************** - * Return the next byte in the pseudo-random sequence - */ -static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab UNUSED) -{ - //(void) pcrc_32_tab; /* avoid "unused parameter" warning */ - unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an - * unpredictable manner on 16-bit systems; not a problem - * with any known compiler so far, though */ - - temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; - return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); -} - -/*********************************************************************** - * Update the encryption keys with the next byte of plain text - */ -static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) -{ - (*(pkeys+0)) = CRC32((*(pkeys+0)), c); - (*(pkeys+1)) += (*(pkeys+0)) & 0xff; - (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; - { - register int keyshift = (int)((*(pkeys+1)) >> 24); - (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); - } - return c; -} - - -/*********************************************************************** - * Initialize the encryption keys and the random header according to - * the given password. - */ -static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) -{ - *(pkeys+0) = 305419896L; - *(pkeys+1) = 591751049L; - *(pkeys+2) = 878082192L; - while (*passwd != '\0') { - update_keys(pkeys,pcrc_32_tab,(int)*passwd); - passwd++; - } -} - -#define zdecode(pkeys,pcrc_32_tab,c) \ - (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) - -#define zencode(pkeys,pcrc_32_tab,c,t) \ - (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) - -#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED - -#define RAND_HEAD_LEN 12 - /* "last resort" source for second part of crypt seed pattern */ -# ifndef ZCR_SEED2 -# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ -# endif - -static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) - const char *passwd; /* password string */ - unsigned char *buf; /* where to write header */ - int bufSize; - unsigned long* pkeys; - const unsigned long* pcrc_32_tab; - unsigned long crcForCrypting; -{ - int n; /* index in random header */ - int t; /* temporary */ - int c; /* random byte */ - unsigned char header[RAND_HEAD_LEN-2]; /* random header */ - static unsigned calls = 0; /* ensure different random header each time */ - - if (bufSize> 7) & 0xff; - header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); - } - /* Encrypt random header (last two bytes is high word of crc) */ - init_keys(passwd, pkeys, pcrc_32_tab); - for (n = 0; n < RAND_HEAD_LEN-2; n++) - { - buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); - } - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); - return n; -} - -#endif diff --git a/interface/external/quazip/include/ioapi.h b/interface/external/quazip/include/ioapi.h deleted file mode 100644 index f4c2180932..0000000000 --- a/interface/external/quazip/include/ioapi.h +++ /dev/null @@ -1,77 +0,0 @@ -/* ioapi.h -- IO base function header for compress/uncompress .zip - files using zlib + zip or unzip API - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - Modified by Sergey A. Tachenov to integrate with Qt. -*/ - -#ifndef _ZLIBIOAPI_H -#define _ZLIBIOAPI_H - - -#define ZLIB_FILEFUNC_SEEK_CUR (1) -#define ZLIB_FILEFUNC_SEEK_END (2) -#define ZLIB_FILEFUNC_SEEK_SET (0) - -#define ZLIB_FILEFUNC_MODE_READ (1) -#define ZLIB_FILEFUNC_MODE_WRITE (2) -#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) - -#define ZLIB_FILEFUNC_MODE_EXISTING (4) -#define ZLIB_FILEFUNC_MODE_CREATE (8) - - -#ifndef ZCALLBACK - -#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) -#define ZCALLBACK CALLBACK -#else -#define ZCALLBACK -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, voidpf file, int mode)); -typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); -typedef uLong (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); -typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); - -typedef struct zlib_filefunc_def_s -{ - open_file_func zopen_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell_file_func ztell_file; - seek_file_func zseek_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; -} zlib_filefunc_def; - - - -void fill_qiodevice_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); - -#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) -#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) -#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) -#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) -#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) -#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/interface/external/quazip/include/quaadler32.h b/interface/external/quazip/include/quaadler32.h deleted file mode 100644 index 643e38361e..0000000000 --- a/interface/external/quazip/include/quaadler32.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef QUAADLER32_H -#define QUAADLER32_H - -#include - -#include "quachecksum32.h" - -/// Adler32 checksum -/** \class QuaAdler32 quaadler32.h - * This class wrappers the adler32 function with the QuaChecksum32 interface. - * See QuaChecksum32 for more info. - */ -class QUAZIP_EXPORT QuaAdler32 : public QuaChecksum32 -{ - -public: - QuaAdler32(); - - quint32 calculate(const QByteArray &data); - - void reset(); - void update(const QByteArray &buf); - quint32 value(); - -private: - quint32 checksum; -}; - -#endif //QUAADLER32_H diff --git a/interface/external/quazip/include/quachecksum32.h b/interface/external/quazip/include/quachecksum32.h deleted file mode 100644 index 6837d26b86..0000000000 --- a/interface/external/quazip/include/quachecksum32.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef QUACHECKSUM32_H -#define QUACHECKSUM32_H - -#include -#include "quazip_global.h" - -/// Checksum interface. -/** \class QuaChecksum32 quachecksum32.h - * This is an interface for 32 bit checksums. - * Classes implementing this interface can calcunate a certin - * checksum in a single step: - * \code - * QChecksum32 *crc32 = new QuaCrc32(); - * rasoult = crc32->calculate(data); - * \endcode - * or by streaming the data: - * \code - * QChecksum32 *crc32 = new QuaCrc32(); - * while(!fileA.atEnd()) - * crc32->update(fileA.read(bufSize)); - * resoultA = crc32->value(); - * crc32->reset(); - * while(!fileB.atEnd()) - * crc32->update(fileB.read(bufSize)); - * resoultB = crc32->value(); - * \endcode - */ -class QUAZIP_EXPORT QuaChecksum32 -{ - -public: - ///Calculates the checksum for data. - /** \a data source data - * \return data checksum - * - * This function has no efect on the value returned by value(). - */ - virtual quint32 calculate(const QByteArray &data) = 0; - - ///Resets the calculation on a checksun for a stream. - virtual void reset() = 0; - - ///Updates the calculated checksum for the stream - /** \a buf next portion of data from the stream - */ - virtual void update(const QByteArray &buf) = 0; - - ///Value of the checksum calculated for the stream passed throw update(). - /** \return checksum - */ - virtual quint32 value() = 0; -}; - -#endif //QUACHECKSUM32_H diff --git a/interface/external/quazip/include/quacrc32.h b/interface/external/quazip/include/quacrc32.h deleted file mode 100644 index 4c86d56657..0000000000 --- a/interface/external/quazip/include/quacrc32.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef QUACRC32_H -#define QUACRC32_H - -#include "quachecksum32.h" - -///CRC32 checksum -/** \class QuaCrc32 quacrc32.h -* This class wrappers the crc32 function with the QuaChecksum32 interface. -* See QuaChecksum32 for more info. -*/ -class QUAZIP_EXPORT QuaCrc32 : public QuaChecksum32 { - -public: - QuaCrc32(); - - quint32 calculate(const QByteArray &data); - - void reset(); - void update(const QByteArray &buf); - quint32 value(); - -private: - quint32 checksum; -}; - -#endif //QUACRC32_H diff --git a/interface/external/quazip/include/quagzipfile.h b/interface/external/quazip/include/quagzipfile.h deleted file mode 100644 index 0a71173824..0000000000 --- a/interface/external/quazip/include/quagzipfile.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef QUAZIP_QUAGZIPFILE_H -#define QUAZIP_QUAGZIPFILE_H - -#include -#include "quazip_global.h" - -#include - -class QuaGzipFilePrivate; - -/// GZIP file -/** - This class is a wrapper around GZIP file access functions in zlib. Unlike QuaZip classes, it doesn't allow reading from a GZIP file opened as QIODevice, for example, if your GZIP file is in QBuffer. It only provides QIODevice access to a GZIP file contents, but the GZIP file itself must be identified by its name on disk or by descriptor id. - */ -class QUAZIP_EXPORT QuaGzipFile: public QIODevice { - Q_OBJECT -public: - /// Empty constructor. - /** - Must call setFileName() before trying to open. - */ - QuaGzipFile(); - /// Empty constructor with a parent. - /** - Must call setFileName() before trying to open. - \param parent The parent object, as per QObject logic. - */ - QuaGzipFile(QObject *parent); - /// Constructor. - /** - \param fileName The name of the GZIP file. - \param parent The parent object, as per QObject logic. - */ - QuaGzipFile(const QString &fileName, QObject *parent = NULL); - /// Destructor. - virtual ~QuaGzipFile(); - /// Sets the name of the GZIP file to be opened. - void setFileName(const QString& fileName); - /// Returns the name of the GZIP file. - QString getFileName() const; - /// Returns true. - /** - Strictly speaking, zlib supports seeking for GZIP files, but it is - poorly implemented, because there is no way to implement it - properly. For reading, seeking backwards is very slow, and for - writing, it is downright impossible. Therefore, QuaGzipFile does not - support seeking at all. - */ - virtual bool isSequential() const; - /// Opens the file. - /** - \param mode Can be either QIODevice::Write or QIODevice::Read. - ReadWrite and Append aren't supported. - */ - virtual bool open(QIODevice::OpenMode mode); - /// Opens the file. - /** - \overload - \param fd The file descriptor to read/write the GZIP file from/to. - \param mode Can be either QIODevice::Write or QIODevice::Read. - ReadWrite and Append aren't supported. - */ - virtual bool open(int fd, QIODevice::OpenMode mode); - /// Flushes data to file. - /** - The data is written using Z_SYNC_FLUSH mode. Doesn't make any sense - when reading. - */ - virtual bool flush(); - /// Closes the file. - virtual void close(); -protected: - /// Implementation of QIODevice::readData(). - virtual qint64 readData(char *data, qint64 maxSize); - /// Implementation of QIODevice::writeData(). - virtual qint64 writeData(const char *data, qint64 maxSize); -private: - // not implemented by design to disable copy - QuaGzipFile(const QuaGzipFile &that); - QuaGzipFile& operator=(const QuaGzipFile &that); - QuaGzipFilePrivate *d; -}; - -#endif // QUAZIP_QUAGZIPFILE_H diff --git a/interface/external/quazip/include/quaziodevice.h b/interface/external/quazip/include/quaziodevice.h deleted file mode 100644 index ff0d31a5c4..0000000000 --- a/interface/external/quazip/include/quaziodevice.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef QUAZIP_QUAZIODEVICE_H -#define QUAZIP_QUAZIODEVICE_H - -#include -#include "quazip_global.h" - -#include - -class QuaZIODevicePrivate; - -/// A class to compress/decompress QIODevice. -/** - This class can be used to compress any data written to QIODevice or - decompress it back. Compressing data sent over a QTcpSocket is a good - example. - */ -class QUAZIP_EXPORT QuaZIODevice: public QIODevice { - Q_OBJECT -public: - /// Constructor. - /** - \param io The QIODevice to read/write. - \param parent The parent object, as per QObject logic. - */ - QuaZIODevice(QIODevice *io, QObject *parent = NULL); - /// Destructor. - ~QuaZIODevice(); - /// Flushes data waiting to be written. - /** - Unfortunately, as QIODevice doesn't support flush() by itself, the - only thing this method does is write the compressed data into the - device using Z_SYNC_FLUSH mode. If you need the compressed data to - actually be flushed from the buffer of the underlying QIODevice, you - need to call its flush() method as well, providing it supports it - (like QTcpSocket does). Example: - \code - QuaZIODevice dev(&sock); - dev.open(QIODevice::Write); - dev.write(yourDataGoesHere); - dev.flush(); - sock->flush(); // this actually sends data to network - \endcode - - This may change in the future versions of QuaZIP by implementing an - ugly hack: trying to cast the QIODevice using qobject_cast to known - flush()-supporting subclasses, and calling flush if the resulting - pointer is not zero. - */ - virtual bool flush(); - /// Opens the device. - /** - \param mode Neither QIODevice::ReadWrite nor QIODevice::Append are - not supported. - */ - virtual bool open(QIODevice::OpenMode mode); - /// Closes this device, but not the underlying one. - /** - The underlying QIODevice is not closed in case you want to write - something else to it. - */ - virtual void close(); - /// Returns the underlying device. - QIODevice *getIoDevice() const; - /// Returns true. - virtual bool isSequential() const; -protected: - /// Implementation of QIODevice::readData(). - virtual qint64 readData(char *data, qint64 maxSize); - /// Implementation of QIODevice::writeData(). - virtual qint64 writeData(const char *data, qint64 maxSize); -private: - QuaZIODevicePrivate *d; -}; -#endif // QUAZIP_QUAZIODEVICE_H diff --git a/interface/external/quazip/include/quazip.h b/interface/external/quazip/include/quazip.h deleted file mode 100644 index 4daa322b5f..0000000000 --- a/interface/external/quazip/include/quazip.h +++ /dev/null @@ -1,419 +0,0 @@ -#ifndef QUA_ZIP_H -#define QUA_ZIP_H - -/* -Copyright (C) 2005-2011 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU Lesser 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 Lesser -General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software Foundation, -Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant, see -quazip/(un)zip.h files for details, basically it's zlib license. - **/ - -#include -#include -#include - -#include "zip.h" -#include "unzip.h" - -#include "quazip_global.h" -#include "quazipfileinfo.h" - -// just in case it will be defined in the later versions of the ZIP/UNZIP -#ifndef UNZ_OPENERROR -// define additional error code -#define UNZ_OPENERROR -1000 -#endif - -class QuaZipPrivate; - -/// ZIP archive. -/** \class QuaZip quazip.h - * This class implements basic interface to the ZIP archive. It can be - * used to read table contents of the ZIP archive and retreiving - * information about the files inside it. - * - * You can also use this class to open files inside archive by passing - * pointer to the instance of this class to the constructor of the - * QuaZipFile class. But see QuaZipFile::QuaZipFile(QuaZip*, QObject*) - * for the possible pitfalls. - * - * This class is indended to provide interface to the ZIP subpackage of - * the ZIP/UNZIP package as well as to the UNZIP subpackage. But - * currently it supports only UNZIP. - * - * The use of this class is simple - just create instance using - * constructor, then set ZIP archive file name using setFile() function - * (if you did not passed the name to the constructor), then open() and - * then use different functions to work with it! Well, if you are - * paranoid, you may also wish to call close before destructing the - * instance, to check for errors on close. - * - * You may also use getUnzFile() and getZipFile() functions to get the - * ZIP archive handle and use it with ZIP/UNZIP package API directly. - * - * This class supports localized file names inside ZIP archive, but you - * have to set up proper codec with setCodec() function. By default, - * locale codec will be used, which is probably ok for UNIX systems, but - * will almost certainly fail with ZIP archives created in Windows. This - * is because Windows ZIP programs have strange habit of using DOS - * encoding for file names in ZIP archives. For example, ZIP archive - * with cyrillic names created in Windows will have file names in \c - * IBM866 encoding instead of \c WINDOWS-1251. I think that calling one - * function is not much trouble, but for true platform independency it - * would be nice to have some mechanism for file name encoding auto - * detection using locale information. Does anyone know a good way to do - * it? - **/ -class QUAZIP_EXPORT QuaZip { - friend class QuaZipPrivate; - public: - /// Useful constants. - enum Constants { - MAX_FILE_NAME_LENGTH=256 /**< Maximum file name length. Taken from - \c UNZ_MAXFILENAMEINZIP constant in - unzip.c. */ - }; - /// Open mode of the ZIP file. - enum Mode { - mdNotOpen, ///< ZIP file is not open. This is the initial mode. - mdUnzip, ///< ZIP file is open for reading files inside it. - mdCreate, ///< ZIP file was created with open() call. - mdAppend, /**< ZIP file was opened in append mode. This refers to - * \c APPEND_STATUS_CREATEAFTER mode in ZIP/UNZIP package - * and means that zip is appended to some existing file - * what is useful when that file contains - * self-extractor code. This is obviously \em not what - * you whant to use to add files to the existing ZIP - * archive. - **/ - mdAdd ///< ZIP file was opened for adding files in the archive. - }; - /// Case sensitivity for the file names. - /** This is what you specify when accessing files in the archive. - * Works perfectly fine with any characters thanks to Qt's great - * unicode support. This is different from ZIP/UNZIP API, where - * only US-ASCII characters was supported. - **/ - enum CaseSensitivity { - csDefault=0, ///< Default for platform. Case sensitive for UNIX, not for Windows. - csSensitive=1, ///< Case sensitive. - csInsensitive=2 ///< Case insensitive. - }; - /// Returns the actual case sensitivity for the specified QuaZIP one. - /** - \param cs The value to convert. - \returns If CaseSensitivity::csDefault, then returns the default - file name case sensitivity for the platform. Otherwise, just - returns the appropriate value from the Qt::CaseSensitivity enum. - */ - static Qt::CaseSensitivity convertCaseSensitivity( - CaseSensitivity cs); - private: - QuaZipPrivate *p; - // not (and will not be) implemented - QuaZip(const QuaZip& that); - // not (and will not be) implemented - QuaZip& operator=(const QuaZip& that); - public: - /// Constructs QuaZip object. - /** Call setName() before opening constructed object. */ - QuaZip(); - /// Constructs QuaZip object associated with ZIP file \a zipName. - QuaZip(const QString& zipName); - /// Constructs QuaZip object associated with ZIP file represented by \a ioDevice. - /** The IO device must be seekable, otherwise an error will occur when opening. */ - QuaZip(QIODevice *ioDevice); - /// Destroys QuaZip object. - /** Calls close() if necessary. */ - ~QuaZip(); - /// Opens ZIP file. - /** - * Argument \a mode specifies open mode of the ZIP archive. See Mode - * for details. Note that there is zipOpen2() function in the - * ZIP/UNZIP API which accepts \a globalcomment argument, but it - * does not use it anywhere, so this open() function does not have this - * argument. See setComment() if you need to set global comment. - * - * If the ZIP file is accessed via explicitly set QIODevice, then - * this device is opened in the necessary mode. If the device was - * already opened by some other means, then the behaviour is defined by - * the device implementation, but generally it is not a very good - * idea. For example, QFile will at least issue a warning. - * - * \return \c true if successful, \c false otherwise. - * - * \note ZIP/UNZIP API open calls do not return error code - they - * just return \c NULL indicating an error. But to make things - * easier, quazip.h header defines additional error code \c - * UNZ_ERROROPEN and getZipError() will return it if the open call - * of the ZIP/UNZIP API returns \c NULL. - * - * Argument \a ioApi specifies IO function set for ZIP/UNZIP - * package to use. See unzip.h, zip.h and ioapi.h for details. Note - * that IO API for QuaZip is different from the original package. - * The file path argument was changed to be of type \c voidpf, and - * QuaZip passes a QIODevice pointer there. This QIODevice is either - * set explicitly via setIoDevice() or the QuaZip(QIODevice*) - * constructor, or it is created internally when opening the archive - * by its file name. The default API (qioapi.cpp) just delegates - * everything to the QIODevice API. Not only this allows to use a - * QIODevice instead of file name, but also has a nice side effect - * of raising the file size limit from 2G to 4G. - * - * In short: just forget about the \a ioApi argument and you'll be - * fine. - **/ - bool open(Mode mode, zlib_filefunc_def *ioApi =NULL); - /// Closes ZIP file. - /** Call getZipError() to determine if the close was successful. The - * underlying QIODevice is also closed, regardless of whether it was - * set explicitly or not. */ - void close(); - /// Sets the codec used to encode/decode file names inside archive. - /** This is necessary to access files in the ZIP archive created - * under Windows with non-latin characters in file names. For - * example, file names with cyrillic letters will be in \c IBM866 - * encoding. - **/ - void setFileNameCodec(QTextCodec *fileNameCodec); - /// Sets the codec used to encode/decode file names inside archive. - /** \overload - * Equivalent to calling setFileNameCodec(QTextCodec::codecForName(codecName)); - **/ - void setFileNameCodec(const char *fileNameCodecName); - /// Returns the codec used to encode/decode comments inside archive. - QTextCodec* getFileNameCodec() const; - /// Sets the codec used to encode/decode comments inside archive. - /** This codec defaults to locale codec, which is probably ok. - **/ - void setCommentCodec(QTextCodec *commentCodec); - /// Sets the codec used to encode/decode comments inside archive. - /** \overload - * Equivalent to calling setCommentCodec(QTextCodec::codecForName(codecName)); - **/ - void setCommentCodec(const char *commentCodecName); - /// Returns the codec used to encode/decode comments inside archive. - QTextCodec* getCommentCodec() const; - /// Returns the name of the ZIP file. - /** Returns null string if no ZIP file name has been set, for - * example when the QuaZip instance is set up to use a QIODevice - * instead. - * \sa setZipName(), setIoDevice(), getIoDevice() - **/ - QString getZipName() const; - /// Sets the name of the ZIP file. - /** Does nothing if the ZIP file is open. - * - * Does not reset error code returned by getZipError(). - * \sa setIoDevice(), getIoDevice(), getZipName() - **/ - void setZipName(const QString& zipName); - /// Returns the device representing this ZIP file. - /** Returns null string if no device has been set explicitly, for - * example when opening a ZIP file by name. - * \sa setIoDevice(), getZipName(), setZipName() - **/ - QIODevice *getIoDevice() const; - /// Sets the device representing the ZIP file. - /** Does nothing if the ZIP file is open. - * - * Does not reset error code returned by getZipError(). - * \sa getIoDevice(), getZipName(), setZipName() - **/ - void setIoDevice(QIODevice *ioDevice); - /// Returns the mode in which ZIP file was opened. - Mode getMode() const; - /// Returns \c true if ZIP file is open, \c false otherwise. - bool isOpen() const; - /// Returns the error code of the last operation. - /** Returns \c UNZ_OK if the last operation was successful. - * - * Error code resets to \c UNZ_OK every time you call any function - * that accesses something inside ZIP archive, even if it is \c - * const (like getEntriesCount()). open() and close() calls reset - * error code too. See documentation for the specific functions for - * details on error detection. - **/ - int getZipError() const; - /// Returns number of the entries in the ZIP central directory. - /** Returns negative error code in the case of error. The same error - * code will be returned by subsequent getZipError() call. - **/ - int getEntriesCount() const; - /// Returns global comment in the ZIP file. - QString getComment() const; - /// Sets the global comment in the ZIP file. - /** The comment will be written to the archive on close operation. - * QuaZip makes a distinction between a null QByteArray() comment - * and an empty "" comment in the QuaZip::mdAdd mode. - * A null comment is the default and it means "don't change - * the comment". An empty comment removes the original comment. - * - * \sa open() - **/ - void setComment(const QString& comment); - /// Sets the current file to the first file in the archive. - /** Returns \c true on success, \c false otherwise. Call - * getZipError() to get the error code. - **/ - bool goToFirstFile(); - /// Sets the current file to the next file in the archive. - /** Returns \c true on success, \c false otherwise. Call - * getZipError() to determine if there was an error. - * - * Should be used only in QuaZip::mdUnzip mode. - * - * \note If the end of file was reached, getZipError() will return - * \c UNZ_OK instead of \c UNZ_END_OF_LIST_OF_FILE. This is to make - * things like this easier: - * \code - * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { - * // do something - * } - * if(zip.getZipError()==UNZ_OK) { - * // ok, there was no error - * } - * \endcode - **/ - bool goToNextFile(); - /// Sets current file by its name. - /** Returns \c true if successful, \c false otherwise. Argument \a - * cs specifies case sensitivity of the file name. Call - * getZipError() in the case of a failure to get error code. - * - * This is not a wrapper to unzLocateFile() function. That is - * because I had to implement locale-specific case-insensitive - * comparison. - * - * Here are the differences from the original implementation: - * - * - If the file was not found, error code is \c UNZ_OK, not \c - * UNZ_END_OF_LIST_OF_FILE (see also goToNextFile()). - * - If this function fails, it unsets the current file rather than - * resetting it back to what it was before the call. - * - * If \a fileName is null string then this function unsets the - * current file and return \c true. Note that you should close the - * file first if it is open! See - * QuaZipFile::QuaZipFile(QuaZip*,QObject*) for the details. - * - * Should be used only in QuaZip::mdUnzip mode. - * - * \sa setFileNameCodec(), CaseSensitivity - **/ - bool setCurrentFile(const QString& fileName, CaseSensitivity cs =csDefault); - /// Returns \c true if the current file has been set. - bool hasCurrentFile() const; - /// Retrieves information about the current file. - /** Fills the structure pointed by \a info. Returns \c true on - * success, \c false otherwise. In the latter case structure pointed - * by \a info remains untouched. If there was an error, - * getZipError() returns error code. - * - * Should be used only in QuaZip::mdUnzip mode. - * - * Does nothing and returns \c false in any of the following cases. - * - ZIP is not open; - * - ZIP does not have current file; - * - \a info is \c NULL; - * - * In all these cases getZipError() returns \c UNZ_OK since there - * is no ZIP/UNZIP API call. - **/ - bool getCurrentFileInfo(QuaZipFileInfo* info)const; - /// Returns the current file name. - /** Equivalent to calling getCurrentFileInfo() and then getting \c - * name field of the QuaZipFileInfo structure, but faster and more - * convenient. - * - * Should be used only in QuaZip::mdUnzip mode. - **/ - QString getCurrentFileName()const; - /// Returns \c unzFile handle. - /** You can use this handle to directly call UNZIP part of the - * ZIP/UNZIP package functions (see unzip.h). - * - * \warning When using the handle returned by this function, please - * keep in mind that QuaZip class is unable to detect any changes - * you make in the ZIP file state (e. g. changing current file, or - * closing the handle). So please do not do anything with this - * handle that is possible to do with the functions of this class. - * Or at least return the handle in the original state before - * calling some another function of this class (including implicit - * destructor calls and calls from the QuaZipFile objects that refer - * to this QuaZip instance!). So if you have changed the current - * file in the ZIP archive - then change it back or you may - * experience some strange behavior or even crashes. - **/ - unzFile getUnzFile(); - /// Returns \c zipFile handle. - /** You can use this handle to directly call ZIP part of the - * ZIP/UNZIP package functions (see zip.h). Warnings about the - * getUnzFile() function also apply to this function. - **/ - zipFile getZipFile(); - /// Changes the data descriptor writing mode. - /** - According to the ZIP format specification, a file inside archive - may have a data descriptor immediately following the file - data. This is reflected by a special flag in the local file header - and in the central directory. By default, QuaZIP sets this flag - and writes the data descriptor unless both method and level were - set to 0, in which case it operates in 1.0-compatible mode and - never writes data descriptors. - - By setting this flag to false, it is possible to disable data - descriptor writing, thus increasing compatibility with archive - readers that don't understand this feature of the ZIP file format. - - Setting this flag affects all the QuaZipFile instances that are - opened after this flag is set. - - The data descriptor writing mode is enabled by default. - - \param enabled If \c true, enable local descriptor writing, - disable it otherwise. - - \sa QuaZipFile::setDataDescriptorWritingEnabled() - */ - void setDataDescriptorWritingEnabled(bool enabled); - /// Returns the data descriptor default writing mode. - /** - \sa setDataDescriptorWritingEnabled() - */ - bool isDataDescriptorWritingEnabled() const; - /// Returns a list of files inside the archive. - /** - \return A list of file names or an empty list if there - was an error or if the archive is empty (call getZipError() to - figure out which). - \sa getFileInfoList() - */ - QStringList getFileNameList() const; - /// Returns information list about all files inside the archive. - /** - \return A list of QuaZipFileInfo objects or an empty list if there - was an error or if the archive is empty (call getZipError() to - figure out which). - \sa getFileNameList() - */ - QList getFileInfoList() const; -}; - -#endif diff --git a/interface/external/quazip/include/quazip_global.h b/interface/external/quazip/include/quazip_global.h deleted file mode 100644 index d9d09ade18..0000000000 --- a/interface/external/quazip/include/quazip_global.h +++ /dev/null @@ -1,55 +0,0 @@ -/** -Copyright (C) 2005-2011 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU Lesser 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 Lesser -General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software Foundation, -Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant, see -quazip/(un)zip.h files for details, basically it's zlib license. - */ - -#ifndef QUAZIP_GLOBAL_H -#define QUAZIP_GLOBAL_H - -#include - -/** - This is automatically defined when building a static library, but when - including QuaZip sources directly into a project, QUAZIP_STATIC should - be defined explicitly to avoid possible troubles with unnecessary - importing/exporting. - */ -#ifdef QUAZIP_STATIC -#define QUAZIP_EXPORT -#else -/** - * When building a DLL with MSVC, QUAZIP_BUILD must be defined. - * qglobal.h takes care of defining Q_DECL_* correctly for msvc/gcc. - */ -#if defined(QUAZIP_BUILD) - #define QUAZIP_EXPORT Q_DECL_EXPORT -#else - #define QUAZIP_EXPORT Q_DECL_IMPORT -#endif -#endif // QUAZIP_STATIC - -#ifdef __GNUC__ -#define UNUSED __attribute__((__unused__)) -#else -#define UNUSED -#endif - -#endif // QUAZIP_GLOBAL_H diff --git a/interface/external/quazip/include/quazipdir.h b/interface/external/quazip/include/quazipdir.h deleted file mode 100644 index e2d70bc888..0000000000 --- a/interface/external/quazip/include/quazipdir.h +++ /dev/null @@ -1,171 +0,0 @@ -#ifndef QUAZIP_QUAZIPDIR_H -#define QUAZIP_QUAZIPDIR_H - -class QuaZipDirPrivate; - -#include "quazip.h" -#include "quazipfileinfo.h" -#include -#include -#include - -/// Provides ZIP archive navigation. -/** -* This class is modelled after QDir, and is designed to provide similar -* features for ZIP archives. -* -* The only significant difference from QDir is that the root path is not -* '/', but an empty string since that's how the file paths are stored in -* the archive. However, QuaZipDir understands the paths starting with -* '/'. It is important in a few places: -* -* - In the cd() function. -* - In the constructor. -* - In the exists() function. -* -* Note that since ZIP uses '/' on all platforms, the '\' separator is -* not supported. -*/ -class QUAZIP_EXPORT QuaZipDir { -private: - QSharedDataPointer d; -public: - /// The copy constructor. - QuaZipDir(const QuaZipDir &that); - /// Constructs a QuaZipDir instance pointing to the specified directory. - /** - If \a dir is not specified, points to the root of the archive. - The same happens if the \a dir is "/". - */ - QuaZipDir(QuaZip *zip, const QString &dir = QString()); - /// Destructor. - ~QuaZipDir(); - /// The assignment operator. - bool operator==(const QuaZipDir &that); - /// operator!= - /** - \return \c true if either this and \a that use different QuaZip - instances or if they point to different directories. - */ - inline bool operator!=(const QuaZipDir &that) {return !operator==(that);} - /// operator== - /** - \return \c true if both this and \a that use the same QuaZip - instance and point to the same directory. - */ - QuaZipDir& operator=(const QuaZipDir &that); - /// Returns the name of the entry at the specified position. - QString operator[](int pos) const; - /// Returns the current case sensitivity mode. - QuaZip::CaseSensitivity caseSensitivity() const; - /// Changes the 'current' directory. - /** - * If the path starts with '/', it is interpreted as an absolute - * path from the root of the archive. Otherwise, it is interpreted - * as a path relative to the current directory as was set by the - * previous cd() or the constructor. - * - * Note that the subsequent path() call will not return a path - * starting with '/' in all cases. - */ - bool cd(const QString &dirName); - /// Goes up. - bool cdUp(); - /// Returns the number of entries in the directory. - uint count() const; - /// Returns the current directory name. - /** - The name doesn't include the path. - */ - QString dirName() const; - /// Returns the list of the entries in the directory. - /** - \param nameFilters The list of file patterns to list, uses the same - syntax as QDir. - \param filters The entry type filters, only Files and Dirs are - accepted. - \param sort Sorting mode (not supported yet). - */ - QList entryInfoList(const QStringList &nameFilters, - QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entries in the directory. - /** - \overload - - The same as entryInfoList(QStringList(), filters, sort). - */ - QList entryInfoList(QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entry names in the directory. - /** - The same as entryInfoList(nameFilters, filters, sort), but only - returns entry names. - */ - QStringList entryList(const QStringList &nameFilters, - QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entry names in the directory. - /** - \overload - - The same as entryList(QStringList(), filters, sort). - */ - QStringList entryList(QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns \c true if the entry with the specified name exists. - /** - The ".." is considered to exist if the current directory - is not root. The "." and "/" are considered to - always exist. Paths starting with "/" are relative to - the archive root, other paths are relative to the current dir. - */ - bool exists(const QString &fileName) const; - /// Return \c true if the directory pointed by this QuaZipDir exists. - bool exists() const; - /// Returns the full path to the specified file. - /** - Doesn't check if the file actually exists. - */ - QString filePath(const QString &fileName) const; - /// Returns the default filter. - QDir::Filters filter(); - /// Returns if the QuaZipDir points to the root of the archive. - /** - Not that the root path is the empty string, not '/'. - */ - bool isRoot() const; - /// Return the default name filter. - QStringList nameFilters() const; - /// Returns the path to the current dir. - /** - The path never starts with '/', and the root path is an empty - string. - */ - QString path() const; - /// Returns the path to the specified file relative to the current dir. - QString relativeFilePath(const QString &fileName) const; - /// Sets the default case sensitivity mode. - void setCaseSensitivity(QuaZip::CaseSensitivity caseSensitivity); - /// Sets the default filter. - void setFilter(QDir::Filters filters); - /// Sets the default name filter. - void setNameFilters(const QStringList &nameFilters); - /// Goes to the specified path. - /** - The difference from cd() is that this function never checks if the - path actually exists and doesn't use relative paths, so it's - possible to go to the root directory with setPath(""). - - Note that this function still chops the trailing and/or leading - '/' and treats a single '/' as the root path (path() will still - return an empty string). - */ - void setPath(const QString &path); - /// Sets the default sorting mode. - void setSorting(QDir::SortFlags sort); - /// Returns the default sorting mode. - QDir::SortFlags sorting() const; -}; - -#endif // QUAZIP_QUAZIPDIR_H diff --git a/interface/external/quazip/include/quazipfile.h b/interface/external/quazip/include/quazipfile.h deleted file mode 100644 index f6cc41a6bc..0000000000 --- a/interface/external/quazip/include/quazipfile.h +++ /dev/null @@ -1,442 +0,0 @@ -#ifndef QUA_ZIPFILE_H -#define QUA_ZIPFILE_H - -/* -Copyright (C) 2005-2011 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU Lesser 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 Lesser -General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software Foundation, -Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant, see -quazip/(un)zip.h files for details, basically it's zlib license. - **/ - -#include - -#include "quazip_global.h" -#include "quazip.h" -#include "quazipnewinfo.h" - -class QuaZipFilePrivate; - -/// A file inside ZIP archive. -/** \class QuaZipFile quazipfile.h - * This is the most interesting class. Not only it provides C++ - * interface to the ZIP/UNZIP package, but also integrates it with Qt by - * subclassing QIODevice. This makes possible to access files inside ZIP - * archive using QTextStream or QDataStream, for example. Actually, this - * is the main purpose of the whole QuaZIP library. - * - * You can either use existing QuaZip instance to create instance of - * this class or pass ZIP archive file name to this class, in which case - * it will create internal QuaZip object. See constructors' descriptions - * for details. Writing is only possible with the existing instance. - * - * Note that due to the underlying library's limitation it is not - * possible to use multiple QuaZipFile instances to open several files - * in the same archive at the same time. If you need to write to - * multiple files in parallel, then you should write to temporary files - * first, then pack them all at once when you have finished writing. If - * you need to read multiple files inside the same archive in parallel, - * you should extract them all into a temporary directory first. - * - * \section quazipfile-sequential Sequential or random-access? - * - * At the first thought, QuaZipFile has fixed size, the start and the - * end and should be therefore considered random-access device. But - * there is one major obstacle to making it random-access: ZIP/UNZIP API - * does not support seek() operation and the only way to implement it is - * through reopening the file and re-reading to the required position, - * but this is prohibitively slow. - * - * Therefore, QuaZipFile is considered to be a sequential device. This - * has advantage of availability of the ungetChar() operation (QIODevice - * does not implement it properly for non-sequential devices unless they - * support seek()). Disadvantage is a somewhat strange behaviour of the - * size() and pos() functions. This should be kept in mind while using - * this class. - * - **/ -class QUAZIP_EXPORT QuaZipFile: public QIODevice { - friend class QuaZipFilePrivate; - Q_OBJECT - private: - QuaZipFilePrivate *p; - // these are not supported nor implemented - QuaZipFile(const QuaZipFile& that); - QuaZipFile& operator=(const QuaZipFile& that); - protected: - /// Implementation of the QIODevice::readData(). - qint64 readData(char *data, qint64 maxSize); - /// Implementation of the QIODevice::writeData(). - qint64 writeData(const char *data, qint64 maxSize); - public: - /// Constructs a QuaZipFile instance. - /** You should use setZipName() and setFileName() or setZip() before - * trying to call open() on the constructed object. - **/ - QuaZipFile(); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object. - * - * You should use setZipName() and setFileName() or setZip() before - * trying to call open() on the constructed object. - **/ - QuaZipFile(QObject *parent); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object and \a - * zipName specifies ZIP archive file name. - * - * You should use setFileName() before trying to call open() on the - * constructed object. - * - * QuaZipFile constructed by this constructor can be used for read - * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. - **/ - QuaZipFile(const QString& zipName, QObject *parent =NULL); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object, \a - * zipName specifies ZIP archive file name and \a fileName and \a cs - * specify a name of the file to open inside archive. - * - * QuaZipFile constructed by this constructor can be used for read - * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. - * - * \sa QuaZip::setCurrentFile() - **/ - QuaZipFile(const QString& zipName, const QString& fileName, - QuaZip::CaseSensitivity cs =QuaZip::csDefault, QObject *parent =NULL); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object. - * - * \a zip is the pointer to the existing QuaZip object. This - * QuaZipFile object then can be used to read current file in the - * \a zip or to write to the file inside it. - * - * \warning Using this constructor for reading current file can be - * tricky. Let's take the following example: - * \code - * QuaZip zip("archive.zip"); - * zip.open(QuaZip::mdUnzip); - * zip.setCurrentFile("file-in-archive"); - * QuaZipFile file(&zip); - * file.open(QIODevice::ReadOnly); - * // ok, now we can read from the file - * file.read(somewhere, some); - * zip.setCurrentFile("another-file-in-archive"); // oops... - * QuaZipFile anotherFile(&zip); - * anotherFile.open(QIODevice::ReadOnly); - * anotherFile.read(somewhere, some); // this is still ok... - * file.read(somewhere, some); // and this is NOT - * \endcode - * So, what exactly happens here? When we change current file in the - * \c zip archive, \c file that references it becomes invalid - * (actually, as far as I understand ZIP/UNZIP sources, it becomes - * closed, but QuaZipFile has no means to detect it). - * - * Summary: do not close \c zip object or change its current file as - * long as QuaZipFile is open. Even better - use another constructors - * which create internal QuaZip instances, one per object, and - * therefore do not cause unnecessary trouble. This constructor may - * be useful, though, if you already have a QuaZip instance and do - * not want to access several files at once. Good example: - * \code - * QuaZip zip("archive.zip"); - * zip.open(QuaZip::mdUnzip); - * // first, we need some information about archive itself - * QByteArray comment=zip.getComment(); - * // and now we are going to access files inside it - * QuaZipFile file(&zip); - * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { - * file.open(QIODevice::ReadOnly); - * // do something cool with file here - * file.close(); // do not forget to close! - * } - * zip.close(); - * \endcode - **/ - QuaZipFile(QuaZip *zip, QObject *parent =NULL); - /// Destroys a QuaZipFile instance. - /** Closes file if open, destructs internal QuaZip object (if it - * exists and \em is internal, of course). - **/ - virtual ~QuaZipFile(); - /// Returns the ZIP archive file name. - /** If this object was created by passing QuaZip pointer to the - * constructor, this function will return that QuaZip's file name - * (or null string if that object does not have file name yet). - * - * Otherwise, returns associated ZIP archive file name or null - * string if there are no name set yet. - * - * \sa setZipName() getFileName() - **/ - QString getZipName()const; - /// Returns a pointer to the associated QuaZip object. - /** Returns \c NULL if there is no associated QuaZip or it is - * internal (so you will not mess with it). - **/ - QuaZip* getZip()const; - /// Returns file name. - /** This function returns file name you passed to this object either - * by using - * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) - * or by calling setFileName(). Real name of the file may differ in - * case if you used case-insensitivity. - * - * Returns null string if there is no file name set yet. This is the - * case when this QuaZipFile operates on the existing QuaZip object - * (constructor QuaZipFile(QuaZip*,QObject*) or setZip() was used). - * - * \sa getActualFileName - **/ - QString getFileName() const; - /// Returns case sensitivity of the file name. - /** This function returns case sensitivity argument you passed to - * this object either by using - * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) - * or by calling setFileName(). - * - * Returns unpredictable value if getFileName() returns null string - * (this is the case when you did not used setFileName() or - * constructor above). - * - * \sa getFileName - **/ - QuaZip::CaseSensitivity getCaseSensitivity() const; - /// Returns the actual file name in the archive. - /** This is \em not a ZIP archive file name, but a name of file inside - * archive. It is not necessary the same name that you have passed - * to the - * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*), - * setFileName() or QuaZip::setCurrentFile() - this is the real file - * name inside archive, so it may differ in case if the file name - * search was case-insensitive. - * - * Equivalent to calling getCurrentFileName() on the associated - * QuaZip object. Returns null string if there is no associated - * QuaZip object or if it does not have a current file yet. And this - * is the case if you called setFileName() but did not open the - * file yet. So this is perfectly fine: - * \code - * QuaZipFile file("somezip.zip"); - * file.setFileName("somefile"); - * QString name=file.getName(); // name=="somefile" - * QString actual=file.getActualFileName(); // actual is null string - * file.open(QIODevice::ReadOnly); - * QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows - * \endcode - * - * \sa getZipName(), getFileName(), QuaZip::CaseSensitivity - **/ - QString getActualFileName()const; - /// Sets the ZIP archive file name. - /** Automatically creates internal QuaZip object and destroys - * previously created internal QuaZip object, if any. - * - * Will do nothing if this file is already open. You must close() it - * first. - **/ - void setZipName(const QString& zipName); - /// Returns \c true if the file was opened in raw mode. - /** If the file is not open, the returned value is undefined. - * - * \sa open(OpenMode,int*,int*,bool,const char*) - **/ - bool isRaw() const; - /// Binds to the existing QuaZip instance. - /** This function destroys internal QuaZip object, if any, and makes - * this QuaZipFile to use current file in the \a zip object for any - * further operations. See QuaZipFile(QuaZip*,QObject*) for the - * possible pitfalls. - * - * Will do nothing if the file is currently open. You must close() - * it first. - **/ - void setZip(QuaZip *zip); - /// Sets the file name. - /** Will do nothing if at least one of the following conditions is - * met: - * - ZIP name has not been set yet (getZipName() returns null - * string). - * - This QuaZipFile is associated with external QuaZip. In this - * case you should call that QuaZip's setCurrentFile() function - * instead! - * - File is already open so setting the name is meaningless. - * - * \sa QuaZip::setCurrentFile - **/ - void setFileName(const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault); - /// Opens a file for reading. - /** Returns \c true on success, \c false otherwise. - * Call getZipError() to get error code. - * - * \note Since ZIP/UNZIP API provides buffered reading only, - * QuaZipFile does not support unbuffered reading. So do not pass - * QIODevice::Unbuffered flag in \a mode, or open will fail. - **/ - virtual bool open(OpenMode mode); - /// Opens a file for reading. - /** \overload - * Argument \a password specifies a password to decrypt the file. If - * it is NULL then this function behaves just like open(OpenMode). - **/ - inline bool open(OpenMode mode, const char *password) - {return open(mode, NULL, NULL, false, password);} - /// Opens a file for reading. - /** \overload - * Argument \a password specifies a password to decrypt the file. - * - * An integers pointed by \a method and \a level will receive codes - * of the compression method and level used. See unzip.h. - * - * If raw is \c true then no decompression is performed. - * - * \a method should not be \c NULL. \a level can be \c NULL if you - * don't want to know the compression level. - **/ - bool open(OpenMode mode, int *method, int *level, bool raw, const char *password =NULL); - /// Opens a file for writing. - /** \a info argument specifies information about file. It should at - * least specify a correct file name. Also, it is a good idea to - * specify correct timestamp (by default, current time will be - * used). See QuaZipNewInfo. - * - * The \a password argument specifies the password for crypting. Pass NULL - * if you don't need any crypting. The \a crc argument was supposed - * to be used for crypting too, but then it turned out that it's - * false information, so you need to set it to 0 unless you want to - * use the raw mode (see below). - * - * Arguments \a method and \a level specify compression method and - * level. The only method supported is Z_DEFLATED, but you may also - * specify 0 for no compression. If all of the files in the archive - * use both method 0 and either level 0 is explicitly specified or - * data descriptor writing is disabled with - * QuaZip::setDataDescriptorWritingEnabled(), then the - * resulting archive is supposed to be compatible with the 1.0 ZIP - * format version, should you need that. Except for this, \a level - * has no other effects with method 0. - * - * If \a raw is \c true, no compression is performed. In this case, - * \a crc and uncompressedSize field of the \a info are required. - * - * Arguments \a windowBits, \a memLevel, \a strategy provide zlib - * algorithms tuning. See deflateInit2() in zlib. - **/ - bool open(OpenMode mode, const QuaZipNewInfo& info, - const char *password =NULL, quint32 crc =0, - int method =Z_DEFLATED, int level =Z_DEFAULT_COMPRESSION, bool raw =false, - int windowBits =-MAX_WBITS, int memLevel =DEF_MEM_LEVEL, int strategy =Z_DEFAULT_STRATEGY); - /// Returns \c true, but \ref quazipfile-sequential "beware"! - virtual bool isSequential()const; - /// Returns current position in the file. - /** Implementation of the QIODevice::pos(). When reading, this - * function is a wrapper to the ZIP/UNZIP unztell(), therefore it is - * unable to keep track of the ungetChar() calls (which is - * non-virtual and therefore is dangerous to reimplement). So if you - * are using ungetChar() feature of the QIODevice, this function - * reports incorrect value until you get back characters which you - * ungot. - * - * When writing, pos() returns number of bytes already written - * (uncompressed unless you use raw mode). - * - * \note Although - * \ref quazipfile-sequential "QuaZipFile is a sequential device" - * and therefore pos() should always return zero, it does not, - * because it would be misguiding. Keep this in mind. - * - * This function returns -1 if the file or archive is not open. - * - * Error code returned by getZipError() is not affected by this - * function call. - **/ - virtual qint64 pos()const; - /// Returns \c true if the end of file was reached. - /** This function returns \c false in the case of error. This means - * that you called this function on either not open file, or a file - * in the not open archive or even on a QuaZipFile instance that - * does not even have QuaZip instance associated. Do not do that - * because there is no means to determine whether \c false is - * returned because of error or because end of file was reached. - * Well, on the other side you may interpret \c false return value - * as "there is no file open to check for end of file and there is - * no end of file therefore". - * - * When writing, this function always returns \c true (because you - * are always writing to the end of file). - * - * Error code returned by getZipError() is not affected by this - * function call. - **/ - virtual bool atEnd()const; - /// Returns file size. - /** This function returns csize() if the file is open for reading in - * raw mode, usize() if it is open for reading in normal mode and - * pos() if it is open for writing. - * - * Returns -1 on error, call getZipError() to get error code. - * - * \note This function returns file size despite that - * \ref quazipfile-sequential "QuaZipFile is considered to be sequential device", - * for which size() should return bytesAvailable() instead. But its - * name would be very misguiding otherwise, so just keep in mind - * this inconsistence. - **/ - virtual qint64 size()const; - /// Returns compressed file size. - /** Equivalent to calling getFileInfo() and then getting - * compressedSize field, but more convenient and faster. - * - * File must be open for reading before calling this function. - * - * Returns -1 on error, call getZipError() to get error code. - **/ - qint64 csize()const; - /// Returns uncompressed file size. - /** Equivalent to calling getFileInfo() and then getting - * uncompressedSize field, but more convenient and faster. See - * getFileInfo() for a warning. - * - * File must be open for reading before calling this function. - * - * Returns -1 on error, call getZipError() to get error code. - **/ - qint64 usize()const; - /// Gets information about current file. - /** This function does the same thing as calling - * QuaZip::getCurrentFileInfo() on the associated QuaZip object, - * but you can not call getCurrentFileInfo() if the associated - * QuaZip is internal (because you do not have access to it), while - * you still can call this function in that case. - * - * File must be open for reading before calling this function. - * - * Returns \c false in the case of an error. - **/ - bool getFileInfo(QuaZipFileInfo *info); - /// Closes the file. - /** Call getZipError() to determine if the close was successful. - **/ - virtual void close(); - /// Returns the error code returned by the last ZIP/UNZIP API call. - int getZipError() const; - /// Returns the number of bytes available for reading. - virtual qint64 bytesAvailable() const; -}; - -#endif diff --git a/interface/external/quazip/include/quazipfileinfo.h b/interface/external/quazip/include/quazipfileinfo.h deleted file mode 100644 index 327425f13e..0000000000 --- a/interface/external/quazip/include/quazipfileinfo.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef QUA_ZIPFILEINFO_H -#define QUA_ZIPFILEINFO_H - -/* -Copyright (C) 2005-2011 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU Lesser 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 Lesser -General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software Foundation, -Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant, see -quazip/(un)zip.h files for details, basically it's zlib license. - **/ - -#include -#include -#include - -#include "quazip_global.h" - -/// Information about a file inside archive. -/** Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to - * fill this structure. */ -struct QUAZIP_EXPORT QuaZipFileInfo { - /// File name. - QString name; - /// Version created by. - quint16 versionCreated; - /// Version needed to extract. - quint16 versionNeeded; - /// General purpose flags. - quint16 flags; - /// Compression method. - quint16 method; - /// Last modification date and time. - QDateTime dateTime; - /// CRC. - quint32 crc; - /// Compressed file size. - quint32 compressedSize; - /// Uncompressed file size. - quint32 uncompressedSize; - /// Disk number start. - quint16 diskNumberStart; - /// Internal file attributes. - quint16 internalAttr; - /// External file attributes. - quint32 externalAttr; - /// Comment. - QString comment; - /// Extra field. - QByteArray extra; - /// Get the file permissions. - /** - Returns the high 16 bits of external attributes converted to - QFile::Permissions. - */ - QFile::Permissions getPermissions() const; -}; - -#endif diff --git a/interface/external/quazip/include/quazipnewinfo.h b/interface/external/quazip/include/quazipnewinfo.h deleted file mode 100644 index cd321c2712..0000000000 --- a/interface/external/quazip/include/quazipnewinfo.h +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef QUA_ZIPNEWINFO_H -#define QUA_ZIPNEWINFO_H - -/* -Copyright (C) 2005-2011 Sergey A. Tachenov - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU Lesser 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 Lesser -General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software Foundation, -Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant, see -quazip/(un)zip.h files for details, basically it's zlib license. - **/ - -#include -#include - -#include "quazip_global.h" - -/// Information about a file to be created. -/** This structure holds information about a file to be created inside - * ZIP archive. At least name should be set to something correct before - * passing this structure to - * QuaZipFile::open(OpenMode,const QuaZipNewInfo&,int,int,bool). - **/ -struct QUAZIP_EXPORT QuaZipNewInfo { - /// File name. - /** This field holds file name inside archive, including path relative - * to archive root. - **/ - QString name; - /// File timestamp. - /** This is the last file modification date and time. Will be stored - * in the archive central directory. It is a good practice to set it - * to the source file timestamp instead of archive creating time. Use - * setFileDateTime() or QuaZipNewInfo(const QString&, const QString&). - **/ - QDateTime dateTime; - /// File internal attributes. - quint16 internalAttr; - /// File external attributes. - /** - The highest 16 bits contain Unix file permissions and type (dir or - file). The constructor QuaZipNewInfo(const QString&, const QString&) - takes permissions from the provided file. - */ - quint32 externalAttr; - /// File comment. - /** Will be encoded using QuaZip::getCommentCodec(). - **/ - QString comment; - /// File local extra field. - QByteArray extraLocal; - /// File global extra field. - QByteArray extraGlobal; - /// Uncompressed file size. - /** This is only needed if you are using raw file zipping mode, i. e. - * adding precompressed file in the zip archive. - **/ - ulong uncompressedSize; - /// Constructs QuaZipNewInfo instance. - /** Initializes name with \a name, dateTime with current date and - * time. Attributes are initialized with zeros, comment and extra - * field with null values. - **/ - QuaZipNewInfo(const QString& name); - /// Constructs QuaZipNewInfo instance. - /** Initializes name with \a name. Timestamp and permissions are taken - * from the specified file. If the \a file does not exists or its timestamp - * is inaccessible (e. g. you do not have read permission for the - * directory file in), uses current time and zero permissions. Other attributes are - * initialized with zeros, comment and extra field with null values. - * - * \sa setFileDateTime() - **/ - QuaZipNewInfo(const QString& name, const QString& file); - /// Sets the file timestamp from the existing file. - /** Use this function to set the file timestamp from the existing - * file. Use it like this: - * \code - * QuaZipFile zipFile(&zip); - * QFile file("file-to-add"); - * file.open(QIODevice::ReadOnly); - * QuaZipNewInfo info("file-name-in-archive"); - * info.setFileDateTime("file-to-add"); // take the timestamp from file - * zipFile.open(QIODevice::WriteOnly, info); - * \endcode - * - * This function does not change dateTime if some error occured (e. g. - * file is inaccessible). - **/ - void setFileDateTime(const QString& file); - /// Sets the file permissions from the existing file. - /** - Takes permissions from the file and sets the high 16 bits of - external attributes. Uses QFileInfo to get permissions on all - platforms. - */ - void setFilePermissions(const QString &file); - /// Sets the file permissions. - /** - Modifies the highest 16 bits of external attributes. The type part - is set to dir if the name ends with a slash, and to regular file - otherwise. - */ - void setPermissions(QFile::Permissions permissions); -}; - -#endif diff --git a/interface/external/quazip/include/unzip.h b/interface/external/quazip/include/unzip.h deleted file mode 100644 index 33c9dc1ab3..0000000000 --- a/interface/external/quazip/include/unzip.h +++ /dev/null @@ -1,356 +0,0 @@ -/* unzip.h -- IO for uncompress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - - Multi volume ZipFile (span) are not supported. - Encryption compatible with pkzip 2.04g only supported - Old compressions used by old PKZip 1.x are not supported - - - I WAIT FEEDBACK at mail info@winimage.com - Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Modified by Sergey A. Tachenov to integrate with Qt. - - -*/ - -/* for more info about .ZIP format, see - http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip - http://www.info-zip.org/pub/infozip/doc/ - PkWare has also a specification at : - ftp://ftp.pkware.com/probdesc.zip -*/ - -#ifndef _unz_H -#define _unz_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ZLIB_H -#include "zlib.h" -#endif - -#ifndef _ZLIBIOAPI_H -#include "ioapi.h" -#endif - -#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagunzFile__ { int unused; } unzFile__; -typedef unzFile__ *unzFile; -#else -typedef voidp unzFile; -#endif - - -#define UNZ_OK (0) -#define UNZ_END_OF_LIST_OF_FILE (-100) -#define UNZ_ERRNO (Z_ERRNO) -#define UNZ_EOF (0) -#define UNZ_PARAMERROR (-102) -#define UNZ_BADZIPFILE (-103) -#define UNZ_INTERNALERROR (-104) -#define UNZ_CRCERROR (-105) - -/* tm_unz contain date/time info */ -typedef struct tm_unz_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_unz; - -/* unz_global_info structure contain global data about the ZIPfile - These data comes from the end of central dir */ -typedef struct unz_global_info_s -{ - uLong number_entry; /* total number of entries in - the central dir on this disk */ - uLong size_comment; /* size of the global comment of the zipfile */ -} unz_global_info; - - -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_info_s -{ - uLong version; /* version made by 2 bytes */ - uLong version_needed; /* version needed to extract 2 bytes */ - uLong flag; /* general purpose bit flag 2 bytes */ - uLong compression_method; /* compression method 2 bytes */ - uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ - uLong crc; /* crc-32 4 bytes */ - uLong compressed_size; /* compressed size 4 bytes */ - uLong uncompressed_size; /* uncompressed size 4 bytes */ - uLong size_filename; /* filename length 2 bytes */ - uLong size_file_extra; /* extra field length 2 bytes */ - uLong size_file_comment; /* file comment length 2 bytes */ - - uLong disk_num_start; /* disk number start 2 bytes */ - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ - - tm_unz tmu_date; -} unz_file_info; - -extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, - const char* fileName2, - int iCaseSensitivity)); -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) -*/ - - -extern unzFile ZEXPORT unzOpen OF((voidpf file)); -/* - Open a Zip file. path contain whatever zopen_file from the IO API - accepts. For Qt implementation it is a pointer to QIODevice, for - fopen() implementation it's a file name. - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ - -extern unzFile ZEXPORT unzOpen2 OF((voidpf file, - zlib_filefunc_def* pzlib_filefunc_def)); -/* - Open a Zip file, like unzOpen, but provide a set of file low level API - for read/write the zip file (see ioapi.h) -*/ - -extern int ZEXPORT unzClose OF((unzFile file)); -/* - Close a ZipFile opened with unzipOpen. - If there is files inside the .Zip opened with unzOpenCurrentFile (see later), - these files MUST be closed with unzipCloseCurrentFile before call unzipClose. - return UNZ_OK if there is no problem. */ - -extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, - unz_global_info *pglobal_info)); -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ - - -extern int ZEXPORT unzGetGlobalComment OF((unzFile file, - char *szComment, - uLong uSizeBuf)); -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ - - -/***************************************************************************/ -/* Unzip package allow you browse the directory of the zipfile */ - -extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ - -extern int ZEXPORT unzGoToNextFile OF((unzFile file)); -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ - -extern int ZEXPORT unzLocateFile OF((unzFile file, - const char *szFileName, - int iCaseSensitivity)); -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ - - -/* ****************************************** */ -/* Ryan supplied functions */ -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; /* offset in zip file directory */ - uLong num_of_file; /* # of file */ -} unz_file_pos; - -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos); - -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos); - -/* ****************************************** */ - -extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, - unz_file_info *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); -/* - Get Info about the current file - if pfile_info!=NULL, the *pfile_info structure will contain somes info about - the current file - if szFileName!=NULL, the filemane string will be copied in szFileName - (fileNameBufferSize is the size of the buffer) - if extraField!=NULL, the extra field information will be copied in extraField - (extraFieldBufferSize is the size of the buffer). - This is the Central-header version of the extra field - if szComment!=NULL, the comment string of the file will be copied in szComment - (commentBufferSize is the size of the buffer) -*/ - -/***************************************************************************/ -/* for reading the content of the current zipfile, you can open it, read data - from it, and close it (you can close it before reading all the file) - */ - -extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); -/* - Open for reading data the current file in the zipfile. - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, - const char* password)); -/* - Open for reading data the current file in the zipfile. - password is a crypting password - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, - int* method, - int* level, - int raw)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - -extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, - int* method, - int* level, - int raw, - const char* password)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - - -extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); -/* - Close the file in zip opened with unzOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ - -extern int ZEXPORT unzReadCurrentFile OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read bytes from the current file (opened by unzOpenCurrentFile) - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ - -extern z_off_t ZEXPORT unztell OF((unzFile file)); -/* - Give the current position in uncompressed data -*/ - -extern int ZEXPORT unzeof OF((unzFile file)); -/* - return 1 if the end of file was reached, 0 elsewhere -*/ - -extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ - -/***************************************************************************/ - -/* Get the current file offset */ -extern uLong ZEXPORT unzGetOffset (unzFile file); - -/* Set the current file offset */ -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); - - - -#ifdef __cplusplus -} -#endif - -#endif /* _unz_H */ diff --git a/interface/external/quazip/include/zip.h b/interface/external/quazip/include/zip.h deleted file mode 100644 index 269ec2dace..0000000000 --- a/interface/external/quazip/include/zip.h +++ /dev/null @@ -1,245 +0,0 @@ -/* zip.h -- IO for compress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This unzip package allow creates .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - Multi volume ZipFile (span) are not supported. - Encryption compatible with pkzip 2.04g only supported - Old compressions used by old PKZip 1.x are not supported - - For uncompress .zip file, look at unzip.h - - - I WAIT FEEDBACK at mail info@winimage.com - Visit also http://www.winimage.com/zLibDll/unzip.html for evolution - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Modified by Sergey A. Tachenov to integrate with Qt. - - -*/ - -/* for more info about .ZIP format, see - http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip - http://www.info-zip.org/pub/infozip/doc/ - PkWare has also a specification at : - ftp://ftp.pkware.com/probdesc.zip -*/ - -#ifndef _zip_H -#define _zip_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ZLIB_H -#include "zlib.h" -#endif - -#ifndef _ZLIBIOAPI_H -#include "ioapi.h" -#endif - -#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagzipFile__ { int unused; } zipFile__; -typedef zipFile__ *zipFile; -#else -typedef voidp zipFile; -#endif - -#define ZIP_OK (0) -#define ZIP_EOF (0) -#define ZIP_ERRNO (Z_ERRNO) -#define ZIP_PARAMERROR (-102) -#define ZIP_BADZIPFILE (-103) -#define ZIP_INTERNALERROR (-104) - -#define ZIP_WRITE_DATA_DESCRIPTOR 0x8u - -#ifndef DEF_MEM_LEVEL -# if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -# else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -# endif -#endif -/* default memLevel */ - -/* tm_zip contain date/time info */ -typedef struct tm_zip_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_zip; - -typedef struct -{ - tm_zip tmz_date; /* date in understandable format */ - uLong dosDate; /* if dos_date == 0, tmu_date is used */ -/* uLong flag; */ /* general purpose bit flag 2 bytes */ - - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ -} zip_fileinfo; - -typedef const char* zipcharpc; - - -#define APPEND_STATUS_CREATE (0) -#define APPEND_STATUS_CREATEAFTER (1) -#define APPEND_STATUS_ADDINZIP (2) - -extern zipFile ZEXPORT zipOpen OF((voidpf file, int append)); -/* - Create a zipfile. - file is whatever the IO API accepts. For Qt IO API it's a pointer to - QIODevice. For fopen() IO API it's a file name (const char*). - if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip - will be created at the end of the file. - (useful if the file contain a self extractor code) - if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will - add files in existing zip (be sure you don't add file that doesn't exist) - If the zipfile cannot be opened, the return value is NULL. - Else, the return value is a zipFile Handle, usable with other function - of this zip package. -*/ - -/* Note : there is no delete function into a zipfile. - If you want delete file into a zipfile, you must open a zipfile, and create another - Of couse, you can use RAW reading and writing to copy the file you did not want delte -*/ - -extern zipFile ZEXPORT zipOpen2 OF((voidpf file, - int append, - zipcharpc* globalcomment, - zlib_filefunc_def* pzlib_filefunc_def)); - -extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level)); -/* - Open a file in the ZIP for writing. - filename : the filename in zip (if NULL, '-' without quote will be used - *zipfi contain supplemental information - if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local - contains the extrafield data the the local header - if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global - contains the extrafield data the the local header - if comment != NULL, comment contain the comment string - method contain the compression method (0 for store, Z_DEFLATED for deflate) - level contain the level of compression (can be Z_DEFAULT_COMPRESSION) -*/ - - -extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw)); - -/* - Same than zipOpenNewFileInZip, except if raw=1, we write raw file - */ - -extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCtypting)); - -/* - Same than zipOpenNewFileInZip2, except - windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 - password : crypting password (NULL for no crypting) - crcForCtypting : crc of file to compress (needed for crypting) - */ - - -extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, - const void* buf, - unsigned len)); -/* - Write data in the zipfile -*/ - -extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); -/* - Close the current file in the zipfile -*/ - -extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, - uLong uncompressed_size, - uLong crc32)); -/* - Close the current file in the zipfile, for fiel opened with - parameter raw=1 in zipOpenNewFileInZip2 - uncompressed_size and crc32 are value for the uncompressed size -*/ - -extern int ZEXPORT zipClose OF((zipFile file, - const char* global_comment)); -/* - Close the zipfile -*/ - -/* - Added by Sergey A. Tachenov to tweak zipping behaviour. - */ -extern int ZEXPORT zipSetFlags(zipFile file, unsigned flags); -extern int ZEXPORT zipClearFlags(zipFile file, unsigned flags); - -#ifdef __cplusplus -} -#endif - -#endif /* _zip_H */ diff --git a/interface/external/quazip/lib/MacOS/libquazip.a b/interface/external/quazip/lib/MacOS/libquazip.a deleted file mode 100644 index 6008f9f6122e840def67337c66db9e7806397a98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 224800 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