Android: add a splash screen editor to manifest editor

Task-number: QTCREATORBUG-24013
Task-number: QTCREATORBUG-24011
Change-Id: Iea7e8ff8f9bf616612827b70de67e01801ab1229
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
Ville Voutilainen
2020-06-02 09:33:21 +03:00
parent 3fa6861e98
commit a2cd1e45df
10 changed files with 433 additions and 70 deletions

View File

@@ -51,4 +51,5 @@ add_qtc_plugin(Android
javaeditor.cpp javaeditor.h
javaindenter.cpp javaindenter.h
javaparser.cpp javaparser.h
splashiconcontainerwidget.cpp splashiconcontainerwidget.h
)

View File

@@ -53,7 +53,8 @@ HEADERS += \
androidpackageinstallationstep.h \
androidextralibrarylistmodel.h \
createandroidmanifestwizard.h \
androidsdkdownloader.h
androidsdkdownloader.h \
splashiconcontainerwidget.h
SOURCES += \
androidconfigurations.cpp \
@@ -99,7 +100,8 @@ SOURCES += \
androidpackageinstallationstep.cpp \
androidextralibrarylistmodel.cpp \
createandroidmanifestwizard.cpp \
androidsdkdownloader.cpp
androidsdkdownloader.cpp \
splashiconcontainerwidget.cpp
FORMS += \
androidsettingswidget.ui \

View File

@@ -117,6 +117,8 @@ Project {
"javaindenter.h",
"javaparser.cpp",
"javaparser.h",
"splashiconcontainerwidget.cpp"
"splashiconcontainerwidget.h"
]
}
}

View File

