]> gitweb.fperrin.net Git - Dictionary.git/commitdiff
Support opening .quickdic files from file manager.
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>
Sun, 20 Aug 2017 12:38:49 +0000 (14:38 +0200)
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>
Sun, 20 Aug 2017 12:38:49 +0000 (14:38 +0200)
AndroidManifest.xml
Util
src/com/hughes/android/dictionary/DictionaryActivity.java
src/com/hughes/android/dictionary/engine/Dictionary.java
src/com/hughes/android/dictionary/engine/Index.java

index a94fcfe86446fe5312352ba0876f8cefd7aa46f7..945d192034d91cbfba72a2411f72a0d6b82fb535 100644 (file)
 
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="content"
+                      android:host="*"
+                      android:mimeType="application/octet-stream"
+                      android:pathPattern=".*\\.quickdic" />
+                <data android:scheme="file"
+                      android:host="*"
+                      android:mimeType="application/octet-stream"
+                      android:pathPattern=".*\\.quickdic" />
+                <data android:scheme="content"
+                      android:host="*"
+                      android:pathPattern=".*\\.quickdic" />
+                <data android:scheme="file"
+                      android:host="*"
+                      android:pathPattern=".*\\.quickdic" />
+            </intent-filter>
         </activity>
         <activity
             android:name=".AboutActivity"
diff --git a/Util b/Util
index 819e981b344df2aac43dfee495ef4ea2fc73c03a..1f1b243cb81d95167abba1c9005d7ae61f6d70fe 160000 (submodule)
--- a/Util
+++ b/Util
@@ -1 +1 @@
-Subproject commit 819e981b344df2aac43dfee495ef4ea2fc73c03a
+Subproject commit 1f1b243cb81d95167abba1c9005d7ae61f6d70fe
index c4d2ddae81a926ede0ede7237abe1c3a953823e1..b5451a79d1d561c85b3dac2a404b420997761540 100644 (file)
@@ -99,6 +99,7 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
 import java.text.SimpleDateFormat;
 import java.util.Arrays;
 import java.util.Collections;
