/* * Copyright (C) 2010-2011 Geometer Plus <contact@geometerplus.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ package org.geometerplus.android.fbreader; import java.util.*; import android.app.*; import android.content.*; import android.net.Uri; import android.util.DisplayMetrics; import android.view.Gravity; import org.geometerplus.zlibrary.core.filesystem.ZLFile; import org.geometerplus.zlibrary.core.filesystem.ZLResourceFile; import org.geometerplus.zlibrary.core.options.ZLStringOption; import org.geometerplus.zlibrary.core.resources.ZLResource; import org.geometerplus.zlibrary.core.xml.ZLXMLReaderAdapter; import org.geometerplus.zlibrary.core.xml.ZLStringMap; import org.geometerplus.zlibrary.text.view.ZLTextWordRegion; import org.geometerplus.zlibrary.ui.androidfly.library.ZLAndroidApplication; import org.geometerplus.android.util.UIUtil; import org.geometerplus.android.util.PackageUtil; public abstract class DictionaryUtil { // Map: dictionary info -> hide if package is not installed private static LinkedHashMap<PackageInfo,Boolean> ourDictionaryInfos = new LinkedHashMap<PackageInfo,Boolean>(); private static ZLStringOption ourDictionaryOption; private static class InfoReader extends ZLXMLReaderAdapter { @Override public boolean dontCacheAttributeValues() { return true; } @Override public boolean startElementHandler(String tag, ZLStringMap attributes) { if ("dictionary".equals(tag)) { final String id = attributes.getValue("id"); final String title = attributes.getValue("title"); ourDictionaryInfos.put(new PackageInfo( id, attributes.getValue("package"), attributes.getValue("class"), title != null ? title : id, attributes.getValue("action"), attributes.getValue("dataKey"), attributes.getValue("pattern") ), !"always".equals(attributes.getValue("list"))); } return false; } } private interface ColorDict3 { String ACTION = "colordict.intent.action.SEARCH"; String QUERY = "EXTRA_QUERY"; String HEIGHT = "EXTRA_HEIGHT"; String WIDTH = "EXTRA_WIDTH"; String GRAVITY = "EXTRA_GRAVITY"; String MARGIN_LEFT = "EXTRA_MARGIN_LEFT"; String MARGIN_TOP = "EXTRA_MARGIN_TOP"; String MARGIN_BOTTOM = "EXTRA_MARGIN_BOTTOM"; String MARGIN_RIGHT = "EXTRA_MARGIN_RIGHT"; String FULLSCREEN = "EXTRA_FULLSCREEN"; } private static Map<PackageInfo,Boolean> infos() { if (ourDictionaryInfos.isEmpty()) {//hym 修改 把dictionaries.xml 放到了default目录下面 new InfoReader().read(ZLResourceFile.createResourceFile("default/dictionaries.xml")); } return ourDictionaryInfos; } public static List<PackageInfo> dictionaryInfos(Context context) { final LinkedList<PackageInfo> list = new LinkedList<PackageInfo>(); for (Map.Entry<PackageInfo,Boolean> entry : infos().entrySet()) { final PackageInfo info = entry.getKey(); if (!entry.getValue() || PackageUtil.canBeStarted(context, getDictionaryIntent(info, "test"))) { list.add(info); } } return list; } private static PackageInfo firstInfo() { for (Map.Entry<PackageInfo,Boolean> entry : infos().entrySet()) { if (!entry.getValue()) { return entry.getKey(); } } throw new RuntimeException("There are no available dictionary infos"); } public static ZLStringOption dictionaryOption() { if (ourDictionaryOption == null) { ourDictionaryOption = new ZLStringOption("Dictionary", "Id", firstInfo().Id); } return ourDictionaryOption; } private static PackageInfo getCurrentDictionaryInfo() { final String id = dictionaryOption().getValue(); for (PackageInfo info : infos().keySet()) { if (info.Id.equals(id)) { return info; } } return firstInfo(); } private static Intent getDictionaryIntent(String text) { return getDictionaryIntent(getCurrentDictionaryInfo(), text); } public static Intent getDictionaryIntent(PackageInfo dictionaryInfo, String text) { final Intent intent = new Intent(dictionaryInfo.IntentAction); if (dictionaryInfo.PackageName != null) { String cls = dictionaryInfo.ClassName; if (cls != null && cls.startsWith(".")) { cls = dictionaryInfo.PackageName + cls; } intent.setComponent(new ComponentName( dictionaryInfo.PackageName, cls )); } intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); text = dictionaryInfo.IntentDataPattern.replace("%s", text); if (dictionaryInfo.IntentKey != null) { return intent.putExtra(dictionaryInfo.IntentKey, text); } else { return intent.setData(Uri.parse(text)); } } public static void openWordInDictionary(Activity activity, ZLTextWordRegion region) { String text = region.Word.toString(); int start = 0; int end = text.length(); for (; start < end && !Character.isLetterOrDigit(text.charAt(start)); ++start); for (; start < end && !Character.isLetterOrDigit(text.charAt(end - 1)); --end); if (start == end) { return; } final PackageInfo info = getCurrentDictionaryInfo(); final Intent intent = getDictionaryIntent(info, text.substring(start, end)); try { if ("ColorDict".equals(info.Id)) { final DisplayMetrics metrics = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); final int screenHeight = metrics.heightPixels; final int topSpace = region.getTop(); final int bottomSpace = metrics.heightPixels - region.getBottom(); final boolean showAtBottom = bottomSpace >= topSpace; final int space = (showAtBottom ? bottomSpace : topSpace) - 20; final int maxHeight = Math.min(400, screenHeight * 2 / 3); final int minHeight = Math.min(200, screenHeight * 2 / 3); intent.putExtra(ColorDict3.HEIGHT, Math.max(minHeight, Math.min(maxHeight, space))); intent.putExtra(ColorDict3.GRAVITY, showAtBottom ? Gravity.BOTTOM : Gravity.TOP); final ZLAndroidApplication application = ZLAndroidApplication.Instance(); intent.putExtra(ColorDict3.FULLSCREEN, !application.ShowStatusBarOption.getValue()); } activity.startActivity(intent); } catch(ActivityNotFoundException e){ DictionaryUtil.installDictionaryIfNotInstalled(activity); } } public static void installDictionaryIfNotInstalled(final Activity activity) { if (PackageUtil.canBeStarted(activity, getDictionaryIntent("test"))) { return; } final PackageInfo dictionaryInfo = getCurrentDictionaryInfo(); final ZLResource dialogResource = ZLResource.resource("dialog"); final ZLResource buttonResource = dialogResource.getResource("button"); final ZLResource installResource = dialogResource.getResource("installDictionary"); new AlertDialog.Builder(activity) .setTitle(installResource.getResource("title").getValue()) .setMessage(installResource.getResource("message").getValue().replace("%s", dictionaryInfo.Title)) .setIcon(0) .setPositiveButton( buttonResource.getResource("install").getValue(), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { installDictionary(activity, dictionaryInfo); } } ) .setNegativeButton(buttonResource.getResource("skip").getValue(), null) .create().show(); } private static void installDictionary(Activity activity, PackageInfo dictionaryInfo) { if (!PackageUtil.installFromMarket(activity, dictionaryInfo.PackageName)) { UIUtil.showErrorMessage(activity, "cannotRunAndroidMarket", dictionaryInfo.Title); } } }