@@ -50,6 +50,7 @@ AndroidManifestEditorIconContainerWidget::AndroidManifestEditorIconContainerWidg
{
auto iconLayout = new QHBoxLayout(this);
auto masterIconButton = new AndroidManifestEditorIconWidget(this,
lowDpiIconSize,
lowDpiIconSize,
tr("Master icon"), tr("Select master icon"));
masterIconButton->setIcon(QIcon::fromTheme(QLatin1String("document-open"), Utils::Icons::OPENFILE.icon()));
@@ -63,6 +64,7 @@ AndroidManifestEditorIconContainerWidget::AndroidManifestEditorIconContainerWidg
iconLayout->addStretch(1);
auto lIconButton = new AndroidManifestEditorIconWidget(this,
lowDpiIconSize,
lowDpiIconSize,
tr("Low DPI icon"), tr("Select low DPI icon"),
textEditorWidget, lowDpiIconPath);
@@ -71,6 +73,7 @@ AndroidManifestEditorIconContainerWidget::AndroidManifestEditorIconContainerWidg
iconLayout->addStretch(1);
auto mIconButton = new AndroidManifestEditorIconWidget(this,
mediumDpiIconSize,
mediumDpiIconSize,
tr("Medium DPI icon"), tr("Select medium DPI icon"),
textEditorWidget, mediumDpiIconPath);
@@ -79,6 +82,7 @@ AndroidManifestEditorIconContainerWidget::AndroidManifestEditorIconContainerWidg
iconLayout->addStretch(1);
auto hIconButton = new AndroidManifestEditorIconWidget(this,
highDpiIconSize,
highDpiIconSize,
tr("High DPI icon"), tr("Select high DPI icon"),
textEditorWidget, highDpiIconPath);

View File

@@ -56,11 +56,11 @@ AndroidManifestEditorIconWidget::AndroidManifestEditorIconWidget(QWidget *parent
}
AndroidManifestEditorIconWidget::AndroidManifestEditorIconWidget(
QWidget *parent, const QSize &buttonSize, const QString &title,
QWidget *parent, const QSize &iconSize, const QSize &buttonSize, const QString &title,
const QString &tooltip,
TextEditor::TextEditorWidget *textEditorWidget,
const QString &targetIconPath)
: QWidget(parent), m_buttonSize(buttonSize),
: QWidget(parent), m_iconSize(iconSize), m_buttonSize(buttonSize),
m_textEditorWidget(textEditorWidget), m_targetIconPath(targetIconPath)
{
auto iconLayout = new QVBoxLayout(this);
@@ -108,9 +108,12 @@ AndroidManifestEditorIconWidget::AndroidManifestEditorIconWidget(
this->setLayout(iconLayout);
connect(m_button, &QAbstractButton::clicked,
this, &AndroidManifestEditorIconWidget::selectIcon);
if (clearButton)
if (clearButton) {
connect(clearButton, &QAbstractButton::clicked,
this, &AndroidManifestEditorIconWidget::removeIcon);
connect(clearButton, &QAbstractButton::clicked,
this, &AndroidManifestEditorIconWidget::iconRemoved);
}
m_iconSelectionText = tooltip;
}
@@ -128,14 +131,26 @@ void AndroidManifestEditorIconWidget::loadIcon()
void AndroidManifestEditorIconWidget::setIconFromPath(const QString &iconPath)
{
if (!m_textEditorWidget) {
iconSelected(iconPath);
iconSelected(iconPath);
if (!m_textEditorWidget)
return;
}
m_iconPath = iconPath;
QString baseDir = manifestDir(m_textEditorWidget);
copyIcon();
QString iconFile = baseDir + m_targetIconPath;
if (!m_scaled) {
QImage original(iconFile);
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);
}
}
m_button->setIcon(QIcon(iconFile));
}
@@ -156,11 +171,9 @@ void AndroidManifestEditorIconWidget::removeIcon()
qCDebug(androidManifestEditorLog) << "Icon target path empty, cannot remove icon.";
return;
}
QFileInfo targetFile(targetPath);
if (targetFile.exists()) {
QDir rmRf(targetFile.absoluteDir());
rmRf.removeRecursively();
}
QFile targetFile(targetPath);
targetFile.remove();
m_iconPath.clear();
setScaleWarningLabelVisible(false);
m_button->setIcon(QIcon());
}
@@ -170,6 +183,11 @@ bool AndroidManifestEditorIconWidget::hasIcon()
return !m_iconPath.isEmpty();
}
void AndroidManifestEditorIconWidget::setScaled(bool scaled)
{
m_scaled = scaled;
}
void AndroidManifestEditorIconWidget::setScaleWarningLabelVisible(bool visible)
{
if (m_scaleWarningLabel)
@@ -187,10 +205,15 @@ void AndroidManifestEditorIconWidget::copyIcon()
return;
}
QFileInfo targetFile(targetPath);
QImage original(m_iconPath);
if (m_iconPath != targetPath)
removeIcon();
if (original.isNull()) {
m_iconPath.clear();
return;
}
if (m_iconPath == targetPath)
return;
removeIcon();
QImage original(m_iconPath);
if (!targetPath.isEmpty() && !original.isNull()) {
QDir dir;
if (!dir.mkpath(QFileInfo(targetPath).absolutePath())) {
@@ -198,11 +221,14 @@ void AndroidManifestEditorIconWidget::copyIcon()
m_iconPath.clear();
return;
}
QSize targetSize = m_buttonSize;
QImage scaled = original.scaled(targetSize.width(), targetSize.height(),
Qt::KeepAspectRatio, Qt::SmoothTransformation);
setScaleWarningLabelVisible(scaled.width() > original.width() || scaled.height() > original.height());
scaled.save(targetPath);
QSize targetSize = m_iconSize;
if (m_scaled) {
QImage scaled = original.scaled(targetSize.width(), targetSize.height(),
Qt::KeepAspectRatio, Qt::SmoothTransformation);
setScaleWarningLabelVisible(scaled.width() > original.width() || scaled.height() > original.height());
scaled.save(targetPath);
} else
original.save(targetPath);
m_iconPath = m_targetIconPath;
} else {
m_iconPath.clear();

View File

@@ -45,6 +45,7 @@ class AndroidManifestEditorIconWidget : public QWidget
public:
explicit AndroidManifestEditorIconWidget(QWidget *parent);
AndroidManifestEditorIconWidget(QWidget *parent,
const QSize &iconSize,
const QSize &buttonSize,
const QString &title,
const QString &tooltip,
@@ -54,9 +55,10 @@ public:
void loadIcon();
void setIconFromPath(const QString &iconPath);
bool hasIcon();
void setScaled(bool scaled);
signals:
void iconSelected(const QString &path);
void iconRemoved();
private:
void selectIcon();
@@ -65,12 +67,14 @@ private:
void setScaleWarningLabelVisible(bool visible);
private:
QToolButton *m_button = nullptr;
QSize m_iconSize;
QSize m_buttonSize;
QLabel *m_scaleWarningLabel = nullptr;
TextEditor::TextEditorWidget *m_textEditorWidget = nullptr;
QString m_iconPath;
QString m_targetIconPath;
QString m_iconSelectionText;
bool m_scaled = true;
};
} // namespace Internal

