]> gitweb.fperrin.net Git - Dictionary.git/commitdiff
Long-click on word can jump there!
authorThad Hughes <thad.hughes@gmail.com>
Tue, 17 Jan 2012 01:01:45 +0000 (17:01 -0800)
committerThad Hughes <thad.hughes@gmail.com>
Tue, 17 Jan 2012 01:01:45 +0000 (17:01 -0800)
res/values/strings.xml
res/values/themes.xml
src/com/hughes/android/dictionary/DictionaryActivity.java
src/com/hughes/android/dictionary/MyClickableSpan.java [new file with mode: 0644]

index 4688787a3f6c6a1b684eb02a8b77254f14261260..bd3925583e85ea74a0a7c68d0cb88c0b131dfc64 100644 (file)
        <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="about">About QuickDic…</string> 
        <string name="addToWordList">Add to word list: %s</string>
-  <string name="failedAddingToWordList">Failure adding 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="unzippingDictionary">Unzipping dictionary…</string>
   <string name="failedToUnzipDictionary">Failed to unzip dictionary…</string>
 
index d070800a15b536271b3a78ccd747001157802da7..5ac84e691a0ce03f4d63dec797a5c954a586a19a 100644 (file)
@@ -3,29 +3,33 @@
   
   <!-- Default: dark theme -->
     
-  <style name="Theme.Default" parent="@android:style/Theme"></style>
+  <style name="Theme.Default" parent="@android:style/Theme">
+      <item name="android:textColorLink">#FFFFFF</item>
+  </style>
 
   <style name="Theme.Default.TokenRow.Fg" parent="@style/Theme.Light">
     <item name="android:textColor">#FFFFFF</item>
   </style>
   
-  <color name="theme_default_token_row_main_bg">#0000FF</color>
-  <color name="theme_default_token_row_other_bg">#888888</color>
-  <color name="theme_default_other_lang_bg">#222222</color>
+  <color name="theme_default_token_row_main_bg">#111111</color>
+  <color name="theme_default_token_row_other_bg">#111111</color>
+  <color name="theme_default_other_lang_bg">#000000</color>
   
   
   <!-- ****************************************************************** -->
 
-  <style name="Theme.Light" parent="@android:style/Theme.Light"></style>
+  <style name="Theme.Light" parent="@android:style/Theme.Light">
+      <item name="android:textColorLink">#000000</item>
+  </style>
 
   <style name="Theme.Light.TokenRow.Fg" parent="@style/Theme.Light">
-    <item name="android:textColor">#FFFFFF</item>
+    <item name="android:textColor">#000000</item>
   </style>
   
   <color name="theme_light_token_row_fg">#FFFFFF</color>
-  <color name="theme_light_token_row_main_bg">#0000FF</color>
-  <color name="theme_light_token_row_other_bg">#888888</color>
-  <color name="theme_light_other_lang_bg">#DDDDDD</color>
+  <color name="theme_light_token_row_main_bg">#EEEEEE</color>
+  <color name="theme_light_token_row_other_bg">#EEEEEE</color>
+  <color name="theme_light_other_lang_bg">#FFFFFF</color>
   
 
 </resources>
\ No newline at end of file
index ac9fd9b03a1a39d3358fd3e39aca957576266a88..4d8d6ed2f853718fea3fce55ce0976a4e2d4e63a 100644 (file)
@@ -25,6 +25,8 @@ import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;\r
 import java.util.concurrent.ThreadFactory;\r
 import java.util.concurrent.atomic.AtomicBoolean;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
 \r
 import android.app.ListActivity;\r
 import android.content.Context;\r
@@ -39,6 +41,7 @@ import android.text.Editable;
 import android.text.Selection;\r
 import android.text.Spannable;\r
 import android.text.TextWatcher;\r
+import android.text.method.LinkMovementMethod;\r
 import android.text.style.StyleSpan;\r
 import android.util.Log;\r
 import android.util.TypedValue;\r
@@ -48,11 +51,12 @@ import android.view.KeyEvent;
 import android.view.Menu;\r
 import android.view.MenuItem;\r
 import android.view.MenuItem.OnMenuItemClickListener;\r
+import android.view.MotionEvent;\r
 import android.view.View;\r
 import android.view.View.OnClickListener;\r
+import android.view.View.OnLongClickListener;\r
 import android.view.ViewGroup;\r
 import android.view.inputmethod.InputMethodManager;\r
