mirror of
https://github.com/QuasarApp/installer-framework.git
synced 2025-05-10 03:59:32 +00:00
Merge remote-tracking branch 'origin/1.4' into 1.5
Change-Id: Ib2d382d1aa398b642dc15f4df7c03b19bf638546
This commit is contained in:
commit
7778787b91
@ -1,3 +1,11 @@
|
|||||||
|
1.4.1
|
||||||
|
- Added support to pass a query string when downloading archives. (QTIFW-329)
|
||||||
|
- Fixed progress display for redirected HTTP Downloads. (QTIFW-267)
|
||||||
|
- Add support to repogen to update only newer components. (QTIFW-234)
|
||||||
|
- Added more autotests.
|
||||||
|
- Improved documentation.
|
||||||
|
- Minor bugfixes.
|
||||||
|
|
||||||
1.4
|
1.4
|
||||||
- Force updating of Essential components. (QTIFW-38, QTIFW-155)
|
- Force updating of Essential components. (QTIFW-38, QTIFW-155)
|
||||||
- Display release date in Updater and Packagemanager. (QTIFW-25)
|
- Display release date in Updater and Packagemanager. (QTIFW-25)
|
||||||
@ -41,6 +49,7 @@
|
|||||||
- Minor documentation fixes and additions.
|
- Minor documentation fixes and additions.
|
||||||
- Added more autotests.
|
- Added more autotests.
|
||||||
- Bugfixes
|
- Bugfixes
|
||||||
|
- Added Japanese translation.
|
||||||
- Updated translations
|
- Updated translations
|
||||||
- Cleaned up the Code.
|
- Cleaned up the Code.
|
||||||
|
|
||||||
|
@ -199,10 +199,10 @@
|
|||||||
\o Filename for a watermark used as \a QWizard::WatermarkPixmap.
|
\o Filename for a watermark used as \a QWizard::WatermarkPixmap.
|
||||||
\row
|
\row
|
||||||
\o Banner
|
\o Banner
|
||||||
\o Filename for a banner used as \a QWizard::BannerPixmap.
|
\o Filename for a banner used as \a QWizard::BannerPixmap (only used by ModernStyle).
|
||||||
\row
|
\row
|
||||||
\o Background
|
\o Background
|
||||||
\o Filename for an image used as \a QWizard::BackgroundPixmap.
|
\o Filename for an image used as \a QWizard::BackgroundPixmap (only used by MacStyle).
|
||||||
\row
|
\row
|
||||||
\o RunProgram
|
\o RunProgram
|
||||||
\o Command executed after the installer is done if the user accepts
|
\o Command executed after the installer is done if the user accepts
|
||||||
@ -265,6 +265,10 @@
|
|||||||
\o List of language codes to be used for translating the user interface. To add several language
|
\o List of language codes to be used for translating the user interface. To add several language
|
||||||
variants, specify several Translation sections that each specify the name of a language
|
variants, specify several Translation sections that each specify the name of a language
|
||||||
variant. Optional. For more information, see \l{Translating Pages}.
|
variant. Optional. For more information, see \l{Translating Pages}.
|
||||||
|
\row
|
||||||
|
\o UrlQueryString
|
||||||
|
\o This string needs to be in the form "key=value" and will be appended to archive download
|
||||||
|
requests. This can be used to transmit information to the webserver hosting the repository.
|
||||||
|
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
@ -445,6 +449,7 @@
|
|||||||
\row
|
\row
|
||||||
\o Virtual
|
\o Virtual
|
||||||
\o Set to \c true to hide the component from the installer.
|
\o Set to \c true to hide the component from the installer.
|
||||||
|
Note that setting this on a root component does not work.
|
||||||
\row
|
\row
|
||||||
\o SortingPriority
|
\o SortingPriority
|
||||||
\o Priority of the component in the tree. The tree is sorted from
|
\o Priority of the component in the tree. The tree is sorted from
|
||||||
@ -1007,34 +1012,35 @@
|
|||||||
Updates.xml file in the current repository. You can add, replace, or remove
|
Updates.xml file in the current repository. You can add, replace, or remove
|
||||||
repositories.
|
repositories.
|
||||||
|
|
||||||
\section2 Adding Repositories
|
|
||||||
To update a repository, add the following code to Updates.xml:
|
|
||||||
|
|
||||||
\code
|
\code
|
||||||
<RepositoryUpdate>
|
<RepositoryUpdate>
|
||||||
<Repository action="add" url="http://www.example.com/repository" name="user" password="password"
|
<Repository action="..." OPTIONS />
|
||||||
displayname="Example Repository" />
|
<Repository action="..." OPTIONS />
|
||||||
</RepositoryUpdate>
|
</RepositoryUpdate>
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
|
\section2 Adding Repositories
|
||||||
|
To update a repository, add the following code to the RepositoryUpdate section:
|
||||||
|
|
||||||
|
\code
|
||||||
|
<Repository action="add" url="http://www.example.com/repository" name="user" password="password"
|
||||||
|
displayname="Example Repository" />
|
||||||
|
\endcode
|
||||||
|
|
||||||
\section2 Removing Repositories
|
\section2 Removing Repositories
|
||||||
To remove a repository, add the following code to Updates.xml:
|
To remove a repository, add the following code to the RepositoryUpdate section:
|
||||||
|
|
||||||
\code
|
\code
|
||||||
<RepositoryUpdate>
|
<Repository action="remove" url="http://www.example.com/repository" />
|
||||||
<Repository action="remove" url="http://www.example.com/repository" />
|
|
||||||
</RepositoryUpdate>
|
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
\section2 Replacing repositories
|
\section2 Replacing repositories
|
||||||
To replace one repository with another, add the following code to Updates.xml:
|
To replace one repository with another, add the following code to the RepositoryUpdate section:
|
||||||
|
|
||||||
\code
|
\code
|
||||||
<RepositoryUpdate>
|
<Repository action="replace" oldurl="http://www.example.com/repository"
|
||||||
<Repository action="replace" oldurl="http://www.example.com/repository"
|
newurl="http://www.example.com/newrepository" name="user" password="password"
|
||||||
newurl="http://www.example.com/newrepository" name="user" password="password"
|
displayname="New Example Repository" />
|
||||||
displayname="New Example Repository" />
|
|
||||||
</RepositoryUpdate>
|
|
||||||
\endcode
|
\endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -56,6 +56,9 @@ unix:INCLUDEPATH += $$IFW_SOURCE_TREE/src/libs/7zip/unix/CPP
|
|||||||
LIBS += -L$$IFW_LIB_PATH
|
LIBS += -L$$IFW_LIB_PATH
|
||||||
# The order is important. The linker needs to parse archives in reversed dependency order.
|
# The order is important. The linker needs to parse archives in reversed dependency order.
|
||||||
equals(TEMPLATE, app):LIBS += -linstaller
|
equals(TEMPLATE, app):LIBS += -linstaller
|
||||||
|
win32:equals(TEMPLATE, app) {
|
||||||
|
LIBS += -luser32
|
||||||
|
}
|
||||||
unix:!macx:LIBS += -lutil
|
unix:!macx:LIBS += -lutil
|
||||||
macx:LIBS += -framework Carbon -framework Security
|
macx:LIBS += -framework Carbon -framework Security
|
||||||
|
|
||||||
@ -106,6 +109,9 @@ static {
|
|||||||
LIBS += -l7z
|
LIBS += -l7z
|
||||||
win32-g++*: LIBS += -lmpr -luuid
|
win32-g++*: LIBS += -lmpr -luuid
|
||||||
|
|
||||||
win32:exists($$IFW_LIB_PATH/installer.lib):POST_TARGETDEPS += $$IFW_LIB_PATH/installer.lib
|
equals(TEMPLATE, app) {
|
||||||
unix:exists($$IFW_LIB_PATH/libinstaller.a):POST_TARGETDEPS += $$IFW_LIB_PATH/libinstaller.a
|
win32-msvc*:POST_TARGETDEPS += $$IFW_LIB_PATH/installer.lib $$IFW_LIB_PATH/7z.lib
|
||||||
|
win32-g++*:POST_TARGETDEPS += $$IFW_LIB_PATH/libinstaller.a $$IFW_LIB_PATH/lib7z.a
|
||||||
|
unix:POST_TARGETDEPS += $$IFW_LIB_PATH/libinstaller.a $$IFW_LIB_PATH/lib7z.a
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
include(../../../installerfw.pri)
|
|
||||||
|
|
||||||
QT = core
|
QT = core
|
||||||
TARGET = 7z
|
TARGET = 7z
|
||||||
TEMPLATE = lib
|
TEMPLATE = lib
|
||||||
|
include(../../../installerfw.pri)
|
||||||
INCLUDEPATH += . ..
|
INCLUDEPATH += . ..
|
||||||
CONFIG += staticlib
|
CONFIG += staticlib
|
||||||
DESTDIR = $$IFW_LIB_PATH
|
DESTDIR = $$IFW_LIB_PATH
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
using namespace QInstaller;
|
using namespace QInstaller;
|
||||||
using namespace QInstallerCreator;
|
using namespace QInstallerCreator;
|
||||||
@ -220,33 +221,26 @@ qint64 QInstaller::findMagicCookie(QFile *in, quint64 magicCookie)
|
|||||||
Q_ASSERT(in);
|
Q_ASSERT(in);
|
||||||
Q_ASSERT(in->isOpen());
|
Q_ASSERT(in->isOpen());
|
||||||
Q_ASSERT(in->isReadable());
|
Q_ASSERT(in->isReadable());
|
||||||
const qint64 oldPos = in->pos();
|
|
||||||
const qint64 MAX_SEARCH = 1024 * 1024; // stop searching after one MB
|
const qint64 fileSize = in->size();
|
||||||
qint64 searched = 0;
|
const size_t markerSize = sizeof(qint64);
|
||||||
try {
|
|
||||||
while (searched < MAX_SEARCH) {
|
// Search through 1MB, if smaller through the whole file. Note: QFile::map() does not change QFile::pos().
|
||||||
const qint64 pos = in->size() - searched - sizeof(qint64);
|
const qint64 maxSearch = qMin((1024LL * 1024LL), fileSize);
|
||||||
if (pos < 0)
|
const uchar *const mapped = in->map(fileSize - maxSearch, maxSearch);
|
||||||
throw Error(QObject::tr("Searched whole file, no marker found"));
|
if (!mapped) {
|
||||||
if (!in->seek(pos)) {
|
throw Error(QObject::tr("Could not map %1 from file %2: %3").arg(QString::number(maxSearch),
|
||||||
throw Error(QObject::tr("Could not seek to %1 in file %2: %3").arg(QString::number(pos),
|
in->fileName(), in->errorString()));
|
||||||
in->fileName(), in->errorString()));
|
|
||||||
}
|
|
||||||
const quint64 num = static_cast<quint64>(retrieveInt64(in));
|
|
||||||
if (num == magicCookie) {
|
|
||||||
in->seek(oldPos);
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
searched += 1;
|
|
||||||
}
|
|
||||||
throw Error(QObject::tr("No marker found, stopped after %1.").arg(humanReadableSize(MAX_SEARCH)));
|
|
||||||
} catch (const Error& err) {
|
|
||||||
in->seek(oldPos);
|
|
||||||
throw err;
|
|
||||||
} catch (...) {
|
|
||||||
in->seek(oldPos);
|
|
||||||
throw Error(QObject::tr("No marker found, unknown exception caught."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qint64 searched = maxSearch - markerSize;
|
||||||
|
while (searched >= 0) {
|
||||||
|
if (memcmp(&magicCookie, (mapped + searched), markerSize) == 0)
|
||||||
|
return (fileSize - maxSearch) + searched;
|
||||||
|
--searched;
|
||||||
|
}
|
||||||
|
throw Error(QObject::tr("No marker found, stopped after %1.").arg(humanReadableSize(maxSearch)));
|
||||||
|
|
||||||
return -1; // never reached
|
return -1; // never reached
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -802,7 +796,7 @@ BinaryContentPrivate::BinaryContentPrivate(const BinaryContentPrivate &other)
|
|||||||
BinaryContentPrivate::~BinaryContentPrivate()
|
BinaryContentPrivate::~BinaryContentPrivate()
|
||||||
{
|
{
|
||||||
foreach (const QByteArray &rccData, m_resourceMappings)
|
foreach (const QByteArray &rccData, m_resourceMappings)
|
||||||
QResource::unregisterResource((const uchar*)rccData.constData());
|
QResource::unregisterResource((const uchar*)rccData.constData(), QLatin1String(":/metadata"));
|
||||||
m_resourceMappings.clear();
|
m_resourceMappings.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1143,6 +1137,29 @@ int BinaryContent::registerEmbeddedQResources()
|
|||||||
return d->m_resourceMappings.count();
|
return d->m_resourceMappings.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Registers the passed file as default resource content. If the embedded resources are already mapped into
|
||||||
|
memory, it will replace the first with the new content.
|
||||||
|
*/
|
||||||
|
void BinaryContent::registerAsDefaultQResource(const QString &path)
|
||||||
|
{
|
||||||
|
QFile resource(path);
|
||||||
|
bool success = resource.open(QIODevice::ReadOnly);
|
||||||
|
if (success && (d->m_resourceMappings.count() > 0)) {
|
||||||
|
success = QResource::unregisterResource((const uchar*)d->m_resourceMappings.first().constData(),
|
||||||
|
QLatin1String(":/metadata"));
|
||||||
|
if (success)
|
||||||
|
d->m_resourceMappings.remove(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
d->m_resourceMappings.prepend(addResourceFromBinary(&resource, Range<qint64>::fromStartAndEnd(0,
|
||||||
|
resource.size())));
|
||||||
|
} else {
|
||||||
|
qWarning() << QString::fromLatin1("Could not register '%1' as default resource.").arg(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the binary component index as read from the file.
|
Returns the binary component index as read from the file.
|
||||||
*/
|
*/
|
||||||
|
@ -242,6 +242,7 @@ public:
|
|||||||
|
|
||||||
qint64 magicMarker() const;
|
qint64 magicMarker() const;
|
||||||
int registerEmbeddedQResources();
|
int registerEmbeddedQResources();
|
||||||
|
void registerAsDefaultQResource(const QString &path);
|
||||||
QInstallerCreator::ComponentIndex componentIndex() const;
|
QInstallerCreator::ComponentIndex componentIndex() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -211,6 +211,7 @@ Component::Component(PackageManagerCore *core)
|
|||||||
setPrivate(d);
|
setPrivate(d);
|
||||||
|
|
||||||
connect(this, SIGNAL(valueChanged(QString, QString)), this, SLOT(updateModelData(QString, QString)));
|
connect(this, SIGNAL(valueChanged(QString, QString)), this, SLOT(updateModelData(QString, QString)));
|
||||||
|
qRegisterMetaType<QList<QInstaller::Component*> >("QList<QInstaller::Component*>");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -899,6 +900,7 @@ OperationList Component::operations() const
|
|||||||
if (!d->m_minimumProgressOperation) {
|
if (!d->m_minimumProgressOperation) {
|
||||||
d->m_minimumProgressOperation = KDUpdater::UpdateOperationFactory::instance()
|
d->m_minimumProgressOperation = KDUpdater::UpdateOperationFactory::instance()
|
||||||
.create(QLatin1String("MinimumProgress"));
|
.create(QLatin1String("MinimumProgress"));
|
||||||
|
d->m_minimumProgressOperation->setValue(QLatin1String("component"), name());
|
||||||
d->m_operations.append(d->m_minimumProgressOperation);
|
d->m_operations.append(d->m_minimumProgressOperation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -906,6 +908,7 @@ OperationList Component::operations() const
|
|||||||
d->m_licenseOperation = KDUpdater::UpdateOperationFactory::instance()
|
d->m_licenseOperation = KDUpdater::UpdateOperationFactory::instance()
|
||||||
.create(QLatin1String("License"));
|
.create(QLatin1String("License"));
|
||||||
d->m_licenseOperation->setValue(QLatin1String("installer"), QVariant::fromValue(d->m_core));
|
d->m_licenseOperation->setValue(QLatin1String("installer"), QVariant::fromValue(d->m_core));
|
||||||
|
d->m_licenseOperation->setValue(QLatin1String("component"), name());
|
||||||
|
|
||||||
QVariantMap licenses;
|
QVariantMap licenses;
|
||||||
const QList<QPair<QString, QString> > values = d->m_licenses.values();
|
const QList<QPair<QString, QString> > values = d->m_licenses.values();
|
||||||
|
@ -182,7 +182,7 @@ void DownloadArchivesJob::fetchNextArchive()
|
|||||||
if (m_downloader != 0)
|
if (m_downloader != 0)
|
||||||
m_downloader->deleteLater();
|
m_downloader->deleteLater();
|
||||||
|
|
||||||
m_downloader = setupDownloader();
|
m_downloader = setupDownloader(QString(), m_core->value(QLatin1String("UrlQueryString")));
|
||||||
if (!m_downloader) {
|
if (!m_downloader) {
|
||||||
m_archivesToDownload.removeFirst();
|
m_archivesToDownload.removeFirst();
|
||||||
QMetaObject::invokeMethod(this, "fetchNextArchive", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(this, "fetchNextArchive", Qt::QueuedConnection);
|
||||||
@ -292,13 +292,16 @@ void DownloadArchivesJob::finishWithError(const QString &error)
|
|||||||
emitFinishedWithError(QInstaller::DownloadError, msg.arg(error, m_downloader->url().toString()));
|
emitFinishedWithError(QInstaller::DownloadError, msg.arg(error, m_downloader->url().toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
KDUpdater::FileDownloader *DownloadArchivesJob::setupDownloader(const QString &suffix)
|
KDUpdater::FileDownloader *DownloadArchivesJob::setupDownloader(const QString &suffix, const QString &queryString)
|
||||||
{
|
{
|
||||||
KDUpdater::FileDownloader *downloader = 0;
|
KDUpdater::FileDownloader *downloader = 0;
|
||||||
const QFileInfo fi = QFileInfo(m_archivesToDownload.first().first);
|
const QFileInfo fi = QFileInfo(m_archivesToDownload.first().first);
|
||||||
const Component *const component = m_core->componentByName(QFileInfo(fi.path()).fileName());
|
const Component *const component = m_core->componentByName(QFileInfo(fi.path()).fileName());
|
||||||
if (component) {
|
if (component) {
|
||||||
const QUrl url(m_archivesToDownload.first().second + suffix);
|
QString fullQueryString;
|
||||||
|
if (!queryString.isEmpty())
|
||||||
|
fullQueryString = QLatin1String("?") + queryString;
|
||||||
|
const QUrl url(m_archivesToDownload.first().second + suffix + fullQueryString);
|
||||||
const QString &scheme = url.scheme();
|
const QString &scheme = url.scheme();
|
||||||
downloader = FileDownloaderFactory::instance().create(scheme, this);
|
downloader = FileDownloaderFactory::instance().create(scheme, this);
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ protected Q_SLOTS:
|
|||||||
void emitDownloadProgress(double progress);
|
void emitDownloadProgress(double progress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KDUpdater::FileDownloader *setupDownloader(const QString &suffix = QString());
|
KDUpdater::FileDownloader *setupDownloader(const QString &suffix = QString(), const QString &queryString = QString());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PackageManagerCore *m_core;
|
PackageManagerCore *m_core;
|
||||||
|
@ -75,13 +75,12 @@ bool ExtractArchiveOperation::performOperation()
|
|||||||
Receiver receiver;
|
Receiver receiver;
|
||||||
Callback callback;
|
Callback callback;
|
||||||
|
|
||||||
// usually we have to connect it as queued connection but then some blocking work is in the main thread
|
connect(&callback, SIGNAL(currentFileChanged(QString)), this, SLOT(fileFinished(QString)));
|
||||||
connect(&callback, SIGNAL(progressChanged(QString)), this, SLOT(slotProgressChanged(QString)),
|
connect(&callback, SIGNAL(progressChanged(double)), this, SIGNAL(progressChanged(double)));
|
||||||
Qt::DirectConnection);
|
|
||||||
|
|
||||||
if (PackageManagerCore *core = this->value(QLatin1String("installer")).value<PackageManagerCore*>()) {
|
if (PackageManagerCore *core = this->value(QLatin1String("installer")).value<PackageManagerCore*>()) {
|
||||||
connect(core, SIGNAL(statusChanged(QInstaller::PackageManagerCore::Status)), &callback,
|
connect(core, SIGNAL(statusChanged(QInstaller::PackageManagerCore::Status)), &callback,
|
||||||
SLOT(statusChanged(QInstaller::PackageManagerCore::Status)), Qt::QueuedConnection);
|
SLOT(statusChanged(QInstaller::PackageManagerCore::Status)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Runnable is derived from QRunable which will be deleted by the ThreadPool -> no parent is needed
|
//Runnable is derived from QRunable which will be deleted by the ThreadPool -> no parent is needed
|
||||||
@ -125,8 +124,8 @@ bool ExtractArchiveOperation::undoOperation()
|
|||||||
const QStringList files = value(QLatin1String("files")).toStringList();
|
const QStringList files = value(QLatin1String("files")).toStringList();
|
||||||
|
|
||||||
WorkerThread *const thread = new WorkerThread(this, files);
|
WorkerThread *const thread = new WorkerThread(this, files);
|
||||||
connect(thread, SIGNAL(outputTextChanged(QString)), this, SIGNAL(outputTextChanged(QString)),
|
connect(thread, SIGNAL(currentFileChanged(QString)), this, SIGNAL(outputTextChanged(QString)));
|
||||||
Qt::QueuedConnection);
|
connect(thread, SIGNAL(progressChanged(double)), this, SIGNAL(progressChanged(double)));
|
||||||
|
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
connect(thread, SIGNAL(finished()), &loop, SLOT(quit()), Qt::QueuedConnection);
|
connect(thread, SIGNAL(finished()), &loop, SLOT(quit()), Qt::QueuedConnection);
|
||||||
@ -149,7 +148,7 @@ Operation *ExtractArchiveOperation::clone() const
|
|||||||
/*!
|
/*!
|
||||||
This slot is direct connected to the caller so please don't call it from another thread in the same time.
|
This slot is direct connected to the caller so please don't call it from another thread in the same time.
|
||||||
*/
|
*/
|
||||||
void ExtractArchiveOperation::slotProgressChanged(const QString &filename)
|
void ExtractArchiveOperation::fileFinished(const QString &filename)
|
||||||
{
|
{
|
||||||
QStringList files = value(QLatin1String("files")).toStringList();
|
QStringList files = value(QLatin1String("files")).toStringList();
|
||||||
files.prepend(filename);
|
files.prepend(filename);
|
||||||
|
@ -64,9 +64,10 @@ public:
|
|||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void outputTextChanged(const QString &progress);
|
void outputTextChanged(const QString &progress);
|
||||||
|
void progressChanged(double);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void slotProgressChanged(const QString &progress);
|
void fileFinished(const QString &progress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Callback;
|
class Callback;
|
||||||
|
@ -71,9 +71,12 @@ public:
|
|||||||
ExtractArchiveOperation *const op = m_op;//dynamic_cast< ExtractArchiveOperation* >(parent());
|
ExtractArchiveOperation *const op = m_op;//dynamic_cast< ExtractArchiveOperation* >(parent());
|
||||||
Q_ASSERT(op != 0);
|
Q_ASSERT(op != 0);
|
||||||
|
|
||||||
|
int removedCounter = 0;
|
||||||
foreach (const QString &file, m_files) {
|
foreach (const QString &file, m_files) {
|
||||||
|
removedCounter++;
|
||||||
const QFileInfo fi(file);
|
const QFileInfo fi(file);
|
||||||
emit outputTextChanged(file);
|
emit currentFileChanged(file);
|
||||||
|
emit progressChanged(double(removedCounter) / m_files.count());
|
||||||
if (fi.isFile() || fi.isSymLink()) {
|
if (fi.isFile() || fi.isSymLink()) {
|
||||||
op->deleteFileNowOrLater(fi.absoluteFilePath());
|
op->deleteFileNowOrLater(fi.absoluteFilePath());
|
||||||
} else if (fi.isDir()) {
|
} else if (fi.isDir()) {
|
||||||
@ -85,7 +88,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void outputTextChanged(const QString &filename);
|
void currentFileChanged(const QString &filename);
|
||||||
|
void progressChanged(double);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList m_files;
|
QStringList m_files;
|
||||||
@ -105,7 +109,8 @@ public:
|
|||||||
Callback() : state(S_OK), createBackups(true) {}
|
Callback() : state(S_OK), createBackups(true) {}
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void progressChanged(const QString &filename);
|
void currentFileChanged(const QString &filename);
|
||||||
|
void progressChanged(double progress);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void statusChanged(QInstaller::PackageManagerCore::Status status)
|
void statusChanged(QInstaller::PackageManagerCore::Status status)
|
||||||
@ -130,7 +135,7 @@ public Q_SLOTS:
|
|||||||
protected:
|
protected:
|
||||||
void setCurrentFile(const QString &filename)
|
void setCurrentFile(const QString &filename)
|
||||||
{
|
{
|
||||||
emit progressChanged(QDir::toNativeSeparators(filename));
|
emit currentFileChanged(QDir::toNativeSeparators(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString generateBackupName(const QString &fn)
|
static QString generateBackupName(const QString &fn)
|
||||||
@ -161,8 +166,9 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT setCompleted(quint64 /*completed*/, quint64 /*total*/)
|
HRESULT setCompleted(quint64 completed, quint64 total)
|
||||||
{
|
{
|
||||||
|
emit progressChanged(double(completed) / total);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -289,8 +289,7 @@ void QInstaller::removeDirectory(const QString &path, bool ignoreErrors)
|
|||||||
QDirIterator it(path, QDir::NoDotAndDotDot | QDir::Dirs | QDir::NoSymLinks | QDir::Hidden,
|
QDirIterator it(path, QDir::NoDotAndDotDot | QDir::Dirs | QDir::NoSymLinks | QDir::Hidden,
|
||||||
QDirIterator::Subdirectories);
|
QDirIterator::Subdirectories);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
dirs.prepend(it.next());
|
||||||
dirs.prepend(it.filePath());
|
|
||||||
removeFiles(dirs.at(0), ignoreErrors);
|
removeFiles(dirs.at(0), ignoreErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,14 +460,18 @@ QString QInstaller::generateTemporaryFileName(const QString &templ)
|
|||||||
return f.fileName();
|
return f.fileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QInstaller::createTemporaryDirectory(const QString &templ)
|
QString QInstaller::createTemporaryDirectory(const QString &templateName)
|
||||||
{
|
{
|
||||||
const QString t = QDir::tempPath() + QLatin1String("/") + templ + QLatin1String("XXXXXX");
|
QString path = QDir::tempPath() + QLatin1String("/") + templateName + QLatin1String("XXXXXX");
|
||||||
QTemporaryFile f(t);
|
{
|
||||||
if (!f.open())
|
QTemporaryFile f(path);
|
||||||
throw Error(QObject::tr("Could not create temporary folder for template %1: %2").arg(t, f.errorString()));
|
if (!f.open()) {
|
||||||
const QString path = f.fileName() + QLatin1String("meta");
|
throw Error(QObject::tr("Could not create temporary directory %1: %2").arg(f.fileName(),
|
||||||
qDebug() << "\nCreating meta data directory at" << path;
|
f.errorString()));
|
||||||
|
}
|
||||||
|
path = f.fileName();
|
||||||
|
}
|
||||||
|
qDebug() << "\nCreating temporary directory at:" << path;
|
||||||
|
|
||||||
QInstaller::mkpath(path);
|
QInstaller::mkpath(path);
|
||||||
return path;
|
return path;
|
||||||
|
@ -108,7 +108,7 @@ private:
|
|||||||
Creates a temporary directory
|
Creates a temporary directory
|
||||||
@throws QInstaller::Error if creating the temporary directory fails
|
@throws QInstaller::Error if creating the temporary directory fails
|
||||||
*/
|
*/
|
||||||
QString INSTALLER_EXPORT createTemporaryDirectory(const QString &templ=QString());
|
QString INSTALLER_EXPORT createTemporaryDirectory(const QString &templateName = QString());
|
||||||
|
|
||||||
QString INSTALLER_EXPORT generateTemporaryFileName(const QString &templ=QString());
|
QString INSTALLER_EXPORT generateTemporaryFileName(const QString &templ=QString());
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@
|
|||||||
#include "kdupdaterfiledownloader.h"
|
#include "kdupdaterfiledownloader.h"
|
||||||
#include "kdupdaterfiledownloaderfactory.h"
|
#include "kdupdaterfiledownloaderfactory.h"
|
||||||
|
|
||||||
|
#include "productkeycheck.h"
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
|
||||||
@ -197,14 +199,14 @@ void GetRepositoryMetaInfoJob::startUpdatesXmlDownload()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!url.isValid()) {
|
if (!url.isValid()) {
|
||||||
finished(QInstaller::InvalidUrl, tr("Invalid repository URL: %1").arg(url.toString()));
|
finished(QInstaller::InvalidUrl, tr("Invalid repository URL: %1").arg(m_repository.displayname()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_downloader = FileDownloaderFactory::instance().create(url.scheme(), this);
|
m_downloader = FileDownloaderFactory::instance().create(url.scheme(), this);
|
||||||
if (!m_downloader) {
|
if (!m_downloader) {
|
||||||
finished(QInstaller::InvalidUrl, tr("URL scheme not supported: %1 (%2)").arg(url.scheme(),
|
finished(QInstaller::InvalidUrl, tr("URL scheme not supported: %1 (%2)").arg(url.scheme(),
|
||||||
url.toString()));
|
m_repository.displayname()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,20 +246,7 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
|
|||||||
Q_ASSERT(!fn.isEmpty());
|
Q_ASSERT(!fn.isEmpty());
|
||||||
Q_ASSERT(QFile::exists(fn));
|
Q_ASSERT(QFile::exists(fn));
|
||||||
|
|
||||||
try {
|
|
||||||
m_temporaryDirectory = createTemporaryDirectory(QLatin1String("remoterepo"));
|
|
||||||
m_tempDirDeleter.add(m_temporaryDirectory);
|
|
||||||
} catch (const QInstaller::Error& e) {
|
|
||||||
finished(QInstaller::ExtractionError, e.message());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile updatesFile(fn);
|
QFile updatesFile(fn);
|
||||||
if (!updatesFile.rename(m_temporaryDirectory + QLatin1String("/Updates.xml"))) {
|
|
||||||
finished(QInstaller::DownloadError, tr("Could not move Updates.xml to target location. Error: %1")
|
|
||||||
.arg(updatesFile.errorString()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!updatesFile.open(QIODevice::ReadOnly)) {
|
if (!updatesFile.open(QIODevice::ReadOnly)) {
|
||||||
finished(QInstaller::DownloadError, tr("Could not open Updates.xml for reading. Error: %1")
|
finished(QInstaller::DownloadError, tr("Could not open Updates.xml for reading. Error: %1")
|
||||||
@ -272,7 +261,7 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
|
|||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
const QString msg = tr("Could not fetch a valid version of Updates.xml from repository: %1. "
|
const QString msg = tr("Could not fetch a valid version of Updates.xml from repository: %1. "
|
||||||
"Error: %2").arg(m_repository.url().toString(), err);
|
"Error: %2").arg(m_repository.displayname(), err);
|
||||||
|
|
||||||
const QMessageBox::StandardButton b =
|
const QMessageBox::StandardButton b =
|
||||||
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
|
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
|
||||||
@ -302,15 +291,16 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
|
|||||||
repository.setUsername(el.attribute(QLatin1String("username")));
|
repository.setUsername(el.attribute(QLatin1String("username")));
|
||||||
repository.setPassword(el.attribute(QLatin1String("password")));
|
repository.setPassword(el.attribute(QLatin1String("password")));
|
||||||
repository.setDisplayName(el.attribute(QLatin1String("displayname")));
|
repository.setDisplayName(el.attribute(QLatin1String("displayname")));
|
||||||
repositoryUpdates.insertMulti(action, qMakePair(repository, Repository()));
|
if (ProductKeyCheck::instance()->isValidRepository(repository)) {
|
||||||
|
repositoryUpdates.insertMulti(action, qMakePair(repository, Repository()));
|
||||||
qDebug() << "Repository to add:" << repository.url().toString();
|
qDebug() << "Repository to add:" << repository.displayname();
|
||||||
|
}
|
||||||
} else if (action == QLatin1String("remove")) {
|
} else if (action == QLatin1String("remove")) {
|
||||||
// remove possible default repositories using the given server url
|
// remove possible default repositories using the given server url
|
||||||
Repository repository(el.attribute(QLatin1String("url")), true);
|
Repository repository(el.attribute(QLatin1String("url")), true);
|
||||||
repositoryUpdates.insertMulti(action, qMakePair(repository, Repository()));
|
repositoryUpdates.insertMulti(action, qMakePair(repository, Repository()));
|
||||||
|
|
||||||
qDebug() << "Repository to remove:" << repository.url().toString();
|
qDebug() << "Repository to remove:" << repository.displayname();
|
||||||
} else if (action == QLatin1String("replace")) {
|
} else if (action == QLatin1String("replace")) {
|
||||||
// replace possible default repositories using the given server url
|
// replace possible default repositories using the given server url
|
||||||
Repository oldRepository(el.attribute(QLatin1String("oldUrl")), true);
|
Repository oldRepository(el.attribute(QLatin1String("oldUrl")), true);
|
||||||
@ -319,19 +309,42 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
|
|||||||
newRepository.setPassword(el.attribute(QLatin1String("password")));
|
newRepository.setPassword(el.attribute(QLatin1String("password")));
|
||||||
newRepository.setDisplayName(el.attribute(QLatin1String("displayname")));
|
newRepository.setDisplayName(el.attribute(QLatin1String("displayname")));
|
||||||
|
|
||||||
// store the new repository and the one old it replaces
|
if (ProductKeyCheck::instance()->isValidRepository(newRepository)) {
|
||||||
repositoryUpdates.insertMulti(action, qMakePair(newRepository, oldRepository));
|
// store the new repository and the one old it replaces
|
||||||
qDebug() << "Replace repository:" << oldRepository.url().toString() << "with:"
|
repositoryUpdates.insertMulti(action, qMakePair(newRepository, oldRepository));
|
||||||
<< newRepository.url().toString();
|
qDebug() << "Replace repository:" << oldRepository.displayname() << "with:"
|
||||||
|
<< newRepository.displayname();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Invalid additional repositories action set in Updates.xml fetched from:"
|
qDebug() << "Invalid additional repositories action set in Updates.xml fetched from:"
|
||||||
<< m_repository.url().toString() << "Line:" << el.lineNumber();
|
<< m_repository.displayname() << "Line:" << el.lineNumber();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!repositoryUpdates.isEmpty()) {
|
if (!repositoryUpdates.isEmpty()) {
|
||||||
if (m_core->settings().updateDefaultRepositories(repositoryUpdates) == Settings::UpdatesApplied) {
|
const QSet<Repository> temporaries = m_core->settings().temporaryRepositories();
|
||||||
|
// in case the temp repository introduced something new, we only want that temporary
|
||||||
|
if (temporaries.contains(m_repository)) {
|
||||||
|
|
||||||
|
QSet<Repository> childTempRepositories;
|
||||||
|
typedef QPair<Repository, Repository> RepositoryPair;
|
||||||
|
|
||||||
|
QList<RepositoryPair> values = repositoryUpdates.values(QLatin1String("add"));
|
||||||
|
foreach (const RepositoryPair &value, values)
|
||||||
|
childTempRepositories.insert(value.first);
|
||||||
|
|
||||||
|
values = repositoryUpdates.values(QLatin1String("replace"));
|
||||||
|
foreach (const RepositoryPair &value, values)
|
||||||
|
childTempRepositories.insert(value.first);
|
||||||
|
|
||||||
|
QSet<Repository> newChildTempRepositories = childTempRepositories.subtract(temporaries);
|
||||||
|
if (newChildTempRepositories.count() > 0) {
|
||||||
|
m_core->settings().addTemporaryRepositories(newChildTempRepositories, true);
|
||||||
|
finished(QInstaller::RepositoryUpdatesReceived, tr("Repository updates received."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (m_core->settings().updateDefaultRepositories(repositoryUpdates) == Settings::UpdatesApplied) {
|
||||||
if (m_core->isUpdater() || m_core->isPackageManager())
|
if (m_core->isUpdater() || m_core->isPackageManager())
|
||||||
m_core->writeMaintenanceConfigFiles();
|
m_core->writeMaintenanceConfigFiles();
|
||||||
finished(QInstaller::RepositoryUpdatesReceived, tr("Repository updates received."));
|
finished(QInstaller::RepositoryUpdatesReceived, tr("Repository updates received."));
|
||||||
@ -358,6 +371,19 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
m_temporaryDirectory = createTemporaryDirectory(QLatin1String("remoterepo-"));
|
||||||
|
m_tempDirDeleter.add(m_temporaryDirectory);
|
||||||
|
} catch (const QInstaller::Error& e) {
|
||||||
|
finished(QInstaller::ExtractionError, e.message());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!updatesFile.rename(m_temporaryDirectory + QLatin1String("/Updates.xml"))) {
|
||||||
|
finished(QInstaller::DownloadError, tr("Could not move Updates.xml to target location. Error: %1")
|
||||||
|
.arg(updatesFile.errorString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setTotalAmount(m_packageNames.count() + 1);
|
setTotalAmount(m_packageNames.count() + 1);
|
||||||
setProcessedAmount(1);
|
setProcessedAmount(1);
|
||||||
emit infoMessage(this, tr("Finished updating component meta information."));
|
emit infoMessage(this, tr("Finished updating component meta information."));
|
||||||
@ -427,7 +453,7 @@ void GetRepositoryMetaInfoJob::fetchNextMetaInfo()
|
|||||||
if (!m_downloader) {
|
if (!m_downloader) {
|
||||||
m_currentPackageName.clear();
|
m_currentPackageName.clear();
|
||||||
m_currentPackageVersion.clear();
|
m_currentPackageVersion.clear();
|
||||||
qWarning() << "Scheme not supported:" << url.toString();
|
qWarning() << "Scheme not supported:" << m_repository.displayname();
|
||||||
QMetaObject::invokeMethod(this, "fetchNextMetaInfo", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(this, "fetchNextMetaInfo", Qt::QueuedConnection);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -421,7 +421,7 @@ void PackageManagerCore::writeMaintenanceConfigFiles()
|
|||||||
void PackageManagerCore::reset(const QHash<QString, QString> ¶ms)
|
void PackageManagerCore::reset(const QHash<QString, QString> ¶ms)
|
||||||
{
|
{
|
||||||
d->m_completeUninstall = false;
|
d->m_completeUninstall = false;
|
||||||
d->m_forceRestart = false;
|
d->m_needsHardRestart = false;
|
||||||
d->m_status = PackageManagerCore::Unfinished;
|
d->m_status = PackageManagerCore::Unfinished;
|
||||||
d->m_installerBaseBinaryUnreplaced.clear();
|
d->m_installerBaseBinaryUnreplaced.clear();
|
||||||
|
|
||||||
@ -596,11 +596,17 @@ int PackageManagerCore::downloadNeededArchives(double partProgressSize)
|
|||||||
If a component marked as important was installed during update
|
If a component marked as important was installed during update
|
||||||
process true is returned.
|
process true is returned.
|
||||||
*/
|
*/
|
||||||
bool PackageManagerCore::needsRestart() const
|
bool PackageManagerCore::needsHardRestart() const
|
||||||
{
|
{
|
||||||
return d->m_forceRestart;
|
return d->m_needsHardRestart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackageManagerCore::setNeedsHardRestart(bool needsHardRestart)
|
||||||
|
{
|
||||||
|
d->m_needsHardRestart = needsHardRestart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PackageManagerCore::rollBackInstallation()
|
void PackageManagerCore::rollBackInstallation()
|
||||||
{
|
{
|
||||||
emit titleMessageChanged(tr("Cancelling the Installer"));
|
emit titleMessageChanged(tr("Cancelling the Installer"));
|
||||||
|
@ -248,7 +248,8 @@ public:
|
|||||||
|
|
||||||
int downloadNeededArchives(double partProgressSize);
|
int downloadNeededArchives(double partProgressSize);
|
||||||
|
|
||||||
bool needsRestart() const;
|
bool needsHardRestart() const;
|
||||||
|
void setNeedsHardRestart(bool needsHardRestart = true);
|
||||||
bool finishedWithSuccess() const;
|
bool finishedWithSuccess() const;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
|
@ -225,7 +225,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, q
|
|||||||
, m_updaterApplication(new DummyConfigurationInterface)
|
, m_updaterApplication(new DummyConfigurationInterface)
|
||||||
, m_FSEngineClientHandler(initFSEngineClientHandler())
|
, m_FSEngineClientHandler(initFSEngineClientHandler())
|
||||||
, m_status(PackageManagerCore::Unfinished)
|
, m_status(PackageManagerCore::Unfinished)
|
||||||
, m_forceRestart(false)
|
, m_needsHardRestart(false)
|
||||||
, m_testChecksum(false)
|
, m_testChecksum(false)
|
||||||
, m_launchedAsRoot(AdminAuthorization::hasAdminRights())
|
, m_launchedAsRoot(AdminAuthorization::hasAdminRights())
|
||||||
, m_completeUninstall(false)
|
, m_completeUninstall(false)
|
||||||
@ -1094,7 +1094,25 @@ void PackageManagerCorePrivate::writeUninstallerBinaryData(QIODevice *output, QF
|
|||||||
const qint64 dataBlockStart = output->pos();
|
const qint64 dataBlockStart = output->pos();
|
||||||
|
|
||||||
QVector<Range<qint64> >resourceSegments;
|
QVector<Range<qint64> >resourceSegments;
|
||||||
foreach (const Range<qint64> &segment, layout.metadataResourceSegments) {
|
QVector<Range<qint64> >existingResourceSegments = layout.metadataResourceSegments;
|
||||||
|
|
||||||
|
const QString newDefaultResource = m_core->value(QString::fromLatin1("DefaultResourceReplacement"));
|
||||||
|
if (!newDefaultResource.isEmpty()) {
|
||||||
|
QFile file(newDefaultResource);
|
||||||
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
|
resourceSegments.append(Range<qint64>::fromStartAndLength(output->pos(), file.size()));
|
||||||
|
appendData(output, &file, file.size());
|
||||||
|
existingResourceSegments.remove(0);
|
||||||
|
|
||||||
|
file.remove(); // clear all possible leftovers
|
||||||
|
m_core->setValue(QString::fromLatin1("DefaultResourceReplacement"), QString());
|
||||||
|
} else {
|
||||||
|
qWarning() << QString::fromLatin1("Could not replace default resource with '%1'.")
|
||||||
|
.arg(newDefaultResource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const Range<qint64> &segment, existingResourceSegments) {
|
||||||
input->seek(segment.start());
|
input->seek(segment.start());
|
||||||
resourceSegments.append(Range<qint64>::fromStartAndLength(output->pos(), segment.length()));
|
resourceSegments.append(Range<qint64>::fromStartAndLength(output->pos(), segment.length()));
|
||||||
appendData(output, input, segment.length());
|
appendData(output, input, segment.length());
|
||||||
@ -1156,8 +1174,6 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
|
|||||||
performedOperations.append(takeOwnedOperation(op));
|
performedOperations.append(takeOwnedOperation(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
writeMaintenanceConfigFiles();
|
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
// if it is a bundle, we need some stuff in it...
|
// if it is a bundle, we need some stuff in it...
|
||||||
const QString sourceAppDirPath = QCoreApplication::applicationDirPath();
|
const QString sourceAppDirPath = QCoreApplication::applicationDirPath();
|
||||||
@ -1264,7 +1280,7 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
|
|||||||
|
|
||||||
bool newBinaryWritten = false;
|
bool newBinaryWritten = false;
|
||||||
bool replacementExists = false;
|
bool replacementExists = false;
|
||||||
const QString installerBaseBinary = m_core->replaceVariables(m_installerBaseBinaryUnreplaced);
|
const QString installerBaseBinary = replaceVariables(m_installerBaseBinaryUnreplaced);
|
||||||
if (!installerBaseBinary.isEmpty() && QFileInfo(installerBaseBinary).exists()) {
|
if (!installerBaseBinary.isEmpty() && QFileInfo(installerBaseBinary).exists()) {
|
||||||
qDebug() << "Got a replacement installer base binary:" << installerBaseBinary;
|
qDebug() << "Got a replacement installer base binary:" << installerBaseBinary;
|
||||||
|
|
||||||
@ -1272,8 +1288,8 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
|
|||||||
try {
|
try {
|
||||||
openForRead(&replacementBinary, replacementBinary.fileName());
|
openForRead(&replacementBinary, replacementBinary.fileName());
|
||||||
writeUninstallerBinary(&replacementBinary, replacementBinary.size(), true);
|
writeUninstallerBinary(&replacementBinary, replacementBinary.size(), true);
|
||||||
|
qDebug() << "Wrote the binary with the new replacement.";
|
||||||
|
|
||||||
m_forceRestart = true;
|
|
||||||
newBinaryWritten = true;
|
newBinaryWritten = true;
|
||||||
replacementExists = true;
|
replacementExists = true;
|
||||||
} catch (const Error &error) {
|
} catch (const Error &error) {
|
||||||
@ -1283,10 +1299,17 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
|
|||||||
if (!replacementBinary.remove()) {
|
if (!replacementBinary.remove()) {
|
||||||
// Is there anything more sensible we can do with this error? I think not. It's not serious
|
// Is there anything more sensible we can do with this error? I think not. It's not serious
|
||||||
// enough for throwing / aborting the process.
|
// enough for throwing / aborting the process.
|
||||||
qDebug() << QString::fromLatin1("Could not remove installer base binary (%1) after updating "
|
qDebug() << QString::fromLatin1("Could not remove installer base binary '%1' after updating "
|
||||||
"the uninstaller: %2").arg(installerBaseBinary, replacementBinary.errorString());
|
"the uninstaller: %2").arg(installerBaseBinary, replacementBinary.errorString());
|
||||||
|
} else {
|
||||||
|
qDebug() << QString::fromLatin1("Removed installer base binary '%1' after updating the "
|
||||||
|
"uninstaller/ maintenance tool.").arg(installerBaseBinary);
|
||||||
}
|
}
|
||||||
m_installerBaseBinaryUnreplaced.clear();
|
m_installerBaseBinaryUnreplaced.clear();
|
||||||
|
} else if (!installerBaseBinary.isEmpty() && !QFileInfo(installerBaseBinary).exists()) {
|
||||||
|
qWarning() << QString::fromLatin1("The current uninstaller/ maintenance tool could not be "
|
||||||
|
"updated. '%1' does not exist. Please fix the 'setInstallerBaseBinary(<temp_installer_base_"
|
||||||
|
"binary_path>)' call in your script.").arg(installerBaseBinary);
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile input;
|
QFile input;
|
||||||
@ -1330,9 +1353,7 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
performedOperations = sortOperationsBasedOnComponentDependencies(
|
performedOperations = sortOperationsBasedOnComponentDependencies(performedOperations);
|
||||||
performedOperations);
|
|
||||||
|
|
||||||
m_core->setValue(QLatin1String("installedOperationAreSorted"), QLatin1String("true"));
|
m_core->setValue(QLatin1String("installedOperationAreSorted"), QLatin1String("true"));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -1363,10 +1384,11 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
|
|||||||
appendInt64(&file, MagicCookie);
|
appendInt64(&file, MagicCookie);
|
||||||
}
|
}
|
||||||
input.close();
|
input.close();
|
||||||
|
writeMaintenanceConfigFiles();
|
||||||
deferredRename(dataFile + QLatin1String(".new"), dataFile, false);
|
deferredRename(dataFile + QLatin1String(".new"), dataFile, false);
|
||||||
|
|
||||||
if (newBinaryWritten) {
|
if (newBinaryWritten) {
|
||||||
const bool restart = replacementExists && isUpdater() && (!statusCanceledOrFailed());
|
const bool restart = replacementExists && isUpdater() && (!statusCanceledOrFailed()) && m_needsHardRestart;
|
||||||
deferredRename(uninstallerName() + QLatin1String(".new"), uninstallerName(), restart);
|
deferredRename(uninstallerName() + QLatin1String(".new"), uninstallerName(), restart);
|
||||||
qDebug() << "Maintenance tool restart:" << (restart ? "true." : "false.");
|
qDebug() << "Maintenance tool restart:" << (restart ? "true." : "false.");
|
||||||
}
|
}
|
||||||
@ -1888,7 +1910,7 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
|
|||||||
throw Error(operation->errorString());
|
throw Error(operation->errorString());
|
||||||
|
|
||||||
if (component->value(scEssential, scFalse) == scTrue)
|
if (component->value(scEssential, scFalse) == scTrue)
|
||||||
m_forceRestart = true;
|
m_needsHardRestart = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
registerPathesForUninstallation(component->pathesForUninstallation(), component->name());
|
registerPathesForUninstallation(component->pathesForUninstallation(), component->name());
|
||||||
@ -2389,9 +2411,11 @@ OperationList PackageManagerCorePrivate::sortOperationsBasedOnComponentDependenc
|
|||||||
|
|
||||||
// create the complete component graph
|
// create the complete component graph
|
||||||
Graph<QString> componentGraph;
|
Graph<QString> componentGraph;
|
||||||
|
const QRegExp dash(QLatin1String("-.*"));
|
||||||
foreach (const Component* componentNode, m_core->availableComponents()) {
|
foreach (const Component* componentNode, m_core->availableComponents()) {
|
||||||
componentGraph.addNode(componentNode->name());
|
componentGraph.addNode(componentNode->name());
|
||||||
componentGraph.addEdges(componentNode->name(), componentNode->dependencies());
|
const QStringList dependencies = componentNode->dependencies().replaceInStrings(dash,QString());
|
||||||
|
componentGraph.addEdges(componentNode->name(), dependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (const QString &componentName, componentGraph.sort())
|
foreach (const QString &componentName, componentGraph.sort())
|
||||||
|
@ -205,7 +205,7 @@ public:
|
|||||||
int m_status;
|
int m_status;
|
||||||
QString m_error;
|
QString m_error;
|
||||||
|
|
||||||
bool m_forceRestart;
|
bool m_needsHardRestart;
|
||||||
bool m_testChecksum;
|
bool m_testChecksum;
|
||||||
bool m_launchedAsRoot;
|
bool m_launchedAsRoot;
|
||||||
bool m_completeUninstall;
|
bool m_completeUninstall;
|
||||||
|
@ -138,7 +138,7 @@ QVariant PackageManagerCoreData::value(const QString &key, const QVariant &_defa
|
|||||||
if (key == scTargetDir) {
|
if (key == scTargetDir) {
|
||||||
QString dir = m_variables.value(key);
|
QString dir = m_variables.value(key);
|
||||||
if (dir.isEmpty())
|
if (dir.isEmpty())
|
||||||
dir = m_settings.value(key, _default).toString();
|
dir = replaceVariables(m_settings.value(key, _default).toString());
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
return QInstaller::normalizePathName(dir);
|
return QInstaller::normalizePathName(dir);
|
||||||
#else
|
#else
|
||||||
|
@ -128,7 +128,7 @@ public:
|
|||||||
setPixmap(QWizard::BannerPixmap, QPixmap());
|
setPixmap(QWizard::BannerPixmap, QPixmap());
|
||||||
|
|
||||||
setLayout(new QVBoxLayout);
|
setLayout(new QVBoxLayout);
|
||||||
setSubTitle(QString());
|
setSubTitle(QLatin1String(" "));
|
||||||
setTitle(widget->windowTitle());
|
setTitle(widget->windowTitle());
|
||||||
m_widget->setProperty("complete", true);
|
m_widget->setProperty("complete", true);
|
||||||
m_widget->setProperty("final", false);
|
m_widget->setProperty("final", false);
|
||||||
@ -248,7 +248,7 @@ PackageManagerGui::PackageManagerGui(PackageManagerCore *core, QWidget *parent)
|
|||||||
connect(m_core, SIGNAL(installationFinished()), this, SLOT(showFinishedPage()), Qt::QueuedConnection);
|
connect(m_core, SIGNAL(installationFinished()), this, SLOT(showFinishedPage()), Qt::QueuedConnection);
|
||||||
connect(m_core, SIGNAL(uninstallationFinished()), this, SLOT(showFinishedPage()), Qt::QueuedConnection);
|
connect(m_core, SIGNAL(uninstallationFinished()), this, SLOT(showFinishedPage()), Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(slotCurrentPageChanged(int)));
|
connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(executeControlScript(int)));
|
||||||
connect(this, SIGNAL(currentIdChanged(int)), m_core, SIGNAL(currentPageChanged(int)));
|
connect(this, SIGNAL(currentIdChanged(int)), m_core, SIGNAL(currentPageChanged(int)));
|
||||||
connect(button(QWizard::FinishButton), SIGNAL(clicked()), this, SIGNAL(finishButtonClicked()));
|
connect(button(QWizard::FinishButton), SIGNAL(clicked()), this, SIGNAL(finishButtonClicked()));
|
||||||
connect(button(QWizard::FinishButton), SIGNAL(clicked()), m_core, SIGNAL(finishButtonClicked()));
|
connect(button(QWizard::FinishButton), SIGNAL(clicked()), m_core, SIGNAL(finishButtonClicked()));
|
||||||
@ -301,8 +301,8 @@ void PackageManagerGui::clickButton(int wb, int delay)
|
|||||||
{
|
{
|
||||||
// transform the FinishButton to CancelButton, because of the needed misuse of the
|
// transform the FinishButton to CancelButton, because of the needed misuse of the
|
||||||
// CancelButton as a FinishButton to have some more control of closing the wizard
|
// CancelButton as a FinishButton to have some more control of closing the wizard
|
||||||
if (!m_core->isInstaller() && currentId() == PackageManagerCore::InstallationFinished &&
|
if ((m_core->isUpdater() || m_core->isPackageManager()) && currentId() ==
|
||||||
wb == QWizard::FinishButton) {
|
PackageManagerCore::InstallationFinished && wb == QWizard::FinishButton) {
|
||||||
wb = QWizard::CancelButton;
|
wb = QWizard::CancelButton;
|
||||||
}
|
}
|
||||||
if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb) ))
|
if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb) ))
|
||||||
@ -315,8 +315,8 @@ bool PackageManagerGui::isButtonEnabled(int wb)
|
|||||||
{
|
{
|
||||||
// transform the FinishButton to CancelButton, because of the needed misuse of the
|
// transform the FinishButton to CancelButton, because of the needed misuse of the
|
||||||
// CancelButton as a FinishButton to have some more control of closing the wizard
|
// CancelButton as a FinishButton to have some more control of closing the wizard
|
||||||
if (!m_core->isInstaller() && currentId() == PackageManagerCore::InstallationFinished &&
|
if ((m_core->isUpdater() || m_core->isPackageManager()) && currentId() ==
|
||||||
wb == QWizard::FinishButton) {
|
PackageManagerCore::InstallationFinished && wb == QWizard::FinishButton) {
|
||||||
wb = QWizard::CancelButton;
|
wb = QWizard::CancelButton;
|
||||||
}
|
}
|
||||||
if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb) ))
|
if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb) ))
|
||||||
@ -353,12 +353,6 @@ void PackageManagerGui::loadControlScript(const QString &scriptPath)
|
|||||||
qDebug() << "Loaded control script" << scriptPath;
|
qDebug() << "Loaded control script" << scriptPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackageManagerGui::slotCurrentPageChanged(int id)
|
|
||||||
{
|
|
||||||
QMetaObject::invokeMethod(this, "delayedControlScriptExecution", Qt::QueuedConnection,
|
|
||||||
Q_ARG(int, id));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PackageManagerGui::callControlScriptMethod(const QString &methodName)
|
void PackageManagerGui::callControlScriptMethod(const QString &methodName)
|
||||||
{
|
{
|
||||||
if (!d->m_controlScriptContext.isValid())
|
if (!d->m_controlScriptContext.isValid())
|
||||||
@ -376,9 +370,9 @@ void PackageManagerGui::callControlScriptMethod(const QString &methodName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackageManagerGui::delayedControlScriptExecution(int id)
|
void PackageManagerGui::executeControlScript(int pageId)
|
||||||
{
|
{
|
||||||
if (PackageManagerPage *const p = qobject_cast<PackageManagerPage*> (page(id)))
|
if (PackageManagerPage *const p = qobject_cast<PackageManagerPage*> (page(pageId)))
|
||||||
callControlScriptMethod(p->objectName() + QLatin1String("Callback"));
|
callControlScriptMethod(p->objectName() + QLatin1String("Callback"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,6 +518,7 @@ void PackageManagerGui::cancelButtonClicked()
|
|||||||
QDialog::reject();
|
QDialog::reject();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
m_core->setNeedsHardRestart(false);
|
||||||
QDialog::reject();
|
QDialog::reject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1870,7 +1865,7 @@ void FinishedPage::entering()
|
|||||||
if (!finishedText.isEmpty())
|
if (!finishedText.isEmpty())
|
||||||
m_msgLabel->setText(finishedText);
|
m_msgLabel->setText(finishedText);
|
||||||
|
|
||||||
if (!packageManagerCore()->value(scRunProgram).isEmpty()) {
|
if (!packageManagerCore()->isUninstaller() && !packageManagerCore()->value(scRunProgram).isEmpty()) {
|
||||||
m_runItCheckBox->show();
|
m_runItCheckBox->show();
|
||||||
m_runItCheckBox->setText(packageManagerCore()->value(scRunProgramDescription, tr("Run %1 now."))
|
m_runItCheckBox->setText(packageManagerCore()->value(scRunProgramDescription, tr("Run %1 now."))
|
||||||
.arg(productName()));
|
.arg(productName()));
|
||||||
@ -1903,7 +1898,7 @@ void FinishedPage::handleFinishClicked()
|
|||||||
{
|
{
|
||||||
const QString program = packageManagerCore()->replaceVariables(packageManagerCore()->value(scRunProgram));
|
const QString program = packageManagerCore()->replaceVariables(packageManagerCore()->value(scRunProgram));
|
||||||
const QStringList args = packageManagerCore()->replaceVariables(
|
const QStringList args = packageManagerCore()->replaceVariables(
|
||||||
packageManagerCore()->value(scRunProgramArguments)).split(QLatin1Char(' '));
|
packageManagerCore()->value(scRunProgramArguments)).split(QLatin1Char(' '), QString::SkipEmptyParts);
|
||||||
if (!m_runItCheckBox->isChecked() || program.isEmpty())
|
if (!m_runItCheckBox->isChecked() || program.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1942,7 +1937,7 @@ int RestartPage::nextId() const
|
|||||||
|
|
||||||
void RestartPage::entering()
|
void RestartPage::entering()
|
||||||
{
|
{
|
||||||
if (!packageManagerCore()->needsRestart()) {
|
if (!packageManagerCore()->needsHardRestart()) {
|
||||||
if (QAbstractButton *finish = wizard()->button(QWizard::FinishButton))
|
if (QAbstractButton *finish = wizard()->button(QWizard::FinishButton))
|
||||||
finish->setVisible(false);
|
finish->setVisible(false);
|
||||||
QMetaObject::invokeMethod(this, "restart", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(this, "restart", Qt::QueuedConnection);
|
||||||
|
@ -116,8 +116,7 @@ protected Q_SLOTS:
|
|||||||
void wizardWidgetInsertionRequested(QWidget *widget, QInstaller::PackageManagerCore::WizardPage page);
|
void wizardWidgetInsertionRequested(QWidget *widget, QInstaller::PackageManagerCore::WizardPage page);
|
||||||
void wizardWidgetRemovalRequested(QWidget *widget);
|
void wizardWidgetRemovalRequested(QWidget *widget);
|
||||||
void wizardPageVisibilityChangeRequested(bool visible, int page);
|
void wizardPageVisibilityChangeRequested(bool visible, int page);
|
||||||
void slotCurrentPageChanged(int id);
|
void executeControlScript(int pageId);
|
||||||
void delayedControlScriptExecution(int id);
|
|
||||||
void setValidatorForCustomPageRequested(QInstaller::Component *component, const QString &name,
|
void setValidatorForCustomPageRequested(QInstaller::Component *component, const QString &name,
|
||||||
const QString &callbackName);
|
const QString &callbackName);
|
||||||
|
|
||||||
|
@ -103,6 +103,14 @@ void ProgressCoordinator::registerPartProgress(QObject *sender, const char *sign
|
|||||||
Q_ASSERT(isConnected);
|
Q_ASSERT(isConnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This slot gets the progress changed signals from different tasks. The values 0 and 1 are handled as
|
||||||
|
special values.
|
||||||
|
|
||||||
|
0 - is just ignored, so you can use a timer which gives the progress, e.g. like a downloader does.
|
||||||
|
1 - means the task is finished, even if there comes another 1 from that task, so it will be ignored.
|
||||||
|
*/
|
||||||
void ProgressCoordinator::partProgressChanged(double fraction)
|
void ProgressCoordinator::partProgressChanged(double fraction)
|
||||||
{
|
{
|
||||||
if (fraction < 0 || fraction > 1) {
|
if (fraction < 0 || fraction > 1) {
|
||||||
@ -110,6 +118,16 @@ void ProgressCoordinator::partProgressChanged(double fraction)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no fraction no change
|
||||||
|
if (fraction == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// ignore senders sending 100% multiple times
|
||||||
|
if (fraction == 1 && m_senderPendingCalculatedPercentageHash.contains(sender())
|
||||||
|
&& m_senderPendingCalculatedPercentageHash.value(sender()) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
double partProgressSize = m_senderPartProgressSizeHash.value(sender(), 0);
|
double partProgressSize = m_senderPartProgressSizeHash.value(sender(), 0);
|
||||||
if (partProgressSize == 0) {
|
if (partProgressSize == 0) {
|
||||||
qWarning() << "It seems that this sender was not registered in the right way:" << sender();
|
qWarning() << "It seems that this sender was not registered in the right way:" << sender();
|
||||||
@ -137,9 +155,9 @@ void ProgressCoordinator::partProgressChanged(double fraction)
|
|||||||
newCurrentCompletePercentage = 100;
|
newCurrentCompletePercentage = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qRound(m_currentCompletePercentage) < qRound(newCurrentCompletePercentage)) {
|
// In undo mode, the progress has to go backward, new has to be smaller than current
|
||||||
qWarning("This should not happen!");
|
if (qRound(m_currentCompletePercentage) < qRound(newCurrentCompletePercentage))
|
||||||
}
|
qDebug("Something is wrong with the calculation of the progress.");
|
||||||
|
|
||||||
m_currentCompletePercentage = newCurrentCompletePercentage;
|
m_currentCompletePercentage = newCurrentCompletePercentage;
|
||||||
if (fraction == 1) {
|
if (fraction == 1) {
|
||||||
@ -170,12 +188,13 @@ void ProgressCoordinator::partProgressChanged(double fraction)
|
|||||||
newCurrentCompletePercentage = 100;
|
newCurrentCompletePercentage = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qRound(m_currentCompletePercentage) > qRound(newCurrentCompletePercentage)) {
|
// In normal mode, the progress has to go forward, new has to be larger than current
|
||||||
qWarning("This should not happen!");
|
if (qRound(m_currentCompletePercentage) > qRound(newCurrentCompletePercentage))
|
||||||
}
|
qDebug("Something is wrong with the calculation of the progress.");
|
||||||
|
|
||||||
m_currentCompletePercentage = newCurrentCompletePercentage;
|
m_currentCompletePercentage = newCurrentCompletePercentage;
|
||||||
|
|
||||||
if (fraction == 1 || fraction == 0) {
|
if (fraction == 1) {
|
||||||
m_currentBasePercentage = m_currentBasePercentage + pendingCalculatedPartPercentage;
|
m_currentBasePercentage = m_currentBasePercentage + pendingCalculatedPartPercentage;
|
||||||
m_senderPendingCalculatedPercentageHash.insert(sender(), 0);
|
m_senderPendingCalculatedPercentageHash.insert(sender(), 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -8,5 +8,5 @@ host-bin/qdoc
|
|||||||
*.la
|
*.la
|
||||||
*.prl
|
*.prl
|
||||||
*.pc
|
*.pc
|
||||||
|
*.pri
|
||||||
|
*.cmake
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
bin/qmake
|
||||||
|
bin/lrelease
|
||||||
|
bin/qdoc
|
||||||
|
host-bin/qmake
|
||||||
|
host-bin/lrelease
|
||||||
|
host-bin/qdoc
|
||||||
|
%%
|
||||||
|
*.la
|
||||||
|
*.prl
|
||||||
|
*.pc
|
||||||
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
bin/qmake
|
||||||
|
bin/lrelease
|
||||||
|
bin/qdoc
|
||||||
|
host-bin/qmake
|
||||||
|
host-bin/lrelease
|
||||||
|
host-bin/qdoc
|
||||||
|
%%
|
||||||
|
*.la
|
||||||
|
*.prl
|
||||||
|
*.pc
|
||||||
|
*.pri
|
||||||
|
*.cmake
|
@ -8,4 +8,6 @@ host-bin/qdoc.exe
|
|||||||
*.la
|
*.la
|
||||||
*.prl
|
*.prl
|
||||||
*.pc
|
*.pc
|
||||||
|
*.pri
|
||||||
|
*.cmake
|
||||||
|
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
bin/qmake.exe
|
||||||
|
bin/lrelease.exe
|
||||||
|
bin/qdoc.exe
|
||||||
|
host-bin/qmake.exe
|
||||||
|
host-bin/lrelease.exe
|
||||||
|
host-bin/qdoc.exe
|
||||||
|
%%
|
||||||
|
*.la
|
||||||
|
*.prl
|
||||||
|
*.pc
|
||||||
|
*.pri
|
||||||
|
*.cmake
|
||||||
|
|
@ -8,6 +8,8 @@
|
|||||||
<file>files-to-patch-macx-qt5</file>
|
<file>files-to-patch-macx-qt5</file>
|
||||||
<file>files-to-patch-linux-emb-arm</file>
|
<file>files-to-patch-linux-emb-arm</file>
|
||||||
<file>files-to-patch-windows-emb-arm</file>
|
<file>files-to-patch-windows-emb-arm</file>
|
||||||
<file>files-to-patch-macx-emb-arm</file>
|
<file>files-to-patch-windows-emb-arm-qt5</file>
|
||||||
|
<file>files-to-patch-macx-emb-arm-qt5</file>
|
||||||
|
<file>files-to-patch-linux-emb-arm-qt5</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -65,29 +65,24 @@ static QString errnoToQString(int error)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool removeDirectory(const QString &path, QString *errorString, bool force = true)
|
static bool removeDirectory(const QString &path, QString *errorString, bool force)
|
||||||
{
|
{
|
||||||
Q_ASSERT(errorString);
|
Q_ASSERT(errorString);
|
||||||
const QFileInfoList entries = QDir(path).entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden);
|
|
||||||
for (QFileInfoList::const_iterator it = entries.constBegin(); it != entries.constEnd(); ++it) {
|
QDir dir = path;
|
||||||
if (it->isDir() && !it->isSymLink()) {
|
const QFileInfoList entries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden);
|
||||||
removeDirectory(it->filePath(), errorString, force);
|
foreach (const QFileInfo &entry, entries) {
|
||||||
} else if (force) {
|
if (entry.isDir() && (!entry.isSymLink()))
|
||||||
QFile f(it->filePath());
|
removeDirectory(entry.filePath(), errorString, force);
|
||||||
if (!f.remove())
|
else if (force && (!QFile(entry.filePath()).remove()))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// even remove some hidden, OS-created files in there
|
// even remove some hidden, OS-created files in there
|
||||||
#if defined Q_OS_MAC
|
QInstaller::removeSystemGeneratedFiles(path);
|
||||||
QFile::remove(path + QLatin1String("/.DS_Store"));
|
|
||||||
#elif defined Q_OS_WIN
|
|
||||||
QFile::remove(path + QLatin1String("/Thumbs.db"));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
const bool success = QDir().rmdir(path);
|
const bool success = dir.rmdir(path);
|
||||||
if (errno)
|
if (errno)
|
||||||
*errorString = errnoToQString(errno);
|
*errorString = errnoToQString(errno);
|
||||||
return success;
|
return success;
|
||||||
@ -170,7 +165,7 @@ bool CopyOperation::performOperation()
|
|||||||
QFile sourceFile(source);
|
QFile sourceFile(source);
|
||||||
if (!sourceFile.exists()) {
|
if (!sourceFile.exists()) {
|
||||||
setError(UserDefinedError);
|
setError(UserDefinedError);
|
||||||
setErrorString(tr("Could not copy a none existing file: %1").arg(source));
|
setErrorString(tr("Could not copy a non-existent file: %1").arg(source));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// If destination file exists, we cannot use QFile::copy() because it does not overwrite an existing
|
// If destination file exists, we cannot use QFile::copy() because it does not overwrite an existing
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include <kdrunoncechecker.h>
|
#include <kdrunoncechecker.h>
|
||||||
#include <kdupdaterfiledownloaderfactory.h>
|
#include <kdupdaterfiledownloaderfactory.h>
|
||||||
|
|
||||||
|
#include <QDirIterator>
|
||||||
#include <QtCore/QTranslator>
|
#include <QtCore/QTranslator>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
@ -254,11 +255,10 @@ int main(int argc, char *argv[])
|
|||||||
qDebug() << "Resource tree before loading the in-binary resource:";
|
qDebug() << "Resource tree before loading the in-binary resource:";
|
||||||
qDebug() << "Language: " << QLocale().uiLanguages().value(0, QLatin1String("No UI language set"));
|
qDebug() << "Language: " << QLocale().uiLanguages().value(0, QLatin1String("No UI language set"));
|
||||||
|
|
||||||
QDir dir(QLatin1String(":/"));
|
QDirIterator it(QLatin1String(":/"), QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden,
|
||||||
foreach (const QString &i, dir.entryList()) {
|
QDirIterator::Subdirectories);
|
||||||
const QByteArray ba = i.toUtf8();
|
while (it.hasNext())
|
||||||
qDebug().nospace() << " :/" << ba.constData();
|
qDebug() << QString::fromLatin1(" %1").arg(it.next());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// register custom operations before reading the binary content cause they may used in
|
// register custom operations before reading the binary content cause they may used in
|
||||||
@ -296,59 +296,6 @@ int main(int argc, char *argv[])
|
|||||||
// instantiate the installer we are actually going to use
|
// instantiate the installer we are actually going to use
|
||||||
QInstaller::PackageManagerCore core(content.magicMarker(), content.performedOperations());
|
QInstaller::PackageManagerCore core(content.magicMarker(), content.performedOperations());
|
||||||
|
|
||||||
if (QInstaller::isVerbose()) {
|
|
||||||
qDebug() << "Resource tree after loading the in-binary resource:";
|
|
||||||
|
|
||||||
QDir dir = QDir(QLatin1String(":/"));
|
|
||||||
foreach (const QString &i, dir.entryList())
|
|
||||||
qDebug() << QString::fromLatin1(" :/%1").arg(i);
|
|
||||||
|
|
||||||
dir = QDir(QLatin1String(":/metadata/"));
|
|
||||||
foreach (const QString &i, dir.entryList())
|
|
||||||
qDebug() << QString::fromLatin1(" :/metadata/%1").arg(i);
|
|
||||||
|
|
||||||
dir = QDir(QLatin1String(":/translations/"));
|
|
||||||
foreach (const QString &i, dir.entryList())
|
|
||||||
qDebug() << QString::fromLatin1(" :/translations/%1").arg(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString directory = QLatin1String(":/translations");
|
|
||||||
const QStringList translations = core.settings().translations();
|
|
||||||
|
|
||||||
// install the default Qt translator
|
|
||||||
QScopedPointer<QTranslator> translator(new QTranslator(&app));
|
|
||||||
foreach (const QLocale locale, QLocale().uiLanguages()) {
|
|
||||||
// As there is no qt_en.qm, we simply end the search when the next
|
|
||||||
// preferred language is English.
|
|
||||||
if (locale.language() == QLocale::English)
|
|
||||||
break;
|
|
||||||
if (translator->load(locale, QLatin1String("qt"), QString::fromLatin1("_"), directory)) {
|
|
||||||
app.installTranslator(translator.take());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
translator.reset(new QTranslator(&app));
|
|
||||||
// install English translation as fallback so that correct license button text is used
|
|
||||||
if (translator->load(QLatin1String("en_us"), directory))
|
|
||||||
app.installTranslator(translator.take());
|
|
||||||
|
|
||||||
if (translations.isEmpty()) {
|
|
||||||
translator.reset(new QTranslator(&app));
|
|
||||||
foreach (const QLocale locale, QLocale().uiLanguages()) {
|
|
||||||
if (translator->load(locale, QLatin1String(""), QLatin1String(""), directory)) {
|
|
||||||
app.installTranslator(translator.take());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
foreach (const QString &translation, translations) {
|
|
||||||
translator.reset(new QTranslator(&app));
|
|
||||||
if (translator->load(translation, QLatin1String(":/translations")))
|
|
||||||
app.installTranslator(translator.take());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString controlScript;
|
QString controlScript;
|
||||||
QHash<QString, QString> params;
|
QHash<QString, QString> params;
|
||||||
for (int i = 1; i < args.size(); ++i) {
|
for (int i = 1; i < args.size(); ++i) {
|
||||||
@ -413,6 +360,56 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this needs to happen after we parse the arguments, but before we use the actual resources
|
||||||
|
const QString newDefaultResource = core.value(QString::fromLatin1("DefaultResourceReplacement"));
|
||||||
|
if (!newDefaultResource.isEmpty())
|
||||||
|
content.registerAsDefaultQResource(newDefaultResource);
|
||||||
|
|
||||||
|
if (QInstaller::isVerbose()) {
|
||||||
|
qDebug() << "Resource tree after loading the in-binary resource:";
|
||||||
|
QDirIterator it(QLatin1String(":/"), QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden,
|
||||||
|
QDirIterator::Subdirectories);
|
||||||
|
while (it.hasNext())
|
||||||
|
qDebug() << QString::fromLatin1(" %1").arg(it.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString directory = QLatin1String(":/translations");
|
||||||
|
const QStringList translations = core.settings().translations();
|
||||||
|
|
||||||
|
// install the default Qt translator
|
||||||
|
QScopedPointer<QTranslator> translator(new QTranslator(&app));
|
||||||
|
foreach (const QLocale locale, QLocale().uiLanguages()) {
|
||||||
|
// As there is no qt_en.qm, we simply end the search when the next
|
||||||
|
// preferred language is English.
|
||||||
|
if (locale.language() == QLocale::English)
|
||||||
|
break;
|
||||||
|
if (translator->load(locale, QLatin1String("qt"), QString::fromLatin1("_"), directory)) {
|
||||||
|
app.installTranslator(translator.take());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
translator.reset(new QTranslator(&app));
|
||||||
|
// install English translation as fallback so that correct license button text is used
|
||||||
|
if (translator->load(QLatin1String("en_us"), directory))
|
||||||
|
app.installTranslator(translator.take());
|
||||||
|
|
||||||
|
if (translations.isEmpty()) {
|
||||||
|
translator.reset(new QTranslator(&app));
|
||||||
|
foreach (const QLocale locale, QLocale().uiLanguages()) {
|
||||||
|
if (translator->load(locale, QLatin1String(""), QLatin1String(""), directory)) {
|
||||||
|
app.installTranslator(translator.take());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach (const QString &translation, translations) {
|
||||||
|
translator.reset(new QTranslator(&app));
|
||||||
|
if (translator->load(translation, QLatin1String(":/translations")))
|
||||||
|
app.installTranslator(translator.take());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create the wizard gui
|
// Create the wizard gui
|
||||||
TabController controller(0);
|
TabController controller(0);
|
||||||
controller.setManager(&core);
|
controller.setManager(&core);
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
# include <windows.h>
|
||||||
# include <wincon.h>
|
# include <wincon.h>
|
||||||
|
|
||||||
# ifndef ENABLE_INSERT_MODE
|
# ifndef ENABLE_INSERT_MODE
|
||||||
@ -135,6 +136,12 @@ public:
|
|||||||
m_oldCerr = std::cerr.rdbuf();
|
m_oldCerr = std::cerr.rdbuf();
|
||||||
m_newCerr.open("CONOUT$");
|
m_newCerr.open("CONOUT$");
|
||||||
std::cerr.rdbuf(m_newCerr.rdbuf());
|
std::cerr.rdbuf(m_newCerr.rdbuf());
|
||||||
|
# ifndef Q_CC_MINGW
|
||||||
|
HMENU systemMenu = GetSystemMenu(GetConsoleWindow(), FALSE);
|
||||||
|
if (systemMenu != NULL)
|
||||||
|
RemoveMenu(systemMenu, SC_CLOSE, MF_BYCOMMAND);
|
||||||
|
DrawMenuBar(GetConsoleWindow());
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
~MyApplicationConsole()
|
~MyApplicationConsole()
|
||||||
|
@ -75,16 +75,19 @@ IntroductionPageImpl::IntroductionPageImpl(QInstaller::PackageManagerCore *core)
|
|||||||
QVBoxLayout *layout = new QVBoxLayout(widget);
|
QVBoxLayout *layout = new QVBoxLayout(widget);
|
||||||
|
|
||||||
m_packageManager = new QRadioButton(tr("Package manager"), this);
|
m_packageManager = new QRadioButton(tr("Package manager"), this);
|
||||||
|
m_packageManager->setObjectName(QLatin1String("PackageManagerRadioButton"));
|
||||||
layout->addWidget(m_packageManager);
|
layout->addWidget(m_packageManager);
|
||||||
m_packageManager->setChecked(core->isPackageManager());
|
m_packageManager->setChecked(core->isPackageManager());
|
||||||
connect(m_packageManager, SIGNAL(toggled(bool)), this, SLOT(setPackageManager(bool)));
|
connect(m_packageManager, SIGNAL(toggled(bool)), this, SLOT(setPackageManager(bool)));
|
||||||
|
|
||||||
m_updateComponents = new QRadioButton(tr("Update components"), this);
|
m_updateComponents = new QRadioButton(tr("Update components"), this);
|
||||||
|
m_updateComponents->setObjectName(QLatin1String("UpdaterRadioButton"));
|
||||||
layout->addWidget(m_updateComponents);
|
layout->addWidget(m_updateComponents);
|
||||||
m_updateComponents->setChecked(core->isUpdater());
|
m_updateComponents->setChecked(core->isUpdater());
|
||||||
connect(m_updateComponents, SIGNAL(toggled(bool)), this, SLOT(setUpdater(bool)));
|
connect(m_updateComponents, SIGNAL(toggled(bool)), this, SLOT(setUpdater(bool)));
|
||||||
|
|
||||||
m_removeAllComponents = new QRadioButton(tr("Remove all components"), this);
|
m_removeAllComponents = new QRadioButton(tr("Remove all components"), this);
|
||||||
|
m_removeAllComponents->setObjectName(QLatin1String("UninstallerRadioButton"));
|
||||||
layout->addWidget(m_removeAllComponents);
|
layout->addWidget(m_removeAllComponents);
|
||||||
m_removeAllComponents->setChecked(core->isUninstaller());
|
m_removeAllComponents->setChecked(core->isUninstaller());
|
||||||
connect(m_removeAllComponents, SIGNAL(toggled(bool)), this, SLOT(setUninstaller(bool)));
|
connect(m_removeAllComponents, SIGNAL(toggled(bool)), this, SLOT(setUninstaller(bool)));
|
||||||
|
@ -150,7 +150,6 @@ int TabController::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
d->m_gui->restart();
|
d->m_gui->restart();
|
||||||
d->m_gui->setWindowModality(Qt::WindowModal);
|
|
||||||
d->m_gui->show();
|
d->m_gui->show();
|
||||||
|
|
||||||
onCurrentIdChanged(d->m_gui->currentId());
|
onCurrentIdChanged(d->m_gui->currentId());
|
||||||
|
@ -99,7 +99,7 @@
|
|||||||
<translation>無効な引数: %1個の引数が渡されましたが、必要なのは2個です。</translation>
|
<translation>無効な引数: %1個の引数が渡されましたが、必要なのは2個です。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Could not copy a none existing file: %1</source>
|
<source>Could not copy a non-existent file: %1</source>
|
||||||
<translation>存在しないファイルはコピーできません: %1</translation>
|
<translation>存在しないファイルはコピーできません: %1</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
5
tests/auto/installer/binaryformat/binaryformat.pro
Normal file
5
tests/auto/installer/binaryformat/binaryformat.pro
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
include(../../qttest.pri)
|
||||||
|
|
||||||
|
QT -= gui
|
||||||
|
|
||||||
|
SOURCES += tst_binaryformat.cpp
|
115
tests/auto/installer/binaryformat/tst_binaryformat.cpp
Normal file
115
tests/auto/installer/binaryformat/tst_binaryformat.cpp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Installer Framework.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <binaryformat.h>
|
||||||
|
#include <errors.h>
|
||||||
|
#include <fileutils.h>
|
||||||
|
|
||||||
|
#include <QTest>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
|
static const qint64 scTinySize = 72704LL;
|
||||||
|
static const qint64 scSmallSize = 524288LL;
|
||||||
|
static const qint64 scLargeSize = 2097152LL;
|
||||||
|
|
||||||
|
class tst_BinaryFormat : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void findMagicCookieSmallFile()
|
||||||
|
{
|
||||||
|
QTemporaryFile file;
|
||||||
|
file.open();
|
||||||
|
|
||||||
|
try {
|
||||||
|
QInstaller::blockingWrite(&file, QByteArray(scSmallSize, '1'));
|
||||||
|
QInstaller::appendInt64(&file, QInstaller::MagicCookie);
|
||||||
|
|
||||||
|
QCOMPARE(QInstaller::findMagicCookie(&file, QInstaller::MagicCookie), scSmallSize);
|
||||||
|
} catch (const QInstaller::Error &error) {
|
||||||
|
QFAIL(qPrintable(error.message()));
|
||||||
|
} catch (...) {
|
||||||
|
QFAIL("Unexpected error.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void findMagicCookieLargeFile()
|
||||||
|
{
|
||||||
|
QTemporaryFile file;
|
||||||
|
file.open();
|
||||||
|
|
||||||
|
try {
|
||||||
|
QInstaller::blockingWrite(&file, QByteArray(scLargeSize, '1'));
|
||||||
|
QInstaller::appendInt64(&file, QInstaller::MagicCookie);
|
||||||
|
QInstaller::blockingWrite(&file, QByteArray(scTinySize, '2'));
|
||||||
|
|
||||||
|
QCOMPARE(QInstaller::findMagicCookie(&file, QInstaller::MagicCookie), scLargeSize);
|
||||||
|
} catch (const QInstaller::Error &error) {
|
||||||
|
QFAIL(qPrintable(error.message()));
|
||||||
|
} catch (...) {
|
||||||
|
QFAIL("Unexpected error.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFindMagicCookieWithError()
|
||||||
|
{
|
||||||
|
QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"No marker found, stopped after 71.00 KiB.\" ");
|
||||||
|
|
||||||
|
QTemporaryFile file;
|
||||||
|
file.open();
|
||||||
|
|
||||||
|
try {
|
||||||
|
QInstaller::blockingWrite(&file, QByteArray(scTinySize, '1'));
|
||||||
|
|
||||||
|
// throws
|
||||||
|
QInstaller::findMagicCookie(&file, QInstaller::MagicCookie);
|
||||||
|
} catch (const QInstaller::Error &error) {
|
||||||
|
QCOMPARE(qPrintable(error.message()), "No marker found, stopped after 71.00 KiB.");
|
||||||
|
} catch (...) {
|
||||||
|
QFAIL("Unexpected error.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QTEST_MAIN(tst_BinaryFormat)
|
||||||
|
|
||||||
|
#include "tst_binaryformat.moc"
|
@ -12,5 +12,6 @@ SUBDIRS += \
|
|||||||
consumeoutputoperationtest \
|
consumeoutputoperationtest \
|
||||||
mkdiroperationtest \
|
mkdiroperationtest \
|
||||||
copyoperationtest \
|
copyoperationtest \
|
||||||
solver
|
solver \
|
||||||
|
binaryformat
|
||||||
|
|
||||||
|
@ -26,9 +26,9 @@ public:
|
|||||||
|
|
||||||
virtual void init() {}
|
virtual void init() {}
|
||||||
|
|
||||||
void callProtectedDelayedControlScriptExecution(int id)
|
void callProtectedDelayedExecuteControlScript(int id)
|
||||||
{
|
{
|
||||||
delayedControlScriptExecution(id);
|
executeControlScript(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -218,18 +218,16 @@ private slots:
|
|||||||
testGui.loadControlScript(":///data/auto-install.qs");
|
testGui.loadControlScript(":///data/auto-install.qs");
|
||||||
QCOMPARE(m_core.value("GuiTestValue"), QString("hello"));
|
QCOMPARE(m_core.value("GuiTestValue"), QString("hello"));
|
||||||
|
|
||||||
testGui.show();
|
|
||||||
// show event calls automatically the first callback which does not exist
|
// show event calls automatically the first callback which does not exist
|
||||||
setExpectedScriptOutput("Control script callback \"IntroductionPageCallback\" does not exist. ");
|
setExpectedScriptOutput("Control script callback \"IntroductionPageCallback\" does not exist. ");
|
||||||
// give some time to the event triggering mechanism
|
testGui.show();
|
||||||
qApp->processEvents();
|
|
||||||
|
|
||||||
// inside the auto-install script we are clicking the next button, with a not existing button
|
// inside the auto-install script we are clicking the next button, with a not existing button
|
||||||
QTest::ignoreMessage(QtWarningMsg, "Button with type: \"unknown button\" not found! ");
|
QTest::ignoreMessage(QtWarningMsg, "Button with type: \"unknown button\" not found! ");
|
||||||
testGui.callProtectedDelayedControlScriptExecution(PackageManagerCore::ComponentSelection);
|
testGui.callProtectedDelayedExecuteControlScript(PackageManagerCore::ComponentSelection);
|
||||||
|
|
||||||
setExpectedScriptOutput("FinishedPageCallback - OK");
|
setExpectedScriptOutput("FinishedPageCallback - OK");
|
||||||
testGui.callProtectedDelayedControlScriptExecution(PackageManagerCore::InstallationFinished);
|
testGui.callProtectedDelayedExecuteControlScript(PackageManagerCore::InstallationFinished);
|
||||||
} catch (const Error &error) {
|
} catch (const Error &error) {
|
||||||
QFAIL(qPrintable(error.message()));
|
QFAIL(qPrintable(error.message()));
|
||||||
}
|
}
|
||||||
|
@ -164,6 +164,7 @@ int main(int argc, char *argv[])
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
const QUrl url(a.arguments().value(1));
|
const QUrl url(a.arguments().value(1));
|
||||||
|
KDUpdater::FileDownloaderFactory::setFollowRedirects(true);
|
||||||
qDebug() << url.toString();
|
qDebug() << url.toString();
|
||||||
KDUpdater::FileDownloader *loader = KDUpdater::FileDownloaderFactory::instance().create(url.scheme(), 0);
|
KDUpdater::FileDownloader *loader = KDUpdater::FileDownloaderFactory::instance().create(url.scheme(), 0);
|
||||||
if (loader) {
|
if (loader) {
|
||||||
|
@ -400,7 +400,7 @@ private:
|
|||||||
const QString oldPath;
|
const QString oldPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QString createBinaryResourceFile(const QString &directory)
|
static QString createBinaryResourceFile(const QString &directory, const QString &binaryName)
|
||||||
{
|
{
|
||||||
QTemporaryFile projectFile(directory + QLatin1String("/rccprojectXXXXXX.qrc"));
|
QTemporaryFile projectFile(directory + QLatin1String("/rccprojectXXXXXX.qrc"));
|
||||||
if (!projectFile.open())
|
if (!projectFile.open())
|
||||||
@ -408,16 +408,19 @@ static QString createBinaryResourceFile(const QString &directory)
|
|||||||
projectFile.close();
|
projectFile.close();
|
||||||
|
|
||||||
const WorkingDirectoryChange wd(directory);
|
const WorkingDirectoryChange wd(directory);
|
||||||
const QString binaryName = generateTemporaryFileName();
|
|
||||||
const QString projectFileName = QFileInfo(projectFile.fileName()).absoluteFilePath();
|
const QString projectFileName = QFileInfo(projectFile.fileName()).absoluteFilePath();
|
||||||
|
|
||||||
// 1. create the .qrc file
|
// 1. create the .qrc file
|
||||||
runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-project")
|
if (runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-project") << QLatin1String("-o")
|
||||||
<< QLatin1String("-o") << projectFileName);
|
<< projectFileName) != EXIT_SUCCESS) {
|
||||||
|
throw Error(QString::fromLatin1("Could not create rcc project file."));
|
||||||
|
}
|
||||||
|
|
||||||
// 2. create the binary resource file from the .qrc file
|
// 2. create the binary resource file from the .qrc file
|
||||||
runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-binary")
|
if (runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-binary") << QLatin1String("-o")
|
||||||
<< QLatin1String("-o") << binaryName << projectFileName);
|
<< binaryName << projectFileName) != EXIT_SUCCESS) {
|
||||||
|
throw Error(QString::fromLatin1("Could not compile rcc project file."));
|
||||||
|
}
|
||||||
|
|
||||||
return binaryName;
|
return binaryName;
|
||||||
}
|
}
|
||||||
@ -467,7 +470,12 @@ static void printUsage()
|
|||||||
std::cout << " -r|--resources r1,.,rn include the given resource files into the binary" << std::endl;
|
std::cout << " -r|--resources r1,.,rn include the given resource files into the binary" << std::endl;
|
||||||
|
|
||||||
std::cout << " -v|--verbose Verbose output" << std::endl;
|
std::cout << " -v|--verbose Verbose output" << std::endl;
|
||||||
std::cout << std::endl << std::endl;
|
std::cout << " -rcc|--compile-resource Compiles the default resource and outputs the result into"
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << " 'update.rcc' in the current path." << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "Packages are to be found in the current working directory and get listed as "
|
||||||
|
"their names" << std::endl << std::endl;
|
||||||
std::cout << "Example (offline installer):" << std::endl;
|
std::cout << "Example (offline installer):" << std::endl;
|
||||||
char sep = QDir::separator().toLatin1();
|
char sep = QDir::separator().toLatin1();
|
||||||
std::cout << " " << appName << " --offline-only -c installer-config" << sep << "config.xml -p "
|
std::cout << " " << appName << " --offline-only -c installer-config" << sep << "config.xml -p "
|
||||||
@ -481,6 +489,9 @@ static void printUsage()
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << "Creates an installer for the SDK without qt and qt creator." << std::endl;
|
std::cout << "Creates an installer for the SDK without qt and qt creator." << std::endl;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
std::cout << "Example update.rcc:" << std::endl;
|
||||||
|
std::cout << " " << appName << " -c installer-config" << sep << "config.xml -p packages-directory "
|
||||||
|
"-rcc" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyConfigData(const QString &configFile, const QString &targetDir)
|
void copyConfigData(const QString &configFile, const QString &targetDir)
|
||||||
@ -576,6 +587,7 @@ int main(int argc, char **argv)
|
|||||||
QStringList resources;
|
QStringList resources;
|
||||||
QStringList filteredPackages;
|
QStringList filteredPackages;
|
||||||
QInstallerTools::FilterType ftype = QInstallerTools::Exclude;
|
QInstallerTools::FilterType ftype = QInstallerTools::Exclude;
|
||||||
|
bool compileResource = false;
|
||||||
|
|
||||||
const QStringList args = app.arguments().mid(1);
|
const QStringList args = app.arguments().mid(1);
|
||||||
for (QStringList::const_iterator it = args.begin(); it != args.end(); ++it) {
|
for (QStringList::const_iterator it = args.begin(); it != args.end(); ++it) {
|
||||||
@ -661,6 +673,8 @@ int main(int argc, char **argv)
|
|||||||
} else if (*it == QLatin1String("--ignore-translations")
|
} else if (*it == QLatin1String("--ignore-translations")
|
||||||
|| *it == QLatin1String("--ignore-invalid-packages")) {
|
|| *it == QLatin1String("--ignore-invalid-packages")) {
|
||||||
continue;
|
continue;
|
||||||
|
} else if (*it == QLatin1String("-rcc") || *it == QLatin1String("--compile-resource")) {
|
||||||
|
compileResource = true;
|
||||||
} else {
|
} else {
|
||||||
if (it->startsWith(QLatin1String("-"))) {
|
if (it->startsWith(QLatin1String("-"))) {
|
||||||
return printErrorAndUsageAndExit(QString::fromLatin1("Error: Unknown option \"%1\" used. Maybe you "
|
return printErrorAndUsageAndExit(QString::fromLatin1("Error: Unknown option \"%1\" used. Maybe you "
|
||||||
@ -689,7 +703,7 @@ int main(int argc, char **argv)
|
|||||||
ftype = QInstallerTools::Include;
|
ftype = QInstallerTools::Include;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.isEmpty())
|
if (target.isEmpty() && !compileResource)
|
||||||
return printErrorAndUsageAndExit(QString::fromLatin1("Error: Target parameter missing."));
|
return printErrorAndUsageAndExit(QString::fromLatin1("Error: Target parameter missing."));
|
||||||
|
|
||||||
if (configFile.isEmpty())
|
if (configFile.isEmpty())
|
||||||
@ -723,11 +737,11 @@ int main(int argc, char **argv)
|
|||||||
if (!target.endsWith(QLatin1String(".app")) && !target.endsWith(QLatin1String(".dmg")))
|
if (!target.endsWith(QLatin1String(".app")) && !target.endsWith(QLatin1String(".dmg")))
|
||||||
target += QLatin1String(".app");
|
target += QLatin1String(".app");
|
||||||
#endif
|
#endif
|
||||||
{
|
if (!compileResource) {
|
||||||
Input input;
|
Input input;
|
||||||
input.outputPath = target;
|
input.outputPath = target;
|
||||||
input.installerExePath = templateBinary;
|
input.installerExePath = templateBinary;
|
||||||
input.binaryResourcePath = createBinaryResourceFile(tmpMetaDir);
|
input.binaryResourcePath = createBinaryResourceFile(tmpMetaDir, generateTemporaryFileName());
|
||||||
input.binaryResources = createBinaryResourceFiles(resources);
|
input.binaryResources = createBinaryResourceFiles(resources);
|
||||||
|
|
||||||
QInstallerTools::copyComponentData(packagesDirectories, tmpMetaDir, &packages);
|
QInstallerTools::copyComponentData(packagesDirectories, tmpMetaDir, &packages);
|
||||||
@ -755,6 +769,9 @@ int main(int argc, char **argv)
|
|||||||
QFile::remove(input.binaryResourcePath);
|
QFile::remove(input.binaryResourcePath);
|
||||||
foreach (const QString &resource, input.binaryResources)
|
foreach (const QString &resource, input.binaryResources)
|
||||||
QFile::remove(resource);
|
QFile::remove(resource);
|
||||||
|
} else {
|
||||||
|
createBinaryResourceFile(tmpMetaDir, QDir::currentPath() + QLatin1String("/update.rcc"));
|
||||||
|
exitCode = EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
} catch (const Error &e) {
|
} catch (const Error &e) {
|
||||||
std::cerr << "Caught exception: " << e.message() << std::endl;
|
std::cerr << "Caught exception: " << e.message() << std::endl;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user