com.nttec.everychan.ui.NewTabFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.nttec.everychan.ui.NewTabFragment.java

Source

/*
 * Everychan Android (Meta Imageboard Client)
 * Copyright (C) 2014-2016  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 com.nttec.everychan.ui;

import java.io.File;
import java.util.List;

import com.nttec.everychan.R;
import com.nttec.everychan.api.ChanModule;
import com.nttec.everychan.api.models.UrlPageModel;
import com.nttec.everychan.common.Logger;
import com.nttec.everychan.common.MainApplication;
import com.nttec.everychan.lib.FileDialogActivity;
import com.nttec.everychan.lib.dslv.DragSortController;
import com.nttec.everychan.lib.dslv.DragSortListView;
import com.nttec.everychan.ui.tabs.LocalHandler;
import com.nttec.everychan.ui.tabs.UrlHandler;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.KeyEvent;
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.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class NewTabFragment extends Fragment implements AdapterView.OnItemClickListener, View.OnClickListener {
    private static final String TAG = "NewTabFragment";
    private static final int REQUEST_FILE = 500;

    private MainActivity activity;
    private Resources resources;

    private DragSortListView listView;
    private QuickAccessAdapter adapter;
    private List<QuickAccess.Entry> list;

    private View addressBar;
    private boolean addressBarOpened = false;
    private Button openAddressBar;
    private EditText addressField;
    private Button addressGo;
    private Button openLocal;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activity = (MainActivity) getActivity();
        resources = MainApplication.getInstance().resources;
        list = QuickAccess.getQuickAccessFromPreferences();
        adapter = new QuickAccessAdapter(activity, list);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        activity.setTitle(R.string.tabs_newtab);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
            CompatibilityImpl.setActionBarDefaultIcon(activity);
        View v = inflater.inflate(R.layout.newtab_fragment, container, false);
        listView = (DragSortListView) v.findViewById(android.R.id.list);
        DragSortController controller = new DragSortController(listView, R.id.newtab_quickaccess_drag_handle,
                DragSortController.ON_DRAG, 0) {
            @Override
            public View onCreateFloatView(int position) {
                return adapter.getView(position, null, listView);
            }

            @Override
            public void onDragFloatView(View floatView, Point floatPoint, Point touchPoint) {
            }

            @Override
            public void onDestroyFloatView(View floatView) {
            }
        };
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(this);
        listView.setDragEnabled(true);
        listView.setFloatViewManager(controller);
        listView.setOnTouchListener(controller);
        listView.setDropListener(new DragSortListView.DropListener() {
            @Override
            public void drop(int from, int to) {
                if (from != to) {
                    QuickAccess.Entry moved = list.remove(from);
                    list.add(to, moved);
                    adapter.setDraggingItem(-1);
                    saveQuickAccessToPreferences();
                }
            }
        });
        registerForContextMenu(listView);
        addressBar = v.findViewById(R.id.newtab_address_bar);
        openAddressBar = (Button) v.findViewById(R.id.newtab_open_address_bar);
        openAddressBar.setOnClickListener(this);
        addressField = (EditText) v.findViewById(R.id.newtab_address_field);
        addressField.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
                    onClick(v);
                    return true;
                }
                return false;
            }
        });
        addressGo = (Button) v.findViewById(R.id.newtab_address_go);
        addressGo.setOnClickListener(this);
        openLocal = (Button) v.findViewById(R.id.newtab_open_local);
        openLocal.setOnClickListener(this);
        return v;
    }

    /**
     *  ?? ( ? ?  ? -?? ? ?)
     */
    public void updateList() {
        try {
            list = QuickAccess.getQuickAccessFromPreferences();
            adapter = new QuickAccessAdapter(activity, list);
            listView.setAdapter(adapter);
        } catch (Exception e) {
            Logger.e(TAG, e);
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.newtab_open_address_bar:
            if (addressBarOpened) {
                hideKeyboard(v);
                addressBar.setVisibility(View.GONE);
                addressBarOpened = false;
            } else {
                addressBar.setVisibility(View.VISIBLE);
                addressField.requestFocus();
                showKeyboard(v);
                addressBarOpened = true;
            }
            break;
        case R.id.newtab_open_local:
            hideKeyboard(v);
            openLocal();
            break;
        case R.id.newtab_address_go:
        case R.id.newtab_address_field:
            String url = addressField.getText().toString();
            if (url.length() == 0)
                return;
            hideKeyboard(v);
            openNewTab(url);
            break;
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        adapter.setDraggingItem(-1);
        hideKeyboard(listView);
        QuickAccess.Entry entry = adapter.getItem(position);
        if (entry.chan == null) {
            openChansList();
        } else {
            UrlPageModel model = new UrlPageModel();
            model.chanName = entry.chan.getChanName();
            model.type = entry.boardName == null ? UrlPageModel.TYPE_INDEXPAGE : UrlPageModel.TYPE_BOARDPAGE;
            if (entry.boardName != null) {
                model.boardName = entry.boardName;
                model.boardPage = UrlPageModel.DEFAULT_FIRST_PAGE;
            }
            openNewTab(entry.chan.buildUrl(model));
        }
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        if (list.size() > 1) {
            menu.add(Menu.NONE, R.id.context_menu_quickaccess_move, 1, R.string.context_menu_move);
        }
        QuickAccess.Entry entry = adapter.getItem(((AdapterView.AdapterContextMenuInfo) menuInfo).position);
        if (entry.chan == null)
            return;
        menu.add(Menu.NONE, R.id.context_menu_quickaccess_remove, 2, R.string.context_menu_quickaccess_remove);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        int position = ((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).position;
        switch (item.getItemId()) {
        case R.id.context_menu_quickaccess_move:
            adapter.setDraggingItem(position);
            return true;
        case R.id.context_menu_quickaccess_remove:
            list.remove(position);
            adapter.notifyDataSetChanged();
            saveQuickAccessToPreferences();
            return true;
        }
        return false;
    }

    private void openLocal() {
        if (!CompatibilityUtils.hasAccessStorage(activity))
            return;
        final ListAdapter savedThreadsAdapter = new ArrayAdapter<Object>(activity, 0) {
            private static final int HEAD_ITEM = 0;
            private static final int NORMAL_ITEM = 1;

            private LayoutInflater inflater = LayoutInflater.from(activity);
            private int drawablePadding = (int) (resources.getDisplayMetrics().density * 5 + 0.5f);

            {
                add(new Object());
                for (Database.SavedThreadEntry entity : MainApplication.getInstance().database.getSavedThreads()) {
                    File file = new File(entity.filepath);
                    if (file.exists())
                        add(entity);
                }
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View v;
                if (position == 0) {
                    v = convertView == null ? inflater.inflate(android.R.layout.simple_list_item_1, parent, false)
                            : convertView;
                    TextView tv = (TextView) v.findViewById(android.R.id.text1);
                    tv.setText(R.string.newtab_select_local_file);
                } else {
                    Database.SavedThreadEntry item = (Database.SavedThreadEntry) getItem(position);
                    v = convertView == null ? inflater.inflate(android.R.layout.simple_list_item_2, parent, false)
                            : convertView;
                    TextView t1 = (TextView) v.findViewById(android.R.id.text1);
                    TextView t2 = (TextView) v.findViewById(android.R.id.text2);
                    t1.setSingleLine();
                    t2.setSingleLine();
                    t1.setEllipsize(TextUtils.TruncateAt.END);
                    t2.setEllipsize(TextUtils.TruncateAt.START);
                    t1.setText(item.title);
                    t2.setText(item.filepath);
                    ChanModule chan = MainApplication.getInstance().getChanModule(item.chan);
                    if (chan != null) {
                        t1.setCompoundDrawablesWithIntrinsicBounds(chan.getChanFavicon(), null, null, null);
                        t1.setCompoundDrawablePadding(drawablePadding);
                    }
                }
                return v;
            }

            @Override
            public int getViewTypeCount() {
                return 2;
            }

            @Override
            public int getItemViewType(int position) {
                return position == 0 ? HEAD_ITEM : NORMAL_ITEM;
            }
        };

        if (savedThreadsAdapter.getCount() == 1) {
            selectFile();
            return;
        }
        DialogInterface.OnClickListener listListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (which == 0) {
                    selectFile();
                } else {
                    Database.SavedThreadEntry item = (Database.SavedThreadEntry) savedThreadsAdapter.getItem(which);
                    LocalHandler.open(item.filepath, activity);
                }
            }
        };
        new AlertDialog.Builder(activity).setTitle(R.string.newtab_saved_threads_title)
                .setAdapter(savedThreadsAdapter, listListener).setNegativeButton(android.R.string.cancel, null)
                .show();
    }

    private void selectFile() {
        Intent selectFile = new Intent(activity, FileDialogActivity.class);
        selectFile.putExtra(FileDialogActivity.SELECTION_MODE, FileDialogActivity.SELECTION_MODE_OPEN);
        selectFile.putExtra(FileDialogActivity.FORMAT_FILTER, new String[] { ".zip", ".mhtml", ".html" });
        selectFile.putExtra(FileDialogActivity.START_PATH,
                MainApplication.getInstance().settings.getDownloadDirectory().getAbsolutePath());
        startActivityForResult(selectFile, REQUEST_FILE);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_FILE && resultCode == Activity.RESULT_OK) {
            String path = data.getStringExtra(FileDialogActivity.RESULT_PATH);
            LocalHandler.open(path, activity);
        }
    }

    private void openNewTab(String url) {
        UrlHandler.open(url, activity, MainApplication.getInstance().settings.useFakeBrowser());
    }

    private void showKeyboard(View v) {
        try {
            ((InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE))
                    .toggleSoftInputFromWindow(v.getWindowToken(), InputMethodManager.SHOW_FORCED, 0);
        } catch (Exception e) {
            Logger.e(TAG, e);
        }
    }

    private void hideKeyboard(View v) {
        try {
            InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
        } catch (Exception e) {
            Logger.e(TAG, e);
        }
    }

    private static boolean isSingleboardChan(ChanModule chan) {
        try {
            UrlPageModel index = new UrlPageModel();
            index.type = UrlPageModel.TYPE_INDEXPAGE;
            index.chanName = chan.getChanName();
            index = chan.parseUrl(chan.buildUrl(index));
            return index.type != UrlPageModel.TYPE_INDEXPAGE;
        } catch (Exception e) {
            Logger.e(TAG, e);
        }
        return false;
    }

    private void openChansList() {
        final ArrayAdapter<ChanModule> chansAdapter = new ArrayAdapter<ChanModule>(activity, 0) {
            private LayoutInflater inflater = LayoutInflater.from(activity);
            private int drawablePadding = (int) (resources.getDisplayMetrics().density * 5 + 0.5f);

            {
                for (ChanModule chan : MainApplication.getInstance().chanModulesList)
                    add(chan);
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ChanModule chan = getItem(position);
                TextView view = (TextView) (convertView == null
                        ? inflater.inflate(android.R.layout.simple_list_item_1, parent, false)
                        : convertView);
                view.setText(chan.getDisplayingName());
                view.setCompoundDrawablesWithIntrinsicBounds(chan.getChanFavicon(), null, null, null);
                view.setCompoundDrawablePadding(drawablePadding);
                return view;
            }
        };

        DialogInterface.OnClickListener onChanSelected = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ChanModule chan = chansAdapter.getItem(which);
                UrlPageModel model = new UrlPageModel();
                model.chanName = chan.getChanName();
                model.type = UrlPageModel.TYPE_INDEXPAGE;
                openNewTab(chan.buildUrl(model));
            }
        };

        final AlertDialog chansListDialog = new AlertDialog.Builder(activity)
                .setTitle(R.string.newtab_quickaccess_all_boards).setAdapter(chansAdapter, onChanSelected)
                .setNegativeButton(android.R.string.cancel, null).create();

        chansListDialog.getListView().setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
            @Override
            public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
                MenuItem.OnMenuItemClickListener contextMenuHandler = new MenuItem.OnMenuItemClickListener() {
                    @SuppressLint("InlinedApi")
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        final ChanModule chan = chansAdapter
                                .getItem(((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).position);
                        switch (item.getItemId()) {
                        case R.id.context_menu_favorites_from_fragment:
                            if (MainApplication.getInstance().database.isFavorite(chan.getChanName(), null, null,
                                    null)) {
                                MainApplication.getInstance().database.removeFavorite(chan.getChanName(), null,
                                        null, null);
                            } else {
                                try {
                                    UrlPageModel indexPage = new UrlPageModel();
                                    indexPage.chanName = chan.getChanName();
                                    indexPage.type = UrlPageModel.TYPE_INDEXPAGE;
                                    MainApplication.getInstance().database.addFavorite(chan.getChanName(), null,
                                            null, null, chan.getChanName(), chan.buildUrl(indexPage));
                                } catch (Exception e) {
                                    Logger.e(TAG, e);
                                }
                            }
                            return true;
                        case R.id.context_menu_quickaccess_add:
                            QuickAccess.Entry newEntry = new QuickAccess.Entry();
                            newEntry.chan = chan;
                            list.add(0, newEntry);
                            adapter.notifyDataSetChanged();
                            saveQuickAccessToPreferences();
                            chansListDialog.dismiss();
                            return true;
                        case R.id.context_menu_quickaccess_custom_board:
                            LinearLayout dialogLayout = new LinearLayout(activity);
                            dialogLayout.setOrientation(LinearLayout.VERTICAL);
                            final EditText boardField = new EditText(activity);
                            final EditText descriptionField = new EditText(activity);
                            boardField.setHint(R.string.newtab_quickaccess_addcustom_boardcode);
                            descriptionField.setHint(R.string.newtab_quickaccess_addcustom_boarddesc);
                            LinearLayout.LayoutParams fieldsParams = new LinearLayout.LayoutParams(
                                    LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                            dialogLayout.addView(boardField, fieldsParams);
                            dialogLayout.addView(descriptionField, fieldsParams);
                            DialogInterface.OnClickListener onOkClicked = new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    String boardName = boardField.getText().toString();
                                    for (QuickAccess.Entry entry : list)
                                        if (entry.boardName != null && entry.chan != null)
                                            if (entry.chan.getChanName().equals(chan.getChanName())
                                                    && entry.boardName.equals(boardName)) {
                                                Toast.makeText(activity,
                                                        R.string.newtab_quickaccess_addcustom_already_exists,
                                                        Toast.LENGTH_LONG).show();
                                                return;
                                            }

                                    try {
                                        if (boardName.trim().length() == 0)
                                            throw new Exception();
                                        UrlPageModel boardPageModel = new UrlPageModel();
                                        boardPageModel.type = UrlPageModel.TYPE_BOARDPAGE;
                                        boardPageModel.chanName = chan.getChanName();
                                        boardPageModel.boardName = boardName;
                                        boardPageModel.boardPage = UrlPageModel.DEFAULT_FIRST_PAGE;
                                        chan.buildUrl(boardPageModel); //,  ??  ?    
                                    } catch (Exception e) {
                                        Toast.makeText(activity,
                                                R.string.newtab_quickaccess_addcustom_incorrect_code,
                                                Toast.LENGTH_LONG).show();
                                        return;
                                    }

                                    QuickAccess.Entry newEntry = new QuickAccess.Entry();
                                    newEntry.chan = chan;
                                    newEntry.boardName = boardName;
                                    newEntry.boardDescription = descriptionField.getText().toString();
                                    list.add(0, newEntry);
                                    adapter.notifyDataSetChanged();
                                    saveQuickAccessToPreferences();
                                    chansListDialog.dismiss();
                                }
                            };
                            new AlertDialog.Builder(activity)
                                    .setTitle(resources.getString(R.string.newtab_quickaccess_addcustom_title,
                                            chan.getChanName()))
                                    .setView(dialogLayout).setPositiveButton(android.R.string.ok, onOkClicked)
                                    .setNegativeButton(android.R.string.cancel, null).show();
                            return true;
                        }
                        return false;
                    }
                };
                String thisChanName = chansAdapter.getItem(((AdapterView.AdapterContextMenuInfo) menuInfo).position)
                        .getChanName();
                boolean canAddToQuickAccess = true;
                for (QuickAccess.Entry entry : list)
                    if (entry.boardName == null && entry.chan != null
                            && entry.chan.getChanName().equals(thisChanName)) {
                        canAddToQuickAccess = false;
                        break;
                    }
                menu.add(Menu.NONE, R.id.context_menu_favorites_from_fragment, 1,
                        MainApplication.getInstance().database.isFavorite(thisChanName, null, null, null)
                                ? R.string.context_menu_remove_favorites
                                : R.string.context_menu_add_favorites)
                        .setOnMenuItemClickListener(contextMenuHandler);
                menu.add(Menu.NONE, R.id.context_menu_quickaccess_add, 2, R.string.context_menu_quickaccess_add)
                        .setOnMenuItemClickListener(contextMenuHandler).setVisible(canAddToQuickAccess);
                menu.add(Menu.NONE, R.id.context_menu_quickaccess_custom_board, 3,
                        R.string.context_menu_quickaccess_custom_board)
                        .setOnMenuItemClickListener(contextMenuHandler);
                if (isSingleboardChan(
                        chansAdapter.getItem(((AdapterView.AdapterContextMenuInfo) menuInfo).position)))
                    menu.findItem(R.id.context_menu_quickaccess_custom_board).setVisible(false);
            }
        });
        chansListDialog.show();
    }

    private static class QuickAccessAdapter extends ArrayAdapter<QuickAccess.Entry> {
        private Resources resources;
        private LayoutInflater inflater;
        private int drawablePadding;

        private int draggingItem = -1;

        public QuickAccessAdapter(Activity activity, List<QuickAccess.Entry> list) {
            super(activity, 0, list);
            this.resources = MainApplication.getInstance().resources;
            this.inflater = LayoutInflater.from(activity);
            this.drawablePadding = (int) (resources.getDisplayMetrics().density * 5 + 0.5f);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            QuickAccess.Entry entry = getItem(position);
            View view = (convertView == null ? inflater.inflate(R.layout.newtab_quickaccess_item, parent, false)
                    : convertView);
            TextView tv = (TextView) view.findViewById(R.id.newtab_quickaccess_text);
            if (entry.chan != null) {
                tv.setText(entry.boardName == null ? entry.chan.getDisplayingName()
                        : resources.getString(R.string.boardslist_format, entry.boardName, entry.boardDescription));
                tv.setCompoundDrawablesWithIntrinsicBounds(entry.chan.getChanFavicon(), null, null, null);
                tv.setCompoundDrawablePadding(drawablePadding);
            } else {
                tv.setText(R.string.newtab_quickaccess_all_boards);
                tv.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
            }
            View dragHandler = view.findViewById(R.id.newtab_quickaccess_drag_handle);
            dragHandler.getLayoutParams().width = position == draggingItem ? ViewGroup.LayoutParams.WRAP_CONTENT
                    : 0;
            dragHandler.setLayoutParams(dragHandler.getLayoutParams());
            return view;
        }

        public void setDraggingItem(int position) {
            if (draggingItem != position) {
                draggingItem = position;
                notifyDataSetChanged();
            }
        }
    }

    private void saveQuickAccessToPreferences() {
        QuickAccess.saveQuickAccessToPreferences(list);
    }
}