View File

@@ -31,6 +31,7 @@
#include "androidmanifestdocument.h"
#include "androidmanager.h"
#include "androidservicewidget.h"
#include "splashiconcontainerwidget.h"
#include <coreplugin/icore.h>
#include <coreplugin/infobar.h>
@@ -250,11 +251,13 @@ void AndroidManifestEditorWidget::initializePage()
}
m_iconButtons = new AndroidManifestEditorIconContainerWidget(applicationGroupBox, m_textEditorWidget);
formLayout->addRow(tr("Application icon:"), new QLabel());
formLayout->addRow(QString(), m_iconButtons);
m_splashButtons = new SplashIconContainerWidget(applicationGroupBox, m_textEditorWidget);
formLayout->addRow(tr("Splash screen:"), new QLabel());
formLayout->addRow(QString(), m_splashButtons);
m_services = new AndroidServiceWidget(this);
formLayout->addRow(tr("Android services:"), m_services);
@@ -271,6 +274,8 @@ void AndroidManifestEditorWidget::initializePage()
this, setDirtyFunc);
connect(m_services, &AndroidServiceWidget::servicesModified,
this, setDirtyFunc);
connect(m_splashButtons, &SplashIconContainerWidget::splashScreensModified,
this, setDirtyFunc);
connect(m_services, &AndroidServiceWidget::servicesModified,
this, &AndroidManifestEditorWidget::clearInvalidServiceInfo);
connect(m_services, &AndroidServiceWidget::servicesInvalid,
@@ -801,21 +806,27 @@ void AndroidManifestEditorWidget::syncToWidgets(const QDomDocument &doc)
m_activityNameLineEdit->setText(activityElem.attribute(QLatin1String("android:label")));
QDomElement metadataElem = activityElem.firstChildElement(QLatin1String("meta-data"));
const int parseItemsCount = 2;
int counter = 0;
enum ActivityParseGuard {none = 0, libName = 1, styleExtract = 2, stickySplash = 4, done = 8};
int activityParseGuard = ActivityParseGuard::none;
while (!metadataElem.isNull()) {
if (metadataElem.attribute(QLatin1String("android:name")) == QLatin1String("android.app.lib_name")) {
if (metadataElem.attribute(QLatin1String("android:name")) == QLatin1String("android.app.lib_name")
&& !(activityParseGuard & ActivityParseGuard::libName)) {
m_targetLineEdit->setEditText(metadataElem.attribute(QLatin1String("android:value")));
++counter;
activityParseGuard |= ActivityParseGuard::libName;
} else if (metadataElem.attribute(QLatin1String("android:name"))
== QLatin1String("android.app.extract_android_style")) {
== QLatin1String("android.app.extract_android_style")
&& !(activityParseGuard & ActivityParseGuard::styleExtract)) {
m_styleExtractMethod->setCurrentText(
metadataElem.attribute(QLatin1String("android:value")));
++counter;
activityParseGuard |= ActivityParseGuard::styleExtract;
} else if (metadataElem.attribute(QLatin1String("android:name"))
== QLatin1String("android.app.splash_screen_sticky")
&& !(activityParseGuard & ActivityParseGuard::stickySplash)) {
QString sticky = metadataElem.attribute(QLatin1String("android:value"));
m_splashButtons->setSticky(sticky == QLatin1String("true"));
activityParseGuard |= ActivityParseGuard::stickySplash;
}
if (counter == parseItemsCount)
if (activityParseGuard == ActivityParseGuard::done)
break;
metadataElem = metadataElem.nextSiblingElement(QLatin1String("meta-data"));
}
@@ -887,6 +898,7 @@ void AndroidManifestEditorWidget::syncToWidgets(const QDomDocument &doc)
m_services->setServices(services);
m_iconButtons->loadIcons();
m_splashButtons->loadImages();
m_stayClean = false;
m_dirty = false;
@@ -1085,28 +1097,7 @@ void AndroidManifestEditorWidget::parseApplication(QXmlStreamReader &reader, QXm
}
}
static int findService(const QString &name, const QList<AndroidServiceData> &data)
{
for (int i = 0; i < data.size(); ++i) {
if (data[i].className() == name)
return i;
}
return -1;
}
static void writeServiceMetadataElement(const char *name,
const char *attributeName,
const char *value,
QXmlStreamWriter &writer)
{
writer.writeStartElement(QLatin1String("meta-data"));
writer.writeAttribute(QLatin1String("android:name"), QLatin1String(name));
writer.writeAttribute(QLatin1String(attributeName), QLatin1String(value));
writer.writeEndElement();
}
static void writeServiceMetadataElement(const char *name,
static void writeMetadataElement(const char *name,
const char *attributeName,
const QString &value,
QXmlStreamWriter &writer)
@@ -1118,28 +1109,69 @@ static void writeServiceMetadataElement(const char *name,
}
void AndroidManifestEditorWidget::parseSplashScreen(QXmlStreamWriter &writer)
{
if (m_splashButtons->hasImages())
writeMetadataElement("android.app.splash_screen_drawable",
"android:resource", "@drawable/logo",
writer);
if (m_splashButtons->hasPortraitImages())
writeMetadataElement("android.app.splash_screen_drawable_portrait",
"android:resource", "@drawable/logo_portrait",
writer);
if (m_splashButtons->hasLandscapeImages())
writeMetadataElement("android.app.splash_screen_drawable_landscape",
"android:resource", "@drawable/logo_landscape",
writer);
if (m_splashButtons->isSticky())
writeMetadataElement("android.app.splash_screen_sticky",
"android:value", "true",
writer);
}
static int findService(const QString &name, const QList<AndroidServiceData> &data)
{
for (int i = 0; i < data.size(); ++i) {
if (data[i].className() == name)
return i;
}
return -1;
}
static void writeMetadataElement(const char *name,
const char *attributeName,
const char *value,
QXmlStreamWriter &writer)
{
writer.writeStartElement(QLatin1String("meta-data"));
writer.writeAttribute(QLatin1String("android:name"), QLatin1String(name));
writer.writeAttribute(QLatin1String(attributeName), QLatin1String(value));
writer.writeEndElement();
}
static void addServiceArgumentsAndLibName(const AndroidServiceData &service, QXmlStreamWriter &writer)
{
if (!service.isRunInExternalLibrary() && !service.serviceArguments().isEmpty())
writeServiceMetadataElement("android.app.arguments", "android:value", service.serviceArguments(), writer);
writeMetadataElement("android.app.arguments", "android:value", service.serviceArguments(), writer);
if (service.isRunInExternalLibrary() && !service.externalLibraryName().isEmpty())
writeServiceMetadataElement("android.app.lib_name", "android:value", service.externalLibraryName(), writer);
writeMetadataElement("android.app.lib_name", "android:value", service.externalLibraryName(), writer);
else
writeServiceMetadataElement("android.app.lib_name", "android:value", "-- %%INSERT_APP_LIB_NAME%% --", writer);
writeMetadataElement("android.app.lib_name", "android:value", "-- %%INSERT_APP_LIB_NAME%% --", writer);
}
static void addServiceMetadata(QXmlStreamWriter &writer)
{
writeServiceMetadataElement("android.app.qt_sources_resource_id", "android:resource", "@array/qt_sources", writer);
writeServiceMetadataElement("android.app.repository", "android:value", "default", writer);
writeServiceMetadataElement("android.app.qt_libs_resource_id", "android:resource", "@array/qt_libs", writer);
writeServiceMetadataElement("android.app.bundled_libs_resource_id", "android:resource", "@array/bundled_libs", writer);
writeServiceMetadataElement("android.app.bundle_local_qt_libs", "android:value", "-- %%BUNDLE_LOCAL_QT_LIBS%% --", writer);
writeServiceMetadataElement("android.app.use_local_qt_libs", "android:value", "-- %%USE_LOCAL_QT_LIBS%% --", writer);
writeServiceMetadataElement("android.app.libs_prefix", "android:value", "/data/local/tmp/qt/", writer);
writeServiceMetadataElement("android.app.load_local_libs_resource_id", "android:resource", "@array/load_local_libs", writer);
writeServiceMetadataElement("android.app.load_local_jars", "android:value", "-- %%INSERT_LOCAL_JARS%% --", writer);
writeServiceMetadataElement("android.app.static_init_classes", "android:value", "-- %%INSERT_INIT_CLASSES%% --", writer);
writeMetadataElement("android.app.qt_sources_resource_id", "android:resource", "@array/qt_sources", writer);
writeMetadataElement("android.app.repository", "android:value", "default", writer);
writeMetadataElement("android.app.qt_libs_resource_id", "android:resource", "@array/qt_libs", writer);
writeMetadataElement("android.app.bundled_libs_resource_id", "android:resource", "@array/bundled_libs", writer);
writeMetadataElement("android.app.bundle_local_qt_libs", "android:value", "-- %%BUNDLE_LOCAL_QT_LIBS%% --", writer);
writeMetadataElement("android.app.use_local_qt_libs", "android:value", "-- %%USE_LOCAL_QT_LIBS%% --", writer);
writeMetadataElement("android.app.libs_prefix", "android:value", "/data/local/tmp/qt/", writer);
writeMetadataElement("android.app.load_local_libs_resource_id", "android:resource", "@array/load_local_libs", writer);
writeMetadataElement("android.app.load_local_jars", "android:value", "-- %%INSERT_LOCAL_JARS%% --", writer);
writeMetadataElement("android.app.static_init_classes", "android:value", "-- %%INSERT_INIT_CLASSES%% --", writer);
}
void AndroidManifestEditorWidget::parseService(QXmlStreamReader &reader, QXmlStreamWriter &writer)
@@ -1240,6 +1272,7 @@ void AndroidManifestEditorWidget::parseActivity(QXmlStreamReader &reader, QXmlSt
while (!reader.atEnd()) {
if (reader.isEndElement()) {
parseSplashScreen(writer);
if (!found) {
writer.writeEmptyElement(QLatin1String("meta-data"));
writer.writeAttribute(QLatin1String("android:name"),
@@ -1250,10 +1283,16 @@ void AndroidManifestEditorWidget::parseActivity(QXmlStreamReader &reader, QXmlSt
writer.writeCurrentToken(reader);
return;
} else if (reader.isStartElement()) {
if (reader.name() == QLatin1String("meta-data"))
found = parseMetaData(reader, writer) || found; // ORDER MATTERS
else
if (reader.name() == QLatin1String("meta-data")) {
QString metaTagName = reader.attributes().value(QLatin1String("android:name")).toString();
if (metaTagName.startsWith(QLatin1String("android.app.splash_screen")))
parseUnknownElement(reader, writer, true);
else
found = parseMetaData(reader, writer) || found; // ORDER MATTERS
} else
parseUnknownElement(reader, writer);
} else if (reader.isWhitespace()) {
/* no copying of whitespace */
} else {
writer.writeCurrentToken(reader);
}

View File

@@ -55,6 +55,7 @@ class AndroidManifestEditor;
class AndroidManifestEditorIconContainerWidget;
class AndroidManifestEditorWidget;
class AndroidServiceWidget;
class SplashIconContainerWidget;
class PermissionsModel: public QAbstractListModel
{
@@ -143,6 +144,7 @@ private:
void parseManifest(QXmlStreamReader &reader, QXmlStreamWriter &writer);
void parseApplication(QXmlStreamReader &reader, QXmlStreamWriter &writer);
void parseSplashScreen(QXmlStreamWriter &writer);
void parseService(QXmlStreamReader &reader, QXmlStreamWriter &writer);
void parseNewServices(QXmlStreamWriter &writer);
void parseActivity(QXmlStreamReader &reader, QXmlStreamWriter &writer);
@@ -173,6 +175,7 @@ private:
QComboBox *m_targetLineEdit;
QComboBox *m_styleExtractMethod;
AndroidManifestEditorIconContainerWidget *m_iconButtons;
SplashIconContainerWidget *m_splashButtons;
// Permissions
QCheckBox *m_defaultPermissonsCheckBox;

View File

@@ -0,0 +1,215 @@
/****************************************************************************
**
** 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 "splashiconcontainerwidget.h"
#include "androidmanifesteditoriconwidget.h"
#include <utils/utilsicons.h>
#include <QCheckBox>
#include <QTabWidget>
#include <QVBoxLayout>
namespace Android {
namespace Internal {
namespace {
const QString highDpiImagePath = "/res/drawable-hdpi/logo.png";
const QString mediumDpiImagePath = "/res/drawable-mdpi/logo.png";
const QString lowDpiImagePath = "/res/drawable-ldpi/logo.png";
const QString highDpiLandscapeImagePath = "/res/drawable-hdpi/logo_landscape.png";
const QString mediumDpiLandscapeImagePath = "/res/drawable-mdpi/logo_landscape.png";
const QString lowDpiLandscapeImagePath = "/res/drawable-ldpi/logo_landscape.png";
const QString highDpiPortraitImagePath = "/res/drawable-hdpi/logo_portrait.png";
const QString mediumDpiPortraitImagePath = "/res/drawable-mdpi/logo_portrait.png";
const QString lowDpiPortraitImagePath = "/res/drawable-ldpi/logo_portrait.png";
const QSize lowDpiImageSize{200, 320};
const QSize mediumDpiImageSize{320, 480};
const QSize highDpiImageSize{480, 720};
const QSize lowDpiLandscapeImageSize{320, 200};
const QSize mediumDpiLandscapeImageSize{480, 320};
const QSize highDpiLandscapeImageSize{720, 480};
const QSize displaySize{48, 72};
const QSize landscapeDisplaySize{72, 48};
}
static QWidget *createPage(TextEditor::TextEditorWidget *textEditorWidget,
QVector<AndroidManifestEditorIconWidget *> &buttonContainer,
QVector<AndroidManifestEditorIconWidget *> &portraitButtonContainer,
QVector<AndroidManifestEditorIconWidget *> &landscapeButtonContainer,
const QSize &splashSize,
const QSize &portraitSplashSize,
const QSize &landscapeSplashSize,
const QString &splashPath,
const QString &portraitSplashPath,
const QString &landscapeSplashPath)
{
QWidget *page = new QWidget();
auto iconLayout = new QHBoxLayout(page);
auto splashButton = new AndroidManifestEditorIconWidget(page,
splashSize,
landscapeDisplaySize,
SplashIconContainerWidget::tr("Splash screen"),
SplashIconContainerWidget::tr("Select splash screen image"),
textEditorWidget, splashPath);
splashButton->setScaled(false);
iconLayout->addWidget(splashButton);
buttonContainer.push_back(splashButton);
iconLayout->addStretch(1);
auto portraitButton = new AndroidManifestEditorIconWidget(page,
portraitSplashSize,
displaySize,
SplashIconContainerWidget::tr("Portrait splash screen"),
SplashIconContainerWidget::tr("Select portrait splash screen image"),
textEditorWidget, portraitSplashPath);
iconLayout->addWidget(portraitButton);
portraitButtonContainer.push_back(portraitButton);
iconLayout->addStretch(1);
auto landscapeButton = new AndroidManifestEditorIconWidget(page,
landscapeSplashSize,
landscapeDisplaySize,
SplashIconContainerWidget::tr("Landscape splash screen"),
SplashIconContainerWidget::tr("Select landscape splash screen image"),
textEditorWidget, landscapeSplashPath);
iconLayout->addWidget(landscapeButton);
landscapeButtonContainer.push_back(landscapeButton);
iconLayout->addStretch(1);
iconLayout->addStretch(6);
return page;
}
SplashIconContainerWidget::SplashIconContainerWidget(
QWidget *parent,
TextEditor::TextEditorWidget *textEditorWidget)
: QWidget(parent)
{
auto layout = new QVBoxLayout(this);
m_stickyCheck = new QCheckBox(tr("Sticky splash screen"), this);
m_stickyCheck->setToolTip(tr("A non-sticky splash screen is hidden automatically when an activity is drawn.\n"
"To hide a sticky splash screen, invoke QtAndroid::hideSplashScreen()."));
QTabWidget *tab = new QTabWidget(this);
auto hdpiPage = createPage(textEditorWidget,
m_imageButtons, m_portraitImageButtons, m_landscapeImageButtons,
highDpiImageSize,
highDpiImageSize,
highDpiLandscapeImageSize,
highDpiImagePath, highDpiPortraitImagePath, highDpiLandscapeImagePath);
tab->addTab(hdpiPage, tr("High DPI splash screen"));
auto mdpiPage = createPage(textEditorWidget,
m_imageButtons, m_portraitImageButtons, m_landscapeImageButtons,
mediumDpiImageSize,
mediumDpiImageSize,
mediumDpiLandscapeImageSize,
mediumDpiImagePath, mediumDpiPortraitImagePath, mediumDpiLandscapeImagePath);
tab->addTab(mdpiPage, tr("Medium DPI splash screen"));
auto ldpiPage = createPage(textEditorWidget,
m_imageButtons, m_portraitImageButtons, m_landscapeImageButtons,
lowDpiImageSize,
lowDpiImageSize,
lowDpiLandscapeImageSize,
lowDpiImagePath, lowDpiPortraitImagePath, lowDpiLandscapeImagePath);
tab->addTab(ldpiPage, tr("Low DPI splash screen"));
layout->addWidget(m_stickyCheck);
layout->setAlignment(m_stickyCheck, Qt::AlignLeft);
layout->addWidget(tab);
for (auto &&imageButton : m_imageButtons)
connect(imageButton, &AndroidManifestEditorIconWidget::iconSelected,
this, &SplashIconContainerWidget::splashScreensModified);
for (auto &&imageButton : m_portraitImageButtons) {
connect(imageButton, &AndroidManifestEditorIconWidget::iconSelected,
this, &SplashIconContainerWidget::splashScreensModified);
connect(imageButton, &AndroidManifestEditorIconWidget::iconRemoved,
this, &SplashIconContainerWidget::splashScreensModified);
}
for (auto &&imageButton : m_landscapeImageButtons) {
connect(imageButton, &AndroidManifestEditorIconWidget::iconSelected,
this, &SplashIconContainerWidget::splashScreensModified);
connect(imageButton, &AndroidManifestEditorIconWidget::iconRemoved,
this, &SplashIconContainerWidget::splashScreensModified);
}
connect(m_stickyCheck, &QCheckBox::stateChanged, [this](int state) {
bool old = m_splashScreenSticky;
m_splashScreenSticky = (state == Qt::Checked);
if (old != m_splashScreenSticky)
splashScreensModified();
});
}
void SplashIconContainerWidget::loadImages()
{
for (auto &&imageButton : m_imageButtons)
imageButton->loadIcon();
for (auto &&imageButton : m_portraitImageButtons)
imageButton->loadIcon();
for (auto &&imageButton : m_landscapeImageButtons)
imageButton->loadIcon();
}
bool SplashIconContainerWidget::hasImages()
{
for (auto &&iconButton : m_imageButtons) {
if (iconButton->hasIcon())
return true;
}
return false;
}
bool SplashIconContainerWidget::hasPortraitImages()
{
for (auto &&iconButton : m_portraitImageButtons) {
if (iconButton->hasIcon())
return true;
}
return false;
}
bool SplashIconContainerWidget::hasLandscapeImages()
{
for (auto &&iconButton : m_landscapeImageButtons) {
if (iconButton->hasIcon())
return true;
}
return false;
}
bool SplashIconContainerWidget::isSticky()
{
return m_splashScreenSticky;
}
void SplashIconContainerWidget::setSticky(bool sticky)
{
m_splashScreenSticky = sticky;
m_stickyCheck->setCheckState(m_splashScreenSticky ? Qt::Checked : Qt::Unchecked);
}
} // namespace Internal
} // namespace Android

View File

@@ -0,0 +1,67 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#pragma once
#include <QVector>
#include <QWidget>
QT_BEGIN_NAMESPACE
class QCheckBox;
QT_END_NAMESPACE
namespace TextEditor {
class TextEditorWidget;
}
namespace Android {
namespace Internal {
class AndroidManifestEditorIconWidget;
class SplashIconContainerWidget : public QWidget
{
Q_OBJECT
public:
explicit SplashIconContainerWidget(QWidget *parent,
TextEditor::TextEditorWidget *textEditorWidget);
void loadImages();
bool hasImages();
bool hasPortraitImages();
bool hasLandscapeImages();
bool isSticky();
void setSticky(bool sticky);
signals:
void splashScreensModified();
private:
QVector<AndroidManifestEditorIconWidget *> m_imageButtons;
QVector<AndroidManifestEditorIconWidget *> m_portraitImageButtons;
QVector<AndroidManifestEditorIconWidget *> m_landscapeImageButtons;
bool m_splashScreenSticky = false;
QCheckBox *m_stickyCheck = nullptr;
};
} // namespace Internal
} // namespace Android