Merge remote-tracking branch 'origin/2.0'

Conflicts:
	Changelog

Change-Id: Idd7d569f97fba75b05bfc006c7a5b0b9cf8ccf73
This commit is contained in:
Kai Koehne 2015-04-21 14:18:07 +02:00
commit ffed7d2b6d
20 changed files with 169 additions and 55 deletions

View File

@ -1,5 +1,13 @@
2.1.0
2.0.1
- Do not throw exception on empty translation files.
- Fix --checkupdates mode.
- Prevent disabled component to be selected using the Select All button. (QTIFW-635)
- Windows: Fix crashes in elevated installation. (QTIFW-6656, QTIFW-659)
- Fix crash on exit for Windows XP, Vista. (QTIFW-652)
- Documentation updates.
2.0.0
- Require Qt 5.4 as a minimal version, Qt 4 code removed.
- Only support Qt 5 on documentation side as well.
@ -62,7 +70,7 @@
- Updated and improved translations.
- Fixed various bugs. (QTIFW-397, QTIFW-469, QTIFW-481, QTIFW-524, QTIFW-538, QTIFW-541, QTIFW-542, QTIFW-562, QTIFW-564, QTIFW-568, QTIFW-569, QTIFW-583, QTIFW-589, QTIFW-593, QTIFW-600, QTIFW-602, QTIFW-605, QTIFW-612, QTIFW-615, QTIFW-616, QTIFW-618, QTIFW-620, QTIFW-621, QTIFW-622, QTIFW-625, QTBUG-633)
Thanks go to Christoph Vogtländer, Sze Howe Koh, Ray Donnelly, Tasuku Suzuki, Takayuki Orito, Sascha Cunz and Cuoghi Massimiliano for contributions.
Thanks go to Christoph Vogtländer, Sze Howe Koh, Ray Donnelly, Tasuku Suzuki, Takayuki Orito, Sascha Cunz, Zhang Xingtao, Sergey Belyashov and Cuoghi Massimiliano for contributions.
1.6.0
- No longer requires Xcode command line tools on Mac. (QTBUG-38015)

View File

@ -248,11 +248,13 @@
\uicontrol Start menu.
\row
\li TargetDir
\li Default target directory for installation.
\li Default target directory for installation. On Linux, this is
usually the user's home directory.
\row
\li AdminTargetDir
\li Default target directory for installation with administrator
rights.
rights. Only available on Linux, where you usually do not want
to install in the administrator user's home directory.
\row
\li RemoteRepositories
\li List of remote repositories. This element can contain several \c <Repository> child
@ -641,8 +643,7 @@
\row
\li Essential
\li Marks the package as essential to force a restart of the
\c UpdateAgent or \c MaintenanceTool. This is relevant for
updates found with \c UpdateAgent. If there are updates available
\c MaintenanceTool. If there are updates available
for an essential component, the package manager stays disabled
until that component is updated. Newly introduced essential components
are automatically installed when running the updater.

View File

