mirror of
https://github.com/QuasarApp/installer-framework.git
synced 2025-04-28 06:24:32 +00:00
Merge remote-tracking branch 'origin/2.0'
Conflicts: Changelog Change-Id: Idd7d569f97fba75b05bfc006c7a5b0b9cf8ccf73
This commit is contained in:
commit
ffed7d2b6d
10
Changelog
10
Changelog
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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]]
|
||||
|
@ -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 = "")
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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 \
|
||||
|
@ -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)
|
||||
|
74
src/libs/installer/localsocket.h
Normal file
74
src/libs/installer/localsocket.h
Normal 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
|
@ -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*>());
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "repository.h"
|
||||
#include "kdupdaterfiledownloaderfactory.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QFileInfo>
|
||||
#include <QStringList>
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include "kdupdaterapplication.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
@ -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"));
|
||||
|
@ -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 {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user