[neon/backports-jammy/packagekit-qt/Neon/unstable] /: New upstream version 1.0.1

Matthias Klumpp null at kde.org
Wed Mar 15 04:29:32 GMT 2023


Git commit 2a9ff450ed4b82e8923e9ba22d09cf74c6e3fcae by Matthias Klumpp.
Committed on 21/01/2018 at 19:36.
Pushed by carlosdem into branch 'Neon/unstable'.

New upstream version 1.0.1

A  +4    -0    .gitignore
M  +23   -19   CMakeLists.txt
A  +49   -0    RELEASE
M  +2    -2    config.h.in
A  +69   -0    release.sh
M  +4    -1    src/CMakeLists.txt
A  +1    -0    src/Offline
M  +0    -1    src/bitfield.cpp
M  +1    -10   src/common.h
M  +82   -81   src/daemon.cpp
M  +34   -12   src/daemon.h
M  +55   -49   src/daemonprivate.cpp
M  +17   -10   src/daemonprivate.h
M  +6    -7    src/modules/CMakeLists.txt
D  +0    -12   src/modules/packagekit-qt-config-version.cmake.in
M  +3    -6    src/modules/packagekit-qt-config.cmake.in
A  +187  -0    src/offline.cpp     [License: LGPL (v2+)]
A  +142  -0    src/offline.h     [License: LGPL (v2+)]
A  +49   -0    src/offline_p.h     [License: LGPL (v2+)]
D  +0    -11   src/packagekitqt4.pc.in
M  +4    -4    src/packagekitqt5.pc.in
M  +74   -33   src/transaction.cpp
M  +32   -55   src/transaction.h
M  +29   -50   src/transactionprivate.cpp
M  +11   -12   src/transactionprivate.h

https://invent.kde.org/neon/backports-jammy/packagekit-qt/commit/2a9ff450ed4b82e8923e9ba22d09cf74c6e3fcae

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b92d68d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+build/
+*~
+*.o
+*.moc
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 86af861..f94a1fa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,8 +1,14 @@
-# CMakeLists for PackageKit-Qt
-project(packagekit-qt)
+cmake_minimum_required(VERSION 3.1)
+cmake_policy(SET CMP0048 NEW)
 
-cmake_minimum_required(VERSION 2.8.6 FATAL_ERROR)
-find_package(PkgConfig REQUIRED)
+if (POLICY CMP0043)
+  cmake_policy(SET CMP0043 NEW)
+endif()
+if (POLICY CMP0063)
+  cmake_policy(SET CMP0063 NEW)
+endif()
+
+project(packagekit-qt VERSION 1.0.1)
 
 # Used to set installation paths
 set(CMAKE_AUTOMOC ON)
@@ -11,21 +17,20 @@ set(BUILD_SHARED_LIBS ON)
 set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON)
 include(GNUInstallDirs)
 
-set(QPACKAGEKIT_VERSION_MAJOR  "0")
-set(QPACKAGEKIT_VERSION_MINOR  "9")
-set(QPACKAGEKIT_VERSION_PATCH  "6")
-set(QPACKAGEKIT_VERSION_SUFFIX "${VERSION_SUFFIX}")
-set(QPACKAGEKIT_API_LEVEL "0")
-set(QPACKAGEKIT_VERSION "${QPACKAGEKIT_VERSION_MAJOR}.${QPACKAGEKIT_VERSION_MINOR}.${QPACKAGEKIT_VERSION_PATCH}")
+set(QPACKAGEKIT_API_LEVEL "1")
 
-add_definitions(-DQT_NO_CAST_TO_ASCII
-                -DQT_NO_CAST_FROM_ASCII
-                -DQT_NO_URL_CAST_FROM_STRING
-                -DQT_NO_CAST_FROM_BYTEARRAY
-                -DQT_NO_SIGNALS_SLOTS_KEYWORDS
-                -DQT_USE_FAST_OPERATOR_PLUS
-                -DQT_USE_QSTRINGBUILDER
-               )
+add_definitions(
+    -DQT_NO_KEYWORDS
+    -DQT_NO_CAST_TO_ASCII
+    -DQT_NO_CAST_FROM_ASCII
+    -DQT_STRICT_ITERATORS
+    -DQT_NO_URL_CAST_FROM_STRING
+    -DQT_NO_CAST_FROM_BYTEARRAY
+    -DQT_USE_QSTRINGBUILDER
+    -DQT_NO_SIGNALS_SLOTS_KEYWORDS
+    -DQT_USE_FAST_OPERATOR_PLUS
+    -DQT_DISABLE_DEPRECATED_BEFORE=0x050900
+)
 
 # Forbid in-tree building
 if(${CMAKE_SOURCE_DIR} MATCHES ${CMAKE_BINARY_DIR})
