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
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
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
\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
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
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
}\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
\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