org.gnucash.android.ui.accounts.AddAccountFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.gnucash.android.ui.accounts.AddAccountFragment.java

Source

/*
 * Copyright (c) 2012 Ngewi Fet <ngewif@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gnucash.android.ui.accounts;

import java.util.Arrays;
import java.util.Currency;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import org.gnucash.android.R;
import org.gnucash.android.data.Account;
import org.gnucash.android.data.Money;
import org.gnucash.android.db.AccountsDbAdapter;
import org.gnucash.android.db.DatabaseHelper;
import org.gnucash.android.ui.transactions.TransactionsListFragment;

import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;

/**
 * Fragment used for creating and editing accounts
 * @author Ngewi Fet <ngewif@gmail.com>
 */
public class AddAccountFragment extends SherlockFragment {

    /**
     * EditText for the name of the account to be created/edited
     */
    private EditText mNameEditText;

    /**
     * Spinner for selecting the currency of the account
     * Currencies listed are those specified by ISO 4217
     */
    private Spinner mCurrencySpinner;

    /**
     * Accounts database adapter
     */
    private AccountsDbAdapter mAccountsDbAdapter;

    /**
     * List of all currency codes (ISO 4217) supported by the app
     */
    private List<String> mCurrencyCodes;

    /**
     * Record ID of the account which was selected
     * This is used if we are editing an account instead of creating one
     */
    private long mSelectedAccountId = 0;

    /**
     * Reference to account object which will be created at end of dialog
     */
    private Account mAccount = null;

    private Cursor mCursor;

    private SimpleCursorAdapter mCursorAdapter;

    private Spinner mParentAccountSpinner;

    private CheckBox mParentCheckBox;

    private Spinner mAccountTypeSpinner;

    /**
     * Default constructor
     * Required, else the app crashes on screen rotation
     */
    public AddAccountFragment() {
        //nothing to see here, move along
    }

    /**
     * Construct a new instance of the dialog
     * @param dbAdapter {@link AccountsDbAdapter} for saving the account
     * @return New instance of the dialog fragment
     */
    static public AddAccountFragment newInstance(AccountsDbAdapter dbAdapter) {
        AddAccountFragment f = new AddAccountFragment();
        f.mAccountsDbAdapter = dbAdapter;
        return f;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        if (mAccountsDbAdapter == null) {
            mAccountsDbAdapter = new AccountsDbAdapter(getSherlockActivity());
        }
    }