@@ -51,7 +56,6 @@ set (LOCALSTATEDIR "/var")
 set (CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/packagekitqt5/")
 
 add_definitions("-DLOCALSTATEDIR=\"${LOCALSTATEDIR}\"")
-add_definitions("-std=gnu++11")
 
 configure_file(config.h.in ${CMAKE_BINARY_DIR}/config.h)
 
diff --git a/RELEASE b/RELEASE
new file mode 100644
index 0000000..bda64c5
--- /dev/null
+++ b/RELEASE
@@ -0,0 +1,49 @@
+PackageKit-Qt Release Notes
+
+1. Write NEWS entries for PackageKit-Qt in the same format as usual.
+
+git shortlog QPACKAGEKIT_0_9_6.. | grep -i -v trivial | grep -v Merge > NEWS.new
+
+--------------------------------------------------------------------------------
+Version 0.9.7
+~~~~~~~~~~~~~
+Released: 2014-xx-xx
+
+Notes:
+
+Features:
+
+Bugfixes:
+--------------------------------------------------------------------------------
+
+2. Update library version if new ABI or API in CMakeLists.txt
+
+3. Commit changes in PackageKit-Qt git:
+
+git commit -a -m "Release version 0.9.7"
+git tag -s -f -m "Release 0.9.7" QPACKAGEKIT_0_9_7
+<gpg password>
+git push --tags
+git push
+
+4. run './release.sh --version=0.9.7 --git-tag=QPACKAGEKIT_0_9_7 --sign'
+
+5. Upload tarball to:
+
+scp *.tar.* annarchy.freedesktop.org:/srv/www.freedesktop.org/www/software/PackageKit/releases/
+
+6. Do post release version bump in CMakeLists.txt, RELEASE
+
+7. Commit trivial changes:
+
+git commit -a -m "trivial: post release version bump"
+git push
+
+8. Send an email to packagekit at lists.freedesktop.org
+
+=================================================
+PackageKit-Qt 0.9.7 released!
+
+Tarballs available here: http://www.packagekit.org/releases/
+
+=================================================
diff --git a/config.h.in b/config.h.in
index 8ab6511..ff89761 100644
--- a/config.h.in
+++ b/config.h.in
@@ -17,9 +17,9 @@
 #define PACKAGE_URL "http://packagekit.org"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "@VERSION@"
+#define PACKAGE_VERSION "@PROJECT_VERSION@"
 
 /* Version number of package */
-#define VERSION "@VERSION@"
+#define VERSION "@PROJECT_VERSION@"
 
 #endif /*CONFIG_H*/
diff --git a/release.sh b/release.sh
new file mode 100755
index 0000000..f67ab1b
--- /dev/null
+++ b/release.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+#
+# Create QPK release tarball from version control system
+#
+# (c) 2011 Matthias Klumpp
+# GPLv2+
+set -e
+OPTION_SPEC="version:,git-tag:,sign"
+PARSED_OPTIONS=$(getopt -n "$0" -a -o h --l "$OPTION_SPEC" -- "$@")
+
+eval set -- "$PARSED_OPTIONS"
+
+if [ $? != 0 ] ; then usage ; exit 1 ; fi
+
+while true ; do
+	case "$1" in
+		--version ) case "$2" in
+			    "") echo "version parameter needs an argument!"; exit 3 ;;
+			     *) export QPK_VERSION=$2 ; shift 2 ;;
+			   esac ;;
+		--git-tag ) case "$2" in
+			    "") echo "git-tag parameter needs an argument!"; exit 3 ;;
+			     *) export GIT_TAG=$2 ; shift 2 ;;
+			   esac ;;
+		--sign )  SIGN_RELEASE=1; shift; ;;
+		--) shift ; break ;;
+		* ) echo "ERROR: unknown flag $1"; exit 2;;
+	esac
+done
+
+if [ "$QPK_VERSION" = "" ]; then
+ echo "No PackageKit-Qt version set!"
+ exit 1
+fi
+if [ "$GIT_TAG" = "" ]; then
+ echo "No Git tag set!"
+ exit 1
+fi
+
+rm -rf ./release-tar-tmp
+
+# check if we can build PackageKit-Qt
+mkdir -p ./t-build-release
+make -C ./build clean all
+rm -rf ./t-build-release
+
+mkdir -p ./release-tar-tmp
+git archive --prefix="PackageKit-Qt-$QPK_VERSION/" "$GIT_TAG^{tree}" | tar -x -C ./release-tar-tmp
+
+R_ROOT="./release-tar-tmp/PackageKit-Qt-$QPK_VERSION"
+
+# cleanup files which should not go to the release tarball
+find ./release-tar-tmp -name .gitignore -type f -delete
+rm $R_ROOT/release.sh
+rm $R_ROOT/RELEASE
+
+# create release tarball
+cd ./release-tar-tmp
+tar cvJf "PackageKit-Qt-$QPK_VERSION.tar.xz" "./PackageKit-Qt-$QPK_VERSION/"
+mv "PackageKit-Qt-$QPK_VERSION.tar.xz" ../
+cd ..
+
+# cleanup
+rm -r ./release-tar-tmp
+
+# sign release, if flag is set
+if [ "$SIGN_RELEASE" = "1" ]; then
+ gpg --armor --sign --detach-sig "PackageKit-Qt-$QPK_VERSION.tar.xz"
+fi
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0b58c12..096ebd7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -12,6 +12,8 @@ set(packagekitqt_HEADERS
     details.h
     bitfield.h
     packagekitqt_global.h
+    offline.h
+    Offline
 )
 
 set(packagekitqt_SRC
@@ -21,6 +23,7 @@ set(packagekitqt_SRC
     transaction.cpp
     transactionprivate.cpp
     details.cpp
+    offline.cpp
 )
 
 find_path(PK_INTERFACES_DIR org.freedesktop.PackageKit.xml
@@ -41,7 +44,7 @@ qt5_add_dbus_interface(packagekitqt_SRC ${PK_INTERFACE_XML} daemonproxy)
 qt5_add_dbus_interface(packagekitqt_SRC ${PK_TRANSACTION_INTERFACE_XML} transactionproxy)
 
 add_library(packagekitqt5 ${packagekitqt_SRC} ${packagekitqt_HEADERS} ${packagekitqt_HEADERS_PRIVATE})
-set_target_properties(packagekitqt5 PROPERTIES VERSION ${QPACKAGEKIT_VERSION} SOVERSION ${QPACKAGEKIT_API_LEVEL})
+set_target_properties(packagekitqt5 PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${QPACKAGEKIT_API_LEVEL})
 
 target_link_libraries(packagekitqt5 PUBLIC Qt5::DBus)
 
diff --git a/src/Offline b/src/Offline
new file mode 100644
index 0000000..d19ee9e
--- /dev/null
+++ b/src/Offline
@@ -0,0 +1 @@
+#include "offline.h"
diff --git a/src/bitfield.cpp b/src/bitfield.cpp
index a4d7fd3..b488e6a 100644
--- a/src/bitfield.cpp
+++ b/src/bitfield.cpp
@@ -78,7 +78,6 @@ Bitfield Bitfield::operator|= (Bitfield mask)
 	return m_val;
 }
 
-
 Bitfield& Bitfield::operator= (const Bitfield& other)
 {
     if (this == &other)
diff --git a/src/common.h b/src/common.h
index 24b7894..fe81128 100644
--- a/src/common.h
+++ b/src/common.h
@@ -1,6 +1,7 @@
 /*
  * This file is part of the QPackageKit project
  * Copyright (C) 2008 Adrien Bustany <madcat at mymadcat.com>
+ * Copyright (C) 2010-2018 Daniel Nicoletti <dantti12 at gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -17,16 +18,6 @@
  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301, USA.
  */
-#include <QtCore/QLoggingCategory>
-
-Q_DECLARE_LOGGING_CATEGORY(PACKAGEKITQT_TRANSACTION)
-Q_DECLARE_LOGGING_CATEGORY(PACKAGEKITQT_DAEMON)
-
-#define PK_NAME					"org.freedesktop.PackageKit"
-#define PK_PATH					"/org/freedesktop/PackageKit"
-#define PK_TRANSACTION_INTERFACE "org.freedesktop.PackageKit.Transaction"
-
-#define DBUS_PROPERTIES  "org.freedesktop.DBus.Properties"
 
 #define AUTH_PACKAGE_INSTALL			"org.freedesktop.packagekit.package-install"
 #define AUTH_PACKAGE_INSTALL_UNTRUSTED		"org.freedesktop.packagekit.package-install-untrusted"
diff --git a/src/daemon.cpp b/src/daemon.cpp
index 7529a3e..8d9eed9 100644
--- a/src/daemon.cpp
+++ b/src/daemon.cpp
@@ -1,7 +1,7 @@
 /*
  * This file is part of the QPackageKit project
  * Copyright (C) 2008 Adrien Bustany <madcat at mymadcat.com>
- * Copyright (C) 2010-2016 Daniel Nicoletti <dantti12 at gmail.com>
+ * Copyright (C) 2010-2018 Daniel Nicoletti <dantti12 at gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -27,10 +27,11 @@
 #include "common.h"
 
 Q_LOGGING_CATEGORY(PACKAGEKITQT_DAEMON, "packagekitqt.daemon")
+Q_LOGGING_CATEGORY(PACKAGEKITQT_OFFLINE, "packagekitqt.offline")
 
 using namespace PackageKit;
 
-Daemon* Daemon::m_global = 0;
+Daemon* Daemon::m_global = nullptr;
 
 Daemon* Daemon::global()
 {
@@ -46,20 +47,20 @@ Daemon::Daemon(QObject *parent) :
     d_ptr(new DaemonPrivate(this))
 {
     Q_D(Daemon);
-    d->daemon = new ::OrgFreedesktopPackageKitInterface(QLatin1String(PK_NAME),
-                                                        QLatin1String(PK_PATH),
+    d->daemon = new ::OrgFreedesktopPackageKitInterface(PK_NAME,
+                                                        PK_PATH,
                                                         QDBusConnection::systemBus(),
                                                         this);
 
-    QDBusConnection::systemBus().connect(QLatin1String(PK_NAME),
-                                         QLatin1String(PK_PATH),
-                                         QLatin1String(DBUS_PROPERTIES),
+    QDBusConnection::systemBus().connect(PK_NAME,
+                                         PK_PATH,
+                                         DBUS_PROPERTIES,
                                          QLatin1String("PropertiesChanged"),
                                          this,
                                          SLOT(propertiesChanged(QString,QVariantMap,QStringList)));
 }
 
-void DaemonPrivate::setupSignal(const QMetaMethod &signal, bool connect)
+void DaemonPrivate::setupSignal(const QMetaMethod &signal)
 {
     Q_Q(Daemon);
 
@@ -81,11 +82,7 @@ void DaemonPrivate::setupSignal(const QMetaMethod &signal, bool connect)
     }
 
     if (signalToConnect && memberToConnect) {
-        if (connect) {
-            QObject::connect(daemon, signalToConnect, q, memberToConnect);
-        } else {
-            QObject::disconnect(daemon, signalToConnect, q, memberToConnect);
-        }
+        QObject::connect(daemon, signalToConnect, q, memberToConnect);
     }
 }
 
@@ -93,20 +90,14 @@ void Daemon::connectNotify(const QMetaMethod &signal)
 {
     Q_D(Daemon);
     if (!d->connectedSignals.contains(signal) && d->daemon) {
-        d->setupSignal(signal, true);
+        d->setupSignal(signal);
+        d->connectedSignals << signal;
     }
-    d->connectedSignals << signal;
 }
 
 void Daemon::disconnectNotify(const QMetaMethod &signal)
 {
-    Q_D(Daemon);
-    if (d->connectedSignals.contains(signal)) {
-        d->connectedSignals.removeOne(signal);
-        if (d->daemon && !d->connectedSignals.contains(signal)) {
-            d->setupSignal(signal, false);
-        }
-    }
+    QObject::disconnectNotify(signal);
 }
 
 Daemon::~Daemon()
@@ -196,7 +187,7 @@ void Daemon::setHints(const QStringList &hints)
 
 void Daemon::setHints(const QString &hints)
 {
-    global()->d_ptr->hints = QStringList() << hints;
+    global()->d_ptr->hints = QStringList{ hints };
 }
 
 QStringList Daemon::hints()
@@ -219,6 +210,11 @@ QDBusPendingReply<> Daemon::suggestDaemonQuit()
     return global()->d_ptr->daemon->SuggestDaemonQuit();
 }
 
+Offline *Daemon::offline() const
+{
+    return global()->d_ptr->offline;
+}
+
 uint Daemon::versionMajor()
 {
     return global()->d_ptr->versionMajor;
@@ -236,32 +232,27 @@ uint Daemon::versionMicro()
 
 QString Daemon::packageName(const QString &packageID)
 {
-    return packageID.section(QLatin1Char(';'), 0, 0);
+    return Transaction::packageName(packageID);
 }
 
 QString Daemon::packageVersion(const QString &packageID)
 {
-    return packageID.section(QLatin1Char(';'), 1, 1);
+    return Transaction::packageVersion(packageID);
 }
 
 QString Daemon::packageArch(const QString &packageID)
 {
-    return packageID.section(QLatin1Char(';'), 2, 2);
+    return Transaction::packageArch(packageID);
 }
 
 QString Daemon::packageData(const QString &packageID)
 {
-    return packageID.section(QLatin1Char(';'), 3, 3);
-}
-
-QString Daemon::packageIcon(const QString &packageID)
-{
-    return Transaction::packageIcon(packageID);
+    return Transaction::packageData(packageID);
 }
 
 Transaction *Daemon::acceptEula(const QString &eulaId)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleAcceptEula;
     ret->d_ptr->eulaId = eulaId;
     return ret;
@@ -269,7 +260,7 @@ Transaction *Daemon::acceptEula(const QString &eulaId)
 
 Transaction *Daemon::downloadPackages(const QStringList &packageIDs, bool storeInCache)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleDownloadPackages;
     ret->d_ptr->search = packageIDs;
     ret->d_ptr->storeInCache = storeInCache;
@@ -278,19 +269,19 @@ Transaction *Daemon::downloadPackages(const QStringList &packageIDs, bool storeI
 
 Transaction *Daemon::downloadPackage(const QString &packageID, bool storeInCache)
 {
-    return downloadPackages(QStringList() << packageID, storeInCache);
+    return downloadPackages(QStringList{ packageID }, storeInCache);
 }
 
 Transaction *Daemon::getCategories()
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleGetCategories;
     return ret;
 }
 
 Transaction *Daemon::dependsOn(const QStringList &packageIDs, Transaction::Filters filters, bool recursive)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleDependsOn;
     ret->d_ptr->search = packageIDs;
     ret->d_ptr->filters = filters;
@@ -300,12 +291,12 @@ Transaction *Daemon::dependsOn(const QStringList &packageIDs, Transaction::Filte
 
 Transaction *Daemon::dependsOn(const QString &packageID, Transaction::Filters filters, bool recursive)
 {
-    return dependsOn(QStringList() << packageID, filters, recursive);
+    return dependsOn(QStringList{ packageID }, filters, recursive);
 }
 
 Transaction *Daemon::getDetails(const QStringList &packageIDs)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleGetDetails;
     ret->d_ptr->search = packageIDs;
     return ret;
@@ -313,12 +304,12 @@ Transaction *Daemon::getDetails(const QStringList &packageIDs)
 
 Transaction *Daemon::getDetails(const QString &packageID)
 {
-    return getDetails(QStringList() << packageID);
+    return getDetails(QStringList{ packageID });
 }
 
 Transaction *Daemon::getDetailsLocal(const QStringList &files)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleGetDetailsLocal;
     ret->d_ptr->search = files;
     return ret;
@@ -326,12 +317,12 @@ Transaction *Daemon::getDetailsLocal(const QStringList &files)
 
 Transaction *Daemon::getDetailsLocal(const QString &file)
 {
-    return getDetailsLocal(QStringList() << file);
+    return getDetailsLocal(QStringList{ file });
 }
 
 Transaction *Daemon::getFiles(const QStringList &packageIDs)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleGetFiles;
     ret->d_ptr->search = packageIDs;
     return ret;
@@ -339,12 +330,12 @@ Transaction *Daemon::getFiles(const QStringList &packageIDs)
 
 Transaction *Daemon::getFiles(const QString &packageID)
 {
-    return getFiles(QStringList() << packageID);
+    return getFiles(QStringList{ packageID });
 }
 
 Transaction *Daemon::getFilesLocal(const QStringList &files)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleGetFilesLocal;
     ret->d_ptr->search = files;
     return ret;
@@ -352,12 +343,12 @@ Transaction *Daemon::getFilesLocal(const QStringList &files)
 
 Transaction *Daemon::getFilesLocal(const QString &file)
 {
-    return getFilesLocal(QStringList() << file);
+    return getFilesLocal(QStringList{ file });
 }
 
 Transaction *Daemon::getOldTransactions(uint number)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleGetOldTransactions;
     ret->d_ptr->numberOfOldTransactions = number;
     return ret;
@@ -365,7 +356,7 @@ Transaction *Daemon::getOldTransactions(uint number)
 
 Transaction *Daemon::getPackages(Transaction::Filters filters)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleGetPackages;
     ret->d_ptr->filters = filters;
     return ret;
@@ -373,7 +364,7 @@ Transaction *Daemon::getPackages(Transaction::Filters filters)
 
 Transaction *Daemon::getRepoList(Transaction::Filters filters)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleGetRepoList;
     ret->d_ptr->filters = filters;
     return ret;
@@ -381,7 +372,7 @@ Transaction *Daemon::getRepoList(Transaction::Filters filters)
 
 Transaction *Daemon::requiredBy(const QStringList &packageIDs, Transaction::Filters filters, bool recursive)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleRequiredBy;
     ret->d_ptr->search = packageIDs;
     ret->d_ptr->filters = filters;
@@ -391,12 +382,12 @@ Transaction *Daemon::requiredBy(const QStringList &packageIDs, Transaction::Filt
 
 Transaction *Daemon::requiredBy(const QString &packageID, Transaction::Filters filters, bool recursive)
 {
-    return requiredBy(QStringList() << packageID, filters, recursive);
+    return requiredBy(QStringList{ packageID }, filters, recursive);
 }
 
 Transaction *Daemon::getUpdatesDetails(const QStringList &packageIDs)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleGetUpdateDetail;
     ret->d_ptr->search = packageIDs;
     return ret;
@@ -404,12 +395,12 @@ Transaction *Daemon::getUpdatesDetails(const QStringList &packageIDs)
 
 Transaction *Daemon::getUpdateDetail(const QString &packageID)
 {
-    return getUpdatesDetails(QStringList() << packageID);
+    return getUpdatesDetails(QStringList{ packageID });
 }
 
 Transaction *Daemon::getUpdates(Transaction::Filters filters)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleGetUpdates;
     ret->d_ptr->filters = filters;
     return ret;
@@ -417,14 +408,24 @@ Transaction *Daemon::getUpdates(Transaction::Filters filters)
 
 Transaction *Daemon::getDistroUpgrades()
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleGetDistroUpgrades;
     return ret;
 }
 
+Transaction *Daemon::upgradeSystem(const QString &distroId, Transaction::UpgradeKind kind, Transaction::TransactionFlags flags)
+{
+    auto ret = new Transaction;
+    ret->d_ptr->role = Transaction::RoleUpgradeSystem;
+    ret->d_ptr->upgradeDistroId = distroId;
+    ret->d_ptr->upgradeKind = kind;
+    ret->d_ptr->transactionFlags = flags;
+    return ret;
+}
+
 Transaction *Daemon::installFiles(const QStringList &files, Transaction::TransactionFlags flags)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleInstallFiles;
     ret->d_ptr->search = files;
     ret->d_ptr->transactionFlags = flags;
@@ -433,12 +434,12 @@ Transaction *Daemon::installFiles(const QStringList &files, Transaction::Transac
 
 Transaction *Daemon::installFile(const QString &file, Transaction::TransactionFlags flags)
 {
-    return installFiles(QStringList() << file, flags);
+    return installFiles(QStringList{ file }, flags);
 }
 
 Transaction *Daemon::installPackages(const QStringList &packageIDs, Transaction::TransactionFlags flags)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleInstallPackages;
     ret->d_ptr->search = packageIDs;
     ret->d_ptr->transactionFlags = flags;
@@ -447,12 +448,12 @@ Transaction *Daemon::installPackages(const QStringList &packageIDs, Transaction:
 
 Transaction *Daemon::installPackage(const QString &packageID, Transaction::TransactionFlags flags)
 {
-    return installPackages(QStringList() << packageID, flags);
+    return installPackages(QStringList{ packageID }, flags);
 }
 
 Transaction *Daemon::installSignature(Transaction::SigType type, const QString &keyID, const QString &packageID)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleInstallSignature;
     ret->d_ptr->signatureType = type;
     ret->d_ptr->signatureKey = keyID;
@@ -462,7 +463,7 @@ Transaction *Daemon::installSignature(Transaction::SigType type, const QString &
 
 Transaction *Daemon::refreshCache(bool force)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleRefreshCache;
     ret->d_ptr->refreshCacheForce = force;
     return ret;
@@ -470,7 +471,7 @@ Transaction *Daemon::refreshCache(bool force)
 
 Transaction *Daemon::removePackages(const QStringList &packageIDs, bool allowDeps, bool autoremove, Transaction::TransactionFlags flags)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleRemovePackages;
     ret->d_ptr->search = packageIDs;
     ret->d_ptr->allowDeps = allowDeps;
@@ -481,12 +482,12 @@ Transaction *Daemon::removePackages(const QStringList &packageIDs, bool allowDep
 
 Transaction *Daemon::removePackage(const QString &packageID, bool allowDeps, bool autoremove, Transaction::TransactionFlags flags)
 {
-    return removePackages(QStringList() << packageID, allowDeps, autoremove, flags);
+    return removePackages(QStringList{ packageID }, allowDeps, autoremove, flags);
 }
 
 Transaction *Daemon::repairSystem(Transaction::TransactionFlags flags)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleRepairSystem;
     ret->d_ptr->transactionFlags = flags;
     return ret;
@@ -494,7 +495,7 @@ Transaction *Daemon::repairSystem(Transaction::TransactionFlags flags)
 
 Transaction *Daemon::repoEnable(const QString &repoId, bool enable)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleRepoEnable;
     ret->d_ptr->repoId = repoId;
     ret->d_ptr->repoEnable = enable;
@@ -503,7 +504,7 @@ Transaction *Daemon::repoEnable(const QString &repoId, bool enable)
 
 Transaction *Daemon::repoRemove(const QString &repoId, bool autoremove, Transaction::TransactionFlags flags)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleRepoRemove;
     ret->d_ptr->repoId = repoId;
     ret->d_ptr->autoremove = autoremove;
@@ -513,7 +514,7 @@ Transaction *Daemon::repoRemove(const QString &repoId, bool autoremove, Transact
 
 Transaction *Daemon::repoSetData(const QString &repoId, const QString &parameter, const QString &value)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleRepoSetData;
     ret->d_ptr->repoId = repoId;
     ret->d_ptr->repoParameter = parameter;
@@ -523,7 +524,7 @@ Transaction *Daemon::repoSetData(const QString &repoId, const QString &parameter
 
 Transaction *Daemon::resolve(const QStringList &packageNames, Transaction::Filters filters)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleResolve;
     ret->d_ptr->search = packageNames;
     ret->d_ptr->filters = filters;
@@ -532,12 +533,12 @@ Transaction *Daemon::resolve(const QStringList &packageNames, Transaction::Filte
 
 Transaction *Daemon::resolve(const QString &packageName, Transaction::Filters filters)
 {
-    return resolve(QStringList() << packageName, filters);
+    return resolve(QStringList{ packageName }, filters);
 }
 
 Transaction *Daemon::searchFiles(const QStringList &search, Transaction::Filters filters)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleSearchFile;
     ret->d_ptr->search = search;
     ret->d_ptr->filters = filters;
@@ -546,12 +547,12 @@ Transaction *Daemon::searchFiles(const QStringList &search, Transaction::Filters
 
 Transaction *Daemon::searchFiles(const QString &search, Transaction::Filters filters)
 {
-    return searchFiles(QStringList() << search, filters);
+    return searchFiles(QStringList{ search }, filters);
 }
 
 Transaction *Daemon::searchDetails(const QStringList &search, Transaction::Filters filters)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleSearchDetails;
     ret->d_ptr->search = search;
     ret->d_ptr->filters = filters;
@@ -560,12 +561,12 @@ Transaction *Daemon::searchDetails(const QStringList &search, Transaction::Filte
 
 Transaction *Daemon::searchDetails(const QString &search, Transaction::Filters filters)
 {
-    return searchDetails(QStringList() << search, filters);
+    return searchDetails(QStringList{ search }, filters);
 }
 
 Transaction *Daemon::searchGroups(const QStringList &groups, Transaction::Filters filters)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleSearchGroup;
     ret->d_ptr->search = groups;
     ret->d_ptr->filters = filters;
@@ -574,7 +575,7 @@ Transaction *Daemon::searchGroups(const QStringList &groups, Transaction::Filter
 
 Transaction *Daemon::searchGroup(const QString &group, Transaction::Filters filters)
 {
-    return searchGroups(QStringList() << group, filters);
+    return searchGroups(QStringList{ group }, filters);
 }
 
 Transaction *Daemon::searchGroup(Transaction::Group group, Transaction::Filters filters)
@@ -599,7 +600,7 @@ Transaction *Daemon::searchGroups(Transaction::Groups groups, Transaction::Filte
 
 Transaction *Daemon::searchNames(const QStringList &search, Transaction::Filters filters)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleSearchName;
     ret->d_ptr->search = search;
     ret->d_ptr->filters = filters;
@@ -608,12 +609,12 @@ Transaction *Daemon::searchNames(const QStringList &search, Transaction::Filters
 
 Transaction *Daemon::searchNames(const QString &search, Transaction::Filters filters)
 {
-    return searchNames(QStringList() << search, filters);
+    return searchNames(QStringList{ search }, filters);
 }
 
 Transaction *Daemon::updatePackages(const QStringList &packageIDs, Transaction::TransactionFlags flags)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleUpdatePackages;
     ret->d_ptr->search = packageIDs;
     ret->d_ptr->transactionFlags = flags;
@@ -622,12 +623,12 @@ Transaction *Daemon::updatePackages(const QStringList &packageIDs, Transaction::
 
 Transaction *Daemon::updatePackage(const QString &packageID, Transaction::TransactionFlags flags)
 {
-    return updatePackages(QStringList() << packageID, flags);
+    return updatePackages(QStringList{ packageID }, flags);
 }
 
 Transaction *Daemon::whatProvides(const QStringList &search, Transaction::Filters filters)
 {
-    Transaction *ret = new Transaction;
+    auto ret = new Transaction;
     ret->d_ptr->role = Transaction::RoleWhatProvides;
     ret->d_ptr->search = search;
     ret->d_ptr->filters = filters;
@@ -636,7 +637,7 @@ Transaction *Daemon::whatProvides(const QStringList &search, Transaction::Filter
 
 Transaction *Daemon::whatProvides(const QString &search, Transaction::Filters filters)
 {
-    return whatProvides(QStringList() << search, filters);
+    return whatProvides(QStringList{ search }, filters);
 }
 
 QString Daemon::enumToString(const QMetaObject &metaObject, int value, const char *enumName)
diff --git a/src/daemon.h b/src/daemon.h
index 212a15c..607d32c 100644
--- a/src/daemon.h
+++ b/src/daemon.h
@@ -1,7 +1,7 @@
 /*
  * This file is part of the QPackageKit project
  * Copyright (C) 2008 Adrien Bustany <madcat at mymadcat.com>
- * Copyright (C) 2010-2016 Daniel Nicoletti <dantti12 at gmail.com>
+ * Copyright (C) 2010-2018 Daniel Nicoletti <dantti12 at gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -33,6 +33,8 @@
 
 namespace PackageKit {
 
+class Offline;
+
 /**
  * \class Daemon daemon.h Daemon
  * \author Adrien Bustany \e <madcat at mymadcat.com>
@@ -257,6 +259,12 @@ public:
      */
     static QDBusPendingReply<> suggestDaemonQuit();
 
+    /**
+     * Returns a class representing PackageKit offline interface, as with the Daemon
+     * class this will only have valid properties if isRunning() is true
+     */
+    Offline *offline() const;
+
     /**
      * Returns the package name from the \p packageID
      */
@@ -276,13 +284,6 @@ public:
      * Returns the package data from the \p packageID
      */
     Q_INVOKABLE static QString packageData(const QString &packageID);
-
-    /**
-     * Returns the package icon from the \p packageID
-     *
-     * @deprecated use Appstream to fetch icons
-     */
-    Q_INVOKABLE QT_DEPRECATED static QString packageIcon(const QString &packageID);
     
     static QString enumToString(const QMetaObject &metaObject, int value, const char *enumName);
 
@@ -522,6 +523,30 @@ public:
      */
     static Transaction *getDistroUpgrades();
 
+    /**
+     * Updates the whole system
+     *
+     * This method perfoms a distribution upgrade to the
+     * specified version.
+     *
+     * The \p type of upgrade, e.g. minimal, default or complete.
+     * Minimal upgrades will download the smallest amount of data
+     * before launching a installer.
+     * The default is to download enough data to launch a full
+     * graphical installer, but a complete upgrade will be
+     * required if there is no internet access during install time.
+     *
+     * \note This method typically emits
+     * \li progress()
+     * \li status()
+     * \li error()
+     * \li package()
+     *
+     * \warning check \sa errorCode() signal to know if it the call has any error
+     */
+    static Transaction *upgradeSystem(const QString &distroId, Transaction::UpgradeKind kind,
+                                      Transaction::TransactionFlags flags = Transaction::TransactionFlagOnlyTrusted);
+
     /**
      * \brief Installs the local packages \p files
      *
@@ -827,9 +852,7 @@ protected:
     void connectNotify(const QMetaMethod &signal) override;
 
     /**
-     * This method disconnects from DBus signals
      * \attention Make sure to call this method in inherited classes
-     * otherwise no signals will be disconnected
      */
     void disconnectNotify(const QMetaMethod &signal) override;
 
@@ -837,10 +860,9 @@ protected:
 
 private:
     Q_DECLARE_PRIVATE(Daemon)
-    Q_PRIVATE_SLOT(d_func(), void serviceOwnerChanged(QString,QString,QString))
     Q_PRIVATE_SLOT(d_func(), void propertiesChanged(QString,QVariantMap,QStringList))
     Q_PRIVATE_SLOT(d_func(), void updateProperties(QVariantMap))
-    Daemon(QObject *parent = 0);
+    Daemon(QObject *parent = nullptr);
     static Daemon *m_global;
 };
 
diff --git a/src/daemonprivate.cpp b/src/daemonprivate.cpp
index a5af33b..e423916 100644
--- a/src/daemonprivate.cpp
+++ b/src/daemonprivate.cpp
@@ -1,7 +1,7 @@
 /*
  * This file is part of the QPackageKit project
  * Copyright (C) 2008 Adrien Bustany <madcat at mymadcat.com>
- * Copyright (C) 2010-2016 Daniel Nicoletti <dantti12 at gmail.com>
+ * Copyright (C) 2010-2018 Daniel Nicoletti <dantti12 at gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -23,83 +23,89 @@
 #include "transaction.h"
 #include "common.h"
 
+#include "offline_p.h"
+
+#include <QDBusServiceWatcher>
 #include <QDBusConnection>
 #include <QDBusMessage>
 #include <QDBusArgument>
 #include <QDBusReply>
-#include <QDebug>
 
 using namespace PackageKit;
 
 DaemonPrivate::DaemonPrivate(Daemon* parent)
     : q_ptr(parent)
-{
-    m_watcher = new QDBusServiceWatcher(QLatin1String(PK_NAME),
-                                        QDBusConnection::systemBus(),
-                                        QDBusServiceWatcher::WatchForOwnerChange,
-                                        q_ptr);
-    q_ptr->connect(m_watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
-                   SLOT(serviceOwnerChanged(QString,QString,QString)));
-
-    // On PK 0.9 this will always be async
-    getAllProperties(false);
-}
-
-void DaemonPrivate::serviceOwnerChanged(const QString &service, const QString &oldOwner, const QString &newOwner)
+    , offline(new Offline(parent))
 {
     Q_Q(Daemon);
-    Q_UNUSED(service)
 
-    if (newOwner.isEmpty() || !oldOwner.isEmpty()) {
-        // TODO check if we don't emit this twice when
-        // the daemon exits cleanly
-        q->daemonQuit();
-    }
+    auto watcher = new QDBusServiceWatcher(PK_NAME,
+                                           QDBusConnection::systemBus(),
+                                           QDBusServiceWatcher::WatchForOwnerChange,
+                                           q_ptr);
+    q->connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged,
+                   q, [this, q] (const QString &service, const QString &oldOwner, const QString &newOwner) {
+        Q_UNUSED(service)
+        if (newOwner.isEmpty() || !oldOwner.isEmpty()) {
+            // TODO check if we don't emit this twice when
+            // the daemon exits cleanly
+            q->daemonQuit();
+        }
 
-    // There is a new PackageKit running get it's props
-    if (!newOwner.isEmpty()) {
-        // We don't have more transactions running
-        q->transactionListChanged(QStringList());
+        // There is a new PackageKit running get it's props
+        if (!newOwner.isEmpty()) {
+            // We don't have more transactions running
+            q->transactionListChanged(QStringList());
 
-        getAllProperties(false);
+            getAllProperties();
 
-        if (!running) {
-            running = true;
+            if (!running) {
+                running = true;
+                q->isRunningChanged();
+            }
+        } else if (running) {
+            running = false;
             q->isRunningChanged();
         }
-    } else if (running) {
-        running = false;
-        q->isRunningChanged();
-    }
+    });
+
+    getAllProperties();
 }
 
-void DaemonPrivate::getAllProperties(bool sync)
+void DaemonPrivate::getAllProperties()
 {
     Q_Q(Daemon);
 
-    QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String(PK_NAME),
-                                                          QLatin1String(PK_PATH),
-                                                          QLatin1String(DBUS_PROPERTIES),
+    QDBusMessage message = QDBusMessage::createMethodCall(PK_NAME,
+                                                          PK_PATH,
+                                                          DBUS_PROPERTIES,
                                                           QLatin1String("GetAll"));
-    message << QLatin1String(PK_NAME);
-    if (sync) {
-        QDBusReply<QVariantMap> reply = QDBusConnection::systemBus().call(message);
-        if (reply.isValid()) {
-            updateProperties(reply.value());
-        }
-    } else {
-        QDBusConnection::systemBus().callWithCallback(message,
-                                                      q,
-                                                      SLOT(updateProperties(QVariantMap)));
-    }
+    message << PK_NAME;
+    QDBusConnection::systemBus().callWithCallback(message,
+                                                  q,
+                                                  SLOT(updateProperties(QVariantMap)));
+
+    message = QDBusMessage::createMethodCall(PK_NAME,
+                                             PK_PATH,
+                                             DBUS_PROPERTIES,
+                                             QLatin1String("GetAll"));
+    message << PK_OFFLINE_INTERFACE;
+    QDBusConnection::systemBus().callWithCallback(message,
+                                                  offline,
+                                                  SLOT(updateProperties(QVariantMap)));
 }
 
 void DaemonPrivate::propertiesChanged(const QString &interface, const QVariantMap &properties, const QStringList &invalidatedProperties)
 {
-    Q_UNUSED(interface)
     Q_UNUSED(invalidatedProperties)
 
-    updateProperties(properties);
+    if (interface == PK_NAME) {
+        updateProperties(properties);
+    } else if (interface == PK_OFFLINE_INTERFACE) {
+        offline->d_ptr->updateProperties(properties);
+    } else {
+        qCWarning(PACKAGEKITQT_DAEMON) << "Unknown PackageKit interface:" << interface;
+    }
 }
 
 void DaemonPrivate::updateProperties(const QVariantMap &properties)
diff --git a/src/daemonprivate.h b/src/daemonprivate.h
index 5e63bd6..9bf794c 100644
--- a/src/daemonprivate.h
+++ b/src/daemonprivate.h
@@ -22,15 +22,26 @@
 #ifndef DAEMON_PRIVATE_H
 #define DAEMON_PRIVATE_H
 
-#include <QtCore/QStringList>
-#include <QtDBus/QDBusServiceWatcher>
+#include <QStringList>
+#include <QLoggingCategory>
 
 #include "daemon.h"
+#include "offline.h"
+
+Q_DECLARE_LOGGING_CATEGORY(PACKAGEKITQT_TRANSACTION)
+Q_DECLARE_LOGGING_CATEGORY(PACKAGEKITQT_DAEMON)
 
 class OrgFreedesktopPackageKitInterface;
 
 namespace PackageKit {
 
+static QString PK_NAME = QStringLiteral("org.freedesktop.PackageKit");
+static QString PK_OFFLINE_INTERFACE = QStringLiteral("org.freedesktop.PackageKit.Offline");
+static QString PK_PATH = QStringLiteral("/org/freedesktop/PackageKit");
+static QString PK_TRANSACTION_INTERFACE = QStringLiteral("org.freedesktop.PackageKit.Transaction");
+
+static QString DBUS_PROPERTIES = QStringLiteral("org.freedesktop.DBus.Properties");
+
 class DaemonPrivate
 {
     Q_DECLARE_PUBLIC(Daemon)
@@ -43,8 +54,8 @@ protected:
     QStringList hints;
     QList<QMetaMethod> connectedSignals;
 
-    void setupSignal(const QMetaMethod &signal, bool connect);
-    void getAllProperties(bool sync);
+    void setupSignal(const QMetaMethod &signal);
+    void getAllProperties();
 
     QString backendAuthor;
     QString backendDescription;
@@ -52,23 +63,19 @@ protected:
     QString distroId;
     Transaction::Filters filters = Transaction::FilterNone;
     Transaction::Groups groups = Transaction::GroupUnknown;
-    bool locked = false;
     QStringList mimeTypes;
     Daemon::Network networkState = Daemon::NetworkUnknown;
     Transaction::Roles roles = Transaction::RoleUnknown;
+    Offline *offline;
     uint versionMajor = 0;
     uint versionMicro = 0;
     uint versionMinor = 0;
-
+    bool locked = false;
     bool running = false;
 
 protected Q_SLOTS:
-    void serviceOwnerChanged(const QString &service, const QString &oldOwner, const QString &newOwner);
     void propertiesChanged(const QString &interface, const QVariantMap &properties, const QStringList &invalidatedProperties);
     void updateProperties(const QVariantMap &properties);
-
-private:
-    QDBusServiceWatcher *m_watcher;
 };
 
 } // End namespace PackageKit
diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt
index 3e3c0d5..9ff1b46 100644
--- a/src/modules/CMakeLists.txt
+++ b/src/modules/CMakeLists.txt
@@ -1,14 +1,13 @@
-# CMakeLists for PackageKit-Qt lib extra modules
+include(CMakePackageConfigHelpers)
 
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packagekit-qt-config.cmake.in
+configure_package_config_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/packagekit-qt-config.cmake.in
   ${CMAKE_CURRENT_BINARY_DIR}/packagekitqt5-config.cmake
-  @ONLY
-)
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packagekit-qt-config-version.cmake.in
-  ${CMAKE_CURRENT_BINARY_DIR}/packagekitqt5-config-version.cmake
-  @ONLY
+  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/packagekitqt5/
 )
 
+write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/packagekitqt5-config-version.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion)
+
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/packagekitqt5-config.cmake
         ${CMAKE_CURRENT_BINARY_DIR}/packagekitqt5-config-version.cmake
         DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/packagekitqt5/
diff --git a/src/modules/packagekit-qt-config-version.cmake.in b/src/modules/packagekit-qt-config-version.cmake.in
deleted file mode 100644
index 78200a1..0000000
--- a/src/modules/packagekit-qt-config-version.cmake.in
+++ /dev/null
@@ -1,12 +0,0 @@
-SET(PACKAGE_VERSION @VERSION@)
-IF (PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION)
-  SET(PACKAGE_VERSION_EXACT "true")
-ENDIF (PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION)
-IF (NOT PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
-  SET(PACKAGE_VERSION_COMPATIBLE "true")
-ELSE (NOT PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
-  SET(PACKAGE_VERSION_UNSUITABLE "true")
-ENDIF (NOT PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
-IF (PACKAGE_VERSION_UNSUITABLE)
-  MESSAGE("VERSION CHECK FAILED FOR ${PACKAGE_FIND_NAME}. WANTED ${PACKAGE_FIND_VERSION}, HAVE ${PACKAGE_VERSION}")
-ENDIF(PACKAGE_VERSION_UNSUITABLE)
diff --git a/src/modules/packagekit-qt-config.cmake.in b/src/modules/packagekit-qt-config.cmake.in
index 4684978..6dc5f24 100644
--- a/src/modules/packagekit-qt-config.cmake.in
+++ b/src/modules/packagekit-qt-config.cmake.in
@@ -1,10 +1,7 @@
-# - Config information for PackageKit-Qt5
-# This file defines:
-#
-#  PackageKitQt5_LIBRARIES - Link these to use PackageKitQt5
+ at PACKAGE_INIT@
+
+check_required_components(Qt5DBus)
 
-SET(prefix "@CMAKE_INSTALL_PREFIX@")
-SET(exec_prefix "@CMAKE_INSTALL_PREFIX@")
 SET(PackageKitQt5_LIBRARIES "PK::packagekitqt5")
 
 include("${CMAKE_CURRENT_LIST_DIR}/PackageKitQtTargets.cmake")
diff --git a/src/offline.cpp b/src/offline.cpp
new file mode 100644
index 0000000..15a5218
--- /dev/null
+++ b/src/offline.cpp
@@ -0,0 +1,187 @@
+/*
+ * This file is part of the PackageKitQt project
+ * Copyright (C) 2018 Daniel Nicoletti <dantti12 at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "offline_p.h"
+
+Q_DECLARE_LOGGING_CATEGORY(PACKAGEKITQT_OFFLINE)
+
+using namespace PackageKit;
+
+Offline::Offline(QObject *parent) : QObject(parent)
+  , d_ptr(new OfflinePrivate(this))
+{
+    QDBusConnection::systemBus().connect(PK_NAME,
+                                         PK_PATH,
+                                         DBUS_PROPERTIES,
+                                         QLatin1String("PropertiesChanged"),
+                                         this,
+                                         SLOT(propertiesChanged(QString,QVariantMap,QStringList)));
+}
+
+Offline::~Offline()
+{
+    delete d_ptr;
+}
+
+QVariantMap Offline::preparedUpgrade() const
+{
+    Q_D(const Offline);
+    return d->preparedUpgrade;
+}
+
+Offline::Action Offline::triggerAction() const
+{
+    Q_D(const Offline);
+    return d->triggerAction;
+}
+
+bool Offline::updatePrepared() const
+{
+    Q_D(const Offline);
+    return d->updatePrepared;
+}
+
+bool Offline::updateTriggered() const
+{
+    Q_D(const Offline);
+    return d->updateTriggered;
+}
+
+bool Offline::upgradePrepared() const
+{
+    Q_D(const Offline);
+    return d->upgradePrepared;
+}
+
+bool Offline::upgradeTriggered() const
+{
+    Q_D(const Offline);
+    return d->upgradeTriggered;
+}
+
+QDBusPendingReply<> Offline::trigger(Action action)
+{
+    Q_D(Offline);
+
+    QString actionStr;
+    switch(action) {
+    case ActionPowerOff:
+        actionStr = QStringLiteral("power-off");
+        break;
+    case ActionReboot:
+        actionStr = QStringLiteral("reboot");
+        break;
+    case ActionUnset:
+        break;
+    };
+    Q_ASSERT(!actionStr.isEmpty());
+
+    return d->iface.Trigger(actionStr);
+}
+
+QDBusPendingReply<> Offline::triggerUpgrade(Action action)
+{
+    Q_D(Offline);
+
+    QString actionStr;
+    switch(action) {
+    case ActionPowerOff:
+        actionStr = QStringLiteral("power-off");
+        break;
+    case ActionReboot:
+        actionStr = QStringLiteral("reboot");
+        break;
+    case ActionUnset:
+        break;
+    };
+    Q_ASSERT(!actionStr.isEmpty());
+
+    return d->iface.TriggerUpgrade(actionStr);
+}
+
+QDBusPendingReply<> Offline::cancel()
+{
+    Q_D(Offline);
+    return d->iface.Cancel();
+}
+
+QDBusPendingReply<> Offline::clearResults()
+{
+    Q_D(Offline);
+    return d->iface.ClearResults();
+}
+
+void Offline::getPrepared()
+{
+    Q_D(Offline);
+    QDBusPendingReply<QStringList> reply = d->iface.GetPrepared();
+    auto watcher = new QDBusPendingCallWatcher(reply, this);
+    connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher *call) {
+        QDBusPendingReply<QStringList> reply = *call;
+        QStringList pkgids;
+        if (!reply.isError()) {
+            pkgids = reply.argumentAt<0>();
+        } else {
+            qCWarning(PACKAGEKITQT_OFFLINE) << "Failed to GetPrepared" << reply.error();
+        }
+        Q_EMIT preparedUpdates(pkgids);
+        call->deleteLater();
+    });
+}
+
+void OfflinePrivate::updateProperties(const QVariantMap &properties)
+{
+    Q_Q(Offline);
+
+    QVariantMap::ConstIterator it = properties.constBegin();
+    while (it != properties.constEnd()) {
+        const QString &property = it.key();
+        const QVariant &value = it.value();
+        if (property == QLatin1String("PreparedUpgrade")) {
+            preparedUpgrade = value.toMap();;
+        } else if (property == QLatin1String("TriggerAction")) {
+            const QString actionStr = value.toString();
+            if (actionStr == QLatin1String("power-off")) {
+                triggerAction = Offline::ActionPowerOff;
+            } else if (actionStr == QLatin1String("reboot")) {
+                triggerAction = Offline::ActionReboot;
+            } else {
+                triggerAction = Offline::ActionUnset;
+            }
+        } else if (property == QLatin1String("UpdatePrepared")) {
+            updatePrepared = value.toBool();
+        } else if (property == QLatin1String("UpdateTriggered")) {
+            updateTriggered = value.toBool();
+        } else if (property == QLatin1String("UpgradePrepared")) {
+            upgradePrepared = value.toBool();
+        } else if (property == QLatin1String("UpgradeTriggered")) {
+            upgradeTriggered = value.toBool();
+        } else {
+            qCWarning(PACKAGEKITQT_OFFLINE) << "Unknown property:" << property << value;
+        }
+
+        ++it;
+    }
+
+    if (!properties.isEmpty()) {
+        q->changed();
+    }
+}
+
+#include "moc_offline.cpp"
diff --git a/src/offline.h b/src/offline.h
new file mode 100644
index 0000000..d6d3755
--- /dev/null
+++ b/src/offline.h
@@ -0,0 +1,142 @@
+/*
+ * This file is part of the PackageKitQt project
+ * Copyright (C) 2018 Daniel Nicoletti <dantti12 at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef OFFLINE_H
+#define OFFLINE_H
+
+#include <QObject>
+#include <QDBusPendingReply>
+#include <QVariantMap>
+
+#include <packagekitqt_global.h>
+
+namespace PackageKit {
+
+class OfflinePrivate;
+class PACKAGEKITQT_LIBRARY Offline : public QObject
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(Offline)
+public:
+    /**
+     * Actions to trigger
+     *
+     * \sa offlineTrigger()
+     */
+    enum Action {
+        ActionUnset,
+        ActionPowerOff, /** < powers off the computer after applying offline updates */
+        ActionReboot    /** < reboots the computer after applying offline updates */
+    };
+    Q_ENUM(Action)
+
+    ~Offline();
+
+    Q_PROPERTY(QVariantMap preparedUpgrade READ preparedUpgrade NOTIFY changed)
+    /**
+     * Details about a prepared system upgrade.
+     * Currently recognized keys are "name" and "version".
+     */
+    QVariantMap preparedUpgrade() const;
+
+    Q_PROPERTY(Action triggerAction READ triggerAction NOTIFY changed)
+    /**
+     * The action to take when finished applying updates, known values
+     */
+    Action triggerAction() const;
+
+    Q_PROPERTY(bool updatePrepared READ updatePrepared NOTIFY changed)
+    /**
+     * If an update has been prepared and is ready to be triggered.
+     */
+    bool updatePrepared() const;
+
+    Q_PROPERTY(bool updateTriggered READ updateTriggered NOTIFY changed)
+    /**
+     * If an update has been triggered.
+     */
+    bool updateTriggered() const;
+
+    Q_PROPERTY(bool upgradePrepared READ upgradePrepared NOTIFY changed)
+    /**
+     * If a system upgrade has been prepared and is ready to be triggered.
+     */
+    bool upgradePrepared() const;
+
+    Q_PROPERTY(bool upgradeTriggered READ upgradeTriggered NOTIFY changed)
+    /**
+     * If a system upgrade has been triggered.
+     */
+    bool upgradeTriggered() const;
+
+    /**
+     * Triggers the offline update for the next boot
+     *
+     * @p action is the action to take when finished applying updates
+     */
+    QDBusPendingReply<> trigger(Action action);
+
+    /**
+     * Triggers the offline system upgrade for next boot.
+     *
+     * @p action is the action to take when finished installing the system upgrade
+     */
+    QDBusPendingReply<> triggerUpgrade(Action action);
+
+    /**
+     * Cancels the offline update so the next boot procceeds as normal.
+     */
+    QDBusPendingReply<> cancel();
+
+    /**
+     *  Clears the offline update results store.
+     */
+    QDBusPendingReply<> clearResults();
+
+    /**
+     * Asks for the list of prepared packages for update.
+     * \sa preparedUpdates() signal
+     */
+    void getPrepared();
+
+Q_SIGNALS:
+    /**
+     * A list of package-ids ready to be installed
+     */
+    void preparedUpdates(const QStringList &updates);
+
+    /**
+     * Emitted when any of the properties changes
+     */
+    void changed();
+
+protected:
+    friend class DaemonPrivate;
+
+    explicit Offline(QObject *parent = nullptr);
+
+private:
+    Q_PRIVATE_SLOT(d_func(), void updateProperties(QVariantMap))
+
+    OfflinePrivate *d_ptr;
+};
+
+}
+
+#endif // OFFLINE_H
diff --git a/src/offline_p.h b/src/offline_p.h
new file mode 100644
index 0000000..ac01cb0
--- /dev/null
+++ b/src/offline_p.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the PackageKitQt project
+ * Copyright (C) 2018 Daniel Nicoletti <dantti12 at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef OFFLINE_P_H
+#define OFFLINE_P_H
+
+#include "offline.h"
+#include "daemonproxy.h"
+#include "daemonprivate.h"
+
+namespace PackageKit {
+class OfflinePrivate
+{
+    Q_DECLARE_PUBLIC(Offline)
+public:
+    OfflinePrivate(Offline *q) : q_ptr(q), iface(PK_NAME, PK_PATH, QDBusConnection::systemBus())
+    {
+    }
+
+    void updateProperties(const QVariantMap &properties);
+
+    Offline *q_ptr;
+    OrgFreedesktopPackageKitOfflineInterface iface;
+    QVariantMap preparedUpgrade;
+    Offline::Action triggerAction = Offline::ActionUnset;
+    bool updatePrepared = false;
+    bool updateTriggered = false;
+    bool upgradePrepared = false;
+    bool upgradeTriggered = false;
+};
+}
+
+#endif // OFFLINE_P_H
diff --git a/src/packagekitqt4.pc.in b/src/packagekitqt4.pc.in
deleted file mode 100644
index 2030ff2..0000000
--- a/src/packagekitqt4.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-libdir=@CMAKE_INSTALL_FULL_LIBDIR@
-includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
-
-Name: @LIBNAME@
-Description: PackageKit is a system daemon for installing stuff.
-Version: @VERSION@
-Requires: QtCore, QtDBus, QtXml
-Libs: -L${libdir} -l at LIBNAME@
-Cflags: -I${includedir}/PackageKit/@LIBNAME@
diff --git a/src/packagekitqt5.pc.in b/src/packagekitqt5.pc.in
index 99ace5b..7d896e4 100644
--- a/src/packagekitqt5.pc.in
+++ b/src/packagekitqt5.pc.in
@@ -5,7 +5,7 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
 
 Name: @LIBNAME@
 Description: PackageKit is a system daemon for installing stuff.
