com.duy.pascal.ui.editor.BaseEditorActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.duy.pascal.ui.editor.BaseEditorActivity.java

Source

/*
 *  Copyright (c) 2017 Tran Le Duy
 *
 * 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.duy.pascal.ui.editor;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatEditText;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import android.widget.Toast;

import com.commonsware.cwac.pager.PageDescriptor;
import com.commonsware.cwac.pager.SimplePageDescriptor;
import com.duy.pascal.ui.BaseActivity;
import com.duy.pascal.ui.EditorControl;
import com.duy.pascal.ui.R;
import com.duy.pascal.ui.code.CompileManager;
import com.duy.pascal.ui.code.sample.activities.CodeSampleActivity;
import com.duy.pascal.ui.editor.interfaces.IEditorContext;
import com.duy.pascal.ui.file.FileActionListener;
import com.duy.pascal.ui.file.FileClipboard;
import com.duy.pascal.ui.file.FileExplorerView;
import com.duy.pascal.ui.file.FileManager;
import com.duy.pascal.ui.file.Pref;
import com.duy.pascal.ui.file.fragment.FileListPagerFragment;
import com.duy.pascal.ui.file.util.FileListSorter;
import com.duy.pascal.ui.file.util.FileUtils;
import com.duy.pascal.ui.file.util.TabFileUtils;
import com.duy.pascal.ui.setting.PascalPreferences;
import com.duy.pascal.ui.utils.DLog;
import com.duy.pascal.ui.view.SymbolListView;
import com.github.clans.fab.FloatingActionMenu;
import com.kobakei.ratethisapp.RateThisApp;
import com.ogaclejapan.smarttablayout.SmartTabLayout;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Created by Duy on 09-Mar-17.
 */

