summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/3rdparty/android/extract.h117
-rw-r--r--src/android/jar/jar.pri3
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java1344
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java6
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java17
-rw-r--r--src/plugins/platforms/android/android.pro7
-rw-r--r--src/plugins/platforms/android/extract.cpp135
7 files changed, 1625 insertions, 4 deletions
diff --git a/src/3rdparty/android/extract.h b/src/3rdparty/android/extract.h
new file mode 100644
index 0000000000..f7928e20a8
--- /dev/null
+++ b/src/3rdparty/android/extract.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef EXTRACT_H
+#define EXTRACT_H
+
+#include <cstdint>
+#include <cstring>
+// shamelessly stolen from ResourceTypes.h Android's sources
+/**
+ * This chunk specifies how to split an image into segments for
+ * scaling.
+ *
+ * There are J horizontal and K vertical segments. These segments divide
+ * the image into J*K regions as follows (where J=4 and K=3):
+ *
+ * F0 S0 F1 S1
+ * +-----+----+------+-------+
+ * S2| 0 | 1 | 2 | 3 |
+ * +-----+----+------+-------+
+ * | | | | |
+ * | | | | |
+ * F2| 4 | 5 | 6 | 7 |
+ * | | | | |
+ * | | | | |
+ * +-----+----+------+-------+
+ * S3| 8 | 9 | 10 | 11 |
+ * +-----+----+------+-------+
+ *
+ * Each horizontal and vertical segment is considered to by either
+ * stretchable (marked by the Sx labels) or fixed (marked by the Fy
+ * labels), in the horizontal or vertical axis, respectively. In the
+ * above example, the first is horizontal segment (F0) is fixed, the
+ * next is stretchable and then they continue to alternate. Note that
+ * the segment list for each axis can begin or end with a stretchable
+ * or fixed segment.
+ *
+ * The relative sizes of the stretchy segments indicates the relative
+ * amount of stretchiness of the regions bordered by the segments. For
+ * example, regions 3, 7 and 11 above will take up more horizontal space
+ * than regions 1, 5 and 9 since the horizontal segment associated with
+ * the first set of regions is larger than the other set of regions. The
+ * ratios of the amount of horizontal (or vertical) space taken by any
+ * two stretchable slices is exactly the ratio of their corresponding
+ * segment lengths.
+ *
+ * xDivs and yDivs point to arrays of horizontal and vertical pixel
+ * indices. The first pair of Divs (in either array) indicate the
+ * starting and ending points of the first stretchable segment in that
+ * axis. The next pair specifies the next stretchable segment, etc. So
+ * in the above example xDiv[0] and xDiv[1] specify the horizontal
+ * coordinates for the regions labeled 1, 5 and 9. xDiv[2] and
+ * xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that
+ * the leftmost slices always start at x=0 and the rightmost slices
+ * always end at the end of the image. So, for example, the regions 0,
+ * 4 and 8 (which are fixed along the X axis) start at x value 0 and
+ * go to xDiv[0] and slices 2, 6 and 10 start at xDiv[1] and end at
+ * xDiv[2].
+ *
+ * The array pointed to by the colors field lists contains hints for
+ * each of the regions. They are ordered according left-to-right and
+ * top-to-bottom as indicated above. For each segment that is a solid
+ * color the array entry will contain that color value; otherwise it
+ * will contain NO_COLOR. Segments that are completely transparent
+ * will always have the value TRANSPARENT_COLOR.
+ *
+ * The PNG chunk type is "npTc".
+ */
+struct Res_png_9patch
+{
+ Res_png_9patch() : wasDeserialized(false), xDivs(NULL),
+ yDivs(NULL), colors(NULL) { }
+
+ int8_t wasDeserialized;
+ int8_t numXDivs;
+ int8_t numYDivs;
+ int8_t numColors;
+
+ // These tell where the next section of a patch starts.
+ // For example, the first patch includes the pixels from
+ // 0 to xDivs[0]-1 and the second patch includes the pixels
+ // from xDivs[0] to xDivs[1]-1.
+ // Note: allocation/free of these pointers is left to the caller.
+ int32_t* xDivs;
+ int32_t* yDivs;
+
+ int32_t paddingLeft, paddingRight;
+ int32_t paddingTop, paddingBottom;
+
+ enum {
+ // The 9 patch segment is not a solid color.
+ NO_COLOR = 0x00000001,
+
+ // The 9 patch segment is completely transparent.
+ TRANSPARENT_COLOR = 0x00000000
+ };
+ // Note: allocation/free of this pointer is left to the caller.
+ uint32_t* colors;
+
+ // Deserialize/Unmarshall the patch data
+ static Res_png_9patch* deserialize(const void* data);
+};
+
+#endif
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..4544eebd33
--- /dev/null
+++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
@@ -0,0 +1,1344 @@
+/****************************************************************************
+**
+** 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 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.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.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);
+
+ 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_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 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 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) {
+ 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};
+ final String[] DrawableStatesLabels = {"active", "checked", "enabled", "focused", "pressed", "selected", "window_focused", "background", "multiline", "activated"};
+ final String[] DisableDrawableStatesLabels = {"inactive", "unchecked", "disabled", "not_focused", "no_pressed", "unselected", "window_not_focused", "background", "multiline", "activated"};
+
+ 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++)
+ {
+ JSONObject layerJsonObject=getDrawable(layers.getDrawable(i), filename+"__"+layers.getId(i));
+ layerJsonObject.put("id", layers.getId(i));
+ 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);
+ 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("solidColor",gradientStateClass.getField("mSolidColor").getInt(obj));
+ json.put("strokeWidth",gradientStateClass.getField("mStrokeWidth").getInt(obj));
+ json.put("strokeColor",gradientStateClass.getField("mStrokeColor").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));
+ } 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);
+ return getJsonChunkInfo(extractNativeChunkInfo(mNativeChunk.getInt(np)));
+ }
+ }
+
+ public JSONObject getDrawable(Object drawable, String 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 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());
+// 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_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));
+ }
+ a.recycle();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ 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(JSONObject parentObject, 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();
+ parentObject.put(styleName, 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(JSONObject parentObject, String styleName, String qtClass)
+ {
+ JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
+ try {
+ extractProgressBarInfo(json, styleName);
+ parentObject.put(styleName, json);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+ void extractAbsSeekBar(JSONObject parentObject, 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"));
+
+ a.recycle();
+ parentObject.put(styleName, 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(JSONObject json) {
+ try
+ {
+ json.put("simple_list_item",extractItemStyle(android.R.layout.simple_list_item_1, "simple_list_item", android.R.style.TextAppearance_Large));
+ json.put("simple_list_item_checked",extractItemStyle(android.R.layout.simple_list_item_checked, "simple_list_item_checked", android.R.style.TextAppearance_Large));
+ json.put("simple_list_item_multiple_choice",extractItemStyle(android.R.layout.simple_list_item_multiple_choice, "simple_list_item_multiple_choice", android.R.style.TextAppearance_Large));
+ json.put("simple_list_item_single_choice",extractItemStyle(android.R.layout.simple_list_item_single_choice, "simple_list_item_single_choice", android.R.style.TextAppearance_Large));
+ json.put("simple_spinner_item",extractItemStyle(android.R.layout.simple_spinner_item, "simple_spinner_item", -1));
+ json.put("simple_spinner_dropdown_item",extractItemStyle(android.R.layout.simple_spinner_dropdown_item, "simple_spinner_dropdown_item",android.R.style.TextAppearance_Large));
+ json.put("simple_dropdown_item_1line",extractItemStyle(android.R.layout.simple_dropdown_item_1line, "simple_dropdown_item_1line",android.R.style.TextAppearance_Large));
+ } 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();
+
+ JSONObject json = new JSONObject();
+ try {
+ json.put("buttonStyle", extractTextAppearanceInformations("buttonStyle", "QPushButton", null, -1));
+ json.put("spinnerStyle", extractTextAppearanceInformations("spinnerStyle", "QComboBox", null, -1));
+ extractProgressBar(json, "progressBarStyleHorizontal", "QProgressBar");
+ extractAbsSeekBar(json, "seekBarStyle", "QSlider");
+ extractCompoundButton(json, "checkboxStyle", "QCheckBox");
+ json.put("editTextStyle", extractTextAppearanceInformations("editTextStyle", "QLineEdit", null, -1));
+ extractCompoundButton(json, "radioButtonStyle", "QRadioButton");
+ json.put("textViewStyle", extractTextAppearanceInformations("textViewStyle", "QWidget", null, -1));
+ extractItemsStyle(json);
+ extractCompoundButton(json, "buttonStyleToggle", null);
+ OutputStreamWriter jsonWriter;
+ jsonWriter = new OutputStreamWriter(new FileOutputStream(m_extractPath+"style.json"));
+ jsonWriter.write(json.toString(1));
+ 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 554c54d4a0..7e7312cde8 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -99,6 +99,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;
@@ -426,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);
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 f99bb84077..43b04d17f0 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
@@ -116,6 +116,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";
@@ -177,6 +178,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()
{
@@ -629,6 +631,17 @@ public class QtActivity extends Activity
m_activityInfo.metaData.getString("android.app.static_init_classes").split(":"));
}
loaderParams.putStringArrayList(NATIVE_LIBRARIES_KEY, libraryList);
+
+
+ if (bundlingQtLibs) {
+ String themePath = pluginsPrefix + "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"
@@ -867,8 +880,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
diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro
index 243eea071a..32c37ab17a 100644
--- a/src/plugins/platforms/android/android.pro
+++ b/src/plugins/platforms/android/android.pro
@@ -21,7 +21,9 @@ CONFIG += qpa/genericunixfontdatabase
OTHER_FILES += $$PWD/android.json
-INCLUDEPATH += $$PWD
+INCLUDEPATH += \
+ $$PWD \
+ $$QT_SOURCE_TREE/src/3rdparty/android
SOURCES += $$PWD/androidplatformplugin.cpp \
$$PWD/androidjnimain.cpp \
@@ -48,7 +50,8 @@ SOURCES += $$PWD/androidplatformplugin.cpp \
$$PWD/qandroidplatformrasterwindow.cpp \
$$PWD/qandroidplatformbackingstore.cpp \
$$PWD/qandroidplatformopenglcontext.cpp \
- $$PWD/qandroidplatformforeignwindow.cpp
+ $$PWD/qandroidplatformforeignwindow.cpp \
+ $$PWD/extract.cpp
HEADERS += $$PWD/qandroidplatformintegration.h \
$$PWD/androidjnimain.h \
diff --git a/src/plugins/platforms/android/extract.cpp b/src/plugins/platforms/android/extract.cpp
new file mode 100644
index 0000000000..82687e61a7
--- /dev/null
+++ b/src/plugins/platforms/android/extract.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+
+
+#include <jni.h>
+#include <android/log.h>
+#include <extract.h>
+#include <alloca.h>
+
+#define LOG_TAG "extractSyleInfo"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)
+
+extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo(JNIEnv * env, jobject, Res_png_9patch* chunk)
+{
+ Res_png_9patch::deserialize(chunk);
+ //printChunkInformation(chunk);
+ jintArray result;
+ size_t size = 3+chunk->numXDivs+chunk->numYDivs+chunk->numColors;
+ result = env->NewIntArray(size);
+ if (!result)
+ return 0;
+
+ jint *data = (jint*)malloc(sizeof(jint)*size);
+ size_t pos = 0;
+ data[pos++]=chunk->numXDivs;
+ data[pos++]=chunk->numYDivs;
+ data[pos++]=chunk->numColors;
+ for (int x = 0; x <chunk->numXDivs; x ++)
+ data[pos++]=chunk->xDivs[x];
+ for (int y = 0; y <chunk->numYDivs; y ++)
+ data[pos++]=chunk->yDivs[y];
+ for (int c = 0; c <chunk->numColors; c ++)
+ data[pos++]=chunk->colors[c];
+ env->SetIntArrayRegion(result, 0, size, data);
+ free(data);
+ return result;
+}
+
+extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractChunkInfo(JNIEnv * env, jobject obj, jbyteArray chunkObj)
+{
+ size_t chunkSize = env->GetArrayLength(chunkObj);
+ void* storage = alloca(chunkSize);
+ env->GetByteArrayRegion(chunkObj, 0, chunkSize,
+ reinterpret_cast<jbyte*>(storage));
+
+ if (!env->ExceptionCheck())
+ return Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo(env, obj, static_cast<Res_png_9patch*>(storage));
+ else
+ env->ExceptionClear();
+ return 0;
+}
+
+// The following part was shamelessly stolen from ResourceTypes.cpp from Android's sources
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+static void deserializeInternal(const void* inData, Res_png_9patch* outData) {
+ char* patch = (char*) inData;
+ if (inData != outData) {
+ memmove(&outData->wasDeserialized, patch, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors
+ memmove(&outData->paddingLeft, patch + 12, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors
+ }
+ outData->wasDeserialized = true;
+ char* data = (char*)outData;
+ data += sizeof(Res_png_9patch);
+ outData->xDivs = (int32_t*) data;
+ data += outData->numXDivs * sizeof(int32_t);
+ outData->yDivs = (int32_t*) data;
+ data += outData->numYDivs * sizeof(int32_t);
+ outData->colors = (uint32_t*) data;
+}
+
+Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
+{
+ if (sizeof(void*) != sizeof(int32_t)) {
+ LOGE("Cannot deserialize on non 32-bit system\n");
+ return NULL;
+ }
+ deserializeInternal(inData, (Res_png_9patch*) inData);
+ return (Res_png_9patch*) inData;
+}