-Version: @VERSION@
-Requires: Qt5Core, Qt5DBus, Qt5Xml
-Libs: -L${libdir} -l at LIBNAME@
-Cflags: -I${includedir}/PackageKit/@LIBNAME@
+Version: @PROJECT_VERSION@
+Requires: Qt5Core, Qt5DBus
+Libs: -L${libdir} -lpackagekitqt5
+Cflags: -I${includedir}/packagekitqt5/PackageKit
diff --git a/src/transaction.cpp b/src/transaction.cpp
index a5fa4b8..4b717a0 100644
--- a/src/transaction.cpp
+++ b/src/transaction.cpp
@@ -1,7 +1,7 @@
 /*
  * This file is part of the QPackageKit project
  * Copyright (C) 2008 Adrien Bustany <madcat at mymadcat.com>
- * Copyright (C) 2010-2011 Daniel Nicoletti <dantti85-pk at yahoo.com.br>
+ * Copyright (C) 2010-2018 Daniel Nicoletti <dantti12 at gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -35,12 +35,26 @@ using namespace PackageKit;
 Transaction::Transaction()
     : d_ptr(new TransactionPrivate(this))
 {
+    Q_D(Transaction);
+
     connect(Daemon::global(), SIGNAL(daemonQuit()), SLOT(daemonQuit()));
 
     QDBusPendingReply<QDBusObjectPath> reply = Daemon::global()->createTransaction();
-    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
-    connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
-            this, SLOT(createTransactionFinished(QDBusPendingCallWatcher*)));
+    auto watcher = new QDBusPendingCallWatcher(reply, this);
+    connect(watcher, &QDBusPendingCallWatcher::finished,
+            this, [this, d] (QDBusPendingCallWatcher *call)
+    {
+        QDBusPendingReply<QDBusObjectPath> reply = *call;
+        if (reply.isError()) {
+            errorCode(Transaction::ErrorInternalError, reply.error().message());
+            d->finished(Transaction::ExitFailed, 0);
+            d->destroy();
+        } else {
+            // Setup our new Transaction ID
+            d->setup(reply.argumentAt<0>());
+        }
+        call->deleteLater();
+    });
 }
 
 Transaction::Transaction(const QDBusObjectPath &tid)
@@ -55,21 +69,18 @@ Transaction::Transaction(const QDBusObjectPath &tid)
 void Transaction::connectNotify(const QMetaMethod &signal)
 {
     Q_D(Transaction);
-    if (!d->connectedSignals.contains(signal) && d->p) {
-        d->setupSignal(signal, true);
+    if (!d->connectedSignals.contains(signal)) {
+        d->connectedSignals << signal;
+
+        if (d->p) {
+            d->setupSignal(signal);
+        }
     }
-    d->connectedSignals << signal;
 }
 
 void Transaction::disconnectNotify(const QMetaMethod &signal)
 {
-    Q_D(Transaction);
-    if (d->connectedSignals.contains(signal)) {
-        d->connectedSignals.removeOne(signal);
-        if (d->p && !d->connectedSignals.contains(signal)) {
-            d->setupSignal(signal, false);
-        }
-    }
+    QObject::disconnectNotify(signal);
 }
 
 Transaction::Transaction(TransactionPrivate *d)
@@ -77,7 +88,7 @@ Transaction::Transaction(TransactionPrivate *d)
 {
 }
 
-void TransactionPrivate::setupSignal(const QMetaMethod &signal, bool connect)
+void TransactionPrivate::setupSignal(const QMetaMethod &signal)
 {
     Q_Q(Transaction);
 
@@ -102,9 +113,6 @@ void TransactionPrivate::setupSignal(const QMetaMethod &signal, bool connect)
     } else if (signal == QMetaMethod::fromSignal(&Transaction::finished)) {
         signalToConnect = SIGNAL(Finished(uint,uint));
         memberToConnect = SLOT(finished(uint,uint));
-    } else if (signal == QMetaMethod::fromSignal(&Transaction::message)) {
-        signalToConnect = SIGNAL(Message(uint,QString));
-        memberToConnect = SLOT(message(uint,QString));
     } else if (signal == QMetaMethod::fromSignal(&Transaction::package)) {
         signalToConnect = SIGNAL(Package(uint,QString,QString));
         memberToConnect = SLOT(Package(uint,QString,QString));
@@ -135,11 +143,7 @@ void TransactionPrivate::setupSignal(const QMetaMethod &signal, bool connect)
     }
 
     if (signalToConnect && memberToConnect) {
-        if (connect) {
-            QObject::connect(p, signalToConnect, q, memberToConnect);
-        } else {
-            QObject::disconnect(p, signalToConnect, q, memberToConnect);
-        }
+        QObject::connect(p, signalToConnect, q, memberToConnect);
     }
 }
 
@@ -178,27 +182,65 @@ QDBusPendingReply<> Transaction::cancel()
 
 QString Transaction::packageName(const QString &packageID)
 {
-    return packageID.section(QLatin1Char(';'), 0, 0);
+    QString ret;
+    ret = packageID.left(packageID.indexOf(QLatin1Char(';')));
+    return ret;
 }
 
 QString Transaction::packageVersion(const QString &packageID)
 {
-    return packageID.section(QLatin1Char(';'), 1, 1);
+    QString ret;
+    int start = packageID.indexOf(QLatin1Char(';'));
+    if (start == -1) {
+        return ret;
+    }
+    int end = packageID.indexOf(QLatin1Char(';'), ++start);
+    if (Q_UNLIKELY(end == -1)) {
+        ret = packageID.mid(start);
+    } else {
+        ret = packageID.mid(start, end - start);
+    }
+    return ret;
 }
 
 QString Transaction::packageArch(const QString &packageID)
 {
-    return packageID.section(QLatin1Char(';'), 2, 2);
+    QString ret;
+    int start = packageID.indexOf(QLatin1Char(';'));
+    if (start == -1) {
+        return ret;
+    }
+    start = packageID.indexOf(QLatin1Char(';'), ++start);
+    if (start == -1) {
+        return ret;
+    }
+    int end = packageID.indexOf(QLatin1Char(';'), ++start);
+    if (Q_UNLIKELY(end == -1)) {
+        ret = packageID.mid(start);
+    } else {
+        ret = packageID.mid(start, end - start);
+    }
+    return ret;
 }
 
 QString Transaction::packageData(const QString &packageID)
 {
-    return packageID.section(QLatin1Char(';'), 3, 3);
-}
+    QString ret;
+    int start = packageID.indexOf(QLatin1Char(';'));
+    if (start == -1) {
+        return ret;
+    }
+    start = packageID.indexOf(QLatin1Char(';'), ++start);
+    if (start == -1) {
+        return ret;
+    }
+    start = packageID.indexOf(QLatin1Char(';'), ++start);
+    if (start == -1) {
+        return ret;
+    }
 
-QString Transaction::packageIcon(const QString &packageID)
-{
-    return QString();
+    ret = packageID.mid(++start);
+    return ret;
 }
 
 QString Transaction::lastPackage() const
@@ -254,7 +296,7 @@ QDBusPendingReply<> Transaction::setHints(const QStringList &hints)
 
 QDBusPendingReply<> Transaction::setHints(const QString &hints)
 {
-    return setHints(QStringList() << hints);
+    return setHints(QStringList{ hints });
 }
 
 Transaction::Status Transaction::status() const
@@ -342,4 +384,3 @@ Transaction::InternalError Transaction::parseError(const QString &errorName)
 }
 
 #include "moc_transaction.cpp"
-
diff --git a/src/transaction.h b/src/transaction.h
index 28348aa..71c9fcc 100644
--- a/src/transaction.h
+++ b/src/transaction.h
@@ -1,7 +1,7 @@
 /*
  * This file is part of the QPackageKit project
  * Copyright (C) 2008 Adrien Bustany <madcat at mymadcat.com>
- * Copyright (C) 2010-2016 Daniel Nicoletti <dantti12 at gmail.com>
+ * Copyright (C) 2010-2018 Daniel Nicoletti <dantti12 at gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -45,7 +45,7 @@ class Details;
 * A Transaction is created whenever you do an asynchronous action (for example a Search, Install...).
 * This class allows you to monitor and control the flow of the action.
 *
-* You should delete the transaction after finished() is emitted
+* Transaction will be automatically deleted after finished() is emitted
 *
 * \sa Daemon
 */