-import android.webkit.WebView;\r
 import android.widget.AdapterView;\r
 import android.widget.AdapterView.AdapterContextMenuInfo;\r
 import android.widget.BaseAdapter;\r
@@ -67,7 +71,6 @@ import android.widget.Toast;
 \r
 import com.hughes.android.dictionary.engine.Dictionary;\r
 import com.hughes.android.dictionary.engine.Index;\r
-import com.hughes.android.dictionary.engine.Language;\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
@@ -374,13 +377,17 @@ public class DictionaryActivity extends ListActivity {
       currentSearchOperation = null;\r
     }\r
     \r
-    indexIndex = (indexIndex + 1) % dictionary.indices.size();\r
+    changeIndex((indexIndex + 1)% dictionary.indices.size());\r
+    onSearchTextChange(searchText.getText().toString());\r
+  }\r
+\r
+  private void changeIndex(final int newIndex) {\r
+    indexIndex = newIndex;\r
     index = dictionary.indices.get(indexIndex);\r
     indexAdapter = new IndexAdapter(index);\r
-    Log.d(LOG, "onLanguageButton, newLang=" + index.longName);\r
+    Log.d(LOG, "changingIndex, newLang=" + index.longName);\r
     setListAdapter(indexAdapter);\r
     updateLangButton();\r
-    onSearchTextChange(searchText.getText().toString());\r
   }\r
   \r
   void onUpDownButton(final boolean up) {\r
@@ -477,6 +484,21 @@ public class DictionaryActivity extends ListActivity {
         return false;\r
       }\r
     });\r
+    \r
+    if (selectedSpannableText != null) {\r
+      final String selectedText = selectedSpannableText;\r
+      final MenuItem searchForSelection = menu.add(getString(R.string.searchForSelection, selectedSpannableText));\r
+      searchForSelection.setOnMenuItemClickListener(new OnMenuItemClickListener() {\r
+        public boolean onMenuItemClick(MenuItem item) {\r
+          if (indexIndex != selectedSpannableIndex) {\r
+            changeIndex(selectedSpannableIndex);\r
+          }\r
+          searchText.setText(selectedText);\r
+          return false;\r
+        }\r
+      });\r
+    }\r
+    \r
 \r
   }\r
   \r
@@ -684,63 +706,140 @@ public class DictionaryActivity extends ListActivity {
     }\r
 \r
     @Override\r
