]> gitweb.fperrin.net Git - Dictionary.git/blobdiff - src/com/hughes/android/dictionary/DictionaryActivity.java
Enable keyboard-only navigation to HTML entries.
[Dictionary.git] / src / com / hughes / android / dictionary / DictionaryActivity.java
index 683ff5094ec48d953ee12d7eedb1f116ca6247bd..42012d3ec7e4e333428de50ae20fccd1ae13886c 100644 (file)
@@ -20,6 +20,7 @@ import android.app.SearchManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
 import android.graphics.Color;
 import android.graphics.Typeface;
 import android.net.Uri;
@@ -420,7 +421,15 @@ public class DictionaryActivity extends ActionBarActivity {
         }
         Log.d(LOG, "Loading index " + indexIndex);
         index = dictionary.indices.get(indexIndex);
+        getListView().setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
         getListView().setEmptyView(findViewById(android.R.id.empty));
+        getListView().setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int row, long id) {
+                onListItemClick(getListView(), view, row, id);
+            }
+        });
+
         setListAdapter(new IndexAdapter(index));
 
         // Pre-load the collators.
@@ -497,18 +506,12 @@ public class DictionaryActivity extends ActionBarActivity {
         saveOnlyFirstSubentry = prefs.getBoolean(getString(R.string.saveOnlyFirstSubentryKey),
                                 false);
         clickOpensContextMenu = prefs.getBoolean(getString(R.string.clickOpensContextMenuKey),
-                                false);
+                                !getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN));
         Log.d(LOG, "wordList=" + wordList + ", saveOnlyFirstSubentry=" + saveOnlyFirstSubentry);
 
         onCreateSetupActionBarAndSearchView();
 
         View floatSwapButton = findViewById(R.id.floatSwapButton);