@@ -130,7 +130,8 @@ public:
         RoleRepairSystem,       // Since 0.7.2
         RoleGetDetailsLocal,    // Since 0.8.17
         RoleGetFilesLocal,      // Since 0.9.1
-        RoleRepoRemove          // Since 0.9.1
+        RoleRepoRemove,         // Since 0.9.1
+        RoleUpgradeSystem       // since 1.0.11
     };
     Q_ENUM(Role)
     typedef Bitfield Roles;
@@ -259,36 +260,14 @@ public:
         FilterNotCollections = 0x0800000,
         FilterApplication    = 0x1000000,
         FilterNotApplication = 0x2000000,
+        FilterDownloaded     = 0x4000000,
+        FilterNotDownloaded  = 0x8000000,
         /* this always has to be at the end of the list */
-        FilterLast           = 0x4000000
+        FilterLast           = 0x10000000
     };
     Q_ENUM(Filter)
     Q_DECLARE_FLAGS(Filters, Filter)
 
-    /**
-     * Describes a message's type
-     */
-    enum Message {
-        MessageUnknown,
-        MessageBrokenMirror,
-        MessageConnectionRefused,
-        MessageParameterInvalid,
-        MessagePriorityInvalid,
-        MessageBackendError,
-        MessageDaemonError,
-        MessageCacheBeingRebuilt,
-        MessageUntrustedPackage,
-        MessageNewerPackageExists,
-        MessageCouldNotFindPackage,
-        MessageConfigFilesChanged,
-        MessagePackageAlreadyInstalled,
-        MessageAutoremoveIgnored,
-        MessageRepoMetadataDownloadFailed,
-        MessageRepoForDevelopersOnly,
-        MessageOtherUpdatesHeldBack
-    };
-    Q_ENUM(Message)
-
     /**
      * Describes the current state of the transaction
      */
