]> gitweb.fperrin.net Git - Dictionary.git/commitdiff
go
authorThad Hughes <thad.hughes@gmail.com>
Sat, 19 Feb 2011 19:50:27 +0000 (11:50 -0800)
committerThad Hughes <thad.hughes@gmail.com>
Sat, 19 Feb 2011 19:50:27 +0000 (11:50 -0800)
12 files changed:
AndroidManifest.xml
res/values-de/strings.xml
res/values/strings.xml
src/com/hughes/android/dictionary/DictionaryActivity.java
src/com/hughes/android/dictionary/engine/EntrySource.java
src/com/hughes/android/dictionary/engine/EntryTypeName.java
src/com/hughes/android/dictionary/engine/Index.java
src/com/hughes/android/dictionary/engine/Language.java
src/com/hughes/android/dictionary/engine/PairEntry.java
src/com/hughes/android/dictionary/engine/RowBase.java
src/com/hughes/android/dictionary/engine/TokenRow.java
src/com/hughes/android/dictionary/engine/TransliteratorManager.java [new file with mode: 0644]

index 644efd27aa137698087d5d4782858857486df3fb..091a0b092584ac86f37e427b76194fbec4654f46 100644 (file)
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.hughes.android.dictionary" android:versionCode="9"
+ package="com.hughes.android.dictionary"
+ android:versionCode="9"
  android:versionName="2.0"
  android:installLocation="auto">
 
index a9b4a7afed9fdf3101996409fc8a6f3bed27cdcc..dd4f3560451bf31d31852f323c94d8924431eb4a 100755 (executable)
        <string name="contactMe">Wenn QuickDic dir gefällt, würde ich gern von dir hören.  Bitte schicke Bemerkungen, Aufforderungen, oder Programmfehler an:</string>
        <string name="currentDictInfo">Wörterbuch Info:</string>
        <string name="noDictLoaded">Kein Wörterbuch geöffnet.</string>
-  <string name="aboutText"><![CDATA[%s\n
-\n
-Einträgezahl: %d\n
-%s:\n
-  Wörterzahl: %d\n
-  Reihezahl: %d\n
-%s:\n
-  Wörterzahl: %d\n
-  Reihezahl: %d\n
-]]></string>
        
        <!-- Download. -->
-       <string name="downloading">%d von %d Bytes heruntergeladen...</string>
+       <string name="downloading">%1$d von %2$d Bytes heruntergeladen...</string>
        <string name="downloadFinished">Herunterladen fertig, %d Bytes heruntergeladen.</string>
        <string name="errorDownloadingFile">"Fehler während des Herunterladens: \n%s"</string>
 
index 4f69aab5253e0b7910d0fa7122d07de47735b613..03d9cc57b9df6fccfc58f51a52f522610f05dc9f 100644 (file)
@@ -38,7 +38,7 @@
   <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=%s, error=%s</string>
+  <string name="invalidDictionary">Invalid dictionary: file=%1$s, error=%2$s</string>
   <string name="numPairEntries">Entries: %d</string>
   <string name="numTokens">Tokens: %d</string>
   <string name="numRows">Rows: %d</string>
@@ -62,7 +62,7 @@
   <string name="webPageUrl">http://sites.google.com/site/quickdic/home</string>
  
        <!-- Download. -->
-       <string name="downloading">Downloading, %d of %d bytes.</string>
+       <string name="downloading">Downloading, %1$d of %2$d bytes.</string>
        <string name="downloadFinished">Download finished, %d bytes downloaded.</string>
        <string name="errorDownloadingFile">"Error downloading file: \n%s"</string>
 
index 5e251b7f234cc1c207fa9f1c79f3b591d808a04f..10b3cf6dc42be147f56b14e37f6376b24f3013ac 100644 (file)
@@ -9,6 +9,7 @@ import java.text.SimpleDateFormat;
 import java.util.Date;\r
 import java.util.concurrent.Executor;\r
 import java.util.concurrent.Executors;\r
+import java.util.concurrent.ThreadFactory;\r
 import java.util.concurrent.atomic.AtomicBoolean;\r
 \r
 import android.app.ListActivity;\r