-    public View getView(int position, View convertView, ViewGroup parent) {\r
+    public View getView(int position, final View convertView, ViewGroup parent) {\r
       final RowBase row = index.rows.get(position);\r
       if (row instanceof PairEntry.Row) {\r
-        return getView((PairEntry.Row) row, parent);\r
+        return getView((PairEntry.Row) row, parent, convertView);\r
       } else if (row instanceof TokenRow) {\r
-        return getView((TokenRow) row, parent);\r
+        return getView((TokenRow) row, parent, convertView);\r
       } else {\r
         throw new IllegalArgumentException("Unsupported Row type: " + row.getClass());\r
       }\r
     }\r
 \r
-    private View getView(PairEntry.Row row, ViewGroup parent) {\r
-      final WebView result = new WebView(parent.getContext());\r
+    private View getView(PairEntry.Row row, ViewGroup parent, final View convertView) {\r
+      final TableLayout result = new TableLayout(parent.getContext());\r
       final PairEntry entry = row.getEntry();\r
       final int rowCount = entry.pairs.size();\r
-      final StringBuilder html = new StringBuilder();\r
-      html.append("<html><table width=\"100%\">");\r
       for (int r = 0; r < rowCount; ++r) {\r
-        html.append("<tr>");\r
+        final TableRow tableRow = new TableRow(result.getContext());\r
 \r
-        final Pair pair = entry.pairs.get(r);\r
-        // TODO: escape both the token and the text.\r
-        final String token = row.getTokenRow(true).getToken();\r
-        final String col1Text = index.swapPairEntries ? pair.lang2 : pair.lang1;\r
-        final String col2Text = index.swapPairEntries ? pair.lang1 : pair.lang2;\r
-        \r
-        col1Text.replaceAll(token, String.format("<b>%s</b", token));\r
+        final TextView col1 = new TextView(tableRow.getContext());\r
+        final TextView col2 = new TextView(tableRow.getContext());\r
+        final TableRow.LayoutParams layoutParams = new TableRow.LayoutParams();\r
+        layoutParams.weight = 0.5f;\r
 \r
-        // Column1\r
-        html.append("<td width=\"50%\">");\r
+        // Set the columns in the table.\r
         if (r > 0) {\r
-          html.append("<li>");\r
+          final TextView bullet = new TextView(tableRow.getContext());\r
+          bullet.setText(" • ");\r
+          tableRow.addView(bullet);\r
         }\r
-        html.append(col1Text);\r
-        html.append("</td>");\r
-\r
-        // Column2\r
-        html.append("<td width=\"50%\">");\r
+        tableRow.addView(col1, layoutParams);\r
+        final TextView margin = new TextView(tableRow.getContext());\r
+        margin.setText(" ");\r
+        tableRow.addView(margin);\r
         if (r > 0) {\r
-          html.append("<li>");\r
+          final TextView bullet = new TextView(tableRow.getContext());\r
+          bullet.setText(" • ");\r
+          tableRow.addView(bullet);\r
         }\r
-        html.append(col2Text);\r
-        html.append("</td>");\r
-\r
-//        column1.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSizeSp);\r
-//        column2.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSizeSp);\r
+        tableRow.addView(col2, layoutParams);\r
+        col1.setWidth(1);\r
+        col2.setWidth(1);\r
+        \r
+        // Set what's in the columns.\r
 \r
-        html.append("</tr>");\r
+        // TODO: color words by gender\r
+        final Pair pair = entry.pairs.get(r);\r
+        final String col1Text = index.swapPairEntries ? pair.lang2 : pair.lang1;\r
+        final String col2Text = index.swapPairEntries ? pair.lang1 : pair.lang2;\r
+        \r
+        col1.setText(col1Text, TextView.BufferType.SPANNABLE);\r
+        col2.setText(col2Text, TextView.BufferType.SPANNABLE);\r
+        \r
+        // Bold the token instances in col1.\r
+        final Spannable col1Spannable = (Spannable) col1.getText();\r
+        int startPos = 0;\r
+        final String token = row.getTokenRow(true).getToken();\r
+        while ((startPos = col1Text.indexOf(token, startPos)) != -1) {\r
+          col1Spannable.setSpan(new StyleSpan(Typeface.BOLD), startPos,\r
+              startPos + token.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);\r
+          startPos += token.length();\r
+        }\r
+        \r
+        createTokenLinkSpans(col1, col1Spannable, col1Text);\r
+        createTokenLinkSpans(col2, (Spannable) col2.getText(), col2Text);\r
+        \r
+        col1.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSizeSp);\r
+        col2.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSizeSp);\r
+        // col2.setBackgroundResource(theme.otherLangBg);\r
+        \r
+        if (index.swapPairEntries) {\r
+          col2.setOnLongClickListener(textViewLongClickListenerIndex0);\r
+          col1.setOnLongClickListener(textViewLongClickListenerIndex1);\r
+        } else {\r
+          col1.setOnLongClickListener(textViewLongClickListenerIndex0);\r
+          col2.setOnLongClickListener(textViewLongClickListenerIndex1);\r
+        }\r
+        \r
+        result.addView(tableRow);\r
       }\r
-      html.append("</html></table>");\r
-      \r
-      result.loadData(html.toString(), "text/html", null);\r
 \r
       return result;\r
+\r
+      \r
+//      final WebView result = (WebView) (convertView instanceof WebView ? convertView : new WebView(parent.getContext()));\r
+//        \r
+//      final PairEntry entry = row.getEntry();\r
+//      final int rowCount = entry.pairs.size();\r
+//      final StringBuilder html = new StringBuilder();\r
+//      html.append("<html><body><table width=\"100%\">");\r
+//      for (int r = 0; r < rowCount; ++r) {\r
+//        html.append("<tr>");\r
+//\r
+//        final Pair pair = entry.pairs.get(r);\r
+//        // TODO: escape both the token and the text.\r
+//        final String token = row.getTokenRow(true).getToken();\r
+//        final String col1Text = index.swapPairEntries ? pair.lang2 : pair.lang1;\r
+//        final String col2Text = index.swapPairEntries ? pair.lang1 : pair.lang2;\r
+//        \r
+//        col1Text.replaceAll(token, String.format("<b>%s</b>", token));\r
+//\r
+//        // Column1\r
+//        html.append("<td width=\"50%\">");\r
+//        if (r > 0) {\r
+//          html.append("<li>");\r
+//        }\r
+//        html.append(col1Text);\r
+//        html.append("</td>");\r
+//\r
+//        // Column2\r
+//        html.append("<td width=\"50%\">");\r
+//        if (r > 0) {\r
+//          html.append("<li>");\r
+//        }\r
+//        html.append(col2Text);\r
+//        html.append("</td>");\r
+//\r
+////        column1.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSizeSp);\r
+////        column2.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSizeSp);\r
+//\r
+//        html.append("</tr>");\r
+//      }\r
+//      html.append("</table></body></html>");\r
+//      \r
+//      Log.i(LOG, html.toString());\r
+//      \r
+//      result.getSettings().setRenderPriority(RenderPriority.HIGH);\r
+//      result.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);\r
+//      \r
+//      result.loadData("<html><body><table><tr><td>line (connected series of public conveyances, and hence, an established arrangement for forwarding merchandise, etc.) (noun)</td><td>verbinding</td></tr></table></body></html>", "text/html", "utf-8");\r
+//\r
+//      return result;\r
     }\r
 \r
