/* * 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.recycler; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; 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.Toast; import com.money.manager.ex.R; import com.money.manager.ex.common.events.ListItemClickedEvent; 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.domainmodel.Account; import com.money.manager.ex.domainmodel.Currency; import com.money.manager.ex.investment.events.AllPricesDownloadedEvent; import com.money.manager.ex.investment.events.PriceDownloadedEvent; import com.money.manager.ex.settings.AppSettings; import com.money.manager.ex.view.recycler.ContextMenuRecyclerView; import com.money.manager.ex.view.recycler.DividerItemDecoration; import com.money.manager.ex.view.recycler.RecyclerViewContextMenuInfo; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.SubscriberExceptionEvent; import java.util.LinkedHashMap; import java.util.List; import io.github.luizgrp.sectionedrecyclerviewadapter.Section; import io.github.luizgrp.sectionedrecyclerviewadapter.SectionedRecyclerViewAdapter; import timber.log.Timber; /** * Recycler list fragment. * Missing pieces: * - search * - back button * - context menu * - update data after currency edit/insert * - update list after currency exchange rate update. */ public class CurrencyRecyclerListFragment extends Fragment { public static CurrencyRecyclerListFragment createInstance() { CurrencyRecyclerListFragment fragment = new CurrencyRecyclerListFragment(); // bundle return fragment; } private CurrencyService mCurrencyService; private CurrencyContentObserver mObserver; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // create content observer mObserver = new CurrencyContentObserver(null); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_currency_recycler_list, container, false); // View view = super.onCreateView(inflater, container, savedInstanceState); return view; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { ContextMenuRecyclerView list = getRecyclerView(); registerForContextMenu(list); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // todo setSearchMenuVisible(true); // Focus on search menu if set in preferences. AppSettings settings = new AppSettings(getActivity()); boolean focusOnSearch = settings.getBehaviourSettings().getFilterInSelectors(); // todo setMenuItemSearchIconified(!focusOnSearch); // todo setEmptyText(getActivity().getResources().getString(R.string.currencies_empty)); setHasOptionsMenu(true); // todo setFloatingActionButtonVisible(true); // todo attachFloatingActionButtonToListView(true); initializeList(); } @Override public void onPause() { super.onPause(); // register content observer CurrencyRepository repo = new CurrencyRepository(getActivity()); getActivity().getContentResolver().registerContentObserver(repo.getUri(), true, mObserver); } @Override public void onResume() { super.onResume(); // unregister content observer getActivity().getContentResolver().unregisterContentObserver(mObserver); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { RecyclerViewContextMenuInfo info = (RecyclerViewContextMenuInfo) menuInfo; Currency currency = getCurrencyAtPosition(info.position); menu.setHeaderTitle(currency.getName()); // 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) { RecyclerViewContextMenuInfo info = (RecyclerViewContextMenuInfo) item.getMenuInfo(); Currency currency = getCurrencyAtPosition(info.position); int currencyId = currency.getCurrencyId(); 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. // todo: this.mPreviousOrientation = ActivityUtils.forceCurrentOrientation(getActivity()); // add the currency information. String symbol = currency.getCode(); 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; } // Events @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { super.onStop(); EventBus.getDefault().unregister(this); } @Subscribe public void onEvent(PriceDownloadedEvent event) { CurrencyUIFeatures ui = new CurrencyUIFeatures(getContext()); boolean updated = ui.onPriceDownloaded(event.symbol, event.price, event.date); if (!updated) { // show error msg new UIHelper(getActivity()).showToast("could not update the price!"); } } @Subscribe public void onEvent(AllPricesDownloadedEvent event) { loadData(getAdapter()); // update ui. getAdapter().notifyItemRangeChanged(0, getAdapter().getItemCount()); } @Subscribe public void onEvent(ExchangeRateUpdateConfirmedEvent event) { // proceed with rate update List<Currency> currencies = getService().getUsedCurrencies(); if (event.updateAll) { // add unused currencies. currencies.addAll(getService().getUnusedCurrencies()); } getService().updateExchangeRates(currencies); } @Subscribe public void onEvent(SubscriberExceptionEvent exceptionEvent) { Timber.e(exceptionEvent.throwable, "events"); } @Subscribe public void onEvent(ListItemClickedEvent event) { // item selected. Show context menu. // todo: complete getActivity().openContextMenu(event.view); } @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(); // remove from data. LinkedHashMap<String, Section> sectionMap = getAdapter().getSectionsMap(); for(Section section : sectionMap.values()){ CurrencySection currencySection = (CurrencySection) section; currencySection.currencies.remove(event.itemPosition); } // update ui. getAdapter().notifyItemRemoved(event.itemPosition); } } // Menu. @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.menu_currency_formats_list_activity, menu); menu.findItem(R.id.menu_show_used).setVisible(false); } @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.showActiveInactiveSelectorForUpdate(); break; } return super.onOptionsItemSelected(item); } // @Override // public void onFloatingActionButtonClicked() { // CurrencyUIFeatures ui = new CurrencyUIFeatures(getActivity()); // ui.startCurrencyEditActivity(null); // } // Private private SectionedRecyclerViewAdapter getAdapter() { return (SectionedRecyclerViewAdapter) getRecyclerView().getAdapter(); } private Currency getCurrencyAtPosition(int position) { int sectionPosition = getAdapter().getSectionPosition(position); CurrencySection section = (CurrencySection) getAdapter().getSectionForPosition(position); //Currency currency = section.currencies.get(sectionPosition); Currency currency = section.getItemAtPosition(sectionPosition); return currency; } private ContextMenuRecyclerView getRecyclerView() { return (ContextMenuRecyclerView) getActivity().findViewById(R.id.list); } private CurrencyService getService() { if(mCurrencyService == null) { mCurrencyService = new CurrencyService(getActivity()); } return mCurrencyService; } private void initializeList() { Context context = getActivity(); RecyclerView recyclerView = getRecyclerView(); if (recyclerView == null) return; // Layout manager recyclerView.setLayoutManager(new LinearLayoutManager(context)); // Adapter final SectionedRecyclerViewAdapter adapter = new SectionedRecyclerViewAdapter(); // load data loadData(adapter); recyclerView.setAdapter(adapter); // Separator recyclerView.addItemDecoration(new DividerItemDecoration(context, LinearLayoutManager.VERTICAL)); // Behaviours. List click listener. recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getContext(), new RecyclerItemClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { Currency currency = getCurrencyAtPosition(position); int id = currency.getCurrencyId(); String name = currency.getName(); EventBus.getDefault().post(new ListItemClickedEvent(id, name, view)); } })); } private void loadData(SectionedRecyclerViewAdapter adapter) { CurrencyService service = new CurrencyService(getActivity()); adapter.removeAllSections(); // List<Currency> currencies = new ArrayList<>(); //for (Currency currency : service.getUsedCurrencies()) currencies.put(currency.getCode(), currency); adapter.addSection(new CurrencySection(getString(R.string.active_currencies), service.getUsedCurrencies())); // currencies = new ArrayList<>(); // for (Currency currency : service.getUnusedCurrencies()) currencies.put(currency.getCode(), currency); adapter.addSection(new CurrencySection(getString(R.string.inactive_currencies), service.getUnusedCurrencies())); } }