summaryrefslogtreecommitdiffstats
path: root/src/libs/installer
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/installer')
-rw-r--r--src/libs/installer/adminauthorization_win.cpp6
-rw-r--r--src/libs/installer/adminauthorization_x11.cpp17
-rw-r--r--src/libs/installer/binarycontent.cpp10
-rw-r--r--src/libs/installer/binaryformat.cpp4
-rw-r--r--src/libs/installer/component.cpp51
-rw-r--r--src/libs/installer/component.h7
-rw-r--r--src/libs/installer/componentchecker.cpp12
-rw-r--r--src/libs/installer/componentmodel.cpp10
-rw-r--r--src/libs/installer/constants.h9
-rw-r--r--src/libs/installer/consumeoutputoperation.cpp31
-rw-r--r--src/libs/installer/consumeoutputoperation.h3
-rw-r--r--src/libs/installer/copydirectoryoperation.cpp48
-rw-r--r--src/libs/installer/copydirectoryoperation.h3
-rw-r--r--src/libs/installer/copyfiletask.cpp13
-rw-r--r--src/libs/installer/createdesktopentryoperation.cpp29
-rw-r--r--src/libs/installer/createdesktopentryoperation.h3
-rw-r--r--src/libs/installer/createlinkoperation.cpp24
-rw-r--r--src/libs/installer/createlinkoperation.h3
-rw-r--r--src/libs/installer/createlocalrepositoryoperation.cpp70
-rw-r--r--src/libs/installer/createlocalrepositoryoperation.h3
-rw-r--r--src/libs/installer/createshortcutoperation.cpp125
-rw-r--r--src/libs/installer/createshortcutoperation.h12
-rw-r--r--src/libs/installer/downloadarchivesjob.cpp36
-rw-r--r--src/libs/installer/downloadarchivesjob.h4
-rw-r--r--src/libs/installer/downloadfiletask.cpp78
-rw-r--r--src/libs/installer/downloadfiletask.h2
-rw-r--r--src/libs/installer/downloadfiletask_p.h4
-rw-r--r--src/libs/installer/elevatedexecuteoperation.cpp34
-rw-r--r--src/libs/installer/elevatedexecuteoperation.h13
-rw-r--r--src/libs/installer/environmentvariablesoperation.cpp32
-rw-r--r--src/libs/installer/environmentvariablesoperation.h3
-rw-r--r--src/libs/installer/errors.h12
-rw-r--r--src/libs/installer/extractarchiveoperation.cpp74
-rw-r--r--src/libs/installer/extractarchiveoperation.h3
-rw-r--r--src/libs/installer/extractarchiveoperation_p.h144
-rw-r--r--src/libs/installer/fakestopprocessforupdateoperation.cpp17
-rw-r--r--src/libs/installer/fakestopprocessforupdateoperation.h3
-rw-r--r--src/libs/installer/fileio.cpp12
-rw-r--r--src/libs/installer/fileutils.cpp67
-rw-r--r--src/libs/installer/fileutils.h2
-rw-r--r--src/libs/installer/globalsettingsoperation.cpp20
-rw-r--r--src/libs/installer/globalsettingsoperation.h3
-rw-r--r--src/libs/installer/init.cpp64
-rw-r--r--src/libs/installer/installer.pro10
-rw-r--r--src/libs/installer/installercalculator.cpp14
-rw-r--r--src/libs/installer/installiconsoperation.cpp48
-rw-r--r--src/libs/installer/installiconsoperation.h3
-rw-r--r--src/libs/installer/lib7z_create.h82
-rw-r--r--src/libs/installer/lib7z_extract.h85
-rw-r--r--src/libs/installer/lib7z_facade.cpp1856
-rw-r--r--src/libs/installer/lib7z_facade.h261
-rw-r--r--src/libs/installer/lib7z_guid.h97
-rw-r--r--src/libs/installer/lib7z_list.h62
-rw-r--r--src/libs/installer/licenseoperation.cpp23
-rw-r--r--src/libs/installer/licenseoperation.h3
-rw-r--r--src/libs/installer/linereplaceoperation.cpp24
-rw-r--r--src/libs/installer/linereplaceoperation.h3
-rw-r--r--src/libs/installer/link.cpp26
-rw-r--r--src/libs/installer/messageboxhandler.cpp4
-rw-r--r--src/libs/installer/metadatajob.cpp52
-rw-r--r--src/libs/installer/metadatajob.h4
-rw-r--r--src/libs/installer/metadatajob_p.h12
-rw-r--r--src/libs/installer/minimumprogressoperation.cpp9
-rw-r--r--src/libs/installer/minimumprogressoperation.h3
-rw-r--r--src/libs/installer/packagemanagercore.cpp135
-rw-r--r--src/libs/installer/packagemanagercore.h6
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp316
-rw-r--r--src/libs/installer/packagemanagercore_p.h38
-rw-r--r--src/libs/installer/packagemanagercoredata.cpp82
-rw-r--r--src/libs/installer/packagemanagercoredata.h3
-rw-r--r--src/libs/installer/packagemanagergui.cpp280
-rw-r--r--src/libs/installer/packagemanagergui.h5
-rw-r--r--src/libs/installer/packagemanagerpagefactory.cpp5
-rw-r--r--src/libs/installer/packagemanagerpagefactory.h13
-rw-r--r--src/libs/installer/packagemanagerproxyfactory.cpp2
-rw-r--r--src/libs/installer/packagemanagerproxyfactory.h2
-rw-r--r--src/libs/installer/packagesource.cpp91
-rw-r--r--src/libs/installer/packagesource.h63
-rw-r--r--src/libs/installer/performinstallationform.cpp11
-rw-r--r--src/libs/installer/progresscoordinator.cpp2
-rw-r--r--src/libs/installer/proxycredentialsdialog.h2
-rw-r--r--src/libs/installer/qinstallerglobal.h9
-rw-r--r--src/libs/installer/qprocesswrapper.cpp24
-rw-r--r--src/libs/installer/qprocesswrapper.h1
-rw-r--r--src/libs/installer/qtpatch.cpp14
-rw-r--r--src/libs/installer/registerfiletypeoperation.cpp23
-rw-r--r--src/libs/installer/registerfiletypeoperation.h3
-rw-r--r--src/libs/installer/remoteclient.cpp13
-rw-r--r--src/libs/installer/remoteclient.h2
-rw-r--r--src/libs/installer/remoteclient_p.h8
-rw-r--r--src/libs/installer/remoteobject.h2
-rw-r--r--src/libs/installer/remoteserver.cpp8
-rw-r--r--src/libs/installer/remoteserver_p.h6
-rw-r--r--src/libs/installer/remoteserverconnection_p.h24
-rw-r--r--src/libs/installer/replaceoperation.cpp24
-rw-r--r--src/libs/installer/replaceoperation.h3
-rw-r--r--src/libs/installer/repository.cpp2
-rw-r--r--src/libs/installer/resources/install.pngbin0 -> 268 bytes
-rw-r--r--src/libs/installer/resources/installer.qrc4
-rw-r--r--src/libs/installer/resources/keepinstalled.pngbin0 -> 239 bytes
-rw-r--r--src/libs/installer/resources/keepuninstalled.pngbin0 -> 203 bytes
-rw-r--r--src/libs/installer/resources/uninstall.pngbin0 -> 240 bytes
-rw-r--r--src/libs/installer/scriptengine.cpp20
-rw-r--r--src/libs/installer/scriptengine_p.h4
-rw-r--r--src/libs/installer/selfrestartoperation.cpp24
-rw-r--r--src/libs/installer/selfrestartoperation.h3
-rw-r--r--src/libs/installer/settings.cpp48
-rw-r--r--src/libs/installer/settings.h2
-rw-r--r--src/libs/installer/settingsoperation.cpp19
-rw-r--r--src/libs/installer/settingsoperation.h3
-rw-r--r--src/libs/installer/simplemovefileoperation.cpp36
-rw-r--r--src/libs/installer/simplemovefileoperation.h3
-rw-r--r--src/libs/installer/sysinfo_win.cpp2
-rw-r--r--src/libs/installer/testrepository.cpp164
-rw-r--r--src/libs/installer/testrepository.h52
-rw-r--r--src/libs/installer/unziptask.cpp50
116 files changed, 2692 insertions, 2765 deletions
diff --git a/src/libs/installer/adminauthorization_win.cpp b/src/libs/installer/adminauthorization_win.cpp
index 85b9586ad..59ff3efdb 100644
--- a/src/libs/installer/adminauthorization_win.cpp
+++ b/src/libs/installer/adminauthorization_win.cpp
@@ -111,14 +111,14 @@ bool AdminAuthorization::execute(QWidget *, const QString &program, const QStrin
shellExecuteInfo.lpParameters = (wchar_t *)args.utf16();
shellExecuteInfo.fMask = SEE_MASK_NOASYNC;
- qDebug() << QString::fromLatin1("Starting elevated process %1 with arguments: %2.").arg(file, args);
+ qDebug() << "Starting elevated process" << file << "with arguments" << args;
if (ShellExecuteExW(&shellExecuteInfo)) {
qDebug() << "Finished starting elevated process.";
return true;
} else {
- qWarning() << QString::fromLatin1("Error while starting elevated process: %1, "
- "Error: %2").arg(program, QInstaller::windowsErrorString(GetLastError()));
+ qWarning() << "Error while starting elevated process" << program
+ << ":" << QInstaller::windowsErrorString(GetLastError());
}
return false;
}
diff --git a/src/libs/installer/adminauthorization_x11.cpp b/src/libs/installer/adminauthorization_x11.cpp
index 97c6093ae..20eacf1cc 100644
--- a/src/libs/installer/adminauthorization_x11.cpp
+++ b/src/libs/installer/adminauthorization_x11.cpp
@@ -55,6 +55,7 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <errno.h>
#include <iostream>
@@ -130,10 +131,14 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
if (pipe(pipedData) != 0)
return false;
- int flags = ::fcntl(pipedData[0], F_GETFD);
+ int flags = ::fcntl(pipedData[0], F_GETFL);
if (flags != -1)
::fcntl(pipedData[0], F_SETFL, flags | O_NONBLOCK);
+ flags = ::fcntl(masterFD, F_GETFL);
+ if (flags != -1)
+ ::fcntl(masterFD, F_SETFL, flags | O_NONBLOCK);
+
pid_t child = fork();
if (child < -1) {
@@ -151,8 +156,8 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
::close(pipedData[1]);
QRegExp re(QLatin1String("[Pp]assword.*:"));
+ QByteArray data;
QByteArray errData;
- flags = ::fcntl(masterFD, F_GETFD);
int bytes = 0;
int errBytes = 0;
char buf[1024];
@@ -162,14 +167,18 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
if (::waitpid(child, &state, WNOHANG) == -1)
break;
bytes = ::read(masterFD, buf, 1023);
+ if (bytes == -1 && errno == EAGAIN)
+ bytes = 0;
+ else if (bytes > 0)
+ data.append(buf, bytes);
errBytes = ::read(pipedData[0], errBuf, 1023);
if (errBytes > 0)
{
- errData.append(buf, errBytes);
+ errData.append(errBuf, errBytes);
errBytes=0;
}
if (bytes > 0) {
- const QString line = QString::fromLatin1(buf, bytes);
+ const QString line = QString::fromLatin1(data);
if (re.indexIn(line) != -1) {
const QString password = getPassword(parent);
if (password.isEmpty()) {
diff --git a/src/libs/installer/binarycontent.cpp b/src/libs/installer/binarycontent.cpp
index 4396c2964..8daeafda9 100644
--- a/src/libs/installer/binarycontent.cpp
+++ b/src/libs/installer/binarycontent.cpp
@@ -118,7 +118,7 @@ BinaryLayout BinaryContent::binaryLayout(QFile *file, quint64 magicCookie)
const qint64 posOfMetaDataCount = layout.endOfBinaryContent - (4 * sizeof(qint64));
if (!file->seek(posOfMetaDataCount)) {
throw QInstaller::Error(QCoreApplication::translate("BinaryLayout",
- "Could not seek to %1 to read the embedded meta data count.").arg(posOfMetaDataCount));
+ "Cannot seek to %1 to read the embedded meta data count.").arg(posOfMetaDataCount));
}
// read the meta resources count
@@ -129,7 +129,7 @@ BinaryLayout BinaryContent::binaryLayout(QFile *file, quint64 magicCookie)
+ (8 * sizeof(qint64))); // meta count, offset/length collection index, marker, cookie...
if (!file->seek(posOfResourceCollectionsSegment)) {
throw Error(QCoreApplication::translate("BinaryLayout",
- "Could not seek to %1 to read the resource collection segment.")
+ "Cannot seek to %1 to read the resource collection segment.")
.arg(posOfResourceCollectionsSegment));
}
@@ -204,7 +204,7 @@ void BinaryContent::readBinaryContent(QFile *file, QList<OperationBlob> *operati
const qint64 posOfOperationsBlock = layout.operationsSegment.start();
if (!file->seek(posOfOperationsBlock)) {
throw Error(QCoreApplication::translate("BinaryContent",
- "Could not seek to %1 to read the operation data.").arg(posOfOperationsBlock));
+ "Cannot seek to %1 to read the operation data.").arg(posOfOperationsBlock));
}
// read the operations count
qint64 operationsCount = QInstaller::retrieveInt64(file);
@@ -221,7 +221,7 @@ void BinaryContent::readBinaryContent(QFile *file, QList<OperationBlob> *operati
if (manager) { // read the collection index and data
const qint64 posOfResourceCollectionBlock = layout.resourceCollectionsSegment.start();
if (!file->seek(posOfResourceCollectionBlock)) {
- throw Error(QCoreApplication::translate("BinaryContent", "Could not seek to %1 to "
+ throw Error(QCoreApplication::translate("BinaryContent", "Cannot seek to %1 to "
"read the resource collection block.").arg(posOfResourceCollectionBlock));
}
manager->read(file, layout.endOfExectuable);
@@ -260,7 +260,7 @@ void BinaryContent::writeBinaryContent(QFile *out, const QList<OperationBlob> &o
const bool isOpen = resource->isOpen();
if ((!isOpen) && (!resource->open())) {
throw Error(QCoreApplication::translate("BinaryContent",
- "Could not open meta resource. Error: %1").arg(resource->errorString()));
+ "Cannot open meta resource %1.").arg(resource->errorString()));
}
resource->seek(0);
diff --git a/src/libs/installer/binaryformat.cpp b/src/libs/installer/binaryformat.cpp
index b38f9799d..c8bc38304 100644
--- a/src/libs/installer/binaryformat.cpp
+++ b/src/libs/installer/binaryformat.cpp
@@ -169,7 +169,7 @@ bool Resource::open()
}
if (!QIODevice::open(QIODevice::ReadOnly)) {
- setErrorString(tr("Could not open Resource '%1' read-only.").arg(QString::fromUtf8(m_name)));
+ setErrorString(tr("Cannot open resource %1 for reading.").arg(QString::fromUtf8(m_name)));
return false;
}
return true;
@@ -397,7 +397,7 @@ Range<qint64> ResourceCollectionManager::write(QFileDevice *out, qint64 offset)
foreach (const QSharedPointer<Resource> &resource, collection.resources()) {
if (!resource->open()) {
- throw QInstaller::Error(tr("Could not open resource %1: %2")
+ throw QInstaller::Error(tr("Cannot open resource %1: %2")
.arg(QString::fromUtf8(resource->name()), resource->errorString()));
}
resource->copyData(out);
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index 5346aac77..07f526a21 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -43,8 +43,7 @@
#include "settings.h"
#include "utils.h"
-#include <kdupdaterupdatesourcesinfo.h>
-#include <kdupdaterupdateoperationfactory.h>
+#include "updateoperationfactory.h"
#include <productkeycheck.h>
@@ -64,13 +63,13 @@
using namespace QInstaller;
static const QLatin1String scScriptTag("Script");
-static const QLatin1String scAutoDependOn("AutoDependOn");
static const QLatin1String scVirtual("Virtual");
static const QLatin1String scInstalled("Installed");
static const QLatin1String scUpdateText("UpdateText");
static const QLatin1String scUninstalled("Uninstalled");
static const QLatin1String scCurrentState("CurrentState");
static const QLatin1String scForcedInstallation("ForcedInstallation");
+static const QLatin1String scCheckable("Checkable");
/*!
\inmodule QtInstallerFramework
@@ -216,7 +215,7 @@ Component::Component(PackageManagerCore *core)
{
setPrivate(d);
- connect(this, SIGNAL(valueChanged(QString, QString)), this, SLOT(updateModelData(QString, QString)));
+ connect(this, &Component::valueChanged, this, &Component::updateModelData);
qRegisterMetaType<QList<QInstaller::Component*> >("QList<QInstaller::Component*>");
}
@@ -245,10 +244,9 @@ Component::~Component()
/*!
Sets variables according to the values set in the package.xml file of a local \a package.
*/
-void Component::loadDataFromPackage(const LocalPackage &package)
+void Component::loadDataFromPackage(const KDUpdater::LocalPackage &package)
{
setValue(scName, package.name);
- // pixmap ???
setValue(scDisplayName, package.title);
setValue(scDescription, package.description);
setValue(scVersion, package.version);
@@ -257,14 +255,8 @@ void Component::loadDataFromPackage(const LocalPackage &package)
setValue(QLatin1String("LastUpdateDate"), package.lastUpdateDate.toString());
setValue(QLatin1String("InstallDate"), package.installDate.toString());
setValue(scUncompressedSize, QString::number(package.uncompressedSize));
-
- QString dependstr;
- foreach (const QString &val, package.dependencies)
- dependstr += val + QLatin1String(",");
-
- if (package.dependencies.count() > 0)
- dependstr.chop(1);
- setValue(scDependencies, dependstr);
+ setValue(scDependencies, package.dependencies.join(QLatin1String(",")));
+ setValue(scAutoDependOn, package.autoDependencies.join(QLatin1String(",")));
setValue(scForcedInstallation, package.forcedInstallation ? scTrue : scFalse);
if (package.forcedInstallation & !PackageManagerCore::noForceInstallation()) {
@@ -273,6 +265,7 @@ void Component::loadDataFromPackage(const LocalPackage &package)
}
setValue(scVirtual, package.virtualComp ? scTrue : scFalse);
setValue(scCurrentState, scInstalled);
+ setValue(scCheckable, package.checkable ? scTrue : scFalse);
}
/*!
@@ -290,7 +283,7 @@ void Component::loadDataFromPackage(const Package &package)
setValue(scAutoDependOn, package.data(scAutoDependOn).toString());
setValue(scCompressedSize, package.data(scCompressedSize).toString());
setValue(scUncompressedSize, package.data(scUncompressedSize).toString());
- setValue(scRemoteVersion, package.data(scRemoteVersion).toString());
+ setValue(scVersion, package.data(scVersion).toString());
setValue(scInheritVersion, package.data(scInheritVersion).toString());
setValue(scDependencies, package.data(scDependencies).toString());
setValue(scDownloadableArchives, package.data(scDownloadableArchives).toString());
@@ -305,6 +298,7 @@ void Component::loadDataFromPackage(const Package &package)
setValue(scScriptTag, package.data(scScriptTag).toString());
setValue(scReplaces, package.data(scReplaces).toString());
setValue(scReleaseDate, package.data(scReleaseDate).toString());
+ setValue(scCheckable, package.data(scCheckable).toString());
QString forced = package.data(scForcedInstallation, scFalse).toString().toLower();
if (PackageManagerCore::noForceInstallation())
@@ -315,7 +309,7 @@ void Component::loadDataFromPackage(const Package &package)
setCheckState(Qt::Checked);
}
- setLocalTempPath(QInstaller::pathFromUrl(package.sourceInfoUrl()));
+ setLocalTempPath(QInstaller::pathFromUrl(package.packageSource().url));
const QStringList uis = package.data(QLatin1String("UserInterfaces")).toString()
.split(QInstaller::commaRegExp(), QString::SkipEmptyParts);
if (!uis.isEmpty())
@@ -396,6 +390,8 @@ void Component::setValue(const QString &key, const QString &value)
if (key == scName)
d->m_componentName = normalizedValue;
+ if (key == scCheckable)
+ this->setCheckable(normalizedValue.toLower() == scTrue);
d->m_vars[key] = normalizedValue;
emit valueChanged(key, normalizedValue);
@@ -578,8 +574,8 @@ void Component::loadUserInterfaces(const QDir &directory, const QStringList &uis
while (it.hasNext()) {
QFile file(it.next());
if (!file.open(QIODevice::ReadOnly)) {
- throw Error(tr("Could not open the requested UI file '%1'. Error: %2").arg(it.fileName(),
- file.errorString()));
+ throw Error(tr("Cannot open the requested UI file \"%1\": %2").arg(
+ it.fileName(), file.errorString()));
}
static QUiLoader loader;
@@ -587,8 +583,8 @@ void Component::loadUserInterfaces(const QDir &directory, const QStringList &uis
loader.setLanguageChangeEnabled(true);
QWidget *const widget = loader.load(&file, 0);
if (!widget) {
- throw Error(tr("Could not load the requested UI file '%1'. Error: %2").arg(it.fileName(),
- loader.errorString()));
+ throw Error(tr("Cannot load the requested UI file \"%1\": %2").arg(
+ it.fileName(), loader.errorString()));
}
d->scriptEngine()->newQObject(widget);
d->m_userInterfaces.insert(widget->objectName(), widget);
@@ -632,7 +628,7 @@ void Component::loadLicenses(const QString &directory, const QHash<QString, QVar
QFile file(fileInfo.filePath());
if (!file.open(QIODevice::ReadOnly)) {
- throw Error(tr("Could not open the requested license file '%1'. Error: %2").arg(
+ throw Error(tr("Cannot open the requested license file \"%1\": %2").arg(
file.fileName(), file.errorString()));
}
QTextStream stream(&file);
@@ -831,7 +827,7 @@ void Component::addDownloadableArchive(const QString &path)
Q_ASSERT(isFromOnlineRepository());
qDebug() << "addDownloadable" << path;
- d->m_downloadableArchives.append(d->m_vars.value(scRemoteVersion) + path);
+ d->m_downloadableArchives.append(d->m_vars.value(scVersion) + path);
}
/*!
@@ -910,15 +906,14 @@ OperationList Component::operations() const
if (!d->m_minimumProgressOperation) {
d->m_minimumProgressOperation = KDUpdater::UpdateOperationFactory::instance()
- .create(QLatin1String("MinimumProgress"));
+ .create(QLatin1String("MinimumProgress"), d->m_core);
d->m_minimumProgressOperation->setValue(QLatin1String("component"), name());
d->m_operations.append(d->m_minimumProgressOperation);
}
if (!d->m_licenses.isEmpty()) {
d->m_licenseOperation = KDUpdater::UpdateOperationFactory::instance()
- .create(QLatin1String("License"));
- d->m_licenseOperation->setValue(QLatin1String("installer"), QVariant::fromValue(d->m_core));
+ .create(QLatin1String("License"), d->m_core);
d->m_licenseOperation->setValue(QLatin1String("component"), name());
QVariantMap licenses;
@@ -992,11 +987,12 @@ Operation *Component::createOperation(const QString &operationName, const QStrin
Operation *Component::createOperation(const QString &operationName, const QStringList &parameters)
{
- Operation *operation = KDUpdater::UpdateOperationFactory::instance().create(operationName);
+ Operation *operation = KDUpdater::UpdateOperationFactory::instance().create(operationName,
+ d->m_core);
if (operation == 0) {
const QMessageBox::StandardButton button =
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
- QLatin1String("OperationDoesNotExistError"), tr("Error"), tr("Error: Operation %1 does not exist")
+ QLatin1String("OperationDoesNotExistError"), tr("Error"), tr("Error: Operation %1 does not exist.")
.arg(operationName), QMessageBox::Abort | QMessageBox::Ignore);
if (button == QMessageBox::Abort)
d->m_operationsCreatedSuccessfully = false;
@@ -1005,7 +1001,6 @@ Operation *Component::createOperation(const QString &operationName, const QStrin
if (operation->name() == QLatin1String("Delete"))
operation->setValue(QLatin1String("performUndo"), false);
- operation->setValue(QLatin1String("installer"), qVariantFromValue(d->m_core));
operation->setArguments(d->m_core->replaceVariables(parameters));
operation->setValue(QLatin1String("component"), name());
diff --git a/src/libs/installer/component.h b/src/libs/installer/component.h
index a075a0145..395bf90dd 100644
--- a/src/libs/installer/component.h
+++ b/src/libs/installer/component.h
@@ -46,11 +46,6 @@
QT_FORWARD_DECLARE_CLASS(QDebug)
QT_FORWARD_DECLARE_CLASS(QQmlV4Function)
-namespace KDUpdater {
- class Update;
- struct PackageInfo;
-}
-
namespace QInstaller {
class PackageManagerCore;
@@ -94,7 +89,7 @@ public:
};
void loadDataFromPackage(const Package &package);
- void loadDataFromPackage(const LocalPackage &package);
+ void loadDataFromPackage(const KDUpdater::LocalPackage &package);
QHash<QString, QString> variables() const;
Q_INVOKABLE void setValue(const QString &key, const QString &value);
diff --git a/src/libs/installer/componentchecker.cpp b/src/libs/installer/componentchecker.cpp
index 8dbcab42b..f95d856a8 100644
--- a/src/libs/installer/componentchecker.cpp
+++ b/src/libs/installer/componentchecker.cpp
@@ -50,6 +50,12 @@ QStringList ComponentChecker::checkComponent(Component *component)
if (!core)
return checkResult;
+ if (component->childCount() && !component->archives().isEmpty()) {
+ checkResult << QString::fromLatin1("Component %1 contains data to be installed "
+ "while having child components. This may not work properly.")
+ .arg(component->name());
+ }
+
const bool defaultPropertyScriptValue = component->variables().value(scDefault).compare(scScript, Qt::CaseInsensitive) == 0;
const bool defaultPropertyValue = component->variables().value(scDefault).compare(scTrue, Qt::CaseInsensitive) == 0;
const QStringList autoDependencies = component->autoDependencies();
@@ -127,13 +133,13 @@ QStringList ComponentChecker::checkComponent(Component *component)
Moreover, the "Next" button will be disabled.
*/
checkResult << QString::fromLatin1("Component %1 auto depends on other components "
- "while having children components. This will not work properly.")
+ "while having child components. This will not work properly.")
.arg(component->name());
}
if (!component->dependencies().isEmpty()) {
checkResult << QString::fromLatin1("Component %1 depends on other components "
- "while having children components. This will not work properly.")
+ "while having child components. This will not work properly.")
.arg(component->name());
}
@@ -153,7 +159,7 @@ QStringList ComponentChecker::checkComponent(Component *component)
Moreover, the "Next" button will be disabled.
*/
checkResult << QString::fromLatin1("Other components depend on component %1 "
- "which has children components. This will not work properly.")
+ "which has child components. This will not work properly.")
.arg(component->name());
}
}
diff --git a/src/libs/installer/componentmodel.cpp b/src/libs/installer/componentmodel.cpp
index 65d907d00..adcda4db5 100644
--- a/src/libs/installer/componentmodel.cpp
+++ b/src/libs/installer/componentmodel.cpp
@@ -82,6 +82,10 @@ class IconCache
{
public:
IconCache() {
+ m_icons.insert(ComponentModelHelper::Install, QIcon(QLatin1String(":/install.png")));
+ m_icons.insert(ComponentModelHelper::Uninstall, QIcon(QLatin1String(":/uninstall.png")));
+ m_icons.insert(ComponentModelHelper::KeepInstalled, QIcon(QLatin1String(":/keepinstalled.png")));
+ m_icons.insert(ComponentModelHelper::KeepUninstalled, QIcon(QLatin1String(":/keepuninstalled.png")));
}
QIcon icon(ComponentModelHelper::InstallAction action) const {
@@ -102,7 +106,7 @@ ComponentModel::ComponentModel(int columns, PackageManagerCore *core)
, m_modelState(DefaultChecked)
{
m_headerData.insert(0, columns, QVariant());
- connect(this, SIGNAL(modelReset()), this, SLOT(slotModelReset()));
+ connect(this, &QAbstractItemModel::modelReset, this, &ComponentModel::slotModelReset);
}
/*!
@@ -408,7 +412,7 @@ void ComponentModel::setRootComponents(QList<QInstaller::Component*> rootCompone
// show virtual components only in case we run as updater or if the core engine is set to show them
const bool showVirtuals = m_core->isUpdater() || m_core->virtualComponentsVisible();
foreach (Component *const component, rootComponents) {
- connect(component, SIGNAL(virtualStateChanged()), this, SLOT(onVirtualStateChanged()));
+ connect(component, &Component::virtualStateChanged, this, &ComponentModel::onVirtualStateChanged);
if ((!showVirtuals) && component->isVirtual())
continue;
m_rootComponentList.append(component);
@@ -468,7 +472,7 @@ void ComponentModel::slotModelReset()
foreach (Component *const component, components) {
if (component->checkState() == Qt::Checked)
checked.insert(component);
- connect(component, SIGNAL(virtualStateChanged()), this, SLOT(onVirtualStateChanged()));
+ connect(component, &Component::virtualStateChanged, this, &ComponentModel::onVirtualStateChanged);
}
updateCheckedState(checked, Qt::Checked);
diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h
index e48a22c02..1cba6d572 100644
--- a/src/libs/installer/constants.h
+++ b/src/libs/installer/constants.h
@@ -46,7 +46,6 @@ static const QLatin1String scScript("script");
static const QLatin1String scName("Name");
static const QLatin1String scVersion("Version");
static const QLatin1String scDefault("Default");
-static const QLatin1String scRemoteVersion("Version");
static const QLatin1String scDisplayVersion("DisplayVersion");
static const QLatin1String scRemoteDisplayVersion("RemoteDisplayVersion");
static const QLatin1String scInheritVersion("inheritVersionFrom");
@@ -58,6 +57,7 @@ static const QLatin1String scReleaseDate("ReleaseDate");
static const QLatin1String scDescription("Description");
static const QLatin1String scDisplayName("DisplayName");
static const QLatin1String scDependencies("Dependencies");
+static const QLatin1String scAutoDependOn("AutoDependOn");
static const QLatin1String scNewComponent("NewComponent");
static const QLatin1String scRepositories("Repositories");
static const QLatin1String scCompressedSize("CompressedSize");
@@ -69,6 +69,7 @@ static const QLatin1String scRequiresAdminRights("RequiresAdminRights");
// constants used throughout the components class
static const QLatin1String scVirtual("Virtual");
static const QLatin1String scSortingPriority("SortingPriority");
+static const QLatin1String scCheckable("Checkable");
// constants used throughout the settings and package manager core class
static const QLatin1String scTitle("Title");
@@ -83,10 +84,16 @@ static const QLatin1String scAllowNonAsciiCharacters("AllowNonAsciiCharacters");
static const QLatin1String scRepositorySettingsPageVisible("RepositorySettingsPageVisible");
static const QLatin1String scAllowSpaceInPath("AllowSpaceInPath");
static const QLatin1String scWizardStyle("WizardStyle");
+static const QLatin1String scStyleSheet("StyleSheet");
static const QLatin1String scTitleColor("TitleColor");
static const QLatin1String scWizardDefaultWidth("WizardDefaultWidth");
static const QLatin1String scWizardDefaultHeight("WizardDefaultHeight");
+static const QLatin1String scUrlQueryString("UrlQueryString");
static const QLatin1String scProductUUID("ProductUUID");
+static const QLatin1String scAllUsers("AllUsers");
+
+const char scRelocatable[] = "@RELOCATABLE_PATH@";
+
}
#endif // CONSTANTS_H
diff --git a/src/libs/installer/consumeoutputoperation.cpp b/src/libs/installer/consumeoutputoperation.cpp
index 497af969a..d7aa6b49f 100644
--- a/src/libs/installer/consumeoutputoperation.cpp
+++ b/src/libs/installer/consumeoutputoperation.cpp
@@ -42,7 +42,8 @@
using namespace QInstaller;
-ConsumeOutputOperation::ConsumeOutputOperation()
+ConsumeOutputOperation::ConsumeOutputOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("ConsumeOutput"));
}
@@ -58,15 +59,12 @@ bool ConsumeOutputOperation::performOperation()
// 2. executable path
// 3. argument for the executable
// 4. more arguments possible ...
- if (arguments().count() < 3) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.").arg(name()).arg(
- arguments().count()).arg(tr("at least 2"), QLatin1String("(<to be saved installer key name>, "
- "<executable>, [argument1], [argument2], ...)")));
+
+ if (!checkArgumentCount(2, INT_MAX, tr("<to be saved installer key name> "
+ "<executable> [argument1] [argument2] [...]")))
return false;
- }
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
if (!core) {
setError(UserDefinedError);
setErrorString(tr("Needed installer object in %1 operation is empty.").arg(name()));
@@ -76,8 +74,8 @@ bool ConsumeOutputOperation::performOperation()
const QString installerKeyName = arguments().at(0);
if (installerKeyName.isEmpty()) {
setError(UserDefinedError);
- setErrorString(tr("Can not save the output of %1 to an empty installer key value.").arg(
- arguments().at(1)));
+ setErrorString(tr("Cannot save the output of \"%1\" to an empty installer key value.").arg(
+ QDir::toNativeSeparators(arguments().at(1))));
return false;
}
@@ -90,7 +88,7 @@ bool ConsumeOutputOperation::performOperation()
if (!executable.exists() || !executable.isExecutable()) {
setError(UserDefinedError);
- setErrorString(tr("File '%1' does not exist or is not an executable binary.").arg(
+ setErrorString(tr("File \"%1\" does not exist or is not an executable binary.").arg(
QDir::toNativeSeparators(executable.absoluteFilePath())));
return false;
}
@@ -111,7 +109,7 @@ bool ConsumeOutputOperation::performOperation()
<< "standard output: " << process.readAllStandardOutput()
<< "error output: " << process.readAllStandardError();
setError(UserDefinedError);
- setErrorString(tr("Running '%1' resulted in a crash.").arg(
+ setErrorString(tr("Running \"%1\" resulted in a crash.").arg(
QDir::toNativeSeparators(executable.absoluteFilePath())));
return false;
}
@@ -129,8 +127,7 @@ bool ConsumeOutputOperation::performOperation()
}
if (executableOutput.isEmpty()) {
- qWarning() << QString::fromLatin1("Cannot get any query output from executable: '%1'").arg(
- executable.absoluteFilePath());
+ qWarning() << "Cannot get any query output from executable" << executable.absoluteFilePath();
}
core->setValue(installerKeyName, QString::fromLocal8Bit(executableOutput));
return true;
@@ -145,9 +142,3 @@ bool ConsumeOutputOperation::testOperation()
{
return true;
}
-
-Operation *ConsumeOutputOperation::clone() const
-{
- return new ConsumeOutputOperation();
-}
-
diff --git a/src/libs/installer/consumeoutputoperation.h b/src/libs/installer/consumeoutputoperation.h
index f9f59dd58..067d79d65 100644
--- a/src/libs/installer/consumeoutputoperation.h
+++ b/src/libs/installer/consumeoutputoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT ConsumeOutputOperation : public Operation
{
public:
- ConsumeOutputOperation();
+ explicit ConsumeOutputOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
private:
};
diff --git a/src/libs/installer/copydirectoryoperation.cpp b/src/libs/installer/copydirectoryoperation.cpp
index 0a1fe6dca..afe85ca28 100644
--- a/src/libs/installer/copydirectoryoperation.cpp
+++ b/src/libs/installer/copydirectoryoperation.cpp
@@ -51,7 +51,8 @@ public:
};
-CopyDirectoryOperation::CopyDirectoryOperation()
+CopyDirectoryOperation::CopyDirectoryOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CopyDirectory"));
}
@@ -62,13 +63,10 @@ void CopyDirectoryOperation::backup()
bool CopyDirectoryOperation::performOperation()
{
- const QStringList args = arguments();
- if (args.count() < 2 || args.count() > 3) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("2 or 3"), tr(" (<source> <target> [forceOverwrite])")));
+ if (!checkArgumentCount(2, 3, tr("<source> <target> [\"forceOverwrite\"]")))
return false;
- }
+
+ const QStringList args = arguments();
const QString sourcePath = args.at(0);
const QString targetPath = args.at(1);
bool overwrite = false;
@@ -79,19 +77,22 @@ bool CopyDirectoryOperation::performOperation()
overwrite = true;
} else {
setError(InvalidArguments);
- setErrorString(tr("Invalid argument in %0: Third argument needs to be forceOverwrite, "
- "if specified").arg(name()));
+ setErrorString(tr("Invalid argument in %1: Third argument needs to be forceOverwrite, "
+ "if specified.").arg(name()));
return false;
}
}
const QFileInfo sourceInfo(sourcePath);
const QFileInfo targetInfo(targetPath);
- if (!sourceInfo.exists() || !sourceInfo.isDir() || !targetInfo.exists() || !targetInfo.isDir()) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: Directories are invalid: %1 %2").arg(name())
- .arg(sourcePath).arg(targetPath));
- return false;
+
+ foreach (const QFileInfo &dir, QList<QFileInfo>() << sourceInfo << targetInfo) {
+ if (!dir.exists() || !dir.isDir()) {
+ setError(InvalidArguments);
+ setErrorString(tr("Invalid argument in %1: Directory \"%2\" is invalid.").arg(name())
+ .arg(QDir::toNativeSeparators(sourcePath)));
+ return false;
+ }
}
const QDir sourceDir = sourceInfo.absoluteDir();
@@ -122,22 +123,24 @@ bool CopyDirectoryOperation::performOperation()
} else if (itemInfo.isDir()) {
if (!targetDir.mkpath(targetDir.absoluteFilePath(relativePath))) {
setError(InvalidArguments);
- setErrorString(tr("Could not create %0").arg(targetDir.absoluteFilePath(relativePath)));
+ setErrorString(tr("Cannot create directory \"%1\".").arg(
+ QDir::toNativeSeparators(targetDir.absoluteFilePath(relativePath))));
return false;
}
} else {
const QString absolutePath = targetDir.absoluteFilePath(relativePath);
if (overwrite && QFile::exists(absolutePath) && !deleteFileNowOrLater(absolutePath)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to overwrite %1").arg(absolutePath));
+ setErrorString(tr("Failed to overwrite \"%1\".").arg(QDir::toNativeSeparators(absolutePath)));
return false;
}
QFile file(sourceDir.absoluteFilePath(itemName));
if (!file.copy(absolutePath)) {
setError(UserDefinedError);
- setErrorString(tr("Could not copy %0 to %1, error was: %3").arg(sourceDir.absoluteFilePath(itemName),
- targetDir.absoluteFilePath(relativePath),
- file.errorString()));
+ setErrorString(tr("Cannot copy file \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(sourceDir.absoluteFilePath(itemName)),
+ QDir::toNativeSeparators(targetDir.absoluteFilePath(relativePath)),
+ file.errorString()));
return false;
}
autoPush.m_files.prepend(targetDir.absoluteFilePath(relativePath));
@@ -156,7 +159,7 @@ bool CopyDirectoryOperation::undoOperation()
foreach (const QString &file, files) {
if (!QFile::remove(file)) {
setError(InvalidArguments);
- setErrorString(tr("Could not remove %0").arg(file));
+ setErrorString(tr("Cannot remove file \"%1\".").arg(QDir::toNativeSeparators(file)));
return false;
}
dir.rmpath(QFileInfo(file).absolutePath());
@@ -171,8 +174,3 @@ bool CopyDirectoryOperation::testOperation()
{
return true;
}
-
-Operation *CopyDirectoryOperation::clone() const
-{
- return new CopyDirectoryOperation();
-}
diff --git a/src/libs/installer/copydirectoryoperation.h b/src/libs/installer/copydirectoryoperation.h
index 18467b21a..7df3a4b60 100644
--- a/src/libs/installer/copydirectoryoperation.h
+++ b/src/libs/installer/copydirectoryoperation.h
@@ -45,13 +45,12 @@ class INSTALLER_EXPORT CopyDirectoryOperation : public QObject, public Operation
Q_OBJECT
public:
- CopyDirectoryOperation();
+ explicit CopyDirectoryOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
Q_SIGNALS:
void outputTextChanged(const QString &progress);
diff --git a/src/libs/installer/copyfiletask.cpp b/src/libs/installer/copyfiletask.cpp
index 327162637..a189a77bb 100644
--- a/src/libs/installer/copyfiletask.cpp
+++ b/src/libs/installer/copyfiletask.cpp
@@ -33,6 +33,7 @@
#include "copyfiletask.h"
#include "observer.h"
+#include <QDir>
#include <QFileInfo>
#include <QTemporaryFile>
@@ -68,8 +69,8 @@ void CopyFileTask::doTask(QFutureInterface<FileTaskResult> &fi)
QFile source(item.source());
if (!source.open(QIODevice::ReadOnly)) {
- fi.reportException(TaskException(tr("Could not open source '%1' for read. Error: %2.")
- .arg(source.fileName(), source.errorString())));
+ fi.reportException(TaskException(tr("Cannot open file \"%1\" for reading: %2")
+ .arg(QDir::toNativeSeparators(source.fileName()), source.errorString())));
fi.reportFinished(); return; // error
}
observer.setBytesToTransfer(source.size());
@@ -84,8 +85,8 @@ void CopyFileTask::doTask(QFutureInterface<FileTaskResult> &fi)
file.reset(new QFile(target));
}
if (!file->open(QIODevice::WriteOnly | QIODevice::Truncate)) {
- fi.reportException(TaskException(tr("Could not open target '%1' for write. Error: %2.")
- .arg(file->fileName(), file->errorString())));
+ fi.reportException(TaskException(tr("Cannot open file \"%1\" for writing: %2")
+ .arg(QDir::toNativeSeparators(file->fileName()), file->errorString())));
fi.reportFinished(); return; // error
}
@@ -101,8 +102,8 @@ void CopyFileTask::doTask(QFutureInterface<FileTaskResult> &fi)
while (written < read) {
const qint64 toWrite = file->write(buffer.constData() + written, read - written);
if (toWrite < 0) {
- fi.reportException(TaskException(tr("Writing to target '%1' failed. Error: %2.")
- .arg(file->fileName(), file->errorString())));
+ fi.reportException(TaskException(tr("Writing to file \"%1\" failed: %2")
+ .arg(QDir::toNativeSeparators(file->fileName()), file->errorString())));
}
written += toWrite;
}
diff --git a/src/libs/installer/createdesktopentryoperation.cpp b/src/libs/installer/createdesktopentryoperation.cpp
index 956060e61..ebe7f7ab3 100644
--- a/src/libs/installer/createdesktopentryoperation.cpp
+++ b/src/libs/installer/createdesktopentryoperation.cpp
@@ -96,7 +96,8 @@ QString CreateDesktopEntryOperation::absoluteFileName()
return QDir(directory).absoluteFilePath(filename);
}
-CreateDesktopEntryOperation::CreateDesktopEntryOperation()
+CreateDesktopEntryOperation::CreateDesktopEntryOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CreateDesktopEntry"));
}
@@ -121,32 +122,27 @@ void CreateDesktopEntryOperation::backup()
}
if (!file.copy(value(QLatin1String("backupOfExistingDesktopEntry")).toString()))
- setErrorString(tr("Could not backup file %1: %2").arg(filename, file.errorString()));
+ setErrorString(tr("Cannot backup file \"%1\": %2").arg(QDir::toNativeSeparators(filename), file.errorString()));
}
bool CreateDesktopEntryOperation::performOperation()
{
- const QStringList args = arguments();
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String("")));
+ if (!checkArgumentCount(2))
return false;
- }
const QString filename = absoluteFileName();
- const QString &values = args[1];
+ const QString &values = arguments().at(1);
QFile file(filename);
if (file.exists() && !file.remove()) {
setError(UserDefinedError);
- setErrorString(tr("Failed to overwrite %1").arg(filename));
+ setErrorString(tr("Failed to overwrite file \"%1\".").arg(QDir::toNativeSeparators(filename)));
return false;
}
if(!file.open(QIODevice::WriteOnly)) {
setError(UserDefinedError);
- setErrorString(tr("Could not write Desktop Entry at %1").arg(filename));
+ setErrorString(tr("Cannot write desktop entry to \"%1\".").arg(QDir::toNativeSeparators(filename)));
return false;
}
@@ -172,7 +168,7 @@ bool CreateDesktopEntryOperation::undoOperation()
// first remove the link
QFile file(filename);
if (file.exists() && !file.remove()) {
- qWarning() << "Could not delete file" << filename << file.errorString();
+ qWarning() << "Cannot delete file" << filename << ":" << file.errorString();
return true;
}
@@ -182,13 +178,13 @@ bool CreateDesktopEntryOperation::undoOperation()
QFile backupFile(value(QLatin1String("backupOfExistingDesktopEntry")).toString());
if (!backupFile.exists()) {
// do not treat this as a real error: The backup file might have been just nuked by the user.
- qWarning() << "Could not restore original desktop entry at" << filename
+ qWarning() << "Cannot restore original desktop entry at" << filename
<< ": Backup file" << backupFile.fileName() << "does not exist anymore.";
return true;
}
if (!backupFile.rename(filename))
- qWarning() << "Could not restore the file" << filename << ":" << backupFile.errorString();
+ qWarning() << "Cannot restore the file" << filename << ":" << backupFile.errorString();
return true;
}
@@ -197,8 +193,3 @@ bool CreateDesktopEntryOperation::testOperation()
{
return true;
}
-
-Operation *CreateDesktopEntryOperation::clone() const
-{
- return new CreateDesktopEntryOperation();
-}
diff --git a/src/libs/installer/createdesktopentryoperation.h b/src/libs/installer/createdesktopentryoperation.h
index 74f942739..c70fe0968 100644
--- a/src/libs/installer/createdesktopentryoperation.h
+++ b/src/libs/installer/createdesktopentryoperation.h
@@ -41,14 +41,13 @@ namespace QInstaller {
class INSTALLER_EXPORT CreateDesktopEntryOperation : public Operation
{
public:
- CreateDesktopEntryOperation();
+ explicit CreateDesktopEntryOperation(PackageManagerCore *core);
~CreateDesktopEntryOperation();
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation* clone() const;
QString absoluteFileName();
};
diff --git a/src/libs/installer/createlinkoperation.cpp b/src/libs/installer/createlinkoperation.cpp
index dac579a1b..0f329693d 100644
--- a/src/libs/installer/createlinkoperation.cpp
+++ b/src/libs/installer/createlinkoperation.cpp
@@ -34,11 +34,13 @@
#include "link.h"
+#include <QDir>
#include <QFileInfo>
using namespace QInstaller;
-CreateLinkOperation::CreateLinkOperation()
+CreateLinkOperation::CreateLinkOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CreateLink"));
}
@@ -49,22 +51,18 @@ void CreateLinkOperation::backup()
bool CreateLinkOperation::performOperation()
{
- QStringList args = arguments();
-
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String("")));
+ if (!checkArgumentCount(2))
return false;
- }
+ const QStringList args = arguments();
const QString& linkPath = args.at(0);
const QString& targetPath = args.at(1);
Link link = Link::create(linkPath, targetPath);
if (!link.exists()) {
setError(UserDefinedError);
- setErrorString(tr("Could not create link from %1 to %2.").arg(linkPath, targetPath));
+ setErrorString(tr("Cannot create link from \"%1\" to \"%2\".").arg(
+ QDir::toNativeSeparators(linkPath), QDir::toNativeSeparators(targetPath)));
return false;
}
@@ -84,7 +82,8 @@ bool CreateLinkOperation::undoOperation()
}
if (!link.remove()) {
setError(UserDefinedError);
- setErrorString(tr("Could not remove link from %1 to %2.").arg(linkPath, targetPath));
+ setErrorString(tr("Cannot remove link from \"%1\" to \"%2\".").arg(
+ QDir::toNativeSeparators(linkPath), QDir::toNativeSeparators(targetPath)));
return false;
}
@@ -95,8 +94,3 @@ bool CreateLinkOperation::testOperation()
{
return true;
}
-
-Operation *CreateLinkOperation::clone() const
-{
- return new CreateLinkOperation();
-}
diff --git a/src/libs/installer/createlinkoperation.h b/src/libs/installer/createlinkoperation.h
index 2095638ca..15787c5ab 100644
--- a/src/libs/installer/createlinkoperation.h
+++ b/src/libs/installer/createlinkoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT CreateLinkOperation : public Operation
{
public:
- CreateLinkOperation();
+ explicit CreateLinkOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
}
diff --git a/src/libs/installer/createlocalrepositoryoperation.cpp b/src/libs/installer/createlocalrepositoryoperation.cpp
index 5068e26dd..6bcac3cb6 100644
--- a/src/libs/installer/createlocalrepositoryoperation.cpp
+++ b/src/libs/installer/createlocalrepositoryoperation.cpp
@@ -39,11 +39,12 @@
#include "fileio.h"
#include "fileutils.h"
#include "copydirectoryoperation.h"
+#include "lib7z_create.h"
#include "lib7z_facade.h"
#include "packagemanagercore.h"
#include "productkeycheck.h"
-#include "kdupdaterupdateoperations.h"
+#include "updateoperations.h"
#include <QtCore/QDir>
#include <QtCore/QDirIterator>
@@ -87,8 +88,8 @@ static void fixPermissions(const QString &repoPath)
if (!QFile::setPermissions(it.filePath(), QFile::ReadOwner | QFile::WriteOwner
| QFile::ReadUser | QFile::WriteUser | QFile::ReadGroup | QFile::ReadOther)) {
- throw Error(CreateLocalRepositoryOperation::tr("Could not set file permissions %1!")
- .arg(it.filePath()));
+ throw Error(CreateLocalRepositoryOperation::tr("Cannot set permissions for file \"%1\".")
+ .arg(QDir::toNativeSeparators(it.filePath())));
}
}
}
@@ -108,8 +109,8 @@ static void removeFiles(const QString &path, AutoHelper *const helper)
if (fi.isSymLink() || fi.isFile()) {
QFile f(fi.filePath());
if (!f.remove()) {
- throw Error(CreateLocalRepositoryOperation::tr("Could not remove file %1: %2")
- .arg(f.fileName(), f.errorString()));
+ throw Error(CreateLocalRepositoryOperation::tr("Cannot remove file \"%1\": %2")
+ .arg(QDir::toNativeSeparators(f.fileName()), f.errorString()));
}
helper->m_files.removeAll(f.fileName());
}
@@ -126,8 +127,9 @@ static QString createArchive(const QString repoPath, const QString &sourceDir, c
Lib7z::createArchive(&archive, QStringList() << sourceDir);
removeFiles(sourceDir, helper); // cleanup the files we compressed
if (!archive.rename(sourceDir + fileName)) {
- throw Error(CreateLocalRepositoryOperation::tr("Could not move file %1 to %2. Error: %3")
- .arg(archive.fileName(), sourceDir + fileName, archive.errorString()));
+ throw Error(CreateLocalRepositoryOperation::tr("Cannot move file \"%1\" to \"%2\": %3")
+ .arg(QDir::toNativeSeparators(archive.fileName()),
+ QDir::toNativeSeparators(sourceDir + fileName), archive.errorString()));
}
return archive.fileName();
}
@@ -137,7 +139,8 @@ static QString createArchive(const QString repoPath, const QString &sourceDir, c
// -- CreateLocalRepositoryOperation
-CreateLocalRepositoryOperation::CreateLocalRepositoryOperation()
+CreateLocalRepositoryOperation::CreateLocalRepositoryOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CreateLocalRepository"));
}
@@ -151,24 +154,20 @@ bool CreateLocalRepositoryOperation::performOperation()
AutoHelper helper(this);
emit progressChanged(0.0);
- const QStringList args = arguments();
-
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String("")));
+ if (!checkArgumentCount(2))
return false;
- }
try {
+ const QStringList args = arguments();
+
const QString binaryPath = QFileInfo(args.at(0)).absoluteFilePath();
// Note the "/" at the end, important to make copy directory operation behave well
const QString repoPath = QFileInfo(args.at(1)).absoluteFilePath() + QLatin1Char('/');
// check if this is an offline version, otherwise there will be no binary data
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
if (core && !core->isOfflineOnly()) {
- throw QInstaller::Error(tr("Installer needs to be an offline version: %1.")
+ throw QInstaller::Error(tr("Installer at \"%1\" needs to be an offline one.")
.arg(QDir::toNativeSeparators(binaryPath)));
}
@@ -190,9 +189,10 @@ bool CreateLocalRepositoryOperation::performOperation()
setValue(QLatin1String("createddir"), mkDirOp.value(QLatin1String("createddir")));
// copy the whole meta data into local repository
- CopyDirectoryOperation copyDirOp;
+ CopyDirectoryOperation copyDirOp(core);
copyDirOp.setArguments(QStringList() << QLatin1String(":/metadata/") << repoPath);
- connect(&copyDirOp, SIGNAL(outputTextChanged(QString)), this, SIGNAL(outputTextChanged(QString)));
+ connect(&copyDirOp, &CopyDirectoryOperation::outputTextChanged,
+ this, &CreateLocalRepositoryOperation::outputTextChanged);
const bool success = copyDirOp.performOperation();
helper.m_files = copyDirOp.value(QLatin1String("files")).toStringList();
@@ -211,13 +211,15 @@ bool CreateLocalRepositoryOperation::performOperation()
// open the updates xml file we previously copied
QFile updatesXml(repoPath + QLatin1String("Updates.xml"));
if (!updatesXml.exists() || !updatesXml.open(QIODevice::ReadOnly))
- throw QInstaller::Error(tr("Could not open file: %1").arg(updatesXml.fileName()));
+ throw QInstaller::Error(tr("Cannot open file \"%1\" for reading.").arg(
+ QDir::toNativeSeparators(updatesXml.fileName())));
// read the content of the updates xml
QString error;
QDomDocument doc;
if (!doc.setContent(&updatesXml, &error))
- throw QInstaller::Error(tr("Could not read: %1. Error: %2").arg(updatesXml.fileName(), error));
+ throw QInstaller::Error(tr("Cannot read file \"%1\": %2").arg(
+ QDir::toNativeSeparators(updatesXml.fileName()), error));
// build for each available package a name - version mapping
QHash<QString, QString> nameVersionHash;
@@ -247,8 +249,9 @@ bool CreateLocalRepositoryOperation::performOperation()
QFile file(binaryPath);
if (!file.open(QIODevice::ReadOnly)) {
- throw QInstaller::Error(tr("Could not open file: %1. Error: %2").arg(file.fileName(),
- file.errorString()));
+ throw QInstaller::Error(tr("Cannot open file \"%1\" for reading: %2").arg(
+ QDir::toNativeSeparators(file.fileName()),
+ file.errorString()));
}
// start to read the binary layout
@@ -265,8 +268,8 @@ bool CreateLocalRepositoryOperation::performOperation()
for (int i = 0; i < names.count(); ++i) {
const QString name = names.at(i);
if (!repo.mkpath(name)) {
- throw QInstaller::Error(tr("Could not create target dir: %1.")
- .arg(repo.filePath(name)));
+ throw QInstaller::Error(tr("Cannot create target directory: \"%1\".")
+ .arg(QDir::toNativeSeparators(repo.filePath(name))));
}
// zip the meta files that come with the offline installer
helper.m_files.prepend(Static::createArchive(repoPath,
@@ -334,10 +337,10 @@ bool CreateLocalRepositoryOperation::undoOperation()
QDir dir;
const QStringList files = value(QLatin1String("files")).toStringList();
foreach (const QString &file, files) {
- emit outputTextChanged(tr("Removing file: %0").arg(file));
+ emit outputTextChanged(tr("Removing file \"%1\".").arg(QDir::toNativeSeparators(file)));
if (!QFile::remove(file)) {
setError(InvalidArguments);
- setErrorString(tr("Could not remove %0.").arg(file));
+ setErrorString(tr("Cannot remove file \"%1\".").arg(QDir::toNativeSeparators(file)));
return false;
}
dir.rmpath(QFileInfo(file).absolutePath());
@@ -356,12 +359,12 @@ bool CreateLocalRepositoryOperation::undoOperation()
#if defined(Q_OS_WIN) && !defined(Q_CC_MINGW)
char msg[128];
if (strerror_s(msg, sizeof msg, errno) != 0) {
- setError(UserDefinedError, tr("Cannot remove directory %1: %2").arg(createdDir.path(),
- QString::fromLocal8Bit(msg)));
+ setError(UserDefinedError, tr("Cannot remove directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(createdDir.path()), QString::fromLocal8Bit(msg)));
}
#else
- setError(UserDefinedError, tr("Cannot remove directory %1: %2").arg(createdDir.path(),
- QString::fromLocal8Bit(strerror(errno))));
+ setError(UserDefinedError, tr("Cannot remove directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(createdDir.path()), QString::fromLocal8Bit(strerror(errno))));
#endif
}
setValue(QLatin1String("files"), QStringList());
@@ -374,11 +377,6 @@ bool CreateLocalRepositoryOperation::testOperation()
return true;
}
-Operation *CreateLocalRepositoryOperation::clone() const
-{
- return new CreateLocalRepositoryOperation();
-}
-
void CreateLocalRepositoryOperation::emitFullProgress()
{
emit progressChanged(1.0);
diff --git a/src/libs/installer/createlocalrepositoryoperation.h b/src/libs/installer/createlocalrepositoryoperation.h
index 5216077ed..a982930a9 100644
--- a/src/libs/installer/createlocalrepositoryoperation.h
+++ b/src/libs/installer/createlocalrepositoryoperation.h
@@ -46,13 +46,12 @@ class INSTALLER_EXPORT CreateLocalRepositoryOperation : public QObject, public O
friend struct AutoHelper;
public:
- CreateLocalRepositoryOperation();
+ explicit CreateLocalRepositoryOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
signals:
void progressChanged(double progress);
diff --git a/src/libs/installer/createshortcutoperation.cpp b/src/libs/installer/createshortcutoperation.cpp
index 89838ddcb..99da0f531 100644
--- a/src/libs/installer/createshortcutoperation.cpp
+++ b/src/libs/installer/createshortcutoperation.cpp
@@ -46,6 +46,7 @@ using namespace QInstaller;
#ifdef Q_OS_WIN
#include <qt_windows.h>
#include <shlobj.h>
+#include <Intshcut.h>
#ifndef PIDLIST_ABSOLUTE
typedef ITEMIDLIST *PIDLIST_ABSOLUTE;
@@ -98,39 +99,62 @@ static QString takeArgument(const QString argument, QStringList *arguments)
static bool createLink(const QString &fileName, const QString &linkName, QString workingDir,
const QString &arguments = QString(), const QString &iconPath = QString(),
- const QString &iconId = QString())
+ const QString &iconId = QString(), const QString &description = QString())
{
#ifdef Q_OS_WIN
- bool success = QFile::link(fileName, linkName);
+ // CoInitialize cleanup object
+ DeCoInitializer _;
- if (!success)
- return success;
+ IUnknown *iunkn = NULL;
- if (workingDir.isEmpty())
- workingDir = QFileInfo(fileName).absolutePath();
- workingDir = QDir::toNativeSeparators(workingDir);
+ if (fileName.toLower().startsWith(QLatin1String("http:"))
+ || fileName.toLower().startsWith(QLatin1String("ftp:"))) {
+ IUniformResourceLocator *iurl = NULL;
+ if (FAILED(CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
+ IID_IUniformResourceLocator, (LPVOID*)&iurl))) {
+ return false;
+ }
- // CoInitialize cleanup object
- DeCoInitializer _;
+ if (FAILED(iurl->SetURL((wchar_t *)fileName.utf16(), IURL_SETURL_FL_GUESS_PROTOCOL))) {
+ iurl->Release();
+ return false;
+ }
+ iunkn = iurl;
+ } else {
+ bool success = QFile::link(fileName, linkName);
+
+ if (!success) {
+ return success;
+ }
+
+ if (workingDir.isEmpty())
+ workingDir = QFileInfo(fileName).absolutePath();
+ workingDir = QDir::toNativeSeparators(workingDir);
- IShellLink *psl = NULL;
- if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl)))
- return success;
+ IShellLink *psl = NULL;
+ if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ IID_IShellLink, (LPVOID*)&psl))) {
+ return success;
+ }
- // TODO: implement this server side, since there's not Qt equivalent to set working dir and arguments
- psl->SetPath((wchar_t *)QDir::toNativeSeparators(fileName).utf16());
- psl->SetWorkingDirectory((wchar_t *)workingDir.utf16());
- if (!arguments.isNull())
- psl->SetArguments((wchar_t*)arguments.utf16());
- if (!iconPath.isNull())
- psl->SetIconLocation((wchar_t*)(iconPath.utf16()), iconId.toInt());
+ // TODO: implement this server side, since there's not Qt equivalent to set working dir and arguments
+ psl->SetPath((wchar_t *)QDir::toNativeSeparators(fileName).utf16());
+ psl->SetWorkingDirectory((wchar_t *)workingDir.utf16());
+ if (!arguments.isNull())
+ psl->SetArguments((wchar_t*)arguments.utf16());
+ if (!iconPath.isNull())
+ psl->SetIconLocation((wchar_t*)(iconPath.utf16()), iconId.toInt());
+ if (!description.isNull())
+ psl->SetDescription((wchar_t*)(description.utf16()));
+ iunkn = psl;
+ }
IPersistFile *ppf = NULL;
- if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (void **)&ppf))) {
+ if (SUCCEEDED(iunkn->QueryInterface(IID_IPersistFile, (void **)&ppf))) {
ppf->Save((wchar_t*)QDir::toNativeSeparators(linkName).utf16(), true);
ppf->Release();
}
- psl->Release();
+ iunkn->Release();
PIDLIST_ABSOLUTE pidl; // Force start menu cache update
if (SUCCEEDED(SHGetFolderLocation(0, CSIDL_STARTMENU, 0, 0, &pidl))) {
@@ -142,7 +166,7 @@ static bool createLink(const QString &fileName, const QString &linkName, QString
CoTaskMemFree(pidl);
}
- return success;
+ return true;
#else
Q_UNUSED(arguments)
Q_UNUSED(workingDir)
@@ -157,13 +181,17 @@ static bool createLink(const QString &fileName, const QString &linkName, QString
// -- CreateShortcutOperation
-CreateShortcutOperation::CreateShortcutOperation()
+CreateShortcutOperation::CreateShortcutOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
+ , m_optionalArgumentsRead(false)
{
setName(QLatin1String("CreateShortcut"));
}
void CreateShortcutOperation::backup()
{
+ ensureOptionalArgumentsRead();
+
QDir linkPath(QFileInfo(arguments().at(1)).absolutePath());
QStringList directoriesToCreate;
@@ -176,25 +204,38 @@ void CreateShortcutOperation::backup()
setValue(QLatin1String("createddirs"), directoriesToCreate);
}
-bool CreateShortcutOperation::performOperation()
+void CreateShortcutOperation::ensureOptionalArgumentsRead()
{
+ if (m_optionalArgumentsRead)
+ return;
+
+ m_optionalArgumentsRead = true;
+
QStringList args = arguments();
- const QString iconId = takeArgument(QString::fromLatin1("iconId="), &args);
- const QString iconPath = takeArgument(QString::fromLatin1("iconPath="), &args);
- const QString workingDir = takeArgument(QString::fromLatin1("workingDirectory="), &args);
+ m_iconId = takeArgument(QString::fromLatin1("iconId="), &args);
+ m_iconPath = takeArgument(QString::fromLatin1("iconPath="), &args);
+ m_workingDir = takeArgument(QString::fromLatin1("workingDirectory="), &args);
+ m_description = takeArgument(QString::fromLatin1("description="), &args);
+
+ setArguments(args);
+}
+
+bool CreateShortcutOperation::performOperation()
+{
+ ensureOptionalArgumentsRead();
- if (args.count() != 2 && args.count() != 3) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("2 or 3"),
- tr(" (optional: 'workingDirectory=...', 'iconPath=...', 'iconId=...')")));
+ if (!checkArgumentCount(2, 3, tr("<target> <link location> [target arguments] "
+ "[\"workingDirectory=...\"] [\"iconPath=...\"] [\"iconId=...\"] "
+ "[\"description=...\"]"))) {
return false;
}
+ QStringList args = arguments();
+
const QString linkTarget = args.at(0);
const QString linkLocation = args.at(1);
- const QString targetArguments = args.value(2); //used value because it could be not existing
+ const QString targetArguments = args.value(2); // value() used since it's optional
const QString linkPath = QFileInfo(linkLocation).absolutePath().trimmed();
const bool created = QDir(linkPath).exists() || QDir::root().mkpath(linkPath);
@@ -204,11 +245,11 @@ bool CreateShortcutOperation::performOperation()
#if defined(Q_OS_WIN) && !defined(Q_CC_MINGW)
char msg[128];
if (strerror_s(msg, sizeof msg, errno) != 0) {
- setErrorString(tr("Could not create folder %1: %2.").arg(QDir::toNativeSeparators(linkPath),
+ setErrorString(tr("Cannot create directory \"%1\": %2").arg(QDir::toNativeSeparators(linkPath),
QString::fromLocal8Bit(msg)));
}
#else
- setErrorString(tr("Could not create folder %1: %2.").arg(QDir::toNativeSeparators(linkPath),
+ setErrorString(tr("Cannot create directory \"%1\": %2").arg(QDir::toNativeSeparators(linkPath),
QString::fromLocal8Bit(strerror(errno))));
#endif
return false;
@@ -218,15 +259,16 @@ bool CreateShortcutOperation::performOperation()
QString errorString;
if (QFile::exists(linkLocation) && !deleteFileNowOrLater(linkLocation, &errorString)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to overwrite %1: %2").arg(QDir::toNativeSeparators(linkLocation),
+ setErrorString(tr("Failed to overwrite \"%1\": %2").arg(QDir::toNativeSeparators(linkLocation),
errorString));
return false;
}
- const bool linked = createLink(linkTarget, linkLocation, workingDir, targetArguments, iconPath, iconId);
+ const bool linked = createLink(linkTarget, linkLocation, m_workingDir, targetArguments, m_iconPath, m_iconId,
+ m_description);
if (!linked) {
setError(UserDefinedError);
- setErrorString(tr("Could not create link %1: %2").arg(QDir::toNativeSeparators(linkLocation),
+ setErrorString(tr("Cannot create link \"%1\": %2").arg(QDir::toNativeSeparators(linkLocation),
qt_error_string()));
return false;
}
@@ -235,6 +277,8 @@ bool CreateShortcutOperation::performOperation()
bool CreateShortcutOperation::undoOperation()
{
+ ensureOptionalArgumentsRead();
+
const QString &linkLocation = arguments().at(1);
if (!deleteFileNowOrLater(linkLocation) )
qDebug() << "Cannot delete:" << linkLocation;
@@ -276,8 +320,3 @@ bool CreateShortcutOperation::testOperation()
{
return true;
}
-
-Operation *CreateShortcutOperation::clone() const
-{
- return new CreateShortcutOperation();
-}
diff --git a/src/libs/installer/createshortcutoperation.h b/src/libs/installer/createshortcutoperation.h
index 832ecbc7e..b39c0a340 100644
--- a/src/libs/installer/createshortcutoperation.h
+++ b/src/libs/installer/createshortcutoperation.h
@@ -41,13 +41,21 @@ namespace QInstaller {
class INSTALLER_EXPORT CreateShortcutOperation : public Operation
{
public:
- CreateShortcutOperation();
+ explicit CreateShortcutOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
+
+private:
+ void ensureOptionalArgumentsRead();
+
+ bool m_optionalArgumentsRead;
+ QString m_iconId;
+ QString m_iconPath;
+ QString m_workingDir;
+ QString m_description;
};
}
diff --git a/src/libs/installer/downloadarchivesjob.cpp b/src/libs/installer/downloadarchivesjob.cpp
index e7f60f9cf..52031121d 100644
--- a/src/libs/installer/downloadarchivesjob.cpp
+++ b/src/libs/installer/downloadarchivesjob.cpp
@@ -38,8 +38,8 @@
#include "packagemanagercore.h"
#include "utils.h"
-#include "kdupdaterfiledownloader.h"
-#include "kdupdaterfiledownloaderfactory.h"
+#include "filedownloader.h"
+#include "filedownloaderfactory.h"
#include <QtCore/QFile>
#include <QtCore/QTimerEvent>
@@ -52,7 +52,7 @@ using namespace KDUpdater;
Creates a new DownloadArchivesJob with \a parent.
*/
DownloadArchivesJob::DownloadArchivesJob(PackageManagerCore *core)
- : KDJob(core)
+ : Job(core)
, m_core(core)
, m_downloader(0)
, m_archivesDownloaded(0)
@@ -125,8 +125,8 @@ void DownloadArchivesJob::fetchNextArchiveHash()
return;
}
- connect(m_downloader, SIGNAL(downloadCompleted()), this, SLOT(finishedHashDownload()),
- Qt::QueuedConnection);
+ connect(m_downloader, &FileDownloader::downloadCompleted,
+ this, &DownloadArchivesJob::finishedHashDownload, Qt::QueuedConnection);
m_downloader->download();
} else {
QMetaObject::invokeMethod(this, "fetchNextArchive", Qt::QueuedConnection);
@@ -164,7 +164,7 @@ void DownloadArchivesJob::fetchNextArchive()
if (m_downloader != 0)
m_downloader->deleteLater();
- m_downloader = setupDownloader(QString(), m_core->value(QLatin1String("UrlQueryString")));
+ m_downloader = setupDownloader(QString(), m_core->value(scUrlQueryString));
if (!m_downloader) {
m_archivesToDownload.removeFirst();
QMetaObject::invokeMethod(this, "fetchNextArchiveHash", Qt::QueuedConnection);
@@ -173,7 +173,8 @@ void DownloadArchivesJob::fetchNextArchive()
emit progressChanged(double(m_archivesDownloaded) / m_archivesToDownloadCount);
connect(m_downloader, SIGNAL(downloadProgress(double)), this, SLOT(emitDownloadProgress(double)));
- connect(m_downloader, SIGNAL(downloadCompleted()), this, SLOT(registerFile()), Qt::QueuedConnection);
+ connect(m_downloader, &FileDownloader::downloadCompleted,
+ this, &DownloadArchivesJob::registerFile, Qt::QueuedConnection);
m_downloader->download();
}
@@ -220,7 +221,7 @@ void DownloadArchivesJob::registerFile()
QMessageBox::Retry | QMessageBox::Cancel, QMessageBox::Cancel);
if (res == QMessageBox::Cancel) {
- finishWithError(tr("Could not verify Hash"));
+ finishWithError(tr("Cannot verify Hash"));
return;
}
} else {
@@ -240,7 +241,7 @@ void DownloadArchivesJob::registerFile()
void DownloadArchivesJob::downloadCanceled()
{
- emitFinishedWithError(KDJob::Canceled, m_downloader->errorString());
+ emitFinishedWithError(Job::Canceled, m_downloader->errorString());
}
void DownloadArchivesJob::downloadFailed(const QString &error)
@@ -250,7 +251,7 @@ void DownloadArchivesJob::downloadFailed(const QString &error)
const QMessageBox::StandardButton b =
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
- QLatin1String("archiveDownloadError"), tr("Download Error"), tr("Could not download archive: %1 : %2")
+ QLatin1String("archiveDownloadError"), tr("Download Error"), tr("Cannot download archive %1: %2")
.arg(m_archivesToDownload.first().second, error), QMessageBox::Retry | QMessageBox::Cancel);
if (b == QMessageBox::Retry)
@@ -262,7 +263,7 @@ void DownloadArchivesJob::downloadFailed(const QString &error)
void DownloadArchivesJob::finishWithError(const QString &error)
{
const FileDownloader *const dl = qobject_cast<const FileDownloader*> (sender());
- const QString msg = tr("Could not fetch archives: %1\nError while loading %2");
+ const QString msg = tr("Cannot fetch archives: %1\nError while loading %2");
if (dl != 0)
emitFinishedWithError(QInstaller::DownloadError, msg.arg(error, dl->url().toString()));
else
@@ -291,24 +292,23 @@ KDUpdater::FileDownloader *DownloadArchivesJob::setupDownloader(const QString &s
auth.setPassword(component->value(QLatin1String("password")));
downloader->setAuthenticator(auth);
- connect(downloader, SIGNAL(downloadCanceled()), this, SLOT(downloadCanceled()));
- connect(downloader, SIGNAL(downloadAborted(QString)), this, SLOT(downloadFailed(QString)),
+ connect(downloader, &FileDownloader::downloadCanceled, this, &DownloadArchivesJob::downloadCanceled);
+ connect(downloader, &FileDownloader::downloadAborted, this, &DownloadArchivesJob::downloadFailed,
Qt::QueuedConnection);
- connect(downloader, SIGNAL(downloadStatus(QString)), this, SIGNAL(downloadStatusChanged(QString)));
+ connect(downloader, &FileDownloader::downloadStatus, this, &DownloadArchivesJob::downloadStatusChanged);
if (FileDownloaderFactory::isSupportedScheme(scheme)) {
downloader->setDownloadedFileName(component->localTempPath() + QLatin1Char('/')
+ component->name() + QLatin1Char('/') + fi.fileName() + suffix);
}
- emit outputTextChanged(tr("Downloading archive '%1' for component: %2")
+ emit outputTextChanged(tr("Downloading archive \"%1\" for component %2.")
.arg(fi.fileName() + suffix, component->displayName()));
} else {
- emit outputTextChanged(tr("Scheme not supported: %1 (%2)").arg(scheme, url.toString()));
+ emit outputTextChanged(tr("Scheme %1 not supported (URL: %2).").arg(scheme, url.toString()));
}
} else {
- emit outputTextChanged(tr("Could not find component for: %1.").arg(QFileInfo(fi.path())
- .fileName()));
+ emit outputTextChanged(tr("Cannot find component for %1.").arg(QFileInfo(fi.path()).fileName()));
}
return downloader;
}
diff --git a/src/libs/installer/downloadarchivesjob.h b/src/libs/installer/downloadarchivesjob.h
index ddc1cc7d0..2fcc01131 100644
--- a/src/libs/installer/downloadarchivesjob.h
+++ b/src/libs/installer/downloadarchivesjob.h
@@ -34,7 +34,7 @@
#ifndef DOWNLOADARCHIVESJOB_H
#define DOWNLOADARCHIVESJOB_H
-#include <kdjob.h>
+#include "job.h"
#include <QtCore/QPair>
@@ -51,7 +51,7 @@ namespace QInstaller {
class MessageBoxHandler;
class PackageManagerCore;
-class DownloadArchivesJob : public KDJob
+class DownloadArchivesJob : public Job
{
Q_OBJECT
diff --git a/src/libs/installer/downloadfiletask.cpp b/src/libs/installer/downloadfiletask.cpp
index e1e4d9ffb..19cb217d6 100644
--- a/src/libs/installer/downloadfiletask.cpp
+++ b/src/libs/installer/downloadfiletask.cpp
@@ -36,12 +36,12 @@
#include "downloadfiletask_p.h"
#include <QCoreApplication>
+#include <QDir>
#include <QEventLoop>
#include <QFileInfo>
#include <QNetworkProxyFactory>
#include <QSslError>
#include <QTemporaryFile>
-#include <QTimer>
namespace QInstaller {
@@ -54,7 +54,8 @@ AuthenticationRequiredException::AuthenticationRequiredException(Type type, cons
Downloader::Downloader()
: m_finished(0)
{
- connect(&m_nam, SIGNAL(finished(QNetworkReply*)), SLOT(onFinished(QNetworkReply*)));
+ connect(&m_timer, &QTimer::timeout, this, &Downloader::onTimeout);
+ connect(&m_nam, &QNetworkAccessManager::finished, this, &Downloader::onFinished);
}
Downloader::~Downloader()
@@ -77,15 +78,17 @@ void Downloader::download(QFutureInterface<FileTaskResult> &fi, const QList<File
fi.setExpectedResultCount(items.count());
m_nam.setProxyFactory(networkProxyFactory);
- connect(&m_nam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this,
- SLOT(onAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
- connect(&m_nam, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this,
- SLOT(onProxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
- QTimer::singleShot(0, this, SLOT(doDownload()));
+ connect(&m_nam, &QNetworkAccessManager::authenticationRequired, this,
+ &Downloader::onAuthenticationRequired);
+ connect(&m_nam, &QNetworkAccessManager::proxyAuthenticationRequired, this,
+ &Downloader::onProxyAuthenticationRequired);
+ QTimer::singleShot(0, this, &Downloader::doDownload);
}
void Downloader::doDownload()
{
+ m_timer.start(1000); // Use a timer to check for canceled downloads.
+
foreach (const FileTaskItem &item, m_items) {
if (!startDownload(item))
break;
@@ -125,15 +128,17 @@ void Downloader::onReadyRead()
}
if (file->exists() && (!QFileInfo(file->fileName()).isFile())) {
- m_futureInterface->reportException(TaskException(tr("Target file '%1' already exists "
+ m_futureInterface->reportException(TaskException(tr("Target file \"%1\" already exists "
"but is not a file.").arg(file->fileName())));
return;
}
if (!file->open(QIODevice::WriteOnly | QIODevice::Truncate)) {
//: %2 is a sentence describing the error
- m_futureInterface->reportException(TaskException(tr("Could not open target '%1' for "
- "write. Error: %2.").arg(file->fileName(), file->errorString())));
+ m_futureInterface->reportException(
+ TaskException(tr("Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(file->fileName()),
+ file->errorString())));
return;
}
data.file = std::move(file);
@@ -142,8 +147,9 @@ void Downloader::onReadyRead()
if (!data.file->isOpen()) {
//: %2 is a sentence describing the error.
m_futureInterface->reportException(
- TaskException(tr("Target '%1' not open for write. Error: %2.").arg(
- data.file->fileName(), data.file->errorString())));
+ TaskException(tr("File \"%1\" not open for writing: %2").arg(
+ QDir::toNativeSeparators(data.file->fileName()),
+ data.file->errorString())));
return;
}
@@ -161,8 +167,9 @@ void Downloader::onReadyRead()
if (toWrite < 0) {
//: %2 is a sentence describing the error.
m_futureInterface->reportException(
- TaskException(tr("Writing to target '%1' failed. Error: %2.").arg(
- data.file->fileName(), data.file->errorString())));
+ TaskException(tr("Writing to file \"%1\" failed: %2").arg(
+ QDir::toNativeSeparators(data.file->fileName()),
+ data.file->errorString())));
return;
}
written += toWrite;
@@ -208,7 +215,7 @@ void Downloader::onFinished(QNetworkReply *reply)
reply->deleteLater();
return;
} else {
- m_futureInterface->reportException(TaskException(tr("Redirect loop detected '%1'.")
+ m_futureInterface->reportException(TaskException(tr("Redirect loop detected for \"%1\".")
.arg(url.toString())));
return;
}
@@ -225,7 +232,7 @@ void Downloader::onFinished(QNetworkReply *reply)
const QByteArray expectedCheckSum = data.taskItem.value(TaskRole::Checksum).toByteArray();
if (!expectedCheckSum.isEmpty()) {
if (expectedCheckSum != data.observer->checkSum().toHex()) {
- m_futureInterface->reportException(TaskException(tr("Checksum mismatch detected '%1'.")
+ m_futureInterface->reportException(TaskException(tr("Checksum mismatch detected for \"%1\".")
.arg(reply->url().toString())));
}
}
@@ -255,12 +262,12 @@ void Downloader::onError(QNetworkReply::NetworkError error)
const Data &data = *m_downloads[reply];
//: %2 is a sentence describing the error
m_futureInterface->reportException(
- TaskException(tr("Network error while downloading '%1': %2.").arg(
+ TaskException(tr("Network error while downloading \"%1\": %2").arg(
data.taskItem.source(), reply->errorString())));
} else {
//: %1 is a sentence describing the error
m_futureInterface->reportException(
- TaskException(tr("Unknown network error while downloading: %1.").arg(error)));
+ TaskException(tr("Unknown network error while downloading \"%1\".").arg(error)));
}
}
@@ -270,7 +277,7 @@ void Downloader::onSslErrors(const QList<QSslError> &sslErrors)
Q_UNUSED(sslErrors);
#else
foreach (const QSslError &error, sslErrors)
- qDebug() << QString::fromLatin1("SSL error: %s").arg(error.errorString());
+ qDebug() << "SSL error:" << error.errorString();
#endif
}
@@ -317,6 +324,28 @@ void Downloader::onProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuth
}
+/*!
+ \internal
+
+ Canceling from the outside will not get noticed if we are waiting on a connection that
+ does not create any events. QNam will drop after 45 seconds, though the user might have
+ canceled the download before. In that case we block until the QNam timeout is reached,
+ worst case resulting in deadlock while the application is shutting down at the same time.
+*/
+void Downloader::onTimeout()
+{
+ if (testCanceled()) {
+ // Inject exception, we can't use QFuturInterface::reportException() as the exception
+ // store is "frozen" once cancel was called. On the other hand, client code could use
+ // QFutureWatcherBase::isCanceled() or QFuture::isCanceled() to check for canceled futures.
+ m_futureInterface->exceptionStore()
+ .setException(TaskException(tr("Network transfers canceled.")));
+ m_futureInterface->reportFinished();
+ emit finished();
+ }
+}
+
+
// -- private
bool Downloader::testCanceled()
@@ -335,7 +364,7 @@ QNetworkReply *Downloader::startDownload(const FileTaskItem &item)
QUrl const source = item.source();
if (!source.isValid()) {
//: %2 is a sentence describing the error
- m_futureInterface->reportException(TaskException(tr("Invalid source '%1'. Error: %2.")
+ m_futureInterface->reportException(TaskException(tr("Invalid source URL \"%1\": %2")
.arg(source.toString(), source.errorString())));
return 0;
}
@@ -344,14 +373,13 @@ QNetworkReply *Downloader::startDownload(const FileTaskItem &item)
std::unique_ptr<Data> data(new Data(item));
m_downloads[reply] = std::move(data);
- connect(reply, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
+ connect(reply, &QIODevice::readyRead, this, &Downloader::onReadyRead);
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this,
SLOT(onError(QNetworkReply::NetworkError)));
#ifndef QT_NO_SSL
- connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(onSslErrors(QList<QSslError>)));
+ connect(reply, &QNetworkReply::sslErrors, this, &Downloader::onSslErrors);
#endif
- connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onDownloadProgress(qint64,
- qint64)));
+ connect(reply, &QNetworkReply::downloadProgress, this, &Downloader::onDownloadProgress);
return reply;
}
@@ -398,7 +426,7 @@ void DownloadFileTask::doTask(QFutureInterface<FileTaskResult> &fi)
{
QEventLoop el;
Downloader downloader;
- connect(&downloader, SIGNAL(finished()), &el, SLOT(quit()));
+ connect(&downloader, &Downloader::finished, &el, &QEventLoop::quit);
QList<FileTaskItem> items = taskItems();
if (!m_authenticator.isNull()) {
diff --git a/src/libs/installer/downloadfiletask.h b/src/libs/installer/downloadfiletask.h
index a61527135..425b2d021 100644
--- a/src/libs/installer/downloadfiletask.h
+++ b/src/libs/installer/downloadfiletask.h
@@ -35,7 +35,7 @@
#define DOWNLOADFILETASK_H
#include "abstractfiletask.h"
-#include "kdupdaterfiledownloaderfactory.h"
+#include "filedownloaderfactory.h"
#include <QAuthenticator>
Q_DECLARE_METATYPE(QAuthenticator)
diff --git a/src/libs/installer/downloadfiletask_p.h b/src/libs/installer/downloadfiletask_p.h
index f71ba06fd..5583779b4 100644
--- a/src/libs/installer/downloadfiletask_p.h
+++ b/src/libs/installer/downloadfiletask_p.h
@@ -41,6 +41,7 @@
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
+#include <QTimer>
#include <memory>
#include <unordered_map>
@@ -95,7 +96,7 @@ private slots:
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator);
void onProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
-
+ void onTimeout();
private:
bool testCanceled();
@@ -104,6 +105,7 @@ private:
private:
QFutureInterface<FileTaskResult> *m_futureInterface;
+ QTimer m_timer;
int m_finished;
QNetworkAccessManager m_nam;
QList<FileTaskItem> m_items;
diff --git a/src/libs/installer/elevatedexecuteoperation.cpp b/src/libs/installer/elevatedexecuteoperation.cpp
index 5de3c0203..3f3cdbb2a 100644
--- a/src/libs/installer/elevatedexecuteoperation.cpp
+++ b/src/libs/installer/elevatedexecuteoperation.cpp
@@ -63,8 +63,9 @@ public:
bool showStandardError;
};
-ElevatedExecuteOperation::ElevatedExecuteOperation()
- : d(new Private(this))
+ElevatedExecuteOperation::ElevatedExecuteOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
+ , d(new Private(this))
{
// this operation has to "overwrite" the Execute operation from KDUpdater
setName(QLatin1String("Execute"));
@@ -79,12 +80,9 @@ bool ElevatedExecuteOperation::performOperation()
{
// This operation receives only one argument. It is the complete
// command line of the external program to execute.
- if (arguments().isEmpty()) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("at least 1"), QLatin1String("")));
+ if (!checkArgumentCount(1, INT_MAX))
return false;
- }
+
QStringList args;
foreach (const QString &argument, arguments()) {
if (argument!=QLatin1String("UNDOEXECUTE"))
@@ -144,7 +142,7 @@ bool ElevatedExecuteOperation::Private::run(const QStringList &arguments)
const bool success = QProcessWrapper::startDetached(args.front(), args.mid(1));
if (!success) {
q->setError(UserDefinedError);
- q->setErrorString(tr("Execution failed: Could not start detached: \"%1\"").arg(callstr));
+ q->setErrorString(tr("Cannot start detached: \"%1\"").arg(callstr));
}
return success;
}
@@ -163,12 +161,12 @@ bool ElevatedExecuteOperation::Private::run(const QStringList &arguments)
if (showStandardError)
process->setProcessChannelMode(QProcessWrapper::MergedChannels);
- connect(q, SIGNAL(cancelProcess()), process, SLOT(cancel()));
+ connect(q, &ElevatedExecuteOperation::cancelProcess, process, &QProcessWrapper::cancel);
//we still like the none blocking possibility to perform this operation without threads
QEventLoop loop;
if (QThread::currentThread() == qApp->thread()) {
- QObject::connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit()));
+ QObject::connect(process, &QProcessWrapper::finished, &loop, &QEventLoop::quit);
}
//readProcessOutput should only called from this current Thread -> Qt::DirectConnection
QObject::connect(process, SIGNAL(readyRead()), q, SLOT(readProcessOutput()), Qt::DirectConnection);
@@ -196,7 +194,7 @@ bool ElevatedExecuteOperation::Private::run(const QStringList &arguments)
if (!success) {
q->setError(UserDefinedError);
//TODO: pass errorString() through the wrapper */
- q->setErrorString(tr("Execution failed: Could not start: \"%1\"(%2)").arg(callstr,
+ q->setErrorString(tr("Cannot start: \"%1\": %2").arg(callstr,
process->errorString()));
returnValue = false;
}
@@ -212,14 +210,14 @@ bool ElevatedExecuteOperation::Private::run(const QStringList &arguments)
if (process->exitStatus() == QProcessWrapper::CrashExit) {
q->setError(UserDefinedError);
- q->setErrorString(tr("Execution failed(Crash): \"%1\"").arg(callstr));
+ q->setErrorString(tr("Program crashed: \"%1\"").arg(callstr));
returnValue = false;
}
if (!allowedExitCodes.contains(process->exitCode())) {
q->setError(UserDefinedError);
if (customErrorMessage.isEmpty()) {
- q->setErrorString(tr("Execution failed(Unexpected exit code: %1): \"%2\"")
+ q->setErrorString(tr("Execution failed (Unexpected exit code: %1): \"%2\"")
.arg(QString::number(process->exitCode()), callstr));
} else {
q->setErrorString(customErrorMessage);
@@ -228,13 +226,14 @@ bool ElevatedExecuteOperation::Private::run(const QStringList &arguments)
QByteArray standardErrorOutput = process->readAllStandardError();
// in error case it would be useful to see something in verbose output
if (!standardErrorOutput.isEmpty())
- qWarning() << standardErrorOutput;
+ qWarning().noquote() << standardErrorOutput;
returnValue = false;
}
Q_ASSERT(process);
- process->deleteLater();
+ Q_ASSERT(process->state() == QProcessWrapper::NotRunning);
+ delete process;
process = 0;
return returnValue;
@@ -289,11 +288,6 @@ bool ElevatedExecuteOperation::testOperation()
return true;
}
-Operation *ElevatedExecuteOperation::clone() const
-{
- return new ElevatedExecuteOperation;
-}
-
void ElevatedExecuteOperation::backup()
{
}
diff --git a/src/libs/installer/elevatedexecuteoperation.h b/src/libs/installer/elevatedexecuteoperation.h
index c218e6aaa..88c3f22d2 100644
--- a/src/libs/installer/elevatedexecuteoperation.h
+++ b/src/libs/installer/elevatedexecuteoperation.h
@@ -43,14 +43,13 @@ class INSTALLER_EXPORT ElevatedExecuteOperation : public QObject, public Operati
Q_OBJECT
public:
- ElevatedExecuteOperation();
+ explicit ElevatedExecuteOperation(PackageManagerCore *core);
~ElevatedExecuteOperation();
-
- virtual void backup();
- virtual bool performOperation();
- virtual bool undoOperation();
- virtual bool testOperation();
- virtual Operation *clone() const;
+
+ void backup() Q_DECL_OVERRIDE;
+ bool performOperation() Q_DECL_OVERRIDE;
+ bool undoOperation() Q_DECL_OVERRIDE;
+ bool testOperation() Q_DECL_OVERRIDE;
Q_SIGNALS:
void cancelProcess();
diff --git a/src/libs/installer/environmentvariablesoperation.cpp b/src/libs/installer/environmentvariablesoperation.cpp
index 24016569b..1b869fb11 100644
--- a/src/libs/installer/environmentvariablesoperation.cpp
+++ b/src/libs/installer/environmentvariablesoperation.cpp
@@ -45,7 +45,8 @@
using namespace QInstaller;
using namespace KDUpdater;
-EnvironmentVariableOperation::EnvironmentVariableOperation()
+EnvironmentVariableOperation::EnvironmentVariableOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("EnvironmentVariable"));
}
@@ -79,7 +80,7 @@ UpdateOperation::Error writeSetting(const QString &regPath,
oldValue->clear();
SettingsType registry(regPath, QSettingsWrapper::NativeFormat);
if (!registry.isWritable()) {
- *errorString = UpdateOperation::tr("Registry path %1 is not writable").arg(regPath);
+ *errorString = UpdateOperation::tr("Registry path %1 is not writable.").arg(regPath);
return UpdateOperation::UserDefinedError;
}
@@ -91,7 +92,7 @@ UpdateOperation::Error writeSetting(const QString &regPath,
registry.sync();
if (registry.status() != QSettingsWrapper::NoError) {
- *errorString = UpdateOperation::tr("Could not write to registry path %1").arg(regPath);
+ *errorString = UpdateOperation::tr("Cannot write to registry path %1.").arg(regPath);
return UpdateOperation::UserDefinedError;
}
@@ -120,21 +121,16 @@ UpdateOperation::Error undoSetting(const QString &regPath,
bool EnvironmentVariableOperation::performOperation()
{
- QStringList args = arguments();
- if (args.count() < 2 || args.count() > 4) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("2 to 4"), QLatin1String("")));
+ if (!checkArgumentCount(2, 4))
return false;
- }
- const QString name = arguments().at(0);
- const QString value = arguments().at(1);
- bool isPersistent = false;
+ const QStringList args = arguments();
+ const QString name = args.at(0);
+ const QString value = args.at(1);
#ifdef Q_OS_WIN
- isPersistent = arguments().count() >= 3 ? arguments().at(2) == QLatin1String("true") : true;
- const bool isSystemWide = arguments().count() >= 4 ? arguments().at(3) == QLatin1String("true") : false;
+ const bool isPersistent = arguments().count() > 2 ? arguments().at(2) == QLatin1String("true") : true;
+ const bool isSystemWide = arguments().count() > 3 ? arguments().at(3) == QLatin1String("true") : false;
QString oldvalue;
if (isPersistent) {
const QString regPath = isSystemWide ? QLatin1String("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet"
@@ -157,9 +153,8 @@ bool EnvironmentVariableOperation::performOperation()
setValue(QLatin1String("oldvalue"), oldvalue);
return true;
}
-#endif
Q_ASSERT(!isPersistent);
- Q_UNUSED(isPersistent)
+#endif
setValue(QLatin1String("oldvalue"), Environment::instance().value(name));
Environment::instance().setTemporaryValue(name, value);
@@ -214,8 +209,3 @@ bool EnvironmentVariableOperation::testOperation()
{
return true;
}
-
-Operation *EnvironmentVariableOperation::clone() const
-{
- return new EnvironmentVariableOperation();
-}
diff --git a/src/libs/installer/environmentvariablesoperation.h b/src/libs/installer/environmentvariablesoperation.h
index 2fa3bc289..507b4aff6 100644
--- a/src/libs/installer/environmentvariablesoperation.h
+++ b/src/libs/installer/environmentvariablesoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT EnvironmentVariableOperation : public Operation
{
public:
- EnvironmentVariableOperation();
+ explicit EnvironmentVariableOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
}
diff --git a/src/libs/installer/errors.h b/src/libs/installer/errors.h
index 0c9502cbb..40bdefcf4 100644
--- a/src/libs/installer/errors.h
+++ b/src/libs/installer/errors.h
@@ -44,13 +44,15 @@ namespace QInstaller {
class Error : public std::exception
{
public:
- Error() {}
+ Error()
+ {}
+
explicit Error(const QString &message)
: m_message(message)
- {
- qDebug() << "create Error-Exception:" << message;
- }
- virtual ~Error() throw() {}
+ {}
+
+ virtual ~Error() throw()
+ {}
QString message() const { return m_message; }
diff --git a/src/libs/installer/extractarchiveoperation.cpp b/src/libs/installer/extractarchiveoperation.cpp
index dba9fd93d..f91068e40 100644
--- a/src/libs/installer/extractarchiveoperation.cpp
+++ b/src/libs/installer/extractarchiveoperation.cpp
@@ -31,17 +31,15 @@
**
**************************************************************************/
-#include "extractarchiveoperation.h"
#include "extractarchiveoperation_p.h"
-#include <QtCore/QEventLoop>
-#include <QtCore/QThread>
-#include <QtCore/QThreadPool>
+#include <QEventLoop>
+#include <QThreadPool>
-using namespace QInstaller;
+namespace QInstaller {
-
-ExtractArchiveOperation::ExtractArchiveOperation()
+ExtractArchiveOperation::ExtractArchiveOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Extract"));
}
@@ -53,55 +51,46 @@ void ExtractArchiveOperation::backup()
bool ExtractArchiveOperation::performOperation()
{
- const QStringList args = arguments();
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String("")));
+ if (!checkArgumentCount(2))
return false;
- }
- const QString archivePath = args.first();
+ const QStringList args = arguments();
+ const QString archivePath = args.at(0);
const QString targetDir = args.at(1);
Receiver receiver;
Callback callback;
- connect(&callback, SIGNAL(currentFileChanged(QString)), this, SLOT(fileFinished(QString)));
- connect(&callback, SIGNAL(progressChanged(double)), this, SIGNAL(progressChanged(double)));
+ connect(&callback, &Callback::currentFileChanged, this, &ExtractArchiveOperation::fileFinished);
+ connect(&callback, &Callback::progressChanged, this, &ExtractArchiveOperation::progressChanged);
- if (PackageManagerCore *core = this->value(QLatin1String("installer")).value<PackageManagerCore*>()) {
- connect(core, SIGNAL(statusChanged(QInstaller::PackageManagerCore::Status)), &callback,
- SLOT(statusChanged(QInstaller::PackageManagerCore::Status)));
+ if (PackageManagerCore *core = packageManager()) {
+ connect(core, &PackageManagerCore::statusChanged, &callback, &Callback::statusChanged);
}
- //Runnable is derived from QRunable which will be deleted by the ThreadPool -> no parent is needed
Runnable *runnable = new Runnable(archivePath, targetDir, &callback);
- connect(runnable, SIGNAL(finished(bool,QString)), &receiver, SLOT(runnableFinished(bool,QString)),
+ connect(runnable, &Runnable::finished, &receiver, &Receiver::runnableFinished,
Qt::QueuedConnection);
QEventLoop loop;
- connect(&receiver, SIGNAL(finished()), &loop, SLOT(quit()));
+ connect(&receiver, &Receiver::finished, &loop, &QEventLoop::quit);
if (QThreadPool::globalInstance()->tryStart(runnable)) {
loop.exec();
} else {
- // in case there is no availabe thread we should call it directly this is more a hack
+ // HACK: In case there is no availabe thread we should call it directly.
runnable->run();
receiver.runnableFinished(true, QString());
}
- typedef QPair<QString, QString> StringPair;
- QVector<StringPair> backupFiles = callback.backupFiles;
-
- //TODO use backups for rollback, too? doesn't work for uninstallation though
+ // TODO: Use backups for rollback, too? Doesn't work for uninstallation though.
- //delete all backups we can delete right now, remember the rest
- foreach (const StringPair &i, backupFiles)
+ // delete all backups we can delete right now, remember the rest
+ foreach (const Backup &i, callback.backupFiles())
deleteFileNowOrLater(i.second);
- if (!receiver.success) {
+ if (!receiver.success()) {
setError(UserDefinedError);
- setErrorString(receiver.errorString);
+ setErrorString(receiver.errorString());
return false;
}
return true;
@@ -110,17 +99,16 @@ bool ExtractArchiveOperation::performOperation()
bool ExtractArchiveOperation::undoOperation()
{
Q_ASSERT(arguments().count() == 2);
- //const QString archivePath = arguments().first();
- //const QString targetDir = arguments().last();
-
const QStringList files = value(QLatin1String("files")).toStringList();
WorkerThread *const thread = new WorkerThread(this, files);
- connect(thread, SIGNAL(currentFileChanged(QString)), this, SIGNAL(outputTextChanged(QString)));
- connect(thread, SIGNAL(progressChanged(double)), this, SIGNAL(progressChanged(double)));
+ connect(thread, &WorkerThread::currentFileChanged, this,
+ &ExtractArchiveOperation::outputTextChanged);
+ connect(thread, &WorkerThread::progressChanged, this,
+ &ExtractArchiveOperation::progressChanged);
QEventLoop loop;
- connect(thread, SIGNAL(finished()), &loop, SLOT(quit()), Qt::QueuedConnection);
+ connect(thread, &QThread::finished, &loop, &QEventLoop::quit, Qt::QueuedConnection);
thread->start();
loop.exec();
thread->deleteLater();
@@ -132,18 +120,16 @@ bool ExtractArchiveOperation::testOperation()
return true;
}
-Operation *ExtractArchiveOperation::clone() const
-{
- return new ExtractArchiveOperation();
-}
-
/*!
- 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::fileFinished(const QString &filename)
{
QStringList files = value(QLatin1String("files")).toStringList();
files.prepend(filename);
setValue(QLatin1String("files"), files);
- emit outputTextChanged(filename);
+ emit outputTextChanged(QDir::toNativeSeparators(filename));
}
+
+} // namespace QInstaller
diff --git a/src/libs/installer/extractarchiveoperation.h b/src/libs/installer/extractarchiveoperation.h
index 51ade8ca9..50a544c80 100644
--- a/src/libs/installer/extractarchiveoperation.h
+++ b/src/libs/installer/extractarchiveoperation.h
@@ -46,13 +46,12 @@ class INSTALLER_EXPORT ExtractArchiveOperation : public QObject, public Operatio
friend class WorkerThread;
public:
- ExtractArchiveOperation();
+ explicit ExtractArchiveOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
Q_SIGNALS:
void outputTextChanged(const QString &progress);
diff --git a/src/libs/installer/extractarchiveoperation_p.h b/src/libs/installer/extractarchiveoperation_p.h
index 66529d934..3e2b1ce74 100644
--- a/src/libs/installer/extractarchiveoperation_p.h
+++ b/src/libs/installer/extractarchiveoperation_p.h
@@ -36,24 +36,23 @@
#include "extractarchiveoperation.h"
#include "fileutils.h"
+#include "lib7z_extract.h"
#include "lib7z_facade.h"
#include "packagemanagercore.h"
-#include <QtCore/QDir>
-#include <QtCore/QFile>
-#include <QtCore/QPair>
-#include <QtCore/QThread>
-#include <QtCore/QVector>
+#include <QRunnable>
+#include <QThread>
namespace QInstaller {
class WorkerThread : public QThread
{
Q_OBJECT
+ Q_DISABLE_COPY(WorkerThread)
+
public:
- WorkerThread(ExtractArchiveOperation *op, const QStringList &files, QObject *parent = 0)
- : QThread(parent)
- , m_files(files)
+ WorkerThread(ExtractArchiveOperation *op, const QStringList &files)
+ : m_files(files)
, m_op(op)
{
setObjectName(QLatin1String("ExtractArchive"));
@@ -61,26 +60,25 @@ public:
void run()
{
- ExtractArchiveOperation *const op = m_op;//dynamic_cast< ExtractArchiveOperation* >(parent());
- Q_ASSERT(op != 0);
+ Q_ASSERT(m_op != 0);
int removedCounter = 0;
foreach (const QString &file, m_files) {
removedCounter++;
+
const QFileInfo fi(file);
- emit currentFileChanged(file);
+ emit currentFileChanged(QDir::toNativeSeparators(file));
emit progressChanged(double(removedCounter) / m_files.count());
if (fi.isFile() || fi.isSymLink()) {
- op->deleteFileNowOrLater(fi.absoluteFilePath());
+ m_op->deleteFileNowOrLater(fi.absoluteFilePath());
} else if (fi.isDir()) {
- const QDir d = fi.dir();
removeSystemGeneratedFiles(file);
- d.rmdir(file); // directory may not exist
+ fi.dir().rmdir(file); // directory may not exist
}
}
}
-Q_SIGNALS:
+signals:
void currentFileChanged(const QString &filename);
void progressChanged(double);
@@ -89,44 +87,42 @@ private:
ExtractArchiveOperation *m_op;
};
+typedef QPair<QString, QString> Backup;
+typedef QVector<Backup> BackupFiles;
class ExtractArchiveOperation::Callback : public QObject, public Lib7z::ExtractCallback
{
Q_OBJECT
+ Q_DISABLE_COPY(Callback)
public:
- HRESULT state;
- bool createBackups;
- QVector<QPair<QString, QString> > backupFiles;
-
- Callback() : state(S_OK), createBackups(true) {}
+ Callback() = default;
-Q_SIGNALS:
- void currentFileChanged(const QString &filename);
- void progressChanged(double progress);
+ BackupFiles backupFiles() const {
+ return m_backupFiles;
+ }
-public Q_SLOTS:
+public slots:
void statusChanged(QInstaller::PackageManagerCore::Status status)
{
switch(status) {
case PackageManagerCore::Canceled:
- state = E_ABORT;
+ m_state = E_ABORT;
break;
case PackageManagerCore::Failure:
- state = E_FAIL;
+ m_state = E_FAIL;
break;
- default: // fall through
- // PackageManagerCore::Unfinished, PackageManagerCore::Success, PackageManagerCore::Running
- // PackageManagerCore::ForceUpdate
-
- // already set
- //state = S_OK;
+ default: // ignore all other status values
break;
}
}
-protected:
- void setCurrentFile(const QString &filename)
+signals:
+ void currentFileChanged(const QString &filename);
+ void progressChanged(double progress);
+
+private:
+ void setCurrentFile(const QString &filename) Q_DECL_OVERRIDE
{
emit currentFileChanged(QDir::toNativeSeparators(filename));
}
@@ -141,94 +137,106 @@ protected:
return res;
}
- bool prepareForFile(const QString &filename)
+ bool prepareForFile(const QString &filename) Q_DECL_OVERRIDE
{
- if (!createBackups)
- return true;
if (!QFile::exists(filename))
return true;
const QString backup = generateBackupName(filename);
QFile f(filename);
const bool renamed = f.rename(backup);
if (f.exists() && !renamed) {
- qCritical("Could not rename %s to %s: %s", qPrintable(filename), qPrintable(backup),
+ qCritical("Cannot rename %s to %s: %s", qPrintable(filename), qPrintable(backup),
qPrintable(f.errorString()));
return false;
}
- backupFiles.push_back(qMakePair(filename, backup));
+ m_backupFiles.append(qMakePair(filename, backup));
return true;
}
- HRESULT setCompleted(quint64 completed, quint64 total)
+ HRESULT setCompleted(quint64 completed, quint64 total) Q_DECL_OVERRIDE
{
emit progressChanged(double(completed) / total);
- return state;
+ return m_state;
}
+
+private:
+ HRESULT m_state = S_OK;
+ BackupFiles m_backupFiles;
};
class ExtractArchiveOperation::Runnable : public QObject, public QRunnable
{
Q_OBJECT
+ Q_DISABLE_COPY(Runnable)
public:
- Runnable(const QString &archivePath_, const QString &targetDir_, ExtractArchiveOperation::Callback *callback_)
- : QObject()
- , QRunnable()
- , archivePath(archivePath_)
- , targetDir(targetDir_)
- , callback(callback_) {}
+ Runnable(const QString &archivePath, const QString &targetDir,
+ ExtractArchiveOperation::Callback *callback)
+ : m_archivePath(archivePath)
+ , m_targetDir(targetDir)
+ , m_callback(callback)
+ {}
void run()
{
- QFile archive(archivePath);
+ QFile archive(m_archivePath);
if (!archive.open(QIODevice::ReadOnly)) {
-
- emit finished(false, tr("Could not open %1 for reading: %2.").arg(archivePath, archive.errorString()));
+ emit finished(false, tr("Cannot open archive \"%1\" for reading: %2").arg(m_archivePath,
+ archive.errorString()));
return;
}
try {
- Lib7z::extractArchive(&archive, targetDir, callback);
+ Lib7z::extractArchive(&archive, m_targetDir, m_callback);
emit finished(true, QString());
} catch (const Lib7z::SevenZipException& e) {
- emit finished(false, tr("Error while extracting '%1': %2").arg(archivePath, e.message()));
+ emit finished(false, tr("Error while extracting archive \"%1\": %2").arg(m_archivePath,
+ e.message()));
} catch (...) {
- emit finished(false, tr("Unknown exception caught while extracting %1.").arg(archivePath));
+ emit finished(false, tr("Unknown exception caught while extracting \"%1\".")
+ .arg(m_archivePath));
}
}
-Q_SIGNALS:
+signals:
void finished(bool success, const QString &errorString);
private:
- const QString archivePath;
- const QString targetDir;
- ExtractArchiveOperation::Callback *const callback;
+ QString m_archivePath;
+ QString m_targetDir;
+ ExtractArchiveOperation::Callback *m_callback;
};
-
class ExtractArchiveOperation::Receiver : public QObject
{
Q_OBJECT
+ Q_DISABLE_COPY(Receiver)
+
public:
- explicit Receiver(QObject *parent = 0)
- : QObject(parent)
- , success(false) {}
+ Receiver() = default;
-public Q_SLOTS:
+ bool success() const {
+ return m_success;
+ }
+
+ QString errorString() const {
+ return m_errorString;
+ }
+
+public slots:
void runnableFinished(bool ok, const QString &msg)
{
- success = ok;
- errorString = msg;
+ m_success = ok;
+ m_errorString = msg;
emit finished();
}
-Q_SIGNALS:
+signals:
void finished();
-public:
- bool success;
- QString errorString;
+private:
+ bool m_success = false;
+ QString m_errorString;
};
}
diff --git a/src/libs/installer/fakestopprocessforupdateoperation.cpp b/src/libs/installer/fakestopprocessforupdateoperation.cpp
index 2d49d0f46..d03319491 100644
--- a/src/libs/installer/fakestopprocessforupdateoperation.cpp
+++ b/src/libs/installer/fakestopprocessforupdateoperation.cpp
@@ -39,7 +39,8 @@
using namespace KDUpdater;
using namespace QInstaller;
-FakeStopProcessForUpdateOperation::FakeStopProcessForUpdateOperation()
+FakeStopProcessForUpdateOperation::FakeStopProcessForUpdateOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("FakeStopProcessForUpdate"));
}
@@ -56,15 +57,12 @@ bool FakeStopProcessForUpdateOperation::performOperation()
bool FakeStopProcessForUpdateOperation::undoOperation()
{
setError(KDUpdater::UpdateOperation::NoError);
- if (arguments().size() != 1) {
- setError(KDUpdater::UpdateOperation::InvalidArguments, tr("Number of arguments does not "
- "match: one is required"));
+ if (!checkArgumentCount(1))
return false;
- }
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
if (!core) {
- setError(KDUpdater::UpdateOperation::UserDefinedError, tr("Could not get package manager "
+ setError(KDUpdater::UpdateOperation::UserDefinedError, tr("Cannot get package manager "
"core."));
return false;
}
@@ -93,8 +91,3 @@ bool FakeStopProcessForUpdateOperation::testOperation()
{
return true;
}
-
-Operation *FakeStopProcessForUpdateOperation::clone() const
-{
- return new FakeStopProcessForUpdateOperation();
-}
diff --git a/src/libs/installer/fakestopprocessforupdateoperation.h b/src/libs/installer/fakestopprocessforupdateoperation.h
index 702a81b5e..8eb0ed38a 100644
--- a/src/libs/installer/fakestopprocessforupdateoperation.h
+++ b/src/libs/installer/fakestopprocessforupdateoperation.h
@@ -43,13 +43,12 @@ class INSTALLER_EXPORT FakeStopProcessForUpdateOperation : public QObject, publi
Q_OBJECT
public:
- FakeStopProcessForUpdateOperation();
+ explicit FakeStopProcessForUpdateOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
}
diff --git a/src/libs/installer/fileio.cpp b/src/libs/installer/fileio.cpp
index 5817d148c..8921f7257 100644
--- a/src/libs/installer/fileio.cpp
+++ b/src/libs/installer/fileio.cpp
@@ -38,6 +38,7 @@
#include <QCoreApplication>
#include <QByteArray>
+#include <QDir>
#include <QFileDevice>
#include <QString>
@@ -107,7 +108,8 @@ void QInstaller::openForRead(QFileDevice *dev)
Q_ASSERT(dev);
if (!dev->open(QIODevice::ReadOnly)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Cannot open file %1 for reading: %2").arg(dev->fileName(), dev->errorString()));
+ "Cannot open file \"%1\" for reading: %2").arg(
+ QDir::toNativeSeparators(dev->fileName()), dev->errorString()));
}
}
@@ -116,7 +118,8 @@ void QInstaller::openForWrite(QFileDevice *dev)
Q_ASSERT(dev);
if (!dev->open(QIODevice::WriteOnly)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Cannot open file %1 for writing: %2").arg(dev->fileName(), dev->errorString()));
+ "Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(dev->fileName()), dev->errorString()));
}
}
@@ -125,7 +128,8 @@ void QInstaller::openForAppend(QFileDevice *dev)
Q_ASSERT(dev);
if (!dev->open(QIODevice::WriteOnly | QIODevice::Append)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Cannot open file %1 for writing: %2").arg(dev->fileName(), dev->errorString()));
+ "Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(dev->fileName()), dev->errorString()));
}
}
@@ -159,7 +163,7 @@ qint64 QInstaller::blockingCopy(QFileDevice *in, QFileDevice *out, qint64 size)
size -= actual;
actual = qMin(blockSize, size);
} catch (const Error &error) {
- throw Error(QCoreApplication::translate("QInstaller", "Copy failed. Error: %1")
+ throw Error(QCoreApplication::translate("QInstaller", "Copy failed: %1")
.arg(error.message()));
}
}
diff --git a/src/libs/installer/fileutils.cpp b/src/libs/installer/fileutils.cpp
index 79dc4273e..04a24ad8e 100644
--- a/src/libs/installer/fileutils.cpp
+++ b/src/libs/installer/fileutils.cpp
@@ -181,10 +181,11 @@ void QInstaller::removeFiles(const QString &path, bool ignoreErrors)
QFile f(fi.filePath());
if (!f.remove()) {
const QString errorMessage = QCoreApplication::translate("QInstaller",
- "Could not remove file %1: %2").arg(f.fileName(), f.errorString());
+ "Cannot remove file \"%1\": %2").arg(
+ QDir::toNativeSeparators(f.fileName()), f.errorString());
if (!ignoreErrors)
throw Error(errorMessage);
- qWarning() << errorMessage;
+ qWarning().noquote() << errorMessage;
}
}
}
@@ -222,10 +223,11 @@ void QInstaller::removeDirectory(const QString &path, bool ignoreErrors)
errno = 0;
if (d.exists(path) && !d.rmdir(dir)) {
const QString errorMessage = QCoreApplication::translate("QInstaller",
- "Could not remove folder %1: %2").arg(dir, errnoToQString(errno));
+ "Cannot remove directory \"%1\": %2").arg(QDir::toNativeSeparators(dir),
+ errnoToQString(errno));
if (!ignoreErrors)
throw Error(errorMessage);
- qWarning() << errorMessage;
+ qWarning().noquote() << errorMessage;
}
}
}
@@ -269,7 +271,7 @@ void QInstaller::removeDirectoryThreaded(const QString &path, bool ignoreErrors)
{
RemoveDirectoryThread thread(path, ignoreErrors);
QEventLoop loop;
- QObject::connect(&thread, SIGNAL(finished()), &loop, SLOT(quit()));
+ QObject::connect(&thread, &RemoveDirectoryThread::finished, &loop, &QEventLoop::quit);
thread.start();
loop.exec();
if (!thread.error().isEmpty())
@@ -292,8 +294,8 @@ void QInstaller::copyDirectoryContents(const QString &sourceDir, const QString &
Q_ASSERT(QFileInfo(sourceDir).isDir());
Q_ASSERT(!QFileInfo(targetDir).exists() || QFileInfo(targetDir).isDir());
if (!QDir().mkpath(targetDir)) {
- throw Error(QCoreApplication::translate("QInstaller", "Could not create folder %1")
- .arg(targetDir));
+ throw Error(QCoreApplication::translate("QInstaller", "Cannot create directory \"%1\".")
+ .arg(QDir::toNativeSeparators(targetDir)));
}
QDirIterator it(sourceDir, QDir::NoDotAndDotDot | QDir::AllEntries);
while (it.hasNext()) {
@@ -306,8 +308,10 @@ void QInstaller::copyDirectoryContents(const QString &sourceDir, const QString &
const QString target = QDir(targetDir).absoluteFilePath(i.fileName());
if (!f.copy(target)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Could not copy file from %1 to %2: %3").arg(f.fileName(), target,
- f.errorString()));
+ "Cannot copy file from \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(f.fileName()),
+ QDir::toNativeSeparators(target),
+ f.errorString()));
}
}
}
@@ -318,8 +322,8 @@ void QInstaller::moveDirectoryContents(const QString &sourceDir, const QString &
Q_ASSERT(QFileInfo(sourceDir).isDir());
Q_ASSERT(!QFileInfo(targetDir).exists() || QFileInfo(targetDir).isDir());
if (!QDir().mkpath(targetDir)) {
- throw Error(QCoreApplication::translate("QInstaller", "Could not create folder %1")
- .arg(targetDir));
+ throw Error(QCoreApplication::translate("QInstaller", "Cannot create directory \"%1\".")
+ .arg(QDir::toNativeSeparators(targetDir)));
}
QDirIterator it(sourceDir, QDir::NoDotAndDotDot | QDir::AllEntries);
while (it.hasNext()) {
@@ -335,8 +339,10 @@ void QInstaller::moveDirectoryContents(const QString &sourceDir, const QString &
const QString target = QDir(targetDir).absoluteFilePath(i.fileName());
if (!f.rename(target)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Could not move file from %1 to %2: %3").arg(f.fileName(), target,
- f.errorString()));
+ "Cannot move file from \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(f.fileName()),
+ QDir::toNativeSeparators(target),
+ f.errorString()));
}
}
}
@@ -346,8 +352,8 @@ void QInstaller::mkdir(const QString &path)
{
errno = 0;
if (!QDir().mkdir(QFileInfo(path).absoluteFilePath())) {
- throw Error(QCoreApplication::translate("QInstaller", "Could not create folder %1: %2")
- .arg(path, errnoToQString(errno)));
+ throw Error(QCoreApplication::translate("QInstaller", "Cannot create directory \"%1\": %2")
+ .arg(QDir::toNativeSeparators(path), errnoToQString(errno)));
}
}
@@ -355,8 +361,8 @@ void QInstaller::mkpath(const QString &path)
{
errno = 0;
if (!QDir().mkpath(QFileInfo(path).absoluteFilePath())) {
- throw Error(QCoreApplication::translate("QInstaller", "Could not create folder %1: %2")
- .arg(path, errnoToQString(errno)));
+ throw Error(QCoreApplication::translate("QInstaller", "Cannot create directory \"%1\": %2")
+ .arg(QDir::toNativeSeparators(path), errnoToQString(errno)));
}
}
@@ -366,7 +372,7 @@ QString QInstaller::generateTemporaryFileName(const QString &templ)
QTemporaryFile f;
if (!f.open()) {
throw Error(QCoreApplication::translate("QInstaller",
- "Could not open temporary file: %1").arg(f.errorString()));
+ "Cannot open temporary file: %1").arg(f.errorString()));
}
return f.fileName();
}
@@ -385,7 +391,7 @@ QString QInstaller::generateTemporaryFileName(const QString &templ)
QFile f(tmp.arg(templ, suffix).arg(count));
if (!f.open(QIODevice::WriteOnly)) {
throw Error(QCoreApplication::translate("QInstaller",
- "Could not open temporary file for template %1: %2").arg(templ, f.errorString()));
+ "Cannot open temporary file for template %1: %2").arg(templ, f.errorString()));
}
f.remove();
return f.fileName();
@@ -486,14 +492,13 @@ void QInstaller::setApplicationIcon(const QString &application, const QString &i
{
QFile iconFile(icon);
if (!iconFile.open(QIODevice::ReadOnly)) {
- qWarning() << QString::fromLatin1("Could not use '%1' as application icon: %2.")
- .arg(icon, iconFile.errorString());
+ qWarning() << "Cannot use" << icon << "as an application icon:" << iconFile.errorString();
return;
}
if (QImageReader::imageFormat(icon) != "ico") {
- qWarning() << QString::fromLatin1("Could not use '%1' as application icon, unsupported format %2.")
- .arg(icon, QLatin1String(QImageReader::imageFormat(icon)));
+ qWarning() << "Cannot use" << icon << "as an application icon, unsupported format"
+ << QImageReader::imageFormat(icon).constData();
return;
}
@@ -579,3 +584,19 @@ bool QInstaller::isInBundle(const QString &path, QString *bundlePath)
#endif
return false;
}
+
+/*!
+ Replaces the path \a before with the path \a after at the beginning of \a path and returns
+ the replaced path. If \a before cannot be found in \a path, the original value is returned.
+*/
+QString QInstaller::replacePath(const QString &path, const QString &before, const QString &after)
+{
+ if (path.isEmpty() || before.isEmpty())
+ return path;
+
+ QString pathToPatch = QDir::cleanPath(path);
+ const QString pathToReplace = QDir::cleanPath(before);
+ if (pathToPatch.startsWith(pathToReplace))
+ return QDir::cleanPath(after) + pathToPatch.mid(pathToReplace.size());
+ return path;
+}
diff --git a/src/libs/installer/fileutils.h b/src/libs/installer/fileutils.h
index 45f3a9acf..a9235df67 100644
--- a/src/libs/installer/fileutils.h
+++ b/src/libs/installer/fileutils.h
@@ -99,6 +99,8 @@ private:
quint64 INSTALLER_EXPORT fileSize(const QFileInfo &info);
bool INSTALLER_EXPORT isInBundle(const QString &path, QString *bundlePath = 0);
+ QString replacePath(const QString &path, const QString &pathBefore, const QString &pathAfter);
+
#ifdef Q_OS_WIN
QString INSTALLER_EXPORT getLongPathName(const QString &name);
QString INSTALLER_EXPORT getShortPathName(const QString &name);
diff --git a/src/libs/installer/globalsettingsoperation.cpp b/src/libs/installer/globalsettingsoperation.cpp
index 0dcc990e8..c266d5c57 100644
--- a/src/libs/installer/globalsettingsoperation.cpp
+++ b/src/libs/installer/globalsettingsoperation.cpp
@@ -36,7 +36,8 @@
using namespace QInstaller;
-GlobalSettingsOperation::GlobalSettingsOperation()
+GlobalSettingsOperation::GlobalSettingsOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("GlobalConfig"));
}
@@ -54,7 +55,7 @@ bool GlobalSettingsOperation::performOperation()
if (!settings->isWritable()) {
setError(UserDefinedError);
- setErrorString(tr("Settings are not writable"));
+ setErrorString(tr("Settings are not writable."));
return false;
}
@@ -64,7 +65,7 @@ bool GlobalSettingsOperation::performOperation()
if (settings->status() != QSettingsWrapper::NoError) {
setError(UserDefinedError);
- setErrorString(tr("Failed to write settings"));
+ setErrorString(tr("Failed to write settings."));
return false;
}
@@ -97,24 +98,15 @@ bool GlobalSettingsOperation::testOperation()
return true;
}
-Operation *GlobalSettingsOperation::clone() const
-{
- return new GlobalSettingsOperation();
-}
-
QSettingsWrapper *GlobalSettingsOperation::setup(QString *key, QString *value, const QStringList &arguments)
{
- if (arguments.count() != 3 && arguments.count() != 4 && arguments.count() != 5) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments.count()).arg(tr("3, 4 or 5"), QLatin1String("")));
+ if (!checkArgumentCount(3, 5))
return 0;
- }
if (arguments.count() == 5) {
QSettingsWrapper::Scope scope = QSettingsWrapper::UserScope;
if (arguments.at(0) == QLatin1String("SystemScope"))
- scope = QSettingsWrapper::SystemScope;
+ scope = QSettingsWrapper::SystemScope;
const QString &company = arguments.at(1);
const QString &application = arguments.at(2);
*key = arguments.at(3);
diff --git a/src/libs/installer/globalsettingsoperation.h b/src/libs/installer/globalsettingsoperation.h
index dab8866db..d64b13ce4 100644
--- a/src/libs/installer/globalsettingsoperation.h
+++ b/src/libs/installer/globalsettingsoperation.h
@@ -42,13 +42,12 @@ class QSettingsWrapper;
class INSTALLER_EXPORT GlobalSettingsOperation : public Operation
{
public:
- GlobalSettingsOperation();
+ explicit GlobalSettingsOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
private:
QSettingsWrapper *setup(QString *key, QString *value, const QStringList &args);
diff --git a/src/libs/installer/init.cpp b/src/libs/installer/init.cpp
index 9eb49669a..fffd21320 100644
--- a/src/libs/installer/init.cpp
+++ b/src/libs/installer/init.cpp
@@ -53,75 +53,20 @@
#include "settingsoperation.h"
#include "consumeoutputoperation.h"
-
+#include "lib7z_facade.h"
#include "utils.h"
-#include "kdupdaterupdateoperationfactory.h"
-#include "kdupdaterfiledownloaderfactory.h"
-
-#include "7zCrc.h"
+#include "updateoperationfactory.h"
+#include "filedownloaderfactory.h"
#include <QtPlugin>
#include <QElapsedTimer>
#include <iostream>
-namespace NArchive {
- namespace NXz {
- void registerArcxz();
- }
- namespace NSplit {
- void registerArcSplit();
- }
- namespace NLzma {
- namespace NLzmaAr {
- void registerArcLzma();
- }
- namespace NLzma86Ar {
- void registerArcLzma86();
- }
- }
-}
-
-void registerArc7z();
-
-void registerCodecBCJ();
-void registerCodecBCJ2();
-
-void registerCodecCopy();
-void registerCodecLZMA();
-void registerCodecLZMA2();
-
-void registerCodecDelta();
-void registerCodecBranch();
-void registerCodecByteSwap();
-
using namespace KDUpdater;
using namespace QInstaller;
-static void initArchives()
-{
- CrcGenerateTable();
-
- registerArc7z();
-
- registerCodecBCJ();
- registerCodecBCJ2();
-
- registerCodecCopy();
- registerCodecLZMA();
- registerCodecLZMA2();
-
- registerCodecDelta();
- registerCodecBranch();
- registerCodecByteSwap();
-
- NArchive::NXz::registerArcxz();
- NArchive::NSplit::registerArcSplit();
- NArchive::NLzma::NLzmaAr::registerArcLzma();
- NArchive::NLzma::NLzma86Ar::registerArcLzma86();
-}
-
#if defined(QT_STATIC)
static void initResources()
{
@@ -198,7 +143,8 @@ void messageHandler(QtMsgType type, const QMessageLogContext &context, const QSt
void QInstaller::init()
{
- ::initArchives();
+ Lib7z::initSevenZ();
+
#if defined(QT_STATIC)
::initResources();
#endif
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index cfa83d08d..ed27d61d6 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -125,7 +125,12 @@ HEADERS += packagemanagercore.h \
serverauthenticationdialog.h \
keepaliveobject.h \
systeminfo.h \
- localsocket.h
+ localsocket.h \
+ packagesource.h \
+ lib7z_guid.h \
+ lib7z_create.h \
+ lib7z_extract.h \
+ lib7z_list.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \
@@ -199,7 +204,8 @@ SOURCES += packagemanagercore.cpp \
proxycredentialsdialog.cpp \
serverauthenticationdialog.cpp \
keepaliveobject.cpp \
- systeminfo.cpp
+ systeminfo.cpp \
+ packagesource.cpp
FORMS += proxycredentialsdialog.ui \
serverauthenticationdialog.ui
diff --git a/src/libs/installer/installercalculator.cpp b/src/libs/installer/installercalculator.cpp
index 0f92ecb3a..353335215 100644
--- a/src/libs/installer/installercalculator.cpp
+++ b/src/libs/installer/installercalculator.cpp
@@ -76,7 +76,7 @@ QString InstallerCalculator::installReason(Component *component) const
"Components added as automatic dependencies:");
case Dependent:
return QCoreApplication::translate("InstallerCalculator", "Components added as "
- "dependency for '%1':").arg(installReasonReferencedComponent(component));
+ "dependency for \"%1\":").arg(installReasonReferencedComponent(component));
case Resolved:
return QCoreApplication::translate("InstallerCalculator",
"Components that have resolved dependencies:");
@@ -107,8 +107,8 @@ void InstallerCalculator::realAppendToInstallComponents(Component *component)
QString InstallerCalculator::recursionError(Component *component)
{
- return QCoreApplication::translate("InstallerCalculator", "Recursion detected, component '%1' "
- "already added with reason: '%2'").arg(component->name(), installReason(component));
+ return QCoreApplication::translate("InstallerCalculator", "Recursion detected, component \"%1\" "
+ "already added with reason: \"%2\"").arg(component->name(), installReason(component));
}
bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &components)
@@ -120,7 +120,7 @@ bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &co
foreach (Component *component, components){
if (m_toInstallComponentIds.contains(component->name())) {
const QString errorMessage = recursionError(component);
- qWarning() << errorMessage;
+ qWarning().noquote() << errorMessage;
m_componentsToInstallError.append(errorMessage);
Q_ASSERT_X(!m_toInstallComponentIds.contains(component->name()), Q_FUNC_INFO,
qPrintable(errorMessage));
@@ -170,9 +170,9 @@ bool InstallerCalculator::appendComponentToInstall(Component *component)
PackageManagerCore::componentByName(dependencyComponentName, m_allComponents);
if (!dependencyComponent) {
const QString errorMessage = QCoreApplication::translate("InstallerCalculator",
- "Cannot find missing dependency '%1' for '%2'.").arg(dependencyComponentName,
+ "Cannot find missing dependency \"%1\" for \"%2\".").arg(dependencyComponentName,
component->name());
- qWarning() << errorMessage;
+ qWarning().noquote() << errorMessage;
m_componentsToInstallError.append(errorMessage);
return false;
}
@@ -181,7 +181,7 @@ bool InstallerCalculator::appendComponentToInstall(Component *component)
&& !m_toInstallComponentIds.contains(dependencyComponent->name())) {
if (m_visitedComponents.value(component).contains(dependencyComponent)) {
const QString errorMessage = recursionError(component);
- qWarning() << errorMessage;
+ qWarning().noquote() << errorMessage;
m_componentsToInstallError = errorMessage;
Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent),
Q_FUNC_INFO, qPrintable(errorMessage));
diff --git a/src/libs/installer/installiconsoperation.cpp b/src/libs/installer/installiconsoperation.cpp
index e5622dc2e..a91b644b8 100644
--- a/src/libs/installer/installiconsoperation.cpp
+++ b/src/libs/installer/installiconsoperation.cpp
@@ -91,7 +91,8 @@ QString InstallIconsOperation::targetDirectory()
return directory;
}
-InstallIconsOperation::InstallIconsOperation()
+InstallIconsOperation::InstallIconsOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("InstallIcons"));
}
@@ -108,20 +109,16 @@ void InstallIconsOperation::backup()
bool InstallIconsOperation::performOperation()
{
- const QStringList args = arguments();
- if ((args.count() != 1) && (args.count() != 2)) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("1 or 2"), tr(" (Sourcepath, [Vendorprefix])")));
+ if (!checkArgumentCount(1, 2, tr("<source path> [vendor prefix]")))
return false;
- }
+ const QStringList args = arguments();
const QString source = args.at(0);
- const QString vendor = args.value(1);
+ const QString vendor = args.value(1); // value() used since it's optional
if (source.isEmpty()) {
setError(InvalidArguments);
- setErrorString(tr("Invalid Argument: source folder must not be empty."));
+ setErrorString(tr("Invalid Argument: source directory must not be empty."));
return false;
}
@@ -132,7 +129,7 @@ bool InstallIconsOperation::performOperation()
QStringList backupFiles;
QStringList createdDirectories;
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
// iterate a second time to get the actual work done
QDirIterator it(sourceDir.path(), QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot,
@@ -170,7 +167,8 @@ bool InstallIconsOperation::performOperation()
QFile bf(target);
if (!bf.copy(backup)) {
setError(UserDefinedError);
- setErrorString(tr("Could not backup file %1: %2").arg(target, bf.errorString()));
+ setErrorString(tr("Cannot backup file \"%1\": %2").arg(
+ QDir::toNativeSeparators(target), bf.errorString()));
undoOperation();
return false;
}
@@ -183,7 +181,8 @@ bool InstallIconsOperation::performOperation()
QString errStr;
if (!deleteFileNowOrLater(target, &errStr)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to overwrite %1: %2").arg(target, errStr));
+ setErrorString(tr("Failed to overwrite \"%1\": %2").arg(
+ QDir::toNativeSeparators(target), errStr));
undoOperation();
return false;
}
@@ -194,7 +193,8 @@ bool InstallIconsOperation::performOperation()
QFile cf(source);
if (!cf.copy(target)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to copy file %1: %2").arg(target, cf.errorString()));
+ setErrorString(tr("Failed to copy file \"%1\": %2").arg(
+ QDir::toNativeSeparators(target), cf.errorString()));
undoOperation();
return false;
}
@@ -204,7 +204,8 @@ bool InstallIconsOperation::performOperation()
setValue(QLatin1String("files"), files);
} else if (fi.isDir() && !QDir(target).exists()) {
if (!QDir().mkpath(target)) {
- setErrorString(tr("Could not create folder at %1: %2").arg(target, qt_error_string()));
+ setErrorString(tr("Cannot create directory \"%1\": %2").arg(
+ QDir::toNativeSeparators(target), qt_error_string()));
undoOperation();
return false;
}
@@ -236,7 +237,7 @@ bool InstallIconsOperation::undoOperation()
QFile installedTarget(target);
if (installedTarget.exists() && !(installedTarget.copy(source) && installedTarget.remove())) {
- warningMessages << QString::fromLatin1("Could not move file from '%1' to '%2', error: %3)").arg(
+ warningMessages << QString::fromLatin1("Cannot move file from \"%1\" to \"%2\": %3)").arg(
target, source, installedTarget.errorString());
}
}
@@ -252,13 +253,13 @@ bool InstallIconsOperation::undoOperation()
deleteFileNowOrLater(target);
// then copy the backup onto the target
if (!QFile::copy(backup, target)) {
- warningMessages << QString::fromLatin1("Could not restore the backup '%1' to '%2'").arg(
+ warningMessages << QString::fromLatin1("Cannot restore the backup \"%1\" to \"%2\".").arg(
backup, target);
}
// finally remove the backp
if (!deleteFileNowOrLater(backup))
- warningMessages << QString::fromLatin1("Could not remove the backup '%1'").arg(backup);
+ warningMessages << QString::fromLatin1("Cannot remove the backup \"%1\".").arg(backup);
}
@@ -268,14 +269,14 @@ bool InstallIconsOperation::undoOperation()
const QDir dir(*it);
removeSystemGeneratedFiles(dir.absolutePath());
if (dir.exists() && !QDir::root().rmdir(dir.path()))
- warningMessages << QString::fromLatin1("Could not remove directory '%1'").arg(dir.path());
+ warningMessages << QString::fromLatin1("Cannot remove directory \"%1\".").arg(dir.path());
}
if (!warningMessages.isEmpty()) {
- qWarning() << QString::fromLatin1("Undo of operation '%1' with arguments '%2' had some problems.").arg(
- name(), arguments().join(QLatin1String(", ")));
+ qWarning() << "Undo of operation" << name() << "with arguments"
+ << arguments().join(QLatin1String(", ")) << "had some problems.";
foreach (const QString &message, warningMessages) {
- qWarning() << message;
+ qWarning().noquote() << message;
}
}
@@ -286,8 +287,3 @@ bool InstallIconsOperation::testOperation()
{
return true;
}
-
-Operation *InstallIconsOperation::clone() const
-{
- return new InstallIconsOperation();
-}
diff --git a/src/libs/installer/installiconsoperation.h b/src/libs/installer/installiconsoperation.h
index 534317d2b..ad3362098 100644
--- a/src/libs/installer/installiconsoperation.h
+++ b/src/libs/installer/installiconsoperation.h
@@ -44,14 +44,13 @@ class INSTALLER_EXPORT InstallIconsOperation : public QObject, public Operation
{
Q_OBJECT
public:
- InstallIconsOperation();
+ explicit InstallIconsOperation(PackageManagerCore *core);
~InstallIconsOperation();
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
Q_SIGNALS:
void outputTextChanged(const QString &progress);
diff --git a/src/libs/installer/lib7z_create.h b/src/libs/installer/lib7z_create.h
new file mode 100644
index 000000000..73cf1299c
--- /dev/null
+++ b/src/libs/installer/lib7z_create.h
@@ -0,0 +1,82 @@
+/**************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see http://qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+#ifndef LIB7Z_CREATE_H
+#define LIB7Z_CREATE_H
+
+#include "installer_global.h"
+
+#include <Common/MyCom.h>
+#include <7zip/UI/Common/Update.h>
+
+QT_BEGIN_NAMESPACE
+class QFileDevice;
+class QStringList;
+QT_END_NAMESPACE
+
+namespace Lib7z
+{
+ enum struct QTmpFile {
+ No,
+ Yes
+ };
+
+ enum struct Compression {
+ Non = 0,
+ Fastest = 1,
+ Fast = 3,
+ Normal = 5,
+ Maximum = 7,
+ Ultra = 9
+ };
+
+ class INSTALLER_EXPORT UpdateCallback : public IUpdateCallbackUI2, public CMyUnknownImp
+ {
+ Q_DISABLE_COPY(UpdateCallback)
+
+ public:
+ UpdateCallback() = default;
+ virtual ~UpdateCallback() {}
+
+ MY_UNKNOWN_IMP
+ INTERFACE_IUpdateCallbackUI2(;)
+ };
+
+ void INSTALLER_EXPORT createArchive(QFileDevice *archive, const QStringList &sources,
+ Compression level = Compression::Normal, UpdateCallback *callback = 0);
+ void INSTALLER_EXPORT createArchive(const QString &archive, const QStringList &sources,
+ QTmpFile mode, Compression level = Compression::Normal, UpdateCallback *callback = 0);
+
+} // namespace Lib7z
+
+#endif // LIB7Z_CREATE_H
diff --git a/src/libs/installer/lib7z_extract.h b/src/libs/installer/lib7z_extract.h
new file mode 100644
index 000000000..f6182c727
--- /dev/null
+++ b/src/libs/installer/lib7z_extract.h
@@ -0,0 +1,85 @@
+/**************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see http://qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+#ifndef LIB7Z_EXTRACT_H
+#define LIB7Z_EXTRACT_H
+
+#include "installer_global.h"
+
+#include <Common/MyCom.h>
+#include <7zip/Archive/IArchive.h>
+
+#include <QString>
+
+class CArc;
+
+QT_BEGIN_NAMESPACE
+class QFileDevice;
+QT_END_NAMESPACE
+
+namespace Lib7z
+{
+ class INSTALLER_EXPORT ExtractCallback : public IArchiveExtractCallback, public CMyUnknownImp
+ {
+ Q_DISABLE_COPY(ExtractCallback)
+
+ public:
+ ExtractCallback() = default;
+ virtual ~ExtractCallback() = default;
+
+ void setArchive(CArc *carc) { arc = carc; }
+ void setTarget(const QString &dir) { targetDir = dir; }
+
+ MY_UNKNOWN_IMP
+ INTERFACE_IArchiveExtractCallback(;)
+
+ protected:
+ virtual bool prepareForFile(const QString & /*filename*/) { return true; }
+ virtual void setCurrentFile(const QString &filename) { Q_UNUSED(filename) }
+ virtual HRESULT setCompleted(quint64 /*completed*/, quint64 /*total*/) { return S_OK; }
+
+ private:
+ CArc *arc = 0;
+
+ QString targetDir;
+ quint64 total = 0;
+ quint64 completed = 0;
+ quint32 currentIndex = 0;
+ };
+
+ void INSTALLER_EXPORT extractArchive(QFileDevice *archive, const QString &targetDirectory,
+ ExtractCallback *callback = 0);
+
+} // namespace Lib7z
+
+#endif // LIB7Z_EXTRACT_H
diff --git a/src/libs/installer/lib7z_facade.cpp b/src/libs/installer/lib7z_facade.cpp
index 8f21343db..86dc86e7a 100644
--- a/src/libs/installer/lib7z_facade.cpp
+++ b/src/libs/installer/lib7z_facade.cpp
@@ -30,106 +30,199 @@
** $QT_END_LICENSE$
**
**************************************************************************/
+
#include "lib7z_facade.h"
#include "errors.h"
#include "fileio.h"
+#include "lib7z_create.h"
+#include "lib7z_extract.h"
+#include "lib7z_list.h"
+#include "lib7z_guid.h"
+
#ifndef Q_OS_WIN
# include "StdAfx.h"
#endif
-#include "Common/MyInitGuid.h"
+#include <7zCrc.h>
+
+#include <7zip/Archive/IArchive.h>
-#include "7zip/Archive/IArchive.h"
-#include "7zip/UI/Common/OpenArchive.h"
-#include "7zip/UI/Common/Update.h"
+#include <7zip/UI/Common/ArchiveCommandLine.h>
+#include <7zip/UI/Common/OpenArchive.h>
-#include "Windows/FileIO.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
+#include <Windows/FileDir.h>
+#include <Windows/FileIO.h>
+#include <Windows/PropVariant.h>
+#include <Windows/PropVariantConv.h>
+#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QIODevice>
-#include <QtCore/QMutexLocker>
#include <QPointer>
-#include <QTemporaryFile>
#include <QReadWriteLock>
+#include <QTemporaryFile>
-#ifdef _MSC_VER
-#pragma warning(disable:4297)
-#endif
+#include <mutex>
+#include <memory>
#ifdef Q_OS_WIN
+HINSTANCE g_hInstance = 0;
+
+# define S_IFMT 00170000
+# define S_IFLNK 0120000
+# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+# define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 /* trick for Unix */
+# if !defined(Q_CC_MINGW)
+# include <time.h> // for localtime_s
+# endif
+#else
+extern "C" int global_use_utf16_conversion;
+
+#include <myWindows/config.h>
+#include <sys/stat.h>
+#endif
+
+namespace NArchive {
+ namespace N7z {
+ void registerArcDec7z();
+ }
+ namespace NXz {
+ void registerArcxz();
+ }
+ namespace NSplit {
+ void registerArcSplit();
+ }
+ namespace NLzma {
+ namespace NLzmaAr {
+ void registerArcLzma();
+ }
+ namespace NLzma86Ar {
+ void registerArcLzma86();
+ }
+ }
+}
+using namespace NWindows;
+
+void registerCodecBCJ();
+void registerCodecBCJ2();
+
+void registerCodecLZMA();
+void registerCodecLZMA2();
+
+void registerCodecCopy();
+void registerCodecDelta();
+void registerCodecBranch();
+void registerCodecByteSwap();
+
+namespace Lib7z {
+
-#include <time.h>
-#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 /* trick for Unix */
-#define S_IFMT 00170000
-#define S_IFLNK 0120000
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+// -- 7z init codecs, archives
-typedef BOOL (WINAPI *CREATEHARDLINK)(LPCSTR dst, LPCSTR str, LPSECURITY_ATTRIBUTES sa);
+std::once_flag gOnceFlag;
-bool CreateHardLinkWrapper(const QString &dest, const QString &file)
+void initSevenZ()
{
- static HMODULE module = 0;
- static CREATEHARDLINK proc = 0;
+ std::call_once(gOnceFlag, [] {
+ CrcGenerateTable();
- if (module == 0)
- module = LoadLibrary(L"kernel32.dll");
- if (module == 0)
- return false;
- if (proc == 0)
- proc = (CREATEHARDLINK) GetProcAddress(module, "CreateHardLinkA");
- if (proc == 0)
- return false;
- QString target = file;
- if (!QFileInfo(file).isAbsolute())
- {
- target = QFileInfo(dest).dir().absoluteFilePath(file);
- }
- const QString link = QDir::toNativeSeparators(dest);
- const QString existingFile = QDir::toNativeSeparators(target);
- return proc(link.toLocal8Bit(), existingFile.toLocal8Bit(), 0);
-}
+ registerCodecBCJ();
+ registerCodecBCJ2();
-#else
-#include <sys/stat.h>
+ registerCodecLZMA();
+ registerCodecLZMA2();
+
+ registerCodecCopy();
+ registerCodecDelta();
+ registerCodecBranch();
+ registerCodecByteSwap();
+
+ NArchive::N7z::registerArcDec7z();
+ NArchive::NXz::registerArcxz();
+ NArchive::NSplit::registerArcSplit();
+ NArchive::NLzma::NLzmaAr::registerArcLzma();
+ NArchive::NLzma::NLzma86Ar::registerArcLzma86();
+
+#ifndef Q_OS_WIN
+# ifdef ENV_HAVE_LOCALE
+ const QByteArray locale = qgetenv("LC_ALL").toUpper();
+ if (!locale.isEmpty() && (locale != "C") && (locale != "POSIX"))
+ global_use_utf16_conversion = 1;
+# elif defined(LOCALE_IS_UTF8)
+ global_use_utf16_conversion = 1;
+# else
+ global_use_utf16_conversion = 0;
+# endif
#endif
+ });
+}
-#include <memory>
-#include <cassert>
+// -- error handling
-using namespace Lib7z;
-using namespace NWindows;
+Q_GLOBAL_STATIC(QString, getLastErrorString)
+Q_GLOBAL_STATIC(QReadWriteLock, lastErrorReadWriteLock)
+QString lastError()
+{
+ QReadLocker locker(lastErrorReadWriteLock());
+ Q_UNUSED(locker)
+ return *getLastErrorString();
+}
-namespace Lib7z {
- Q_GLOBAL_STATIC(QReadWriteLock, lastErrorReadWriteLock)
- Q_GLOBAL_STATIC(QString, getLastErrorString)
+void setLastError(const QString &errorString)
+{
+ QWriteLocker locker(lastErrorReadWriteLock());
+ Q_UNUSED(locker)
+ *getLastErrorString() = errorString;
+}
- QString lastError()
- {
- QReadLocker locker(lastErrorReadWriteLock());
- Q_UNUSED(locker)
- return *getLastErrorString();
- }
+QString errorMessageFrom7zResult(const LONG &extractResult)
+{
+ if (!lastError().isEmpty())
+ return lastError();
- void setLastError(const QString &errorString)
- {
- QWriteLocker locker(lastErrorReadWriteLock());
- Q_UNUSED(locker)
- *getLastErrorString() = errorString;
+ QString errorMessage = QCoreApplication::translate("Lib7z", "internal code: %1");
+ switch (extractResult) {
+ case S_OK:
+ qFatal("S_OK value is not a valid error code.");
+ break;
+ case E_NOTIMPL:
+ errorMessage = errorMessage.arg(QLatin1String("E_NOTIMPL"));
+ break;
+ case E_NOINTERFACE:
+ errorMessage = errorMessage.arg(QLatin1String("E_NOINTERFACE"));
+ break;
+ case E_ABORT:
+ errorMessage = errorMessage.arg(QLatin1String("E_ABORT"));
+ break;
+ case E_FAIL:
+ errorMessage = errorMessage.arg(QLatin1String("E_FAIL"));
+ break;
+ case STG_E_INVALIDFUNCTION:
+ errorMessage = errorMessage.arg(QLatin1String("STG_E_INVALIDFUNCTION"));
+ break;
+ case E_OUTOFMEMORY:
+ errorMessage = QCoreApplication::translate("Lib7z", "not enough memory");
+ break;
+ case E_INVALIDARG:
+ errorMessage = errorMessage.arg(QLatin1String("E_INVALIDARG"));
+ break;
+ default:
+ errorMessage = QCoreApplication::translate("Lib7z", "Error: %1").arg(extractResult);
+ break;
}
+ return errorMessage;
}
-namespace {
-/**
-* RAII class to create a directory (tryCreate()) and delete it on destruction unless released.
+/*!
+ RAII class to create a directory (tryCreate()) and delete it on destruction unless released.
*/
-struct DirectoryGuard {
+struct DirectoryGuard
+{
explicit DirectoryGuard(const QString &path)
: m_path(path)
, m_created(false)
@@ -144,14 +237,15 @@ struct DirectoryGuard {
return;
QDir dir(m_path);
if (!dir.rmdir(m_path))
- qWarning() << "Could not delete directory " << m_path;
+ qWarning() << "Cannot delete directory " << m_path;
}
- /**
- * Tries to create the directorie structure.
- * Returns a list of every directory created.
+ /*!
+ Tries to create the directory structure.
+ Returns a list of every directory created.
*/
- QStringList tryCreate() {
+ QStringList tryCreate()
+ {
if (m_path.isEmpty())
return QStringList();
@@ -160,13 +254,12 @@ struct DirectoryGuard {
return QStringList();
if (fi.exists() && !fi.isDir()) {
throw SevenZipException(QCoreApplication::translate("DirectoryGuard",
- "Path exists but is not a folder: %1").arg(m_path));
+ "Path \"%1\" exists but is not a directory.").arg(QDir::toNativeSeparators(m_path)));
}
QStringList created;
QDir toCreate(m_path);
- while (!toCreate.exists())
- {
+ while (!toCreate.exists()) {
QString p = toCreate.absolutePath();
created.push_front(p);
p = p.section(QLatin1Char('/'), 0, -2);
@@ -177,12 +270,13 @@ struct DirectoryGuard {
m_created = dir.mkpath(m_path);
if (!m_created) {
throw SevenZipException(QCoreApplication::translate("DirectoryGuard",
- "Could not create folder: %1").arg(m_path));
+ "Cannot create directory \"%1\".").arg(QDir::toNativeSeparators(m_path)));
}
return created;
}
- void release() {
+ void release()
+ {
m_released = true;
}
@@ -190,7 +284,6 @@ struct DirectoryGuard {
bool m_created;
bool m_released;
};
-}
static UString QString2UString(const QString &str)
{
@@ -202,32 +295,12 @@ static QString UString2QString(const UString& str)
return QString::fromStdWString(static_cast<const wchar_t*>(str));
}
-static QString generateTempFileName()
-{
- QTemporaryFile tmp;
- if (!tmp.open()) {
- throw SevenZipException(QCoreApplication::translate("QInstaller",
- "Could not create temporary file"));
- }
- return QDir::toNativeSeparators(tmp.fileName());
-}
-
-/*
-static QStringList UStringVector2QStringList(const UStringVector& vec)
-{
-QStringList res;
-for (int i = 0; i < vec.Size(); ++i)
-res += UString2QString(vec[i]);
-return res;
-}
-*/
-
-static NCOM::CPropVariant readProperty(IInArchive* archive, int index, int propId)
+static NCOM::CPropVariant readProperty(IInArchive *archive, int index, int propId)
{
NCOM::CPropVariant prop;
if (archive->GetProperty(index, propId, &prop) != S_OK) {
- throw SevenZipException(QCoreApplication::translate("QInstaller",
- "Could not retrieve property %1 for item %2").arg(QString::number(propId),
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Cannot retrieve property %1 for item %2.").arg(QString::number(propId),
QString::number(index)));
}
return prop;
@@ -238,193 +311,134 @@ static bool IsFileTimeZero(const FILETIME *lpFileTime)
return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);
}
-static bool IsDST(const QDateTime& datetime = QDateTime())
-{
- const time_t seconds = static_cast< time_t >(datetime.isValid() ? datetime.toTime_t()
- : QDateTime::currentDateTime().toTime_t());
-#if defined(Q_OS_WIN) && !defined(Q_CC_MINGW)
- struct tm t;
- localtime_s(&t, &seconds);
-#else
- const struct tm &t = *localtime(&seconds);
-#endif
- return t.tm_isdst;
-}
-
-static bool getFileTimeFromProperty(IInArchive* archive, int index, int propId, FILETIME *fileTime)
+static bool getFileTimeFromProperty(IInArchive* archive, int index, int propId, FILETIME *ft)
{
const NCOM::CPropVariant prop = readProperty(archive, index, propId);
if (prop.vt != VT_FILETIME) {
- throw SevenZipException(QCoreApplication::translate("QInstaller",
- "Property %1 for item %2 not of type VT_FILETIME but %3").arg(QString::number(propId),
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Property %1 for item %2 not of type VT_FILETIME but %3.").arg(QString::number(propId),
QString::number(index), QString::number(prop.vt)));
}
- *fileTime = prop.filetime;
-
- if (IsFileTimeZero(fileTime))
- return false;
- return true;
+ *ft = prop.filetime;
+ return !IsFileTimeZero(ft);
}
-static
-QDateTime getDateTimeProperty(IInArchive* archive, int index, int propId, const QDateTime& defaultValue)
+static bool getDateTimeProperty(IInArchive *arc, int index, int id, QDateTime *value)
{
- FILETIME fileTime;
- if (!getFileTimeFromProperty(archive, index, propId, &fileTime))
- return defaultValue;
+ FILETIME ft7z;
+ if (!getFileTimeFromProperty(arc, index, id, &ft7z))
+ return false;
- FILETIME localFileTime;
- if (!FileTimeToLocalFileTime(&fileTime, &localFileTime)) {
- throw SevenZipException(QCoreApplication::translate("QInstaller",
- "Could not convert file time to local time"));
- }
SYSTEMTIME st;
- if (!BOOLToBool(FileTimeToSystemTime(&localFileTime, &st))) {
- throw SevenZipException(QCoreApplication::translate("QInstaller",
- "Could not convert local file time to system time"));
+ if (!BOOLToBool(FileTimeToSystemTime(&ft7z, &st))) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Cannot convert UTC file time to system time."));
}
- const QDate date(st.wYear, st.wMonth, st.wDay);
- const QTime time(st.wHour, st.wMinute, st.wSecond);
- QDateTime result(date, time);
-
- // fix daylight saving time
- const bool dst = IsDST();
- if (dst != IsDST(result))
- result = result.addSecs(dst ? -3600 : 3600);
-
- return result;
+ *value = QDateTime(QDate(st.wYear, st.wMonth, st.wDay), QTime(st.wHour, st.wMinute,
+ st.wSecond), Qt::UTC);
+ return value->isValid();
}
-static quint64 getUInt64Property(IInArchive* archive, int index, int propId, quint64 defaultValue=0)
+static quint64 getUInt64Property(IInArchive *archive, int index, int propId, quint64 defaultValue)
{
- const NCOM::CPropVariant prop = readProperty(archive, index, propId);
- if (prop.vt == VT_EMPTY)
- return defaultValue;
- return static_cast<quint64>(ConvertPropVariantToUInt64(prop));
+ UInt64 value;
+ if (ConvertPropVariantToUInt64(readProperty(archive, index, propId), value))
+ return value;
+ return defaultValue;
}
-static quint32 getUInt32Property(IInArchive* archive, int index, int propId, quint32 defaultValue=0)
+static quint32 getUInt32Property(IInArchive *archive, int index, int propId, quint32 defaultValue)
{
const NCOM::CPropVariant prop = readProperty(archive, index, propId);
if (prop.vt == VT_EMPTY)
return defaultValue;
- return static_cast< quint32 >(prop.ulVal);
+ return static_cast<quint32>(prop.ulVal);
}
-static QFile::Permissions getPermissions(IInArchive* archive, int index, bool* hasPermissions = 0)
+static QFile::Permissions getPermissions(IInArchive *archive, int index, bool *hasPermissions)
{
quint32 attributes = getUInt32Property(archive, index, kpidAttrib, 0);
QFile::Permissions permissions = 0;
if (attributes & FILE_ATTRIBUTE_UNIX_EXTENSION) {
if (hasPermissions != 0)
*hasPermissions = true;
- // filter the unix permissions
+ // filter the Unix permissions
attributes = (attributes >> 16) & 0777;
- permissions |= static_cast< QFile::Permissions >((attributes & 0700) << 2); // owner rights
- permissions |= static_cast< QFile::Permissions >((attributes & 0070) << 1); // group
- permissions |= static_cast< QFile::Permissions >((attributes & 0007) << 0); // and world rights
+ permissions |= static_cast<QFile::Permissions>((attributes & 0700) << 2); // owner rights
+ permissions |= static_cast<QFile::Permissions>((attributes & 0070) << 1); // group
+ permissions |= static_cast<QFile::Permissions>((attributes & 0007) << 0); // and world rights
} else if (hasPermissions != 0) {
*hasPermissions = false;
}
return permissions;
}
-namespace Lib7z {
+#define LIB7Z_ASSERTS(X, MODE) \
+ Q_ASSERT(X); \
+ Q_ASSERT(X->isOpen()); \
+ Q_ASSERT(X->is ## MODE()); \
+ Q_ASSERT(!X->isSequential());
+
class QIODeviceSequentialOutStream : public ISequentialOutStream, public CMyUnknownImp
{
-public:
- enum Behavior {
- KeepDeviceUntouched,
- CloseAndDeleteDevice
- };
+ Q_DISABLE_COPY(QIODeviceSequentialOutStream)
+public:
MY_UNKNOWN_IMP
- explicit QIODeviceSequentialOutStream(QIODevice* device, Behavior behavior);
- ~QIODeviceSequentialOutStream();
- QString errorString() const;
- /* reimp */ STDMETHOD(Write)(const void* data, UInt32 size, UInt32* processedSize);
-
-private:
- Behavior m_behavior;
- QString m_errorString;
- QPointer<QIODevice> m_device;
-};
-
-QIODeviceSequentialOutStream::QIODeviceSequentialOutStream(QIODevice* device, Behavior behavior)
- : ISequentialOutStream()
- , CMyUnknownImp()
- , m_behavior(behavior)
- , m_device(device)
-{
- Q_ASSERT(m_device);
-
- if (!device->isOpen() && !m_device->open(QIODevice::WriteOnly))
- m_errorString = m_device->errorString();
-}
-
-QIODeviceSequentialOutStream::~QIODeviceSequentialOutStream()
-{
- if (m_behavior == CloseAndDeleteDevice) {
- m_device->close();
- delete m_device;
- m_device = 0;
+ explicit QIODeviceSequentialOutStream(std::unique_ptr<QIODevice> device)
+ : ISequentialOutStream()
+ , m_device(std::move(device))
+ {
+ LIB7Z_ASSERTS(m_device, Writable)
}
-}
-QString QIODeviceSequentialOutStream::errorString() const
-{
- return m_errorString;
-}
+ QString errorString() const {
+ return m_errorString;
+ }
-HRESULT QIODeviceSequentialOutStream::Write(const void* data, UInt32 size, UInt32* processedSize)
-{
- if (!m_device) {
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize)
+ {
if (processedSize)
*processedSize = 0;
- m_errorString = QCoreApplication::translate("QIODeviceSequentialOutStream",
- "No device set for output stream");
- return E_FAIL;
- }
- if (!m_device->isOpen()) {
- const bool opened = m_device->open(QIODevice::WriteOnly);
- if (!opened) {
- if (processedSize)
- *processedSize = 0;
+
+ const qint64 written = m_device->write(reinterpret_cast<const char*>(data), size);
+ if (written == -1) {
m_errorString = m_device->errorString();
return E_FAIL;
}
- }
- const qint64 written = m_device->write(reinterpret_cast<const char*>(data), size);
- if (written == -1) {
if (processedSize)
- *processedSize = 0;
- m_errorString = m_device->errorString();
- return E_FAIL;
+ *processedSize = written;
+ m_errorString.clear();
+ return S_OK;
}
- if (processedSize)
- *processedSize = written;
- m_errorString = QString();
- return S_OK;
-}
+private:
+ QString m_errorString;
+ std::unique_ptr<QIODevice> m_device;
+};
class QIODeviceInStream : public IInStream, public CMyUnknownImp
{
+ Q_DISABLE_COPY(QIODeviceInStream)
+
public:
MY_UNKNOWN_IMP
- explicit QIODeviceInStream(QIODevice* device) : IInStream(), CMyUnknownImp(), m_device(device)
+ explicit QIODeviceInStream(QIODevice *device)
+ : IInStream()
+ , CMyUnknownImp()
+ , m_device(device)
{
- assert(m_device);
- assert(!m_device->isSequential());
+ LIB7Z_ASSERTS(m_device, Readable)
}
- /* reimp */ STDMETHOD(Read)(void* data, UInt32 size, UInt32* processedSize)
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize)
{
- assert(m_device);
- assert(m_device->isReadable());
+ if (m_device.isNull())
+ return E_FAIL;
+
const qint64 actual = m_device->read(reinterpret_cast<char*>(data), size);
Q_ASSERT(actual != 0 || m_device->atEnd());
if (processedSize)
@@ -432,29 +446,28 @@ public:
return actual >= 0 ? S_OK : E_FAIL;
}
- /* reimp */ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64* newPosition)
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- assert(m_device);
- assert(!m_device->isSequential());
- assert(m_device->isReadable());
+ if (m_device.isNull())
+ return E_FAIL;
if (seekOrigin > STREAM_SEEK_END)
return STG_E_INVALIDFUNCTION;
UInt64 np = 0;
- switch(seekOrigin) {
- case STREAM_SEEK_SET:
- np = offset;
- break;
- case STREAM_SEEK_CUR:
- np = m_device->pos() + offset;
- break;
- case STREAM_SEEK_END:
- np = m_device->size() + offset;
- break;
- default:
- return STG_E_INVALIDFUNCTION;
+ switch (seekOrigin) {
+ case STREAM_SEEK_SET:
+ np = offset;
+ break;
+ case STREAM_SEEK_CUR:
+ np = m_device->pos() + offset;
+ break;
+ case STREAM_SEEK_END:
+ np = m_device->size() + offset;
+ break;
+ default:
+ return STG_E_INVALIDFUNCTION;
}
- np = qBound(static_cast<UInt64>(0), np, static_cast<UInt64>(m_device->size() - 1));
+ np = qBound(static_cast<UInt64>(0), np, static_cast<UInt64>(m_device->size()));
const bool ok = m_device->seek(np);
if (newPosition)
*newPosition = np;
@@ -464,1129 +477,646 @@ public:
private:
QPointer<QIODevice> m_device;
};
-}
-
-File::File()
- : permissions(0)
- , uncompressedSize(0)
- , compressedSize(0)
- , isDirectory(false)
-{
-}
-
-QVector<File> File::subtreeInPreorder() const
-{
- QVector<File> res;
- res += *this;
- Q_FOREACH (const File& child, children)
- res += child.subtreeInPreorder();
- return res;
-}
-
-bool File::operator<(const File& other) const
-{
- if (path != other.path)
- return path < other.path;
- if (mtime != other.mtime)
- return mtime < other.mtime;
- if (uncompressedSize != other.uncompressedSize)
- return uncompressedSize < other.uncompressedSize;
- if (compressedSize != other.compressedSize)
- return compressedSize < other.compressedSize;
- if (isDirectory != other.isDirectory)
- return !isDirectory;
- if (permissions != other.permissions)
- return permissions < other.permissions;
- return false;
-}
-
-bool File::operator==(const File& other) const
-{
- return mtime == other.mtime
- && path == other.path
- && uncompressedSize == other.uncompressedSize
- && compressedSize == other.compressedSize
- && isDirectory == other.isDirectory
- && children == other.children
- && (permissions == other.permissions
- || permissions == static_cast< QFile::Permissions >(-1)
- || other.permissions == static_cast< QFile::Permissions >(-1));
-}
-
-QByteArray Lib7z::formatKeyValuePairs(const QVariantList& l)
-{
- assert(l.size() % 2 == 0);
- QByteArray res;
- for (QVariantList::ConstIterator it = l.constBegin(); it != l.constEnd(); ++it) {
- if (!res.isEmpty())
- res += ", ";
- res += qPrintable(it->toString()) + QByteArray(" = ");
- ++it;
- res += qPrintable(it->toString());
- }
- return res;
-}
-
-class Job::Private
-{
-public:
- Private()
- : error(Lib7z::NoError)
- {}
-
- int error;
- QString errorString;
-};
-
-Job::Job(QObject* parent)
- : QObject(parent)
- , QRunnable()
- , d(new Private)
-{
-}
-
-Job::~Job()
-{
- delete d;
-}
-
-void Job::emitResult()
-{
- emit finished(this);
-}
-
-void Job::setError(int code)
-{
- d->error = code;
-}
-void Job::setErrorString(const QString &str)
+bool operator==(const File &lhs, const File &rhs)
{
- d->errorString = str;
+ return lhs.path == rhs.path
+ && lhs.utcTime == rhs.utcTime
+ && lhs.isDirectory == rhs.isDirectory
+ && lhs.compressedSize == rhs.compressedSize
+ && lhs.uncompressedSize == rhs.uncompressedSize
+ && (lhs.permissions == rhs.permissions
+ || lhs.permissions == static_cast<QFile::Permissions>(-1)
+ || rhs.permissions == static_cast<QFile::Permissions>(-1));
}
-void Job::emitProgress(qint64 completed, qint64 total)
+QVector<File> listArchive(QFileDevice *archive)
{
- emit progress(completed, total);
-}
-
-int Job::error() const
-{
- return d->error;
-}
+ LIB7Z_ASSERTS(archive, Readable)
-bool Job::hasError() const
-{
- return d->error != NoError;
-}
-
-void Job::run()
-{
- doStart();
-}
-
-QString Job::errorString() const
-{
- return d->errorString;
-}
+ const qint64 initialPos = archive->pos();
+ try {
+ CCodecs codecs;
+ if (codecs.Load() != S_OK)
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot load codecs."));
-void Job::start()
-{
- QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection);
-}
+ COpenOptions op;
+ op.codecs = &codecs;
-class ListArchiveJob::Private
-{
-public:
- QPointer<QFileDevice> archive;
- QVector<File> files;
-};
+ CObjectVector<COpenType> types;
+ op.types = &types; // Empty, because we use a stream.
-ListArchiveJob::ListArchiveJob(QObject* parent)
- : Job(parent)
- , d(new Private)
-{
-}
+ CIntVector excluded;
+ op.excludedFormats = &excluded;
-ListArchiveJob::~ListArchiveJob()
-{
- delete d;
-}
-
-QFileDevice* ListArchiveJob::archive() const
-{
- return d->archive;
-}
-
-void ListArchiveJob::setArchive(QFileDevice* device)
-{
- d->archive = device;
-}
+ const CMyComPtr<IInStream> stream = new QIODeviceInStream(archive);
+ op.stream = stream; // CMyComPtr is needed, otherwise it crashes in OpenStream().
-QVector<File> ListArchiveJob::index() const
-{
- return d->files;
-}
+ CObjectVector<CProperty> properties;
+ op.props = &properties;
-class OpenArchiveInfo
-{
-private:
- OpenArchiveInfo(QFileDevice* device)
- : codecs(new CCodecs)
- {
- if (codecs->Load() != S_OK) {
- throw SevenZipException(QCoreApplication::translate("OpenArchiveInfo",
- "Could not load codecs"));
- }
- if (!codecs->FindFormatForArchiveType(L"", formatIndices)) {
- throw SevenZipException(QCoreApplication::translate("OpenArchiveInfo",
- "Could not retrieve default format"));
- }
- stream = new QIODeviceInStream(device);
- if (archiveLink.Open2(codecs.data(), formatIndices, false, stream, UString(), 0) != S_OK) {
- throw SevenZipException(QCoreApplication::translate("OpenArchiveInfo",
- "Could not open archive"));
+ CArchiveLink archiveLink;
+ if (archiveLink.Open2(op, nullptr) != S_OK) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Cannot open archive \"%1\".").arg(archive->fileName()));
}
- if (archiveLink.Arcs.Size() == 0)
- throw SevenZipException(QCoreApplication::translate("OpenArchiveInfo", "No CArc found"));
-
- m_cleaner = new OpenArchiveInfoCleaner();
- m_cleaner->moveToThread(device->thread());
- QObject::connect(device, SIGNAL(destroyed(QObject*)), m_cleaner, SLOT(deviceDestroyed(QObject*)));
- }
-
-public:
- ~OpenArchiveInfo()
- {
- m_cleaner->deleteLater();
- }
-
- static OpenArchiveInfo* value(QFileDevice* device)
- {
- QMutexLocker _(&m_mutex);
- if (!instances.contains(device))
- instances.insert(device, new OpenArchiveInfo(device));
- return instances.value(device);
- }
-
- static OpenArchiveInfo* take(QFileDevice *device)
- {
- QMutexLocker _(&m_mutex);
- if (instances.contains(device))
- return instances.take(device);
- return 0;
- }
-
- CArchiveLink archiveLink;
-
-private:
- CIntVector formatIndices;
- CMyComPtr<IInStream> stream;
- QScopedPointer<CCodecs> codecs;
- OpenArchiveInfoCleaner *m_cleaner;
-
- static QMutex m_mutex;
- static QHash< QIODevice*, OpenArchiveInfo* > instances;
-};
-
-QMutex OpenArchiveInfo::m_mutex;
-QHash< QIODevice*, OpenArchiveInfo* > OpenArchiveInfo::instances;
-
-void OpenArchiveInfoCleaner::deviceDestroyed(QObject* dev)
-{
- QFileDevice* device = static_cast<QFileDevice*>(dev);
- Q_ASSERT(device);
- delete OpenArchiveInfo::take(device);
-}
-
-QVector<File> Lib7z::listArchive(QFileDevice* archive)
-{
- assert(archive);
- try {
- const OpenArchiveInfo* const openArchive = OpenArchiveInfo::value(archive);
QVector<File> flat;
-
- for (int i = 0; i < openArchive->archiveLink.Arcs.Size(); ++i) {
- const CArc& arc = openArchive->archiveLink.Arcs[i];
- IInArchive* const arch = arc.Archive;
-
+ for (unsigned i = 0; i < archiveLink.Arcs.Size(); ++i) {
+ IInArchive *const arch = archiveLink.Arcs[i].Archive;
UInt32 numItems = 0;
if (arch->GetNumberOfItems(&numItems) != S_OK) {
throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve number of items in archive"));
+ "Cannot retrieve number of items in archive."));
}
flat.reserve(flat.size() + numItems);
for (uint item = 0; item < numItems; ++item) {
UString s;
- if (arc.GetItemPath(item, s) != S_OK) {
+ if (archiveLink.Arcs[i].GetItemPath(item, s) != S_OK) {
throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve path of archive item %1").arg(item));
+ "Cannot retrieve path of archive item \"%1\".").arg(item));
}
File f;
f.archiveIndex.setX(i);
f.archiveIndex.setY(item);
f.path = UString2QString(s).replace(QLatin1Char('\\'), QLatin1Char('/'));
- IsArchiveItemFolder(arch, item, f.isDirectory);
- f.permissions = getPermissions(arch, item);
- f.mtime = getDateTimeProperty(arch, item, kpidMTime, QDateTime());
+ Archive_IsItem_Folder(arch, item, f.isDirectory);
+ f.permissions = getPermissions(arch, item, 0);
+ getDateTimeProperty(arch, item, kpidMTime, &(f.utcTime));
f.uncompressedSize = getUInt64Property(arch, item, kpidSize, 0);
f.compressedSize = getUInt64Property(arch, item, kpidPackSize, 0);
- flat.push_back(f);
- qApp->processEvents();
+ flat.append(f);
}
}
return flat;
- } catch (const SevenZipException& e) {
- throw e;
} catch (const char *err) {
+ archive->seek(initialPos);
throw SevenZipException(err);
+ } catch (const SevenZipException &e) {
+ archive->seek(initialPos);
+ throw e; // re-throw unmodified
} catch (...) {
+ archive->seek(initialPos);
throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Unknown exception caught (%1)").arg(QString::fromLatin1(Q_FUNC_INFO)));
+ "Unknown exception caught (%1).").arg(QString::fromLatin1(Q_FUNC_INFO)));
}
return QVector<File>(); // never reached
}
-void ListArchiveJob::doStart()
+
+// -- ExtractCallback
+
+STDMETHODIMP ExtractCallback::SetTotal(UInt64 t)
{
- try {
- if (!d->archive)
- throw SevenZipException(tr("Could not list archive: QIODevice already destroyed."));
- d->files = listArchive(d->archive);
- } catch (const SevenZipException& e) {
- setError(Failed);
- setErrorString(e.message());
- } catch (...) {
- setError(Failed);
- setErrorString(tr("Unknown exception caught (%1)").arg(tr("Failed")));
- }
- emitResult();
+ total = t;
+ return S_OK;
}
-class Lib7z::ExtractCallbackImpl : public IArchiveExtractCallback, public CMyUnknownImp
+STDMETHODIMP ExtractCallback::SetCompleted(const UInt64 *c)
{
-public:
- MY_UNKNOWN_IMP
- explicit ExtractCallbackImpl(ExtractCallback* qq)
- : q(qq)
- , currentIndex(0)
- , arc(0)
- , total(0)
- , completed(0)
- , device(0)
- {
- }
+ completed = *c;
+ if (total > 0)
+ return setCompleted(completed, total);
+ return S_OK;
+}
- void setTarget(QIODevice* dev)
- {
- device = dev;
- }
+// this method will be called by CFolderOutStream::OpenFile to stream via
+// CDecoder::CodeSpec extracted content to an output stream.
+STDMETHODIMP ExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 /*askExtractMode*/)
+{
+ *outStream = 0;
+ if (targetDir.isEmpty())
+ return E_FAIL;
- void setTarget(const QString &targetDirectory)
- {
- targetDir = targetDirectory;
- }
+ Q_ASSERT(arc);
+ currentIndex = index;
- // this method will be called by CFolderOutStream::OpenFile to stream via
- // CDecoder::CodeSpec extracted content to an output stream.
- /* reimp */ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream** outStream, Int32 askExtractMode)
- {
- Q_UNUSED(askExtractMode)
- *outStream = 0;
- if (device != 0) {
- QIODeviceSequentialOutStream *qOutStream = new QIODeviceSequentialOutStream(device,
- QIODeviceSequentialOutStream::KeepDeviceUntouched);
- if (!qOutStream->errorString().isEmpty()) {
- Lib7z::setLastError(qOutStream->errorString());
- return E_FAIL;
- }
- CMyComPtr<ISequentialOutStream> stream = qOutStream;
- *outStream = stream.Detach();
- return S_OK;
- } else if (!targetDir.isEmpty()) {
- assert(arc);
-
- currentIndex = index;
-
- UString s;
- if (arc->GetItemPath(index, s) != S_OK) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not retrieve path of archive item %1").arg(index));
- return E_FAIL;
- }
+ UString s;
+ if (arc->GetItemPath(index, s) != S_OK) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot retrieve path of archive item %1.").arg(index));
+ return E_FAIL;
+ }
- const QString path = UString2QString(s).replace(QLatin1Char('\\'), QLatin1Char('/'));
- const QFileInfo fi(QString::fromLatin1("%1/%2").arg(targetDir, path));
+ const QFileInfo fi(QString::fromLatin1("%1/%2").arg(targetDir, UString2QString(s)));
- DirectoryGuard guard(fi.absolutePath());
- const QStringList directories = guard.tryCreate();
+ DirectoryGuard guard(fi.absolutePath());
+ const QStringList directories = guard.tryCreate();
- bool isDir = false;
- IsArchiveItemFolder(arc->Archive, index, isDir);
- if (isDir)
- QDir(fi.absolutePath()).mkdir(fi.fileName());
+ bool isDir = false;
+ Archive_IsItem_Folder(arc->Archive, index, isDir);
+ if (isDir)
+ QDir(fi.absolutePath()).mkdir(fi.fileName());
- // this makes sure that all directories created get removed as well
- foreach (const QString &directory, directories)
- q->setCurrentFile(directory);
+ // this makes sure that all directories created get removed as well
+ foreach (const QString &directory, directories)
+ setCurrentFile(directory);
- if (!isDir && !q->prepareForFile(fi.absoluteFilePath()))
- return E_FAIL;
+ if (!isDir && !prepareForFile(fi.absoluteFilePath()))
+ return E_FAIL;
- q->setCurrentFile(fi.absoluteFilePath());
+ setCurrentFile(fi.absoluteFilePath());
- if (!isDir) {
+ if (!isDir) {
#ifndef Q_OS_WIN
- // do not follow symlinks, so we need to remove an existing one
- if (fi.isSymLink() && (!QFile::remove(fi.absoluteFilePath()))) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not remove already existing symlink. %1").arg(fi.absoluteFilePath()));
- return E_FAIL;
- }
+ // do not follow symlinks, so we need to remove an existing one
+ if (fi.isSymLink() && (!QFile::remove(fi.absoluteFilePath()))) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot remove already existing symlink %1.").arg(fi.absoluteFilePath()));
+ return E_FAIL;
+ }
#endif
- QIODeviceSequentialOutStream *qOutStream = new QIODeviceSequentialOutStream(
- new QFile(fi.absoluteFilePath()), QIODeviceSequentialOutStream::CloseAndDeleteDevice);
- if (!qOutStream->errorString().isEmpty()) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not open file: %1 (%2)").arg(fi.absoluteFilePath(),
- qOutStream->errorString()));
- return E_FAIL;
- }
- CMyComPtr<ISequentialOutStream> stream = qOutStream;
- *outStream = stream;
- stream.Detach();
- }
-
- guard.release();
- return S_OK;
+ std::unique_ptr<QFile> file(new QFile(fi.absoluteFilePath()));
+ if (!file->open(QIODevice::WriteOnly)) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(fi.absoluteFilePath()), file->errorString()));
+ return E_FAIL;
}
- return E_FAIL;
+ CMyComPtr<ISequentialOutStream> stream =
+ new QIODeviceSequentialOutStream(std::move(file));
+ *outStream = stream.Detach(); // CMyComPtr is needed, otherwise it crashes in Write().
}
- /* reimp */ STDMETHOD(PrepareOperation)(Int32 askExtractMode)
- {
- Q_UNUSED(askExtractMode)
+ guard.release();
+ return S_OK;
+}
+
+STDMETHODIMP ExtractCallback::PrepareOperation(Int32 /*askExtractMode*/)
+{
+ return S_OK;
+}
+
+STDMETHODIMP ExtractCallback::SetOperationResult(Int32 /*resultEOperationResult*/)
+{
+ if (targetDir.isEmpty())
return S_OK;
- }
- /* reimp */ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult)
- {
- Q_UNUSED(resultEOperationResult)
+ UString s;
+ if (arc->GetItemPath(currentIndex, s) != S_OK) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot retrieve path of archive item %1.").arg(currentIndex));
+ return E_FAIL;
+ }
- if (!targetDir.isEmpty()) {
- bool hasPerm = false;
- const QFile::Permissions permissions = getPermissions(arc->Archive, currentIndex, &hasPerm);
+ const QString absFilePath = QFileInfo(QString::fromLatin1("%1/%2").arg(targetDir,
+ UString2QString(s).replace(QLatin1Char('\\'), QLatin1Char('/')))).absoluteFilePath();
- UString s;
- if (arc->GetItemPath(currentIndex, s) != S_OK) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not retrieve path of archive item %1").arg(currentIndex));
- return E_FAIL;
- }
- const QString path = UString2QString(s).replace(QLatin1Char('\\'), QLatin1Char('/'));
- const QString absFilePath = QFileInfo(QString::fromLatin1("%1/%2").arg(targetDir, path))
- .absoluteFilePath();
-
- // do we have a symlink?
- const quint32 attributes = getUInt32Property(arc->Archive, currentIndex, kpidAttrib, 0);
- struct stat stat_info;
- stat_info.st_mode = attributes >> 16;
- if (S_ISLNK(stat_info.st_mode)) {
+ // do we have a symlink?
+ const quint32 attributes = getUInt32Property(arc->Archive, currentIndex, kpidAttrib, 0);
+ struct stat stat_info;
+ stat_info.st_mode = attributes >> 16;
+ if (S_ISLNK(stat_info.st_mode)) {
#ifdef Q_OS_WIN
- qFatal(QString::fromLatin1("Creating a link from archive is not implemented for windows. "
- "Link filename: %1").arg(absFilePath).toLatin1());
- // TODO
-// if (!CreateHardLinkWrapper(absFilePath, QLatin1String(symlinkTarget))) {
-// return S_FALSE;
-// }
+ qFatal(QString::fromLatin1("Creating a link from archive is not implemented for "
+ "windows. Link filename: %1").arg(absFilePath).toLatin1());
+ // TODO
+ //if (!NFile::NDir::MyCreateHardLink(CFSTR(QDir::toNativeSeparators(absFilePath).utf16()),
+ // CFSTR(QDir::toNativeSeparators(symlinkTarget).utf16())) {
+ // return S_FALSE;
+ //}
#else
- QFileInfo symlinkPlaceHolderFileInfo(absFilePath);
- if (symlinkPlaceHolderFileInfo.isSymLink()) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not create symlink at '%1'. Another one is already existing.")
- .arg(absFilePath));
- return E_FAIL;
- }
- QFile symlinkPlaceHolderFile(absFilePath);
- if (!symlinkPlaceHolderFile.open(QIODevice::ReadOnly)) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not read symlink target from file '%1'.").arg(absFilePath));
- return E_FAIL;
- }
+ QFileInfo symlinkPlaceHolderFileInfo(absFilePath);
+ if (symlinkPlaceHolderFileInfo.isSymLink()) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot create symlink at \"%1\". Another one is already existing.")
+ .arg(absFilePath));
+ return E_FAIL;
+ }
+ QFile symlinkPlaceHolderFile(absFilePath);
+ if (!symlinkPlaceHolderFile.open(QIODevice::ReadOnly)) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot read symlink target from file \"%1\".").arg(absFilePath));
+ return E_FAIL;
+ }
- const QByteArray symlinkTarget = symlinkPlaceHolderFile.readAll();
- symlinkPlaceHolderFile.close();
- symlinkPlaceHolderFile.remove();
- QFile targetFile(QString::fromLatin1(symlinkTarget));
- if (!targetFile.link(absFilePath)) {
- Lib7z::setLastError(QCoreApplication::translate("ExtractCallbackImpl",
- "Could not create symlink at %1. %2").arg(absFilePath,
- targetFile.errorString()));
- return E_FAIL;
- }
- return S_OK;
+ const QByteArray symlinkTarget = symlinkPlaceHolderFile.readAll();
+ symlinkPlaceHolderFile.close();
+ symlinkPlaceHolderFile.remove();
+ QFile targetFile(QString::fromLatin1(symlinkTarget));
+ if (!targetFile.link(absFilePath)) {
+ setLastError(QCoreApplication::translate("ExtractCallbackImpl",
+ "Cannot create symlink at %1: %2").arg(absFilePath,
+ targetFile.errorString()));
+ return E_FAIL;
+ }
+ return S_OK;
#endif
- }
+ }
- try {
- if (!absFilePath.isEmpty()) {
- // This might fail for archives without all properties, we can only be sure about
- // modification time, as it's always stored by default in 7z archives. Also note that
- // we restore modification time on Unix only, as access time and change time are
- // supposed to be set to the time of installation.
- FILETIME mTime;
- if (getFileTimeFromProperty(arc->Archive, currentIndex, kpidMTime, &mTime)) {
- NWindows::NFile::NIO::COutFile file;
- if (file.Open(QString2UString(absFilePath), 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL))
- file.SetTime(&mTime, &mTime, &mTime);
- }
+ try { // Note: This part might also fail while running a elevated installation.
+ if (!absFilePath.isEmpty()) {
+ // This might fail for archives without all properties, we can only be sure
+ // about modification time, as it's always stored by default in 7z archives.
+ // Also note that we restore modification time on Unix only, as access time
+ // and change time are supposed to be set to the time of installation.
+ FILETIME mTime;
+ const UString fileName = QString2UString(absFilePath);
+ if (getFileTimeFromProperty(arc->Archive, currentIndex, kpidMTime, &mTime)) {
+ NWindows::NFile::NIO::COutFile file;
+ if (file.Open(fileName, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL))
+ file.SetTime(&mTime, &mTime, &mTime);
+ }
#ifdef Q_OS_WIN
- FILETIME cTime, aTime;
- bool success = getFileTimeFromProperty(arc->Archive, currentIndex, kpidCTime, &cTime);
- if (success && getFileTimeFromProperty(arc->Archive, currentIndex, kpidATime, &aTime)) {
- NWindows::NFile::NIO::COutFile file;
- if (file.Open(QString2UString(absFilePath), 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL))
- file.SetTime(&cTime, &aTime, &mTime);
- }
+ FILETIME cTime, aTime;
+ if (getFileTimeFromProperty(arc->Archive, currentIndex, kpidCTime, &cTime)
+ && getFileTimeFromProperty(arc->Archive, currentIndex, kpidATime, &aTime)) {
+ NWindows::NFile::NIO::COutFile file;
+ if (file.Open(fileName, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL))
+ file.SetTime(&cTime, &aTime, &mTime);
+ }
#endif
- }
- } catch (...) {}
-
- if (hasPerm)
- QFile::setPermissions(absFilePath, permissions);
}
+ } catch (...) {}
- return S_OK;
- }
-
- /* reimp */ STDMETHOD(SetTotal)(UInt64 t)
- {
- total = t;
- return S_OK;
- }
-
- /* reimp */ STDMETHOD(SetCompleted)(const UInt64* c)
- {
- completed = *c;
- if (total > 0)
- return q->setCompleted(completed, total);
- return S_OK;
- }
-
- void setArchive(const CArc* archive)
- {
- arc = archive;
- }
-
-private:
- ExtractCallback* const q;
- UInt32 currentIndex;
- const CArc* arc;
- UInt64 total;
- UInt64 completed;
- QPointer<QIODevice> device;
- QString targetDir;
-};
+ bool hasPerm = false;
+ const QFile::Permissions permissions = getPermissions(arc->Archive, currentIndex, &hasPerm);
+ if (hasPerm)
+ QFile::setPermissions(absFilePath, permissions);
+ return S_OK;
+}
+/*!
+ \fn bool ExtractCallback::prepareForFile(const QString &filename)
-class Lib7z::ExtractCallbackPrivate
-{
-public:
- explicit ExtractCallbackPrivate(ExtractCallback* qq)
- {
- impl = new ExtractCallbackImpl(qq);
- }
+ Implement to prepare for file \a filename to be extracted, e.g. by renaming existing files.
+ Return \c true if the preparation was successful and extraction can be continued. If \c false
+ is returned, the extraction will be aborted. The default implementation returns \c true.
+*/
- CMyComPtr<ExtractCallbackImpl> impl;
-};
-ExtractCallback::ExtractCallback()
- : d(new ExtractCallbackPrivate(this))
-{
-}
+// -- UpdateCallback
-ExtractCallback::~ExtractCallback()
+HRESULT UpdateCallback::SetTotal(UInt64)
{
- delete d;
+ return S_OK;
}
-ExtractCallbackImpl* ExtractCallback::impl()
+HRESULT UpdateCallback::SetCompleted(const UInt64*)
{
- return d->impl;
+ return S_OK;
}
-const ExtractCallbackImpl* ExtractCallback::impl() const
+HRESULT UpdateCallback::SetRatioInfo(const UInt64*, const UInt64*)
{
- return d->impl;
+ return S_OK;
}
-void ExtractCallback::setTarget(QFileDevice* dev)
+HRESULT UpdateCallback::CheckBreak()
{
- d->impl->setTarget(dev);
+ return S_OK;
}
-void ExtractCallback::setTarget(const QString &dir)
+HRESULT UpdateCallback::Finilize()
{
- d->impl->setTarget(dir);
+ return S_OK;
}
-HRESULT ExtractCallback::setCompleted(quint64, quint64)
+HRESULT UpdateCallback::SetNumFiles(UInt64)
{
return S_OK;
}
-void ExtractCallback::setCurrentFile(const QString&)
+HRESULT UpdateCallback::GetStream(const wchar_t*, bool)
{
+ return S_OK;
}
-bool ExtractCallback::prepareForFile(const QString&)
+HRESULT UpdateCallback::OpenFileError(const wchar_t*, DWORD)
{
- return true;
+ return S_OK;
}
-class Lib7z::ExtractCallbackJobImpl : public ExtractCallback
-{
-public:
- explicit ExtractCallbackJobImpl(ExtractItemJob* j)
- : ExtractCallback()
- , job(j)
- {}
-
-private:
- /* reimp */ HRESULT setCompleted(quint64 c, quint64 t)
- {
- emit job->progress(c, t);
- return S_OK;
- }
-
- ExtractItemJob* const job;
-};
-
-class Lib7z::UpdateCallbackImpl : public IUpdateCallbackUI2, public CMyUnknownImp
-{
-public:
- MY_UNKNOWN_IMP
- UpdateCallbackImpl()
- {
- }
- virtual ~UpdateCallbackImpl()
- {
- }
- /**
- * \reimp
- */
- HRESULT SetTotal(UInt64)
- {
- return S_OK;
- }
- /**
- * \reimp
- */
- HRESULT SetCompleted(const UInt64*)
- {
- return S_OK;
- }
- HRESULT SetRatioInfo(const UInt64*, const UInt64*)
- {
- return S_OK;
- }
- HRESULT CheckBreak()
- {
- return S_OK;
- }
- HRESULT Finilize()
- {
- return S_OK;
- }
- HRESULT SetNumFiles(UInt64)
- {
- return S_OK;
- }
- HRESULT GetStream(const wchar_t*, bool)
- {
- return S_OK;
- }
- HRESULT OpenFileError(const wchar_t*, DWORD)
- {
- return S_OK;
- }
- HRESULT CryptoGetTextPassword2(Int32* passwordIsDefined, OLECHAR** password)
- {
- *password = 0;
- *passwordIsDefined = false;
- return S_OK;
- }
- HRESULT CryptoGetTextPassword(OLECHAR**)
- {
- return E_NOTIMPL;
- }
- HRESULT OpenResult(const wchar_t*, LONG)
- {
- return S_OK;
- }
- HRESULT StartScanning()
- {
- return S_OK;
- }
- HRESULT ScanProgress(UInt64, UInt64, const wchar_t*)
- {
- return S_OK;
- }
- HRESULT CanNotFindError(const wchar_t*, DWORD)
- {
- return S_OK;
- }
- HRESULT FinishScanning()
- {
- return S_OK;
- }
- HRESULT StartArchive(const wchar_t*, bool)
- {
- return S_OK;
- }
- HRESULT FinishArchive()
- {
- return S_OK;
- }
-
- /**
- * \reimp
- */
- HRESULT SetOperationResult(Int32)
- {
- // TODO!
- return S_OK;
- }
- void setSourcePaths(const QStringList &paths)
- {
- sourcePaths = paths;
- }
- void setTarget(QIODevice* archive)
- {
- target = archive;
- }
-
-private:
- QIODevice* target;
- QStringList sourcePaths;
-};
-
-class Lib7z::UpdateCallbackPrivate
-{
-public:
- UpdateCallbackPrivate()
- {
- m_impl = new UpdateCallbackImpl;
- }
-
- UpdateCallbackImpl* impl()
- {
- return m_impl;
- }
-
-private:
- CMyComPtr< UpdateCallbackImpl > m_impl;
-};
-
-UpdateCallback::UpdateCallback()
- : d(new UpdateCallbackPrivate)
+HRESULT UpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
{
+ *password = 0;
+ *passwordIsDefined = false;
+ return S_OK;
}
-UpdateCallback::~UpdateCallback()
+HRESULT UpdateCallback::CryptoGetTextPassword(BSTR *password)
{
- delete d;
+ *password = 0;
+ return E_NOTIMPL;
}
-UpdateCallbackImpl* UpdateCallback::impl()
+HRESULT UpdateCallback::OpenResult(const wchar_t*, HRESULT, const wchar_t*)
{
- return d->impl();
+ return S_OK;
}
-void UpdateCallback::setSourcePaths(const QStringList &paths)
+HRESULT UpdateCallback::StartScanning()
{
- d->impl()->setSourcePaths(paths);
+ return S_OK;
}
-void UpdateCallback::setTarget(QFileDevice* target)
+HRESULT UpdateCallback::ScanProgress(UInt64, UInt64, UInt64, const wchar_t*, bool)
{
- d->impl()->setTarget(target);
+ return S_OK;
}
-class ExtractItemJob::Private
-{
-public:
- Private(ExtractItemJob* qq)
- : q(qq)
- , target(0)
- , callback(new ExtractCallbackJobImpl(q))
- {
- }
-
- ExtractItemJob* q;
- File item;
- QPointer<QFileDevice> archive;
- QString targetDirectory;
- QFileDevice* target;
- ExtractCallback* callback;
-};
-
-ExtractItemJob::ExtractItemJob(QObject* parent)
- : Job(parent)
- , d(new Private(this))
+HRESULT UpdateCallback::CanNotFindError(const wchar_t*, DWORD)
{
+ return S_OK;
}
-ExtractItemJob::~ExtractItemJob()
+HRESULT UpdateCallback::FinishScanning()
{
- delete d;
+ return S_OK;
}
-File ExtractItemJob::item() const
+HRESULT UpdateCallback::StartArchive(const wchar_t*, bool)
{
- return d->item;
+ return S_OK;
}
-void ExtractItemJob::setItem(const File& item)
+HRESULT UpdateCallback::FinishArchive()
{
- d->item = item;
+ return S_OK;
}
-QFileDevice* ExtractItemJob::archive() const
+HRESULT UpdateCallback::SetOperationResult(Int32)
{
- return d->archive;
+ return S_OK;
}
-void ExtractItemJob::setArchive(QFileDevice* archive)
+/*!
+ Function to create an empty 7z container. Using a temporary file only is not working, since
+ 7z checks the output file for a valid signature, otherwise it rejects overwriting the file.
+*/
+static QString createTmp7z()
{
- d->archive = archive;
-}
+ QTemporaryFile file;
+ if (!file.open()) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot create "
+ "temporary file: %1").arg(file.errorString()));
+ }
-QString ExtractItemJob::targetDirectory() const
-{
- return d->targetDirectory;
+ file.write(QByteArray::fromHex("377A.BCAF.271C" // Signature.
+ ".0003.8D9B.D50F.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000" // Crc + Data.
+ ));
+ file.setAutoRemove(false);
+ return file.fileName();
}
-void ExtractItemJob::setTargetDirectory(const QString &dir)
-{
- d->targetDirectory = dir;
- d->target = 0;
-}
+/*!
+ Creates an archive using the given file device \a archive. \a sourcePaths can contain one or
+ more files, one or more directories or a combination of files and folders. The \c * wildcard
+ is supported also. The value of \a level specifies the compression ratio, the default is set
+ to \c 5 (Normal compression). The \a callback can be used to get information about the archive
+ creation process. If no \a callback is given, an empty implementation is used.
-void ExtractItemJob::setTarget(QFileDevice* dev)
+ \note Throws SevenZipException on error.
+ \note Filenames are stored case-sensitive with UTF-8 encoding.
+ \note The ownership of \a callback is transferred to the function and gets delete on exit.
+*/
+void INSTALLER_EXPORT createArchive(QFileDevice *archive, const QStringList &sources,
+ Compression level, UpdateCallback *callback)
{
- d->target = dev;
-}
+ LIB7Z_ASSERTS(archive, Writable)
-namespace{
- QString errorMessageFrom7zResult(const LONG & extractResult)
- {
- if (!Lib7z::lastError().isEmpty())
- return Lib7z::lastError();
-
- QString errorMessage = QCoreApplication::translate("Lib7z", "internal code: %1");
- switch (extractResult) {
- case S_OK:
- qFatal("S_OK value is not a valid error code.");
- break;
- case E_NOTIMPL:
- errorMessage = errorMessage.arg(QLatin1String("E_NOTIMPL"));
- break;
- case E_NOINTERFACE:
- errorMessage = errorMessage.arg(QLatin1String("E_NOINTERFACE"));
- break;
- case E_ABORT:
- errorMessage = errorMessage.arg(QLatin1String("E_ABORT"));
- break;
- case E_FAIL:
- errorMessage = errorMessage.arg(QLatin1String("E_FAIL"));
- break;
- case STG_E_INVALIDFUNCTION:
- errorMessage = errorMessage.arg(QLatin1String("STG_E_INVALIDFUNCTION"));
- break;
- case E_OUTOFMEMORY:
- errorMessage = QCoreApplication::translate("Lib7z", "not enough memory");
- break;
- case E_INVALIDARG:
- errorMessage = errorMessage.arg(QLatin1String("E_INVALIDARG"));
- break;
- default:
- errorMessage = QCoreApplication::translate("Lib7z", "Error: %1").arg(extractResult);
- break;
- }
- return errorMessage;
- }
-}
+ const QString tmpArchive = createTmp7z();
+ Lib7z::createArchive(tmpArchive, sources, QTmpFile::No, level, callback);
-void Lib7z::createArchive(QFileDevice* archive, const QStringList &sourcePaths, UpdateCallback* callback)
+ try {
+ QFile source(tmpArchive);
+ QInstaller::openForRead(&source);
+ QInstaller::blockingCopy(&source, archive, source.size());
+ } catch (const QInstaller::Error &error) {
+ throw SevenZipException(error.message());
+ }
+}
+
+/*!
+ Creates an archive with the given filename \a archive. \a sourcePaths can contain one or more
+ files, one or more directories or a combination of files and folders. Also the \c * wildcard
+ is supported. To be able to use the function during an elevated installation, set \a mode to
+ \c QTmpFile::Yes. The value of \a level specifies the compression ratio, the default is set
+ to \c 5 (Normal compression). The \a callback can be used to get information about the archive
+ creation process. If no \a callback is given, an empty implementation is used.
+
+ \note Throws SevenZipException on error.
+ \note If \a archive exists, it will be overwritten.
+ \note Filenames are stored case-sensitive with UTF-8 encoding.
+ \note The ownership of \a callback is transferred to the function and gets delete on exit.
+*/
+void createArchive(const QString &archive, const QStringList &sources, QTmpFile mode,
+ Compression level, UpdateCallback *callback)
{
- assert(archive);
-
- QScopedPointer<UpdateCallback> dummyCallback(callback ? 0 : new UpdateCallback);
- if (!callback)
- callback = dummyCallback.data();
-
try {
- callback->setTarget(archive);
-
- QScopedPointer<CCodecs> codecs(new CCodecs);
- if (codecs->Load() != S_OK)
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Could not load codecs"));
-
- CIntVector formatIndices;
-
- if (!codecs.data()->FindFormatForArchiveType(L"", formatIndices)) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve default format"));
- }
-
- // yes this is crap, but there seems to be no streaming solution to this...
-
- const QString tempFile = generateTempFileName();
-
- NWildcard::CCensor censor;
- foreach (const QString &path, sourcePaths) {
- const QString cleanPath = QDir::toNativeSeparators(QDir::cleanPath(path));
- const UString nativePath = QString2UString(cleanPath);
- if (UString2QString(nativePath) != cleanPath) {
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Could not convert"
- "path: %1.").arg(path));
- }
- censor.AddItem(true /* always include item */, nativePath, false /* never recurse*/);
+ QString target = archive;
+ if (mode == QTmpFile::Yes)
+ target = createTmp7z();
+
+ CArcCmdLineOptions options;
+ try {
+ UStringVector commandStrings;
+ commandStrings.Add(L"a"); // mode: add
+ commandStrings.Add(L"-t7z"); // type: 7z
+ commandStrings.Add(L"-mtm=on"); // time: modeifier|creation|access
+ commandStrings.Add(L"-mtc=on");
+ commandStrings.Add(L"-mta=on");
+ commandStrings.Add(L"-mmt=on"); // threads: multi-threaded
+#ifdef Q_OS_WIN
+ commandStrings.Add(L"-sccUTF-8"); // files: case-sensitive|UTF8
+#endif
+ commandStrings.Add(QString2UString(QString::fromLatin1("-mx=%1").arg(int(level)))); // compression: level
+ commandStrings.Add(QString2UString(QDir::toNativeSeparators(target)));
+ foreach (const QString &source, sources)
+ commandStrings.Add(QString2UString(source));
+
+ CArcCmdLineParser parser;
+ parser.Parse1(commandStrings, options);
+ parser.Parse2(options);
+ } catch (const CArcCmdLineException &e) {
+ throw SevenZipException(UString2QString(e));
}
- callback->setSourcePaths(sourcePaths);
-
- CArchivePath archivePath;
- archivePath.ParseFromPath(QString2UString(tempFile));
- CUpdateArchiveCommand command;
- command.ArchivePath = archivePath;
- command.ActionSet = NUpdateArchive::kAddActionSet;
+ CCodecs codecs;
+ if (codecs.Load() != S_OK)
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot load codecs."));
- CUpdateOptions options;
- options.Commands.Add(command);
- options.ArchivePath = archivePath;
- options.MethodMode.FormatIndex = codecs->FindFormatForArchiveType(L"7z");
-
- // preserve creation time
- CProperty tc;
- tc.Name = UString(L"TC");
- tc.Value = UString(L"ON");
- options.MethodMode.Properties.Add(tc);
-
- // preserve access time
- CProperty ta;
- ta.Name = UString(L"TA");
- ta.Value = UString(L"ON");
- options.MethodMode.Properties.Add(ta);
+ CObjectVector<COpenType> types;
+ if (!ParseOpenTypes(codecs, options.ArcType, types))
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Unsupported archive type."));
CUpdateErrorInfo errorInfo;
- const HRESULT res = UpdateArchive(codecs.data(), censor, options, errorInfo, 0, callback->impl());
- if (res != S_OK || !QFile::exists(tempFile)) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not create archive %1. %2").arg(tempFile, errorMessageFrom7zResult(res)));
+ CMyComPtr<UpdateCallback> comCallback = callback == 0 ? new UpdateCallback : callback;
+ const HRESULT res = UpdateArchive(&codecs, types, options.ArchiveName, options.Censor,
+ options.UpdateOptions, errorInfo, nullptr, comCallback, true);
+
+ const QFile tempFile(UString2QString(options.ArchiveName));
+ if (res != S_OK || !tempFile.exists()) {
+ QString errorMsg;
+ if (res == S_OK) {
+ errorMsg = QCoreApplication::translate("Lib7z", "Cannot create archive \"%1\"")
+ .arg(QDir::toNativeSeparators(tempFile.fileName()));
+ } else {
+ errorMsg = QCoreApplication::translate("Lib7z", "Cannot create archive \"%1\": %2")
+ .arg(QDir::toNativeSeparators(tempFile.fileName()), errorMessageFrom7zResult(res));
+ }
+ throw SevenZipException(errorMsg);
}
- {
- //TODO remove temp file even if one the following throws
- QFile file(tempFile);
- QInstaller::openForRead(&file);
- QInstaller::blockingCopy(&file, archive, file.size());
- }
+ if (mode == QTmpFile::Yes) {
+ QFile org(archive);
+ if (org.exists() && !org.remove()) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot remove "
+ "old archive \"%1\": %2").arg(QDir::toNativeSeparators(org.fileName()),
+ org.errorString()));
+ }
- QFile file(tempFile);
- if (!file.remove()) {
- qWarning("%s: Could not remove temporary file %s: %s", Q_FUNC_INFO, qPrintable(tempFile),
- qPrintable(file.errorString()));
+ QFile arc(UString2QString(options.ArchiveName));
+ if(!arc.rename(archive)) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot rename "
+ "temporary archive \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(arc.fileName()),
+ QDir::toNativeSeparators(archive),
+ arc.errorString()));
+ }
}
} catch (const char *err) {
- qDebug() << err;
throw SevenZipException(err);
+ } catch (SevenZipException &e) {
+ throw e; // re-throw unmodified
} catch (const QInstaller::Error &err) {
throw SevenZipException(err.message());
} catch (...) {
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Unknown exception caught (%1)")
- .arg(QString::fromLatin1(Q_FUNC_INFO)));
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Unknown exception caught (%1)").arg(QString::fromLatin1(Q_FUNC_INFO)));
}
}
-void Lib7z::extractFileFromArchive(QFileDevice* archive, const File& item, QFileDevice* target,
- ExtractCallback* callback)
+/*!
+ Extracts the given \a archive content into target directory \a directory using the provided
+ extract callback \a callback. The output filenames are deduced from the \a archive content.
+
+ \note Throws SevenZipException on error.
+ \note The ownership of \a callback is not transferred to the function.
+*/
+void extractArchive(QFileDevice *archive, const QString &directory, ExtractCallback *callback)
{
- assert(archive);
- assert(target);
+ LIB7Z_ASSERTS(archive, Readable)
- std::auto_ptr<ExtractCallback> dummyCallback(callback ? 0 : new ExtractCallback);
- if (!callback)
- callback = dummyCallback.get();
+ // Guard a given object against unwanted delete.
+ CMyComPtr<ExtractCallback> externCallback = callback;
+
+ CMyComPtr<ExtractCallback> localCallback;
+ if (!externCallback) {
+ callback = new ExtractCallback;
+ localCallback = callback;
+ }
+ DirectoryGuard outDir(QFileInfo(directory).absolutePath());
try {
- const OpenArchiveInfo* const openArchive = OpenArchiveInfo::value(archive);
+ outDir.tryCreate();
- const int arcIdx = item.archiveIndex.x();
- if (arcIdx < 0 || arcIdx >= openArchive->archiveLink.Arcs.Size()) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "CArc index %1 out of bounds [0, %2]").arg(openArchive->archiveLink.Arcs.Size() - 1));
- }
- const CArc& arc = openArchive->archiveLink.Arcs[arcIdx];
- IInArchive* const parchive = arc.Archive;
+ CCodecs codecs;
+ if (codecs.Load() != S_OK)
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot load codecs."));
- const UInt32 itemIdx = item.archiveIndex.y();
- UInt32 numItems = 0;
- if (parchive->GetNumberOfItems(&numItems) != S_OK) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve number of items in archive"));
- }
+ COpenOptions op;
+ op.codecs = &codecs;
- if (itemIdx >= numItems) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Item index %1 out of bounds [0, %2]").arg(itemIdx).arg(numItems - 1));
- }
+ CObjectVector<COpenType> types;
+ op.types = &types; // Empty, because we use a stream.
- UString s;
- if (arc.GetItemPath(itemIdx, s) != S_OK) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve path of archive item %1").arg(itemIdx));
- }
- assert(item.path == UString2QString(s).replace(QLatin1Char('\\'), QLatin1Char('/')));
+ CIntVector excluded;
+ op.excludedFormats = &excluded;
- callback->setTarget(target);
- const LONG extractResult = parchive->Extract(&itemIdx, 1, /*testmode=*/0, callback->impl());
+ const CMyComPtr<IInStream> stream = new QIODeviceInStream(archive);
+ op.stream = stream; // CMyComPtr is needed, otherwise it crashes in OpenStream().
- if (extractResult != S_OK)
- throw SevenZipException(errorMessageFrom7zResult(extractResult));
+ CObjectVector<CProperty> properties;
+ op.props = &properties;
- } catch (const char *err) {
- throw SevenZipException(err);
- } catch (const Lib7z::SevenZipException& e) {
- throw e;
- } catch (...) {
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Unknown exception caught (%1)")
- .arg(QString::fromLatin1(Q_FUNC_INFO)));
- }
-}
-
-void Lib7z::extractFileFromArchive(QFileDevice* archive, const File& item,
- const QString &targetDirectory, ExtractCallback* callback)
-{
- assert(archive);
+ CArchiveLink archiveLink;
+ if (archiveLink.Open2(op, nullptr) != S_OK) {
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Cannot open archive \"%1\".").arg(archive->fileName()));
+ }
- QScopedPointer<ExtractCallback> dummyCallback(callback ? 0 : new ExtractCallback);
- if (!callback)
- callback = dummyCallback.data();
+ callback->setTarget(directory);
+ for (unsigned a = 0; a < archiveLink.Arcs.Size(); ++a) {
+ callback->setArchive(&archiveLink.Arcs[a]);
+ IInArchive *const arch = archiveLink.Arcs[a].Archive;
- QFileInfo fi(targetDirectory + QLatin1String("/") + item.path);
- DirectoryGuard outDir(fi.absolutePath());
- outDir.tryCreate();
- QFile out(fi.absoluteFilePath());
- if (!out.open(QIODevice::WriteOnly)) { //TODO use tmp file
+ const LONG result = arch->Extract(0, static_cast<UInt32>(-1), false, callback);
+ if (result != S_OK)
+ throw SevenZipException(errorMessageFrom7zResult(result));
+ }
+ } catch (const SevenZipException &e) {
+ externCallback.Detach();
+ throw e; // re-throw unmodified
+ } catch (...) {
+ externCallback.Detach();
throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not create output file for writing: %1").arg(fi.absoluteFilePath()));
+ "Unknown exception caught (%1).").arg(QString::fromLatin1(Q_FUNC_INFO)));
}
- callback->setTarget(&out);
- extractFileFromArchive(archive, item, &out, callback);
- if (item.permissions)
- out.setPermissions(item.permissions);
outDir.release();
+ externCallback.Detach();
}
-void Lib7z::extractArchive(QFileDevice* archive, const QString &targetDirectory,
- ExtractCallback* callback)
-{
- assert(archive);
-
- QScopedPointer<ExtractCallback> dummyCallback(callback ? 0 : new ExtractCallback);
- if (!callback)
- callback = dummyCallback.data();
-
- callback->setTarget(targetDirectory);
-
- const QFileInfo fi(targetDirectory);
- DirectoryGuard outDir(fi.absolutePath());
- outDir.tryCreate();
-
- const OpenArchiveInfo* const openArchive = OpenArchiveInfo::value(archive);
-
- for (int a = 0; a < openArchive->archiveLink.Arcs.Size(); ++a)
- {
- const CArc& arc = openArchive->archiveLink.Arcs[a];
- IInArchive* const arch = arc.Archive;
- callback->impl()->setArchive(&arc);
- const LONG extractResult = arch->Extract(0, static_cast< UInt32 >(-1), false, callback->impl());
-
- if (extractResult != S_OK)
- throw SevenZipException(errorMessageFrom7zResult(extractResult));
- }
-
- outDir.release();
-}
+/*!
+ Returns \c true if the given \a archive is supported; otherwise returns \c false.
-bool Lib7z::isSupportedArchive(const QString &archive)
+ \note Throws SevenZipException on error.
+*/
+bool isSupportedArchive(QFileDevice *archive)
{
- QFile file(archive);
- if (!file.open(QIODevice::ReadOnly))
- return false;
+ LIB7Z_ASSERTS(archive, Readable)
- return isSupportedArchive(&file);
-}
-
-bool Lib7z::isSupportedArchive(QFileDevice* archive)
-{
- assert(archive);
- assert(!archive->isSequential());
const qint64 initialPos = archive->pos();
try {
- QScopedPointer<CCodecs> codecs(new CCodecs);
- if (codecs->Load() != S_OK)
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Could not load codecs"));
+ CCodecs codecs;
+ if (codecs.Load() != S_OK)
+ throw SevenZipException(QCoreApplication::translate("Lib7z", "Cannot load codecs."));
- CIntVector formatIndices;
+ COpenOptions op;
+ op.codecs = &codecs;
+
+ CObjectVector<COpenType> types;
+ op.types = &types; // Empty, because we use a stream.
+
+ CIntVector excluded;
+ op.excludedFormats = &excluded;
- if (!codecs->FindFormatForArchiveType(L"", formatIndices)) {
- throw SevenZipException(QCoreApplication::translate("Lib7z",
- "Could not retrieve default format"));
- }
- CArchiveLink archiveLink;
- //CMyComPtr is needed, otherwise it crashes in OpenStream()
const CMyComPtr<IInStream> stream = new QIODeviceInStream(archive);
+ op.stream = stream; // CMyComPtr is needed, otherwise it crashes in OpenStream().
+
+ CObjectVector<CProperty> properties;
+ op.props = &properties;
- const HRESULT result = archiveLink.Open2(codecs.data(), formatIndices, /*stdInMode*/false, stream,
- UString(), 0);
+ CArchiveLink archiveLink;
+ const HRESULT result = archiveLink.Open2(op, nullptr);
archive->seek(initialPos);
return result == S_OK;
- } catch (const SevenZipException& e) {
- archive->seek(initialPos);
- throw e;
} catch (const char *err) {
archive->seek(initialPos);
throw SevenZipException(err);
+ } catch (const SevenZipException &e) {
+ archive->seek(initialPos);
+ throw e; // re-throw unmodified
} catch (...) {
archive->seek(initialPos);
- throw SevenZipException(QCoreApplication::translate("Lib7z", "Unknown exception caught (%1)")
- .arg(QString::fromLatin1(Q_FUNC_INFO)));
+ throw SevenZipException(QCoreApplication::translate("Lib7z",
+ "Unknown exception caught (%1).").arg(QString::fromLatin1(Q_FUNC_INFO)));
}
return false; // never reached
}
-void ExtractItemJob::doStart()
+/*!
+ Returns \c true if the given \a archive is supported; otherwise returns \c false.
+
+ \note Throws SevenZipException on error.
+*/
+bool isSupportedArchive(const QString &archive)
{
- try {
- if (!d->archive)
- throw SevenZipException(tr("Could not list archive: QIODevice not set or already destroyed."));
- if (d->target)
- extractFileFromArchive(d->archive, d->item, d->target, d->callback);
- else if (!d->item.path.isEmpty())
- extractFileFromArchive(d->archive, d->item, d->targetDirectory, d->callback);
- else
- extractArchive(d->archive, d->targetDirectory, d->callback);
- } catch (const SevenZipException& e) {
- setError(Failed);
- setErrorString(tr("Error while extracting '%1': %2").arg(d->item.path, e.message()));
- } catch (...) {
- setError(Failed);
- setErrorString(tr("Unknown exception caught (%1)").arg(tr("Failed")));
- }
- emitResult();
+ QFile file(archive);
+ if (!file.open(QIODevice::ReadOnly))
+ return false;
+ return isSupportedArchive(&file);
}
+
+} // namespace Lib7z
diff --git a/src/libs/installer/lib7z_facade.h b/src/libs/installer/lib7z_facade.h
index 1af879614..44c5f6cac 100644
--- a/src/libs/installer/lib7z_facade.h
+++ b/src/libs/installer/lib7z_facade.h
@@ -34,253 +34,48 @@
#define LIB7Z_FACADE_H
#include "installer_global.h"
+#include "errors.h"
-#include <QCoreApplication>
-#include <QDateTime>
-#include <QFile>
-#include <QPoint>
-#include <QRunnable>
-#include <QString>
-#include <QVariant>
-#include <QVector>
-
-#include "Common/MyWindows.h"
-
-#include <stdexcept>
-#include <string>
+#include <Common/MyWindows.h>
+#include <7zip/UI/Console/PercentPrinter.h>
QT_BEGIN_NAMESPACE
-class QStringList;
-template <typename T> class QVector;
+class QFileDevice;
QT_END_NAMESPACE
-namespace Lib7z {
- class INSTALLER_EXPORT SevenZipException : public std::runtime_error {
- public:
- explicit SevenZipException( const QString& msg ) : std::runtime_error( msg.toStdString() ), m_message( msg ) {}
- explicit SevenZipException( const char* msg ) : std::runtime_error( msg ), m_message( QString::fromLocal8Bit( msg ) ) {}
- explicit SevenZipException( const std::string& msg ) : std::runtime_error( msg ), m_message( QString::fromLocal8Bit( msg.c_str() ) ) {}
-
- ~SevenZipException() throw() {}
- QString message() const { return m_message; }
- private:
- QString m_message;
- };
-
- class INSTALLER_EXPORT File {
- public:
- File();
- QVector<File> subtreeInPreorder() const;
-
- bool operator<( const File& other ) const;
- bool operator==( const File& other ) const;
-
- QFile::Permissions permissions;
- QString path;
- QDateTime mtime;
- quint64 uncompressedSize;
- quint64 compressedSize;
- bool isDirectory;
- QVector<File> children;
- QPoint archiveIndex;
- };
-
- class ExtractCallbackPrivate;
- class ExtractCallbackImpl;
-
- class ExtractCallback {
- friend class ::Lib7z::ExtractCallbackImpl;
- public:
- ExtractCallback();
- virtual ~ExtractCallback();
-
- void setTarget(QFileDevice* archive);
- void setTarget(const QString& dir );
-
- protected:
- /**
- * Reimplement to prepare for file @p filename to be extracted, e.g. by renaming existing files.
- * @return @p true if the preparation was successful and extraction can be continued.
- * If @p false is returned, the extraction will be aborted. Default implementation returns @p true.
- */
- virtual bool prepareForFile( const QString& filename );
- virtual void setCurrentFile( const QString& filename );
- virtual HRESULT setCompleted( quint64 completed, quint64 total );
+namespace Lib7z
+{
+ void INSTALLER_EXPORT initSevenZ();
+ bool INSTALLER_EXPORT isSupportedArchive(QFileDevice *archive);
+ bool INSTALLER_EXPORT isSupportedArchive(const QString &archive);
- public: //for internal use
- const ExtractCallbackImpl* impl() const;
- ExtractCallbackImpl* impl();
-
- private:
- ExtractCallbackPrivate* const d;
- };
-
- class UpdateCallbackPrivate;
- class UpdateCallbackImpl;
-
- class UpdateCallback
+ class INSTALLER_EXPORT SevenZipException : public QInstaller::Error
{
- friend class ::Lib7z::UpdateCallbackImpl;
public:
- UpdateCallback();
- virtual ~UpdateCallback();
-
- void setTarget(QFileDevice* archive);
- void setSourcePaths(const QStringList& paths);
-
- virtual UpdateCallbackImpl* impl();
-
- private:
- UpdateCallbackPrivate* const d;
- };
-
- class OpenArchiveInfoCleaner : public QObject {
- Q_OBJECT
- public:
- OpenArchiveInfoCleaner() {}
- private Q_SLOTS:
- void deviceDestroyed(QObject*);
- };
-
- /*!
- Extracts the given File \a file from \a archive into output device \a out using the
- provided extract callback \a callback.
-
- Throws Lib7z::SevenZipException on error.
- */
- void INSTALLER_EXPORT extractFileFromArchive(QFileDevice* archive, const File& item,
- QFileDevice* out, ExtractCallback* callback=0 );
-
- /*!
- Extracts the given File \a file from \a archive into target directory \a targetDirectory
- using the provided extract callback \a callback. The output filename is deduced from the
- \a file path name.
-
- Throws Lib7z::SevenZipException on error.
- */
- void INSTALLER_EXPORT extractFileFromArchive(QFileDevice* archive, const File& item,
- const QString& targetDirectory, ExtractCallback* callback = 0);
-
- /*!
- Extracts the given \a archive content into target directory \a targetDirectory using the
- provided extract callback \a callback. The output filenames are deduced from the \a archive
- content.
+ explicit SevenZipException(const QString &msg)
+ : QInstaller::Error(msg)
+ {}
- Throws Lib7z::SevenZipException on error.
- */
- void INSTALLER_EXPORT extractArchive(QFileDevice* archive, const QString& targetDirectory,
- ExtractCallback* callback = 0);
-
- /*
- * @thows Lib7z::SevenZipException
- */
- void INSTALLER_EXPORT createArchive(QFileDevice* archive, const QStringList& sourcePaths,
- UpdateCallback* callback = 0 );
-
- /*
- * @throws Lib7z::SevenZipException
- */
- QVector<File> INSTALLER_EXPORT listArchive(QFileDevice* archive);
-
- /*
- * @throws Lib7z::SevenZipException
- */
- bool INSTALLER_EXPORT isSupportedArchive(QFileDevice* archive);
-
- /*
- * @throws Lib7z::SevenZipException
- */
- bool INSTALLER_EXPORT isSupportedArchive(const QString& archive);
-
- enum Error {
- NoError=0,
- Failed=1,
- UserDefinedError=128
+ explicit SevenZipException(const char *msg)
+ : QInstaller::Error(QString::fromLocal8Bit(msg))
+ {}
};
- class ExtractCallbackJobImpl;
-
- class INSTALLER_EXPORT Job : public QObject, public QRunnable
+ class INSTALLER_EXPORT PercentPrinter : public CPercentPrinter
{
- friend class ::Lib7z::ExtractCallbackJobImpl;
- Q_OBJECT
- public:
-
- explicit Job( QObject* parent=0 );
- ~Job();
- void start();
- int error() const;
- bool hasError() const;
- QString errorString() const;
-
- /* reimp */ void run();
-
- protected:
- void emitResult();
- void setError( int code );
- void setErrorString( const QString& err );
- void emitProgress( qint64 completed, qint64 total );
-
- Q_SIGNALS:
- void finished( Lib7z::Job* job );
- void progress( qint64 completed, qint64 total );
-
- private Q_SLOTS:
- virtual void doStart() = 0;
-
- private:
- class Private;
- Private* const d;
- };
-
- class INSTALLER_EXPORT ListArchiveJob : public Job {
- Q_OBJECT
public:
-
- explicit ListArchiveJob( QObject* parent=0 );
- ~ListArchiveJob();
-
- QFileDevice* archive() const;
- void setArchive(QFileDevice* archive);
-
- QVector<File> index() const;
-
- private:
- /* reimp */ void doStart();
-
- private:
- class Private;
- Private* const d;
- };
-
- class INSTALLER_EXPORT ExtractItemJob : public Job {
- Q_OBJECT
- friend class ::Lib7z::ExtractCallback;
- public:
-
- explicit ExtractItemJob( QObject* parent=0 );
- ~ExtractItemJob();
-
- File item() const;
- void setItem( const File& item );
-
- QFileDevice* archive() const;
- void setArchive(QFileDevice* archive);
-
- QString targetDirectory() const;
- void setTargetDirectory( const QString& dir );
-
- void setTarget(QFileDevice* dev);
-
- private:
- /* reimp */ void doStart();
-
- private:
- class Private;
- Private* const d;
+ PercentPrinter() : CPercentPrinter(1 << 16) {
+ OutStream = &g_StdOut;
+ }
+
+ void PrintRatio() { CPercentPrinter::PrintRatio(); }
+ void ClosePrint() { CPercentPrinter::ClosePrint(); }
+ void RePrintRatio() { CPercentPrinter::RePrintRatio(); }
+ void PrintNewLine() { CPercentPrinter::PrintNewLine(); }
+ void PrintString(const char *s) { CPercentPrinter::PrintString(s); }
+ void PrintString(const wchar_t *s) { CPercentPrinter::PrintString(s); }
};
- QByteArray INSTALLER_EXPORT formatKeyValuePairs( const QVariantList& l );
-}
+} // namespace Lib7z
#endif // LIB7Z_FACADE_H
diff --git a/src/libs/installer/lib7z_guid.h b/src/libs/installer/lib7z_guid.h
new file mode 100644
index 000000000..16434558c
--- /dev/null
+++ b/src/libs/installer/lib7z_guid.h
@@ -0,0 +1,97 @@
+/**************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see http://qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+#ifndef LIB7Z_GUID_H
+#define LIB7Z_GUID_H
+
+#include <Common/MyInitGuid.h>
+
+#ifdef __cplusplus
+#define DEFINE_7Z_GUID(name, b4, b5, b6) extern "C" const GUID IID_ ## name = { 0x23170F69, \
+ 0x40C1, 0x278A, { 0x00, 0x00, 0x00, b4, b5, b6, 0x00, 0x00 } }
+#else
+#define DEFINE_7Z_GUID(name, b4, b5, b6) extern const GUID IID_ ## name = { 0x23170F69, \
+ 0x40C1, 0x278A, { 0x00, 0x00, 0x00, b4, b5, b6, 0x00, 0x00 } }
+#endif
+
+DEFINE_7Z_GUID(IInArchiveGetStream, 0x06, 0x00, 0x40);
+DEFINE_7Z_GUID(IInArchive, 0x06, 0x00, 0x60);
+
+DEFINE_7Z_GUID(IOutStream, 0x03, 0x00, 0x04);
+DEFINE_7Z_GUID(IOutStreamFlush, 0x03, 0x00, 0x07);
+DEFINE_7Z_GUID(IOutArchive, 0x06, 0x00, 0xA0);
+
+DEFINE_7Z_GUID(IInStream, 0x03, 0x00, 0x03);
+
+DEFINE_7Z_GUID(ISetProperties, 0x06, 0x00, 0x03);
+
+DEFINE_7Z_GUID(ISequentialInStream, 0x03, 0x00, 0x01);
+DEFINE_7Z_GUID(ISequentialOutStream, 0x03, 0x00, 0x02);
+
+DEFINE_7Z_GUID(IStreamGetSize, 0x03, 0x00, 0x06);
+DEFINE_7Z_GUID(IStreamGetProps, 0x03, 0x00, 0x08);
+DEFINE_7Z_GUID(IStreamGetProps2, 0x03, 0x00, 0x09);
+
+DEFINE_7Z_GUID(IArchiveKeepModeForNextOpen, 0x06, 0x00, 0x04);
+DEFINE_7Z_GUID(IArchiveAllowTail, 0x06, 0x00, 0x05);
+DEFINE_7Z_GUID(IArchiveOpenCallback, 0x06, 0x00, 0x10);
+DEFINE_7Z_GUID(IArchiveExtractCallback, 0x06, 0x00, 0x20);
+DEFINE_7Z_GUID(IArchiveOpenVolumeCallback, 0x06, 0x00, 0x30);
+DEFINE_7Z_GUID(IArchiveOpenSetSubArchiveName, 0x06, 0x00, 0x50);
+DEFINE_7Z_GUID(IArchiveOpenSeq, 0x06, 0x00, 0x61);
+DEFINE_7Z_GUID(IArchiveGetRawProps, 0x06, 0x00, 0x70);
+DEFINE_7Z_GUID(IArchiveGetRootProps, 0x06, 0x00, 0x71);
+DEFINE_7Z_GUID(IArchiveUpdateCallback, 0x06, 0x00, 0x80);
+DEFINE_7Z_GUID(IArchiveUpdateCallback2, 0x06, 0x00, 0x82);
+
+DEFINE_7Z_GUID(ICompressProgressInfo, 0x04, 0x00, 0x04);
+DEFINE_7Z_GUID(ICompressCoder, 0x04, 0x00, 0x05);
+DEFINE_7Z_GUID(ICompressSetCoderProperties, 0x04, 0x00, 0x20);
+DEFINE_7Z_GUID(ICompressSetDecoderProperties2, 0x04, 0x00, 0x22);
+DEFINE_7Z_GUID(ICompressWriteCoderProperties, 0x04, 0x00, 0x23);
+DEFINE_7Z_GUID(ICompressGetInStreamProcessedSize, 0x04, 0x00, 0x24);
+DEFINE_7Z_GUID(ICompressSetCoderMt, 0x04, 0x00, 0x25);
+DEFINE_7Z_GUID(ICompressSetOutStream, 0x04, 0x00, 0x32);
+DEFINE_7Z_GUID(ICompressSetInStream, 0x04, 0x00, 0x31);
+DEFINE_7Z_GUID(ICompressSetOutStreamSize, 0x04, 0x00, 0x34);
+DEFINE_7Z_GUID(ICompressSetBufSize, 0x04, 0x00, 0x35);
+DEFINE_7Z_GUID(ICompressGetSubStreamSize, 0x04, 0x00, 0x30);
+DEFINE_7Z_GUID(ICryptoResetInitVector, 0x04, 0x00, 0x8C);
+DEFINE_7Z_GUID(ICryptoSetPassword, 0x04, 0x00, 0x90);
+
+DEFINE_7Z_GUID(ICryptoGetTextPassword, 0x05, 0x00, 0x10);
+DEFINE_7Z_GUID(ICryptoGetTextPassword2, 0x05, 0x00, 0x11);
+
+#undef DEFINE_7Z_GUID
+
+#endif // LIB7Z_GUID_H
diff --git a/src/libs/installer/lib7z_list.h b/src/libs/installer/lib7z_list.h
new file mode 100644
index 000000000..6e2646025
--- /dev/null
+++ b/src/libs/installer/lib7z_list.h
@@ -0,0 +1,62 @@
+/**************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see http://qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+#ifndef LIB7Z_LIST_H
+#define LIB7Z_LIST_H
+
+#include "installer_global.h"
+
+#include <QDateTime>
+#include <QFile>
+#include <QPoint>
+
+namespace Lib7z
+{
+ struct INSTALLER_EXPORT File
+ {
+ public:
+ QString path;
+ QDateTime utcTime;
+ QPoint archiveIndex;
+ bool isDirectory = false;
+ quint64 compressedSize = 0;
+ quint64 uncompressedSize = 0;
+ QFile::Permissions permissions = 0;
+ };
+ INSTALLER_EXPORT bool operator==(const File &lhs, const File &rhs);
+
+ QVector<File> INSTALLER_EXPORT listArchive(QFileDevice *archive);
+
+} // namespace Lib7z
+
+#endif // LIB7Z_LIST_H
diff --git a/src/libs/installer/licenseoperation.cpp b/src/libs/installer/licenseoperation.cpp
index 2faf8d4a7..0f4797ac0 100644
--- a/src/libs/installer/licenseoperation.cpp
+++ b/src/libs/installer/licenseoperation.cpp
@@ -42,7 +42,8 @@
using namespace QInstaller;
-LicenseOperation::LicenseOperation()
+LicenseOperation::LicenseOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("License"));
}
@@ -60,26 +61,25 @@ bool LicenseOperation::performOperation()
return false;
}
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
if (!core) {
setError( UserDefinedError );
setErrorString(tr("Needed installer object in %1 operation is empty.").arg(name()));
return false;
}
- QString targetDir = QString::fromLatin1("%1/%2").arg(core->value(scTargetDir),
- QLatin1String("Licenses"));
+ QString targetDir = QString::fromLatin1("%1%2%3").arg(core->value(scTargetDir),
+ QDir::separator(), QLatin1String("Licenses"));
QDir dir;
dir.mkpath(targetDir);
setArguments(QStringList(targetDir));
- for (QVariantMap::const_iterator it = licenses.begin(); it != licenses.end(); ++it) {
- QFile file(targetDir + QDir::separator() + it.key());
+ for (QVariantMap::const_iterator it = licenses.constBegin(); it != licenses.constEnd(); ++it) {
+ QFile file(targetDir + QLatin1Char('/') + it.key());
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
setError(UserDefinedError);
- setErrorString(tr("Can not write license file: %1.").arg(targetDir + QDir::separator()
- + it.key()));
+ setErrorString(tr("Can not write license file \"%1\".").arg(QDir::toNativeSeparators(file.fileName())));
return false;
}
@@ -92,7 +92,7 @@ bool LicenseOperation::performOperation()
bool LicenseOperation::undoOperation()
{
- QVariantMap licenses = value(QLatin1String("licenses")).toMap();
+ const QVariantMap licenses = value(QLatin1String("licenses")).toMap();
if (licenses.isEmpty()) {
setError(UserDefinedError);
setErrorString(tr("No license files found to delete."));
@@ -113,8 +113,3 @@ bool LicenseOperation::testOperation()
{
return true;
}
-
-Operation *LicenseOperation::clone() const
-{
- return new LicenseOperation();
-}
diff --git a/src/libs/installer/licenseoperation.h b/src/libs/installer/licenseoperation.h
index 4cb75590b..88d7857a1 100644
--- a/src/libs/installer/licenseoperation.h
+++ b/src/libs/installer/licenseoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT LicenseOperation : public Operation
{
public:
- LicenseOperation();
+ explicit LicenseOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation* clone() const;
};
} // namespace QInstaller
diff --git a/src/libs/installer/linereplaceoperation.cpp b/src/libs/installer/linereplaceoperation.cpp
index 670ebbd63..1a3d2c670 100644
--- a/src/libs/installer/linereplaceoperation.cpp
+++ b/src/libs/installer/linereplaceoperation.cpp
@@ -39,7 +39,8 @@
using namespace QInstaller;
-LineReplaceOperation::LineReplaceOperation()
+LineReplaceOperation::LineReplaceOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("LineReplace"));
}
@@ -50,18 +51,14 @@ void LineReplaceOperation::backup()
bool LineReplaceOperation::performOperation()
{
- const QStringList args = arguments();
-
// Arguments:
// 1. filename
// 2. startsWith Search-String
// 3. Replace-Line-String
- if (args.count() != 3) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 3"), QLatin1String("")));
+ if (!checkArgumentCount(3))
return false;
- }
+
+ const QStringList args = arguments();
const QString fileName = args.at(0);
const QString searchString = args.at(1);
const QString replaceString = args.at(2);
@@ -69,7 +66,8 @@ bool LineReplaceOperation::performOperation()
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to open '%1' for reading.").arg(fileName));
+ setErrorString(tr("Cannot open file \"%1\" for reading: %2").arg(
+ QDir::toNativeSeparators(fileName), file.errorString()));
return false;
}
@@ -86,7 +84,8 @@ bool LineReplaceOperation::performOperation()
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to open '%1' for writing.").arg(fileName));
+ setErrorString(tr("Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(fileName), file.errorString()));
return false;
}
@@ -106,8 +105,3 @@ bool LineReplaceOperation::testOperation()
{
return true;
}
-
-Operation *LineReplaceOperation::clone() const
-{
- return new LineReplaceOperation();
-}
diff --git a/src/libs/installer/linereplaceoperation.h b/src/libs/installer/linereplaceoperation.h
index b28cf661c..c80325ade 100644
--- a/src/libs/installer/linereplaceoperation.h
+++ b/src/libs/installer/linereplaceoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT LineReplaceOperation : public Operation
{
public:
- LineReplaceOperation();
+ explicit LineReplaceOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
} // namespace
diff --git a/src/libs/installer/link.cpp b/src/libs/installer/link.cpp
index a8c640a50..ead52e513 100644
--- a/src/libs/installer/link.cpp
+++ b/src/libs/installer/link.cpp
@@ -93,8 +93,7 @@ public:
OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0);
if (m_dirHandle == INVALID_HANDLE_VALUE) {
- qWarning() << QString::fromLatin1("Could not open: '%1'; error: %2\n").arg(path)
- .arg(QInstaller::windowsErrorString(GetLastError()));
+ qWarning() << "Cannot open" << path << ":" << QInstaller::windowsErrorString(GetLastError());
}
}
@@ -143,14 +142,12 @@ QString readWindowsSymLink(const QString &path)
Link createJunction(const QString &linkPath, const QString &targetPath)
{
if (!QDir().mkpath(linkPath)) {
- qWarning() << QString::fromLatin1("Could not create the mount directory: %1").arg(
- linkPath);
+ qWarning() << "Cannot create the mount directory" << linkPath;
return Link(linkPath);
}
FileHandleWrapper dirHandle(linkPath);
if (dirHandle.handle() == INVALID_HANDLE_VALUE) {
- qWarning() << QString::fromLatin1("Could not open: '%1'; error: %2\n").arg(linkPath)
- .arg(QInstaller::windowsErrorString(GetLastError()));
+ qWarning() << "Cannot open" << linkPath << ":" << QInstaller::windowsErrorString(GetLastError());
return Link(linkPath);
}
@@ -180,8 +177,8 @@ Link createJunction(const QString &linkPath, const QString &targetPath)
if (!::DeviceIoControl(dirHandle.handle(), FSCTL_SET_REPARSE_POINT, reparseStructData,
reparseStructData->ReparseDataLength + REPARSE_DATA_BUFFER_HEADER_SIZE, 0, 0,
&bytesReturned, 0)) {
- qWarning() << QString::fromLatin1("Could not set the reparse point: for '%1' to %2; error: %3"
- ).arg(linkPath, targetPath).arg(QInstaller::windowsErrorString(GetLastError()));
+ qWarning() << "Cannot set the reparse point for" << linkPath << "to" << targetPath
+ << ":" << QInstaller::windowsErrorString(GetLastError());
}
return Link(linkPath);
}
@@ -202,8 +199,7 @@ bool removeJunction(const QString &path)
REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, 0, 0,
&bytesReturned, 0)) {
- qWarning() << QString::fromLatin1("Could not remove the reparse point: '%1'; error: %3"
- ).arg(path).arg(QInstaller::windowsErrorString(GetLastError()));
+ qWarning() << "Cannot remove the reparse point" << path << ":" << QInstaller::windowsErrorString(GetLastError());
return false;
}
}
@@ -216,8 +212,7 @@ Link createLnSymlink(const QString &linkPath, const QString &targetPath)
int linkedError = symlink(QFileInfo(targetPath).absoluteFilePath().toUtf8(),
QFileInfo(linkPath).absoluteFilePath().toUtf8());
if (linkedError != 0) {
- qWarning() << QString::fromLatin1("Could not create a symlink: from '%1' to %2; error: %3"
- ).arg(linkPath, targetPath).arg(linkedError);
+ qWarning() << "Cannot create a symlink from" << linkPath << "to" << targetPath << ":" << linkedError;
}
@@ -244,8 +239,7 @@ Link Link::create(const QString &link, const QString &targetPath)
if (!linkPathExists)
linkPathExists = QDir().mkpath(linkPath);
if (!linkPathExists) {
- qWarning() << QString::fromLatin1("Could not create the needed directories: %1").arg(
- link);
+ qWarning() << "Cannot create the needed directories" << link;
return Link(link);
}
@@ -253,8 +247,8 @@ Link Link::create(const QString &link, const QString &targetPath)
if (QFileInfo(targetPath).isDir())
return createJunction(link, targetPath);
- qWarning() << QString::fromLatin1("At the moment the %1 can not create anything else as "\
- "junctions for directories under windows").arg(QLatin1String(Q_FUNC_INFO));
+ qWarning() << "At the moment the" << Q_FUNC_INFO << "can not create anything else as "
+ << "junctions for directories under windows";
return Link(link);
#else
return createLnSymlink(link, targetPath);
diff --git a/src/libs/installer/messageboxhandler.cpp b/src/libs/installer/messageboxhandler.cpp
index 0c61424b5..66ccc23e0 100644
--- a/src/libs/installer/messageboxhandler.cpp
+++ b/src/libs/installer/messageboxhandler.cpp
@@ -406,8 +406,8 @@ QMessageBox::StandardButton MessageBoxHandler::showMessageBox(MessageType messag
messageTypeHash.insert(warningType, QLatin1String("warning"));
};
- qDebug() << QString::fromLatin1("created %1 message box %2: '%3', %4").arg(messageTypeHash
- .value(messageType),identifier, title, text);
+ qDebug().nospace() << "Created " << messageTypeHash.value(messageType).toUtf8().constData()
+ << " message box " << identifier << ": " << title << ", " << text;
if (qobject_cast<QApplication*> (qApp) == 0)
return defaultButton;
diff --git a/src/libs/installer/metadatajob.cpp b/src/libs/installer/metadatajob.cpp
index 77a04104c..5186df409 100644
--- a/src/libs/installer/metadatajob.cpp
+++ b/src/libs/installer/metadatajob.cpp
@@ -45,13 +45,13 @@
namespace QInstaller {
MetadataJob::MetadataJob(QObject *parent)
- : KDJob(parent)
+ : Job(parent)
, m_core(0)
{
setCapabilities(Cancelable);
- connect(&m_xmlTask, SIGNAL(finished()), this, SLOT(xmlTaskFinished()));
- connect(&m_metadataTask, SIGNAL(finished()), this, SLOT(metadataTaskFinished()));
- connect(&m_metadataTask, SIGNAL(progressValueChanged(int)), this, SLOT(progressChanged(int)));
+ connect(&m_xmlTask, &QFutureWatcherBase::finished, this, &MetadataJob::xmlTaskFinished);
+ connect(&m_metadataTask, &QFutureWatcherBase::finished, this, &MetadataJob::metadataTaskFinished);
+ connect(&m_metadataTask, &QFutureWatcherBase::progressValueChanged, this, &MetadataJob::progressChanged);
}
MetadataJob::~MetadataJob()
@@ -71,13 +71,13 @@ void MetadataJob::doStart()
{
reset();
if (!m_core) {
- emitFinishedWithError(KDJob::Canceled, tr("Missing package manager core engine."));
+ emitFinishedWithError(Job::Canceled, tr("Missing package manager core engine."));
return; // We can't do anything here without core, so avoid tons of !m_core checks.
}
emit infoMessage(this, tr("Preparing meta information download..."));
const bool onlineInstaller = m_core->isInstaller() && !m_core->isOfflineOnly();
- if (onlineInstaller || (m_core->isUpdater() || m_core->isPackageManager())) {
+ if (onlineInstaller || m_core->isMaintainer()) {
QList<FileTaskItem> items;
const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance();
foreach (const Repository &repo, m_core->settings().repositories()) {
@@ -87,8 +87,8 @@ void MetadataJob::doStart()
authenticator.setPassword(repo.password());
QString url = repo.url().toString() + QLatin1String("/Updates.xml?");
- if (!m_core->value(QLatin1String("UrlQueryString")).isEmpty())
- url += m_core->value(QLatin1String("UrlQueryString")) + QLatin1Char('&');
+ if (!m_core->value(scUrlQueryString).isEmpty())
+ url += m_core->value(scUrlQueryString) + QLatin1Char('&');
// also append a random string to avoid proxy caches
FileTaskItem item(url.append(QString::number(qrand() * qrand())));
@@ -108,7 +108,7 @@ void MetadataJob::doStart()
void MetadataJob::doCancel()
{
reset();
- emitFinishedWithError(KDJob::Canceled, tr("Meta data download canceled."));
+ emitFinishedWithError(Job::Canceled, tr("Meta data download canceled."));
}
void MetadataJob::xmlTaskFinished()
@@ -121,7 +121,7 @@ void MetadataJob::xmlTaskFinished()
if (e.type() == AuthenticationRequiredException::Type::Proxy) {
const QNetworkProxy proxy = e.proxy();
ProxyCredentialsDialog proxyCredentials(proxy);
- qDebug() << e.message();
+ qDebug().noquote() << e.message();
if (proxyCredentials.exec() == QDialog::Accepted) {
qDebug() << "Retrying with new credentials ...";
@@ -136,7 +136,7 @@ void MetadataJob::xmlTaskFinished()
emitFinishedWithError(QInstaller::DownloadError, tr("Missing proxy credentials."));
}
} else if (e.type() == AuthenticationRequiredException::Type::Server) {
- qDebug() << e.message();
+ qDebug().noquote() << e.message();
ServerAuthenticationDialog dlg(e.message(), e.taskItem());
if (dlg.exec() == QDialog::Accepted) {
Repository original = e.taskItem().value(TaskRole::UserRole)
@@ -157,7 +157,7 @@ void MetadataJob::xmlTaskFinished()
if (s.updateDefaultRepositories(update) == Settings::UpdatesApplied
|| s.updateUserRepositories(update) == Settings::UpdatesApplied) {
- if (m_core->isUpdater() || m_core->isPackageManager())
+ if (m_core->isMaintainer())
m_core->writeMaintenanceConfigFiles();
}
}
@@ -178,7 +178,7 @@ void MetadataJob::xmlTaskFinished()
emitFinishedWithError(QInstaller::DownloadError, tr("Unknown exception during download."));
}
- if (error() != KDJob::NoError)
+ if (error() != Job::NoError)
return;
if (status == XmlDownloadSuccess) {
@@ -211,7 +211,7 @@ void MetadataJob::unzipTaskFinished()
emitFinishedWithError(QInstaller::DownloadError, tr("Unknown exception during extracting."));
}
- if (error() != KDJob::NoError)
+ if (error() != Job::NoError)
return;
delete m_unzipTasks.value(watcher);
@@ -243,7 +243,7 @@ void MetadataJob::metadataTaskFinished()
QFutureWatcher<void> *watcher = new QFutureWatcher<void>();
m_unzipTasks.insert(watcher, qobject_cast<QObject*> (task));
- connect(watcher, SIGNAL(finished()), this, SLOT(unzipTaskFinished()));
+ connect(watcher, &QFutureWatcherBase::finished, this, &MetadataJob::unzipTaskFinished);
watcher->setFuture(QtConcurrent::run(&UnzipArchiveTask::doTask, task));
}
} else {
@@ -269,7 +269,7 @@ void MetadataJob::reset()
m_packages.clear();
m_metadata.clear();
- setError(KDJob::NoError);
+ setError(Job::NoError);
setErrorString(QString());
setCapabilities(Cancelable);
@@ -290,13 +290,13 @@ void MetadataJob::reset()
MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &results)
{
foreach (const FileTaskResult &result, results) {
- if (error() != KDJob::NoError)
+ if (error() != Job::NoError)
return XmlDownloadFailure;
Metadata metadata;
QTemporaryDir tmp(QDir::tempPath() + QLatin1String("/remoterepo-XXXXXX"));
if (!tmp.isValid()) {
- qDebug() << "Could not create unique temporary directory.";
+ qDebug() << "Cannot create unique temporary directory.";
return XmlDownloadFailure;
}
@@ -306,20 +306,20 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
QFile file(result.target());
if (!file.rename(metadata.directory + QLatin1String("/Updates.xml"))) {
- qDebug() << "Could not rename target to Updates.xml. Error:" << file.errorString();
+ qDebug() << "Cannot rename target to Updates.xml:" << file.errorString();
return XmlDownloadFailure;
}
if (!file.open(QIODevice::ReadOnly)) {
- qDebug() << "Could not open Updates.xml for reading. Error:" << file.errorString();
+ qDebug() << "Cannot open Updates.xml for reading:" << file.errorString();
return XmlDownloadFailure;
}
QString error;
QDomDocument doc;
if (!doc.setContent(&file, &error)) {
- qDebug() << QString::fromLatin1("Could not fetch a valid version of Updates.xml from "
- "repository: %1. Error: %2").arg(metadata.repository.displayname(), error);
+ qDebug().nospace() << "Cannot fetch a valid version of Updates.xml from repository "
+ << metadata.repository.displayname() << ": " << error;
return XmlDownloadFailure;
}
file.close();
@@ -343,7 +343,7 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
for (int j = 0; j < c2.count(); ++j) {
if (c2.at(j).toElement().tagName() == scName)
packageName = c2.at(j).toElement().text();
- else if (c2.at(j).toElement().tagName() == scRemoteVersion)
+ else if (c2.at(j).toElement().tagName() == scVersion)
packageVersion = (online ? c2.at(j).toElement().text() : QString());
else if ((c2.at(j).toElement().tagName() == QLatin1String("SHA1")) && testCheckSum)
packageHash = c2.at(j).toElement().text();
@@ -404,12 +404,12 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
if (ProductKeyCheck::instance()->isValidRepository(newRepository)) {
// store the new repository and the one old it replaces
repositoryUpdates.insertMulti(action, qMakePair(newRepository, oldRepository));
- qDebug() << "Replace repository:" << oldRepository.displayname() << "with:"
+ qDebug() << "Replace repository" << oldRepository.displayname() << "with"
<< newRepository.displayname();
}
} else {
qDebug() << "Invalid additional repositories action set in Updates.xml fetched "
- "from:" << metadata.repository.displayname() << "Line:" << el.lineNumber();
+ "from" << metadata.repository.displayname() << "line:" << el.lineNumber();
}
}
}
@@ -437,7 +437,7 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
return XmlDownloadRetry;
}
} else if (s.updateDefaultRepositories(repositoryUpdates) == Settings::UpdatesApplied) {
- if (m_core->isUpdater() || m_core->isPackageManager())
+ if (m_core->isMaintainer())
m_core->writeMaintenanceConfigFiles();
QFile::remove(result.target());
return XmlDownloadRetry;
diff --git a/src/libs/installer/metadatajob.h b/src/libs/installer/metadatajob.h
index 4350d0182..10fffe172 100644
--- a/src/libs/installer/metadatajob.h
+++ b/src/libs/installer/metadatajob.h
@@ -36,7 +36,7 @@
#include "downloadfiletask.h"
#include "fileutils.h"
-#include "kdjob.h"
+#include "job.h"
#include "repository.h"
#include <QFutureWatcher>
@@ -51,7 +51,7 @@ struct Metadata
Repository repository;
};
-class INSTALLER_EXPORT MetadataJob : public KDJob
+class INSTALLER_EXPORT MetadataJob : public Job
{
Q_OBJECT
Q_DISABLE_COPY(MetadataJob)
diff --git a/src/libs/installer/metadatajob_p.h b/src/libs/installer/metadatajob_p.h
index 549571820..a07c7a80f 100644
--- a/src/libs/installer/metadatajob_p.h
+++ b/src/libs/installer/metadatajob_p.h
@@ -34,9 +34,13 @@
#ifndef METADATAJOB_P_H
#define METADATAJOB_P_H
+#include "lib7z_extract.h"
#include "lib7z_facade.h"
#include "metadatajob.h"
+#include <QDir>
+#include <QFile>
+
namespace QInstaller{
class UnzipArchiveException : public QException
@@ -82,14 +86,14 @@ public:
Lib7z::extractArchive(&archive, m_targetDir);
} catch (const Lib7z::SevenZipException& e) {
fi.reportException(UnzipArchiveException(MetadataJob::tr("Error while extracting "
- "'%1': %2").arg(m_archive, e.message())));
+ "archive \"%1\": %2").arg(QDir::toNativeSeparators(m_archive), e.message())));
} catch (...) {
fi.reportException(UnzipArchiveException(MetadataJob::tr("Unknown exception "
- "caught while extracting %1.").arg(m_archive)));
+ "caught while extracting archive \"%1\".").arg(QDir::toNativeSeparators(m_archive))));
}
} else {
- fi.reportException(UnzipArchiveException(MetadataJob::tr("Could not open %1 for "
- "reading. Error: %2").arg(m_archive, archive.errorString())));
+ fi.reportException(UnzipArchiveException(MetadataJob::tr("Cannot open file \"%1\" for "
+ "reading: %2").arg(QDir::toNativeSeparators(m_archive), archive.errorString())));
}
fi.reportFinished();
diff --git a/src/libs/installer/minimumprogressoperation.cpp b/src/libs/installer/minimumprogressoperation.cpp
index 2929135af..a5f1fc881 100644
--- a/src/libs/installer/minimumprogressoperation.cpp
+++ b/src/libs/installer/minimumprogressoperation.cpp
@@ -35,7 +35,8 @@
using namespace QInstaller;
-MinimumProgressOperation::MinimumProgressOperation()
+MinimumProgressOperation::MinimumProgressOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
// This shouldn't be callable by script, but we need a name for the binary format
setName(QLatin1String("MinimumProgress"));
@@ -61,9 +62,3 @@ bool MinimumProgressOperation::testOperation()
{
return true;
}
-
-Operation *MinimumProgressOperation::clone() const
-{
- return new MinimumProgressOperation();
-}
-
diff --git a/src/libs/installer/minimumprogressoperation.h b/src/libs/installer/minimumprogressoperation.h
index 796ac02aa..4b4e4def9 100644
--- a/src/libs/installer/minimumprogressoperation.h
+++ b/src/libs/installer/minimumprogressoperation.h
@@ -45,13 +45,12 @@ class MinimumProgressOperation : public QObject, public Operation
Q_OBJECT
public:
- MinimumProgressOperation();
+ explicit MinimumProgressOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
signals:
void progressChanged(double progress);
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 81fd29472..2b7ec4536 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -60,12 +60,14 @@
#include <QtCore/QMutex>
#include <QtCore/QSettings>
#include <QtCore/QTemporaryFile>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
#include <QDesktopServices>
#include <QFileDialog>
-#include "kdsysinfo.h"
-#include "kdupdaterupdateoperationfactory.h"
+#include "sysinfo.h"
+#include "updateoperationfactory.h"
#ifdef Q_OS_WIN
# include "qt_windows.h"
@@ -427,7 +429,7 @@ void PackageManagerCore::writeMaintenanceTool()
gainAdminRights();
gainedAdminRights = true;
}
- d->m_updaterApplication.packagesInfo()->writeToDisk();
+ d->m_localPackageHub->writeToDisk();
if (gainedAdminRights)
dropAdminRights();
d->m_needToWriteMaintenanceTool = false;
@@ -638,11 +640,11 @@ int PackageManagerCore::downloadNeededArchives(double partProgressSize)
DownloadArchivesJob archivesJob(this);
archivesJob.setAutoDelete(false);
archivesJob.setArchivesToDownload(archivesToDownload);
- connect(this, SIGNAL(installationInterrupted()), &archivesJob, SLOT(cancel()));
- connect(&archivesJob, SIGNAL(outputTextChanged(QString)), ProgressCoordinator::instance(),
- SLOT(emitLabelAndDetailTextChanged(QString)));
- connect(&archivesJob, SIGNAL(downloadStatusChanged(QString)), ProgressCoordinator::instance(),
- SIGNAL(downloadStatusChanged(QString)));
+ connect(this, &PackageManagerCore::installationInterrupted, &archivesJob, &Job::cancel);
+ connect(&archivesJob, &DownloadArchivesJob::outputTextChanged,
+ ProgressCoordinator::instance(), &ProgressCoordinator::emitLabelAndDetailTextChanged);
+ connect(&archivesJob, &DownloadArchivesJob::downloadStatusChanged,
+ ProgressCoordinator::instance(), &ProgressCoordinator::downloadStatusChanged);
ProgressCoordinator::instance()->registerPartProgress(&archivesJob,
SIGNAL(progressChanged(double)), partProgressSize);
@@ -650,13 +652,13 @@ int PackageManagerCore::downloadNeededArchives(double partProgressSize)
archivesJob.start();
archivesJob.waitForFinished();
- if (archivesJob.error() == KDJob::Canceled)
+ if (archivesJob.error() == Job::Canceled)
interrupt();
- else if (archivesJob.error() != KDJob::NoError)
+ else if (archivesJob.error() != Job::NoError)
throw Error(archivesJob.errorString());
if (d->statusCanceledOrFailed())
- throw Error(tr("Installation canceled by user"));
+ throw Error(tr("Installation canceled by user."));
ProgressCoordinator::instance()->emitDownloadStatus(tr("All downloads finished."));
@@ -705,7 +707,6 @@ void PackageManagerCore::rollBackInstallation()
}
}
- KDUpdater::PackagesInfo &packages = *d->m_updaterApplication.packagesInfo();
while (!d->m_performedOperationsCurrentSession.isEmpty()) {
try {
Operation *const operation = d->m_performedOperationsCurrentSession.takeLast();
@@ -732,14 +733,14 @@ void PackageManagerCore::rollBackInstallation()
component = d->componentsToReplace().value(componentName).second;
if (component) {
component->setUninstalled();
- packages.removePackage(component->name());
+ d->m_localPackageHub->removePackage(component->name());
}
}
- packages.writeToDisk();
+ d->m_localPackageHub->writeToDisk();
if (isInstaller()) {
- if (packages.packageInfoCount() == 0) {
- QFile file(packages.fileName());
+ if (d->m_localPackageHub->packageInfoCount() == 0) {
+ QFile file(d->m_localPackageHub->fileName());
file.remove();
}
}
@@ -749,7 +750,7 @@ void PackageManagerCore::rollBackInstallation()
} catch (const Error &e) {
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
QLatin1String("ElevationError"), tr("Authentication Error"), tr("Some components "
- "could not be removed completely because admin rights could not be acquired: %1.")
+ "could not be removed completely because administrative rights could not be acquired: %1.")
.arg(e.message()));
} catch (...) {
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(), QLatin1String("unknown"),
@@ -785,6 +786,32 @@ bool PackageManagerCore::fileExists(const QString &filePath) const
return QFileInfo(filePath).exists();
}
+/*!
+ Returns the contents of the file \a filePath using the encoding specified
+ by \a codecName. The file is read in the text mode, that is, end-of-line
+ terminators are translated to the local encoding.
+
+ \note If the file does not exist or an error occurs while reading the file, an
+ empty string is returned.
+
+ \sa {installer::readFile}{installer.readFile}
+
+ */
+QString PackageManagerCore::readFile(const QString &filePath, const QString &codecName) const
+{
+ QFile f(filePath);
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
+ return QString();
+
+ QTextCodec *codec = QTextCodec::codecForName(qPrintable(codecName));
+ if (!codec)
+ return QString();
+
+ QTextStream stream(&f);
+ stream.setCodec(codec);
+ return stream.readAll();
+}
+
// -- QInstaller
/*!
@@ -867,7 +894,7 @@ PackageManagerCore::~PackageManagerCore()
delete d;
RemoteClient::instance().setActive(false);
- RemoteClient::instance().shutdown();
+ RemoteClient::instance().destroy();
QMutexLocker _(globalVirtualComponentsFontMutex());
delete sVirtualComponentsFont;
@@ -966,7 +993,7 @@ bool PackageManagerCore::fetchLocalPackagesTree()
d->setStatus(Running);
if (!isPackageManager()) {
- d->setStatus(Failure, tr("Application not running in Package Manager mode!"));
+ d->setStatus(Failure, tr("Application not running in Package Manager mode."));
return false;
}
@@ -988,7 +1015,7 @@ bool PackageManagerCore::fetchLocalPackagesTree()
component->loadDataFromPackage(installedPackages.value(key));
const QString &name = component->name();
if (components.contains(name)) {
- qCritical("Could not register component! Component with identifier %s already registered.",
+ qCritical("Cannot register component! Component with identifier %s already registered.",
qPrintable(name));
continue;
}
@@ -1025,8 +1052,18 @@ void PackageManagerCore::networkSettingsChanged()
d->m_repoFetched = false;
d->m_updateSourcesAdded = false;
- if (d->isUpdater() || d->isPackageManager())
+ if (isMaintainer() ) {
+ bool gainedAdminRights = false;
+ QTemporaryFile tempAdminFile(d->targetDir() + QStringLiteral("/XXXXXX"));
+ if (!tempAdminFile.open() || !tempAdminFile.isWritable()) {
+ gainAdminRights();
+ gainedAdminRights = true;
+ }
d->writeMaintenanceConfigFiles();
+ if (gainedAdminRights)
+ dropAdminRights();
+ }
+
KDUpdater::FileDownloaderFactory::instance().setProxyFactory(proxyFactory());
emit coreNetworkSettingsChanged();
@@ -1074,7 +1111,7 @@ bool PackageManagerCore::fetchRemotePackagesTree()
d->setStatus(Running);
if (isUninstaller()) {
- d->setStatus(Failure, tr("Application running in Uninstaller mode!"));
+ d->setStatus(Failure, tr("Application running in Uninstaller mode."));
return false;
}
@@ -1110,7 +1147,7 @@ bool PackageManagerCore::fetchRemotePackagesTree()
}
const LocalPackage localPackage = installedPackages.value(name);
- const QString updateVersion = update->data(scRemoteVersion).toString();
+ const QString updateVersion = update->data(scVersion).toString();
if (KDUpdater::compareVersion(updateVersion, localPackage.version) <= 0)
break; // remote version equals or is less than the installed maintenance tool
@@ -1617,8 +1654,8 @@ ComponentModel *PackageManagerCore::defaultComponentModel() const
d->m_defaultModel = componentModel(const_cast<PackageManagerCore*> (this),
QLatin1String("AllComponentsModel"));
}
- connect(this, SIGNAL(finishAllComponentsReset(QList<QInstaller::Component*>)), d->m_defaultModel,
- SLOT(setRootComponents(QList<QInstaller::Component*>)));
+ connect(this, &PackageManagerCore::finishAllComponentsReset, d->m_defaultModel,
+ &ComponentModel::setRootComponents);
return d->m_defaultModel;
}
@@ -1632,8 +1669,8 @@ ComponentModel *PackageManagerCore::updaterComponentModel() const
d->m_updaterModel = componentModel(const_cast<PackageManagerCore*> (this),
QLatin1String("UpdaterComponentsModel"));
}
- connect(this, SIGNAL(finishUpdaterComponentsReset(QList<QInstaller::Component*>)), d->m_updaterModel,
- SLOT(setRootComponents(QList<QInstaller::Component*>)));
+ connect(this, &PackageManagerCore::finishUpdaterComponentsReset, d->m_updaterModel,
+ &ComponentModel::setRootComponents);
return d->m_updaterModel;
}
@@ -1701,20 +1738,21 @@ bool PackageManagerCore::killProcess(const QString &absoluteFilePath) const
processPath = QDir::cleanPath(processPath.replace(QLatin1Char('\\'), QLatin1Char('/')));
if (processPath == normalizedPath) {
- qDebug() << QString::fromLatin1("try to kill process: %1(%2)").arg(process.name).arg(process.id);
+ qDebug().nospace() << "try to kill process " << process.name << " (" << process.id << ")";
//to keep the ui responsible use QtConcurrent::run
QFutureWatcher<bool> futureWatcher;
const QFuture<bool> future = QtConcurrent::run(KDUpdater::killProcess, process, 30000);
QEventLoop loop;
- loop.connect(&futureWatcher, SIGNAL(finished()), SLOT(quit()), Qt::QueuedConnection);
+ connect(&futureWatcher, &QFutureWatcher<bool>::finished,
+ &loop, &QEventLoop::quit, Qt::QueuedConnection);
futureWatcher.setFuture(future);
if (!future.isFinished())
loop.exec();
- qDebug() << QString::fromLatin1("\"%1\" killed!").arg(process.name);
+ qDebug() << process.name << "killed!";
return future.result();
}
}
@@ -1865,14 +1903,7 @@ QString PackageManagerCore::environmentVariable(const QString &name) const
*/
bool PackageManagerCore::operationExists(const QString &name)
{
- static QSet<QString> existingOperations;
- if (existingOperations.contains(name))
- return true;
- QScopedPointer<Operation> op(KDUpdater::UpdateOperationFactory::instance().create(name));
- if (!op.data())
- return false;
- existingOperations.insert(name);
- return true;
+ return KDUpdater::UpdateOperationFactory::instance().containsProduct(name);
}
/*!
@@ -1884,7 +1915,7 @@ bool PackageManagerCore::operationExists(const QString &name)
*/
bool PackageManagerCore::performOperation(const QString &name, const QStringList &arguments)
{
- QScopedPointer<Operation> op(KDUpdater::UpdateOperationFactory::instance().create(name));
+ QScopedPointer<Operation> op(KDUpdater::UpdateOperationFactory::instance().create(name, this));
if (!op.data())
return false;
@@ -2261,6 +2292,14 @@ bool PackageManagerCore::isPackageManager() const
}
/*!
+ Returns \c true if it is a package manager or an updater.
+*/
+bool PackageManagerCore::isMaintainer() const
+{
+ return isPackageManager() || isUpdater();
+}
+
+/*!
Runs the installer. Returns \c true on success, \c false otherwise.
\sa {installer::runInstaller}{installer.runInstaller}
@@ -2309,7 +2348,7 @@ bool PackageManagerCore::run()
return d->runInstaller();
else if (isUninstaller())
return d->runUninstaller();
- else if (isPackageManager() || isUpdater())
+ else if (isMaintainer())
return d->runPackageUpdater();
return false;
}
@@ -2328,7 +2367,7 @@ bool PackageManagerCore::updateComponentData(struct Data &data, Component *compo
// check if we already added the component to the available components list
const QString name = data.package->data(scName).toString();
if (data.components->contains(name)) {
- qCritical("Could not register component! Component with identifier %s already registered.",
+ qCritical("Cannot register component! Component with identifier %s already registered.",
qPrintable(name));
return false;
}
@@ -2529,7 +2568,7 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
continue; // Update for not installed package found, skip it.
const LocalPackage &localPackage = locals.value(name);
- const QString updateVersion = update->data(scRemoteVersion).toString();
+ const QString updateVersion = update->data(scVersion).toString();
if (KDUpdater::compareVersion(updateVersion, localPackage.version) <= 0)
continue;
@@ -2650,7 +2689,7 @@ void PackageManagerCore::updateDisplayVersions(const QString &displayKey)
}
visited.clear();
const QString displayVersionRemote = findDisplayVersion(key, componentsHash,
- scRemoteVersion, visited);
+ scVersion, visited);
if (displayVersionRemote.isEmpty())
componentsHash.value(key)->setValue(displayKey, tr("invalid"));
else
@@ -2698,3 +2737,13 @@ ComponentModel *PackageManagerCore::componentModel(PackageManagerCore *core, con
return model;
}
+
+QStringList PackageManagerCore::filesForDelayedDeletion() const
+{
+ return d->m_filesForDelayedDeletion;
+}
+
+void PackageManagerCore::addFilesForDelayedDeletion(const QStringList &files)
+{
+ d->m_filesForDelayedDeletion.append(files);
+}
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index c9fe6e102..f00f33e72 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -189,6 +189,7 @@ public:
Q_INVOKABLE bool isFileExtensionRegistered(const QString &extension) const;
Q_INVOKABLE bool fileExists(const QString &filePath) const;
+ Q_INVOKABLE QString readFile(const QString &filePath, const QString &codecName) const;
public:
ScriptEngine *componentScriptEngine() const;
@@ -229,6 +230,8 @@ public:
Q_INVOKABLE void setPackageManager();
Q_INVOKABLE bool isPackageManager() const;
+ bool isMaintainer() const;
+
bool isVerbose() const;
void setVerbose(bool on);
@@ -259,6 +262,9 @@ public:
void setNeedsHardRestart(bool needsHardRestart = true);
bool finishedWithSuccess() const;
+ QStringList filesForDelayedDeletion() const;
+ void addFilesForDelayedDeletion(const QStringList &files);
+
public Q_SLOTS:
bool runInstaller();
bool runUninstaller();
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 18f72e03d..642d7f5ae 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -54,13 +54,13 @@
#include "componentchecker.h"
#include "globals.h"
-#include "kdselfrestarter.h"
-#include "kdupdaterfiledownloaderfactory.h"
-#include "kdupdaterupdatesourcesinfo.h"
-#include "kdupdaterupdateoperationfactory.h"
+#include "selfrestarter.h"
+#include "filedownloaderfactory.h"
+#include "updateoperationfactory.h"
#include <productkeycheck.h>
+#include <QSettings>
#include <QtConcurrentRun>
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
@@ -97,9 +97,9 @@ public:
{
if (!m_operation)
return;
- qDebug() << QString::fromLatin1("%1 %2 operation: %3").arg(state, m_operation->value(
+ qDebug().noquote() << QString::fromLatin1("%1 %2 operation: %3").arg(state, m_operation->value(
QLatin1String("component")).toString(), m_operation->name());
- qDebug() << QString::fromLatin1("\t- arguments: %1").arg(m_operation->arguments()
+ qDebug().noquote() << QString::fromLatin1("\t- arguments: %1").arg(m_operation->arguments()
.join(QLatin1String(", ")));
}
~OperationTracer() {
@@ -176,7 +176,7 @@ static void deferredRename(const QString &oldName, const QString &newName, bool
#else
QFile::remove(newName);
QFile::rename(oldName, newName);
- KDSelfRestarter::setRestartOnQuit(restart);
+ SelfRestarter::setRestartOnQuit(restart);
#endif
}
@@ -185,7 +185,7 @@ static void deferredRename(const QString &oldName, const QString &newName, bool
PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core)
: m_updateFinder(0)
- , m_updaterApplication(new DummyConfigurationInterface)
+ , m_localPackageHub(std::make_shared<LocalPackageHub>())
, m_core(core)
, m_updates(false)
, m_repoFetched(false)
@@ -206,7 +206,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core)
PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, qint64 magicInstallerMaker,
const QList<OperationBlob> &performedOperations)
: m_updateFinder(0)
- , m_updaterApplication(new DummyConfigurationInterface)
+ , m_localPackageHub(std::make_shared<LocalPackageHub>())
, m_status(PackageManagerCore::Unfinished)
, m_needsHardRestart(false)
, m_testChecksum(false)
@@ -232,24 +232,27 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, q
{
foreach (const OperationBlob &operation, performedOperations) {
QScopedPointer<QInstaller::Operation> op(KDUpdater::UpdateOperationFactory::instance()
- .create(operation.name));
+ .create(operation.name, core));
if (op.isNull()) {
- qWarning() << QString::fromLatin1("Failed to load unknown operation %1")
- .arg(operation.name);
+ qWarning() << "Failed to load unknown operation" << operation.name;
continue;
}
if (!op->fromXml(operation.xml)) {
- qWarning() << "Failed to load XML for operation:" << operation.name;
+ qWarning() << "Failed to load XML for operation" << operation.name;
continue;
}
m_performedOperationsOld.append(op.take());
}
- connect(this, SIGNAL(installationStarted()), m_core, SIGNAL(installationStarted()));
- connect(this, SIGNAL(installationFinished()), m_core, SIGNAL(installationFinished()));
- connect(this, SIGNAL(uninstallationStarted()), m_core, SIGNAL(uninstallationStarted()));
- connect(this, SIGNAL(uninstallationFinished()), m_core, SIGNAL(uninstallationFinished()));
+ connect(this, &PackageManagerCorePrivate::installationStarted,
+ m_core, &PackageManagerCore::installationStarted);
+ connect(this, &PackageManagerCorePrivate::installationFinished,
+ m_core, &PackageManagerCore::installationFinished);
+ connect(this, &PackageManagerCorePrivate::uninstallationStarted,
+ m_core, &PackageManagerCore::uninstallationStarted);
+ connect(this, &PackageManagerCorePrivate::uninstallationFinished,
+ m_core, &PackageManagerCore::uninstallationFinished);
}
PackageManagerCorePrivate::~PackageManagerCorePrivate()
@@ -311,7 +314,8 @@ bool PackageManagerCorePrivate::performOperationThreaded(Operation *operation, O
const QFuture<bool> future = QtConcurrent::run(runOperation, operation, type);
QEventLoop loop;
- loop.connect(&futureWatcher, SIGNAL(finished()), SLOT(quit()), Qt::QueuedConnection);
+ QObject::connect(&futureWatcher, &decltype(futureWatcher)::finished, &loop, &QEventLoop::quit,
+ Qt::QueuedConnection);
futureWatcher.setFuture(future);
if (!future.isFinished())
@@ -343,7 +347,7 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
return false;
// append all components to their respective parents
QHash<QString, Component*>::const_iterator it;
- for (it = components.begin(); it != components.end(); ++it) {
+ for (it = components.constBegin(); it != components.constEnd(); ++it) {
QString id = it.key();
QInstaller::Component *component = it.value();
while (!id.isEmpty() && component->parentComponent() == 0) {
@@ -395,7 +399,7 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
foreach (QInstaller::Component *component, components) {
const QStringList warnings = ComponentChecker::checkComponent(component);
foreach (const QString &warning, warnings)
- qCWarning(lcComponentChecker) << warning;
+ qCWarning(lcComponentChecker).noquote() << warning;
}
} catch (const Error &error) {
clearAllComponentLists();
@@ -413,7 +417,7 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
void PackageManagerCorePrivate::cleanUpComponentEnvironment()
{
// clean up registered (downloaded) data
- if (m_core->isUpdater() || m_core->isPackageManager())
+ if (m_core->isMaintainer())
BinaryFormatEngineHandler::instance()->clear();
// there could be still some references to already deleted components,
@@ -548,45 +552,37 @@ void PackageManagerCorePrivate::initialize(const QHash<QString, QString> &params
readMaintenanceConfigFiles(QCoreApplication::applicationDirPath());
#endif
}
+ processFilesForDelayedDeletion();
+ m_data.setDynamicPredefinedVariables();
+
+ disconnect(this, &PackageManagerCorePrivate::installationStarted,
+ ProgressCoordinator::instance(), &ProgressCoordinator::reset);
+ connect(this, &PackageManagerCorePrivate::installationStarted,
+ ProgressCoordinator::instance(), &ProgressCoordinator::reset);
+ disconnect(this, &PackageManagerCorePrivate::uninstallationStarted,
+ ProgressCoordinator::instance(), &ProgressCoordinator::reset);
+ connect(this, &PackageManagerCorePrivate::uninstallationStarted,
+ ProgressCoordinator::instance(), &ProgressCoordinator::reset);
- foreach (Operation *currentOperation, m_performedOperationsOld)
- currentOperation->setValue(QLatin1String("installer"), QVariant::fromValue(m_core));
-
- disconnect(this, SIGNAL(installationStarted()), ProgressCoordinator::instance(), SLOT(reset()));
- connect(this, SIGNAL(installationStarted()), ProgressCoordinator::instance(), SLOT(reset()));
- disconnect(this, SIGNAL(uninstallationStarted()), ProgressCoordinator::instance(), SLOT(reset()));
- connect(this, SIGNAL(uninstallationStarted()), ProgressCoordinator::instance(), SLOT(reset()));
-
- m_updaterApplication.updateSourcesInfo()->setFileName(QString());
- KDUpdater::PackagesInfo &packagesInfo = *m_updaterApplication.packagesInfo();
- packagesInfo.setFileName(componentsXmlPath());
+ if (!isInstaller())
+ m_localPackageHub->setFileName(componentsXmlPath());
- // Note: force overwriting the application name and version in case we run as installer. Both will be
- // set to wrong initial values if we install into an already existing installation. This can happen
- // if the components.xml path has not been changed, but name or version of the new installer.
- if (isInstaller() || packagesInfo.applicationName().isEmpty()) {
+ if (isInstaller() || m_localPackageHub->applicationName().isEmpty()) {
// TODO: this seems to be wrong, we should ask for ProductName defaulting to applicationName...
- packagesInfo.setApplicationName(m_data.settings().applicationName());
+ m_localPackageHub->setApplicationName(m_data.settings().applicationName());
}
- if (isInstaller() || packagesInfo.applicationVersion().isEmpty()) {
- packagesInfo.setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
- }
+ if (isInstaller() || m_localPackageHub->applicationVersion().isEmpty())
+ m_localPackageHub->setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
- if (isInstaller()) {
- // TODO: this seems to be wrong, we should ask for ProductName defaulting to applicationName...
- m_updaterApplication.addUpdateSource(m_data.settings().applicationName(),
- m_data.settings().applicationName(), QString(), QUrl(QLatin1String("resource://metadata/")), 0);
- m_updaterApplication.updateSourcesInfo()->setModified(false);
- }
+ if (isInstaller())
+ m_packageSources.insert(PackageSource(QUrl(QLatin1String("resource://metadata/")), 0));
m_metadataJob.disconnect();
m_metadataJob.setAutoDelete(false);
m_metadataJob.setPackageManagerCore(m_core);
- connect(&m_metadataJob, SIGNAL(infoMessage(KDJob*, QString)), this,
- SLOT(infoMessage(KDJob*, QString)));
- connect(&m_metadataJob, SIGNAL(progress(KDJob *, quint64, quint64)), this,
- SLOT(infoProgress(KDJob *, quint64, quint64)));
+ connect(&m_metadataJob, &Job::infoMessage, this, &PackageManagerCorePrivate::infoMessage);
+ connect(&m_metadataJob, &Job::progress, this, &PackageManagerCorePrivate::infoProgress);
KDUpdater::FileDownloaderFactory::instance().setProxyFactory(m_core->proxyFactory());
}
@@ -656,7 +652,7 @@ QByteArray PackageManagerCorePrivate::replaceVariables(const QByteArray &ba) con
*/
Operation *PackageManagerCorePrivate::createOwnedOperation(const QString &type)
{
- m_ownedOperations.append(KDUpdater::UpdateOperationFactory::instance().create(type));
+ m_ownedOperations.append(KDUpdater::UpdateOperationFactory::instance().create(type, m_core));
return m_ownedOperations.last();
}
@@ -737,24 +733,30 @@ void PackageManagerCorePrivate::writeMaintenanceConfigFiles()
// write current state (variables) to the maintenance tool ini file
const QString iniPath = targetDir() + QLatin1Char('/') + m_data.settings().maintenanceToolIniFile();
- QVariantHash variables;
+ QVariantHash variables; // Do not change to QVariantMap! Breaks existing .ini files,
+ // cause the variant types do not match while restoring the variables from the file.
QSettingsWrapper cfg(iniPath, QSettingsWrapper::IniFormat);
foreach (const QString &key, m_data.keys()) {
- if (key != scRunProgramDescription && key != scRunProgram && key != scRunProgramArguments)
- variables.insert(key, m_data.value(key));
+ if (key == scRunProgramDescription || key == scRunProgram || key == scRunProgramArguments)
+ continue;
+ QVariant value = m_data.value(key);
+ if (value.canConvert(QVariant::String))
+ value = replacePath(value.toString(), targetDir(), QLatin1String(scRelocatable));
+ variables.insert(key, value);
}
cfg.setValue(QLatin1String("Variables"), variables);
- QVariantList repos;
+ QVariantList repos; // Do not change either!
foreach (const Repository &repo, m_data.settings().defaultRepositories())
repos.append(QVariant().fromValue(repo));
cfg.setValue(QLatin1String("DefaultRepositories"), repos);
- cfg.sync();
+ cfg.setValue(QLatin1String("FilesForDelayedDeletion"), m_filesForDelayedDeletion);
+ cfg.sync();
if (cfg.status() != QSettingsWrapper::NoError) {
const QString reason = cfg.status() == QSettingsWrapper::AccessError ? tr("Access error")
: tr("Format error");
- throw Error(tr("Could not write installer configuration to %1: %2").arg(iniPath, reason));
+ throw Error(tr("Cannot write installer configuration to %1: %2").arg(iniPath, reason));
}
QFile file(targetDir() + QLatin1Char('/') + QLatin1String("network.xml"));
@@ -799,17 +801,22 @@ void PackageManagerCorePrivate::readMaintenanceConfigFiles(const QString &target
{
QSettingsWrapper cfg(targetDir + QLatin1Char('/') + m_data.settings().maintenanceToolIniFile(),
QSettingsWrapper::IniFormat);
- const QVariantHash vars = cfg.value(QLatin1String("Variables")).toHash();
- for (QHash<QString, QVariant>::ConstIterator it = vars.constBegin(); it != vars.constEnd(); ++it)
- m_data.setValue(it.key(), it.value().toString());
-
+ const QVariantHash v = cfg.value(QLatin1String("Variables")).toHash(); // Do not change to
+ // QVariantMap! Breaks reading from existing .ini files, cause the variant types do not match.
+ for (QVariantHash::const_iterator it = v.constBegin(); it != v.constEnd(); ++it) {
+ m_data.setValue(it.key(), replacePath(it.value().toString(), QLatin1String(scRelocatable),
+ targetDir));
+ }
QSet<Repository> repos;
- const QVariantList variants = cfg.value(QLatin1String("DefaultRepositories")).toList();
+ const QVariantList variants = cfg.value(QLatin1String("DefaultRepositories"))
+ .toList(); // Do not change either!
foreach (const QVariant &variant, variants)
repos.insert(variant.value<Repository>());
if (!repos.isEmpty())
m_data.settings().setDefaultRepositories(repos);
+ m_filesForDelayedDeletion = cfg.value(QLatin1String("FilesForDelayedDeletion")).toStringList();
+
QFile file(targetDir + QLatin1String("/network.xml"));
if (!file.open(QIODevice::ReadOnly))
return;
@@ -1008,13 +1015,13 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q
{
QFile dummy(resourcePath.filePath(QLatin1String("installer.dat")));
if (dummy.exists() && !dummy.remove()) {
- throw Error(tr("Could not remove data file '%1': %2").arg(dummy.fileName(),
+ throw Error(tr("Cannot remove data file \"%1\": %2").arg(dummy.fileName(),
dummy.errorString()));
}
}
if (!dataOut.rename(resourcePath.filePath(QLatin1String("installer.dat")))) {
- throw Error(tr("Could not write maintenance tool data to %1: %2").arg(out.fileName(),
+ throw Error(tr("Cannot write maintenance tool data to %1: %2").arg(out.fileName(),
out.errorString()));
}
dataOut.setAutoRemove(false);
@@ -1033,13 +1040,13 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q
{
QFile dummy(maintenanceToolRenamedName);
if (dummy.exists() && !dummy.remove()) {
- throw Error(tr("Could not remove data file '%1': %2").arg(dummy.fileName(),
+ throw Error(tr("Cannot remove data file \"%1\": %2").arg(dummy.fileName(),
dummy.errorString()));
}
}
if (!out.copy(maintenanceToolRenamedName)) {
- throw Error(tr("Could not write maintenance tool to %1: %2").arg(maintenanceToolRenamedName,
+ throw Error(tr("Cannot write maintenance tool to \"%1\": %2").arg(maintenanceToolRenamedName,
out.errorString()));
}
@@ -1071,8 +1078,7 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinaryData(QFileDevice *outp
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);
+ qWarning() << "Cannot replace default resource with" << QDir::toNativeSeparators(newDefaultResource);
}
}
@@ -1085,9 +1091,6 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinaryData(QFileDevice *outp
const qint64 operationsStart = output->pos();
QInstaller::appendInt64(output, performedOperations.count());
foreach (Operation *operation, performedOperations) {
- // the installer can't be put into XML, remove it first
- operation->clearValue(QLatin1String("installer"));
-
QInstaller::appendString(output, operation->name());
QInstaller::appendString(output, operation->toXml().toString());
@@ -1263,17 +1266,17 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
if (!replacementBinary.remove()) {
// Is there anything more sensible we can do with this error? I think not. It's not serious
// enough for throwing / aborting the process.
- qDebug() << QString::fromLatin1("Could not remove installer base binary '%1' after updating "
- "the maintenance tool: %2").arg(installerBaseBinary, replacementBinary.errorString());
+ qDebug() << "Cannot remove installer base binary" << installerBaseBinary
+ << "after updating the maintenance tool:" << replacementBinary.errorString();
} else {
- qDebug() << QString::fromLatin1("Removed installer base binary '%1' after updating the "
- "maintenance tool.").arg(installerBaseBinary);
+ qDebug() << "Removed installer base binary" << installerBaseBinary
+ << "after updating the maintenance tool.";
}
m_installerBaseBinaryUnreplaced.clear();
} else if (!installerBaseBinary.isEmpty() && !QFileInfo(installerBaseBinary).exists()) {
- qWarning() << QString::fromLatin1("The current 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);
+ qWarning() << "The current maintenance tool could not be updated." << installerBaseBinary
+ << "does not exist. Please fix the \"setInstallerBaseBinary(<temp_installer_base_"
+ "binary_path>)\" call in your script.";
}
QFile input;
@@ -1283,9 +1286,9 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
try {
if (isInstaller()) {
if (QFile::exists(dataFile)) {
- qWarning() << QString::fromLatin1("Found binary data file '%1' but "
+ qWarning() << "Found binary data file" << dataFile << "but "
"deliberately not used. Running as installer requires to read the "
- "resources from the application binary.").arg(dataFile);
+ "resources from the application binary.";
}
throw Error();
}
@@ -1334,12 +1337,12 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
QFile dummy(dataFile + QLatin1String(".new"));
if (dummy.exists() && !dummy.remove()) {
- throw Error(tr("Could not remove data file '%1': %2").arg(dummy.fileName(),
+ throw Error(tr("Cannot remove data file \"%1\": %2").arg(dummy.fileName(),
dummy.errorString()));
}
if (!file.rename(dataFile + QLatin1String(".new"))) {
- throw Error(tr("Could not write maintenance tool binary data to %1: %2")
+ throw Error(tr("Cannot write maintenance tool binary data to %1: %2")
.arg(file.fileName(), file.errorString()));
}
file.setAutoRemove(false);
@@ -1399,7 +1402,7 @@ QString PackageManagerCorePrivate::registerPath()
}
QString path = QLatin1String("HKEY_CURRENT_USER");
- if (m_data.value(QLatin1String("AllUsers"), scFalse).toString() == scTrue)
+ if (m_data.value(scAllUsers, scFalse).toString() == scTrue)
path = QLatin1String("HKEY_LOCAL_MACHINE");
return path + QLatin1String("\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\")
@@ -1491,14 +1494,13 @@ bool PackageManagerCorePrivate::runInstaller()
componentsInstallPartProgressSize = double(1);
// Force an update on the components xml as the install dir might have changed.
- KDUpdater::PackagesInfo &info = *m_updaterApplication.packagesInfo();
- info.setFileName(componentsXmlPath());
+ m_localPackageHub->setFileName(componentsXmlPath());
// Clear the packages as we might install into an already existing installation folder.
- info.clearPackageInfoList();
+ m_localPackageHub->clearPackageInfos();
// also update the application name, might be set from a script as well
- info.setApplicationName(m_data.value(QLatin1String("ProductName"),
+ m_localPackageHub->setApplicationName(m_data.value(QLatin1String("ProductName"),
m_data.settings().applicationName()).toString());
- info.setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
+ m_localPackageHub->setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
const int progressOperationCount = countProgressOperations(componentsToInstall)
// add one more operation as we support progress
@@ -1526,7 +1528,6 @@ bool PackageManagerCorePrivate::runInstaller()
binaryFile = resourcePath.filePath(QLatin1String("installer.dat"));
#endif
createRepo->setValue(QLatin1String("uninstall-only"), true);
- createRepo->setValue(QLatin1String("installer"), QVariant::fromValue(m_core));
createRepo->setArguments(QStringList() << binaryFile << target
+ QLatin1String("/repository"));
@@ -1867,7 +1868,7 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
bool ignoreError = false;
bool ok = performOperationThreaded(operation);
while (!ok && !ignoreError && m_core->status() != PackageManagerCore::Canceled) {
- qDebug() << QString::fromLatin1("Operation '%1' with arguments: '%2' failed: %3")
+ qDebug() << QString::fromLatin1("Operation \"%1\" with arguments \"%2\" failed: %3")
.arg(operation->name(), operation->arguments().join(QLatin1String("; ")),
operation->errorString());
const QMessageBox::StandardButton button =
@@ -1905,7 +1906,7 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
if (!component->stopProcessForUpdateRequests().isEmpty()) {
Operation *stopProcessForUpdatesOp = KDUpdater::UpdateOperationFactory::instance()
- .create(QLatin1String("FakeStopProcessForUpdate"));
+ .create(QLatin1String("FakeStopProcessForUpdate"), m_core);
const QStringList arguments(component->stopProcessForUpdateRequests().join(QLatin1String(",")));
stopProcessForUpdatesOp->setArguments(arguments);
addPerformed(stopProcessForUpdatesOp);
@@ -1913,12 +1914,18 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
}
// now mark the component as installed
- KDUpdater::PackagesInfo &packages = *m_updaterApplication.packagesInfo();
- packages.installPackage(component->name(), component->value(scVersion), component->value(scDisplayName),
- component->value(scDescription), component->dependencies(), component->forcedInstallation(),
- component->isVirtual(), component->value(scUncompressedSize).toULongLong(),
- component->value(scInheritVersion));
- packages.writeToDisk();
+ m_localPackageHub->addPackage(component->name(),
+ component->value(scVersion),
+ component->value(scDisplayName),
+ component->value(scDescription),
+ component->dependencies(),
+ component->autoDependencies(),
+ component->forcedInstallation(),
+ component->isVirtual(),
+ component->value(scUncompressedSize).toULongLong(),
+ component->value(scInheritVersion),
+ component->isCheckable());
+ m_localPackageHub->writeToDisk();
component->setInstalled();
component->markAsPerformedInstallation();
@@ -2039,7 +2046,6 @@ void PackageManagerCorePrivate::unregisterMaintenanceTool()
void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOperations, double progressSize,
bool adminRightsGained, bool deleteOperation)
{
- KDUpdater::PackagesInfo &packages = *m_updaterApplication.packagesInfo();
try {
foreach (Operation *undoOperation, undoOperations) {
if (statusCanceledOrFailed())
@@ -2075,7 +2081,7 @@ void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOpera
component = componentsToReplace().value(componentName).second;
if (component) {
component->setUninstalled();
- packages.removePackage(component->name());
+ m_localPackageHub->removePackage(component->name());
}
}
@@ -2086,13 +2092,13 @@ void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOpera
delete undoOperation;
}
} catch (const Error &error) {
- packages.writeToDisk();
+ m_localPackageHub->writeToDisk();
throw Error(error.message());
} catch (...) {
- packages.writeToDisk();
+ m_localPackageHub->writeToDisk();
throw Error(tr("Unknown error"));
}
- packages.writeToDisk();
+ m_localPackageHub->writeToDisk();
}
PackagesList PackageManagerCorePrivate::remotePackages()
@@ -2103,12 +2109,14 @@ PackagesList PackageManagerCorePrivate::remotePackages()
m_updates = false;
delete m_updateFinder;
- m_updateFinder = new KDUpdater::UpdateFinder(&m_updaterApplication);
+ m_updateFinder = new KDUpdater::UpdateFinder;
m_updateFinder->setAutoDelete(false);
+ m_updateFinder->setPackageSources(m_packageSources);
+ m_updateFinder->setLocalPackageHub(m_localPackageHub);
m_updateFinder->run();
if (m_updateFinder->updates().isEmpty()) {
- setStatus(PackageManagerCore::Failure, tr("Could not retrieve remote tree: %1.")
+ setStatus(PackageManagerCore::Failure, tr("Cannot retrieve remote tree %1.")
.arg(m_updateFinder->errorString()));
return PackagesList();
}
@@ -2124,27 +2132,32 @@ PackagesList PackageManagerCorePrivate::remotePackages()
*/
LocalPackagesHash PackageManagerCorePrivate::localInstalledPackages()
{
+ if (isInstaller())
+ return LocalPackagesHash();
+
LocalPackagesHash installedPackages;
+ if (m_localPackageHub->error() != LocalPackageHub::NoError) {
+ if (m_localPackageHub->fileName().isEmpty())
+ m_localPackageHub->setFileName(componentsXmlPath());
+ else
+ m_localPackageHub->refresh();
- if (!isInstaller()) {
- KDUpdater::PackagesInfo &packagesInfo = *m_updaterApplication.packagesInfo();
- if (!packagesInfo.isValid()) {
- packagesInfo.setFileName(componentsXmlPath());
- if (packagesInfo.applicationName().isEmpty())
- packagesInfo.setApplicationName(m_data.settings().applicationName());
- if (packagesInfo.applicationVersion().isEmpty())
- packagesInfo.setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
- }
+ if (m_localPackageHub->applicationName().isEmpty())
+ m_localPackageHub->setApplicationName(m_data.settings().applicationName());
+ if (m_localPackageHub->applicationVersion().isEmpty())
+ m_localPackageHub->setApplicationVersion(QLatin1String(QUOTE(IFW_REPOSITORY_FORMAT_VERSION)));
+ }
- if (packagesInfo.error() != KDUpdater::PackagesInfo::NoError)
- setStatus(PackageManagerCore::Failure, tr("Failure to read packages from: %1.").arg(componentsXmlPath()));
+ if (m_localPackageHub->error() != LocalPackageHub::NoError) {
+ setStatus(PackageManagerCore::Failure, tr("Failure to read packages from %1.")
+ .arg(componentsXmlPath()));
+ }
- foreach (const LocalPackage &package, packagesInfo.packageInfos()) {
- if (statusCanceledOrFailed())
- break;
- installedPackages.insert(package.name, package);
- }
- }
+ foreach (const LocalPackage &package, m_localPackageHub->packageInfos()) {
+ if (statusCanceledOrFailed())
+ break;
+ installedPackages.insert(package.name, package);
+ }
return installedPackages;
}
@@ -2162,12 +2175,12 @@ bool PackageManagerCorePrivate::fetchMetaInformationFromRepositories()
m_metadataJob.start();
m_metadataJob.waitForFinished();
} catch (Error &error) {
- setStatus(PackageManagerCore::Failure, tr("Could not retrieve meta information: %1")
+ setStatus(PackageManagerCore::Failure, tr("Cannot retrieve meta information: %1")
.arg(error.message()));
return m_repoFetched;
}
- if (m_metadataJob.error() != KDJob::NoError) {
+ if (m_metadataJob.error() != Job::NoError) {
switch (m_metadataJob.error()) {
case QInstaller::UserIgnoreError:
break; // we can simply ignore this error, the user knows about it
@@ -2192,19 +2205,13 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe
return m_updateSourcesAdded;
}
- // forces an refresh / clear on all update sources
- m_updaterApplication.updateSourcesInfo()->refresh();
- if (isInstaller()) {
- m_updaterApplication.addUpdateSource(m_data.settings().applicationName(),
- m_data.settings().applicationName(), QString(),
- QUrl(QLatin1String("resource://metadata/")), 0);
- m_updaterApplication.updateSourcesInfo()->setModified(false);
- }
+ m_packageSources.clear();
+ if (isInstaller())
+ m_packageSources.insert(PackageSource(QUrl(QLatin1String("resource://metadata/")), 0));
m_updates = false;
m_updateSourcesAdded = false;
- const QString &appName = m_data.settings().applicationName();
foreach (const Metadata &data, metadata) {
if (statusCanceledOrFailed())
return false;
@@ -2219,7 +2226,7 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe
QInstaller::openForRead(&updatesFile);
} catch(const Error &e) {
qDebug() << "Error opening Updates.xml:" << e.message();
- setStatus(PackageManagerCore::Failure, tr("Could not add temporary update source information."));
+ setStatus(PackageManagerCore::Failure, tr("Cannot add temporary update source information."));
return false;
}
@@ -2228,9 +2235,9 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe
QString error;
QDomDocument doc;
if (!doc.setContent(&updatesFile, &error, &line, &column)) {
- qDebug() << QString::fromLatin1("Parse error in file %4: %1 at line %2 col %3").arg(error,
- QString::number(line), QString::number(column), updatesFile.fileName());
- setStatus(PackageManagerCore::Failure, tr("Could not add temporary update source information."));
+ qDebug().nospace() << "Parse error in file" << updatesFile.fileName()
+ << ": " << error << " at line " << line << " col " << column;
+ setStatus(PackageManagerCore::Failure, tr("Cannot add temporary update source information."));
return false;
}
@@ -2238,14 +2245,12 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe
if (!checksum.isNull())
m_core->setTestChecksum(checksum.toElement().text().toLower() == scTrue);
}
- m_updaterApplication.addUpdateSource(appName, appName, QString(),
- QUrl::fromLocalFile(data.directory), 1);
+ m_packageSources.insert(PackageSource(QUrl::fromLocalFile(data.directory), 1));
ProductKeyCheck::instance()->addPackagesFromXml(data.directory + QLatin1String("/Updates.xml"));
}
- m_updaterApplication.updateSourcesInfo()->setModified(false);
- if (m_updaterApplication.updateSourcesInfo()->updateSourceInfoCount() == 0) {
- setStatus(PackageManagerCore::Failure, tr("Could not find any update source information."));
+ if (m_packageSources.count() == 0) {
+ setStatus(PackageManagerCore::Failure, tr("Cannot find any update source information."));
return false;
}
@@ -2297,25 +2302,20 @@ OperationList PackageManagerCorePrivate::sortOperationsBasedOnComponentDependenc
const QString componentName = operation->value(QLatin1String("component")).toString();
if (componentName.isEmpty())
sortedOperations.append(operation);
- else {
- OperationList componentOperationList = componentOperationHash.value(componentName);
- componentOperationList.append(operation);
- componentOperationHash.insert(operation->value(QLatin1String("component")).toString(),
- componentOperationList);
- }
+ else
+ componentOperationHash[componentName].append(operation);
}
- const QString empty;
const QRegExp dash(QLatin1String("-.*"));
Graph<QString> componentGraph; // create the complete component graph
foreach (const Component* node, m_core->components(PackageManagerCore::ComponentType::All)) {
componentGraph.addNode(node->name());
- componentGraph.addEdges(node->name(), node->dependencies().replaceInStrings(dash, empty));
+ componentGraph.addEdges(node->name(), node->dependencies().replaceInStrings(dash, QString()));
}
const QStringList resolvedComponents = componentGraph.sort();
if (componentGraph.hasCycle()) {
- throw Error(tr("Dependency cycle between components detected: '%1' and '%2'.")
+ throw Error(tr("Dependency cycle between components \"%1\" and \"%2\" detected.")
.arg(componentGraph.cycle().first, componentGraph.cycle().second));
}
foreach (const QString &componentName, resolvedComponents)
@@ -2331,4 +2331,20 @@ void PackageManagerCorePrivate::handleMethodInvocationRequest(const QString &inv
QMetaObject::invokeMethod(obj, qPrintable(invokableMethodName));
}
+void PackageManagerCorePrivate::processFilesForDelayedDeletion()
+{
+ if (m_filesForDelayedDeletion.isEmpty())
+ return;
+
+ const QStringList filesForDelayedDeletion = std::move(m_filesForDelayedDeletion);
+ foreach (const QString &i, filesForDelayedDeletion) {
+ QFile file(i); //TODO: this should happen asnyc and report errors, I guess
+ if (file.exists() && !file.remove()) {
+ qWarning("Cannot delete file %s: %s", qPrintable(i),
+ qPrintable(file.errorString()));
+ m_filesForDelayedDeletion << i; // try again next time
+ }
+ }
+}
+
} // namespace QInstaller
diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h
index ca2c43b9a..d78bd3e69 100644
--- a/src/libs/installer/packagemanagercore_p.h
+++ b/src/libs/installer/packagemanagercore_p.h
@@ -38,15 +38,15 @@
#include "packagemanagercore.h"
#include "packagemanagercoredata.h"
#include "packagemanagerproxyfactory.h"
+#include "packagesource.h"
#include "qinstallerglobal.h"
-#include "kdsysinfo.h"
-#include "kdupdaterapplication.h"
-#include "kdupdaterupdatefinder.h"
+#include "sysinfo.h"
+#include "updatefinder.h"
#include <QObject>
-class KDJob;
+class Job;
QT_FORWARD_DECLARE_CLASS(QFile)
QT_FORWARD_DECLARE_CLASS(QFileDevice)
@@ -65,27 +65,6 @@ class InstallerCalculator;
class UninstallerCalculator;
class RemoteFileEngineHandler;
-/*
- The default configuration interface implementation does call QSettings to save files for later deletion,
- though according to QSettings there should nothing be written if QSettings is not setup properly (which
- we do not in our case). Still, caused by a broken QSettings implementation at least on Linux we write an
- empty config file which resulted in QTIFW-196. To workaround the issue we now use this empty dummy class.
-*/
-class DummyConfigurationInterface : public KDUpdater::ConfigurationInterface
-{
-public:
- QVariant value(const QString &key) const
- {
- Q_UNUSED(key)
- return QVariant();
- }
- void setValue(const QString &key, const QVariant &value)
- {
- if (value.isNull())
- qDebug() << "DummyConfigurationInterface called with key:" << key << "and value:" << value;
- }
-};
-
class PackageManagerCorePrivate : public QObject
{
Q_OBJECT
@@ -196,7 +175,9 @@ signals:
public:
UpdateFinder *m_updateFinder;
- Application m_updaterApplication;
+ QSet<PackageSource> m_packageSources;
+ std::shared_ptr<LocalPackageHub> m_localPackageHub;
+ QStringList m_filesForDelayedDeletion;
int m_status;
QString m_error;
@@ -224,10 +205,10 @@ public:
bool m_dependsOnLocalInstallerBinary;
private slots:
- void infoMessage(KDJob *, const QString &message) {
+ void infoMessage(Job *, const QString &message) {
emit m_core->metaJobInfoMessage(message);
}
- void infoProgress(KDJob *, quint64 progress, quint64) {
+ void infoProgress(Job *, quint64 progress, quint64) {
emit m_core->metaJobProgress(progress);
}
@@ -249,6 +230,7 @@ private:
LocalPackagesHash localInstalledPackages();
bool fetchMetaInformationFromRepositories();
bool addUpdateResourcesFromRepositories(bool parseChecksum);
+ void processFilesForDelayedDeletion();
private:
PackageManagerCore *m_core;
diff --git a/src/libs/installer/packagemanagercoredata.cpp b/src/libs/installer/packagemanagercoredata.cpp
index 2241e4bcc..671717d0b 100644
--- a/src/libs/installer/packagemanagercoredata.cpp
+++ b/src/libs/installer/packagemanagercoredata.cpp
@@ -51,27 +51,14 @@ namespace QInstaller
PackageManagerCoreData::PackageManagerCoreData(const QHash<QString, QString> &variables)
{
m_variables = variables;
+ setDynamicPredefinedVariables();
// Set some common variables that may used e.g. as placeholder in some of the settings variables or
// in a script or...
- m_variables.insert(QLatin1String("rootDir"), QDir::rootPath());
- m_variables.insert(QLatin1String("homeDir"), QDir::homePath());
- m_variables.insert(QLatin1String("RootDir"), QDir::rootPath());
- m_variables.insert(QLatin1String("HomeDir"), QDir::homePath());
m_variables.insert(scTargetConfigurationFile, QLatin1String("components.xml"));
m_variables.insert(QLatin1String("InstallerDirPath"), QCoreApplication::applicationDirPath());
m_variables.insert(QLatin1String("InstallerFilePath"), QCoreApplication::applicationFilePath());
- QString dir = QLatin1String("/opt");
-#ifdef Q_OS_WIN
- TCHAR buffer[MAX_PATH + 1] = { 0 };
- SHGetFolderPath(0, CSIDL_PROGRAM_FILES, 0, 0, buffer);
- dir = QString::fromWCharArray(buffer);
-#elif defined (Q_OS_OSX)
- dir = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(0);
-#endif
- m_variables.insert(QLatin1String("ApplicationsDir"), dir);
-
#ifdef Q_OS_WIN
m_variables.insert(QLatin1String("os"), QLatin1String("win"));
#elif defined(Q_OS_OSX)
@@ -82,26 +69,6 @@ PackageManagerCoreData::PackageManagerCoreData(const QHash<QString, QString> &va
// TODO: add more platforms as needed...
#endif
-#ifdef Q_OS_WIN
- QSettingsWrapper user(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\"
- "CurrentVersion\\Explorer\\User Shell Folders"), QSettingsWrapper::NativeFormat);
- QSettingsWrapper system(QLatin1String("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\"
- "CurrentVersion\\Explorer\\Shell Folders"), QSettingsWrapper::NativeFormat);
-
- const QString programs = user.value(QLatin1String("Programs"), QString()).toString();
- const QString allPrograms = system.value(QLatin1String("Common Programs"), QString()).toString();
-
- QString desktop;
- if (m_variables.value(QLatin1String("AllUsers")) == scTrue) {
- desktop = system.value(QLatin1String("Desktop")).toString();
- } else {
- desktop = user.value(QLatin1String("Desktop")).toString();
- }
- m_variables.insert(QLatin1String("DesktopDir"), replaceWindowsEnvironmentVariables(desktop));
- m_variables.insert(QLatin1String("UserStartMenuProgramsPath"), replaceWindowsEnvironmentVariables(programs));
- m_variables.insert(QLatin1String("AllUsersStartMenuProgramsPath"), replaceWindowsEnvironmentVariables(allPrograms));
-#endif
-
m_settings = Settings::fromFileAndPrefix(QLatin1String(":/metadata/installer-config/config.xml"),
QLatin1String(":/metadata/installer-config/"), Settings::RelaxedParseMode);
@@ -131,12 +98,57 @@ void PackageManagerCoreData::clear()
m_settings = Settings();
}
+/*!
+ Set some common variables that may be used e.g. as placeholder in some of the settings
+ variables or in a script or...
+*/
+void PackageManagerCoreData::setDynamicPredefinedVariables()
+{
+ m_variables.insert(QLatin1String("rootDir"), QDir::rootPath());
+ m_variables.insert(QLatin1String("homeDir"), QDir::homePath());
+ m_variables.insert(QLatin1String("RootDir"), QDir::rootPath());
+ m_variables.insert(QLatin1String("HomeDir"), QDir::homePath());
+
+ QString dir = QLatin1String("/opt");
+#ifdef Q_OS_WIN
+ TCHAR buffer[MAX_PATH + 1] = { 0 };
+ SHGetFolderPath(0, CSIDL_PROGRAM_FILES, 0, 0, buffer);
+ dir = QString::fromWCharArray(buffer);
+#elif defined (Q_OS_OSX)
+ dir = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(0);
+#endif
+ m_variables.insert(QLatin1String("ApplicationsDir"), dir);
+
+#ifdef Q_OS_WIN
+ QSettingsWrapper user(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\"
+ "CurrentVersion\\Explorer\\User Shell Folders"), QSettingsWrapper::NativeFormat);
+ QSettingsWrapper system(QLatin1String("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\"
+ "CurrentVersion\\Explorer\\Shell Folders"), QSettingsWrapper::NativeFormat);
+
+ const QString programs = user.value(QLatin1String("Programs"), QString()).toString();
+ const QString allPrograms = system.value(QLatin1String("Common Programs"), QString())
+ .toString();
+
+ QString desktop;
+ if (m_variables.value(QLatin1String("AllUsers")) == scTrue) {
+ desktop = system.value(QLatin1String("Desktop")).toString();
+ } else {
+ desktop = user.value(QLatin1String("Desktop")).toString();
+ }
+ m_variables.insert(QLatin1String("DesktopDir"), replaceWindowsEnvironmentVariables(desktop));
+ m_variables.insert(QLatin1String("UserStartMenuProgramsPath"),
+ replaceWindowsEnvironmentVariables(programs));
+ m_variables.insert(QLatin1String("AllUsersStartMenuProgramsPath"),
+ replaceWindowsEnvironmentVariables(allPrograms));
+#endif
+}
+
Settings &PackageManagerCoreData::settings() const
{
return m_settings;
}
-QList<QString> PackageManagerCoreData::keys() const
+QStringList PackageManagerCoreData::keys() const
{
return m_variables.keys();
}
diff --git a/src/libs/installer/packagemanagercoredata.h b/src/libs/installer/packagemanagercoredata.h
index e83bf921a..f0a15748b 100644
--- a/src/libs/installer/packagemanagercoredata.h
+++ b/src/libs/installer/packagemanagercoredata.h
@@ -45,9 +45,10 @@ public:
explicit PackageManagerCoreData(const QHash<QString, QString> &variables);
void clear();
+ void setDynamicPredefinedVariables();
Settings &settings() const;
- QList<QString> keys() const;
+ QStringList keys() const;
bool contains(const QString &key) const;
bool setValue(const QString &key, const QString &normalizedValue);
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index 9aab80de0..34e1471ae 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -45,7 +45,7 @@
#include "scriptengine.h"
#include "productkeycheck.h"
-#include "kdsysinfo.h"
+#include "sysinfo.h"
#include <QApplication>
@@ -110,7 +110,6 @@ public:
setLayout(new QVBoxLayout);
layout()->addWidget(widget);
layout()->setContentsMargins(0, 0, 0, 0);
- layout()->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));
addPageAndProperties(packageManagerCore()->controlScriptEngine());
addPageAndProperties(packageManagerCore()->componentScriptEngine());
@@ -207,6 +206,7 @@ public:
, m_modified(false)
, m_autoSwitchPage(true)
, m_showSettingsButton(false)
+ , m_silent(false)
{
m_wizardButtonTypes.insert(QWizard::BackButton, QLatin1String("QWizard::BackButton"));
m_wizardButtonTypes.insert(QWizard::NextButton, QLatin1String("QWizard::NextButton"));
@@ -230,6 +230,7 @@ public:
bool m_modified;
bool m_autoSwitchPage;
bool m_showSettingsButton;
+ bool m_silent;
QHash<int, QWizardPage*> m_defaultPages;
QHash<int, QString> m_defaultButtonText;
@@ -315,48 +316,65 @@ PackageManagerGui::PackageManagerGui(PackageManagerCore *core, QWidget *parent)
if (!m_core->settings().wizardStyle().isEmpty())
setWizardStyle(getStyle(m_core->settings().wizardStyle()));
+ // set custom stylesheet
+ const QString styleSheetFile = m_core->settings().styleSheet();
+ if (!styleSheetFile.isEmpty()
+ && QFileInfo::exists(styleSheetFile)) {
+ QFile sheet(styleSheetFile);
+ if (sheet.open(QIODevice::ReadOnly))
+ setStyleSheet(QString::fromLatin1(sheet.readAll()));
+ else
+ qWarning() << "The specified style sheet file can not be opened.";
+ } else {
+ qWarning() << "A style sheet file is specified, but it does not exist.";
+ }
+
setOption(QWizard::NoBackButtonOnStartPage);
setOption(QWizard::NoBackButtonOnLastPage);
- connect(this, SIGNAL(rejected()), m_core, SLOT(setCanceled()));
- connect(this, SIGNAL(interrupted()), m_core, SLOT(interrupt()));
+ connect(this, &QDialog::rejected, m_core, &PackageManagerCore::setCanceled);
+ connect(this, &PackageManagerGui::interrupted, m_core, &PackageManagerCore::interrupt);
// both queued to show the finished page once everything is done
- connect(m_core, SIGNAL(installationFinished()), this, SLOT(showFinishedPage()),
+ connect(m_core, &PackageManagerCore::installationFinished,
+ this, &PackageManagerGui::showFinishedPage,
Qt::QueuedConnection);
- connect(m_core, SIGNAL(uninstallationFinished()), this, SLOT(showFinishedPage()),
+ connect(m_core, &PackageManagerCore::uninstallationFinished,
+ this, &PackageManagerGui::showFinishedPage,
Qt::QueuedConnection);
- connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(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()), m_core, SIGNAL(finishButtonClicked()));
+ connect(this, &QWizard::currentIdChanged, this, &PackageManagerGui::currentPageChanged);
+ connect(this, &QWizard::currentIdChanged, m_core, &PackageManagerCore::currentPageChanged);
+ connect(button(QWizard::FinishButton), &QAbstractButton::clicked,
+ this, &PackageManagerGui::finishButtonClicked);
+ connect(button(QWizard::FinishButton), &QAbstractButton::clicked,
+ m_core, &PackageManagerCore::finishButtonClicked);
// make sure the QUiLoader's retranslateUi is executed first, then the script
- connect(this, SIGNAL(languageChanged()), m_core, SLOT(languageChanged()), Qt::QueuedConnection);
- connect(this, SIGNAL(languageChanged()), this, SLOT(onLanguageChanged()), Qt::QueuedConnection);
+ connect(this, &PackageManagerGui::languageChanged,
+ m_core, &PackageManagerCore::languageChanged, Qt::QueuedConnection);
+ connect(this, &PackageManagerGui::languageChanged,
+ this, &PackageManagerGui::onLanguageChanged, Qt::QueuedConnection);
connect(m_core,
- SIGNAL(wizardPageInsertionRequested(QWidget*,QInstaller::PackageManagerCore::WizardPage)),
- this, SLOT(wizardPageInsertionRequested(QWidget*,QInstaller::PackageManagerCore::WizardPage)));
- connect(m_core, SIGNAL(wizardPageRemovalRequested(QWidget*)), this,
- SLOT(wizardPageRemovalRequested(QWidget*)));
- connect(m_core,
- SIGNAL(wizardWidgetInsertionRequested(QWidget*,QInstaller::PackageManagerCore::WizardPage)),
- this, SLOT(wizardWidgetInsertionRequested(QWidget*,QInstaller::PackageManagerCore::WizardPage)));
- connect(m_core, SIGNAL(wizardWidgetRemovalRequested(QWidget*)), this,
- SLOT(wizardWidgetRemovalRequested(QWidget*)));
- connect(m_core, SIGNAL(wizardPageVisibilityChangeRequested(bool,int)), this,
- SLOT(wizardPageVisibilityChangeRequested(bool,int)), Qt::QueuedConnection);
+ &PackageManagerCore::wizardPageInsertionRequested,
+ this, &PackageManagerGui::wizardPageInsertionRequested);
+ connect(m_core, &PackageManagerCore::wizardPageRemovalRequested,
+ this, &PackageManagerGui::wizardPageRemovalRequested);
+ connect(m_core, &PackageManagerCore::wizardWidgetInsertionRequested,
+ this, &PackageManagerGui::wizardWidgetInsertionRequested);
+ connect(m_core, &PackageManagerCore::wizardWidgetRemovalRequested,
+ this, &PackageManagerGui::wizardWidgetRemovalRequested);
+ connect(m_core, &PackageManagerCore::wizardPageVisibilityChangeRequested,
+ this, &PackageManagerGui::wizardPageVisibilityChangeRequested, Qt::QueuedConnection);
- connect(m_core,
- SIGNAL(setValidatorForCustomPageRequested(QInstaller::Component*,QString,QString)), this,
- SLOT(setValidatorForCustomPageRequested(QInstaller::Component*,QString,QString)));
+ connect(m_core, &PackageManagerCore::setValidatorForCustomPageRequested,
+ this, &PackageManagerGui::setValidatorForCustomPageRequested);
- connect(m_core, SIGNAL(setAutomatedPageSwitchEnabled(bool)), this,
- SLOT(setAutomatedPageSwitchEnabled(bool)));
+ connect(m_core, &PackageManagerCore::setAutomatedPageSwitchEnabled,
+ this, &PackageManagerGui::setAutomatedPageSwitchEnabled);
- connect(this, SIGNAL(customButtonClicked(int)), this, SLOT(customButtonClicked(int)));
+ connect(this, &QWizard::customButtonClicked, this, &PackageManagerGui::customButtonClicked);
for (int i = QWizard::BackButton; i < QWizard::CustomButton1; ++i)
d->m_defaultButtonText.insert(i, buttonText(QWizard::WizardButton(i)));
@@ -400,6 +418,23 @@ QWizard::WizardStyle PackageManagerGui::getStyle(const QString &name)
}
/*!
+ Hides the GUI when \a silent is \c true.
+*/
+void PackageManagerGui::setSilent(bool silent)
+{
+ d->m_silent = silent;
+ setVisible(!silent);
+}
+
+/*!
+ Returns the current silent state.
+*/
+bool PackageManagerGui::isSilent() const
+{
+ return d->m_silent;
+}
+
+/*!
Enables automatic page switching when \a request is \c true.
*/
void PackageManagerGui::setAutomatedPageSwitchEnabled(bool request)
@@ -450,7 +485,7 @@ void PackageManagerGui::clickButton(int wb, int delay)
wb = QWizard::CancelButton;
if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb)))
- QTimer::singleShot(delay, b, SLOT(click()));
+ QTimer::singleShot(delay, b, &QAbstractButton::click);
else
qWarning() << "Button with type: " << d->buttonType(wb) << "not found!";
}
@@ -743,13 +778,13 @@ void PackageManagerGui::cancelButtonClicked()
question = tr("Do you want to quit the installer application?");
if (m_core->isUninstaller())
question = tr("Do you want to quit the uninstaller application?");
- if (m_core->isUpdater() || m_core->isPackageManager())
+ if (m_core->isMaintainer())
question = tr("Do you want to quit the maintenance application?");
}
const QMessageBox::StandardButton button =
MessageBoxHandler::question(MessageBoxHandler::currentBestSuitParent(),
- QLatin1String("cancelInstallation"), tr("Question"), question,
+ QLatin1String("cancelInstallation"), tr("%1 Question").arg(m_core->value(scTitle)), question,
QMessageBox::Yes | QMessageBox::No);
if (button == QMessageBox::Yes) {
@@ -1154,7 +1189,7 @@ int PackageManagerPage::nextId() const
core->calculateComponentsToInstall();
foreach (Component* component, core->orderedComponentsToInstall()) {
- if ((core->isPackageManager() || core->isUpdater()) && component->isInstalled())
+ if (core->isMaintainer() && component->isInstalled())
continue; // package manager or updater, hide as long as the component is installed
// The component is about to be installed and provides a license, so the page needs to
@@ -1215,20 +1250,22 @@ IntroductionPage::IntroductionPage(PackageManagerCore *core)
m_packageManager->setObjectName(QLatin1String("PackageManagerRadioButton"));
boxLayout->addWidget(m_packageManager);
m_packageManager->setChecked(core->isPackageManager());
- connect(m_packageManager, SIGNAL(toggled(bool)), this, SLOT(setPackageManager(bool)));
+ connect(m_packageManager, &QAbstractButton::toggled, this, &IntroductionPage::setPackageManager);
m_updateComponents = new QRadioButton(tr("Update components"), this);
m_updateComponents->setObjectName(QLatin1String("UpdaterRadioButton"));
boxLayout->addWidget(m_updateComponents);
m_updateComponents->setChecked(core->isUpdater());
- connect(m_updateComponents, SIGNAL(toggled(bool)), this, SLOT(setUpdater(bool)));
+ connect(m_updateComponents, &QAbstractButton::toggled, this, &IntroductionPage::setUpdater);
m_removeAllComponents = new QRadioButton(tr("Remove all components"), this);
m_removeAllComponents->setObjectName(QLatin1String("UninstallerRadioButton"));
boxLayout->addWidget(m_removeAllComponents);
m_removeAllComponents->setChecked(core->isUninstaller());
- connect(m_removeAllComponents, SIGNAL(toggled(bool)), this, SLOT(setUninstaller(bool)));
- connect(m_removeAllComponents, SIGNAL(toggled(bool)), core, SLOT(setCompleteUninstallation(bool)));
+ connect(m_removeAllComponents, &QAbstractButton::toggled,
+ this, &IntroductionPage::setUninstaller);
+ connect(m_removeAllComponents, &QAbstractButton::toggled,
+ core, &PackageManagerCore::setCompleteUninstallation);
boxLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
@@ -1256,16 +1293,18 @@ IntroductionPage::IntroductionPage(PackageManagerCore *core)
core->setCompleteUninstallation(core->isUninstaller());
- connect(core, SIGNAL(metaJobProgress(int)), this, SLOT(onProgressChanged(int)));
- connect(core, SIGNAL(metaJobInfoMessage(QString)), this, SLOT(setMessage(QString)));
- connect(core, SIGNAL(coreNetworkSettingsChanged()), this, SLOT(onCoreNetworkSettingsChanged()));
+ connect(core, &PackageManagerCore::metaJobProgress, this, &IntroductionPage::onProgressChanged);
+ connect(core, &PackageManagerCore::metaJobInfoMessage, this, &IntroductionPage::setMessage);
+ connect(core, &PackageManagerCore::coreNetworkSettingsChanged,
+ this, &IntroductionPage::onCoreNetworkSettingsChanged);
m_updateComponents->setEnabled(ProductKeyCheck::instance()->hasValidKey());
#ifdef Q_OS_WIN
if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
m_taskButton = new QWinTaskbarButton(this);
- connect(core, SIGNAL(metaJobProgress(int)), m_taskButton->progress(), SLOT(setValue(int)));
+ connect(core, &PackageManagerCore::metaJobProgress,
+ m_taskButton->progress(), &QWinTaskbarProgress::setValue);
} else {
m_taskButton = 0;
}
@@ -1281,7 +1320,7 @@ int IntroductionPage::nextId() const
if (packageManagerCore()->isUninstaller())
return PackageManagerCore::ReadyForInstallation;
- if (packageManagerCore()->isUpdater() || packageManagerCore()->isPackageManager())
+ if (packageManagerCore()->isMaintainer())
return PackageManagerCore::ComponentSelection;
return PackageManagerPage::nextId();
@@ -1306,8 +1345,7 @@ bool IntroductionPage::validatePage()
}
gui()->setSettingsButtonEnabled(false);
- const bool maintenance = core->isUpdater() || core->isPackageManager();
- if (maintenance) {
+ if (core->isMaintainer()) {
showAll();
setMaintenanceToolsEnabled(false);
} else {
@@ -1368,7 +1406,7 @@ bool IntroductionPage::validatePage()
setComplete(true);
}
- if (maintenance) {
+ if (core->isMaintainer()) {
showMaintenanceTools();
setMaintenanceToolsEnabled(true);
} else {
@@ -1550,7 +1588,7 @@ void IntroductionPage::entering()
m_progressBar->setValue(0);
m_progressBar->setRange(0, 0);
PackageManagerCore *core = packageManagerCore();
- if (core->isUninstaller() || core->isUpdater() || core->isPackageManager()) {
+ if (core->isUninstaller() || core->isMaintainer()) {
showMaintenanceTools();
setMaintenanceToolsEnabled(true);
}
@@ -1641,8 +1679,8 @@ LicenseAgreementPage::LicenseAgreementPage(PackageManagerCore *core)
m_licenseListWidget = new QListWidget(this);
m_licenseListWidget->setObjectName(QLatin1String("LicenseListWidget"));
m_licenseListWidget->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
- connect(m_licenseListWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
- this, SLOT(currentItemChanged(QListWidgetItem*)));
+ connect(m_licenseListWidget, &QListWidget::currentItemChanged,
+ this, &LicenseAgreementPage::currentItemChanged);
m_textBrowser = new QTextBrowser(this);
m_textBrowser->setReadOnly(true);
@@ -1650,7 +1688,7 @@ LicenseAgreementPage::LicenseAgreementPage(PackageManagerCore *core)
m_textBrowser->setOpenExternalLinks(true);
m_textBrowser->setObjectName(QLatin1String("LicenseTextBrowser"));
m_textBrowser->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
- connect(m_textBrowser, SIGNAL(anchorClicked(QUrl)), this, SLOT(openLicenseUrl(QUrl)));
+ connect(m_textBrowser, &QTextBrowser::anchorClicked, this, &LicenseAgreementPage::openLicenseUrl);
QHBoxLayout *licenseBoxLayout = new QHBoxLayout();
licenseBoxLayout->addWidget(m_licenseListWidget);
@@ -1689,8 +1727,8 @@ LicenseAgreementPage::LicenseAgreementPage(PackageManagerCore *core)
gridLayout->addWidget(m_rejectLabel, 1, 1);
layout->addLayout(gridLayout);
- connect(m_acceptRadioButton, SIGNAL(toggled(bool)), this, SIGNAL(completeChanged()));
- connect(m_rejectRadioButton, SIGNAL(toggled(bool)), this, SIGNAL(completeChanged()));
+ connect(m_acceptRadioButton, &QAbstractButton::toggled, this, &QWizardPage::completeChanged);
+ connect(m_rejectRadioButton, &QAbstractButton::toggled, this, &QWizardPage::completeChanged);
m_rejectRadioButton->setChecked(true);
}
@@ -1817,7 +1855,8 @@ public:
layout->addLayout(hlayout, 1);
m_checkDefault = new QPushButton;
- connect(m_checkDefault, SIGNAL(clicked()), this, SLOT(selectDefault()));
+ connect(m_checkDefault, &QAbstractButton::clicked,
+ this, &ComponentSelectionPage::Private::selectDefault);
if (m_core->isInstaller()) {
m_checkDefault->setObjectName(QLatin1String("SelectDefaultComponentsButton"));
m_checkDefault->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+A",
@@ -1835,7 +1874,8 @@ public:
m_checkAll = new QPushButton;
hlayout->addWidget(m_checkAll);
- connect(m_checkAll, SIGNAL(clicked()), this, SLOT(selectAll()));
+ connect(m_checkAll, &QAbstractButton::clicked,
+ this, &ComponentSelectionPage::Private::selectAll);
m_checkAll->setObjectName(QLatin1String("SelectAllComponentsButton"));
m_checkAll->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+S",
"select all components")));
@@ -1843,7 +1883,8 @@ public:
m_uncheckAll = new QPushButton;
hlayout->addWidget(m_uncheckAll);
- connect(m_uncheckAll, SIGNAL(clicked()), this, SLOT(deselectAll()));
+ connect(m_uncheckAll, &QAbstractButton::clicked,
+ this, &ComponentSelectionPage::Private::deselectAll);
m_uncheckAll->setObjectName(QLatin1String("DeselectAllComponentsButton"));
m_uncheckAll->setShortcut(QKeySequence(ComponentSelectionPage::tr("Alt+D",
"deselect all components")));
@@ -1858,15 +1899,15 @@ public:
{
m_checkDefault->setVisible(m_core->isInstaller() || m_core->isPackageManager());
if (m_treeView->selectionModel()) {
- disconnect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(currentSelectedChanged(QModelIndex)));
+ disconnect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &ComponentSelectionPage::Private::currentSelectedChanged);
}
m_currentModel = m_core->isUpdater() ? m_updaterModel : m_allModel;
m_treeView->setModel(m_currentModel);
m_treeView->setExpanded(m_currentModel->index(0, 0), true);
- const bool installActionColumnVisible = false;
+ const bool installActionColumnVisible = m_core->settings().installActionColumnVisible();
if (!installActionColumnVisible)
m_treeView->hideColumn(ComponentModelHelper::ActionColumn);
@@ -1900,8 +1941,8 @@ public:
hasChildren = m_currentModel->hasChildren(m_currentModel->index(row, 0));
m_treeView->setRootIsDecorated(hasChildren);
- connect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(currentSelectedChanged(QModelIndex)));
+ connect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &ComponentSelectionPage::Private::currentSelectedChanged);
m_treeView->setCurrentIndex(m_currentModel->index(0, 0));
}
@@ -2148,19 +2189,24 @@ TargetDirectoryPage::TargetDirectoryPage(PackageManagerCore *core)
QLabel *msgLabel = new QLabel(this);
msgLabel->setWordWrap(true);
msgLabel->setObjectName(QLatin1String("MessageLabel"));
- msgLabel->setText(tr("Please specify the folder where %1 will be installed.").arg(productName()));
+ msgLabel->setText(tr("Please specify the directory where %1 will be installed.").arg(productName()));
layout->addWidget(msgLabel);
QHBoxLayout *hlayout = new QHBoxLayout;
+ m_textChangeTimer.setSingleShot(true);
+ m_textChangeTimer.setInterval(200);
+ connect(&m_textChangeTimer, &QTimer::timeout, this, &QWizardPage::completeChanged);
+
m_lineEdit = new QLineEdit(this);
m_lineEdit->setObjectName(QLatin1String("TargetDirectoryLineEdit"));
- connect(m_lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(completeChanged()));
+ connect(m_lineEdit, &QLineEdit::textChanged,
+ &m_textChangeTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
hlayout->addWidget(m_lineEdit);
QPushButton *browseButton = new QPushButton(this);
browseButton->setObjectName(QLatin1String("BrowseDirectoryButton"));
- connect(browseButton, SIGNAL(clicked()), this, SLOT(dirRequested()));
+ connect(browseButton, &QAbstractButton::clicked, this, &TargetDirectoryPage::dirRequested);
browseButton->setShortcut(QKeySequence(tr("Alt+R", "browse file system to choose a file")));
browseButton->setText(tr("B&rowse..."));
hlayout->addWidget(browseButton);
@@ -2231,6 +2277,11 @@ void TargetDirectoryPage::initializePage()
*/
bool TargetDirectoryPage::validatePage()
{
+ m_textChangeTimer.stop();
+
+ if (!isComplete())
+ return false;
+
if (!isVisible())
return true;
@@ -2256,14 +2307,14 @@ bool TargetDirectoryPage::validatePage()
QFileInfo fi2(targetDir + QDir::separator() + fileName);
if (fi2.exists()) {
- return failWithError(QLatin1String("TargetDirectoryInUse"), tr("The folder you selected already "
+ return failWithError(QLatin1String("TargetDirectoryInUse"), tr("The directory you selected already "
"exists and contains an installation. Choose a different target for installation."));
}
return askQuestion(QLatin1String("OverwriteTargetDirectory"),
- tr("You have selected an existing, non-empty folder for installation.\nNote that it will be "
+ tr("You have selected an existing, non-empty directory for installation.\nNote that it will be "
"completely wiped on uninstallation of this application.\nIt is not advisable to install into "
- "this folder as installation might fail.\nDo you want to continue?"));
+ "this directory as installation might fail.\nDo you want to continue?"));
} else if (fi.isFile() || fi.isSymLink()) {
return failWithError(QLatin1String("WrongTargetDirectory"), tr("You have selected an existing file "
"or symlink, please choose a different target for installation."));
@@ -2318,7 +2369,7 @@ bool TargetDirectoryPage::isComplete() const
QString TargetDirectoryPage::targetDirWarning() const
{
if (targetDir().isEmpty())
- return tr("The installation path cannot be empty, please specify a valid folder.");
+ return tr("The installation path cannot be empty, please specify a valid directory.");
QDir target(targetDir());
if (target.isRelative())
@@ -2381,7 +2432,7 @@ QString TargetDirectoryPage::targetDirWarning() const
}
if (nativeTargetDir.endsWith(QLatin1Char('.')))
- return tr("The installation path must not end with '.', please specify a valid folder.");
+ return tr("The installation path must not end with '.', please specify a valid directory.");
QString ambiguousChars = QLatin1String("[\"~<>|?*!@#$%^&:,; ]"
"|(\\\\CON)(\\\\|$)|(\\\\PRN)(\\\\|$)|(\\\\AUX)(\\\\|$)|(\\\\NUL)(\\\\|$)|(\\\\COM\\d)(\\\\|$)|(\\\\LPT\\d)(\\\\|$)");
@@ -2396,8 +2447,8 @@ QString TargetDirectoryPage::targetDirWarning() const
// check if there are not allowed characters in the target path
QRegularExpressionMatch match = ambCharRegEx.match(nativeTargetDir);
if (match.hasMatch()) {
- return tr("The installation path must not contain '%1', "
- "please specify a valid folder.").arg(match.captured(0));
+ return tr("The installation path must not contain \"%1\", "
+ "please specify a valid directory.").arg(match.captured(0));
}
return QString();
@@ -2442,7 +2493,7 @@ StartMenuDirectoryPage::StartMenuDirectoryPage(PackageManagerCore *core)
setObjectName(QLatin1String("StartMenuDirectoryPage"));
setColoredTitle(tr("Start Menu shortcuts"));
setColoredSubTitle(tr("Select the Start Menu in which you would like to create the program's "
- "shortcuts. You can also enter a name to create a new folder."));
+ "shortcuts. You can also enter a name to create a new directory."));
m_lineEdit = new QLineEdit(this);
m_lineEdit->setText(core->value(scStartMenuDir, productName()));
@@ -2450,7 +2501,7 @@ StartMenuDirectoryPage::StartMenuDirectoryPage(PackageManagerCore *core)
startMenuPath = core->value(QLatin1String("UserStartMenuProgramsPath"));
QStringList dirs = QDir(startMenuPath).entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
- if (core->value(QLatin1String("AllUsers")) == scTrue) {
+ if (core->value(scAllUsers, scFalse) == scTrue) {
startMenuPath = core->value(QLatin1String("AllUsersStartMenuProgramsPath"));
dirs += QDir(startMenuPath).entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
}
@@ -2466,8 +2517,8 @@ StartMenuDirectoryPage::StartMenuDirectoryPage(PackageManagerCore *core)
setLayout(layout);
- connect(m_listWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this,
- SLOT(currentItemChanged(QListWidgetItem*)));
+ connect(m_listWidget, &QListWidget::currentItemChanged, this,
+ &StartMenuDirectoryPage::currentItemChanged);
}
/*!
@@ -2573,7 +2624,7 @@ void ReadyForInstallationPage::entering()
.absolutePath())));
setComplete(true);
return;
- } else if (packageManagerCore()->isPackageManager() || packageManagerCore()->isUpdater()) {
+ } else if (packageManagerCore()->isMaintainer()) {
setButtonText(QWizard::CommitButton, tr("U&pdate"));
setColoredTitle(tr("Ready to Update Packages"));
m_msgLabel->setText(tr("Setup is now ready to begin updating your installation."));
@@ -2599,19 +2650,19 @@ void ReadyForInstallationPage::entering()
// at the moment there is no better way to check this
if (targetVolume.size() == 0 && installVolumeAvailableSize == 0) {
- qDebug() << QString::fromLatin1("Could not determine available space on device. Volume "
- "descriptor: %1, Mount path: %2. Continue silently.").arg(targetVolume
- .volumeDescriptor(), targetVolume.mountPath());
+ qDebug().nospace() << "Cannot determine available space on device. "
+ "Volume descriptor: " << targetVolume.volumeDescriptor()
+ << ", Mount path: " << targetVolume.mountPath() << ". Continue silently.";
return; // TODO: Shouldn't this also disable the "Next" button?
}
const bool tempOnSameVolume = (targetVolume == tempVolume);
if (tempOnSameVolume) {
- qDebug() << "Tmp and install folder are on the same volume. Volume mount point:"
+ qDebug() << "Tmp and install directories are on the same volume. Volume mount point:"
<< targetVolume.mountPath() << "Free space available:"
<< humanReadableSize(installVolumeAvailableSize);
} else {
- qDebug() << "Tmp is on a different volume than the install folder. Tmp volume mount point:"
+ qDebug() << "Tmp is on a different volume than the installation directory. Tmp volume mount point:"
<< tempVolume.mountPath() << "Free space available:"
<< humanReadableSize(tempVolumeAvailableSize) << "Install volume mount point:"
<< targetVolume.mountPath() << "Free space available:"
@@ -2643,7 +2694,7 @@ void ReadyForInstallationPage::entering()
if (tempOnSameVolume && (installVolumeAvailableSize <= (required + tempRequired))) {
m_msgLabel->setText(tr("Not enough disk space to store temporary files and the "
- "installation! Available space: %1, at least required %2.")
+ "installation. %1 are available, while %2 are at least required.")
.arg(humanReadableSize(installVolumeAvailableSize),
humanReadableSize(required + tempRequired)));
setComplete(false);
@@ -2651,16 +2702,16 @@ void ReadyForInstallationPage::entering()
}
if (installVolumeAvailableSize < required) {
- m_msgLabel->setText(tr("Not enough disk space to store all selected components! Available "
- "space: %1, at least required: %2.").arg(humanReadableSize(installVolumeAvailableSize),
+ m_msgLabel->setText(tr("Not enough disk space to store all selected components! %1 are available "
+ "while %2 are at least required.").arg(humanReadableSize(installVolumeAvailableSize),
humanReadableSize(required)));
setComplete(false);
return;
}
if (tempVolumeAvailableSize < tempRequired) {
- m_msgLabel->setText(tr("Not enough disk space to store temporary files! Available space: "
- "%1, at least required: %2.").arg(humanReadableSize(tempVolumeAvailableSize),
+ m_msgLabel->setText(tr("Not enough disk space to store temporary files! %1 are available "
+ "while %2 are at least required.").arg(humanReadableSize(tempVolumeAvailableSize),
humanReadableSize(tempRequired)));
setComplete(false);
return;
@@ -2774,22 +2825,27 @@ PerformInstallationPage::PerformInstallationPage(PackageManagerCore *core)
m_performInstallationForm->setupUi(this);
- connect(ProgressCoordinator::instance(), SIGNAL(detailTextChanged(QString)),
- m_performInstallationForm, SLOT(appendProgressDetails(QString)));
- connect(ProgressCoordinator::instance(), SIGNAL(detailTextResetNeeded()),
- m_performInstallationForm, SLOT(clearDetailsBrowser()));
- connect(m_performInstallationForm, SIGNAL(showDetailsChanged()), this,
- SLOT(toggleDetailsWereChanged()));
+ connect(ProgressCoordinator::instance(), &ProgressCoordinator::detailTextChanged,
+ m_performInstallationForm, &PerformInstallationForm::appendProgressDetails);
+ connect(ProgressCoordinator::instance(), &ProgressCoordinator::detailTextResetNeeded,
+ m_performInstallationForm, &PerformInstallationForm::clearDetailsBrowser);
+ connect(m_performInstallationForm, &PerformInstallationForm::showDetailsChanged,
+ this, &PerformInstallationPage::toggleDetailsWereChanged);
- connect(core, SIGNAL(installationStarted()), this, SLOT(installationStarted()));
- connect(core, SIGNAL(installationFinished()), this, SLOT(installationFinished()));
+ connect(core, &PackageManagerCore::installationStarted,
+ this, &PerformInstallationPage::installationStarted);
+ connect(core, &PackageManagerCore::installationFinished,
+ this, &PerformInstallationPage::installationFinished);
- connect(core, SIGNAL(uninstallationStarted()), this, SLOT(uninstallationStarted()));
- connect(core, SIGNAL(uninstallationFinished()), this, SLOT(uninstallationFinished()));
+ connect(core, &PackageManagerCore::uninstallationStarted,
+ this, &PerformInstallationPage::uninstallationStarted);
+ connect(core, &PackageManagerCore::uninstallationFinished,
+ this, &PerformInstallationPage::uninstallationFinished);
- connect(core, SIGNAL(titleMessageChanged(QString)), this, SLOT(setTitleMessage(QString)));
- connect(this, SIGNAL(setAutomatedPageSwitchEnabled(bool)), core,
- SIGNAL(setAutomatedPageSwitchEnabled(bool)));
+ connect(core, &PackageManagerCore::titleMessageChanged,
+ this, &PerformInstallationPage::setTitleMessage);
+ connect(this, &PerformInstallationPage::setAutomatedPageSwitchEnabled,
+ core, &PackageManagerCore::setAutomatedPageSwitchEnabled);
m_performInstallationForm->setDetailsWidgetVisible(true);
@@ -2828,7 +2884,7 @@ void PerformInstallationPage::entering()
setColoredTitle(tr("Uninstalling %1").arg(productName()));
QTimer::singleShot(30, packageManagerCore(), SLOT(runUninstaller()));
- } else if (packageManagerCore()->isPackageManager() || packageManagerCore()->isUpdater()) {
+ } else if (packageManagerCore()->isMaintainer()) {
setButtonText(QWizard::CommitButton, tr("&Update"));
setColoredTitle(tr("Updating components of %1").arg(productName()));
@@ -2954,11 +3010,11 @@ FinishedPage::FinishedPage(PackageManagerCore *core)
void FinishedPage::entering()
{
if (m_commitButton) {
- disconnect(m_commitButton, SIGNAL(clicked()), this, SLOT(handleFinishClicked()));
+ disconnect(m_commitButton, &QAbstractButton::clicked, this, &FinishedPage::handleFinishClicked);
m_commitButton = 0;
}
- if (packageManagerCore()->isUpdater() || packageManagerCore()->isPackageManager()) {
+ if (packageManagerCore()->isMaintainer()) {
#ifdef Q_OS_OSX
gui()->setOption(QWizard::NoCancelButton, false);
#endif
@@ -2967,13 +3023,13 @@ void FinishedPage::entering()
cancel->setEnabled(true);
cancel->setVisible(true);
// we don't use the usual FinishButton so we need to connect the misused CancelButton
- connect(cancel, SIGNAL(clicked()), gui(), SIGNAL(finishButtonClicked()));
- connect(cancel, SIGNAL(clicked()), packageManagerCore(), SIGNAL(finishButtonClicked()));
+ connect(cancel, &QAbstractButton::clicked, gui(), &PackageManagerGui::finishButtonClicked);
+ connect(cancel, &QAbstractButton::clicked, packageManagerCore(), &PackageManagerCore::finishButtonClicked);
// for the moment we don't want the rejected signal connected
- disconnect(gui(), SIGNAL(rejected()), packageManagerCore(), SLOT(setCanceled()));
+ disconnect(gui(), &QDialog::rejected, packageManagerCore(), &PackageManagerCore::setCanceled);
- connect(gui()->button(QWizard::CommitButton), SIGNAL(clicked()), this,
- SLOT(cleanupChangedConnects()));
+ connect(gui()->button(QWizard::CommitButton), &QAbstractButton::clicked,
+ this, &FinishedPage::cleanupChangedConnects);
}
setButtonText(QWizard::CommitButton, tr("Restart"));
setButtonText(QWizard::CancelButton, gui()->defaultButtonText(QWizard::FinishButton));
@@ -2992,8 +3048,8 @@ void FinishedPage::entering()
gui()->updateButtonLayout();
if (m_commitButton) {
- disconnect(m_commitButton, SIGNAL(clicked()), this, SLOT(handleFinishClicked()));
- connect(m_commitButton, SIGNAL(clicked()), this, SLOT(handleFinishClicked()));
+ disconnect(m_commitButton, &QAbstractButton::clicked, this, &FinishedPage::handleFinishClicked);
+ connect(m_commitButton, &QAbstractButton::clicked, this, &FinishedPage::handleFinishClicked);
}
if (packageManagerCore()->status() == PackageManagerCore::Success) {
@@ -3060,12 +3116,12 @@ void FinishedPage::cleanupChangedConnects()
{
if (QAbstractButton *cancel = gui()->button(QWizard::CancelButton)) {
// remove the workaround connect from entering page
- disconnect(cancel, SIGNAL(clicked()), gui(), SIGNAL(finishButtonClicked()));
- disconnect(cancel, SIGNAL(clicked()), packageManagerCore(), SIGNAL(finishButtonClicked()));
- connect(gui(), SIGNAL(rejected()), packageManagerCore(), SLOT(setCanceled()));
+ disconnect(cancel, &QAbstractButton::clicked, gui(), &PackageManagerGui::finishButtonClicked);
+ disconnect(cancel, &QAbstractButton::clicked, packageManagerCore(), &PackageManagerCore::finishButtonClicked);
+ connect(gui(), &QDialog::rejected, packageManagerCore(), &PackageManagerCore::setCanceled);
- disconnect(gui()->button(QWizard::CommitButton), SIGNAL(clicked()), this,
- SLOT(cleanupChangedConnects()));
+ disconnect(gui()->button(QWizard::CommitButton), &QAbstractButton::clicked,
+ this, &FinishedPage::cleanupChangedConnects);
}
}
diff --git a/src/libs/installer/packagemanagergui.h b/src/libs/installer/packagemanagergui.h
index f56dbb645..8faa75263 100644
--- a/src/libs/installer/packagemanagergui.h
+++ b/src/libs/installer/packagemanagergui.h
@@ -38,6 +38,7 @@
#include <QtCore/QEvent>
#include <QtCore/QMetaType>
+#include <QtCore/QTimer>
#include <QWizard>
#include <QWizardPage>
@@ -92,6 +93,9 @@ public:
void updateButtonLayout();
static QWizard::WizardStyle getStyle(const QString &name);
+ void setSilent(bool silent);
+ bool isSilent() const;
+
Q_SIGNALS:
void interrupted();
void languageChanged();
@@ -352,6 +356,7 @@ private:
private:
QLineEdit *m_lineEdit;
QLabel *m_warningLabel;
+ QTimer m_textChangeTimer;
};
diff --git a/src/libs/installer/packagemanagerpagefactory.cpp b/src/libs/installer/packagemanagerpagefactory.cpp
index a046284a3..7106864c0 100644
--- a/src/libs/installer/packagemanagerpagefactory.cpp
+++ b/src/libs/installer/packagemanagerpagefactory.cpp
@@ -41,9 +41,4 @@ PackageManagerPageFactory &PackageManagerPageFactory::instance()
return factory;
}
-PackageManagerPage *PackageManagerPageFactory::create(int id, PackageManagerCore *core) const
-{
- return KDGenericFactory<PackageManagerPage, int, PackageManagerCore*>::createWithArg(id, core);
-}
-
}
diff --git a/src/libs/installer/packagemanagerpagefactory.h b/src/libs/installer/packagemanagerpagefactory.h
index 6ac37732b..57056c375 100644
--- a/src/libs/installer/packagemanagerpagefactory.h
+++ b/src/libs/installer/packagemanagerpagefactory.h
@@ -34,16 +34,16 @@
#ifndef PACKAGEMANAGERPAGEFACTORY_H
#define PACKAGEMANAGERPAGEFACTORY_H
-#include <kdgenericfactory.h>
-#include <packagemanagergui.h>
+#include "genericfactory.h"
+#include "qinstallerglobal.h"
namespace QInstaller {
class PackageManagerCore;
class PackageManagerPage;
-class INSTALLER_EXPORT PackageManagerPageFactory : public KDGenericFactory<PackageManagerPage,
- int, QInstaller::PackageManagerCore*>
+class INSTALLER_EXPORT PackageManagerPageFactory : public GenericFactory<PackageManagerPage, int,
+ PackageManagerCore*>
{
Q_DISABLE_COPY(PackageManagerPageFactory)
@@ -51,12 +51,11 @@ public:
static PackageManagerPageFactory &instance();
template<typename T> void registerPackageManagerPage(int id)
{
- registerProductWithArg<T>(id);
+ registerProduct<T>(id);
}
- PackageManagerPage *create(int id, QInstaller::PackageManagerCore *core) const;
private:
- PackageManagerPageFactory() {}
+ PackageManagerPageFactory() = default;
};
} // namespace QInstaller
diff --git a/src/libs/installer/packagemanagerproxyfactory.cpp b/src/libs/installer/packagemanagerproxyfactory.cpp
index 56ca0b851..df9c3b443 100644
--- a/src/libs/installer/packagemanagerproxyfactory.cpp
+++ b/src/libs/installer/packagemanagerproxyfactory.cpp
@@ -120,7 +120,7 @@ void PackageManagerProxyFactory::setProxyCredentials(const QNetworkProxy &proxy,
auto p = std::find_if(m_proxyCredentials.begin(), m_proxyCredentials.end(),
FindProxyCredential(proxy.hostName(), proxy.port()));
- if (p == m_proxyCredentials.constEnd()) {
+ if (p == m_proxyCredentials.end()) {
ProxyCredential proxyCredential;
proxyCredential.host = proxy.hostName();
proxyCredential.port = proxy.port();
diff --git a/src/libs/installer/packagemanagerproxyfactory.h b/src/libs/installer/packagemanagerproxyfactory.h
index 765debfca..a2ba09103 100644
--- a/src/libs/installer/packagemanagerproxyfactory.h
+++ b/src/libs/installer/packagemanagerproxyfactory.h
@@ -34,7 +34,7 @@
#ifndef PACKAGEMANAGERPROXYFACTORY_H
#define PACKAGEMANAGERPROXYFACTORY_H
-#include "kdupdaterfiledownloaderfactory.h"
+#include "filedownloaderfactory.h"
namespace QInstaller {
diff --git a/src/libs/installer/packagesource.cpp b/src/libs/installer/packagesource.cpp
new file mode 100644
index 000000000..f60c5c8e1
--- /dev/null
+++ b/src/libs/installer/packagesource.cpp
@@ -0,0 +1,91 @@
+/**************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see http://qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "packagesource.h"
+
+namespace QInstaller {
+
+/*!
+ \inmodule QtInstallerFramework
+ \class QInstaller::PackageSource
+ \brief The PackageSource class specifies a single package source.
+
+ An package source represents a link to an repository that contains packages applicable by
+ the installer or package maintenance application. This structure describes a single package
+ source in terms of url and priority. While different repositories can host the same packages,
+ packages coming from a higher priority source take precedence over lower priority packages
+ during applicable package computation.
+*/
+
+/*!
+ \fn PackageSource::PackageSource()
+
+ Constructs an empty package source info object. The object's priority is set to -1. The url is
+ initialized using a \l{default-constructed value}.
+*/
+
+/*!
+ \fn PackageSource::PackageSource(const QUrl &u, int p)
+
+ Constructs an package source info object. The object's url is set to \a u, while the priority
+ is set to \a p.
+*/
+
+/*!
+ \variable PackageSource::url
+ \brief The URL of the package source.
+*/
+
+/*!
+ \variable PackageSource::priority
+ \brief The priority of the package source.
+*/
+
+/*!
+ Returns the hash value for the \a key, using \a seed to seed the calculation.
+*/
+uint qHash(const PackageSource &key, uint seed)
+{
+ return qHash(key.url, seed) ^ key.priority;
+}
+
+/*!
+ Returns \c true if \a lhs and \a rhs are equal; otherwise returns \c false.
+*/
+bool operator==(const PackageSource &lhs, const PackageSource &rhs)
+{
+ return lhs.url == rhs.url && lhs.priority == rhs.priority;
+}
+
+} // namespace QInstaller
diff --git a/src/libs/installer/packagesource.h b/src/libs/installer/packagesource.h
new file mode 100644
index 000000000..6bc565c15
--- /dev/null
+++ b/src/libs/installer/packagesource.h
@@ -0,0 +1,63 @@
+/**************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see http://qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#ifndef PACKAGESOURCE_H
+#define PACKAGESOURCE_H
+
+#include "installer_global.h"
+
+#include <QUrl>
+
+namespace QInstaller {
+
+struct INSTALLER_EXPORT PackageSource
+{
+ PackageSource()
+ : priority(-1)
+ {}
+ PackageSource(const QUrl &u, int p)
+ : url(u)
+ , priority(p)
+ {}
+
+ QUrl url;
+ int priority;
+};
+
+INSTALLER_EXPORT uint qHash(const PackageSource &key, uint seed);
+INSTALLER_EXPORT bool operator==(const PackageSource &lhs, const PackageSource &rhs);
+
+} // namespace QInstaller
+
+#endif // PACKAGESOURCE_H
diff --git a/src/libs/installer/performinstallationform.cpp b/src/libs/installer/performinstallationform.cpp
index d9a99e71c..dbf059c94 100644
--- a/src/libs/installer/performinstallationform.cpp
+++ b/src/libs/installer/performinstallationform.cpp
@@ -122,13 +122,13 @@ void PerformInstallationForm::setupUi(QWidget *widget)
m_downloadStatus->setObjectName(QLatin1String("DownloadStatus"));
m_downloadStatus->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
topLayout->addWidget(m_downloadStatus);
- connect(ProgressCoordinator::instance(), SIGNAL(downloadStatusChanged(QString)), this,
- SLOT(onDownloadStatusChanged(QString)));
+ connect(ProgressCoordinator::instance(), &ProgressCoordinator::downloadStatusChanged, this,
+ &PerformInstallationForm::onDownloadStatusChanged);
m_detailsButton = new QPushButton(tr("&Show Details"), widget);
m_detailsButton->setObjectName(QLatin1String("DetailsButton"));
m_detailsButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
- connect(m_detailsButton, SIGNAL(clicked()), this, SLOT(toggleDetails()));
+ connect(m_detailsButton, &QAbstractButton::clicked, this, &PerformInstallationForm::toggleDetails);
topLayout->addWidget(m_detailsButton);
QVBoxLayout *bottomLayout = new QVBoxLayout();
@@ -147,7 +147,8 @@ void PerformInstallationForm::setupUi(QWidget *widget)
baseLayout->addLayout(bottomLayout);
m_updateTimer = new QTimer(widget);
- connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateProgress())); //updateProgress includes label
+ connect(m_updateTimer, &QTimer::timeout,
+ this, &PerformInstallationForm::updateProgress); //updateProgress includes label
m_updateTimer->setInterval(30);
m_progressBar->setRange(0, 100);
@@ -181,7 +182,7 @@ void PerformInstallationForm::updateProgress()
m_progressBar->setValue(progressPercentage);
#ifdef Q_OS_WIN
if (m_taskButton) {
- if (!m_taskButton->window())
+ if (!m_taskButton->window() && QApplication::activeWindow())
m_taskButton->setWindow(QApplication::activeWindow()->windowHandle());
m_taskButton->progress()->setValue(progressPercentage);
}
diff --git a/src/libs/installer/progresscoordinator.cpp b/src/libs/installer/progresscoordinator.cpp
index b2552126d..7dfffed59 100644
--- a/src/libs/installer/progresscoordinator.cpp
+++ b/src/libs/installer/progresscoordinator.cpp
@@ -106,7 +106,7 @@ void ProgressCoordinator::registerPartProgress(QObject *sender, const char *sign
void ProgressCoordinator::partProgressChanged(double fraction)
{
if (fraction < 0 || fraction > 1) {
- qWarning() << "The fraction is outside from possible value:" << QString::number(fraction);
+ qWarning() << "The fraction is outside from possible value:" << fraction;
return;
}
diff --git a/src/libs/installer/proxycredentialsdialog.h b/src/libs/installer/proxycredentialsdialog.h
index f4935c53d..046d246f5 100644
--- a/src/libs/installer/proxycredentialsdialog.h
+++ b/src/libs/installer/proxycredentialsdialog.h
@@ -35,7 +35,7 @@
#include <QDialog>
-class QNetworkProxy;
+QT_FORWARD_DECLARE_CLASS(QNetworkProxy)
namespace QInstaller {
diff --git a/src/libs/installer/qinstallerglobal.h b/src/libs/installer/qinstallerglobal.h
index af3866d01..d6b08de7b 100644
--- a/src/libs/installer/qinstallerglobal.h
+++ b/src/libs/installer/qinstallerglobal.h
@@ -36,9 +36,9 @@
#include <installer_global.h>
-#include <kdupdaterupdate.h>
-#include <kdupdaterupdateoperation.h>
-#include <kdupdaterpackagesinfo.h>
+#include "update.h"
+#include "updateoperation.h"
+#include "localpackagehub.h"
namespace QInstaller {
@@ -60,8 +60,7 @@ typedef QList<QInstaller::Operation*> OperationList;
typedef KDUpdater::Update Package;
typedef QList<QInstaller::Package*> PackagesList;
-typedef KDUpdater::PackageInfo LocalPackage;
-typedef QHash<QString, LocalPackage> LocalPackagesHash;
+typedef QHash<QString, KDUpdater::LocalPackage> LocalPackagesHash;
} // namespace QInstaller
diff --git a/src/libs/installer/qprocesswrapper.cpp b/src/libs/installer/qprocesswrapper.cpp
index 40291719e..ca9abdea3 100644
--- a/src/libs/installer/qprocesswrapper.cpp
+++ b/src/libs/installer/qprocesswrapper.cpp
@@ -48,20 +48,17 @@ QProcessWrapper::QProcessWrapper(QObject *parent)
qRegisterMetaType<QProcess::ProcessState>();
m_timer.start(250);
- connect(&m_timer, SIGNAL(timeout()), this, SLOT(processSignals()));
- connect(&process, SIGNAL(bytesWritten(qint64)), SIGNAL(bytesWritten(qint64)));
- connect(&process, SIGNAL(aboutToClose()), SIGNAL(aboutToClose()));
- connect(&process, SIGNAL(readChannelFinished()), SIGNAL(readChannelFinished()));
+ connect(&m_timer, &QTimer::timeout, this, &QProcessWrapper::processSignals);
+ connect(&process, &QIODevice::bytesWritten, this, &QProcessWrapper::bytesWritten);
+ connect(&process, &QIODevice::aboutToClose, this, &QProcessWrapper::aboutToClose);
+ connect(&process, &QIODevice::readChannelFinished, this, &QProcessWrapper::readChannelFinished);
connect(&process, SIGNAL(error(QProcess::ProcessError)), SIGNAL(error(QProcess::ProcessError)));
- connect(&process, SIGNAL(readyReadStandardOutput()), SIGNAL(readyReadStandardOutput()));
- connect(&process, SIGNAL(readyReadStandardError()), SIGNAL(readyReadStandardError()));
- connect(&process, SIGNAL(finished(int)), SIGNAL(finished(int)));
- connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)),
- SIGNAL(finished(int,QProcess::ExitStatus)));
- connect(&process, SIGNAL(readyRead()), SIGNAL(readyRead()));
- connect(&process, SIGNAL(started()), SIGNAL(started()));
- connect(&process, SIGNAL(stateChanged(QProcess::ProcessState)),
- SIGNAL(stateChanged(QProcess::ProcessState)));
+ connect(&process, &QProcess::readyReadStandardOutput, this, &QProcessWrapper::readyReadStandardOutput);
+ connect(&process, &QProcess::readyReadStandardError, this, &QProcessWrapper::readyReadStandardError);
+ connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)), SIGNAL(finished(int,QProcess::ExitStatus)));
+ connect(&process, &QIODevice::readyRead, this, &QProcessWrapper::readyRead);
+ connect(&process, &QProcess::started, this, &QProcessWrapper::started);
+ connect(&process, &QProcess::stateChanged, this, &QProcessWrapper::stateChanged);
}
QProcessWrapper::~QProcessWrapper()
@@ -102,7 +99,6 @@ void QProcessWrapper::processSignals()
emit stateChanged(static_cast<QProcess::ProcessState> (receivedSignals.takeFirst()
.toInt()));
} else if (name == QLatin1String(Protocol::QProcessSignalFinished)) {
- emit finished(receivedSignals.first().toInt());
emit finished(receivedSignals.takeFirst().toInt(),
static_cast<QProcess::ExitStatus> (receivedSignals.takeFirst().toInt()));
}
diff --git a/src/libs/installer/qprocesswrapper.h b/src/libs/installer/qprocesswrapper.h
index c80281ff8..7277b33ce 100644
--- a/src/libs/installer/qprocesswrapper.h
+++ b/src/libs/installer/qprocesswrapper.h
@@ -122,7 +122,6 @@ Q_SIGNALS:
void error(QProcess::ProcessError);
void readyReadStandardOutput();
void readyReadStandardError();
- void finished(int exitCode);
void finished(int exitCode, QProcess::ExitStatus exitStatus);
void readyRead();
void started();
diff --git a/src/libs/installer/qtpatch.cpp b/src/libs/installer/qtpatch.cpp
index 28c514fc4..17abe8a7b 100644
--- a/src/libs/installer/qtpatch.cpp
+++ b/src/libs/installer/qtpatch.cpp
@@ -90,8 +90,8 @@ QHash<QString, QByteArray> QtPatch::qmakeValues(const QString &qmakePath, QByteA
if (process.exitStatus() == QProcess::CrashExit) {
qWarning() << qmake.absoluteFilePath() << args
<< "crashed with exit code" << process.exitCode()
- << "standard output: " << output
- << "error output: " << process.readAllStandardError();
+ << "standard output:" << output
+ << "error output:" << process.readAllStandardError();
return qmakeValueHash;
}
qmakeValueHash = readQmakeOutput(output);
@@ -125,7 +125,7 @@ bool QtPatch::patchBinaryFile(const QString &fileName,
openFileForPatching(&file);
if (!file.isOpen()) {
qDebug() << "qpatch: warning: file" << qPrintable(fileName) << "cannot open.";
- qDebug() << qPrintable(file.errorString());
+ qDebug().noquote() << file.errorString();
return false;
}
@@ -173,8 +173,7 @@ bool QtPatch::patchTextFile(const QString &fileName,
QFile file(fileName);
if (!file.open(QFile::ReadOnly)) {
- qDebug() << QString::fromLatin1("qpatch: warning: Open the file '%1' stopped: %2").arg(
- fileName, file.errorString());
+ qDebug() << "Cannot open file" << fileName << "for patching:" << file.errorString();
return false;
}
@@ -188,7 +187,7 @@ bool QtPatch::patchTextFile(const QString &fileName,
}
if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
- qDebug() << QString::fromLatin1("qpatch: error: file '%1' not writable").arg(fileName);
+ qDebug() << "File" << fileName << "not writable.";
return false;
}
@@ -208,7 +207,6 @@ bool QtPatch::openFileForPatching(QFile *file)
}
return file->openMode() == QFile::ReadWrite;
}
- qDebug() << QString::fromLatin1("qpatch: error: File '%1 is open, so it cannot be opened again.").arg(
- file->fileName());
+ qDebug() << "File" << file->fileName() << "is open, so it cannot be opened again.";
return false;
}
diff --git a/src/libs/installer/registerfiletypeoperation.cpp b/src/libs/installer/registerfiletypeoperation.cpp
index 936bbeb25..89d1934c3 100644
--- a/src/libs/installer/registerfiletypeoperation.cpp
+++ b/src/libs/installer/registerfiletypeoperation.cpp
@@ -33,6 +33,7 @@
#include "registerfiletypeoperation.h"
+#include "constants.h"
#include "packagemanagercore.h"
#include "qsettingswrapper.h"
@@ -78,7 +79,8 @@ static QVariantHash readHive(QSettingsWrapper *const settings, const QString &hi
// -- RegisterFileTypeOperation
-RegisterFileTypeOperation::RegisterFileTypeOperation()
+RegisterFileTypeOperation::RegisterFileTypeOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("RegisterFileType"));
}
@@ -93,16 +95,12 @@ bool RegisterFileTypeOperation::performOperation()
QStringList args = arguments();
QString progId = takeProgIdArgument(args);
- if (args.count() < 2 || args.count() > 5) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("2 to 5"), QLatin1String("")));
+ if (!checkArgumentCount(2, 5, tr("<extension> <command> [description [contentType [icon]]]")))
return false;
- }
bool allUsers = false;
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
- if (core && core->value(QLatin1String("AllUsers")) == QLatin1String("true"))
+ PackageManagerCore *const core = packageManager();
+ if (core && core->value(scAllUsers) == scTrue)
allUsers = true;
QSettingsWrapper settings(QLatin1String(allUsers ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER")
@@ -165,8 +163,8 @@ bool RegisterFileTypeOperation::undoOperation()
}
bool allUsers = false;
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
- if (core && core->value(QLatin1String("AllUsers")) == QLatin1String("true"))
+ PackageManagerCore *const core = packageManager();
+ if (core && core->value(scAllUsers) == scTrue)
allUsers = true;
QSettingsWrapper settings(QLatin1String(allUsers ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER")
@@ -220,8 +218,3 @@ bool RegisterFileTypeOperation::testOperation()
{
return true;
}
-
-Operation *RegisterFileTypeOperation::clone() const
-{
- return new RegisterFileTypeOperation();
-}
diff --git a/src/libs/installer/registerfiletypeoperation.h b/src/libs/installer/registerfiletypeoperation.h
index e595b8262..0c50ab02b 100644
--- a/src/libs/installer/registerfiletypeoperation.h
+++ b/src/libs/installer/registerfiletypeoperation.h
@@ -43,13 +43,12 @@ class INSTALLER_EXPORT RegisterFileTypeOperation : public QObject, public Operat
Q_OBJECT
public:
- RegisterFileTypeOperation();
+ explicit RegisterFileTypeOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
}
diff --git a/src/libs/installer/remoteclient.cpp b/src/libs/installer/remoteclient.cpp
index 8a9d4cdc8..59a236635 100644
--- a/src/libs/installer/remoteclient.cpp
+++ b/src/libs/installer/remoteclient.cpp
@@ -36,6 +36,8 @@
namespace QInstaller {
+RemoteClient *RemoteClient::s_instance = 0;
+
RemoteClient::RemoteClient()
: d_ptr(new RemoteClientPrivate(this))
{
@@ -47,8 +49,9 @@ RemoteClient::~RemoteClient()
RemoteClient &RemoteClient::instance()
{
- static RemoteClient instance;
- return instance;
+ if (!s_instance)
+ s_instance = new RemoteClient;
+ return *s_instance;
}
QString RemoteClient::socketName() const
@@ -81,6 +84,12 @@ void RemoteClient::shutdown()
d_ptr.reset(new RemoteClientPrivate(this));
}
+void RemoteClient::destroy()
+{
+ delete s_instance;
+ s_instance = 0;
+}
+
bool RemoteClient::isActive() const
{
Q_D(const RemoteClient);
diff --git a/src/libs/installer/remoteclient.h b/src/libs/installer/remoteclient.h
index 75cdd12c0..278132ba8 100644
--- a/src/libs/installer/remoteclient.h
+++ b/src/libs/installer/remoteclient.h
@@ -54,6 +54,7 @@ public:
Protocol::StartAs startAs);
void shutdown();
+ void destroy();
QString socketName() const;
QString authorizationKey() const;
@@ -66,6 +67,7 @@ private:
~RemoteClient();
private:
+ static RemoteClient *s_instance;
QScopedPointer<RemoteClientPrivate> d_ptr;
};
diff --git a/src/libs/installer/remoteclient_p.h b/src/libs/installer/remoteclient_p.h
index 0edfdab41..e88d0579d 100644
--- a/src/libs/installer/remoteclient_p.h
+++ b/src/libs/installer/remoteclient_p.h
@@ -131,11 +131,11 @@ public:
const QMessageBox::Button res =
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
QLatin1String("AuthorizationError"),
- QCoreApplication::translate("RemoteClient", "Could not get authorization."),
- QCoreApplication::translate("RemoteClient", "Could not get authorization that "
+ QCoreApplication::translate("RemoteClient", "Cannot get authorization."),
+ QCoreApplication::translate("RemoteClient", "Cannot get authorization that "
"is needed for continuing the installation.\n Either abort the "
- "installation or use the fallback solution by running\n\n%1\n\nas root "
- "and then clicking OK.").arg(fallback),
+ "installation or use the fallback solution by running\n\n%1\n\nas a user "
+ "with the appropriate rights and then clicking OK.").arg(fallback),
QMessageBox::Abort | QMessageBox::Ok, QMessageBox::Ok);
if (res == QMessageBox::Ok)
diff --git a/src/libs/installer/remoteobject.h b/src/libs/installer/remoteobject.h
index a09bede67..72c20eaa4 100644
--- a/src/libs/installer/remoteobject.h
+++ b/src/libs/installer/remoteobject.h
@@ -96,7 +96,7 @@ public:
QByteArray data;
while (!receivePacket(m_socket, &command, &data)) {
if (!m_socket->waitForReadyRead(-1)) {
- throw Error(tr("Could not read all data after sending command: %1. "
+ throw Error(tr("Cannot read all data after sending command: %1. "
"Bytes expected: %2, Bytes received: %3. Error: %4").arg(name).arg(0)
.arg(m_socket->bytesAvailable()).arg(m_socket->errorString()));
}
diff --git a/src/libs/installer/remoteserver.cpp b/src/libs/installer/remoteserver.cpp
index 3ecc90f02..dfb622bbf 100644
--- a/src/libs/installer/remoteserver.cpp
+++ b/src/libs/installer/remoteserver.cpp
@@ -80,13 +80,13 @@ void RemoteServer::start()
d->m_localServer = new LocalServer(d->m_socketName, d->m_key);
d->m_localServer->moveToThread(&d->m_thread);
- connect(&d->m_thread, SIGNAL(finished()), d->m_localServer, SLOT(deleteLater()));
- connect(d->m_localServer, SIGNAL(newIncomingConnection()), this, SLOT(restartWatchdog()));
- connect(d->m_localServer, SIGNAL(shutdownRequested()), this, SLOT(deleteLater()));
+ connect(&d->m_thread, &QThread::finished, d->m_localServer, &QObject::deleteLater);
+ connect(d->m_localServer, &LocalServer::newIncomingConnection, this, &RemoteServer::restartWatchdog);
+ connect(d->m_localServer, &LocalServer::shutdownRequested, this, &QObject::deleteLater);
d->m_thread.start();
if (d->m_mode == Protocol::Mode::Production) {
- connect(d->m_watchdog.data(), SIGNAL(timeout()), this, SLOT(deleteLater()));
+ connect(d->m_watchdog.data(), &QTimer::timeout, this, &QObject::deleteLater);
d->m_watchdog->start();
}
}
diff --git a/src/libs/installer/remoteserver_p.h b/src/libs/installer/remoteserver_p.h
index b069e1331..bbd83e117 100644
--- a/src/libs/installer/remoteserver_p.h
+++ b/src/libs/installer/remoteserver_p.h
@@ -84,9 +84,9 @@ private:
if (m_shutdown)
return;
- QThread *const thread = new RemoteServerConnection(socketDescriptor, m_key, this);
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- connect(thread, SIGNAL(shutdownRequested()), this, SLOT(shutdown()));
+ RemoteServerConnection *thread = new RemoteServerConnection(socketDescriptor, m_key, this);
+ connect(thread, &QThread::finished, thread, &QObject::deleteLater);
+ connect(thread, &RemoteServerConnection::shutdownRequested, this, &LocalServer::shutdown);
thread->start();
emit newIncomingConnection();
}
diff --git a/src/libs/installer/remoteserverconnection_p.h b/src/libs/installer/remoteserverconnection_p.h
index 00eaf1a9e..0c94c5f5d 100644
--- a/src/libs/installer/remoteserverconnection_p.h
+++ b/src/libs/installer/remoteserverconnection_p.h
@@ -51,19 +51,21 @@ private:
explicit QProcessSignalReceiver(QProcess *process)
: QObject(process)
{
- connect(process, SIGNAL(bytesWritten(qint64)), SLOT(onBytesWritten(qint64)));
- connect(process, SIGNAL(aboutToClose()), SLOT(onAboutToClose()));
- connect(process, SIGNAL(readChannelFinished()), SLOT(onReadChannelFinished()));
+ connect(process, &QIODevice::bytesWritten, this, &QProcessSignalReceiver::onBytesWritten);
+ connect(process, &QIODevice::aboutToClose, this, &QProcessSignalReceiver::onAboutToClose);
+ connect(process, &QIODevice::readChannelFinished, this, &QProcessSignalReceiver::onReadChannelFinished);
connect(process, SIGNAL(error(QProcess::ProcessError)),
SLOT(onError(QProcess::ProcessError)));
- connect(process, SIGNAL(readyReadStandardOutput()), SLOT(onReadyReadStandardOutput()));
- connect(process, SIGNAL(readyReadStandardError()), SLOT(onReadyReadStandardError()));
- connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
- SLOT(onFinished(int, QProcess::ExitStatus)));
- connect(process, SIGNAL(readyRead()), SLOT(onReadyRead()));
- connect(process, SIGNAL(started()), SLOT(onStarted()));
- connect(process, SIGNAL(stateChanged(QProcess::ProcessState)),
- SLOT(onStateChanged(QProcess::ProcessState)));
+ connect(process, &QProcess::readyReadStandardOutput,
+ this, &QProcessSignalReceiver::onReadyReadStandardOutput);
+ connect(process, &QProcess::readyReadStandardError,
+ this, &QProcessSignalReceiver::onReadyReadStandardError);
+ connect(process, SIGNAL(finished(int,QProcess::ExitStatus)),
+ SLOT(onFinished(int,QProcess::ExitStatus)));
+ connect(process, &QIODevice::readyRead, this, &QProcessSignalReceiver::onReadyRead);
+ connect(process, &QProcess::started, this, &QProcessSignalReceiver::onStarted);
+ connect(process, &QProcess::stateChanged,
+ this, &QProcessSignalReceiver::onStateChanged);
}
private Q_SLOTS:
diff --git a/src/libs/installer/replaceoperation.cpp b/src/libs/installer/replaceoperation.cpp
index a3f470d5d..55d501278 100644
--- a/src/libs/installer/replaceoperation.cpp
+++ b/src/libs/installer/replaceoperation.cpp
@@ -39,7 +39,8 @@
using namespace QInstaller;
-ReplaceOperation::ReplaceOperation()
+ReplaceOperation::ReplaceOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Replace"));
}
@@ -50,18 +51,14 @@ void ReplaceOperation::backup()
bool ReplaceOperation::performOperation()
{
- const QStringList args = arguments();
-
// Arguments:
// 1. filename
// 2. Source-String
// 3. Replace-String
- if (args.count() != 3) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 3"), QLatin1String("")));
+ if (!checkArgumentCount(3))
return false;
- }
+
+ const QStringList args = arguments();
const QString fileName = args.at(0);
const QString before = args.at(1);
const QString after = args.at(2);
@@ -69,7 +66,8 @@ bool ReplaceOperation::performOperation()
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to open %1 for reading").arg(fileName));
+ setErrorString(tr("Cannot open file \"%1\" for reading: %2").arg(
+ QDir::toNativeSeparators(fileName), file.errorString()));
return false;
}
@@ -79,7 +77,8 @@ bool ReplaceOperation::performOperation()
if (!file.open(QIODevice::WriteOnly)) {
setError(UserDefinedError);
- setErrorString(tr("Failed to open %1 for writing").arg(fileName));
+ setErrorString(tr("Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(fileName), file.errorString()));
return false;
}
@@ -100,8 +99,3 @@ bool ReplaceOperation::testOperation()
{
return true;
}
-
-Operation *ReplaceOperation::clone() const
-{
- return new ReplaceOperation();
-}
diff --git a/src/libs/installer/replaceoperation.h b/src/libs/installer/replaceoperation.h
index 881e81b89..3cae90d04 100644
--- a/src/libs/installer/replaceoperation.h
+++ b/src/libs/installer/replaceoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT ReplaceOperation : public Operation
{
public:
- ReplaceOperation();
+ explicit ReplaceOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
} // namespace QInstaller
diff --git a/src/libs/installer/repository.cpp b/src/libs/installer/repository.cpp
index 49d5fd16a..9a501fdfe 100644
--- a/src/libs/installer/repository.cpp
+++ b/src/libs/installer/repository.cpp
@@ -32,7 +32,7 @@
**************************************************************************/
#include "repository.h"
-#include "kdupdaterfiledownloaderfactory.h"
+#include "filedownloaderfactory.h"
#include <QDataStream>
#include <QFileInfo>
diff --git a/src/libs/installer/resources/install.png b/src/libs/installer/resources/install.png
new file mode 100644
index 000000000..8e3309c9f
--- /dev/null
+++ b/src/libs/installer/resources/install.png
Binary files differ
diff --git a/src/libs/installer/resources/installer.qrc b/src/libs/installer/resources/installer.qrc
index 77bf00f65..48a7c65bd 100644
--- a/src/libs/installer/resources/installer.qrc
+++ b/src/libs/installer/resources/installer.qrc
@@ -3,5 +3,9 @@
<file>installer.png</file>
<file>installer.ico</file>
<file>installer.icns</file>
+ <file>install.png</file>
+ <file>uninstall.png</file>
+ <file>keepinstalled.png</file>
+ <file>keepuninstalled.png</file>
</qresource>
</RCC>
diff --git a/src/libs/installer/resources/keepinstalled.png b/src/libs/installer/resources/keepinstalled.png
new file mode 100644
index 000000000..7f8489e28
--- /dev/null
+++ b/src/libs/installer/resources/keepinstalled.png
Binary files differ
diff --git a/src/libs/installer/resources/keepuninstalled.png b/src/libs/installer/resources/keepuninstalled.png
new file mode 100644
index 000000000..2753092cc
--- /dev/null
+++ b/src/libs/installer/resources/keepuninstalled.png
Binary files differ
diff --git a/src/libs/installer/resources/uninstall.png b/src/libs/installer/resources/uninstall.png
new file mode 100644
index 000000000..5646770da
--- /dev/null
+++ b/src/libs/installer/resources/uninstall.png
Binary files differ
diff --git a/src/libs/installer/scriptengine.cpp b/src/libs/installer/scriptengine.cpp
index 0560e7e90..adf841bde 100644
--- a/src/libs/installer/scriptengine.cpp
+++ b/src/libs/installer/scriptengine.cpp
@@ -203,6 +203,15 @@ QList<QJSValue> GuiProxy::findChildren(QObject *parent, const QString &objectNam
return children;
}
+/*!
+ Hides the GUI when \a silent is \c true.
+*/
+void GuiProxy::setSilent(bool silent)
+{
+ if (m_gui)
+ m_gui->setSilent(silent);
+}
+
void GuiProxy::cancelButtonClicked()
{
if (m_gui)
@@ -265,7 +274,7 @@ ScriptEngine::ScriptEngine(PackageManagerCore *core) :
setGuiQObject(core->guiObject());
QQmlEngine::setObjectOwnership(core, QQmlEngine::CppOwnership);
global.setProperty(QLatin1String("installer"), m_engine.newQObject(core));
- connect(core, SIGNAL(guiObjectChanged(QObject*)), this, SLOT(setGuiQObject(QObject*)));
+ connect(core, &PackageManagerCore::guiObjectChanged, this, &ScriptEngine::setGuiQObject);
} else {
global.setProperty(QLatin1String("installer"), m_engine.newQObject(new QObject));
}
@@ -371,7 +380,7 @@ QJSValue ScriptEngine::loadInContext(const QString &context, const QString &file
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
- throw Error(tr("Could not open the requested script file at %1: %2.")
+ throw Error(tr("Cannot open script file at %1: %2")
.arg(fileName, file.errorString()));
}
@@ -389,9 +398,10 @@ QJSValue ScriptEngine::loadInContext(const QString &context, const QString &file
QJSValue scriptContext = evaluate(scriptContent, fileName);
scriptContext.setProperty(QLatin1String("Uuid"), QUuid::createUuid().toString());
if (scriptContext.isError()) {
- throw Error(tr("Exception while loading the component script '%1'. (%2)").arg(
- QFileInfo(file).absoluteFilePath(), scriptContext.toString().isEmpty() ?
- QString::fromLatin1("Unknown error.") : scriptContext.toString()));
+ throw Error(tr("Exception while loading the component script \"%1\": %2").arg(
+ QDir::toNativeSeparators(QFileInfo(file).absoluteFilePath()),
+ scriptContext.toString().isEmpty() ?
+ tr("Unknown error.") : scriptContext.toString()));
}
return scriptContext;
}
diff --git a/src/libs/installer/scriptengine_p.h b/src/libs/installer/scriptengine_p.h
index 1a1dac0e3..b15478680 100644
--- a/src/libs/installer/scriptengine_p.h
+++ b/src/libs/installer/scriptengine_p.h
@@ -54,7 +54,7 @@ public:
ConsoleProxy() {}
public slots :
- void log(const QString &log) { qDebug() << log; }
+ void log(const QString &log) { qDebug().noquote() << log; }
};
class InstallerProxy : public QObject
@@ -158,6 +158,8 @@ public:
Q_INVOKABLE QJSValue findChild(QObject *parent, const QString &objectName);
Q_INVOKABLE QList<QJSValue> findChildren(QObject *parent, const QString &objectName);
+ Q_INVOKABLE void setSilent(bool silent);
+
signals:
void interrupted();
void languageChanged();
diff --git a/src/libs/installer/selfrestartoperation.cpp b/src/libs/installer/selfrestartoperation.cpp
index 54b970074..df1fec2c4 100644
--- a/src/libs/installer/selfrestartoperation.cpp
+++ b/src/libs/installer/selfrestartoperation.cpp
@@ -34,30 +34,31 @@
#include "selfrestartoperation.h"
#include "packagemanagercore.h"
-#include <kdselfrestarter.h>
+#include "selfrestarter.h"
using namespace QInstaller;
-SelfRestartOperation::SelfRestartOperation()
+SelfRestartOperation::SelfRestartOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("SelfRestart"));
}
void SelfRestartOperation::backup()
{
- setValue(QLatin1String("PreviousSelfRestart"), KDSelfRestarter::restartOnQuit());
+ setValue(QLatin1String("PreviousSelfRestart"), SelfRestarter::restartOnQuit());
}
bool SelfRestartOperation::performOperation()
{
- PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ PackageManagerCore *const core = packageManager();
if (!core) {
setError(UserDefinedError);
- setErrorString(tr("Installer object needed in '%1' operation is empty.").arg(name()));
+ setErrorString(tr("Installer object needed in operation %1 is empty.").arg(name()));
return false;
}
- if (!core->isUpdater() && !core->isPackageManager()) {
+ if (!core->isMaintainer()) {
setError(UserDefinedError);
setErrorString(tr("Self Restart: Only valid within updater or packagemanager mode."));
return false;
@@ -68,13 +69,13 @@ bool SelfRestartOperation::performOperation()
setErrorString(tr("Self Restart: Invalid arguments"));
return false;
}
- KDSelfRestarter::setRestartOnQuit(true);
- return KDSelfRestarter::restartOnQuit();
+ SelfRestarter::setRestartOnQuit(true);
+ return SelfRestarter::restartOnQuit();
}
bool SelfRestartOperation::undoOperation()
{
- KDSelfRestarter::setRestartOnQuit(value(QLatin1String("PreviousSelfRestart")).toBool());
+ SelfRestarter::setRestartOnQuit(value(QLatin1String("PreviousSelfRestart")).toBool());
return true;
}
@@ -82,8 +83,3 @@ bool SelfRestartOperation::testOperation()
{
return true;
}
-
-Operation *SelfRestartOperation::clone() const
-{
- return new SelfRestartOperation();
-}
diff --git a/src/libs/installer/selfrestartoperation.h b/src/libs/installer/selfrestartoperation.h
index aed08aead..b4a4fa78d 100644
--- a/src/libs/installer/selfrestartoperation.h
+++ b/src/libs/installer/selfrestartoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT SelfRestartOperation : public Operation
{
public:
- SelfRestartOperation();
+ explicit SelfRestartOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
};
}
diff --git a/src/libs/installer/settings.cpp b/src/libs/installer/settings.cpp
index 7093a88a5..5389573fa 100644
--- a/src/libs/installer/settings.cpp
+++ b/src/libs/installer/settings.cpp
@@ -61,6 +61,7 @@ static const QLatin1String scRemoteRepositories("RemoteRepositories");
static const QLatin1String scDependsOnLocalInstallerBinary("DependsOnLocalInstallerBinary");
static const QLatin1String scTranslations("Translations");
static const QLatin1String scCreateLocalRepository("CreateLocalRepository");
+static const QLatin1String scInstallActionColumnVisible("InstallActionColumnVisible");
static const QLatin1String scFtpProxy("FtpProxy");
static const QLatin1String scHttpProxy("HttpProxy");
@@ -84,9 +85,10 @@ static void raiseError(QXmlStreamReader &reader, const QString &error, Settings:
} else {
QFile *xmlFile = qobject_cast<QFile*>(reader.device());
if (xmlFile) {
- qWarning() << QString::fromLatin1("Ignoring following settings reader error in %1, line %2, "
- "column %3: %4").arg(xmlFile->fileName()).arg(reader.lineNumber()).arg(reader.columnNumber())
- .arg(error);
+ qWarning().noquote().nospace()
+ << "Ignoring following settings reader error in " << xmlFile->fileName()
+ << ", line " << reader.lineNumber() << ", column " << reader.columnNumber()
+ << ": " << error;
} else {
qWarning("Ignoring following settings reader error: %s", qPrintable(error));
}
@@ -102,7 +104,7 @@ static QStringList readArgumentAttributes(QXmlStreamReader &reader, Settings::Pa
switch (token) {
case QXmlStreamReader::StartElement: {
if (!reader.attributes().isEmpty()) {
- raiseError(reader, QString::fromLatin1("Unexpected attribute for element '%1'.")
+ raiseError(reader, QString::fromLatin1("Unexpected attribute for element \"%1\".")
.arg(reader.name().toString()), parseMode);
return arguments;
} else {
@@ -110,7 +112,7 @@ static QStringList readArgumentAttributes(QXmlStreamReader &reader, Settings::Pa
(lc) ? arguments.append(reader.readElementText().toLower()) :
arguments.append(reader.readElementText());
} else {
- raiseError(reader, QString::fromLatin1("Unexpected element '%1'.").arg(reader.name()
+ raiseError(reader, QString::fromLatin1("Unexpected element \"%1\".").arg(reader.name()
.toString()), parseMode);
return arguments;
}
@@ -152,23 +154,23 @@ static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefaul
} else if (reader.name() == QLatin1String("Enabled")) {
repo.setEnabled(bool(reader.readElementText().toInt()));
} else {
- raiseError(reader, QString::fromLatin1("Unexpected element '%1'.").arg(reader.name()
+ raiseError(reader, QString::fromLatin1("Unexpected element \"%1\".").arg(reader.name()
.toString()), parseMode);
}
if (!reader.attributes().isEmpty()) {
- raiseError(reader, QString::fromLatin1("Unexpected attribute for element '%1'.")
+ raiseError(reader, QString::fromLatin1("Unexpected attribute for element \"%1\".")
.arg(reader.name().toString()), parseMode);
}
}
set.insert(repo);
} else {
- raiseError(reader, QString::fromLatin1("Unexpected element '%1'.").arg(reader.name().toString()),
+ raiseError(reader, QString::fromLatin1("Unexpected element \"%1\".").arg(reader.name().toString()),
parseMode);
}
if (!reader.attributes().isEmpty()) {
- raiseError(reader, QString::fromLatin1("Unexpected attribute for element '%1'.").arg(reader
+ raiseError(reader, QString::fromLatin1("Unexpected attribute for element \"%1\".").arg(reader
.name().toString()), parseMode);
}
}
@@ -235,12 +237,12 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
file.setFileName(overrideConfig.fileName());
if (!file.open(QIODevice::ReadOnly))
- throw Error(tr("Could not open settings file %1 for reading: %2").arg(path, file.errorString()));
+ throw Error(tr("Cannot open settings file %1 for reading: %2").arg(path, file.errorString()));
QXmlStreamReader reader(&file);
if (reader.readNextStartElement()) {
if (reader.name() != QLatin1String("Installer")) {
- reader.raiseError(QString::fromLatin1("Unexpected element '%1' as root element.").arg(reader
+ reader.raiseError(QString::fromLatin1("Unexpected element \"%1\" as root element.").arg(reader
.name().toString()));
}
}
@@ -252,26 +254,26 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
<< scStartMenuDir << scMaintenanceToolName << scMaintenanceToolIniFile << scRemoveTargetDir
<< scRunProgram << scRunProgramArguments << scRunProgramDescription
<< scDependsOnLocalInstallerBinary
- << scAllowSpaceInPath << scAllowNonAsciiCharacters << scWizardStyle << scTitleColor
+ << scAllowSpaceInPath << scAllowNonAsciiCharacters << scWizardStyle << scStyleSheet << scTitleColor
<< scWizardDefaultWidth << scWizardDefaultHeight
<< scRepositorySettingsPageVisible << scTargetConfigurationFile
- << scRemoteRepositories << scTranslations << QLatin1String(scControlScript)
- << scCreateLocalRepository;
+ << scRemoteRepositories << scTranslations << scUrlQueryString << QLatin1String(scControlScript)
+ << scCreateLocalRepository << scInstallActionColumnVisible;
Settings s;
s.d->m_data.insert(scPrefix, prefix);
while (reader.readNextStartElement()) {
const QString name = reader.name().toString();
if (!elementList.contains(name))
- raiseError(reader, QString::fromLatin1("Unexpected element '%1'.").arg(name), parseMode);
+ raiseError(reader, QString::fromLatin1("Unexpected element \"%1\".").arg(name), parseMode);
if (!reader.attributes().isEmpty()) {
- raiseError(reader, QString::fromLatin1("Unexpected attribute for element '%1'.").arg(name),
+ raiseError(reader, QString::fromLatin1("Unexpected attribute for element \"%1\".").arg(name),
parseMode);
}
if (s.d->m_data.contains(name))
- reader.raiseError(QString::fromLatin1("Element '%1' has been defined before.").arg(name));
+ reader.raiseError(QString::fromLatin1("Element \"%1\" has been defined before.").arg(name));
if (name == scTranslations) {
s.setTranslations(readArgumentAttributes(reader, parseMode, QLatin1String("Translation"), true));
@@ -323,6 +325,8 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
s.d->m_data.insert(scRepositorySettingsPageVisible, true);
if (!s.d->m_data.contains(scCreateLocalRepository))
s.d->m_data.insert(scCreateLocalRepository, false);
+ if (!s.d->m_data.contains(scInstallActionColumnVisible))
+ s.d->m_data.insert(scInstallActionColumnVisible, false);
return s;
}
@@ -377,6 +381,11 @@ QString Settings::wizardStyle() const
return d->m_data.value(scWizardStyle).toString();
}
+QString Settings::styleSheet() const
+{
+ return d->absolutePathFromKey(scStyleSheet);
+}
+
QString Settings::titleColor() const
{
return d->m_data.value(scTitleColor).toString();
@@ -477,6 +486,11 @@ bool Settings::createLocalRepository() const
return d->m_data.value(scCreateLocalRepository).toBool();
}
+bool Settings::installActionColumnVisible() const
+{
+ return d->m_data.value(scInstallActionColumnVisible, false).toBool();
+}
+
bool Settings::allowSpaceInPath() const
{
return d->m_data.value(scAllowSpaceInPath, true).toBool();
diff --git a/src/libs/installer/settings.h b/src/libs/installer/settings.h
index 2d7a894c3..9171ff6ae 100644
--- a/src/libs/installer/settings.h
+++ b/src/libs/installer/settings.h
@@ -88,6 +88,7 @@ public:
QString installerWindowIcon() const;
QString systemIconSuffix() const;
QString wizardStyle() const;
+ QString styleSheet() const;
QString titleColor() const;
int wizardDefaultWidth() const;
int wizardDefaultHeight() const;
@@ -111,6 +112,7 @@ public:
QString configurationFileName() const;
bool createLocalRepository() const;
+ bool installActionColumnVisible() const;
bool dependsOnLocalInstallerBinary() const;
bool hasReplacementRepos() const;
diff --git a/src/libs/installer/settingsoperation.cpp b/src/libs/installer/settingsoperation.cpp
index c7e15c423..1692cab91 100644
--- a/src/libs/installer/settingsoperation.cpp
+++ b/src/libs/installer/settingsoperation.cpp
@@ -32,7 +32,7 @@
**************************************************************************/
#include "settingsoperation.h"
#include "packagemanagercore.h"
-#include "kdupdaterupdateoperations.h"
+#include "updateoperations.h"
#include "qsettingswrapper.h"
#include <QDir>
@@ -40,7 +40,8 @@
using namespace QInstaller;
-SettingsOperation::SettingsOperation()
+SettingsOperation::SettingsOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Settings"));
}
@@ -68,7 +69,7 @@ bool SettingsOperation::checkArguments()
if (!missingArguments.isEmpty()) {
setError(InvalidArguments);
- setErrorString(tr("Missing argument(s) '%1' calling '%2' with arguments '%3'.").arg(
+ setErrorString(tr("Missing argument(s) \"%1\" calling %2 with arguments \"%3\".").arg(
missingArguments.join(QLatin1String("; ")), name(), arguments().join(QLatin1String("; "))));
return false;
}
@@ -78,7 +79,7 @@ bool SettingsOperation::checkArguments()
if (!possibleMethodValues.contains(method)) {
setError(InvalidArguments);
- setErrorString(tr("Current method argument calling '%1' with arguments '%2' is not "
+ setErrorString(tr("Current method argument calling \"%1\" with arguments \"%2\" is not "
"supported. Please use set, remove, add_array_value or remove_array_value.").arg(name(),
arguments().join(QLatin1String("; "))));
return false;
@@ -182,14 +183,14 @@ bool SettingsOperation::undoOperation()
if (cleanUp) {
QFile settingsFile(path);
if (!settingsFile.remove())
- qWarning() << settingsFile.errorString();
+ qWarning().noquote() << settingsFile.errorString();
if (!value(QLatin1String("createddir")).toString().isEmpty()) {
KDUpdater::MkdirOperation mkDirOperation;
mkDirOperation.setArguments(QStringList() << QFileInfo(path).absolutePath());
mkDirOperation.setValue(QLatin1String("createddir"), value(QLatin1String("createddir")));
if (!mkDirOperation.undoOperation()) {
- qWarning() << mkDirOperation.errorString();
+ qWarning().noquote() << mkDirOperation.errorString();
}
}
}
@@ -200,9 +201,3 @@ bool SettingsOperation::testOperation()
{
return true;
}
-
-Operation *SettingsOperation::clone() const
-{
- return new SettingsOperation();
-}
-
diff --git a/src/libs/installer/settingsoperation.h b/src/libs/installer/settingsoperation.h
index 7a1e9d5fa..83249635b 100644
--- a/src/libs/installer/settingsoperation.h
+++ b/src/libs/installer/settingsoperation.h
@@ -41,13 +41,12 @@ namespace QInstaller {
class INSTALLER_EXPORT SettingsOperation : public Operation
{
public:
- SettingsOperation();
+ explicit SettingsOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
private:
bool checkArguments();
diff --git a/src/libs/installer/simplemovefileoperation.cpp b/src/libs/installer/simplemovefileoperation.cpp
index 7e5cac8bb..6d904fa2a 100644
--- a/src/libs/installer/simplemovefileoperation.cpp
+++ b/src/libs/installer/simplemovefileoperation.cpp
@@ -33,11 +33,13 @@
#include "simplemovefileoperation.h"
+#include <QDir>
#include <QtCore/QFileInfo>
namespace QInstaller {
-SimpleMoveFileOperation::SimpleMoveFileOperation()
+SimpleMoveFileOperation::SimpleMoveFileOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("SimpleMoveFile"));
}
@@ -48,21 +50,17 @@ void SimpleMoveFileOperation::backup()
bool SimpleMoveFileOperation::performOperation()
{
- const QStringList args = arguments();
- if (args.count() != 2) {
- setError(InvalidArguments);
- setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String("")));
+ if (!checkArgumentCount(2))
return false;
- }
+ const QStringList args = arguments();
const QString source = args.at(0);
const QString target = args.at(1);
if (source.isEmpty() || target.isEmpty()) {
setError(UserDefinedError);
- setErrorString(tr("None of the arguments can be empty: source '%1', target '%2'.")
- .arg(source, target));
+ setErrorString(tr("None of the arguments can be empty: source \"%1\", target \"%2\".")
+ .arg(QDir::toNativeSeparators(source), QDir::toNativeSeparators(target)));
return false;
}
@@ -72,8 +70,8 @@ bool SimpleMoveFileOperation::performOperation()
if (file.exists()) {
if (!file.remove()) {
setError(UserDefinedError);
- setErrorString(tr("Cannot move source '%1' to target '%2', because target exists and is "
- "not removable.").arg(source, target));
+ setErrorString(tr("Cannot move file from \"%1\" to \"%2\", because the target path exists and is "
+ "not removable.").arg(QDir::toNativeSeparators(source), QDir::toNativeSeparators(target)));
return false;
}
}
@@ -81,12 +79,14 @@ bool SimpleMoveFileOperation::performOperation()
file.setFileName(source);
if (!file.rename(target)) {
setError(UserDefinedError);
- setErrorString(tr("Cannot move source '%1' to target '%2': %3").arg(source, target,
- file.errorString()));
+ setErrorString(tr("Cannot move file \"%1\" to \"%2\": %3").arg(
+ QDir::toNativeSeparators(source), QDir::toNativeSeparators(target),
+ file.errorString()));
return false;
}
- emit outputTextChanged(tr("Move '%1' to '%2'.").arg(source, target));
+ emit outputTextChanged(tr("Moving file \"%1\" to \"%2\".").arg(QDir::toNativeSeparators(source),
+ QDir::toNativeSeparators(target)));
return true;
}
@@ -96,7 +96,8 @@ bool SimpleMoveFileOperation::undoOperation()
const QString target = arguments().at(1);
QFile(target).rename(source);
- emit outputTextChanged(tr("Move '%1' to '%2'.").arg(target, source));
+ emit outputTextChanged(tr("Moving file \"%1\" to \"%2\".").arg(QDir::toNativeSeparators(target),
+ QDir::toNativeSeparators(source)));
return true;
}
@@ -106,9 +107,4 @@ bool SimpleMoveFileOperation::testOperation()
return true;
}
-Operation *SimpleMoveFileOperation::clone() const
-{
- return new SimpleMoveFileOperation();
-}
-
} // namespace QInstaller
diff --git a/src/libs/installer/simplemovefileoperation.h b/src/libs/installer/simplemovefileoperation.h
index 3d6c1c58d..64338a016 100644
--- a/src/libs/installer/simplemovefileoperation.h
+++ b/src/libs/installer/simplemovefileoperation.h
@@ -45,13 +45,12 @@ class INSTALLER_EXPORT SimpleMoveFileOperation : public QObject, public Operatio
Q_OBJECT
public:
- SimpleMoveFileOperation();
+ explicit SimpleMoveFileOperation(PackageManagerCore *core);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- Operation *clone() const;
Q_SIGNALS:
void outputTextChanged(const QString &progress);
diff --git a/src/libs/installer/sysinfo_win.cpp b/src/libs/installer/sysinfo_win.cpp
index ec14ead4f..57ab67e1c 100644
--- a/src/libs/installer/sysinfo_win.cpp
+++ b/src/libs/installer/sysinfo_win.cpp
@@ -31,7 +31,7 @@
**
**************************************************************************/
-#include "kdsysinfo.h"
+#include "sysinfo.h"
#include "link.h"
#ifdef Q_CC_MINGW
diff --git a/src/libs/installer/testrepository.cpp b/src/libs/installer/testrepository.cpp
index 37067b10f..6767d9aaa 100644
--- a/src/libs/installer/testrepository.cpp
+++ b/src/libs/installer/testrepository.cpp
@@ -32,26 +32,29 @@
**************************************************************************/
#include "testrepository.h"
-#include <kdupdaterfiledownloader.h>
-#include <kdupdaterfiledownloaderfactory.h>
+#include "packagemanagercore.h"
+#include "packagemanagerproxyfactory.h"
+#include "proxycredentialsdialog.h"
+#include "serverauthenticationdialog.h"
-#include <QtCore/QFile>
+#include <QFile>
-using namespace QInstaller;
+namespace QInstaller {
-TestRepository::TestRepository(QObject *parent)
- : KDJob(parent)
- , m_downloader(0)
+TestRepository::TestRepository(PackageManagerCore *parent)
+ : Job(parent)
+ , m_core(parent)
{
- setTimeout(10000);
setAutoDelete(false);
setCapabilities(Cancelable);
+
+ connect(&m_timer, &QTimer::timeout, this, &TestRepository::onTimeout);
+ connect(&m_xmlTask, &QFutureWatcherBase::finished, this, &TestRepository::downloadCompleted);
}
TestRepository::~TestRepository()
{
- if (m_downloader)
- m_downloader->deleteLater();
+ reset();
}
Repository TestRepository::repository() const
@@ -61,100 +64,125 @@ Repository TestRepository::repository() const
void TestRepository::setRepository(const Repository &repository)
{
- cancel();
-
- setError(NoError);
- setErrorString(QString());
+ reset();
m_repository = repository;
}
void TestRepository::doStart()
{
- if (m_downloader)
- m_downloader->deleteLater();
+ reset();
+ if (!m_core) {
+ emitFinishedWithError(Job::Canceled, tr("Missing package manager core engine."));
+ return; // We can't do anything here without core, so avoid tons of !m_core checks.
+ }
const QUrl url = m_repository.url();
if (url.isEmpty()) {
- emitFinishedWithError(InvalidUrl, tr("Empty repository URL."));
- return;
- }
-
- m_downloader = KDUpdater::FileDownloaderFactory::instance().create(url.scheme(), this);
- if (!m_downloader) {
- emitFinishedWithError(InvalidUrl, tr("URL scheme not supported: %1 (%2).")
- .arg(url.scheme(), url.toString()));
+ emitFinishedWithError(QInstaller::InvalidUrl, tr("Empty repository URL."));
return;
}
QAuthenticator auth;
auth.setUser(m_repository.username());
auth.setPassword(m_repository.password());
- m_downloader->setAuthenticator(auth);
-
- connect(m_downloader, SIGNAL(downloadCompleted()), this, SLOT(downloadCompleted()));
- connect(m_downloader, SIGNAL(downloadAborted(QString)), this, SLOT(downloadAborted(QString)),
- Qt::QueuedConnection);
- connect(m_downloader, SIGNAL(authenticatorChanged(QAuthenticator)), this,
- SLOT(onAuthenticatorChanged(QAuthenticator)));
- m_downloader->setAutoRemoveDownloadedFile(true);
- m_downloader->setUrl(QUrl(url.toString() + QString::fromLatin1("/Updates.xml")));
+ FileTaskItem item(m_repository.url().toString() + QLatin1String("/Updates.xml?") +
+ QString::number(qrand() * qrand()));
+ item.insert(TaskRole::Authenticator, QVariant::fromValue(auth));
- m_downloader->download();
+ m_timer.start(10000);
+ DownloadFileTask *const xmlTask = new DownloadFileTask(item);
+ if (m_core)
+ xmlTask->setProxyFactory(m_core->proxyFactory());
+ m_xmlTask.setFuture(QtConcurrent::run(&DownloadFileTask::doTask, xmlTask));
}
void TestRepository::doCancel()
{
- if (m_downloader) {
- QString errorString = m_downloader->errorString();
- if (errorString.isEmpty())
- errorString = tr("Got a timeout while testing: '%1'").arg(m_repository.displayname());
- // at the moment the download sends downloadCompleted() if we cancel it, so just
- disconnect(m_downloader, 0, this, 0);
- m_downloader->cancelDownload();
- emitFinishedWithError(KDJob::Canceled, errorString);
- }
+ reset();
+ emitFinishedWithError(Job::Canceled, tr("Download canceled."));
+}
+
+void TestRepository::onTimeout()
+{
+ reset();
+ emitFinishedWithError(Job::Canceled, tr("Timeout while testing repository \"%1\".")
+ .arg(m_repository.displayname()));
}
void TestRepository::downloadCompleted()
{
- QString errorMsg;
- int error = DownloadError;
+ if (error() != Job::NoError)
+ return;
+
+ try {
+ m_xmlTask.waitForFinished();
- if (m_downloader->isDownloaded()) {
- QFile file(m_downloader->downloadedFileName());
- if (file.exists() && file.open(QIODevice::ReadOnly)) {
+ m_timer.stop();
+ QFile file(m_xmlTask.future().results().value(0).target());
+ if (file.open(QIODevice::ReadOnly)) {
QDomDocument doc;
QString errorMsg;
if (!doc.setContent(&file, &errorMsg)) {
- error = InvalidUpdatesXml;
- errorMsg = tr("Could not parse Updates.xml! Error: %1.").arg(errorMsg);
+ emitFinishedWithError(QInstaller::InvalidUpdatesXml,
+ tr("Cannot parse Updates.xml: %1").arg(errorMsg));
} else {
- error = NoError;
+ emitFinishedWithError(Job::NoError, QString(/*Success*/)); // OPK
}
} else {
- errorMsg = tr("Updates.xml could not be opened for reading!");
+ emitFinishedWithError(QInstaller::DownloadError,
+ tr("Cannot open Updates.xml for reading: %1").arg(file.errorString()));
}
- } else {
- errorMsg = tr("Updates.xml could not be found on server!");
+ } catch (const AuthenticationRequiredException &e) {
+ m_timer.stop();
+ if (e.type() == AuthenticationRequiredException::Type::Server) {
+ ServerAuthenticationDialog dlg(e.message(), e.taskItem());
+ if (dlg.exec() == QDialog::Accepted) {
+ m_repository.setUsername(dlg.user());
+ m_repository.setPassword(dlg.password());
+ }
+ QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection);
+ return;
+ } else if (e.type() == AuthenticationRequiredException::Type::Proxy) {
+ const QNetworkProxy proxy = e.proxy();
+ ProxyCredentialsDialog proxyCredentials(proxy);
+ if (proxyCredentials.exec() == QDialog::Accepted) {
+ PackageManagerProxyFactory *factory = m_core->proxyFactory();
+ factory->setProxyCredentials(proxy, proxyCredentials.userName(),
+ proxyCredentials.password());
+ m_core->setProxyFactory(factory);
+ }
+ QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection);
+ return;
+ } else {
+ emitFinishedWithError(QInstaller::DownloadError, tr("Authentication failed."));
+ }
+ } catch (const TaskException &e) {
+ m_timer.stop();
+ emitFinishedWithError(QInstaller::DownloadError, e.message());
+ } catch (const QUnhandledException &e) {
+ m_timer.stop();
+ emitFinishedWithError(QInstaller::DownloadError, QLatin1String(e.what()));
+ } catch (...) {
+ m_timer.stop();
+ emitFinishedWithError(QInstaller::DownloadError,
+ tr("Unknown error while testing repository \"%1\".").arg(m_repository.displayname()));
}
+}
- if (error > NoError)
- emitFinishedWithError(error, errorMsg);
- else
- emitFinished();
- m_downloader->deleteLater();
- m_downloader = 0;
-}
+// -- private
-void TestRepository::downloadAborted(const QString &reason)
+void TestRepository::reset()
{
- emitFinishedWithError(DownloadError, reason);
-}
+ m_timer.stop();
+ setError(NoError);
+ setErrorString(QString());
-void TestRepository::onAuthenticatorChanged(const QAuthenticator &authenticator)
-{
- m_repository.setUsername(authenticator.user());
- m_repository.setPassword(authenticator.password());
+ try {
+ if (m_xmlTask.isRunning())
+ m_xmlTask.cancel();
+ } catch (...) {}
}
+
+} // namespace QInstaller
diff --git a/src/libs/installer/testrepository.h b/src/libs/installer/testrepository.h
index 4e387b15d..55e492803 100644
--- a/src/libs/installer/testrepository.h
+++ b/src/libs/installer/testrepository.h
@@ -33,55 +33,47 @@
#ifndef TESTREPOSITORY_H
#define TESTREPOSITORY_H
-#include "qinstallerglobal.h"
+#include "downloadfiletask.h"
+#include "job.h"
+#include "repository.h"
-#include <repository.h>
-#include <settings.h>
-
-#include <kdjob.h>
-
-QT_BEGIN_NAMESPACE
-class QAuthenticator;
-class QLocale;
-class QVariant;
-QT_END_NAMESPACE
-
-namespace KDUpdater {
- class FileDownloader;
-}
+#include <QFutureWatcher>
+#include <QTimer>
namespace QInstaller {
- class PackageManagerCore;
-}
-namespace QInstaller {
+class PackageManagerCore;
-class INSTALLER_EXPORT TestRepository : public KDJob
+class INSTALLER_EXPORT TestRepository : public Job
{
Q_OBJECT
+ Q_DISABLE_COPY(TestRepository)
public:
-
- explicit TestRepository(QObject *parent = 0);
+ explicit TestRepository(PackageManagerCore *parent = 0);
~TestRepository();
- QInstaller::Repository repository() const;
- void setRepository(const QInstaller::Repository &repository);
+ Repository repository() const;
+ void setRepository(const Repository &repository);
-private:
+private slots:
void doStart();
void doCancel();
-private Q_SLOTS:
+ void onTimeout();
void downloadCompleted();
- void downloadAborted(const QString &reason);
- void onAuthenticatorChanged(const QAuthenticator &authenticator);
private:
- QInstaller::Repository m_repository;
- KDUpdater::FileDownloader *m_downloader;
+ void reset();
+
+private:
+ PackageManagerCore *m_core;
+
+ QTimer m_timer;
+ Repository m_repository;
+ QFutureWatcher<FileTaskResult> m_xmlTask;
};
-} //namespace QInstaller
+} // namespace QInstaller
#endif // TESTREPOSITORY_H
diff --git a/src/libs/installer/unziptask.cpp b/src/libs/installer/unziptask.cpp
index 5c00e78a2..7e05dc1c6 100644
--- a/src/libs/installer/unziptask.cpp
+++ b/src/libs/installer/unziptask.cpp
@@ -30,7 +30,9 @@
** $QT_END_LICENSE$
**
**************************************************************************/
+
#include "unziptask.h"
+#include "lib7z_facade.h"
#ifdef Q_OS_UNIX
# include "StdAfx.h"
@@ -39,21 +41,15 @@
// TODO: include once we switch from lib7z_fascade.h
//#include "Common/MyInitGuid.h"
-#include "7zip/IPassword.h"
+#include "7zip/Archive/IArchive.h"
#include "7zip/Common/FileStreams.h"
#include "7zip/UI/Common/OpenArchive.h"
#include "Windows/FileDir.h"
#include "Windows/PropVariant.h"
-#include "7zCrc.h"
-
#include <QDir>
-void registerArc7z();
-void registerCodecLZMA();
-void registerCodecLZMA2();
-
namespace QInstaller {
class ArchiveExtractCallback : public IArchiveExtractCallback, public CMyUnknownImp
@@ -104,11 +100,11 @@ public:
return E_FAIL;
bool isDir = false;
- if (IsArchiveItemFolder(m_arc.Archive, m_currentIndex, isDir) != S_OK)
+ if (Archive_IsItem_Folder(m_arc.Archive, m_currentIndex, isDir) != S_OK)
return E_FAIL;
bool isEncrypted = false;
- if (GetArchiveItemBoolProp(m_arc.Archive, m_currentIndex, kpidEncrypted, isEncrypted) != S_OK)
+ if (Archive_GetItemBoolProp(m_arc.Archive, m_currentIndex, kpidEncrypted, isEncrypted) != S_OK)
return E_FAIL;
if (isDir || isEncrypted)
@@ -154,7 +150,7 @@ public:
default: // fall through and bail
case NArchive::NExtract::NOperationResult::kCRCError:
case NArchive::NExtract::NOperationResult::kDataError:
- case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
m_outFileStream->Close();
m_outFileStreamComPtr.Release();
return E_FAIL;
@@ -162,7 +158,7 @@ public:
UInt32 attributes;
if (GetAttributes(&attributes))
- NWindows::NFile::NDirectory::MySetFileAttributes((wchar_t*)(m_currentTarget.utf16()), attributes);
+ NWindows::NFile::NDir::SetFileAttrib((wchar_t*)(m_currentTarget.utf16()), attributes);
FILETIME accessTime, creationTime, modificationTime;
const bool writeAccessTime = GetTime(kpidATime, &accessTime);
@@ -239,13 +235,7 @@ UnzipTask::UnzipTask(const QString &source, const QString &target)
: m_source(source)
, m_target(target)
{
- {
- CrcGenerateTable();
-
- registerArc7z();
- registerCodecLZMA();
- registerCodecLZMA2();
- }
+ Lib7z::initSevenZ();
}
void UnzipTask::doTask(QFutureInterface<QString> &fi)
@@ -256,19 +246,29 @@ void UnzipTask::doTask(QFutureInterface<QString> &fi)
if (codecs.Load() != S_OK)
return;
- CIntVector formatIndices;
- if (!codecs.FindFormatForArchiveType(L"", formatIndices))
- return;
- CInFileStream *fileStream = new CInFileStream;
+ COpenOptions op;
+ op.codecs = &codecs;
+
+ CObjectVector<COpenType> types;
+ op.types = &types; // Empty, because we use a stream.
+
+ CIntVector excluded;
+ op.excludedFormats = &excluded;
+
+ const CMyComPtr<CInFileStream> fileStream = new CInFileStream;
fileStream->Open((wchar_t*) (m_source.utf16()));
+ op.stream = fileStream; // CMyComPtr is needed, otherwise it crashes in OpenStream().
+
+ CObjectVector<CProperty> properties;
+ op.props = &properties;
CArchiveLink archiveLink;
- if (archiveLink.Open2(&codecs, formatIndices, false, fileStream, UString(), 0) != S_OK)
+ if (archiveLink.Open2(op, nullptr) != S_OK)
return;
UINT32 count = 0;
- for (int i = 0; i < archiveLink.Arcs.Size(); ++i) {
+ for (unsigned i = 0; i < archiveLink.Arcs.Size(); ++i) {
const CArc& arc = archiveLink.Arcs[i];
UInt32 numItems = 0;
if (arc.Archive->GetNumberOfItems(&numItems) != S_OK)
@@ -277,7 +277,7 @@ void UnzipTask::doTask(QFutureInterface<QString> &fi)
}
fi.setExpectedResultCount(count);
- for (int i = 0; i < archiveLink.Arcs.Size(); ++i) {
+ for (unsigned i = 0; i < archiveLink.Arcs.Size(); ++i) {
if (fi.isCanceled())
break;
if (fi.isPaused())