com.flowzr.activity.AccountListFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.flowzr.activity.AccountListFragment.java

Source

/*******************************************************************************
 * Copyright (c) 2010 Denis Solonenko.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Denis Solonenko - initial API and implementation
 ******************************************************************************/
package com.flowzr.activity;

import java.util.Calendar;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ListAdapter;
import android.widget.TextView;
import greendroid.widget.QuickActionGrid;
import greendroid.widget.QuickActionWidget;
import com.flowzr.R;
import com.flowzr.adapter.AccountListAdapter2;
import com.flowzr.blotter.BlotterFilter;
import com.flowzr.blotter.TotalCalculationTask;
import com.flowzr.datetime.Period;
import com.flowzr.datetime.PeriodType;
import com.flowzr.db.DatabaseAdapter;
import com.flowzr.dialog.AccountInfoDialog;
import com.flowzr.filter.Criteria;
import com.flowzr.filter.DateTimeCriteria;
import com.flowzr.filter.WhereFilter;
import com.flowzr.graph.Report2DChart;
import com.flowzr.model.Account;
import com.flowzr.model.Total;
import com.flowzr.report.ReportType;
import com.flowzr.utils.IntegrityFix;
import com.flowzr.utils.MyPreferences;
import com.flowzr.utils.Utils;
import com.flowzr.view.NodeInflater;

//import static com.flowzr.utils.MyPreferences.isQuickMenuEnabledForAccount;

/*
 * Dev note:
 * Little change in contextual menus
 * -longClick  : contextualMenu
 * -simple tap : show blotter (1)
 * API<isGreenDroid supported - Android ContextMenu
 * API>isGReenDroid supported - GreenDroid QuickAction as standard (+1 Twitter Android app has it)
 * in order to keep compatibility for API<11 I didn't went up to contextual action mode 
 * (http://developer.android.com/guide/topics/ui/menus.html#context-menu)
 * See : http://www.miximum.fr/tutos/849-porting-the-contextual-anction-mode-for-pre-honeycomb-android-apps
 * for a possible greendroid replacement ?
 * 
 * While refactoring to fragment I may have lost the QuickOptionMenu enabled see (1)
 * 
 * 
 */

public class AccountListFragment extends AbstractTotalListFragment {

    private static final int NEW_ACCOUNT_REQUEST = 1;
    public static final int EDIT_ACCOUNT_REQUEST = 2;
    private static final int VIEW_ACCOUNT_REQUEST = 3;
    private static final int PURGE_ACCOUNT_REQUEST = 4;

    protected Menu myMenu;
    protected TextView totalText;

    OnAccountSelectedListener mListener;