@ -172,6 +172,15 @@
(using \c QSettings::NativeFormat, which might be the Windows
registry) or by \c application and \c company name. Set \c scope
to "SystemScope" to create an entry in the system scope.
\note: The operation is using QSettings to store the key value pair. QSettings
always treats backslash as a special character and provides no API for reading
or writing such entries. Do not use slashes ('/' and '\') in section or key names;
the backslash character is used to separate sub keys. On windows, '\' are converted
by QSettings to '/', which makes them identical. Because the backslash character is
used by QSettings to separate sub keys, you cannot read or write windows registry
entries that contain slashes or backslashes. You should use a native windows API if
you need to do so.
\row
\li EnvironmentVariable
\li "EnvironmentVariable" \c key \c value [\c persistent [\c system]]

View File

@ -82,12 +82,6 @@
Returns the name of the component as shown in the user interface.
*/
/*!
\qmlproperty boolean component::selected
Indicates whether the component is currently selected.
*/
/*!
\qmlproperty boolean component::autoCreateOperations
@ -176,6 +170,12 @@
\sa setValue
*/
/*!
\qmlsignal component::virtualStateChanged()
Emitted when the virtual state of the component changes.
*/
/*!
\qmlmethod string component::value(string key, string value = "")

View File

@ -557,9 +557,11 @@ void Component::loadTranslations(const QDir &directory, const QStringList &qms)
}
QScopedPointer<QTranslator> translator(new QTranslator(this));
if (!translator->load(filename))
throw Error(tr("Could not open the requested translation file '%1'.").arg(filename));
qApp->installTranslator(translator.take());
if (translator->load(filename)) {
// Do not throw if translator returns false as it may just be an intentionally
// empty file. See also QTBUG-31031
qApp->installTranslator(translator.take());
}
}
}

View File

@ -42,8 +42,13 @@ namespace QInstaller {
QStringList ComponentChecker::checkComponent(Component *component)
{
PackageManagerCore *core = component->packageManagerCore();
QStringList checkResult;
if (!component)
return checkResult;
PackageManagerCore *core = component->packageManagerCore();
if (!core)
return checkResult;
if (component->childCount() && !component->archives().isEmpty()) {
checkResult << QString::fromLatin1("Component %1 contains data to be installed "
@ -80,7 +85,7 @@ QStringList ComponentChecker::checkComponent(Component *component)
foreach (const QString &dependency, dependencies) {
Component *dependencyComponent = PackageManagerCore::componentByName(
dependency, allComponents);
if (autoDependencies.contains(dependencyComponent->name())) {
if (dependencyComponent && autoDependencies.contains(dependencyComponent->name())) {
checkResult << QString::fromLatin1("Component %1 specifies both dependency "
"and auto dependency on component %2. The dependency might be superfluous.")
.arg(component->name(), dependencyComponent->name());

View File

@ -577,7 +577,7 @@ QSet<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &compone
// we can start in descending order to check node and tri-state nodes properly
for (int i = sortedNodes.count(); i > 0; i--) {
Component * const node = sortedNodes.at(i - 1);
if (!node->isCheckable())
if (!node->isCheckable() || !node->isEnabled())
continue;
Qt::CheckState newState = state;

View File

@ -123,7 +123,8 @@ HEADERS += packagemanagercore.h \
proxycredentialsdialog.h \
serverauthenticationdialog.h \
keepaliveobject.h \
systeminfo.h
systeminfo.h \
localsocket.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \

View File

@ -34,8 +34,8 @@
#include "keepaliveobject.h"
#include "remoteclient.h"
#include "localsocket.h"
#include <QLocalSocket>
#include <QTimer>
namespace QInstaller {
@ -49,7 +49,7 @@ KeepAliveObject::KeepAliveObject()
void KeepAliveObject::start()
{
m_timer = new QTimer(this);
m_socket = new QLocalSocket(this);
m_socket = new LocalSocket(this);
connect(m_timer, &QTimer::timeout, [this]() {
if (m_socket->state() != QLocalSocket::UnconnectedState)

View File

@ -0,0 +1,74 @@
/**************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
**
** $QT_END_LICENSE$
**
**************************************************************************/
#ifndef LOCALSOCKET_H
#define LOCALSOCKET_H
#include <QLocalSocket>
#if defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK(5,5,0)
// This is a crude hack to work around QLocalSocket::waitForReadyRead returning instantly
// if there are still bytes left in the buffer. This has been fixed in Qt 5.5.0 ...
class LocalSocket : public QLocalSocket
{
public:
LocalSocket(QObject *parent = 0) : QLocalSocket(parent), inReadyRead(false)
{
}
qint64 bytesAvailable() const {
if (inReadyRead)
return 0;
return QLocalSocket::bytesAvailable();
}
bool waitForReadyRead(int msecs = 30000) {
inReadyRead = true;
bool result = QLocalSocket::waitForReadyRead(msecs);
inReadyRead = false;
return result;
}
private:
bool inReadyRead;
};
#else
typedef QLocalSocket LocalSocket;
#endif
#endif // LOCALSOCKET_H

View File

@ -374,10 +374,6 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
else if (component->isInstalled())
component->setCheckState(Qt::Checked);
}
const QStringList warnings = ComponentChecker::checkComponent(component);
foreach (const QString &warning, warnings)
qWarning() << warning;
}
std::sort(m_rootComponents.begin(), m_rootComponents.end(), Component::SortingPriorityGreaterThan());
@ -396,6 +392,11 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
restoreCheckState();
foreach (QInstaller::Component *component, components) {
const QStringList warnings = ComponentChecker::checkComponent(component);
foreach (const QString &warning, warnings)
qWarning() << warning;
}
} catch (const Error &error) {
clearAllComponentLists();
emit m_core->finishAllComponentsReset(QList<QInstaller::Component*>());

View File

@ -1251,8 +1251,12 @@ IntroductionPage::IntroductionPage(PackageManagerCore *core)
m_updateComponents->setEnabled(ProductKeyCheck::instance()->hasValidKey());
#ifdef Q_OS_WIN
m_taskButton = new QWinTaskbarButton(this);
connect(core, SIGNAL(metaJobProgress(int)), m_taskButton->progress(), SLOT(setValue(int)));
if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
m_taskButton = new QWinTaskbarButton(this);
connect(core, SIGNAL(metaJobProgress(int)), m_taskButton->progress(), SLOT(setValue(int)));
} else {
m_taskButton = 0;
}
#endif
}
@ -1298,14 +1302,16 @@ bool IntroductionPage::validatePage()
}
#ifdef Q_OS_WIN
if (!m_taskButton->window()) {
if (QWidget *widget = QApplication::activeWindow())
m_taskButton->setWindow(widget->windowHandle());
}
if (m_taskButton) {
if (!m_taskButton->window()) {
if (QWidget *widget = QApplication::activeWindow())
m_taskButton->setWindow(widget->windowHandle());
}
m_taskButton->progress()->reset();
m_taskButton->progress()->resume();
m_taskButton->progress()->setVisible(true);
m_taskButton->progress()->reset();
m_taskButton->progress()->resume();
m_taskButton->progress()->setVisible(true);
}
#endif
// fetch updater packages
@ -1358,7 +1364,8 @@ bool IntroductionPage::validatePage()
gui()->setSettingsButtonEnabled(true);
#ifdef Q_OS_WIN
m_taskButton->progress()->setVisible(!isComplete());
if (m_taskButton)
m_taskButton->progress()->setVisible(!isComplete());
#endif
return isComplete();
}
@ -1446,8 +1453,10 @@ void IntroductionPage::setErrorMessage(const QString &error)
m_errorLabel->setPalette(palette);
#ifdef Q_OS_WIN
m_taskButton->progress()->stop();
m_taskButton->progress()->setValue(100);
if (m_taskButton) {
m_taskButton->progress()->stop();
m_taskButton->progress()->setValue(100);
}
#endif
}