@@ -328,7 +307,8 @@ public:
         StatusScanProcessList,
         StatusCheckExecutableFiles,
         StatusCheckLibraries,
-        StatusCopyFiles
+        StatusCopyFiles,
+        StatusRunHook
     };
     Q_ENUM(Status)
 
@@ -355,13 +335,28 @@ public:
 
     /**
      * Describes the type of distribution upgrade to perform
-     * \sa upgradeSystem()
+     * \sa Daemon::upgradeSystem()
+      */
+    enum UpgradeKind {
+        UpgradeKindUnknown,
+        UpgradeKindMinimal,
+        UpgradeKindDefault,
+        UpgradeKindComplete
+    };
+    Q_ENUM(UpgradeKind)
+
+    /**
+     * Describes the type of distribution upgrade to perform
+     * \sa Daemon::upgradeSystem()
      */
     enum TransactionFlag {
-        TransactionFlagNone         = 1 << 0, // Since: 0.8.1
-        TransactionFlagOnlyTrusted  = 1 << 1, // Since: 0.8.1
-        TransactionFlagSimulate     = 1 << 2, // Since: 0.8.1
-        TransactionFlagOnlyDownload = 1 << 3  // Since: 0.8.1
+        TransactionFlagNone           = 1 << 0, // Since: 0.8.1
+        TransactionFlagOnlyTrusted    = 1 << 1, // Since: 0.8.1
+        TransactionFlagSimulate       = 1 << 2, // Since: 0.8.1
+        TransactionFlagOnlyDownload   = 1 << 3,  // Since: 1.0.2
+        TransactionFlagAllowReinstall = 1 << 4,  // Since: 1.0.2
+        TransactionFlagJustReinstall  = 1 << 5,  // Since: 1.0.2
+        TransactionFlagAllowDowngrade = 1 << 6  // Since: 0.8.1
     };
     Q_DECLARE_FLAGS(TransactionFlags, TransactionFlag)
     Q_ENUM(TransactionFlag)