@@ -124,7 +125,8 @@ public class DictionaryActivity extends ActionBarActivity {
     DictionaryApplication application;
 
     File dictFile = null;
-    RandomAccessFile dictRaf = null;
+    FileChannel dictRaf = null;
+    String dictFileTitleName = null;
 
     Dictionary dictionary = null;
 
@@ -224,6 +226,22 @@ public class DictionaryActivity extends ActionBarActivity {
         return search.length();
     }
 
+    private void dictionaryOpenFail(Exception e) {
+        Log.e(LOG, "Unable to load dictionary.", e);
+        if (dictRaf != null) {
+            try {
+                dictRaf.close();
+            } catch (IOException e1) {
+                Log.e(LOG, "Unable to close dictRaf.", e1);
+            }
+            dictRaf = null;
+        }
+        Toast.makeText(this, getString(R.string.invalidDictionary, "", e.getMessage()),
+                       Toast.LENGTH_LONG).show();
+        startActivity(DictionaryManagerActivity.getLaunchIntent(getApplicationContext()));
+        finish();
+    }
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         DictionaryApplication.INSTANCE.init(getApplicationContext());
@@ -246,6 +264,15 @@ public class DictionaryActivity extends ActionBarActivity {
         theme = application.getSelectedTheme();
         textColorFg = getResources().getColor(theme.tokenRowFgColor);
 
+        if (dictRaf != null) {
+            try {
+                dictRaf.close();
+            } catch (IOException e) {
+                Log.e(LOG, "Failed to close dictionary", e);
+            }
+            dictRaf = null;
+        }
+
         final Intent intent = getIntent();
         String intentAction = intent.getAction();
         /**
@@ -322,6 +349,18 @@ public class DictionaryActivity extends ActionBarActivity {
                 getIntent().putExtra(C.SEARCH_TOKEN, query);
             }
         }
+        // Support opening dictionary file directly
+        if (intentAction != null && intentAction.equals(Intent.ACTION_VIEW)) {
+            Uri uri = intent.getData();
+            intent.putExtra(C.DICT_FILE, uri.toString());
+            dictFileTitleName = uri.getLastPathSegment();
+            try {
+                dictRaf = getContentResolver().openAssetFileDescriptor(uri, "r").createInputStream().getChannel();
+            } catch (Exception e) {
+                dictionaryOpenFail(e);
+                return;
+            }
+        }
         /**
          * @author Dominik Köppl If no dictionary is chosen, use the default
          *         dictionary specified in the preferences If this step does
@@ -345,7 +384,7 @@ public class DictionaryActivity extends ActionBarActivity {
                 try {
                     Log.d(LOG, "Checking dictionary " + dics.get(i).uncompressedFilename);
                     final File dictfile = application.getPath(dics.get(i).uncompressedFilename);
-                    Dictionary dic = new Dictionary(new RandomAccessFile(dictfile, "r"));
+                    Dictionary dic = new Dictionary(new RandomAccessFile(dictfile, "r").getChannel());
                     for (int j = 0; j < dic.indices.size(); ++j) {
                         Index idx = dic.indices.get(j);
                         Log.d(LOG, "Checking index " + idx.shortName);
@@ -377,7 +416,7 @@ public class DictionaryActivity extends ActionBarActivity {
             finish();
             return;
         }
-        if (dictFilename != null)
+        if (dictRaf == null && dictFilename != null)
             dictFile = new File(dictFilename);
 
         ttsReady = false;
@@ -390,24 +429,14 @@ public class DictionaryActivity extends ActionBarActivity {
         });
 
         try {
-            final String name = application.getDictionaryName(dictFile.getName());
-            this.setTitle("QuickDic: " + name);
-            dictRaf = new RandomAccessFile(dictFile, "r");
+            if (dictRaf == null) {
+                dictFileTitleName = application.getDictionaryName(dictFile.getName());
+                dictRaf = new RandomAccessFile(dictFile, "r").getChannel();
+            }
+            this.setTitle("QuickDic: " + dictFileTitleName);
             dictionary = new Dictionary(dictRaf);
         } catch (Exception e) {
-            Log.e(LOG, "Unable to load dictionary.", e);
-            if (dictRaf != null) {
-                try {
-                    dictRaf.close();
-                } catch (IOException e1) {
-                    Log.e(LOG, "Unable to close dictRaf.", e1);
-                }
-                dictRaf = null;
-            }
-            Toast.makeText(this, getString(R.string.invalidDictionary, "", e.getMessage()),
-                           Toast.LENGTH_LONG).show();
-            startActivity(DictionaryManagerActivity.getLaunchIntent(getApplicationContext()));
-            finish();
+            dictionaryOpenFail(e);
             return;
         }
         String targetIndex = intent.getStringExtra(C.INDEX_SHORT_NAME);
@@ -652,8 +681,10 @@ public class DictionaryActivity extends ActionBarActivity {
                                            final String indexShortName, final String searchToken) {
         final SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(
                 context).edit();
-        prefs.putString(C.DICT_FILE, dictFile.getPath());
-        prefs.putString(C.INDEX_SHORT_NAME, indexShortName);
+        if (dictFile != null) {
+            prefs.putString(C.DICT_FILE, dictFile.getPath());
+            prefs.putString(C.INDEX_SHORT_NAME, indexShortName);
+        }
         prefs.putString(C.SEARCH_TOKEN, ""); // Don't need to save search token.
         prefs.commit();
     }
@@ -961,16 +992,20 @@ public class DictionaryActivity extends ActionBarActivity {
                     dialog.setContentView(R.layout.about_dictionary_dialog);
                     final TextView textView = (TextView) dialog.findViewById(R.id.text);
 
-                    final String name = application.getDictionaryName(dictFile.getName());
-                    dialog.setTitle(name);
+                    dialog.setTitle(dictFileTitleName);
 
                     final StringBuilder builder = new StringBuilder();
                     final DictionaryInfo dictionaryInfo = dictionary.getDictionaryInfo();
-                    dictionaryInfo.uncompressedBytes = dictFile.length();
                     if (dictionaryInfo != null) {
+                        try {
+                            dictionaryInfo.uncompressedBytes = dictRaf.size();
+                        } catch (IOException e) {
+                        }
                         builder.append(dictionaryInfo.dictInfo).append("\n\n");
-                        builder.append(getString(R.string.dictionaryPath, dictFile.getPath()))
-                        .append("\n");
+                        if (dictFile != null) {
+                            builder.append(getString(R.string.dictionaryPath, dictFile.getPath()))
+                            .append("\n");
+                        }
                         builder.append(
                             getString(R.string.dictionarySize, dictionaryInfo.uncompressedBytes))
                         .append("\n");
index 2dba73d602e2f720da547124adf37c3a75e302cb..151bad6b66bfb781fa160c8c2cebe09cc6d935aa 100644 (file)
@@ -22,11 +22,14 @@ import com.hughes.util.raf.RAFListSerializer;
 import com.hughes.util.raf.RAFSerializable;
 
 import java.io.DataInput;
+import java.io.DataInputStream;
 import java.io.DataOutput;
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.io.RandomAccessFile;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -66,7 +69,8 @@ public class Dictionary implements RAFSerializable<Dictionary> {
         indices = new ArrayList<Index>();
     }
 
-    public Dictionary(final RandomAccessFile raf) throws IOException {
+    public Dictionary(final FileChannel ch) throws IOException {
+        DataInput raf = new DataInputStream(Channels.newInputStream(ch));
         dictFileVersion = raf.readInt();
         if (dictFileVersion < 0 || dictFileVersion > CURRENT_DICT_VERSION) {
             throw new IOException("Invalid dictionary version: " + dictFileVersion);
@@ -77,31 +81,31 @@ public class Dictionary implements RAFSerializable<Dictionary> {
         // Load the sources, then seek past them, because reading them later
         // disrupts the offset.
         try {
-            final RAFList<EntrySource> rafSources = RAFList.create(raf, new EntrySource.Serializer(
-                    this), raf.getFilePointer(), dictFileVersion, dictInfo + " sources: ");
+            final RAFList<EntrySource> rafSources = RAFList.create(ch, new EntrySource.Serializer(
+                    this), ch.position(), dictFileVersion, dictInfo + " sources: ");
             sources = new ArrayList<EntrySource>(rafSources);
-            raf.seek(rafSources.getEndOffset());
+            ch.position(rafSources.getEndOffset());
 
             pairEntries = CachingList.create(
-                              RAFList.create(raf, new PairEntry.Serializer(this), raf.getFilePointer(), dictFileVersion, dictInfo + " pairs: "),
+                              RAFList.create(ch, new PairEntry.Serializer(this), ch.position(), dictFileVersion, dictInfo + " pairs: "),
                               CACHE_SIZE);
             textEntries = CachingList.create(
-                              RAFList.create(raf, new TextEntry.Serializer(this), raf.getFilePointer(), dictFileVersion, dictInfo + " text: "),
+                              RAFList.create(ch, new TextEntry.Serializer(this), ch.position(), dictFileVersion, dictInfo + " text: "),
                               CACHE_SIZE);
             if (dictFileVersion >= 5) {
                 htmlEntries = CachingList.create(
-                                  RAFList.create(raf, new HtmlEntry.Serializer(this), raf.getFilePointer(), dictFileVersion, dictInfo + " html: "),
+                                  RAFList.create(ch, new HtmlEntry.Serializer(this), ch.position(), dictFileVersion, dictInfo + " html: "),
                                   CACHE_SIZE);
             } else {
                 htmlEntries = Collections.emptyList();
             }
             if (dictFileVersion >= 7) {
-                htmlData = RAFList.create(raf, new HtmlEntry.DataDeserializer(), raf.getFilePointer(), dictFileVersion, dictInfo + " html: ");
+                htmlData = RAFList.create(ch, new HtmlEntry.DataDeserializer(), ch.position(), dictFileVersion, dictInfo + " html: ");
             } else {
                 htmlData = null;
             }
-            indices = CachingList.createFullyCached(RAFList.create(raf, indexSerializer,
-                                                    raf.getFilePointer(), dictFileVersion, dictInfo + " index: "));
+            indices = CachingList.createFullyCached(RAFList.create(ch, new IndexSerializer(ch),
+                                                    ch.position(), dictFileVersion, dictInfo + " index: "));
         } catch (RuntimeException e) {
             final IOException ioe = new IOException("RuntimeException loading dictionary");
             ioe.initCause(e);
@@ -131,15 +135,21 @@ public class Dictionary implements RAFSerializable<Dictionary> {
         assert htmlData == null;
         RAFList.write(raf, htmlEntries, new HtmlEntry.DataSerializer(), 128, true);
         System.out.println("indices start: " + raf.getFilePointer());
-        RAFList.write(raf, indices, indexSerializer);
+        RAFList.write(raf, indices, new IndexSerializer(null));
         System.out.println("end: " + raf.getFilePointer());
         raf.writeUTF(END_OF_DICTIONARY);
     }
 
-    private final RAFListSerializer<Index> indexSerializer = new RAFListSerializer<Index>() {
+    private final class IndexSerializer implements RAFListSerializer<Index> {
+        private final FileChannel ch;
+
+        public IndexSerializer(FileChannel ch) {
+            this.ch = ch;
+        }
+
         @Override
         public Index read(DataInput raf, final int readIndex) throws IOException {
-            return new Index(Dictionary.this, raf);
+            return new Index(Dictionary.this, ch, raf);
         }
 
         @Override
@@ -187,7 +197,7 @@ public class Dictionary implements RAFSerializable<Dictionary> {
         RandomAccessFile raf = null;
         try {
             raf = new RandomAccessFile(file, "r");
-            final Dictionary dict = new Dictionary(raf);
+            final Dictionary dict = new Dictionary(raf.getChannel());
             final DictionaryInfo dictionaryInfo = dict.getDictionaryInfo();
             dictionaryInfo.uncompressedFilename = file.getName();
             dictionaryInfo.uncompressedBytes = file.length();
index 04691ff0c5ede6e8289c16949cec69b2bc54d1d4..c254d303dcdbe452829d3e9b8e7494538a4f09fc 100644 (file)
@@ -32,10 +32,13 @@ import com.hughes.util.raf.UniformRAFList;
 import com.ibm.icu.text.Transliterator;
 
 import java.io.DataInput;
+import java.io.DataInputStream;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.io.RandomAccessFile;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
 import java.util.AbstractList;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -117,9 +120,8 @@ public final class Index implements RAFSerializable<Index> {
         return new NormalizeComparator(normalizer(), sortLanguage.getCollator(), dict.dictFileVersion);
     }
 
-    public Index(final Dictionary dict, final DataInput inp) throws IOException {
+    public Index(final Dictionary dict, final FileChannel inp, final DataInput raf) throws IOException {
         this.dict = dict;
-        RandomAccessFile raf = (RandomAccessFile)inp;
         shortName = raf.readUTF();
         longName = raf.readUTF();
         final String languageCode = raf.readUTF();
@@ -133,7 +135,7 @@ public final class Index implements RAFSerializable<Index> {
             mainTokenCount = raf.readInt();
         }
         sortedIndexEntries = CachingList.create(
-                                 RAFList.create(raf, indexEntrySerializer, raf.getFilePointer(),
+                                 RAFList.create(inp, new IndexEntrySerializer(dict.dictFileVersion == 6 ? inp : null), inp.position(),
                                                 dict.dictFileVersion, dict.dictInfo + " idx " + languageCode + ": "), CACHE_SIZE);
         if (dict.dictFileVersion >= 7) {
             int count = StringUtil.readVarInt(raf);
@@ -147,7 +149,7 @@ public final class Index implements RAFSerializable<Index> {
             stoplist = Collections.emptySet();
         }
         rows = CachingList.create(
-                   UniformRAFList.create(raf, new RowBase.Serializer(this), raf.getFilePointer()),
+                   UniformRAFList.create(inp, new RowBase.Serializer(this), inp.position()),
                    CACHE_SIZE);
     }
 
@@ -162,7 +164,7 @@ public final class Index implements RAFSerializable<Index> {
         if (dict.dictFileVersion >= 2) {
             raf.writeInt(mainTokenCount);
         }
-        RAFList.write(raf, sortedIndexEntries, indexEntrySerializer, 32, true);
+        RAFList.write(raf, sortedIndexEntries, new IndexEntrySerializer(null), 32, true);
         StringUtil.writeVarInt(raf, stoplist.size());
         for (String i : stoplist) {
             raf.writeUTF(i);
@@ -176,10 +178,16 @@ public final class Index implements RAFSerializable<Index> {
         }
     }
 
-    private final RAFSerializer<IndexEntry> indexEntrySerializer = new RAFSerializer<IndexEntry>() {
+    private final class IndexEntrySerializer implements RAFSerializer<IndexEntry> {
+        private final FileChannel ch;
+
+        public IndexEntrySerializer(FileChannel ch) {
+            this.ch = ch;
+        }
+
         @Override
         public IndexEntry read(DataInput raf) throws IOException {
-            return new IndexEntry(Index.this, raf);
+            return new IndexEntry(Index.this, ch, raf);
         }
 
         @Override
@@ -206,7 +214,7 @@ public final class Index implements RAFSerializable<Index> {
             this.htmlEntries = new ArrayList<HtmlEntry>();
         }
 
-        public IndexEntry(final Index index, final DataInput raf) throws IOException {
+        public IndexEntry(final Index index, final FileChannel ch, final DataInput raf) throws IOException {
             token = raf.readUTF();
             if (index.dict.dictFileVersion >= 7) {
                 startRow = StringUtil.readVarInt(raf);
@@ -239,8 +247,8 @@ public final class Index implements RAFSerializable<Index> {
                 }
             } else if (index.dict.dictFileVersion >= 6) {
                 this.htmlEntries = CachingList.create(
-                                       RAFList.create((RandomAccessFile)raf, index.dict.htmlEntryIndexSerializer,
-                                                      ((RandomAccessFile)raf).getFilePointer(), index.dict.dictFileVersion,
+                                       RAFList.create(ch, index.dict.htmlEntryIndexSerializer,
+                                                      ch.position(), index.dict.dictFileVersion,
                                                       index.dict.dictInfo + " htmlEntries: "), 1);
             } else {
                 this.htmlEntries = Collections.emptyList();