summaryrefslogtreecommitdiffstats
path: root/src/sdk
diff options
context:
space:
mode:
Diffstat (limited to 'src/sdk')
-rw-r--r--src/sdk/commandlineparser.cpp109
-rw-r--r--src/sdk/commandlineparser.h56
-rw-r--r--src/sdk/console.h98
-rw-r--r--src/sdk/console_win.cpp142
-rw-r--r--src/sdk/constants.h62
-rw-r--r--src/sdk/installerbase.cpp633
-rw-r--r--src/sdk/installerbase.h63
-rw-r--r--src/sdk/installerbase_p.cpp327
-rw-r--r--src/sdk/installerbase_p.h92
-rw-r--r--src/sdk/installerbasecommons.cpp508
-rw-r--r--src/sdk/installerbasecommons.h102
-rw-r--r--src/sdk/main.cpp203
-rw-r--r--src/sdk/sdk.pro46
-rw-r--r--src/sdk/sdkapp.h115
-rw-r--r--src/sdk/settingsdialog.cpp36
-rw-r--r--src/sdk/settingsdialog.h21
-rw-r--r--src/sdk/settingsdialog.ui545
-rw-r--r--src/sdk/tabcontroller.cpp35
-rw-r--r--src/sdk/tabcontroller.h21
-rw-r--r--src/sdk/translations/ja_jp.ts22
-rw-r--r--src/sdk/updatechecker.cpp118
-rw-r--r--src/sdk/updatechecker.h50
22 files changed, 1353 insertions, 2051 deletions
diff --git a/src/sdk/commandlineparser.cpp b/src/sdk/commandlineparser.cpp
new file mode 100644
index 000000000..9c4200b3e
--- /dev/null
+++ b/src/sdk/commandlineparser.cpp
@@ -0,0 +1,109 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "commandlineparser.h"
+
+#include "constants.h"
+
+namespace CommandLineOptions {
+const char KeyValue[] = "Key=Value";
+} // namespace CommandLineOptions
+
+CommandLineParser::CommandLineParser()
+{
+ m_parser.addHelpOption();
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::Version),
+ QLatin1String("Displays version information.")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::FrameworkVersion),
+ QLatin1String("Displays the version of the Qt Installer Framework.")));
+
+ m_parser.addOption(QCommandLineOption(QStringList()
+ << QLatin1String(CommandLineOptions::VerboseShort)
+ << QLatin1String(CommandLineOptions::VerboseLong),
+ QLatin1String("Verbose mode. Prints out more information.")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::Proxy),
+ QLatin1String("Use system proxy on Windows and OS X. This option has no effect on Linux.")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::Script),
+ QLatin1String("Execute the script given as argument."), QLatin1String("file")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::CheckUpdates),
+ QLatin1String("Check for updates and return an XML description.")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::Updater),
+ QLatin1String("Start application in updater mode.")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::ManagePackages),
+ QLatin1String("Start application in package manager mode.")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::NoForceInstallation),
+ QLatin1String("Allow deselecting components that are marked as forced.")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::ShowVirtualComponents),
+ QLatin1String("Show virtual components in installer and package manager.")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::CreateOfflineRepository),
+ QLatin1String("Create a local repository inside the installation directory. This option "
+ "has no effect on online installers.")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::AddRepository),
+ QLatin1String("Add a local or remote repository to the list of user defined repositories."),
+ QLatin1String("URI,...")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::AddTmpRepository),
+ QLatin1String("Add a local or remote repository to the list of temporary available "
+ "repositories."), QLatin1String("URI,...")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::SetTmpRepository),
+ QLatin1String("Set a local or remote repository as temporary repository, it is the only "
+ "one used during fetch.\nNote: URI must be prefixed with the protocol, i.e. file:///, "
+ "https://, http:// or ftp://."), QLatin1String("URI,...")));
+
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::StartServer),
+ QLatin1String("Starts the application as headless process waiting for commands to execute."
+ " Mode can be DEBUG or PRODUCTION. In DEBUG mode, the option values can be omitted."
+ "Note: The server will not shutdown on his own, you need to quit the process by hand."),
+ QLatin1String("mode,port,key")));
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::StartClient),
+ QString::fromLatin1("Starts the application to debug the client-server communication. If "
+ "a value is omitted, the client will use a default instead. Note: The server process is "
+ "not started by the client application in that case, you need to start it on your own."),
+ QLatin1String("port,key")));
+
+ m_parser.addPositionalArgument(QLatin1String(CommandLineOptions::KeyValue),
+ QLatin1String("Key Value pair to be set."));
+}
diff --git a/src/sdk/commandlineparser.h b/src/sdk/commandlineparser.h
new file mode 100644
index 000000000..2bdd34f0d
--- /dev/null
+++ b/src/sdk/commandlineparser.h
@@ -0,0 +1,56 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#ifndef COMMANDLINEPARSER_H
+#define COMMANDLINEPARSER_H
+
+#include <QCommandLineParser>
+
+class CommandLineParser
+{
+public:
+ CommandLineParser();
+
+ QString helpText() const { return m_parser.helpText(); }
+ bool isSet(const QString &option) { return m_parser.isSet(option); }
+ QStringList unknownOptionNames() const { return m_parser.unknownOptionNames(); }
+ QStringList positionalArguments() const { return m_parser.positionalArguments(); }
+ bool parse(const QStringList &argumens) { return m_parser.parse(argumens); }
+ QString value(const QString &option) const { return m_parser.value(option); }
+
+private:
+ QCommandLineParser m_parser;
+};
+
+#endif // COMMANDLINEPARSER_H
diff --git a/src/sdk/console.h b/src/sdk/console.h
index 7eb4aa3f4..a29c7b088 100644
--- a/src/sdk/console.h
+++ b/src/sdk/console.h
@@ -16,24 +16,17 @@
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
**
** $QT_END_LICENSE$
**
@@ -42,90 +35,37 @@
#ifndef CONSOLE_H
#define CONSOLE_H
-#include <QtCore/QtGlobal>
+#include <QtGlobal>
#ifdef Q_OS_WIN
-# include <qt_windows.h>
-# include <wincon.h>
-
-# include <fstream>
-# include <iostream>
-
-# ifndef ENABLE_INSERT_MODE
-# define ENABLE_INSERT_MODE 0x0020
-# endif
-
-# ifndef ENABLE_QUICK_EDIT_MODE
-# define ENABLE_QUICK_EDIT_MODE 0x0040
-# endif
-# ifndef ENABLE_EXTENDED_FLAGS
-# define ENABLE_EXTENDED_FLAGS 0x0080
-# endif
+#include <fstream>
+#include <iostream>
class Console
{
public:
- Console()
- {
- AllocConsole();
- HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
- if (handle != INVALID_HANDLE_VALUE) {
- COORD largestConsoleWindowSize = GetLargestConsoleWindowSize(handle);
- largestConsoleWindowSize.X -= 3;
- largestConsoleWindowSize.Y = 5000;
- SetConsoleScreenBufferSize(handle, largestConsoleWindowSize);
- }
-
- handle = GetStdHandle(STD_INPUT_HANDLE);
- if (handle != INVALID_HANDLE_VALUE)
- SetConsoleMode(handle, ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS);
-
- m_oldCin = std::cin.rdbuf();
- m_newCin.open("CONIN$");
- std::cin.rdbuf(m_newCin.rdbuf());
-
- m_oldCout = std::cout.rdbuf();
- m_newCout.open("CONOUT$");
- std::cout.rdbuf(m_newCout.rdbuf());
-
- m_oldCerr = std::cerr.rdbuf();
- m_newCerr.open("CONOUT$");
- std::cerr.rdbuf(m_newCerr.rdbuf());
-# ifndef Q_CC_MINGW
- HMENU systemMenu = GetSystemMenu(GetConsoleWindow(), FALSE);
- if (systemMenu != NULL)
- RemoveMenu(systemMenu, SC_CLOSE, MF_BYCOMMAND);
- DrawMenuBar(GetConsoleWindow());
-# endif
- }
-
- ~Console()
- {
- system("PAUSE");
-
- std::cin.rdbuf(m_oldCin);
- std::cerr.rdbuf(m_oldCerr);
- std::cout.rdbuf(m_oldCout);
-
- FreeConsole();
- }
+ Console();
+ ~Console();
private:
- std::ifstream m_newCin;
+ bool parentConsole;
+
std::ofstream m_newCout;
std::ofstream m_newCerr;
- std::streambuf* m_oldCin;
std::streambuf* m_oldCout;
std::streambuf* m_oldCerr;
};
-#else
+
+#else // Q_OS_WIN
+
class Console
{
public:
Console() {}
};
-#endif
+
+#endif // Q_OS_WIN
#endif // CONSOLE_H
diff --git a/src/sdk/console_win.cpp b/src/sdk/console_win.cpp
new file mode 100644
index 000000000..da5dca49f
--- /dev/null
+++ b/src/sdk/console_win.cpp
@@ -0,0 +1,142 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "console.h"
+
+# include <qt_windows.h>
+# include <wincon.h>
+
+
+# ifndef ENABLE_INSERT_MODE
+# define ENABLE_INSERT_MODE 0x0020
+# endif
+
+# ifndef ENABLE_QUICK_EDIT_MODE
+# define ENABLE_QUICK_EDIT_MODE 0x0040
+# endif
+
+# ifndef ENABLE_EXTENDED_FLAGS
+# define ENABLE_EXTENDED_FLAGS 0x0080
+# endif
+
+static bool isRedirected(HANDLE stdHandle)
+{
+ if (stdHandle == NULL) // launched from GUI
+ return false;
+ DWORD fileType = GetFileType(stdHandle);
+ if (fileType == FILE_TYPE_UNKNOWN) {
+ // launched from console, but no redirection
+ return false;
+ }
+ // redirected into file, pipe ...
+ return true;
+}
+
+/**
+ * Redirects stdout, stderr output to console
+ *
+ * Console is a RAII class that ensures stdout, stderr output is visible
+ * for GUI applications on Windows.
+ *
+ * If the application is launched from the explorer, startup menu etc
+ * a new console window is created.
+ *
+ * If the application is launched from the console (cmd.exe), output is
+ * printed there.
+ *
+ * If the application is launched from the console, but stdout is redirected
+ * (e.g. into a file), Console does not interfere.
+ */
+Console::Console() :
+ m_oldCout(0),
+ m_oldCerr(0)
+{
+ bool isCoutRedirected = isRedirected(GetStdHandle(STD_OUTPUT_HANDLE));
+ bool isCerrRedirected = isRedirected(GetStdHandle(STD_ERROR_HANDLE));
+
+ if (!isCoutRedirected) { // verbose output only ends up in cout
+ // try to use parent console. else launch & set up new console
+ parentConsole = AttachConsole(ATTACH_PARENT_PROCESS);
+ if (!parentConsole) {
+ AllocConsole();
+ HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (handle != INVALID_HANDLE_VALUE) {
+ COORD largestConsoleWindowSize = GetLargestConsoleWindowSize(handle);
+ largestConsoleWindowSize.X -= 3;
+ largestConsoleWindowSize.Y = 5000;
+ SetConsoleScreenBufferSize(handle, largestConsoleWindowSize);
+ }
+ handle = GetStdHandle(STD_INPUT_HANDLE);
+ if (handle != INVALID_HANDLE_VALUE)
+ SetConsoleMode(handle, ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE
+ | ENABLE_EXTENDED_FLAGS);
+# ifndef Q_CC_MINGW
+ HMENU systemMenu = GetSystemMenu(GetConsoleWindow(), FALSE);
+ if (systemMenu != NULL)
+ RemoveMenu(systemMenu, SC_CLOSE, MF_BYCOMMAND);
+ DrawMenuBar(GetConsoleWindow());
+# endif
+ }
+ }
+
+ if (!isCoutRedirected) {
+ m_oldCout = std::cout.rdbuf();
+ m_newCout.open("CONOUT$");
+ std::cout.rdbuf(m_newCout.rdbuf());
+ }
+
+ if (!isCerrRedirected) {
+ m_oldCerr = std::cerr.rdbuf();
+ m_newCerr.open("CONOUT$");
+ std::cerr.rdbuf(m_newCerr.rdbuf());
+ }
+}
+
+Console::~Console()
+{
+ if (!parentConsole) {
+ system("PAUSE");
+ } else {
+ // simulate enter key to switch to boot prompt
+ PostMessage(GetConsoleWindow(), WM_KEYDOWN, 0x0D, 0);
+ }
+
+ if (m_oldCerr)
+ std::cerr.rdbuf(m_oldCerr);
+ if (m_oldCout)
+ std::cout.rdbuf(m_oldCout);
+
+ if (m_oldCout)
+ FreeConsole();
+}
diff --git a/src/sdk/constants.h b/src/sdk/constants.h
new file mode 100644
index 000000000..44fe1f598
--- /dev/null
+++ b/src/sdk/constants.h
@@ -0,0 +1,62 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#ifndef CONSTANTS_H
+#define CONSTANTS_H
+
+namespace CommandLineOptions {
+
+const char HelpShort[] = "h";
+const char HelpLong[] = "help";
+const char Version[] = "version";
+const char FrameworkVersion[] = "framework-version";
+const char VerboseShort[] = "v";
+const char VerboseLong[] = "verbose";
+const char Proxy[] = "proxy";
+const char Script[] = "script";
+const char CheckUpdates[] = "checkupdates";
+const char Updater[] = "updater";
+const char ManagePackages[] = "manage-packages";
+const char NoForceInstallation[] = "no-force-installations";
+const char ShowVirtualComponents[] = "show-virtual-components";
+const char CreateOfflineRepository[] = "create-offline-repository";
+const char AddRepository[] = "addRepository";
+const char AddTmpRepository[] = "addTempRepository";
+const char SetTmpRepository[] = "setTempRepository";
+const char StartServer[] = "startserver";
+const char StartClient[] = "startclient";
+
+} // namespace CommandLineOptions
+
+#endif // CONSTANTS_H
diff --git a/src/sdk/installerbase.cpp b/src/sdk/installerbase.cpp
index 8c9fdad51..6253f3e25 100644
--- a/src/sdk/installerbase.cpp
+++ b/src/sdk/installerbase.cpp
@@ -16,485 +16,290 @@
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
**
** $QT_END_LICENSE$
**
**************************************************************************/
-#include "installerbase_p.h"
+#include "constants.h"
+#include "commandlineparser.h"
+#include "installerbase.h"
#include "installerbasecommons.h"
-#include "sdkapp.h"
#include "tabcontroller.h"
-#include <binaryformat.h>
+#include <binaryformatenginehandler.h>
+#include <copydirectoryoperation.h>
#include <errors.h>
-#include <fileutils.h>
-#include <fsengineserver.h>
#include <init.h>
-#include <lib7z_facade.h>
-#include <operationrunner.h>
+#include <kdupdaterupdateoperations.h>
+#include <messageboxhandler.h>
#include <packagemanagercore.h>
-#include <packagemanagergui.h>
-#include <qinstallerglobal.h>
+#include <packagemanagerproxyfactory.h>
+#include <qprocesswrapper.h>
+#include <protocol.h>
+#include <productkeycheck.h>
#include <settings.h>
#include <utils.h>
-#include <updater.h>
-#include <messageboxhandler.h>
-#include <kdselfrestarter.h>
#include <kdrunoncechecker.h>
#include <kdupdaterfiledownloaderfactory.h>
-#include <productkeycheck.h>
-
#include <QDirIterator>
-#include <QtCore/QTranslator>
-
-#include <QtNetwork/QNetworkProxyFactory>
-
-#include <iostream>
-#include <fstream>
-
-#include <string>
-
-#define QUOTE_(x) #x
-#define QUOTE(x) QUOTE_(x)
-#define VERSION "IFW Version: \"" QUOTE(IFW_VERSION) "\", Installer base SHA1: \"" QUOTE(_GIT_SHA1_) \
- "\", Build date: " QUOTE(__DATE__) "."
-
-using namespace QInstaller;
-using namespace QInstallerCreator;
+#include <QTemporaryFile>
+#include <QTranslator>
+#include <QUuid>
-static const char installer_create_datetime_placeholder [32] = "MY_InstallerCreateDateTime_MY";
-
-static QStringList repositories(const QStringList &arguments, const int index)
+InstallerBase::InstallerBase(int &argc, char *argv[])
+ : SDKApp<QApplication>(argc, argv)
+ , m_core(0)
{
- if (index < arguments.size()) {
- QStringList items = arguments.at(index).split(QLatin1Char(','));
- foreach (const QString &item, items) {
- qDebug() << "Adding custom repository:" << item;
- }
- return items;
- } else {
- std::cerr << "No repository specified" << std::endl;
- }
- return QStringList();
+ QInstaller::init(); // register custom operations
}
-// -- main
-
-int main(int argc, char *argv[])
+InstallerBase::~InstallerBase()
{
-// increase maximum numbers of file descriptors
-#if defined (Q_OS_MAC)
- struct rlimit rl;
- getrlimit(RLIMIT_NOFILE, &rl);
- rl.rlim_cur = qMin((rlim_t)OPEN_MAX, rl.rlim_max);
- setrlimit(RLIMIT_NOFILE, &rl);
-#endif
-
- QStringList args = QInstaller::parseCommandLineArgs(argc, argv);
-
-// hack to use cleanlooks if it is under Ubuntu
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
- std::string standardString;
- std::string cleanLooks ="-style=cleanlooks";
- std::ifstream input("/etc/os-release");
- bool isUbuntu = false;
- while (std::getline(input, standardString)) {
- if (standardString == "ID=ubuntu")
- isUbuntu = true;
- }
+ delete m_core;
+}
- if (isUbuntu) {
- argc++;
- char **newArgv = new char* [argc];
- newArgv[0] = argv[0];
- newArgv[1] = const_cast<char*>(cleanLooks.data());
- for (int i = 1; i < argc-1; ++i) {
- newArgv[i+1] = argv[i];
+int InstallerBase::run()
+{
+ KDRunOnceChecker runCheck(qApp->applicationDirPath() + QLatin1String("/lockmyApp1234865.lock"));
+ if (runCheck.isRunning(KDRunOnceChecker::ConditionFlag::Lockfile)) {
+ // It is possible to install an application and thus the maintenance tool into a
+ // directory that requires elevated permission to create a lock file. Since this
+ // cannot be done without requesting credentials from the user, we silently ignore
+ // the fact that we could not create the lock file and check the running processes.
+ if (runCheck.isRunning(KDRunOnceChecker::ConditionFlag::ProcessList)) {
+ QInstaller::MessageBoxHandler::information(0, QLatin1String("AlreadyRunning"),
+ QString::fromLatin1("Waiting for %1").arg(qAppName()),
+ QString::fromLatin1("Another %1 instance is already running. Wait "
+ "until it finishes, close it, or restart your system.").arg(qAppName()));
+ return EXIT_FAILURE;
}
- argv = newArgv;
}
-#endif
- qsrand(QDateTime::currentDateTime().toTime_t());
- const KDSelfRestarter restarter(argc, argv);
- KDRunOnceChecker runCheck(QLatin1String("lockmyApp1234865.lock"));
-
- try {
- if (args.contains(QLatin1String("--help")) || args.contains(QLatin1String("-h"))) {
- InstallerBase::showUsage();
- return 0;
- }
-
- if (args.contains(QLatin1String("--version"))) {
- QString versionOutPut;
- QDateTime dateTimeCheck = QDateTime::fromString(QLatin1String(
- installer_create_datetime_placeholder), QLatin1String("yyyy-MM-dd - HH:mm:ss"));
- if (dateTimeCheck.isValid()) {
- versionOutPut.append(QLatin1String("Installer creation time: "));
- versionOutPut.append(QLatin1String(installer_create_datetime_placeholder));
- versionOutPut.append(QLatin1String("\n"));
- }
- versionOutPut.append(QLatin1String(VERSION));
- InstallerBase::showVersion(versionOutPut);
- return 0;
- }
-
- // this is the FSEngineServer as an admin rights process upon request:
- if (args.count() >= 3 && args[1] == QLatin1String("--startserver")) {
- SDKApp<QCoreApplication> app(argc, argv);
- FSEngineServer* const server = new FSEngineServer(args[2].toInt());
- if (args.count() >= 4)
- server->setAuthorizationKey(args[3]);
- QObject::connect(server, SIGNAL(destroyed()), &app, SLOT(quit()));
- return app.exec();
- }
-
- // Make sure we honor the system's proxy settings
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
- QUrl proxyUrl(QString::fromLatin1(qgetenv("http_proxy")));
- if (proxyUrl.isValid()) {
- QNetworkProxy proxy(QNetworkProxy::HttpProxy, proxyUrl.host(), proxyUrl.port(),
- proxyUrl.userName(), proxyUrl.password());
- QNetworkProxy::setApplicationProxy(proxy);
- }
-#else
- if (args.contains(QLatin1String("--proxy")))
- QNetworkProxyFactory::setUseSystemConfiguration(true);
-#endif
-
- if (args.contains(QLatin1String("--checkupdates"))) {
- SDKApp<QCoreApplication> app(argc, argv);
- if (runCheck.isRunning(KDRunOnceChecker::ProcessList))
- return 0;
-
- Updater u;
- if (args.contains(QLatin1String("--verbose")) || args.contains(QLatin1String("-v"))) {
- app.setVerbose();
- u.setVerbose(true);
- }
- return u.checkForUpdates() ? 0 : 1;
- }
-
- if (args.contains(QLatin1String("--runoperation"))
- || args.contains(QLatin1String("--undooperation"))) {
- SDKApp<QCoreApplication> app(argc, argv);
- OperationRunner o;
- o.setVerbose(args.contains(QLatin1String("--verbose"))
- || args.contains(QLatin1String("-v")));
- return o.runOperation(args);
- }
-
- if (args.contains(QLatin1String("--update-installerbase"))) {
- SDKApp<QCoreApplication> app(argc, argv);
- if (runCheck.isRunning(KDRunOnceChecker::ProcessList))
- return 0;
-
- return InstallerBase().replaceMaintenanceToolBinary(args);
- }
-
- if (args.contains(QLatin1String("--dump-binary-data"))) {
- bool verbose = args.contains(QLatin1String("--verbose")) || args.contains(QLatin1String("-v"));
-
- args = args.mid(args.indexOf(QLatin1String("--dump-binary-data")) + 1, 4);
- // we expect at least -o and the output path
- if (args.count() < 2 || !args.contains(QLatin1String("-o"))) {
- InstallerBase::showUsage();
- return EXIT_FAILURE;
- }
-
- // output path
- const QString output = args.at(args.indexOf(QLatin1String("-o")) + 1);
- if (output.isEmpty()) {
- InstallerBase::showUsage();
- return EXIT_FAILURE;
- }
+ QString fileName = datFile(binaryFile());
+ quint64 cookie = QInstaller::BinaryContent::MagicCookieDat;
+ if (fileName.isEmpty()) {
+ fileName = binaryFile();
+ cookie = QInstaller::BinaryContent::MagicCookie;
+ }
- SDKApp<QCoreApplication> app(argc, argv);
+ QFile binary(fileName);
+ QInstaller::openForRead(&binary);
- // input, if not given use current app
- QString input;
- if (args.indexOf(QLatin1String("-i")) >= 0)
- input = args.value(args.indexOf(QLatin1String("-i")) + 1);
+ qint64 magicMarker;
+ QInstaller::ResourceCollectionManager manager;
+ QList<QInstaller::OperationBlob> oldOperations;
+ QInstaller::BinaryContent::readBinaryContent(&binary, &oldOperations, &manager, &magicMarker,
+ cookie);
- if (input.isEmpty() || input == QLatin1String("-o") || input == output)
- input = QCoreApplication::applicationFilePath();
+ if (QInstaller::isVerbose()) {
+ qDebug() << "Language:" << QLocale().uiLanguages().value(0,
+ QLatin1String("No UI language set")).toUtf8().constData();
+ qDebug() << "Arguments: " << arguments().join(QLatin1String(", ")).toUtf8().constData();
+ }
- OperationRunner o(input);
- o.setVerbose(verbose);
- return o.runOperation(QStringList(QLatin1String("--runoperation"))
- << QLatin1String("CreateLocalRepository") << input << output);
- }
+ CommandLineParser parser;
+ parser.parse(arguments());
+
+ SDKApp::registerMetaResources(manager.collectionByName("QResources"));
+ if (parser.isSet(QLatin1String(CommandLineOptions::StartClient))) {
+ const QStringList arguments = parser.value(QLatin1String(CommandLineOptions::StartServer))
+ .split(QLatin1Char(','), QString::SkipEmptyParts);
+ m_core = new QInstaller::PackageManagerCore(magicMarker, oldOperations, QString(arguments
+ .value(0, QString::number(QInstaller::Protocol::DefaultPort))).toInt(),
+ arguments.value(1, QLatin1String(QInstaller::Protocol::DefaultAuthorizationKey)),
+ QInstaller::Protocol::Mode::Debug);
+ } else {
+ m_core = new QInstaller::PackageManagerCore(magicMarker, oldOperations,
+ 30000 + qrand() % 100, QUuid::createUuid().toString());
+ }
- // from here, the "normal" installer binary is running
- SDKApp<QApplication> app(argc, argv);
- args = app.arguments();
+ {
+ using namespace QInstaller;
+ ProductKeyCheck::instance()->init(m_core);
+ ProductKeyCheck::instance()->addPackagesFromXml(QLatin1String(":/metadata/Updates.xml"));
+ BinaryFormatEngineHandler::instance()->registerResources(manager.collections());
+ }
+ if (QInstaller::isVerbose())
+ dumpResourceTree();
+
+ QString controlScript;
+ if (parser.isSet(QLatin1String(CommandLineOptions::Script))) {
+ controlScript = parser.value(QLatin1String(CommandLineOptions::Script));
+ if (!QFileInfo(controlScript).exists())
+ throw QInstaller::Error(QLatin1String("Script file does not exist."));
+ }
- if (runCheck.isRunning(KDRunOnceChecker::ProcessList)) {
- if (runCheck.isRunning(KDRunOnceChecker::Lockfile))
- return 0;
+ if (parser.isSet(QLatin1String(CommandLineOptions::Proxy))) {
+ m_core->settings().setProxyType(QInstaller::Settings::SystemProxy);
+ KDUpdater::FileDownloaderFactory::instance().setProxyFactory(m_core->proxyFactory());
+ }
- while (runCheck.isRunning(KDRunOnceChecker::ProcessList))
- Sleep::sleep(1);
- }
+ if (parser.isSet(QLatin1String(CommandLineOptions::ShowVirtualComponents))) {
+ QFont f;
+ f.setItalic(true);
+ QInstaller::PackageManagerCore::setVirtualComponentsFont(f);
+ QInstaller::PackageManagerCore::setVirtualComponentsVisible(true);
+ }
- if (args.contains(QLatin1String("--verbose")) || args.contains(QLatin1String("-v"))) {
- app.setVerbose();
- QInstaller::setVerbose(true);
- }
+ if (parser.isSet(QLatin1String(CommandLineOptions::Updater))) {
+ if (m_core->isInstaller())
+ throw QInstaller::Error(QLatin1String("Cannot start installer binary as updater."));
+ m_core->setUpdater();
+ }
- if (QInstaller::isVerbose()) {
- qDebug() << VERSION;
- qDebug() << "Arguments:" << args;
- qDebug() << "Resource tree before loading the in-binary resource:";
- qDebug() << "Language: " << QLocale().uiLanguages().value(0, QLatin1String("No UI language set"));
+ if (parser.isSet(QLatin1String(CommandLineOptions::ManagePackages))) {
+ if (m_core->isInstaller())
+ throw QInstaller::Error(QLatin1String("Cannot start installer binary as package manager."));
+ m_core->setPackageManager();
+ }
- QDirIterator it(QLatin1String(":/"), QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden,
- QDirIterator::Subdirectories);
- while (it.hasNext())
- qDebug() << QString::fromLatin1(" %1").arg(it.next());
- }
+ if (parser.isSet(QLatin1String(CommandLineOptions::AddRepository))) {
+ const QStringList repoList = repositories(parser
+ .value(QLatin1String(CommandLineOptions::AddRepository)));
+ if (repoList.isEmpty())
+ throw QInstaller::Error(QLatin1String("Empty repository list for option 'addRepository'."));
+ m_core->addUserRepositories(repoList);
+ }
- // register custom operations before reading the binary content cause they may used in
- // the uninstaller for the recorded list of during the installation performed operations
- QInstaller::init();
-
- QString binaryFile = QCoreApplication::applicationFilePath();
- const int index = args.indexOf(QLatin1String("--binarydatafile"));
- if (index >= 0) {
- binaryFile = args.value(index + 1);
- if (binaryFile.isEmpty()) {
- std::cerr << QFileInfo(app.applicationFilePath()).fileName() << " --binarydatafile [missing "
- "argument]" << std::endl;
- return PackageManagerCore::Failure;
- }
+ if (parser.isSet(QLatin1String(CommandLineOptions::AddTmpRepository))) {
+ const QStringList repoList = repositories(parser
+ .value(QLatin1String(CommandLineOptions::AddTmpRepository)));
+ if (repoList.isEmpty())
+ throw QInstaller::Error(QLatin1String("Empty repository list for option 'addTempRepository'."));
+ m_core->setTemporaryRepositories(repoList, false);
+ }
- // Consume the arguments to avoid "Unknown option" output. Also there's no need to check for a
- // valid binary, will throw in readAndRegisterFromBinary(...) if the magic cookie can't be found.
- args.removeAt(index + 1);
- args.removeAll(QLatin1String("--binarydatafile"));
- }
+ if (parser.isSet(QLatin1String(CommandLineOptions::SetTmpRepository))) {
+ const QStringList repoList = repositories(parser
+ .value(QLatin1String(CommandLineOptions::SetTmpRepository)));
+ if (repoList.isEmpty())
+ throw QInstaller::Error(QLatin1String("Empty repository list for option 'setTempRepository'."));
+ m_core->setTemporaryRepositories(repoList, true);
+ }
-#ifdef Q_OS_MAC
- // Load the external binary resource if we got one passed, otherwise assume we are a bundle. In that
- // case we need to figure out the path into the bundles resources folder to get the binary data.
- if (index < 0) {
- QDir resourcePath(QFileInfo(binaryFile).dir());
- resourcePath.cdUp();
- resourcePath.cd(QLatin1String("Resources"));
- binaryFile = resourcePath.filePath(QLatin1String("installer.dat"));
- }
-#endif
- BinaryContent content = BinaryContent::readAndRegisterFromBinary(binaryFile);
-
- // instantiate the installer we are actually going to use
- QInstaller::PackageManagerCore core(content.magicMarker(), content.performedOperations());
- ProductKeyCheck::instance()->init(&core);
-
- QString controlScript;
- QHash<QString, QString> params;
- for (int i = 1; i < args.size(); ++i) {
- const QString &argument = args.at(i);
- if (argument.isEmpty())
- continue;
-
- if (argument.contains(QLatin1Char('='))) {
- const QString name = argument.section(QLatin1Char('='), 0, 0);
- const QString value = argument.section(QLatin1Char('='), 1, 1);
- params.insert(name, value);
- core.setValue(name, value);
- } else if (argument == QLatin1String("--script") || argument == QLatin1String("Script")) {
- ++i;
- if (i < args.size()) {
- controlScript = args.at(i);
- if (!QFileInfo(controlScript).exists())
- return PackageManagerCore::Failure;
- } else {
- return PackageManagerCore::Failure;
- }
- } else if (argument == QLatin1String("--verbose") || argument == QLatin1String("-v")) {
- core.setVerbose(true);
- } else if (argument == QLatin1String("--proxy")) {
- core.settings().setProxyType(QInstaller::Settings::SystemProxy);
- KDUpdater::FileDownloaderFactory::instance().setProxyFactory(core.proxyFactory());
- } else if (argument == QLatin1String("--show-virtual-components")
- || argument == QLatin1String("ShowVirtualComponents")) {
- QFont f;
- f.setItalic(true);
- PackageManagerCore::setVirtualComponentsFont(f);
- PackageManagerCore::setVirtualComponentsVisible(true);
- } else if ((argument == QLatin1String("--updater")
- || argument == QLatin1String("Updater")) && core.isUninstaller()) {
- core.setUpdater();
- } else if ((argument == QLatin1String("--manage-packages")
- || argument == QLatin1String("ManagePackages")) && core.isUninstaller()) {
- core.setPackageManager();
- } else if (argument == QLatin1String("--addTempRepository")
- || argument == QLatin1String("--setTempRepository")) {
- ++i;
- QStringList repoList = repositories(args, i);
- if (repoList.isEmpty())
- return PackageManagerCore::Failure;
-
- // We cannot use setRemoteRepositories as that is a synchronous call which "
- // tries to get the data from server and this isn't what we want at this point
- const bool replace = (argument == QLatin1String("--setTempRepository"));
- core.setTemporaryRepositories(repoList, replace);
- } else if (argument == QLatin1String("--addRepository")) {
- ++i;
- QStringList repoList = repositories(args, i);
- if (repoList.isEmpty())
- return PackageManagerCore::Failure;
- core.addUserRepositories(repoList);
- } else if (argument == QLatin1String("--no-force-installations")) {
- PackageManagerCore::setNoForceInstallation(true);
- } else if (argument == QLatin1String("--create-offline-repository")) {
- PackageManagerCore::setCreateLocalRepositoryFromBinary(true);
- } else {
- std::cerr << "Unknown option: " << argument << std::endl;
- }
+ QInstaller::PackageManagerCore::setNoForceInstallation(parser
+ .isSet(QLatin1String(CommandLineOptions::NoForceInstallation)));
+ QInstaller::PackageManagerCore::setCreateLocalRepositoryFromBinary(parser
+ .isSet(QLatin1String(CommandLineOptions::CreateOfflineRepository)));
+
+ QHash<QString, QString> params;
+ const QStringList positionalArguments = parser.positionalArguments();
+ foreach (const QString &argument, positionalArguments) {
+ if (argument.contains(QLatin1Char('='))) {
+ const QString name = argument.section(QLatin1Char('='), 0, 0);
+ const QString value = argument.section(QLatin1Char('='), 1, 1);
+ params.insert(name, value);
+ m_core->setValue(name, value);
}
+ }
- // this needs to happen after we parse the arguments, but before we use the actual resources
- const QString newDefaultResource = core.value(QString::fromLatin1("DefaultResourceReplacement"));
- if (!newDefaultResource.isEmpty())
- content.registerAsDefaultQResource(newDefaultResource);
-
- if (QInstaller::isVerbose()) {
- qDebug() << "Resource tree after loading the in-binary resource:";
- QDirIterator it(QLatin1String(":/"), QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden,
- QDirIterator::Subdirectories);
- while (it.hasNext())
- qDebug() << QString::fromLatin1(" %1").arg(it.next());
+ const QString directory = QLatin1String(":/translations");
+ const QStringList translations = m_core->settings().translations();
+
+ // install the default Qt translator
+ QScopedPointer<QTranslator> translator(new QTranslator(QCoreApplication::instance()));
+ foreach (const QLocale locale, QLocale().uiLanguages()) {
+ // As there is no qt_en.qm, we simply end the search when the next
+ // preferred language is English.
+ if (locale.language() == QLocale::English)
+ break;
+ if (translator->load(locale, QLatin1String("qt"), QString::fromLatin1("_"), directory)) {
+ QCoreApplication::instance()->installTranslator(translator.take());
+ break;
}
+ }
- const QString directory = QLatin1String(":/translations");
- const QStringList translations = core.settings().translations();
+ translator.reset(new QTranslator(QCoreApplication::instance()));
+ // install English translation as fallback so that correct license button text is used
+ if (translator->load(QLatin1String("en_us"), directory))
+ QCoreApplication::instance()->installTranslator(translator.take());
- // install the default Qt translator
- QScopedPointer<QTranslator> translator(new QTranslator(&app));
+ if (translations.isEmpty()) {
+ translator.reset(new QTranslator(QCoreApplication::instance()));
foreach (const QLocale locale, QLocale().uiLanguages()) {
- // As there is no qt_en.qm, we simply end the search when the next
- // preferred language is English.
- if (locale.language() == QLocale::English)
- break;
- if (translator->load(locale, QLatin1String("qt"), QString::fromLatin1("_"), directory)) {
- app.installTranslator(translator.take());
+ if (translator->load(locale, QLatin1String(""), QLatin1String(""), directory)) {
+ QCoreApplication::instance()->installTranslator(translator.take());
break;
}
}
-
- translator.reset(new QTranslator(&app));
- // install English translation as fallback so that correct license button text is used
- if (translator->load(QLatin1String("en_us"), directory))
- app.installTranslator(translator.take());
-
- if (translations.isEmpty()) {
- translator.reset(new QTranslator(&app));
- foreach (const QLocale locale, QLocale().uiLanguages()) {
- if (translator->load(locale, QLatin1String(""), QLatin1String(""), directory)) {
- app.installTranslator(translator.take());
- break;
- }
- }
- } else {
- foreach (const QString &translation, translations) {
- translator.reset(new QTranslator(&app));
- if (translator->load(translation, QLatin1String(":/translations")))
- app.installTranslator(translator.take());
- }
+ } else {
+ foreach (const QString &translation, translations) {
+ translator.reset(new QTranslator(QCoreApplication::instance()));
+ if (translator->load(translation, QLatin1String(":/translations")))
+ QCoreApplication::instance()->installTranslator(translator.take());
}
+ }
- // Create the wizard gui
- TabController controller(0);
- controller.setManager(&core);
- controller.setManagerParams(params);
- controller.setControlScript(controlScript);
+ //create the wizard GUI
+ TabController controller(0);
+ controller.setManager(m_core);
+ controller.setManagerParams(params);
+ controller.setControlScript(controlScript);
- if (core.isInstaller()) {
- controller.setGui(new InstallerGui(&core));
- } else {
- controller.setGui(new MaintenanceGui(&core));
- }
+ if (m_core->isInstaller())
+ controller.setGui(new InstallerGui(m_core));
+ else
+ controller.setGui(new MaintenanceGui(m_core));
- //
- // Sanity check to detect a broken installations with missing operations.
- // Every installed package should have at least one MinimalProgress operation.
- //
- QSet<QString> installedPackages = core.localInstalledPackages().keys().toSet();
- QSet<QString> operationPackages;
- foreach (QInstaller::Operation *operation, content.performedOperations()) {
- if (operation->hasValue(QLatin1String("component")))
- operationPackages.insert(operation->value(QLatin1String("component")).toString());
- }
+ QInstaller::PackageManagerCore::Status status =
+ QInstaller::PackageManagerCore::Status(controller.init());
+ if (status != QInstaller::PackageManagerCore::Success)
+ return status;
- QSet<QString> packagesWithoutOperation = installedPackages - operationPackages;
- QSet<QString> orphanedOperations = operationPackages - installedPackages;
- if (!packagesWithoutOperation.isEmpty() || !orphanedOperations.isEmpty()) {
- qCritical() << "Operations missing for installed packages" << packagesWithoutOperation.toList();
- qCritical() << "Orphaned operations" << orphanedOperations.toList();
- MessageBoxHandler::critical(
- MessageBoxHandler::currentBestSuitParent(),
- QLatin1String("Corrupt_Installation_Error"),
- QCoreApplication::translate("QInstaller", "Corrupt installation"),
- QCoreApplication::translate("QInstaller",
- "Your installation seems to be corrupted. "
- "Please consider re-installing from scratch."
- ));
- } else {
- qDebug() << "Operations sanity check succeeded.";
- }
+ const int result = QCoreApplication::instance()->exec();
+ if (result != 0)
+ return result;
+
+ if (m_core->finishedWithSuccess())
+ return QInstaller::PackageManagerCore::Success;
- PackageManagerCore::Status status = PackageManagerCore::Status(controller.init());
- if (status != PackageManagerCore::Success)
+ status = m_core->status();
+ switch (status) {
+ case QInstaller::PackageManagerCore::Success:
return status;
- const int result = app.exec();
- if (result != 0)
- return result;
+ case QInstaller::PackageManagerCore::Canceled:
+ return status;
- if (core.finishedWithSuccess())
- return PackageManagerCore::Success;
+ default:
+ break;
+ }
+ return QInstaller::PackageManagerCore::Failure;
+}
- status = core.status();
- switch (status) {
- case PackageManagerCore::Success:
- return status;
- case PackageManagerCore::Canceled:
- return status;
+// -- private
- default:
- break;
- }
- return PackageManagerCore::Failure;
- } catch(const Error &e) {
- std::cerr << qPrintable(e.message()) << std::endl;
- } catch (const std::exception &e) {
- std::cerr << e.what() << std::endl;
- } catch(...) {
- std::cerr << "Unknown error, aborting." << std::endl;
+void InstallerBase::dumpResourceTree() const
+{
+ qDebug() << "Resource tree:";
+ QDirIterator it(QLatin1String(":/"), QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden,
+ QDirIterator::Subdirectories);
+ while (it.hasNext()) {
+ if (it.next().startsWith(QLatin1String(":/qt-project.org")))
+ continue;
+ qDebug() << " " << it.filePath().toUtf8().constData();
}
+}
- return PackageManagerCore::Failure;
+QStringList InstallerBase::repositories(const QString &list) const
+{
+ const QStringList items = list.split(QLatin1Char(','), QString::SkipEmptyParts);
+ foreach (const QString &item, items)
+ qDebug() << "Adding custom repository:" << item.toUtf8().constData();
+ return items;
}
diff --git a/src/sdk/installerbase.h b/src/sdk/installerbase.h
new file mode 100644
index 000000000..8230a89e0
--- /dev/null
+++ b/src/sdk/installerbase.h
@@ -0,0 +1,63 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#ifndef INSTALLERBASE_H
+#define INSTALLERBASE_H
+
+#include "sdkapp.h"
+
+namespace QInstaller {
+ class PackageManagerCore;
+}
+
+class InstallerBase : public SDKApp<QApplication>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(InstallerBase)
+
+public:
+ InstallerBase(int &argc, char *argv[]);
+ ~InstallerBase();
+
+ int run();
+
+private:
+ void dumpResourceTree() const;
+ QStringList repositories(const QString &list) const;
+
+private:
+ QInstaller::PackageManagerCore *m_core;
+};
+
+#endif // INSTALLERBASE_H
diff --git a/src/sdk/installerbase_p.cpp b/src/sdk/installerbase_p.cpp
deleted file mode 100644
index 57de0dc5d..000000000
--- a/src/sdk/installerbase_p.cpp
+++ /dev/null
@@ -1,327 +0,0 @@
-/**************************************************************************
-**
-** Copyright (C) 2012-2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-**************************************************************************/
-#include "installerbase_p.h"
-#include "console.h"
-
-#include <binaryformat.h>
-#include <errors.h>
-#include <fileutils.h>
-#include <lib7z_facade.h>
-#include <qprocesswrapper.h>
-#include <utils.h>
-
-#include <kdsavefile.h>
-#include <kdupdaterfiledownloader.h>
-#include <kdupdaterfiledownloaderfactory.h>
-
-#include <QtCore/QDir>
-#include <QtCore/QDebug>
-#include <QtCore/QTemporaryFile>
-#include <QtCore/QUrl>
-
-#include <QMessageBox>
-
-#include <iomanip>
-#include <iostream>
-
-using namespace KDUpdater;
-using namespace QInstaller;
-using namespace QInstallerCreator;
-
-
-// -- InstallerBase
-
-InstallerBase::InstallerBase(QObject *parent)
- : QObject(parent)
- , m_downloadFinished(false)
-{
-}
-
-InstallerBase::~InstallerBase()
-{
-}
-
-int InstallerBase::replaceMaintenanceToolBinary(QStringList arguments)
-{
- QInstaller::setVerbose(arguments.contains(QLatin1String("--verbose"))
- || arguments.contains(QLatin1String("-v")));
-
- arguments.removeAll(QLatin1String("--verbose"));
- arguments.removeAll(QLatin1String("-v"));
- arguments.removeAll(QLatin1String("--update-installerbase"));
-
- QUrl url = arguments.value(1);
- if (!FileDownloaderFactory::isSupportedScheme(url.scheme()) && QFileInfo(url.toString()).exists())
- url = QLatin1String("file:///") + url.toString();
- m_downloader.reset(FileDownloaderFactory::instance().create(url.scheme(), 0));
- if (m_downloader.isNull()) {
- qDebug() << QString::fromLatin1("Scheme not supported: %1 (%2)").arg(url.scheme(), url.toString());
- return EXIT_FAILURE;
- }
- m_downloader->setUrl(url);
- m_downloader->setAutoRemoveDownloadedFile(true);
-
- QString target = QDir::tempPath() + QLatin1String("/") + QFileInfo(arguments.at(1)).fileName();
- if (FileDownloaderFactory::isSupportedScheme(url.scheme()))
- m_downloader->setDownloadedFileName(target);
-
- connect(m_downloader.data(), SIGNAL(downloadStarted()), this, SLOT(downloadStarted()));
- connect(m_downloader.data(), SIGNAL(downloadCanceled()), this, SLOT(downloadFinished()));
- connect(m_downloader.data(), SIGNAL(downloadCompleted()), this, SLOT(downloadFinished()));
- connect(m_downloader.data(), SIGNAL(downloadAborted(QString)), this, SLOT(downloadAborted(QString)));
-
- m_downloader->download();
-
- while (true) {
- QCoreApplication::processEvents();
- if (m_downloadFinished)
- break;
- }
-
- if (!m_downloader->isDownloaded()) {
- qDebug() << QString::fromLatin1("Could not download file %1: . Error: %2.").arg(
- m_downloader->url().toString(), m_downloader->errorString());
- return EXIT_FAILURE;
- }
-
- if (Lib7z::isSupportedArchive(target)) {
- QFile archive(target);
- if (archive.open(QIODevice::ReadOnly)) {
- try {
- Lib7z::extractArchive(&archive, QDir::tempPath());
- if (!archive.remove()) {
- qDebug() << QString::fromLatin1("Could not delete file %1: %2").arg(
- target, archive.errorString());
- }
- } catch (const Lib7z::SevenZipException& e) {
- qDebug() << QString::fromLatin1("Error while extracting '%1': %2").arg(target, e.message());
- return EXIT_FAILURE;
- } catch (...) {
- qDebug() << QString::fromLatin1("Unknown exception caught while extracting %1.").arg(target);
- return EXIT_FAILURE;
- }
- } else {
- qDebug() << QString::fromLatin1("Could not open %1 for reading: %2.").arg(
- target, archive.errorString());
- return EXIT_FAILURE;
- }
-#ifndef Q_OS_WIN
- target = QDir::tempPath() + QLatin1String("/.tempSDKMaintenanceTool");
-#else
- target = QDir::tempPath() + QLatin1String("/temp/SDKMaintenanceToolBase.exe");
-#endif
- }
-
- try {
- QFile installerBase(target);
- QInstaller::openForRead(&installerBase, installerBase.fileName());
- writeMaintenanceBinary(arguments.value(0), &installerBase, installerBase.size());
- deferredRename(arguments.value(0) + QLatin1String(".new"), arguments.value(0));
- } catch (const QInstaller::Error &error) {
- qDebug() << error.message();
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
-
-/* static*/
-void InstallerBase::showUsage()
-{
-#define WIDTH1 46
-#define WIDTH2 40
- Console c;
- std::cout << "Usage: SDKMaintenanceTool [OPTIONS]" << std::endl << std::endl;
-
- std::cout << "User:"<<std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --help" << std::setw(WIDTH2)
- << "Show commandline usage" << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --version" << std::setw(WIDTH2)
- << "Show current version" << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --checkupdates" << std::setw(WIDTH2)
- << "Check for updates and return an XML file describing" << std::endl
- << std::setw(WIDTH1) << " " << std::setw(WIDTH2) << "the available updates" << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --updater" << std::setw(WIDTH2)
- << "Start in updater mode." << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --manage-packages" << std::setw(WIDTH2)
- << "Start in packagemanager mode." << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --proxy" << std::setw(WIDTH2)
- << "Set system proxy on Win and Mac." << std::endl
- << std::setw(WIDTH1) << " " << std::setw(WIDTH2) << "This option has no effect on Linux." << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --verbose" << std::setw(WIDTH2)
- << "Show debug output on the console" << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --create-offline-repository"
- << std::setw(WIDTH2) << "Offline installer only: Create a local repository inside the" << std::endl
- << std::setw(WIDTH1) << " " << std::setw(WIDTH2) << "installation directory based on the offline" << std::endl
- << std::setw(WIDTH1) << " " << std::setw(WIDTH2) << "installer's content." << std::endl;
-
- std::cout << "\nDeveloper:"<< std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left)
- << " --runoperation [OPERATION] [arguments...]" << std::setw(WIDTH2)
- << "Perform an operation with a list of arguments" << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left)
- << " --undooperation [OPERATION] [arguments...]" << std::setw(WIDTH2)
- << "Undo an operation with a list of arguments" <<std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left)
- << " --script [scriptName]" << std::setw(WIDTH2) << "Execute a script" << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --no-force-installations"
- << std::setw(WIDTH2) << "Enable deselection of forced components" << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --addRepository [URI]"
- << std::setw(WIDTH2) << "Add a local or remote repo to the list of user defined repos." << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --addTempRepository [URI]"
- << std::setw(WIDTH2) << "Add a local or remote repo to the list of temporary available" << std::endl
- << std::setw(WIDTH1) << " " << std::setw(WIDTH2) << "repos." << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --setTempRepository [URI]"
- << std::setw(WIDTH2) << "Set a local or remote repo as tmp repo, it is the only one" << std::endl
- << std::setw(WIDTH1) << " " << std::setw(WIDTH2) << "used during fetch." << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " " << std::setw(WIDTH2) << "Note: URI "
- "must be prefixed with the protocol, i.e. file:///" << std::endl
- << std::setw(WIDTH1) << " " << std::setw(WIDTH2) << "http:// or ftp://. It can consist of multiple" << std::endl
- << std::setw(WIDTH1) << " " << std::setw(WIDTH2) << "addresses separated by comma only." << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --show-virtual-components"
- << std::setw(WIDTH2) << "Show virtual components in package manager and updater" << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left)
- << " --binarydatafile [binary_data_file]" << std::setw(WIDTH2) << "Use the binary data of "
- "another installer or maintenance tool." << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left)
- << " --update-installerbase [new_installerbase]" << std::setw(WIDTH2)
- << "Patch a full installer with a new installer base" << std::endl;
- std::cout << std::setw(WIDTH1) << std::setiosflags(std::ios::left) << " --dump-binary-data -i [PATH] -o [PATH]"
- << std::setw(WIDTH2) << "Dumps the binary content into specified output path (offline" << std::endl
- << std::setw(WIDTH1) << " " << std::setw(WIDTH2) << "installer only)." << std::endl
- << std::setw(WIDTH1) << " " << std::setw(WIDTH2) << "Input path pointing to binary data file, if omitted" << std::endl
- << std::setw(WIDTH1) << " " << std::setw(WIDTH2) << "the current application is used as input." << std::endl;
-}
-
-/* static*/
-void InstallerBase::showVersion(const QString &version)
-{
- Console c;
- std::cout << qPrintable(version) << std::endl;
-}
-
-
-// -- private slots
-
-void InstallerBase::downloadStarted()
-{
- m_downloadFinished = false;
- qDebug() << QString::fromLatin1("Download started! Source: %1, Target: %2").arg(
- m_downloader->url().toString(), m_downloader->downloadedFileName());
-}
-
-void InstallerBase::downloadFinished()
-{
- m_downloadFinished = true;
- qDebug() << QString::fromLatin1("Download finished! Source: %1, Target: %2").arg(
- m_downloader->url().toString(), m_downloader->downloadedFileName());
-}
-
-void InstallerBase::downloadProgress(double progress)
-{
- qDebug() << "Progress: " << progress;
-}
-
-void InstallerBase::downloadAborted(const QString &error)
-{
- m_downloadFinished = true;
- qDebug() << QString::fromLatin1("Download aborted! Source: %1, Target: %2, Error: %3").arg(
- m_downloader->url().toString(), m_downloader->downloadedFileName(), error);
-}
-
-
-// -- private
-
-void InstallerBase::deferredRename(const QString &oldName, const QString &newName)
-{
-#ifdef Q_OS_WIN
- QTemporaryFile vbScript(QDir::temp().absoluteFilePath(QLatin1String("deferredrenameXXXXXX.vbs")));
- {
- openForWrite(&vbScript, vbScript.fileName());
- vbScript.setAutoRemove(false);
-
- QTextStream batch(&vbScript);
- batch << "Set fso = WScript.CreateObject(\"Scripting.FileSystemObject\")\n";
- batch << "Set tmp = WScript.CreateObject(\"WScript.Shell\")\n";
- batch << QString::fromLatin1("file = \"%1\"\n").arg(QDir::toNativeSeparators(newName));
- batch << QString::fromLatin1("backup = \"%1.bak\"\n").arg(QDir::toNativeSeparators(newName));
- batch << "on error resume next\n";
-
- batch << "while fso.FileExists(file)\n";
- batch << " fso.MoveFile file, backup\n";
- batch << " WScript.Sleep(1000)\n";
- batch << "wend\n";
- batch << QString::fromLatin1("fso.MoveFile \"%1\", file\n").arg(QDir::toNativeSeparators(oldName));
- batch << "fso.DeleteFile(WScript.ScriptFullName)\n";
- }
-
- QProcessWrapper::startDetached(QLatin1String("cscript"), QStringList() << QLatin1String("//Nologo")
- << QDir::toNativeSeparators(vbScript.fileName()));
-#else
- QFile::rename(newName, newName + QLatin1String(".bak"));
- QFile::rename(oldName, newName);
-#endif
-}
-
-void InstallerBase::writeMaintenanceBinary(const QString &target, QFile *const source, qint64 size)
-{
- KDSaveFile out(target + QLatin1String(".new"));
- QInstaller::openForWrite(&out, out.fileName()); // throws an exception in case of error
-
- if (!source->seek(0)) {
- throw QInstaller::Error(QObject::tr("Failed to seek in file %1. Reason: %2.").arg(source->fileName(),
- source->errorString()));
- }
-
- QInstaller::appendData(&out, source, size);
- QInstaller::appendInt64(&out, 0); // resource count
- QInstaller::appendInt64(&out, 4 * sizeof(qint64)); // data block size
- QInstaller::appendInt64(&out, QInstaller::MagicUninstallerMarker);
- QInstaller::appendInt64(&out, QInstaller::MagicCookie);
-
- out.setPermissions(out.permissions() | QFile::WriteUser | QFile::ReadGroup | QFile::ReadOther
- | QFile::ExeOther | QFile::ExeGroup | QFile::ExeUser);
-
- if (!out.commit(KDSaveFile::OverwriteExistingFile)) {
- throw QInstaller::Error(QString::fromLatin1("Could not write new maintenance-tool to %1. Reason: %2.")
- .arg(out.fileName(), out.errorString()));
- }
-}
diff --git a/src/sdk/installerbase_p.h b/src/sdk/installerbase_p.h
deleted file mode 100644
index 5d3e66e31..000000000
--- a/src/sdk/installerbase_p.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/**************************************************************************
-**
-** Copyright (C) 2012-2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-**************************************************************************/
-
-#ifndef INSTALLERBASE_P_H
-#define INSTALLERBASE_P_H
-
-#include <QThread>
-
-namespace KDUpdater {
- class FileDownloader;
-}
-
-QT_BEGIN_NAMESPACE
-class QFile;
-QT_END_NAMESPACE
-
-class Sleep : public QThread
-{
-public:
- static void sleep(unsigned long ms)
- {
- QThread::usleep(ms);
- }
-};
-
-class InstallerBase : public QObject
-{
- Q_OBJECT
-
-public:
- explicit InstallerBase(QObject *parent = 0);
- ~InstallerBase();
-
- int replaceMaintenanceToolBinary(QStringList arguments);
-
- static void showUsage();
- static void showVersion(const QString &version);
-
-private slots:
- void downloadStarted();
- void downloadFinished();
- void downloadProgress(double progress);
- void downloadAborted(const QString &error);
-
-private:
- void deferredRename(const QString &source, const QString &target);
- void writeMaintenanceBinary(const QString &target, QFile *source, qint64 size);
-
-private:
- volatile bool m_downloadFinished;
- QScopedPointer<KDUpdater::FileDownloader> m_downloader;
-};
-
-#endif // INSTALLERBASE_P_H
diff --git a/src/sdk/installerbasecommons.cpp b/src/sdk/installerbasecommons.cpp
index 263eb5767..efdd58b75 100644
--- a/src/sdk/installerbasecommons.cpp
+++ b/src/sdk/installerbasecommons.cpp
@@ -16,508 +16,31 @@
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
**
** $QT_END_LICENSE$
**
**************************************************************************/
#include "installerbasecommons.h"
-#include <component.h>
-#include <messageboxhandler.h>
#include <packagemanagercore.h>
+#include <scriptengine.h>
#include <packagemanagerpagefactory.h>
-#include <settings.h>
-
#include <productkeycheck.h>
-#include <QtCore/QDir>
-#include <QtCore/QFileInfo>
-#include <QtCore/QTimer>
-
-#include <QLabel>
-#include <QProgressBar>
-#include <QRadioButton>
-#include <QStackedWidget>
-#include <QVBoxLayout>
-
-#ifdef Q_OS_WIN
-#include <qt_windows.h>
-#endif
-
using namespace QInstaller;
-// -- IntroductionPageImpl
-
-IntroductionPageImpl::IntroductionPageImpl(QInstaller::PackageManagerCore *core)
- : QInstaller::IntroductionPage(core)
- , m_updatesFetched(false)
- , m_allPackagesFetched(false)
-{
- QWidget *widget = new QWidget(this);
- QVBoxLayout *layout = new QVBoxLayout(widget);
-
- m_packageManager = new QRadioButton(tr("Package manager"), this);
- m_packageManager->setObjectName(QLatin1String("PackageManagerRadioButton"));
- layout->addWidget(m_packageManager);
- m_packageManager->setChecked(core->isPackageManager());
- connect(m_packageManager, SIGNAL(toggled(bool)), this, SLOT(setPackageManager(bool)));
-
- m_updateComponents = new QRadioButton(tr("Update components"), this);
- m_updateComponents->setObjectName(QLatin1String("UpdaterRadioButton"));
- layout->addWidget(m_updateComponents);
- m_updateComponents->setChecked(core->isUpdater());
- connect(m_updateComponents, SIGNAL(toggled(bool)), this, SLOT(setUpdater(bool)));
-
- m_removeAllComponents = new QRadioButton(tr("Remove all components"), this);
- m_removeAllComponents->setObjectName(QLatin1String("UninstallerRadioButton"));
- layout->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)));
-
- layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
-
- m_label = new QLabel(this);
- m_label->setWordWrap(true);
- m_label->setText(tr("Retrieving information from remote installation sources..."));
- layout->addWidget(m_label);
-
- m_progressBar = new QProgressBar(this);
- m_progressBar->setRange(0, 0);
- layout->addWidget(m_progressBar);
-
- layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
-
- m_errorLabel = new QLabel(this);
- m_errorLabel->setWordWrap(true);
- layout->addWidget(m_errorLabel);
-
- widget->setLayout(layout);
- setWidget(widget);
-
- 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()));
-
- m_updateComponents->setEnabled(ProductKeyCheck::instance()->hasValidKey());
-}
-
-int IntroductionPageImpl::nextId() const
-{
- if (packageManagerCore()->isUninstaller())
- return PackageManagerCore::ReadyForInstallation;
-
- if (packageManagerCore()->isUpdater() || packageManagerCore()->isPackageManager())
- return PackageManagerCore::ComponentSelection;
-
- return QInstaller::IntroductionPage::nextId();
-}
-
-bool IntroductionPageImpl::validatePage()
-{
- PackageManagerCore *core = packageManagerCore();
- if (core->isUninstaller())
- return true;
-
- setComplete(false);
- if (!validRepositoriesAvailable()) {
- setErrorMessage(QLatin1String("<font color=\"red\">") + tr("At least one valid and enabled "
- "repository required for this action to succeed.") + QLatin1String("</font>"));
- return isComplete();
- }
-
- gui()->setSettingsButtonEnabled(false);
- const bool maintanence = core->isUpdater() || core->isPackageManager();
- if (maintanence) {
- showAll();
- setMaintenanceToolsEnabled(false);
- } else {
- showMetaInfoUdate();
- }
-
- // fetch updater packages
- if (core->isUpdater()) {
- if (!m_updatesFetched) {
- m_updatesFetched = core->fetchRemotePackagesTree();
- if (!m_updatesFetched)
- setErrorMessage(core->error());
- }
-
- callControlScript(QLatin1String("UpdaterSelectedCallback"));
-
- if (m_updatesFetched) {
- if (core->updaterComponents().count() <= 0)
- setErrorMessage(QLatin1String("<b>") + tr("No updates available.") + QLatin1String("</b>"));
- else
- setComplete(true);
- }
- }
-
- // fetch common packages
- if (core->isInstaller() || core->isPackageManager()) {
- bool localPackagesTreeFetched = false;
- if (!m_allPackagesFetched) {
- // first try to fetch the server side packages tree
- m_allPackagesFetched = core->fetchRemotePackagesTree();
- if (!m_allPackagesFetched) {
- QString error = core->error();
- if (core->isPackageManager() && core->status() != PackageManagerCore::ForceUpdate) {
- // if that fails and we're in maintenance mode, try to fetch local installed tree
- localPackagesTreeFetched = core->fetchLocalPackagesTree();
- if (localPackagesTreeFetched) {
- // if that succeeded, adjust error message
- error = QLatin1String("<font color=\"red\">") + error + tr(" Only local package "
- "management available.") + QLatin1String("</font>");
- }
- }
- setErrorMessage(error);
- }
- }
-
- callControlScript(QLatin1String("PackageManagerSelectedCallback"));
-
- if (m_allPackagesFetched | localPackagesTreeFetched)
- setComplete(true);
- }
-
- if (maintanence) {
- showMaintenanceTools();
- setMaintenanceToolsEnabled(true);
- } else {
- hideAll();
- }
- gui()->setSettingsButtonEnabled(true);
-
- return isComplete();
-}
-
-void IntroductionPageImpl::showAll()
-{
- showWidgets(true);
-}
-
-void IntroductionPageImpl::hideAll()
-{
- showWidgets(false);
-}
-
-void IntroductionPageImpl::showMetaInfoUdate()
-{
- showWidgets(false);
- m_label->setVisible(true);
- m_progressBar->setVisible(true);
-}
-
-void IntroductionPageImpl::showMaintenanceTools()
-{
- showWidgets(true);
- m_label->setVisible(false);
- m_progressBar->setVisible(false);
-}
-
-void IntroductionPageImpl::setMaintenanceToolsEnabled(bool enable)
-{
- m_packageManager->setEnabled(enable);
- m_updateComponents->setEnabled(enable && ProductKeyCheck::instance()->hasValidKey());
- m_removeAllComponents->setEnabled(enable);
-}
-
-// -- public slots
-
-void IntroductionPageImpl::setMessage(const QString &msg)
-{
- m_label->setText(msg);
-}
-
-void IntroductionPageImpl::onProgressChanged(int progress)
-{
- m_progressBar->setRange(0, 100);
- m_progressBar->setValue(progress);
-}
-
-void IntroductionPageImpl::setErrorMessage(const QString &error)
-{
- QPalette palette;
- const PackageManagerCore::Status s = packageManagerCore()->status();
- if (s == PackageManagerCore::Failure || s == PackageManagerCore::Failure) {
- palette.setColor(QPalette::WindowText, Qt::red);
- } else {
- palette.setColor(QPalette::WindowText, palette.color(QPalette::WindowText));
- }
-
- m_errorLabel->setText(error);
- m_errorLabel->setPalette(palette);
-}
-
-void IntroductionPageImpl::callControlScript(const QString &callback)
-{
- // Initialize the gui. Needs to be done after check repositories as only then the ui can handle
- // hide of pages depending on the components.
- gui()->init();
- gui()->callControlScriptMethod(callback);
-}
-
-bool IntroductionPageImpl::validRepositoriesAvailable() const
-{
- const PackageManagerCore *const core = packageManagerCore();
- bool valid = (core->isInstaller() && core->isOfflineOnly()) || core->isUninstaller();
-
- if (!valid) {
- foreach (const Repository &repo, core->settings().repositories()) {
- if (repo.isEnabled() && repo.isValid()) {
- valid = true;
- break;
- }
- }
- }
- return valid;
-}
-
-// -- private slots
-
-void IntroductionPageImpl::setUpdater(bool value)
-{
- if (value) {
- entering();
- gui()->showSettingsButton(true);
- packageManagerCore()->setUpdater();
- emit packageManagerCoreTypeChanged();
- }
-}
-
-void IntroductionPageImpl::setUninstaller(bool value)
-{
- if (value) {
- entering();
- gui()->showSettingsButton(false);
- packageManagerCore()->setUninstaller();
- emit packageManagerCoreTypeChanged();
- }
-}
-
-void IntroductionPageImpl::setPackageManager(bool value)
-{
- if (value) {
- entering();
- gui()->showSettingsButton(true);
- packageManagerCore()->setPackageManager();
- emit packageManagerCoreTypeChanged();
- }
-}
-
-void IntroductionPageImpl::onCoreNetworkSettingsChanged()
-{
- m_updatesFetched = false;
- m_allPackagesFetched = false;
-}
-
-// -- private
-
-void IntroductionPageImpl::entering()
-{
- setComplete(true);
- showWidgets(false);
- setMessage(QString());
- setErrorMessage(QString());
- setButtonText(QWizard::CancelButton, tr("Quit"));
-
- m_progressBar->setValue(0);
- m_progressBar->setRange(0, 0);
- PackageManagerCore *core = packageManagerCore();
- if (core->isUninstaller() ||core->isUpdater() || core->isPackageManager()) {
- showMaintenanceTools();
- setMaintenanceToolsEnabled(true);
- }
- setSettingsButtonRequested((!core->isOfflineOnly()) && (!core->isUninstaller()));
-}
-
-void IntroductionPageImpl::leaving()
-{
- m_progressBar->setValue(0);
- m_progressBar->setRange(0, 0);
- setButtonText(QWizard::CancelButton, gui()->defaultButtonText(QWizard::CancelButton));
-}
-
-void IntroductionPageImpl::showWidgets(bool show)
-{
- m_label->setVisible(show);
- m_progressBar->setVisible(show);
- m_packageManager->setVisible(show);
- m_updateComponents->setVisible(show);
- m_removeAllComponents->setVisible(show);
-}
-
-
-// -- TargetDirectoryPageImpl
-
-/*!
- A custom target directory selection based due to the no-space restriction...
-*/
-TargetDirectoryPageImpl::TargetDirectoryPageImpl(PackageManagerCore *core)
- : TargetDirectoryPage(core)
-{
- QPalette palette;
- palette.setColor(QPalette::WindowText, Qt::red);
-
- m_warningLabel = new QLabel(this);
- m_warningLabel->setPalette(palette);
- m_warningLabel->setWordWrap(true);
-
- insertWidget(m_warningLabel, QLatin1String("MessageLabel"), 2);
-}
-
-QString TargetDirectoryPageImpl::targetDirWarning() const
-{
- if (targetDir().isEmpty()) {
- return TargetDirectoryPageImpl::tr("The installation path cannot be empty, please specify a valid "
- "folder.");
- }
-
- if (QDir(targetDir()).isRelative()) {
- return TargetDirectoryPageImpl::tr("The installation path cannot be relative, please specify an "
- "absolute path.");
- }
-
- QDir target(targetDir());
- target = target.canonicalPath();
-
- if (target.isRoot()) {
- return TargetDirectoryPageImpl::tr("As the install directory is completely deleted, installing "
- "in %1 is forbidden.").arg(QDir::toNativeSeparators(QDir::rootPath()));
- }
-
- if (target == QDir::home()) {
- return TargetDirectoryPageImpl::tr("As the install directory is completely deleted, installing "
- "in %1 is forbidden.").arg(QDir::toNativeSeparators(QDir::homePath()));
- }
-
- QString dir = QDir::toNativeSeparators(targetDir());
-#ifdef Q_OS_WIN
- // folder length (set by user) + maintenance tool name length (no extension) + extra padding
- if ((dir.length() + packageManagerCore()->settings().uninstallerName().length() + 20) >= MAX_PATH) {
- return TargetDirectoryPageImpl::tr("The path you have entered is too long, please make sure to "
- "specify a valid path.");
- }
-
- if (dir.count() >= 3 && dir.indexOf(QRegExp(QLatin1String("[a-zA-Z]:"))) == 0
- && dir.at(2) != QLatin1Char('\\')) {
- return TargetDirectoryPageImpl::tr("The path you have entered is not valid, please make sure to "
- "specify a valid drive.");
- }
-
- // remove e.g. "c:"
- dir = dir.mid(2);
-#endif
-
- QString ambiguousChars = QLatin1String("[~<>|?*!@#$%^&:,; ]");
- if (packageManagerCore()->settings().allowSpaceInPath())
- ambiguousChars.remove(QLatin1Char(' '));
-
- // check if there are not allowed characters in the target path
- if (dir.contains(QRegExp(ambiguousChars))) {
- return TargetDirectoryPageImpl::tr("The installation path must not contain %1, "
- "please specify a valid folder.").arg(ambiguousChars);
- }
-
- dir = targetDir();
- if (!packageManagerCore()->settings().allowNonAsciiCharacters()) {
- for (int i = 0; i < dir.length(); ++i) {
- if (dir.at(i).unicode() & 0xff80) {
- return TargetDirectoryPageImpl::tr("The path or installation directory contains non ASCII "
- "characters. This is currently not supported! Please choose a different path or "
- "installation directory.");
- }
- }
- }
-
- return QString();
-}
-
-bool TargetDirectoryPageImpl::isComplete() const
-{
- m_warningLabel->setText(targetDirWarning());
- return m_warningLabel->text().isEmpty();
-}
-
-bool TargetDirectoryPageImpl::askQuestion(const QString &identifier, const QString &message)
-{
- QMessageBox::StandardButton bt =
- MessageBoxHandler::warning(MessageBoxHandler::currentBestSuitParent(), identifier,
- TargetDirectoryPageImpl::tr("Warning"), message, QMessageBox::Yes | QMessageBox::No);
- return bt == QMessageBox::Yes;
-}
-
-bool TargetDirectoryPageImpl::failWithError(const QString &identifier, const QString &message)
-{
- MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(), identifier,
- TargetDirectoryPageImpl::tr("Error"), message);
- return false;
-}
-
-bool TargetDirectoryPageImpl::validatePage()
-{
- if (!isVisible())
- return true;
-
- const QString remove = packageManagerCore()->value(QLatin1String("RemoveTargetDir"));
- if (!QVariant(remove).toBool())
- return true;
-
- const QString targetDir = this->targetDir();
- const QDir dir(targetDir);
- // the directory exists and is empty...
- if (dir.exists() && dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty())
- return true;
-
- const QFileInfo fi(targetDir);
- if (fi.isDir()) {
- QString fileName = packageManagerCore()->settings().uninstallerName();
-#if defined(Q_OS_MAC)
- if (QFileInfo(QCoreApplication::applicationDirPath() + QLatin1String("/../..")).isBundle())
- fileName += QLatin1String(".app/Contents/MacOS/") + fileName;
-#elif defined(Q_OS_WIN)
- fileName += QLatin1String(".exe");
-#endif
-
- QFileInfo fi2(targetDir + QDir::separator() + fileName);
- if (fi2.exists()) {
- return failWithError(QLatin1String("TargetDirectoryInUse"), tr("The folder 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 "
- "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?"));
- } 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."));
- }
- return true;
-}
-
-
// -- InstallerGui
InstallerGui::InstallerGui(PackageManagerCore *core)
@@ -530,8 +53,9 @@ InstallerGui::InstallerGui(PackageManagerCore *core)
"constructed.").arg(id)));
setPage(id, page);
}
- setPage(PackageManagerCore::Introduction, new IntroductionPageImpl(core));
- setPage(PackageManagerCore::TargetDirectory, new TargetDirectoryPageImpl(core));
+
+ setPage(PackageManagerCore::Introduction, new IntroductionPage(core));
+ setPage(PackageManagerCore::TargetDirectory, new TargetDirectoryPage(core));
setPage(PackageManagerCore::ComponentSelection, new ComponentSelectionPage(core));
setPage(PackageManagerCore::LicenseCheck, new LicenseAgreementPage(core));
#ifdef Q_OS_WIN
@@ -544,6 +68,10 @@ InstallerGui::InstallerGui(PackageManagerCore *core)
void InstallerGui::init()
{
+ foreach (const int id, pageIds()) {
+ packageManagerCore()->controlScriptEngine()->addQObjectChildren(page(id));
+ packageManagerCore()->componentScriptEngine()->addQObjectChildren(page(id));
+ }
}
@@ -560,7 +88,7 @@ MaintenanceGui::MaintenanceGui(PackageManagerCore *core)
setPage(id, page);
}
- IntroductionPageImpl *intro = new IntroductionPageImpl(core);
+ IntroductionPage *intro = new IntroductionPage(core);
connect(intro, SIGNAL(packageManagerCoreTypeChanged()), this, SLOT(updateRestartPage()));
setPage(PackageManagerCore::Introduction, intro);
@@ -580,6 +108,10 @@ MaintenanceGui::MaintenanceGui(PackageManagerCore *core)
void MaintenanceGui::init()
{
+ foreach (const int id, pageIds()) {
+ packageManagerCore()->controlScriptEngine()->addQObjectChildren(page(id));
+ packageManagerCore()->componentScriptEngine()->addQObjectChildren(page(id));
+ }
}
void MaintenanceGui::updateRestartPage()
diff --git a/src/sdk/installerbasecommons.h b/src/sdk/installerbasecommons.h
index 79330eaf7..b3ba68c35 100644
--- a/src/sdk/installerbasecommons.h
+++ b/src/sdk/installerbasecommons.h
@@ -16,24 +16,17 @@
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
**
** $QT_END_LICENSE$
**
@@ -44,87 +37,6 @@
#include <packagemanagergui.h>
-QT_BEGIN_NAMESPACE
-class QLabel;
-class QString;
-class QProgressBar;
-QT_END_NAMESPACE
-
-
-// -- IntroductionPageImpl
-
-class IntroductionPageImpl : public QInstaller::IntroductionPage
-{
- Q_OBJECT
-
-public:
- explicit IntroductionPageImpl(QInstaller::PackageManagerCore *core);
-
- int nextId() const;
- bool validatePage();
-
- void showAll();
- void hideAll();
- void showMetaInfoUdate();
- void showMaintenanceTools();
- void setMaintenanceToolsEnabled(bool enable);
-
-public Q_SLOTS:
- void onCoreNetworkSettingsChanged();
- void setMessage(const QString &msg);
- void onProgressChanged(int progress);
- void setErrorMessage(const QString &error);
-
-Q_SIGNALS:
- void packageManagerCoreTypeChanged();
-
-private Q_SLOTS:
- void setUpdater(bool value);
- void setUninstaller(bool value);
- void setPackageManager(bool value);
-
-private:
- void entering();
- void leaving();
-
- void showWidgets(bool show);
- void callControlScript(const QString &callback);
-
- bool validRepositoriesAvailable() const;
-
-private:
- bool m_updatesFetched;
- bool m_updatesCompleted;
- bool m_allPackagesFetched;
-
- QLabel *m_label;
- QLabel *m_errorLabel;
- QProgressBar *m_progressBar;
- QRadioButton *m_packageManager;
- QRadioButton *m_updateComponents;
- QRadioButton *m_removeAllComponents;
-};
-
-
-// --TargetDirectoryPageImpl
-
-class TargetDirectoryPageImpl : public QInstaller::TargetDirectoryPage
-{
- Q_OBJECT
-
-public:
- explicit TargetDirectoryPageImpl(QInstaller::PackageManagerCore *core);
-
- QString targetDirWarning() const;
- bool isComplete() const;
- bool askQuestion(const QString &identifier, const QString &message);
- bool failWithError(const QString &identifier, const QString &message);
- bool validatePage();
-
-private:
- QLabel *m_warningLabel;
-};
-
// -- InstallerGui
diff --git a/src/sdk/main.cpp b/src/sdk/main.cpp
new file mode 100644
index 000000000..2e698f35d
--- /dev/null
+++ b/src/sdk/main.cpp
@@ -0,0 +1,203 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "console.h"
+#include "constants.h"
+#include "commandlineparser.h"
+#include "installerbase.h"
+#include "sdkapp.h"
+#include "updatechecker.h"
+
+#include <errors.h>
+#include <kdselfrestarter.h>
+#include <remoteserver.h>
+#include <utils.h>
+
+#include <QCommandLineParser>
+#include <QDateTime>
+#include <QNetworkProxyFactory>
+
+#include <iostream>
+
+#define QUOTE_(x) #x
+#define QUOTE(x) QUOTE_(x)
+#define VERSION "IFW Version: \"" QUOTE(IFW_VERSION_STR) "\""
+#define BUILDDATE "Build date: " QUOTE(__DATE__)
+#define SHA "Installer Framework SHA1: \"" QUOTE(_GIT_SHA1_) "\""
+static const char PLACEHOLDER[32] = "MY_InstallerCreateDateTime_MY";
+
+int main(int argc, char *argv[])
+{
+ // increase maximum numbers of file descriptors
+#if defined (Q_OS_OSX)
+ QCoreApplication::setSetuidAllowed(true);
+ struct rlimit rl;
+ getrlimit(RLIMIT_NOFILE, &rl);
+ rl.rlim_cur = qMin((rlim_t) OPEN_MAX, rl.rlim_max);
+ setrlimit(RLIMIT_NOFILE, &rl);
+#endif
+
+ qsrand(QDateTime::currentDateTime().toTime_t());
+
+ // We need to start either a command line application or a GUI application. Since we
+ // fail doing so at least on Linux while parsing the argument using a core application
+ // object and later starting the GUI application, we now parse the arguments first.
+ CommandLineParser parser;
+ parser.parse(QInstaller::parseCommandLineArgs(argc, argv));
+
+ QStringList mutually;
+ if (parser.isSet(QLatin1String(CommandLineOptions::CheckUpdates)))
+ mutually << QLatin1String(CommandLineOptions::CheckUpdates);
+ if (parser.isSet(QLatin1String(CommandLineOptions::Updater)))
+ mutually << QLatin1String(CommandLineOptions::Updater);
+ if (parser.isSet(QLatin1String(CommandLineOptions::ManagePackages)))
+ mutually << QLatin1String(CommandLineOptions::ManagePackages);
+
+ const bool help = parser.isSet(QLatin1String(CommandLineOptions::HelpShort))
+ || parser.isSet(QLatin1String(CommandLineOptions::HelpLong));
+ if (help
+ || parser.isSet(QLatin1String(CommandLineOptions::Version))
+ || parser.isSet(QLatin1String(CommandLineOptions::FrameworkVersion))
+ || mutually.count() > 1) {
+ Console c;
+ QCoreApplication app(argc, argv);
+
+ if (parser.isSet(QLatin1String(CommandLineOptions::Version))) {
+ std::cout << VERSION << std::endl << BUILDDATE << std::endl << SHA << std::endl;
+ const QDateTime dateTime = QDateTime::fromString(QLatin1String(PLACEHOLDER),
+ QLatin1String("yyyy-MM-dd - HH:mm:ss"));
+ if (dateTime.isValid())
+ std::cout << "Installer creation time: " << PLACEHOLDER << std::endl;
+ return EXIT_SUCCESS;
+ }
+
+ if (parser.isSet(QLatin1String(CommandLineOptions::FrameworkVersion))) {
+ std::cout << QUOTE(IFW_VERSION_STR) << std::endl;
+ return EXIT_SUCCESS;
+ }
+
+ std::cout << qPrintable(parser.helpText()) << std::endl;
+ if (mutually.count() > 1) {
+ std::cerr << qPrintable(QString::fromLatin1("The following options are mutually "
+ "exclusive: %1.").arg(mutually.join(QLatin1String(", ")))) << std::endl;
+ }
+ return help ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+
+ if (parser.isSet(QLatin1String(CommandLineOptions::StartServer))) {
+ const QStringList arguments = parser.value(QLatin1String(CommandLineOptions::StartServer))
+ .split(QLatin1Char(','), QString::SkipEmptyParts);
+
+ QString port, key;
+ const QString mode = arguments.value(0);
+ bool argumentsValid = (mode.compare(QLatin1String(QInstaller::Protocol::ModeDebug),
+ Qt::CaseInsensitive) == 0);
+ if (argumentsValid) {
+ port = arguments.value(1, QString::number(QInstaller::Protocol::DefaultPort));
+ key = arguments.value(2, QLatin1String(QInstaller::Protocol::DefaultAuthorizationKey));
+ } else {
+ port = arguments.value(1);
+ key = arguments.value(2);
+ }
+
+ const bool production = (mode.compare(QLatin1String(QInstaller::Protocol::ModeProduction),
+ Qt::CaseInsensitive) == 0);
+ if (production)
+ argumentsValid = (!key.isEmpty()) && (!port.isEmpty());
+
+ SDKApp<QCoreApplication> app(argc, argv);
+ if (!argumentsValid) {
+ Console c;
+ std::cout << qPrintable(parser.helpText()) << std::endl;
+ std::cerr << "Wrong argument(s) for option --startserver." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ QInstaller::RemoteServer *server = new QInstaller::RemoteServer;
+ QObject::connect(server, SIGNAL(destroyed()), &app, SLOT(quit()));
+ server->init(port.toInt(), key, (production ? QInstaller::Protocol::Mode::Production
+ : QInstaller::Protocol::Mode::Debug));
+
+ server->start();
+ return app.exec();
+ }
+
+ try {
+ QScopedPointer<Console> console;
+ if (parser.isSet(QLatin1String(CommandLineOptions::VerboseShort))
+ || parser.isSet(QLatin1String(CommandLineOptions::VerboseLong))) {
+ console.reset(new Console);
+ QInstaller::setVerbose(true);
+ }
+
+ // On Windows we need the console window from above, we are a GUI application.
+ const QStringList unknownOptionNames = parser.unknownOptionNames();
+ if (!unknownOptionNames.isEmpty()) {
+ const QString options = unknownOptionNames.join(QLatin1String(", "));
+ std::cerr << "Unknown option: " << qPrintable(options) << std::endl;
+ }
+
+ if (parser.isSet(QLatin1String(CommandLineOptions::Proxy))) {
+ // Make sure we honor the system's proxy settings
+#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX)
+ QUrl proxyUrl(QString::fromLatin1(qgetenv("http_proxy")));
+ if (proxyUrl.isValid()) {
+ QNetworkProxy proxy(QNetworkProxy::HttpProxy, proxyUrl.host(), proxyUrl.port(),
+ proxyUrl.userName(), proxyUrl.password());
+ QNetworkProxy::setApplicationProxy(proxy);
+ }
+#else
+ QNetworkProxyFactory::setUseSystemConfiguration(true);
+#endif
+ }
+
+ if (parser.isSet(QLatin1String(CommandLineOptions::CheckUpdates)))
+ return UpdateChecker(argc, argv).check();
+
+ if (QInstaller::isVerbose())
+ std::cout << VERSION << std::endl << BUILDDATE << std::endl << SHA << std::endl;
+
+ const KDSelfRestarter restarter(argc, argv);
+ return InstallerBase(argc, argv).run();
+
+ } catch (const QInstaller::Error &e) {
+ std::cerr << qPrintable(e.message()) << std::endl;
+ } catch (const std::exception &e) {
+ std::cerr << e.what() << std::endl;
+ } catch (...) {
+ std::cerr << "Unknown exception caught." << std::endl;
+ }
+
+ return EXIT_FAILURE;
+}
diff --git a/src/sdk/sdk.pro b/src/sdk/sdk.pro
index 51098e3b3..1227ed1c8 100644
--- a/src/sdk/sdk.pro
+++ b/src/sdk/sdk.pro
@@ -4,16 +4,12 @@ TARGET = installerbase
include(../../installerfw.pri)
-QT += network script xml
-
-isEqual(QT_MAJOR_VERSION, 5) {
- QT += widgets
- # add the minimal plugin in static case to be able to start the installer
- # headless with: installer-binary -platform minimal
- # using QT += qpa_minimal_plugin would result in a minimal only compiled version
- !win32:CONFIG(static, static|shared) {
+QT += network qml xml widgets
+# add the minimal plugin in static build to be able to start the installer headless with:
+# installer-binary -platform minimal
+# using QT += qpa_minimal_plugin would result in a minimal only compiled version
+!win32:CONFIG(static, static|shared) {
QTPLUGIN += qminimal
- }
}
DESTDIR = $$IFW_APP_PATH
@@ -110,30 +106,32 @@ exists($$LRELEASE) {
}
FORMS += settingsdialog.ui
-HEADERS += installerbase_p.h \
+HEADERS += \
tabcontroller.h \
installerbasecommons.h \
settingsdialog.h \
console.h \
- sdkapp.h
-
-SOURCES = installerbase.cpp \
- installerbase_p.cpp \
+ sdkapp.h \
+ updatechecker.h \
+ installerbase.h \
+ constants.h \
+ commandlineparser.h
+
+SOURCES = \
+ main.cpp \
+ installerbase.cpp \
tabcontroller.cpp \
installerbasecommons.cpp \
- settingsdialog.cpp
+ settingsdialog.cpp \
+ updatechecker.cpp \
+ commandlineparser.cpp
win32 {
# Force to overwrite the default manifest file with our own extended version.
- isEqual(QT_MAJOR_VERSION, 4) {
- !win32-g++* {
- win32:RC_FILE = installerbase.rc
- QMAKE_POST_LINK += $$quote(mt.exe -updateresource:$$IFW_APP_PATH/$${TARGET}.exe -manifest \"$${IFW_SOURCE_TREE}\\src\\sdk\\installerbase.manifest\")
- }
- } else {
- RC_FILE = installerbase_qt5.rc
- QMAKE_MANIFEST = installerbase.manifest
- }
+ RC_FILE = installerbase_qt5.rc
+ QMAKE_MANIFEST = installerbase.manifest
+
+ SOURCES += console_win.cpp
}
macx:include(../../no_app_bundle.pri)
diff --git a/src/sdk/sdkapp.h b/src/sdk/sdkapp.h
index 78d586560..1a5520c85 100644
--- a/src/sdk/sdkapp.h
+++ b/src/sdk/sdkapp.h
@@ -16,24 +16,17 @@
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
**
** $QT_END_LICENSE$
**
@@ -42,9 +35,15 @@
#ifndef SDKAPP_H
#define SDKAPP_H
-#include "console.h"
+#include <binarycontent.h>
+#include <binaryformat.h>
+#include <fileio.h>
+#include <fileutils.h>
#include <QApplication>
+#include <QDir>
+#include <QFileInfo>
+#include <QResource>
template<class T>
class SDKApp : public T
@@ -52,33 +51,99 @@ class SDKApp : public T
public:
SDKApp(int& argc, char** argv)
: T(argc, argv)
- , m_console(0)
{
}
virtual ~SDKApp()
{
- delete m_console;
- }
-
- void setVerbose()
- {
- if (!m_console)
- m_console = new Console;
+ foreach (const QByteArray &ba, m_resourceMappings)
+ QResource::unregisterResource((const uchar*) ba.data(), QLatin1String(":/metadata"));
}
- virtual bool notify(QObject *receiver, QEvent *event)
+ bool notify(QObject *receiver, QEvent *event)
{
try {
return T::notify(receiver, event);
} catch (std::exception &e) {
qFatal("Exception thrown: %s", e.what());
+ } catch (...) {
+ qFatal("Unknown exception caught.");
}
return false;
}
+ /*!
+ Returns the installer / maintenance tool binary. In case of an installer this will be the
+ installer binary itself, which contains the binary layout and the binary content. In case
+ of an maintenance tool, it will return a binary that has just a binary layout append.
+
+ Note on OS X: For compatibility reason this function will return the a .dat file located
+ inside the resource folder in the application bundle, as on OS X the binary layout cannot
+ be appended to the actual installer / maintenance tool binary itself because of signing.
+ */
+ QString binaryFile() const
+ {
+ QString binaryFile = QCoreApplication::applicationFilePath();
+#ifdef Q_OS_OSX
+ // The installer binary on OSX does not contain the binary content, it's put into
+ // the resources folder as separate file. Adjust the actual binary path. No error
+ // checking here since we will fail later while reading the binary content.
+ QDir resourcePath(QFileInfo(binaryFile).dir());
+ resourcePath.cdUp();
+ resourcePath.cd(QLatin1String("Resources"));
+ return resourcePath.filePath(QLatin1String("installer.dat"));
+#endif
+ return binaryFile;
+ }
+
+ /*!
+ Returns the corresponding .dat file for a given installer / maintenance tool binary or an
+ empty string if it fails to find one.
+ */
+ QString datFile(const QString &binaryFile) const
+ {
+ QFile file(binaryFile);
+ QInstaller::openForRead(&file);
+ const quint64 cookiePos = QInstaller::BinaryContent::findMagicCookie(&file,
+ QInstaller::BinaryContent::MagicCookie);
+ if (!file.seek(cookiePos - sizeof(qint64))) // seek to read the marker
+ return QString(); // ignore error, we will fail later
+
+ const qint64 magicMarker = QInstaller::retrieveInt64(&file);
+ if (magicMarker == QInstaller::BinaryContent::MagicUninstallerMarker) {
+ QFileInfo fi(binaryFile);
+ QString bundlePath;
+ if (QInstaller::isInBundle(fi.absoluteFilePath(), &bundlePath))
+ fi.setFile(bundlePath);
+ return fi.absoluteDir().filePath(fi.baseName() + QLatin1String(".dat"));
+ }
+ return QString();
+ }
+
+ void registerMetaResources(const QInstaller::ResourceCollection &collection)
+ {
+ foreach (const QSharedPointer<QInstaller::Resource> &resource, collection.resources()) {
+ const bool isOpen = resource->isOpen();
+ if ((!isOpen) && (!resource->open()))
+ continue;
+
+ if (!resource->seek(0))
+ continue;
+
+ const QByteArray ba = resource->readAll();
+ if (ba.isEmpty())
+ continue;
+
+ if (QResource::registerResource((const uchar*) ba.data(), QLatin1String(":/metadata")))
+ m_resourceMappings.append(ba);
+
+ if (!isOpen) // If we reach that point, either the resource was opened already...
+ resource->close(); // or we did open it and have to close it again.
+ }
+ }
+
private:
- Console *m_console;
+ QList<QByteArray> m_resourceMappings;
};
#endif // SDKAPP_H
diff --git a/src/sdk/settingsdialog.cpp b/src/sdk/settingsdialog.cpp
index 305fc051a..3281cc45d 100644
--- a/src/sdk/settingsdialog.cpp
+++ b/src/sdk/settingsdialog.cpp
@@ -16,24 +16,17 @@
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
**
** $QT_END_LICENSE$
**
@@ -229,16 +222,10 @@ SettingsDialog::SettingsDialog(PackageManagerCore *core, QWidget *parent)
const QNetworkProxy &ftpProxy = settings.ftpProxy();
m_ui->m_ftpProxy->setText(ftpProxy.hostName());
m_ui->m_ftpProxyPort->setValue(ftpProxy.port());
- m_ui->m_ftpProxyUser->setText(ftpProxy.user());
- m_ui->m_ftpProxyPass->setText(ftpProxy.password());
- m_ui->m_ftpProxyNeedsAuth->setChecked(!ftpProxy.user().isEmpty() | !ftpProxy.password().isEmpty());
const QNetworkProxy &httpProxy = settings.httpProxy();
m_ui->m_httpProxy->setText(httpProxy.hostName());
m_ui->m_httpProxyPort->setValue(httpProxy.port());
- m_ui->m_httpProxyUser->setText(httpProxy.user());
- m_ui->m_httpProxyPass->setText(httpProxy.password());
- m_ui->m_httpProxyNeedsAuth->setChecked(!httpProxy.user().isEmpty() | !httpProxy.password().isEmpty());
connect(m_ui->m_addRepository, SIGNAL(clicked()), this, SLOT(addRepository()));
connect(m_ui->m_showPasswords, SIGNAL(clicked()), this, SLOT(updatePasswords()));
@@ -291,12 +278,12 @@ void SettingsDialog::accept()
if (newSettings.proxyType() == Settings::UserDefinedProxy) {
// update ftp proxy settings
newSettings.setFtpProxy(QNetworkProxy(QNetworkProxy::HttpProxy, m_ui->m_ftpProxy->text(),
- m_ui->m_ftpProxyPort->value(), m_ui->m_ftpProxyUser->text(), m_ui->m_ftpProxyPass->text()));
+ m_ui->m_ftpProxyPort->value()));
settingsChanged |= (settings.ftpProxy() != newSettings.ftpProxy());
// update http proxy settings
newSettings.setHttpProxy(QNetworkProxy(QNetworkProxy::HttpProxy, m_ui->m_httpProxy->text(),
- m_ui->m_httpProxyPort->value(), m_ui->m_httpProxyUser->text(), m_ui->m_httpProxyPass->text()));
+ m_ui->m_httpProxyPort->value()));
settingsChanged |= (settings.httpProxy() != newSettings.httpProxy());
}
@@ -428,13 +415,8 @@ void SettingsDialog::setupRepositoriesTreeWidget()
for (int i = 0; i < treeWidget->model()->columnCount(); ++i)
treeWidget->resizeColumnToContents(i);
-#if QT_VERSION < 0x050000
- treeWidget->header()->setResizeMode(0, QHeaderView::Fixed);
- treeWidget->header()->setResizeMode(1, QHeaderView::Fixed);
-#else
treeWidget->header()->setSectionResizeMode(0, QHeaderView::Fixed);
treeWidget->header()->setSectionResizeMode(1, QHeaderView::Fixed);
-#endif
treeWidget->header()->setMinimumSectionSize(treeWidget->columnWidth(1));
treeWidget->setItemDelegateForColumn(0, new PasswordDelegate(treeWidget));
diff --git a/src/sdk/settingsdialog.h b/src/sdk/settingsdialog.h
index 942adfc2f..fb0253d26 100644
--- a/src/sdk/settingsdialog.h
+++ b/src/sdk/settingsdialog.h
@@ -16,24 +16,17 @@
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
**
** $QT_END_LICENSE$
**
diff --git a/src/sdk/settingsdialog.ui b/src/sdk/settingsdialog.ui
index d3ca959a6..3683f3cd1 100644
--- a/src/sdk/settingsdialog.ui
+++ b/src/sdk/settingsdialog.ui
@@ -56,253 +56,118 @@
</item>
<item>
<widget class="QWidget" name="m_rootWidget" native="true">
- <layout class="QVBoxLayout" name="verticalLayout_6">
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <layout class="QVBoxLayout" name="m_httpRootLayout">
- <item>
- <layout class="QHBoxLayout" name="m_httpProxyLayout">
- <item>
- <widget class="QLabel" name="m_httpProxyLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>HTTP proxy:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="m_httpProxy">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="m_httpProxyPortLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Port:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="m_httpProxyPort">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="maximum">
- <number>65535</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QCheckBox" name="m_httpProxyNeedsAuth">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>HTTP proxy requires authentication</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QWidget" name="m_httpAuthWidget" native="true">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="m_httpProxyUserLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Username:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="m_httpProxyUser">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="m_httpProxyPassLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Password:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="m_httpProxyPass">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="echoMode">
- <enum>QLineEdit::Password</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_httpProxyLabel">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>HTTP proxy:</string>
+ </property>
+ </widget>
</item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="m_httpProxy">
+ <property name="enabled">
+ <bool>false</bool>
</property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="m_httpProxyPortLabel">
+ <property name="enabled">
+ <bool>false</bool>
</property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>10</height>
- </size>
+ <property name="text">
+ <string>Port:</string>
</property>
- </spacer>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QSpinBox" name="m_httpProxyPort">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
</item>
- <item>
- <layout class="QVBoxLayout" name="m_ftpRootLayout">
- <item>
- <layout class="QHBoxLayout" name="m_ftpProxyLayout">
- <item>
- <widget class="QLabel" name="m_ftpProxyLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>FTP proxy:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="m_ftpProxy">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="m_ftpProxyPortLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Port:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="m_ftpProxyPort">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="maximum">
- <number>65535</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QCheckBox" name="m_ftpProxyNeedsAuth">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>FTP proxy requires authentication</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QWidget" name="m_ftpAuthWidget" native="true">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="m_ftpProxyUserLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Username:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="m_ftpProxyUser">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="m_ftpProxyPassLabel">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Password:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="m_ftpProxyPass">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="echoMode">
- <enum>QLineEdit::Password</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
+ <item row="1" column="0">
+ <widget class="QWidget" name="m_httpAuthWidget" native="true">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ </layout>
+ </widget>
</item>
- <item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="m_ftpProxyLabel">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>FTP proxy:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="m_ftpProxy">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="m_ftpProxyPortLabel">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QSpinBox" name="m_ftpProxyPort">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QWidget" name="m_ftpAuthWidget" native="true">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -478,22 +343,6 @@
<connection>
<sender>m_manualProxySettings</sender>
<signal>toggled(bool)</signal>
- <receiver>m_httpProxyPortLabel</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>349</x>
- <y>78</y>
- </hint>
- <hint type="destinationlabel">
- <x>347</x>
- <y>96</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>m_manualProxySettings</sender>
- <signal>toggled(bool)</signal>
<receiver>m_httpProxyPort</receiver>
<slot>setEnabled(bool)</slot>
<hints>
@@ -510,32 +359,16 @@
<connection>
<sender>m_manualProxySettings</sender>
<signal>toggled(bool)</signal>
- <receiver>m_ftpProxyLabel</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>61</x>
- <y>76</y>
- </hint>
- <hint type="destinationlabel">
- <x>109</x>
- <y>243</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>m_manualProxySettings</sender>
- <signal>toggled(bool)</signal>
- <receiver>m_ftpProxy</receiver>
+ <receiver>m_httpProxyPortLabel</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
- <x>204</x>
+ <x>349</x>
<y>78</y>
</hint>
<hint type="destinationlabel">
- <x>203</x>
- <y>248</y>
+ <x>347</x>
+ <y>96</y>
</hint>
</hints>
</connection>
@@ -558,48 +391,48 @@
<connection>
<sender>m_manualProxySettings</sender>
<signal>toggled(bool)</signal>
- <receiver>m_ftpProxyPort</receiver>
+ <receiver>m_ftpProxyLabel</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
- <x>406</x>
- <y>78</y>
+ <x>61</x>
+ <y>76</y>
</hint>
<hint type="destinationlabel">
- <x>380</x>
- <y>252</y>
+ <x>109</x>
+ <y>243</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_manualProxySettings</sender>
<signal>toggled(bool)</signal>
- <receiver>m_httpProxyNeedsAuth</receiver>
+ <receiver>m_ftpProxy</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
- <x>53</x>
- <y>75</y>
+ <x>204</x>
+ <y>78</y>
</hint>
<hint type="destinationlabel">
- <x>100</x>
- <y>129</y>
+ <x>203</x>
+ <y>248</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_manualProxySettings</sender>
<signal>toggled(bool)</signal>
- <receiver>m_ftpProxyNeedsAuth</receiver>
+ <receiver>m_ftpProxyPort</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
- <x>88</x>
- <y>74</y>
+ <x>406</x>
+ <y>78</y>
</hint>
<hint type="destinationlabel">
- <x>95</x>
- <y>274</y>
+ <x>380</x>
+ <y>252</y>
</hint>
</hints>
</connection>
@@ -635,133 +468,5 @@
</hint>
</hints>
</connection>
- <connection>
- <sender>m_ftpProxyNeedsAuth</sender>
- <signal>toggled(bool)</signal>
- <receiver>m_ftpProxyUserLabel</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>82</x>
- <y>283</y>
- </hint>
- <hint type="destinationlabel">
- <x>77</x>
- <y>303</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>m_ftpProxyNeedsAuth</sender>
- <signal>toggled(bool)</signal>
- <receiver>m_ftpProxyUser</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>180</x>
- <y>284</y>
- </hint>
- <hint type="destinationlabel">
- <x>170</x>
- <y>304</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>m_ftpProxyNeedsAuth</sender>
- <signal>toggled(bool)</signal>
- <receiver>m_ftpProxyPass</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>224</x>
- <y>283</y>
- </hint>
- <hint type="destinationlabel">
- <x>223</x>
- <y>330</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>m_ftpProxyNeedsAuth</sender>
- <signal>toggled(bool)</signal>
- <receiver>m_ftpProxyPassLabel</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>317</x>
- <y>282</y>
- </hint>
- <hint type="destinationlabel">
- <x>122</x>
- <y>335</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>m_httpProxyNeedsAuth</sender>
- <signal>toggled(bool)</signal>
- <receiver>m_httpProxyUserLabel</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>81</x>
- <y>134</y>
- </hint>
- <hint type="destinationlabel">
- <x>70</x>
- <y>154</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>m_httpProxyNeedsAuth</sender>
- <signal>toggled(bool)</signal>
- <receiver>m_httpProxyPassLabel</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>87</x>
- <y>137</y>
- </hint>
- <hint type="destinationlabel">
- <x>84</x>
- <y>186</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>m_httpProxyNeedsAuth</sender>
- <signal>toggled(bool)</signal>
- <receiver>m_httpProxyUser</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>183</x>
- <y>135</y>
- </hint>
- <hint type="destinationlabel">
- <x>182</x>
- <y>154</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>m_httpProxyNeedsAuth</sender>
- <signal>toggled(bool)</signal>
- <receiver>m_httpProxyPass</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>287</x>
- <y>134</y>
- </hint>
- <hint type="destinationlabel">
- <x>285</x>
- <y>182</y>
- </hint>
- </hints>
- </connection>
</connections>
</ui>
diff --git a/src/sdk/tabcontroller.cpp b/src/sdk/tabcontroller.cpp
index 8c9f2cc0d..035622dfb 100644
--- a/src/sdk/tabcontroller.cpp
+++ b/src/sdk/tabcontroller.cpp
@@ -16,24 +16,17 @@
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
**
** $QT_END_LICENSE$
**
@@ -95,7 +88,7 @@ TabController::TabController(QObject *parent)
TabController::~TabController()
{
- d->m_core->writeUninstaller();
+ d->m_core->writeMaintenanceTool();
delete d;
}
@@ -137,8 +130,8 @@ int TabController::init()
connect(d->m_gui, SIGNAL(settingsButtonClicked()), this, SLOT(onSettingsButtonClicked()));
}
- IntroductionPageImpl *page =
- qobject_cast<IntroductionPageImpl*> (d->m_gui->page(PackageManagerCore::Introduction));
+ IntroductionPage *page =
+ qobject_cast<IntroductionPage*> (d->m_gui->page(PackageManagerCore::Introduction));
if (page) {
page->setMessage(QString());
page->setErrorMessage(QString());
@@ -174,7 +167,7 @@ void TabController::restartWizard()
// Make sure we are writing the .dat file with the list of uninstall operations already now.
// Otherwise we will write at the end of the next updater run, with a potentially
// empty component list (if no updates are found).
- d->m_core->writeUninstaller();
+ d->m_core->writeMaintenanceTool();
// restart and switch back to intro page
QTimer::singleShot(0, this, SLOT(init()));
@@ -189,8 +182,8 @@ void TabController::onSettingsButtonClicked()
if (d->m_networkSettingsChanged) {
d->m_core->setCanceled();
- IntroductionPageImpl *page =
- qobject_cast<IntroductionPageImpl*> (d->m_gui->page(PackageManagerCore::Introduction));
+ IntroductionPage *page =
+ qobject_cast<IntroductionPage*> (d->m_gui->page(PackageManagerCore::Introduction));
if (page) {
page->setMessage(QString());
page->setErrorMessage(QString());
@@ -202,7 +195,7 @@ void TabController::onSettingsButtonClicked()
void TabController::onCurrentIdChanged(int newId)
{
if (d->m_gui) {
- if (PackageManagerPage *page = d->m_gui->page(newId))
+ if (PackageManagerPage *page = qobject_cast<PackageManagerPage *>(d->m_gui->page(newId)))
d->m_gui->showSettingsButton(page->settingsButtonRequested());
}
}
diff --git a/src/sdk/tabcontroller.h b/src/sdk/tabcontroller.h
index 546837997..831211453 100644
--- a/src/sdk/tabcontroller.h
+++ b/src/sdk/tabcontroller.h
@@ -16,24 +16,17 @@
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
**
** $QT_END_LICENSE$
**
diff --git a/src/sdk/translations/ja_jp.ts b/src/sdk/translations/ja_jp.ts
index 3303cfd10..0222d7c14 100644
--- a/src/sdk/translations/ja_jp.ts
+++ b/src/sdk/translations/ja_jp.ts
@@ -255,7 +255,7 @@
</message>
<message>
<source>Could not create folder %1: Unknown error.</source>
- <translation>フォルダー %1 を作成できませんでした: 未知のエラーです。</translation>
+ <translation>フォルダ %1 を作成できませんでした: 未知のエラーです。</translation>
</message>
<message>
<source>Cannot remove directory %1: %2</source>
@@ -362,11 +362,11 @@
</message>
<message>
<source>Could not remove folder %1: The folder does not exist.</source>
- <translation>フォルダー %1 を削除できませんでした: フォルダーが存在しません。</translation>
+ <translation>フォルダ %1 を削除できませんでした: フォルダが存在しません。</translation>
</message>
<message>
<source>Could not remove folder %1: %2</source>
- <translation>フォルダー %1 を削除できませんでした: %2</translation>
+ <translation>フォルダ %1 を削除できませんでした: %2</translation>
</message>
<message>
<source>Cannot recreate directory %1: %2</source>
@@ -875,7 +875,7 @@
</message>
<message>
<source>Could not create folder %1: %2.</source>
- <translation>フォルダー %1 を作成できませんでした: %2</translation>
+ <translation>フォルダ %1 を作成できませんでした: %2</translation>
</message>
<message>
<source>Could not create link %1: %2</source>
@@ -1905,7 +1905,7 @@ Qt のバイナリにパッチを適用しようとしましたが、Qt の他
</message>
<message>
<source>The install directory cannot be empty, please specify a valid folder.</source>
- <translation>インストールディレクトリが殻にできません。有効なフォルダを指定してください。</translation>
+ <translation>インストールディレクトリが空にできません。有効なフォルダを指定してください。</translation>
</message>
<message>
<source>As the install directory is completely deleted on uninstall, installing in %1 is forbidden.</source>
@@ -2034,11 +2034,11 @@ Qt のバイナリにパッチを適用しようとしましたが、Qt の他
</message>
<message>
<source>Could not remove folder %1: %2</source>
- <translation>フォルダー %1 を削除できませんでした: %2</translation>
+ <translation>フォルダ %1 を削除できませんでした: %2</translation>
</message>
<message>
<source>Could not create folder %1</source>
- <translation>フォルダー %1 を作成できませんでした</translation>
+ <translation>フォルダ %1 を作成できませんでした</translation>
</message>
<message>
<source>Could not copy file from %1 to %2: %3</source>
@@ -2050,7 +2050,7 @@ Qt のバイナリにパッチを適用しようとしましたが、Qt の他
</message>
<message>
<source>Could not create folder %1: %2</source>
- <translation>フォルダー %1 を作成できませんでした: %2</translation>
+ <translation>フォルダ %1 を作成できませんでした: %2</translation>
</message>
<message>
<source>Could not open temporary file: %1</source>
@@ -2078,11 +2078,11 @@ Qt のバイナリにパッチを適用しようとしましたが、Qt の他
</message>
<message>
<source>Path exists but is not a folder: %1</source>
- <translation>パスが存在していますが、フォルダーではありません: %1</translation>
+ <translation>パスが存在していますが、フォルダではありません: %1</translation>
</message>
<message>
<source>Could not create folder: %1</source>
- <translation>フォルダーを作成できませんでした: %1</translation>
+ <translation>フォルダを作成できませんでした: %1</translation>
</message>
<message>
<source>Could not create temporary file</source>
@@ -2242,7 +2242,7 @@ Qt のバイナリにパッチを適用しようとしましたが、Qt の他
</message>
<message>
<source>Could not create folder at %1: %2</source>
- <translation>%1 にフォルダーを作成できませんでした: %2</translation>
+ <translation>%1 にフォルダを作成できませんでした: %2</translation>
</message>
<message>
<source>Invalid arguments: %1 arguments given, %2 to %3 expected.</source>
diff --git a/src/sdk/updatechecker.cpp b/src/sdk/updatechecker.cpp
new file mode 100644
index 000000000..7f2e50275
--- /dev/null
+++ b/src/sdk/updatechecker.cpp
@@ -0,0 +1,118 @@
+/**************************************************************************
+**
+** Copyright (C) 2012-2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "updatechecker.h"
+
+#include <binaryformatenginehandler.h>
+#include <component.h>
+#include <errors.h>
+#include <init.h>
+#include <kdrunoncechecker.h>
+#include <packagemanagercore.h>
+#include <productkeycheck.h>
+
+#include <QDomDocument>
+
+#include <iostream>
+
+UpdateChecker::UpdateChecker(int &argc, char *argv[])
+ : SDKApp<QCoreApplication>(argc, argv)
+{
+ QInstaller::init(); // register custom operations
+}
+
+int UpdateChecker::check()
+{
+ KDRunOnceChecker runCheck(qApp->applicationDirPath() + QLatin1String("/lockmyApp15021976.lock"));
+ if (runCheck.isRunning(KDRunOnceChecker::ConditionFlag::Lockfile)) {
+ // It is possible to install an application and thus the maintenance tool into a
+ // directory that requires elevated permission to create a lock file. Since this
+ // cannot be done without requesting credentials from the user, we silently ignore
+ // the fact that we could not create the lock file and check the running processes.
+ if (runCheck.isRunning(KDRunOnceChecker::ConditionFlag::ProcessList))
+ throw QInstaller::Error(QLatin1String("An instance is already checking for updates."));
+ }
+
+ QString fileName = datFile(binaryFile());
+ quint64 cookie = QInstaller::BinaryContent::MagicCookieDat;
+ if (fileName.isEmpty()) {
+ fileName = binaryFile();
+ cookie = QInstaller::BinaryContent::MagicCookie;
+ }
+
+ QFile binary(fileName);
+ QInstaller::openForRead(&binary);
+
+ qint64 magicMarker;
+ QList<QInstaller::OperationBlob> operations;
+ QInstaller::ResourceCollectionManager manager;
+ QInstaller::BinaryContent::readBinaryContent(&binary, &operations, &manager, &magicMarker,
+ cookie);
+
+ if (magicMarker != QInstaller::BinaryContent::MagicInstallerMarker)
+ throw QInstaller::Error(QLatin1String("Installers cannot check for updates."));
+
+ SDKApp::registerMetaResources(manager.collectionByName("QResources"));
+
+ QInstaller::PackageManagerCore core(QInstaller::BinaryContent::MagicUpdaterMarker, operations);
+ QInstaller::PackageManagerCore::setVirtualComponentsVisible(true);
+ {
+ using namespace QInstaller;
+ ProductKeyCheck::instance()->init(&core);
+ ProductKeyCheck::instance()->addPackagesFromXml(QLatin1String(":/metadata/Updates.xml"));
+ BinaryFormatEngineHandler::instance()->registerResources(manager.collections());
+ }
+ if (!core.fetchRemotePackagesTree())
+ throw QInstaller::Error(core.error());
+
+ const QList<QInstaller::Component *> components =
+ core.components(QInstaller::PackageManagerCore::ComponentType::Root);
+ if (components.isEmpty())
+ throw QInstaller::Error(QLatin1String("There are currently no updates available."));
+
+ QDomDocument doc;
+ QDomElement root = doc.createElement(QLatin1String("updates"));
+ doc.appendChild(root);
+
+ foreach (QInstaller::Component *component, components) {
+ QDomElement update = doc.createElement(QLatin1String("update"));
+ update.setAttribute(QLatin1String("name"), component->value(QInstaller::scDisplayName));
+ update.setAttribute(QLatin1String("version"), component->value(QInstaller::scRemoteVersion));
+ update.setAttribute(QLatin1String("size"), component->value(QInstaller::scUncompressedSize));
+ root.appendChild(update);
+ }
+
+ std::cout << qPrintable(doc.toString(4)) << std::endl;
+ return EXIT_SUCCESS;
+}
diff --git a/src/sdk/updatechecker.h b/src/sdk/updatechecker.h
new file mode 100644
index 000000000..134ef704b
--- /dev/null
+++ b/src/sdk/updatechecker.h
@@ -0,0 +1,50 @@
+/**************************************************************************
+**
+** Copyright (C) 2012-2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#ifndef UPDATECHECKER_H
+#define UPDATECHECKER_H
+
+#include "sdkapp.h"
+
+class UpdateChecker : public SDKApp<QCoreApplication>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(UpdateChecker)
+
+public:
+ UpdateChecker(int &argc, char *argv[]);
+ int check();
+};
+
+#endif // UPDATECHECKER_H