@@ -462,7 +457,8 @@ public:
         InfoPreparing,
         InfoDecompressing,
         InfoUntrusted,
-        InfoTrusted
+        InfoTrusted,
+        InfoUnavailable
     };
     Q_ENUM(Info)
 
@@ -674,13 +670,6 @@ public:
      */
     static QString packageData(const QString &packageID);
 
-    /**
-     * Returns the package icon from the \p packageID
-     *
-     * @deprecated use Appstream to fetch icons
-     */
-    static QT_DEPRECATED QString packageIcon(const QString &packageID);
-
 Q_SIGNALS:
     void allowCancelChanged();
 
@@ -769,13 +758,6 @@ Q_SIGNALS:
      */
     void finished(PackageKit::Transaction::Exit status, uint runtime);
 
-    /**
-     * Conveys a message sent from the backend
-     *
-     * \p type is the type of the \p message
-     */
-    void message(PackageKit::Transaction::Message type, const QString &message);
-
     /**
      * Emitted when the transaction sends a new package
      */
@@ -846,9 +828,7 @@ protected:
     void connectNotify(const QMetaMethod &signal) override;
 
     /**
-     * This method disconnects from DBus signals
      * \attention Make sure to call this method in inherited classes
-     * otherwise no signals will be disconnected
      */
     void disconnectNotify(const QMetaMethod &signal) override;
 
