aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/android/androidmanifesteditoriconwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/android/androidmanifesteditoriconwidget.cpp')
-rw-r--r--src/plugins/android/androidmanifesteditoriconwidget.cpp297
1 files changed, 297 insertions, 0 deletions
diff --git a/src/plugins/android/androidmanifesteditoriconwidget.cpp b/src/plugins/android/androidmanifesteditoriconwidget.cpp
new file mode 100644
index 0000000000..486f4dfcea
--- /dev/null
+++ b/src/plugins/android/androidmanifesteditoriconwidget.cpp
@@ -0,0 +1,297 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "androidmanifesteditoriconwidget.h"
+
+#include <texteditor/textdocument.h>
+#include <texteditor/texteditor.h>
+#include <utils/utilsicons.h>
+
+#include <QFileDialog>
+#include <QFileInfo>
+#include <QGridLayout>
+#include <QLabel>
+#include <QLoggingCategory>
+#include <QPainter>
+#include <QToolButton>
+#include <QVBoxLayout>
+
+namespace Android {
+namespace Internal {
+
+namespace {
+static Q_LOGGING_CATEGORY(androidManifestEditorLog, "qtc.android.manifestEditor", QtWarningMsg)
+const auto fileDialogIconFiles = QWidget::tr("Images (*.png *.jpg *.webp *.svg)");
+QString manifestDir(TextEditor::TextEditorWidget *textEditorWidget)
+{
+ // Get the manifest file's directory from its filepath.
+ return textEditorWidget->textDocument()->filePath().toFileInfo().absolutePath();
+}
+}
+
+AndroidManifestEditorIconWidget::AndroidManifestEditorIconWidget(QWidget *parent) : QWidget(parent)
+{
+
+}
+
+AndroidManifestEditorIconWidget::AndroidManifestEditorIconWidget(
+ QWidget *parent, const QSize &iconSize, const QSize &buttonSize, const QString &title,
+ const QString &tooltip,
+ TextEditor::TextEditorWidget *textEditorWidget,
+ const QString &targetIconPath,
+ const QString &targetIconFileName)
+ : QWidget(parent), m_iconSize(iconSize), m_buttonSize(buttonSize),
+ m_textEditorWidget(textEditorWidget),
+ m_targetIconPath(targetIconPath), m_targetIconFileName(targetIconFileName)
+{
+ auto iconLayout = new QVBoxLayout(this);
+ auto iconTitle = new QLabel(title, this);
+ auto iconButtonLayout = new QGridLayout();
+ m_button = new QToolButton(this);
+ m_button->setMinimumSize(buttonSize);
+ m_button->setMaximumSize(buttonSize);
+ m_button->setToolTip(tooltip);
+ m_button->setIconSize(buttonSize);
+ QSize clearAndWarningSize(16, 16);
+ QToolButton *clearButton = nullptr;
+ if (textEditorWidget) {
+ clearButton = new QToolButton(this);
+ clearButton->setMinimumSize(clearAndWarningSize);
+ clearButton->setMaximumSize(clearAndWarningSize);
+ clearButton->setIcon(Utils::Icons::CLOSE_FOREGROUND.icon());
+ }
+ if (textEditorWidget) {
+ m_scaleWarningLabel = new QLabel(this);
+ m_scaleWarningLabel->setMinimumSize(clearAndWarningSize);
+ m_scaleWarningLabel->setMaximumSize(clearAndWarningSize);
+ m_scaleWarningLabel->setPixmap(Utils::Icons::WARNING.icon().pixmap(clearAndWarningSize));
+ m_scaleWarningLabel->setToolTip(tr("Icon scaled up."));
+ m_scaleWarningLabel->setVisible(false);
+ }
+ auto label = new QLabel(tr("Click to select..."), parent);
+ iconLayout->addWidget(iconTitle);
+ iconLayout->setAlignment(iconTitle, Qt::AlignHCenter);
+ iconButtonLayout->setColumnMinimumWidth(0, 16);
+ iconButtonLayout->addWidget(m_button, 0, 1, 1, 3);
+ iconButtonLayout->setAlignment(m_button, Qt::AlignVCenter);
+ if (textEditorWidget) {
+ iconButtonLayout->addWidget(clearButton, 0, 4, 1, 1);
+ iconButtonLayout->setAlignment(clearButton, Qt::AlignTop);
+ }
+ if (textEditorWidget) {
+ iconButtonLayout->addWidget(m_scaleWarningLabel, 0, 0, 1, 1);
+ iconButtonLayout->setAlignment(m_scaleWarningLabel, Qt::AlignTop);
+ }
+ iconLayout->addLayout(iconButtonLayout);
+ iconLayout->setAlignment(iconButtonLayout, Qt::AlignHCenter);
+ iconLayout->addWidget(label);
+ iconLayout->setAlignment(label, Qt::AlignHCenter);
+ this->setLayout(iconLayout);
+ connect(m_button, &QAbstractButton::clicked,
+ this, &AndroidManifestEditorIconWidget::selectIcon);
+ if (clearButton)
+ connect(clearButton, &QAbstractButton::clicked,
+ this, &AndroidManifestEditorIconWidget::clearIcon);
+ m_iconSelectionText = tooltip;
+}
+
+void AndroidManifestEditorIconWidget::setIcon(const QIcon &icon)
+{
+ m_button->setIcon(icon);
+}
+
+void AndroidManifestEditorIconWidget::clearIcon()
+{
+ removeIcon();
+ iconRemoved();
+}
+
+void AndroidManifestEditorIconWidget::loadIcon()
+{
+ QString baseDir = manifestDir(m_textEditorWidget);
+ QString iconFile = baseDir + m_targetIconPath + m_targetIconFileName;
+ setIconFromPath(iconFile);
+}
+
+void AndroidManifestEditorIconWidget::setIconFromPath(const QString &iconPath)
+{
+ if (!m_textEditorWidget)
+ return;
+ m_iconPath = iconPath;
+ QString baseDir = manifestDir(m_textEditorWidget);
+ QImage original(iconPath);
+ if (!original.isNull() && m_scaledToOriginalAspectRatio) {
+ if ((original.width() > original.height() && m_buttonSize.height() > m_buttonSize.width())
+ || (original.height() > original.width() && m_buttonSize.width() > m_buttonSize.height())) {
+ auto width = m_buttonSize.height();
+ auto height = m_buttonSize.width();
+ m_buttonSize = QSize(width, height);
+ m_button->setMinimumSize(m_buttonSize);
+ m_button->setMaximumSize(m_buttonSize);
+ m_button->setIconSize(m_buttonSize);
+ auto targetWidth = m_iconSize.height();
+ auto targetHeight = m_iconSize.width();
+ m_iconSize = QSize(targetWidth, targetHeight);
+ }
+ }
+ copyIcon();
+ QString iconFile = baseDir + m_targetIconPath + m_targetIconFileName;
+ m_button->setIcon(QIcon(iconFile));
+}
+
+void AndroidManifestEditorIconWidget::selectIcon()
+{
+ QString file = QFileDialog::getOpenFileName(this, m_iconSelectionText,
+ QDir::homePath(), fileDialogIconFiles);
+ if (file.isEmpty())
+ return;
+ setIconFromPath(file);
+ iconSelected(file, this);
+}
+
+void AndroidManifestEditorIconWidget::removeIcon()
+{
+ QString baseDir = manifestDir(m_textEditorWidget);
+ const QString targetPath = baseDir + m_targetIconPath + m_targetIconFileName;
+ if (targetPath.isEmpty()) {
+ qCDebug(androidManifestEditorLog) << "Icon target path empty, cannot remove icon.";
+ return;
+ }
+ QFile targetFile(targetPath);
+ targetFile.remove();
+ m_iconPath.clear();
+ setScaleWarningLabelVisible(false);
+ m_button->setIcon(QIcon());
+}
+
+bool AndroidManifestEditorIconWidget::hasIcon() const
+{
+ return !m_iconPath.isEmpty();
+}
+
+void AndroidManifestEditorIconWidget::setScaledToOriginalAspectRatio(bool scaled)
+{
+ m_scaledToOriginalAspectRatio = scaled;
+}
+
+void AndroidManifestEditorIconWidget::setScaledWithoutStretching(bool scaled)
+{
+ m_scaledWithoutStretching = scaled;
+}
+
+void AndroidManifestEditorIconWidget::setTargetIconFileName(const QString &targetIconFileName)
+{
+ m_targetIconFileName = targetIconFileName;
+}
+
+void AndroidManifestEditorIconWidget::setTargetIconPath(const QString &targetIconPath)
+{
+ m_targetIconPath = targetIconPath;
+}
+
+QString AndroidManifestEditorIconWidget::targetIconFileName() const
+{
+ return m_targetIconFileName;
+}
+
+QString AndroidManifestEditorIconWidget::targetIconPath() const
+{
+ return m_targetIconPath;
+}
+
+void AndroidManifestEditorIconWidget::setScaleWarningLabelVisible(bool visible)
+{
+ if (m_scaleWarningLabel)
+ m_scaleWarningLabel->setVisible(visible);
+}
+
+static QImage scaleWithoutStretching(const QImage& original, const QSize& targetSize)
+{
+ QImage ret(targetSize, QImage::Format_ARGB32);
+ ret.fill(Qt::white);
+ if (targetSize.height() > targetSize.width()) {
+ // portrait target, scale to width and paint in the vertical middle
+ QImage scaled = original.scaledToWidth(targetSize.width());
+ int heightDiffHalf = (targetSize.height() - scaled.height()) / 2;
+ QPainter painter(&ret);
+ QRect targetRect(0, heightDiffHalf, targetSize.width(), scaled.height());
+ QRect sourceRect(0, 0, scaled.width(), scaled.height());
+ painter.drawImage(targetRect, scaled, sourceRect);
+ } else if (targetSize.width() > targetSize.height()) {
+ // landscape target, scale to height and paint in the horizontal middle
+ QImage scaled = original.scaledToHeight(targetSize.height());
+ int widthDiffHalf = (targetSize.width() - scaled.width()) / 2;
+ QPainter painter(&ret);
+ QRect targetRect(widthDiffHalf, 0, scaled.width(), targetSize.height());
+ QRect sourceRect(0, 0, scaled.width(), scaled.height());
+ painter.drawImage(targetRect, scaled, sourceRect);
+ } else
+ ret = original.scaled(targetSize.width(), targetSize.height(),
+ Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ return ret;
+}
+
+void AndroidManifestEditorIconWidget::copyIcon()
+{
+ if (m_targetIconPath.isEmpty())
+ return;
+ QString baseDir = manifestDir(m_textEditorWidget);
+ const QString targetPath = baseDir + m_targetIconPath + m_targetIconFileName;
+ if (targetPath.isEmpty()) {
+ qCDebug(androidManifestEditorLog) << "Icon target path empty, cannot copy icon.";
+ return;
+ }
+ QImage original(m_iconPath);
+ if (m_iconPath != targetPath)
+ removeIcon();
+ if (original.isNull()) {
+ m_iconPath.clear();
+ return;
+ }
+ if (m_iconPath == targetPath)
+ return;
+ if (!targetPath.isEmpty() && !original.isNull()) {
+ QDir dir;
+ if (!dir.mkpath(QFileInfo(targetPath).absolutePath())) {
+ qCDebug(androidManifestEditorLog) << "Cannot create icon target path.";
+ m_iconPath.clear();
+ return;
+ }
+ QImage scaled;
+ if (!m_scaledWithoutStretching)
+ scaled = original.scaled(m_iconSize.width(), m_iconSize.height(),
+ Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ else
+ scaled = scaleWithoutStretching(original, m_iconSize);
+ setScaleWarningLabelVisible(scaled.width() > original.width() || scaled.height() > original.height());
+ scaled.save(targetPath);
+ m_iconPath = targetPath;
+ } else {
+ m_iconPath.clear();
+ }
+}
+
+} // namespace Internal
+} // namespace Android