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;
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;
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;
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;
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;
// package for test.
final Handler uiHandler = new Handler();
+
+ TextToSpeech textToSpeech;
+ volatile boolean ttsReady;
private final Executor searchExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
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());
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);
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();
});
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);
@Override
protected void onResume() {
+ Log.d(LOG, "onResume");
super.onResume();
if (PreferenceActivity.prefsMightHaveChanged) {
PreferenceActivity.prefsMightHaveChanged = false;
if (initialSearchText != null) {
setSearchText(initialSearchText, true);
}
+ showKeyboard();
}
@Override
// 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);
// 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() {
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;
}
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);
}
}
});
}
+
+ 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;
+ }
+ });
+ }
}
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
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());
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}]+");
}
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;
}