@@ -869,14 +849,11 @@ private:
     friend class Daemon;
     Q_DECLARE_PRIVATE(Transaction)
     Q_DISABLE_COPY(Transaction)
-    Q_PRIVATE_SLOT(d_func(), void createTransactionFinished(QDBusPendingCallWatcher*))
-    Q_PRIVATE_SLOT(d_func(), void methodCallFinished(QDBusPendingCallWatcher*))
     Q_PRIVATE_SLOT(d_func(), void distroUpgrade(uint type, const QString &name, const QString &description))
     Q_PRIVATE_SLOT(d_func(), void details(const QVariantMap &values))
     Q_PRIVATE_SLOT(d_func(), void errorCode(uint error, const QString &details))
     Q_PRIVATE_SLOT(d_func(), void mediaChangeRequired(uint mediaType, const QString &mediaId, const QString &mediaText))
     Q_PRIVATE_SLOT(d_func(), void finished(uint exitCode, uint runtime))
-    Q_PRIVATE_SLOT(d_func(), void message(uint type, const QString &message))
     Q_PRIVATE_SLOT(d_func(), void Package(uint info, const QString &pid, const QString &summary))
     Q_PRIVATE_SLOT(d_func(), void ItemProgress(const QString &itemID, uint status, uint percentage))
     Q_PRIVATE_SLOT(d_func(), void RepoSignatureRequired(const QString &pid, const QString &repoName, const QString &keyUrl, const QString &keyUserid, const QString &keyId, const QString &keyFingerprint, const QString &keyTimestamp, uint type))
