summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2021-10-26 08:50:07 +0300
committerKatja Marttila <katja.marttila@qt.io>2022-03-21 17:08:39 +0200
commit6ec6ac70d98195bb41a5ed60e47984bc640066fc (patch)
tree28e937e933a18479a9d114aa989d20d5083f7aaa /src
parenta47cad8ed9e7e0c5ecd4a67c9603332d72228a7c (diff)
Add click option for product image
Product image can now be clicked. It opens either url in Web browser or if file reference is given, then it will be opened with the suitable application. Task-number: QTIFW-2361 Change-Id: I59ed1355e90c23c8d0a5124779725825ca1ee2c8 Reviewed-by: Arttu Tarkiainen <arttu.tarkiainen@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/libs/ifwtools/binarycreator.cpp31
-rw-r--r--src/libs/installer/aspectratiolabel.cpp39
-rw-r--r--src/libs/installer/aspectratiolabel.h8
-rw-r--r--src/libs/installer/packagemanagergui.cpp21
-rw-r--r--src/libs/installer/performinstallationform.cpp29
-rw-r--r--src/libs/installer/performinstallationform.h6
-rw-r--r--src/libs/installer/settings.cpp41
-rw-r--r--src/libs/installer/settings.h4
8 files changed, 133 insertions, 46 deletions
diff --git a/src/libs/ifwtools/binarycreator.cpp b/src/libs/ifwtools/binarycreator.cpp
index 95ff93393..7ea652250 100644
--- a/src/libs/ifwtools/binarycreator.cpp
+++ b/src/libs/ifwtools/binarycreator.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -609,17 +609,28 @@ void QInstallerTools::copyConfigData(const QString &configFile, const QString &t
qDebug().noquote() << QString::fromLatin1("Read dom element: <%1>%2</%1>.").arg(tagName, elementText);
if (tagName == QLatin1String("ProductImages")) {
- const QDomNodeList childNodes = domElement.childNodes();
- for (int index = 0; index < childNodes.count(); ++index) {
- const QDomElement childElement = childNodes.at(index).toElement();
- const QString childName = childElement.tagName();
- if (childName != QLatin1String("Image"))
+ const QDomNodeList productImageNode = domElement.childNodes();
+ for (int j = 0; j < productImageNode.count(); ++j) {
+ QDomElement productImagesElement = productImageNode.at(j).toElement();
+ if (productImagesElement.isNull())
continue;
+ const QString childName = productImagesElement.tagName();
+ if (childName != QLatin1String("ProductImage"))
+ continue;
+ const QDomNodeList imageNode = productImagesElement.childNodes();
+ for (int k = 0; k < imageNode.count(); ++k) {
+ QDomElement productImageElement = imageNode.at(k).toElement();
+ if (productImageElement.isNull())
+ continue;
+ const QString imageChildName = productImageElement.tagName();
+ if (imageChildName != QLatin1String("Image"))
+ continue;
+ const QString targetFile = targetDir + QLatin1Char('/') + productImageElement.text();
+ const QFileInfo childFileInfo = QFileInfo(sourceConfigFilePath, productImageElement.text());
+ QInstallerTools::copyWithException(childFileInfo.absoluteFilePath(), targetFile, imageChildName);
+ copyHighDPIImage(childFileInfo, imageChildName, targetFile);
+ }
- const QString targetFile = targetDir + QLatin1Char('/') + childElement.text();
- const QFileInfo childFileInfo = QFileInfo(sourceConfigFilePath, childElement.text());
- QInstallerTools::copyWithException(childFileInfo.absoluteFilePath(), targetFile, childName);
- copyHighDPIImage(childFileInfo, childName, targetFile);
}
continue;
}
diff --git a/src/libs/installer/aspectratiolabel.cpp b/src/libs/installer/aspectratiolabel.cpp
index c8c3c1693..b2cf2f7e8 100644
--- a/src/libs/installer/aspectratiolabel.cpp
+++ b/src/libs/installer/aspectratiolabel.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -28,6 +28,9 @@
#include "aspectratiolabel.h"
+#include <QDesktopServices>
+#include <QTimer>
+
using namespace QInstaller;
/*!
@@ -42,16 +45,21 @@ using namespace QInstaller;
*/
AspectRatioLabel::AspectRatioLabel(QWidget *parent)
: QLabel(parent)
+ , m_discardMousePress(false)
{
setMinimumSize(1, 1);
setScaledContents(false);
}
/*!
- Sets the \a pixmap shown on the label. Setting a new pixmap clears the previous content.
+ Sets the \a pixmap shown on the label and an optional \a url. Setting a new
+ pixmap clears the previous content. When clicking the \a pixmap, \a url
+ is opened in a browser. If the \a url is a reference to a file, it will
+ be opened with a suitable application instead of a Web browser.
*/
-void AspectRatioLabel::setPixmap(const QPixmap &pixmap)
+void AspectRatioLabel::setPixmapAndUrl(const QPixmap &pixmap, const QString &url)
{
+ m_clickableUrl = url;
m_pixmap = pixmap;
QLabel::setPixmap(scaledPixmap());
}
@@ -98,3 +106,28 @@ void AspectRatioLabel::resizeEvent(QResizeEvent *event)
if (!m_pixmap.isNull())
QLabel::setPixmap(scaledPixmap());
}
+
+/*!
+ \reimp
+*/
+void AspectRatioLabel::mousePressEvent(QMouseEvent* event)
+{
+ Q_UNUSED(event)
+ if (!m_clickableUrl.isEmpty() && !m_discardMousePress)
+ QDesktopServices::openUrl(m_clickableUrl);
+}
+
+/*!
+ \reimp
+*/
+bool AspectRatioLabel::event(QEvent *e)
+{
+ if (e->type() == QEvent::WindowActivate) {
+ QTimer::singleShot(100, [&]() {
+ m_discardMousePress = false;
+ });
+ } else if (e->type() == QEvent::WindowDeactivate) {
+ m_discardMousePress = true;
+ }
+ return QLabel::event(e);
+}
diff --git a/src/libs/installer/aspectratiolabel.h b/src/libs/installer/aspectratiolabel.h
index 82ce0ebbd..5ce9593fa 100644
--- a/src/libs/installer/aspectratiolabel.h
+++ b/src/libs/installer/aspectratiolabel.h
@@ -48,14 +48,20 @@ public:
QSize sizeHint() const override;
public slots:
- void setPixmap (const QPixmap &pixmap);
+ void setPixmapAndUrl (const QPixmap &pixmap, const QString &url = QString());
void resizeEvent(QResizeEvent *event) override;
+protected:
+ void mousePressEvent(QMouseEvent* event) override;
+ bool event(QEvent *e) override;
+
private:
QPixmap scaledPixmap() const;
private:
QPixmap m_pixmap;
+ QString m_clickableUrl;
+ bool m_discardMousePress;
};
} // namespace QInstaller
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index fa46e4720..e49d45879 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -2698,7 +2698,7 @@ void ReadyForInstallationPage::updatePageListTitle()
*/
PerformInstallationPage::PerformInstallationPage(PackageManagerCore *core)
: PackageManagerPage(core)
- , m_performInstallationForm(new PerformInstallationForm(this))
+ , m_performInstallationForm(new PerformInstallationForm(core, this))
{
setPixmap(QWizard::WatermarkPixmap, QPixmap());
setObjectName(QLatin1String("PerformInstallationPage"));
@@ -2836,17 +2836,26 @@ void PerformInstallationPage::setTitleMessage(const QString &title)
*/
void PerformInstallationPage::changeCurrentImage()
{
- const QStringList productImages = packageManagerCore()->settings().productImages();
+ const QMap<QString, QVariant> productImages = packageManagerCore()->settings().productImages();
if (productImages.isEmpty())
return;
- const QString nextImage = (m_currentImage.isEmpty() || m_currentImage == productImages.last())
- ? productImages.first()
- : productImages.at(productImages.indexOf(m_currentImage) + 1);
+ QString nextImage;
+ QString nextUrl;
+ if (m_currentImage.isEmpty() || m_currentImage == productImages.lastKey()) {
+ nextImage = productImages.firstKey();
+ nextUrl = productImages.value(nextImage).toString();
+ } else {
+ QMap<QString, QVariant>::const_iterator i = productImages.constFind(m_currentImage);
+ if (++i != productImages.end()) {
+ nextImage = i.key();
+ nextUrl = i.value().toString();
+ }
+ }
// Do not update the pixmap if there was only one image available
if (nextImage != m_currentImage) {
- m_performInstallationForm->setImageFromFileName(nextImage);
+ m_performInstallationForm->setImageFromFileName(nextImage, nextUrl);
m_currentImage = nextImage;
}
}
diff --git a/src/libs/installer/performinstallationform.cpp b/src/libs/installer/performinstallationform.cpp
index 81790cbc2..e97767b04 100644
--- a/src/libs/installer/performinstallationform.cpp
+++ b/src/libs/installer/performinstallationform.cpp
@@ -31,6 +31,9 @@
#include "progresscoordinator.h"
#include "globals.h"
#include "aspectratiolabel.h"
+#include "packagemanagercore.h"
+#include "settings.h"
+#include "fileutils.h"
#include <QApplication>
#include <QLabel>
@@ -41,6 +44,7 @@
#include <QImageReader>
#include <QScrollArea>
#include <QTextEdit>
+#include <QFileInfo>
#include <QtCore/QTimer>
@@ -76,9 +80,10 @@ using namespace QInstaller;
*/
/*!
- Constructs the perform installation UI with \a parent as parent.
+ Constructs the perform installation UI with package manager specified by \a core and
+ with \a parent as parent.
*/
-PerformInstallationForm::PerformInstallationForm(QObject *parent)
+PerformInstallationForm::PerformInstallationForm(PackageManagerCore *core, QObject *parent)
: QObject(parent)
, m_progressBar(nullptr)
, m_progressLabel(nullptr)
@@ -88,6 +93,7 @@ PerformInstallationForm::PerformInstallationForm(QObject *parent)
, m_detailsButton(nullptr)
, m_detailsBrowser(nullptr)
, m_updateTimer(nullptr)
+ , m_core(core)
{
#ifdef Q_OS_WIN
if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
@@ -290,20 +296,27 @@ void PerformInstallationForm::onDownloadStatusChanged(const QString &status)
}
/*!
- Sets currently shown form image specified by \a fileName.
+ Sets currently shown form image specified by \a fileName. When clicking the image,
+ \a url is opened in a browser. If the \a url is a reference to a file, it will
+ be opened with a suitable application instead of a Web browser. \a url can be empty.
*/
-void PerformInstallationForm::setImageFromFileName(const QString &fileName)
+void PerformInstallationForm::setImageFromFileName(const QString &fileName, const QString &url)
{
- if (!QFile::exists(fileName)) {
+ QString imagePath = QFileInfo(fileName).isAbsolute()
+ ? fileName
+ : m_core->settings().value(QLatin1String("Prefix")).toString() + QLatin1Char('/') + fileName;
+ QInstaller::replaceHighDpiImage(imagePath);
+
+ if (!QFile::exists(imagePath)) {
qCWarning(QInstaller::lcInstallerInstallLog) << "Image file does not exist:" << fileName;
return;
}
- QImageReader reader(fileName);
+ QImageReader reader(imagePath);
QPixmap pixmap = QPixmap::fromImageReader(&reader);
if (!pixmap.isNull()) {
- m_productImagesLabel->setPixmap(pixmap);
+ m_productImagesLabel->setPixmapAndUrl(pixmap, url);
} else {
qCWarning(QInstaller::lcInstallerInstallLog) <<
- QString::fromLatin1("Failed to load image '%1' : %2.").arg(fileName, reader.errorString());
+ QString::fromLatin1("Failed to load image '%1' : %2.").arg(imagePath, reader.errorString());
}
}
diff --git a/src/libs/installer/performinstallationform.h b/src/libs/installer/performinstallationform.h
index 6c5c3ee70..7fe0e743e 100644
--- a/src/libs/installer/performinstallationform.h
+++ b/src/libs/installer/performinstallationform.h
@@ -46,13 +46,14 @@ QT_END_NAMESPACE
namespace QInstaller {
class AspectRatioLabel;
+class PackageManagerCore;
class PerformInstallationForm : public QObject
{
Q_OBJECT
public:
- explicit PerformInstallationForm(QObject *parent);
+ explicit PerformInstallationForm(PackageManagerCore *core, QObject *parent);
void setupUi(QWidget *widget);
void setDetailsWidgetVisible(bool visible);
@@ -71,7 +72,7 @@ public slots:
void toggleDetails();
void clearDetailsBrowser();
void onDownloadStatusChanged(const QString &status);
- void setImageFromFileName(const QString &fileName);
+ void setImageFromFileName(const QString &fileName, const QString &url);
private:
QProgressBar *m_progressBar;
@@ -82,6 +83,7 @@ private:
QPushButton *m_detailsButton;
QTextEdit *m_detailsBrowser;
QTimer *m_updateTimer;
+ PackageManagerCore *m_core;
#ifdef Q_OS_WIN
QWinTaskbarButton *m_taskButton;
diff --git a/src/libs/installer/settings.cpp b/src/libs/installer/settings.cpp
index 0b94e57a6..a2be73810 100644
--- a/src/libs/installer/settings.cpp
+++ b/src/libs/installer/settings.cpp
@@ -145,6 +145,26 @@ static QStringList readArgumentAttributes(QXmlStreamReader &reader, Settings::Pa
return arguments;
}
+static QMap<QString, QVariant> readProductImages(QXmlStreamReader &reader)
+{
+ QMap<QString, QVariant> productImages;
+ while (reader.readNextStartElement()) {
+ if (reader.name() == QLatin1String("ProductImage")) {
+ QString key = QString();
+ QString value = QString();
+ while (reader.readNextStartElement()) {
+ if (reader.name() == QLatin1String("Image")) {
+ key = reader.readElementText();
+ } else if (reader.name() == QLatin1String("Url")) {
+ value = reader.readElementText();
+ }
+ }
+ productImages.insert(key, value);
+ }
+ }
+ return productImages;
+}
+
static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefault, Settings::ParseMode parseMode,
QString *displayName = nullptr, bool *preselected = nullptr,
QString *tooltip = nullptr)
@@ -326,7 +346,7 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
} else if (name == scRunProgramArguments) {
s.setRunProgramArguments(readArgumentAttributes(reader, parseMode, QLatin1String("Argument")));
} else if (name == scProductImages) {
- s.setProductImages(readArgumentAttributes(reader, parseMode, QLatin1String("Image")));
+ s.setProductImages(readProductImages(reader));
} else if (name == scRemoteRepositories) {
s.addDefaultRepositories(readRepositories(reader, true, parseMode));
} else if (name == scRepositoryCategories) {
@@ -497,25 +517,18 @@ bool Settings::wizardShowPageList() const
return d->m_data.value(scWizardShowPageList, true).toBool();
}
-QStringList Settings::productImages() const
+QMap<QString, QVariant> Settings::productImages() const
{
const QVariant variant = d->m_data.value(scProductImages);
- QStringList imagePaths;
- if (variant.canConvert<QStringList>()) {
- foreach (auto image, variant.value<QStringList>()) {
- QString imagePath = QFileInfo(image).isAbsolute()
- ? image
- : d->m_data.value(scPrefix).toString() + QLatin1Char('/') + image;
- QInstaller::replaceHighDpiImage(imagePath);
- imagePaths.append(imagePath);
- }
- }
+ QMap<QString, QVariant> imagePaths;
+ if (variant.canConvert<QVariantMap>())
+ imagePaths = variant.toMap();
return imagePaths;
}
-void Settings::setProductImages(const QStringList &images)
+void Settings::setProductImages(const QMap<QString, QVariant> &images)
{
- d->m_data.replace(scProductImages, images);
+ d->m_data.insert(scProductImages, QVariant::fromValue(images));
}
QString Settings::installerApplicationIcon() const
diff --git a/src/libs/installer/settings.h b/src/libs/installer/settings.h
index 68a1592ff..74ed79d44 100644
--- a/src/libs/installer/settings.h
+++ b/src/libs/installer/settings.h
@@ -92,8 +92,8 @@ public:
int wizardMinimumWidth() const;
int wizardMinimumHeight() const;
bool wizardShowPageList() const;
- QStringList productImages() const;
- void setProductImages(const QStringList &images);
+ QMap<QString, QVariant> productImages() const;
+ void setProductImages(const QMap<QString, QVariant> &images);
QString applicationName() const;
QString version() const;