diff options
| author | David A. Madore <david+git@madore.org> | 2010-04-27 02:13:49 +0200 | 
|---|---|---|
| committer | David A. Madore <david+git@madore.org> | 2010-04-27 02:24:17 +0200 | 
| commit | 221e994358da9d5e18fe490a19389093dfe4e755 (patch) | |
| tree | a386603af4a5cf4ee501c4456d653560b8965058 | |
| parent | e37377a5d3ca4c78c440b097af4186cbbd81a6a0 (diff) | |
| download | UnicodeMap-221e994358da9d5e18fe490a19389093dfe4e755.tar.gz UnicodeMap-221e994358da9d5e18fe490a19389093dfe4e755.tar.bz2 UnicodeMap-221e994358da9d5e18fe490a19389093dfe4e755.zip  | |
Implement a search mechanism.
| -rw-r--r-- | res/layout/main_layout.xml | 2 | ||||
| -rw-r--r-- | res/layout/search_dialog.xml | 24 | ||||
| -rw-r--r-- | res/menu/options_menu.xml | 5 | ||||
| -rw-r--r-- | res/values/strings.xml | 5 | ||||
| -rw-r--r-- | src/org/madore/android/unicodeMap/UnicodeDatabase.java | 12 | ||||
| -rw-r--r-- | src/org/madore/android/unicodeMap/UnicodeMapActivity.java | 109 | 
6 files changed, 151 insertions, 6 deletions
diff --git a/res/layout/main_layout.xml b/res/layout/main_layout.xml index 571a2dc..89480d7 100644 --- a/res/layout/main_layout.xml +++ b/res/layout/main_layout.xml @@ -21,7 +21,7 @@  	android:layout_width="0dip"  	android:layout_height="wrap_content"  	android:layout_weight="1" /> -    <Button android:id="@+id/button" +    <Button android:id="@+id/copyButton"  	android:layout_width="wrap_content"  	android:layout_height="fill_parent"  	android:text="@string/copy_button" /> diff --git a/res/layout/search_dialog.xml b/res/layout/search_dialog.xml new file mode 100644 index 0000000..7c7be92 --- /dev/null +++ b/res/layout/search_dialog.xml @@ -0,0 +1,24 @@ +<?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: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"> +    <EditText android:id="@+id/searchTerm" +        android:layout_width="0dip" +        android:layout_height="wrap_content" +        android:layout_weight="1" /> +    <Button android:id="@+id/searchButton" +        android:layout_width="wrap_content" +        android:layout_height="fill_parent" +        android:text="@string/search_button" /> +  </LinearLayout> +  <TextView +      android:layout_width="fill_parent" +      android:layout_height="wrap_content" +      android:text="@string/search_hint" /> +</LinearLayout> diff --git a/res/menu/options_menu.xml b/res/menu/options_menu.xml new file mode 100644 index 0000000..a187813 --- /dev/null +++ b/res/menu/options_menu.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> +  <item android:id="@+id/menuSearch" +      android:title="@string/menu_search" /> +</menu> diff --git a/res/values/strings.xml b/res/values/strings.xml index 605a255..b77be4a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6,4 +6,9 @@      <string name="copy_button">Copy</string>      <string name="copied_toast">Copied to clipboard</string>      <string name="empty_list">(Empty!)</string> +    <string name="menu_search">Search</string> +    <string name="search_title">Search in character names</string> +    <string name="search_button">Search</string> +    <string name="search_hint">Case is insensitive and matches whole string; use a % sign as wildcard (e.g.: "latin%letter r%")</string> +    <string name="list_too_long">Only %d first results shown</string>  </resources> diff --git a/src/org/madore/android/unicodeMap/UnicodeDatabase.java b/src/org/madore/android/unicodeMap/UnicodeDatabase.java index b81c99a..84efb63 100644 --- a/src/org/madore/android/unicodeMap/UnicodeDatabase.java +++ b/src/org/madore/android/unicodeMap/UnicodeDatabase.java @@ -217,7 +217,17 @@ public class UnicodeDatabase {  		       "id >= ? AND id < ?",  		       new String[] { Integer.toString(from),  				      Integer.toString(to) }, -		       null, null, null, null); +		       null, null, "id", null); +	return new CursorIterable(c); +    } + +    public Iterable<UnicodeCharacter> searchNames(String like, int limit) { +	final Cursor c +	    = db.query(UNICODE_TABLE_NAME, queryColumns, +		       "name LIKE ?", +		       new String[] { like }, +		       null, null, "id", +		       (limit>0)?Integer.toString(limit):null);  	return new CursorIterable(c);      } diff --git a/src/org/madore/android/unicodeMap/UnicodeMapActivity.java b/src/org/madore/android/unicodeMap/UnicodeMapActivity.java index 1b43d9d..74dca91 100644 --- a/src/org/madore/android/unicodeMap/UnicodeMapActivity.java +++ b/src/org/madore/android/unicodeMap/UnicodeMapActivity.java @@ -4,13 +4,18 @@ import java.util.Arrays;  import java.util.List;  import java.util.ArrayList;  import java.util.Formatter; +import java.util.regex.Pattern;  import android.content.Context;  import android.content.Intent;  import android.os.Bundle;  import android.os.Handler;  import android.os.Message;  import android.view.View; +import android.view.ViewGroup;  import android.view.Window; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MenuInflater;  import android.view.KeyEvent;  import android.widget.*;  import android.text.ClipboardManager; @@ -83,7 +88,10 @@ public final class UnicodeMapActivity extends ListActivity {  					      list);  		stack.add(adapter);  		positionStack.add(position); -		positionYStack.add(view.getTop()); +		if ( view != null ) +		    positionYStack.add(view.getTop()); +		else +		    positionYStack.add(0);  		setListAdapter(adapter);  	    } else  		throw new AssertionError("unknown UnicodeDisplayable"); @@ -159,12 +167,12 @@ public final class UnicodeMapActivity extends ListActivity {  	setListAdapter(rootAdapter);  	final ClipboardManager cmgr  	    = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); -	final Button btn = (Button) findViewById(R.id.button); +	final Button btn = (Button) findViewById(R.id.copyButton);  	textForm = (EditText) findViewById(R.id.edit);  	btn.setOnClickListener(new View.OnClickListener() {  		public void onClick(View view) {  		    cmgr.setText(textForm.getText()); -		    Toast.makeText(getApplicationContext(), +		    Toast.makeText(UnicodeMapActivity.this,  				   R.string.copied_toast,  				   Toast.LENGTH_SHORT).show();  		} @@ -176,17 +184,110 @@ public final class UnicodeMapActivity extends ListActivity {  	lv.setOnItemLongClickListener(listener);      } +    final static int searchLimit = 1000; + +    protected void doSearch(String s) { +	List<UnicodeDisplayable> list +	    = new ArrayList<UnicodeDisplayable>(128); +	for ( UnicodeCharacter ch : db.searchNames(s,searchLimit+1) ) +	    list.add(ch); +	boolean overflowed = ( list.size() > searchLimit ); +	if ( overflowed ) +	    list.remove(list.size()-1); +	UnicodeArrayAdapter adapter +	    = new UnicodeArrayAdapter(UnicodeMapActivity.this, +				      list); +	stack.add(adapter); +	final ListView lv = getListView(); +	int position = lv.getSelectedItemPosition(); +	int position0 = lv.getFirstVisiblePosition(); +	if ( position == AdapterView.INVALID_POSITION ) +	    position = position0; +	positionStack.add(position); +	View view = lv.getChildAt(position-position0); +	if ( view != null ) +	    positionYStack.add(view.getTop()); +	else +	    positionYStack.add(0); +	setListAdapter(adapter); +	if ( overflowed ) { +	    String str = getResources().getString(R.string.list_too_long); +	    android.util.Log.e("UnicodeMapActivity", "format is: "+str); +	    Toast.makeText(UnicodeMapActivity.this, +			   String.format(str, searchLimit), +			   Toast.LENGTH_SHORT).show(); +	} +    } + +    protected void querySearch() { +	final Dialog dialog = new Dialog(UnicodeMapActivity.this); +	// dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); +	dialog.setTitle(R.string.search_title); +	dialog.setOwnerActivity(this); +	dialog.setContentView(R.layout.search_dialog); +	dialog.setCancelable(true); +	dialog.getWindow().setLayout(ViewGroup.LayoutParams.FILL_PARENT, +				     ViewGroup.LayoutParams.WRAP_CONTENT); +	final EditText textForm +	    = (EditText) dialog.findViewById(R.id.searchTerm); +	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) ) +			    doSearch(s); +			dialog.dismiss(); +			return true; +		    } +		    return false; +		} +	    }); +	final Button btn = (Button) dialog.findViewById(R.id.searchButton); +	btn.setOnClickListener(new View.OnClickListener() { +		public void onClick(View view) { +		    String s = textForm.getText().toString(); +		    if ( ! Pattern.matches("^\\s*$", s) ) { +			doSearch(s); +			dialog.dismiss(); +		    } +		} +	    }); +	dialog.show(); +    } +      @Override      public boolean onKeyDown(int keyCode, KeyEvent event) { -	if ( ( keyCode == KeyEvent.KEYCODE_BACK) && stack.size() > 1 ) { +	if ( ( keyCode == KeyEvent.KEYCODE_BACK ) && stack.size() > 1 ) {  	    final ListView lv = getListView();  	    stack.remove(stack.size()-1);  	    setListAdapter(stack.get(stack.size()-1));  	    lv.setSelectionFromTop(positionStack.remove(positionStack.size()-1),  				   positionYStack.remove(positionYStack.size()-1));  	    return true; +	} else if ( keyCode == KeyEvent.KEYCODE_SEARCH ) { +	    querySearch(); +	    return true;  	}  	return super.onKeyDown(keyCode, event);      } +    @Override +    public boolean onOptionsItemSelected(MenuItem item) { +	switch ( item.getItemId() ) { +	case R.id.menuSearch: +	    querySearch(); +	    return true; +	default: +	    return super.onContextItemSelected(item); +	} +    } + +    @Override +    public boolean onCreateOptionsMenu(Menu menu) { +	MenuInflater inflater = getMenuInflater(); +	inflater.inflate(R.menu.options_menu, menu); +	return true; +    } +  }  | 
