mirror of
https://github.com/QuasarApp/installer-framework.git
synced 2025-05-09 11:39:34 +00:00
Merge remote-tracking branch 'origin/3.1' into master
Change-Id: I65e3ed3858cda954a5f916031d4ff02a39a9aa87
This commit is contained in:
commit
3946e2f860
Changelog
dist
doc
installerfw.prisrc
libs
installer
componentselectionpage_p.cppcomponentselectionpage_p.hmetadatajob.cpppackagemanagercore.cpppackagemanagercore.hpackagemanagercore_p.cpppackagemanagercore_p.hpackagemanagergui.cpprepository.cpprepository.hsettings.cpp
kdtools
sdk
tests/auto/installer/compareversion
@ -1,3 +1,12 @@
|
||||
3.1.1
|
||||
- Add fetch to the same pane with package categories (QTIFW-1284)
|
||||
- Change text in Select Components view when selection of components is not possible (QTIFW-1241)
|
||||
- Fix long description texts not properly shown by enabling scrolling (QTIFW-1308)
|
||||
- Fix install button string having a font name in French translation (QTIFW-1333)
|
||||
- Fix maintenancetool size (QTIFW-1322)
|
||||
- Update Russian translation
|
||||
- Enable links and text selection in component description fields (QTIFW-1292)
|
||||
|
||||
3.1.0
|
||||
- Fix wizard's maximum size not to exceed screen maximum size (QTIFW-1227)
|
||||
- Allow maintenancetool signing in Windows (QTIFW-667)
|
||||
|
6
dist/config/config.xml
vendored
6
dist/config/config.xml
vendored
@ -1,13 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<Installer>
|
||||
<Name>Qt Installer Framework</Name>
|
||||
<Title>Qt Installer Framework 3.1.0</Title>
|
||||
<Version>3.1.0</Version>
|
||||
<Title>Qt Installer Framework 3.2.0</Title>
|
||||
<Version>3.2.0 </Version>
|
||||
<Publisher>Qt Project</Publisher>
|
||||
<ProductUrl>http://qt-project.org</ProductUrl>
|
||||
<Watermark>watermark.png</Watermark>
|
||||
<MaintenanceToolName>Uninstaller</MaintenanceToolName>
|
||||
|
||||
<!-- Tweaked for windows in installscript.qs -->
|
||||
<TargetDir>@HomeDir@/Qt/QtIFW-3.1.0</TargetDir>
|
||||
<TargetDir>@HomeDir@/Qt/QtIFW-3.2.0</TargetDir>
|
||||
</Installer>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<Package>
|
||||
<DisplayName>Qt Installer Framework Binaries</DisplayName>
|
||||
<Description>Installs the binaries, examples and help files.</Description>
|
||||
<Version>3.1.0</Version>
|
||||
<ReleaseDate>2019-01-06</ReleaseDate>
|
||||
<Version>3.2.0</Version>
|
||||
<ReleaseDate>2019-05-27</ReleaseDate>
|
||||
<Default>True</Default>
|
||||
</Package>
|
||||
|
@ -2,8 +2,8 @@
|
||||
<Package>
|
||||
<DisplayName>Qt Installer Framework</DisplayName>
|
||||
<Description>Installs the Qt Installer Framework.</Description>
|
||||
<Version>3.1.0</Version>
|
||||
<ReleaseDate>2019-01-06</ReleaseDate>
|
||||
<Version>3.2.0</Version>
|
||||
<ReleaseDate>2019-05-25</ReleaseDate>
|
||||
<Licenses>
|
||||
<License name="The Qt Company GPL Exception 1.0" file="LICENSE.GPL3-EXCEPT" />
|
||||
<License name="Third Party Code Licenses" file="3RDPARTY" />
|
||||
|
@ -585,7 +585,10 @@
|
||||
Translations may be specified similarly to DisplayName tag.
|
||||
If a localization that matches the locale is not found and an untranslated
|
||||
version exists, that one will be used. Otherwise no Description will be
|
||||
shown for that locale.
|
||||
shown for that locale. User clickable external links, for example a component's
|
||||
homepage, can be included in component description by specifying a URL
|
||||
address like this: {external-link}='https://www.qt.io/'. The URL must be valid
|
||||
and contain a full path to the desired resource.
|
||||
\row
|
||||
\li Version
|
||||
\li Version number of the component in the following format:
|
||||
|
@ -174,8 +174,8 @@
|
||||
|
||||
\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
|
||||
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
|
||||
|
@ -3,8 +3,8 @@
|
||||
}
|
||||
IFW_PRI_INCLUDED = 1
|
||||
|
||||
IFW_VERSION_STR = 3.1.0
|
||||
IFW_VERSION = 0x030100
|
||||
IFW_VERSION_STR = 3.2.0
|
||||
IFW_VERSION = 0x030200
|
||||
|
||||
IFW_REPOSITORY_FORMAT_VERSION = 1.0.0
|
||||
IFW_NEWLINE = $$escape_expand(\\n\\t)
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QLabel>
|
||||
#include <QScrollArea>
|
||||
#include <QPushButton>
|
||||
#include <QGroupBox>
|
||||
#include <QProgressBar>
|
||||
@ -69,17 +70,24 @@ ComponentSelectionPagePrivate::ComponentSelectionPagePrivate(ComponentSelectionP
|
||||
m_descriptionVLayout = new QVBoxLayout;
|
||||
m_descriptionVLayout->setObjectName(QLatin1String("DescriptionLayout"));
|
||||
|
||||
m_descriptionScrollArea = new QScrollArea(q);
|
||||
m_descriptionScrollArea->setWidgetResizable(true);
|
||||
m_descriptionScrollArea->setFrameShape(QFrame::NoFrame);
|
||||
m_descriptionScrollArea->setObjectName(QLatin1String("DescriptionScrollArea"));
|
||||
|
||||
m_descriptionLabel = new QLabel(q);
|
||||
m_descriptionLabel->setWordWrap(true);
|
||||
m_descriptionLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
m_descriptionLabel->setOpenExternalLinks(true);
|
||||
m_descriptionLabel->setObjectName(QLatin1String("ComponentDescriptionLabel"));
|
||||
m_descriptionVLayout->addWidget(m_descriptionLabel);
|
||||
m_descriptionLabel->setAlignment(Qt::AlignTop);
|
||||
m_descriptionScrollArea->setWidget(m_descriptionLabel);
|
||||
m_descriptionVLayout->addWidget(m_descriptionScrollArea);
|
||||
|
||||
m_sizeLabel = new QLabel(q);
|
||||
m_sizeLabel->setWordWrap(true);
|
||||
m_sizeLabel->setObjectName(QLatin1String("ComponentSizeLabel"));
|
||||
m_descriptionVLayout->addWidget(m_sizeLabel);
|
||||
m_descriptionVLayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
|
||||
QSizePolicy::MinimumExpanding));
|
||||
|
||||
m_treeViewVLayout = new QVBoxLayout;
|
||||
m_treeViewVLayout->setObjectName(QLatin1String("TreeviewLayout"));
|
||||
@ -193,7 +201,7 @@ void ComponentSelectionPagePrivate::setupCategoryLayout()
|
||||
m_categoryGroupBox->setTitle(m_core->settings().repositoryCategoryDisplayName());
|
||||
m_categoryGroupBox->setObjectName(QLatin1String("CategoryGroupBox"));
|
||||
QVBoxLayout *categoryLayout = new QVBoxLayout(m_categoryGroupBox);
|
||||
QPushButton *fetchCategoryButton = new QPushButton(tr("Refresh"));
|
||||
QPushButton *fetchCategoryButton = new QPushButton(tr("Filter"));
|
||||
fetchCategoryButton->setObjectName(QLatin1String("FetchCategoryButton"));
|
||||
connect(fetchCategoryButton, &QPushButton::clicked, this,
|
||||
&ComponentSelectionPagePrivate::fetchRepositoryCategories);
|
||||
@ -208,9 +216,9 @@ void ComponentSelectionPagePrivate::setupCategoryLayout()
|
||||
checkBox->setToolTip(repository.tooltip());
|
||||
categoryLayout->addWidget(checkBox);
|
||||
}
|
||||
categoryLayout->addWidget(fetchCategoryButton);
|
||||
|
||||
vLayout->addWidget(m_categoryGroupBox);
|
||||
vLayout->addWidget(fetchCategoryButton);
|
||||
vLayout->addStretch();
|
||||
m_mainHLayout->insertWidget(0, m_categoryWidget);
|
||||
}
|
||||
@ -290,8 +298,15 @@ void ComponentSelectionPagePrivate::currentSelectedChanged(const QModelIndex &cu
|
||||
return;
|
||||
|
||||
m_sizeLabel->setText(QString());
|
||||
m_descriptionLabel->setText(m_currentModel->data(m_currentModel->index(current.row(),
|
||||
ComponentModelHelper::NameColumn, current.parent()), Qt::ToolTipRole).toString());
|
||||
|
||||
QString description = m_currentModel->data(m_currentModel->index(current.row(),
|
||||
ComponentModelHelper::NameColumn, current.parent()), Qt::ToolTipRole).toString();
|
||||
|
||||
// replace {external-link}='' fields in component description with proper link tags
|
||||
description.replace(QRegularExpression(QLatin1String("{external-link}='(.*?)'")),
|
||||
QLatin1String("<a href=\"\\1\"><span style=\"color:#17a81a;\">\\1</span></a>"));
|
||||
|
||||
m_descriptionLabel->setText(description);
|
||||
|
||||
Component *component = m_currentModel->componentFromIndex(current);
|
||||
if ((m_core->isUninstaller()) || (!component))
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
class QTreeView;
|
||||
class QLabel;
|
||||
class QScrollArea;
|
||||
class QPushButton;
|
||||
class QGroupBox;
|
||||
class QListWidgetItem;
|
||||
@ -87,6 +88,7 @@ private:
|
||||
PackageManagerCore *m_core;
|
||||
QTreeView *m_treeView;
|
||||
QLabel *m_sizeLabel;
|
||||
QScrollArea *m_descriptionScrollArea;
|
||||
QLabel *m_descriptionLabel;
|
||||
QVBoxLayout *m_descriptionVLayout;
|
||||
QPushButton *m_checkAll;
|
||||
|
@ -619,13 +619,25 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
|
||||
}
|
||||
}
|
||||
}
|
||||
if (metadata.repository.archivename().isEmpty()) {
|
||||
if (metadata.repository.categoryname().isEmpty()) {
|
||||
m_metaFromDefaultRepositories.insert(metadata.directory, metadata);
|
||||
} else {
|
||||
//Hash metadata to help checking if meta for repository is already fetched
|
||||
ArchiveMetadata archiveMetadata;
|
||||
archiveMetadata.metaData = metadata;
|
||||
m_fetchedArchive.insertMulti(metadata.repository.archivename(), archiveMetadata);
|
||||
m_fetchedArchive.insertMulti(metadata.repository.categoryname(), archiveMetadata);
|
||||
|
||||
//Check if other categories have the same url (contains same metadata)
|
||||
//so we can speed up other category fetches
|
||||
foreach (RepositoryCategory category, m_core->settings().repositoryCategories()) {
|
||||
if (category.displayname() != metadata.repository.categoryname()) {
|
||||
foreach (Repository repository, category.repositories()) {
|
||||
if (repository.url() == metadata.repository.url()) {
|
||||
m_fetchedArchive.insertMulti(category.displayname(), archiveMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Hash for faster lookups
|
||||
m_metaFromArchive.insert(metadata.directory, metadata);
|
||||
}
|
||||
@ -732,11 +744,20 @@ QSet<Repository> MetadataJob::getRepositories()
|
||||
// If repository is already fetched, do not fetch it again.
|
||||
// In updater mode, fetch always all archive repositories to get updates
|
||||
foreach (RepositoryCategory repositoryCategory, m_core->settings().repositoryCategories()) {
|
||||
if (m_core->isUpdater() || (repositoryCategory.isEnabled() && !m_fetchedArchive.contains(repositoryCategory.displayname()))) {
|
||||
foreach (Repository repository, repositoryCategory.repositories()) {
|
||||
repositories.insert(repository);
|
||||
if (m_core->isUpdater() || (repositoryCategory.isEnabled())) {
|
||||
foreach (Repository repository, repositoryCategory.repositories()) {
|
||||
QHashIterator<QString, ArchiveMetadata> i(m_fetchedArchive);
|
||||
bool fetch = true;
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
ArchiveMetadata metaData = i.value();
|
||||
if (repository.url() == metaData.metaData.repository.url())
|
||||
fetch = false;
|
||||
}
|
||||
if (fetch)
|
||||
repositories.insert(repository);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return repositories;
|
||||
}
|
||||
|
@ -664,6 +664,22 @@ int PackageManagerCore::downloadNeededArchives(double partProgressSize)
|
||||
return archivesJob.numberOfDownloads();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c true if essential component update is found.
|
||||
*/
|
||||
bool PackageManagerCore::foundEssentialUpdate() const
|
||||
{
|
||||
return d->m_foundEssentialUpdate;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the value of \a foundEssentialUpdate, defaults \c true.
|
||||
*/
|
||||
void PackageManagerCore::setFoundEssentialUpdate(bool foundEssentialUpdate)
|
||||
{
|
||||
d->m_foundEssentialUpdate = foundEssentialUpdate;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c true if a hard restart of the application is requested.
|
||||
*/
|
||||
@ -2733,7 +2749,7 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
|
||||
data.components = &components;
|
||||
data.installedPackages = &locals;
|
||||
|
||||
bool foundEssentialUpdate = false;
|
||||
setFoundEssentialUpdate(false);
|
||||
LocalPackagesHash installedPackages = locals;
|
||||
QStringList replaceMes;
|
||||
|
||||
@ -2789,7 +2805,7 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
|
||||
continue;
|
||||
|
||||
if (update->data(scEssential, scFalse).toString().toLower() == scTrue)
|
||||
foundEssentialUpdate = true;
|
||||
setFoundEssentialUpdate(true);
|
||||
|
||||
// this is not a dependency, it is a real update
|
||||
components.insert(name, d->m_updaterComponentsDeps.takeLast());
|
||||
@ -2840,7 +2856,7 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
|
||||
}
|
||||
}
|
||||
|
||||
if (foundEssentialUpdate) {
|
||||
if (foundEssentialUpdate()) {
|
||||
foreach (QInstaller::Component *component, components) {
|
||||
if (d->statusCanceledOrFailed())
|
||||
return false;
|
||||
|
@ -266,6 +266,9 @@ public:
|
||||
|
||||
int downloadNeededArchives(double partProgressSize);
|
||||
|
||||
bool foundEssentialUpdate() const;
|
||||
void setFoundEssentialUpdate(bool foundEssentialUpdate = true);
|
||||
|
||||
bool needsHardRestart() const;
|
||||
void setNeedsHardRestart(bool needsHardRestart = true);
|
||||
bool finishedWithSuccess() const;
|
||||
|
@ -1336,7 +1336,11 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
|
||||
newBinaryWritten = true;
|
||||
QFile tmp(binaryName);
|
||||
QInstaller::openForRead(&tmp);
|
||||
#ifdef Q_OS_OSX
|
||||
writeMaintenanceToolBinary(&tmp, tmp.size(), true);
|
||||
#else
|
||||
writeMaintenanceToolBinary(&tmp, layout.endOfBinaryContent - layout.binaryContentSize, true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,6 +247,7 @@ private:
|
||||
bool m_updateSourcesAdded;
|
||||
qint64 m_magicBinaryMarker;
|
||||
bool m_componentsToInstallCalculated;
|
||||
bool m_foundEssentialUpdate;
|
||||
|
||||
mutable ScriptEngine *m_componentScriptEngine;
|
||||
mutable ScriptEngine *m_controlScriptEngine;
|
||||
|
@ -1898,7 +1898,8 @@ void ComponentSelectionPage::entering()
|
||||
QT_TR_NOOP("Please select the components you want to update."),
|
||||
QT_TR_NOOP("Please select the components you want to install."),
|
||||
QT_TR_NOOP("Please select the components you want to uninstall."),
|
||||
QT_TR_NOOP("Select the components to install. Deselect installed components to uninstall them. Any components already installed will not be updated.")
|
||||
QT_TR_NOOP("Select the components to install. Deselect installed components to uninstall them. Any components already installed will not be updated."),
|
||||
QT_TR_NOOP("Mandatory components need to be updated first before you can select other components to update.")
|
||||
};
|
||||
|
||||
int index = 0;
|
||||
@ -1906,6 +1907,7 @@ void ComponentSelectionPage::entering()
|
||||
if (core->isInstaller()) index = 1;
|
||||
if (core->isUninstaller()) index = 2;
|
||||
if (core->isPackageManager()) index = 3;
|
||||
if (core->foundEssentialUpdate() && core->isUpdater()) index = 4;
|
||||
setColoredSubTitle(tr(strings[index]));
|
||||
|
||||
d->updateTreeView();
|
||||
|
@ -57,7 +57,7 @@ Repository::Repository(const Repository &other)
|
||||
, m_password(other.m_password)
|
||||
, m_displayname(other.m_displayname)
|
||||
, m_compressed(other.m_compressed)
|
||||
, m_archivename(other.m_archivename)
|
||||
, m_categoryname(other.m_categoryname)
|
||||
{
|
||||
registerMetaType();
|
||||
}
|
||||
@ -202,17 +202,17 @@ void Repository::setDisplayName(const QString &displayname)
|
||||
/*!
|
||||
Returns the archive name if the repository belongs to an archive.
|
||||
*/
|
||||
QString Repository::archivename() const
|
||||
QString Repository::categoryname() const
|
||||
{
|
||||
return m_archivename;
|
||||
return m_categoryname;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the archive name to \a archivename if the repository belongs to an archive.
|
||||
Sets the category name to \a categoryname if the repository belongs to an category.
|
||||
*/
|
||||
void Repository::setArchiveName(const QString &archivename)
|
||||
void Repository::setCategoryName(const QString &categoryname)
|
||||
{
|
||||
m_archivename = archivename;
|
||||
m_categoryname = categoryname;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -265,7 +265,7 @@ const Repository &Repository::operator=(const Repository &other)
|
||||
m_password = other.m_password;
|
||||
m_displayname = other.m_displayname;
|
||||
m_compressed = other.m_compressed;
|
||||
m_archivename = other.m_archivename;
|
||||
m_categoryname = other.m_categoryname;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -280,7 +280,7 @@ QDataStream &operator>>(QDataStream &istream, Repository &repository)
|
||||
{
|
||||
QByteArray url, username, password, displayname, compressed;
|
||||
istream >> url >> repository.m_default >> repository.m_enabled >> username >> password
|
||||
>> displayname >> repository.m_archivename;
|
||||
>> displayname >> repository.m_categoryname;
|
||||
repository.setUrl(QUrl::fromEncoded(QByteArray::fromBase64(url)));
|
||||
repository.setUsername(QString::fromUtf8(QByteArray::fromBase64(username)));
|
||||
repository.setPassword(QString::fromUtf8(QByteArray::fromBase64(password)));
|
||||
@ -292,7 +292,7 @@ QDataStream &operator<<(QDataStream &ostream, const Repository &repository)
|
||||
{
|
||||
return ostream << repository.m_url.toEncoded().toBase64() << repository.m_default << repository.m_enabled
|
||||
<< repository.m_username.toUtf8().toBase64() << repository.m_password.toUtf8().toBase64()
|
||||
<< repository.m_displayname.toUtf8().toBase64() << repository.m_archivename.toUtf8().toBase64();
|
||||
<< repository.m_displayname.toUtf8().toBase64() << repository.m_categoryname.toUtf8().toBase64();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -64,8 +64,8 @@ public:
|
||||
QString displayname() const;
|
||||
void setDisplayName(const QString &displayname);
|
||||
|
||||
QString archivename() const;
|
||||
void setArchiveName(const QString &archivename);
|
||||
QString categoryname() const;
|
||||
void setCategoryName(const QString &categoryname);
|
||||
|
||||
bool isCompressed() const;
|
||||
void setCompressed(bool compressed);
|
||||
@ -85,7 +85,7 @@ private:
|
||||
QString m_username;
|
||||
QString m_password;
|
||||
QString m_displayname;
|
||||
QString m_archivename;
|
||||
QString m_categoryname;
|
||||
bool m_compressed;
|
||||
};
|
||||
|
||||
|
@ -168,7 +168,7 @@ static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefaul
|
||||
}
|
||||
}
|
||||
if (displayName && !displayName->isEmpty())
|
||||
repo.setArchiveName(*displayName);
|
||||
repo.setCategoryName(*displayName);
|
||||
set.insert(repo);
|
||||
} else if (reader.name() == QLatin1String("Tooltip")) {
|
||||
*tooltip = reader.readElementText();
|
||||
@ -832,7 +832,7 @@ void Settings::setSaveDefaultRepositories(bool save)
|
||||
QString Settings::repositoryCategoryDisplayName() const
|
||||
{
|
||||
QString displayName = d->m_data.value(QLatin1String(scRepositoryCategoryDisplayName)).toString();
|
||||
return displayName.isEmpty() ? tr("Show package categories") : displayName;
|
||||
return displayName.isEmpty() ? tr("Select Package Categories") : displayName;
|
||||
}
|
||||
|
||||
void Settings::setRepositoryCategoryDisplayName(const QString& name)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Installer Framework.
|
||||
@ -601,18 +601,18 @@ int KDUpdater::compareVersion(const QString &v1, const QString &v2)
|
||||
bool v2_ok = false;
|
||||
|
||||
if (index == v1_comps.count() && index < v2_comps.count()) {
|
||||
v2_comps.at(index).toInt(&v2_ok);
|
||||
v2_comps.at(index).toLongLong(&v2_ok);
|
||||
return v2_ok ? -1 : +1;
|
||||
}
|
||||
if (index < v1_comps.count() && index == v2_comps.count()) {
|
||||
v1_comps.at(index).toInt(&v1_ok);
|
||||
v1_comps.at(index).toLongLong(&v1_ok);
|
||||
return v1_ok ? +1 : -1;
|
||||
}
|
||||
if (index >= v1_comps.count() || index >= v2_comps.count())
|
||||
break;
|
||||
|
||||
int v1_comp = v1_comps.at(index).toInt(&v1_ok);
|
||||
int v2_comp = v2_comps.at(index).toInt(&v2_ok);
|
||||
qlonglong v1_comp = v1_comps.at(index).toLongLong(&v1_ok);
|
||||
qlonglong v2_comp = v2_comps.at(index).toLongLong(&v2_ok);
|
||||
|
||||
if (!v1_ok) {
|
||||
if (v1_comps.at(index) == QLatin1String("x"))
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Installer Framework.
|
||||
@ -44,6 +44,7 @@ public:
|
||||
|
||||
private:
|
||||
bool parentConsole;
|
||||
bool newConsoleCreated;
|
||||
|
||||
std::ofstream m_newCout;
|
||||
std::ofstream m_newCerr;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Installer Framework.
|
||||
@ -74,7 +74,9 @@ static bool isRedirected(HANDLE stdHandle)
|
||||
*/
|
||||
Console::Console() :
|
||||
m_oldCout(nullptr),
|
||||
m_oldCerr(nullptr)
|
||||
m_oldCerr(nullptr),
|
||||
parentConsole(false),
|
||||
newConsoleCreated(false)
|
||||
{
|
||||
bool isCoutRedirected = isRedirected(GetStdHandle(STD_OUTPUT_HANDLE));
|
||||
bool isCerrRedirected = isRedirected(GetStdHandle(STD_ERROR_HANDLE));
|
||||
@ -83,6 +85,7 @@ Console::Console() :
|
||||
// try to use parent console. else launch & set up new console
|
||||
parentConsole = AttachConsole(ATTACH_PARENT_PROCESS);
|
||||
if (!parentConsole) {
|
||||
newConsoleCreated = true;
|
||||
AllocConsole();
|
||||
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
@ -119,11 +122,11 @@ Console::Console() :
|
||||
|
||||
Console::~Console()
|
||||
{
|
||||
if (!parentConsole) {
|
||||
system("PAUSE");
|
||||
} else {
|
||||
if (parentConsole) {
|
||||
// simulate enter key to switch to boot prompt
|
||||
PostMessage(GetConsoleWindow(), WM_KEYDOWN, 0x0D, 0);
|
||||
} else if (newConsoleCreated) {
|
||||
system("PAUSE");
|
||||
}
|
||||
|
||||
if (m_oldCerr)
|
||||
|
@ -1835,7 +1835,7 @@ Copiez le programme d’installation sur un disque local</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Install</source>
|
||||
<translation>{&Tahoma8}&Installer</translation>
|
||||
<translation>&Installer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Installing %1</source>
|
||||
@ -1901,7 +1901,7 @@ Copiez le programme d’installation sur un disque local</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Install</source>
|
||||
<translation>{&Tahoma8}&Installer</translation>
|
||||
<translation>&Installer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Ready to Install</source>
|
||||
|
@ -689,14 +689,6 @@
|
||||
<source>Cannot open temporary file for template %1: %2</source>
|
||||
<translation>Не удалось открыть временный файл для шаблона %1: %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Corrupt installation</source>
|
||||
<translation>Установка повреждена</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Your installation seems to be corrupted. Please consider re-installing from scratch.</source>
|
||||
<translation>Видимо, установленное приложение повреждено. Попробуйте его заново переустановить.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No marker found, stopped after %1.</source>
|
||||
<translation>Маркер не найден, остановлено после %1.</translation>
|
||||
@ -764,9 +756,17 @@
|
||||
<source>Cannot resolve isDefault in %1</source>
|
||||
<translation>Невозможно выполнить метод isDefault в сценарии %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error loading the selected component. This component can not be installed.</source>
|
||||
<translation>Возникла ошибка при загрузке выбранного компонента. Установить его не получится.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Update Info: </source>
|
||||
<translation>Информация об обновлении:</translation>
|
||||
<translation>Информация об обновлении: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error loading the selected component. This component can not be updated.</source>
|
||||
<translation>Возникла ошибка при загрузке выбранного компонента. Обновить его не получится.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot open the requested UI file "%1": %2</source>
|
||||
@ -898,15 +898,22 @@
|
||||
<source>Select the components to install. Deselect installed components to uninstall them. Any components already installed will not be updated.</source>
|
||||
<translation>Выберите компоненты для установки. Для удаления уже установленных компонентов снимите отметки выбора. Уже установленные компоненты не будут обновлены.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>To install new compressed repository, browse the repositories from your computer</source>
|
||||
<translation>Для установки нового хранилища укажите путь к нему на вашем компьютере</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open File</source>
|
||||
<translation>Открытие файла</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QInstaller::ComponentSelectionPagePrivate</name>
|
||||
<message>
|
||||
<source>Filter</source>
|
||||
<translation>Отфильтровать</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error</source>
|
||||
<translation>Ошибка</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QInstaller::ConsumeOutputOperation</name>
|
||||
<message>
|
||||
@ -1150,10 +1157,6 @@ Error while loading %2</source>
|
||||
<source>Redirect loop detected for "%1".</source>
|
||||
<translation>Обнаружено кольцо перенаправлений «%1».</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Checksum mismatch detected for "%1".</source>
|
||||
<translation>Обнаружено несовпадение контрольной суммы «%1».</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Network error while downloading '%1': %2.</source>
|
||||
<translation>Возникла ошибка сети при загрузке «%1»: %2.</translation>
|
||||
@ -1192,6 +1195,13 @@ Error while loading %2</source>
|
||||
<translation>Не удалось исполнить (неожиданный код завершения: %1): «%2»</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QInstaller::ExtractArchiveOperation</name>
|
||||
<message>
|
||||
<source>Extracting "%1"</source>
|
||||
<translation>Извлечение «%1»</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QInstaller::ExtractArchiveOperation::Runnable</name>
|
||||
<message>
|
||||
@ -1349,16 +1359,16 @@ Error while loading %2</source>
|
||||
<translation>Добро пожаловать в мастер установки %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Add or remove components</source>
|
||||
<translation>Добавление или удаление компонентов</translation>
|
||||
<source>&Add or remove components</source>
|
||||
<translation>&Добавление или удаление компонентов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Update components</source>
|
||||
<translation>Обновление компонентов</translation>
|
||||
<source>&Update components</source>
|
||||
<translation>&Обновление компонентов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove all components</source>
|
||||
<translation>Удаление всех компонентов</translation>
|
||||
<source>&Remove all components</source>
|
||||
<translation>&Удаление всех компонентов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Retrieving information from remote installation sources...</source>
|
||||
@ -1377,8 +1387,8 @@ Error while loading %2</source>
|
||||
<translation> Доступно только локальное управление пакетами.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Quit</source>
|
||||
<translation>Выйти</translation>
|
||||
<source>&Quit</source>
|
||||
<translation>&Выйти</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -1483,8 +1493,16 @@ Error while loading %2</source>
|
||||
<translation>Возникло неизвестное исключение во время загрузки.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Retrieving meta information from remote repository...</source>
|
||||
<translation>Получение метаданных из внешнего хранилища...</translation>
|
||||
<source>Checksum mismatch detected for "%1".</source>
|
||||
<translation>Обнаружено несовпадение контрольной суммы у «%1».</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Retrieving meta information from remote repository... %1/%2 </source>
|
||||
<translation>Получение метаданных из внешнего хранилища... %1/%2 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Retrieving meta information from remote repository... </source>
|
||||
<translation>Получение метаданных из внешнего хранилища... </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failure to fetch repositories.</source>
|
||||
@ -1636,7 +1654,7 @@ Downloading packages...</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creating local repository</source>
|
||||
<translation>Создаётся локальный репозиторий</translation>
|
||||
<translation>Создаётся локальное хранилище</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>
|
||||
@ -1721,6 +1739,10 @@ Installing component %1...</source>
|
||||
%2</source>
|
||||
<translation>Ошибка во время процесса установки (%1): %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Done</source>
|
||||
<translation>Готово</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot prepare uninstall</source>
|
||||
<translation>Невозможно подготовиться к удалению</translation>
|
||||
@ -1963,10 +1985,6 @@ Please copy the installer to a local drive</source>
|
||||
<source>Register File Type: Invalid arguments</source>
|
||||
<translation>Регистрация типов файлов: недопустимые параметры</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><extension> <command> [description [contentType [icon]]]</source>
|
||||
<translation><расширение> <команда> [описание [типСодержимого [значок]]]</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QInstaller::RemoteObject</name>
|
||||
@ -2022,6 +2040,10 @@ Please copy the installer to a local drive</source>
|
||||
<source>Unknown error.</source>
|
||||
<translation>Неизвестная ошибка.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>on line number: </source>
|
||||
<translation>в строке: </translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QInstaller::SelfRestartOperation</name>
|
||||
@ -2283,6 +2305,10 @@ as a user with the appropriate rights and then clicking OK.</source>
|
||||
<source>Cannot open settings file %1 for reading: %2</source>
|
||||
<translation>Невозможно открыть файл настроек %1 на чтение: %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select Package Categories</source>
|
||||
<translation>Выберите категории пакетов</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SettingsDialog</name>
|
||||
@ -2320,7 +2346,7 @@ as a user with the appropriate rights and then clicking OK.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Repositories</source>
|
||||
<translation>Репозитории</translation>
|
||||
<translation>Хранилища</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Add Username and Password for authentication if needed.</source>
|
||||
@ -2328,7 +2354,7 @@ as a user with the appropriate rights and then clicking OK.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use temporary repositories only</source>
|
||||
<translation>использовать только временные репозитории</translation>
|
||||
<translation>использовать только временные хранилища</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Add</source>
|
||||
@ -2340,15 +2366,15 @@ as a user with the appropriate rights and then clicking OK.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Test</source>
|
||||
<translation>Тестировать</translation>
|
||||
<translation>Проверить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show Passwords</source>
|
||||
<translation>Показывать пароль</translation>
|
||||
<translation>Показать пароли</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Check this to use repository during fetch.</source>
|
||||
<translation>Поставьте флажок, чтобы использовать репозиторий в процессе получения.</translation>
|
||||
<translation>Поставьте флажок, чтобы использовать хранилище в процессе получения.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Add the username to authenticate on the server.</source>
|
||||
@ -2360,7 +2386,7 @@ as a user with the appropriate rights and then clicking OK.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>The servers URL that contains a valid repository.</source>
|
||||
<translation>Адреса серверов, которые содержат рабочие репозиторий.</translation>
|
||||
<translation>Адреса серверов, которые содержат рабочие хранилища.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hide Passwords</source>
|
||||
@ -2380,19 +2406,19 @@ as a user with the appropriate rights and then clicking OK.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Repository</source>
|
||||
<translation>Репозиторий</translation>
|
||||
<translation>Хранилище</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Default repositories</source>
|
||||
<translation>Репозитории по умолчанию</translation>
|
||||
<translation>Хранилища по умолчанию</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Temporary repositories</source>
|
||||
<translation>Временные репозитории</translation>
|
||||
<translation>Временные хранилища</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>User defined repositories</source>
|
||||
<translation>Использовать назначенные репозитории</translation>
|
||||
<translation>Использовать назначенные хранилища</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error occurred while testing this repository.</source>
|
||||
@ -2410,6 +2436,14 @@ as a user with the appropriate rights and then clicking OK.</source>
|
||||
<source>Do you want to enable the repository?</source>
|
||||
<translation>Желаете включить хранилище?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select All</source>
|
||||
<translation>Выбрать всё</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Deselect All</source>
|
||||
<translation>Снять выбор</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>UpdateOperation</name>
|
||||
|
@ -21,12 +21,13 @@ for(file, IB_ALL_TRANSLATIONS) {
|
||||
ts-all.commands = cd $$wd && $$LUPDATE $$lupdate_opts $$sources -ts $$IB_ALL_TRANSLATIONS
|
||||
QMAKE_EXTRA_TARGETS += ts-all
|
||||
|
||||
lconvert_options = -sort-contexts -locations none -i
|
||||
isEqual(QMAKE_DIR_SEP, /) {
|
||||
commit-ts.commands = \
|
||||
cd $$wd; \
|
||||
git add -N src/sdk/translations/*_??.ts && \
|
||||
for f in `git diff-files --name-only src/sdk/translations/*_??.ts`; do \
|
||||
$$LCONVERT -locations none -i \$\$f -o \$\$f; \
|
||||
$$LCONVERT $$lconvert_options \$\$f -o \$\$f; \
|
||||
done; \
|
||||
git add src/sdk/translations/*_??.ts && git commit
|
||||
} else {
|
||||
@ -34,7 +35,7 @@ isEqual(QMAKE_DIR_SEP, /) {
|
||||
cd $$wd && \
|
||||
git add -N src/sdk/translations/*_??.ts && \
|
||||
for /f usebackq %%f in (`git diff-files --name-only src/sdk/translations/*_??.ts`) do \
|
||||
$$LCONVERT -locations none -i %%f -o %%f $$escape_expand(\\n\\t) \
|
||||
$$LCONVERT $$lconvert_options %%f -o %%f $$escape_expand(\\n\\t) \
|
||||
cd $$wd && git add src/sdk/translations/*_??.ts && git commit
|
||||
}
|
||||
QMAKE_EXTRA_TARGETS += commit-ts
|
||||
|
@ -47,7 +47,11 @@ void tst_CompareVersion::compareVersion()
|
||||
QCOMPARE(KDUpdater::compareVersion("2.1", "2.0"), +1);
|
||||
QCOMPARE(KDUpdater::compareVersion("2.0", "2.0"), 0);
|
||||
QCOMPARE(KDUpdater::compareVersion("2.1", "2.1"), 0);
|
||||
|
||||
QCOMPARE(KDUpdater::compareVersion("2.1", "2.1-201903190747"), -1);
|
||||
QCOMPARE(KDUpdater::compareVersion("2.1-201903190747", "2.1"), +1);
|
||||
QCOMPARE(KDUpdater::compareVersion("2.1-201903190747", "2.1-201903190747"), 0);
|
||||
QCOMPARE(KDUpdater::compareVersion("2.1-0", "2.1-201903190747"), -1);
|
||||
QCOMPARE(KDUpdater::compareVersion("2.1-201903190747", "2.1-0"), +1);
|
||||
QCOMPARE(KDUpdater::compareVersion("2.0.12.4", "2.1.10.4"), -1);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user