View File

@ -89,8 +89,12 @@ PerformInstallationForm::PerformInstallationForm(QObject *parent)
, m_updateTimer(0)
{
#ifdef Q_OS_WIN
m_taskButton = new QWinTaskbarButton(this);
m_taskButton->progress()->setVisible(true);
if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
m_taskButton = new QWinTaskbarButton(this);
m_taskButton->progress()->setVisible(true);
} else {
m_taskButton = 0;
}
#endif
}
@ -177,9 +181,11 @@ void PerformInstallationForm::updateProgress()
m_progressBar->setValue(progressPercentage);
#ifdef Q_OS_WIN
if (!m_taskButton->window())
m_taskButton->setWindow(QApplication::activeWindow()->windowHandle());
m_taskButton->progress()->setValue(progressPercentage);
if (m_taskButton) {
if (!m_taskButton->window())
m_taskButton->setWindow(QApplication::activeWindow()->windowHandle());
m_taskButton->progress()->setValue(progressPercentage);
}
#endif
static QString lastLabelText;

View File

@ -36,6 +36,7 @@
#include "protocol.h"
#include "remoteclient.h"
#include "localsocket.h"
#include <QCoreApplication>
#include <QElapsedTimer>
@ -73,7 +74,7 @@ bool RemoteObject::authorize()
if (m_socket)
delete m_socket;
m_socket = new QLocalSocket;
m_socket = new LocalSocket;
m_socket->connectToServer(RemoteClient::instance().socketName());
QElapsedTimer stopWatch;

View File

@ -101,10 +101,6 @@ public:
"Bytes expected: %2, Bytes received: %3. Error: %4").arg(name).arg(0)
.arg(m_socket->bytesAvailable()).arg(m_socket->errorString()));
}
#if defined Q_OS_WIN && QT_VERSION < QT_VERSION_CHECK(5,5,0)
// work around QTBUG-16688
QCoreApplication::processEvents();
#endif
}
Q_ASSERT(command == Protocol::Reply);

View File

@ -39,8 +39,10 @@
#include "remoteserverconnection_p.h"
#include "utils.h"
#include "permissionsettings.h"
#include "localsocket.h"
#include <QCoreApplication>
#include <QDataStream>
#include <QLocalSocket>
namespace QInstaller {
@ -70,7 +72,7 @@ private:
void RemoteServerConnection::run()
{
QLocalSocket socket;
LocalSocket socket;
socket.setSocketDescriptor(m_socketDescriptor);
QScopedPointer<PermissionSettings> settings;
@ -81,10 +83,6 @@ void RemoteServerConnection::run()
if (!receivePacket(&socket, &cmd, &data)) {
socket.waitForReadyRead(250);
#if defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK(5,5,0)
// work around QTBUG-16688
QCoreApplication::processEvents();
#endif
continue;
}

View File

@ -35,6 +35,7 @@
#include "repository.h"
#include "kdupdaterfiledownloaderfactory.h"
#include <QDataStream>
#include <QFileInfo>
#include <QStringList>

View File

@ -36,6 +36,7 @@
#include "kdupdaterapplication.h"
#include <QDataStream>
#include <QDebug>
#include <QDir>
#include <QFileInfo>

View File

@ -80,7 +80,7 @@ int UpdateChecker::check()
QInstaller::BinaryContent::readBinaryContent(&binary, &operations, &manager, &magicMarker,
cookie);
if (magicMarker != QInstaller::BinaryContent::MagicInstallerMarker)
if (magicMarker == QInstaller::BinaryContent::MagicInstallerMarker)
throw QInstaller::Error(QLatin1String("Installers cannot check for updates."));
SDKApp::registerMetaResources(manager.collectionByName("QResources"));

View File

@ -35,9 +35,10 @@
#ifndef QINSTALLER_REPOSITORYGEN_H
#define QINSTALLER_REPOSITORYGEN_H
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVector>
#include <QHash>
#include <QString>
#include <QStringList>
#include <QVector>
namespace QInstallerTools {