    public void onResume(Bundle s) {
        Log.i("flowzr", "entering on resume");
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnAccountSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
        }
    }

    public AccountListFragment() {
        super(R.layout.account_list);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        setHasOptionsMenu(true);
        return inflater.inflate(R.layout.account_list, container, false);
    }

    protected void createFromTemplate() {
        Bundle bundle = new Bundle();
        bundle.putInt(EXTRA_REQUEST_TYPE, BlotterFragment.NEW_TRANSACTION_FROM_TEMPLATE_REQUEST);
        Intent intent = new Intent(getActivity(), EntityListActivity.class);
        intent.putExtra(EntityListActivity.REQUEST_NEW_TRANSACTION_FROM_TEMPLATE, true);
        intent.putExtra(EXTRA_REQUEST_TYPE, BlotterFragment.NEW_TRANSACTION_FROM_TEMPLATE_REQUEST);
        startActivityForResult(intent, BlotterFragment.NEW_TRANSACTION_FROM_TEMPLATE_REQUEST);

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        DateTimeCriteria criteria;
        Intent intent = null;
        // Handle presses on the action bar items
        switch (item.getItemId()) {
        case R.id.action_add_account:
            addItem();
            return true;
        //           case R.id.action_hide_closed: 
        //              //@TODO unimplemented
        //               return true;
        case R.id.action_integrity_fix:
            doIntegrityFix();
            return true;
        case R.id.action_list_template:
            createFromTemplate();
            return true;
        case R.id.action_planner:
            WhereFilter filter = new WhereFilter(getView().getResources().getString(R.string.planner));
            Calendar date = Calendar.getInstance();
            date.add(Calendar.MONTH, 1);
            criteria = new DateTimeCriteria(PeriodType.THIS_MONTH);
            long now = System.currentTimeMillis();
            if (now > criteria.getLongValue1()) {
                Period period = criteria.getPeriod();
                period.start = now;
                criteria = new DateTimeCriteria(period);
            }
            filter.put(criteria);
            intent = new Intent(getActivity(), EntityListActivity.class);
            intent.putExtra(EntityListActivity.REQUEST_PLANNER, true);
            filter.toIntent(intent);
            startActivity(intent);
            return true;
        case R.id.action_scheduled_transaction:
            WhereFilter blotterFilter = new WhereFilter(getView().getResources().getString(R.string.scheduled));
            blotterFilter.eq(BlotterFilter.IS_TEMPLATE, String.valueOf(2));
            blotterFilter.eq(BlotterFilter.PARENT_ID, String.valueOf(0));
            //blotterFilter.toBundle(bundle);       
            //((MainActivity) getActivity()).loadTabFragment(new ScheduledListActivity(),R.layout.scheduled_transactions, bundle,MainActivity.TAB_BLOTTER);
            intent = new Intent(getActivity(), EntityListActivity.class);
            intent.putExtra(EntityListActivity.REQUEST_SCHEDULED, true);
            blotterFilter.toIntent(intent);
            startActivity(intent);
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.clear();
        inflater.inflate(R.menu.accounts_actions, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (getView().findViewById(R.id.fragment_land_container) != null) {
            Fragment fragment = new AccountListTotalsDetailsActivity();
            getChildFragmentManager().beginTransaction().replace(R.id.fragment_land_container, fragment)
                    .commitAllowingStateLoss();
            getChildFragmentManager().executePendingTransactions();
        }
        recreateCursor();
        recreateAdapter();
        calculateTotals();
        integrityCheck();
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getActivity().getMenuInflater();
        inflater.inflate(R.menu.account_context, menu);
    }

    protected void prepareActionGrid() {
        actionGrid = new QuickActionGrid(this.getActivity());
        actionGrid.addQuickAction(
                new MyQuickAction(this.getActivity(), R.drawable.ic_action_discard, R.string.delete)); //0
        actionGrid.addQuickAction(new MyQuickAction(this.getActivity(), R.drawable.ic_action_about, R.string.info)); //1
        actionGrid.addQuickAction(new MyQuickAction(this.getActivity(), R.drawable.ic_action_edit, R.string.edit)); //2   
        actionGrid.addQuickAction(
                new MyQuickAction(this.getActivity(), R.drawable.ic_action_new, R.string.transaction)); //3
        actionGrid.addQuickAction(
                new MyQuickAction(this.getActivity(), R.drawable.ic_action_import_export, R.string.transfer)); //4     
        actionGrid.addQuickAction(
                new MyQuickAction(this.getActivity(), R.drawable.amount_input, R.string.update_balance)); //5
        actionGrid.addQuickAction(new MyQuickAction(this.getActivity(), R.drawable.ic_action_cancel,
                R.string.delete_old_transactions)); //6
        actionGrid.addQuickAction(
                new MyQuickAction(this.getActivity(), R.drawable.ic_action_secure, R.string.close_account)); //7        
        actionGrid.setOnQuickActionClickListener(accountActionListener);
    }

    private QuickActionWidget.OnQuickActionClickListener accountActionListener = new QuickActionWidget.OnQuickActionClickListener() {
        public void onQuickActionClicked(QuickActionWidget widget, int position) {
            switch (position) {
            case 0:
                deleteItem(selectedId);
                break;
            case 1:
                showAccountInfo(selectedId);
                break;
            case 2:
                editAccount(selectedId);
                break;
            case 3:
                addTransaction(selectedId, TransactionActivity.class);
                break;
            case 4:
                addTransaction(selectedId, TransferActivity.class);
                break;
            case 5:
                updateAccountBalance(selectedId);
                break;
            case 6:
                deleteOldTransaction(selectedId);
                break;
            case 7:
                closeAccount(selectedId);
                break;
            }
        }
    };

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        super.onContextItemSelected(item);
        AdapterView.AdapterContextMenuInfo mi = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        switch (item.getItemId()) {
        case R.id.context_account_delete_old: {
            deleteOldTransaction(mi.id);
        }
        case R.id.context_account_close: {
            closeAccount(mi.id);
        }
        case R.id.context_account_delete:
            deleteItem(selectedId);
            break;
        case R.id.context_account_info:
            showAccountInfo(selectedId);
            break;
        case R.id.context_account_edit:
            editAccount(selectedId);
            break;
        case R.id.context_account_add_transaction:
            addTransaction(selectedId, TransactionActivity.class);
            break;
        case R.id.context_account_add_transfer:
            addTransaction(selectedId, TransferActivity.class);
            break;
        case R.id.context_account_update_balance:
            updateAccountBalance(selectedId);
            break;
        }
        return false;
    }

    private void deleteOldTransaction(long id) {
        Intent intent = new Intent(this.getActivity(), PurgeAccountActivity.class);
        intent.putExtra(PurgeAccountActivity.ACCOUNT_ID, id);
        startActivityForResult(intent, PURGE_ACCOUNT_REQUEST);
    }

    private void closeAccount(long id) {
        Account a = em.getAccount(id);
        a.isActive = !a.isActive;
        em.saveAccount(a);
        recreateCursor();
    }

    private void addTransaction(long accountId, Class<? extends AbstractTransactionActivity> clazz) {
        Intent intent = new Intent(this.getActivity(), clazz);
        intent.putExtra(TransactionActivity.ACCOUNT_ID_EXTRA, accountId);
        startActivityForResult(intent, VIEW_ACCOUNT_REQUEST);
    }

    @Override
    public void recreateCursor() {
        super.recreateCursor();
        calculateTotals();
    }

    private AccountTotalsCalculationTask totalCalculationTask;

    private void calculateTotals() {
        totalText = (TextView) getView().findViewById(R.id.total);
        if (totalText != null) {
            if (totalCalculationTask != null) {
                totalCalculationTask.stop();
                totalCalculationTask.cancel(true);
            }

            totalText.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    showTotals();
                }
            });
            totalCalculationTask = new AccountTotalsCalculationTask(this.getActivity(), totalText);
            totalCalculationTask.execute();
        }
    }

    private void showTotals() {
        Intent intent = new Intent(getActivity(), EntityListActivity.class);
        intent.putExtra(EntityListActivity.REQUEST_ACCOUNT_TOTALS, true);
        startActivity(intent);
    }

    public class AccountTotalsCalculationTask extends TotalCalculationTask {

        public AccountTotalsCalculationTask(Context context, TextView totalText) {
            super(context, totalText);
        }

        @Override
        public Total getTotalInHomeCurrency() {
            return db.getAccountsTotalInHomeCurrency();
        }

        @Override
        public Total[] getTotals() {
            return new Total[0];
        }

    }

    @Override
    protected ListAdapter createAdapter(Cursor cursor) {
        return new AccountListAdapter2(getActivity(), cursor);
    }

    @Override
    protected Cursor createCursor() {
        if (MyPreferences.isHideClosedAccounts(getActivity())) {
            return em.getAllActiveAccounts();
        } else {
            return em.getAllAccounts();
        }
    }

    private boolean updateAccountBalance(long id) {
        Account a = em.getAccount(id);
        if (a != null) {
            Intent intent = new Intent(this.getActivity(), TransactionActivity.class);
            intent.putExtra(TransactionActivity.ACCOUNT_ID_EXTRA, a.id);
            intent.putExtra(TransactionActivity.CURRENT_BALANCE_EXTRA, a.totalAmount);
            startActivityForResult(intent, 0);
            return true;
        }
        return false;
    }

    @Override
    protected void addItem() {
        Intent intent = new Intent(AccountListFragment.this.getActivity(), AccountActivity.class);
        startActivityForResult(intent, NEW_ACCOUNT_REQUEST);
    }

    protected void deleteItem(final long id) {
        new AlertDialog.Builder(this.getActivity()).setMessage(R.string.delete_account_confirm)
                .setPositiveButton(R.string.yes, new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {
                        db.deleteAccount(id);
                        recreateCursor();
                        ((MainActivity) getActivity()).mAdapter.notifyDataSetChanged();
                    }
                }).setNegativeButton(R.string.no, null).show();
    }

    @Override
    protected void deleteItem(View v, int position, final long id) {
        deleteItem(id);

    }

    @Override
    public void editItem(View v, int position, long id) {
        editAccount(id);
    }

    private void editAccount(long id) {
        Intent intent = new Intent(AccountListFragment.this.getActivity(), AccountActivity.class);
        intent.putExtra(AccountActivity.ACCOUNT_ID_EXTRA, id);
        startActivityForResult(intent, EDIT_ACCOUNT_REQUEST);
    }

    private void showAccountInfo(long id) {
        LayoutInflater layoutInflater = (LayoutInflater) this.getActivity()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        NodeInflater inflater = new NodeInflater(layoutInflater);
        AccountInfoDialog accountInfoDialog = new AccountInfoDialog(this, id, db, inflater);
        accountInfoDialog.show();
    }

    @Override
    protected void viewItem(View v, int position, long id) {
        showAccountTransactions(id);
    }

    public interface OnAccountSelectedListener {
        public void onAccountSelected(String title, long id);
    }

    private void showAccountTransactions(long id) {
        Account account = em.getAccount(id);
        if (account != null) {
            mListener.onAccountSelected(account.title, id);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == VIEW_ACCOUNT_REQUEST || requestCode == PURGE_ACCOUNT_REQUEST) {
            recreateCursor();
        }
        if (resultCode != MainActivity.RESULT_CANCELED) {
            ((MainActivity) getActivity()).mAdapter.notifyDataSetChanged();
        }

        /*        if (resultCode == MainActivity.RESULT_OK && requestCode == NEW_TRANSACTION_FROM_TEMPLATE_REQUEST) {
        createTransactionFromTemplate(data);
                }*/
    }

    public void doIntegrityFix() {
        new IntegrityFixTask().execute();
    }

    private class IntegrityFixTask extends AsyncTask<Void, Void, Void> {

        ProgressDialog progressDialog;

        @Override
        protected void onPreExecute() {
            progressDialog = ProgressDialog.show(getActivity(), null, getString(R.string.integrity_fix_in_progress),
                    true);
            progressDialog.show();
        }

        @Override
        protected void onPostExecute(Void o) {
            ((MainActivity) getActivity()).refreshCurrentTab();
            progressDialog.dismiss();
        }

        @Override
        protected Void doInBackground(Void... objects) {
            DatabaseAdapter db = new DatabaseAdapter(AccountListFragment.this.getActivity());
            new IntegrityFix(db).fix();
            return null;
        }
    }

    public static Fragment newInstance(Bundle args) {
        AccountListFragment f = new AccountListFragment();
        f.setArguments(args);
        return f;
    }

    @Override
    protected String getMyTitle() {
        return getResources().getString(R.string.accounts);
    }

}