summaryrefslogtreecommitdiffstats
path: root/src/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/android')
-rw-r--r--src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java17
-rw-r--r--src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java2
-rw-r--r--src/android/android.pro2
-rw-r--r--src/android/jar/jar.pri3
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java1778
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java63
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java10
-rw-r--r--src/android/java/java.pro4
-rw-r--r--src/android/java/res/values/strings.xml3
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java22
-rw-r--r--src/android/java/version.xml8
-rw-r--r--src/android/templates/AndroidManifest.xml (renamed from src/android/java/AndroidManifest.xml)12
-rw-r--r--src/android/templates/build.gradle51
-rw-r--r--src/android/templates/res/values/libs.xml (renamed from src/android/java/res/values/libs.xml)0
-rw-r--r--src/android/templates/templates.pro21
15 files changed, 1948 insertions, 48 deletions
diff --git a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java
index 3275b90e33..a4626b9bb1 100644
--- a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java
+++ b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java
@@ -346,13 +346,24 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
{
// Log.i(TAG, "ACTION " + action + " on " + virtualViewId);
// dumpNodes(virtualViewId);
+ boolean success = false;
switch (action) {
case AccessibilityNodeInfo.ACTION_CLICK:
- boolean success = QtNativeAccessibility.clickAction(virtualViewId);
+ success = QtNativeAccessibility.clickAction(virtualViewId);
if (success)
sendEventForVirtualViewId(virtualViewId, AccessibilityEvent.TYPE_VIEW_CLICKED);
- return success;
+ break;
+ case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
+ success = QtNativeAccessibility.scrollForward(virtualViewId);
+ if (success)
+ sendEventForVirtualViewId(virtualViewId, AccessibilityEvent.TYPE_VIEW_SCROLLED);
+ break;
+ case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
+ success = QtNativeAccessibility.scrollBackward(virtualViewId);
+ if (success)
+ sendEventForVirtualViewId(virtualViewId, AccessibilityEvent.TYPE_VIEW_SCROLLED);
+ break;
}
- return false;
+ return success;
}
}
diff --git a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java
index 8a53623957..f0bf4a0897 100644
--- a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java
+++ b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java
@@ -53,6 +53,8 @@ class QtNativeAccessibility
static native Rect screenRect(int objectId);
static native int hitTest(float x, float y);
static native boolean clickAction(int objectId);
+ static native boolean scrollForward(int objectId);
+ static native boolean scrollBackward(int objectId);
static native boolean populateNode(int objectId, AccessibilityNodeInfo node);
}
diff --git a/src/android/android.pro b/src/android/android.pro
index 1850f012c0..55a94a2c06 100644
--- a/src/android/android.pro
+++ b/src/android/android.pro
@@ -1,2 +1,2 @@
TEMPLATE = subdirs
-SUBDIRS = jar java accessibility
+SUBDIRS = jar java templates accessibility
diff --git a/src/android/jar/jar.pri b/src/android/jar/jar.pri
index 5906231c73..66feda1d56 100644
--- a/src/android/jar/jar.pri
+++ b/src/android/jar/jar.pri
@@ -12,7 +12,8 @@ JAVASOURCES += \
$$PATHPREFIX/QtMessageDialogHelper.java \
$$PATHPREFIX/QtNative.java \
$$PATHPREFIX/QtNativeLibrariesDir.java \
- $$PATHPREFIX/QtSurface.java
+ $$PATHPREFIX/QtSurface.java \
+ $$PATHPREFIX/ExtractStyle.java
# install
target.path = $$[QT_INSTALL_PREFIX]/jar
diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
new file mode 100644
index 0000000000..68e8b26cb1
--- /dev/null
+++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
@@ -0,0 +1,1778 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Android port of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+package org.qtproject.qt5.android;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.xmlpull.v1.XmlPullParser;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.graphics.NinePatch;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ClipDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.GradientDrawable.Orientation;
+import android.graphics.drawable.LayerDrawable;
+import android.graphics.drawable.NinePatchDrawable;
+import android.graphics.drawable.RotateDrawable;
+import android.graphics.drawable.ScaleDrawable;
+import android.graphics.drawable.StateListDrawable;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+import android.view.inputmethod.EditorInfo;
+
+
+public class ExtractStyle {
+
+ native static int[] extractChunkInfo(byte[] chunkData);
+ native static int[] extractNativeChunkInfo(int nativeChunk);
+ native static int[] extractChunkInfo20(byte[] chunkData);
+ native static int[] extractNativeChunkInfo20(long nativeChunk);
+
+
+ Class<?> styleableClass = getStylableClass();
+ final int[] EMPTY_STATE_SET = {};
+ final int[] ENABLED_STATE_SET = {android.R.attr.state_enabled};
+ final int[] FOCUSED_STATE_SET = {android.R.attr.state_focused};
+ final int[] SELECTED_STATE_SET = {android.R.attr.state_selected};
+ final int[] PRESSED_STATE_SET = {android.R.attr.state_pressed};
+ final int[] WINDOW_FOCUSED_STATE_SET = {android.R.attr.state_window_focused};
+ final int[] ENABLED_FOCUSED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, FOCUSED_STATE_SET);
+ final int[] ENABLED_SELECTED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, SELECTED_STATE_SET);
+ final int[] ENABLED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] FOCUSED_SELECTED_STATE_SET = stateSetUnion(FOCUSED_STATE_SET, SELECTED_STATE_SET);
+ final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] ENABLED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(ENABLED_FOCUSED_STATE_SET, SELECTED_STATE_SET);
+ final int[] ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] PRESSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] PRESSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, SELECTED_STATE_SET);
+ final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] PRESSED_FOCUSED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, FOCUSED_STATE_SET);
+ final int[] PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] PRESSED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_FOCUSED_STATE_SET, SELECTED_STATE_SET);
+ final int[] PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] PRESSED_ENABLED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, ENABLED_STATE_SET);
+ final int[] PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] PRESSED_ENABLED_SELECTED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET, SELECTED_STATE_SET);
+ final int[] PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] PRESSED_ENABLED_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET, FOCUSED_STATE_SET);
+ final int[] PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+ final int[] PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_ENABLED_FOCUSED_STATE_SET, SELECTED_STATE_SET);
+ final int[] PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET);
+
+
+ final int View_background = getField(styleableClass,"View_background");
+ final int View_padding = getField(styleableClass,"View_padding");
+ final int View_paddingLeft = getField(styleableClass,"View_paddingLeft");
+ final int View_paddingTop = getField(styleableClass,"View_paddingTop");
+ final int View_paddingRight = getField(styleableClass,"View_paddingRight");
+ final int View_paddingBottom = getField(styleableClass,"View_paddingBottom");
+ final int View_scrollX = getField(styleableClass,"View_scrollX");
+ final int View_scrollY = getField(styleableClass,"View_scrollY");
+ final int View_id = getField(styleableClass,"View_id");
+ final int View_tag = getField(styleableClass,"View_tag");
+ final int View_fitsSystemWindows = getField(styleableClass,"View_fitsSystemWindows");
+ final int View_focusable = getField(styleableClass,"View_focusable");
+ final int View_focusableInTouchMode = getField(styleableClass,"View_focusableInTouchMode");
+ final int View_clickable = getField(styleableClass,"View_clickable");
+ final int View_longClickable = getField(styleableClass,"View_longClickable");
+ final int View_saveEnabled = getField(styleableClass,"View_saveEnabled");
+ final int View_duplicateParentState = getField(styleableClass,"View_duplicateParentState");
+ final int View_visibility = getField(styleableClass,"View_visibility");
+ final int View_drawingCacheQuality = getField(styleableClass,"View_drawingCacheQuality");
+ final int View_contentDescription = getField(styleableClass,"View_contentDescription");
+ final int View_soundEffectsEnabled = getField(styleableClass,"View_soundEffectsEnabled");
+ final int View_hapticFeedbackEnabled = getField(styleableClass,"View_hapticFeedbackEnabled");
+ final int View_scrollbars = getField(styleableClass,"View_scrollbars");
+ final int View_fadingEdge = getField(styleableClass,"View_fadingEdge");
+ final int View_scrollbarStyle = getField(styleableClass,"View_scrollbarStyle");
+ final int View_scrollbarFadeDuration = getField(styleableClass,"View_scrollbarFadeDuration");
+ final int View_scrollbarDefaultDelayBeforeFade = getField(styleableClass,"View_scrollbarDefaultDelayBeforeFade");
+ final int View_scrollbarSize = getField(styleableClass,"View_scrollbarSize");
+ final int View_scrollbarThumbHorizontal = getField(styleableClass,"View_scrollbarThumbHorizontal");
+ final int View_scrollbarThumbVertical = getField(styleableClass,"View_scrollbarThumbVertical");
+ final int View_scrollbarTrackHorizontal = getField(styleableClass,"View_scrollbarTrackHorizontal");
+ final int View_scrollbarTrackVertical = getField(styleableClass,"View_scrollbarTrackVertical");
+ final int View_isScrollContainer = getField(styleableClass,"View_isScrollContainer");
+ final int View_keepScreenOn = getField(styleableClass,"View_keepScreenOn");
+ final int View_filterTouchesWhenObscured = getField(styleableClass,"View_filterTouchesWhenObscured");
+ final int View_nextFocusLeft = getField(styleableClass,"View_nextFocusLeft");
+ final int View_nextFocusRight = getField(styleableClass,"View_nextFocusRight");
+ final int View_nextFocusUp = getField(styleableClass,"View_nextFocusUp");
+ final int View_nextFocusDown = getField(styleableClass,"View_nextFocusDown");
+ final int View_minWidth = getField(styleableClass,"View_minWidth");
+ final int View_minHeight = getField(styleableClass,"View_minHeight");
+ final int View_onClick = getField(styleableClass,"View_onClick");
+ final int View_overScrollMode = getField(styleableClass,"View_overScrollMode");
+ final int View_paddingStart = getField(styleableClass,"View_paddingStart");
+ final int View_paddingEnd = getField(styleableClass,"View_paddingEnd");
+
+ final int TextAppearance_textColorHighlight = getField(styleableClass,"TextAppearance_textColorHighlight");
+ final int TextAppearance_textColor = getField(styleableClass,"TextAppearance_textColor");
+ final int TextAppearance_textColorHint = getField(styleableClass,"TextAppearance_textColorHint");
+ final int TextAppearance_textColorLink = getField(styleableClass,"TextAppearance_textColorLink");
+ final int TextAppearance_textSize = getField(styleableClass,"TextAppearance_textSize");
+ final int TextAppearance_typeface = getField(styleableClass,"TextAppearance_typeface");
+ final int TextAppearance_textStyle = getField(styleableClass,"TextAppearance_textStyle");
+ final int TextAppearance_textAllCaps = getField(styleableClass,"TextAppearance_textAllCaps");
+ final int TextView_editable = getField(styleableClass,"TextView_editable");
+ final int TextView_inputMethod = getField(styleableClass,"TextView_inputMethod");
+ final int TextView_numeric = getField(styleableClass,"TextView_numeric");
+ final int TextView_digits = getField(styleableClass,"TextView_digits");
+ final int TextView_phoneNumber = getField(styleableClass,"TextView_phoneNumber");
+ final int TextView_autoText = getField(styleableClass,"TextView_autoText");
+ final int TextView_capitalize = getField(styleableClass,"TextView_capitalize");
+ final int TextView_bufferType = getField(styleableClass,"TextView_bufferType");
+ final int TextView_selectAllOnFocus = getField(styleableClass,"TextView_selectAllOnFocus");
+ final int TextView_autoLink = getField(styleableClass,"TextView_autoLink");
+ final int TextView_linksClickable = getField(styleableClass,"TextView_linksClickable");
+ final int TextView_drawableLeft = getField(styleableClass,"TextView_drawableLeft");
+ final int TextView_drawableTop = getField(styleableClass,"TextView_drawableTop");
+ final int TextView_drawableRight = getField(styleableClass,"TextView_drawableRight");
+ final int TextView_drawableBottom = getField(styleableClass,"TextView_drawableBottom");
+ final int TextView_drawableStart = getField(styleableClass,"TextView_drawableStart");
+ final int TextView_drawableEnd = getField(styleableClass,"TextView_drawableEnd");
+ final int TextView_drawablePadding = getField(styleableClass,"TextView_drawablePadding");
+ final int TextView_textCursorDrawable = getField(styleableClass,"TextView_textCursorDrawable");
+ final int TextView_maxLines = getField(styleableClass,"TextView_maxLines");
+ final int TextView_maxHeight = getField(styleableClass,"TextView_maxHeight");
+ final int TextView_lines = getField(styleableClass,"TextView_lines");
+ final int TextView_height = getField(styleableClass,"TextView_height");
+ final int TextView_minLines = getField(styleableClass,"TextView_minLines");
+ final int TextView_minHeight = getField(styleableClass,"TextView_minHeight");
+ final int TextView_maxEms = getField(styleableClass,"TextView_maxEms");
+ final int TextView_maxWidth = getField(styleableClass,"TextView_maxWidth");
+ final int TextView_ems = getField(styleableClass,"TextView_ems");
+ final int TextView_width = getField(styleableClass,"TextView_width");
+ final int TextView_minEms = getField(styleableClass,"TextView_minEms");
+ final int TextView_minWidth = getField(styleableClass,"TextView_minWidth");
+ final int TextView_gravity = getField(styleableClass,"TextView_gravity");
+ final int TextView_hint = getField(styleableClass,"TextView_hint");
+ final int TextView_text = getField(styleableClass,"TextView_text");
+ final int TextView_scrollHorizontally = getField(styleableClass,"TextView_scrollHorizontally");
+ final int TextView_singleLine = getField(styleableClass,"TextView_singleLine");
+ final int TextView_ellipsize = getField(styleableClass,"TextView_ellipsize");
+ final int TextView_marqueeRepeatLimit = getField(styleableClass,"TextView_marqueeRepeatLimit");
+ final int TextView_includeFontPadding = getField(styleableClass,"TextView_includeFontPadding");
+ final int TextView_cursorVisible = getField(styleableClass,"TextView_cursorVisible");
+ final int TextView_maxLength = getField(styleableClass,"TextView_maxLength");
+ final int TextView_textScaleX = getField(styleableClass,"TextView_textScaleX");
+ final int TextView_freezesText = getField(styleableClass,"TextView_freezesText");
+ final int TextView_shadowColor = getField(styleableClass,"TextView_shadowColor");
+ final int TextView_shadowDx = getField(styleableClass,"TextView_shadowDx");
+ final int TextView_shadowDy = getField(styleableClass,"TextView_shadowDy");
+ final int TextView_shadowRadius = getField(styleableClass,"TextView_shadowRadius");
+ final int TextView_enabled = getField(styleableClass,"TextView_enabled");
+ final int TextView_textColorHighlight = getField(styleableClass,"TextView_textColorHighlight");
+ final int TextView_textColor = getField(styleableClass,"TextView_textColor");
+ final int TextView_textColorHint = getField(styleableClass,"TextView_textColorHint");
+ final int TextView_textColorLink = getField(styleableClass,"TextView_textColorLink");
+ final int TextView_textSize = getField(styleableClass,"TextView_textSize");
+ final int TextView_typeface = getField(styleableClass,"TextView_typeface");
+ final int TextView_textStyle = getField(styleableClass,"TextView_textStyle");
+ final int TextView_password = getField(styleableClass,"TextView_password");
+ final int TextView_lineSpacingExtra = getField(styleableClass,"TextView_lineSpacingExtra");
+ final int TextView_lineSpacingMultiplier = getField(styleableClass,"TextView_lineSpacingMultiplier");
+ final int TextView_inputType = getField(styleableClass,"TextView_inputType");
+ final int TextView_imeOptions = getField(styleableClass,"TextView_imeOptions");
+ final int TextView_imeActionLabel = getField(styleableClass,"TextView_imeActionLabel");
+ final int TextView_imeActionId = getField(styleableClass,"TextView_imeActionId");
+ final int TextView_privateImeOptions = getField(styleableClass,"TextView_privateImeOptions");
+ final int TextView_textSelectHandleLeft = getField(styleableClass,"TextView_textSelectHandleLeft");
+ final int TextView_textSelectHandleRight = getField(styleableClass,"TextView_textSelectHandleRight");
+ final int TextView_textSelectHandle = getField(styleableClass,"TextView_textSelectHandle");
+ final int TextView_textIsSelectable = getField(styleableClass,"TextView_textIsSelectable");
+ final int TextView_textAllCaps = getField(styleableClass,"TextView_textAllCaps");
+
+ final int ImageView_src = getField(styleableClass,"ImageView_src");
+ final int ImageView_baselineAlignBottom = getField(styleableClass,"ImageView_baselineAlignBottom");
+ final int ImageView_adjustViewBounds = getField(styleableClass,"ImageView_adjustViewBounds");
+ final int ImageView_maxWidth = getField(styleableClass,"ImageView_maxWidth");
+ final int ImageView_maxHeight = getField(styleableClass,"ImageView_maxHeight");
+ final int ImageView_scaleType = getField(styleableClass,"ImageView_scaleType");
+ final int ImageView_tint = getField(styleableClass,"ImageView_tint");
+ final int ImageView_cropToPadding = getField(styleableClass,"ImageView_cropToPadding");
+
+ final Resources.Theme m_theme;
+ final String m_extractPath;
+ Context m_context;
+ final int defaultBackgroundColor;
+ final int defaultTextColor;
+
+ class SimpleJsonWriter
+ {
+ private OutputStreamWriter m_writer;
+ private boolean m_addComma = false;
+ private int m_indentLevel = 0;
+ public SimpleJsonWriter(String filePath) throws FileNotFoundException
+ {
+ m_writer = new OutputStreamWriter(new FileOutputStream(filePath));
+ }
+
+ public void close() throws IOException
+ {
+ m_writer.close();
+ }
+
+ private void writeIndent() throws IOException
+ {
+ m_writer.write(" ", 0, m_indentLevel);
+ }
+
+ SimpleJsonWriter beginObject() throws IOException
+ {
+ writeIndent();
+ m_writer.write("{\n");
+ ++m_indentLevel;
+ m_addComma = false;
+ return this;
+ }
+
+ SimpleJsonWriter endObject() throws IOException
+ {
+ m_writer.write("\n");
+ writeIndent();
+ m_writer.write("}\n");
+ --m_indentLevel;
+ m_addComma = false;
+ return this;
+ }
+
+ SimpleJsonWriter name(String name) throws IOException
+ {
+ if (m_addComma) {
+ m_writer.write(",\n");
+ }
+ writeIndent();
+ m_writer.write(JSONObject.quote(name) + ": ");
+ m_addComma = true;
+ return this;
+ }
+
+ SimpleJsonWriter value(JSONObject value) throws IOException
+ {
+ m_writer.write(value.toString());
+ return this;
+ }
+ }
+
+ class FakeCanvas extends Canvas {
+ int[] chunkData = null;
+ class Size {
+ public int s,e;
+ Size(int start, int end)
+ {
+ s=start;
+ e=end;
+ }
+ }
+
+ public boolean isHardwareAccelerated() {
+ return true;
+ }
+
+ public void drawPatch(Bitmap bmp, byte[] chunks, RectF dst, Paint paint) {
+ if (Build.VERSION.SDK_INT > 19)
+ chunkData = extractChunkInfo20(chunks);
+ else
+ chunkData = extractChunkInfo(chunks);
+ }
+ }
+
+
+
+ private int[] stateSetUnion(final int[] stateSet1, final int[] stateSet2)
+ {
+ try
+ {
+ final int stateSet1Length = stateSet1.length;
+ final int stateSet2Length = stateSet2.length;
+ final int[] newSet = new int[stateSet1Length + stateSet2Length];
+ int k = 0;
+ int i = 0;
+ int j = 0;
+ // This is a merge of the two input state sets and assumes that the
+ // input sets are sorted by the order imposed by ViewDrawableStates.
+ int[] viewDrawableStatesState=(int[]) styleableClass.getDeclaredField("ViewDrawableStates").get(null);
+ for (int viewState : viewDrawableStatesState)
+ {
+ if (i < stateSet1Length && stateSet1[i] == viewState)
+ {
+ newSet[k++] = viewState;
+ i++;
+ } else if (j < stateSet2Length && stateSet2[j] == viewState) {
+ newSet[k++] = viewState;
+ j++;
+ }
+ if (k > 1) {
+ assert(newSet[k - 1] > newSet[k - 2]);
+ }
+ }
+ return newSet;
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private Class<?> getStylableClass() {
+ try {
+ return Class.forName("android.R$styleable");
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ int getField(Class<?> clazz, String fieldName)
+ {
+ try {
+ return clazz.getDeclaredField(fieldName).getInt(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return -1;
+ }
+
+ JSONObject getColorStateList(ColorStateList colorList)
+ {
+ JSONObject json = new JSONObject();
+ try
+ {
+ json.put("EMPTY_STATE_SET", colorList.getColorForState(EMPTY_STATE_SET, 0));
+ json.put("WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("SELECTED_STATE_SET", colorList.getColorForState(SELECTED_STATE_SET, 0));
+ json.put("SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_STATE_SET, 0));
+ json.put("FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(FOCUSED_SELECTED_STATE_SET, 0));
+ json.put("FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("ENABLED_STATE_SET", colorList.getColorForState(ENABLED_STATE_SET, 0));
+ json.put("ENABLED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("ENABLED_SELECTED_STATE_SET", colorList.getColorForState(ENABLED_SELECTED_STATE_SET, 0));
+ json.put("ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("ENABLED_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_STATE_SET, 0));
+ json.put("ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("ENABLED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_SELECTED_STATE_SET, 0));
+ json.put("ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("PRESSED_STATE_SET", colorList.getColorForState(PRESSED_STATE_SET, 0));
+ json.put("PRESSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("PRESSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_SELECTED_STATE_SET, 0));
+ json.put("PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("PRESSED_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_STATE_SET, 0));
+ json.put("PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("PRESSED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_SELECTED_STATE_SET, 0));
+ json.put("PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("PRESSED_ENABLED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_STATE_SET, 0));
+ json.put("PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("PRESSED_ENABLED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_SELECTED_STATE_SET, 0));
+ json.put("PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("PRESSED_ENABLED_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_STATE_SET, 0));
+ json.put("PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0));
+ json.put("PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET, 0));
+ json.put("PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ return json;
+ }
+
+ final int [] DrawableStates ={android.R.attr.state_active, android.R.attr.state_checked
+ , android.R.attr.state_enabled, android.R.attr.state_focused
+ , android.R.attr.state_pressed, android.R.attr.state_selected
+ , android.R.attr.state_window_focused, 16908288, 16843597, 16843518, 16843547};
+ final String[] DrawableStatesLabels = {"active", "checked", "enabled", "focused", "pressed", "selected", "window_focused", "background", "multiline", "activated", "accelerated"};
+ final String[] DisableDrawableStatesLabels = {"inactive", "unchecked", "disabled", "not_focused", "no_pressed", "unselected", "window_not_focused", "background", "multiline", "activated", "accelerated"};
+
+ String getFileName(String file, String[] states)
+ {
+ for (String state: states)
+ file+="__"+state;
+ return file;
+ }
+
+ String getStatesName(String[] states)
+ {
+ String statesName="";
+ for (String state: states)
+ {
+ if (statesName.length()>0)
+ statesName+="__";
+ statesName += state;
+ }
+ return statesName;
+ }
+
+ void addDrawableItemIfNotExists(JSONObject json, ArrayList<Integer> list, Drawable item, String[] states, String filename)
+ {
+ for (Integer it : list)
+ {
+ if (it.equals(item.hashCode()))
+ return;
+ }
+ list.add(item.hashCode());
+ try {
+ json.put(getStatesName(states), getDrawable(item, getFileName(filename, states)));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+ void addSolution(String filename, JSONObject json, int c, Drawable drawable, ArrayList<Integer> drawableList, int u)
+ {
+ int pos=0;
+ int states[] = new int[c];
+ String [] statesText = new String[c];
+
+ for (int n= 0;u > 0;++n, u>>= 1)
+ if ((u & 1) > 0)
+ {
+ statesText[pos]=DrawableStatesLabels[n];
+ states[pos++]=DrawableStates[n];
+ }
+ drawable.setState(states);
+ addDrawableItemIfNotExists(json, drawableList, drawable.getCurrent(), statesText, filename);
+ }
+
+ int bitCount(int u)
+ {
+ int n;
+ for (n= 0;u > 0;++n, u&= (u - 1));
+ return n;
+ }
+
+ Object getStateListDrawable_old(Drawable drawable, String filename)
+ {
+ JSONObject json = new JSONObject();
+ ArrayList<Integer> drawableList= new ArrayList<Integer>();
+ drawable.setState(EMPTY_STATE_SET);
+ try {
+ json.put("empty", getDrawable(drawable.getCurrent(), filename));
+ drawableList.add(drawable.getCurrent().hashCode());
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ for (int c = 1;c<=DrawableStates.length;c++)
+ for (int u= 0;u < 1 << DrawableStates.length;u++)
+ if (bitCount(u) == c)
+ addSolution(filename, json, c, drawable, drawableList, u);
+ return json;
+ }
+
+ JSONObject getStatesList(int [] states) throws JSONException
+ {
+ JSONObject json = new JSONObject();
+ for (int s : states)
+ {
+ boolean found=false;
+ for (int d = 0;d<DrawableStates.length;d++)
+ {
+ if (s==DrawableStates[d])
+ {
+ json.put(DrawableStatesLabels[d], true);
+ found=true;
+ break;
+ }
+ else if (s==-DrawableStates[d])
+ {
+ json.put(DrawableStatesLabels[d], false);
+
+ found=true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ json.put("unhandled_state_"+s,s>0);
+ }
+ }
+ return json;
+ }
+
+ String getStatesName(int [] states)
+ {
+ String statesName="";
+ for (int s : states)
+ {
+ boolean found=false;
+ for (int d = 0;d<DrawableStates.length;d++)
+ {
+ if (s==DrawableStates[d])
+ {
+ if (statesName.length()>0)
+ statesName+="__";
+ statesName+=DrawableStatesLabels[d];
+ found=true;
+ break;
+ }
+ else if (s==-DrawableStates[d])
+ {
+ if (statesName.length()>0)
+ statesName+="__";
+ statesName+=DisableDrawableStatesLabels[d];
+ found=true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ if (statesName.length()>0)
+ statesName+=";";
+ statesName+=s;
+ }
+ }
+ if (statesName.length()>0)
+ return statesName;
+ return "empty";
+ }
+
+ private JSONObject getLayerDrawable(Object drawable, String filename)
+ {
+ JSONObject json = new JSONObject();
+ LayerDrawable layers = (LayerDrawable) drawable;
+ final int nr=layers.getNumberOfLayers();
+ try {
+ JSONArray array =new JSONArray();
+ for (int i = 0; i < nr; i++)
+ {
+ int id = layers.getId(i);
+ if (id == -1)
+ id = i;
+ JSONObject layerJsonObject=getDrawable(layers.getDrawable(i), filename+"__"+id);
+ layerJsonObject.put("id", id);
+ array.put(layerJsonObject);
+ }
+ json.put("type", "layer");
+ Rect padding = new Rect();
+ if (layers.getPadding(padding))
+ json.put("padding", getJsonRect(padding));
+ json.put("layers", array);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ private JSONObject getStateListDrawable(Object drawable, String filename)
+ {
+ JSONObject json = new JSONObject();
+ try {
+ StateListDrawable stateList = (StateListDrawable) drawable;
+ final int numStates = (Integer) StateListDrawable.class.getMethod("getStateCount").invoke(stateList);
+ JSONArray array =new JSONArray();
+ for (int i = 0; i < numStates; i++)
+ {
+ JSONObject stateJson = new JSONObject();
+ final Drawable d = (Drawable) StateListDrawable.class.getMethod("getStateDrawable", Integer.TYPE).invoke(stateList, i);
+ final int [] states = (int[]) StateListDrawable.class.getMethod("getStateSet", Integer.TYPE).invoke(stateList, i);
+ if (states == null)
+ continue;
+ stateJson.put("states", getStatesList(states));
+ stateJson.put("drawable", getDrawable(d, filename+"__"+getStatesName(states)));
+ array.put(stateJson);
+ }
+ json.put("type", "stateslist");
+ Rect padding = new Rect();
+ if (stateList.getPadding(padding))
+ json.put("padding", getJsonRect(padding));
+ json.put("stateslist", array);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ private JSONObject getGradientDrawable(GradientDrawable drawable) {
+ JSONObject json = new JSONObject();
+ try {
+ json.put("type", "gradient");
+ Object obj=drawable.getConstantState();
+ Class<?> gradientStateClass=obj.getClass();
+ json.put("shape",gradientStateClass.getField("mShape").getInt(obj));
+ json.put("gradient",gradientStateClass.getField("mGradient").getInt(obj));
+ GradientDrawable.Orientation orientation=(Orientation) gradientStateClass.getField("mOrientation").get(obj);
+ json.put("orientation",orientation.name());
+ int [] intArray=(int[]) gradientStateClass.getField("mColors").get(obj);
+ json.put("colors",getJsonArray(intArray, 0, intArray.length));
+ json.put("positions",getJsonArray((float[]) gradientStateClass.getField("mPositions").get(obj)));
+ json.put("strokeWidth",gradientStateClass.getField("mStrokeWidth").getInt(obj));
+ json.put("strokeDashWidth",gradientStateClass.getField("mStrokeDashWidth").getFloat(obj));
+ json.put("strokeDashGap",gradientStateClass.getField("mStrokeDashGap").getFloat(obj));
+ json.put("radius",gradientStateClass.getField("mRadius").getFloat(obj));
+ float [] floatArray=(float[]) gradientStateClass.getField("mRadiusArray").get(obj);
+ if (floatArray!=null)
+ json.put("radiusArray",getJsonArray(floatArray));
+ Rect rc= (Rect) gradientStateClass.getField("mPadding").get(obj);
+ if (rc!=null)
+ json.put("padding",getJsonRect(rc));
+ json.put("width",gradientStateClass.getField("mWidth").getInt(obj));
+ json.put("height",gradientStateClass.getField("mHeight").getInt(obj));
+ json.put("innerRadiusRatio",gradientStateClass.getField("mInnerRadiusRatio").getFloat(obj));
+ json.put("thicknessRatio",gradientStateClass.getField("mThicknessRatio").getFloat(obj));
+ json.put("innerRadius",gradientStateClass.getField("mInnerRadius").getInt(obj));
+ json.put("thickness",gradientStateClass.getField("mThickness").getInt(obj));
+ if (Build.VERSION.SDK_INT < 20) {
+ json.put("solidColor",gradientStateClass.getField("mSolidColor").getInt(obj));
+ json.put("strokeColor",gradientStateClass.getField("mStrokeColor").getInt(obj));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ private JSONObject getRotateDrawable(RotateDrawable drawable, String filename) {
+ JSONObject json = new JSONObject();
+ try {
+ json.put("type", "rotate");
+ Object obj = drawable.getConstantState();
+ Class<?> rotateStateClass = obj.getClass();
+ Field f = rotateStateClass.getDeclaredField("mDrawable");
+ f.setAccessible(true);
+ json.put("drawable", getDrawable(f.get(obj), filename));
+ f = rotateStateClass.getDeclaredField("mPivotX");
+ f.setAccessible(true);
+ json.put("pivotX", f.getFloat(obj));
+ f = rotateStateClass.getDeclaredField("mPivotXRel");
+ f.setAccessible(true);
+ json.put("pivotXRel", f.getBoolean(obj));
+ f = rotateStateClass.getDeclaredField("mPivotY");
+ f.setAccessible(true);
+ json.put("pivotY", f.getFloat(obj));
+ f = rotateStateClass.getDeclaredField("mPivotYRel");
+ f.setAccessible(true);
+ json.put("pivotYRel", f.getBoolean(obj));
+ f = rotateStateClass.getDeclaredField("mFromDegrees");
+ f.setAccessible(true);
+ json.put("fromDegrees", f.getFloat(obj));
+ f = rotateStateClass.getDeclaredField("mToDegrees");
+ f.setAccessible(true);
+ json.put("toDegrees", f.getFloat(obj));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ private JSONObject getAnimationDrawable(AnimationDrawable drawable, String filename) {
+ JSONObject json = new JSONObject();
+ try {
+ json.put("type", "animation");
+ json.put("oneshot", drawable.isOneShot());
+ final int count = drawable.getNumberOfFrames();
+ JSONArray frames = new JSONArray();
+ for (int i = 0; i < count; ++i)
+ {
+ JSONObject frame = new JSONObject();
+ frame.put("duration", drawable.getDuration(i));
+ frame.put("drawable", getDrawable(drawable.getFrame(i), filename+"__"+i));
+ frames.put(frame);
+ }
+ json.put("frames", frames);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ private JSONObject getJsonRect(Rect rect) throws JSONException
+ {
+ JSONObject jsonRect = new JSONObject();
+ jsonRect.put("left", rect.left);
+ jsonRect.put("top", rect.top);
+ jsonRect.put("right", rect.right);
+ jsonRect.put("bottom", rect.bottom);
+ return jsonRect;
+
+ }
+
+ private JSONArray getJsonArray(int[] array, int pos, int len)
+ {
+ JSONArray a = new JSONArray();
+ final int l = pos+len;
+ for (int i=pos; i<l;i++)
+ a.put(array[i]);
+ return a;
+ }
+
+ private JSONArray getJsonArray(float[] array) throws JSONException
+ {
+ JSONArray a = new JSONArray();
+ if (array != null)
+ for (float val: array)
+ a.put(val);
+ return a;
+ }
+
+ private JSONObject getJsonChunkInfo(int[] chunkData) throws JSONException
+ {
+ JSONObject jsonRect = new JSONObject();
+ jsonRect.put("xdivs", getJsonArray(chunkData, 3, chunkData[0]));
+ jsonRect.put("ydivs", getJsonArray(chunkData, 3 + chunkData[0], chunkData[1]));
+ jsonRect.put("colors", getJsonArray(chunkData, 3 + chunkData[0] + chunkData[1], chunkData[2]));
+ return jsonRect;
+ }
+
+ private JSONObject findPatchesMarings(Drawable d) throws JSONException, NoSuchFieldException, IllegalAccessException
+ {
+ Field mNinePatch = ((NinePatchDrawable)d).getClass().getDeclaredField("mNinePatch");
+ mNinePatch.setAccessible(true);
+ NinePatch np = (NinePatch) mNinePatch.get(d);
+ if (Build.VERSION.SDK_INT < 19)
+ {
+ Field mChunk = np.getClass().getDeclaredField("mChunk");
+ mChunk.setAccessible(true);
+ return getJsonChunkInfo(extractChunkInfo((byte[]) mChunk.get(np)));
+ }
+ else
+ {
+ Field mNativeChunk = np.getClass().getDeclaredField("mNativeChunk");
+ mNativeChunk.setAccessible(true);
+ if (Build.VERSION.SDK_INT > 19)
+ return getJsonChunkInfo(extractNativeChunkInfo20(mNativeChunk.getLong(np)));
+ return getJsonChunkInfo(extractNativeChunkInfo(mNativeChunk.getInt(np)));
+ }
+ }
+
+ class DrawableCache
+ {
+ public DrawableCache(JSONObject json, Object drawable)
+ {
+ object = json;
+ this.drawable = drawable;
+ }
+ JSONObject object;
+ Object drawable;
+ }
+ private HashMap<String, DrawableCache> m_drawableCache = new HashMap<String, DrawableCache>();
+
+ public JSONObject getDrawable(Object drawable, String filename)
+ {
+ DrawableCache dc = m_drawableCache.get(filename);
+ if (dc != null)
+ {
+ if (dc.drawable.equals(drawable))
+ return dc.object;
+ else
+ Log.e(QtNative.QtTAG, "Different drawable objects points to the same file name \"" + filename +"\"");
+ }
+ JSONObject json = new JSONObject();
+ Bitmap bmp;
+ if (drawable instanceof Bitmap)
+ bmp = (Bitmap) drawable;
+ else
+ {
+ if (drawable instanceof BitmapDrawable)
+ bmp = ((BitmapDrawable)drawable).getBitmap();
+ else
+ {
+ if (drawable instanceof ScaleDrawable)
+ {
+ return getDrawable(((ScaleDrawable)drawable).getDrawable(), filename);
+ }
+ if (drawable instanceof LayerDrawable)
+ {
+ return getLayerDrawable(drawable, filename);
+ }
+ if (drawable instanceof StateListDrawable)
+ {
+ return getStateListDrawable(drawable, filename);
+ }
+ if (drawable instanceof GradientDrawable)
+ {
+ return getGradientDrawable((GradientDrawable) drawable);
+ }
+ if (drawable instanceof RotateDrawable)
+ {
+ return getRotateDrawable((RotateDrawable) drawable, filename);
+ }
+ if (drawable instanceof AnimationDrawable)
+ {
+ return getAnimationDrawable((AnimationDrawable) drawable, filename);
+ }
+ if (drawable instanceof ClipDrawable)
+ {
+ try {
+ json.put("type", "clipDrawable");
+ Drawable.ConstantState dcs = ((ClipDrawable)drawable).getConstantState();
+ Field f = dcs.getClass().getDeclaredField("mDrawable");
+ f.setAccessible(true);
+ json.put("drawable", getDrawable(f.get(dcs), filename));
+ Rect padding = new Rect();
+ if (((Drawable) drawable).getPadding(padding))
+ json.put("padding", getJsonRect(padding));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+ if (drawable instanceof ColorDrawable)
+ {
+ bmp = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
+ Drawable d = (Drawable) drawable;
+ d.setBounds(0, 0, 1, 1);
+ d.draw(new Canvas(bmp));
+ Rect padding = new Rect();
+ try {
+ json.put("type", "color");
+ json.put("color", bmp.getPixel(0, 0));
+ if (d.getPadding(padding))
+ json.put("padding", getJsonRect(padding));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+ else
+ {
+ Drawable d = (Drawable) drawable;
+ int w=d.getIntrinsicWidth();
+ int h=d.getIntrinsicHeight();
+ d.setLevel(10000);
+ if (w<1 || h< 1)
+ {
+ w=100;
+ h=100;
+ }
+ bmp = Bitmap.createBitmap(w, h, Config.ARGB_8888);
+ d.setBounds(0, 0, w, h);
+ d.draw(new Canvas(bmp));
+ if (drawable instanceof NinePatchDrawable)
+ {
+ NinePatchDrawable npd = (NinePatchDrawable) drawable;
+ try {
+ json.put("type", "9patch");
+ json.put("drawable", getDrawable(bmp, filename));
+ Rect padding = new Rect();
+ if (npd.getPadding(padding))
+ json.put("padding", getJsonRect(padding));
+ json.put("chunkInfo", findPatchesMarings(d));
+ return json;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ FileOutputStream out;
+ try {
+ filename = m_extractPath+filename+".png";
+ out = new FileOutputStream(filename);
+ bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
+ out.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ try {
+ json.put("type", "image");
+ json.put("path", filename);
+ json.put("width", bmp.getWidth());
+ json.put("height", bmp.getHeight());
+ m_drawableCache.put(filename, new DrawableCache(json, drawable));
+// MinistroActivity.nativeChmode(filename, 0644);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ public void extractViewInformations(String styleName, int styleId, JSONObject json, String qtClassName, AttributeSet attribSet)
+ {
+ try {
+ int[] viewAttrs;
+ viewAttrs = (int[]) styleableClass.getDeclaredField("View").get(null);
+ TypedArray a =m_theme.obtainStyledAttributes(attribSet, viewAttrs, styleId, 0);
+
+ if (null != qtClassName)
+ json.put("qtClass", qtClassName);
+ json.put("defaultBackgroundColor", defaultBackgroundColor);
+ json.put("defaultTextColorPrimary", defaultTextColor);
+ final int N = a.getIndexCount();
+ for (int i = 0; i < N; i++) {
+ int attr = a.getIndex(i);
+ if (attr == View_background)
+ json.put("View_background", getDrawable(a.getDrawable(attr), styleName + "_View_background"));
+ else if (attr == View_padding)
+ json.put("View_padding", a.getDimensionPixelSize(attr, -1));
+ else if (attr == View_paddingLeft)
+ json.put("View_paddingLeft", a.getDimensionPixelSize(attr, -1));
+ else if (attr == View_paddingTop)
+ json.put("View_paddingTop", a.getDimensionPixelSize(attr, -1));
+ else if (attr == View_paddingRight)
+ json.put("View_paddingRight", a.getDimensionPixelSize(attr, -1));
+ else if (attr == View_paddingBottom)
+ json.put("View_paddingBottom", a.getDimensionPixelSize(attr, -1));
+ else if (attr == View_scrollX)
+ json.put("View_paddingBottom", a.getDimensionPixelOffset(attr, 0));
+ else if (attr == View_scrollY)
+ json.put("View_scrollY", a.getDimensionPixelOffset(attr, 0));
+ else if (attr == View_id)
+ json.put("View_id", a.getResourceId(attr, -1));
+ else if (attr == View_tag)
+ json.put("View_tag", a.getText(attr));
+ else if (attr == View_fitsSystemWindows)
+ json.put("View_fitsSystemWindows", a.getBoolean(attr, false));
+ else if (attr == View_focusable)
+ json.put("View_focusable", a.getBoolean(attr, false));
+ else if (attr == View_focusableInTouchMode)
+ json.put("View_focusableInTouchMode", a.getBoolean(attr, false));
+ else if (attr == View_clickable)
+ json.put("View_clickable", a.getBoolean(attr, false));
+ else if (attr == View_longClickable)
+ json.put("View_longClickable", a.getBoolean(attr, false));
+ else if (attr == View_saveEnabled)
+ json.put("View_saveEnabled", a.getBoolean(attr, true));
+ else if (attr == View_duplicateParentState)
+ json.put("View_duplicateParentState", a.getBoolean(attr, false));
+ else if (attr == View_visibility)
+ json.put("View_visibility", a.getInt(attr, 0));
+ else if (attr == View_drawingCacheQuality)
+ json.put("View_drawingCacheQuality", a.getInt(attr, 0));
+ else if (attr == View_drawingCacheQuality)
+ json.put("View_contentDescription", a.getString(attr));
+ else if (attr == View_soundEffectsEnabled)
+ json.put("View_soundEffectsEnabled", a.getBoolean(attr, true));
+ else if (attr == View_hapticFeedbackEnabled)
+ json.put("View_hapticFeedbackEnabled", a.getBoolean(attr, true));
+ else if (attr == View_scrollbars)
+ json.put("View_scrollbars", a.getInt(attr, 0));
+ else if (attr == View_fadingEdge)
+ json.put("View_fadingEdge", a.getInt(attr, 0));
+ else if (attr == View_scrollbarStyle)
+ json.put("View_scrollbarStyle", a.getInt(attr, 0));
+ else if (attr == View_scrollbarFadeDuration)
+ json.put("View_scrollbarFadeDuration", a.getInt(attr, 0));
+ else if (attr == View_scrollbarDefaultDelayBeforeFade)
+ json.put("View_scrollbarDefaultDelayBeforeFade", a.getInt(attr, 0));
+ else if (attr == View_scrollbarSize)
+ json.put("View_scrollbarSize", a.getDimensionPixelSize(attr, -1));
+ else if (attr == View_scrollbarThumbHorizontal)
+ json.put("View_scrollbarThumbHorizontal", getDrawable(a.getDrawable(attr), styleName + "_View_scrollbarThumbHorizontal"));
+ else if (attr == View_scrollbarThumbVertical)
+ json.put("View_scrollbarThumbVertical", getDrawable(a.getDrawable(attr), styleName + "_View_scrollbarThumbVertical"));
+ else if (attr == View_scrollbarTrackHorizontal)
+ json.put("View_scrollbarTrackHorizontal", getDrawable(a.getDrawable(attr), styleName + "_View_scrollbarTrackHorizontal"));
+ else if (attr == View_scrollbarTrackVertical)
+ json.put("View_scrollbarTrackVertical", getDrawable(a.getDrawable(attr), styleName + "_View_scrollbarTrackVertical"));
+ else if (attr == View_isScrollContainer)
+ json.put("View_isScrollContainer", a.getBoolean(attr, false));
+ else if (attr == View_keepScreenOn)
+ json.put("View_keepScreenOn", a.getBoolean(attr, false));
+ else if (attr == View_filterTouchesWhenObscured)
+ json.put("View_filterTouchesWhenObscured", a.getBoolean(attr, false));
+ else if (attr == View_nextFocusLeft)
+ json.put("View_nextFocusLeft", a.getResourceId(attr, -1));
+ else if (attr == View_nextFocusRight)
+ json.put("View_nextFocusRight", a.getResourceId(attr, -1));
+ else if (attr == View_nextFocusUp)
+ json.put("View_nextFocusUp", a.getResourceId(attr, -1));
+ else if (attr == View_nextFocusDown)
+ json.put("View_nextFocusDown", a.getResourceId(attr, -1));
+ else if (attr == View_minWidth)
+ json.put("View_minWidth", a.getDimensionPixelSize(attr, 0));
+ else if (attr == View_minHeight)
+ json.put("View_minHeight", a.getDimensionPixelSize(attr, 0));
+ else if (attr == View_onClick)
+ json.put("View_onClick", a.getString(attr));
+ else if (attr == View_overScrollMode)
+ json.put("View_overScrollMode", a.getInt(attr, 1));
+ else if (attr == View_paddingStart)
+ json.put("View_paddingStart", a.getDimensionPixelSize(attr, 0));
+ else if (attr == View_paddingEnd)
+ json.put("View_paddingEnd", a.getDimensionPixelSize(attr, 0));
+ }
+ a.recycle();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public JSONObject extractTextAppearance(int styleId)
+ {
+ JSONObject json = new JSONObject();
+ try
+ {
+ TypedArray a = m_theme.obtainStyledAttributes(styleId, (int[]) styleableClass.getDeclaredField("TextAppearance").get(null));
+ int n = a.getIndexCount();
+ for (int i = 0; i < n; i++)
+ {
+ int attr = a.getIndex(i);
+ if (attr == TextAppearance_textColorHighlight)
+ json.put("TextAppearance_textColorHighlight", a.getColor(attr, 0));
+ else if (attr == TextAppearance_textColor)
+ json.put("TextAppearance_textColor", getColorStateList(a.getColorStateList(attr)));
+ else if (attr == TextAppearance_textColorHint)
+ json.put("TextAppearance_textColorHint", getColorStateList(a.getColorStateList(attr)));
+ else if (attr == TextAppearance_textColorLink)
+ json.put("TextAppearance_textColorLink", getColorStateList(a.getColorStateList(attr)));
+ else if (attr == TextAppearance_textSize)
+ json.put("TextAppearance_textSize", a.getDimensionPixelSize(attr, 15));
+ else if (attr == TextAppearance_typeface)
+ json.put("TextAppearance_typeface", a.getInt(attr, -1));
+ else if (attr == TextAppearance_textStyle)
+ json.put("TextAppearance_textStyle", a.getInt(attr, -1));
+ else if (attr == TextAppearance_textAllCaps)
+ json.put("TextAppearance_textAllCaps", a.getBoolean(attr, false));
+ }
+ a.recycle();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ public JSONObject extractTextAppearanceInformations(String styleName, String qtClass, AttributeSet attribSet, int textAppearance)
+ {
+ JSONObject json = new JSONObject();
+ try
+ {
+ int textColorHighlight = 0; //
+ ColorStateList textColor = null; //
+ ColorStateList textColorHint = null; //
+ ColorStateList textColorLink = null; //
+ int textSize = 15; //
+ int typefaceIndex = -1; //
+ int styleIndex = -1;
+ boolean allCaps = false;
+
+ Class<?> attrClass= Class.forName("android.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+
+ extractViewInformations(styleName, styleId, json, qtClass, attribSet);
+
+ int[] textViewAttrs=(int[]) styleableClass.getDeclaredField("TextView").get(null);
+ TypedArray a =m_theme.obtainStyledAttributes(null, textViewAttrs, styleId, 0);
+
+ TypedArray appearance = null;
+ if (-1==textAppearance)
+ textAppearance = a.getResourceId(styleableClass.getDeclaredField("TextView_textAppearance").getInt(null), -1);
+
+ if (textAppearance != -1)
+ appearance = m_theme.obtainStyledAttributes(textAppearance, (int[]) styleableClass.getDeclaredField("TextAppearance").get(null));
+
+ if (appearance != null)
+ {
+ int n = appearance.getIndexCount();
+ for (int i = 0; i < n; i++)
+ {
+ int attr = appearance.getIndex(i);
+ if (attr == TextAppearance_textColorHighlight)
+ textColorHighlight = appearance.getColor(attr, textColorHighlight);
+ else if (attr == TextAppearance_textColor)
+ textColor = appearance.getColorStateList(attr);
+ else if (attr == TextAppearance_textColorHint)
+ textColorHint = appearance.getColorStateList(attr);
+ else if (attr == TextAppearance_textColorLink)
+ textColorLink = appearance.getColorStateList(attr);
+ else if (attr == TextAppearance_textSize)
+ textSize = appearance.getDimensionPixelSize(attr, textSize);
+ else if (attr == TextAppearance_typeface)
+ typefaceIndex = appearance.getInt(attr, -1);
+ else if (attr == TextAppearance_textStyle)
+ styleIndex = appearance.getInt(attr, -1);
+ else if (attr == TextAppearance_textAllCaps)
+ allCaps = appearance.getBoolean(attr, false);
+ }
+ appearance.recycle();
+ }
+
+ int n = a.getIndexCount();
+
+ for (int i = 0; i < n; i++) {
+ int attr = a.getIndex(i);
+
+ if (attr == TextView_editable)
+ json.put("TextView_editable", a.getBoolean(attr, false));
+ else if (attr == TextView_inputMethod)
+ json.put("TextView_inputMethod", a.getText(attr));
+ else if (attr == TextView_numeric)
+ json.put("TextView_numeric", a.getInt(attr, 0));
+ else if (attr == TextView_digits)
+ json.put("TextView_digits", a.getText(attr));
+ else if (attr == TextView_phoneNumber)
+ json.put("TextView_phoneNumber", a.getBoolean(attr, false));
+ else if (attr == TextView_autoText)
+ json.put("TextView_autoText", a.getBoolean(attr, false));
+ else if (attr == TextView_capitalize)
+ json.put("TextView_capitalize", a.getInt(attr, -1));
+ else if (attr == TextView_bufferType)
+ json.put("TextView_bufferType", a.getInt(attr, 0));
+ else if (attr == TextView_selectAllOnFocus)
+ json.put("TextView_selectAllOnFocus", a.getBoolean(attr, false));
+ else if (attr == TextView_autoLink)
+ json.put("TextView_autoLink", a.getInt(attr, 0));
+ else if (attr == TextView_linksClickable)
+ json.put("TextView_linksClickable", a.getBoolean(attr, true));
+ else if (attr == TextView_linksClickable)
+ json.put("TextView_linksClickable", a.getBoolean(attr, true));
+ else if (attr == TextView_drawableLeft)
+ json.put("TextView_drawableLeft", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableLeft"));
+ else if (attr == TextView_drawableTop)
+ json.put("TextView_drawableTop", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableTop"));
+ else if (attr == TextView_drawableRight)
+ json.put("TextView_drawableRight", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableRight"));
+ else if (attr == TextView_drawableBottom)
+ json.put("TextView_drawableBottom", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableBottom"));
+ else if (attr == TextView_drawableStart)
+ json.put("TextView_drawableStart", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableStart"));
+ else if (attr == TextView_drawableEnd)
+ json.put("TextView_drawableEnd", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableEnd"));
+ else if (attr == TextView_drawablePadding)
+ json.put("TextView_drawablePadding", a.getDimensionPixelSize(attr, 0));
+ else if (attr == TextView_textCursorDrawable)
+ json.put("TextView_textCursorDrawable", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textCursorDrawable"));
+ else if (attr == TextView_maxLines)
+ json.put("TextView_maxLines", a.getInt(attr, -1));
+ else if (attr == TextView_maxHeight)
+ json.put("TextView_maxHeight", a.getDimensionPixelSize(attr, -1));
+ else if (attr == TextView_lines)
+ json.put("TextView_lines", a.getInt(attr, -1));
+ else if (attr == TextView_height)
+ json.put("TextView_height", a.getDimensionPixelSize(attr, -1));
+ else if (attr == TextView_minLines)
+ json.put("TextView_minLines", a.getInt(attr, -1));
+ else if (attr == TextView_minHeight)
+ json.put("TextView_minHeight", a.getDimensionPixelSize(attr, -1));
+ else if (attr == TextView_maxEms)
+ json.put("TextView_maxEms", a.getInt(attr, -1));
+ else if (attr == TextView_maxWidth)
+ json.put("TextView_maxWidth", a.getDimensionPixelSize(attr, -1));
+ else if (attr == TextView_ems)
+ json.put("TextView_ems", a.getInt(attr, -1));
+ else if (attr == TextView_width)
+ json.put("TextView_width", a.getDimensionPixelSize(attr, -1));
+ else if (attr == TextView_minEms)
+ json.put("TextView_minEms", a.getInt(attr, -1));
+ else if (attr == TextView_minWidth)
+ json.put("TextView_minWidth", a.getDimensionPixelSize(attr, -1));
+ else if (attr == TextView_gravity)
+ json.put("TextView_gravity", a.getInt(attr, -1));
+ else if (attr == TextView_hint)
+ json.put("TextView_hint", a.getText(attr));
+ else if (attr == TextView_text)
+ json.put("TextView_text", a.getText(attr));
+ else if (attr == TextView_scrollHorizontally)
+ json.put("TextView_scrollHorizontally", a.getBoolean(attr, false));
+ else if (attr == TextView_singleLine)
+ json.put("TextView_singleLine", a.getBoolean(attr, false));
+ else if (attr == TextView_ellipsize)
+ json.put("TextView_ellipsize", a.getInt(attr, -1));
+ else if (attr == TextView_marqueeRepeatLimit)
+ json.put("TextView_marqueeRepeatLimit", a.getInt(attr, 3));
+ else if (attr == TextView_includeFontPadding)
+ json.put("TextView_includeFontPadding", a.getBoolean(attr, true));
+ else if (attr == TextView_cursorVisible)
+ json.put("TextView_cursorVisible", a.getBoolean(attr, true));
+ else if (attr == TextView_maxLength)
+ json.put("TextView_maxLength", a.getInt(attr, -1));
+ else if (attr == TextView_textScaleX)
+ json.put("TextView_textScaleX", a.getFloat(attr, 1.0f));
+ else if (attr == TextView_freezesText)
+ json.put("TextView_freezesText", a.getBoolean(attr, false));
+ else if (attr == TextView_shadowColor)
+ json.put("TextView_shadowColor", a.getInt(attr, 0));
+ else if (attr == TextView_shadowDx)
+ json.put("TextView_shadowDx", a.getFloat(attr, 0));
+ else if (attr == TextView_shadowDy)
+ json.put("TextView_shadowDy", a.getFloat(attr, 0));
+ else if (attr == TextView_shadowRadius)
+ json.put("TextView_shadowRadius", a.getFloat(attr, 0));
+ else if (attr == TextView_enabled)
+ json.put("TextView_enabled", a.getBoolean(attr,true));
+ else if (attr == TextView_textColorHighlight)
+ textColorHighlight = a.getColor(attr, textColorHighlight);
+ else if (attr == TextView_textColor)
+ textColor = a.getColorStateList(attr);
+ else if (attr == TextView_textColorHint)
+ textColorHint = a.getColorStateList(attr);
+ else if (attr == TextView_textColorLink)
+ textColorLink = a.getColorStateList(attr);
+ else if (attr == TextView_textSize)
+ textSize = a.getDimensionPixelSize(attr, textSize);
+ else if (attr == TextView_typeface)
+ typefaceIndex = a.getInt(attr, typefaceIndex);
+ else if (attr == TextView_textStyle)
+ styleIndex = a.getInt(attr, styleIndex);
+ else if (attr == TextView_password)
+ json.put("TextView_password", a.getBoolean(attr,false));
+ else if (attr == TextView_lineSpacingExtra)
+ json.put("TextView_lineSpacingExtra", a.getDimensionPixelSize(attr, 0));
+ else if (attr == TextView_lineSpacingMultiplier)
+ json.put("TextView_lineSpacingMultiplier", a.getFloat(attr, 1.0f));
+ else if (attr == TextView_inputType)
+ json.put("TextView_inputType", a.getInt(attr, EditorInfo.TYPE_NULL));
+ else if (attr == TextView_imeOptions)
+ json.put("TextView_imeOptions", a.getInt(attr, EditorInfo.IME_NULL));
+ else if (attr == TextView_imeActionLabel)
+ json.put("TextView_imeActionLabel", a.getText(attr));
+ else if (attr == TextView_imeActionId)
+ json.put("TextView_imeActionId", a.getInt(attr,0));
+ else if (attr == TextView_privateImeOptions)
+ json.put("TextView_privateImeOptions", a.getString(attr));
+ else if (attr == TextView_textSelectHandleLeft && styleName.equals("textViewStyle"))
+ json.put("TextView_textSelectHandleLeft", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandleLeft"));
+ else if (attr == TextView_textSelectHandleRight && styleName.equals("textViewStyle"))
+ json.put("TextView_textSelectHandleRight", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandleRight"));
+ else if (attr == TextView_textSelectHandle && styleName.equals("textViewStyle"))
+ json.put("TextView_textSelectHandle", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandle"));
+ else if (attr == TextView_textIsSelectable)
+ json.put("TextView_textIsSelectable", a.getBoolean(attr, false));
+ else if (attr == TextView_textAllCaps)
+ allCaps = a.getBoolean(attr, false);
+ }
+ a.recycle();
+
+ json.put("TextAppearance_textColorHighlight",textColorHighlight);
+ json.put("TextAppearance_textColor", getColorStateList(textColor));
+ json.put("TextAppearance_textColorHint", getColorStateList(textColorHint));
+ json.put("TextAppearance_textColorLink", getColorStateList(textColorLink));
+ json.put("TextAppearance_textSize",textSize);
+ json.put("TextAppearance_typeface",typefaceIndex);
+ json.put("TextAppearance_textStyle",styleIndex);
+ json.put("TextAppearance_textAllCaps",allCaps);
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ final String[] sScaleTypeArray = {
+ "MATRIX",
+ "FIT_XY",
+ "FIT_START",
+ "FIT_CENTER",
+ "FIT_END",
+ "CENTER",
+ "CENTER_CROP",
+ "CENTER_INSIDE"
+ };
+
+ public JSONObject extractImageViewInformations(String styleName, String qtClassName )
+ {
+ JSONObject json = new JSONObject();
+ try
+ {
+ Class<?> attrClass= Class.forName("android.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+
+ extractViewInformations(styleName, styleId, json, qtClassName, null);
+
+ int[] imageViewAttrs=(int[]) styleableClass.getDeclaredField("ImageView").get(null);
+ TypedArray a =m_theme.obtainStyledAttributes(null, imageViewAttrs, styleId, 0);
+ Drawable d = a.getDrawable(ImageView_src);
+ if (d != null)
+ json.put("ImageView_src", getDrawable(d, styleName + "_ImageView_src"));
+
+ json.put("ImageView_baselineAlignBottom", a.getBoolean(ImageView_baselineAlignBottom, false));
+ json.put("ImageView_adjustViewBounds", a.getBoolean(ImageView_adjustViewBounds, false));
+ json.put("ImageView_maxWidth", a.getDimensionPixelSize(ImageView_maxWidth, Integer.MAX_VALUE));
+ json.put("ImageView_maxHeight", a.getDimensionPixelSize(ImageView_maxHeight, Integer.MAX_VALUE));
+ int index = a.getInt(ImageView_scaleType, -1);
+ if (index >= 0)
+ json.put("ImageView_scaleType", sScaleTypeArray[index]);
+
+ int tint = a.getInt(ImageView_tint, 0);
+ if (tint != 0)
+ json.put("ImageView_tint", tint);
+
+
+ json.put("ImageView_cropToPadding",a.getBoolean(ImageView_cropToPadding, false));
+ a.recycle();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ return json;
+
+ }
+
+ void extractCompoundButton(SimpleJsonWriter jsonWriter, String styleName, String qtClass)
+ {
+ JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
+ Class<?> attrClass;
+ try {
+ attrClass = Class.forName("android.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+ int[] compoundButtonAttrs=(int[]) styleableClass.getDeclaredField("CompoundButton").get(null);
+
+ TypedArray a = m_theme.obtainStyledAttributes(
+ null, compoundButtonAttrs, styleId, 0);
+
+ Drawable d = a.getDrawable(getField(styleableClass,"CompoundButton_button"));
+ if (d != null)
+ json.put("CompoundButton_button", getDrawable(d, styleName + "_CompoundButton_button"));
+
+ a.recycle();
+ jsonWriter.name(styleName).value(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ void extractProgressBarInfo(JSONObject json, String styleName)
+ {
+ Class<?> attrClass;
+ try {
+ attrClass = Class.forName("android.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+ int[] progressBarAttrs=(int[]) styleableClass.getDeclaredField("ProgressBar").get(null);
+
+ TypedArray a = m_theme.obtainStyledAttributes(null, progressBarAttrs, styleId, 0);
+ int mMinWidth = 24;
+ int mMaxWidth = 48;
+ int mMinHeight = 24;
+ int mMaxHeight = 48;
+ mMinWidth = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_minWidth"), mMinWidth);
+ mMaxWidth = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_maxWidth"), mMaxWidth);
+ mMinHeight = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_minHeight"), mMinHeight);
+ mMaxHeight = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_maxHeight"), mMaxHeight);
+
+ json.put("ProgressBar_indeterminateDuration", a.getInt(getField(styleableClass, "ProgressBar_indeterminateDuration"), 4000));
+ json.put("ProgressBar_minWidth", mMinWidth);
+ json.put("ProgressBar_maxWidth", mMaxWidth);
+ json.put("ProgressBar_minHeight", mMinHeight);
+ json.put("ProgressBar_maxHeight", mMaxHeight);
+ json.put("ProgressBar_progress_id", android.R.id.progress);
+ json.put("ProgressBar_secondaryProgress_id", android.R.id.secondaryProgress);
+
+ Drawable d = a.getDrawable(getField(styleableClass,"ProgressBar_progressDrawable"));
+ if (d != null)
+ json.put("ProgressBar_progressDrawable", getDrawable(d, styleName + "_ProgressBar_progressDrawable"));
+
+ d = a.getDrawable(getField(styleableClass,"ProgressBar_indeterminateDrawable"));
+ if (d != null)
+ json.put("ProgressBar_indeterminateDrawable", getDrawable(d, styleName + "_ProgressBar_indeterminateDrawable"));
+
+ a.recycle();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ void extractProgressBar(SimpleJsonWriter writer, String styleName, String qtClass)
+ {
+ JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
+ try {
+ extractProgressBarInfo(json, styleName);
+ writer.name(styleName).value(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ void extractAbsSeekBar(SimpleJsonWriter jsonWriter, String styleName, String qtClass)
+ {
+ JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
+ extractProgressBarInfo(json, styleName);
+ Class<?> attrClass;
+ try {
+ attrClass = Class.forName("android.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+ int[] compoundButtonAttrs=(int[]) styleableClass.getDeclaredField("SeekBar").get(null);
+
+ TypedArray a = m_theme.obtainStyledAttributes(
+ null, compoundButtonAttrs, styleId, 0);
+
+ Drawable d = a.getDrawable(getField(styleableClass,"SeekBar_thumb"));
+ if (d != null)
+ json.put("SeekBar_thumb", getDrawable(d, styleName + "_SeekBar_thumb"));
+
+ try {
+ json.put("SeekBar_thumbOffset", styleableClass.getDeclaredField("SeekBar_thumbOffset").getInt(null));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ a.recycle();
+ jsonWriter.name(styleName).value(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ void extractSwitch(SimpleJsonWriter jsonWriter, String styleName, String qtClass)
+ {
+ JSONObject json = new JSONObject();
+ try {
+ Class<?> attrClass = Class.forName("com.android.internal.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+
+ int[] switchAttrs = (int[]) styleableClass.getDeclaredField("Switch").get(null);
+ TypedArray a = m_theme.obtainStyledAttributes(null, switchAttrs, styleId, 0);
+
+ Drawable thumb = a.getDrawable(getField(styleableClass,"Switch_thumb"));
+ if (thumb != null)
+ json.put("Switch_thumb", getDrawable(thumb, styleName + "_Switch_thumb"));
+
+ Drawable track = a.getDrawable(getField(styleableClass,"Switch_track"));
+ if (track != null)
+ json.put("Switch_track", getDrawable(track, styleName + "_Switch_track"));
+
+ int textAppearance = a.getResourceId(styleableClass.getDeclaredField("Switch_switchTextAppearance").getInt(null), -1);
+ json.put("Switch_switchTextAppearance", extractTextAppearance(textAppearance));
+
+ json.put("Switch_textOn", a.getText(getField(styleableClass, "Switch_textOn")));
+ json.put("Switch_textOff", a.getText(getField(styleableClass, "Switch_textOff")));
+ json.put("Switch_switchMinWidth", a.getDimensionPixelSize(getField(styleableClass, "Switch_switchMinWidth"), 0));
+ json.put("Switch_switchPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_switchPadding"), 0));
+ json.put("Switch_thumbTextPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_thumbTextPadding"), 0));
+
+ a.recycle();
+ jsonWriter.name(styleName).value(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ JSONObject extractCheckedTextView(AttributeSet attribSet, String itemName)
+ {
+ JSONObject json = extractTextAppearanceInformations("textViewStyle", itemName, attribSet, -1);
+ try {
+ Class<?> attrClass= Class.forName("android.R$attr");
+ int styleId = attrClass.getDeclaredField("textViewStyle").getInt(null);
+ int[] compoundButtonAttrs=(int[]) styleableClass.getDeclaredField("CheckedTextView").get(null);
+
+ TypedArray a = m_theme.obtainStyledAttributes(attribSet, compoundButtonAttrs, styleId, 0);
+
+ Drawable d = a.getDrawable(getField(styleableClass,"CheckedTextView_checkMark"));
+ if (d != null)
+ json.put("CheckedTextView_checkMark", getDrawable(d, itemName+"_CheckedTextView_checkMark"));
+
+ a.recycle();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ private JSONObject extractItemStyle(int resourceId, String itemName, int textAppearance) {
+ try
+ {
+ XmlResourceParser parser = m_context.getResources().getLayout(resourceId);
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG &&
+ type != XmlPullParser.END_DOCUMENT) {
+ // Empty
+ }
+
+ if (type != XmlPullParser.START_TAG) {
+ return null;
+ }
+
+ AttributeSet attributes = Xml.asAttributeSet(parser);
+ String name = parser.getName();
+ if (name.equals("TextView"))
+ return extractTextAppearanceInformations("textViewStyle", itemName, attributes, textAppearance);
+ if (name.equals("CheckedTextView"))
+ return extractCheckedTextView(attributes, itemName);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private void extractItemsStyle(SimpleJsonWriter jsonWriter) {
+ try
+ {
+ jsonWriter.name("simple_list_item").value(extractItemStyle(android.R.layout.simple_list_item_1, "simple_list_item", android.R.style.TextAppearance_Large));
+ jsonWriter.name("simple_list_item_checked").value(extractItemStyle(android.R.layout.simple_list_item_checked, "simple_list_item_checked", android.R.style.TextAppearance_Large));
+ jsonWriter.name("simple_list_item_multiple_choice").value(extractItemStyle(android.R.layout.simple_list_item_multiple_choice, "simple_list_item_multiple_choice", android.R.style.TextAppearance_Large));
+ jsonWriter.name("simple_list_item_single_choice").value(extractItemStyle(android.R.layout.simple_list_item_single_choice, "simple_list_item_single_choice", android.R.style.TextAppearance_Large));
+ jsonWriter.name("simple_spinner_item").value(extractItemStyle(android.R.layout.simple_spinner_item, "simple_spinner_item", -1));
+ jsonWriter.name("simple_spinner_dropdown_item").value(extractItemStyle(android.R.layout.simple_spinner_dropdown_item, "simple_spinner_dropdown_item",android.R.style.TextAppearance_Large));
+ jsonWriter.name("simple_dropdown_item_1line").value(extractItemStyle(android.R.layout.simple_dropdown_item_1line, "simple_dropdown_item_1line",android.R.style.TextAppearance_Large));
+ if (Build.VERSION.SDK_INT > 10) {
+ Class<?> layoutClass = Class.forName("android.R$layout");
+ int styleId = layoutClass.getDeclaredField("simple_selectable_list_item").getInt(null);
+ jsonWriter.name("simple_selectable_list_item").value(extractItemStyle(styleId, "simple_selectable_list_item",android.R.style.TextAppearance_Large));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ void extractListView(SimpleJsonWriter writer, String styleName, String qtClass)
+ {
+ JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
+ try {
+ Class<?> attrClass = Class.forName("android.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+
+ int[] styleAttrs = (int[]) styleableClass.getDeclaredField("ListView").get(null);
+ TypedArray a = m_theme.obtainStyledAttributes(null, styleAttrs, styleId, 0);
+
+ Drawable divider = a.getDrawable(getField(styleableClass,"ListView_divider"));
+ if (divider != null)
+ json.put("ListView_divider", getDrawable(divider, styleName + "_ListView_divider"));
+
+ json.put("ListView_dividerHeight", a.getDimensionPixelSize(getField(styleableClass, "ListView_dividerHeight"), 0));
+
+ a.recycle();
+ writer.name(styleName).value(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ void extractCalendar(SimpleJsonWriter writer, String styleName, String qtClass)
+ {
+ JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
+ try {
+ Class<?> attrClass = Class.forName("android.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+
+ int[] styleAttrs = (int[]) styleableClass.getDeclaredField("CalendarView").get(null);
+ TypedArray a = m_theme.obtainStyledAttributes(null, styleAttrs, styleId, 0);
+
+ Drawable d = a.getDrawable(getField(styleableClass,"CalendarView_selectedDateVerticalBar"));
+ if (d != null)
+ json.put("CalendarView_selectedDateVerticalBar", getDrawable(d, styleName + "_CalendarView_selectedDateVerticalBar"));
+
+ int dateTextAppearance = a.getResourceId(styleableClass.getDeclaredField("CalendarView_dateTextAppearance").getInt(null), -1);
+ json.put("CalendarView_dateTextAppearance", extractTextAppearance(dateTextAppearance));
+
+ int weekDayTextAppearance = a.getResourceId(styleableClass.getDeclaredField("CalendarView_weekDayTextAppearance").getInt(null), -1);
+ json.put("CalendarView_weekDayTextAppearance", extractTextAppearance(weekDayTextAppearance));
+
+ json.put("CalendarView_firstDayOfWeek", a.getInt(getField(styleableClass, "CalendarView_firstDayOfWeek"), 0));
+ json.put("CalendarView_focusedMonthDateColor", a.getColor(getField(styleableClass, "CalendarView_focusedMonthDateColor"), 0));
+ json.put("CalendarView_selectedWeekBackgroundColor", a.getColor(getField(styleableClass, "CalendarView_selectedWeekBackgroundColor"), 0));
+ json.put("CalendarView_showWeekNumber", a.getBoolean(getField(styleableClass, "CalendarView_showWeekNumber"), true));
+ json.put("CalendarView_shownWeekCount", a.getInt(getField(styleableClass, "CalendarView_shownWeekCount"), 6));
+ json.put("CalendarView_unfocusedMonthDateColor", a.getColor(getField(styleableClass, "CalendarView_unfocusedMonthDateColor"), 0));
+ json.put("CalendarView_weekNumberColor", a.getColor(getField(styleableClass, "CalendarView_weekNumberColor"), 0));
+ json.put("CalendarView_weekSeparatorLineColor", a.getColor(getField(styleableClass, "CalendarView_weekSeparatorLineColor"), 0));
+
+ a.recycle();
+ writer.name(styleName).value(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ void extractToolBar(SimpleJsonWriter writer, String styleName, String qtClass)
+ {
+ JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
+ try {
+ Class<?> attrClass = Class.forName("com.android.internal.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+
+ int[] styleAttrs = (int[]) styleableClass.getDeclaredField("ActionBar").get(null);
+ TypedArray a = m_theme.obtainStyledAttributes(null, styleAttrs, styleId, 0);
+
+ Drawable d = a.getDrawable(getField(styleableClass,"ActionBar_background"));
+ if (d != null)
+ json.put("ActionBar_background", getDrawable(d, styleName + "_ActionBar_background"));
+
+ d = a.getDrawable(getField(styleableClass,"ActionBar_backgroundStacked"));
+ if (d != null)
+ json.put("ActionBar_backgroundStacked", getDrawable(d, styleName + "_ActionBar_backgroundStacked"));
+
+ d = a.getDrawable(getField(styleableClass,"ActionBar_backgroundSplit"));
+ if (d != null)
+ json.put("ActionBar_backgroundSplit", getDrawable(d, styleName + "_ActionBar_backgroundSplit"));
+
+ d = a.getDrawable(getField(styleableClass,"ActionBar_divider"));
+ if (d != null)
+ json.put("ActionBar_divider", getDrawable(d, styleName + "_ActionBar_divider"));
+
+ json.put("ActionBar_itemPadding", a.getDimensionPixelSize(getField(styleableClass, "ActionBar_itemPadding"), 0));
+
+ a.recycle();
+ writer.name(styleName).value(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ void extractTabBar(SimpleJsonWriter writer, String styleName, String qtClass)
+ {
+ JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
+ try {
+ Class<?> attrClass = Class.forName("android.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+
+ int[] styleAttrs = (int[]) styleableClass.getDeclaredField("LinearLayout").get(null);
+ TypedArray a = m_theme.obtainStyledAttributes(null, styleAttrs, styleId, 0);
+
+ Drawable d = a.getDrawable(getField(styleableClass,"LinearLayout_divider"));
+ if (d != null)
+ json.put("LinearLayout_divider", getDrawable(d, styleName + "_LinearLayout_divider"));
+ json.put("LinearLayout_showDividers", a.getInt(getField(styleableClass, "LinearLayout_showDividers"), 0));
+ json.put("LinearLayout_dividerPadding", a.getDimensionPixelSize(getField(styleableClass, "LinearLayout_dividerPadding"), 0));
+
+ a.recycle();
+ writer.name(styleName).value(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void extractWindow(SimpleJsonWriter writer, String styleName) {
+ JSONObject json = new JSONObject();
+ try
+ {
+ Class<?> attrClass = Class.forName("android.R$attr");
+ int[] windowAttrs = (int[]) styleableClass.getDeclaredField("Window").get(null);
+
+ int backgroundId = attrClass.getDeclaredField("windowBackground").getInt(null);
+ TypedArray a = m_theme.obtainStyledAttributes(null, windowAttrs, backgroundId, 0);
+ Drawable background = a.getDrawable(getField(styleableClass, "Window_windowBackground"));
+ if (background != null)
+ json.put("Window_windowBackground", getDrawable(background, styleName + "_Window_windowBackground"));
+ a.recycle();
+
+ int frameId = attrClass.getDeclaredField("windowFrame").getInt(null);
+ a = m_theme.obtainStyledAttributes(null, windowAttrs, frameId, 0);
+ Drawable frame = a.getDrawable(getField(styleableClass, "Window_windowFrame"));
+ if (frame != null)
+ json.put("Window_windowFrame", getDrawable(frame, styleName + "_Window_windowFrame"));
+ a.recycle();
+
+ writer.name(styleName).value(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public ExtractStyle(Context context, String extractPath)
+ {
+// Log.i(MinistroService.TAG, "Extract " + extractPath);
+ m_extractPath = extractPath + "/";
+ new File(m_extractPath).mkdirs();
+// MinistroActivity.nativeChmode(m_extractPath, 0755);
+ m_context = context;
+ m_theme = context.getTheme();
+ TypedArray array = m_theme.obtainStyledAttributes(new int[]{
+ android.R.attr.colorBackground,
+ android.R.attr.textColorPrimary,
+ });
+ defaultBackgroundColor = array.getColor(0, 0);
+ defaultTextColor = array.getColor(1, 0xFFFFFF);
+ array.recycle();
+
+ try
+ {
+ SimpleJsonWriter jsonWriter = new SimpleJsonWriter(m_extractPath+"style.json");
+ jsonWriter.beginObject();
+ try {
+ extractWindow(jsonWriter, "windowStyle");
+ jsonWriter.name("buttonStyle").value(extractTextAppearanceInformations("buttonStyle", "QPushButton", null, -1));
+ jsonWriter.name("spinnerStyle").value(extractTextAppearanceInformations("spinnerStyle", "QComboBox", null, -1));
+ extractProgressBar(jsonWriter, "progressBarStyleHorizontal", "QProgressBar");
+ extractProgressBar(jsonWriter, "progressBarStyleLarge", null);
+ extractProgressBar(jsonWriter, "progressBarStyleSmall", null);
+ extractProgressBar(jsonWriter, "progressBarStyle", null);
+ extractAbsSeekBar(jsonWriter, "seekBarStyle", "QSlider");
+ if (Build.VERSION.SDK_INT > 13) {
+ extractSwitch(jsonWriter, "switchStyle", null);
+ }
+ extractCompoundButton(jsonWriter, "checkboxStyle", "QCheckBox");
+ jsonWriter.name("editTextStyle").value(extractTextAppearanceInformations("editTextStyle", "QLineEdit", null, -1));
+ extractCompoundButton(jsonWriter, "radioButtonStyle", "QRadioButton");
+ jsonWriter.name("textViewStyle").value(extractTextAppearanceInformations("textViewStyle", "QWidget", null, -1));
+ jsonWriter.name("scrollViewStyle").value(extractTextAppearanceInformations("scrollViewStyle", "QAbstractScrollArea", null, -1));
+ extractListView(jsonWriter, "listViewStyle", "QListView");
+ jsonWriter.name("listSeparatorTextViewStyle").value(extractTextAppearanceInformations("listSeparatorTextViewStyle", null, null, -1));
+ extractItemsStyle(jsonWriter);
+ extractCompoundButton(jsonWriter, "buttonStyleToggle", null);
+ if (Build.VERSION.SDK_INT > 10) {
+ extractCalendar(jsonWriter, "calendarViewStyle", "QCalendarWidget");
+ extractToolBar(jsonWriter, "actionBarStyle", "QToolBar");
+ jsonWriter.name("actionButtonStyle").value(extractTextAppearanceInformations("actionButtonStyle", "QToolButton", null, -1));
+ jsonWriter.name("actionBarTabTextStyle").value(extractTextAppearanceInformations("actionBarTabTextStyle", null, null, -1));
+ jsonWriter.name("actionBarTabStyle").value(extractTextAppearanceInformations("actionBarTabStyle", null, null, -1));
+ jsonWriter.name("actionOverflowButtonStyle").value(extractImageViewInformations("actionOverflowButtonStyle", null));
+ extractTabBar(jsonWriter, "actionBarTabBarStyle", "QTabBar");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ jsonWriter.endObject();
+ jsonWriter.close();
+// MinistroActivity.nativeChmode(m_extractPath+"style.json", 0644);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index 9e067f14c5..db970b6656 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -45,6 +45,7 @@ package org.qtproject.qt5.android;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
@@ -99,6 +100,7 @@ public class QtActivityDelegate
private static final String APPLICATION_PARAMETERS_KEY = "application.parameters";
private static final String STATIC_INIT_CLASSES_KEY = "static.init.classes";
private static final String NECESSITAS_API_LEVEL_KEY = "necessitas.api.level";
+ private static final String EXTRACT_STYLE_KEY = "extract.android.style";
private static String m_environmentVariables = null;
private static String m_applicationParameters = null;
@@ -109,6 +111,7 @@ public class QtActivityDelegate
private String m_mainLib;
private long m_metaState;
private int m_lastChar = 0;
+ private int m_softInputMode = 0;
private boolean m_fullScreen = false;
private boolean m_started = false;
private HashMap<Integer, QtSurface> m_surfaces = null;
@@ -245,10 +248,12 @@ public class QtActivityDelegate
if (m_imm == null)
return;
- if (height > m_layout.getHeight() * 2 / 3)
- m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
- else
+ if (m_softInputMode == 0 && height > m_layout.getHeight() * 2 / 3)
+ m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+ else if (m_softInputMode == 0)
m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
+ else
+ m_activity.getWindow().setSoftInputMode(m_softInputMode);
int initialCapsMode = 0;
int imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
@@ -422,6 +427,11 @@ public class QtActivityDelegate
if (null == m_mainLib && libraries.size() > 0)
m_mainLib = libraries.get(libraries.size() - 1);
+ if (loaderParams.containsKey(EXTRACT_STYLE_KEY)) {
+ String path = loaderParams.getString(EXTRACT_STYLE_KEY);
+ new ExtractStyle(m_activity, path);
+ }
+
try {
m_super_dispatchKeyEvent = m_activity.getClass().getMethod("super_dispatchKeyEvent", KeyEvent.class);
m_super_onRestoreInstanceState = m_activity.getClass().getMethod("super_onRestoreInstanceState", Bundle.class);
@@ -463,6 +473,12 @@ public class QtActivityDelegate
else
m_applicationParameters = "";
+ try {
+ m_softInputMode = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), 0).softInputMode;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
return true;
}
@@ -496,6 +512,9 @@ public class QtActivityDelegate
? extras.getString("gdbserver_socket")
: "+debug-socket";
+ if (!(new File(gdbserverPath)).exists())
+ gdbserverPath += ".so";
+
// start debugger
m_debuggerProcess = Runtime.getRuntime().exec(gdbserverPath
+ socket
@@ -531,6 +550,11 @@ public class QtActivityDelegate
int timeOut = 30000; // ms until we give up on ping and pong
int maxAttempts = timeOut / napTime;
+ if (gdbserverSocket != null) {
+ debugLog("removing gdb socket " + gdbserverSocket);
+ new File(gdbserverSocket).delete();
+ }
+
if (usePing) {
debugLog("removing ping file " + pingFile);
File ping = new File(pingFile);
@@ -605,6 +629,8 @@ public class QtActivityDelegate
debugLog("go to sleep");
Thread.sleep(napTime);
}
+ debugLog("Removing pingFile " + pingFile);
+ new File(pingFile).delete();
if (i == maxAttempts) {
debugLog("time out when waiting for pong file");
@@ -794,15 +820,6 @@ public class QtActivityDelegate
if (!m_started)
return false;
- if (keyCode == KeyEvent.KEYCODE_MENU) {
- try {
- return (Boolean)m_super_onKeyDown.invoke(m_activity, keyCode, event);
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- }
-
m_metaState = MetaKeyKeyListener.handleKeyDown(m_metaState, keyCode, event);
int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(m_metaState));
int lc = c;
@@ -837,15 +854,6 @@ public class QtActivityDelegate
if (!m_started)
return false;
- if (keyCode == KeyEvent.KEYCODE_MENU) {
- try {
- return (Boolean)m_super_onKeyUp.invoke(m_activity, keyCode, event);
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- }
-
if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP
|| keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_MUTE)
@@ -883,7 +891,7 @@ public class QtActivityDelegate
return false;
}
- private boolean m_opionsMenuIsVisible = false;
+ private boolean m_optionsMenuIsVisible = false;
public boolean onCreateOptionsMenu(Menu menu)
{
menu.clear();
@@ -891,7 +899,7 @@ public class QtActivityDelegate
}
public boolean onPrepareOptionsMenu(Menu menu)
{
- m_opionsMenuIsVisible = true;
+ m_optionsMenuIsVisible = true;
boolean res = QtNative.onPrepareOptionsMenu(menu);
setActionBarVisibility(res && menu.size() > 0);
return res;
@@ -904,7 +912,7 @@ public class QtActivityDelegate
public void onOptionsMenuClosed(Menu menu)
{
- m_opionsMenuIsVisible = false;
+ m_optionsMenuIsVisible = false;
QtNative.onOptionsMenuClosed(menu);
}
@@ -918,7 +926,7 @@ public class QtActivityDelegate
}
}
else
- if (m_opionsMenuIsVisible)
+ if (m_optionsMenuIsVisible)
m_activity.closeOptionsMenu();
}
private boolean m_contextMenuVisible = false;
@@ -1082,11 +1090,14 @@ public class QtActivityDelegate
Log.e(QtNative.QtTAG, "Surface " + id +" not found!");
}
+ if (view == null)
+ return;
+
// Keep last frame in stack until it is replaced to get correct
// shutdown transition
if (m_surfaces.size() == 0 && m_nativeViews.size() == 0) {
m_dummyView = view;
- } else if (view != null) {
+ } else {
m_layout.removeView(view);
}
}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 0e2af9a192..8b0febe641 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -470,6 +470,16 @@ public class QtNative
});
}
+ private static void openOptionsMenu()
+ {
+ runAction(new Runnable() {
+ @Override
+ public void run() {
+ m_activity.openOptionsMenu();
+ }
+ });
+ }
+
private static byte[][] getSSLCertificates()
{
ArrayList<byte[]> certificateList = new ArrayList<byte[]>();
diff --git a/src/android/java/java.pro b/src/android/java/java.pro
index cff2d55d86..9d37eb1026 100644
--- a/src/android/java/java.pro
+++ b/src/android/java/java.pro
@@ -1,8 +1,6 @@
CONFIG -= qt android_install
javaresources.files = \
- $$PWD/AndroidManifest.xml \
- $$PWD/version.xml \
$$PWD/res \
$$PWD/src
@@ -18,8 +16,6 @@ INSTALLS += javaresources
OUT_PATH = $$shell_path($$OUT_PWD)
QMAKE_POST_LINK += \
- $${QMAKE_COPY} $$shell_path($$PWD/AndroidManifest.xml) $$OUT_PATH $$RETURN \
- $${QMAKE_COPY} $$shell_path($$PWD/version.xml) $$OUT_PATH $$RETURN \
$${QMAKE_COPY_DIR} $$shell_path($$PWD/res) $$OUT_PATH $$RETURN \
$${QMAKE_COPY_DIR} $$shell_path($$PWD/src) $$OUT_PATH
}
diff --git a/src/android/java/res/values/strings.xml b/src/android/java/res/values/strings.xml
index 300f0673a4..fcc3eb097b 100644
--- a/src/android/java/res/values/strings.xml
+++ b/src/android/java/res/values/strings.xml
@@ -1,7 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
- <string name="app_name"><!-- %%INSERT_APP_NAME%% --></string>
-
+ <!-- %%INSERT_STRINGS -->
<string name="ministro_not_found_msg">Can\'t find Ministro service.\nThe application can\'t start.</string>
<string name="ministro_needed_msg">This application requires Ministro service. Would you like to install it?</string>
<string name="fatal_error_msg">Your application encountered a fatal error and cannot continue.</string>
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
index 45be15bc01..e526c0a210 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
@@ -117,6 +117,7 @@ public class QtActivity extends Activity
private static final String MAIN_LIBRARY_KEY = "main.library";
private static final String STATIC_INIT_CLASSES_KEY = "static.init.classes";
private static final String NECESSITAS_API_LEVEL_KEY = "necessitas.api.level";
+ private static final String EXTRACT_STYLE_KEY = "extract.android.style";
/// Ministro server parameter keys
private static final String REQUIRED_MODULES_KEY = "required.modules";
@@ -178,6 +179,7 @@ public class QtActivity extends Activity
// * unstable - unstable repository, DO NOT use this repository in production,
// this repository is used to push Qt snapshots.
private String[] m_qtLibs = null; // required qt libs
+ private int m_displayDensity = -1;
public QtActivity()
{
@@ -630,6 +632,15 @@ public class QtActivity extends Activity
m_activityInfo.metaData.getString("android.app.static_init_classes").split(":"));
}
loaderParams.putStringArrayList(NATIVE_LIBRARIES_KEY, libraryList);
+
+
+ String themePath = getApplicationInfo().dataDir + "/qt-reserved-files/android-style/";
+ String stylePath = themePath + m_displayDensity + "/";
+ if (!(new File(stylePath)).exists())
+ loaderParams.putString(EXTRACT_STYLE_KEY, stylePath);
+ ENVIRONMENT_VARIABLES += "\tMINISTRO_ANDROID_STYLE_PATH=" + stylePath
+ + "\tQT_ANDROID_THEMES_ROOT_PATH=" + themePath;
+
loaderParams.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES
+ "\tQML2_IMPORT_PATH=" + pluginsPrefix + "/qml"
+ "\tQML_IMPORT_PATH=" + pluginsPrefix + "/imports"
@@ -868,8 +879,10 @@ public class QtActivity extends Activity
return;
}
+ m_displayDensity = getResources().getDisplayMetrics().densityDpi;
+
ENVIRONMENT_VARIABLES += "\tQT_ANDROID_THEME=" + QT_ANDROID_DEFAULT_THEME
- + "/\tQT_ANDROID_THEME_DISPLAY_DPI=" + getResources().getDisplayMetrics().densityDpi + "\t";
+ + "/\tQT_ANDROID_THEME_DISPLAY_DPI=" + m_displayDensity + "\t";
if (null == getLastNonConfigurationInstance()) {
// if splash screen is defined, then show it
@@ -877,6 +890,13 @@ public class QtActivity extends Activity
getWindow().setBackgroundDrawableResource(m_activityInfo.metaData.getInt("android.app.splash_screen_drawable"));
else
getWindow().setBackgroundDrawable(new ColorDrawable(0xff000000));
+
+ if (m_activityInfo.metaData.containsKey("android.app.background_running")
+ && m_activityInfo.metaData.getBoolean("android.app.background_running")) {
+ ENVIRONMENT_VARIABLES += "QT_BLOCK_EVENT_LOOPS_WHEN_SUSPENDED=0\t";
+ } else {
+ ENVIRONMENT_VARIABLES += "QT_BLOCK_EVENT_LOOPS_WHEN_SUSPENDED=1\t";
+ }
startApp(true);
}
}
diff --git a/src/android/java/version.xml b/src/android/java/version.xml
deleted file mode 100644
index e05bba7588..0000000000
--- a/src/android/java/version.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<version value="5.3">
- <ignore>
- <file>AndroidManifest.xml</file>
- <file>libs.xml</file>
- <file>logo.png</file>
- <file>icon.png</file>
- </ignore>
-</version>
diff --git a/src/android/java/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml
index 8e551ba7ac..60c612976f 100644
--- a/src/android/java/AndroidManifest.xml
+++ b/src/android/templates/AndroidManifest.xml
@@ -1,9 +1,9 @@
<?xml version='1.0' encoding='utf-8'?>
<manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
- <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="@string/app_name">
+ <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation"
android:name="org.qtproject.qt5.android.bindings.QtActivity"
- android:label="@string/app_name"
+ android:label="-- %%INSERT_APP_NAME%% --"
android:screenOrientation="unspecified"
android:launchMode="singleTop">
<intent-filter>
@@ -36,6 +36,14 @@
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>
-->
<!-- Splash screen -->
+
+ <!-- Background running -->
+ <!-- Warning: changing this value to true may cause unexpected crashes if the
+ application still try to draw after
+ "applicationStateChanged(Qt::ApplicationSuspended)"
+ signal is sent! -->
+ <meta-data android:name="android.app.background_running" android:value="false"/>
+ <!-- Background running -->
</activity>
</application>
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/>
diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle
new file mode 100644
index 0000000000..d1ff362269
--- /dev/null
+++ b/src/android/templates/build.gradle
@@ -0,0 +1,51 @@
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.12.1'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+}
+
+android {
+ /*******************************************************
+ * The following variables:
+ * - androidBuildToolsVersion,
+ * - androidCompileSdkVersion
+ * - qt5AndroidDir - holds the path to qt android files
+ * needed to build any Qt application
+ * on Android.
+ *
+ * are defined in gradle.properties file. This file is
+ * updated by QtCreator and androiddeployqt tools.
+ * Changing them manually might break the compilation!
+ *******************************************************/
+
+ compileSdkVersion androidCompileSdkVersion.toInteger()
+
+ buildToolsVersion androidBuildToolsVersion
+
+ sourceSets {
+ main {
+ manifest.srcFile 'AndroidManifest.xml'
+ java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
+ aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
+ res.srcDirs = [qt5AndroidDir + '/res', 'res']
+ resources.srcDirs = ['src']
+ renderscript.srcDirs = ['src']
+ assets.srcDirs = ['assets']
+ jniLibs.srcDirs = ['libs']
+ }
+ }
+
+ lintOptions {
+ abortOnError false
+ }
+}
diff --git a/src/android/java/res/values/libs.xml b/src/android/templates/res/values/libs.xml
index 664ab0abec..664ab0abec 100644
--- a/src/android/java/res/values/libs.xml
+++ b/src/android/templates/res/values/libs.xml
diff --git a/src/android/templates/templates.pro b/src/android/templates/templates.pro
new file mode 100644
index 0000000000..684a556c5b
--- /dev/null
+++ b/src/android/templates/templates.pro
@@ -0,0 +1,21 @@
+CONFIG -= qt android_install
+
+templates.files = \
+ $$PWD/AndroidManifest.xml \
+ $$PWD/res
+
+templates.path = $$[QT_INSTALL_PREFIX]/src/android/templates
+
+INSTALLS += templates
+
+!prefix_build:!equals(OUT_PWD, $$PWD) {
+ RETURN = $$escape_expand(\\n\\t)
+ equals(QMAKE_HOST.os, Windows) {
+ RETURN = $$escape_expand(\\r\\n\\t)
+ }
+ OUT_PATH = $$shell_path($$OUT_PWD)
+
+ QMAKE_POST_LINK += \
+ $${QMAKE_COPY} $$shell_path($$PWD/AndroidManifest.xml) $$OUT_PATH $$RETURN \
+ $${QMAKE_COPY_DIR} $$shell_path($$PWD/res) $$OUT_PATH
+}