@@ -50,8 +51,10 @@ import android.widget.Toast;
 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.PairEntry.Pair;\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.PersistentObjectCache;\r
 \r
 public class DictionaryActivity extends ListActivity {\r
@@ -68,7 +71,12 @@ public class DictionaryActivity extends ListActivity {
   \r
   // package for test.\r
   final Handler uiHandler = new Handler();\r
-  private final Executor searchExecutor = Executors.newSingleThreadExecutor();\r
+  private final Executor searchExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {\r
+    @Override\r
+    public Thread newThread(Runnable r) {\r
+      return new Thread(r, "searchExecutor");\r
+    }\r
+  });\r
   private SearchOperation currentSearchOperation = null;\r
 \r
   EditText searchText;\r
@@ -116,6 +124,7 @@ public class DictionaryActivity extends ListActivity {
   @Override\r
   public void onCreate(Bundle savedInstanceState) {\r
     super.onCreate(savedInstanceState);\r
+    Log.d(LOG, "onCreate:" + this);\r
     \r
     final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);\r
     \r
@@ -143,14 +152,32 @@ public class DictionaryActivity extends ListActivity {
       return;\r
     }\r
 \r
+    indexIndex = prefs.getInt(C.INDEX_INDEX, 0) % dictionary.indices.size();\r
+    Log.d(LOG, "Loading index.");\r
+    index = dictionary.indices.get(indexIndex);\r
+    setListAdapter(new IndexAdapter(index));\r
+\r
     // Pre-load the collators.\r
     searchExecutor.execute(new Runnable() {\r
       public void run() {\r
         final long startMillis = System.currentTimeMillis();\r
-        Log.d(LOG, "Constructing index for lang=" + index.sortLanguage.getSymbol());\r
+        \r
+        TransliteratorManager.init(new TransliteratorManager.Callback() {\r
+          @Override\r
+          public void onTransliteratorReady() {\r
+            uiHandler.post(new Runnable() {\r
+              @Override\r
+              public void run() {\r
+                onSearchTextChange(searchText.getText().toString());\r
+              }\r
+            });\r
+          }\r
+        });\r
+        \r
         for (final Index index : dictionary.indices) {\r
           Log.d(LOG, "Starting collator load for lang=" + index.sortLanguage.getSymbol());\r
-          final com.ibm.icu.text.Collator c = index.sortLanguage.getCollator();\r
+          \r
+          final com.ibm.icu.text.Collator c = index.sortLanguage.getCollator();          \r
           if (c.compare("pre-print", "preppy") >= 0) {\r
             Log.e(LOG, c.getClass()\r
                 + " is buggy, lookups may not work properly.");\r
@@ -161,10 +188,7 @@ public class DictionaryActivity extends ListActivity {
       }\r
     });\r
     \r
-    indexIndex = prefs.getInt(C.INDEX_INDEX, 0) % dictionary.indices.size();\r
-    index = dictionary.indices.get(indexIndex);\r
-    setListAdapter(new IndexAdapter(index));\r
-    \r
+\r
     setContentView(R.layout.dictionary_activity);\r
     searchText = (EditText) findViewById(R.id.SearchText);\r
     langButton = (Button) findViewById(R.id.LangButton);\r
@@ -212,6 +236,7 @@ public class DictionaryActivity extends ListActivity {
         if (!searchText.isFocused()) {\r
           // TODO: don't do this if multi words are entered.\r
           final RowBase row = (RowBase) getListAdapter().getItem(position);\r
+          Log.d(LOG, "onItemSelected: " + row.index());\r
           final TokenRow tokenRow = row.getTokenRow(true);\r
           searchText.setText(tokenRow.getToken());\r
         }\r
@@ -312,7 +337,7 @@ public class DictionaryActivity extends ListActivity {
     searchText.removeTextChangedListener(searchTextWatcher);\r
     searchText.setText(dest.token);\r
     jumpToRow(index.sortedIndexEntries.get(destIndexEntry).startRow);\r
-    searchText.removeTextChangedListener(searchTextWatcher);\r
+    searchText.addTextChangedListener(searchTextWatcher);\r
   }\r
 \r
   // --------------------------------------------------------------------------\r
@@ -454,7 +479,18 @@ public class DictionaryActivity extends ListActivity {
     final Index.IndexEntry searchResult = searchOperation.searchResult;\r
     Log.d(LOG, "searchFinished: " + searchOperation + ", searchResult=" + searchResult);\r
 \r
-    jumpToRow(searchResult.startRow);\r
+    currentSearchOperation = null;\r
+\r
+    uiHandler.postDelayed(new Runnable() {\r
+      @Override\r
+      public void run() {\r
+        if (currentSearchOperation == null) {\r
+          jumpToRow(searchResult.startRow);\r
+        } else {\r
+          Log.d(LOG, "More coming, waiting for currentSearchOperation.");\r
+        }\r
+      }\r
+    }, 50);\r
     \r
 //    if (!searchResult.success) {\r
 //      if (vibrator != null) {\r
@@ -464,6 +500,7 @@ public class DictionaryActivity extends ListActivity {
 //      searchText.setSelection(searchResult.longestPrefixString.length());\r
 //      return;\r
 //    }\r
+    \r
   }\r
   \r
   private final void jumpToRow(final int row) {\r
@@ -551,7 +588,7 @@ public class DictionaryActivity extends ListActivity {
     private View getView(PairEntry.Row row, ViewGroup parent) {\r
       final TableLayout result = new TableLayout(parent.getContext());\r
       final PairEntry entry = row.getEntry();\r
-      final int rowCount = entry.pairs.length;\r
+      final int rowCount = entry.pairs.size();\r
       for (int r = 0; r < rowCount; ++r) {\r
         final TableRow tableRow = new TableRow(result.getContext());\r
 \r
@@ -577,7 +614,8 @@ public class DictionaryActivity extends ListActivity {
         column2.setWidth(1);\r
 \r
         // TODO: color words by gender\r
-        final String col1Text = index.swapPairEntries ? entry.pairs[r].lang2 : entry.pairs[r].lang1;\r
+        final Pair pair = entry.pairs.get(r);\r
+        final String col1Text = index.swapPairEntries ? pair.lang2 : pair.lang1;\r
         column1.setText(col1Text, TextView.BufferType.SPANNABLE);\r
         final Spannable col1Spannable = (Spannable) column1.getText();\r
         \r
@@ -589,7 +627,7 @@ public class DictionaryActivity extends ListActivity {
           startPos += token.length();\r
         }\r
 \r
-        final String col2Text = index.swapPairEntries ? entry.pairs[r].lang1 : entry.pairs[r].lang2;\r
+        final String col2Text = index.swapPairEntries ? pair.lang1 : pair.lang2;\r
         column2.setText(col2Text, TextView.BufferType.NORMAL);\r
 \r
         result.addView(tableRow);\r
index 391e8cec218b89a29900eb29ba39ea6b351be307..bded4d5aa04a1d956f9de1993af5badcbd467cda 100644 (file)
@@ -12,10 +12,12 @@ public class EntrySource extends IndexedObject implements Serializable {
   private static final long serialVersionUID = -1323165134846120269L;
   
   final String name;
+  final int pairEntryStart;
   
-  public EntrySource(final int index, final String name) {
+  public EntrySource(final int index, final String name, final int pairEntryStart) {
     super(index);
     this.name = name;
+    this.pairEntryStart = pairEntryStart;
   }
   
   @Override
@@ -30,12 +32,14 @@ public class EntrySource extends IndexedObject implements Serializable {
     public EntrySource read(RandomAccessFile raf, int readIndex)
         throws IOException {
       final String name = raf.readUTF();
-      return new EntrySource(readIndex, name);
+      final int pairEntryStart = raf.readInt();
+      return new EntrySource(readIndex, name, pairEntryStart);
     }
 
     @Override
     public void write(RandomAccessFile raf, EntrySource t) throws IOException {
       raf.writeUTF(t.name);
+      raf.writeInt(t.pairEntryStart);
     }    
   };
   
index c65db05bcf104249a0d611bd54e3e0dff6d77382..409b6369f44c874f16721a6624256700b89a9553 100644 (file)
@@ -16,6 +16,7 @@ public enum EntryTypeName {
   MULTIROW_TAIL_ONE_WORD(0),
 
   WIKTIONARY_TITLE_MULTI_WORD(0),
+  WIKTIONARY_PRONUNCIATION(0),
   WIKTIONARY_MEANING_MULTI_WORD(0),
   WIKTIONARY_FORM_OF(0),
   WIKTIONARY_EXAMPLE_HEADWORDS(0),
index d0d2404a02bba315ed6b7fc65bdedc4e600b7de2..f05c0dc772dfe54f0f4d62e923e6475c04b5e140 100644 (file)
@@ -33,7 +33,7 @@ public final class Index implements RAFSerializable<Index> {
   final String normalizerRules;
   
   // Built from the two above.
-  final Transliterator normalizer;
+  private Transliterator normalizer;
     
   // persisted
   public final List<IndexEntry> sortedIndexEntries;
@@ -57,7 +57,14 @@ public final class Index implements RAFSerializable<Index> {
     sortedIndexEntries = new ArrayList<IndexEntry>();
     rows = new ArrayList<RowBase>();
     
-    normalizer = Transliterator.createFromRules("", normalizerRules, Transliterator.FORWARD);
+    normalizer = null;
+  }
+  
+  public synchronized Transliterator normalizer() {
+    if (normalizer == null) {
+      normalizer = Transliterator.createFromRules("", normalizerRules, Transliterator.FORWARD);
+    }
+    return normalizer;
   }
   
   public Index(final Dictionary dict, final RandomAccessFile raf) throws IOException {
@@ -73,8 +80,6 @@ public final class Index implements RAFSerializable<Index> {
     }
     sortedIndexEntries = CachingList.create(RAFList.create(raf, IndexEntry.SERIALIZER, raf.getFilePointer()), CACHE_SIZE);
     rows = CachingList.create(UniformRAFList.create(raf, new RowBase.Serializer(this), raf.getFilePointer()), CACHE_SIZE);
-
-    normalizer = Transliterator.createFromRules("", normalizerRules, Transliterator.FORWARD);
   }
   
   @Override
@@ -96,10 +101,10 @@ public final class Index implements RAFSerializable<Index> {
   
   public static final class IndexEntry implements RAFSerializable<Index.IndexEntry> {
     public final String token;
+    private final String normalizedToken;
     public final int startRow;
     public final int numRows;
     
-    private String normalizedToken;
     
     static final RAFSerializer<IndexEntry> SERIALIZER = new RAFSerializer<IndexEntry> () {
       @Override
@@ -111,10 +116,11 @@ public final class Index implements RAFSerializable<Index> {
         t.write(raf);
       }};
       
-    public IndexEntry(final String token, final int startRow, final int numRows) {
+    public IndexEntry(final String token, final String normalizedToken, final int startRow, final int numRows) {
       assert token.equals(token.trim());
       assert token.length() > 0;
       this.token = token;
+      this.normalizedToken = normalizedToken;
       this.startRow = startRow;
       this.numRows = numRows;
     }
@@ -123,28 +129,35 @@ public final class Index implements RAFSerializable<Index> {
       token = raf.readUTF();
       startRow = raf.readInt();
       numRows = raf.readInt();
+      final boolean hasNormalizedForm = raf.readBoolean();
+      normalizedToken = hasNormalizedForm ? raf.readUTF() : token;
     }
     
     public void write(RandomAccessFile raf) throws IOException {
       raf.writeUTF(token);
       raf.writeInt(startRow);
       raf.writeInt(numRows);
+      final boolean hasNormalizedForm = !token.equals(normalizedToken);
+      raf.writeBoolean(hasNormalizedForm);
+      if (hasNormalizedForm) {
+        raf.writeUTF(normalizedToken);
+      }
     }
 
     public String toString() {
       return String.format("%s@%d(%d)", token, startRow, numRows);
     }
 
-    public synchronized String normalizedToken(final Transliterator normalizer) {
-      if (normalizedToken == null) {
-        normalizedToken = normalizer.transform(token);
-      }
+    public String normalizedToken() {
       return normalizedToken;
     }
   }
   
   public IndexEntry findInsertionPoint(String token, final AtomicBoolean interrupted) {
-    token = normalizer.transliterate(token);
+    final Transliterator normalizer = normalizer();
+    if (TransliteratorManager.init(null)) {
+      token = normalizer.transliterate(token);
+    }
 
     int start = 0;
     int end = sortedIndexEntries.size();
@@ -157,22 +170,22 @@ public final class Index implements RAFSerializable<Index> {
       }
       final IndexEntry midEntry = sortedIndexEntries.get(mid);
 
-      final int comp = sortCollator.compare(token, midEntry.normalizedToken(normalizer));
+      final int comp = sortCollator.compare(token, midEntry.normalizedToken());
       if (comp == 0) {
         final int result = windBackCase(token, mid, interrupted);
         return sortedIndexEntries.get(result);
       } else if (comp < 0) {
-        System.out.println("Upper bound: " + midEntry + ", norm=" + midEntry.normalizedToken(normalizer) + ", mid=" + mid);
+        //System.out.println("Upper bound: " + midEntry + ", norm=" + midEntry.normalizedToken() + ", mid=" + mid);
         end = mid;
       } else {
-        System.out.println("Lower bound: " + midEntry + ", norm=" + midEntry.normalizedToken(normalizer) + ", mid=" + mid);
+        //System.out.println("Lower bound: " + midEntry + ", norm=" + midEntry.normalizedToken() + ", mid=" + mid);
         start = mid + 1;
       }
     }
 
     // If we search for a substring of a string that's in there, return that.
     int result = Math.min(start, sortedIndexEntries.size() - 1);
-    result = windBackCase(sortedIndexEntries.get(result).normalizedToken(normalizer), result, interrupted);
+    result = windBackCase(sortedIndexEntries.get(result).normalizedToken(), result, interrupted);
     return sortedIndexEntries.get(result);
   }
   
@@ -222,7 +235,7 @@ public final class Index implements RAFSerializable<Index> {
 //  }
   
   private final int windBackCase(final String token, int result, final AtomicBoolean interrupted) {
-    while (result > 0 && sortedIndexEntries.get(result - 1).normalizedToken(normalizer).equals(token)) {
+    while (result > 0 && sortedIndexEntries.get(result - 1).normalizedToken().equals(token)) {
       --result;
       if (interrupted.get()) {
         return result;
index 42ad7b60c43b758399db8a4e59a95de773ea6578..cc1c3325c972beeebc31ce1171c9c84c5433df66 100755 (executable)
@@ -13,13 +13,11 @@ public class Language {
   final String symbol;\r
   final Locale locale;\r
   \r
-  final Collator collator;\r
+  private Collator collator;\r
 \r
   public Language(final Locale locale) {\r
     this.symbol = locale.getLanguage();\r
     this.locale = locale;\r
-    this.collator = Collator.getInstance(locale);\r
-    this.collator.setStrength(Collator.IDENTICAL);\r
 \r
     symbolToLangauge.put(symbol.toLowerCase(), this);\r
   }\r
@@ -33,7 +31,11 @@ public class Language {
     return symbol;\r
   }\r
   \r
-  public Collator getCollator() {\r
+  public synchronized Collator getCollator() {\r
+    if (collator == null) {\r
+      this.collator = Collator.getInstance(locale);\r
+      this.collator.setStrength(Collator.IDENTICAL);\r
+    }\r
     return collator;\r
   }\r
   \r
@@ -53,18 +55,14 @@ public class Language {
     }\r
   };\r
   \r
-  static {\r
-    for (final String lang : Locale.getISOLanguages()) {\r
-      if (lookup(lang) == null) {\r
-        new Language(new Locale(lang));\r
-      }\r
-    }\r
-  }\r
-\r
   // ----------------------------------------------------------------\r
 \r
-  public static Language lookup(final String symbol) {\r
-    return symbolToLangauge.get(symbol.toLowerCase());\r
+  public static synchronized Language lookup(final String symbol) {\r
+    Language lang = symbolToLangauge.get(symbol.toLowerCase());\r
+    if (lang == null) {\r
+      lang = new Language(new Locale(symbol));\r
+    }\r
+    return lang;\r
   }\r
 \r
 }\r
index 5406ed5b2468ff9d9393c79ea738e0e36a953fd4..9160ac0ca05d55593906981dafaefffe5965ce33 100644 (file)
@@ -3,68 +3,39 @@ package com.hughes.android.dictionary.engine;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.io.RandomAccessFile;
+import java.util.ArrayList;
+import java.util.List;
 
 import com.hughes.util.raf.RAFSerializable;
 import com.hughes.util.raf.RAFSerializer;
 
 public class PairEntry extends Entry implements RAFSerializable<PairEntry>, Comparable<PairEntry> {
   
-  public static final class Pair {
-    
-    public final String lang1;
-    public final String lang2;
-    
-    public Pair(final String lang1, final String lang2) {
-      this.lang1 = lang1;
-      this.lang2 = lang2;
-    }
+  public final List<Pair> pairs;
 
-    public Pair(final String lang1, final String lang2, final boolean swap) {
-      this(swap ? lang2 : lang1, swap ? lang1 : lang2);
-    }
-
-    public String toString() {
-      return lang1 + " :: " + lang2;
-    }
-
-    public String toStringTab() {
-      return lang1 + "\t" + lang2;
-    }
-
-    public String get(int i) {
-      if (i == 0) {
-        return lang1;
-      } else if (i == 1) {
-        return lang2;
-      }
-      throw new IllegalArgumentException();
-    }
-
-  }
-  
-  public final Pair[] pairs;
-  
-  public PairEntry(final Pair[] pairs) {
-    this.pairs = pairs;
+  public PairEntry() {
+    pairs = new ArrayList<Pair>(1);
   }
-  
+
   public PairEntry(final String lang1, final String lang2) {
-    this.pairs = new Pair[] { new Pair(lang1, lang2) };
+    pairs = new ArrayList<Pair>(1);
+    this.pairs.add(new Pair(lang1, lang2));
   }
   
   public PairEntry(final RandomAccessFile raf) throws IOException {
-    pairs = new Pair[raf.readInt()];
-    for (int i = 0; i < pairs.length; ++i) {
-      pairs[i] = new Pair(raf.readUTF(), raf.readUTF());
+    final int size = raf.readInt();
+    pairs = new ArrayList<PairEntry.Pair>(size);
+    for (int i = 0; i < size; ++i) {
+      pairs.add(new Pair(raf.readUTF(), raf.readUTF()));
     }
   }
   @Override
   public void write(RandomAccessFile raf) throws IOException {
     // TODO: this could be a short.
-    raf.writeInt(pairs.length);
-    for (int i = 0; i < pairs.length; ++i) {
-      raf.writeUTF(pairs[i].lang1);
-      raf.writeUTF(pairs[i].lang2);
+    raf.writeInt(pairs.size());
+    for (int i = 0; i < pairs.size(); ++i) {
+      raf.writeUTF(pairs.get(i).lang1);
+      raf.writeUTF(pairs.get(i).lang2);
     }
   }
   
@@ -100,8 +71,8 @@ public class PairEntry extends Entry implements RAFSerializable<PairEntry>, Comp
     @Override
     public void print(PrintStream out) {
       final PairEntry pairEntry = getEntry();
-      for (int i = 0; i < pairEntry.pairs.length; ++i) {
-        out.print((i == 0 ? "  " : "    ") + pairEntry.pairs[i]);
+      for (int i = 0; i < pairEntry.pairs.size(); ++i) {
+        out.print((i == 0 ? "  " : "    ") + pairEntry.pairs.get(i));
         out.println();
       }
     }
@@ -116,21 +87,21 @@ public class PairEntry extends Entry implements RAFSerializable<PairEntry>, Comp
 
   public String getRawText(final boolean compact) {
     if (compact) {
-      return this.pairs[0].toStringTab();
+      return this.pairs.get(0).toStringTab();
     }
     final StringBuilder builder = new StringBuilder();
-    for (int i = 0; i < this.pairs.length; ++i) {
+    for (int i = 0; i < this.pairs.size(); ++i) {
       if (i > 0) {
         builder.append(" | ");
       }
-      builder.append(this.pairs[i].lang1);
+      builder.append(this.pairs.get(i).lang1);
     }
     builder.append("\t");
-    for (int i = 0; i < this.pairs.length; ++i) {
+    for (int i = 0; i < this.pairs.size(); ++i) {
       if (i > 0) {
         builder.append(" | ");
       }
-      builder.append(this.pairs[i].lang2);
+      builder.append(this.pairs.get(i).lang2);
     }
     return builder.toString();
   }
@@ -144,6 +115,42 @@ public class PairEntry extends Entry implements RAFSerializable<PairEntry>, Comp
   public String toString() {
     return getRawText(false);
   }
+
+  // -----------------------------------------------------------------------
+  
+  public static final class Pair {
+    
+    public final String lang1;
+    public final String lang2;
+    
+    public Pair(final String lang1, final String lang2) {
+      this.lang1 = lang1;
+      this.lang2 = lang2;
+      //assert lang1.trim().length() > 0 || lang2.trim().length() > 0 : "Empty pair!!!";
+    }
+
+    public Pair(final String lang1, final String lang2, final boolean swap) {
+      this(swap ? lang2 : lang1, swap ? lang1 : lang2);
+    }
+
+    public String toString() {
+      return lang1 + " :: " + lang2;
+    }
+
+    public String toStringTab() {
+      return lang1 + "\t" + lang2;
+    }
+
+    public String get(int i) {
+      if (i == 0) {
+        return lang1;
+      } else if (i == 1) {
+        return lang2;
+      }
+      throw new IllegalArgumentException();
+    }
+
+  }
   
 
 }
index 7ac86d0bc9e502dd59ba840891a2822937ea5d80..9104398bdf1675f806d17ae47a52d3ab7b4ab395 100644 (file)
@@ -53,8 +53,13 @@ public abstract class RowBase extends IndexedObject {
         }
         if (rUp < index.rows.size()) {
           final RowBase rowUp = index.rows.get(rUp);
-          final TokenRow candidateUp = rowUp.getTokenRow(false);
+          TokenRow candidateUp = rowUp.getTokenRow(false);
           if (candidateUp != null) {
+            // Did we hit the next set of TokenRows?
+            if (candidateUp.index() > this.index()) {  
+              final int tokenIndex = index.sortedIndexEntries.get(candidateUp.referenceIndex - 1).startRow;
+              candidateUp = (TokenRow) index.rows.get(tokenIndex);
+            }
             for (--rUp; rUp >= index(); --rUp) {
               index.rows.get(rUp).setTokenRow(candidateUp);
             }
index e40d124b5e7800b3d80722bfea4ae076c939169c..a47de2f293aab76b0e127940ae5343da35452a67 100644 (file)
@@ -34,7 +34,7 @@ public class TokenRow extends RowBase {
 
   @Override
   public void print(final PrintStream out) {
-    out.println(getToken());
+    out.println("===" + getToken() + "===");
   }
 
   @Override
diff --git a/src/com/hughes/android/dictionary/engine/TransliteratorManager.java b/src/com/hughes/android/dictionary/engine/TransliteratorManager.java
new file mode 100644 (file)
index 0000000..50a7ca6
--- /dev/null
@@ -0,0 +1,58 @@
+package com.hughes.android.dictionary.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.util.Log;
+
+import com.ibm.icu.text.Transliterator;
+
+public class TransliteratorManager {
+
+  private static boolean starting = false;
+  private static boolean ready = false;
+  
+  private static List<Callback> callbacks = new ArrayList<TransliteratorManager.Callback>();
+  
+  public static synchronized boolean init(final Callback callback) {
+    if (ready) {
+      return true;
+    }
+    if (callback != null) {
+      callbacks.add(callback);
+    }
+    if (!starting) {
+      starting = true;
+      new Thread(init).start();
+    }
+    return false;
+  }
+  
+  private static final Runnable init = new Runnable() {
+    @Override
+    public void run() {
+      System.out.println("Starting Transliterator load.");
+      final String transliterated = 
+        Transliterator.createFromRules("", ":: Any-Latin; :: Lower; :: NFD; :: [:Nonspacing Mark:] Remove; :: NFC ;", 
+            Transliterator.FORWARD).transliterate("Îñţérñåţîöñåļîžåţîờñ");
+      if (!"internationalization".equals(transliterated)) {
+        System.out.println("Wrong transliteratation: " + transliterated);
+      }
+
+      final List<Callback> callbacks = new ArrayList<TransliteratorManager.Callback>();
+      synchronized (TransliteratorManager.class) {
+        callbacks.addAll(TransliteratorManager.callbacks);
+        ready = true;
+      }
+      for (final Callback callback : callbacks) {
+        callback.onTransliteratorReady();
+      }
+    }
+  };
+  
+  
+  public interface Callback {
+    void onTransliteratorReady();
+  }
+
+}