org.dvbviewer.controller.ui.fragments.RecordingList.java Source code

Java tutorial

Introduction

Here is the source code for org.dvbviewer.controller.ui.fragments.RecordingList.java

Source

/*
 * Copyright  2013 dvbviewer-controller Project
 * 
 * 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 org.dvbviewer.controller.ui.fragments;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.http.ParseException;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.client.ClientProtocolException;
import org.dvbviewer.controller.R;
import org.dvbviewer.controller.entities.IEPG;
import org.dvbviewer.controller.entities.Recording;
import org.dvbviewer.controller.io.RecordingHandler;
import org.dvbviewer.controller.io.ServerRequest;
import org.dvbviewer.controller.ui.base.AsyncLoader;
import org.dvbviewer.controller.ui.base.BaseActivity.AsyncCallback;
import org.dvbviewer.controller.ui.base.BaseListFragment;
import org.dvbviewer.controller.ui.phone.IEpgDetailsActivity;
import org.dvbviewer.controller.ui.phone.StreamConfigActivity;
import org.dvbviewer.controller.ui.widget.CheckableLinearLayout;
import org.dvbviewer.controller.utils.ArrayListAdapter;
import org.dvbviewer.controller.utils.DateUtils;
import org.dvbviewer.controller.utils.ServerConsts;
import org.dvbviewer.controller.utils.UIUtils;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;

/**
 * The Class RecordingList.
 *
 * @author RayBa
 * @date 07.04.2013
 */