-        floatSwapButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View arg0) {
-                onLanguageButtonClick();
-            }
-        });
         floatSwapButton.setOnLongClickListener(new OnLongClickListener() {
             @Override
             public boolean onLongClick(View v) {
@@ -517,21 +520,6 @@ public class DictionaryActivity extends ActionBarActivity {
             }
         });
 
-        final FloatingActionButton floatSearchButton = (FloatingActionButton)findViewById(R.id.floatSearchButton);
-        floatSearchButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View arg0) {
-                if (!searchView.hasFocus()) {
-                    searchView.requestFocus();
-                }
-                if (searchView.getQuery().toString().length() > 0) {
-                    searchView.setQuery("", false);
-                }
-                showKeyboard();
-                searchView.setIconified(false);
-            }
-        });
-
         // Set the search text from the intent, then the saved state.
         String text = getIntent().getStringExtra(C.SEARCH_TOKEN);
         if (savedInstanceState != null) {
@@ -564,14 +552,8 @@ public class DictionaryActivity extends ActionBarActivity {
             ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
         customSearchView.setLayoutParams(layoutParams);
 
-        listView.setOnItemClickListener(new OnItemClickListener() {
-            @Override
-            public void onItemClick(AdapterView<?> parent, View view, int row, long id) {
-                onListItemClick(getListView(), view, row, id);
-            }
-        });
-
         languageButton = new ImageButton(customSearchView.getContext());
+        languageButton.setId(R.id.languageButton);
         languageButton.setScaleType(ScaleType.FIT_CENTER);
         languageButton.setOnClickListener(new OnClickListener() {
             @Override
@@ -584,6 +566,7 @@ public class DictionaryActivity extends ActionBarActivity {
         customSearchView.addView(languageButton, lpb);
 
         searchView = new SearchView(getSupportActionBar().getThemedContext());
+        searchView.setId(R.id.searchView);
 
         // Get rid of search icon, it takes up too much space.
         // There is still text saying "search" in the search field.
@@ -626,6 +609,10 @@ public class DictionaryActivity extends ActionBarActivity {
         // Avoid wasting space on large left inset
         Toolbar tb = (Toolbar)customSearchView.getParent();
         tb.setContentInsetsRelative(0, 0);
+
+        getListView().setNextFocusLeftId(R.id.searchView);
+        findViewById(R.id.floatSwapButton).setNextFocusRightId(R.id.languageButton);
+        languageButton.setNextFocusLeftId(R.id.floatSwapButton);
     }
 
     @Override
@@ -762,7 +749,18 @@ public class DictionaryActivity extends ActionBarActivity {
         }
     }
 
-    void onLanguageButtonClick() {
+    public void onSearchButtonClick(View dummy) {
+        if (!searchView.hasFocus()) {
+            searchView.requestFocus();
+        }
+        if (searchView.getQuery().toString().length() > 0) {
+            searchView.setQuery("", false);
+        }
+        showKeyboard();
+        searchView.setIconified(false);
+    }
+
+    public void onLanguageButtonClick(View dummy) {
         if (dictionary.indices.size() == 1) {
             // No need to work to switch indices.
             return;
@@ -797,6 +795,7 @@ public class DictionaryActivity extends ActionBarActivity {
         button.setOnClickListener(intentLauncher);
         listView.addHeaderView(button);
 
+        listView.setItemsCanFocus(true);
         listView.setAdapter(new BaseAdapter() {
             @Override
             public View getView(int position, View convertView, ViewGroup parent) {
@@ -1013,9 +1012,22 @@ public class DictionaryActivity extends ActionBarActivity {
 
     @Override
     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
-        AdapterContextMenuInfo adapterContextMenuInfo = (AdapterContextMenuInfo) menuInfo;
+        final AdapterContextMenuInfo adapterContextMenuInfo = (AdapterContextMenuInfo) menuInfo;
         final RowBase row = (RowBase) getListAdapter().getItem(adapterContextMenuInfo.position);
 
+        if (clickOpensContextMenu && (row instanceof HtmlEntry.Row ||
+            (row instanceof TokenRow && ((TokenRow)row).getIndexEntry().htmlEntries.size() > 0))) {
+            final List<HtmlEntry> html = row instanceof TokenRow ? ((TokenRow)row).getIndexEntry().htmlEntries : Collections.singletonList(((HtmlEntry.Row)row).getEntry());
+            final String highlight = row instanceof HtmlEntry.Row ? ((HtmlEntry.Row)row).getTokenRow(true).getToken() : null;
+            final MenuItem open = menu.add("Open");
+            open.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+                public boolean onMenuItemClick(MenuItem item) {
+                    showHtml(html, highlight);
+                    return false;
+                }
+            });
+        }
+
         final android.view.MenuItem addToWordlist = menu.add(getString(R.string.addToWordList,
                 wordList.getName()));
         addToWordlist
@@ -1077,6 +1089,37 @@ public class DictionaryActivity extends ActionBarActivity {
                 }
             });
         }
+        if (row instanceof PairEntry.Row && ttsReady) {
+            final List<Pair> pairs = ((PairEntry.Row)row).getEntry().pairs;
+            final MenuItem speakLeft = menu.add(R.string.speak_left);
+            speakLeft.setOnMenuItemClickListener(new android.view.MenuItem.OnMenuItemClickListener() {
+                @Override
+                public boolean onMenuItemClick(android.view.MenuItem item) {
+                    int idx = index.swapPairEntries ? 1 : 0;
+                    updateTTSLanguage(idx);
+                    String text = "";
+                    for (Pair p : pairs) text += p.get(idx);
+                    text = text.replaceAll("\\{[^{}]*\\}", "").replace("{", "").replace("}", "");
+                    textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH,
+                                       new HashMap<String, String>());
+                    return false;
+                }
+            });
+            final MenuItem speakRight = menu.add(R.string.speak_right);
+            speakRight.setOnMenuItemClickListener(new android.view.MenuItem.OnMenuItemClickListener() {
+                @Override
+                public boolean onMenuItemClick(android.view.MenuItem item) {
+                    int idx = index.swapPairEntries ? 0 : 1;
+                    updateTTSLanguage(idx);
+                    String text = "";
+                    for (Pair p : pairs) text += p.get(idx);
+                    text = text.replaceAll("\\{[^{}]*\\}", "").replace("{", "").replace("}", "");
+                    textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH,
+                                       new HashMap<String, String>());
+                    return false;
+                }
+            });
+        }
     }
 
     private void jumpToTextFromHyperLink(
@@ -1129,10 +1172,15 @@ public class DictionaryActivity extends ActionBarActivity {
         // searchView.selectAll();
     }
 
-    protected void onListItemClick(ListView l, View v, int row, long id) {
+    protected void onListItemClick(ListView l, View v, int rowIdx, long id) {
         defocusSearchText();
         if (clickOpensContextMenu && dictRaf != null) {
             openContextMenu(v);
+        } else {
+            final RowBase row = (RowBase)getListAdapter().getItem(rowIdx);
+            if (!(row instanceof PairEntry.Row)) {
+                v.performClick();
+            }
         }
     }
 
@@ -1376,6 +1424,16 @@ public class DictionaryActivity extends ActionBarActivity {
     // IndexAdapter
     // --------------------------------------------------------------------------
 
+    private void showHtml(final List<HtmlEntry> htmlEntries, final String htmlTextToHighlight) {
+        String html = HtmlEntry.htmlBody(htmlEntries, index.shortName);
+        // Log.d(LOG, "html=" + html);
+        startActivityForResult(
+            HtmlDisplayActivity.getHtmlIntent(getApplicationContext(), String.format(
+                    "<html><head></head><body>%s</body></html>", html),
+                                              htmlTextToHighlight, false),
+            0);
+    }
+
     static ViewGroup.LayoutParams WEIGHT_1 = new LinearLayout.LayoutParams(
         ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, 1.0f);
 
@@ -1540,7 +1598,7 @@ public class DictionaryActivity extends ActionBarActivity {
             // 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.setFocusable(false);
             result.setLongClickable(true);
 //            result.setBackgroundResource(android.R.drawable.menuitem_background);
 
@@ -1607,16 +1665,17 @@ public class DictionaryActivity extends ActionBarActivity {
                 textView.setOnClickListener(new OnClickListener() {
                     @Override
                     public void onClick(View v) {
-                        String html = HtmlEntry.htmlBody(htmlEntries, index.shortName);
-                        // Log.d(LOG, "html=" + html);
-                        startActivityForResult(
-                            HtmlDisplayActivity.getHtmlIntent(getApplicationContext(), String.format(
-                                    "<html><head></head><body>%s</body></html>", html),
-                                                              htmlTextToHighlight, false),
-                            0);
+                        showHtml(htmlEntries, htmlTextToHighlight);
+                    }
+                });
+                result.setOnClickListener(new OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        textView.performClick();
                     }
                 });
             }
+            result.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
             return result;
         }