public abstract class BaseEditorActivity extends BaseActivity
        implements SymbolListView.OnKeyListener, EditorControl, FileActionListener, IEditorContext,
        View.OnClickListener, PopupMenu.OnMenuItemClickListener, DrawerLayout.DrawerListener {
    private static final String TAG = "BaseEditorActivity";

    protected FileManager mFileManager;
    protected EditorPagerAdapter mPagerAdapter;
    protected Toolbar mToolbar;
    protected AppBarLayout mAppBarLayout;
    protected DrawerLayout mDrawerLayout;
    protected SymbolListView mKeyList;
    protected NavigationView mNavigationView;
    protected SmartTabLayout mTabLayout;
    protected View mContainerSymbol;
    protected ViewPager mViewPager;
    protected FloatingActionMenu mFabMenu;
    private KeyBoardEventListener mKeyBoardListener;
    private FileListPagerFragment mFileExplorer;
    private FileClipboard mFileClipboard;
    private PopupMenu mFileMenu;

    protected void onShowKeyboard() {
        hideAppBar();
    }

    protected void onHideKeyboard() {
        showAppBar();
    }

    /**
     * hide appbar layout when keyboard visible
     */
    private void hideAppBar() {
        mTabLayout.setVisibility(View.GONE);
    }

    /**
     * show appbar layout when keyboard gone
     */
    private void showAppBar() {
        mTabLayout.setVisibility(View.VISIBLE);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_editor);

        bindView();
        setupToolbar();
        setupPageView();
        initFileView();
        loadFileFromIntent();
    }

    private void loadFileFromIntent() {
        Intent intent = getIntent();
        if (intent != null && intent.getSerializableExtra(CompileManager.EXTRA_FILE) != null) {
            File file = (File) intent.getSerializableExtra(CompileManager.EXTRA_FILE);
            //No need save last file because it is the first file
            addNewPageEditor(file);
            //Remove path
            intent.removeExtra(CompileManager.EXTRA_FILE);
        }
    }

    private void bindView() {
        mDrawerLayout = findViewById(R.id.drawer_layout);
        mDrawerLayout.addDrawerListener(this);

        mKeyList = findViewById(R.id.recycler_view);
        mFileManager = new FileManager(this);
        mNavigationView = findViewById(R.id.navigation_view);
        mTabLayout = findViewById(R.id.tab_layout);
        mContainerSymbol = findViewById(R.id.container_symbol);
        mViewPager = findViewById(R.id.view_pager);

        findViewById(R.id.row_open_drawer).setOnClickListener(this);
        findViewById(R.id.row_open_file).setOnClickListener(this);
        findViewById(R.id.row_open_code_sample).setOnClickListener(this);
    }

    private void initFileView() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        mFileExplorer = (FileListPagerFragment) fragmentManager.findFragmentByTag(FileListPagerFragment.TAG);
        if (mFileExplorer == null) {
            File path = FileManager.getSrcPath(this);
            mFileExplorer = (FileListPagerFragment) FileListPagerFragment.newFragment(path);
        }
        FragmentTransaction fm = fragmentManager.beginTransaction();
        fm.replace(R.id.file_explorer, mFileExplorer, FileListPagerFragment.TAG).commit();

        mFabMenu = findViewById(R.id.fab_menu);
        mFabMenu.findViewById(R.id.action_new_file).setOnClickListener(this);
        mFabMenu.findViewById(R.id.action_new_folder).setOnClickListener(this);

        View menuAnchor = findViewById(R.id.img_file_menus);
        mFileMenu = new PopupMenu(this, menuAnchor);
        mFileMenu.setOnMenuItemClickListener(this);

        Menu menu = mFileMenu.getMenu();
        getMenuInflater().inflate(R.menu.explorer_menu, menu);
        Pref pref = Pref.getInstance(this);
        menu.findItem(R.id.show_hidden_files_menu).setChecked(pref.isShowHiddenFiles());
        MenuItem pasteMenu = menu.findItem(R.id.paste_menu);
        int sortId;
        switch (pref.getFileSortType()) {
        case FileListSorter.SORT_DATE:
            sortId = R.id.sort_by_datetime_menu;
            break;
        case FileListSorter.SORT_SIZE:
            sortId = R.id.sort_by_size_menu;
            break;
        case FileListSorter.SORT_TYPE:
            sortId = R.id.sort_by_type_menu;
            break;
        default:
            sortId = R.id.sort_by_name_menu;
            break;
        }
        menu.findItem(sortId).setChecked(true);
        menuAnchor.setOnClickListener(this);

        findViewById(R.id.img_home_dir).setOnClickListener(this);
    }

    protected void setupPageView() {
        ArrayList<File> listFile = TabFileUtils.getTabFiles(this);
        ArrayList<PageDescriptor> pages = new ArrayList<>();
        for (File file : listFile) {
            pages.add(new SimplePageDescriptor(file.getPath(), file.getName()));
        }
        mPagerAdapter = new EditorPagerAdapter(getSupportFragmentManager(), pages);
        mViewPager.setAdapter(mPagerAdapter);
        addCustomTab();
        mTabLayout.setViewPager(mViewPager);

        if (isFirstLauncher()) {
            String fileName = Integer.toHexString((int) System.currentTimeMillis()) + ".pas";
            File file = mFileManager.createNewFileInMode(fileName);
            if (file != null) {
                addNewPageEditor(file);
            }
        }

        int pos = getPreferences().getInt(PascalPreferences.TAB_POSITION_FILE);
        if (mPagerAdapter.getCount() > pos) {
            mViewPager.setCurrentItem(pos);
        }
    }

    private boolean isFirstLauncher() {
        String firstLauncherKey = BaseEditorActivity.class.getName();
        boolean result = mPreferences.getPreferences().getBoolean(firstLauncherKey, true);
        mPreferences.getPreferences().edit().putBoolean(firstLauncherKey, false).apply();
        return result;
    }

    private void addCustomTab() {
        mTabLayout.setCustomTabView(new SmartTabLayout.TabProvider() {
            @Override
            public View createTabView(ViewGroup container, final int position, PagerAdapter adapter) {
                LayoutInflater inflater = LayoutInflater.from(BaseEditorActivity.this);
                View view = inflater.inflate(R.layout.item_tab_file, container, false);
                View close = view.findViewById(R.id.img_close);
                close.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        removePage(position);
                    }
                });
                TextView txtTitle = view.findViewById(R.id.txt_name);
                txtTitle.setText(adapter.getPageTitle(position));
                txtTitle.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mViewPager.setCurrentItem(position);
                    }
                });
                if (position == mViewPager.getCurrentItem()) {
                    txtTitle.setSelected(true);
                }
                return view;
            }
        });
    }

    protected void setupToolbar() {
        //setup action bar
        mToolbar = findViewById(R.id.toolbar);
        mAppBarLayout = findViewById(R.id.app_bar);

        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);

        ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar,
                R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        mDrawerToggle.syncState();

        //attach listener hide/show keyboard
        mKeyBoardListener = new KeyBoardEventListener(this);
        mDrawerLayout.getViewTreeObserver().addOnGlobalLayoutListener(mKeyBoardListener);
    }

    /**
     * remove a page in <code>position</code>
     */
    protected void removePage(int position) {
        Fragment fragment = mPagerAdapter.getExistingFragment(position);
        if (fragment == null) {
            DLog.d(TAG, "removePage: " + "null page " + position);
            return;
        }
        //delete in database
        String filePath = fragment.getTag();
        mFileManager.removeTabFile(filePath);
        //remove page
        mPagerAdapter.remove(position);
        mTabLayout.setViewPager(mViewPager);
        String msg = getString(R.string.closed) + " " + new File(filePath).getName();
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    /**
     * Add new page for editor
     * Check if not in list file, add it to tab and select tab of file
     *
     * @param file - file need load
     */
    protected void addNewPageEditor(@NonNull File file) {
        DLog.d(TAG, "addNewPageEditor() called with: file = [" + file + "]");
        int position = mPagerAdapter.getPositionForTag(file.getPath());
        if (position != -1) { //existed in list file
            mViewPager.setCurrentItem(position);
        } else { //new file
            if (mPagerAdapter.getCount() >= getPreferences().getMaxPage()) {
                Fragment existingFragment = mPagerAdapter.getExistingFragment(0);
                if (existingFragment != null) {
                    mFileManager.removeTabFile(existingFragment.getTag());
                    removePage(0);
                }
            }
            //add to database
            mFileManager.addNewPath(file.getPath());
            //new page
            mPagerAdapter.add(new SimplePageDescriptor(file.getPath(), file.getName()));
            mPagerAdapter.notifyDataSetChanged();
            mViewPager.setCurrentItem(mPagerAdapter.getCount() - 1);
            mTabLayout.setViewPager(mViewPager);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        getPreferences().put(PascalPreferences.TAB_POSITION_FILE, mViewPager.getCurrentItem());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        DLog.d(TAG, "onNewIntent() called with: intent = [" + intent + "]");
        if (intent.getSerializableExtra(CompileManager.EXTRA_FILE) != null) {
            File file = (File) intent.getSerializableExtra(CompileManager.EXTRA_FILE);
            if (!file.exists()) {
                Toast.makeText(this, R.string.file_not_found, Toast.LENGTH_SHORT).show();
                return;
            }
            addNewPageEditor(file);
            //remove path
            intent.removeExtra(CompileManager.EXTRA_FILE);
        }
    }

    protected abstract String getCode();

    @Override
    public boolean onFileSelected(@NonNull File file) {
        return false;
    }

    @Override
    public void onFileLongClick(@NonNull File file) {
    }

    @Override
    public void doRemoveFile(@NonNull final File file) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(getString(R.string.remove_file_msg) + " " + file.getName());
        builder.setTitle(R.string.delete_file);
        builder.setIcon(R.drawable.ic_delete_forever_white_24dp);
        builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                int position = mPagerAdapter.getPositionForTag(file.getPath());
                boolean success = FileUtils.deleteRecursive(file);
                if (success) {
                    if (position >= 0) {
                        removePage(position);
                    }
                    Toast.makeText(getApplicationContext(), R.string.deleted, Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getApplicationContext(), R.string.failed, Toast.LENGTH_SHORT).show();
                }

                //reload file
                FileExplorerView controller = (FileExplorerView) getSupportFragmentManager()
                        .findFragmentByTag("fragment_file_view");
                if (controller != null) {
                    controller.refresh();
                } else {
                    DLog.d(TAG, "onClick: Fragment file is null");
                }
            }
        });
        builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });
        builder.create().show();
    }

    @Override
    public void onPrepareDeleteFile(@NonNull File file) {
        int position = mPagerAdapter.getPositionForTag(file.getPath());
        if (position >= 0) {
            removePage(position);
        }
    }

    @NonNull
    @Override
    public FileClipboard getFileClipboard() {
        if (mFileClipboard == null) {
            mFileClipboard = new FileClipboard();
        }
        return mFileClipboard;
    }

    /**
     * @return current file selected
     */
    @Nullable
    @Override
    public File getCurrentFile() {
        EditorFragment editorFragment = mPagerAdapter.getCurrentFragment();
        if (editorFragment != null) {
            String filePath = editorFragment.getFilePath();
            return new File(filePath);
        }
        return null;
    }

    @Override
    public boolean doCompile() {
        return false;
    }

    @Override
    public void saveAs() {
        saveFile();
        final AppCompatEditText edittext = new AppCompatEditText(this);
        edittext.setHint(R.string.enter_new_file_name);
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.save_as).setView(edittext).setIcon(R.drawable.ic_create_new_folder_white_24dp)
                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        String fileName = edittext.getText().toString();
                        dialog.cancel();
                        File currentFile = getCurrentFile();
                        if (currentFile != null) {
                            try {
                                mFileManager.copy(currentFile.getPath(), currentFile.getParent() + "/" + fileName);
                            } catch (IOException e) {
                                e.printStackTrace();
                                Toast.makeText(BaseEditorActivity.this, R.string.can_not_save_file,
                                        Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
                }).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });
        builder.create().show();
    }

    @Override
    public void findAndReplace() {

    }

    @Override
    public void runProgram() {

    }

    @Override
    public void saveFile() {

    }

    @Override
    public void showDocumentActivity() {

    }

    @Override
    public void createNewSourceFile(View view) {
        mFileExplorer.createNewFile();
    }

    @Override
    protected void onDestroy() {
        closeKeyBoard();
        mDrawerLayout.getViewTreeObserver().removeGlobalOnLayoutListener(mKeyBoardListener);
        super.onDestroy();
    }

    // closes the soft keyboard
    protected void closeKeyBoard() {
        // Central system API to the overall input method framework (IMF) architecture
        InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

        View currentFocus = getCurrentFocus();
        if (currentFocus != null) {
            // Base interface for a remotable object
            IBinder windowToken = currentFocus.getWindowToken();

            // Hide type
            int hideType = InputMethodManager.HIDE_NOT_ALWAYS;

            // Hide the KeyBoard
            if (inputManager != null) {
                inputManager.hideSoftInputFromWindow(windowToken, hideType);
            }
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.img_file_menus:
            mFileMenu.show();
            break;
        case R.id.action_new_file:
            mFileExplorer.createNewFile();
            mFabMenu.close(true);
            break;
        case R.id.action_new_folder:
            mFileExplorer.createNewFolder();
            mFabMenu.close(true);
            break;
        case R.id.img_home_dir:
            mFileExplorer.show(FileManager.getSrcPath(this));
            break;
        case R.id.row_open_drawer:
            mDrawerLayout.openDrawer(GravityCompat.END);
            break;
        case R.id.row_open_file:
            mDrawerLayout.openDrawer(GravityCompat.START);
            break;
        case R.id.row_open_code_sample:
            startActivity(new Intent(this, CodeSampleActivity.class));
            break;

        }
    }

    @Override
    public void onKeyClick(View view, String text) {

    }

    @Override
    public void onKeyLongClick(String text) {

    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        DLog.d(TAG, "onMenuItemClick() called with: item = [" + item + "]");

        Pref pref = Pref.getInstance(this);
        int id = item.getItemId();
        if (id == R.id.show_hidden_files_menu) {
            item.setChecked(!item.isChecked());
            pref.setShowHiddenFiles(item.isChecked());
        } else if (id == R.id.sort_by_name_menu) {
            item.setChecked(true);
            pref.setFileSortType(FileListSorter.SORT_NAME);
        } else if (id == R.id.sort_by_datetime_menu) {
            item.setChecked(true);
            pref.setFileSortType(FileListSorter.SORT_DATE);
        } else if (id == R.id.sort_by_size_menu) {
            item.setChecked(true);
            pref.setFileSortType(FileListSorter.SORT_SIZE);
        } else if (id == R.id.sort_by_type_menu) {
            item.setChecked(true);
            pref.setFileSortType(FileListSorter.SORT_TYPE);
        }
        return mFileExplorer.onOptionsItemSelected(item);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Monitor launch times and interval from installation
        RateThisApp.onStart(this);
        // If the criteria is satisfied, "Rate this app" dialog will be shown
        RateThisApp.showRateDialogIfNeeded(this);
    }

    @Override
    public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {

    }

    @Override
    public void onDrawerOpened(@NonNull View drawerView) {

    }

    @Override
    public void onDrawerClosed(@NonNull View drawerView) {

    }

    @Override
    public void onDrawerStateChanged(int newState) {

    }

    private class KeyBoardEventListener implements ViewTreeObserver.OnGlobalLayoutListener {
        BaseEditorActivity activity;

        KeyBoardEventListener(BaseEditorActivity activityIde) {
            this.activity = activityIde;
        }

        public void onGlobalLayout() {
            int i = 0;
            int navHeight = this.activity.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
            navHeight = navHeight > 0 ? this.activity.getResources().getDimensionPixelSize(navHeight) : 0;
            int statusBarHeight = this.activity.getResources().getIdentifier("status_bar_height", "dimen",
                    "android");
            if (statusBarHeight > 0) {
                i = this.activity.getResources().getDimensionPixelSize(statusBarHeight);
            }
            Rect rect = new Rect();
            activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
            if (activity.mDrawerLayout.getRootView().getHeight() - ((navHeight + i) + rect.height()) <= 0) {
                activity.onHideKeyboard();
            } else {
                activity.onShowKeyboard();
            }
        }
    }
}