summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/android
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-11-24 13:37:06 +0100
committerFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-11-24 13:39:13 +0100
commit34aba4724f196e34ed02cf50073f41968f119bb6 (patch)
tree0ebdfcabda989ab76ee6de53c6461553c7a767a5 /src/plugins/platforms/android
parentb86b2a742afae118bf974c82ba966ddb0cae4afb (diff)
parentb1cf07f495e10c93e53651ac03e46ebdaea0a97e (diff)
Merge remote-tracking branch 'origin/5.4' into dev
Conflicts: src/corelib/io/qiodevice.cpp src/plugins/bearer/linux_common/qofonoservice_linux.cpp src/plugins/bearer/linux_common/qofonoservice_linux_p.h src/plugins/platforms/android/qandroidplatformtheme.cpp src/tools/bootstrap/bootstrap.pro src/widgets/styles/qmacstyle_mac.mm Change-Id: Ia02aab6c4598ce74e9c30bb4666d5e2ef000f99b
Diffstat (limited to 'src/plugins/platforms/android')
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp59
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp29
-rw-r--r--src/plugins/platforms/android/androidjnimain.h23
-rw-r--r--src/plugins/platforms/android/androidjnimenu.cpp27
-rw-r--r--src/plugins/platforms/android/androidjnimenu.h2
-rw-r--r--src/plugins/platforms/android/qandroidplatformclipboard.cpp5
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp22
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h6
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenu.cpp3
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp297
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.h16
11 files changed, 350 insertions, 139 deletions
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 536415339f..62da60ab92 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -48,10 +48,6 @@ using namespace QtAndroid;
namespace QtAndroidInput
{
- static jmethodID m_showSoftwareKeyboardMethodID = 0;
- static jmethodID m_resetSoftwareKeyboardMethodID = 0;
- static jmethodID m_hideSoftwareKeyboardMethodID = 0;
- static jmethodID m_updateSelectionMethodID = 0;
static bool m_ignoreMouseEvents = false;
static bool m_softwareKeyboardVisible = false;
@@ -62,30 +58,28 @@ namespace QtAndroidInput
void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd)
{
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << ">>> UPDATESELECTION" << selStart << selEnd << candidatesStart << candidatesEnd;
#endif
- env.jniEnv->CallStaticVoidMethod(applicationClass(), m_updateSelectionMethodID,
- selStart, selEnd, candidatesStart, candidatesEnd);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
+ "updateSelection",
+ "(IIII)V",
+ selStart,
+ selEnd,
+ candidatesStart,
+ candidatesEnd);
}
void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints)
{
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- env.jniEnv->CallStaticVoidMethod(applicationClass(),
- m_showSoftwareKeyboardMethodID,
- left,
- top,
- width,
- height,
- inputHints);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
+ "showSoftwareKeyboard",
+ "(IIIII)V",
+ left,
+ top,
+ width,
+ height,
+ inputHints);
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints;
#endif
@@ -93,11 +87,7 @@ namespace QtAndroidInput
void resetSoftwareKeyboard()
{
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- env.jniEnv->CallStaticVoidMethod(applicationClass(), m_resetSoftwareKeyboardMethodID);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "resetSoftwareKeyboard");
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ RESETSOFTWAREKEYBOARD";
#endif
@@ -105,11 +95,7 @@ namespace QtAndroidInput
void hideSoftwareKeyboard()
{
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- env.jniEnv->CallStaticVoidMethod(applicationClass(), m_hideSoftwareKeyboardMethodID);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "hideSoftwareKeyboard");
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ HIDESOFTWAREKEYBOARD";
#endif
@@ -722,13 +708,6 @@ namespace QtAndroidInput
{"keyboardVisibilityChanged", "(Z)V", (void *)keyboardVisibilityChanged}
};
-#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
- VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
- if (!VAR) { \
- __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
- return false; \
- }
-
bool registerNatives(JNIEnv *env)
{
jclass appClass = QtAndroid::applicationClass();
@@ -738,10 +717,6 @@ namespace QtAndroidInput
return false;
}
- GET_AND_CHECK_STATIC_METHOD(m_showSoftwareKeyboardMethodID, appClass, "showSoftwareKeyboard", "(IIIII)V");
- GET_AND_CHECK_STATIC_METHOD(m_resetSoftwareKeyboardMethodID, appClass, "resetSoftwareKeyboard", "()V");
- GET_AND_CHECK_STATIC_METHOD(m_hideSoftwareKeyboardMethodID, appClass, "hideSoftwareKeyboard", "()V");
- GET_AND_CHECK_STATIC_METHOD(m_updateSelectionMethodID, appClass, "updateSelection", "(IIII)V");
return true;
}
}
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 235e004904..df0a8c56cb 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -80,7 +80,6 @@ static jmethodID m_createBitmapMethodID = Q_NULLPTR;
static jobject m_ARGB_8888_BitmapConfigValue = Q_NULLPTR;
static jobject m_RGB_565_BitmapConfigValue = Q_NULLPTR;
-jmethodID m_setFullScreenMethodID = Q_NULLPTR;
static bool m_statusBarShowing = true;
static jclass m_bitmapDrawableClass = Q_NULLPTR;
@@ -182,13 +181,7 @@ namespace QtAndroid
if (m_statusBarShowing)
return;
- QtAndroid::AttachedJNIEnv env;
- if (!env.jniEnv) {
- qWarning("Failed to get JNI Environment.");
- return;
- }
-
- env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, false);
+ QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "setFullScreen", "(Z)V", false);
m_statusBarShowing = true;
}
@@ -197,13 +190,7 @@ namespace QtAndroid
if (!m_statusBarShowing)
return;
- QtAndroid::AttachedJNIEnv env;
- if (!env.jniEnv) {
- qWarning("Failed to get JNI Environment.");
- return;
- }
-
- env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, true);
+ QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "setFullScreen", "(Z)V", true);
m_statusBarShowing = false;
}
@@ -453,16 +440,9 @@ static void *startMainMethod(void */*data*/)
if (res < 0)
qWarning() << "dlclose failed:" << dlerror();
}
- m_mainLibraryHnd = Q_NULLPTR;
- m_main = Q_NULLPTR;
- QtAndroid::AttachedJNIEnv env;
- if (!env.jniEnv)
- return 0;
- if (m_applicationClass) {
- jmethodID quitApp = env.jniEnv->GetStaticMethodID(m_applicationClass, "quitApp", "()V");
- env.jniEnv->CallStaticVoidMethod(m_applicationClass, quitApp);
- }
+ if (m_applicationClass)
+ QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "quitApp", "()V");
return 0;
}
@@ -723,7 +703,6 @@ static int registerNatives(JNIEnv *env)
jclass clazz;
FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNative");
m_applicationClass = static_cast<jclass>(env->NewGlobalRef(clazz));
- GET_AND_CHECK_STATIC_METHOD(m_setFullScreenMethodID, m_applicationClass, "setFullScreen", "(Z)V");
if (env->RegisterNatives(m_applicationClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
__android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index 01330ce283..8cf9274857 100644
--- a/src/plugins/platforms/android/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -85,29 +85,6 @@ namespace QtAndroid
jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env);
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0);
- struct AttachedJNIEnv
- {
- AttachedJNIEnv()
- {
- attached = false;
- if (QtAndroid::javaVM()->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) {
- if (QtAndroid::javaVM()->AttachCurrentThread(&jniEnv, NULL) < 0) {
- __android_log_print(ANDROID_LOG_ERROR, "Qt", "AttachCurrentThread failed");
- jniEnv = Q_NULLPTR;
- return;
- }
- attached = true;
- }
- }
-
- ~AttachedJNIEnv()
- {
- if (attached)
- QtAndroid::javaVM()->DetachCurrentThread();
- }
- bool attached;
- JNIEnv *jniEnv;
- };
const char *classErrorMsgFmt();
const char *methodErrorMsgFmt();
const char *qtTagText();
diff --git a/src/plugins/platforms/android/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp
index 1251bbf193..36c349f6b4 100644
--- a/src/plugins/platforms/android/androidjnimenu.cpp
+++ b/src/plugins/platforms/android/androidjnimenu.cpp
@@ -44,6 +44,7 @@
#include <QSet>
#include <QWindow>
#include <QtCore/private/qjnihelpers_p.h>
+#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
@@ -61,9 +62,6 @@ namespace QtAndroidMenu
static QMutex menuBarMutex(QMutex::Recursive);
static jmethodID openContextMenuMethodID = 0;
- static jmethodID closeContextMenuMethodID = 0;
- static jmethodID resetOptionsMenuMethodID = 0;
- static jmethodID openOptionsMenuMethodID = 0;
static jmethodID clearMenuMethodID = 0;
static jmethodID addMenuItemMethodID = 0;
@@ -78,16 +76,12 @@ namespace QtAndroidMenu
void resetMenuBar()
{
- AttachedJNIEnv env;
- if (env.jniEnv)
- env.jniEnv->CallStaticVoidMethod(applicationClass(), resetOptionsMenuMethodID);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "resetOptionsMenu");
}
void openOptionsMenu()
{
- AttachedJNIEnv env;
- if (env.jniEnv)
- env.jniEnv->CallStaticVoidMethod(applicationClass(), openOptionsMenuMethodID);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "openOptionsMenu");
}
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env)
@@ -103,22 +97,14 @@ namespace QtAndroidMenu
visibleMenu = menu;
menu->aboutToShow();
- if (env) {
- env->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
- } else {
- AttachedJNIEnv aenv;
- if (aenv.jniEnv)
- aenv.jniEnv->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
- }
+ env->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
}
void hideContextMenu(QAndroidPlatformMenu *menu)
{
QMutexLocker lock(&visibleMenuMutex);
if (visibleMenu == menu) {
- AttachedJNIEnv env;
- if (env.jniEnv)
- env.jniEnv->CallStaticVoidMethod(applicationClass(), closeContextMenuMethodID);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "closeContextMenu");
pendingContextMenus.clear();
} else {
pendingContextMenus.removeOne(menu);
@@ -430,9 +416,6 @@ namespace QtAndroidMenu
}
GET_AND_CHECK_STATIC_METHOD(openContextMenuMethodID, appClass, "openContextMenu", "(IIII)V");
- GET_AND_CHECK_STATIC_METHOD(closeContextMenuMethodID, appClass, "closeContextMenu", "()V");
- GET_AND_CHECK_STATIC_METHOD(resetOptionsMenuMethodID, appClass, "resetOptionsMenu", "()V");
- GET_AND_CHECK_STATIC_METHOD(openOptionsMenuMethodID, appClass, "openOptionsMenu", "()V");
jclass clazz;
FIND_AND_CHECK_CLASS("android/view/Menu");
diff --git a/src/plugins/platforms/android/androidjnimenu.h b/src/plugins/platforms/android/androidjnimenu.h
index c54eb37f37..f85db9ff86 100644
--- a/src/plugins/platforms/android/androidjnimenu.h
+++ b/src/plugins/platforms/android/androidjnimenu.h
@@ -50,7 +50,7 @@ namespace QtAndroidMenu
{
// Menu support
void openOptionsMenu();
- void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env = 0);
+ void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env);
void hideContextMenu(QAndroidPlatformMenu *menu);
void syncMenu(QAndroidPlatformMenu *menu);
void androidPlatformMenuDestroyed(QAndroidPlatformMenu *menu);
diff --git a/src/plugins/platforms/android/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/qandroidplatformclipboard.cpp
index fb73db8455..2605ec9901 100644
--- a/src/plugins/platforms/android/qandroidplatformclipboard.cpp
+++ b/src/plugins/platforms/android/qandroidplatformclipboard.cpp
@@ -44,6 +44,7 @@ QAndroidPlatformClipboard::QAndroidPlatformClipboard()
QMimeData *QAndroidPlatformClipboard::mimeData(QClipboard::Mode mode)
{
+ Q_UNUSED(mode);
Q_ASSERT(supportsMode(mode));
m_mimeData.setText(QtAndroidClipboard::hasClipboardText()
? QtAndroidClipboard::clipboardText()
@@ -53,8 +54,8 @@ QMimeData *QAndroidPlatformClipboard::mimeData(QClipboard::Mode mode)
void QAndroidPlatformClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
{
- Q_ASSERT(supportsMode(mode));
- QtAndroidClipboard::setClipboardText(data != 0 && data->hasText() ? data->text() : QString());
+ if (supportsMode(mode))
+ QtAndroidClipboard::setClipboardText(data != 0 && data->hasText() ? data->text() : QString());
if (data != 0)
data->deleteLater();
}
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 8a3a958d3b..07bdf95bf4 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -78,10 +78,24 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA
return QtAndroid::javaVM();
if (resource == "QtActivity")
return QtAndroid::activity();
- if (resource == "AndroidStylePalettes")
- return &m_palettes;
- if (resource == "AndroidStyleFonts")
- return &m_fonts;
+ if (resource == "AndroidStyleData") {
+ if (m_androidStyle)
+ return &m_androidStyle->m_styleData;
+ else
+ return Q_NULLPTR;
+ }
+ if (resource == "AndroidStandardPalette") {
+ if (m_androidStyle)
+ return &m_androidStyle->m_standardPalette;
+ else
+ return Q_NULLPTR;
+ }
+ if (resource == "AndroidQWidgetFonts") {
+ if (m_androidStyle)
+ return &m_androidStyle->m_QWidgetsFonts;
+ else
+ return Q_NULLPTR;
+ }
if (resource == "AndroidDeviceName") {
static QString deviceName = QtAndroid::deviceName();
return &deviceName;
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index 13c98442e9..7b4ab08847 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -44,6 +44,8 @@
#include "qandroidplatformscreen.h"
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QDesktopWidget;
@@ -51,12 +53,12 @@ class QAndroidPlatformServices;
class QAndroidSystemLocale;
class QPlatformAccessibility;
+struct AndroidStyle;
class QAndroidPlatformNativeInterface: public QPlatformNativeInterface
{
public:
void *nativeResourceForIntegration(const QByteArray &resource);
- QHash<int, QPalette> m_palettes;
- QHash<int, QFont> m_fonts;
+ std::shared_ptr<AndroidStyle> m_androidStyle;
};
class QAndroidPlatformIntegration : public QPlatformIntegration
diff --git a/src/plugins/platforms/android/qandroidplatformmenu.cpp b/src/plugins/platforms/android/qandroidplatformmenu.cpp
index f3505fac3c..8f992f6bea 100644
--- a/src/plugins/platforms/android/qandroidplatformmenu.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenu.cpp
@@ -34,6 +34,7 @@
#include "qandroidplatformmenu.h"
#include "qandroidplatformmenuitem.h"
#include "androidjnimenu.h"
+#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
@@ -140,7 +141,7 @@ void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &t
Q_UNUSED(parentWindow);
Q_UNUSED(item);
setVisible(true);
- QtAndroidMenu::showContextMenu(this, targetRect);
+ QtAndroidMenu::showContextMenu(this, targetRect, QJNIEnvironmentPrivate());
}
QPlatformMenuItem *QAndroidPlatformMenu::menuItemAt(int position) const
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index 914de9d270..b955cff44d 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -37,17 +37,281 @@
#include "qandroidplatformmenu.h"
#include "qandroidplatformmenuitem.h"
#include "qandroidplatformdialoghelpers.h"
-#include <QVariant>
-#include <QFileInfo>
+
#include <QCoreApplication>
+#include <QDebug>
+#include <QFileInfo>
+#include <QJsonDocument>
+#include <QVariant>
+
#include <private/qguiapplication_p.h>
#include <qandroidplatformintegration.h>
QT_BEGIN_NAMESPACE
+namespace {
+ const int textStyle_bold = 1;
+ const int textStyle_italic = 2;
+
+ const int typeface_sans = 1;
+ const int typeface_serif = 2;
+ const int typeface_monospace = 3;
+}
+
+static int fontType(const QString &androidControl)
+{
+ if (androidControl == QLatin1String("defaultStyle"))
+ return QPlatformTheme::SystemFont;
+ if (androidControl == QLatin1String("textViewStyle"))
+ return QPlatformTheme::LabelFont;
+ else if (androidControl == QLatin1String("buttonStyle"))
+ return QPlatformTheme::PushButtonFont;
+ else if (androidControl == QLatin1String("checkboxStyle"))
+ return QPlatformTheme::CheckBoxFont;
+ else if (androidControl == QLatin1String("radioButtonStyle"))
+ return QPlatformTheme::RadioButtonFont;
+ else if (androidControl == QLatin1String("simple_list_item_single_choice"))
+ return QPlatformTheme::ItemViewFont;
+ else if (androidControl == QLatin1String("simple_spinner_dropdown_item"))
+ return QPlatformTheme::ComboMenuItemFont;
+ else if (androidControl == QLatin1String("spinnerStyle"))
+ return QPlatformTheme::ComboLineEditFont;
+ else if (androidControl == QLatin1String("simple_list_item"))
+ return QPlatformTheme::ListViewFont;
+ return -1;
+}
+
+static int paletteType(const QString &androidControl)
+{
+ if (androidControl == QLatin1String("defaultStyle"))
+ return QPlatformTheme::SystemPalette;
+ if (androidControl == QLatin1String("textViewStyle"))
+ return QPlatformTheme::LabelPalette;
+ else if (androidControl == QLatin1String("buttonStyle"))
+ return QPlatformTheme::ButtonPalette;
+ else if (androidControl == QLatin1String("checkboxStyle"))
+ return QPlatformTheme::CheckBoxPalette;
+ else if (androidControl == QLatin1String("radioButtonStyle"))
+ return QPlatformTheme::RadioButtonPalette;
+ else if (androidControl == QLatin1String("simple_list_item_single_choice"))
+ return QPlatformTheme::ItemViewPalette;
+ else if (androidControl == QLatin1String("editTextStyle"))
+ return QPlatformTheme::TextLineEditPalette;
+ else if (androidControl == QLatin1String("spinnerStyle"))
+ return QPlatformTheme::ComboBoxPalette;
+ return -1;
+}
+
+static void setPaletteColor(const QVariantMap &object,
+ QPalette &palette,
+ QPalette::ColorRole role)
+{
+ // QPalette::Active -> ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET
+ palette.setColor(QPalette::Active,
+ role,
+ QRgb(object.value(QLatin1String("ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET")).toInt()));
+
+ // QPalette::Inactive -> ENABLED_STATE_SET
+ palette.setColor(QPalette::Inactive,
+ role,
+ QRgb(object.value(QLatin1String("ENABLED_STATE_SET")).toInt()));
+
+ // QPalette::Disabled -> EMPTY_STATE_SET
+ palette.setColor(QPalette::Disabled,
+ role,
+ QRgb(object.value(QLatin1String("EMPTY_STATE_SET")).toInt()));
+
+ palette.setColor(QPalette::Current, role, palette.color(QPalette::Active, role));
+
+ if (role == QPalette::WindowText) {
+ // QPalette::BrightText -> PRESSED
+ // QPalette::Active -> PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET
+ palette.setColor(QPalette::Active,
+ QPalette::BrightText,
+ QRgb(object.value(QLatin1String("PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET")).toInt()));
+
+ // QPalette::Inactive -> PRESSED_ENABLED_STATE_SET
+ palette.setColor(QPalette::Inactive,
+ QPalette::BrightText,
+ QRgb(object.value(QLatin1String("PRESSED_ENABLED_STATE_SET")).toInt()));
+
+ // QPalette::Disabled -> PRESSED_STATE_SET
+ palette.setColor(QPalette::Disabled,
+ QPalette::BrightText,
+ QRgb(object.value(QLatin1String("PRESSED_STATE_SET")).toInt()));
+
+ palette.setColor(QPalette::Current, QPalette::BrightText, palette.color(QPalette::Active, QPalette::BrightText));
+
+ // QPalette::HighlightedText -> SELECTED
+ // QPalette::Active -> ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET
+ palette.setColor(QPalette::Active,
+ QPalette::HighlightedText,
+ QRgb(object.value(QLatin1String("ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET")).toInt()));
+
+ // QPalette::Inactive -> ENABLED_SELECTED_STATE_SET
+ palette.setColor(QPalette::Inactive,
+ QPalette::HighlightedText,
+ QRgb(object.value(QLatin1String("ENABLED_SELECTED_STATE_SET")).toInt()));
+
+ // QPalette::Disabled -> SELECTED_STATE_SET
+ palette.setColor(QPalette::Disabled,
+ QPalette::HighlightedText,
+ QRgb(object.value(QLatin1String("SELECTED_STATE_SET")).toInt()));
+
+ palette.setColor(QPalette::Current,
+ QPalette::HighlightedText,
+ palette.color(QPalette::Active, QPalette::HighlightedText));
+
+ // Same colors for Text
+ palette.setColor(QPalette::Active, QPalette::Text, palette.color(QPalette::Active, role));
+ palette.setColor(QPalette::Inactive, QPalette::Text, palette.color(QPalette::Inactive, role));
+ palette.setColor(QPalette::Disabled, QPalette::Text, palette.color(QPalette::Disabled, role));
+ palette.setColor(QPalette::Current, QPalette::Text, palette.color(QPalette::Current, role));
+
+ // And for ButtonText
+ palette.setColor(QPalette::Active, QPalette::ButtonText, palette.color(QPalette::Active, role));
+ palette.setColor(QPalette::Inactive, QPalette::ButtonText, palette.color(QPalette::Inactive, role));
+ palette.setColor(QPalette::Disabled, QPalette::ButtonText, palette.color(QPalette::Disabled, role));
+ palette.setColor(QPalette::Current, QPalette::ButtonText, palette.color(QPalette::Current, role));
+ }
+}
+
+static std::shared_ptr<AndroidStyle> loadAndroidStyle(QPalette *defaultPalette)
+{
+ QString stylePath(QLatin1String(qgetenv("MINISTRO_ANDROID_STYLE_PATH")));
+ const QLatin1Char slashChar('/');
+ if (!stylePath.isEmpty() && !stylePath.endsWith(slashChar))
+ stylePath += slashChar;
+
+ QString androidTheme = QLatin1String(qgetenv("QT_ANDROID_THEME"));
+ if (!androidTheme.isEmpty() && !androidTheme.endsWith(slashChar))
+ androidTheme += slashChar;
+
+ if (stylePath.isEmpty()) {
+ stylePath = QLatin1String("/data/data/org.kde.necessitas.ministro/files/dl/style/")
+ + QLatin1String(qgetenv("QT_ANDROID_THEME_DISPLAY_DPI")) + slashChar;
+ }
+ Q_ASSERT(!stylePath.isEmpty());
+
+ if (!androidTheme.isEmpty() && QFileInfo(stylePath + androidTheme + QLatin1String("style.json")).exists())
+ stylePath += androidTheme;
+
+ QFile f(stylePath + QLatin1String("style.json"));
+ if (!f.open(QIODevice::ReadOnly))
+ return std::shared_ptr<AndroidStyle>();
+
+ QJsonParseError error;
+ QJsonDocument document = QJsonDocument::fromJson(f.readAll(), &error);
+ if (document.isNull()) {
+ qCritical() << error.errorString();
+ return std::shared_ptr<AndroidStyle>();
+ }
+
+ if (!document.isObject()) {
+ qCritical() << "Style.json does not contain a valid style.";
+ return std::shared_ptr<AndroidStyle>();
+ }
+ std::shared_ptr<AndroidStyle> style(new AndroidStyle);
+ style->m_styleData = document.object();
+ for (QJsonObject::const_iterator objectIterator = style->m_styleData.constBegin();
+ objectIterator != style->m_styleData.constEnd();
+ ++objectIterator) {
+ QString key = objectIterator.key();
+ QJsonValue value = objectIterator.value();
+ if (!value.isObject()) {
+ qWarning("Style.json structure is unrecognized.");
+ continue;
+ }
+ QJsonObject item = value.toObject();
+ QJsonObject::const_iterator attributeIterator = item.find(QLatin1String("qtClass"));
+ QByteArray qtClassName;
+ if (attributeIterator != item.constEnd()) {
+ // The item has palette and font information for a specific Qt Class (e.g. QWidget, QPushButton, etc.)
+ qtClassName = attributeIterator.value().toString().toLatin1();
+ }
+ const int ft = fontType(key);
+ if (ft > -1 || !qtClassName.isEmpty()) {
+ // Extract font information
+ QFont font;
+
+ // Font size (in pixels)
+ attributeIterator = item.find(QLatin1String("TextAppearance_textSize"));
+ if (attributeIterator != item.constEnd())
+ font.setPixelSize(int(attributeIterator.value().toDouble()));
+
+ // Font style
+ attributeIterator = item.find(QLatin1String("TextAppearance_textStyle"));
+ if (attributeIterator != item.constEnd()) {
+ const int style = int(attributeIterator.value().toDouble());
+ font.setBold(style & textStyle_bold);
+ font.setItalic(style & textStyle_italic);
+ }
+
+ // Font typeface
+ attributeIterator = item.find(QLatin1String("TextAppearance_typeface"));
+ if (attributeIterator != item.constEnd()) {
+ QFont::StyleHint styleHint = QFont::AnyStyle;
+ switch (int(attributeIterator.value().toDouble())) {
+ case typeface_sans:
+ styleHint = QFont::SansSerif;
+ break;
+ case typeface_serif:
+ styleHint = QFont::Serif;
+ break;
+ case typeface_monospace:
+ styleHint = QFont::Monospace;
+ break;
+ }
+ font.setStyleHint(styleHint, QFont::PreferMatch);
+ }
+ if (!qtClassName.isEmpty())
+ style->m_QWidgetsFonts.insert(qtClassName, font);
+
+ if (ft > -1) {
+ style->m_fonts.insert(ft, font);
+ if (ft == QPlatformTheme::SystemFont)
+ QGuiApplication::setFont(font);
+ }
+ // Extract font information
+ }
+
+ const int pt = paletteType(key);
+ if (pt > -1 || !qtClassName.isEmpty()) {
+ // Extract palette information
+ QPalette palette;
+ attributeIterator = item.find(QLatin1String("defaultTextColorPrimary"));
+ if (attributeIterator != item.constEnd())
+ palette.setColor(QPalette::WindowText, QRgb(int(attributeIterator.value().toDouble())));
+
+ attributeIterator = item.find(QLatin1String("defaultBackgroundColor"));
+ if (attributeIterator != item.constEnd())
+ palette.setColor(QPalette::Background, QRgb(int(attributeIterator.value().toDouble())));
+
+ attributeIterator = item.find(QLatin1String("TextAppearance_textColor"));
+ if (attributeIterator != item.constEnd())
+ setPaletteColor(attributeIterator.value().toObject().toVariantMap(), palette, QPalette::WindowText);
+
+ attributeIterator = item.find(QLatin1String("TextAppearance_textColorLink"));
+ if (attributeIterator != item.constEnd())
+ setPaletteColor(attributeIterator.value().toObject().toVariantMap(), palette, QPalette::Link);
+
+ attributeIterator = item.find(QLatin1String("TextAppearance_textColorHighlight"));
+ if (attributeIterator != item.constEnd())
+ palette.setColor(QPalette::Highlight, QRgb(int(attributeIterator.value().toDouble())));
+
+ if (pt == QPlatformTheme::SystemPalette)
+ *defaultPalette = style->m_standardPalette = palette;
+
+ if (pt > -1)
+ style->m_palettes.insert(pt, palette);
+ // Extract palette information
+ }
+ }
+ return style;
+}
+
QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *androidPlatformNativeInterface)
{
- m_androidPlatformNativeInterface = androidPlatformNativeInterface;
QColor background(229, 229, 229);
QColor light = background.lighter(150);
QColor mid(background.darker(130));
@@ -80,6 +344,9 @@ QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *an
m_defaultPalette.setBrush(QPalette::Active, QPalette::Highlight, highlight);
m_defaultPalette.setBrush(QPalette::Inactive, QPalette::Highlight, highlight);
m_defaultPalette.setBrush(QPalette::Disabled, QPalette::Highlight, highlight.lighter(150));
+ m_androidStyleData = loadAndroidStyle(&m_defaultPalette);
+ QGuiApplication::setPalette(m_defaultPalette);
+ androidPlatformNativeInterface->m_androidStyle = m_androidStyleData;
}
QPlatformMenuBar *QAndroidPlatformTheme::createPlatformMenuBar() const
@@ -132,9 +399,11 @@ static inline int paletteType(QPlatformTheme::Palette type)
const QPalette *QAndroidPlatformTheme::palette(Palette type) const
{
- QHash<int, QPalette>::const_iterator it = m_androidPlatformNativeInterface->m_palettes.find(paletteType(type));
- if (it != m_androidPlatformNativeInterface->m_palettes.end())
- return &(it.value());
+ if (m_androidStyleData) {
+ auto it = m_androidStyleData->m_palettes.find(paletteType(type));
+ if (it != m_androidStyleData->m_palettes.end())
+ return &(it.value());
+ }
return &m_defaultPalette;
}
@@ -154,9 +423,11 @@ static inline int fontType(QPlatformTheme::Font type)
const QFont *QAndroidPlatformTheme::font(Font type) const
{
- QHash<int, QFont>::const_iterator it = m_androidPlatformNativeInterface->m_fonts.find(fontType(type));
- if (it != m_androidPlatformNativeInterface->m_fonts.end())
- return &(it.value());
+ if (m_androidStyleData) {
+ auto it = m_androidStyleData->m_fonts.find(fontType(type));
+ if (it != m_androidStyleData->m_fonts.end())
+ return &(it.value());
+ }
// default in case the style has not set a font
static QFont systemFont("Roboto", 14.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi
@@ -165,18 +436,12 @@ const QFont *QAndroidPlatformTheme::font(Font type) const
return 0;
}
-static const QLatin1String STYLES_PATH("/data/data/org.kde.necessitas.ministro/files/dl/style/");
-static const QLatin1String STYLE_FILE("/style.json");
-
QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const
{
switch (hint) {
case StyleNames:
if (qEnvironmentVariableIntValue("QT_USE_ANDROID_NATIVE_STYLE")
- && (!qgetenv("MINISTRO_ANDROID_STYLE_PATH").isEmpty()
- || QFileInfo(STYLES_PATH
- + QLatin1String(qgetenv("QT_ANDROID_THEME_DISPLAY_DPI"))
- + STYLE_FILE).exists())) {
+ && m_androidStyleData) {
return QStringList("android");
}
return QStringList("fusion");
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.h b/src/plugins/platforms/android/qandroidplatformtheme.h
index 01611bf9d4..334e86ad7a 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.h
+++ b/src/plugins/platforms/android/qandroidplatformtheme.h
@@ -37,8 +37,22 @@
#include <qpa/qplatformtheme.h>
#include <QtGui/qpalette.h>
+#include <QJsonObject>
+
+#include <memory>
+
QT_BEGIN_NAMESPACE
+struct AndroidStyle
+{
+ QJsonObject m_styleData;
+ QPalette m_standardPalette;
+ QHash<int, QPalette> m_palettes;
+ QHash<int, QFont> m_fonts;
+ QHash<QByteArray, QFont> m_QWidgetsFonts;
+ QHash<QByteArray, QFont> m_QWidgetsPalettes;
+};
+
class QAndroidPlatformNativeInterface;
class QAndroidPlatformTheme: public QPlatformTheme
{
@@ -57,7 +71,7 @@ public:
private:
- QAndroidPlatformNativeInterface * m_androidPlatformNativeInterface;
+ std::shared_ptr<AndroidStyle> m_androidStyleData;
QPalette m_defaultPalette;
};