1 package com.hughes.android.dictionary;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.OutputStream;
7 import java.io.RandomAccessFile;
8 import java.util.concurrent.Executor;
9 import java.util.concurrent.Executors;
10 import java.util.concurrent.atomic.AtomicBoolean;
12 import android.app.ListActivity;
13 import android.os.Bundle;
14 import android.os.Handler;
15 import android.text.Editable;
16 import android.text.TextWatcher;
17 import android.util.Log;
18 import android.view.ContextMenu;
19 import android.view.Menu;
20 import android.view.MenuItem;
21 import android.view.View;
22 import android.view.ViewGroup;
23 import android.view.ContextMenu.ContextMenuInfo;
24 import android.view.MenuItem.OnMenuItemClickListener;
25 import android.view.View.OnClickListener;
26 import android.widget.AdapterView;
27 import android.widget.BaseAdapter;
28 import android.widget.Button;
29 import android.widget.EditText;
30 import android.widget.ListView;
31 import android.widget.TableLayout;
32 import android.widget.TableRow;
33 import android.widget.TextView;
34 import android.widget.AdapterView.OnItemLongClickListener;
36 import com.hughes.android.dictionary.Dictionary.IndexEntry;
37 import com.hughes.android.dictionary.Dictionary.Language;
38 import com.hughes.android.dictionary.Dictionary.Row;
40 public class DictionaryActivity extends ListActivity {
42 private RandomAccessFile dictRaf = null;
43 private Dictionary dictionary = null;
44 private Language activeLanguge = null;
46 private File wordList = new File("/sdcard/wordList.txt");
48 final Handler uiHandler = new Handler();
50 private Executor searchExecutor = Executors.newSingleThreadExecutor();
51 private SearchOperation searchOperation = null;
52 // private List<Entry> entries = Collections.emptyList();
53 private DictionaryListAdapter dictionaryListAdapter = new DictionaryListAdapter();
54 private int selectedRow = -1;
56 /** Called when the activity is first created. */
58 public void onCreate(Bundle savedInstanceState) {
59 Log.d("THAD", "onCreate");
60 super.onCreate(savedInstanceState);
63 dictRaf = new RandomAccessFile("/sdcard/de-en.dict", "r");
64 dictionary = new Dictionary(dictRaf);
65 activeLanguge = dictionary.languages[Entry.LANG1];
66 } catch (Exception e) {
67 throw new RuntimeException(e);
70 setContentView(R.layout.main);
72 final EditText searchText = (EditText) findViewById(R.id.SearchText);
73 searchText.addTextChangedListener(new DictionaryTextWatcher());
75 setListAdapter(dictionaryListAdapter);
77 onSearchTextChange("");
78 final Button langButton = (Button) findViewById(R.id.LangButton);
79 langButton.setOnClickListener(new OnClickListener() {
80 public void onClick(View v) {
85 registerForContextMenu(getListView());
86 getListView().setOnItemLongClickListener((new OnItemLongClickListener() {
87 public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
95 public String getSelectedRowText() {
96 return activeLanguge.rowToString(activeLanguge.rows.get(selectedRow));
99 private MenuItem switchLanguageMenuItem = null;
102 public boolean onCreateOptionsMenu(final Menu menu) {
103 switchLanguageMenuItem = menu.add("Switch to language.");
108 public boolean onPrepareOptionsMenu(final Menu menu) {
109 switchLanguageMenuItem.setTitle(String.format("Switch to %s", dictionary.languages[Entry.otherLang(activeLanguge.lang)].symbol));
110 return super.onPrepareOptionsMenu(menu);
114 public boolean onOptionsItemSelected(final MenuItem item) {
115 if (item == switchLanguageMenuItem) {
118 return super.onOptionsItemSelected(item);
122 public void onCreateContextMenu(ContextMenu menu, View v,
123 ContextMenuInfo menuInfo) {
124 if (selectedRow == -1) {
127 final MenuItem addToWordlist = menu.add("Add to wordlist.");
128 addToWordlist.setOnMenuItemClickListener(new OnMenuItemClickListener() {
129 public boolean onMenuItemClick(MenuItem item) {
130 final String rawText = getSelectedRowText();
131 Log.d("THAD", "Writing : " + rawText);
133 final OutputStream out = new FileOutputStream(wordList, true);
134 out.write((rawText + "\n").getBytes());
136 } catch (IOException e) {
137 throw new RuntimeException(e);
144 void switchLanguage() {
145 activeLanguge = dictionary.languages[(activeLanguge == dictionary.languages[0]) ? 1 : 0];
147 dictionaryListAdapter.notifyDataSetChanged();
148 final EditText searchText = (EditText) findViewById(R.id.SearchText);
149 onSearchTextChange(searchText.getText().toString());
152 void updateLangButton() {
153 final Button langButton = (Button) findViewById(R.id.LangButton);
154 langButton.setText(dictionary.languages[activeLanguge.lang].symbol.toUpperCase());
158 protected void onListItemClick(ListView l, View v, int row, long id) {
160 Log.d("THAD", "Clicked: " + getSelectedRowText());
161 openContextMenu(getListView());
164 void onSearchTextChange(final String searchText) {
165 Log.d("THAD", "onSearchTextChange: " + searchText);
166 if (searchOperation != null) {
167 searchOperation.interrupted.set(true);
169 searchOperation = new SearchOperation(searchText);
170 searchExecutor.execute(searchOperation);
173 private void jumpToRow(final int row) {
175 getListView().setSelection(row);
178 private final class SearchOperation implements Runnable {
179 final String searchText;
180 final AtomicBoolean interrupted = new AtomicBoolean(false);
182 public SearchOperation(final String searchText) {
183 this.searchText = searchText;
187 Log.d("THAD", "SearchOperation: " + searchText);
188 final int indexLocation = activeLanguge.lookup(searchText, interrupted);
189 if (interrupted.get()) {
192 final IndexEntry indexEntry = activeLanguge.sortedIndex
194 uiHandler.post(new Runnable() {
196 jumpToRow(indexEntry.startRow);
202 private class DictionaryListAdapter extends BaseAdapter {
204 public int getCount() {
205 return activeLanguge.rows.size();
208 public Dictionary.Row getItem(int position) {
209 assert position < activeLanguge.rows.size();
210 return activeLanguge.rows.get(position);
213 public long getItemId(int position) {
217 public View getView(final int position, final View convertView,
218 final ViewGroup parent) {
219 final Row row = getItem(position);
221 TextView result = null;
222 if (convertView instanceof TextView) {
223 result = (TextView) convertView;
225 result = new TextView(parent.getContext());
227 result.setText(activeLanguge.rowToString(row));
228 result.setTextAppearance(parent.getContext(),
229 android.R.style.TextAppearance_Large);
233 TableLayout result = null;
234 if (convertView instanceof TableLayout) {
235 result = (TableLayout) convertView;
237 result = new TableLayout(parent.getContext());
240 TableRow tableRow = null;
241 if (result.getChildCount() != 1) {
242 result.removeAllViews();
243 tableRow = new TableRow(result.getContext());
244 result.addView(tableRow);
246 tableRow = (TableRow) result.getChildAt(0);
248 TextView column1 = null;
249 TextView column2 = null;
250 if (tableRow.getChildCount() != 2
251 || !(tableRow.getChildAt(0) instanceof TextView)
252 || !(tableRow.getChildAt(1) instanceof TextView)) {
253 tableRow.removeAllViews();
254 column1 = new TextView(tableRow.getContext());
255 column2 = new TextView(tableRow.getContext());
256 tableRow.addView(column1);
257 tableRow.addView(column2);
259 column1 = (TextView) tableRow.getChildAt(0);
260 column2 = (TextView) tableRow.getChildAt(1);
262 column1.setWidth(100);
263 column2.setWidth(100);
264 // column1.setTextAppearance(parent.getContext(), android.R.style.Text);
265 final Entry entry = dictionary.entries.get(row.getIndex());
266 column1.setText(entry.getAllText(activeLanguge.lang));
267 column2.setText(entry.getAllText(Entry.otherLang(activeLanguge.lang)));
268 // result.setTextAppearance(parent.getContext(),
269 // android.R.style.TextAppearance_Small);
275 private class DictionaryTextWatcher implements TextWatcher {
276 public void afterTextChanged(Editable searchText) {
277 onSearchTextChange(searchText.toString());
280 public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
284 public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {