<activity android:name="AboutActivity"></activity>
<activity android:name="PreferenceActivity"></activity>
+ <activity android:name="DownloadActivity"></activity>
</application>
</manifest>
\ No newline at end of file
-
<LinearLayout android:id="@+id/LinearLayout01"
android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent">
<LinearLayout android:id="@+id/LinearLayout02"
- android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal">
-
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal">
+
<ImageView android:id="@+id/ImageView01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:background="@drawable/icon"></ImageView>
-
+
<TextView android:text=" Dictionary 1.0" android:id="@+id/title"
android:textAppearance="?android:attr/textAppearanceLarge"
- android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical|fill_vertical"></TextView>
-
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical|fill_vertical"></TextView>
+
</LinearLayout>
-
+
<TextView android:text=" " android:id="@+id/space1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:autoLink="email"
android:clickable="true"></TextView>
+ <TextView android:text=" " android:id="@+id/space2"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"></TextView>
+
+ <TextView android:text="Current dictionary info" android:id="@+id/currentDictInfoTitle"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:layout_width="fill_parent" android:layout_height="wrap_content"></TextView>
+
+ <TextView android:text="No dictionary loaded." android:id="@+id/currentDictInfo"
+ android:layout_width="fill_parent" android:layout_height="wrap_content"></TextView>
</LinearLayout>
--- /dev/null
+
+<LinearLayout android:id="@+id/LinearLayout01"
+ android:orientation="vertical" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <TextView android:id="@+id/TextView01" android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:text="Downloading..."></TextView>
+
+ <LinearLayout android:id="@+id/sourceLayout"
+ android:orientation="horizontal" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android">
+ <TextView android:id="@+id/sourceTitle" android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:text="Source: "></TextView>
+ <TextView android:id="@+id/source" android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:text="source"></TextView>
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/destLayout"
+ android:orientation="horizontal" android:layout_width="fill_parent"
+ android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android">
+ <TextView android:id="@+id/destTitle" android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:text="Destination: "></TextView>
+ <TextView android:id="@+id/dest" android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:text="dest"></TextView>
+ </LinearLayout>
+
+ <ProgressBar android:id="@+id/downloadProgressBar"
+ android:layout_width="wrap_content" android:layout_height="wrap_content" android:indeterminate="false"></ProgressBar>
+
+ <TextView android:id="@+id/downloadComplete" android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:text="Download complete." android:visibility="invisible"></TextView>
+
+</LinearLayout>
<ListView android:id="@id/android:list"
android:layout_width="fill_parent" android:layout_height="fill_parent"
- android:choiceMode="singleChoice" android:clickable="true"></ListView>
+ android:choiceMode="singleChoice" android:clickable="true" android:focusableInTouchMode="true" android:focusable="true"></ListView>
</LinearLayout>
package com.hughes.android.dictionary;\r
\r
import android.app.Activity;\r
+import android.content.Intent;\r
import android.os.Bundle;\r
+import android.widget.TextView;\r
\r
public final class AboutActivity extends Activity {\r
\r
+ public static final String CURRENT_DICT_INFO = "currentDictInfo";\r
+\r
/** Called when the activity is first created. */\r
@Override\r
public void onCreate(final Bundle savedInstanceState) {\r
super.onCreate(savedInstanceState);\r
setContentView(R.layout.about);\r
+ \r
+ final Intent intent = getIntent();\r
+ \r
+ final TextView currentDictInfo = (TextView) findViewById(R.id.currentDictInfo);\r
+ currentDictInfo.setText(intent.getStringExtra(CURRENT_DICT_INFO));\r
}\r
\r
}\r
package com.hughes.android.dictionary;
import java.io.File;
-import java.io.FileOutputStream;
+import java.io.FileWriter;
import java.io.IOException;
-import java.io.OutputStream;
+import java.io.PrintWriter;
import java.io.RandomAccessFile;
+import java.text.SimpleDateFormat;
+import java.util.Date;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import android.app.AlertDialog;
import android.app.ListActivity;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import com.hughes.android.dictionary.Dictionary.Row;
public class DictionaryActivity extends ListActivity {
+
+ String WORD_LIST_FILE;
+ String DICT_FILE;
+ String DICT_FETCH_URL;
- static final Intent aboutIntent = new Intent().setClassName(AboutActivity.class.getPackage().getName(), AboutActivity.class.getCanonicalName());
static final Intent preferencesIntent = new Intent().setClassName(PreferenceActivity.class.getPackage().getName(), PreferenceActivity.class.getCanonicalName());
private final Handler uiHandler = new Handler();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
- Log.d("THAD", "onCreate");
super.onCreate(savedInstanceState);
+ WORD_LIST_FILE = getResources().getString(R.string.wordListFile);
+ DICT_FILE = getResources().getString(R.string.dictFile);
+ DICT_FETCH_URL = getResources().getString(R.string.dictFetchUrl);
+
+ Log.d("THAD", "onCreate");
+
+
}
@Override
public void onResume() {
super.onResume();
+ // Have to close, because we might have downloaded a new copy of the dictionary.
closeCurrentDictionary();
final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
- wordList = new File(settings.getString(getResources().getString(R.string.wordListFile), wordList.getAbsolutePath()));
- dictFile = new File(settings.getString(getResources().getString(R.string.dictFile), "/sdcard/de-en.dict"));
+ wordList = new File(settings.getString(WORD_LIST_FILE, wordList.getAbsolutePath()));
+ final File newDictFile = new File(settings.getString(DICT_FILE, "/sdcard/de-en.dict"));
+ dictFile = newDictFile;
Log.d("THAD", "wordList=" + wordList);
Log.d("THAD", "dictFile=" + dictFile);
if (!dictFile.canRead()) {
+ dictionaryListAdapter.notifyDataSetChanged();
+ Log.d("THAD", "Unable to read dictionary file.");
+ final AlertDialog alert = new AlertDialog.Builder(DictionaryActivity.this).create();
+ alert.setMessage("Unable to read dictionary file: " + wordList.getAbsolutePath());
+ alert.setButton("Download dictionary from Internet", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ startDownloadDictActivity();
+ }});
+ alert.show();
return;
}
dictRaf = new RandomAccessFile(dictFile, "r");
dictionary = new Dictionary(dictRaf);
activeLangaugeData = dictionary.languageDatas[Entry.LANG1];
+ dictionaryListAdapter.notifyDataSetChanged();
} catch (Exception e) {
throw new RuntimeException(e);
}
dictRaf = null;
}
- public String getSelectedRowText() {
+ public String getSelectedRowRawText() {
return activeLangaugeData.rowToString(activeLangaugeData.rows.get(selectedRowIndex));
}
final MenuItem about = menu.add("About...");
about.setOnMenuItemClickListener(new OnMenuItemClickListener(){
public boolean onMenuItemClick(final MenuItem menuItem) {
- startActivity(aboutIntent);
+ final Intent intent = new Intent().setClassName(AboutActivity.class.getPackage().getName(), AboutActivity.class.getCanonicalName());
+ final StringBuilder currentDictInfo = new StringBuilder();
+ if (dictionary == null) {
+ currentDictInfo.append("No dictionary loaded.");
+ } else {
+ currentDictInfo.append("Entry count: " + dictionary.entries.size()).append("\n");
+ for (int i = 0; i < 2; ++i) {
+ final LanguageData languageData = dictionary.languageDatas[i];
+ currentDictInfo.append(languageData.language.symbol).append(":\n");
+ currentDictInfo.append(" Unique token count: " + languageData.sortedIndex.size()).append("\n");
+ currentDictInfo.append(" Row count: " + languageData.rows.size()).append("\n");
+ }
+ }
+ intent.putExtra(AboutActivity.CURRENT_DICT_INFO, currentDictInfo.toString());
+ startActivity(intent);
+ return false;
+ }});
+
+ final MenuItem download = menu.add("Download dictionary...");
+ download.setOnMenuItemClickListener(new OnMenuItemClickListener(){
+ public boolean onMenuItemClick(final MenuItem menuItem) {
+ startDownloadDictActivity();
return false;
}});
final MenuItem addToWordlist = menu.add("Add to wordlist: " + wordList.getName());
addToWordlist.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
- final String rawText = getSelectedRowText();
+ final StringBuilder rawText = new StringBuilder();
+ final String word = activeLangaugeData.getIndexEntryForRow(selectedRowIndex).word;
+ rawText.append(new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date())).append("\t");
+ rawText.append(word).append("\t");
+ rawText.append(getSelectedRowRawText());
Log.d("THAD", "Writing : " + rawText);
try {
- final OutputStream out = new FileOutputStream(wordList, true);
- out.write((rawText + "\n").getBytes());
+ wordList.getParentFile().mkdirs();
+ final PrintWriter out = new PrintWriter(new FileWriter(wordList, true));
+ out.println(rawText.toString());
out.close();
} catch (IOException e) {
+ Log.e("THAD", "Unable to append to " + wordList.getAbsolutePath(), e);
final AlertDialog alert = new AlertDialog.Builder(DictionaryActivity.this).create();
alert.setMessage("Failed to append to file: " + wordList.getAbsolutePath());
alert.show();
@Override
protected void onListItemClick(ListView l, View v, int row, long id) {
selectedRowIndex = row;
- Log.d("THAD", "Clicked: " + getSelectedRowText());
+ Log.d("THAD", "Clicked: " + getSelectedRowRawText());
openContextMenu(getListView());
}
}
}
+ private void startDownloadDictActivity() {
+ final Intent intent = new Intent().setClassName(
+ DownloadActivity.class.getPackage().getName(),
+ DownloadActivity.class.getCanonicalName());
+ final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(DictionaryActivity.this);
+ final String dictFetchUrl = settings.getString(DICT_FETCH_URL, null);
+ final String dictFileName = settings.getString(DICT_FILE, null);
+ intent.putExtra(DownloadActivity.SOURCE, dictFetchUrl);
+ intent.putExtra(DownloadActivity.DEST, dictFileName);
+ startActivity(intent);
+ }
+
private final class SearchOperation implements Runnable {
final String searchText;
final AtomicBoolean interrupted = new AtomicBoolean(false);
} // DictionaryListAdapter
private class DictionaryTextWatcher implements TextWatcher {
- public void afterTextChanged(Editable searchText) {
+ public void afterTextChanged(final Editable searchText) {
if (getSearchText().hasFocus()) {
+ // If they were typing to cause the change, update the UI.
onSearchTextChange(searchText.toString());
}
}
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
}
-
+
}
\ No newline at end of file
--- /dev/null
+package com.hughes.android.dictionary;\r
+\r
+import java.util.concurrent.Executor;\r
+import java.util.concurrent.Executors;\r
+\r
+import android.app.Activity;\r
+import android.content.Intent;\r
+import android.os.Bundle;\r
+import android.os.Handler;\r
+import android.util.Log;\r
+import android.view.View;\r
+import android.widget.ProgressBar;\r
+import android.widget.TextView;\r
+\r
+public class DownloadActivity extends Activity {\r
+\r
+ public static final String SOURCE = "source";\r
+ public static final String DEST = "dest";\r
+\r
+ String source;\r
+ String dest;\r
+ \r
+ private final Executor downloadExecutor = Executors.newSingleThreadExecutor();\r
+ private final Handler uiHandler = new Handler();\r
+\r
+ /** Called when the activity is first created. */\r
+ @Override\r
+ public void onCreate(final Bundle savedInstanceState) {\r
+ super.onCreate(savedInstanceState);\r
+ final Intent intent = getIntent();\r
+ source = intent.getStringExtra(SOURCE);\r
+ dest = intent.getStringExtra(DEST);\r
+ if (source == null || dest == null) {\r
+ throw new RuntimeException("null source or dest.");\r
+ }\r
+ setContentView(R.layout.download);\r
+ \r
+ final TextView sourceTextView = (TextView) findViewById(R.id.source);\r
+ sourceTextView.setText(source);\r
+ \r
+ final TextView destTextView = (TextView) findViewById(R.id.dest);\r
+ destTextView.setText(dest);\r
+\r
+ final ProgressBar progressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);\r
+ progressBar.setIndeterminate(false);\r
+ progressBar.setMax(100);\r
+\r
+ final Runnable runnable = new Runnable() {\r
+ public void run() {\r
+ \r
+ for (int i = 0; i < 100; ++i) {\r
+ \r
+ final int progress = i;\r
+ uiHandler.post(new Runnable() {\r
+ public void run() {\r
+ Log.d("THAD", "Setting progress: " + progress);\r
+ progressBar.setProgress(progress);\r
+ }\r
+ });\r
+ \r
+ try {\r
+ Thread.sleep(100);\r
+ } catch (InterruptedException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ final TextView downloadComplete = (TextView) findViewById(R.id.downloadComplete);\r
+ uiHandler.post(new Runnable() {\r
+ public void run() {\r
+ progressBar.setProgress(100);\r
+ downloadComplete.setVisibility(View.VISIBLE);\r
+ }\r
+ });\r
+ \r
+ }};\r
+ downloadExecutor.execute(runnable);\r
+ \r
+ }\r
+ \r
+}\r
}\r
\r
String getRawText() {\r
- return Arrays.asList(getAllText(LANG1)) + "\t" + Arrays.asList(getAllText(LANG2));\r
+ final StringBuilder result = new StringBuilder();\r
+ for (int i = 0; i < lang1.length; ++i) {\r
+ result.append(i == 0 ? "" : " | ").append(lang1[i]);\r
+ }\r
+ result.append(" :: ");\r
+ for (int i = 0; i < lang2.length; ++i) {\r
+ result.append(i == 0 ? "" : " | ").append(lang2[i]);\r
+ }\r
+ return result.toString();\r
}\r
\r
static byte otherLang(final byte lang) {\r
public static final int icon=0x7f020000;\r
}\r
public static final class id {\r
- public static final int DownButton=0x7f06000d;\r
+ public static final int DownButton=0x7f060019;\r
public static final int ImageView01=0x7f060002;\r
- public static final int LangButton=0x7f06000c;\r
+ public static final int LangButton=0x7f060018;\r
public static final int LinearLayout01=0x7f060000;\r
public static final int LinearLayout02=0x7f060001;\r
- public static final int SearchBarLinearLayout=0x7f060008;\r
- public static final int SearchBarTableLayout=0x7f060009;\r
- public static final int SearchBarTableRow=0x7f06000a;\r
- public static final int SearchText=0x7f06000b;\r
- public static final int UpButton=0x7f06000e;\r
+ public static final int SearchBarLinearLayout=0x7f060014;\r
+ public static final int SearchBarTableLayout=0x7f060015;\r
+ public static final int SearchBarTableRow=0x7f060016;\r
+ public static final int SearchText=0x7f060017;\r
+ public static final int TextView01=0x7f06000b;\r
+ public static final int UpButton=0x7f06001a;\r
public static final int author=0x7f060006;\r
public static final int copyright=0x7f060005;\r
+ public static final int currentDictInfo=0x7f06000a;\r
+ public static final int currentDictInfoTitle=0x7f060009;\r
+ public static final int dest=0x7f060011;\r
+ public static final int destLayout=0x7f06000f;\r
+ public static final int destTitle=0x7f060010;\r
+ public static final int downloadComplete=0x7f060013;\r
+ public static final int downloadProgressBar=0x7f060012;\r
public static final int email=0x7f060007;\r
+ public static final int source=0x7f06000e;\r
+ public static final int sourceLayout=0x7f06000c;\r
+ public static final int sourceTitle=0x7f06000d;\r
public static final int space1=0x7f060004;\r
+ public static final int space2=0x7f060008;\r
public static final int title=0x7f060003;\r
}\r
public static final class layout {\r
public static final int about=0x7f030000;\r
- public static final int main=0x7f030001;\r
+ public static final int download=0x7f030001;\r
+ public static final int main=0x7f030002;\r
}\r
public static final class string {\r
public static final int about_text=0x7f050001;\r