1
0
Fork 0

Initial commit

This commit is contained in:
Clam 2013-07-02 15:35:21 +10:00
commit 1f9a97929e
62 changed files with 99775 additions and 0 deletions

29
.gitignore vendored Normal file
View file

@ -0,0 +1,29 @@
# built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
# Local configuration file (sdk path, etc)
local.properties
# Eclipse project files
.classpath
.project
# Proguard folder generated by Eclipse
proguard/
# Intellij project files
*.iml
*.ipr
*.iws
.idea/

44
AndroidManifest.xml Normal file
View file

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.nyanya.android.traditionalt9"
android:versionCode="2"
android:versionName="1.2" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="10" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="false"
android:icon="@drawable/ic_launcher"
android:label="@string/ime_name"
android:theme="@style/AppTheme" >
<service
android:name="org.nyanya.android.traditionalt9.TraditionalT9"
android:permission="android.permission.BIND_INPUT_METHOD" >
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
<meta-data
android:name="android.view.im"
android:resource="@xml/method" />
</service>
<activity
android:name="org.nyanya.android.traditionalt9.TraditionalT9Settings"
android:label="@string/traditionalt9_settings" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
android:theme="@android:style/Theme.Dialog"
android:name="org.nyanya.android.traditionalt9.AddWordAct"
android:label="@string/title_activity_add_word" >
</activity>
</application>
</manifest>

8
README.md Normal file
View file

