]> gitweb.fperrin.net Git - Dictionary.git/blobdiff - src/com/hughes/android/dictionary/DictionaryActivity.java
Add TTS.
[Dictionary.git] / src / com / hughes / android / dictionary / DictionaryActivity.java
index 75c1905dce56ba0115ef8a60ba419a596d055a98..1516ce4d5e69f626e18579de6d2ada76bc4867ed 100644 (file)
 
 package com.hughes.android.dictionary;
 
-import com.hughes.android.dictionary.DictionaryInfo.IndexInfo;
-import com.hughes.android.dictionary.engine.Dictionary;
-import com.hughes.android.dictionary.engine.EntrySource;
-import com.hughes.android.dictionary.engine.HtmlEntry;
-import com.hughes.android.dictionary.engine.Index;
-import com.hughes.android.dictionary.engine.Index.IndexEntry;
-import com.hughes.android.dictionary.engine.PairEntry;
-import com.hughes.android.dictionary.engine.PairEntry.Pair;
-import com.hughes.android.dictionary.engine.RowBase;
-import com.hughes.android.dictionary.engine.TokenRow;
-import com.hughes.android.dictionary.engine.TransliteratorManager;
-import com.hughes.android.util.IntentLauncher;
-import com.hughes.android.util.NonLinkClickableSpan;
-
 import android.app.Dialog;
 import android.app.ListActivity;
 import android.content.Context;
@@ -38,6 +24,8 @@ import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.preference.PreferenceManager;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.TextToSpeech.OnInitListener;
 import android.text.ClipboardManager;
 import android.text.Editable;
 import android.text.Selection;
@@ -65,6 +53,7 @@ import android.widget.AdapterView.AdapterContextMenuInfo;
 import android.widget.BaseAdapter;
 import android.widget.Button;
 import android.widget.EditText;
