-Subproject commit ad3bdc6d114c4714e14985d7526036e50cbadbc6
+Subproject commit 47ba24f81320001cf29f46e0069e0e7e83ad3553
<h2>Important notes</h2>
<ul>
<li>If QuickDic seems to crash when opening a dictionary
-(especially on Sony Ericcson devices), it's probably a problem
+(especially on Sony Ericsson devices), it's probably a problem
loading the embedded font. Try opening QuickDic's preferences and
changing the font to "System default."</li>
</ul>
<!-- Dark theme -->
- <style name="Theme.Default" parent="AppBaseThemeDark"></style>
+ <style name="Theme.Default" parent="AppBaseThemeDark" />
<style name="Theme.Default.TokenRow.Fg" parent="Theme.Default">
<!-- Light theme -->
- <style name="Theme.Light" parent="AppBaseThemeLight"></style>
+ <style name="Theme.Light" parent="AppBaseThemeLight" />
<style name="Theme.Light.TokenRow.Fg" parent="Theme.Light">
public final class AboutActivity extends Activity {
- public static final String CURRENT_DICT_INFO = "currentDictInfo";
-
/** Called when the activity is first created. */
@Override
public void onCreate(final Bundle savedInstanceState) {
import android.preference.PreferenceManager;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
+import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.support.v7.widget.Toolbar;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
-import android.widget.TextView.BufferType;
import android.widget.Toast;
import com.hughes.android.dictionary.DictionaryInfo.IndexInfo;
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.Language.LanguageResources;
import com.hughes.android.dictionary.engine.PairEntry;
import com.hughes.android.dictionary.engine.PairEntry.Pair;
import com.hughes.android.dictionary.engine.RowBase;
import java.util.Locale;
import java.util.Random;
import java.util.Set;
-import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class DictionaryActivity extends ActionBarActivity {
+public class DictionaryActivity extends AppCompatActivity {
- static final String LOG = "QuickDic";
+ private static final String LOG = "QuickDic";
- DictionaryApplication application;
+ private DictionaryApplication application;
- File dictFile = null;
- FileChannel dictRaf = null;
- String dictFileTitleName = null;
+ private File dictFile = null;
+ private FileChannel dictRaf = null;
+ private String dictFileTitleName = null;
- Dictionary dictionary = null;
+ private Dictionary dictionary = null;
- int indexIndex = 0;
+ private int indexIndex = 0;
- Index index = null;
+ private Index index = null;
- List<RowBase> rowsToShow = null; // if not null, just show these rows.
+ private List<RowBase> rowsToShow = null; // if not null, just show these rows.
- final Random rand = new Random();
+ private final Random rand = new Random();
- final Handler uiHandler = new Handler();
+ private final Handler uiHandler = new Handler();
private final ExecutorService searchExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
- public Thread newThread(Runnable r) {
+ public Thread newThread(@NonNull Runnable r) {
return new Thread(r, "searchExecutor");
}
});
private SearchOperation currentSearchOperation = null;
- TextToSpeech textToSpeech;
- volatile boolean ttsReady;
+ private TextToSpeech textToSpeech;
+ private volatile boolean ttsReady;
- Typeface typeface;
- DictionaryApplication.Theme theme = DictionaryApplication.Theme.LIGHT;
- int textColorFg = Color.BLACK;
- int fontSizeSp;
+ private Typeface typeface;
+ private DictionaryApplication.Theme theme = DictionaryApplication.Theme.LIGHT;
+ private int textColorFg = Color.BLACK;
+ private int fontSizeSp;
private ListView listView;
private ListView getListView() {
return getListView().getAdapter();
}
- SearchView searchView;
- ImageButton languageButton;
- SearchView.OnQueryTextListener onQueryTextListener;
+ private SearchView searchView;
+ private ImageButton languageButton;
+ private SearchView.OnQueryTextListener onQueryTextListener;
- MenuItem nextWordMenuItem, previousWordMenuItem, randomWordMenuItem;
+ private MenuItem nextWordMenuItem;
+ private MenuItem previousWordMenuItem;
// Never null.
private File wordList = null;
private boolean clickOpensContextMenu = false;
// Visible for testing.
- ListAdapter indexAdapter = null;
+ private ListAdapter indexAdapter = null;
/**
* For some languages, loading the transliterators used in this search takes
final Intent intent = getIntent();
String intentAction = intent.getAction();
- /**
- * @author Dominik Köppl Querying the Intent
+ /*
+ @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
}
}
- /**
- * @author Dominik Köppl Querying the Intent Intent.ACTION_SEARCH is a
+ /*
+ @author Dominik Köppl Querying the Intent Intent.ACTION_SEARCH is a
* simple query Arguments follow from android standard (see
* documentation)
*/
return;
}
}
- /**
- * @author Dominik Köppl If no dictionary is chosen, use the default
+ /*
+ @author Dominik Köppl If no dictionary is chosen, use the default
* dictionary specified in the preferences If this step does
* fail (no default dictionary specified), show a toast and
* abort.
finish();
return;
}
- if (dictRaf == null && dictFilename != null)
+ if (dictRaf == null)
dictFile = new File(dictFilename);
ttsReady = false;
}).start();
String fontName = prefs.getString(getString(R.string.fontKey), "FreeSerif.otf.jpg");
- if ("SYSTEM".equals(fontName)) {
- typeface = Typeface.DEFAULT;
- } else if ("SERIF".equals(fontName)) {
- typeface = Typeface.SERIF;
- } else if ("SANS_SERIF".equals(fontName)) {
- typeface = Typeface.SANS_SERIF;
- } else if ("MONOSPACE".equals(fontName)) {
- typeface = Typeface.MONOSPACE;
- } else {
- if ("FreeSerif.ttf.jpg".equals(fontName)) {
- fontName = "FreeSerif.otf.jpg";
- }
- try {
- typeface = Typeface.createFromAsset(getAssets(), fontName);
- } catch (Exception e) {
- Log.w(LOG, "Exception trying to use typeface, using default.", e);
- Toast.makeText(this, getString(R.string.fontFailure, e.getLocalizedMessage()),
- Toast.LENGTH_LONG).show();
- }
+ switch (fontName) {
+ case "SYSTEM":
+ typeface = Typeface.DEFAULT;
+ break;
+ case "SERIF":
+ typeface = Typeface.SERIF;
+ break;
+ case "SANS_SERIF":
+ typeface = Typeface.SANS_SERIF;
+ break;
+ case "MONOSPACE":
+ typeface = Typeface.MONOSPACE;
+ break;
+ default:
+ if ("FreeSerif.ttf.jpg".equals(fontName)) {
+ fontName = "FreeSerif.otf.jpg";
+ }
+ try {
+ typeface = Typeface.createFromAsset(getAssets(), fontName);
+ } catch (Exception e) {
+ Log.w(LOG, "Exception trying to use typeface, using default.", e);
+ Toast.makeText(this, getString(R.string.fontFailure, e.getLocalizedMessage()),
+ Toast.LENGTH_LONG).show();
+ }
+ break;
}
if (typeface == null) {
Log.w(LOG, "Unable to create typeface, using default.");
showKeyboard();
}
- @Override
- protected void onPause() {
- super.onPause();
- }
-
- @Override
/**
* Invoked when MyWebView returns, since the user might have clicked some
* hypertext in the MyWebView.
*/
+ @Override
protected void onActivityResult(int requestCode, int resultCode, Intent result) {
super.onActivityResult(requestCode, resultCode, result);
if (result != null && result.hasExtra(C.SEARCH_TOKEN)) {
manager.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
}
- void updateLangButton() {
+ private void updateLangButton() {
final int flagId = IsoUtils.INSTANCE.getFlagIdForIsoCode(index.shortName);
if (flagId != 0) {
languageButton.setImageResource(flagId);
searchView.getQuery().toString(), false);
}
- void onLanguageButtonLongClick(final Context context) {
+ private void onLanguageButtonLongClick(final Context context) {
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.select_dictionary_dialog);
dialog.setTitle(R.string.selectDictionary);
for (int i = 0; dictionaryInfo.indexInfos != null && i < dictionaryInfo.indexInfos.size(); ++i) {
final IndexInfo indexInfo = dictionaryInfo.indexInfos.get(i);
final View button = IsoUtils.INSTANCE.createButton(parent.getContext(),
- dictionaryInfo, indexInfo, application.languageButtonPixels);
+ indexInfo, application.languageButtonPixels);
final IntentLauncher intentLauncher = new IntentLauncher(parent.getContext(),
getLaunchIntent(getApplicationContext(),
application.getPath(dictionaryInfo.uncompressedFilename),
dialog.show();
}
- void onUpDownButton(final boolean up) {
+ private void onUpDownButton(final boolean up) {
if (isFiltered()) {
return;
}
defocusSearchText();
}
- void onRandomWordButton() {
+ private void onRandomWordButton() {
int destIndexEntry = rand.nextInt(index.sortedIndexEntries.size());
final Index.IndexEntry dest = index.sortedIndexEntries.get(destIndexEntry);
setSearchText(dest.token, false);
// Options Menu
// --------------------------------------------------------------------------
- final Random random = new Random();
-
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
});
}
- randomWordMenuItem = menu.add(getString(R.string.randomWord));
+ final MenuItem randomWordMenuItem = menu.add(getString(R.string.randomWord));
randomWordMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
Log.w(LOG, "Skipping findExact on index " + index.shortName);
}
}
- if (numFound != 1 || indexToUse == -1) {
+ if (numFound != 1) {
indexToUse = defaultIndexToUse;
}
// Without this extra delay, the call to jumpToRow that this
* Called when user clicks outside of search text, so that they can start
* typing again immediately.
*/
- void defocusSearchText() {
+ private void defocusSearchText() {
// Log.d(LOG, "defocusSearchText");
// Request focus so that if we start typing again, it clears the text
// input.
// searchView.selectAll();
}
- protected void onListItemClick(ListView l, View v, int rowIdx, long id) {
+ private void onListItemClick(ListView l, View v, int rowIdx, long id) {
defocusSearchText();
if (clickOpensContextMenu && dictRaf != null) {
openContextMenu(v);
}
@SuppressLint("SimpleDateFormat")
- void onAppendToWordList(final RowBase row) {
+ private void onAppendToWordList(final RowBase row) {
defocusSearchText();
final StringBuilder rawText = new StringBuilder();
getString(R.string.failedAddingToWordList, wordList.getAbsolutePath()),
Toast.LENGTH_LONG).show();
}
- return;
}
@SuppressWarnings("deprecation")
- void onCopy(final RowBase row) {
+ private void onCopy(final RowBase row) {
defocusSearchText();
Log.d(LOG, "Copy, row=" + row);
// Disable the listener, because sometimes it doesn't work.
searchView.setOnQueryTextListener(null);
searchView.setQuery(text, false);
- moveCursorToRight();
searchView.setOnQueryTextListener(onQueryTextListener);
if (triggerSearch) {
setSearchText(text, triggerSearch, true);
}
- // private long cursorDelayMillis = 100;
- private void moveCursorToRight() {
- // if (searchText.getLayout() != null) {
- // cursorDelayMillis = 100;
- // // Surprising, but this can crash when you rotate...
- // Selection.moveToRightEdge(searchView.getQuery(),
- // searchText.getLayout());
- // } else {
- // uiHandler.postDelayed(new Runnable() {
- // @Override
- // public void run() {
- // moveCursorToRight();
- // }
- // }, cursorDelayMillis);
- // cursorDelayMillis = Math.min(10 * 1000, 2 * cursorDelayMillis);
- // }
- }
-
// --------------------------------------------------------------------------
// SearchOperation
// --------------------------------------------------------------------------
getListView().setSelected(true);
}
- static final Pattern WHITESPACE = Pattern.compile("\\s+");
+ private static final Pattern WHITESPACE = Pattern.compile("\\s+");
final class SearchOperation implements Runnable {
0);
}
- static ViewGroup.LayoutParams WEIGHT_1 = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, 1.0f);
-
- static ViewGroup.LayoutParams WEIGHT_0 = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, 0.0f);
-
final class IndexAdapter extends BaseAdapter {
private static final float PADDING_DEFAULT_DP = 8;
IndexAdapter(final Index index, final List<RowBase> rows, final List<String> toHighlight) {
this.index = index;
this.rows = rows;
- this.toHighlight = new LinkedHashSet<String>(toHighlight);
+ this.toHighlight = new LinkedHashSet<>(toHighlight);
getMetrics();
}
}
- static final Pattern CHAR_DASH = Pattern.compile("['\\p{L}\\p{M}\\p{N}]+");
+ private 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) {
}
}
- String selectedSpannableText = null;
+ private String selectedSpannableText = null;
- int selectedSpannableIndex = -1;
+ private int selectedSpannableIndex = -1;
@Override
public boolean onTouchEvent(MotionEvent event) {
}
}
- final TextViewLongClickListener textViewLongClickListenerIndex0 = new TextViewLongClickListener(
+ private final TextViewLongClickListener textViewLongClickListenerIndex0 = new TextViewLongClickListener(
0);
- final TextViewLongClickListener textViewLongClickListenerIndex1 = new TextViewLongClickListener(
+ private final TextViewLongClickListener textViewLongClickListenerIndex1 = new TextViewLongClickListener(
1);
// --------------------------------------------------------------------------
// SearchText
// --------------------------------------------------------------------------
- void onSearchTextChange(final String text) {
+ private void onSearchTextChange(final String text) {
if ("thadolina".equals(text)) {
final Dialog dialog = new Dialog(getListView().getContext());
dialog.setContentView(R.layout.thadolina_dialog);
// Filtered results.
// --------------------------------------------------------------------------
- boolean isFiltered() {
+ private boolean isFiltered() {
return rowsToShow != null;
}
- void setFiltered(final SearchOperation searchOperation) {
+ private void setFiltered(final SearchOperation searchOperation) {
if (nextWordMenuItem != null) {
nextWordMenuItem.setEnabled(false);
previousWordMenuItem.setEnabled(false);
setListAdapter(new IndexAdapter(index, rowsToShow, searchOperation.searchTokens));
}
- void clearFiltered() {
+ private void clearFiltered() {
if (nextWordMenuItem != null) {
nextWordMenuItem.setEnabled(true);
previousWordMenuItem.setEnabled(true);
package com.hughes.android.dictionary;
-import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
-import android.view.View;
-import android.widget.Button;
-import android.widget.ImageButton;
-import android.widget.ImageView.ScaleType;
-import android.widget.LinearLayout;
-import android.widget.Toast;
import com.hughes.android.dictionary.CollatorWrapper;
import com.hughes.android.dictionary.DictionaryInfo.IndexInfo;
import com.hughes.android.dictionary.engine.Dictionary;
-import com.hughes.android.dictionary.engine.Language;
-import com.hughes.android.dictionary.engine.Language.LanguageResources;
import com.hughes.android.dictionary.engine.TransliteratorManager;
import com.hughes.android.util.PersistentObjectCache;
import com.hughes.util.ListUtil;
private static final long serialVersionUID = -1444177164708201263L;
// User-ordered list, persisted, just the ones that are/have been
// present.
- final List<String> dictionaryFilesOrdered = new ArrayList<String>();
+ final List<String> dictionaryFilesOrdered = new ArrayList<>();
- final Map<String, DictionaryInfo> uncompressedFilenameToDictionaryInfo = new HashMap<String, DictionaryInfo>();
+ final Map<String, DictionaryInfo> uncompressedFilenameToDictionaryInfo = new HashMap<>();
/**
* Sometimes a deserialized version of this data structure isn't valid.
- * @return
*/
+ @SuppressWarnings("ConstantConditions")
boolean isValid() {
return uncompressedFilenameToDictionaryInfo != null && dictionaryFilesOrdered != null;
}
if (DOWNLOADABLE_UNCOMPRESSED_FILENAME_NAME_TO_DICTIONARY_INFO != null) {
return;
}
- DOWNLOADABLE_UNCOMPRESSED_FILENAME_NAME_TO_DICTIONARY_INFO = new HashMap<String, DictionaryInfo>();
+ DOWNLOADABLE_UNCOMPRESSED_FILENAME_NAME_TO_DICTIONARY_INFO = new HashMap<>();
final BufferedReader reader = new BufferedReader(
new InputStreamReader(context.getResources().openRawResource(R.raw.dictionary_info)));
try {
} catch (IOException e) {}
}
- private File dictDir;
-
public synchronized void init(Context c) {
if (appContext != null) {
assert c == appContext;
if (dir.isEmpty()) {
dir = selectDefaultDir();
}
- dictDir = new File(dir);
+ File dictDir = new File(dir);
dictDir.mkdirs();
if (!dictDir.isDirectory() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
appContext.getExternalFilesDirs(null);
String defaultLangISO2 = Locale.getDefault().getLanguage().toLowerCase();
String defaultLangName = null;
- final Map<String, String> fileToNameCache = new HashMap<String, String>();
+ final Map<String, String> fileToNameCache = new HashMap<>();
public List<IndexInfo> sortedIndexInfos(List<IndexInfo> indexInfos) {
// Hack to put the default locale first in the name.
if (indexInfos.size() > 1 &&
indexInfos.get(1).shortName.toLowerCase().equals(defaultLangISO2)) {
- List<IndexInfo> result = new ArrayList<DictionaryInfo.IndexInfo>(indexInfos);
+ List<IndexInfo> result = new ArrayList<>(indexInfos);
ListUtil.swap(result, 0, 1);
return result;
}
PersistentObjectCache.getInstance().write(C.DICTIONARY_CONFIGS, dictionaryConfig);
}
- final Comparator collator = USE_COLLATOR ? CollatorWrapper.getInstance() : String.CASE_INSENSITIVE_ORDER;
+ final Comparator<Object> collator = USE_COLLATOR ? CollatorWrapper.getInstance() : null;
final Comparator<String> uncompressedFilenameComparator = new Comparator<String>() {
@Override
public int compare(String uncompressedFilename1, String uncompressedFilename2) {
return 1;
}
}
- return collator.compare(name1, name2);
+ return collator != null ? collator.compare(name1, name2) : name1.compareToIgnoreCase(name2);
}
};
final Comparator<DictionaryInfo> dictionaryInfoComparator = new Comparator<DictionaryInfo>() {
// Are there dictionaries on the device that we didn't know
// about already?
// Pick them up and put them at the end of the list.
- final List<String> toAddSorted = new ArrayList<String>();
+ final List<String> toAddSorted = new ArrayList<>();
final File[] dictDirFiles = getDictDir().listFiles();
if (dictDirFiles != null) {
for (final File file : dictDirFiles) {
}).start();
}
- public boolean matchesFilters(final DictionaryInfo dictionaryInfo, final String[] filters) {
+ private boolean matchesFilters(final DictionaryInfo dictionaryInfo, final String[] filters) {
if (filters == null) {
return true;
}
}
public synchronized List<DictionaryInfo> getDictionariesOnDevice(String[] filters) {
- final List<DictionaryInfo> result = new ArrayList<DictionaryInfo>(
- dictionaryConfig.dictionaryFilesOrdered.size());
+ final List<DictionaryInfo> result = new ArrayList<>(
+ dictionaryConfig.dictionaryFilesOrdered.size());
for (final String uncompressedFilename : dictionaryConfig.dictionaryFilesOrdered) {
final DictionaryInfo dictionaryInfo = dictionaryConfig.uncompressedFilenameToDictionaryInfo
.get(uncompressedFilename);
}
public List<DictionaryInfo> getDownloadableDictionaries(String[] filters) {
- final List<DictionaryInfo> result = new ArrayList<DictionaryInfo>(
- dictionaryConfig.dictionaryFilesOrdered.size());
+ final List<DictionaryInfo> result = new ArrayList<>(
+ dictionaryConfig.dictionaryFilesOrdered.size());
- final Map<String, DictionaryInfo> remaining = new HashMap<String, DictionaryInfo>(
- DOWNLOADABLE_UNCOMPRESSED_FILENAME_NAME_TO_DICTIONARY_INFO);
+ final Map<String, DictionaryInfo> remaining = new HashMap<>(
+ DOWNLOADABLE_UNCOMPRESSED_FILENAME_NAME_TO_DICTIONARY_INFO);
remaining.keySet().removeAll(dictionaryConfig.dictionaryFilesOrdered);
for (final DictionaryInfo dictionaryInfo : remaining.values()) {
if (matchesFilters(dictionaryInfo, filters)) {
return result;
}
- public synchronized boolean isDictionaryOnDevice(String uncompressedFilename) {
- return dictionaryConfig.uncompressedFilenameToDictionaryInfo.get(uncompressedFilename) != null;
- }
-
public boolean updateAvailable(final DictionaryInfo dictionaryInfo) {
final DictionaryInfo downloadable =
DOWNLOADABLE_UNCOMPRESSED_FILENAME_NAME_TO_DICTIONARY_INFO.get(
}
public DictionaryInfo getDownloadable(final String uncompressedFilename) {
- final DictionaryInfo downloadable = DOWNLOADABLE_UNCOMPRESSED_FILENAME_NAME_TO_DICTIONARY_INFO
- .get(uncompressedFilename);
- return downloadable;
+ return DOWNLOADABLE_UNCOMPRESSED_FILENAME_NAME_TO_DICTIONARY_INFO.get(uncompressedFilename);
}
}
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.List;
public class DictionaryInfo implements Serializable {
public static final class IndexInfo implements Serializable {
private static final long serialVersionUID = 6524751236198309438L;
- public static final int NUM_CSV_FIELDS = 3;
+ static final int NUM_CSV_FIELDS = 3;
public final String shortName; // Often LangISO.
- public final int allTokenCount;
+ final int allTokenCount;
public final int mainTokenCount;
public IndexInfo(String shortName, int allTokenCount, int mainTokenCount) {
this.mainTokenCount = mainTokenCount;
}
- public StringBuilder append(StringBuilder result) {
+ void append(StringBuilder result) {
result.append(shortName);
result.append("\t").append(allTokenCount);
result.append("\t").append(mainTokenCount);
- return result;
}
public IndexInfo(final String[] fields, int i) {
public long uncompressedBytes;
public long zipBytes;
public long creationMillis;
- public final ArrayList<IndexInfo> indexInfos = new ArrayList<IndexInfo>();
+ public final ArrayList<IndexInfo> indexInfos = new ArrayList<>();
public String dictInfo;
public DictionaryInfo() {
import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.Settings;
+import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.support.v7.widget.Toolbar;
import android.text.InputType;
import android.util.Log;
-import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.BaseAdapter;
import android.widget.Button;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
// Right-click:
// Delete, move to top.
-public class DictionaryManagerActivity extends ActionBarActivity {
+public class DictionaryManagerActivity extends AppCompatActivity {
- static final String LOG = "QuickDic";
- static boolean blockAutoLaunch = false;
+ private static final String LOG = "QuickDic";
+ private static boolean blockAutoLaunch = false;
private ListView listView;
private ListView getListView() {
}
// For DownloadManager bug workaround
- private Set<Long> finishedDownloadIds = new HashSet<Long>();
+ private final Set<Long> finishedDownloadIds = new HashSet<>();
- DictionaryApplication application;
+ private DictionaryApplication application;
- SearchView filterSearchView;
- ToggleButton showDownloadable;
+ private SearchView filterSearchView;
+ private ToggleButton showDownloadable;
- LinearLayout dictionariesOnDeviceHeaderRow;
- LinearLayout downloadableDictionariesHeaderRow;
+ private LinearLayout dictionariesOnDeviceHeaderRow;
+ private LinearLayout downloadableDictionariesHeaderRow;
- Handler uiHandler;
+ private Handler uiHandler;
- Runnable dictionaryUpdater = new Runnable() {
+ private final Runnable dictionaryUpdater = new Runnable() {
@Override
public void run() {
if (uiHandler == null) {
uiHandler.post(new Runnable() {
@Override
public void run() {
- setMyListAdapater();
+ setMyListAdapter();
}
});
}
};
- final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public synchronized void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
return intent;
}
- public void readableCheckAndError(boolean requestPermission) {
+ private void readableCheckAndError(boolean requestPermission) {
final File dictDir = application.getDictDir();
if (dictDir.canRead() && dictDir.canExecute()) return;
blockAutoLaunch = true;
}
@Override
- public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
+ public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
readableCheckAndError(false);
application.backgroundUpdateDictionaries(dictionaryUpdater);
- setMyListAdapater();
+ setMyListAdapter();
}
@Override
registerReceiver(broadcastReceiver, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
- setMyListAdapater();
+ setMyListAdapter();
registerForContextMenu(getListView());
getListView().setItemsCanFocus(true);
@Override
public boolean onQueryTextChange(String filterText) {
- setMyListAdapater();
+ setMyListAdapter();
return true;
}
});
application.backgroundUpdateDictionaries(dictionaryUpdater);
- setMyListAdapater();
+ setMyListAdapter();
}
@Override
sort.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(final MenuItem menuItem) {
application.sortDictionaries();
- setMyListAdapater();
+ setMyListAdapter();
return true;
}
});
@Override
public boolean onMenuItemClick(android.view.MenuItem item) {
application.moveDictionaryToTop(row.dictionaryInfo);
- setMyListAdapater();
+ setMyListAdapter();
return true;
}
});
@Override
public boolean onMenuItemClick(android.view.MenuItem item) {
application.deleteDictionary(row.dictionaryInfo);
- setMyListAdapater();
+ setMyListAdapter();
return true;
}
});
}
private void onShowDownloadableChanged() {
- setMyListAdapater();
+ setMyListAdapter();
Editor prefs = PreferenceManager.getDefaultSharedPreferences(this).edit();
prefs.putBoolean(C.SHOW_DOWNLOADABLE, showDownloadable.isChecked());
prefs.commit();
class MyListAdapter extends BaseAdapter {
- List<DictionaryInfo> dictionariesOnDevice;
- List<DictionaryInfo> downloadableDictionaries;
+ final List<DictionaryInfo> dictionariesOnDevice;
+ final List<DictionaryInfo> downloadableDictionaries;
class Row {
- DictionaryInfo dictionaryInfo;
- boolean onDevice;
+ final DictionaryInfo dictionaryInfo;
+ final boolean onDevice;
private Row(DictionaryInfo dictionaryInfo, boolean onDevice) {
this.dictionaryInfo = dictionaryInfo;
}
- private void setMyListAdapater() {
+ private void setMyListAdapter() {
final String filter = filterSearchView == null ? "" : filterSearchView.getQuery()
.toString();
final String[] filters = filter.trim().toLowerCase().split("(\\s|-)+");
continue;
}
final IndexInfo indexInfo = sortedIndexInfos.get(i);
- final View button = IsoUtils.INSTANCE.setupButton(textButton, imageButton, dictionaryInfo,
- indexInfo, application.languageButtonPixels);
+ final View button = IsoUtils.INSTANCE.setupButton(textButton, imageButton,
+ indexInfo);
if (canLaunch) {
button.setOnClickListener(
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.AppCompatActivity;
import android.util.Base64;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
-import android.view.View.OnClickListener;
import android.widget.Button;
import com.hughes.util.StringUtil;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
-public final class HtmlDisplayActivity extends ActionBarActivity {
+public final class HtmlDisplayActivity extends AppCompatActivity {
- static final String LOG = "QuickDic";
+ private static final String LOG = "QuickDic";
- static final String HTML_RES = "html_res";
- static final String HTML = "html";
- static final String TEXT_TO_HIGHLIGHT = "textToHighlight";
- static final String SHOW_OK_BUTTON = "showOKButton";
+ private static final String HTML_RES = "html_res";
+ private static final String HTML = "html";
+ private static final String TEXT_TO_HIGHLIGHT = "textToHighlight";
+ private static final String SHOW_OK_BUTTON = "showOKButton";
public static Intent getHelpLaunchIntent(Context c) {
final Intent intent = new Intent(c, HtmlDisplayActivity.class);
// Useful:
// http://www.loc.gov/standards/iso639-2/php/code_list.php
- private final Map<String, LanguageResources> isoCodeToResources = new HashMap<String, LanguageResources>();
+ private final Map<String, LanguageResources> isoCodeToResources = new HashMap<>();
IsoUtils() {
isoCodeToResources.put("AF", new LanguageResources("Afrikaans", R.string.AF,
R.drawable.flag_of_south_africa));
isoCodeToResources.put("LO", new LanguageResources("Lao", R.string.LO,
R.drawable.flag_of_laos));
isoCodeToResources.put("ML", new LanguageResources("Malayalam", R.string.ML));
- isoCodeToResources.put("SL", new LanguageResources("Slovenian", R.string.SL,
- R.drawable.flag_of_slovenia));
isoCodeToResources.put("TA", new LanguageResources("Tamil", R.string.TA));
isoCodeToResources.put("SH", new LanguageResources("Serbo-Croatian", R.string.SH));
isoCodeToResources.put("SD", new LanguageResources("Sindhi", R.string.SD));
// Hack to allow lower-case ISO codes to work:
- for (final String isoCode : new ArrayList<String>(isoCodeToResources.keySet())) {
+ for (final String isoCode : new ArrayList<>(isoCodeToResources.keySet())) {
isoCodeToResources.put(isoCode.toLowerCase(), isoCodeToResources.get(isoCode));
}
}
return lang;
}
- public View createButton(final Context context, final DictionaryInfo dictionaryInfo,
+ public View createButton(final Context context,
final IndexInfo indexInfo, int size) {
LanguageResources languageResources = isoCodeToResources.get(indexInfo.shortName);
View result;
}
public View setupButton(Button textButton, ImageButton imageButton,
- final DictionaryInfo dictionaryInfo,
- final IndexInfo indexInfo, int size) {
+ final IndexInfo indexInfo) {
LanguageResources languageResources = isoCodeToResources.get(indexInfo.shortName);
View result;
public class MyWebView extends WebView {
- static final String LOG = "MyWebView";
+ private static final String LOG = "MyWebView";
HtmlDisplayActivity activity;
- public static void quickdicUrlToIntent(final String url, final Intent intent) {
+ private static void quickdicUrlToIntent(final String url, final Intent intent) {
int firstColon = url.indexOf("?");
if (firstColon == -1)
return;
prefs.edit().putString(getString(R.string.wordListFileKey), application.getWordListFile().getAbsolutePath()).commit();
}
- /**
- * @author Dominik Köppl Preference: select default dictionary As this
+ /*
+ @author Dominik Köppl Preference: select default dictionary As this
* list is dynamically generated, we have to do it in this
* fashion
*/
prefs.registerOnSharedPreferenceChangeListener(this);
}
- @Override
- public void onContentChanged() {
- super.onContentChanged();
- }
-
@Override
public void onSharedPreferenceChanged(SharedPreferences p, String v) {
DictionaryApplication.INSTANCE.init(getApplicationContext());
public final EntrySource entrySource;
- protected AbstractEntry(EntrySource entrySource) {
+ AbstractEntry(EntrySource entrySource) {
super(-1);
this.entrySource = entrySource;
}
- public AbstractEntry(Dictionary dictionary, DataInput raf, final int index)
+ AbstractEntry(Dictionary dictionary, DataInput raf, final int index)
throws IOException {
super(index);
if (dictionary.dictFileVersion >= 1) {
- final int entrySouceIdx = dictionary.dictFileVersion >= 7 ? StringUtil.readVarInt(raf) : raf.readShort();
- this.entrySource = dictionary.sources.get(entrySouceIdx);
+ final int entrySourceIdx = dictionary.dictFileVersion >= 7 ? StringUtil.readVarInt(raf) : raf.readShort();
+ this.entrySource = dictionary.sources.get(entrySourceIdx);
} else {
this.entrySource = null;
}
}
- public void write(DataOutput raf) throws IOException {
+ void write(DataOutput raf) throws IOException {
StringUtil.writeVarInt(raf, entrySource.index());
}
import com.hughes.android.dictionary.DictionaryInfo;
import com.hughes.util.CachingList;
-import com.hughes.util.StringUtil;
import com.hughes.util.raf.RAFList;
import com.hughes.util.raf.RAFListSerializer;
import com.hughes.util.raf.RAFSerializable;
public class Dictionary implements RAFSerializable<Dictionary> {
- static final int CACHE_SIZE = 5000;
+ private static final int CACHE_SIZE = 5000;
- static final int CURRENT_DICT_VERSION = 7;
- static final String END_OF_DICTIONARY = "END OF DICTIONARY";
+ private static final int CURRENT_DICT_VERSION = 7;
+ private static final String END_OF_DICTIONARY = "END OF DICTIONARY";
// persisted
final int dictFileVersion;
- final long creationMillis;
+ private final long creationMillis;
public final String dictInfo;
public final List<PairEntry> pairEntries;
public final List<TextEntry> textEntries;
this.dictFileVersion = CURRENT_DICT_VERSION;
this.creationMillis = System.currentTimeMillis();
this.dictInfo = dictInfo;
- pairEntries = new ArrayList<PairEntry>();
- textEntries = new ArrayList<TextEntry>();
- htmlEntries = new ArrayList<HtmlEntry>();
+ pairEntries = new ArrayList<>();
+ textEntries = new ArrayList<>();
+ htmlEntries = new ArrayList<>();
htmlData = null;
- sources = new ArrayList<EntrySource>();
- indices = new ArrayList<Index>();
+ sources = new ArrayList<>();
+ indices = new ArrayList<>();
}
public Dictionary(final FileChannel ch) throws IOException {
try {
final RAFList<EntrySource> rafSources = RAFList.create(ch, new EntrySource.Serializer(
this), ch.position(), dictFileVersion, dictInfo + " sources: ");
- sources = new ArrayList<EntrySource>(rafSources);
+ sources = new ArrayList<>(rafSources);
ch.position(rafSources.getEndOffset());
pairEntries = CachingList.create(
indices = CachingList.createFullyCached(RAFList.create(ch, new IndexSerializer(ch),
ch.position(), dictFileVersion, dictInfo + " index: "));
} catch (RuntimeException e) {
- final IOException ioe = new IOException("RuntimeException loading dictionary", e);
- throw ioe;
+ throw new IOException("RuntimeException loading dictionary", e);
}
final String end = raf.readUTF();
if (!end.equals(END_OF_DICTIONARY)) {
private final class IndexSerializer implements RAFListSerializer<Index> {
private final FileChannel ch;
- public IndexSerializer(FileChannel ch) {
+ IndexSerializer(FileChannel ch) {
this.ch = ch;
}
public class EntrySource extends IndexedObject {
final String name;
+ @SuppressWarnings("CanBeFinal")
int numEntries;
+ @SuppressWarnings("WeakerAccess")
public EntrySource(final int index, final String name, int numEntries) {
super(index);
this.name = name;
+++ /dev/null
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// 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
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.hughes.android.dictionary.engine;
-
-public enum EntryTypeName {
-
- WIKTIONARY_TITLE_SINGLE_DETAIL(true, true, null),
- WIKTIONARY_TITLE_SINGLE(true, true, null),
- WIKTIONARY_INFLECTD_FORM_SINGLE(false, true, null),
-
- ONE_WORD(true, true, null),
- MULTIROW_HEAD_ONE_WORD(true, true, null),
- MULTIROW_TAIL_ONE_WORD(false, true, null),
-
- SYNONYM_SINGLE(false, true, null),
- ANTONYM_SINGLE(false, true, null),
-
- WIKTIONARY_TITLE_MULTI_DETAIL(false, true, WIKTIONARY_TITLE_SINGLE_DETAIL),
- WIKTIONARY_TITLE_MULTI(false, true, WIKTIONARY_TITLE_SINGLE),
- WIKTIONARY_TRANSLITERATION(),
- // How we file "casa {f}, case {pl}" under "case"
- WIKTIONARY_INFLECTED_FORM_MULTI(false, true, WIKTIONARY_INFLECTD_FORM_SINGLE),
- WIKTIONARY_ENGLISH_DEF_WIKI_LINK(),
- WIKTIONARY_ENGLISH_DEF_OTHER_LANG(),
- WIKTIONARY_ENGLISH_DEF(),
-
- SYNONYM_MULTI(false, true, SYNONYM_SINGLE),
- ANTONYM_MULTI(false, true, ANTONYM_SINGLE),
- DERIVED_TERM(false, true, null),
-
- TWO_WORDS(),
- THREE_WORDS(),
- FOUR_WORDS(),
- FIVE_OR_MORE_WORDS(),
- WIKTIONARY_TRANSLATION_WIKI_TEXT(),
- WIKTIONARY_TRANSLATION_OTHER_TEXT(),
-
- // How we file entries like: "sono: {form of|essere}" under "sono.".
- WIKTIONARY_IS_FORM_OF_SOMETHING_ELSE(false, true, null),
-
- MULTIROW_HEAD_MANY_WORDS(),
- MULTIROW_TAIL_MANY_WORDS(),
- WIKTIONARY_EXAMPLE(),
-
- // The next two are how we file entries like: "sono: {form of|essere}" under
- // "essere".
- WIKTIONARY_BASE_FORM_SINGLE(), // These two should be eligible for removal
- // if the links are otherwise present.
- WIKTIONARY_BASE_FORM_MULTI(false, false, WIKTIONARY_BASE_FORM_SINGLE),
- PART_OF_HYPHENATED(),
- BRACKETED(),
- PARENTHESIZED(),
- WIKTIONARY_TRANSLATION_SENSE(),
- SEE_ALSO(),
- WIKTIONARY_MENTIONED(false, true, null), ;
-
- final boolean mainWord;
- final boolean overridesStopList;
- final EntryTypeName singleWordInstance;
-
- EntryTypeName() {
- this(false, false, null);
- }
-
- EntryTypeName(final boolean mainWord, final boolean overridesStopList,
- final EntryTypeName singleWordInstance) {
- this.mainWord = mainWord;
- this.overridesStopList = overridesStopList;
- this.singleWordInstance = singleWordInstance == null ? this : singleWordInstance;
- }
-
-}
import java.io.DataOutput;
import java.io.IOException;
import java.io.PrintStream;
-import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.lang.ref.SoftReference;
import java.nio.channels.FileChannel;
// Title is not HTML escaped.
public final String title;
- public final LazyHtmlLoader lazyHtmlLoader;
+ private final LazyHtmlLoader lazyHtmlLoader;
+ @SuppressWarnings("WeakerAccess")
public String html;
public HtmlEntry(final EntrySource entrySource, String title) {
html = null;
}
- public void writeBase(DataOutput raf) throws IOException {
+ private void writeBase(DataOutput raf) throws IOException {
super.write(raf);
raf.writeUTF(title);
}
- public void writeData(DataOutput raf) throws IOException {
+ private void writeData(DataOutput raf) throws IOException {
final byte[] bytes = getHtml().getBytes("UTF-8");
StringUtil.writeVarInt(raf, bytes.length);
raf.write(bytes);
}
- public static byte[] readData(DataInput raf) throws IOException {
+ private static byte[] readData(DataInput raf) throws IOException {
int len = StringUtil.readVarInt(raf);
final byte[] bytes = new byte[Math.min(len, 20 * 1024 * 1024)];
raf.readFully(bytes);
}
}
- public String getRawText(final boolean compact) {
+ private String getRawText(final boolean compact) {
return title + ":\n" + getHtml();
}
public static class Row extends RowBase {
- boolean isExpanded = false;
-
Row(final DataInput raf, final int thisRowIndex,
final Index index, int extra) throws IOException {
super(raf, thisRowIndex, index, extra);
return result.toString();
}
+ @SuppressWarnings("WeakerAccess")
public static String formatQuickdicUrl(final String indexShortName, final String text) {
assert !indexShortName.contains(":");
assert text.length() > 0;
// --------------------------------------------------------------------
+ @SuppressWarnings("WeakerAccess")
public static final class LazyHtmlLoader {
final DataInput raf;
final FileChannel ch;
final int index;
// Not sure this volatile is right, but oh well.
- volatile SoftReference<String> htmlRef = new SoftReference<String>(null);
+ volatile SoftReference<String> htmlRef = new SoftReference<>(null);
private LazyHtmlLoader(FileChannel ch, final DataInput inp, List<byte[]> data, int index) throws IOException {
this.data = data;
raf.skipBytes(numZipBytes);
}
- public String getHtml() {
+ String getHtml() {
String html = htmlRef.get();
if (html != null) {
return html;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Dictionary HTML data corrupted", e);
}
- htmlRef = new SoftReference<String>(html);
+ htmlRef = new SoftReference<>(html);
return html;
}
System.out.println("Loading Html: numBytes=" + numBytes + ", numZipBytes="
} catch (IOException e) {
throw new RuntimeException("Dictionary HTML data corrupted", e);
}
- htmlRef = new SoftReference<String>(html);
+ htmlRef = new SoftReference<>(html);
return html;
}
}
// See the License for the specific language governing permissions and
// limitations under the License.
-/**
- *
- */
-
package com.hughes.android.dictionary.engine;
import com.hughes.android.dictionary.DictionaryInfo;
import com.ibm.icu.text.Transliterator;
import java.io.DataInput;
-import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.IOException;
import java.io.PrintStream;
import java.io.RandomAccessFile;
-import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.util.AbstractList;
import java.util.ArrayList;
public final class Index implements RAFSerializable<Index> {
- static final int CACHE_SIZE = 5000;
+ private static final int CACHE_SIZE = 5000;
public final Dictionary dict;
// persisted: tells how the entries are sorted.
public final Language sortLanguage;
- final String normalizerRules;
+ private final String normalizerRules;
// Built from the two above.
private Transliterator normalizer;
public final List<IndexEntry> sortedIndexEntries;
// persisted.
- public final Set<String> stoplist;
+ private final Set<String> stoplist;
// One big list!
// Various sub-types.
public final boolean swapPairEntries;
// Version 2:
- int mainTokenCount = -1;
+ @SuppressWarnings("WeakerAccess")
+ public int mainTokenCount = -1;
// --------------------------------------------------------------------------
this.sortLanguage = sortLanguage;
this.normalizerRules = normalizerRules;
this.swapPairEntries = swapPairEntries;
- sortedIndexEntries = new ArrayList<IndexEntry>();
+ sortedIndexEntries = new ArrayList<>();
this.stoplist = stoplist;
- rows = new ArrayList<RowBase>();
+ rows = new ArrayList<>();
normalizer = null;
}
/**
* Deferred initialization because it can be slow.
*/
+ @SuppressWarnings("WeakerAccess")
public synchronized Transliterator normalizer() {
if (normalizer == null) {
normalizer = TransliteratorManager.get(normalizerRules);
* Note that using this comparator probably involves doing too many text
* normalizations.
*/
+ @SuppressWarnings("WeakerAccess")
public NormalizeComparator getSortComparator() {
return new NormalizeComparator(normalizer(), sortLanguage.getCollator(), dict.dictFileVersion);
}
dict.dictFileVersion, dict.dictInfo + " idx " + languageCode + ": "), CACHE_SIZE, true);
if (dict.dictFileVersion >= 7) {
int count = StringUtil.readVarInt(raf);
- stoplist = new HashSet<String>(count);
+ stoplist = new HashSet<>(count);
for (int i = 0; i < count; ++i) {
stoplist.add(raf.readUTF());
}
private final class IndexEntrySerializer implements RAFSerializer<IndexEntry> {
private final FileChannel ch;
- public IndexEntrySerializer(FileChannel ch) {
+ IndexEntrySerializer(FileChannel ch) {
this.ch = ch;
}
public final String token;
private final String normalizedToken;
public final int startRow;
- public final int numRows; // doesn't count the token row!
+ final int numRows; // doesn't count the token row!
public List<HtmlEntry> htmlEntries;
public IndexEntry(final Index index, final String token, final String normalizedToken,
this.normalizedToken = normalizedToken;
this.startRow = startRow;
this.numRows = numRows;
- this.htmlEntries = new ArrayList<HtmlEntry>();
+ this.htmlEntries = new ArrayList<>();
}
- public IndexEntry(final Index index, final FileChannel ch, final DataInput raf) throws IOException {
+ IndexEntry(final Index index, final FileChannel ch, final DataInput raf) throws IOException {
token = raf.readUTF();
if (index.dict.dictFileVersion >= 7) {
startRow = StringUtil.readVarInt(raf);
return String.format("%s@%d(%d)", token, startRow, numRows);
}
- public String normalizedToken() {
+ String normalizedToken() {
return normalizedToken;
}
}
- static final TransformingList.Transformer<IndexEntry, String> INDEX_ENTRY_TO_TOKEN = new TransformingList.Transformer<IndexEntry, String>() {
+ private static final TransformingList.Transformer<IndexEntry, String> INDEX_ENTRY_TO_TOKEN = new TransformingList.Transformer<IndexEntry, String>() {
@Override
public String transform(IndexEntry t1) {
return t1.token;
return index != -1 ? sortedIndexEntries.get(index) : null;
}
- private int compareIdx(String token, final Comparator sortCollator, int idx) {
+ private int compareIdx(String token, final Comparator<Object> sortCollator, int idx) {
final IndexEntry entry = sortedIndexEntries.get(idx);
return NormalizeComparator.compareWithoutDash(token, entry.normalizedToken(), sortCollator, dict.dictFileVersion);
}
- private int findMatchLen(final Comparator sortCollator, String a, String b) {
+ private int findMatchLen(final Comparator<Object> sortCollator, String a, String b) {
int start = 0;
int end = Math.min(a.length(), b.length());
while (start < end)
return start;
}
- public int findInsertionPointIndex(String token, final AtomicBoolean interrupted) {
+ private int findInsertionPointIndex(String token, final AtomicBoolean interrupted) {
token = normalizeToken(token);
int start = 0;
int end = sortedIndexEntries.size();
- final Comparator sortCollator = sortLanguage.getCollator();
+ final Comparator<Object> sortCollator = sortLanguage.getCollator();
while (start < end) {
final int mid = (start + end) / 2;
if (interrupted.get()) {
if (comp == 0)
comp = sortCollator.compare(token, midEntry.normalizedToken());
if (comp == 0) {
- final int result = windBackCase(token, mid, interrupted);
- return result;
+ return windBackCase(token, mid, interrupted);
} else if (comp < 0) {
// System.out.println("Upper bound: " + midEntry + ", norm=" +
// midEntry.normalizedToken() + ", mid=" + mid);
private static final int MAX_SEARCH_ROWS = 1000;
- private final Map<String, Integer> prefixToNumRows = new HashMap<String, Integer>();
+ private final Map<String, Integer> prefixToNumRows = new HashMap<>();
private synchronized final int getUpperBoundOnRowsStartingWith(final String normalizedPrefix,
final int maxRows, final AtomicBoolean interrupted) {
break;
}
}
- prefixToNumRows.put(normalizedPrefix, numRows);
+ prefixToNumRows.put(normalizedPrefix, rowCount);
return rowCount;
}
final String searchText, final List<String> searchTokens,
final AtomicBoolean interrupted) {
final long startMills = System.currentTimeMillis();
- final List<RowBase> result = new ArrayList<RowBase>();
+ final List<RowBase> result = new ArrayList<>();
- final Set<String> normalizedNonStoplist = new HashSet<String>();
+ final Set<String> normalizedNonStoplist = new HashSet<>();
String bestPrefix = null;
int leastRows = Integer.MAX_VALUE;
+ ", searchTokens=" + searchTokens);
// Place to store the things that match.
- final Map<RowMatchType, List<RowBase>> matches = new EnumMap<RowMatchType, List<RowBase>>(
- RowMatchType.class);
+ final Map<RowMatchType, List<RowBase>> matches = new EnumMap<>(
+ RowMatchType.class);
for (final RowMatchType rowMatchType : RowMatchType.values()) {
if (rowMatchType != RowMatchType.NO_MATCH) {
matches.put(rowMatchType, new ArrayList<RowBase>());
final String searchToken = bestPrefix;
final int insertionPointIndex = findInsertionPointIndex(searchToken, interrupted);
- final Set<RowKey> rowsAlreadySeen = new HashSet<RowBase.RowKey>();
+ final Set<RowKey> rowsAlreadySeen = new HashSet<>();
for (int index = insertionPointIndex; index < sortedIndexEntries.size()
&& matchCount < MAX_SEARCH_ROWS; ++index) {
if (interrupted.get()) {
final RowBase.LengthComparator lengthComparator = new RowBase.LengthComparator(
swapPairEntries);
for (final Collection<RowBase> rows : matches.values()) {
- final List<RowBase> ordered = new ArrayList<RowBase>(rows);
+ final List<RowBase> ordered = new ArrayList<>(rows);
Collections.sort(ordered, lengthComparator);
result.addAll(ordered);
}
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
-import java.util.regex.Pattern;
public class Language {
public static final class LanguageResources {
- public final String englishName;
+ final String englishName;
public final int nameId;
public final int flagId;
}
}
- private static final Map<String, Language> registry = new HashMap<String, Language>();
+ private static final Map<String, Language> registry = new HashMap<>();
- final String isoCode;
- final Locale locale;
-
- private Comparator collator;
+ private final String isoCode;
+ private final Locale locale;
private Language(final Locale locale, final String isoCode) {
this.locale = locale;
return isoCode;
}
- public synchronized Comparator getCollator() {
+ public synchronized Comparator<Object> getCollator() {
if (!DictionaryApplication.USE_COLLATOR)
- return String.CASE_INSENSITIVE_ORDER;
- // Don't think this is thread-safe...
- // if (collator == null) {
- this.collator = CollatorWrapper.getInstanceStrengthIdentical(locale);
- // }
- return collator;
+ return new Comparator<Object>() {
+ @Override
+ public int compare(Object o, Object t1) {
+ return String.class.cast(o).compareToIgnoreCase(String.class.cast(t1));
+ }
+ };
+ // TODO: consider if this should be cached - but must be thread-safe
+ return CollatorWrapper.getInstanceStrengthIdentical(locale);
}
public String getDefaultNormalizerRules() {
private static final String rtlChars =
"\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC";
- private static final String puncChars =
- "\\[\\]\\(\\)\\{\\}\\=";
-
- private static final Pattern RTL_LEFT_BOUNDARY = Pattern.compile("([" + puncChars + "])(["
- + rtlChars + "])");
- private static final Pattern RTL_RIGHT_BOUNDARY = Pattern.compile("([" + rtlChars + "])(["
- + puncChars + "])");
-
+ @SuppressWarnings("unused")
public static String fixBidiText(String text) {
- // text = RTL_LEFT_BOUNDARY.matcher(text).replaceAll("$1\u200e $2");
- // text = RTL_RIGHT_BOUNDARY.matcher(text).replaceAll("$1 \u200e$2");
+ // TODO: RTL text (e.g. arabic) in parenthesis might need extra
+ // \u200e markers sometimes - check what exactly is going on there.
return text;
}
// ----------------------------------------------------------------
public static final Language en = new Language(Locale.ENGLISH, "EN");
- public static final Language fr = new Language(Locale.FRENCH, "FR");
public static final Language it = new Language(Locale.ITALIAN, "IT");
public static final Language de = new Language(Locale.GERMAN, "DE") {
public class NormalizeComparator implements Comparator<String> {
- final Transliterator normalizer;
- final Comparator<String> comparator;
- int version;
+ private final Transliterator normalizer;
+ private final Comparator<Object> comparator;
+ private final int version;
public NormalizeComparator(final Transliterator normalizer,
- final Comparator<String> comparator, int version) {
+ final Comparator<Object> comparator, int version) {
this.normalizer = normalizer;
this.comparator = comparator;
this.version = version;
// Handles comparison between items containing "-".
// Also replaces other problematic cases like "thorn".
- public static int compareWithoutDash(final String a, final String b, final Comparator c, int version) {
+ public static int compareWithoutDash(final String a, final String b, final Comparator<Object> c, int version) {
if (version < 7) return 0;
String s1 = a.replace("-", "").replace("þ", "th").replace("Þ", "Th");
String s2 = b.replace("-", "").replace("þ", "th").replace("Þ", "Th");
package com.hughes.android.dictionary.engine;
import com.hughes.util.StringUtil;
-import com.hughes.util.raf.RAFListSerializer;
import com.hughes.util.raf.RAFListSerializerSkippable;
import com.hughes.util.raf.RAFSerializable;
import com.ibm.icu.text.Transliterator;
public PairEntry(final EntrySource entrySource) {
super(entrySource);
- pairs = new ArrayList<Pair>(1);
+ pairs = new ArrayList<>(1);
}
public PairEntry(final EntrySource entrySource, final String lang1, final String lang2) {
if (size == 1) pairs = Collections.singletonList(new Pair(raf.readUTF(), raf.readUTF()));
else
{
- pairs = new ArrayList<PairEntry.Pair>(size);
+ pairs = new ArrayList<>(size);
for (int i = 0; i < size; ++i) {
pairs.add(new Pair(raf.readUTF(), raf.readUTF()));
}
}
- public String getRawText(final boolean compact) {
+ private String getRawText(final boolean compact) {
if (compact) {
return this.pairs.get(0).toStringTab();
}
public final String lang1;
public final String lang2;
+ @SuppressWarnings("WeakerAccess")
public Pair(final String lang1, final String lang2) {
this.lang1 = lang1;
this.lang2 = lang2;
return lang1 + " :: " + lang2;
}
- public String toStringTab() {
+ String toStringTab() {
return lang1 + "\t" + lang2;
}
/**
* the Index owning this RowBase.
*/
- public final Index index;
+ final Index index;
/**
* Where this RowBase points to.
this.referenceIndex = extra == -1 ? raf.readInt() : ((extra << 16) + raf.readUnsignedShort()); // what this points to.
}
- public RowBase(final int referenceIndex, final int thisRowIndex, final Index index) {
+ RowBase(final int referenceIndex, final int thisRowIndex, final Index index) {
super(thisRowIndex);
this.index = index;
this.referenceIndex = referenceIndex;
return tokenRow;
}
- public void setTokenRow(TokenRow tokenRow) {
+ void setTokenRow(TokenRow tokenRow) {
assert this.tokenRow == null;
assert tokenRow != null;
this.tokenRow = tokenRow;
extra = rowType & 0x1f;
rowType = (rowType >> 5) - 1;
}
- if (rowType == 0) {
- return new PairEntry.Row(raf, listIndex, index, extra);
- } else if (rowType == 1 || rowType == 3) {
- return new TokenRow(raf, listIndex, index, /* hasMainEntry */rowType == 1, extra);
- } else if (rowType == 2) {
- return new TextEntry.Row(raf, listIndex, index, extra);
- } else if (rowType == 4) {
- return new HtmlEntry.Row(raf, listIndex, index, extra);
+ switch (rowType) {
+ case 0:
+ return new PairEntry.Row(raf, listIndex, index, extra);
+ case 1:
+ case 3:
+ return new TokenRow(raf, listIndex, index, /* hasMainEntry */rowType == 1, extra);
+ case 2:
+ return new TextEntry.Row(raf, listIndex, index, extra);
+ case 4:
+ return new HtmlEntry.Row(raf, listIndex, index, extra);
}
throw new RuntimeException("Invalid rowType:" + rowType);
}
}
}
- public int getSideLength(boolean swapPairEntries) {
+ int getSideLength(boolean swapPairEntries) {
return getRawText(false).length();
}
public class TextEntry extends AbstractEntry implements RAFSerializable<TextEntry> {
- final String text;
+ private final String text;
- public TextEntry(final Dictionary dictionary, final DataInput raf, final int index)
+ private TextEntry(final Dictionary dictionary, final DataInput raf, final int index)
throws IOException {
super(dictionary, raf, index);
text = raf.readUTF();
super(raf, thisRowIndex, index, extra);
}
- public TextEntry getEntry() {
+ TextEntry getEntry() {
return index.dict.textEntries.get(referenceIndex);
}
private static boolean starting = false;
private static boolean ready = false;
private static ThreadSetup threadSetup = null;
- private static LRUCacheMap<String, Transliterator> cache = new LRUCacheMap<String, Transliterator>(4);
+ private static final LRUCacheMap<String, Transliterator> cache = new LRUCacheMap<>(4);
// Whom to notify when we're all set up and ready to go.
- private static List<Callback> callbacks = new ArrayList<TransliteratorManager.Callback>();
+ private static final List<Callback> callbacks = new ArrayList<>();
public static Transliterator get(String rules) {
// DO NOT make the method synchronized!
// synchronizing on the class would break the whole
// asynchronous init concept, since the runnable
// then holds the same lock as the init function needs.
- Transliterator result = null;
+ Transliterator result;
synchronized (cache) {
result = cache.get(rules);
if (result == null) {
System.out.println("Wrong transliteration: " + transliterated);
}
- final List<Callback> callbacks = new ArrayList<TransliteratorManager.Callback>();
+ final List<Callback> callbacks;
synchronized (TransliteratorManager.class) {
- callbacks.addAll(TransliteratorManager.callbacks);
+ callbacks = new ArrayList<>(TransliteratorManager.callbacks);
ready = true;
}
for (final Callback callback : callbacks) {
public class IntentLauncher implements OnClickListener {
- final Context context;
- final Intent intent;
+ private final Context context;
+ private final Intent intent;
public IntentLauncher(final Context context, final Intent intent) {
this.context = context;
public class PersistentObjectCache {
private final File dir;
- private final Map<String, Object> objects = new HashMap<String, Object>();
+ private final Map<String, Object> objects = new HashMap<>();
class ConstrainedOIS extends ObjectInputStream {
- public ConstrainedOIS(InputStream in) throws IOException {
+ ConstrainedOIS(InputStream in) throws IOException {
super(in);
}