/*
* TV-Browser for Android
* Copyright (C) 2013 René Mach (rene@tvbrowser.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to use, copy, modify or merge the Software,
* furthermore to publish and distribute the Software free of charge without modifications and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.tvbrowser.tvbrowser;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import org.tvbrowser.content.TvBrowserContentProvider;
import org.tvbrowser.settings.SettingConstants;
import org.tvbrowser.tvbrowser.LoaderUpdater.UnsupportedFragmentException;
import org.tvbrowser.utils.CompatUtils;
import org.tvbrowser.utils.IOUtils;
import org.tvbrowser.utils.PrefUtils;
import org.tvbrowser.utils.ProgramUtils;
import org.tvbrowser.utils.UiUtils;
import org.tvbrowser.view.SeparatorDrawable;
import android.annotation.SuppressLint;
import android.app.TimePickerDialog;
import android.content.BroadcastReceiver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.util.LongSparseArray;
import android.support.v4.util.SparseArrayCompat;
import android.text.Spannable;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
public class FragmentProgramsListRunning extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>, OnSharedPreferenceChangeListener {
private static final String WHERE_CLAUSE_KEY = "WHERE_CLAUSE_KEY";
private static final String DAY_CLAUSE_KEY = "DAY_CLAUSE_KEY";
private static final int TIMEOUT_LAST_EXTRA_CLICK = 750;
private Handler handler = new Handler();
// private boolean mKeepRunning;
//private Thread mUpdateThread;
private int mWhereClauseTime;
private BroadcastReceiver mDataUpdateReceiver;
private BroadcastReceiver mRefreshReceiver;
private BroadcastReceiver mMarkingChangeReceiver;
private BroadcastReceiver mDontWantToSeeReceiver;
private BroadcastReceiver mChannelUpdateDone;
private static final GradientDrawable BEFORE_GRADIENT;
private static final GradientDrawable AFTER_GRADIENT;
private ArrayAdapter<ChannelProgramBlock> mRunningProgramListAdapter;
private ArrayList<ChannelProgramBlock> mProgramBlockList;
private ArrayList<ChannelProgramBlock> mCurrentViewList;
private LongSparseArray<String[]> mMarkingsMap;
private LongSparseArray<String> mTitleMap;
private long mCurrentTime;
int mProgramIDColumn;
int mStartTimeColumn;
int mEndTimeColumn;
int mTitleColumn;
int mPictureColumn;
int mPictureCopyrightColumn;
int mCategoryColumn;
int mGenreColumn;
int mEpsiodeColumn;
int mChannelNameColumn;
int mChannelIDColumn;
private boolean showEpisode;
private boolean showInfo;
private boolean mShowOrderNumber;
private View.OnClickListener mOnClickListener;
private View.OnClickListener mChannelSwitchListener;
private View mContextView;
private long mContextProgramID;
private long mDayStart;
private ListView mListView;
private LinearLayout mTimeBar;
private Spinner mDateSelection;
private ArrayAdapter<DateSelection> mDateAdapter;
private Button mTimeExtra;
private long mLastExtraClick;
private LoaderUpdater mLoaderUpdater;
static {
BEFORE_GRADIENT = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT,new int[] {Color.argb(0x84, 0, 0, 0xff),Color.WHITE});
BEFORE_GRADIENT.setCornerRadius(0f);
AFTER_GRADIENT = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT,new int[] {Color.WHITE,Color.argb(0x84, 0, 0, 0xff)});
AFTER_GRADIENT.setCornerRadius(0f);
}
@Override
public void onResume() {
super.onResume();
mLoaderUpdater.setIsRunning();
mLoaderUpdater.startUpdate();
/*mKeepRunning = true;
startUpdateThread();*/
}
@Override
public void onPause() {
mLoaderUpdater.setIsNotRunning();
super.onPause();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mDataUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
handler.post(new Runnable() {
public void run() {
updateDateSelection();
if(intent != null) {
mLoaderUpdater.startUpdate();
}
}
});
}
};
mRefreshReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(mWhereClauseTime == -1) {
mLoaderUpdater.startUpdate();
}
else {
showEpisode = PrefUtils.getBooleanValue(R.string.SHOW_EPISODE_IN_RUNNING_LIST, R.bool.show_episode_in_running_list_default);
showInfo = PrefUtils.getBooleanValue(R.string.SHOW_INFO_IN_RUNNING_LIST, R.bool.show_info_in_running_list_default);
mShowOrderNumber = PrefUtils.getBooleanValue(R.string.SHOW_SORT_NUMBER_IN_RUNNING_LIST, R.bool.show_sort_number_in_running_list_default);
new Thread() {
public void run() {
if(getActivity() != null && isAdded()) {
ViewGroup list = (ViewGroup)getListView();
for(int i = 0; i < list.getChildCount(); i++) {
CompactLayoutViewHolder holder = (CompactLayoutViewHolder) list.getChildAt(i).getTag();
if(holder.mPrevious.getVisibility() == View.VISIBLE) {
if(holder.mPreviousStartTimeValue <= System.currentTimeMillis()) {
String[] markedColumns = mMarkingsMap.get(holder.mPreviousProgramID);
UiUtils.handleMarkings(getActivity(), null, holder.mPreviousStartTimeValue, holder.mPreviousEndTimeValue, holder.mPrevious, markedColumns, handler);
}
}
if(holder.mNowStartTimeValue <= System.currentTimeMillis()) {
String[] markedColumns = mMarkingsMap.get(holder.mNowProgramID);
UiUtils.handleMarkings(getActivity(), null, holder.mNowStartTimeValue, holder.mNowEndTimeValue, holder.mNow, markedColumns, handler);
}
if(holder.mNextStartTimeValue <= System.currentTimeMillis()) {
String[] markedColumns = mMarkingsMap.get(holder.mNextProgramID);
UiUtils.handleMarkings(getActivity(), null, holder.mNextStartTimeValue, holder.mNextEndTimeValue, holder.mNext, markedColumns, handler);
}
}
}
}
}.start();
}
}
};
mDontWantToSeeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mLoaderUpdater.startUpdate();
}
};
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mDontWantToSeeReceiver, new IntentFilter(SettingConstants.DONT_WANT_TO_SEE_CHANGED));
mMarkingChangeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, final Intent intent) {
new Thread() {
public void run() {
final long programID = intent.getLongExtra(SettingConstants.EXTRA_MARKINGS_ID, -1);
if(mMarkingsMap.indexOfKey(programID) >= 0 && IOUtils.isDatabaseAccessible(getActivity())) {
String[] projection = TvBrowserContentProvider.getColumnArrayWithMarkingColums(TvBrowserContentProvider.DATA_KEY_STARTTIME,TvBrowserContentProvider.DATA_KEY_ENDTIME);
Cursor c = null; try {
c = getActivity().getContentResolver().query(ContentUris.withAppendedId(TvBrowserContentProvider.CONTENT_URI_DATA, programID), projection, null, null, null);
if(c.moveToFirst()) {
try {
final View view = getListView().findViewWithTag(programID);
if(view != null) {
ArrayList<String> markedColumns = new ArrayList<String>();
for(String column : TvBrowserContentProvider.MARKING_COLUMNS) {
int index = c.getColumnIndex(column);
if(index >= 0 && c.getInt(index) >= 1) {
markedColumns.add(column);
}
else if(column.equals(TvBrowserContentProvider.DATA_KEY_MARKING_MARKING) && ProgramUtils.isMarkedWithIcon(getActivity(), programID)) {
markedColumns.add(column);
}
}
mMarkingsMap.put(programID, IOUtils.getStringArrayFromList(markedColumns));
handler.post(new Runnable() {
@Override
public void run() {
getListView().invalidateViews();
}
});
}
}catch(NullPointerException npe) {}
}
} finally {IOUtils.close(c);}
}
}
}.start();
}
};
mChannelUpdateDone = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mLoaderUpdater.startUpdate();
}
};
IntentFilter intent = new IntentFilter(SettingConstants.DATA_UPDATE_DONE);
IntentFilter markingsFilter = new IntentFilter(SettingConstants.MARKINGS_CHANGED);
IntentFilter channelsChanged = new IntentFilter(SettingConstants.CHANNEL_UPDATE_DONE);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mChannelUpdateDone, channelsChanged);
getActivity().registerReceiver(mDataUpdateReceiver, intent);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mRefreshReceiver, SettingConstants.RERESH_FILTER);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mMarkingChangeReceiver, markingsFilter);
}
public void setDay(long start) {
if(start != mDayStart) {
mDayStart = start;
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
today.set(Calendar.MILLISECOND, 0);
if((mDayStart > System.currentTimeMillis() || mDayStart < today.getTimeInMillis()) && mWhereClauseTime < System.currentTimeMillis()) {
Button time = (Button)((ViewGroup)((ViewGroup)getView().getParent()).getParent()).findViewWithTag(mWhereClauseTime);
Button now = (Button)((ViewGroup)((ViewGroup)getView().getParent()).getParent()).findViewById(R.id.now_button);
Button next = (Button)((ViewGroup)((ViewGroup)getView().getParent()).getParent()).findViewById(R.id.button_after1);
if(time != null && !time.equals(now) && (next == null || !time.equals(next))) {
time.performClick();
}
else {
Button button = null;
if(mTimeBar.getChildCount() > 1) {
int startIndex = 1;
if(next != null && next.getVisibility() == View.VISIBLE) {
if(mTimeBar.getChildCount() > 2) {
startIndex = 2;
}
}
for(int i = startIndex; i < mTimeBar.getChildCount(); i++) {
button = (Button)mTimeBar.getChildAt(i);
if(button.getTag(R.id.time_extra) == null) {
break;
}
}
}
selectButton(button);
}
mLoaderUpdater.startUpdate();
}
else {
mLoaderUpdater.startUpdate();
}
}
}
public void setWhereClauseTime(Object time) {
if(time instanceof Integer) {
int testValue = (Integer) time;
if(testValue != mWhereClauseTime) {
final Integer timeTest = mWhereClauseTime;
for(int i = 0; i < mTimeBar.getChildCount(); i++) {
if(timeTest.equals(mTimeBar.getChildAt(i).getTag())) {
mTimeBar.getChildAt(i).setBackgroundResource(android.R.drawable.list_selector_background);
}
}
int oldWhereClauseTime = mWhereClauseTime;
mWhereClauseTime = testValue;
Calendar now = Calendar.getInstance();
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
today.set(Calendar.MILLISECOND, 0);
if(mWhereClauseTime != -1 && mWhereClauseTime != -2 && PrefUtils.getBooleanValue(R.string.RUNNING_PROGRAMS_NEXT_DAY, R.bool.running_programs_next_day_default)) {
int test1 = now.get(Calendar.HOUR_OF_DAY) * 60 + now.get(Calendar.MINUTE);
if((test1 - mWhereClauseTime) > 180 && mDayStart < System.currentTimeMillis() && mDayStart >= today.getTimeInMillis()) {
Spinner date = (Spinner)((ViewGroup)getView().getParent()).findViewById(R.id.running_date_selection);
if(date.getCount() > 2) {
date.setSelection(2);
}
}
else {
mLoaderUpdater.startUpdate();
}
}
else if(oldWhereClauseTime != -1 && (mWhereClauseTime == -1 || mWhereClauseTime == -2)) {
Spinner date = (Spinner)((ViewGroup)getView().getParent()).findViewById(R.id.running_date_selection);
if(date.getCount() > 1) {
date.setSelection(1);
}
mLoaderUpdater.startUpdate();
}
else {
mLoaderUpdater.startUpdate();
}
}
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(WHERE_CLAUSE_KEY, mWhereClauseTime);
outState.putLong(DAY_CLAUSE_KEY, mDayStart);
super.onSaveInstanceState(outState);
}
private static final class CompactLayoutViewHolder {
static final int PREVIOUS = 0;
static final int NOW = 1;
static final int NEXT = 2;
long mPreviousProgramID;
long mNowProgramID;
long mNextProgramID;
long mPreviousStartTimeValue;
long mNowStartTimeValue;
long mNextStartTimeValue;
long mPreviousEndTimeValue;
long mNowEndTimeValue;
long mNextEndTimeValue;
int mCurrentOrientation;
float mCurrentScale;
ViewGroup mChannelInfo;
ImageView mChannelLogo;
TextView mChannel;
View mPrevious;
View mNow;
View mNext;
View mSeparator1;
View mSeparator2;
TextView mPreviousStartTime;
TextView mPreviousTitle;
TextView mPreviousInfos;
TextView mPreviousEpisode;
TextView mNowStartTime;
TextView mNowTitle;
TextView mNowInfos;
TextView mNowEpisode;
TextView mNextStartTime;
TextView mNextTitle;
TextView mNextInfos;
TextView mNextEpisode;
public void setVisibility(int type, int visibility) {
switch(type) {
case PREVIOUS:
mPrevious.setVisibility(visibility);
mPreviousStartTime.setVisibility(visibility);
mPreviousTitle.setVisibility(visibility);
mPreviousEpisode.setVisibility(visibility);
break;
case NOW:
mNow.setVisibility(visibility);
mNowStartTime.setVisibility(visibility);
mNowTitle.setVisibility(visibility);
mNowEpisode.setVisibility(visibility);
break;
case NEXT:
mNext.setVisibility(visibility);
mNextStartTime.setVisibility(visibility);
mNextTitle.setVisibility(visibility);
mNextEpisode.setVisibility(visibility);
break;
}
}
public void setSeparatorVisibility(int visibility) {
if(mSeparator1 != null) {
mSeparator1.setVisibility(visibility);
mSeparator2.setVisibility(visibility);
}
}
public boolean orientationChanged(int orientation) {
return mCurrentOrientation != orientation;
}
public void setColor(int type, int color) {
switch (type) {
case PREVIOUS:
mPreviousEpisode.setTextColor(color);
mPreviousTitle.setTextColor(color);
mPreviousStartTime.setTextColor(color);
mPreviousInfos.setTextColor(color);
break;
case NOW:
mNowEpisode.setTextColor(color);
mNowTitle.setTextColor(color);
mNowStartTime.setTextColor(color);
mNowInfos.setTextColor(color);
break;
case NEXT:
mNextEpisode.setTextColor(color);
mNextTitle.setTextColor(color);
mNextStartTime.setTextColor(color);
mNextInfos.setTextColor(color);
break;
}
}
}
@SuppressLint("NewApi")
private boolean fillCompactLayout(final CompactLayoutViewHolder viewHolder, final int type, final ChannelProgramBlock block, final java.text.DateFormat timeFormat, final int DEFAULT_TEXT_COLOR, boolean channelSet) {
TextView startTimeView = null;
TextView titleView = null;
TextView infoView = null;
TextView episodeView = null;
View layout = null;
long startTime = 0;
long endTime = 0;
long programID = -1;
String title = null;
String episode = null;
Spannable infos = null;
int startTimeResId = 0;
int endTimeResId = 0;
switch(type) {
case CompactLayoutViewHolder.PREVIOUS:
layout = viewHolder.mPrevious;
startTimeView = viewHolder.mPreviousStartTime;
titleView = viewHolder.mPreviousTitle;
episodeView = viewHolder.mPreviousEpisode;
infoView = viewHolder.mPreviousInfos;
startTime = block.mPreviousStart;
endTime = block.mPreviousEnd;
episode = block.mPreviousEpisode;
infos = block.mPreviousCategory;
programID = block.mPreviousProgramID;
startTimeResId = R.id.running_time_previous_start;
endTimeResId = R.id.running_time_previous_end;
break;
case CompactLayoutViewHolder.NOW:
layout = viewHolder.mNow;
startTimeView = viewHolder.mNowStartTime;
titleView = viewHolder.mNowTitle;
episodeView = viewHolder.mNowEpisode;
infoView = viewHolder.mNowInfos;
startTime = block.mNowStart;
endTime = block.mNowEnd;
episode = block.mNowEpisode;
infos = block.mNowCategory;
programID = block.mNowProgramID;
startTimeResId = R.id.running_time_now_start;
endTimeResId = R.id.running_time_now_end;
break;
case CompactLayoutViewHolder.NEXT:
layout = viewHolder.mNext;
startTimeView = viewHolder.mNextStartTime;
titleView = viewHolder.mNextTitle;
episodeView = viewHolder.mNextEpisode;
infoView = viewHolder.mNextInfos;
startTime = block.mNextStart;
endTime = block.mNextEnd;
episode = block.mNextEpisode;
infos = block.mNextCategory;
programID = block.mNextProgramID;
startTimeResId = R.id.running_time_next_start;
endTimeResId = R.id.running_time_next_end;
break;
}
title = mTitleMap.get(programID);
if(startTime > 0 && title != null) {
switch(type) {
case CompactLayoutViewHolder.PREVIOUS:
viewHolder.mPreviousStartTimeValue = startTime;
viewHolder.mPreviousEndTimeValue = endTime;
viewHolder.mPreviousProgramID = programID;
break;
case CompactLayoutViewHolder.NOW:
viewHolder.mNowStartTimeValue = startTime;
viewHolder.mNowEndTimeValue = endTime;
viewHolder.mNowProgramID = programID;
break;
case CompactLayoutViewHolder.NEXT:
viewHolder.mNextStartTimeValue = startTime;
viewHolder.mNextEndTimeValue = endTime;
viewHolder.mNextProgramID = programID;
break;
}
viewHolder.setVisibility(type, View.VISIBLE);
startTimeView.setText(timeFormat.format(startTime));
titleView.setText(ProgramUtils.getMarkIcons(getActivity(), programID, title));
if(!showEpisode || episode == null || episode.trim().length() == 0) {
episodeView.setVisibility(View.GONE);
}
else {
episodeView.setText(episode);
episodeView.setVisibility(View.VISIBLE);
}
if(!showInfo || infos == null || infos.toString().trim().length() == 0) {
infoView.setVisibility(View.GONE);
}
else {
infoView.setText(infos);
infoView.setVisibility(View.VISIBLE);
}
if(endTime <= System.currentTimeMillis()) {
viewHolder.setColor(type, UiUtils.getColor(UiUtils.EXPIRED_COLOR_KEY, getActivity()));
}
else {
viewHolder.setColor(type, DEFAULT_TEXT_COLOR);
}
if(!channelSet) {
String logoNamePref = PrefUtils.getStringValue(R.string.CHANNEL_LOGO_NAME_RUNNING, R.string.channel_logo_name_running_default);
boolean showChannelName = logoNamePref.equals("0") || logoNamePref.equals("2");
boolean showChannelLogo = logoNamePref.equals("0") || logoNamePref.equals("1");
boolean showBigChannelLogo = logoNamePref.equals("3");
Drawable logo = null;
if(showBigChannelLogo) {
logo = SettingConstants.MEDIUM_LOGO_MAP.get(block.mChannelID);
}
else if(showChannelLogo) {
logo = SettingConstants.SMALL_LOGO_MAP.get(block.mChannelID);
}
if(logo != null) {
viewHolder.mChannelLogo.setImageDrawable(logo);
viewHolder.mChannelLogo.setVisibility(View.VISIBLE);
}
else {
viewHolder.mChannelLogo.setVisibility(View.GONE);
}
String shortName = SettingConstants.SHORT_CHANNEL_NAMES.get(block.mChannelName);
if(shortName == null) {
shortName = block.mChannelName;
}
if(mShowOrderNumber && (logo == null || showChannelName)) {
shortName = block.mChannelOrderNumber + ". " + shortName;
}
else if(mShowOrderNumber) {
shortName = block.mChannelOrderNumber + ".";
}
if(logo == null || mShowOrderNumber || showChannelName) {
viewHolder.mChannel.setText(shortName);
viewHolder.mChannel.setVisibility(View.VISIBLE);
}
else {
viewHolder.mChannel.setVisibility(View.GONE);
}
viewHolder.mChannelInfo.setTag(block.mChannelID);
viewHolder.mChannelInfo.setOnClickListener(mChannelSwitchListener);
channelSet = true;
}
viewHolder.mChannelInfo.setTag(startTimeResId, startTime);
viewHolder.mChannelInfo.setTag(endTimeResId, endTime);
layout.setTag(programID);
layout.setOnClickListener(mOnClickListener);
final String[] markingsValue = mMarkingsMap.get(programID);
if(startTime <= System.currentTimeMillis() || (markingsValue != null && markingsValue.length > 0)) {
final long startTime1 = startTime;
final long endTime1 = endTime;
final View layout1 = layout;
new Thread() {
public void run() {
UiUtils.handleMarkings(getActivity(), null, startTime1, endTime1, layout1, markingsValue, handler);
}
}.start();
}
else {
CompatUtils.setBackground(layout, ContextCompat.getDrawable(getActivity(), android.R.drawable.list_selector_background));
}
}
else {
int viewType = View.GONE;
boolean isPortrait = viewHolder.mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT;
Configuration config = getResources().getConfiguration();
if(Build.VERSION.SDK_INT >= 13) {
if(type == CompactLayoutViewHolder.PREVIOUS) {
if(config.smallestScreenWidthDp >= 600 && !isPortrait) {
viewType = View.INVISIBLE;
}
}
else if(type == CompactLayoutViewHolder.NOW && (config.smallestScreenWidthDp >= 600 || !isPortrait)) {
viewType = View.INVISIBLE;
}
}
viewHolder.setVisibility(type, viewType);
if(type == CompactLayoutViewHolder.PREVIOUS) {
viewHolder.setSeparatorVisibility(viewType);
}
titleView.setVisibility(View.GONE);
episodeView.setVisibility(View.GONE);
infoView.setVisibility(View.GONE);
}
return channelSet;
}
private View getCompactView(View convertView, ViewGroup parent, java.text.DateFormat timeFormat, ChannelProgramBlock block, int DEFAULT_TEXT_COLOR) {
CompactLayoutViewHolder viewHolder = null;
float textScale = Float.valueOf(PrefUtils.getStringValue(R.string.PREF_PROGRAM_LISTS_TEXT_SCALE, R.string.pref_program_lists_text_scale_default));
if(convertView == null || ((CompactLayoutViewHolder)convertView.getTag()).orientationChanged(SettingConstants.ORIENTATION) || ((CompactLayoutViewHolder)convertView.getTag()).mCurrentScale != textScale) {
convertView = getActivity().getLayoutInflater().inflate(R.layout.compact_program_panel, parent, false);
UiUtils.scaleTextViews(convertView, textScale);
viewHolder = new CompactLayoutViewHolder();
viewHolder.mCurrentOrientation = SettingConstants.ORIENTATION;
viewHolder.mCurrentScale = textScale;
viewHolder.mChannelInfo = (ViewGroup)convertView.findViewById(R.id.running_list_channel_info);
viewHolder.mChannelLogo = (ImageView)convertView.findViewById(R.id.running_list_channel_logo);
viewHolder.mChannel = (TextView)convertView.findViewById(R.id.running_compact_channel_label);
viewHolder.mSeparator1 = convertView.findViewById(R.id.running_separator_1);
viewHolder.mSeparator2 = convertView.findViewById(R.id.running_separator_2);
viewHolder.mPrevious = convertView.findViewById(R.id.running_compact_previous);
viewHolder.mNow = convertView.findViewById(R.id.running_compact_now);
viewHolder.mNext = convertView.findViewById(R.id.running_compact_next);
registerForContextMenu(viewHolder.mPrevious);
registerForContextMenu(viewHolder.mNow);
registerForContextMenu(viewHolder.mNext);
viewHolder.mPreviousStartTime = (TextView)convertView.findViewById(R.id.running_compact_previous_start);
viewHolder.mNowStartTime = (TextView)convertView.findViewById(R.id.running_compact_now_start);
viewHolder.mNextStartTime = (TextView)convertView.findViewById(R.id.running_compact_next_start);
viewHolder.mPreviousTitle = (TextView)convertView.findViewById(R.id.running_compact_previous_title);
viewHolder.mNowTitle = (TextView)convertView.findViewById(R.id.running_compact_now_title);
viewHolder.mNextTitle = (TextView)convertView.findViewById(R.id.running_compact_next_title);
viewHolder.mPreviousInfos = (TextView)convertView.findViewById(R.id.running_compact_previous_infos);
viewHolder.mNowInfos = (TextView)convertView.findViewById(R.id.running_compact_now_infos);
viewHolder.mNextInfos = (TextView)convertView.findViewById(R.id.running_compact_next_infos);
viewHolder.mPreviousEpisode = (TextView)convertView.findViewById(R.id.running_compact_previous_episode);
viewHolder.mNowEpisode = (TextView)convertView.findViewById(R.id.running_compact_now_episode);
viewHolder.mNextEpisode = (TextView)convertView.findViewById(R.id.running_compact_next_episode);
convertView.setTag(viewHolder);
}
else {
viewHolder = (CompactLayoutViewHolder)convertView.getTag();
}
if(viewHolder != null && block != null /*&& mCurrentCursor != null && !mCurrentCursor.isClosed()*/) {
viewHolder.mChannelInfo.setTag(R.id.running_time_previous_start, null);
viewHolder.mChannelInfo.setTag(R.id.running_time_now_start, null);
viewHolder.mChannelInfo.setTag(R.id.running_time_next_start, null);
viewHolder.mChannelInfo.setTag(R.id.running_time_previous_end, null);
viewHolder.mChannelInfo.setTag(R.id.running_time_now_end, null);
viewHolder.mChannelInfo.setTag(R.id.running_time_next_end, null);
boolean channelSet = false;
if(mWhereClauseTime != -1) {
viewHolder.setSeparatorVisibility(View.VISIBLE);
channelSet = fillCompactLayout(viewHolder, CompactLayoutViewHolder.PREVIOUS, block, timeFormat, DEFAULT_TEXT_COLOR, channelSet);
}
else {
viewHolder.setVisibility(CompactLayoutViewHolder.PREVIOUS, View.GONE);
viewHolder.setSeparatorVisibility(View.GONE);
}
channelSet = fillCompactLayout(viewHolder, CompactLayoutViewHolder.NOW, block, timeFormat, DEFAULT_TEXT_COLOR, channelSet);
channelSet = fillCompactLayout(viewHolder, CompactLayoutViewHolder.NEXT, block, timeFormat, DEFAULT_TEXT_COLOR, channelSet);
ViewGroup group = (ViewGroup)convertView;
for(int i = 0; i < group.getChildCount(); i++) {
View child = group.getChildAt(i);
if(child instanceof LinearLayout) {
RelativeLayout.LayoutParams para = (RelativeLayout.LayoutParams)child.getLayoutParams();
para.height = -2;
}
}
}
return convertView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity());
pref.registerOnSharedPreferenceChangeListener(this);
if(handler == null) {
handler = new Handler();
}
try {
mLoaderUpdater = new LoaderUpdater(FragmentProgramsListRunning.this, handler);
} catch (UnsupportedFragmentException e) {
// Ignore
}
if(savedInstanceState != null) {
mWhereClauseTime = savedInstanceState.getInt(WHERE_CLAUSE_KEY,-1);
mDayStart = savedInstanceState.getLong(DAY_CLAUSE_KEY,-1);
}
else {
mWhereClauseTime = -1;
mDayStart = -1;
}
mMarkingsMap = new LongSparseArray<String[]>();
mTitleMap = new LongSparseArray<String>();
mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Long tag = (Long)v.getTag();
if(tag != null) {
UiUtils.showProgramInfo(getActivity(), tag, getActivity().getCurrentFocus(), handler);
}
}
};
mChannelSwitchListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Integer id = (Integer)v.getTag();
boolean handle = PrefUtils.getBooleanValue(R.string.PREF_RUNNING_LIST_CLICK_TO_CHANNEL_TO_LIST, R.bool.pref_running_list_click_to_channel_to_list_default);
if(handle && id != null) {
Intent showChannel = new Intent(SettingConstants.SHOW_ALL_PROGRAMS_FOR_CHANNEL_INTENT);
showChannel.putExtra(SettingConstants.CHANNEL_ID_EXTRA,id);
Object scrollTime = v.getTag(R.id.running_time_now_start);
Object endTime = v.getTag(R.id.running_time_now_end);
if(scrollTime == null) {
scrollTime = v.getTag(R.id.running_time_previous_start);
endTime = v.getTag(R.id.running_time_previous_end);
}
if(scrollTime == null) {
scrollTime = v.getTag(R.id.running_time_next_start);
endTime = v.getTag(R.id.running_time_next_end);
}
if(scrollTime != null) {
showChannel.putExtra(SettingConstants.EXTRA_START_TIME, ((Long)scrollTime).longValue());
showChannel.putExtra(SettingConstants.EXTRA_END_TIME, ((Long)endTime).longValue());
}
else {
Calendar now = Calendar.getInstance();
if(mDayStart != -1) {
now.setTimeInMillis(mDayStart);
}
now.set(Calendar.SECOND, 0);
now.set(Calendar.MILLISECOND, 0);
if(mWhereClauseTime >= 0) {
now.set(Calendar.HOUR_OF_DAY, mWhereClauseTime / 60);
now.set(Calendar.MINUTE, mWhereClauseTime % 60);
} else if(mWhereClauseTime == -1) {
now.setTimeInMillis(System.currentTimeMillis());
}
showChannel.putExtra(SettingConstants.EXTRA_START_TIME, now.getTimeInMillis());
showChannel.putExtra(SettingConstants.EXTRA_END_TIME, now.getTimeInMillis());
}
if(mDateSelection.getSelectedItemPosition() == 0) {
showChannel.putExtra(SettingConstants.DAY_POSITION_EXTRA, FragmentProgramsList.INDEX_DATE_YESTERDAY);
}
else if(mDateSelection.getSelectedItemPosition() == 1) {
if(endTime == null || (Long) endTime > System.currentTimeMillis()) {
showChannel.putExtra(SettingConstants.DAY_POSITION_EXTRA, FragmentProgramsList.INDEX_DATE_TODAY_TOMORROW);
}
}
LocalBroadcastManager.getInstance(getActivity()).sendBroadcastSync(showChannel);
}
}
};
mProgramBlockList = new ArrayList<FragmentProgramsListRunning.ChannelProgramBlock>();
mCurrentViewList = new ArrayList<FragmentProgramsListRunning.ChannelProgramBlock>();
java.text.DateFormat mTimeFormat = DateFormat.getTimeFormat(getActivity());
String value = ((SimpleDateFormat)mTimeFormat).toLocalizedPattern();
if((value.charAt(0) == 'H' && value.charAt(1) != 'H') || (value.charAt(0) == 'h' && value.charAt(1) != 'h')) {
value = value.charAt(0) + value;
}
final java.text.DateFormat timeFormat = new SimpleDateFormat(value, Locale.getDefault());
final int DEFAULT_TEXT_COLOR = new TextView(getActivity()).getTextColors().getDefaultColor();
mRunningProgramListAdapter = new ArrayAdapter<FragmentProgramsListRunning.ChannelProgramBlock>(getActivity(), R.layout.running_list_entries, mCurrentViewList) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ChannelProgramBlock block = getItem(position);
// if(mIsCompactLayout) {
return getCompactView(convertView, parent, timeFormat, block, DEFAULT_TEXT_COLOR);
/*}
else {
return getLongView(convertView, parent, timeFormat, block, DEFAULT_TEXT_COLOR);
}*/
}
};
mListView.setAdapter(mRunningProgramListAdapter);
SeparatorDrawable drawable = new SeparatorDrawable(getActivity());
getListView().setDivider(drawable);
setDividerSize(PrefUtils.getStringValue(R.string.PREF_RUNNING_DIVIDER_SIZE, R.string.pref_running_divider_size_default));
// getLoaderManager().initLoader(0, null, this);
}
@Override
public void onDetach() {
if(mDataUpdateReceiver != null) {
getActivity().unregisterReceiver(mDataUpdateReceiver);
}
if(mRefreshReceiver != null) {
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mRefreshReceiver);
}
if(mMarkingChangeReceiver != null) {
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mMarkingChangeReceiver);
}
if(mDontWantToSeeReceiver != null) {
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mDontWantToSeeReceiver);
}
if(mChannelUpdateDone != null) {
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mChannelUpdateDone);
}
mLoaderUpdater.setIsNotRunning();
super.onDetach();
}
/* private void startUpdateTshread() {
if(mKeepRunning) {
if(getLoaderManager().hasRunningLoaders()) {
getLoaderManager().getLoader(0).cancelLoad();
}
mUpdateThread = new Thread() {
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
if(!isDetached() && mKeepRunning && !isRemoving()) {
getLoaderManager().restartLoader(0, null, FragmentProgramsListRunning.this);
}
}
});
}
};
mUpdateThread.start();
}
}
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.running_program_fragment, container, false);
mListView = (ListView)view.findViewById(R.id.running_list_fragment_list_view);
mTimeBar = (LinearLayout)view.findViewById(R.id.runnning_time_bar);
initialize(view);
return view;
}
private void pickTime(final View v) {
Log.d("info12", "pickTime " + new Date(mLastExtraClick + TIMEOUT_LAST_EXTRA_CLICK) + " " + new Date(System.currentTimeMillis()));
if(mLastExtraClick + TIMEOUT_LAST_EXTRA_CLICK < System.currentTimeMillis()) {
if(isViewNotVisible(mTimeExtra)) {
((HorizontalScrollView)mTimeBar.getParent()).scrollTo(mTimeExtra.getLeft(), mTimeExtra.getTop());
}
final int time = (Integer)v.getTag();
final TimePickerDialog pick = new TimePickerDialog(getActivity(), TimePickerDialog.THEME_HOLO_DARK, new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
final Integer selectedTime = hourOfDay * 60 + minute;
insertTimeExtra(selectedTime);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, selectedTime / 60);
cal.set(Calendar.MINUTE, selectedTime % 60);
mTimeExtra.setText(DateFormat.getTimeFormat(getActivity().getApplicationContext()).format(cal.getTime()));
mTimeExtra.setTag(selectedTime);
mLastExtraClick = System.currentTimeMillis();
setWhereClauseTime(selectedTime);
PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, getActivity()).edit().putInt(getString(R.string.PREF_MISC_LAST_TIME_EXTRA_VALUE), selectedTime).commit();
}
}, time/60, time%60, DateFormat.is24HourFormat(getActivity()));
pick.show();
}
else {
mLastExtraClick = System.currentTimeMillis();
setWhereClauseTime(mWhereClauseTime);
}
}
private void initialize(View rootView) {
final Button now = (Button)rootView.findViewById(R.id.now_button);
final Button next = (Button)rootView.findViewById(R.id.button_after1);
mDateSelection = (Spinner)rootView.findViewById(R.id.running_date_selection);
now.setTag(-1);
next.setTag(-2);
final View.OnClickListener listenerClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(PrefUtils.getBooleanValue(R.string.PREF_RUNNING_PROGRAMS_SHOW_TIME_PICK_BUTTON_ONLY_WHEN_NEEDED, R.bool.pref_running_programs_show_time_pick_button_only_when_needed_default)) {
mTimeBar.removeView(mTimeExtra);
}
if((v.equals(now) || v.equals(next)) && mDateSelection.getCount() > 1) {
mDateSelection.setSelection(1);
}
setWhereClauseTime(v.getTag());
}
};
final View.OnLongClickListener listenerLongClick = new View.OnLongClickListener() {
@Override
public boolean onLongClick(final View v) {
pickTime(v);
return true;
}
};
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(getActivity());
IntentFilter timeButtonsUpdateFilter = new IntentFilter(SettingConstants.UPDATE_TIME_BUTTONS);
final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
for(int i = mTimeBar.getChildCount() - 1; i >= 0; i--) {
Button button = (Button)mTimeBar.getChildAt(i);
if(button != null) {
button.setOnClickListener(null);
mTimeBar.removeViewAt(i);
}
}
if(getActivity() != null) {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity());
now.setOnClickListener(listenerClick);
mTimeBar.addView(now);
if(PrefUtils.getBooleanValue(R.string.PREF_RUNNING_PROGRAMS_SHOW_NEXT_BUTTON, R.bool.pref_running_programs_show_next_button_default)) {
next.setOnClickListener(listenerClick);
mTimeBar.addView(next);
}
now.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if(mDateSelection.getCount() > 1) {
mDateSelection.setSelection(1);
}
setWhereClauseTime(-2);
return true;
}
});
ArrayList<Integer> values = new ArrayList<Integer>();
int[] defaultValues = getResources().getIntArray(R.array.time_button_defaults);
int timeButtonCount = pref.getInt(getString(R.string.TIME_BUTTON_COUNT),getResources().getInteger(R.integer.time_button_count_default));
for(int i = 1; i <= Math.min(timeButtonCount, getResources().getInteger(R.integer.time_button_count_default)); i++) {
try {
Class<?> string = R.string.class;
Field setting = string.getDeclaredField("TIME_BUTTON_" + i);
Integer value = pref.getInt(getResources().getString((Integer) setting.get(string)), defaultValues[i - 1]);
if(value >= -1 && !values.contains(value)) {
values.add(value);
}
} catch (Exception e) {}
}
for(int i = 7; i <= timeButtonCount; i++) {
Integer value = pref.getInt("TIME_BUTTON_" + i, 0);
if(value >= -1 && !values.contains(value)) {
values.add(value);
}
}
if(PrefUtils.getBooleanValue(R.string.SORT_RUNNING_TIMES, R.bool.sort_running_times_default)) {
Collections.sort(values);
}
Calendar cal = Calendar.getInstance();
int lastExtraTime = PrefUtils.getIntValueWithDefaultKey(R.string.PREF_MISC_LAST_TIME_EXTRA_VALUE, R.integer.pref_misc_last_time_extra_value_default);
cal.set(Calendar.HOUR_OF_DAY, lastExtraTime/60);
cal.set(Calendar.MINUTE, lastExtraTime%60);
getActivity().getLayoutInflater().inflate(R.layout.time_button, mTimeBar);
mLastExtraClick = 0;
mTimeExtra = (Button)mTimeBar.getChildAt(mTimeBar.getChildCount()-1);
mTimeExtra.setText(DateFormat.getTimeFormat(getActivity().getApplicationContext()).format(cal.getTime()));
mTimeExtra.setTag(R.id.time_extra, Boolean.TRUE);
mTimeExtra.setTypeface(null, Typeface.BOLD_ITALIC);
mTimeExtra.setTag(lastExtraTime);
mTimeExtra.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pickTime(v);
}
});
mTimeExtra.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
mLastExtraClick = System.currentTimeMillis();
if((v.equals(now) || v.equals(next)) && mDateSelection.getCount() > 1) {
mDateSelection.setSelection(1);
}
setWhereClauseTime(v.getTag());
return true;
}
});
if(PrefUtils.getBooleanValue(R.string.PREF_RUNNING_PROGRAMS_SHOW_TIME_PICK_BUTTON_ONLY_WHEN_NEEDED, R.bool.pref_running_programs_show_time_pick_button_only_when_needed_default)
&& lastExtraTime != mWhereClauseTime) {
mTimeBar.removeView(mTimeExtra);
}
for(Integer value : values) {
getActivity().getLayoutInflater().inflate(R.layout.time_button, mTimeBar);
cal.set(Calendar.HOUR_OF_DAY, value / 60);
cal.set(Calendar.MINUTE, value % 60);
Button time = (Button)mTimeBar.getChildAt(mTimeBar.getChildCount()-1);
time.setText(DateFormat.getTimeFormat(getActivity().getApplicationContext()).format(cal.getTime()));
time.setTag(value);
time.setOnClickListener(listenerClick);
time.setOnLongClickListener(listenerLongClick);
}
}
}
};
localBroadcastManager.registerReceiver(receiver, timeButtonsUpdateFilter);
receiver.onReceive(null, null);
ArrayList<DateSelection> dateEntries = new ArrayList<DateSelection>();
mDateAdapter = new ArrayAdapter<DateSelection>(getActivity(), android.R.layout.simple_spinner_item, dateEntries);
mDateAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mDateSelection.setAdapter(mDateAdapter);
mDateSelection.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if(pos >= 0) {
DateSelection selection = mDateAdapter.getItem(pos);
setDay(selection.getTime());
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
setDay(-1);
}
});
updateDateSelection();
if(mDateSelection.getCount() > 1) {
mDateSelection.setSelection(1);
}
}
private void updateDateSelection() {
if(getActivity() != null && !isDetached() && mDateSelection != null) {
final int orgPos = mDateSelection.getSelectedItemPosition();
int pos = orgPos;
mDateAdapter.clear();
long last = PrefUtils.getLongValueWithDefaultKey(R.string.META_DATA_DATE_LAST_KNOWN, R.integer.meta_data_date_known_default);
Calendar lastDay = Calendar.getInstance();
lastDay.setTimeInMillis(last);
lastDay.set(Calendar.HOUR_OF_DAY, 4);
lastDay.set(Calendar.MINUTE, 0);
lastDay.set(Calendar.SECOND, 0);
lastDay.set(Calendar.MILLISECOND, 0);
Calendar yesterday = Calendar.getInstance();
yesterday.set(Calendar.HOUR_OF_DAY, 4);
yesterday.set(Calendar.MINUTE, 0);
yesterday.set(Calendar.SECOND, 0);
yesterday.set(Calendar.MILLISECOND, 0);
yesterday.add(Calendar.DAY_OF_YEAR, -1);
long yesterdayStart = yesterday.getTimeInMillis();
long lastStart = lastDay.getTimeInMillis();
Calendar cal = Calendar.getInstance();
for(long day = yesterdayStart; day <= lastStart; day += (24 * 60 * 60000)) {
cal.setTimeInMillis(day);
cal.set(Calendar.HOUR_OF_DAY, 0);
mDateAdapter.add(new DateSelection(cal.getTimeInMillis(), getActivity()));
}
if(pos == -1) {
pos = 1;
}
if(mDateSelection.getCount() > pos) {
mDateSelection.setSelection(pos);
}
else {
mDateSelection.setSelection(mDateSelection.getCount()-1);
}
if(orgPos == pos && pos < mDateAdapter.getCount()) {
final DateSelection selection = mDateAdapter.getItem(pos);
setDay(selection.getTime());
}
}
}
private ListView getListView() {
return mListView;
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] infoCategories = TvBrowserContentProvider.INFO_CATEGORIES_COLUMNS_ARRAY;
int startIndex = 13 + infoCategories.length;
String[] projection = new String[startIndex + TvBrowserContentProvider.MARKING_COLUMNS.length];
showEpisode = PrefUtils.getBooleanValue(R.string.SHOW_EPISODE_IN_RUNNING_LIST, R.bool.show_episode_in_running_list_default);
showInfo = PrefUtils.getBooleanValue(R.string.SHOW_INFO_IN_RUNNING_LIST, R.bool.show_info_in_running_list_default);
mShowOrderNumber = PrefUtils.getBooleanValue(R.string.SHOW_SORT_NUMBER_IN_RUNNING_LIST, R.bool.show_sort_number_in_running_list_default);
projection[0] = TvBrowserContentProvider.KEY_ID;
projection[1] = TvBrowserContentProvider.CHANNEL_KEY_CHANNEL_ID;
projection[2] = TvBrowserContentProvider.DATA_KEY_STARTTIME;
projection[3] = TvBrowserContentProvider.DATA_KEY_ENDTIME;
projection[4] = TvBrowserContentProvider.DATA_KEY_TITLE;
projection[5] = TvBrowserContentProvider.DATA_KEY_SHORT_DESCRIPTION;
projection[6] = TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER;
projection[7] = TvBrowserContentProvider.DATA_KEY_EPISODE_TITLE;
projection[8] = TvBrowserContentProvider.DATA_KEY_GENRE;
projection[9] = TvBrowserContentProvider.DATA_KEY_PICTURE_COPYRIGHT;
projection[10] = TvBrowserContentProvider.DATA_KEY_CATEGORIES;
projection[11] = TvBrowserContentProvider.CHANNEL_KEY_NAME;
projection[12] = TvBrowserContentProvider.DATA_KEY_DONT_WANT_TO_SEE;
System.arraycopy(infoCategories, 0, projection, 13, infoCategories.length);
System.arraycopy(TvBrowserContentProvider.MARKING_COLUMNS, 0, projection, startIndex, TvBrowserContentProvider.MARKING_COLUMNS.length);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 30);
Calendar now = Calendar.getInstance();
now.setTimeInMillis(System.currentTimeMillis());
if(mWhereClauseTime >= 0) {
if(mDayStart >= 0) {
cal.setTimeInMillis(mDayStart);
}
cal.set(Calendar.HOUR_OF_DAY, mWhereClauseTime / 60);
cal.set(Calendar.MINUTE, mWhereClauseTime % 60);
}
if(mWhereClauseTime < 0) {
cal.setTimeInMillis(System.currentTimeMillis());
}
final Integer timeTest = mWhereClauseTime;
for(int i = 0; i < mTimeBar.getChildCount(); i++) {
if(timeTest.equals(mTimeBar.getChildAt(i).getTag())) {
mTimeBar.getChildAt(i).setBackgroundColor(UiUtils.getColor(UiUtils.RUNNING_TIME_SELECTION_KEY, getActivity()));
if(isViewNotVisible(mTimeBar.getChildAt(i))) {
((HorizontalScrollView)mTimeBar.getParent()).scrollTo(mTimeBar.getChildAt(i).getLeft(), mTimeBar.getChildAt(i).getTop());
}
}
}
mCurrentTime = ((long)cal.getTimeInMillis() / 60000) * 60000;
String sort = TvBrowserContentProvider.DATA_KEY_STARTTIME + " ASC";
String where = " ( ( " + TvBrowserContentProvider.DATA_KEY_ENDTIME + "<=" + mCurrentTime + " AND " + TvBrowserContentProvider.DATA_KEY_ENDTIME + ">" + (mCurrentTime - (60000 * 60 * 12)) + " ) ";
if(mWhereClauseTime == -1) {
where = " ( ( " + TvBrowserContentProvider.DATA_KEY_ENDTIME + ">" + mCurrentTime + " AND " + TvBrowserContentProvider.DATA_KEY_STARTTIME + "<" + (mCurrentTime + (60000 * 60 * 12)) + " ) ";
}
else {
where += " OR ( " + TvBrowserContentProvider.DATA_KEY_ENDTIME + ">" + mCurrentTime + " AND " + TvBrowserContentProvider.DATA_KEY_STARTTIME + "<" + (mCurrentTime + (60000 * 60 * 12)) + " ) ";
}
where += ") " + UiUtils.getDontWantToSeeFilterString(getActivity());
where += ((TvBrowser)getActivity()).getFilterSelection(false);
return new CursorLoader(getActivity(), TvBrowserContentProvider.CONTENT_URI_DATA_WITH_CHANNEL, projection, where, null, TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER + " , " + TvBrowserContentProvider.CHANNEL_KEY_CHANNEL_ID + " COLLATE NOCASE, " + sort);
}
private static final class ChannelProgramBlock {
public int mChannelID;
private String mChannelName;
private int mChannelOrderNumber;
public int mPreviousPosition;
public long mPreviousStart;
public long mPreviousEnd;
public long mPreviousProgramID;
// public String mPreviousTitle;
public String mPreviousEpisode;
public String mPreviousGenre;
public Spannable mPreviousCategory;
public String mPreviousPictureCopyright;
public byte[] mPreviousPicture;
public int mNowPosition;
public long mNowStart;
public long mNowEnd;
public long mNowProgramID;
// public String mNowTitle;
public String mNowEpisode;
public String mNowGenre;
public Spannable mNowCategory;
public String mNowPictureCopyright;
public byte[] mNowPicture;
public int mNextPosition;
public long mNextStart;
public long mNextEnd;
public long mNextProgramID;
// public String mNextTitle;
public String mNextEpisode;
public String mNextGenre;
public Spannable mNextCategory;
public String mNextPictureCopyright;
public byte[] mNextPicture;
public boolean mIsComplete;
public ChannelProgramBlock() {
mIsComplete = false;
}
}
@Override
public synchronized void onLoadFinished(Loader<Cursor> loader, final Cursor c) {
Log.d("info6", "RUNNING PROGRAMS: onLoadFinished, searching programs " + System.currentTimeMillis());
if(c != null) {
SparseArrayCompat<ChannelProgramBlock> channelProgramMap = new SparseArrayCompat<ChannelProgramBlock>();
SparseArrayCompat<ChannelProgramBlock> currentProgramMap = new SparseArrayCompat<ChannelProgramBlock>();
boolean showDontWantToSee = PrefUtils.getStringValue(R.string.PREF_I_DONT_WANT_TO_SEE_FILTER_TYPE, R.string.pref_i_dont_want_to_see_filter_type_default).equals(getResources().getStringArray(R.array.pref_simple_string_value_array2)[1]);
mProgramBlockList.clear();
mCurrentViewList.clear();
mMarkingsMap.clear();
mTitleMap.clear();
mProgramIDColumn = c.getColumnIndex(TvBrowserContentProvider.KEY_ID);
mStartTimeColumn = c.getColumnIndex(TvBrowserContentProvider.DATA_KEY_STARTTIME);
mEndTimeColumn = c.getColumnIndex(TvBrowserContentProvider.DATA_KEY_ENDTIME);
mTitleColumn = c.getColumnIndex(TvBrowserContentProvider.DATA_KEY_TITLE);
mPictureColumn = c.getColumnIndex(TvBrowserContentProvider.DATA_KEY_PICTURE);
mPictureCopyrightColumn = c.getColumnIndex(TvBrowserContentProvider.DATA_KEY_PICTURE_COPYRIGHT);
mCategoryColumn = c.getColumnIndex(TvBrowserContentProvider.DATA_KEY_CATEGORIES);
mGenreColumn = c.getColumnIndex(TvBrowserContentProvider.DATA_KEY_GENRE);
mEpsiodeColumn = c.getColumnIndex(TvBrowserContentProvider.DATA_KEY_EPISODE_TITLE);
mChannelNameColumn = c.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_NAME);
mChannelIDColumn = c.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_CHANNEL_ID);
int channelOrderColumn = c.getColumnIndex(TvBrowserContentProvider.CHANNEL_KEY_ORDER_NUMBER);
int dontWantToSeeColumn = c.getColumnIndex(TvBrowserContentProvider.DATA_KEY_DONT_WANT_TO_SEE);
HashMap<String, Integer> markingColumnsMap = new HashMap<String, Integer>();
c.moveToPosition(-1);
for(String column : TvBrowserContentProvider.MARKING_COLUMNS) {
int index = c.getColumnIndex(column);
if(index >= 0) {
markingColumnsMap.put(column, index);
}
}
if(c.getCount() > 0) {
try {
while(!c.isClosed() && c.moveToNext()) {
int channelID = c.getInt(mChannelIDColumn);
ChannelProgramBlock block = channelProgramMap.get(channelID);
ArrayList<String> markedColumsList = new ArrayList<String>();
if(block == null) {
block = new ChannelProgramBlock();
channelProgramMap.put(channelID, block);
mProgramBlockList.add(block);
}
if(!block.mIsComplete) {
long startTime = c.getLong(mStartTimeColumn);
long endTime = c.getLong(mEndTimeColumn);
long programID = c.getLong(mProgramIDColumn);
String title = c.getString(mTitleColumn);
String episode = c.getString(mEpsiodeColumn);
for(String column : TvBrowserContentProvider.MARKING_COLUMNS) {
Integer value = markingColumnsMap.get(column);
if(value != null && c.getInt(value) >= 1) {
markedColumsList.add(column);
}
else if(column.equals(TvBrowserContentProvider.DATA_KEY_MARKING_MARKING) && ProgramUtils.isMarkedWithIcon(getActivity(), programID)) {
markedColumsList.add(column);
}
}
String channelName = c.getString(mChannelNameColumn);
int channelOrderNumber = c.getInt(channelOrderColumn);
String genre = null;
Spannable category = null;
String pictureCopyright = null;
byte[] picture = null;
if(showInfo) {
category = IOUtils.getInfoString(c.getInt(mCategoryColumn), getResources());
}
if(showDontWantToSee || c.getInt(dontWantToSeeColumn) == 0) {
block.mChannelID = channelID;
block.mChannelName = channelName;
block.mChannelOrderNumber = channelOrderNumber;
if(startTime <= mCurrentTime) {
if(endTime <= mCurrentTime || (endTime > mCurrentTime && mWhereClauseTime == -2)) {
block.mPreviousPosition = c.getPosition();
block.mPreviousProgramID = programID;
block.mPreviousStart = startTime;
block.mPreviousEnd = endTime;
mTitleMap.put(programID, title);
block.mPreviousEpisode = episode;
block.mPreviousGenre = genre;
block.mPreviousPicture = picture;
block.mPreviousPictureCopyright = pictureCopyright;
block.mPreviousCategory = category;
if(mWhereClauseTime == -2 && currentProgramMap.indexOfKey(channelID) < 0) {
currentProgramMap.put(channelID, block);
mCurrentViewList.add(block);
}
}
else if(startTime <= mCurrentTime && mCurrentTime < endTime) {
block.mNowPosition = c.getPosition();
block.mNowProgramID = programID;
block.mNowStart = startTime;
block.mNowEnd = endTime;
mTitleMap.put(programID, title);
block.mNowEpisode = episode;
block.mNowGenre = genre;
block.mNowPicture = picture;
block.mNowPictureCopyright = pictureCopyright;
block.mNowCategory = category;
if(currentProgramMap.indexOfKey(channelID) < 0) {
currentProgramMap.put(channelID, block);
mCurrentViewList.add(block);
}
}
}
else if(mWhereClauseTime != -2 || block.mNowPosition > 0) {
block.mNextPosition = c.getPosition();
block.mNextStart = startTime;
block.mNextEnd = endTime;
block.mNextProgramID = programID;
mTitleMap.put(programID, title);
block.mNextEpisode = episode;
block.mNextGenre = genre;
block.mNextPicture = picture;
block.mNextPictureCopyright = pictureCopyright;
block.mNextCategory = category;
block.mIsComplete = true;
if(currentProgramMap.indexOfKey(channelID) < 0) {
currentProgramMap.put(channelID, block);
mCurrentViewList.add(block);
}
}
else if(mWhereClauseTime == -2 && block.mNowPosition == 0) {
block.mNowPosition = c.getPosition();
block.mNowProgramID = programID;
block.mNowStart = startTime;
block.mNowEnd = endTime;
mTitleMap.put(programID, title);
block.mNowEpisode = episode;
block.mNowGenre = genre;
block.mNowPicture = picture;
block.mNowPictureCopyright = pictureCopyright;
block.mNowCategory = category;
if(currentProgramMap.indexOfKey(channelID) < 0) {
currentProgramMap.put(channelID, block);
mCurrentViewList.add(block);
}
}
mMarkingsMap.put(programID, IOUtils.getStringArrayFromList(markedColumsList));
markedColumsList.clear();
}
}
}
}catch(IllegalStateException e1) {}
}
IOUtils.close(c); // FIXME should be a call to an adapter's swapCursor to reuse the loader's cursor
currentProgramMap.clear();
channelProgramMap.clear();
}
Log.d("info6", "RUNNING PROGRAMS: onLoadFinished, searching programs DONE " + System.currentTimeMillis());
mRunningProgramListAdapter.notifyDataSetChanged();
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mCurrentViewList.clear();
mProgramBlockList.clear();
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
Long test = (Long)v.getTag();
if(test != null) {
mContextProgramID = test;
mContextView = v;
UiUtils.createContextMenu(getActivity(), menu, mContextProgramID);
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
if(getUserVisibleHint() && mContextProgramID >= 0) {
UiUtils.handleContextMenuSelection(getActivity(), item, mContextProgramID, mContextView, getActivity().getCurrentFocus());
mContextProgramID = -1;
return true;
}
return false;
}
private void setDividerSize(String size) {
getListView().setDividerHeight(UiUtils.convertDpToPixel(Integer.parseInt(size), getResources()));
}
private void insertTimeExtra(final Integer time) {
boolean timeExtraFound = false;
boolean timeAvailable = false;
int insertIndex = 1;
if(mTimeBar.getChildCount() > 1) {
final Button next = (Button)((ViewGroup)((ViewGroup)getView().getParent()).getParent()).findViewById(R.id.button_after1);
if(next != null && next.getVisibility() == View.VISIBLE) {
if(mTimeBar.getChildCount() > 2) {
insertIndex = 2;
}
}
for(int i = insertIndex; i < mTimeBar.getChildCount(); i++) {
Button button = (Button)mTimeBar.getChildAt(i);
if(button.getTag(R.id.time_extra) != null) {
timeExtraFound = true;
} else if(time.equals(mTimeBar.getChildAt(i).getTag())) {
timeAvailable = true;
}
}
}
if(!timeExtraFound && !timeAvailable) {
mTimeBar.addView(mTimeExtra, insertIndex);
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(!isDetached() && getActivity() != null) {
if(getString(R.string.PREF_RUNNING_DIVIDER_SIZE).equals(key)) {
setDividerSize(PrefUtils.getStringValue(R.string.PREF_RUNNING_DIVIDER_SIZE, R.string.pref_running_divider_size_default));
}
else if(getString(R.string.PREF_RUNNING_PROGRAMS_SHOW_TIME_PICK_BUTTON_ONLY_WHEN_NEEDED).equals(key)) {
boolean enabled = sharedPreferences.getBoolean(key, getResources().getBoolean(R.bool.pref_running_programs_show_time_pick_button_only_when_needed_default));
if(enabled && !mTimeExtra.getTag().equals(mWhereClauseTime)) {
mTimeBar.removeView(mTimeExtra);
}
else {
insertTimeExtra(mWhereClauseTime);
}
}
else if(mListView != null && (getString(R.string.PREF_COLOR_SEPARATOR_LINE).equals(key) || getString(R.string.PREF_COLOR_SEPARATOR_SPACE).equals(key))) {
final Drawable separator = mListView.getDivider();
if(separator instanceof SeparatorDrawable) {
((SeparatorDrawable) separator).updateColors(getActivity());
}
}
}
}
public void selectTime(int time) {
if(time == Integer.MAX_VALUE) {
time = -1;
}
boolean found = false;
for(int i = 0; i < mTimeBar.getChildCount(); i++) {
View button = mTimeBar.getChildAt(i);
if(button.getTag().equals(time - 1)) {
selectButton((Button)button);
found = true;
break;
}
}
if(!found && time == -1) {
setWhereClauseTime(-2);
}
else if(time > 0) {
time--;
mTimeExtra.setTag(time);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, time/60);
cal.set(Calendar.MINUTE, time%60);
mLastExtraClick = System.currentTimeMillis();
mTimeExtra.setText(DateFormat.getTimeFormat(getActivity().getApplicationContext()).format(cal.getTime()));
insertTimeExtra(time);
setWhereClauseTime(mTimeExtra.getTag());
if(isViewNotVisible(mTimeExtra)) {
((HorizontalScrollView)mTimeBar.getParent()).scrollTo(mTimeExtra.getLeft(), mTimeExtra.getTop());
}
}
}
private void selectButton(Button button) {
if(button != null) {
button.performClick();
if(isViewNotVisible(button)) {
((HorizontalScrollView)mTimeBar.getParent()).scrollTo(button.getLeft(), button.getTop());
}
}
}
private boolean isViewNotVisible(View view) {
Rect scrollBounds = new Rect();
((View)mTimeBar.getParent()).getDrawingRect(scrollBounds);
float left = view.getX();
float right = left + view.getWidth();
if (scrollBounds.left < left && scrollBounds.right > right) {
return false;
} else {
return true;
}
}
}