org.barbon.mangaget.fragments.MangaList.java Source code

Java tutorial

Introduction

Here is the source code for org.barbon.mangaget.fragments.MangaList.java

Source

/*
 * Copyright (c) Mattia Barbon <mattia@barbon.org>
 * distributed under the terms of the MIT license
 */

package org.barbon.mangaget.fragments;

import android.content.DialogInterface;

import android.database.Cursor;

import android.os.Bundle;

import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

import android.support.v4.app.ListFragment;

import java.util.HashSet;
import java.util.Set;

import org.barbon.mangaget.Download;
import org.barbon.mangaget.Notifier;
import org.barbon.mangaget.R;
import org.barbon.mangaget.Utils;

import org.barbon.mangaget.data.DB;

import org.barbon.mangaget.scrape.Scraper;

public class MangaList extends ListFragment {
    private static final String SELECTED_ID = "mangaId";

    private SimpleCursorAdapter adapter;
    private OnMangaSelected onMangaSelected;
    private long currentSelection = -1;
    private StatusBinder viewBinder = new StatusBinder();
    private MangaListener listener = new MangaListener();
    private MangaDBListener dbListener = new MangaDBListener();

    public interface OnMangaSelected {
        public void onMangaSelected(long mangaId);
    }

    private class MangaListener extends Notifier.OperationNotificationAdapter {
        @Override
        public void onMangaUpdateStarted(long mangaId) {
            viewBinder.setStatus(mangaId, true);
            adapter.getCursor().requery();
        }

        @Override
        public void onMangaUpdateComplete(long mangaId, boolean success) {
            viewBinder.setStatus(mangaId, false);
            adapter.getCursor().requery();
        }
    }

    private class MangaDBListener extends Notifier.DBNotificationAdapter {
        @Override
        public void onMangaUpdate(long mangaId) {
            adapter.getCursor().requery();
        }
    }

    private static class StatusBinder implements SimpleCursorAdapter.ViewBinder {
        private Set<Long> active = new HashSet<Long>();

        @Override
        public boolean setViewValue(View view, Cursor cursor, int column) {
            if (view.getId() == R.id.manga_progress)
                return bindProgress((ProgressBar) view, cursor, column);
            if (view.getId() == R.id.manga_provider)
                return bindProvider((TextView) view, cursor, column);

            return false;
        }

        public void setStatus(long mangaId, boolean started) {
            if (started)
                active.add(mangaId);
            else
                active.remove(mangaId);
        }

        private boolean bindProgress(ProgressBar progress, Cursor cursor, int column) {
            long id = cursor.getLong(column);

            if (active.contains(id))
                progress.setVisibility(View.VISIBLE);
            else
                progress.setVisibility(View.INVISIBLE);

            return true;
        }

        private boolean bindProvider(TextView view, Cursor cursor, int column) {
            String url = cursor.getString(column);

            view.setText(Scraper.getProviderName(url));

            return true;
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        adapter = new SimpleCursorAdapter(getActivity(), R.layout.manga_item, null,
                new String[] { DB.MANGA_TITLE, DB.ID, DB.MANGA_URL },
                new int[] { R.id.manga_title, R.id.manga_progress, R.id.manga_provider });
        adapter.setViewBinder(viewBinder);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        setEmptyText(getString(R.string.no_manga));
        setListAdapter(adapter);

        if (savedInstanceState != null)
            setSelectedId(savedInstanceState.getLong(SELECTED_ID));

        registerForContextMenu(getListView());
        bindConfirmationDialog(DeleteConfirmationDialog.find(this));
    }

    @Override
    public void onStart() {
        super.onStart();

        DB db = DB.getInstance(getActivity());

        adapter.changeCursor(db.getSubscribedMangaList());
    }

    @Override
    public void onResume() {
        super.onResume();

        Notifier.getInstance().add(listener);
        Notifier.getInstance().add(dbListener);

        if (adapter.getCursor() != null)
            adapter.getCursor().requery();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putLong(SELECTED_ID, currentSelection);
    }

    @Override
    public void onPause() {
        super.onPause();

        Notifier.getInstance().remove(dbListener);
        Notifier.getInstance().remove(listener);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();

        adapter.changeCursor(null);
    }

    // public interface

    public void setOnMangaSelected(OnMangaSelected listener) {
        onMangaSelected = listener;
    }

    // implementation

    private void setSelectedId(final long id) {
        currentSelection = id;

        if (id == -1)
            return;
        if (onMangaSelected == null)
            return;

        onMangaSelected.onMangaSelected(id);
    }

    private void deleteMangaAndChapters(long id) {
        Download.deleteManga(getActivity(), id, true);
    }

    private void deleteManga(long id) {
        Download.deleteManga(getActivity(), id, false);
    }

    private void bindConfirmationDialog(DeleteConfirmationDialog dialog) {
        if (dialog == null)
            return;

        final long mangaId = dialog.getMangaId();
        final boolean deleteChapters = dialog.getDeleteChapters();

        DialogInterface.OnClickListener delete = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (deleteChapters)
                    deleteMangaAndChapters(mangaId);
                else
                    deleteManga(mangaId);
            }
        };

        dialog.setPositiveClick(delete);
    }

    // event handlers

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        setSelectedId(id);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;

        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getActivity().getMenuInflater();

        inflater.inflate(R.menu.manga_context, menu);

        DB db = DB.getInstance(getActivity());
        int status = db.getManga(info.id).getAsInteger(DB.MANGA_SUBSCRIPTION_STATUS);
        ;

        if (status != DB.SUBSCRIPTION_FOLLOWING)
            menu.removeItem(R.id.stop_following);
        else
            menu.removeItem(R.id.follow);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

        switch (item.getItemId()) {
        case R.id.delete: {
            DeleteConfirmationDialog dlg = DeleteConfirmationDialog.newInstance(info.id, false);

            bindConfirmationDialog(dlg);
            dlg.show(this);

            return true;
        }
        case R.id.delete_all: {
            DeleteConfirmationDialog dlg = DeleteConfirmationDialog.newInstance(info.id, true);

            bindConfirmationDialog(dlg);
            dlg.show(this);

            return true;
        }
        case R.id.refresh:
            Download.startMangaUpdate(getActivity(), info.id);
            return true;
        case R.id.follow: {
            DB db = DB.getInstance(getActivity());

            db.updateMangaSubscription(info.id, DB.SUBSCRIPTION_FOLLOWING);

            return true;
        }
        case R.id.stop_following: {
            DB db = DB.getInstance(getActivity());

            db.updateMangaSubscription(info.id, DB.SUBSCRIPTION_SAVED);

            return true;
        }
        default:
            return super.onContextItemSelected(item);
        }
    }
}