com.money.manager.ex.currency.list.CurrencyListFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.money.manager.ex.currency.list.CurrencyListFragment.java

Source

/*
 * Copyright (C) 2012-2016 The Android Money Manager Ex Project Team
 *
 * 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 3
 * 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, see <http://www.gnu.org/licenses/>.
 */
package com.money.manager.ex.currency.list;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.text.TextUtils;
import android.view.ContextMenu;
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.ListView;
import android.widget.Toast;

import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.mmex_icon_font_typeface_library.MMXIconFont;
import com.money.manager.ex.Constants;
import com.money.manager.ex.MoneyManagerApplication;
import com.money.manager.ex.R;
import com.money.manager.ex.common.MmxCursorLoader;
import com.money.manager.ex.common.BaseListFragment;
import com.money.manager.ex.core.UIHelper;
import com.money.manager.ex.currency.CurrencyChartActivity;
import com.money.manager.ex.currency.CurrencyRepository;
import com.money.manager.ex.currency.CurrencyService;
import com.money.manager.ex.currency.CurrencyUIFeatures;
import com.money.manager.ex.currency.events.CurrencyDeletionConfirmedEvent;
import com.money.manager.ex.currency.events.ExchangeRateUpdateConfirmedEvent;
import com.money.manager.ex.datalayer.Select;
import com.money.manager.ex.domainmodel.Account;
import com.money.manager.ex.domainmodel.Currency;
import com.money.manager.ex.investment.events.PriceDownloadedEvent;
import com.money.manager.ex.settings.AppSettings;
import com.money.manager.ex.utils.ActivityUtils;
import com.money.manager.ex.utils.MmxDatabaseUtils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.util.ArrayList;
import java.util.List;

/**
 *  Currency list.
 */
public class CurrencyListFragment extends BaseListFragment {

    private static final int ID_LOADER_CURRENCY = 0;

    // Store previous device orientation when showing other screens (chart, etc.)
    public int mPreviousOrientation = Constants.NOT_SET;

    //    @Inject Lazy<CurrencyService> mCurrencyService;
    private CurrencyService mCurrencyService;

    private String mAction = Intent.ACTION_EDIT;
    private String mCurFilter;
    private boolean mShowOnlyUsedCurrencies;
    private LoaderManager.LoaderCallbacks<Cursor> loaderCallbacks;

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

        MoneyManagerApplication.getApp().iocComponent.inject(this);

        mAction = getActivity().getIntent().getAction();
        if (mAction.equals(Intent.ACTION_MAIN)) {
            mAction = Intent.ACTION_EDIT;
        }

        // Filter currencies only if in the standalone Currencies list. Do not filter in pickers.
        mShowOnlyUsedCurrencies = !mAction.equals(Intent.ACTION_PICK);

        loaderCallbacks = initLoaderCallbacks();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // todo initializeSwipeToRefresh();

