com.money.manager.ex.core.Core.java Source code

Java tutorial

Introduction

Here is the source code for com.money.manager.ex.core.Core.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.core;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Build;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.StyleSpan;
import android.view.LayoutInflater;
import android.view.View;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.money.manager.ex.Constants;
import com.money.manager.ex.MoneyManagerApplication;
import com.money.manager.ex.R;
import com.money.manager.ex.database.MmxOpenHelper;
import com.money.manager.ex.domainmodel.Payee;
import com.money.manager.ex.settings.AppSettings;
import com.money.manager.ex.utils.MmxDatabaseUtils;
import com.money.manager.ex.utils.MmxFileUtils;

import java.io.File;
import java.text.DateFormatSymbols;
import java.text.Normalizer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Locale;

import javax.inject.Inject;

import dagger.Lazy;
import timber.log.Timber;

public class Core {

    @Inject
    public Core(Context context) {
        super();

        this.mContext = context;
        // .getApplicationContext() == null ? context.getApplicationContext() : context;

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

    private Context mContext;
    @Inject
    Lazy<MmxOpenHelper> openHelper;
    @Inject
    Lazy<AppSettings> appSettingsLazy;

    /**
     * Show alert dialog.
     * @param textResourceId id of string to display as a message
     */
    public void alert(int textResourceId) {
        alert(Constants.NOT_SET, textResourceId);
    }

    public void alert(int title, int text) {
        if (title == Constants.NOT_SET) {
            title = R.string.attention;
        }

        new MaterialDialog.Builder(getContext())
                .icon(new UIHelper(getContext()).getIcon(GoogleMaterial.Icon.gmd_warning)).title(title)
                .content(text).positiveText(android.R.string.ok)
                .onPositive(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        dialog.dismiss();
                    }
                }).show();
    }

    /**
     * Backup current database
     * @return new File database backup
     */
    public File backupDatabase() {
        File database = new File(MoneyManagerApplication.getDatabasePath(getContext()));
        if (!database.exists())
            return null;

        //create folder to copy database
        MmxDatabaseUtils dbUtils = new MmxDatabaseUtils(getContext());
        File folderOutput = new File(dbUtils.getDefaultDatabaseDirectory());

        //take a folder of database
        ArrayList<File> filesFromCopy = new ArrayList<>();
        //add current database
        filesFromCopy.add(database);
        //get file journal
        File folder = database.getParentFile();
        if (folder != null) {
            for (File file : folder.listFiles()) {
                if (file.getName().startsWith(database.getName()) && !database.getName().equals(file.getName())) {
                    filesFromCopy.add(file);
                }
            }
        }
        //copy all files
        for (int i = 0; i < filesFromCopy.size(); i++) {
            try {
                MmxFileUtils.copy(filesFromCopy.get(i),
                        new File(folderOutput + "/" + filesFromCopy.get(i).getName()));
            } catch (Exception e) {
                Timber.e(e, "backing up the database");
                return null;
            }
        }

        return new File(folderOutput + "/" + filesFromCopy.get(0).getName());
    }

    //    public String getAppVersionBuild() {
    //        return Integer.toString(getAppVersionCode());
    //    }

    /**
     * Get a versioncode of the application.
     * @return application version name
     */
    public int getAppVersionCode() {
        try {
            PackageInfo packageInfo = getContext().getPackageManager().getPackageInfo(getContext().getPackageName(),
                    0);
            return packageInfo.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            Timber.e(e, "getting app version build number");
            return 0;
        }
    }

    public String getAppVersionName() {
        try {
            return getContext().getPackageManager().getPackageInfo(getContext().getPackageName(), 0).versionName;
        } catch (PackageManager.NameNotFoundException e) {
            Timber.e(e, "getting app version name");
        }
        return "n/a";
    }

    public Context getContext() {
        return mContext;
    }

    /**
     * Method, which returns the last payee used
     * @return last payee used
     */
    public Payee getLastPayeeUsed() {
        //        MmxOpenHelper helper = MmxOpenHelper.getInstance(getContext());
        Payee payee = null;

        String sql = "SELECT C.TransID, C.TransDate, C.PAYEEID, P.PAYEENAME, P.CATEGID, P.SUBCATEGID "
                + "FROM CHECKINGACCOUNT_V1 C " + "INNER JOIN PAYEE_V1 P ON C.PAYEEID = P.PAYEEID "
                + "WHERE C.TransCode <> 'Transfer' " + "ORDER BY C.TransDate DESC, C.TransId DESC " + "LIMIT 1";

        Cursor cursor = openHelper.get().getReadableDatabase().rawQuery(sql, null);

        // check if cursor can be open
        if (cursor != null && cursor.moveToFirst()) {
            payee = new Payee();
            //            payee.setPayeeId(cursor.getInt(cursor.getColumnIndex(Payee.PAYEEID)));
            //            payee.setPayeeName(cursor.getString(cursor.getColumnIndex(Payee.PAYEENAME)));
            //            payee.setCategId(cursor.getInt(cursor.getColumnIndex(Payee.CATEGID)));
            //            payee.setSubCategId(cursor.getInt(cursor.getColumnIndex(Payee.SUBCATEGID)));
            payee.loadFromCursor(cursor);

            cursor.close();
        }
        //close database
        //helper.close();

        return payee;
    }

    /**
     * Return arrays of month formatted and localized
     * @return arrays of months
     */
    public String[] getListMonths() {
        return new DateFormatSymbols().getMonths();
    }

    public String getDefaultSystemDateFormat() {
        Locale locale = Locale.getDefault();
        SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT, locale);
        String pattern = sdf.toLocalizedPattern();
        // replace date
        if (pattern.contains("dd")) {
            pattern = pattern.replace("dd", "%d");
        } else {
            pattern = pattern.replace("d", "%d");
        }
        // replace month
        if (pattern.contains("MM")) {
            pattern = pattern.replace("MM", "%m");
        } else {
            pattern = pattern.replace("M", "%m");
        }
        // replace year
        pattern = pattern.replace("yyyy", "%Y");
        pattern = pattern.replace("yy", "%y");
        // check if exists in format definition
        boolean found = false;
        String[] availableDateFormats = getContext().getResources().getStringArray(R.array.date_format_mask);
        for (int i = 0; i < availableDateFormats.length; i++) {
            if (pattern.equals(availableDateFormats[i])) {
                found = true;
                break;
            }
        }

        return found ? pattern : null;
    }

    public int getColourFromAttribute(int attribute) {
        TypedArray ta = getAttributeValue(attribute);
        int result = ta.getColor(0, Color.TRANSPARENT);

        ta.recycle();

        return result;
    }

    /**
     * This method allows to highlight in bold the content of a search string
     * @param search       string
     * @param originalText string where to find
     * @return CharSequence modified
     */
    public CharSequence highlight(String search, String originalText) {
        if (TextUtils.isEmpty(search))
            return originalText;
        // ignore case and accents
        // the same thing should have been done for the search text
        String normalizedText = Normalizer.normalize(originalText, Normalizer.Form.NFD)
                .replaceAll("\\p{InCombiningDiacriticalMarks}+", "").toLowerCase();

        int start = normalizedText.indexOf(search.toLowerCase());
        if (start < 0) {
            // not found, nothing to to
            return originalText;
        } else {
            // highlight each appearance in the original text
            // while searching in normalized text
            Spannable highlighted = new SpannableString(originalText);
            while (start >= 0) {
                int spanStart = Math.min(start, originalText.length());
                int spanEnd = Math.min(start + search.length(), originalText.length());

                highlighted.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), spanStart, spanEnd,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

                start = normalizedText.indexOf(search, spanEnd);
            }
            return highlighted;
        }
    }

    /**
     * Function that determines if the application is running on tablet
     * @return true if running on the tablet, otherwise false
     */
    public boolean isTablet() {
        int layout = getContext().getResources().getConfiguration().screenLayout;
        return ((layout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE)
                || ((layout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE);
    }

    /**
     * Resolves the id attribute in color
     * @param attr id attribute
     * @return color
     */
    public int resolveColorAttribute(int attr) {
        //        Resources.Theme currentTheme = mContext.getTheme();
        //        return mContext.getResources().getColor(resolveAttribute(attr), currentTheme);
        //return mContext.getResources().getColor(resolveAttribute(attr));
        UIHelper uiHelper = new UIHelper(getContext());
        return ContextCompat.getColor(getContext(), uiHelper.resolveAttribute(attr));
    }

    public boolean isToDisplayChangelog() {
        int currentVersionCode = getAppVersionCode();
        int lastVersionCode = PreferenceManager.getDefaultSharedPreferences(getContext())
                .getInt(getContext().getString(R.string.pref_last_version_key), Constants.NOT_SET);

        return lastVersionCode != currentVersionCode;
    }

    /**
     * Method, which allows you to change the language of the application on the fly.
     * @param languageToLoad language to load for the locale
     * @return and indicator whether the operation was successful
     * Ref: http://stackoverflow.com/questions/22402491/android-change-and-set-default-locale-within-the-app
     */
    public boolean setAppLocale(String languageToLoad) {
        try {
            setAppLocale_Internal(languageToLoad);
        } catch (Exception e) {
            Timber.e(e, "changing app locale");

            return false;
        }
        return true;
    }

    private void setAppLocale_Internal(String languageToLoad) {
        Locale locale;

        if (!TextUtils.isEmpty(languageToLoad)) {
            locale = new Locale(languageToLoad);
            //                locale = Locale.forLanguageTag(languageToLoad);
        } else {
            locale = Locale.getDefault();
        }
        // http://developer.android.com/reference/java/util/Locale.html#setDefault%28java.util.Locale%29
        //            Locale.setDefault(locale);

        // change locale of the configuration
        Resources resources = getContext().getResources();
        Configuration config = resources.getConfiguration();

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            config.locale = locale;
        } else {
            config.setLocale(locale);
        }

        // set new locale
        resources.updateConfiguration(config, resources.getDisplayMetrics());
    }

    public boolean showChangelog() {
        // create changelog layout
        View view = LayoutInflater.from(getContext()).inflate(R.layout.changelog_layout, null);

        // show changelog dialog
        new MaterialDialog.Builder(getContext()).cancelable(false).title(R.string.changelog).customView(view, true)
                .neutralText(android.R.string.ok).onNeutral(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        dialog.dismiss();
                    }
                }).build().show();

        // mark as seen
        int currentVersionCode = getAppVersionCode();
        PreferenceManager.getDefaultSharedPreferences(getContext()).edit()
                .putInt(getContext().getString(R.string.pref_last_version_key), currentVersionCode).apply();

        return true;
    }

    //    public int getColourFromStyledAttribute(int attribute) {
    //        int[] attrs = { attribute };
    //        TypedArray ta = getContext().obtainStyledAttributes(getContext().getTheme(), attrs);
    //    }

    //    public int getColourFromThemeAttribute(int attribute) {
    //        TypedValue typedValue = new TypedValue();
    //        getContext().getTheme().resolveAttribute(attribute, typedValue, true);
    //        return typedValue.resourceId;
    //    }

    // private

    private TypedArray getAttributeValue(int attribute) {
        //        TypedValue typedValue = new TypedValue();
        //        context.getTheme().resolveAttribute(attribute, typedValue, true);
        //        return typedValue;

        //        int[] arrayAttributes = new int[] { attribute };
        //        TypedArray typedArray = context.obtainStyledAttributes(arrayAttributes);
        //        int value = typedArray.getColor(0, context.getResources().getColor(R.color.abBackground));
        //        typedArray.recycle();

        // Create an array of the attributes we want to resolve
        // using values from a theme
        int[] attrs = new int[] { attribute /* index 0 */ };
        // Obtain the styled attributes. 'themedContext' is a context with a
        // theme, typically the current Activity (i.e. 'this')
        TypedArray ta = getContext().obtainStyledAttributes(attrs);
        // To get the value of the 'listItemBackground' attribute that was
        // set in the theme used in 'themedContext'. The parameter is the index
        // of the attribute in the 'attrs' array. The returned Drawable
        // is what you are after
        //        Drawable drawableFromTheme = ta.getDrawable(0 /* index */);

        // Finally, free the resources used by TypedArray
        //        ta.recycle();

        return ta;
    }
}