/* * 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.account; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.support.v4.widget.SimpleCursorAdapter; import android.text.TextUtils; import android.view.ContextMenu; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast; import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.MaterialDialog; import com.mikepenz.google_material_typeface_library.GoogleMaterial; import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.mmex_icon_font_typeface_library.MMXIconFont; import com.money.manager.ex.R; import com.money.manager.ex.adapter.MoneySimpleCursorAdapter; import com.money.manager.ex.common.BaseListFragment; import com.money.manager.ex.common.MmxCursorLoader; import com.money.manager.ex.core.ContextMenuIds; import com.money.manager.ex.core.MenuHelper; import com.money.manager.ex.core.UIHelper; import com.money.manager.ex.datalayer.AccountRepository; import com.money.manager.ex.datalayer.Select; import com.money.manager.ex.domainmodel.Account; import com.money.manager.ex.servicelayer.AccountService; import com.shamanland.fonticon.FontIconDrawable; /** * List of accounts. */ public class AccountListFragment extends BaseListFragment implements LoaderManager.LoaderCallbacks<Cursor> { private static final int LOADER_ACCOUNT = 0; public String mAction = Intent.ACTION_EDIT; private String mCurFilter; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // set show search setSearchMenuVisible(true); // set default value setEmptyText(getActivity().getResources().getString(R.string.account_empty_list)); setHasOptionsMenu(true); int layout = Intent.ACTION_PICK.equals(mAction) ? android.R.layout.simple_list_item_multiple_choice : android.R.layout.simple_list_item_1; // create adapter MoneySimpleCursorAdapter adapter = new MoneySimpleCursorAdapter(getActivity(), layout, null, new String[]{ Account.ACCOUNTNAME }, new int[]{android.R.id.text1}, 0); setListAdapter(adapter); registerForContextMenu(getListView()); getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); setListShown(false); // start loader getLoaderManager().initLoader(LOADER_ACCOUNT, null, this); // set icon searched setMenuItemSearchIconified(!Intent.ACTION_PICK.equals(mAction)); setFloatingActionButtonVisible(true); attachFloatingActionButtonToListView(); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; // get selected item name SimpleCursorAdapter adapter = (SimpleCursorAdapter) getListAdapter(); Cursor cursor = (Cursor) adapter.getItem(info.position); menu.setHeaderTitle(cursor.getString(cursor.getColumnIndex(Account.ACCOUNTNAME))); MenuHelper menuHelper = new MenuHelper(getActivity(), menu); menuHelper.addEditToContextMenu(); menuHelper.addDeleteToContextMenu(); } @Override public boolean onContextItemSelected(android.view.MenuItem item) { ContextMenu.ContextMenuInfo menuInfo = item.getMenuInfo(); // ExpandableListView$ExpandableListContextMenuInfo if (!(menuInfo instanceof AdapterView.AdapterContextMenuInfo)) return false; AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; int accountId = (int) info.id; int itemId = item.getItemId(); ContextMenuIds menuId = ContextMenuIds.get(itemId); if (menuId == null) return false; switch (menuId) { case EDIT: startAccountListEditActivity(accountId); break; case DELETE: AccountService service = new AccountService(getActivity()); if (service.isAccountUsed(accountId)) { new MaterialDialog.Builder(getContext()) .title(R.string.attention) .icon(new UIHelper(getActivity()).getIcon(GoogleMaterial.Icon.gmd_warning)) .content(R.string.account_can_not_deleted) .positiveText(android.R.string.ok) .onPositive(new MaterialDialog.SingleButtonCallback() { @Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { dialog.dismiss(); } }) .build().show(); } else { showDeleteConfirmationDialog(accountId); } break; } return false; } // Loader @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { switch (id) { case LOADER_ACCOUNT: String whereClause = null; String selectionArgs[] = null; if (!TextUtils.isEmpty(mCurFilter)) { whereClause = Account.ACCOUNTNAME + " LIKE ?"; selectionArgs = new String[]{mCurFilter + "%"}; } AccountRepository repo = new AccountRepository(getActivity()); Select query = new Select(repo.getAllColumns()) .where(whereClause, selectionArgs) .orderBy("upper(" + Account.ACCOUNTNAME + ")"); return new MmxCursorLoader(getActivity(), repo.getUri(), query); } return null; } @Override public void onLoaderReset(Loader<Cursor> loader) { switch (loader.getId()) { case LOADER_ACCOUNT: MoneySimpleCursorAdapter adapter = (MoneySimpleCursorAdapter) getListAdapter(); // adapter.swapCursor(null); adapter.changeCursor(null); } } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { switch (loader.getId()) { case LOADER_ACCOUNT: MoneySimpleCursorAdapter adapter = (MoneySimpleCursorAdapter) getListAdapter(); adapter.setHighlightFilter(mCurFilter != null ? mCurFilter.replace("%", "") : ""); // adapter.swapCursor(data); adapter.changeCursor(data); if (isResumed()) { setListShown(true); if (data != null && data.getCount() <= 0 && getFloatingActionButton() != null) { getFloatingActionButton().show(true); } } else { setListShownNoAnimation(true); } } } // End loader /** * 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. * @param newText The search text * @return whether the event was handled or not */ @Override public boolean onQueryTextChange(String newText) { mCurFilter = !TextUtils.isEmpty(newText) ? newText : null; getLoaderManager().restartLoader(LOADER_ACCOUNT, null, this); return true; } @Override protected void setResult() { Intent result; if (Intent.ACTION_PICK.equals(mAction)) { // take cursor Cursor cursor = ((SimpleCursorAdapter) getListAdapter()).getCursor(); for (int i = 0; i < getListView().getCount(); i++) { if (getListView().isItemChecked(i)) { cursor.moveToPosition(i); result = new Intent(); result.putExtra(AccountListActivity.INTENT_RESULT_ACCOUNTID, cursor.getInt(cursor.getColumnIndex(Account.ACCOUNTID))); result.putExtra(AccountListActivity.INTENT_RESULT_ACCOUNTNAME, cursor.getString(cursor.getColumnIndex(Account.ACCOUNTNAME))); getActivity().setResult(Activity.RESULT_OK, result); return; } } } // return cancel getActivity().setResult(AccountListActivity.RESULT_CANCELED); } @Override public String getSubTitle() { return getString(R.string.accounts); } @Override public void onFloatingActionButtonClicked() { startAccountListEditActivity(); } @Override public void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); // show context menu here. getActivity().openContextMenu(v); } private void showDeleteConfirmationDialog(final int accountId) { new MaterialDialog.Builder(getContext()) .title(R.string.delete_account) .icon(FontIconDrawable.inflate(getContext(), R.xml.ic_question)) .content(R.string.confirmDelete) .positiveText(android.R.string.ok) .onPositive(new MaterialDialog.SingleButtonCallback() { @Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { AccountRepository repo = new AccountRepository(getActivity()); if (!repo.delete(accountId)) { Toast.makeText(getActivity(), R.string.db_delete_failed, Toast.LENGTH_SHORT).show(); } // restart loader getLoaderManager().restartLoader(LOADER_ACCOUNT, null, AccountListFragment.this); } }) .negativeText(android.R.string.cancel) .onNegative(new MaterialDialog.SingleButtonCallback() { @Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { dialog.cancel(); } }) .build().show(); } /** * Start the account management Activity */ private void startAccountListEditActivity() { this.startAccountListEditActivity(null); } /** * Start the account management Activity * * @param accountId is null for a new account, not null for editing accountId account */ private void startAccountListEditActivity(Integer accountId) { // create intent, set Account ID Intent intent = new Intent(getActivity(), AccountEditActivity.class); // check accountId not null if (accountId != null) { intent.putExtra(AccountEditActivity.KEY_ACCOUNT_ID, accountId); intent.setAction(Intent.ACTION_EDIT); } else { intent.setAction(Intent.ACTION_INSERT); } // launch activity startActivity(intent); } }