]> gitweb.fperrin.net Git - Dictionary.git/blob - src/com/hughes/android/dictionary/DictionaryActivity.java
go
[Dictionary.git] / src / com / hughes / android / dictionary / DictionaryActivity.java
1 package com.hughes.android.dictionary;
2
3 import java.io.File;
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;
11
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;
35
36 import com.hughes.android.dictionary.Dictionary.IndexEntry;
37 import com.hughes.android.dictionary.Dictionary.Language;
38 import com.hughes.android.dictionary.Dictionary.Row;
39
40 public class DictionaryActivity extends ListActivity {
41
42   private RandomAccessFile dictRaf = null;
43   private Dictionary dictionary = null;
44   private Language activeLanguge = null;
45
46   private File wordList = new File("/sdcard/wordList.txt");
47
48   final Handler uiHandler = new Handler();
49
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;
55
56   /** Called when the activity is first created. */
57   @Override
58   public void onCreate(Bundle savedInstanceState) {
59     Log.d("THAD", "onCreate");
60     super.onCreate(savedInstanceState);
61
62     try {
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);
68     }
69
70     setContentView(R.layout.main);
71
72     final EditText searchText = (EditText) findViewById(R.id.SearchText);
73     searchText.addTextChangedListener(new DictionaryTextWatcher());
74
75     setListAdapter(dictionaryListAdapter);
76
77     onSearchTextChange("");
78     final Button langButton = (Button) findViewById(R.id.LangButton);
79     langButton.setOnClickListener(new OnClickListener() {
80       public void onClick(View v) {
81         switchLanguage();
82       }});
83     updateLangButton();
84
85     registerForContextMenu(getListView());
86     getListView().setOnItemLongClickListener((new OnItemLongClickListener() {
87       public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
88           long arg3) {
89         selectedRow = arg2;
90         return false;
91       }
92     }));
93   }
94   
95   public String getSelectedRowText() {
96     return activeLanguge.rowToString(activeLanguge.rows.get(selectedRow));
97   }
98
99   private MenuItem switchLanguageMenuItem = null;
100   
101   @Override
102   public boolean onCreateOptionsMenu(final Menu menu) {
103     switchLanguageMenuItem = menu.add("Switch to language.");
104     return true;
105   }
106   
107   @Override
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);
111   }
112   
113   @Override
114   public boolean onOptionsItemSelected(final MenuItem item) {
115     if (item == switchLanguageMenuItem) {
116       switchLanguage();
117     }
118     return super.onOptionsItemSelected(item);
119   }
120
121   @Override
122   public void onCreateContextMenu(ContextMenu menu, View v,
123       ContextMenuInfo menuInfo) {
124     if (selectedRow == -1) {
125       return;
126     }
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);
132         try {
133           final OutputStream out = new FileOutputStream(wordList, true);
134           out.write((rawText + "\n").getBytes());
135           out.close();
136         } catch (IOException e) {
137           throw new RuntimeException(e);
138         }
139         return false;
140       }
141     });
142   }
143   
144   void switchLanguage() {
145     activeLanguge = dictionary.languages[(activeLanguge == dictionary.languages[0]) ? 1 : 0];
146     updateLangButton();
147     dictionaryListAdapter.notifyDataSetChanged();
148     final EditText searchText = (EditText) findViewById(R.id.SearchText);
149     onSearchTextChange(searchText.getText().toString());
150   }
151   
152   void updateLangButton() {
153     final Button langButton = (Button) findViewById(R.id.LangButton);
154     langButton.setText(dictionary.languages[activeLanguge.lang].symbol.toUpperCase());
155   }
156
157   @Override
158   protected void onListItemClick(ListView l, View v, int row, long id) {
159     selectedRow = row;
160     Log.d("THAD", "Clicked: " + getSelectedRowText());
161     openContextMenu(getListView());
162   }
163
164   void onSearchTextChange(final String searchText) {
165     Log.d("THAD", "onSearchTextChange: " + searchText);
166     if (searchOperation != null) {
167       searchOperation.interrupted.set(true);
168     }
169     searchOperation = new SearchOperation(searchText);
170     searchExecutor.execute(searchOperation);
171   }
172   
173   private void jumpToRow(final int row) {
174     selectedRow = row;
175     getListView().setSelection(row);
176   }
177
178   private final class SearchOperation implements Runnable {
179     final String searchText;
180     final AtomicBoolean interrupted = new AtomicBoolean(false);
181
182     public SearchOperation(final String searchText) {
183       this.searchText = searchText;
184     }
185
186     public void run() {
187       Log.d("THAD", "SearchOperation: " + searchText);
188       final int indexLocation = activeLanguge.lookup(searchText, interrupted);
189       if (interrupted.get()) {
190         return;
191       }
192       final IndexEntry indexEntry = activeLanguge.sortedIndex
193           .get(indexLocation);
194       uiHandler.post(new Runnable() {
195         public void run() {
196           jumpToRow(indexEntry.startRow);
197         }
198       });
199     }
200   }
201
202   private class DictionaryListAdapter extends BaseAdapter {
203
204     public int getCount() {
205       return activeLanguge.rows.size();
206     }
207
208     public Dictionary.Row getItem(int position) {
209       assert position < activeLanguge.rows.size();
210       return activeLanguge.rows.get(position);
211     }
212
213     public long getItemId(int position) {
214       return position;
215     }
216
217     public View getView(final int position, final View convertView,
218         final ViewGroup parent) {
219       final Row row = getItem(position);
220       if (row.isToken()) {
221         TextView result = null;
222         if (convertView instanceof TextView) {
223           result = (TextView) convertView;
224         } else {
225           result = new TextView(parent.getContext());
226         }
227         result.setText(activeLanguge.rowToString(row));
228         result.setTextAppearance(parent.getContext(),
229             android.R.style.TextAppearance_Large);
230         return result;
231       }
232
233       TableLayout result = null;
234       if (convertView instanceof TableLayout) {
235         result = (TableLayout) convertView;
236       } else {
237         result = new TableLayout(parent.getContext());
238       }
239
240       TableRow tableRow = null;
241       if (result.getChildCount() != 1) {
242         result.removeAllViews();
243         tableRow = new TableRow(result.getContext());
244         result.addView(tableRow);
245       } else {
246         tableRow = (TableRow) result.getChildAt(0);
247       }
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);
258       } else {
259         column1 = (TextView) tableRow.getChildAt(0);
260         column2 = (TextView) tableRow.getChildAt(1);
261       }
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);
270       return result;
271
272     }
273   }
274
275   private class DictionaryTextWatcher implements TextWatcher {
276     public void afterTextChanged(Editable searchText) {
277       onSearchTextChange(searchText.toString());
278     }
279
280     public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
281         int arg3) {
282     }
283
284     public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
285     }
286   }
287
288 }