        return super.onCreateView(inflater, container, savedInstanceState);
    }

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

        EventBus.getDefault().register(this);
    }

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

        EventBus.getDefault().unregister(this);
    }

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

        setSearchMenuVisible(true);
        // Focus on search menu if set in preferences.
        AppSettings settings = new AppSettings(getActivity());
        boolean focusOnSearch = settings.getBehaviourSettings().getFilterInSelectors();
        setMenuItemSearchIconified(!focusOnSearch);

        setEmptyText(getActivity().getResources().getString(R.string.currencies_empty));

        setHasOptionsMenu(true);

        // create and link the adapter
        CurrencyListAdapter adapter = new CurrencyListAdapter(getActivity(), null);
        setListAdapter(adapter);

        getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);

        setListShown(false);
        loadData();

        setFloatingActionButtonVisible(true);
        attachFloatingActionButtonToListView();
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        registerForContextMenu(getListView());
    }

    // Menu.

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

        UIHelper ui = new UIHelper(getActivity());

        MenuItem item = menu.findItem(R.id.menu_update_exchange_rate);
        item.setIcon(ui.getIcon(GoogleMaterial.Icon.gmd_file_download));

        // Customize with font icon, if needed.
        item = menu.findItem(R.id.menu_import_all_currencies);
        item.setIcon(ui.getIcon(MMXIconFont.Icon.mmx_share_square));
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        MenuItem showOnlyUsed = menu.findItem(R.id.menu_show_used);
        if (showOnlyUsed != null) {
            showOnlyUsed.setChecked(mShowOnlyUsedCurrencies);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        CurrencyUIFeatures ui = new CurrencyUIFeatures(getActivity());

        switch (item.getItemId()) {
        case R.id.menu_import_all_currencies:
            ui.showDialogImportAllCurrencies();
            return true;

        case R.id.menu_update_exchange_rate:
            ui.showDialogUpdateExchangeRates();
            break;

        case R.id.menu_show_used:
            if (item.isChecked()) {
                item.setChecked(false);
                // list all accounts
                mShowOnlyUsedCurrencies = false;
                reloadData();
            } else {
                item.setChecked(true);
                // list only used accounts
                mShowOnlyUsedCurrencies = true;
                reloadData();
            }
            break;
        }
        return super.onOptionsItemSelected(item);
    }

    // Context menu

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        // take cursor and move into position
        Cursor cursor = ((CurrencyListAdapter) getListAdapter()).getCursor();
        cursor.moveToPosition(info.position);
        // set currency name
        menu.setHeaderTitle(cursor.getString(cursor.getColumnIndex(Currency.CURRENCYNAME)));

        // compose context menu
        String[] menuItems = getResources().getStringArray(R.array.context_menu_currencies);
        for (int i = 0; i < menuItems.length; i++) {
            menu.add(Menu.NONE, i, i, menuItems[i]);
        }
    }

    @Override
    public boolean onContextItemSelected(android.view.MenuItem item) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        // take cursor and move to position
        Cursor cursor = ((CurrencyListAdapter) getListAdapter()).getCursor();
        cursor.moveToPosition(info.position);
        int currencyId = cursor.getInt(cursor.getColumnIndex(Currency.CURRENCYID));

        CurrencyUIFeatures ui = new CurrencyUIFeatures(getActivity());

        // check item selected
        int selectedItem = item.getItemId();
        switch (selectedItem) {
        case 0: //EDIT
            ui.startCurrencyEditActivity(currencyId);
            break;

        case 1: // Chart
            // remember the device orientation and return to it after the chart.
            this.mPreviousOrientation = ActivityUtils.forceCurrentOrientation(getActivity());

            // add the currency information.
            String symbol = cursor.getString(cursor.getColumnIndex(Currency.CURRENCY_SYMBOL));
            CurrencyService currencyService = this.getService();
            String baseCurrencyCode = currencyService.getBaseCurrencyCode();

            Intent intent = new Intent(getActivity(), CurrencyChartActivity.class);
            intent.setAction(Intent.ACTION_VIEW);
            intent.putExtra(Currency.CURRENCY_SYMBOL, symbol);
            intent.putExtra(CurrencyChartActivity.BASE_CURRENCY_SYMBOL, baseCurrencyCode);

            startActivity(intent);
            break;

        case 2: // Update exchange rate
            getService().updateExchangeRate(currencyId);
            break;

        case 3: //DELETE
            CurrencyService service = new CurrencyService(getActivity());
            boolean used = service.isCurrencyUsed(currencyId);

            if (used) {
                ui.notifyCurrencyCanNotBeDeleted();
            } else {
                ContentValues contentValues = new ContentValues();
                contentValues.put(Account.CURRENCYID, currencyId);
                ui.showDialogDeleteCurrency(currencyId, info.position);
            }
            break;
        }
        return false;
    }

    // Search

    @Override
    public boolean onQueryTextChange(String newText) {
        // Called when the action bar search text has changed.  Update
        // the search filter, and restart the loader to do a new query
        // with this filter.
        mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
        reloadData();
        return true;
    }

    @Override
    protected void setResult() {
        Intent result;
        if (Intent.ACTION_PICK.equals(mAction)) {
            // create intent
            Cursor cursor = ((CurrencyListAdapter) getListAdapter()).getCursor();

            for (int i = 0; i < getListView().getCount(); i++) {
                if (getListView().isItemChecked(i)) {
                    cursor.moveToPosition(i);

                    result = new Intent();
                    result.putExtra(CurrencyListActivity.INTENT_RESULT_CURRENCYID,
                            cursor.getInt(cursor.getColumnIndex(Currency.CURRENCYID)));
                    result.putExtra(CurrencyListActivity.INTENT_RESULT_CURRENCYNAME,
                            cursor.getString(cursor.getColumnIndex(Currency.CURRENCYNAME)));

                    getActivity().setResult(Activity.RESULT_OK, result);

                    return;
                }
            }
        }
        getActivity().setResult(CurrencyListActivity.RESULT_CANCELED);
    }

    @Override
    public void onFloatingActionButtonClicked() {
        CurrencyUIFeatures ui = new CurrencyUIFeatures(getActivity());
        ui.startCurrencyEditActivity(null);
    }

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

        // Show context menu only if we are displaying the list of currencies
        // but not in selection mode.
        if (mAction.equals(Intent.ACTION_EDIT)) {
            getActivity().openContextMenu(v);
        } else {
            // we are picking a currency. Select one.
            setResultAndFinish();
        }
    }

    @Override
    public String getSubTitle() {
        String result;
        //        if (mShowOnlyUsedCurrencies) {
        //            result = getString(R.string.currencies_used);
        //        } else {
        result = getString(R.string.currencies);
        //        }
        return result;
    }

    @Subscribe
    public void onEvent(PriceDownloadedEvent event) {
        CurrencyUIFeatures ui = new CurrencyUIFeatures(getContext());
        ui.onPriceDownloaded(event.symbol, event.price, event.date);
    }

    @Subscribe
    public void onEvent(ExchangeRateUpdateConfirmedEvent event) {
        // proceed with rate update
        // todo: use event.updateAll parameter

        // Update only the visible currencies.
        List<Currency> currencies = getVisibleCurrencies();

        getService().updateExchangeRates(currencies);
    }

    @Subscribe
    public void onEvent(CurrencyDeletionConfirmedEvent event) {
        CurrencyRepository repo = new CurrencyRepository(getContext());
        boolean success = repo.delete(event.currencyId);
        if (success) {
            Toast.makeText(getContext(), R.string.delete_success, Toast.LENGTH_SHORT).show();
        }
        // restart loader
        reloadData();
    }

    // Private methods.

    private List<Currency> getVisibleCurrencies() {
        CurrencyListAdapter adapter = (CurrencyListAdapter) getListAdapter();
        if (adapter == null)
            return null;

        Cursor cursor = adapter.getCursor();
        if (cursor == null)
            return null;

        cursor.moveToPosition(Constants.NOT_SET);
        List<Currency> currencies = new ArrayList<>();

        while (cursor.moveToNext()) {
            Currency currency = Currency.fromCursor(cursor);
            currencies.add(currency);
        }

        return currencies;
    }

    private CurrencyService getService() {
        // todo: redo the currency service to remove any UI interaction (dialog) and then use IoC.
        //        return mCurrencyService.get();
        if (mCurrencyService == null) {
            mCurrencyService = new CurrencyService(getActivity());
        }
        return mCurrencyService;
    }

    private LoaderManager.LoaderCallbacks<Cursor> initLoaderCallbacks() {
        LoaderManager.LoaderCallbacks<Cursor> callbacks = new LoaderManager.LoaderCallbacks<Cursor>() {
            @Override
            public Loader<Cursor> onCreateLoader(int id, Bundle args) {
                switch (id) {
                case ID_LOADER_CURRENCY:
                    String whereClause = "";
                    ArrayList<String> arguments = new ArrayList<>();

                    // filter only used accounts?
                    if (mShowOnlyUsedCurrencies) {
                        // get the list of used currencies.
                        CurrencyService currencyService = getService();
                        List<Currency> usedCurrencies = currencyService.getUsedCurrencies();
                        if (usedCurrencies != null && usedCurrencies.size() > 0) {
                            ArrayList<String> symbols = new ArrayList<>();
                            for (Currency currency : usedCurrencies) {
                                if (currency == null) {
                                    new UIHelper(getActivity()).showToast(R.string.currency_not_found);
                                } else {
                                    symbols.add(currency.getCode());
                                }
                            }

                            MmxDatabaseUtils databaseUtils = new MmxDatabaseUtils(getActivity());
                            whereClause = Currency.CURRENCY_SYMBOL + " IN ("
                                    + databaseUtils.makePlaceholders(usedCurrencies.size()) + ")";
                            arguments.addAll(symbols);
                        }
                    }

                    if (!TextUtils.isEmpty(mCurFilter)) {
                        if (!TextUtils.isEmpty(whereClause)) {
                            whereClause += " AND ";
                        }

                        whereClause += Currency.CURRENCYNAME + " LIKE ?";
                        arguments.add(mCurFilter + "%");
                        //                    selectionArgs = new String[]{ mCurFilter + "%"};
                    }

                    String selectionArgs[] = new String[arguments.size()];
                    selectionArgs = arguments.toArray(selectionArgs);

                    CurrencyRepository repo = new CurrencyRepository(getActivity());
                    Select query = new Select(repo.getAllColumns()).where(whereClause, selectionArgs)
                            .orderBy("upper(" + Currency.CURRENCYNAME + ")");

                    return new MmxCursorLoader(getActivity(), repo.getUri(), query);
                }

                return null;
            }

            @Override
            public void onLoaderReset(Loader<Cursor> loader) {
                switch (loader.getId()) {
                case ID_LOADER_CURRENCY:
                    CurrencyListAdapter adapter = (CurrencyListAdapter) getListAdapter();
                    //                adapter.swapCursor(null);
                    adapter.changeCursor(null);
                    break;
                }
            }

            @Override
            public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
                switch (loader.getId()) {
                case ID_LOADER_CURRENCY:
                    CurrencyListAdapter adapter = (CurrencyListAdapter) getListAdapter();
                    //                adapter.swapCursor(data);
                    adapter.changeCursor(data);

                    if (isResumed()) {
                        setListShown(true);
                        if (data != null && data.getCount() <= 0 && getFloatingActionButton() != null)
                            getFloatingActionButton().show(true);
                    } else {
                        setListShownNoAnimation(true);
                    }
                    break;
                }
            }
        };
        return callbacks;
    }

    private void initializeSwipeToRefresh() {

    }

    private void loadData() {
        getLoaderManager().initLoader(ID_LOADER_CURRENCY, null, this.loaderCallbacks);
    }

    private void reloadData() {
        getLoaderManager().restartLoader(ID_LOADER_CURRENCY, null, this.loaderCallbacks);
    }
}