From e57621493d1fa3cb1f9bd14b14e8012d7503e816 Mon Sep 17 00:00:00 2001
From: "David A. Madore" <david+git@madore.org>
Date: Thu, 29 Apr 2010 03:09:26 +0200
Subject: Add a "go" feature.

---
 res/layout/go_dialog.xml                           | 28 +++++++
 res/menu/options_menu.xml                          |  2 +
 res/values/strings.xml                             |  6 ++
 .../android/unicodeMap/UnicodeMapActivity.java     | 93 +++++++++++++++++++++-
 4 files changed, 125 insertions(+), 4 deletions(-)
 create mode 100644 res/layout/go_dialog.xml

diff --git a/res/layout/go_dialog.xml b/res/layout/go_dialog.xml
new file mode 100644
index 0000000..1ee6319
--- /dev/null
+++ b/res/layout/go_dialog.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="fill_parent"
+    android:padding="10dp"
+    android:orientation="vertical">
+  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content"
+      android:orientation="horizontal">
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="20sp"
+        android:text="U+" />
+    <EditText android:id="@+id/goForm"
+        android:layout_width="80sp"
+        android:layout_height="wrap_content" />
+    <Button android:id="@+id/goButton"
+        android:layout_width="wrap_content"
+        android:layout_height="fill_parent"
+        android:text="@string/go_button" />
+  </LinearLayout>
+  <TextView
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content"
+      android:text="@string/go_hint" />
+</LinearLayout>
diff --git a/res/menu/options_menu.xml b/res/menu/options_menu.xml
index 2cb4eb9..d101b1f 100644
--- a/res/menu/options_menu.xml
+++ b/res/menu/options_menu.xml
@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:id="@+id/menuGo"
+      android:title="@string/menu_go" />
   <item android:id="@+id/menuSearch"
       android:title="@string/menu_search" />
   <item android:id="@+id/menuAbout"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6c90667..acdc3e0 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7,6 +7,12 @@
     <string name="copy_button">Copy</string>
     <string name="copied_toast">Copied to clipboard</string>
     <string name="empty_list">(Empty!)</string>
+    <string name="menu_go">Go</string>
+    <string name="go_title">Go to char number</string>
+    <string name="go_button">Go</string>
+    <string name="go_hint">Enter codepoint (hex)</string>
+    <string name="invalid_codepoint">Invalid codepoint</string>
+    <string name="no_character">No such character</string>
     <string name="menu_search">Search</string>
     <string name="search_title">Search in character names</string>
     <string name="search_button">Search</string>