-    private View getView(TokenRow row, ViewGroup parent) {\r
+    private View getView(TokenRow row, ViewGroup parent, final View convertView) {\r
       final Context context = parent.getContext();\r
       final TextView textView = new TextView(context);\r
       textView.setText(row.getToken());\r
@@ -754,6 +853,52 @@ public class DictionaryActivity extends ListActivity {
     \r
   }\r
 \r
+  static final Pattern CHAR_DASH = Pattern.compile("['\\p{L}0-9]+");\r
+\r
+  private void createTokenLinkSpans(final TextView textView, final Spannable spannable, final String text) {\r
+    // Saw from the source code that LinkMovementMethod sets the selection!\r
+    // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.1_r1/android/text/method/LinkMovementMethod.java#LinkMovementMethod\r
+    textView.setMovementMethod(LinkMovementMethod.getInstance());\r
+    final Matcher matcher = CHAR_DASH.matcher(text);\r
+    while (matcher.find()) {\r
+      spannable.setSpan(new MyClickableSpan(), matcher.start(), matcher.end(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);\r
+    }\r
+  }\r
+  \r
+\r
+  String selectedSpannableText = null;\r
+  int selectedSpannableIndex = -1;\r
+\r
+  @Override\r
+  public boolean onTouchEvent(MotionEvent event) {\r
+    selectedSpannableText = null;\r
+    selectedSpannableIndex = -1;\r
+    return super.onTouchEvent(event);\r
+  }\r
+\r
+  private class TextViewLongClickListener implements OnLongClickListener {\r
+    final int index;\r
+    \r
+    private TextViewLongClickListener(final int index) {\r
+      this.index = index;\r
+    }\r
+\r
+    @Override\r
+    public boolean onLongClick(final View v) {\r
+      final TextView textView = (TextView) v;\r
+      final int start = textView.getSelectionStart();\r
+      final int end = textView.getSelectionEnd();\r
+      if (start >= 0 &&  end >= 0) {\r
+        selectedSpannableText = textView.getText().subSequence(start, end).toString();\r
+        selectedSpannableIndex = index;\r
+      }\r
+      return false;\r
+    }\r
+  }\r
+  final TextViewLongClickListener textViewLongClickListenerIndex0 = new TextViewLongClickListener(0);\r
+  final TextViewLongClickListener textViewLongClickListenerIndex1 = new TextViewLongClickListener(1);\r
+  \r
+\r
   // --------------------------------------------------------------------------\r
   // SearchText\r
   // --------------------------------------------------------------------------\r
diff --git a/src/com/hughes/android/dictionary/MyClickableSpan.java b/src/com/hughes/android/dictionary/MyClickableSpan.java
new file mode 100644 (file)
index 0000000..e3b6e64
--- /dev/null
@@ -0,0 +1,23 @@
+package com.hughes.android.dictionary;
+
+import android.text.TextPaint;
+import android.text.style.ClickableSpan;
+import android.view.View;
+
+public class MyClickableSpan extends ClickableSpan {
+  
+  static MyClickableSpan instance = new MyClickableSpan();
+
+  // Won't see these on a long-click.
+  @Override
+  public void onClick(View widget) {
+  }
+
+  @Override
+  public void updateDrawState(TextPaint ds) {
+    super.updateDrawState(ds);
+    ds.setUnderlineText(false);
+    //ds.setColor(color);
+  }
+
+}