com.jrummyapps.busybox.fragments.ScriptsFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.jrummyapps.busybox.fragments.ScriptsFragment.java

Source

/*
 * Copyright (C) 2016 Jared Rummler <jared.rummler@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 com.jrummyapps.busybox.fragments;

import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import com.jrummyapps.android.analytics.Analytics;
import com.jrummyapps.android.fileproperties.activities.FilePropertiesActivity;
import com.jrummyapps.android.files.FileIntents;
import com.jrummyapps.android.os.Os;
import com.jrummyapps.android.radiant.fragments.RadiantSupportFragment;
import com.jrummyapps.android.transitions.FabDialogMorphSetup;
import com.jrummyapps.android.util.FileUtils;
import com.jrummyapps.android.view.ViewHolder;
import com.jrummyapps.android.widget.jazzylistview.JazzyListView;
import com.jrummyapps.busybox.R;
import com.jrummyapps.busybox.activities.AboutActivity;
import com.jrummyapps.busybox.activities.CreateScriptActivity;
import com.jrummyapps.busybox.activities.SettingsActivity;
import com.jrummyapps.busybox.database.Database;
import com.jrummyapps.busybox.database.ShellScriptTable;
import com.jrummyapps.busybox.dialogs.CreateScriptDialog;
import com.jrummyapps.busybox.models.ShellScript;
import com.jrummyapps.busybox.tasks.ScriptLoader;
import com.jrummyapps.texteditor.activities.TextEditorActivity;
import com.jrummyapps.texteditor.shell.activities.ScriptExecutorActivity;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public class ScriptsFragment extends RadiantSupportFragment
        implements AdapterView.OnItemClickListener, View.OnClickListener {

    public static final int REQUEST_CREATE_SCRIPT = 27;

    private FloatingActionButton fab;
    private JazzyListView listView;
    private Adapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        EventBus.getDefault().register(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_scripts, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        listView = getViewById(android.R.id.list);
        fab = getViewById(R.id.fab);
        onRestoreInstanceState(savedInstanceState);
        listView.setOnItemClickListener(this);
        fab.setOnClickListener(this);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (adapter != null) {
            outState.putParcelableArrayList("scripts", adapter.scripts);
        }
    }

    public void onRestoreInstanceState(@Nullable Bundle savedInstanceState) {
        if (savedInstanceState == null || !savedInstanceState.containsKey("scripts")) {
            new ScriptLoader().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        } else {
            ArrayList<ShellScript> scripts = savedInstanceState.getParcelableArrayList("scripts");
            adapter = new Adapter(scripts);
            listView.setAdapter(adapter);
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.add(0, R.id.action_settings, 0, R.string.settings).setIcon(R.drawable.ic_settings_white_24dp)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        menu.add(0, R.id.action_info, 0, R.string.about).setIcon(R.drawable.ic_information_white_24dp)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        if (itemId == R.id.action_settings) {
            startActivity(new Intent(getActivity(), SettingsActivity.class));
            return true;
        } else if (itemId == R.id.action_info) {
            startActivity(new Intent(getActivity(), AboutActivity.class));
            return true;
        } else {
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CREATE_SCRIPT && resultCode == Activity.RESULT_OK) {
            String name = data.getStringExtra(CreateScriptActivity.EXTRA_SCRIPT_NAME);
            String filename = data.getStringExtra(CreateScriptActivity.EXTRA_FILE_NAME);
            createScript(name, filename);
            return;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        final ShellScript script = adapter.getItem(position);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // hack to get the popupmenu color working on Android 6.0+ for custom color schemes
            ContextCompat.getDrawable(getActivity(), R.drawable.bg_popup_dark);
            ContextCompat.getDrawable(getActivity(), R.drawable.bg_popup_light);
        }

        PopupMenu popupMenu = new PopupMenu(getActivity(), view);

        popupMenu.getMenu().add(0, 1, 0, R.string.run).setIcon(R.drawable.ic_play_white_24dp);
        popupMenu.getMenu().add(0, 2, 0, R.string.edit).setIcon(R.drawable.ic_edit_white_24dp);
        popupMenu.getMenu().add(0, 3, 0, R.string.info).setIcon(R.drawable.ic_information_white_24dp);
        popupMenu.getMenu().add(0, 4, 0, R.string.delete).setIcon(R.drawable.ic_delete_white_24dp);

        getRadiant().tint(popupMenu.getMenu()).forceIcons().apply(getActivity());

        Analytics.newEvent("clicked script").put("script_name", script.name).put("script_file", script.path).log();

        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {

            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()) {
                case 1: { // run
                    Intent intent = new Intent(getActivity(), ScriptExecutorActivity.class);
                    intent.putExtra(FileIntents.INTENT_EXTRA_PATH, script.path);
                    startActivity(intent);
                    return true;
                }
                case 2: { // edit
                    Intent intent = new Intent(getActivity(), TextEditorActivity.class);
                    intent.putExtra(FileIntents.INTENT_EXTRA_PATH, script.path);
                    startActivity(intent);
                    return true;
                }
                case 3: { // info
                    Intent intent = new Intent(getActivity(), FilePropertiesActivity.class);
                    intent.putExtra(FileIntents.INTENT_EXTRA_FILE, new File(script.path));
                    intent.putExtra(FilePropertiesActivity.EXTRA_DESCRIPTION, script.info);
                    startActivity(intent);
                    return true;
                }
                case 4: { // delete
                    ShellScriptTable table = Database.getInstance().getTable(ShellScriptTable.NAME);
                    boolean deleted = table.delete(script) != 0;
                    if (deleted) {
                        adapter.scripts.remove(script);
                        adapter.notifyDataSetChanged();
                        new File(script.path).delete();
                    }
                    return true;
                }
                default:
                    return false;
                }
            }
        });

        popupMenu.show();
    }

    @Override
    public void onClick(View view) {
        if (view == fab) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                Intent intent = new Intent(getActivity(), CreateScriptActivity.class);
                intent.putExtra(FabDialogMorphSetup.EXTRA_SHARED_ELEMENT_START_COLOR, getRadiant().accentColor());
                ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(getActivity(), view,
                        getString(R.string.morphing_dialog_transition));
                getActivity().startActivityForResult(intent, REQUEST_CREATE_SCRIPT, options.toBundle());
            } else {
                new CreateScriptDialog().show(getActivity().getFragmentManager(), "CreateScriptDialog");
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(ScriptLoader.ScriptsLoadedEvent event) {
        adapter = new Adapter(event.scripts);
        listView.setAdapter(adapter);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(CreateScriptDialog.CreateScriptEvent event) {
        createScript(event.name, event.filename);
    }

    private void createScript(String name, String filename) {
        File file = new File(getActivity().getFilesDir(), "scripts/" + filename);
        ShellScript script = new ShellScript(name, file.getAbsolutePath());
        int errorMessage = 0;

        for (ShellScript shellScript : adapter.scripts) {
            if (shellScript.path.equals(script.path) || shellScript.name.equals(script.name)) {
                errorMessage = R.string.a_script_with_that_name_already_exists;
                break;
            }
        }

        try {
            FileUtils.touch(file);
            //noinspection OctalInteger
            Os.chmod(file.getAbsolutePath(), 0755);
        } catch (IOException e) {
            errorMessage = R.string.an_error_occurred_while_creating_the_file;
            Crashlytics.logException(e);
        }

        if (errorMessage != 0) {
            Snackbar snackbar = Snackbar.make(getViewById(R.id.fab), errorMessage, Snackbar.LENGTH_LONG);
            View view = snackbar.getView();
            TextView messageText = (TextView) view.findViewById(R.id.snackbar_text);
            if (getRadiant().isDark()) {
                messageText.setTextColor(getRadiant().primaryTextColor());
                view.setBackgroundColor(getRadiant().backgroundColorDark());
            } else {
                messageText.setTextColor(Color.WHITE);
            }
            snackbar.show();
            return;
        }

        ShellScriptTable table = Database.getInstance().getTable(ShellScriptTable.NAME);
        table.insert(script);
        adapter.scripts.add(script);
        adapter.notifyDataSetChanged();

        Intent intent = new Intent(getActivity(), TextEditorActivity.class);
        intent.putExtra(FileIntents.INTENT_EXTRA_PATH, script.path);
        startActivity(intent);
    }

    private final class Adapter extends BaseAdapter {

        private final ArrayList<ShellScript> scripts;

        public Adapter(ArrayList<ShellScript> scripts) {
            this.scripts = scripts;
        }

        @Override
        public int getCount() {
            return scripts.size();
        }

        @Override
        public ShellScript getItem(int position) {
            return scripts.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            final ShellScript script = getItem(position);
            final ViewHolder holder;
            if (convertView == null) {
                LayoutInflater inflater = LayoutInflater.from(getActivity());
                convertView = inflater.inflate(R.layout.item_script, parent, false);
                holder = new ViewHolder(convertView);

                ImageView imageView = holder.find(R.id.icon);
                imageView.setColorFilter(getRadiant().accentColor());
                imageView.setImageResource(R.drawable.ic_code_array_white_24dp);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.setText(R.id.text, script.name);
            return convertView;
        }

    }

}