    /**
     * Inflates the dialog view and retrieves references to the dialog elements
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_new_account, container, false);
        getSherlockActivity().getSupportActionBar().setTitle(R.string.title_add_account);
        mCurrencySpinner = (Spinner) view.findViewById(R.id.input_currency_spinner);
        mNameEditText = (EditText) view.findViewById(R.id.edit_text_account_name);
        mNameEditText.requestFocus();

        mAccountTypeSpinner = (Spinner) view.findViewById(R.id.input_account_type_spinner);

        mParentAccountSpinner = (Spinner) view.findViewById(R.id.input_parent_account);
        mParentAccountSpinner.setEnabled(false);

        mParentCheckBox = (CheckBox) view.findViewById(R.id.checkbox);
        mParentCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                mParentAccountSpinner.setEnabled(isChecked);
            }
        });

        return view;
    }

    /**
     * Initializes the values of the views in the dialog
     */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.currency_names));
        arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mCurrencySpinner.setAdapter(arrayAdapter);

        loadParentAccountList();
        loadAccountTypesList();

        mSelectedAccountId = getArguments().getLong(TransactionsListFragment.SELECTED_ACCOUNT_ID);
        if (mSelectedAccountId > 0) {
            mAccount = mAccountsDbAdapter.getAccount(mSelectedAccountId);
            getSherlockActivity().getSupportActionBar().setTitle(R.string.title_edit_account);
        }

        if (mAccount != null) {
            initializeViewsWithAccount(mAccount);
        } else {
            initializeViews();
        }
    }

    /**
     * Initialize view with the properties of <code>account</code>.
     * This is applicable when editing an account
     * @param account Account whose fields are used to populate the form
     */
    private void initializeViewsWithAccount(Account account) {
        if (account == null)
            throw new IllegalArgumentException("Account cannot be null");

        String currencyCode = account.getCurrency().getCurrencyCode();
        setSelectedCurrency(currencyCode);

        mNameEditText.setText(account.getName());
        long parentAccountId = mAccountsDbAdapter.getAccountID(account.getParentUID());
        setParentAccountSelection(parentAccountId);

        String[] accountTypeEntries = getResources().getStringArray(R.array.account_type_entries);
        int accountTypeIndex = Arrays.asList(accountTypeEntries).indexOf(account.getAccountType().name());
        mAccountTypeSpinner.setSelection(accountTypeIndex);
    }

    /**
     * Initialize views with defaults for new account
     */
    private void initializeViews() {
        setSelectedCurrency(Money.DEFAULT_CURRENCY_CODE);

        long parentAccountId = getArguments().getLong(AccountsListFragment.ARG_PARENT_ACCOUNT_ID);
        setParentAccountSelection(parentAccountId);

    }

    /**
     * Selects the currency with code <code>currencyCode</code> in the spinner
     * @param currencyCode ISO 4217 currency code to be selected
     */
    private void setSelectedCurrency(String currencyCode) {
        mCurrencyCodes = Arrays.asList(getResources().getStringArray(R.array.currency_codes));
        if (mCurrencyCodes.contains(currencyCode)) {
            mCurrencySpinner.setSelection(mCurrencyCodes.indexOf(currencyCode));
        }
    }

    /**
     * Selects the account with ID <code>parentAccountId</code> in the parent accounts spinner
     * @param parentAccountId Record ID of parent account to be selected
     */
    private void setParentAccountSelection(long parentAccountId) {
        if (parentAccountId > 0) {
            mParentCheckBox.setChecked(true);
            mParentAccountSpinner.setEnabled(true);
        } else
            return;

        for (int pos = 0; pos < mCursorAdapter.getCount(); pos++) {
            if (mCursorAdapter.getItemId(pos) == parentAccountId) {
                mParentAccountSpinner.setSelection(pos);
                break;
            }
        }
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_save:
            saveAccount();
            return true;

        case R.id.menu_cancel:
            finishFragment();
            return true;
        }

        return false;
    }

    private void loadParentAccountList() {
        String condition = DatabaseHelper.KEY_ROW_ID + "!=" + mSelectedAccountId;
        mCursor = mAccountsDbAdapter.fetchAccounts(condition);
        if (mCursor.getCount() <= 0) {
            final View view = getView();
            view.findViewById(R.id.layout_parent_account).setVisibility(View.GONE);
            view.findViewById(R.id.label_parent_account).setVisibility(View.GONE);
        }

        String[] from = new String[] { DatabaseHelper.KEY_NAME };
        int[] to = new int[] { android.R.id.text1 };
        mCursorAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_spinner_item, mCursor, from,
                to, 0);
        mCursorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mParentAccountSpinner.setAdapter(mCursorAdapter);
    }

    private void loadAccountTypesList() {
        String[] accountTypes = getResources().getStringArray(R.array.account_type_entry_values);
        ArrayAdapter<String> accountTypesAdapter = new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_list_item_1, accountTypes);

        accountTypesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mAccountTypeSpinner.setAdapter(accountTypesAdapter);

    }

    /**
     * Finishes the fragment appropriately.
     * Depends on how the fragment was loaded, it might have a backstack or not
     */
    private void finishFragment() {
        InputMethodManager imm = (InputMethodManager) getSherlockActivity()
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(mNameEditText.getWindowToken(), 0);

        final String action = getActivity().getIntent().getAction();
        if (action != null && action.equals(Intent.ACTION_INSERT_OR_EDIT)) {
            getActivity().setResult(Activity.RESULT_OK);
            getActivity().finish();
        } else {
            getSherlockActivity().getSupportFragmentManager().popBackStack();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroyView();
        if (mCursor != null)
            mCursor.close();
        //do not close the database adapter. We got it from the activity, 
        //the activity will take care of it.
    }

    private void saveAccount() {
        if (mAccount == null) {
            String name = getEnteredName();
            if (name == null || name.length() == 0) {
                Toast.makeText(getSherlockActivity(), R.string.toast_no_account_name_entered, Toast.LENGTH_LONG)
                        .show();
                return;
            }
            mAccount = new Account(getEnteredName());
        } else
            mAccount.setName(getEnteredName());

        String curCode = mCurrencyCodes.get(mCurrencySpinner.getSelectedItemPosition());
        mAccount.setCurrency(Currency.getInstance(curCode));

        int selectedAccountType = mAccountTypeSpinner.getSelectedItemPosition();
        String[] accountTypeEntries = getResources().getStringArray(R.array.account_type_entries);
        mAccount.setAccountType(Account.AccountType.valueOf(accountTypeEntries[selectedAccountType]));

        if (mParentCheckBox.isChecked()) {
            long id = mParentAccountSpinner.getSelectedItemId();
            mAccount.setParentUID(mAccountsDbAdapter.getAccountUID(id));
        } else {
            mAccount.setParentUID(null);
        }

        if (mAccountsDbAdapter == null)
            mAccountsDbAdapter = new AccountsDbAdapter(getActivity());
        mAccountsDbAdapter.addAccount(mAccount);

        finishFragment();
    }

    /**
     * Retrieves the name of the account which has been entered in the EditText
     * @return
     */
    public String getEnteredName() {
        return mNameEditText.getText().toString().trim();
    }

}