X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=src%2Fcom%2Fhughes%2Fandroid%2Fdictionary%2FDictionaryManagerActivity.java;h=dacc6d75cd2c806fc72317d2c96b78cec0a9731c;hb=4f0e2b9302b6c3921e444467bb295f0ed6db1b99;hp=85e13738392136708f6ec2bdf688ba147768f065;hpb=4a0a832b09c2e1c189701b4b9e2529b37592e0b0;p=Dictionary.git diff --git a/src/com/hughes/android/dictionary/DictionaryManagerActivity.java b/src/com/hughes/android/dictionary/DictionaryManagerActivity.java index 85e1373..dacc6d7 100644 --- a/src/com/hughes/android/dictionary/DictionaryManagerActivity.java +++ b/src/com/hughes/android/dictionary/DictionaryManagerActivity.java @@ -15,7 +15,6 @@ package com.hughes.android.dictionary; import android.app.AlertDialog; -import android.app.Dialog; import android.app.DownloadManager; import android.app.DownloadManager.Request; import android.content.BroadcastReceiver; @@ -30,35 +29,33 @@ import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.preference.PreferenceManager; +import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; +import android.support.v7.widget.SearchView; +import android.support.v7.widget.SearchView.OnQueryTextListener; import android.util.Log; import android.util.TypedValue; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.LayoutInflater; +import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; -import android.view.View.OnLongClickListener; -import android.view.inputmethod.EditorInfo; import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.CompoundButton; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.Toast; import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.FrameLayout; import android.widget.LinearLayout; +import android.widget.ListAdapter; +import android.widget.ListView; import android.widget.TextView; +import android.widget.Toast; import android.widget.ToggleButton; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.app.SherlockListActivity; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.widget.SearchView; -import com.actionbarsherlock.widget.SearchView.OnQueryTextListener; import com.hughes.android.dictionary.DictionaryInfo.IndexInfo; import com.hughes.android.util.IntentLauncher; @@ -77,11 +74,25 @@ import java.util.zip.ZipFile; // Right-click: // Delete, move to top. -public class DictionaryManagerActivity extends SherlockListActivity { +public class DictionaryManagerActivity extends ActionBarActivity { static final String LOG = "QuickDic"; static boolean blockAutoLaunch = false; + private ListView listView; + private ListView getListView() { + if (listView == null) { + listView = (ListView)findViewById(android.R.id.list); + } + return listView; + } + private void setListAdapter(ListAdapter adapter) { + getListView().setAdapter(adapter); + } + private ListAdapter getListAdapter() { + return getListView().getAdapter(); + } + DictionaryApplication application; SearchView filterSearchView; @@ -91,7 +102,7 @@ public class DictionaryManagerActivity extends SherlockListActivity { LinearLayout downloadableDictionariesHeaderRow; Handler uiHandler; - + Runnable dictionaryUpdater = new Runnable() { @Override public void run() { @@ -101,12 +112,12 @@ public class DictionaryManagerActivity extends SherlockListActivity { uiHandler.post(new Runnable() { @Override public void run() { - setListAdapater(); + setMyListAdapater(); } }); } }; - + final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -120,7 +131,7 @@ public class DictionaryManagerActivity extends SherlockListActivity { final DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); final Cursor cursor = downloadManager.query(query); - if (!cursor.moveToFirst()) { + if (cursor == null || !cursor.moveToFirst()) { Log.e(LOG, "Couldn't find download."); return; } @@ -131,33 +142,49 @@ public class DictionaryManagerActivity extends SherlockListActivity { .getInt(cursor .getColumnIndex(DownloadManager.COLUMN_STATUS)); if (DownloadManager.STATUS_SUCCESSFUL != status) { + final int reason = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_REASON)); Log.w(LOG, "Download failed: status=" + status + - ", reason=" + cursor.getString(cursor - .getColumnIndex(DownloadManager.COLUMN_REASON))); - Toast.makeText(context, getString(R.string.downloadFailed, dest), - Toast.LENGTH_LONG).show(); + ", reason=" + reason); + String msg = Integer.toString(reason); + switch (reason) { + case DownloadManager.ERROR_FILE_ALREADY_EXISTS: msg = "File exists"; break; + case DownloadManager.ERROR_FILE_ERROR: msg = "File error"; break; + case DownloadManager.ERROR_INSUFFICIENT_SPACE: msg = "Not enough space"; break; + } + new AlertDialog.Builder(context).setTitle(getString(R.string.error)).setMessage(getString(R.string.downloadFailed, reason)).setNeutralButton("Close", null).show(); return; } Log.w(LOG, "Download finished: " + dest); + Toast.makeText(context, getString(R.string.unzippingDictionary, dest), + Toast.LENGTH_LONG).show(); + + final File localZipFile = new File(Uri.parse(dest).getPath()); - try { ZipFile zipFile = new ZipFile(localZipFile); final ZipEntry zipEntry = zipFile.entries().nextElement(); Log.d(LOG, "Unzipping entry: " + zipEntry.getName()); final InputStream zipIn = zipFile.getInputStream(zipEntry); - final OutputStream zipOut = new FileOutputStream( - new File(application.getDictDir(), zipEntry.getName())); + File targetFile = new File(application.getDictDir(), zipEntry.getName()); + if (targetFile.exists()) { + targetFile.renameTo(new File(targetFile.getAbsolutePath().replace(".quickdic", ".bak.quickdic"))); + targetFile = new File(application.getDictDir(), zipEntry.getName()); + } + final OutputStream zipOut = new FileOutputStream(targetFile); copyStream(zipIn, zipOut); zipFile.close(); application.backgroundUpdateDictionaries(dictionaryUpdater); - Toast.makeText(context, getString(R.string.downloadFinished, dest), + Toast.makeText(context, getString(R.string.installationFinished, dest), Toast.LENGTH_LONG).show(); } catch (Exception e) { - Toast.makeText(context, getString(R.string.downloadFailed, dest), - Toast.LENGTH_LONG).show(); + String msg = getString(R.string.unzippingFailed, dest); + File dir = application.getDictDir(); + if (!dir.canWrite() || !application.checkFileCreate(dir)) { + msg = getString(R.string.notWritable, dir.getAbsolutePath()); + } + new AlertDialog.Builder(context).setTitle(getString(R.string.error)).setMessage(msg).setNeutralButton("Close", null).show(); Log.e(LOG, "Failed to unzip.", e); } finally { localZipFile.delete(); @@ -166,39 +193,42 @@ public class DictionaryManagerActivity extends SherlockListActivity { } }; - public static Intent getLaunchIntent() { - final Intent intent = new Intent(); - intent.setClassName(DictionaryManagerActivity.class.getPackage().getName(), - DictionaryManagerActivity.class.getName()); + public static Intent getLaunchIntent(Context c) { + final Intent intent = new Intent(c, DictionaryManagerActivity.class); intent.putExtra(C.CAN_AUTO_LAUNCH_DICT, false); return intent; } @Override public void onCreate(Bundle savedInstanceState) { + // This must be first, otherwise the actiona bar doesn't get + // styled properly. setTheme(((DictionaryApplication) getApplication()).getSelectedTheme().themeId); super.onCreate(savedInstanceState); Log.d(LOG, "onCreate:" + this); application = (DictionaryApplication) getApplication(); - + blockAutoLaunch = false; - + // UI init. setContentView(R.layout.dictionary_manager_activity); - dictionariesOnDeviceHeaderRow = (LinearLayout) LayoutInflater.from(getListView().getContext()).inflate( + dictionariesOnDeviceHeaderRow = (LinearLayout) LayoutInflater.from( + getListView().getContext()).inflate( R.layout.dictionary_manager_header_row_on_device, getListView(), false); - downloadableDictionariesHeaderRow = (LinearLayout) LayoutInflater.from(getListView().getContext()).inflate( + downloadableDictionariesHeaderRow = (LinearLayout) LayoutInflater.from( + getListView().getContext()).inflate( R.layout.dictionary_manager_header_row_downloadable, getListView(), false); - showDownloadable = (ToggleButton) downloadableDictionariesHeaderRow.findViewById(R.id.hideDownloadable); + showDownloadable = (ToggleButton) downloadableDictionariesHeaderRow + .findViewById(R.id.hideDownloadable); showDownloadable.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - onShowLocalChanged(); + onShowDownloadableChanged(); } }); @@ -207,41 +237,42 @@ public class DictionaryManagerActivity extends SherlockListActivity { if (!prefs.getString(C.THANKS_FOR_UPDATING_VERSION, "").equals( thanksForUpdatingLatestVersion)) { blockAutoLaunch = true; - startActivity(HtmlDisplayActivity.getWhatsNewLaunchIntent()); + startActivity(HtmlDisplayActivity.getWhatsNewLaunchIntent(getApplicationContext())); prefs.edit().putString(C.THANKS_FOR_UPDATING_VERSION, thanksForUpdatingLatestVersion) .commit(); } - - + registerReceiver(broadcastReceiver, new IntentFilter( DownloadManager.ACTION_DOWNLOAD_COMPLETE)); - - setListAdapater(); + + setMyListAdapater(); registerForContextMenu(getListView()); - + final File dictDir = application.getDictDir(); if (!dictDir.canRead() || !dictDir.canExecute()) { blockAutoLaunch = true; - + AlertDialog.Builder builder = new AlertDialog.Builder(getListView().getContext()); builder.setTitle(getString(R.string.error)); builder.setMessage(getString( - R.string.unableToReadDictionaryDir, - dictDir.getAbsolutePath(), + R.string.unableToReadDictionaryDir, + dictDir.getAbsolutePath(), Environment.getExternalStorageDirectory())); + builder.setNeutralButton("Close", null); builder.create().show(); } - + onCreateSetupActionBar(); } - + private void onCreateSetupActionBar() { ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayShowTitleEnabled(false); - + filterSearchView = new SearchView(getSupportActionBar().getThemedContext()); filterSearchView.setIconifiedByDefault(false); - // filterSearchView.setIconified(false); // puts the magnifying glass in the + // filterSearchView.setIconified(false); // puts the magnifying glass in + // the // wrong place. filterSearchView.setQueryHint(getString(R.string.searchText)); filterSearchView.setSubmitButtonEnabled(false); @@ -258,16 +289,16 @@ public class DictionaryManagerActivity extends SherlockListActivity { // 11 EditorInfo.IME_MASK_ACTION | EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS); - + filterSearchView.setOnQueryTextListener(new OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return true; } - + @Override public boolean onQueryTextChange(String filterText) { - setListAdapater(); + setMyListAdapater(); return true; } }); @@ -277,13 +308,12 @@ public class DictionaryManagerActivity extends SherlockListActivity { actionBar.setDisplayShowCustomEnabled(true); } - @Override public void onDestroy() { super.onDestroy(); unregisterReceiver(broadcastReceiver); } - + private static int copyStream(final InputStream in, final OutputStream out) throws IOException { int bytesRead; @@ -319,20 +349,21 @@ public class DictionaryManagerActivity extends SherlockListActivity { } final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - showDownloadable.setChecked(prefs.getBoolean(C.SHOW_DOWNLOADABLE, false)); + showDownloadable.setChecked(prefs.getBoolean(C.SHOW_DOWNLOADABLE, true)); if (!blockAutoLaunch && getIntent().getBooleanExtra(C.CAN_AUTO_LAUNCH_DICT, true) && prefs.contains(C.DICT_FILE) && prefs.contains(C.INDEX_SHORT_NAME)) { Log.d(LOG, "Skipping DictionaryManager, going straight to dictionary."); - startActivity(DictionaryActivity.getLaunchIntent( - new File(prefs.getString(C.DICT_FILE, "")), prefs.getString(C.INDEX_SHORT_NAME, ""), + startActivity(DictionaryActivity.getLaunchIntent(getApplicationContext(), + new File(prefs.getString(C.DICT_FILE, "")), + prefs.getString(C.INDEX_SHORT_NAME, ""), prefs.getString(C.SEARCH_TOKEN, ""))); finish(); return; } - + // Remove the active dictionary from the prefs so we won't autolaunch // next time. final Editor editor = prefs.edit(); @@ -343,7 +374,7 @@ public class DictionaryManagerActivity extends SherlockListActivity { application.backgroundUpdateDictionaries(dictionaryUpdater); - setListAdapater(); + setMyListAdapater(); } @Override @@ -362,7 +393,7 @@ public class DictionaryManagerActivity extends SherlockListActivity { (AdapterContextMenuInfo) menuInfo; final int position = adapterContextMenuInfo.position; final MyListAdapter.Row row = (MyListAdapter.Row) getListAdapter().getItem(position); - + if (row.dictionaryInfo == null) { return; } @@ -375,7 +406,7 @@ public class DictionaryManagerActivity extends SherlockListActivity { @Override public boolean onMenuItemClick(android.view.MenuItem item) { application.moveDictionaryToTop(row.dictionaryInfo); - setListAdapater(); + setMyListAdapater(); return true; } }); @@ -388,15 +419,15 @@ public class DictionaryManagerActivity extends SherlockListActivity { @Override public boolean onMenuItemClick(android.view.MenuItem item) { application.deleteDictionary(row.dictionaryInfo); - setListAdapater(); + setMyListAdapater(); return true; } - }); + }); } } - private void onShowLocalChanged() { - setListAdapater(); + private void onShowDownloadableChanged() { + setMyListAdapater(); Editor prefs = PreferenceManager.getDefaultSharedPreferences(this).edit(); prefs.putBoolean(C.SHOW_DOWNLOADABLE, showDownloadable.isChecked()); prefs.commit(); @@ -406,18 +437,17 @@ public class DictionaryManagerActivity extends SherlockListActivity { List dictionariesOnDevice; List downloadableDictionaries; - + class Row { DictionaryInfo dictionaryInfo; boolean onDevice; - + private Row(DictionaryInfo dictinoaryInfo, boolean onDevice) { this.dictionaryInfo = dictinoaryInfo; this.onDevice = onDevice; } } - private MyListAdapter(final String[] filters) { dictionariesOnDevice = application.getDictionariesOnDevice(filters); if (showDownloadable.isChecked()) { @@ -438,17 +468,17 @@ public class DictionaryManagerActivity extends SherlockListActivity { return new Row(null, true); } position -= 1; - + if (position < dictionariesOnDevice.size()) { return new Row(dictionariesOnDevice.get(position), true); } position -= dictionariesOnDevice.size(); - + if (position == 0) { return new Row(null, false); } position -= 1; - + assert position < downloadableDictionaries.size(); return new Row(downloadableDictionaries.get(position), false); } @@ -460,40 +490,43 @@ public class DictionaryManagerActivity extends SherlockListActivity { @Override public View getView(int position, View convertView, ViewGroup parent) { - if (convertView instanceof LinearLayout && - convertView != dictionariesOnDeviceHeaderRow && + if (convertView instanceof LinearLayout && + convertView != dictionariesOnDeviceHeaderRow && convertView != downloadableDictionariesHeaderRow) { - /* This is done to try to avoid leaking memory that used to - * happen on Android 4.0.3 */ - ((LinearLayout)convertView).removeAllViews(); + /* + * This is done to try to avoid leaking memory that used to + * happen on Android 4.0.3 + */ + ((LinearLayout) convertView).removeAllViews(); } - + final Row row = getItem(position); - + if (row.onDevice) { if (row.dictionaryInfo == null) { return dictionariesOnDeviceHeaderRow; } return createDictionaryRow(row.dictionaryInfo, parent, true); } - + if (row.dictionaryInfo == null) { return downloadableDictionariesHeaderRow; } return createDictionaryRow(row.dictionaryInfo, parent, false); } - + } - - private void setListAdapater() { - final String filter = filterSearchView == null ? "" : filterSearchView.getQuery().toString(); + + private void setMyListAdapater() { + final String filter = filterSearchView == null ? "" : filterSearchView.getQuery() + .toString(); final String[] filters = filter.trim().toLowerCase().split("(\\s|-)+"); setListAdapter(new MyListAdapter(filters)); } - private View createDictionaryRow(final DictionaryInfo dictionaryInfo, - final ViewGroup parent, final boolean canLaunch) { - + private View createDictionaryRow(final DictionaryInfo dictionaryInfo, + final ViewGroup parent, boolean canLaunch) { + View row = LayoutInflater.from(parent.getContext()).inflate( R.layout.dictionary_manager_row, parent, false); final TextView name = (TextView) row.findViewById(R.id.dictionaryName); @@ -502,13 +535,22 @@ public class DictionaryManagerActivity extends SherlockListActivity { final boolean updateAvailable = application.updateAvailable(dictionaryInfo); final Button downloadButton = (Button) row.findViewById(R.id.downloadButton); - if (!canLaunch || updateAvailable) { - downloadButton.setText(getString(R.string.downloadButton, application.getDownloadable(dictionaryInfo.uncompressedFilename).zipBytes / 1024.0 / 1024.0)); + final DictionaryInfo downloadable = application.getDownloadable(dictionaryInfo.uncompressedFilename); + boolean broken = false; + if (!dictionaryInfo.isValid()) { + broken = true; + canLaunch = false; + } + if (downloadable != null && (!canLaunch || updateAvailable)) { + downloadButton + .setText(getString( + R.string.downloadButton, + downloadable.zipBytes / 1024.0 / 1024.0)); downloadButton.setMinWidth(application.languageButtonPixels * 3 / 2); downloadButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { - downloadDictionary(dictionaryInfo); + downloadDictionary(downloadable.downloadUrl, downloadable.zipBytes, downloadButton); } }); } else { @@ -516,21 +558,23 @@ public class DictionaryManagerActivity extends SherlockListActivity { } LinearLayout buttons = (LinearLayout) row.findViewById(R.id.dictionaryLauncherButtons); - final List sortedIndexInfos = application.sortedIndexInfos(dictionaryInfo.indexInfos); + final List sortedIndexInfos = application + .sortedIndexInfos(dictionaryInfo.indexInfos); final StringBuilder builder = new StringBuilder(); if (updateAvailable) { - builder.append(getString(R.string.updateButton)); + builder.append(getString(R.string.updateAvailable)); } for (IndexInfo indexInfo : sortedIndexInfos) { - final View button = application.createButton(buttons.getContext(), dictionaryInfo, indexInfo); + final View button = application.createButton(buttons.getContext(), dictionaryInfo, + indexInfo); buttons.addView(button); - + if (canLaunch) { button.setOnClickListener( - new IntentLauncher(buttons.getContext(), - DictionaryActivity.getLaunchIntent( - application.getPath(dictionaryInfo.uncompressedFilename), - indexInfo.shortName, ""))); + new IntentLauncher(buttons.getContext(), + DictionaryActivity.getLaunchIntent(getApplicationContext(), + application.getPath(dictionaryInfo.uncompressedFilename), + indexInfo.shortName, ""))); } else { button.setEnabled(false); @@ -538,37 +582,82 @@ public class DictionaryManagerActivity extends SherlockListActivity { if (builder.length() != 0) { builder.append("; "); } - builder.append(getString(R.string.indexInfo, indexInfo.shortName, indexInfo.mainTokenCount)); + builder.append(getString(R.string.indexInfo, indexInfo.shortName, + indexInfo.mainTokenCount)); + } + if (downloadable != null || dictionaryInfo != null) { + builder.append("; "); + builder.append(getString(R.string.downloadButton, (dictionaryInfo != null ? dictionaryInfo.uncompressedBytes : downloadable.uncompressedBytes) / 1024.0 / 1024.0)); + } + if (broken) { + name.setText("Broken: " + application.getDictionaryName(dictionaryInfo.uncompressedFilename)); + builder.append("; Cannot be used, redownload, check hardware/file system"); + // Allow deleting, but cannot open + row.setLongClickable(true); } details.setText(builder.toString()); - + if (canLaunch) { row.setClickable(true); - row.setOnClickListener(new IntentLauncher(parent.getContext(), - DictionaryActivity.getLaunchIntent( - application.getPath(dictionaryInfo.uncompressedFilename), - dictionaryInfo.indexInfos.get(0).shortName, ""))); + row.setOnClickListener(new IntentLauncher(parent.getContext(), + DictionaryActivity.getLaunchIntent(getApplicationContext(), + application.getPath(dictionaryInfo.uncompressedFilename), + dictionaryInfo.indexInfos.get(0).shortName, ""))); row.setFocusable(true); row.setLongClickable(true); } row.setBackgroundResource(android.R.drawable.menuitem_background); - + return row; } - - private void downloadDictionary(final DictionaryInfo dictionaryInfo) { + + private void downloadDictionary(final String downloadUrl, long bytes, Button downloadButton) { DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); + final DownloadManager.Query query = new DownloadManager.Query(); + query.setFilterByStatus(DownloadManager.STATUS_PAUSED | DownloadManager.STATUS_PENDING | DownloadManager.STATUS_RUNNING); + final Cursor cursor = downloadManager.query(query); + + // Due to a bug, cursor is null instead of empty when + // the download manager is disabled. + if (cursor == null) { + new AlertDialog.Builder(DictionaryManagerActivity.this).setTitle(getString(R.string.error)) + .setMessage(getString(R.string.downloadFailed, R.string.downloadManagerQueryFailed)) + .setNeutralButton("Close", null).show(); + return; + } + + while (cursor.moveToNext()) { + if (downloadUrl.equals(cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_URI)))) + break; + } + if (!cursor.isAfterLast()) { + downloadManager.remove(cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID))); + downloadButton + .setText(getString( + R.string.downloadButton, + bytes / 1024.0 / 1024.0)); + cursor.close(); + return; + } + cursor.close(); Request request = new Request( - Uri.parse(dictionaryInfo.downloadUrl)); + Uri.parse(downloadUrl)); try { - final String destFile = new File(new URL(dictionaryInfo.downloadUrl).getFile()).getName(); + final String destFile = new File(new URL(downloadUrl).getFile()) + .getName(); Log.d(LOG, "Downloading to: " + destFile); - - request.setDestinationUri(Uri.fromFile(new File(Environment.getExternalStorageDirectory(), destFile))); + + try { + request.setDestinationInExternalFilesDir(getApplicationContext(), null, destFile); + } catch (IllegalStateException e) { + request.setDestinationUri(Uri.fromFile(new File(Environment + .getExternalStorageDirectory(), destFile))); + } } catch (MalformedURLException e) { throw new RuntimeException(e); } downloadManager.enqueue(request); + downloadButton.setText("X"); } }