diff options
Diffstat (limited to 'app/src/main/java/org/fox/ttcomics2/ComicListFragment.java')
-rw-r--r-- | app/src/main/java/org/fox/ttcomics2/ComicListFragment.java | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/app/src/main/java/org/fox/ttcomics2/ComicListFragment.java b/app/src/main/java/org/fox/ttcomics2/ComicListFragment.java new file mode 100644 index 0000000..9b766f7 --- /dev/null +++ b/app/src/main/java/org/fox/ttcomics2/ComicListFragment.java @@ -0,0 +1,461 @@ +package org.fox.ttcomics2; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.database.Cursor; +import android.database.SQLException; +import android.os.AsyncTask; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.provider.BaseColumns; +import android.support.v4.app.Fragment; +import android.support.v4.widget.SimpleCursorAdapter; +import android.support.v4.widget.SwipeRefreshLayout; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.AdapterContextMenuInfo; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.nostra13.universalimageloader.core.ImageLoader; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +public class ComicListFragment extends Fragment implements OnItemClickListener { + private final String TAG = this.getClass().getSimpleName(); + + private final static int SIZE_DIR = -100; + + // corresponds to tab indexes + private final static int MODE_ALL = 0; + private final static int MODE_UNREAD = 1; + private final static int MODE_UNFINISHED = 2; + private final static int MODE_READ = 3; + + private CommonActivity m_activity; + private SharedPreferences m_prefs; + private ComicsListAdapter m_adapter; + private int m_mode = 0; + private String m_baseDirectory = ""; + private SwipeRefreshLayout m_swipeLayout; + + public ComicListFragment() { + super(); + } + + public void setBaseDirectory(String baseDirectory) { + m_baseDirectory = baseDirectory; + } + + public void setMode(int mode) { + m_mode = mode; + } + + private class ComicsListAdapter extends SimpleCursorAdapter { + public ComicsListAdapter(Context context, int layout, Cursor c, + String[] from, int[] to, int flags) { + super(context, layout, c, from, to, flags); + // TODO Auto-generated constructor stub + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + + Cursor c = (Cursor) getItem(position); + + String filePath = c.getString(c.getColumnIndex("path")); + String fileBaseName = c.getString(c.getColumnIndex("filename")); + String firstChild = c.getString(c.getColumnIndex("firstchild")); + + int lastPos = m_activity.getLastPosition(filePath + "/" + fileBaseName); + int size = m_activity.getSize(filePath + "/" + fileBaseName); + + if (v == null) { + LayoutInflater vi = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + v = vi.inflate(R.layout.comics_grid_row, null); + } + + TextView name = (TextView) v.findViewById(R.id.file_name); + + if (name != null) { + name.setText(fileBaseName); + } + + TextView info = (TextView) v.findViewById(R.id.file_progress_info); + + if (info != null) { + if (size != -1 && size != SIZE_DIR) { + if (lastPos == size - 1) { + info.setText(getString(R.string.file_finished)); + } else if (lastPos > 0) { + info.setText(getString(R.string.file_progress_info, lastPos + 1, size, (int) (lastPos / (float) size * 100f))); + } else { + info.setText(getString(R.string.file_unread, size)); + } + info.setVisibility(View.VISIBLE); + } else if (size == SIZE_DIR) { + info.setText(getString(R.string.list_type_directory)); + info.setVisibility(View.VISIBLE); + } else { + info.setText(getString(R.string.list_type_unknown)); + info.setVisibility(View.VISIBLE); + } + } + + ProgressBar progressBar = (ProgressBar) v.findViewById(R.id.file_progress_bar); + + if (progressBar != null) { + if (size != -1 && size != SIZE_DIR) { + progressBar.setMax(size - 1); + progressBar.setProgress(lastPos); + progressBar.setEnabled(true); + progressBar.setVisibility(View.VISIBLE); + } else { + progressBar.setProgress(0); + progressBar.setMax(0); + progressBar.setEnabled(false); + progressBar.setVisibility(View.VISIBLE); + } + } + + /* ImageView overflow = (ImageView) v.findViewById(R.id.comic_overflow); + + if (overflow != null) { + if (size == SIZE_DIR) { + overflow.setVisibility(View.GONE); + } else { + overflow.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + getActivity().openContextMenu(v); + } + }); + } + } */ + + File thumbnailFile = new File(m_activity.getCacheFileName(firstChild != null ? firstChild : filePath + "/" + fileBaseName)); + + ImageView thumbnail = (ImageView) v.findViewById(R.id.thumbnail); + + if (thumbnail != null && thumbnailFile != null) { + + ImageLoader imageLoader = ImageLoader.getInstance(); + imageLoader.displayImage("file://" + thumbnailFile.getAbsolutePath(), thumbnail); + } + + return v; + } + } + + public int dpToPx(int dp) { + DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); + int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT)); + return px; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + View view = inflater.inflate(R.layout.fragment_comics_list, container, false); + + if (savedInstanceState != null) { + m_mode = savedInstanceState.getInt("mode"); + m_baseDirectory = savedInstanceState.getString("baseDir"); + } + + m_swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.comics_swipe_container); + + m_swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + rescan(true); + } + }); + + m_swipeLayout.setColorScheme(android.R.color.holo_green_dark, + android.R.color.holo_red_dark, + android.R.color.holo_blue_dark, + android.R.color.holo_orange_dark); + + m_adapter = new ComicsListAdapter(getActivity(), R.layout.comics_grid_row, createCursor(), + new String[] { "filename" }, new int[] { R.id.file_name }, 0); + + if (view.findViewById(R.id.comics_list) != null) { + ListView list = (ListView) view.findViewById(R.id.comics_list); + list.setAdapter(m_adapter); + list.setEmptyView(view.findViewById(R.id.no_comics)); + list.setOnItemClickListener(this); + + registerForContextMenu(list); + + } else { + GridView grid = (GridView) view.findViewById(R.id.comics_grid); + grid.setAdapter(m_adapter); + grid.setEmptyView(view.findViewById(R.id.no_comics)); + grid.setOnItemClickListener(this); + + registerForContextMenu(grid); + + } + + return view; + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + + getActivity().getMenuInflater().inflate(R.menu.comic_archive_context, menu); + + AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; + + Cursor c = (Cursor) m_adapter.getItem(info.position); + + if (c != null) { + menu.setHeaderTitle(c.getString(c.getColumnIndex("filename"))); + } + + super.onCreateContextMenu(menu, v, menuInfo); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo) item + .getMenuInfo(); + + Cursor c = (Cursor) m_adapter.getItem(info.position); + String fileName = c.getString(c.getColumnIndex("path")) + "/" + c.getString(c.getColumnIndex("filename")); + + switch (item.getItemId()) { + case R.id.menu_reset_progress: + if (fileName != null) { + m_activity.resetProgress(fileName); + m_adapter.notifyDataSetChanged(); + } + return true; + case R.id.menu_mark_as_read: + + if (fileName != null) { + m_activity.setLastPosition(fileName, m_activity.getSize(fileName)-1); + m_adapter.notifyDataSetChanged(); + } + + return true; + default: + Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); + return super.onContextItemSelected(item); + } + } + + private Cursor createCursor() { + String baseDir = m_baseDirectory.length() == 0 ? m_prefs.getString("comics_directory", "") : m_baseDirectory; + + String selection; + String selectionArgs[]; + + switch (m_mode) { + case MODE_READ: + selection = "path = ? AND position = size - 1"; + selectionArgs = new String[] { baseDir }; + break; + case MODE_UNFINISHED: + selection = "path = ? AND position < size AND position > 0 AND position != size - 1"; + selectionArgs = new String[] { baseDir }; + break; + case MODE_UNREAD: + selection = "path = ? AND position = 0 AND size != ?"; + selectionArgs = new String[] { baseDir, String.valueOf(SIZE_DIR) }; + break; + default: + selection = "path = ?"; + selectionArgs = new String[] { baseDir }; + } + + if (!m_prefs.getBoolean("enable_rar", false)) { + selection += " AND (UPPER(filename) NOT LIKE '%.CBR' AND UPPER(filename) NOT LIKE '%.RAR')"; + } + + return m_activity.getReadableDb().query("comics_cache", new String[] { BaseColumns._ID, "filename", "path", + "(SELECT path || '/' || filename FROM comics_cache AS t2 WHERE t2.path = comics_cache.path || '/' || comics_cache.filename AND filename != '' ORDER BY filename LIMIT 1) AS firstchild" }, + selection, selectionArgs, null, null, "size != " + SIZE_DIR + ", filename, size = " + SIZE_DIR + ", filename"); + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + + m_activity = (CommonActivity)activity; + + m_prefs = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()); + } + + protected void rescan(final boolean fullRescan) { + AsyncTask<String, Integer, Integer> rescanTask = new AsyncTask<String, Integer, Integer>() { + + @Override + protected void onProgressUpdate(Integer... progress) { + if (isAdded()) { + m_activity.setProgress(Math.round(((float)progress[0] / (float)progress[1]) * 10000)); + } + } + + @Override + protected Integer doInBackground(String... params) { + String comicsDir = params[0]; + + File dir = new File(comicsDir); + + int fileIndex = 0; + + if (dir.isDirectory()) { + File archives[] = dir.listFiles(); + + java.util.Arrays.sort(archives); + + for (File archive : archives) { + String filePath = archive.getAbsolutePath(); + + if (archive.isDirectory()) { + m_activity.setSize(filePath, SIZE_DIR); + + } else if (archive.getName().toLowerCase().matches(".*\\.(cbz|zip|cbr|rar)") && isAdded() && m_activity != null && + m_activity.getWritableDb() != null && m_activity.getWritableDb().isOpen()) { + try { + int size = m_activity.getSize(filePath); + + if (size == -1 || fullRescan) { + + ComicArchive cba = null; + + if (archive.getName().toLowerCase().matches(".*\\.(cbz|zip)")) { + cba = new CbzComicArchive(filePath); + } + + if (cba != null && cba.getCount() > 0) { + // Get cover + + try { + File thumbnailFile = new File(m_activity.getCacheFileName(filePath)); + + if (m_activity.isStorageWritable() && (!thumbnailFile.exists() || fullRescan)) { + InputStream is = cba.getItem(0); + + if (is != null) { + FileOutputStream fos = new FileOutputStream(thumbnailFile); + + byte[] buffer = new byte[1024]; + int len; + while ((len = is.read(buffer)) != -1) { + fos.write(buffer, 0, len); + } + + fos.close(); + is.close(); + } + } + + } catch (IOException e) { + e.printStackTrace(); + } + + size = cba.getCount(); + + m_activity.setSize(filePath, size); + } + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + ++fileIndex; + + publishProgress(Integer.valueOf(fileIndex), Integer.valueOf(archives.length)); + } + } + + if (isAdded() && m_activity != null) { + m_activity.cleanupCache(false); + m_activity.cleanupSqliteCache(comicsDir); + } + + return fileIndex; //m_files.size(); + } + + @Override + protected void onPostExecute(Integer result) { + if (isAdded() && m_adapter != null) { + m_adapter.changeCursor(createCursor()); + m_adapter.notifyDataSetChanged(); + + if (m_swipeLayout != null) m_swipeLayout.setRefreshing(false); + } + } + }; + + String comicsDir = m_prefs.getString("comics_directory", null); + + if (comicsDir != null && m_activity.isStorageAvailable()) { + if (m_swipeLayout != null) m_swipeLayout.setRefreshing(true); + + rescanTask.execute(m_baseDirectory.length() > 0 ? m_baseDirectory : comicsDir); + } + } + + @Override + public void onResume() { + super.onResume(); + + m_adapter.notifyDataSetChanged(); + + String comicsDir = m_prefs.getString("comics_directory", ""); + + if (m_activity.getCachedItemCount(m_baseDirectory.length() > 0 ? m_baseDirectory : comicsDir) == 0) { + rescan(false); + } else { + m_adapter.notifyDataSetChanged(); + } + } + + public void onItemClick(AdapterView<?> av, View view, int position, long id) { + //Log.d(TAG, "onItemClick position=" + position); + + Cursor c = (Cursor) m_adapter.getItem(position); + String fileName = c.getString(c.getColumnIndex("path")) + "/" + c.getString(c.getColumnIndex("filename")); + + if (fileName != null) { + m_activity.onComicArchiveSelected(fileName); + } + } + + + @Override + public void onSaveInstanceState(Bundle out) { + super.onSaveInstanceState(out); + + out.putInt("mode", m_mode); + out.putString("baseDir", m_baseDirectory); + } + +} |