<string name="app_name">QuickDic</string>
- <!-- DictionaryListActivity -->
- <string name="dictionaryList">Wörterbuch-Liste</string>
- <string name="selectADictionary"><![CDATA[Wählen Sie ein Wörterbuch.\n
-Long-drücken, um das Wörterbuch Konfiguration zu bearbeiten. Drücken Sie "Menü", um ein neues Wörterbuch hinzufügen.]]></string>
- <string name="addDictionary">Wörterbuch hinzufügen</string>
- <string name="addDefaultDictionaries">Default Wörterbücher hinzufügen</string>
- <string name="removeAllDictionaries">Alle Wörterbücher entfernen</string>
- <string name="editDictionary">Wörterbuch Config bearbeiten</string>
- <string name="deleteDictionary">Wörterbuch entfernen</string>
- <string name="newDictionary">Neues Wörterbuch</string>
+ <!-- DictionaryManagerActivity -->
+ <string name="dictionaryManager">Wörterbuch-Liste</string>
+ <string name="helpText">Long-drücken, um weitere Möglichkeiten zu sehen.</string>
+ <string name="downloadButton">Herunterladen</string>
+ <string name="updateButton">Neuladen</string>
<string name="moveToTop">Nach Anfang ziehen</string>
- <string name="notOnDevice">%s (nicht auf dem Gerät)</string>
+ <string name="deleteDictionary">Wörterbuch entfernen</string>
+ <string name="nameFormat2">%1$s (%2$s=%3$d, %4$s=%5$d Einträge)</string>
- <string name="thanksForUpdatingVersion">3.0.1k</string>
+ <string name="thanksForUpdatingVersion">3.1</string>
<!-- Don't use links in the text below, it crashes the app. -->
<string name="thanksForUpdating"><![CDATA[
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
- Danke, daß Sie QuickDic 3.0.1 heruntergeladen haben.
- <p> neue Funktionen:
+ Danke, daß Sie QuickDic 3.1 heruntergeladen haben.
+ <p> Neue Funktionen:
<ul>
<li> QuickDic ist Open-Source!
<li> Neue Einstellungen:
<!-- DictionaryEditActivity -->
<string name="dictionaryName">Wörterbuch Name</string>
<string name="downloadUrl">Wörterbuch URL</string>
- <string name="downloadButton">Herunterladen</string>
+
<string name="openButton">Öffnen</string>
<string name="dictionaryInfo">Wörterbuch Info:</string>
<string name="localFile">Wörterbuch Datei</string>
<string name="fileNotFound">Datei nicht gefunden: \'%s\'</string>
<string name="invalidDictionary">Ungültige Wörterbuch: file=%1$s, error=%2$s</string>
<string name="numPairEntries">Einträge: %,d</string>
- <string name="numTokens">Tokens: %,d</string>
- <string name="numRows">Reihe: %,d</string>
- <!-- Main -->
- <string name="searchText">Suchtext</string>
- <string name="downloadDictionary">Wörterbuch herunterladen…</string>
- <string name="switchToLanguage">Zu %s wechseln</string>
- <string name="preferences">Einstellungen…</string>
- <string name="about">Über QuickDic…</string>
- <string name="addToWordList">Zum Wortliste hinzufügen: %s</string>
+ <!-- Main -->
+ <string name="searchText">Suchtext</string>
+ <string name="downloadDictionary">Wörterbuch herunterladen…</string>
+ <string name="switchToLanguage">Zu %s wechseln</string>
+ <string name="preferences">Einstellungen…</string>
+ <string name="about">Über QuickDic…</string>
+ <string name="addToWordList">Zum Wortliste hinzufügen: %s</string>
+ <string name="searchForSelection">Suche: %s</string>
<string name="failedAddingToWordList">Fehler beim Hinzufügen zur Wortliste: %s</string>
<string name="unzippingDictionary">Wörterbuch entpacken…</string>
<string name="failedToUnzipDictionary">Fehler beim Entpackung der Wörterbuch…</string>
<string name="fontSizeKey">fontSize</string>
<string name="fontSizeTitle">Schriftgröße</string>
- <string name="fontSizeSummary">Die Größe der Schriftart für die Wörterbuch-Reihen (Neustart erforderlich).</string>
+ <string name="fontSizeSummary">Die Größe der Schriftart für die Wörterbuch-Reihen.</string>
<string name="saveOnlyFirstSubentryKey">saveOnlyFirstSubentry</string>
<string name="saveOnlyFirstSubentryTitle">Speichern nur erste Sub-Eintrag</string>
<string name="themeKey">theme</string>
<string name="themeTitle">UI Theme</string>
- <string name="themeSummary">User-Interface Farbschema (Neustart erforderlich).</string>
+ <string name="themeSummary">User-Interface Farbschema.</string>
</resources>
android:layout_width="fill_parent" android:layout_height="wrap_content" android:indeterminate="false"/>
<TextView android:id="@+id/downloadMessage" android:layout_width="wrap_content"
- android:layout_height="wrap_content" android:visibility="visible" android:text="Download message."/>
+ android:layout_height="wrap_content" android:visibility="visible" android:text="Download message."
+ android:layout_marginTop="10dip"
+ android:layout_marginBottom="10dip"/>
<TextView android:id="@+id/downloadStatus" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:visibility="visible" android:text="Download status."/>
+++ /dev/null
-<ScrollView android:id="@+id/ScrollView01"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
-<LinearLayout
- android:id="@+id/LinearLayout01"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- >
-
-<!-- android:textAppearance="?android:attr/textAppearanceLarge" -->
-
- <!-- Name. -->
- <TextView
- android:id="@+id/dictionaryNameTitle"
- android:text="@string/dictionaryName"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- <EditText
- android:id="@+id/dictionaryName"
- android:inputType="textNoSuggestions"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <!-- Local file. -->
- <TextView
- android:id="@+id/localFileTitle"
- android:text="@string/localFile"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingTop="5dip" />
- <EditText
- android:id="@+id/localFile"
- android:inputType="textUri"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <!-- Download URL. -->
- <TextView
- android:id="@+id/downloadUrlTitle"
- android:text="@string/downloadUrl"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingTop="5dip" />
- <EditText
- android:id="@+id/downloadUrl"
- android:inputType="textUri"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <LinearLayout
- android:id="@+id/LinearLayout03"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
-
- <Button
- android:id="@+id/downloadButton"
- android:text="@string/downloadButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/openButton"
- android:text="@string/openButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
-
- <TextView
- android:id="@+id/dictionaryInfoTitle"
- android:text="@string/dictionaryInfo"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingTop="5dip" />
- <TextView
- android:id="@+id/dictionaryInfo"
- android:text=""
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingTop="20dip" />
-
-</LinearLayout>
-
-</ScrollView>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <WebView
+ android:id="@+id/helpWebView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
\ No newline at end of file
<TextView
android:id="@+id/DictionaryListHeader"
- android:hint="@string/selectADictionary"
+ android:hint="@string/helpText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:imeOptions="actionSearch|flagNoEnterAction|flagNoExtractUi"
--- /dev/null
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+</head>
+<body>
+ <!-- Don't use links in the text below, it crashes the app. -->
+
+ Thanks for updating to QuickDic 3.1.
+ <p> New features:
+ <ul>
+ <li> Long-press any word in a dictionary to lookup that word.
+ <li> Long-press the search text to see search history.
+ <li> Long-press the switch-language button to change dictionaries.
+ <li> New English dictionaries: Tagalog, Urdu. (based on enwiktionary.com data).
+ <li> All dictionaries updated (mostly with better formatting), and can be re-downloaded at your leisure (previously downloaded dictionaries will still work).
+ </ul>
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+</head>
+<body>
+ <!-- Don't use links in the text below, it crashes the app. -->
+
+ Thanks for updating to QuickDic 3.1.
+ <p> New features:
+ <ul>
+ <li> Long-press any word in a dictionary to lookup that word.
+ <li> Long-press the search text to see search history.
+ <li> Long-press the switch-language button to change dictionaries.
+ <li> New English dictionaries: Tagalog, Urdu. (based on enwiktionary.com data).
+ <li> All dictionaries updated (mostly with better formatting), and can be re-downloaded at your leisure (previously downloaded dictionaries will still work).
+ </ul>
+</body>
+</html>
\ No newline at end of file
<string name="CA">Catalan</string>
<string name="HR">Croatian</string>
<string name="CS">Czech</string>
- <string name="ZH">Chinese|Mandarin|Cantonese</string>
+ <string name="ZH">Chinese (Mandarin, Cantonese)</string>
<string name="DA">Danish</string>
<string name="NL">Dutch</string>
<string name="EN">English</string>
<string name="ES">Spanish</string>
<string name="SW">Swahili</string>
<string name="SV">Swedish</string>
+ <string name="TL">Tagalog</string>
<string name="TG">Tajik</string>
<string name="TH">Thai</string>
<string name="BO">Tibetan</string>
<!-- DictionaryManagerActivity -->
<string name="dictionaryManager">Dictionary manager</string>
- <string name="selectADictionary"><![CDATA[Select a dictionary.
-\nLong-press to edit the dictionary config. Press "menu" to add a new dictionary.]]></string>
- <string name="dictionaryConfig">Dictionary config</string>
+ <string name="helpText">Long-press for more options.</string>
+ <string name="downloadButton">Download</string>
+ <string name="updateButton">Update</string>
<string name="moveToTop">Move to top</string>
<string name="deleteDictionary">Delete dictionary</string>
- <string name="notOnDevice">%s (not on device)</string>
+ <string name="nameFormat2">%1$s (%2$s=%3$d, %4$s=%5$d entries)</string>
+
- <string name="thanksForUpdatingVersion">3.0.1h</string>
- <!-- Don't use links in the text below, it crashes the app. -->
- <string name="thanksForUpdating"><![CDATA[
-<html>
-<body>
- Thanks for updating to QuickDic 3.0.1.
- <p> New features:
- <ul>
- <li> QuickDic is open-source!
- <li> New preferences:
- <ul>
- <li> Dictionary font size is adjustable.
- <li> Short clicks on dictionary entries no longer open context menu by default.
- </ul>
- <li> 17 new English dictionaries: Albanian, Armenian, Belarusian, Bengali, Bosnian, Bulgarian, Catalan, Esperanto, Estonian, Hungarian, Indonesian, Latin, Latvian, Polish, Punjabi, Slovak, Swahili. (based on enwiktionary.com data).
- <li> All dictionaries updated (mostly with better formatting), and can be re-downloaded at your leisure (previously downloaded dictionaries will still work).
- </ul>
-</body>
-</html>
-]]>
- </string>
+ <string name="thanksForUpdatingVersion">3.1</string>
<!-- DictionaryEditActivity -->
+ <!--
<string name="dictionaryName">Dictionary name</string>
<string name="downloadUrl">Dictionary download URL</string>
- <string name="downloadButton">Download</string>
<string name="openButton">Open</string>
<string name="dictionaryInfo">Dictionary info:</string>
<string name="indexInfo">Index %1$s, %2$d words</string>
<string name="localFile">Dictionary file</string>
<string name="wordListFile">Word list file</string>
<string name="fileNotFound">File not found: \'%s\'</string>
- <string name="invalidDictionary">Invalid dictionary: file=%1$s, error=%2$s</string>
<string name="numPairEntries">Entries: %,d</string>
-
+ -->
- <!-- Main -->
- <string name="searchText">Search Text</string>
- <string name="downloadDictionary">Download dictionary…</string>
- <string name="switchToLanguage">Switch to %s</string>
- <string name="preferences">Preferences…</string>
- <string name="about">About QuickDic…</string>
- <string name="addToWordList">Add to word list: %s</string>
+ <!-- DictionaryActivity -->
+ <string name="searchText">Search Text</string>
+ <string name="selectDictionary">Select dictionary…</string>
+ <string name="switchToLanguage">Switch to %s</string>
+ <string name="preferences">Preferences…</string>
+ <string name="about">About QuickDic…</string>
+ <string name="addToWordList">Add to word list: %s</string>
<string name="searchForSelection">Find: %s</string>
- <string name="failedAddingToWordList">Failure adding to word list: %s</string>
-
- <!-- do we need? -->
+ <string name="failedAddingToWordList">Failure adding to word list: %s</string>
<string name="unzippingDictionary">Unzipping dictionary…</string>
<string name="failedToUnzipDictionary">Failed to unzip dictionary…</string>
-
+ <string name="invalidDictionary">Invalid dictionary: file=%1$s, error=%2$s</string>
+
<!-- About. -->
- <string name="titleWithVersion">QuickDic 3.0.1</string>
+ <string name="titleWithVersion">QuickDic 3.1</string>
<string name="thadHughes">Thad Hughes</string>
<string name="contactMe">If you\'re using QuickDic, I\'d love to hear from you. Unfortunately, I cannot take responsibility for dictionary content (other than formatting), as it is generated from other sources. Please send comments, suggestions, bug reports, or just a quick hello to:</string>
<string name="myEmail" formatted="false">thad.hughes@gmail.com</string>
<string name="fontSizeKey">fontSize</string>
<string name="fontSizeTitle">Font size</string>
- <string name="fontSizeSummary">The size of the font for dictionary rows (restart required).</string>
+ <string name="fontSizeSummary">The size of the font for dictionary rows.</string>
<string name="saveOnlyFirstSubentryKey">saveOnlyFirstSubentry</string>
<string name="saveOnlyFirstSubentryTitle">Save only first sub-entry</string>
<string name="themeKey">theme</string>
<string name="themeTitle">UI theme</string>
- <string name="themeSummary">User-interface color theme (restart required).</string>
+ <string name="themeSummary">User-interface color theme.</string>
</resources>
public class C {
- static final String DICTIONARY_CONFIGS = "dictionaryConfigs";
+ static final String DICTIONARY_CONFIGS = "dictionaryConfigs2";
static final String DICT_FILE = "dictFile";
static final String INDEX_INDEX = "indexIndex";
R.drawable.theme_default_token_row_other_bg,
R.drawable.theme_default_other_lang_bg),
- LIGHT(R.style.Theme_Light,
+ LIGHT(R.style.Theme_Light,
R.style.Theme_Light_TokenRow_Fg,
R.drawable.theme_light_token_row_main_bg,
R.drawable.theme_light_token_row_other_bg,
import android.widget.TextView;\r
import android.widget.Toast;\r
\r
+import com.hughes.android.dictionary.DictionaryInfo.IndexInfo;\r
import com.hughes.android.dictionary.engine.Dictionary;\r
import com.hughes.android.dictionary.engine.Index;\r
import com.hughes.android.dictionary.engine.PairEntry;\r
import com.hughes.android.dictionary.engine.RowBase;\r
import com.hughes.android.dictionary.engine.TokenRow;\r
import com.hughes.android.dictionary.engine.TransliteratorManager;\r
+import com.hughes.android.util.IntentLauncher;\r
\r
public class DictionaryActivity extends ListActivity {\r
\r
static final String LOG = "QuickDic";\r
\r
- String dictFile = null;\r
+ DictionaryApplication application;\r
+ File dictFile = null;\r
RandomAccessFile dictRaf = null;\r
Dictionary dictionary = null;\r
int indexIndex = 0;\r
\r
final SearchTextWatcher searchTextWatcher = new SearchTextWatcher();\r
\r
- //private Vibrator vibrator = null;\r
- \r
public DictionaryActivity() {\r
}\r
\r
- public static Intent getLaunchIntent(final String dictFile, final int indexIndex, final String searchToken) {\r
+ public static Intent getLaunchIntent(final File dictFile, final int indexIndex, final String searchToken) {\r
final Intent intent = new Intent();\r
intent.setClassName(DictionaryActivity.class.getPackage().getName(), DictionaryActivity.class.getName());\r
- intent.putExtra(C.DICT_FILE, dictFile);\r
+ intent.putExtra(C.DICT_FILE, dictFile.getPath());\r
intent.putExtra(C.INDEX_INDEX, indexIndex);\r
intent.putExtra(C.SEARCH_TOKEN, searchToken);\r
return intent;\r
setSearchText(outState.getString(C.SEARCH_TOKEN));\r
}\r
\r
- public DictionaryApplication getDictionaryApplication() {\r
- return (DictionaryApplication) super.getApplication();\r
- }\r
- \r
@Override\r
- public void onCreate(Bundle savedInstanceState) {\r
+ public void onCreate(Bundle savedInstanceState) { \r
+ Log.d(LOG, "onCreate:" + this);\r
+ super.onCreate(savedInstanceState);\r
+\r
+ application = (DictionaryApplication) getApplication();\r
+ theme = application.getSelectedTheme();\r
+\r
// Clear them so that if something goes wrong, we won't relaunch.\r
clearDictionaryPrefs(this);\r
\r
- Log.d(LOG, "onCreate:" + this);\r
- theme = ((DictionaryApplication)getApplication()).getSelectedTheme();\r
- super.onCreate(savedInstanceState);\r
\r
final Intent intent = getIntent();\r
- dictFile = intent.getStringExtra(C.DICT_FILE);\r
+ dictFile = new File(intent.getStringExtra(C.DICT_FILE));\r
\r
try {\r
- final String name = getDictionaryApplication().getDictionaryName(dictFile);\r
+ final String name = application.getDictionaryName(dictFile.getName());\r
this.setTitle("QuickDic: " + name);\r
dictRaf = new RandomAccessFile(dictFile, "r");\r
dictionary = new Dictionary(dictRaf); \r
langButton.setOnLongClickListener(new OnLongClickListener() {\r
@Override\r
public boolean onLongClick(View v) {\r
- onLanguageButtonLongClick();\r
+ onLanguageButtonLongClick(v.getContext());\r
return true;\r
}\r
});\r
}\r
\r
private static void setDictionaryPrefs(final Context context,\r
- final String dictFile, final int indexIndex, final String searchToken) {\r
+ final File dictFile, final int indexIndex, final String searchToken) {\r
final SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(context).edit();\r
- prefs.putString(C.DICT_FILE, dictFile);\r
+ prefs.putString(C.DICT_FILE, dictFile.getPath());\r
prefs.putInt(C.INDEX_INDEX, indexIndex);\r
prefs.putString(C.SEARCH_TOKEN, searchToken);\r
prefs.commit();\r
static class OpenIndexButton extends Button implements OnClickListener {\r
\r
final Activity activity;\r
- final String dictFile;\r
- final int indexIndex;\r
+ final Intent intent;\r
\r
- public OpenIndexButton(final Context context, final Activity activity, final String text, final String dictFile, final int indexIndex) {\r
+ public OpenIndexButton(final Context context, final Activity activity, final String text, final Intent intent) {\r
super(context);\r
this.activity = activity;\r
- this.dictFile = dictFile;\r
- this.indexIndex = indexIndex;\r
+ this.intent = intent;\r
setOnClickListener(this);\r
setText(text, BufferType.NORMAL);\r
}\r
@Override\r
public void onClick(View v) {\r
activity.finish();\r
- getContext().startActivity(DictionaryActivity.getLaunchIntent(dictFile, indexIndex, ""));\r
+ getContext().startActivity(intent);\r
}\r
\r
}\r
\r
- void onLanguageButtonLongClick() {\r
- Context mContext = getApplicationContext();\r
- Dialog dialog = new Dialog(mContext);\r
- \r
+ void onLanguageButtonLongClick(final Context context) {\r
+ final Dialog dialog = new Dialog(context);\r
dialog.setContentView(R.layout.select_dictionary_dialog);\r
- dialog.setTitle(R.string.selectADictionary);\r
+ dialog.setTitle(R.string.selectDictionary);\r
\r
- ListView listView = (ListView) dialog.findViewById(android.R.id.list);\r
- \r
final List<DictionaryInfo> installedDicts = ((DictionaryApplication)getApplication()).getUsableDicts();\r
-\r
+ ListView listView = (ListView) dialog.findViewById(android.R.id.list);\r
listView.setAdapter(new BaseAdapter() {\r
- \r
@Override\r
public View getView(int position, View convertView, ViewGroup parent) {\r
final LinearLayout result = new LinearLayout(parent.getContext());\r
- //result.addView(new Butt)\r
- // TODO: me\r
+ final DictionaryInfo dictionaryInfo = getItem(position);\r
+ for (int i = 0; i < dictionaryInfo.indexInfos.size(); ++i) {\r
+ final IndexInfo indexInfo = dictionaryInfo.indexInfos.get(i);\r
+ final Button button = new Button(parent.getContext());\r
+ String name = application.getLanguageName(indexInfo.shortName);\r
+ if (name == null) {\r
+ name = indexInfo.shortName;\r
+ }\r
+ button.setText(name);\r
+ final IntentLauncher intentLauncher = new IntentLauncher(parent.getContext(), getLaunchIntent(application.getPath(dictionaryInfo.uncompressedFilename), i, "")) {\r
+ @Override\r
+ protected void onGo() {\r
+ dialog.dismiss();\r
+ DictionaryActivity.this.finish();\r
+ };\r
+ };\r
+ button.setOnClickListener(intentLauncher);\r
+ \r
+ final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);\r
+ layoutParams.width = 0;\r
+ layoutParams.weight = 1.0f;\r
+ button.setLayoutParams(layoutParams);\r
+\r
+ result.addView(button);\r
+ }\r
return result;\r
}\r
\r
return installedDicts.size();\r
}\r
});\r
+ \r
+ dialog.show();\r
}\r
\r
\r
static Map<String,DictionaryInfo> DOWNLOADABLE_NAME_TO_INFO = null;
static final class DictionaryConfig implements Serializable {
- private static final long serialVersionUID = -1444177164708201260L;
+ private static final long serialVersionUID = -1444177164708201262L;
// User-ordered list, persisted, just the ones that are/have been present.
- final List<String> dictionaryFiles = new ArrayList<String>();
+ final List<DictionaryInfo> dictionaryFilesOrdered = new ArrayList<DictionaryInfo>();
+ final Set<String> invalidatedFilenames = new LinkedHashSet<String>();
}
DictionaryConfig dictionaryConfig = null;
-
+
+ static final class DictionaryHistory implements Serializable {
+ private static final long serialVersionUID = -4842995032541390284L;
+ // User-ordered list, persisted, just the ones that are/have been present.
+ final List<DictionaryLink> dictionaryLinks = new ArrayList<DictionaryLink>();
+ }
+ DictionaryHistory dictionaryHistory = null;
+
+
@Override
public void onCreate() {
super.onCreate();
}
}
- private File getPath(String uncompressedFilename) {
+ public File getPath(String uncompressedFilename) {
return new File(DICT_DIR, uncompressedFilename);
}
public List<DictionaryInfo> getUsableDicts() {
- final List<DictionaryInfo> result = new ArrayList<DictionaryInfo>(dictionaryConfig.dictionaryFiles.size());
- for (final String uncompressedFilename : dictionaryConfig.dictionaryFiles) {
- final DictionaryInfo dictionaryInfo = Dictionary.getDictionaryInfo(getPath(uncompressedFilename));
+ final List<DictionaryInfo> result = new ArrayList<DictionaryInfo>(dictionaryConfig.dictionaryFilesOrdered.size());
+ for (int i = 0; i < dictionaryConfig.dictionaryFilesOrdered.size(); ++i) {
+ DictionaryInfo dictionaryInfo = dictionaryConfig.dictionaryFilesOrdered.get(i);
+ if (dictionaryConfig.invalidatedFilenames.contains(dictionaryInfo.uncompressedFilename)) {
+ dictionaryInfo = Dictionary.getDictionaryInfo(getPath(dictionaryInfo.uncompressedFilename));
+ if (dictionaryInfo != null) {
+ dictionaryConfig.dictionaryFilesOrdered.set(i, dictionaryInfo);
+ }
+ }
if (dictionaryInfo != null) {
result.add(dictionaryInfo);
}
}
+ if (!dictionaryConfig.invalidatedFilenames.isEmpty()) {
+ dictionaryConfig.invalidatedFilenames.clear();
+ PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, dictionaryConfig);
+ }
return result;
}
+
+ public String getLanguageName(final String isoCode) {
+ final Integer langCode = Language.isoCodeToResourceId.get(isoCode);
+ final String lang = langCode != null ? getApplicationContext().getString(langCode) : isoCode;
+ return lang;
+ }
final Map<String, String> fileToNameCache = new LinkedHashMap<String, String>();
public synchronized String getDictionaryName(final String uncompressedFilename) {
}
final DictionaryInfo dictionaryInfo = DOWNLOADABLE_NAME_TO_INFO.get(uncompressedFilename);
- final Context context = getApplicationContext();
if (dictionaryInfo != null) {
final StringBuilder nameBuilder = new StringBuilder();
for (int i = 0; i < dictionaryInfo.indexInfos.size(); ++i) {
- final Integer langCode = Language.isoCodeToResourceId.get(dictionaryInfo.indexInfos.get(i).shortName);
- final String lang = langCode != null ? context.getString(langCode) : dictionaryInfo.indexInfos.get(i).shortName;
if (i > 0) {
nameBuilder.append("-");
}
- nameBuilder.append(lang);
+ nameBuilder.append(getLanguageName(dictionaryInfo.indexInfos.get(i).shortName));
}
name = nameBuilder.toString();
} else {
return name;
}
- public void moveDictionaryToTop(final String canonicalPath) {
- dictionaryConfig.dictionaryFiles.remove(canonicalPath);
- dictionaryConfig.dictionaryFiles.add(0, canonicalPath);
+ public void moveDictionaryToTop(final DictionaryInfo dictionaryInfo) {
+ dictionaryConfig.dictionaryFilesOrdered.remove(dictionaryInfo);
+ dictionaryConfig.dictionaryFilesOrdered.add(0, dictionaryInfo);
PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, dictionaryConfig);
}
- public void deleteDictionary(String canonicalPath) {
- while (dictionaryConfig.dictionaryFiles.remove(canonicalPath)) {};
+ public void deleteDictionary(final DictionaryInfo dictionaryInfo) {
+ while (dictionaryConfig.dictionaryFilesOrdered.remove(dictionaryInfo)) {};
+ getPath(dictionaryInfo.uncompressedFilename).delete();
PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, dictionaryConfig);
}
+ final Collator collator = Collator.getInstance();
+ final Comparator<DictionaryInfo> comparator = new Comparator<DictionaryInfo>() {
+ @Override
+ public int compare(DictionaryInfo object1, DictionaryInfo object2) {
+ return collator.compare(getDictionaryName(object1.uncompressedFilename), getDictionaryName(object2.uncompressedFilename));
+ }
+ };
+
public List<DictionaryInfo> getAllDictionaries() {
final List<DictionaryInfo> result = getUsableDicts();
for (final DictionaryInfo usable : result) {
known.add(usable.uncompressedFilename);
}
+ if (!dictionaryConfig.invalidatedFilenames.isEmpty()) {
+ dictionaryConfig.invalidatedFilenames.clear();
+ }
// Are there dictionaries on the device that we didn't know about already?
// Pick them up and put them at the end of the list.
- boolean foundNew = false;
+ final List<DictionaryInfo> toAddSorted = new ArrayList<DictionaryInfo>();
final File[] dictDirFiles = DICT_DIR.listFiles();
for (final File file : dictDirFiles) {
if (!file.getName().endsWith(".quickdic")) {
continue;
}
known.add(file.getName());
- foundNew = true;
- dictionaryConfig.dictionaryFiles.add(file.getName());
- result.add(dictionaryInfo);
+ toAddSorted.add(dictionaryInfo);
}
- if (foundNew) {
+ if (!toAddSorted.isEmpty()) {
+ Collections.sort(toAddSorted, comparator);
+ result.addAll(toAddSorted);
+// for (final DictionaryInfo dictionaryInfo : toAddSorted) {
+// dictionaryConfig.dictionaryFilesOrdered.add(dictionaryInfo.uncompressedFilename);
+// }
+ dictionaryConfig.dictionaryFilesOrdered.addAll(toAddSorted);
PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, dictionaryConfig);
}
// The downloadable ones.
final Map<String,DictionaryInfo> remaining = new LinkedHashMap<String, DictionaryInfo>(DOWNLOADABLE_NAME_TO_INFO);
remaining.keySet().removeAll(known);
- final List<DictionaryInfo> remainingSorted = new ArrayList<DictionaryInfo>(remaining.values());
- final Collator collator = Collator.getInstance();
- Collections.sort(remainingSorted, new Comparator<DictionaryInfo>() {
- @Override
- public int compare(DictionaryInfo object1, DictionaryInfo object2) {
- return collator.compare(getDictionaryName(object1.uncompressedFilename), getDictionaryName(object2.uncompressedFilename));
- }
- });
-
- result.addAll(remainingSorted);
+ toAddSorted.clear();
+ toAddSorted.addAll(remaining.values());
+ Collections.sort(toAddSorted, comparator);
+ result.addAll(toAddSorted);
return result;
}
return getPath(uncompressedFilename).canRead();
}
+ public boolean updateAvailable(final DictionaryInfo dictionaryInfo) {
+ final DictionaryInfo downloadable = DOWNLOADABLE_NAME_TO_INFO.get(dictionaryInfo.uncompressedFilename);
+ return downloadable != null && downloadable.creationMillis > dictionaryInfo.creationMillis;
+ }
+
+ public DictionaryInfo getDownloadable(final String uncompressedFilename) {
+ final DictionaryInfo downloadable = DOWNLOADABLE_NAME_TO_INFO.get(uncompressedFilename);
+ return downloadable;
+ }
+
+ public void invalidateDictionaryInfo(final String uncompressedFilename) {
+ dictionaryConfig.invalidatedFilenames.add(uncompressedFilename);
+ PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, dictionaryConfig);
+ }
}
public long creationMillis;
public final List<IndexInfo> indexInfos = new ArrayList<DictionaryInfo.IndexInfo>();
public String dictInfo;
-
+
+ public DictionaryInfo() {
+ // Blank object.
+ }
+
public StringBuilder append(final StringBuilder result) {
result.append(uncompressedFilename);
result.append("\t").append(downloadUrl);
dictInfo = fields[i++].replaceAll("\\n", "\n");
}
- public DictionaryInfo() {
- // Blank object.
- }
-
@Override
public String toString() {
return uncompressedFilename;
--- /dev/null
+package com.hughes.android.dictionary;
+
+import java.io.Serializable;
+
+public class DictionaryLink implements Serializable {
+
+ private static final long serialVersionUID = -3842984045642836981L;
+
+ final String uncompressedFilename;
+ final int index;
+ final String searchText;
+
+ private DictionaryLink(String uncompressedFilename, int index,
+ String searchText) {
+ this.uncompressedFilename = uncompressedFilename;
+ this.index = index;
+ this.searchText = searchText;
+ }
+
+}
package com.hughes.android.dictionary;
+import java.io.File;
import java.util.List;
import android.app.AlertDialog;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
-import android.widget.TableLayout;
+import android.widget.Button;
+import android.widget.LinearLayout;
import android.widget.TextView;
+import com.hughes.android.util.IntentLauncher;
+import com.hughes.util.StringUtil;
+
public class DictionaryManagerActivity extends ListActivity {
static final String LOG = "QuickDic";
- QuickDicConfig quickDicConfig;
-
static boolean canAutoLaunch = true;
-
- final DictionaryApplication application = (DictionaryApplication) getApplication();
+
+ DictionaryApplication application;
+ Adapter adapter;
public void onCreate(Bundle savedInstanceState) {
- //((DictionaryApplication)getApplication()).applyTheme(this);
-
super.onCreate(savedInstanceState);
Log.d(LOG, "onCreate:" + this);
+
+ application = (DictionaryApplication) getApplication();
// UI init.
setContentView(R.layout.list_activity);
onClick(index);
}
});
+
+ getListView().setClickable(true);
// ContextMenu.
registerForContextMenu(getListView());
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);
final WebView webView = new WebView(getApplicationContext());
- webView.loadData(getString(R.string.thanksForUpdating), "text/html", "utf-8");
+ webView.loadData(StringUtil.readToString(getResources().openRawResource(R.raw.whats_new)), "text/html", "utf-8");
builder.setView(webView);
builder.setNegativeButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
private void onClick(int index) {
final DictionaryInfo dictionaryInfo = adapter.getItem(index);
- final Intent intent = DictionaryActivity.getLaunchIntent(dictionaryInfo.uncompressedFilename, 0, "");
- startActivity(intent);
+ final DictionaryInfo downloadable = application.getDownloadable(dictionaryInfo.uncompressedFilename);
+ if (!application.isDictionaryOnDevice(dictionaryInfo.uncompressedFilename) && downloadable != null) {
+ final Intent intent = DownloadActivity
+ .getLaunchIntent(downloadable.downloadUrl,
+ application.getPath(dictionaryInfo.uncompressedFilename).getPath() + ".zip",
+ dictionaryInfo.dictInfo);
+ startActivity(intent);
+ } else {
+ final Intent intent = DictionaryActivity.getLaunchIntent(application.getPath(dictionaryInfo.uncompressedFilename), 0, "");
+ startActivity(intent);
+ }
}
@Override
if (canAutoLaunch && prefs.contains(C.DICT_FILE) && prefs.contains(C.INDEX_INDEX)) {
canAutoLaunch = false; // Only autolaunch once per-process, on startup.
Log.d(LOG, "Skipping Dictionary List, going straight to dictionary.");
- startActivity(DictionaryActivity.getLaunchIntent(prefs.getString(C.DICT_FILE, ""), prefs.getInt(C.INDEX_INDEX, 0), prefs.getString(C.SEARCH_TOKEN, "")));
+ startActivity(DictionaryActivity.getLaunchIntent(new File(prefs.getString(C.DICT_FILE, "")), prefs.getInt(C.INDEX_INDEX, 0), prefs.getString(C.SEARCH_TOKEN, "")));
// Don't finish, so that user can hit back and get here.
//finish();
return;
}
- setListAdapter(adapter);
+ setListAdapter(adapter = new Adapter());
}
public boolean onCreateOptionsMenu(final Menu menu) {
moveToTopMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
- application.moveDictionaryToTop(dictionaryInfo.uncompressedFilename);
+ application.moveDictionaryToTop(dictionaryInfo);
setListAdapter(adapter = new Adapter());
return true;
}
deleteMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
- application.deleteDictionary(dictionaryInfo.uncompressedFilename);
+ application.deleteDictionary(dictionaryInfo);
setListAdapter(adapter = new Adapter());
return true;
}
}
@Override
- public View getView(int position, View convertView, ViewGroup parent) {
+ public View getView(final int position, final View convertView, final ViewGroup parent) {
final DictionaryInfo dictionaryInfo = getItem(position);
- final TableLayout tableLayout = new TableLayout(parent.getContext());
- final TextView view = new TextView(parent.getContext());
+ final LinearLayout result = new LinearLayout(parent.getContext());
- String name = application.getDictionaryName(dictionaryInfo.uncompressedFilename);
- if (!application.isDictionaryOnDevice(dictionaryInfo.uncompressedFilename)) {
- name = getString(R.string.notOnDevice, name);
+ final boolean updateAvailable = application.updateAvailable(dictionaryInfo);
+ final DictionaryInfo downloadable = application.getDownloadable(dictionaryInfo.uncompressedFilename);
+ if ((!application.isDictionaryOnDevice(dictionaryInfo.uncompressedFilename) || updateAvailable) && downloadable != null) {
+ final Button downloadButton = new Button(parent.getContext());
+ downloadButton.setText(getString(updateAvailable ? R.string.updateButton : R.string.downloadButton));
+ downloadButton.setOnClickListener(new IntentLauncher(parent.getContext(), DownloadActivity
+ .getLaunchIntent(downloadable.downloadUrl,
+ application.getPath(dictionaryInfo.uncompressedFilename).getPath() + ".zip",
+ dictionaryInfo.dictInfo)) {
+ @Override
+ protected void onGo() {
+ application.invalidateDictionaryInfo(dictionaryInfo.uncompressedFilename);
+ }
+ });
+ WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+ layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
+ layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
+ downloadButton.setLayoutParams(layoutParams);
+ result.addView(downloadButton);
}
- view.setText(name);
- view.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22);
- tableLayout.addView(view);
+ final TextView textView = new TextView(parent.getContext());
+ final String name = application.getDictionaryName(dictionaryInfo.uncompressedFilename);
+ textView.setText(name);
+ textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22);
+ result.addView(textView);
+
+ // Because we have a Button inside a ListView row:
+ // http://groups.google.com/group/android-developers/browse_thread/thread/3d96af1530a7d62a?pli=1
+ result.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+ result.setClickable(true);
+ result.setFocusable(true);
+ result.setLongClickable(true);
+ result.setBackgroundResource(android.R.drawable.menuitem_background);
+ result.setOnClickListener(new TextView.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ DictionaryManagerActivity.this.onClick(position);
+ }
+ });
- return tableLayout;
+ return result;
}
}
- Adapter adapter = new Adapter();
public static Intent getLaunchIntent() {
final Intent intent = new Intent();
\r
final AtomicBoolean stop = new AtomicBoolean(false);\r
\r
- public static Intent getLaunchIntent(final String dictFile, final String source, final String dest, final String message) {\r
+ public static Intent getLaunchIntent(final String source, final String dest, final String message) {\r
final Intent intent = new Intent();\r
intent.setClassName(DownloadActivity.class.getPackage().getName(), DownloadActivity.class.getName());\r
intent.putExtra(SOURCE, source);\r
final TextView destTextView = (TextView) findViewById(R.id.dest);\r
destTextView.setText(dest);\r
\r
+ final TextView messageTextView = (TextView) findViewById(R.id.downloadMessage);\r
+ messageTextView.setText(message);\r
+\r
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);\r
progressBar.setIndeterminate(false);\r
progressBar.setMax(100);\r
final OutputStream zipOut = new FileOutputStream(destUnzipped);\r
contentLength = zipEntry.getSize();\r
bytesRead = copyStream(zipIn, zipOut, R.string.unzipping);\r
+ destFile.delete();\r
}\r
}\r
\r
--- /dev/null
+// Copyright 2011 Google Inc. All Rights Reserved.\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+// http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+package com.hughes.android.dictionary;\r
+\r
+import android.app.Activity;\r
+import android.os.Bundle;\r
+\r
+public final class HelpActivity extends Activity {\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.help_activity);\r
+ \r
+ \r
+ }\r
+\r
+}\r
raf = new RandomAccessFile(file, "r");
final Dictionary dict = new Dictionary(raf);
final DictionaryInfo dictionaryInfo = dict.getDictionaryInfo();
+ dictionaryInfo.uncompressedFilename = file.getName();
+ dictionaryInfo.uncompressedSize = file.length();
raf.close();
return dictionaryInfo;
} catch (IOException e) {
public enum EntryTypeName {
- WIKTIONARY_TITLE_SINGLE(true, null),
- WIKTIONARY_INFLECTD_FORM_SINGLE(true, null),
+ WIKTIONARY_TITLE_SINGLE(true, true, null),
+ WIKTIONARY_INFLECTD_FORM_SINGLE(false, true, null),
- ONE_WORD(true, null),
- MULTIROW_HEAD_ONE_WORD(true, null),
- MULTIROW_TAIL_ONE_WORD(true, null),
+ ONE_WORD(true, true, null),
+ MULTIROW_HEAD_ONE_WORD(true, true, null),
+ MULTIROW_TAIL_ONE_WORD(false, true, null),
- WIKTIONARY_TITLE_MULTI(true, WIKTIONARY_TITLE_SINGLE),
+ WIKTIONARY_TITLE_MULTI(false, true, WIKTIONARY_TITLE_SINGLE),
WIKTIONARY_TRANSLITERATION(),
- WIKTIONARY_INFLECTED_FORM_MULTI(true, WIKTIONARY_INFLECTD_FORM_SINGLE),
+ WIKTIONARY_INFLECTED_FORM_MULTI(false, true, WIKTIONARY_INFLECTD_FORM_SINGLE),
WIKTIONARY_ENGLISH_DEF_WIKI_LINK(),
WIKTIONARY_ENGLISH_DEF_OTHER_LANG(),
WIKTIONARY_ENGLISH_DEF(),
WIKTIONARY_TRANSLATION_WIKI_TEXT(),
WIKTIONARY_TRANSLATION_OTHER_TEXT(),
- WIKTIONARY_IS_FORM_OF_SOMETHING_ELSE(true, null),
+ WIKTIONARY_IS_FORM_OF_SOMETHING_ELSE(false, true, null),
MULTIROW_HEAD_MANY_WORDS(),
MULTIROW_TAIL_MANY_WORDS(),
WIKTIONARY_EXAMPLE(),
WIKTIONARY_BASE_FORM_SINGLE(), // These two should be eligible for removal if the links are otherwise present.
- WIKTIONARY_BASE_FORM_MULTI(false, WIKTIONARY_BASE_FORM_SINGLE),
+ WIKTIONARY_BASE_FORM_MULTI(false, false, WIKTIONARY_BASE_FORM_SINGLE),
PART_OF_HYPHENATED(),
BRACKETED(),
PARENTHESIZED(),
SEE_ALSO(),
;
+ final boolean mainWord;
final boolean overridesStopList;
final EntryTypeName singleWordInstance;
private EntryTypeName() {
- this(false, null);
+ this(false, false, null);
}
- private EntryTypeName(final boolean overridesStopList, final EntryTypeName singleWordInstance) {
+ private EntryTypeName(final boolean mainWord, final boolean overridesStopList, final EntryTypeName singleWordInstance) {
+ this.mainWord = mainWord;
this.overridesStopList = overridesStopList;
this.singleWordInstance = singleWordInstance == null ? this : singleWordInstance;
}
isoCodeToResourceId.put("ES", R.string.ES);\r
isoCodeToResourceId.put("SW", R.string.SW);\r
isoCodeToResourceId.put("SV", R.string.SV);\r
+ isoCodeToResourceId.put("TL", R.string.TL);\r
isoCodeToResourceId.put("TG", R.string.TG);\r
isoCodeToResourceId.put("TH", R.string.TH);\r
isoCodeToResourceId.put("BO", R.string.BO);\r
isoCodeToResourceId.put("YI", R.string.YI);\r
isoCodeToResourceId.put("ZU", R.string.ZU);\r
\r
+ \r
// Hack to allow lower-case ISO codes to work:\r
for (final String isoCode : new ArrayList<String>(isoCodeToResourceId.keySet())) {\r
isoCodeToResourceId.put(isoCode.toLowerCase(), isoCodeToResourceId.get(isoCode));\r
}\r
+\r
}\r
\r
\r
package com.hughes.android.util;
-import android.app.Activity;
+import android.content.Context;
import android.content.Intent;
+import android.view.View;
+import android.view.View.OnClickListener;
-public class IntentLauncher {
+public class IntentLauncher implements OnClickListener {
+ final Context context;
final Intent intent;
- final Activity activity;
- private IntentLauncher(final Intent intent, final Activity activity) {
+ public IntentLauncher(final Context context, final Intent intent) {
+ this.context = context;
this.intent = intent;
- this.activity = activity;
}
-
+
+ protected void onGo() {
+ }
+
+
private void go() {
- if (activity != null) {
- activity.finish();
- }
- activity.startActivity(intent);
+ onGo();
+ context.startActivity(intent);
+ }
+
+ @Override
+ public void onClick(View v) {
+ go();
}
+++ /dev/null
-* multi word search
-* link to leo, dict.cc
-* source in context menu
-* quiz
-* colorize things
-
-
-done:
-* sorting of entries
-* better Row/Entry classes?
-* wiktionary
-* better tokenization?
-* publish 2.0 dictionary
-* test email
-* dict manager