package org.madore.android.unicodeMap; 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; import android.app.ListActivity; import android.app.Dialog; import android.app.ProgressDialog; public final class UnicodeMapActivity extends ListActivity { protected UnicodeDatabase db; protected final List rootList = new ArrayList(200); protected final List stack = new ArrayList(10); protected final List positionStack = new ArrayList(10); protected final List positionYStack = new ArrayList(10); EditText textForm; protected void launchPopulation() { final ProgressDialog progress = new ProgressDialog(this); progress.setOwnerActivity(this); progress.setTitle(R.string.loading_database_title); progress.setMessage(getResources().getText(R.string.loading_database_msg)); progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progress.setCancelable(false); progress.show(); final Handler handler = new Handler() { public void handleMessage(Message msg) { int done = msg.getData().getInt("done"); int total = msg.getData().getInt("total"); progress.setMax(total); progress.setProgress(done); if ( done >= total ) progress.dismiss(); } }; final Thread thr = new Thread() { public void run() { final UnicodeDatabase writeDb = new UnicodeDatabase(UnicodeMapActivity.this); writeDb.populate(handler); } }; thr.start(); } protected class MapItemClickListener implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener { public void onItemClick(AdapterView parent, View view, int position, long id) { UnicodeDisplayable it = (UnicodeDisplayable)parent.getItemAtPosition(position); if ( it instanceof UnicodeCharacter ) textForm.append(((UnicodeCharacter)it).getChar()); else if ( it instanceof UnicodeCharacter.Range ) { int from = ((UnicodeCharacter.Range)it).getFrom(); int to = ((UnicodeCharacter.Range)it).getTo(); List list = new ArrayList(db.countRange(from,to)); for ( UnicodeCharacter ch : db.getRange(from,to) ) list.add(ch); UnicodeArrayAdapter adapter = new UnicodeArrayAdapter(UnicodeMapActivity.this, list); stack.add(adapter); positionStack.add(position); if ( view != null ) positionYStack.add(view.getTop()); else positionYStack.add(0); setListAdapter(adapter); } else throw new AssertionError("unknown UnicodeDisplayable"); } public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { UnicodeDisplayable it = (UnicodeDisplayable)parent.getItemAtPosition(position); if ( it instanceof UnicodeCharacter ) { UnicodeCharacter itch = (UnicodeCharacter)it; Dialog dialog = new Dialog(UnicodeMapActivity.this); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setOwnerActivity(UnicodeMapActivity.this); dialog.setContentView(R.layout.char_details); dialog.setCancelable(true); TextView text; text = (TextView) dialog.findViewById(R.id.detailsLabel); text.setText(itch.getLabel()); text = (TextView) dialog.findViewById(R.id.encodingLabel); StringBuilder s = new StringBuilder(); Formatter fmt = new Formatter(s); fmt.format("UTF-8:"); byte[] bytes; bytes = UnicodeCharacter.toUtf8(itch.getChar()); for ( int i=0 ; i list = new ArrayList(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 ) { 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; } }