@@ -896,7 +873,6 @@ Q_DECLARE_METATYPE(PackageKit::Transaction::InternalError)
 Q_DECLARE_METATYPE(PackageKit::Transaction::Role)
 Q_DECLARE_METATYPE(PackageKit::Transaction::Error)
 Q_DECLARE_METATYPE(PackageKit::Transaction::Exit)
-Q_DECLARE_METATYPE(PackageKit::Transaction::Message)
 Q_DECLARE_METATYPE(PackageKit::Transaction::Status)
 Q_DECLARE_METATYPE(PackageKit::Transaction::MediaType)
 Q_DECLARE_METATYPE(PackageKit::Transaction::DistroUpgrade)
@@ -909,5 +885,6 @@ Q_DECLARE_METATYPE(PackageKit::Transaction::SigType)
 Q_DECLARE_METATYPE(PackageKit::Transaction::Filter)
 Q_DECLARE_METATYPE(PackageKit::Transaction::TransactionFlags)
 Q_DECLARE_METATYPE(PackageKit::Transaction::Filters)
+Q_DECLARE_METATYPE(PackageKit::Transaction::UpgradeKind)
 
 #endif
diff --git a/src/transactionprivate.cpp b/src/transactionprivate.cpp
index d1e4cb7..8a40f4c 100644
--- a/src/transactionprivate.cpp
+++ b/src/transactionprivate.cpp
@@ -1,7 +1,7 @@
 /*
  * This file is part of the QPackageKit project
  * Copyright (C) 2008 Adrien Bustany <madcat at mymadcat.com>
- * Copyright (C) 2010-2016 Daniel Nicoletti <dantti12 at gmail.com>
+ * Copyright (C) 2010-2018 Daniel Nicoletti <dantti12 at gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -20,14 +20,13 @@
  */
 
 #include "transactionprivate.h"
+#include "daemonprivate.h"
 
-#include "transactionproxy.h"
 #include "daemon.h"
 #include "common.h"
 #include "details.h"
 
 #include <QStringList>
-#include <QDebug>
 
 using namespace PackageKit;
 
@@ -46,7 +45,7 @@ void TransactionPrivate::setup(const QDBusObjectPath &transactionId)
     Q_Q(Transaction);
 
     tid = transactionId;
-    p = new OrgFreedesktopPackageKitTransactionInterface(QLatin1String(PK_NAME),
+    p = new OrgFreedesktopPackageKitTransactionInterface(PK_NAME,
                                                          tid.path(),
                                                          QDBusConnection::systemBus(),
                                                          q);
@@ -57,25 +56,26 @@ void TransactionPrivate::setup(const QDBusObjectPath &transactionId)
     q->connect(p, SIGNAL(Destroy()), SLOT(destroy()));
 
     // Get current properties
-    QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String(PK_NAME),
+    QDBusMessage message = QDBusMessage::createMethodCall(PK_NAME,
                                                           tid.path(),
-                                                          QLatin1String(DBUS_PROPERTIES),
+                                                          DBUS_PROPERTIES,
                                                           QLatin1String("GetAll"));
-    message << QLatin1String(PK_TRANSACTION_INTERFACE);
+    message << PK_TRANSACTION_INTERFACE;
     QDBusConnection::systemBus().callWithCallback(message,
                                                   q,
                                                   SLOT(updateProperties(QVariantMap)));
 
     // Watch for properties updates
-    QDBusConnection::systemBus().connect(QLatin1String(PK_NAME),
+    QDBusConnection::systemBus().connect(PK_NAME,
                                          tid.path(),
-                                         QLatin1String(DBUS_PROPERTIES),
+                                         DBUS_PROPERTIES,
                                          QLatin1String("PropertiesChanged"),
                                          q,
                                          SLOT(propertiesChanged(QString,QVariantMap,QStringList)));
 
-    foreach (const QMetaMethod &signal, connectedSignals) {
-        setupSignal(signal, true);
+    const QVector<QMetaMethod> signals = connectedSignals;
+    for (const QMetaMethod &signal : signals) {
+        setupSignal(signal);
     }
 
     // Execute pending call
@@ -181,40 +181,24 @@ void TransactionPrivate::runQueuedTransaction()
     case Transaction::RoleRepoRemove:
         reply = p->RepoRemove(transactionFlags, repoId, autoremove);
         break;
+    case Transaction::RoleUpgradeSystem:
+        reply = p->UpgradeSystem(transactionFlags, upgradeDistroId, upgradeKind);
+        break;
     default:
         break;
     }
 
-    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, q);
-    q->connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
-               q, SLOT(methodCallFinished(QDBusPendingCallWatcher*)));
-}
-
-void TransactionPrivate::createTransactionFinished(QDBusPendingCallWatcher *call)
-{
-    Q_Q(Transaction);
-    QDBusPendingReply<QDBusObjectPath> reply = *call;
-    if (reply.isError()) {
-        q->errorCode(Transaction::ErrorInternalError, reply.error().message());
-        finished(Transaction::ExitFailed, 0);
-        destroy();
-    } else {
-        // Setup our new Transaction ID
-        setup(reply.argumentAt<0>());
-    }
-    call->deleteLater();
-}
-
-void TransactionPrivate::methodCallFinished(QDBusPendingCallWatcher *call)
-{
-    Q_Q(Transaction);
-    QDBusPendingReply<> reply = *call;
-    if (reply.isError()) {
-        q->errorCode(Transaction::ErrorInternalError, reply.error().message());
-        finished(Transaction::ExitFailed, 0);
-        destroy();
-    }
-    call->deleteLater();
+    auto watcher = new QDBusPendingCallWatcher(reply, q);
+    q->connect(watcher, &QDBusPendingCallWatcher::finished,
+               q, [this, q] (QDBusPendingCallWatcher *call) {
+        QDBusPendingReply<> reply = *call;
+        if (reply.isError()) {
+            q->errorCode(Transaction::ErrorInternalError, reply.error().message());
+            finished(Transaction::ExitFailed, 0);
+            destroy();
+        }
+        call->deleteLater();
+    });
 }
 
 void TransactionPrivate::details(const QVariantMap &values)
@@ -250,6 +234,7 @@ void TransactionPrivate::finished(uint exitCode, uint runtime)
     Q_Q(Transaction);
     q->finished(static_cast<Transaction::Exit>(exitCode), runtime);
     sentFinished = true;
+    q->deleteLater();
 }
 
 void TransactionPrivate::destroy()
@@ -257,7 +242,7 @@ void TransactionPrivate::destroy()
     Q_Q(Transaction);
     if (p) {
        delete p;
-       p = 0;
+       p = nullptr;
     }
 
     if (!sentFinished) {
@@ -340,12 +325,6 @@ void TransactionPrivate::updateProperties(const QVariantMap &properties)
     }
 }
 
-void TransactionPrivate::message(uint type, const QString &message)
-{
-    Q_Q(Transaction);
-    q->message(static_cast<Transaction::Message>(type), message);
-}
-
 void TransactionPrivate::Package(uint info, const QString &pid, const QString &summary)
 {
     Q_Q(Transaction);
@@ -399,7 +378,7 @@ void TransactionPrivate::transaction(const QDBusObjectPath &oldTid,
 {
     Q_Q(Transaction);
 
-    TransactionPrivate *priv = new TransactionPrivate(q);
+    auto priv = new TransactionPrivate(q);
     priv->tid = tid;
     priv->timespec = QDateTime::fromString(timespec, Qt::ISODate);
     priv->succeeded = succeeded;
@@ -409,7 +388,7 @@ void TransactionPrivate::transaction(const QDBusObjectPath &oldTid,
     priv->uid = uid;
     priv->cmdline = cmdline;
 
-    Transaction *transaction = new Transaction(priv);
+    auto transaction = new Transaction(priv);
     priv->q_ptr = transaction;
 
     q->transaction(transaction);
diff --git a/src/transactionprivate.h b/src/transactionprivate.h
index c0a2b60..1cc77c7 100644
--- a/src/transactionprivate.h
+++ b/src/transactionprivate.h
@@ -23,13 +23,12 @@
 #define PACKAGEKIT_TRANSACTION_PRIVATE_H
 
 #include <QString>
-#include <QHash>
+#include <QList>
 #include <QStringList>
 #include <QDBusPendingCallWatcher>
 
 #include "transaction.h"
-
-class OrgFreedesktopPackageKitTransactionInterface;
+#include "transactionproxy.h"
 
 namespace PackageKit {
 
@@ -45,13 +44,10 @@ protected:
     void runQueuedTransaction();
 
     QDBusObjectPath tid;
-    ::OrgFreedesktopPackageKitTransactionInterface* p = 0;
+    QPointer<::OrgFreedesktopPackageKitTransactionInterface> p;
     Transaction *q_ptr;
-    QList<QMetaMethod> connectedSignals;
+    QVector<QMetaMethod> connectedSignals;
 
-    bool sentFinished = false;
-    bool allowCancel = false;
-    bool callerActive = false;
     qulonglong downloadSizeRemaining = 0;
     uint elapsedTime = 0;
     QString lastPackage;
@@ -61,6 +57,9 @@ protected:
     uint speed = 0;
     Transaction::Status status = Transaction::StatusUnknown;
     uint uid = 0;
+    bool sentFinished = false;
+    bool allowCancel = false;
+    bool callerActive = false;
 
     // Queue params
     QString eulaId;
@@ -88,21 +87,21 @@ protected:
     QString data;
     QString cmdline;
 
-    void setupSignal(const QMetaMethod &signal, bool connect);
+    QString upgradeDistroId;
+    Transaction::UpgradeKind upgradeKind;
+
+    void setupSignal(const QMetaMethod &signal);
 
 private:
     template <typename Func1, typename Func2>
     void processConnect(bool connect, Func1 signal, Func2 slot);
 
 protected Q_SLOTS:
-    void createTransactionFinished(QDBusPendingCallWatcher *call);
-    void methodCallFinished(QDBusPendingCallWatcher *call);
     void details(const QVariantMap &values);
     void distroUpgrade(uint type, const QString &name, const QString &description);
     void errorCode(uint error, const QString &details);
     void mediaChangeRequired(uint mediaType, const QString &mediaId, const QString &mediaText);
     void finished(uint exitCode, uint runtime);
-    void message(uint type, const QString &message);
     void Package(uint info, const QString &pid, const QString &summary);
     void ItemProgress(const QString &itemID, uint status, uint percentage);
     void RepoSignatureRequired(const QString &pid,



More information about the Neon-commits mailing list