nya.miku.wishmaster.ui.settings.AutohideActivity.java Source code

Java tutorial

Introduction

Here is the source code for nya.miku.wishmaster.ui.settings.AutohideActivity.java

Source

/*
 * Overchan Android (Meta Imageboard Client)
 * Copyright (C) 2014-2015  miku-nyan <https://github.com/miku-nyan>
 *     
 * 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 nya.miku.wishmaster.ui.settings;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.apache.http.util.TextUtils;

import nya.miku.wishmaster.R;
import nya.miku.wishmaster.api.ChanModule;
import nya.miku.wishmaster.common.MainApplication;
import nya.miku.wishmaster.lib.org_json.JSONArray;
import nya.miku.wishmaster.lib.org_json.JSONObject;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.TypefaceSpan;
import android.view.ContextMenu;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class AutohideActivity extends ListActivity {
    private ApplicationSettings settings;
    private JSONArray rulesJson;

    private List<String> chans = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        settings = MainApplication.getInstance().settings;
        setTheme(Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB_MR2
                || Build.VERSION.SDK_INT < Build.VERSION_CODES.ECLAIR_0_1 ? settings.getTheme()
                        : R.style.Neutron_Medium);
        super.onCreate(savedInstanceState);
        setTitle(R.string.autohide_title);

        chans = new ArrayList<String>();
        chans.add(getString(R.string.autohide_all_chans));
        for (ChanModule chan : MainApplication.getInstance().chanModulesList)
            chans.add(chan.getChanName());

        rulesJson = new JSONArray(settings.getAutohideRulesJson());
        setListAdapter(new AutohideAdapter(this));
        registerForContextMenu(getListView());
    }

    @SuppressLint("InflateParams")
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        Object item = l.getItemAtPosition(position);
        final int changeId;
        if (item instanceof AutohideRule) {
            changeId = position - 1;
        } else {
            changeId = -1; //-1 - ?  
        }

        Context dialogContext = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
                ? new ContextThemeWrapper(this, R.style.Neutron_Medium)
                : this;
        View dialogView = LayoutInflater.from(dialogContext).inflate(R.layout.dialog_autohide_rule, null);
        final EditText regexEditText = (EditText) dialogView.findViewById(R.id.dialog_autohide_regex);
        final Spinner chanSpinner = (Spinner) dialogView.findViewById(R.id.dialog_autohide_chan_spinner);
        final EditText boardEditText = (EditText) dialogView.findViewById(R.id.dialog_autohide_boardname);
        final EditText threadEditText = (EditText) dialogView.findViewById(R.id.dialog_autohide_threadnum);
        final CheckBox inCommentCheckBox = (CheckBox) dialogView.findViewById(R.id.dialog_autohide_in_comment);
        final CheckBox inSubjectCheckBox = (CheckBox) dialogView.findViewById(R.id.dialog_autohide_in_subject);
        final CheckBox inNameCheckBox = (CheckBox) dialogView.findViewById(R.id.dialog_autohide_in_name);

        chanSpinner.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, chans));
        if (changeId != -1) {
            AutohideRule rule = (AutohideRule) item;
            regexEditText.setText(rule.regex);
            int chanPosition = chans.indexOf(rule.chanName);
            chanSpinner.setSelection(chanPosition != -1 ? chanPosition : 0);
            boardEditText.setText(rule.boardName);
            threadEditText.setText(rule.threadNumber);
            inCommentCheckBox.setChecked(rule.inComment);
            inSubjectCheckBox.setChecked(rule.inSubject);
            inNameCheckBox.setChecked(rule.inName);
        } else {
            chanSpinner.setSelection(0);
        }

        DialogInterface.OnClickListener save = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String regex = regexEditText.getText().toString();
                if (regex.length() == 0) {
                    Toast.makeText(AutohideActivity.this, R.string.autohide_error_empty_regex, Toast.LENGTH_LONG)
                            .show();
                    return;
                }

                try {
                    Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.DOTALL);
                } catch (Exception e) {
                    CharSequence message = null;
                    if (e instanceof PatternSyntaxException) {
                        String eMessage = e.getMessage();
                        if (!TextUtils.isEmpty(eMessage)) {
                            SpannableStringBuilder a = new SpannableStringBuilder(
                                    getString(R.string.autohide_error_incorrect_regex));
                            a.append('\n');
                            int startlen = a.length();
                            a.append(eMessage);
                            a.setSpan(new TypefaceSpan("monospace"), startlen, a.length(),
                                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                            message = a;
                        }
                    }
                    if (message == null)
                        message = getString(R.string.error_unknown);
                    Toast.makeText(AutohideActivity.this, message, Toast.LENGTH_LONG).show();
                    return;
                }

                AutohideRule rule = new AutohideRule();
                int spinnerSelectedPosition = chanSpinner.getSelectedItemPosition();
                rule.regex = regex;
                rule.chanName = spinnerSelectedPosition > 0 ? chans.get(spinnerSelectedPosition) : ""; // 0 ? = ? 
                rule.boardName = boardEditText.getText().toString();
                rule.threadNumber = threadEditText.getText().toString();
                rule.inComment = inCommentCheckBox.isChecked();
                rule.inSubject = inSubjectCheckBox.isChecked();
                rule.inName = inNameCheckBox.isChecked();

                if (!rule.inComment && !rule.inSubject && !rule.inName) {
                    Toast.makeText(AutohideActivity.this, R.string.autohide_error_no_condition, Toast.LENGTH_LONG)
                            .show();
                    return;
                }

                if (changeId == -1) {
                    rulesJson.put(rule.toJson());
                } else {
                    rulesJson.put(changeId, rule.toJson());
                }
                rulesChanged();
            }
        };
        AlertDialog dialog = new AlertDialog.Builder(this).setView(dialogView)
                .setTitle(changeId == -1 ? R.string.autohide_add_rule_title : R.string.autohide_edit_rule_title)
                .setPositiveButton(R.string.autohide_save_button, save)
                .setNegativeButton(android.R.string.cancel, null).create();
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        if (info.position == 0)
            return;
        menu.add(Menu.NONE, R.id.context_menu_delete, 1, R.string.context_menu_delete_autohide_rule);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.context_menu_delete) {
            if (item.getMenuInfo() != null && item.getMenuInfo() instanceof AdapterView.AdapterContextMenuInfo) {
                int position = ((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).position;
                if (position > 0) {
                    rulesJson.remove(position - 1);
                    rulesChanged();
                }
            }
        }
        return super.onContextItemSelected(item);
    }

    private void rulesChanged() {
        settings.saveAutohideRulesJson(rulesJson.toString());
        setListAdapter(new AutohideAdapter(this));
    }

    public static class AutohideRule {
        public String regex;
        public String chanName;
        public String boardName;
        public String threadNumber;
        public boolean inComment;
        public boolean inSubject;
        public boolean inName;

        public JSONObject toJson() {
            JSONObject rule = new JSONObject();
            rule.put("regex", regex);
            rule.put("chanName", chanName);
            rule.put("boardName", boardName);
            rule.put("threadNumber", threadNumber);
            rule.put("inComment", inComment);
            rule.put("inSubject", inSubject);
            rule.put("inName", inName);
            return rule;
        }

        public static AutohideRule fromJson(JSONObject json) {
            AutohideRule rule = new AutohideRule();
            rule.regex = json.getString("regex");
            rule.chanName = json.getString("chanName");
            rule.boardName = json.getString("boardName");
            rule.threadNumber = json.getString("threadNumber");
            rule.inComment = json.getBoolean("inComment");
            rule.inSubject = json.getBoolean("inSubject");
            rule.inName = json.getBoolean("inName");
            return rule;
        }

        public boolean matches(String chanName, String boardName, String threadNumber) {
            return ((TextUtils.isEmpty(this.chanName) || chanName == this.chanName
                    || chanName.equals(this.chanName))
                    && (TextUtils.isEmpty(this.boardName) || boardName == this.boardName
                            || boardName.equals(this.boardName))
                    && (TextUtils.isEmpty(this.threadNumber) || threadNumber == this.threadNumber
                            || threadNumber.equals(this.threadNumber)));
        }
    }

    public static class CompiledAutohideRule extends AutohideRule {
        public Pattern pattern;

        public CompiledAutohideRule(AutohideRule rule) {
            regex = rule.regex;
            chanName = rule.chanName;
            boardName = rule.boardName;
            threadNumber = rule.threadNumber;
            inComment = rule.inComment;
            inSubject = rule.inSubject;
            inName = rule.inName;
            pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.DOTALL);
        }
    }

    private static class AutohideAdapter extends ArrayAdapter<Object> {
        private LayoutInflater inflater;
        private Resources resources;

        public AutohideAdapter(AutohideActivity activity) {
            super(activity, android.R.layout.simple_list_item_2);
            inflater = activity.getLayoutInflater();
            resources = activity.getResources();
            add(new Object());
            for (int i = 0; i < activity.rulesJson.length(); ++i) {
                add(AutohideRule.fromJson(activity.rulesJson.getJSONObject(i)));
            }
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView == null ? inflater.inflate(android.R.layout.simple_list_item_2, parent, false)
                    : convertView;

            String str1, str2;
            Object current = getItem(position);
            if (current instanceof AutohideRule) {
                AutohideRule rule = (AutohideRule) current;
                str1 = rule.regex;
                str2 = (TextUtils.isEmpty(rule.chanName) ? "*" : rule.chanName) + " : "
                        + (TextUtils.isEmpty(rule.boardName) ? "*" : rule.boardName) + " : "
                        + (TextUtils.isEmpty(rule.threadNumber) ? "*" : rule.threadNumber) + " : "
                        + (rule.inComment ? "TEXT|" : "") + (rule.inSubject ? "SUBJ|" : "")
                        + (rule.inName ? "NAME|" : "");
                str2 = str2.substring(0, str2.length() - 1);
            } else {
                str1 = resources.getString(R.string.autohide_add_rule_item);
                str2 = resources.getString(R.string.autohide_add_rule_summary);
            }

            ((TextView) view.findViewById(android.R.id.text1)).setText(str1);
            ((TextView) view.findViewById(android.R.id.text2)).setText(str2);

            return view;
        }

    }
}