@ -0,0 +1,8 @@
Traditional T9 keypad IME for Android.
This is a Input Method Editor for Android that implements predictive text using the hardware keypad on the device. **Useless without a hardware numerical keypad.**
See Wiki for more information: [[Traditional T9 keypad IME for Android]]
Available on Google Play: [Traditional T9 Keypad IME](https://play.google.com/store/apps/details?id=org.nyanya.android.traditionalt9)

95694
assets/dict50-utf8.jet Normal file

File diff suppressed because it is too large Load diff

BIN
ic_launcher-web.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

20
proguard-project.txt Normal file
View file

@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

14
project.properties Normal file
View file

@ -0,0 +1,14 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-10

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- Gradient Bg for bootan -->
<gradient
android:startColor="#424542"
android:endColor="#A5A2A5"
android:angle="90" />
</shape>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/button_grad_press"
android:state_pressed="true" />
<item android:drawable="@drawable/button_grad"
android:state_focused="true" />
<item android:drawable="@drawable/button_grad" />
</selector>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- Gradient Bg for bootan -->
<gradient
android:startColor="#181C18"
android:endColor="#6B6D6B"
android:angle="90" />
</shape>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- Gradient Bg for bootan -->
<gradient
android:startColor="#8C8E8C"
android:endColor="#636163"
android:angle="90" />
</shape>

View file

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/add_word_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:privateImeOptions="org.nyanya.android.traditionalt9.addword=true" >
<requestFocus />
</EditText>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/add_word_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:onClick="addWordButton"
android:text="@string/add_word" />
<Button
android:id="@+id/add_word_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:onClick="cancelButton"
android:text="@string/cancel" />
</RelativeLayout>
</LinearLayout>

View file

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:orientation="vertical"
android:padding="5dp" >
<TextView
android:id="@+id/left_hold_upper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_marginBottom="2dp"
android:layout_marginTop="0dp"
android:gravity="center_vertical"
android:padding="2dp"
android:paddingTop="5dp"
android:text="@string/main_left_insert"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/button_text"
android:textSize="15sp" />
<TextView
android:id="@+id/left_hold_lower"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:drawableLeft="@drawable/holdicon"
android:drawablePadding="5dp"
android:gravity="center_vertical"
android:padding="2dp"
android:text="@string/main_left_addword"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/button_text"
android:textSize="11sp" />
</LinearLayout>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:orientation="vertical"
android:padding="5dp" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_marginBottom="2dp"
android:layout_marginTop="0dp"
android:gravity="center_vertical"
android:padding="2dp"
android:paddingTop="5dp"
android:text="@string/main_left_insert"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/button_text"
android:textSize="15sp" />
</LinearLayout>

61
res/layout/mainview.xml Normal file
View file

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginTop="0dp"
android:background="@drawable/bggradient"
android:baselineAligned="true"
android:gravity="bottom"
android:orientation="horizontal" >
<ViewSwitcher
android:id="@+id/main_left"
android:layout_width="190px"
android:layout_height="58dp"
android:layout_marginLeft="1px"
android:layout_marginRight="1px"
android:background="@drawable/button_custom"
android:clickable="true"
android:focusable="false"
android:longClickable="true" >
<include android:id="@+id/main_left_nohold" layout="@layout/lbuttonnohold" />
<include android:id="@+id/main_left_hold" layout="@layout/lbuttonhold" />
</ViewSwitcher>
<Button
android:id="@+id/main_mid"
android:layout_width="94px"
android:layout_height="58dp"
android:layout_marginLeft="1px"
android:layout_marginRight="1px"
android:background="@drawable/button_custom"
android:focusable="false"
android:longClickable="true"
android:text="@string/main_mid"
android:textColor="@color/button_text" />
<RelativeLayout
android:id="@+id/main_right"
android:layout_width="190px"
android:layout_height="58dp"
android:layout_marginLeft="1px"
android:layout_marginTop="0dp"
android:background="@drawable/button_custom"
android:clickable="true"
android:focusable="false"
android:longClickable="true"
android:paddingLeft="2dp"
android:paddingTop="1dp" >
<include
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
layout="@layout/rbutton" />
</RelativeLayout>
</LinearLayout>

View file

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginTop="0dp"
android:background="@drawable/bggradient"
android:baselineAligned="true"
android:gravity="bottom"
android:orientation="horizontal" >
<Button
android:id="@+id/main_leftold"
android:layout_width="190px"
android:layout_height="match_parent"
android:layout_marginLeft="1px"
android:layout_marginRight="1px"
android:background="@drawable/button_custom"
android:focusable="false"
android:longClickable="true"
android:text="@string/main_left_insert"
android:textColor="@color/button_text" />
<Button
android:id="@+id/main_mid"
android:layout_width="94px"
android:layout_height="match_parent"
android:layout_marginLeft="1px"
android:layout_marginRight="1px"
android:background="@drawable/button_custom"
android:focusable="false"
android:longClickable="true"
android:text="@string/main_mid"
android:textColor="@color/button_text" />
<RelativeLayout
android:id="@+id/main_right"
android:layout_width="190px"
android:layout_height="58dp"
android:layout_marginLeft="1px"
android:layout_marginTop="0dp"
android:background="@drawable/button_custom"
android:clickable="true"
android:focusable="false"
android:longClickable="true"
android:paddingLeft="2dp"
android:paddingTop="1dp" >
<include
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
layout="@layout/rbutton" />
</RelativeLayout>
</LinearLayout>

42
res/layout/rbutton.xml Normal file
View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:orientation="vertical"
android:padding="5dp" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_marginBottom="2dp"
android:layout_marginTop="0dp"
android:drawableLeft="@drawable/rcycle"
android:drawablePadding="5dp"
android:gravity="center_vertical"
android:padding="2dp"
android:paddingTop="5dp"
android:text="@string/main_right_upper"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/button_text"
android:textSize="15sp" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:drawableLeft="@drawable/holdicon"
android:drawablePadding="5dp"
android:gravity="center_vertical"
android:padding="2dp"
android:text="@string/main_right_lower"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/button_text"
android:textSize="11sp" />
</LinearLayout>

202
res/layout/symbolview.xml Normal file
View file

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="2dp" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingLeft="2dp"
android:paddingRight="2dp" >
<TextView
android:id="@+id/text_keyone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:background="@drawable/key_one"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/key_text"
android:textSize="30sp" />
<TextView
android:id="@+id/text_keytwo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerInParent="false"
android:background="@drawable/key_two"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/key_text"
android:textSize="30sp" />
<TextView
android:id="@+id/text_keythree"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@drawable/key_three"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/key_text"
android:textSize="30sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingLeft="2dp"
android:paddingRight="2dp" >
<TextView
android:id="@+id/text_keyfour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:background="@drawable/key_four"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/key_text"
android:textSize="30sp" />
<TextView
android:id="@+id/text_keyfive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="@drawable/key_five"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/key_text"
android:textSize="30sp" />
<TextView
android:id="@+id/text_keysix"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@drawable/key_six"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/key_text"
android:textSize="30sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingLeft="2dp"
android:paddingRight="2dp" >
<TextView
android:id="@+id/text_keyseven"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:background="@drawable/key_seven"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/key_text"
android:textSize="30sp" />
<TextView
android:id="@+id/text_keyeight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="@drawable/key_eight"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/key_text"
android:textSize="30sp" />
<TextView
android:id="@+id/text_keynine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@drawable/key_nine"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/key_text"
android:textSize="30sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingLeft="2dp"
android:paddingRight="2dp" >
<TextView
android:id="@+id/text_keystar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:background="@drawable/key_star"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:text="@string/symbol_prev"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/key_text" />
<TextView
android:id="@+id/text_keyzero"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="@drawable/key_zero"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/key_text"
android:textSize="30sp" />
<TextView
android:id="@+id/text_keypound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@drawable/key_pound"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:text="@string/symbol_next"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/key_text" />
</RelativeLayout>
</LinearLayout>

8
res/menu/add_word.xml Normal file
View file

@ -0,0 +1,8 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/action_settings"/>
</menu>

13
res/values/arrays.xml Normal file
View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="pref_inputmode_entries">
<item >English</item>
<item >Text</item>
<item >Number</item>
</string-array>
<string-array name="pref_inputmode_values">
<item >0</item>
<item >1</item>
<item >2</item>
</string-array>
</resources>

13
res/values/colors.xml Normal file
View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="candidate_normal">#FF000000</color>
<color name="candidate_recommended">#FFE35900</color>
<color name="candidate_other">#ff808080</color>
<color name="candidate_background">#bbffffff</color>
<color name="button_press">#FFFCBE2B</color>
<color name="button_focus">#FF2A9AEB</color>
<color name="button_default">#FFA8A8A8</color>
<color name="button_text">#FFFFFFFF</color>
<color name="key_text">#FF000000</color>
<color name="key_shadow">#FFFFFFFF</color>
</resources>

29
res/values/dimens.xml Normal file
View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2008, 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.
*/
-->
<resources>
<dimen name="key_height">50dip</dimen>
<dimen name="candidate_font_height">16sp</dimen>
<dimen name="candidate_vertical_padding">6sp</dimen>
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

53
res/values/strings.xml Normal file
View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Traditional T9</string>
<string name="ime_name">Traditional T9</string>
<string name="ime_english">English</string>
<string name="ime_number">Numbers</string>
<string name="pref_inputmode">Default Input Mode</string>
<string name="pref_inputmode_desc">Default mode used for \'normal\' text entry</string>
<string name="traditionalt9_settings">Traditional T9 Settings</string>
<string name="main_left_insert">Insert symbol</string>
<string name="main_left_addword">Add word</string>
<string name="main_mid">Done</string>
<string name="main_mid_commit">Commit</string>
<string name="main_right_upper">Cycle Mode</string>
<string name="main_right_lower">Change IME</string>
<string name="main_left_notfound">Add word?</string>
<string name="ricon_desc">Hold Icon</string>
<string name="symbol_next">Next Page</string>
<string name="symbol_prev">Prev Page</string>
<string name="add_word">Add word</string>
<string name="ok">OK</string>
<string name="add_word_blank">Blank word not added.</string>
<string name="add_word_exist1">Word (</string>
<string name="add_word_exist2">) already in DB.</string>
<string name="cancel">Cancel</string>
<string name="title_activity_add_word">Add Word</string>
<string name="action_settings">Settings</string>
<string name="pref_loaddict">Load dictionary</string>
<string name="pref_nukedict">Nuke dictionary</string>
<string name="pref_backupdict">Backup dictionary</string>
<string name="pref_restoredict">Restore dictionary</string>
<string name="pref_querytest">Query test</string>
<string name="pref_loadingdict">Loading dictionary…</string>
<string name="pref_loadingbackup">Restoring dictionary…</string>
<string name="pref_savingbackup">Backing up dictionary…</string>
<string name="pref_nukingdict">Nuking dictionary… Please wait…</string>
<string name="pref_backup_warn">Warning: An existing database backup exists. Do you wish to overwrite?</string>
<string name="pref_backup_title">Backup IME database</string>
<string name="pref_backup_noext">Error: No external storage available for backup. Backup will not continue.</string>
<string name="pref_restore_warn">Backup database entries will overwrite existing database entries. Entries not in the backup will be retained. If that is not desired behaviour select \"%1$s\" before selecting this option.</string>
<string name="pref_restore_title">Restore IME database</string>
<string name="pref_restore_noext">Error: No external storage available for restoring. Restore will not continue.</string>
<string name="pref_restore_nofile">Error: Backup file not found.</string>
<string name="pref_nuke_warn">Warning: This will delete your entire dictionary. Do you wish to continue?</string>
<string name="pref_nuke_title">Nuke IME dictionary</string>
<string name="hello_world">Hello world!</string>
</resources>

20
res/values/styles.xml Normal file
View file

@ -0,0 +1,20 @@
<resources>
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
</resources>

25
res/xml/method.xml Normal file
View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/**
* Copyright (c) 2008, 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.
*/
-->
<!-- The attributes in this XML file provide configuration information -->
<!-- for the Search Manager. -->
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="org.nyanya.android.traditionalt9.TraditionalT9Settings" >
</input-method>

18
res/xml/prefs.xml Normal file
View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="first_preferencescreen">
<ListPreference
android:key="pref_inputmode"
android:title="@string/pref_inputmode"
android:dialogTitle="@string/pref_inputmode"
android:entries="@array/pref_inputmode_entries"
android:entryValues="@array/pref_inputmode_values"
android:defaultValue="0" android:summary="@string/pref_inputmode_desc"/>
<Preference android:title="@string/pref_loaddict" android:key="loaddict"/>
<Preference android:title="@string/pref_nukedict" android:key="nukedict"/>
<Preference android:title="@string/pref_backupdict" android:key="backupdict"/>
<Preference android:title="@string/pref_restoredict" android:key="restoredict"/>
<Preference android:title="@string/pref_querytest" android:key="querytest"/>
</PreferenceScreen>

View file

@ -0,0 +1,275 @@
package org.nyanya.android.traditionalt9;
import android.app.Dialog;
import android.content.Context;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
public abstract class AbsSymDialog extends Dialog
implements View.OnClickListener {
private TraditionalT9 parent;
private View mainview;
private int pagenum = 1;
private int pageoffset = (pagenum-1)*10;
private int MAX_PAGE;
private String title;
private boolean started;
private static final int[] buttons = {
R.id.text_keyone, R.id.text_keytwo, R.id.text_keythree,
R.id.text_keyfour, R.id.text_keyfive, R.id.text_keysix,
R.id.text_keyseven, R.id.text_keyeight, R.id.text_keynine,
R.id.text_keyzero };
private static final int[] buttons2 = { R.id.text_keystar, R.id.text_keypound };
public AbsSymDialog(Context c, View mv) {
super(c);
parent = (TraditionalT9) c;
mainview = mv;
started = true;
setContentView(mv);
View button;
for (int x = 0; x < buttons.length; x++){
button = mv.findViewById(buttons[x]);
button.setOnClickListener(this);
}
for (int x = 0; x < buttons2.length; x++){
button = mv.findViewById(buttons2[x]);
button.setOnClickListener(this);
}
MAX_PAGE = getMaxPage();
title = getTitleText();
}
@Override
public void onClick(View v) {
//Log.d("SymbolPopup - onClick", "click happen: " + v);
switch (v.getId()) {
case R.id.text_keyone:
sendChar(pageoffset+0);
break;
case R.id.text_keytwo:
sendChar(pageoffset+1);
break;
case R.id.text_keythree:
sendChar(pageoffset+2);
break;
case R.id.text_keyfour:
sendChar(pageoffset+3);
break;
case R.id.text_keyfive:
sendChar(pageoffset+4);
break;
case R.id.text_keysix:
sendChar(pageoffset+5);
break;
case R.id.text_keyseven:
sendChar(pageoffset+6);
break;
case R.id.text_keyeight:
sendChar(pageoffset+7);
break;
case R.id.text_keynine:
sendChar(pageoffset+8);
break;
case R.id.text_keyzero:
sendChar(pageoffset+9);
break;
case R.id.text_keypound:
pageChange(1);
break;
case R.id.text_keystar:
pageChange(-1);
break;
}
}
protected abstract String getSymbol(int index);
protected abstract String getTitleText();
protected abstract int getSymbolSize();
protected abstract int getMaxPage();
private void sendChar(int index) {
//Log.d("SymbolDialog - sendChar", "Sending index: " + index);
if (index < getSymbolSize()) {
parent.onText(getSymbol(index));
//then close
pagenum = 1;
pageoffset = (pagenum-1)*10;
this.dismiss();
}
}
private void pageChange(int amt) {
pagenum = pagenum + amt;
if (pagenum > MAX_PAGE ) {
pagenum = 1;
} else if (pagenum < 1) {
pagenum = MAX_PAGE;
}
pageoffset = (pagenum-1)*10;
updateButtons();
}
private void updateButtons() {
// set page number text
setTitle("Insert "+ title + "\t\tPage " + pagenum + "/" + MAX_PAGE);
// update button labels
int symbx = pageoffset;
int stop = symbx + 9;
int nomore = stop;
int symsize = getSymbolSize();
if (nomore >= symsize-1) {
nomore = symsize-1;
}
for (int buttx = 0; symbx <= stop; symbx++) {
//Log.d("SymbolDialog - updateButtons", "buttx: " + buttx + " symbx: " + symbx);
if (symbx > nomore) {
((TextView)mainview.findViewById(buttons[buttx])).setText("");
} else {
((TextView)mainview.findViewById(buttons[buttx])).setText(String.valueOf(getSymbol(symbx)));
}
buttx++;
}
}
@Override public boolean onKeyDown(int keyCode, KeyEvent event){
if (event.getRepeatCount() != 0) {
return true;
}
if (started) {
started = false;
}
//TODO: remove emulator special keys
switch (keyCode) {
case 75:
keyCode = KeyEvent.KEYCODE_POUND;
break;
case 74:
keyCode = KeyEvent.KEYCODE_STAR;
break;
}
//Log.d("AbsSymDialog.onKeyDown", "bootan pres: " + keyCode);
switch (keyCode) {
case KeyEvent.KEYCODE_0:
case KeyEvent.KEYCODE_1:
case KeyEvent.KEYCODE_2:
case KeyEvent.KEYCODE_3:
case KeyEvent.KEYCODE_4:
case KeyEvent.KEYCODE_5:
case KeyEvent.KEYCODE_6:
case KeyEvent.KEYCODE_7:
case KeyEvent.KEYCODE_8:
case KeyEvent.KEYCODE_9:
case KeyEvent.KEYCODE_POUND:
case KeyEvent.KEYCODE_STAR:
event.startTracking();
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override public boolean onKeyUp(int keyCode, KeyEvent event) {
//Log.d("AbsSymDialog.onKeyUp", "Key: " + keyCode);
if (started) {
started = false;
return true;
}
//TODO: remove emulator special keys
switch (keyCode) {
case 75:
keyCode = KeyEvent.KEYCODE_POUND;
break;
case 74:
keyCode = KeyEvent.KEYCODE_STAR;
break;
}
switch (keyCode) {
//pass-through
case KeyEvent.KEYCODE_0:
case KeyEvent.KEYCODE_1:
case KeyEvent.KEYCODE_2:
case KeyEvent.KEYCODE_3:
case KeyEvent.KEYCODE_4:
case KeyEvent.KEYCODE_5:
case KeyEvent.KEYCODE_6:
case KeyEvent.KEYCODE_7:
case KeyEvent.KEYCODE_8:
case KeyEvent.KEYCODE_9:
case KeyEvent.KEYCODE_POUND:
case KeyEvent.KEYCODE_STAR:
onKey(keyCode);
return true;
default:
//KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD).getNumber(keyCode)
//Log.w("onKeyUp", "Unhandled Key: " + keyCode + "(" + event.toString() + ")");
}
return super.onKeyUp(keyCode, event);
}
private void onKey(int keyCode) {
//Log.d("OnKey", "pri: " + keyCode);
//Log.d("onKey", "START Cm: " + mCapsMode);
//HANDLE SPECIAL KEYS
switch (keyCode) {
case KeyEvent.KEYCODE_1:
sendChar(pageoffset+0);
break;
case KeyEvent.KEYCODE_2:
sendChar(pageoffset+1);
break;
case KeyEvent.KEYCODE_3:
sendChar(pageoffset+2);
break;
case KeyEvent.KEYCODE_4:
sendChar(pageoffset+3);
break;
case KeyEvent.KEYCODE_5:
sendChar(pageoffset+4);
break;
case KeyEvent.KEYCODE_6:
sendChar(pageoffset+5);
break;
case KeyEvent.KEYCODE_7:
sendChar(pageoffset+6);
break;
case KeyEvent.KEYCODE_8:
sendChar(pageoffset+7);
break;
case KeyEvent.KEYCODE_9:
sendChar(pageoffset+8);
break;
case KeyEvent.KEYCODE_0:
sendChar(pageoffset+9);
break;
case KeyEvent.KEYCODE_STAR:
pageChange(-1);
break;
case KeyEvent.KEYCODE_POUND:
pageChange(1);
break;
}
}
protected void doShow(View v) {
// based on http://stackoverflow.com/a/13962770
started = true;
Window win = getWindow();
WindowManager.LayoutParams lp = win.getAttributes();
lp.token = v.getWindowToken();
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
win.setAttributes(lp);
win.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
updateButtons();
show();
}
}

View file

@ -0,0 +1,51 @@
package org.nyanya.android.traditionalt9;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
public class AddWordAct extends Activity {
View main;
@Override
protected void onCreate(Bundle savedData) {
super.onCreate(savedData);
View v = getLayoutInflater().inflate(R.layout.addwordview, null);
EditText et = (EditText)v.findViewById(R.id.add_word_text);
String word = getIntent().getStringExtra("org.nyanya.android.traditionalt9.word");
//Log.d("AddWord", "data.get: " + word);
et.setText(word);
et.setSelection(word.length());
setContentView(v);
main = v;
}
public void addWordButton(View v) {
EditText et = (EditText) main.findViewById(R.id.add_word_text);
//Log.d("AddWordAct", "adding word: " + et.getText());
TraditionalT9.ghettoaccess.doAddWord(et.getText().toString());
this.finish();
}
public void cancelButton(View v) {
//Log.d("AddWordAct", "Cancelled...");
//TraditionalT9.ghettoaccess.addCancel();
this.finish();
}
@Override public void onStop() {
TraditionalT9.ghettoaccess.addCancel();
super.onStop();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.add_word, menu);
return true;
}
}

View file

@ -0,0 +1,238 @@
package org.nyanya.android.traditionalt9;
import java.util.ArrayList;
import java.util.List;
import org.nyanya.android.traditionalt9.R;
import org.nyanya.android.traditionalt9.TraditionalT9;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;
public class CandidateView extends View {
//private TraditionalT9 mService;
private List<String> mSuggestions;
protected int mSelectedIndex;
private Drawable mSelectionHighlight;
private Rect mBgPadding;
private static final int MAX_SUGGESTIONS = 32;
private static final int SCROLL_PIXELS = 20;
private int[] mWordWidth = new int[MAX_SUGGESTIONS];
private int[] mWordX = new int[MAX_SUGGESTIONS];
private static final int X_GAP = 10;
private static final List<String> EMPTY_LIST = new ArrayList<String>();
private int mColorNormal;
private int mColorRecommended;
private int mColorOther;
private int mVerticalPadding;
private Paint mPaint;
private int mTargetScrollX;
private int mTotalWidth;
Rect mPadding;
/**
* Construct a CandidateView for showing suggested words for completion.
* @param context
* @param attrs
*/
public CandidateView(Context context) {
super(context);
mSelectionHighlight = context.getResources().getDrawable(
android.R.drawable.list_selector_background);
mSelectionHighlight.setState(new int[] {
android.R.attr.state_enabled,
android.R.attr.state_focused,
android.R.attr.state_window_focused,
android.R.attr.state_pressed
});
Resources r = context.getResources();
setBackgroundColor(r.getColor(R.color.candidate_background));
mColorNormal = r.getColor(R.color.candidate_normal);
mColorRecommended = r.getColor(R.color.candidate_recommended);
mColorOther = r.getColor(R.color.candidate_other);
mVerticalPadding = r.getDimensionPixelSize(R.dimen.candidate_vertical_padding);
mPaint = new Paint();
mPaint.setColor(mColorNormal);
mPaint.setAntiAlias(true);
mPaint.setTextSize(r.getDimensionPixelSize(R.dimen.candidate_font_height));
mPaint.setStrokeWidth(0);
mPadding = new Rect();
setHorizontalFadingEdgeEnabled(true);
setWillNotDraw(false);
setHorizontalScrollBarEnabled(false);
setVerticalScrollBarEnabled(false);
}
/**
* A connection back to the service to communicate with the text field
* @param listener
*/
public void setService(TraditionalT9 listener) {
//mService = listener;
}
@Override
public int computeHorizontalScrollRange() {
return mTotalWidth;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredWidth = resolveSize(50, widthMeasureSpec);
// Get the desired height of the icon menu view (last row of items does
// not have a divider below)
mSelectionHighlight.getPadding(mPadding);
final int desiredHeight = ((int)mPaint.getTextSize()) + mVerticalPadding
+ mPadding.top + mPadding.bottom;
// Maximum possible width and desired height
setMeasuredDimension(measuredWidth,
resolveSize(desiredHeight, heightMeasureSpec));
}
/**
* If the canvas is null, then only touch calculations are performed to pick the target
* candidate.
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mTotalWidth = 0;
if (mSuggestions == null) return;
if (mBgPadding == null) {
mBgPadding = new Rect(0, 0, 0, 0);
if (getBackground() != null) {
getBackground().getPadding(mBgPadding);
}
}
int x = 0;
final int count = mSuggestions.size();
final int height = getHeight();
final Rect bgPadding = mBgPadding;
final Paint paint = mPaint;
final int y = (int) (((height - mPaint.getTextSize()) / 2) - mPaint.ascent());
for (int i = 0; i < count; i++) {
String suggestion = mSuggestions.get(i);
float textWidth = paint.measureText(suggestion);
final int wordWidth = (int) textWidth + X_GAP * 2;
mWordX[i] = x;
mWordWidth[i] = wordWidth;
paint.setColor(mColorNormal);
//if (touchX + scrollX >= x && touchX + scrollX < x + wordWidth && !scrolled) {
if (i == mSelectedIndex) {
canvas.translate(x, 0);
mSelectionHighlight.setBounds(0, bgPadding.top, wordWidth, height);
mSelectionHighlight.draw(canvas);
canvas.translate(-x, 0);
paint.setFakeBoldText(true);
paint.setColor(mColorRecommended);
}
else {
paint.setColor(mColorOther);
}
canvas.drawText(suggestion, x + X_GAP, y, paint);
paint.setColor(mColorOther);
canvas.drawLine(x + wordWidth + 0.5f, bgPadding.top,
x + wordWidth + 0.5f, height + 1, paint);
paint.setFakeBoldText(false);
x += wordWidth;
}
mTotalWidth = x;
if (mTargetScrollX != getScrollX()) {
scrollToTarget();
}
}
private void scrollToTarget() {
int sx = getScrollX();
if (mTargetScrollX > sx) {
sx += SCROLL_PIXELS;
if (sx >= mTargetScrollX) {
sx = mTargetScrollX;
requestLayout();
}
} else {
sx -= SCROLL_PIXELS;
if (sx <= mTargetScrollX) {
sx = mTargetScrollX;
requestLayout();
}
}
scrollTo(sx, getScrollY());
invalidate();
}
public void setSuggestions(List<String> suggestions, int initialSel) {
clear();
if (suggestions != null) {
mSuggestions = suggestions;
mSelectedIndex = initialSel;
}
scrollTo(0, 0);
mTargetScrollX = 0;
// Compute the total width
//onDraw(null);
invalidate();
requestLayout();
}
public void clear() {
mSuggestions = EMPTY_LIST;
mSelectedIndex = -1;
invalidate();
}
protected void scrollSuggestion(int increment) {
if (mSuggestions != null && mSuggestions.size() > 1) {
mSelectedIndex = mSelectedIndex + increment;
if (mSelectedIndex == mSuggestions.size()) {
mSelectedIndex = 0;
} else if (mSelectedIndex < 0) {
mSelectedIndex = mSuggestions.size()-1;
}
int fullsize = getWidth();
int halfsize = fullsize/2;
mTargetScrollX = mWordX[mSelectedIndex] + (mWordWidth[mSelectedIndex]/2) - halfsize;
if (mTargetScrollX < 0) {
mTargetScrollX = 0;
} else if (mTargetScrollX > (mTotalWidth - fullsize) ) {
mTargetScrollX = mTotalWidth - fullsize;
}
invalidate();
}
}
}

View file

@ -0,0 +1,80 @@
package org.nyanya.android.traditionalt9;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import android.util.Log;
public class CharMap {
protected static final Map<Character, Integer> CHARTABLE;
static {
Map<Character, Integer> aMap = new HashMap<Character, Integer>();
aMap.put('.', 1); aMap.put(',', 1); aMap.put('!', 1); aMap.put('?', 1);
aMap.put('-', 1); aMap.put('"', 1); aMap.put('\'', 1); aMap.put('@', 1);
aMap.put('#', 1); aMap.put('$', 1); aMap.put('%', 1); aMap.put('&', 1);
aMap.put('*', 1); aMap.put('(', 1); aMap.put(')', 1); aMap.put('1', 1);
aMap.put('a', 2); aMap.put('\u00e1', 2); aMap.put('\u00e4', 2);
aMap.put('\u00e2', 2); aMap.put('\u00e0', 2); aMap.put('\u00e5', 2);
aMap.put('b', 2); aMap.put('c', 2); aMap.put('\u00e7', 2);
aMap.put('2', 2); aMap.put('d', 3); aMap.put('e', 3);
aMap.put('\u00e9', 3); aMap.put('\u00eb', 3); aMap.put('\u00e8', 3);
aMap.put('\u00ea', 3); aMap.put('f', 3); aMap.put('3', 3);
aMap.put('g', 4); aMap.put('h', 4); aMap.put('i', 4);
aMap.put('\u00ed', 4); aMap.put('\u00ef', 4); aMap.put('4', 4);
aMap.put('j', 5); aMap.put('k', 5); aMap.put('l', 5);
aMap.put('5', 5); aMap.put('m', 6); aMap.put('n', 6);
aMap.put('\u00f1', 6); aMap.put('o', 6); aMap.put('\u00f3', 6);
aMap.put('\u00f6', 6); aMap.put('\u00f4', 6); aMap.put('\u00fb', 6);
aMap.put('6', 6); aMap.put('p', 7); aMap.put('q', 7);
aMap.put('r', 7); aMap.put('s', 7); aMap.put('7', 7);
aMap.put('t', 8); aMap.put('u', 8); aMap.put('\u00fc', 8);
aMap.put('v', 8); aMap.put('8', 8); aMap.put('w', 9);
aMap.put('x', 9); aMap.put('y', 9); aMap.put('z', 9);
aMap.put('9', 9); aMap.put('+', 0); aMap.put('0', 0);
CHARTABLE = Collections.unmodifiableMap(aMap);
}
protected static final char[][] T9TABLE = {
{'0', '+'}, {'.', ',', '!', '?', '-', '"', '\'', '@', '#', '$', '%', '&', '*', '(', ')', '1'},
{'a', 'b', 'c', 'A', 'B', 'C', '2'}, {'d', 'e', 'f', 'D', 'E', 'F', '3'},
{'g', 'h', 'i', 'G', 'H', 'I', '4'}, {'j', 'k', 'l', 'J', 'K', 'L', '5'},
{'m', 'n', 'o', 'M', 'N', 'O', '6'}, {'p', 'q', 'r', 's', 'P', 'Q', 'R', 'S', '7'},
{'t', 'u', 'v', 'T', 'U', 'V', '8'}, {'w', 'x', 'y', 'z', 'W', 'X', 'Y', 'Z', '9'},
{' ', '\n'}
};
protected static final int[] T9CAPSTART = {
0, 0, 3, 3, 3, 3, 3, 4, 3, 4, 0
};
protected static int[] getSequence(String word){
int[] intseq = new int[word.length()];
String tword = word.toLowerCase(Locale.ENGLISH);
for (int i = 0; i < word.length(); i++){
char c = tword.charAt(i);
Integer z = CharMap.CHARTABLE.get(c);
if (z == null){
Log.e("getSequence", "ERROR: "+ (int)c + " NOT FOUND (" + Integer.toHexString((int)c) + ")");
throw new NullPointerException();
}
intseq[i] = z;
}
return intseq;
}
protected static String getStringSequence(String word){
StringBuilder seq = new StringBuilder();
String tword = word.toLowerCase(Locale.ENGLISH);
for (int i = 0; i < word.length(); i++){
char c = tword.charAt(i);
Integer z = CharMap.CHARTABLE.get(c);
if (z == null){
Log.e("getStringSequence", "ERROR: "+ (int)c + " NOT FOUND (" + Integer.toHexString((int)c) + ")");
throw new NullPointerException();
}
seq.append(z.toString());
}
return seq.toString();
}
}

View file

@ -0,0 +1,21 @@
package org.nyanya.android.traditionalt9;
public class DBException extends Exception {
private static final long serialVersionUID = 376752656441823823L;
public DBException() {
super();
}
public DBException(String message) {
super(message);
}
public DBException(String message, Throwable cause) {
super(message, cause);
}
public DBException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,129 @@
package org.nyanya.android.traditionalt9;
import android.content.Context;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.ViewSwitcher;
public class InterfaceHandler implements View.OnClickListener, View.OnLongClickListener {
private static final int[] buttons = { R.id.main_left, R.id.main_right, R.id.main_mid };
private TraditionalT9 parent;
private View mainview;
public InterfaceHandler(View mainview, TraditionalT9 iparent) {
this.parent = iparent;
changeView(mainview);
}
protected View getMainview() {
return mainview;
}
protected void clearParent() {
ViewGroup vg = ((ViewGroup)mainview.getParent());
if (vg != null) {
vg.removeView(mainview);
}
}
protected void changeView(View v){
this.mainview = v;
View button;
for (int x = 0; x < buttons.length; x++){
button = v.findViewById(buttons[x]);
button.setOnClickListener(this);
if (!parent.mAddingWord) {
button.setOnLongClickListener(this);
}
}
}
protected void setPressed(int keyCode, boolean pressed){
int id = 0;
switch(keyCode) {
case KeyEvent.KEYCODE_SOFT_LEFT:
id = R.id.main_left;
break;
case KeyEvent.KEYCODE_SOFT_RIGHT:
id = R.id.main_right;
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
id = R.id.main_mid;
break;
}
if (id != 0) {
((View) mainview.findViewById(id)).setPressed(pressed);
}
}
protected void showNotFound(boolean notfound){
if (notfound) {
((TextView) mainview.findViewById(R.id.left_hold_upper)).setText(R.string.main_left_notfound);
((TextView) mainview.findViewById(R.id.left_hold_lower)).setText(R.string.main_left_insert);
} else {
((TextView) mainview.findViewById(R.id.left_hold_upper)).setText(R.string.main_left_insert);
((TextView) mainview.findViewById(R.id.left_hold_lower)).setText(R.string.main_left_addword);
}
}
protected void emulateMiddleButton() {
((Button) mainview.findViewById(R.id.main_mid)).performClick();
}
protected void midButtonUpdate(boolean composing){
if (composing) {
((Button) mainview.findViewById(R.id.main_mid)).setText(R.string.main_mid_commit);
} else {
((Button) mainview.findViewById(R.id.main_mid)).setText(R.string.main_mid);
}
}
@Override public void onClick(View v) {
switch (v.getId()) {
case R.id.main_left:
if (parent.mAddingWord) {
parent.showSymbolPage();
} else {
if (parent.mWordFound) {
parent.showSymbolPage();
} else {
parent.showAddWord();
}
}
break;
case R.id.main_mid:
parent.handleMidButton();
break;
case R.id.main_right:
parent.nextKeyMode();
break;
}
}
protected void showHold(boolean show) {
ViewSwitcher vs = (ViewSwitcher) mainview.findViewById(R.id.main_left);
if (show) {
vs.setDisplayedChild(1);
} else {
vs.setDisplayedChild(0);
}
}
@Override public boolean onLongClick(View v) {
switch (v.getId()) {
case R.id.main_left:
parent.showAddWord();
break;
case R.id.main_right:
((InputMethodManager) parent.getSystemService (Context.INPUT_METHOD_SERVICE)).showInputMethodPicker();
break;
default:
return false;
}
return true;
}
}

View file

@ -0,0 +1,49 @@
package org.nyanya.android.traditionalt9;
import android.content.Context;
import android.view.View;
public class SmileyDialog extends AbsSymDialog {
private static final String[] symbols = {
//lol wiki http://en.wikipedia.org/wiki/List_of_emoticons
":-)", ":)", ":o)", ":]", ":3", ":c)", ":>", "=]", "=)", ":}",
":-D", ":D", "8-D", "8D", "X-D", "XD", "=-D", "=D", "B^D",
">:[", ":-(", ":(", ":c", ":-<", ":<", ":-[", ":[", ":{",
":'-(", ":'(", ":'-)", ":')", ":@", "D:<", "D:", "D8", "D;", "D=", "DX",
"v.v", "D-':", ">:O", ":-O", ":O", ":O", "o_O", "o_0", "o.O", "8-0",
":*", ";-)", ";)", ";-]", ";]", ";D",
">:P", ":-P", ":P", "XP", "xp", ":-p", ":p", "=p", ":-b", ":b",
">:\\", ">:/", ":-/", ":-.", ":/", ":\\", "=/", "=\\", ":L", "=L", ":S", ">.<",
":|", ":-|", ":$", ":-X", ":X", ":-#", ":#", "O:-)", "0:-3", "0:3", "0:-)", "0:)",
">:)", ">;)", ">:-)", ">_>", "<_<", "\\o/", "<3", "</3",
"=-3", "=3",
};
private static final int MAX_PAGE = (int)Math.ceil(symbols.length / 10.0);
public SmileyDialog(Context c, View mv) {
super(c, mv);
}
@Override
protected String getSymbol(int index) {
return symbols[index];
}
@Override
protected String getTitleText() {
return "Smiley";
}
@Override
protected int getSymbolSize() {
return symbols.length;
}
@Override
protected int getMaxPage() {
return MAX_PAGE;
}
}

View file

@ -0,0 +1,41 @@
package org.nyanya.android.traditionalt9;
import android.content.Context;
import android.view.View;
public class SymbolDialog extends AbsSymDialog {
private static final char[] symbols = {
'.', ',', '!', '?', '$', '&', '%', '#', '@', '"', '\'', ':', ';', '(', ')', '/', '\\',
'-', '+', '=', '*', '<', '>', '[', ']', '{', '}', '^', '|', '_', '~', '`'
}; //32
private static final int MAX_PAGE = (int)Math.ceil(symbols.length / 10.0);
public SymbolDialog(Context c, View mv) {
super(c, mv);
}
@Override
protected String getSymbol(int index) {
return String.valueOf(symbols[index]);
}
@Override
protected String getTitleText() {
return "Symbol";
}
@Override
protected int getSymbolSize() {
return symbols.length;
}
@Override
protected int getMaxPage() {
return MAX_PAGE;
}
}

View file

@ -0,0 +1,317 @@
package org.nyanya.android.traditionalt9;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
import android.util.Log;
public class T9DB {
protected static final String DATABASE_NAME = "t9dict.db";
protected static final int DATABASE_VERSION = 1;
protected static final String WORD_TABLE_NAME = "word";
protected static final String FREQ_TRIGGER_NAME = "freqtrigger";
//50k, 10k
private static final int FREQ_MAX = 50000;
private static final int FREQ_DIV = 10000;
protected static final String COLUMN_ID = BaseColumns._ID;
protected static final String COLUMN_SEQ = "seq";
protected static final String COLUMN_WORD = "word";
protected static final String COLUMN_FREQUENCY = "freq";
private static final int MAX_RESULTS = 8;
private static final int CAPS_OFF = 0;
private static final int CAPS_SINGLE = 1;
private static final int CAPS_ALL = 2;
private DatabaseHelper mOpenHelper;
private SQLiteDatabase db;
private Context parent;
public T9DB(Context caller) {
//create db
parent = caller;
mOpenHelper = new DatabaseHelper(caller);
}
public static SQLiteDatabase getSQLDB(Context caller) {
return new DatabaseHelper(caller).getWritableDatabase();
}
public void init() {
db = mOpenHelper.getWritableDatabase();
//mOpenHelper.onUpgrade(db, 0, DATABASE_VERSION);
}
public void close() {
db.close();
}
public void nuke() {
init();
mOpenHelper.onUpgrade(db, 0, DATABASE_VERSION);
db.close();
db = null;
}
public void addWord(String iword) throws DBException {
Resources r = parent.getResources();
if (iword.equals("")) {
throw new DBException(r.getString(R.string.add_word_blank));
}
//get int sequence
String seq = CharMap.getStringSequence(iword);
//add int sequence into num table
ContentValues values = new ContentValues();
values.put(COLUMN_SEQ, seq);
//add word into word
values.put(COLUMN_WORD, iword);
values.put(COLUMN_FREQUENCY, 1);
try {
db.insertOrThrow(WORD_TABLE_NAME, null, values);
} catch (SQLiteConstraintException e) {
String msg = r.getString(R.string.add_word_exist1) + iword + r.getString(R.string.add_word_exist2);
Log.w("T9DB.addWord", msg);
throw new DBException(msg);
}
}
public void incrementWord(int id) {
db.execSQL("UPDATE " + WORD_TABLE_NAME + " SET " + COLUMN_FREQUENCY + " = " +
COLUMN_FREQUENCY + "+ 1 WHERE " + COLUMN_ID + " = \"" + id + "\"");
// if id's freq is greater than X we should normalise those with the same seq
}
public void updateWords(String is, ArrayList<String> stringList, ArrayList<Integer> intList, int capsMode){
stringList.clear();
intList.clear();
//String[] sa = packInts(stringToInts(is), true);
int islen = is.length();
String q = "SELECT " + COLUMN_ID + ", " + COLUMN_WORD +
" FROM " + WORD_TABLE_NAME +
" WHERE " + COLUMN_SEQ + "=?" +
" ORDER BY " + COLUMN_FREQUENCY + " DESC";
Cursor cur = db.rawQuery(q, new String[] {is});
int hits = 0;
for(cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
intList.add(cur.getInt(0));
stringList.add(cur.getString(1));
if (hits >= 15) {
break;
}
hits++;
}
cur.close();
if (hits < 4) {
char c = is.charAt(islen-1);
c++;
// q = "SELECT " + COLUMN_WORD +", " + COLUMN_FREQUENCY +
// " FROM " + WORD_TABLE_NAME +
// " WHERE " + COLUMN_SEQ + " LIKE ?" +
// " ORDER BY " + COLUMN_SEQ + " ASC, " + COLUMN_FREQUENCY + " DESC;";
// c = db.rawQuery(q, new String[] {is + "_%"});
//above is hella slow below is gotta query fast
q = "SELECT " + COLUMN_ID + ", " + COLUMN_WORD +
" FROM " + WORD_TABLE_NAME +
" WHERE " + COLUMN_SEQ + " >= '" + is + "1" + "' AND " + COLUMN_SEQ + " < '" + is.substring(0, islen-1) + c + "'" +
" ORDER BY " + COLUMN_FREQUENCY + " DESC, " + COLUMN_SEQ + " ASC" +
" LIMIT " + (MAX_RESULTS - hits);
cur = db.rawQuery(q, null);
for(cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
intList.add(cur.getInt(0));
stringList.add(cur.getString(1));
if (hits >= 10) {
break;
}
hits++;
}
cur.close();
}
//Log.d("T9DB.updateWords", "pre: " + stringList);
if (capsMode == CAPS_OFF) {
return;
}
//Log.d("T9DB.updateWords", "filtering...");
// filter list
Iterator<String> iter = stringList.iterator();
String word;
String wordtemp;
int index = 0;
boolean removed = false;
while (iter.hasNext()) {
word = iter.next();
switch (capsMode) {
case CAPS_ALL:
wordtemp = word.toUpperCase(Locale.US);
if (wordtemp.equals(word)) {
index++;
continue;
} else if (stringList.contains(wordtemp)){
//remove this entry
iter.remove();
removed = true;
} else {
stringList.set(index, wordtemp);
}
break;
case CAPS_SINGLE:
if (word.length() > 1) {
wordtemp = word.substring(0, 1).toUpperCase(Locale.US) + word.substring(1);
} else {
wordtemp = word.toUpperCase(Locale.US);
}
if (wordtemp.equals(word)) {
index++;
continue;
} else if (stringList.contains(wordtemp)){
//remove this entry
iter.remove();
removed = true;
} else {
stringList.set(index, wordtemp);
}
break;
}
if (removed) {
intList.remove(index);
removed = false;
} else {
index++;
}
}
return;
}
protected void updateWordsW(String is, ArrayList<String> stringList, ArrayList<Integer> intList,
ArrayList<Integer> freq){
stringList.clear();
intList.clear();
freq.clear();
//String[] sa = packInts(stringToInts(is), true);
int islen = is.length();
String q = "SELECT " + COLUMN_ID + ", " + COLUMN_WORD + ", " + COLUMN_FREQUENCY +
" FROM " + WORD_TABLE_NAME +
" WHERE " + COLUMN_SEQ + "=?" +
" ORDER BY " + COLUMN_FREQUENCY + " DESC";
Cursor cur = db.rawQuery(q, new String[] {is});
int hits = 0;
for(cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
intList.add(cur.getInt(0));
stringList.add(cur.getString(1));
freq.add(cur.getInt(2));
if (hits >= 10) {
break;
}
hits++;
}
cur.close();
if (hits < 4) {
char c = is.charAt(islen-1);
c++;
// q = "SELECT " + COLUMN_WORD +", " + COLUMN_FREQUENCY +
// " FROM " + WORD_TABLE_NAME +
// " WHERE " + COLUMN_SEQ + " LIKE ?" +
// " ORDER BY " + COLUMN_SEQ + " ASC, " + COLUMN_FREQUENCY + " DESC;";
// c = db.rawQuery(q, new String[] {is + "_%"});
//above is hella slow
q = "SELECT " + COLUMN_ID + ", " + COLUMN_WORD + ", " + COLUMN_FREQUENCY +
" FROM " + WORD_TABLE_NAME +
" WHERE " + COLUMN_SEQ + " >= '" + is + "' AND " + COLUMN_SEQ + " < '" + is.substring(0, islen-1) + c + "'" +
" ORDER BY " + COLUMN_FREQUENCY + " DESC, " + COLUMN_SEQ + " ASC" +
" LIMIT " + (MAX_RESULTS - hits);
cur = db.rawQuery(q, null);
for(cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
intList.add(cur.getInt(0));
stringList.add(cur.getString(1));
freq.add(cur.getInt(2));
if (hits >= 10) {
break;
}
hits++;
}
cur.close();
}
return;
}
protected static int[] stringToInts(String s){
int[] il = new int[s.length()];
for (int x = 0; x < s.length(); x++){
il[x] = s.charAt(x) - 48; //lol hope this is ASCII all the time
}
return il;
}
protected static String[] packInts(int[] intseq, boolean stringArray){
int[] ia = packInts(intseq);
String[] sa = {Integer.toString(ia[0]), Integer.toString(ia[1])};
return sa;
}
protected static int[] packInts(int[] intseq){
int[] ia = {0, 0};
for (int x = 0; x < intseq.length; x++){
if (x < 8){
//packing 8 ints (<10) into 32bit int ... I hope...
ia[0] = ia[0] | (intseq[x] << x*4);
} else {
ia[1] = intseq[x] << (x % 8) * 4;
}
}
return ia;
}
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + WORD_TABLE_NAME + " ("
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ COLUMN_SEQ + " TEXT, "
+ COLUMN_WORD + " TEXT UNIQUE, "
+ COLUMN_FREQUENCY + " INTEGER"
+ ")");
db.execSQL("CREATE INDEX idx ON " + WORD_TABLE_NAME + "("
//+ COLUMN_NUMHIGH + ", " + COLUMN_NUMLOW + ")");
+ COLUMN_SEQ + " ASC, " + COLUMN_FREQUENCY + " DESC )");
db.execSQL("CREATE TRIGGER " + FREQ_TRIGGER_NAME + " AFTER UPDATE ON " + WORD_TABLE_NAME
+ " WHEN NEW." + COLUMN_FREQUENCY + " > " + FREQ_MAX
+ " BEGIN"
+ " UPDATE " + WORD_TABLE_NAME + " SET " + COLUMN_FREQUENCY
+ " = " + COLUMN_FREQUENCY + " / " + FREQ_DIV + " WHERE " + COLUMN_SEQ + " = NEW." + COLUMN_SEQ + ";"
+ " END;");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("T9DB", "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + WORD_TABLE_NAME);
db.execSQL("DROP INDEX IF EXISTS idx");
onCreate(db);
Log.w("T9DB", "Done.");
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,773 @@
package org.nyanya.android.traditionalt9;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.DatabaseUtils.InsertHelper;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.util.Log;
public class TraditionalT9Settings extends PreferenceActivity implements
DialogInterface.OnCancelListener {
ProgressDialog pd = null;
AsyncTask<String, Integer, Reply> task = null;
final String dictname = "dict50-utf8.jet";
final String backupname = "t9backup.txt";
final String backupdir = "traditionalt9";
final int BACKUP_Q_LIMIT = 1000;
Context caller = null;
private class Reply {
public boolean status;
public String message;
protected Reply(){
this.status = true;
this.message = "None";
}
}
private void closeStream(Closeable is, Reply reply) {
if (is == null) {
return;
}
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
reply.message = reply.message + "\n & Couldn't close stream: " + e.getMessage();
}
}
private class LoadDictTask extends AsyncTask<String, Integer, Reply> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected Reply doInBackground(String... mode) {
Reply reply = new Reply();
SQLiteDatabase db;
db = T9DB.getSQLDB(caller);
long fsize;
long pos = 0;
long last = 0;
File backupfile = new File(Environment.getExternalStorageDirectory(), backupdir);
if (mode[0].equals("backup")){
//using external backup
backupfile = new File(backupfile, backupname);
fsize = backupfile.length();
} else {
//using asset:
AssetFileDescriptor descriptor;
try {
descriptor = getAssets().openFd(dictname);
fsize = descriptor.getLength();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
reply.status = false;
reply.message = e.getLocalizedMessage();
db.close();
return reply;
}
}
db.setLockingEnabled(false);
InsertHelper wordhelp = new InsertHelper(db, T9DB.WORD_TABLE_NAME);
final int wordColumn = wordhelp.getColumnIndex(T9DB.COLUMN_WORD);
final int freqColumn = wordhelp.getColumnIndex(T9DB.COLUMN_FREQUENCY);
final int seqColumn = wordhelp.getColumnIndex(T9DB.COLUMN_SEQ);
// add characters first, then dictionary:
Log.d("doInBakground", "Adding characters...");
for (Map.Entry<Character, Integer> entry : CharMap.CHARTABLE.entrySet()) {
wordhelp.prepareForReplace();
wordhelp.bind(seqColumn, Integer.toString(entry.getValue()));
wordhelp.bind(wordColumn, Character.toString(entry.getKey()));
wordhelp.bind(freqColumn, 0);
wordhelp.execute();
}
Log.d("doInBakground", "done.");
Log.d("doInBakground", "Adding dict...");
BufferedReader br;
InputStream dictstream = null;
if (mode[0].equals("backup")){
try {
dictstream = new FileInputStream(backupfile);
} catch (FileNotFoundException e) {
reply.status = false;
reply.message = "Backup file not found: " + e.getMessage();
db.close();
closeStream(dictstream, reply); // this is silly but it stops IDE nagging at me.
return reply;
}
}
else {
try {
dictstream = getAssets().open(dictname);
} catch (IOException e) {
e.printStackTrace();
reply.status = false;
reply.message = "IO Error: " + e.getMessage();
db.close();
return reply;
}
}
try {
br = new BufferedReader(new InputStreamReader(dictstream, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
reply.status = false;
reply.message = "UnsupportedEncodingException Error: " + e.getMessage();
db.close();
closeStream(dictstream, reply);
return reply;
}
String word;
String[] ws;
int freq;
try {
word = br.readLine();
} catch (IOException e) {
e.printStackTrace();
reply.status = false;
reply.message = "IO Error: " + e.getMessage();
db.close();
closeStream(dictstream, reply);
return reply;
}
String seq;
int linecount = 1;
int wordlen;
long startnow, endnow;
startnow = SystemClock.uptimeMillis();
db.beginTransaction();
try {
while (word != null) {
if (isCancelled()) {
// this is useless because of dumb android bug that doesn't
// call onCancelled after this method finishes.
reply.status = false;
reply.message = "User cancelled.";
break;
}
if (word.contains(" ")) {
ws = word.split(" ");
word = ws[0];
try {
freq = Integer.parseInt(ws[1]);
} catch (NumberFormatException e) {
reply.status = false;
reply.message = "Number error.";
return reply;
}
} else {
freq = 0;
}
linecount++;
try {
wordlen = word.getBytes("UTF-8").length;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
reply.status = false;
reply.message = "UnsupportedEncodingException Error: " + e.getMessage();
db.close();
closeStream(dictstream, reply);
return reply;
}
pos += wordlen;
try{
seq = CharMap.getStringSequence(word);
} catch (NullPointerException e) {
reply.status = false;
reply.message = "Error on word: " + word;
db.close();
closeStream(dictstream, reply);
return reply;
}
wordhelp.prepareForReplace();
wordhelp.bind(seqColumn, seq);
wordhelp.bind(wordColumn, word);
wordhelp.bind(freqColumn, freq);
wordhelp.execute();
//System.out.println("Progress: " + pos + " Last: " + last + " fsize: " + fsize);
if ((pos - last) > 4096) {
// Log.d("doInBackground", "line: " + linecount);
// Log.d("doInBackground", "word: " + word);
publishProgress((int)((float)pos/fsize*10000));
last = pos;
}
try {
word = br.readLine();
} catch (IOException e) {
e.printStackTrace();
reply.status = false;
reply.message = "IO Error: " + e.getMessage();
db.close();
closeStream(dictstream, reply);
return reply;
}
}
publishProgress(10000);
db.setTransactionSuccessful();
} finally {
db.setLockingEnabled(true);
db.endTransaction();
wordhelp.close();
}
endnow = SystemClock.uptimeMillis();
Log.d("TIMING", "Excution time: "+(endnow-startnow)+" ms");
Log.d("doInBackground", "line: " + linecount);
db.close();
closeStream(dictstream, reply);
return reply;
}
protected void onProgressUpdate(Integer... progress) {
if (pd.isShowing()) {
pd.setProgress(progress[0]);
}
}
protected void onCancelled() {
// Pointless callback. Thanks android.
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(Reply result) {
if (pd == null){
//Log.d("onPostExecute", "pd");
} else {
//Log.d("onPostExecute", "pd");
pd.dismiss();
}
if (result == null){
//bad thing happened
Log.e("onPostExecute", "Bad things happen?");
} else {
Log.d("onPostExecute", "Result: " + result.status + " " + result.message);
if (!result.status) {
showErrorDialog(caller.getResources().getString(R.string.pref_restore_title), result.message);
}
}
}
}
private class DumpDictTask extends AsyncTask<String, Integer, Reply> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected Reply doInBackground(String... ignore) {
Reply reply = new Reply();
SQLiteDatabase db;
db = T9DB.getSQLDB(caller);
long entries;
int current = 0;
int pos = 0;
int last = 0;
File backupfile = new File(new File(Environment.getExternalStorageDirectory(), backupdir), backupname);
db.setLockingEnabled(false);
Log.d("doInBakground", "Dumping dict...");
BufferedWriter bw;
OutputStream dictstream = null;
try {
dictstream = new FileOutputStream(backupfile);
} catch (FileNotFoundException e) {
reply.status = false;
reply.message = "Backup file error: " + e.getMessage();
db.close();
closeStream(dictstream, reply); // this is silly but it stops IDE nagging at me.
return reply;
}
try {
bw = new BufferedWriter(new OutputStreamWriter(dictstream, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
reply.status = false;
reply.message = "UnsupportedEncodingException Error: " + e.getMessage();
db.close();
closeStream(dictstream, reply);
return reply;
}
long startnow, endnow;
startnow = SystemClock.uptimeMillis();
String q = "SELECT count(*) FROM " + T9DB.WORD_TABLE_NAME;
Cursor cur = db.rawQuery(q, null);
cur.moveToFirst();
entries = cur.getInt(0);
//pd.setMax((int)entries);
cur.close();
while (current < entries) {
q = "SELECT " + T9DB.COLUMN_ID + ", " + T9DB.COLUMN_WORD + ", " + T9DB.COLUMN_FREQUENCY +
" FROM " + T9DB.WORD_TABLE_NAME +
" WHERE " + T9DB.COLUMN_ID + ">" + current +
" ORDER BY " + T9DB.COLUMN_ID +
" LIMIT " + BACKUP_Q_LIMIT;
cur = db.rawQuery(q, null);
for(cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
if (isCancelled()) {
// this is useless because of dumb android bug that doesn't
// call onCancelled after this method finishes.
reply.status = false;
reply.message = "User cancelled.";
break;
}
current = cur.getInt(0);
pos++;
try {
bw.write(cur.getString(1));
bw.write(" ");
bw.write(Integer.toString(cur.getInt(2)));
bw.newLine();
} catch (IOException e) {
e.printStackTrace();
reply.status = false;
reply.message = "IO Error: " + e.getMessage();
db.close();
closeStream(dictstream, reply);
return reply; // why complain? I closed the stream above
}
if ((pos - last) > 80) {
publishProgress((int)((float)current/entries*10000));
last = current;
}
}
cur.close();
}
publishProgress(100);
endnow = SystemClock.uptimeMillis();
Log.d("TIMING", "Excution time: "+(endnow-startnow)+" ms");
Log.d("doInBackground", "entries: " + entries + " last: " + pos);
db.close();
try {
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
closeStream(dictstream, reply);
return reply;
}
protected void onProgressUpdate(Integer... progress) {
if (pd.isShowing()) {
pd.setProgress(progress[0]);
}
}
protected void onCancelled() {
// Pointless callback. Thanks android.
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(Reply result) {
if (pd == null){
//Log.d("onPostExecute", "pd");
} else {
//Log.d("onPostExecute", "pd");
pd.dismiss();
}
if (result == null){
//bad thing happened
Log.e("onPostExecute", "Bad things happen?");
} else {
Log.d("onPostExecute", "Result: " + result.status + " " + result.message);
if (!result.status) {
showErrorDialog(caller.getResources().getString(R.string.pref_backup_title), result.message);
}
}
}
}
private class NukeDictTask extends AsyncTask<String, Integer, Reply> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected Reply doInBackground(String... ignore) {
Reply reply = new Reply();
Log.d("doInBakground", "Nuking dict...");
long startnow, endnow;
startnow = SystemClock.uptimeMillis();
T9DB t9db = new T9DB(caller);
t9db.nuke();
endnow = SystemClock.uptimeMillis();
Log.d("TIMING", "Excution time: "+(endnow-startnow)+" ms");
return reply;
}
protected void onCancelled() {
// Pointless callback. Thanks android.
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(Reply result) {
if (pd == null){
//Log.d("onPostExecute", "pd");
} else {
//Log.d("onPostExecute", "pd");
pd.dismiss();
}
if (result == null){
//bad thing happened
Log.e("onPostExecute", "Bad things happen?");
} else {
Log.d("onPostExecute", "Result: " + result.status + " " + result.message);
if (!result.status) {
showErrorDialog(caller.getResources().getString(R.string.pref_nuke_title), result.message);
}
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
Preference button = (Preference)getPreferenceManager().findPreference("loaddict");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
loadDict();
return true;
}
});
}
button = (Preference)getPreferenceManager().findPreference("nukedict");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
nukeDict();
return true;
}
});
}
button = (Preference)getPreferenceManager().findPreference("backupdict");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
backupDict();
return true;
}
});
}
button = (Preference)getPreferenceManager().findPreference("restoredict");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
restoreDict();
return true;
}
});
}
button = (Preference)getPreferenceManager().findPreference("querytest");
if (button != null) {
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference arg0) {
queryTestSingle();
return true;
}
});
}
caller = this;
}
private void loadDict() {
preloader(R.string.pref_loadingdict, "");
}
private void preloader(int msgid, String mode){
pd = new ProgressDialog(this);
pd.setMessage(getResources().getString(msgid));
pd.setOnCancelListener(this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMax(10000);
pd.show();
task = new LoadDictTask();
task.execute(mode);
}
private void predumper(int msgid) {
pd = new ProgressDialog(this);
pd.setMessage(getResources().getString(msgid));
pd.setOnCancelListener(this);
//pd.setProgressNumberFormat(null); Why added in API11...
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMax(10000);
pd.show();
task = new DumpDictTask();
task.execute("");
}
private void prenuke(int msgid) {
pd = new ProgressDialog(this);
pd.setMessage(getResources().getString(msgid));
pd.setCancelable(false);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.show();
task = new NukeDictTask();
task.execute("");
}
private void nukeDict() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.pref_nuke_warn)
.setTitle(R.string.pref_nuke_title)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
prenuke(R.string.pref_nukingdict);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
private void backupDict() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
File saveloc = new File(Environment.getExternalStorageDirectory(), backupdir);
saveloc.mkdirs();
if (!saveloc.canWrite()){
Log.e("backupDict", "can't write : " + saveloc.getAbsolutePath());
showErrorDialogID(builder, R.string.pref_backup_title, R.string.pref_backup_noext);
return;
}
saveloc = new File(saveloc, backupname);
if (saveloc.exists()) {
builder.setMessage(R.string.pref_backup_warn)
.setTitle(R.string.pref_backup_title)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
predumper(R.string.pref_savingbackup);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
} else {
predumper(R.string.pref_savingbackup);
}
} else {
showErrorDialogID(builder, R.string.pref_backup_title, R.string.pref_backup_noext);
}
}
private void showErrorDialog(String title, String msg) {
showErrorDialog(new AlertDialog.Builder(this), title, msg);
}
private void showErrorDialog(AlertDialog.Builder builder, String title, String msg) {
builder.setMessage(msg)
.setTitle(title)
.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
private void showErrorDialogID(AlertDialog.Builder builder, int titleid, int msgid) {
builder.setMessage(msgid)
.setTitle(titleid)
.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
private void restoreDict() {
// Environment.MEDIA_MOUNTED_READ_ONLY;
// Environment.MEDIA_MOUNTED;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(Environment.getExternalStorageState()) ||
Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
if ((new File(new File(Environment.getExternalStorageDirectory(), backupdir), backupname)).exists()) {
Resources res = getResources();
builder.setMessage(res.getString(R.string.pref_restore_warn, res.getString(R.string.pref_nukedict)))
.setTitle(R.string.pref_restore_title)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
preloader(R.string.pref_loadingbackup, "backup");
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
} else {
showErrorDialogID(builder, R.string.pref_restore_title, R.string.pref_restore_nofile);
}
} else {
showErrorDialogID(builder, R.string.pref_restore_title, R.string.pref_restore_noext);
}
}
@SuppressWarnings("unused")
private void queryTestDebug() {
long startnow, endnow;
ArrayList<String> words = new ArrayList<String>();
ArrayList<Integer> ids = new ArrayList<Integer>();
startnow = SystemClock.uptimeMillis();
T9DB tdb = new T9DB(this);
tdb.init();
Log.d("queryTestDebug", "Testing...");
tdb.updateWords("123", words, ids, 0);
Log.d("queryTestDebug", "123->" + words.toString());
Log.d("queryTestDebug", "269->");
tdb.updateWords("269", words, ids, 0);
Iterator<String> i = words.iterator();
while (i.hasNext()){
Log.d("queryTestDebug", "word: " + i.next());
}
Log.d("queryTestDebug", "228->");
tdb.updateWords("228", words, ids, 0);
i = words.iterator();
while (i.hasNext()){
Log.d("queryTestDebug", "word: " + i.next());
}
endnow = SystemClock.uptimeMillis();
Log.d("TIMING", "Excution time: "+(endnow-startnow)+" ms");
tdb.close();
}
@SuppressWarnings("unused")
private void queryTest() {
long startnow, endnow;
startnow = SystemClock.uptimeMillis();
T9DB tdb = new T9DB(this);
tdb.init();
// tdb.getWords("123").iterator();
// tdb.getWords("269").iterator();
// tdb.getWords("228").iterator();
// tdb.getWords("24371").iterator();
// tdb.getWords("22376284").iterator();
// tdb.getWords("68372667367283").iterator();
// tdb.getWords("22637").iterator();
endnow = SystemClock.uptimeMillis();
Log.d("TIMING", "Excution time: "+(endnow-startnow)+" ms");
tdb.close();
}
private void queryTestSingle() {
long startnow, endnow;
int size;
ArrayList<String> words = new ArrayList<String>(8);
ArrayList<Integer> ids = new ArrayList<Integer>(8);
startnow = SystemClock.uptimeMillis();
T9DB tdb = new T9DB(this);
tdb.init();
tdb.updateWords("222", words, ids, 0);
size = ids.size();
if (size > 0) {
tdb.incrementWord(ids.get(0));
tdb.incrementWord(ids.get(0));
tdb.incrementWord(ids.get(0));
}
for (int x=0; x<size; x++){
tdb.incrementWord(ids.get(x));
}
endnow = SystemClock.uptimeMillis();
Log.d("TIMING", "Excution time: "+(endnow-startnow)+" ms");
ArrayList<Integer> freqs = new ArrayList<Integer>(8);
tdb.updateWordsW("222", words, ids, freqs);
Log.d("VALUES", "...");
size = freqs.size();
for (int x = 0; x < size; x++){
Log.d("VALUES", "Word: " + words.get(x) + " id: " + ids.get(x) + " freq: " + freqs.get(x));
}
Log.d("queryTestSingle", "done.");
tdb.close();
}
@Override
public void onCancel(DialogInterface dint) {
task.cancel(false);
}
}

BIN
store-res/TT9-1024x500.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 KiB

BIN
store-res/TT9-180x120.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
store-res/TT9-512x512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB