// Copyright 2011 Google Inc. All Rights Reserved.
-//
+// Some Parts Copyright 2013 Dominik Köppl
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
package com.hughes.android.dictionary;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.RandomAccessFile;
+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;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
+import android.app.SearchManager;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.BaseAdapter;
import android.widget.Button;
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.io.PrintWriter;
-import java.io.RandomAccessFile;
-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;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.hughes.util.StringUtil;
public class DictionaryActivity extends ListActivity {
TextToSpeech textToSpeech;
volatile boolean ttsReady;
+
+ int textColorFg = Color.BLACK;
+
private final Executor searchExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
application = (DictionaryApplication) getApplication();
theme = application.getSelectedTheme();
+ textColorFg = getResources().getColor(theme.tokenRowFgColor);
+
+
final Intent intent = getIntent();
- dictFile = new File(intent.getStringExtra(C.DICT_FILE));
+ String intentAction = intent.getAction();
+ /**
+ * @author Dominik Köppl
+ * Querying the Intent
+ * com.hughes.action.ACTION_SEARCH_DICT is the advanced query
+ * Arguments:
+ * SearchManager.QUERY -> the phrase to search
+ * from -> language in which the phrase is written
+ * to -> to which language shall be translated
+ */
+ if(intentAction != null && intentAction.equals("com.hughes.action.ACTION_SEARCH_DICT"))
+ {
+ String query = intent.getStringExtra(SearchManager.QUERY);
+ String from = intent.getStringExtra("from");
+ if(from != null) from = from.toLowerCase(Locale.US);
+ String to = intent.getStringExtra("to");
+ if(to != null) to = to.toLowerCase(Locale.US);
+ if(query != null)
+ {
+ getIntent().putExtra(C.SEARCH_TOKEN, query);
+ }
+ if(intent.getStringExtra(C.DICT_FILE) == null && (from != null || to != null))
+ {
+ Log.d(LOG, "DictSearch: from: " + from + " to " + to);
+ List<DictionaryInfo> dicts = application.getUsableDicts();
+ for(DictionaryInfo info : dicts)
+ {
+ boolean hasFrom = from == null;
+ boolean hasTo = to == null;
+ for(IndexInfo index : info.indexInfos)
+ {
+ if(!hasFrom && index.shortName.toLowerCase(Locale.US).equals(from)) hasFrom = true;
+ if(!hasTo && index.shortName.toLowerCase(Locale.US).equals(to)) hasTo = true;
+ }
+ if(hasFrom && hasTo)
+ {
+ if(from != null)
+ {
+ int which_index = 0;
+ for(;which_index < info.indexInfos.size(); ++which_index)
+ {
+ if(info.indexInfos.get(which_index).shortName.toLowerCase(Locale.US).equals(from))
+ break;
+ }
+ intent.putExtra(C.INDEX_INDEX, which_index);
+
+ }
+ intent.putExtra(C.DICT_FILE, application.getPath(info.uncompressedFilename).toString());
+ break;
+ }
+ }
+
+ }
+ }
+ /**
+ * @author Dominik Köppl
+ * Querying the Intent
+ * Intent.ACTION_SEARCH is a simple query
+ * Arguments follow from android standard (see documentation)
+ */
+ if (intentAction != null && intentAction.equals(Intent.ACTION_SEARCH))
+ {
+ String query = intent.getStringExtra(SearchManager.QUERY);
+ if(query != null) getIntent().putExtra(C.SEARCH_TOKEN,query);
+ }
+ /**
+ * @author Dominik Köppl
+ * If no dictionary is chosen, use the default dictionary specified in the preferences
+ * If this step does fail (no default directory specified), show a toast and abort.
+ */
+ if(intent.getStringExtra(C.DICT_FILE) == null)
+ {
+ String dictfile = prefs.getString(getString(R.string.defaultDicKey), null);
+ if(dictfile != null) intent.putExtra(C.DICT_FILE, application.getPath(dictfile).toString());
+ }
+ String dictFilename = intent.getStringExtra(C.DICT_FILE);
+
+ if(dictFilename == null)
+ {
+ Toast.makeText(this, getString(R.string.no_dict_file), Toast.LENGTH_LONG).show();
+ startActivity(DictionaryManagerActivity.getLaunchIntent());
+ finish();
+ return;
+ }
+ if(dictFilename != null) dictFile = new File(dictFilename);
ttsReady = false;
textToSpeech = new TextToSpeech(getApplicationContext(), new OnInitListener() {
@Override
public void onInit(int status) {
ttsReady = true;
- updateTTSLanuage();
+ updateTTSLanguage();
}
});
-
+
try {
final String name = application.getDictionaryName(dictFile.getName());
this.setTitle("QuickDic: " + name);
onUpDownButton(false);
}
});
+ upButton.setVisibility(PreferenceManager.getDefaultSharedPreferences(this)
+ .getBoolean(getString(R.string.showPrevNextButtonsKey), true) ? View.VISIBLE
+ : View.GONE);
+ downButton.setVisibility(PreferenceManager.getDefaultSharedPreferences(this)
+ .getBoolean(getString(R.string.showPrevNextButtonsKey), true) ? View.VISIBLE
+ : View.GONE);
// getListView().setOnItemSelectedListener(new ListView.OnItemSelectedListener() {
// @Override
Log.d(LOG, "wordList=" + wordList + ", saveOnlyFirstSubentry=" + saveOnlyFirstSubentry);
setDictionaryPrefs(this, dictFile, indexIndex, searchText.getText().toString());
+
+
+
}
@Override
@Override
public void run() {
Log.d(LOG, "Trying to show soft keyboard.");
+ final boolean searchTextHadFocus = searchText.hasFocus();
+ searchText.requestFocus();
final InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
manager.showSoftInput(searchText, InputMethodManager.SHOW_IMPLICIT);
+ if (!searchTextHadFocus) {
+ defocusSearchText();
+ }
}}, 100);
}
// langButton.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
langButton.setText(index.shortName);
// }
- updateTTSLanuage();
+ updateTTSLanguage();
}
- private void updateTTSLanuage() {
- if (!ttsReady) {
+ private void updateTTSLanguage() {
+ if (!ttsReady || index == null || textToSpeech == null) {
+ Log.d(LOG, "Can't updateTTSLanguage.");
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.LANG_AVAILABLE || ttsResult != TextToSpeech.LANG_COUNTRY_AVAILABLE) {
+ if (ttsResult != TextToSpeech.LANG_AVAILABLE ||
+ ttsResult != TextToSpeech.LANG_COUNTRY_AVAILABLE) {
Log.e(LOG, "TTS not available in this language: ttsResult=" + ttsResult);
}
}
}
});
+ final MenuItem share = menu.add("Share");
+ share.setOnMenuItemClickListener(new OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
+ shareIntent.setType("text/plain");
+ shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, row.getTokenRow(true).getToken());
+ shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, row.getRawText(saveOnlyFirstSubentry));
+ startActivity(shareIntent);
+ return false;
+ }
+ });
+
final MenuItem copy = menu.add(android.R.string.copy);
copy.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
boolean done = false;
SearchOperation(final String searchText, final Index index) {
- this.searchText = searchText.trim();
+ this.searchText = StringUtil.normalizeWhitespace(searchText);
this.index = index;
}
searchResult = index.findInsertionPoint(searchText, interrupted);
} else {
searchTokens = Arrays.asList(searchTokenArray);
- multiWordSearchResult = index.multiWordSearch(searchTokens, interrupted);
+ multiWordSearchResult = index.multiWordSearch(searchText, searchTokens, interrupted);
}
Log.d(LOG,
"searchText=" + searchText + ", searchDuration="
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- final String html = HtmlEntry.htmlBody(htmlEntries, index.shortName);
+ String html = HtmlEntry.htmlBody(htmlEntries, index.shortName);
+ //Log.d(LOG, "html=" + html);
startActivityForResult(
HtmlDisplayActivity.getHtmlIntent(String.format(
"<html><head></head><body>%s</body></html>", html),
}
static final Pattern CHAR_DASH = Pattern.compile("['\\p{L}\\p{M}\\p{N}]+");
-
+
private void createTokenLinkSpans(final TextView textView, final Spannable spannable,
final String text) {
// Saw from the source code that LinkMovementMethod sets the selection!
textView.setMovementMethod(LinkMovementMethod.getInstance());
final Matcher matcher = CHAR_DASH.matcher(text);
while (matcher.find()) {
- spannable.setSpan(new NonLinkClickableSpan(), matcher.start(), matcher.end(),
+ spannable.setSpan(new NonLinkClickableSpan(textColorFg), matcher.start(), matcher.end(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
}