/*
* 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.fragment;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
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.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
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.money.manager.ex.PayeeActivity;
import com.money.manager.ex.R;
import com.money.manager.ex.adapter.MoneySimpleCursorAdapter;
import com.money.manager.ex.core.ContextMenuIds;
import com.money.manager.ex.core.IntentFactory;
import com.money.manager.ex.core.UIHelper;
import com.money.manager.ex.datalayer.PayeeRepository;
import com.money.manager.ex.datalayer.Select;
import com.money.manager.ex.servicelayer.PayeeService;
import com.money.manager.ex.common.BaseListFragment;
import com.money.manager.ex.common.MmxCursorLoader;
import com.money.manager.ex.database.SQLTypeTransaction;
import com.money.manager.ex.domainmodel.Payee;
import com.money.manager.ex.search.SearchParameters;
import com.money.manager.ex.settings.AppSettings;
import com.money.manager.ex.utils.AlertDialogWrapper;
import com.shamanland.fonticon.FontIconDrawable;
/**
* List of Payees. Used as a picker/selector also.
*/
public class PayeeListFragment
extends BaseListFragment
implements LoaderManager.LoaderCallbacks<Cursor> {
public static String mAction = Intent.ACTION_EDIT;
// add menu ite,
// private static final int MENU_ITEM_ADD = 1;
private static final int ID_LOADER_PAYEE = 0;
private static final String SORT_BY_USAGE = "(SELECT COUNT(*) FROM CHECKINGACCOUNT_V1 WHERE PAYEE_V1.PAYEEID = CHECKINGACCOUNT_V1.PAYEEID) DESC";
private static final String SORT_BY_NAME = "UPPER(" + Payee.PAYEENAME + ")";
private Context mContext;
private String mCurFilter;
private int mSort = 0;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mContext = getActivity();
setSearchMenuVisible(true);
// Focus on search menu if set in preferences.
AppSettings settings = new AppSettings(mContext);
boolean focusOnSearch = settings.getBehaviourSettings().getFilterInSelectors();
setMenuItemSearchIconified(!focusOnSearch);
setEmptyText(getActivity().getResources().getString(R.string.payee_empty_list));
setHasOptionsMenu(true);
int layout = android.R.layout.simple_list_item_1;
// associate adapter
MoneySimpleCursorAdapter adapter = new MoneySimpleCursorAdapter(getActivity(),
layout, null, new String[] { Payee.PAYEENAME },
new int[]{android.R.id.text1}, 0);
// set adapter
setListAdapter(adapter);
registerForContextMenu(getListView());
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
setListShown(false);
// init sort
// mSort = PreferenceManager.getDefaultSharedPreferences(getActivity())
// .getInt(getString(PreferenceConstants.PREF_SORT_PAYEE), 0);
mSort = settings.getPayeeSort();
// start loader
getLoaderManager().initLoader(ID_LOADER_PAYEE, null, this);
// set floating button visible
setFloatingActionButtonVisible(true);
attachFloatingActionButtonToListView();
}
// Menu
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_payee, menu);
AppSettings settings = new AppSettings(mContext);
int payeeSort = settings.getPayeeSort();
//Check the default sort order
final MenuItem item;
// PreferenceManager.getDefaultSharedPreferences(getActivity()).getInt(getString(PreferenceConstants.PREF_SORT_PAYEE), 0)
switch (payeeSort) {
case 0:
item = menu.findItem(R.id.menu_sort_name);
item.setChecked(true);
break;
case 1:
item = menu.findItem(R.id.menu_sort_usage);
item.setChecked(true);
break;
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
AppSettings settings = new AppSettings(mContext);
switch (item.getItemId()) {
case R.id.menu_sort_name:
mSort = 0;
item.setChecked(true);
settings.set(R.string.pref_sort_payee, mSort);
// restart search
restartLoader();
return true;
case R.id.menu_sort_usage:
mSort = 1;
item.setChecked(true);
settings.set(R.string.pref_sort_payee, mSort);
// restart search
restartLoader();
return true;
case android.R.id.home:
getActivity().setResult(PayeeActivity.RESULT_CANCELED);
getActivity().finish();
return true;
}
return super.onOptionsItemSelected(item);
}
// Context Menu
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
Cursor cursor = ((SimpleCursorAdapter) getListAdapter()).getCursor();
cursor.moveToPosition(info.position);
menu.setHeaderTitle(cursor.getString(cursor.getColumnIndex(Payee.PAYEENAME)));
menu.add(Menu.NONE, ContextMenuIds.EDIT.getId(), Menu.NONE, getString(R.string.edit));
menu.add(Menu.NONE, ContextMenuIds.DELETE.getId(), Menu.NONE, getString(R.string.delete));
menu.add(Menu.NONE, ContextMenuIds.VIEW_TRANSACTIONS.getId(), Menu.NONE, getString(R.string.view_transactions));
}
@Override
public boolean onContextItemSelected(android.view.MenuItem item) {
AdapterView.AdapterContextMenuInfo info = null;
if (item.getMenuInfo() instanceof AdapterView.AdapterContextMenuInfo) {
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
} else {
return false;
}
// if (item.getMenuInfo() instanceof ExpandableListView.ExpandableListContextMenuInfo) {
// info = item.getMenuInfo();
// }
Cursor cursor = ((SimpleCursorAdapter) getListAdapter()).getCursor();
cursor.moveToPosition(info.position);
// Read values from cursor.
Payee payee = new Payee();
payee.loadFromCursor(cursor);
ContextMenuIds menuId = ContextMenuIds.get(item.getItemId());
if (menuId == null) return false;
switch (menuId) {
case EDIT:
showDialogEditPayeeName(SQLTypeTransaction.UPDATE, payee.getId(), payee.getName());
break;
case DELETE:
PayeeService service = new PayeeService(getActivity());
if (!service.isPayeeUsed(payee.getId())) {
showDialogDeletePayee(payee.getId());
} else {
new AlertDialogWrapper(getActivity())
.setTitle(R.string.attention)
.setIcon(new UIHelper(getActivity()).getIcon(GoogleMaterial.Icon.gmd_warning))
.setMessage(R.string.payee_can_not_deleted)
.setPositiveButton(android.R.string.ok)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
dialog.dismiss();
}
})
.create().show();
}
break;
case VIEW_TRANSACTIONS:
SearchParameters parameters = new SearchParameters();
parameters.payeeId = payee.getId();
parameters.payeeName = payee.getName();
Intent intent = IntentFactory.getSearchIntent(getActivity(), parameters);
startActivity(intent);
}
return false;
}
// Loader
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id) {
case ID_LOADER_PAYEE:
String whereClause = null;
String selectionArgs[] = null;
if (!TextUtils.isEmpty(mCurFilter)) {
whereClause = Payee.PAYEENAME + " LIKE ?"; // + mCurFilter + "%'";
selectionArgs = new String[]{mCurFilter + '%'};
}
PayeeRepository repo = new PayeeRepository(getActivity());
Select query = new Select(repo.getAllColumns())
.where(whereClause, selectionArgs)
.orderBy(mSort == 1 ? SORT_BY_USAGE : SORT_BY_NAME);
return new MmxCursorLoader(getActivity(), repo.getUri(), query);
}
return null;
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
switch (loader.getId()) {
case ID_LOADER_PAYEE:
MoneySimpleCursorAdapter adapter = (MoneySimpleCursorAdapter) getListAdapter();
// adapter.swapCursor(null);
adapter.changeCursor(null);
}
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (data == null) return;
switch (loader.getId()) {
case ID_LOADER_PAYEE:
MoneySimpleCursorAdapter adapter = (MoneySimpleCursorAdapter) getListAdapter();
String highlightFilter = mCurFilter != null
? mCurFilter.replace("%", "")
: "";
adapter.setHighlightFilter(highlightFilter);
// adapter.swapCursor(data);
adapter.changeCursor(data);
if (isResumed()) {
setListShown(true);
if (data.getCount() <= 0 && getFloatingActionButton() != null) {
getFloatingActionButton().show(true);
}
} else {
setListShownNoAnimation(true);
}
}
}
@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;
restartLoader();
return true;
}
@Override
protected void setResult() {
if (Intent.ACTION_PICK.equals(mAction)) {
// Cursor that is already in the desired position, because positioned in the event onListItemClick
Cursor cursor = ((SimpleCursorAdapter) getListAdapter()).getCursor();
int payeeId = cursor.getInt(cursor.getColumnIndex(Payee.PAYEEID));
String payeeName = cursor.getString(cursor.getColumnIndex(Payee.PAYEENAME));
sendResultToActivity(payeeId, payeeName);
return;
}
getActivity().setResult(PayeeActivity.RESULT_CANCELED);
}
private void sendResultToActivity(int payeeId, String payeeName) {
Intent result = new Intent();
result.putExtra(PayeeActivity.INTENT_RESULT_PAYEEID, payeeId);
result.putExtra(PayeeActivity.INTENT_RESULT_PAYEENAME, payeeName);
getActivity().setResult(Activity.RESULT_OK, result);
getActivity().finish();
}
private void showDialogDeletePayee(final int payeeId) {
new AlertDialogWrapper(getContext())
.setTitle(R.string.delete_payee)
.setIcon(new IconicsDrawable(getActivity()).icon(GoogleMaterial.Icon.gmd_warning))
.setMessage(R.string.confirmDelete)
.setPositiveButton(android.R.string.ok,
new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
PayeeRepository repo = new PayeeRepository(getActivity());
boolean success = repo.delete(payeeId);
if (success) {
Toast.makeText(getActivity(), R.string.delete_success, Toast.LENGTH_SHORT).show();
}
restartLoader();
}
})
.setNegativeButton(android.R.string.cancel,
new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
dialog.cancel();
}
})
.create().show();
}
private void showDialogEditPayeeName(final SQLTypeTransaction type, final int payeeId, final String payeeName) {
View viewDialog = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_new_edit_payee, null);
final EditText edtPayeeName = (EditText) viewDialog.findViewById(R.id.editTextPayeeName);
edtPayeeName.setText(payeeName);
if (!TextUtils.isEmpty(payeeName)) {
edtPayeeName.setSelection(payeeName.length());
}
new AlertDialogWrapper(getContext())
.setView(viewDialog)
.setIcon(FontIconDrawable.inflate(getContext(), R.xml.ic_user))
.setTitle(R.string.edit_payeeName)
.setPositiveButton(android.R.string.ok,
new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
// take payee name from the input field.
String name = edtPayeeName.getText().toString();
PayeeService service = new PayeeService(mContext);
// check if action in update or insert
switch (type) {
case INSERT:
Payee payee = service.createNew(name);
if (payee != null) {
// Created a new payee. But only if picking a payee for another activity.
if (mAction.equalsIgnoreCase(Intent.ACTION_PICK)) {
// Select it and close.
sendResultToActivity(payee.getId(), name);
return;
}
} else {
// error inserting.
Toast.makeText(mContext, R.string.db_insert_failed, Toast.LENGTH_SHORT).show();
}
break;
case UPDATE:
int updateResult = service.update(payeeId, name);
if (updateResult <= 0) {
Toast.makeText(mContext, R.string.db_update_failed, Toast.LENGTH_SHORT).show();
}
break;
case DELETE:
break;
default:
break;
}
// restart loader
restartLoader();
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.create().show();
}
@Override
public String getSubTitle() {
return getString(R.string.payees);
}
@Override
public void onFloatingActionButtonClicked() {
String payeeSearch = !TextUtils.isEmpty(mCurFilter) ? mCurFilter.replace("%", "") : "";
showDialogEditPayeeName(SQLTypeTransaction.INSERT, 0, payeeSearch);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// On select go back to the calling activity (if there is one)
if (getActivity().getCallingActivity() != null) {
Cursor cursor = ((SimpleCursorAdapter) getListAdapter()).getCursor();
if (cursor != null) {
if (cursor.moveToPosition(position)) {
setResultAndFinish();
}
}
} else {
// No calling activity, this is the independent Payees view. Show context menu.
getActivity().openContextMenu(v);
}
}
public void restartLoader() {
getLoaderManager().restartLoader(ID_LOADER_PAYEE, null, this);
}
// private void showSearchActivityFor(SearchParameters parameters) {
// Intent intent = new Intent(getActivity(), SearchActivity.class);
// intent.putExtra(SearchActivity.EXTRA_SEARCH_PARAMETERS, parameters);
// intent.setAction(Intent.ACTION_INSERT);
// startActivity(intent);
// }
}