+import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ListAdapter;
@@ -74,6 +63,20 @@ import android.widget.TableRow;
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.hughes.android.dictionary.DictionaryInfo.IndexInfo;
+import com.hughes.android.dictionary.engine.Dictionary;
+import com.hughes.android.dictionary.engine.EntrySource;
+import com.hughes.android.dictionary.engine.HtmlEntry;
+import com.hughes.android.dictionary.engine.Index;
+import com.hughes.android.dictionary.engine.Index.IndexEntry;
+import com.hughes.android.dictionary.engine.PairEntry;
+import com.hughes.android.dictionary.engine.PairEntry.Pair;
+import com.hughes.android.dictionary.engine.RowBase;
+import com.hughes.android.dictionary.engine.TokenRow;
+import com.hughes.android.dictionary.engine.TransliteratorManager;
+import com.hughes.android.util.IntentLauncher;
+import com.hughes.android.util.NonLinkClickableSpan;
+
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
@@ -83,8 +86,10 @@ import java.text.SimpleDateFormat;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.Executor;
@@ -116,6 +121,9 @@ public class DictionaryActivity extends ListActivity {
 
     // package for test.
     final Handler uiHandler = new Handler();
+    
+    TextToSpeech textToSpeech;
+    volatile boolean ttsReady;
 
     private final Executor searchExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
         @Override
@@ -200,6 +208,15 @@ public class DictionaryActivity extends ListActivity {
 
         final Intent intent = getIntent();
         dictFile = new File(intent.getStringExtra(C.DICT_FILE));
+        
+        ttsReady = false;
+        textToSpeech = new TextToSpeech(getApplicationContext(), new OnInitListener() {
+            @Override
+            public void onInit(int status) {
+                ttsReady = true;
+                updateTTSLanuage();
+            }
+        });
 
         try {
             final String name = application.getDictionaryName(dictFile.getName());
@@ -293,11 +310,6 @@ public class DictionaryActivity extends ListActivity {
 
         setContentView(R.layout.dictionary_activity);
         searchText = (EditText) findViewById(R.id.SearchText);
-        searchText.setTypeface(typeface);
-        searchText.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSizeSp);
-
-        langButton = (Button) findViewById(R.id.LangButton);
-
         searchText.requestFocus();
         searchText.addTextChangedListener(searchTextWatcher);
 
@@ -312,17 +324,17 @@ public class DictionaryActivity extends ListActivity {
         setSearchText(text, true);
         Log.d(LOG, "Trying to restore searchText=" + text);
 
-        final Button clearSearchTextButton = (Button) findViewById(R.id.ClearSearchTextButton);
+        final View clearSearchTextButton = findViewById(R.id.ClearSearchTextButton);
         clearSearchTextButton.setOnClickListener(new OnClickListener() {
             public void onClick(View v) {
-                onClearSearchTextButton(clearSearchTextButton);
+                onClearSearchTextButton();
             }
         });
         clearSearchTextButton.setVisibility(PreferenceManager.getDefaultSharedPreferences(this)
                 .getBoolean(getString(R.string.showClearSearchTextButtonKey), true) ? View.VISIBLE
                 : View.GONE);
 
-        final Button langButton = (Button) findViewById(R.id.LangButton);
+        langButton = (Button) findViewById(R.id.LangButton);
         langButton.setOnClickListener(new OnClickListener() {
             public void onClick(View v) {
                 onLanguageButton();
@@ -337,13 +349,13 @@ public class DictionaryActivity extends ListActivity {
         });
         updateLangButton();
 
-        final Button upButton = (Button) findViewById(R.id.UpButton);
+        final View upButton = findViewById(R.id.UpButton);
         upButton.setOnClickListener(new OnClickListener() {
             public void onClick(View v) {
                 onUpDownButton(true);
             }
         });
-        final Button downButton = (Button) findViewById(R.id.DownButton);
+        final View downButton = findViewById(R.id.DownButton);
         downButton.setOnClickListener(new OnClickListener() {
             public void onClick(View v) {
                 onUpDownButton(false);
@@ -390,6 +402,7 @@ public class DictionaryActivity extends ListActivity {
 
     @Override
     protected void onResume() {
+        Log.d(LOG, "onResume");
         super.onResume();
         if (PreferenceActivity.prefsMightHaveChanged) {
             PreferenceActivity.prefsMightHaveChanged = false;
@@ -399,6 +412,7 @@ public class DictionaryActivity extends ListActivity {
         if (initialSearchText != null) {
             setSearchText(initialSearchText, true);
         }
+        showKeyboard();
     }
 
     @Override
@@ -446,8 +460,12 @@ public class DictionaryActivity extends ListActivity {
     // Buttons
     // --------------------------------------------------------------------------
 
-    private void onClearSearchTextButton(final Button clearSearchTextButton) {
+    private void onClearSearchTextButton() {
         setSearchText("", true);
+        showKeyboard();
+    }
+
+    private void showKeyboard() {
         Log.d(LOG, "Trying to show soft keyboard.");
         final InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
         manager.showSoftInput(searchText, InputMethodManager.SHOW_IMPLICIT);
@@ -463,6 +481,19 @@ public class DictionaryActivity extends ListActivity {
         // langButton.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
         langButton.setText(index.shortName);
         // }
+        updateTTSLanuage();
+    }
+    
+    private void updateTTSLanuage() {
+        if (!ttsReady) {
+            return;
+        }
+        final Locale locale = new Locale(index.sortLanguage.getIsoCode());
+        Log.d(LOG, "Setting TTS locale to: " + locale);
+        final int ttsResult = textToSpeech.setLanguage(locale);
+        if (ttsResult != TextToSpeech.SUCCESS) {
+            Log.e(LOG, "TTS not available in this language.");
+        }
     }
 
     void onLanguageButton() {
@@ -508,29 +539,45 @@ public class DictionaryActivity extends ListActivity {
         listView.setAdapter(new BaseAdapter() {
             @Override
             public View getView(int position, View convertView, ViewGroup parent) {
-                final LinearLayout result = new LinearLayout(parent.getContext());
-
                 final DictionaryInfo dictionaryInfo = getItem(position);
-                final Button button = new Button(parent.getContext());
+
+                final LinearLayout result = new LinearLayout(parent.getContext());
+                
+                for (int i = 0; i < dictionaryInfo.indexInfos.size(); ++i) {
+                    if (i > 0) {
+                        final TextView dash = new TextView(parent.getContext());
+                        dash.setText("-");
+                        result.addView(dash);
+                    }
+                    
+                    final IndexInfo indexInfo = dictionaryInfo.indexInfos.get(i);
+                    final Button button = new Button(parent.getContext());
+                    button.setText(indexInfo.shortName);
+                    final IntentLauncher intentLauncher = new IntentLauncher(parent.getContext(),
+                            getLaunchIntent(application.getPath(dictionaryInfo.uncompressedFilename),
+                                    i, searchText.getText().toString())) {
+                        @Override
+                        protected void onGo() {
+                            dialog.dismiss();
+                            DictionaryActivity.this.finish();
+                        };
+                    };
+                    button.setOnClickListener(intentLauncher);
+                    result.addView(button);
+                    
+                }
+                
+                final TextView nameView = new TextView(parent.getContext());
                 final String name = application
                         .getDictionaryName(dictionaryInfo.uncompressedFilename);
-                button.setText(name);
-                final IntentLauncher intentLauncher = new IntentLauncher(parent.getContext(),
-                        getLaunchIntent(application.getPath(dictionaryInfo.uncompressedFilename),
-                                0, searchText.getText().toString())) {
-                    @Override
-                    protected void onGo() {
-                        dialog.dismiss();
-                        DictionaryActivity.this.finish();
-                    };
-                };
-                button.setOnClickListener(intentLauncher);
+                nameView.setText(name);
                 final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                         ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                 layoutParams.width = 0;
                 layoutParams.weight = 1.0f;
-                button.setLayoutParams(layoutParams);
-                result.addView(button);
+                nameView.setLayoutParams(layoutParams);
+                result.addView(nameView);
+
                 return result;
             }
 
@@ -741,11 +788,8 @@ public class DictionaryActivity extends ListActivity {
                         indexToUse = selectedSpannableIndex;
                     }
                     final boolean changeIndex = indexIndex != indexToUse;
-                    setSearchText(selectedText, !changeIndex); // If we're not
-                                                               // changing
-                                                               // index, we have
-                                                               // to
-                                                               // triggerSearch.
+                    // If we're not changing index, we have to trigger search:
+                    setSearchText(selectedText, !changeIndex); 
                     if (changeIndex) {
                         changeIndexGetFocusAndResearch(indexToUse);
                     }
@@ -755,6 +799,17 @@ public class DictionaryActivity extends ListActivity {
                 }
             });
         }
+        
+        if (row instanceof TokenRow) {
+            final MenuItem speak = menu.add(R.string.speak);
+            speak.setOnMenuItemClickListener(new OnMenuItemClickListener() {
+                @Override
+                public boolean onMenuItemClick(MenuItem item) {
+                    textToSpeech.speak(((TokenRow) row).getToken(), TextToSpeech.QUEUE_FLUSH, new HashMap<String, String>());
+                    return false;
+                }
+            });
+        }
 
     }
 
@@ -991,22 +1046,40 @@ public class DictionaryActivity extends ListActivity {
 
     final class IndexAdapter extends BaseAdapter {
 
+        private static final float PADDING_DEFAULT_DP = 8;
+
+        private static final float PADDING_LARGE_DP = 16;
+
         final Index index;
 
         final List<RowBase> rows;
 
         final Set<String> toHighlight;
 
+        private int mPaddingDefault;
+
+        private int mPaddingLarge;
+
         IndexAdapter(final Index index) {
             this.index = index;
             rows = index.rows;
             this.toHighlight = null;
+            getMetrics();
         }
 
         IndexAdapter(final Index index, final List<RowBase> rows, final List<String> toHighlight) {
             this.index = index;
             this.rows = rows;
             this.toHighlight = new LinkedHashSet<String>(toHighlight);
+            getMetrics();
+        }
+
+        private void getMetrics() {
+            // Get the screen's density scale
+            final float scale = getResources().getDisplayMetrics().density;
+            // Convert the dps to pixels, based on density scale
+            mPaddingDefault = (int) (PADDING_DEFAULT_DP * scale + 0.5f);
+            mPaddingLarge = (int) (PADDING_LARGE_DP * scale + 0.5f);
         }
 
         @Override
@@ -1052,6 +1125,7 @@ public class DictionaryActivity extends ListActivity {
 
             final TableRow.LayoutParams layoutParams = new TableRow.LayoutParams();
             layoutParams.weight = 0.5f;
+            layoutParams.leftMargin = mPaddingLarge;
 
             for (int r = 0; r < rowCount; ++r) {
                 final TableRow tableRow = new TableRow(result.getContext());
@@ -1137,59 +1211,75 @@ public class DictionaryActivity extends ListActivity {
             return result;
         }
 
-        private TableLayout getView(HtmlEntry.Row row, ViewGroup parent, final TableLayout result) {
+        private TableLayout getPossibleLinkToHtmlEntryView(final boolean isTokenRow, final String text, final boolean hasMainEntry, final List<HtmlEntry> htmlEntries, final String htmlTextToHighlight, ViewGroup parent, final TableLayout result) {
             final Context context = parent.getContext();
-
-            final HtmlEntry htmlEntry = row.getEntry();
-
-            // final TableRow tableRow = new TableRow(context);
-            final LinearLayout tableRow = new LinearLayout(context);
+            
+            final TableRow tableRow = new TableRow(result.getContext());
+            tableRow.setBackgroundResource(hasMainEntry ? theme.tokenRowMainBg
+                    : theme.tokenRowOtherBg);
+            if (isTokenRow) {
+                tableRow.setPadding(mPaddingDefault, mPaddingDefault, mPaddingDefault, 0);
+            } else {
+                tableRow.setPadding(mPaddingLarge, mPaddingDefault, mPaddingDefault, 0);
+            }
             result.addView(tableRow);
 
-            // Text.
-            final TextView textView = new TextView(context);
-            textView.setText(htmlEntry.title);
-            textView.setLayoutParams(new LinearLayout.LayoutParams(0,
-                    ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f));
-            tableRow.addView(textView);
-
-            // Button.
-            final Button button = new Button(context);
-            button.setText("open");
-            button.setLayoutParams(new LinearLayout.LayoutParams(
-                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 0.0f));
-            tableRow.addView(button);
-
-            button.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    startActivity(HtmlDisplayActivity.getHtmlIntent(String.format(
-                            "<html><head></head><body>%s</body></html>", htmlEntry.html)));
-                }
-            });
-
-            return result;
-        }
-
-        private TableLayout getView(TokenRow row, ViewGroup parent, final TableLayout result) {
-            final Context context = parent.getContext();
             final TextView textView = new TextView(context);
-            textView.setText(row.getToken());
+            textView.setText(text);
             // Doesn't work:
             // textView.setTextColor(android.R.color.secondary_text_light);
-            textView.setTextAppearance(context, theme.tokenRowFg);
             textView.setTypeface(typeface);
-            textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 5 * fontSizeSp / 4);
-
-            final TableRow tableRow = new TableRow(result.getContext());
+            TableRow.LayoutParams lp = new TableRow.LayoutParams(0);
+            if (isTokenRow) {
+                textView.setTextAppearance(context, theme.tokenRowFg);
+                textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 4 * fontSizeSp / 3);
+            } else {
+                textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSizeSp);
+            }
+            lp.weight = 1.0f;
+            
+            textView.setLayoutParams(lp);
             tableRow.addView(textView);
-            tableRow.setBackgroundResource(row.hasMainEntry ? theme.tokenRowMainBg
-                    : theme.tokenRowOtherBg);
-            result.addView(tableRow);
+
+            
+            if (!htmlEntries.isEmpty()) {
+                final ImageButton button = new ImageButton(context);
+                button.setImageResource(R.drawable.ic_menu_forward);
+                button.setOnClickListener(new OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        final String html = HtmlEntry.htmlBody(htmlEntries);
+                        startActivity(HtmlDisplayActivity.getHtmlIntent(String.format(
+                                "<html><head></head><body>%s</body></html>", html), htmlTextToHighlight, false));
+                    }
+                });
+                tableRow.addView(button);
+                lp = new TableRow.LayoutParams(1);
+                lp.weight = 0.0f;
+                button.setLayoutParams(lp);
+                //result.setColumnStretchable(0, true);
+                //result.setColumnStretchable(1, false);
+            }
+            result.setLongClickable(true);
             return result;
         }
+        
+        private TableLayout getView(TokenRow row, ViewGroup parent, final TableLayout result) {
+            final IndexEntry indexEntry = row.getIndexEntry();
+            return getPossibleLinkToHtmlEntryView(true, indexEntry.token, row.hasMainEntry, indexEntry.htmlEntries, null, parent, result);
+        }
+        
+        private TableLayout getView(HtmlEntry.Row row, ViewGroup parent, final TableLayout result) {
+            final HtmlEntry htmlEntry = row.getEntry();
+            final TokenRow tokenRow = row.getTokenRow(true);
+            return getPossibleLinkToHtmlEntryView(false, getString(R.string.seeAlso, htmlEntry.title, htmlEntry.entrySource.getName()), 
+                    false, Collections.singletonList(htmlEntry), tokenRow.getToken(), parent, result);
+        }
+
 
     }
+    
+
 
     static final Pattern CHAR_DASH = Pattern.compile("['\\p{L}\\p{M}\\p{N}]+");
 
@@ -1304,15 +1394,15 @@ public class DictionaryActivity extends ListActivity {
     }
 
     void setFiltered(final SearchOperation searchOperation) {
-        ((Button) findViewById(R.id.UpButton)).setEnabled(false);
-        ((Button) findViewById(R.id.DownButton)).setEnabled(false);
+        ((ImageButton) findViewById(R.id.UpButton)).setEnabled(false);
+        ((ImageButton) findViewById(R.id.DownButton)).setEnabled(false);
         rowsToShow = searchOperation.multiWordSearchResult;
         setListAdapter(new IndexAdapter(index, rowsToShow, searchOperation.searchTokens));
     }
 
     void clearFiltered() {
-        ((Button) findViewById(R.id.UpButton)).setEnabled(true);
-        ((Button) findViewById(R.id.DownButton)).setEnabled(true);
+        ((ImageButton) findViewById(R.id.UpButton)).setEnabled(true);
+        ((ImageButton) findViewById(R.id.DownButton)).setEnabled(true);
         setListAdapter(new IndexAdapter(index));
         rowsToShow = null;
     }