diff --git a/src/org/madore/android/unicodeMap/UnicodeMapActivity.java b/src/org/madore/android/unicodeMap/UnicodeMapActivity.java
index 0c80741..5410b11 100644
--- a/src/org/madore/android/unicodeMap/UnicodeMapActivity.java
+++ b/src/org/madore/android/unicodeMap/UnicodeMapActivity.java
@@ -379,9 +379,10 @@ public final class UnicodeMapActivity extends ListActivity {
 		    if ( ( event.getAction() == KeyEvent.ACTION_DOWN )
 			 && ( keyCode == KeyEvent.KEYCODE_ENTER ) ) {
 			String s = textForm.getText().toString();
-			if ( ! Pattern.matches("^\\s*$", s) )
+			if ( ! Pattern.matches("^\\s*$", s) ) {
 			    doSearch(s);
-			dialog.dismiss();
+			    dialog.dismiss();
+			}
 			return true;
 		    }
 		    return false;
@@ -391,10 +392,91 @@ public final class UnicodeMapActivity extends ListActivity {
 	btn.setOnClickListener(new View.OnClickListener() {
 		public void onClick(View view) {
 		    String s = textForm.getText().toString();
-		    if ( ! Pattern.matches("^\\s*$", s) ) {
+		    if ( ! Pattern.matches("^\\s*$", s) )
 			doSearch(s);
-			dialog.dismiss();
+		    dialog.dismiss();
+		}
+	    });
+	dialog.show();
+    }
+
+    protected void doGo(String s) {
+	try {
+	    s = s.replaceAll("\\s+", "");
+	    int code = Integer.parseInt(s, 16);
+	    if ( code < 0 || code >= 0x110000 )
+		throw new NumberFormatException();
+	    int codeFrom = Math.max((code&~31)-32, 0);
+	    int codeTo = Math.min((code|31)+32, 0x110000);
+	    String str = String.format("%04X\u2013%04X", codeFrom, codeTo-1);
+	    Display newDisp
+		= new RangeDisplay(str, codeFrom, codeTo, rangeLimit);
+	    saveDisplay();
+	    doDisplay(newDisp, true);
+	    int dichoFrom = 0;
+	    int dichoTo = Math.min(codeTo-codeFrom, lv.getAdapter().getCount());
+	    int dicho = Math.max(Math.min(code-codeFrom, dichoTo-1), 0);
+	    LOOP:
+	    while ( true ) {
+		if ( dichoTo <= dichoFrom+1 )
+		    break LOOP;
+		UnicodeCharacter chx
+		    = (UnicodeCharacter) lv.getAdapter().getItem(dicho);
+		int codex = chx.getCodePoint();
+		if ( codex == code )
+		    break LOOP;
+		else if ( codex > code ) {
+		    dichoTo = dicho;
+		    dicho = (dichoFrom+dichoTo)/2;
+		} else if ( codex < code ) {
+		    dichoFrom = dicho;
+		    dicho = (dichoFrom+dichoTo)/2;
+		}
+	    }
+	    lv.setSelectionFromTop(dicho, 0);
+	    if ( db.getSingle(code) == null )
+		Toast.makeText(UnicodeMapActivity.this,
+			       R.string.no_character,
+			       Toast.LENGTH_SHORT).show();
+	} catch (NumberFormatException e) {
+	    Toast.makeText(UnicodeMapActivity.this,
+			   R.string.invalid_codepoint,
+			   Toast.LENGTH_SHORT).show();
+	}
+    }
+
+    protected void queryGo() {
+	final Dialog dialog = new Dialog(UnicodeMapActivity.this);
+	// dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+	dialog.setTitle(R.string.go_title);
+	dialog.setOwnerActivity(this);
+	dialog.setContentView(R.layout.go_dialog);
+	dialog.setCancelable(true);
+	// dialog.getWindow().setLayout(ViewGroup.LayoutParams.FILL_PARENT,
+	// 			     ViewGroup.LayoutParams.WRAP_CONTENT);
+	final EditText textForm
+	    = (EditText) dialog.findViewById(R.id.goForm);
+	textForm.setOnKeyListener(new View.OnKeyListener() {
+		public boolean onKey(View view, int keyCode, KeyEvent event) {
+		    if ( ( event.getAction() == KeyEvent.ACTION_DOWN )
+			 && ( keyCode == KeyEvent.KEYCODE_ENTER ) ) {
+			String s = textForm.getText().toString();
+			if ( ! Pattern.matches("^\\s*$", s) ) {
+			    doGo(s);
+			    dialog.dismiss();
+			}
+			return true;
 		    }
+		    return false;
+		}
+	    });
+	final Button btn = (Button) dialog.findViewById(R.id.goButton);
+	btn.setOnClickListener(new View.OnClickListener() {
+		public void onClick(View view) {
+		    String s = textForm.getText().toString();
+		    if ( ! Pattern.matches("^\\s*$", s) )
+			doGo(s);
+		    dialog.dismiss();
 		}
 	    });
 	dialog.show();
@@ -432,6 +514,9 @@ public final class UnicodeMapActivity extends ListActivity {
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
 	switch ( item.getItemId() ) {
+	case R.id.menuGo:
+	    queryGo();
+	    return true;
 	case R.id.menuSearch:
 	    querySearch();
 	    return true;
-- 
cgit v1.2.3