public class RecordingList extends BaseListFragment implements AsyncCallback, LoaderCallbacks<List<Recording>>,
        OnClickListener, ActionMode.Callback, OnCheckedChangeListener, View.OnClickListener {

    RecordingAdapter mAdapter;
    ActionMode mode;
    int selectedPosition;
    ProgressDialog progressDialog;

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onCreate(android.os.Bundle)
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAdapter = new RecordingAdapter(getActivity());
        setHasOptionsMenu(true);
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onActivityCreated(android.os.Bundle)
     */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setListAdapter(mAdapter);
        getListView().setItemsCanFocus(false);
        registerForContextMenu(getListView());
        Loader<List<Recording>> loader = getLoaderManager().initLoader(0, savedInstanceState, this);
        setListShown(!(!isResumed() || loader.isStarted()));
        setEmptyText(getResources().getString(R.string.no_recordings));
        getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        if (mode != null) {
            mode = getSherlockActivity().startActionMode(this);
        }
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader(int, android.os.Bundle)
     */
    @Override
    public Loader<List<Recording>> onCreateLoader(int arg0, Bundle arg1) {
        AsyncLoader<List<Recording>> loader = new AsyncLoader<List<Recording>>(getActivity()) {

            @Override
            public List<Recording> loadInBackground() {
                List<Recording> result = null;
                try {
                    String xml = ServerRequest.getRSString("/api/recordings.html?utf8=255");
                    RecordingHandler hanler = new RecordingHandler();
                    result = hanler.parse(xml);
                    Collections.sort(result);
                } catch (AuthenticationException e) {
                    Log.e(ChannelEpg.class.getSimpleName(), "AuthenticationException");
                    e.printStackTrace();
                    showToast(getString(R.string.error_invalid_credentials));
                } catch (ParseException e) {
                    Log.e(ChannelEpg.class.getSimpleName(), "ParseException");
                    e.printStackTrace();
                } catch (ClientProtocolException e) {
                    Log.e(ChannelEpg.class.getSimpleName(), "ClientProtocolException");
                    e.printStackTrace();
                } catch (IOException e) {
                    Log.e(ChannelEpg.class.getSimpleName(), "IOException");
                    e.printStackTrace();
                } catch (URISyntaxException e) {
                    Log.e(ChannelEpg.class.getSimpleName(), "URISyntaxException");
                    e.printStackTrace();
                    showToast(getString(R.string.error_invalid_url) + "\n\n" + ServerConsts.REC_SERVICE_URL);
                } catch (IllegalStateException e) {
                    Log.e(ChannelEpg.class.getSimpleName(), "IllegalStateException");
                    e.printStackTrace();
                    showToast(getString(R.string.error_invalid_url) + "\n\n" + ServerConsts.REC_SERVICE_URL);
                } catch (IllegalArgumentException e) {
                    Log.e(ChannelEpg.class.getSimpleName(), "IllegalArgumentException");
                    showToast(getString(R.string.error_invalid_url) + "\n\n" + ServerConsts.REC_SERVICE_URL);
                } catch (Exception e) {
                    Log.e(ChannelEpg.class.getSimpleName(), "Exception");
                    e.printStackTrace();
                }
                return result;
            }
        };
        return loader;
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished(android.support.v4.content.Loader, java.lang.Object)
     */
    @Override
    public void onLoadFinished(Loader<List<Recording>> arg0, List<Recording> arg1) {
        mAdapter.setItems(arg1);
        setListShown(true);
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset(android.support.v4.content.Loader)
     */
    @Override
    public void onLoaderReset(Loader<List<Recording>> arg0) {
        if (isVisible()) {
            setListShown(true);
        }
    }

    /**
     * The Class ViewHolder.
     *
     * @author RayBa
     * @date 07.04.2013
     */
    private class ViewHolder {
        CheckableLinearLayout layout;
        TextView title;
        TextView subTitle;
        TextView channelName;
        TextView date;
        CheckBox check;
        ImageView contextMenu;
    }

    /**
     * The Class RecordingAdapter.
     *
     * @author RayBa
     * @date 07.04.2013
     */
    public class RecordingAdapter extends ArrayListAdapter<Recording> {

        /**
         * The Constructor.
         *
         * @param context the context
         * @author RayBa
         * @date 04.06.2010
         * @description Instantiates a new recording adapter.
         */
        public RecordingAdapter(Context context) {
            super();
        }

        /*
         * (non-Javadoc)
         * 
         * @see android.widget.ArrayAdapter#getView(int, android.view.View,
         * android.view.ViewGroup)
         */
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                LayoutInflater vi = getActivity().getLayoutInflater();
                convertView = vi.inflate(R.layout.list_item_recording, null);
                holder = new ViewHolder();
                holder.layout = (CheckableLinearLayout) convertView;
                holder.title = (TextView) convertView.findViewById(R.id.title);
                holder.subTitle = (TextView) convertView.findViewById(R.id.subTitle);
                holder.channelName = (TextView) convertView.findViewById(R.id.channelName);
                holder.date = (TextView) convertView.findViewById(R.id.date);
                holder.check = (CheckBox) convertView.findViewById(R.id.checkIndicator);
                holder.contextMenu = (ImageView) convertView.findViewById(R.id.contextMenu);
                holder.check.setOnCheckedChangeListener(RecordingList.this);
                holder.check.setOnClickListener(RecordingList.this);
                holder.contextMenu.setOnClickListener(RecordingList.this);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            Recording o = getItem(position);
            if (o != null) {
                holder.check.setTag(position);
                holder.layout.setChecked(getListView().isItemChecked(position));
                holder.title.setText(o.getTitle());
                if (TextUtils.isEmpty(o.getSubTitle())) {
                    holder.subTitle.setVisibility(View.GONE);
                } else {
                    holder.subTitle.setVisibility(View.VISIBLE);
                    holder.subTitle.setText(o.getSubTitle());
                }
                holder.date.setText(DateUtils.formatDateTime(getActivity(), o.getStart().getTime(),
                        DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH));
                holder.channelName.setText(o.getChannel());
                holder.contextMenu.setTag(position);
            }
            return convertView;
        }
    }

    /* (non-Javadoc)
     * @see org.dvbviewer.controller.ui.base.BaseListFragment#onListItemClick(android.widget.ListView, android.view.View, int, long)
     */
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        getListView().setItemChecked(position, !getListView().isItemChecked(position));
        Intent details = new Intent(getActivity(), IEpgDetailsActivity.class);
        IEPG entry = mAdapter.getItem(position);
        details.putExtra(IEPG.class.getSimpleName(), entry);
        startActivity(details);
        if (mode == null) {
            clearSelection();
        }
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onSaveInstanceState(android.os.Bundle)
     */
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    /* (non-Javadoc)
     * @see com.actionbarsherlock.view.ActionMode.Callback#onCreateActionMode(com.actionbarsherlock.view.ActionMode, com.actionbarsherlock.view.Menu)
     */
    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        getSherlockActivity().getSupportMenuInflater().inflate(R.menu.actionmode_recording, menu);
        return true;
    }

    /* (non-Javadoc)
     * @see com.actionbarsherlock.view.ActionMode.Callback#onPrepareActionMode(com.actionbarsherlock.view.ActionMode, com.actionbarsherlock.view.Menu)
     */
    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

    /* (non-Javadoc)
     * @see com.actionbarsherlock.view.ActionMode.Callback#onActionItemClicked(com.actionbarsherlock.view.ActionMode, com.actionbarsherlock.view.MenuItem)
     */
    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menuDelete:
            /**
             * Alertdialog to confirm the delete of Recordings
             */
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setMessage(getResources().getString(R.string.confirmDelete))
                    .setPositiveButton(getResources().getString(R.string.yes), this)
                    .setNegativeButton(getResources().getString(R.string.no), this).show();
            break;

        default:
            break;
        }
        return true;
    }

    /* (non-Javadoc)
     * @see com.actionbarsherlock.view.ActionMode.Callback#onDestroyActionMode(com.actionbarsherlock.view.ActionMode)
     */
    @Override
    public void onDestroyActionMode(ActionMode mode) {
        clearSelection();
    }

    /**
     * Clear selection.
     *
     * @author RayBa
     * @date 07.04.2013
     */
    private void clearSelection() {
        for (int i = 0; i < getListAdapter().getCount(); i++) {
            getListView().setItemChecked(i, false);
        }
        mAdapter.notifyDataSetChanged();
    }

    /* (non-Javadoc)
     * @see android.widget.CompoundButton.OnCheckedChangeListener#onCheckedChanged(android.widget.CompoundButton, boolean)
     */
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        getListView().setItemChecked((Integer) buttonView.getTag(), isChecked);
        int count = getCheckedItemCount();
        if (mode == null && count > 0) {
            mode = getSherlockActivity().startActionMode(RecordingList.this);
        } else if (count <= 0) {
            if (mode != null) {
                mode.finish();
                mode = null;
            }
        }
        if (mode != null) {
            mode.setTitle(count + " " + getResources().getString(R.string.selected));
        }
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo)
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        getActivity().getMenuInflater().inflate(R.menu.context_menu_recordinglist, menu);
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onContextItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onContextItemSelected(android.view.MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menuStream:
            if (item.getMenuInfo() != null) {
                AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
                selectedPosition = info.position;
            }

            if (UIUtils.isTablet(getActivity())) {
                StreamConfig cfg = StreamConfig.newInstance();
                Bundle arguments = new Bundle();
                arguments.putInt(StreamConfig.EXTRA_FILE_ID, (int) mAdapter.getItem(selectedPosition).getId());
                arguments.putInt(StreamConfig.EXTRA_FILE_TYPE, StreamConfig.FILE_TYPE_RECORDING);
                arguments.putInt(StreamConfig.EXTRA_DIALOG_TITLE_RES, R.string.streamConfig);
                cfg.setArguments(arguments);
                cfg.show(getSherlockActivity().getSupportFragmentManager(), StreamConfig.class.getName());
            } else {
                Intent streamConfig = new Intent(getActivity(), StreamConfigActivity.class);
                streamConfig.putExtra(StreamConfig.EXTRA_FILE_ID, (int) mAdapter.getItem(selectedPosition).getId());
                streamConfig.putExtra(StreamConfig.EXTRA_FILE_TYPE, StreamConfig.FILE_TYPE_RECORDING);
                startActivity(streamConfig);
            }

            return true;

        default:
            break;
        }
        return false;
    }

    /* (non-Javadoc)
     * @see com.actionbarsherlock.app.SherlockFragment#onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater)
     */
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.recording_list, menu);
    }

    /* (non-Javadoc)
     * @see com.actionbarsherlock.app.SherlockFragment#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        switch (itemId) {
        case R.id.menuRefresh:
            refresh();
            return true;

        default:
            return false;
        }
    }

    /**
     * Refresh.
     *
     * @author RayBa
     * @date 07.04.2013
     */
    private void refresh() {
        getLoaderManager().restartLoader(0, getArguments(), this);
        setListShown(false);
    }

    /**
     * The Class RecordingDeleter.
     *
     * @author RayBa
     * @date 07.04.2013
     */
    public static class RecordingDeleter extends AsyncTask<Recording, Void, Boolean> {

        AsyncCallback callback;

        /**
         * Instantiates a new recording deleter.
         *
         * @param callback the callback
         * @author RayBa
         * @date 07.04.2013
         */
        public RecordingDeleter(AsyncCallback callback) {
            this.callback = callback;
        }

        /* (non-Javadoc)
         * @see android.os.AsyncTask#onPreExecute()
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            callback.onAsyncActionStart();
        }

        /* (non-Javadoc)
         * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
         */
        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if (result) {
                callback.onAsyncActionStop();
            }

        }

        /* (non-Javadoc)
         * @see android.os.AsyncTask#doInBackground(Params[])
         */
        @Override
        protected Boolean doInBackground(Recording... params) {
            int count = params.length;
            if (count <= 0) {
                return false;
            }
            for (int i = 0; i < count; i++) {
                try {
                    ServerRequest.executeRSGet(ServerConsts.URL_DELETE_RECORDING + params[i].getId());
                } catch (ClientProtocolException e) {
                    e.printStackTrace();
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (AuthenticationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return true;
        }

    }

    /* (non-Javadoc)
     * @see android.content.DialogInterface.OnClickListener#onClick(android.content.DialogInterface, int)
     */
    @Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which) {
        case DialogInterface.BUTTON_POSITIVE:
            Log.i(RecordingList.class.getSimpleName(), "onClick");
            SparseBooleanArray checkedPositions = getListView().getCheckedItemPositions();
            Log.i(RecordingList.class.getSimpleName(), "items selected: " + checkedPositions.size());
            if (checkedPositions != null && checkedPositions.size() > 0) {

                int size = checkedPositions.size();
                RecordingDeleter deleter = new RecordingDeleter(this);
                List<Recording> recordings = new ArrayList<Recording>();
                for (int i = 0; i < size; i++) {
                    if (checkedPositions.valueAt(i)) {
                        recordings.add(mAdapter.getItem(checkedPositions.keyAt(i)));
                    }
                }
                Recording[] array = new Recording[recordings.size()];
                deleter.execute(recordings.toArray(array));
            }
            mode.finish();
            break;

        case DialogInterface.BUTTON_NEGATIVE:
            // No button clicked
            break;
        }
    }

    /* (non-Javadoc)
     * @see org.dvbviewer.controller.ui.base.BaseListFragment#onDestroyView()
     */
    @Override
    public void onDestroyView() {
        if (mode != null) {
            mode.finish();
        }
        super.onDestroyView();
    }

    /* (non-Javadoc)
     * @see android.view.View.OnClickListener#onClick(android.view.View)
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.contextMenu:
            selectedPosition = (Integer) v.getTag();
            getListView().showContextMenu();
            break;

        default:
            break;
        }
    }

    /* (non-Javadoc)
     * @see org.dvbviewer.controller.ui.base.BaseActivity.AsyncCallback#onAsyncActionStart()
     */
    @Override
    public void onAsyncActionStart() {
        progressDialog = new ProgressDialog(getActivity());
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setMessage(getResources().getString(R.string.busyDeleteRecordings));
        progressDialog.setIndeterminate(true);
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    /* (non-Javadoc)
     * @see org.dvbviewer.controller.ui.base.BaseActivity.AsyncCallback#onAsyncActionStop()
     */
    @Override
    public void onAsyncActionStop() {
        progressDialog.dismiss();
        refresh();
    }

}