165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko/* 265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Copyright (C) 2016 The Android Open Source Project 365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * 465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License"); 565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * you may not use this file except in compliance with the License. 665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * You may obtain a copy of the License at 765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * 865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * http://www.apache.org/licenses/LICENSE-2.0 965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * 1065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Unless required by applicable law or agreed to in writing, software 1165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS, 1265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * See the License for the specific language governing permissions and 1465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * limitations under the License 1565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 1665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 1765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkopackage com.android.tv.dvr.ui.list; 1865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 19d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.animation.Animator; 20d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.animation.AnimatorListenerAdapter; 2165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.animation.ValueAnimator; 22d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.annotation.TargetApi; 2365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.app.Activity; 2465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.content.Context; 25d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.content.res.Resources; 26d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.os.Build; 27d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.support.annotation.IntDef; 2865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.v17.leanback.widget.RowPresenter; 2965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.text.TextUtils; 3065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.view.LayoutInflater; 3165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.view.View; 32d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.view.View.OnFocusChangeListener; 3365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.view.ViewGroup; 3465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.view.animation.DecelerateInterpolator; 3565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.widget.ImageView; 3665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.widget.LinearLayout; 3765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.widget.RelativeLayout; 3865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.widget.TextView; 3965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.widget.Toast; 4065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 4165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.R; 4265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.TvApplication; 43d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.common.SoftPreconditions; 4465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.data.Channel; 456ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.dialog.HalfSizedDialogFragment; 46d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.dvr.DvrManager; 4765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.dvr.DvrScheduleManager; 486ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.dvr.data.ScheduledRecording; 49d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.dvr.ui.DvrStopRecordingFragment; 506ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.dvr.ui.DvrUiHelper; 51d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.util.ToastUtils; 5265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.util.Utils; 5365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 54d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport java.lang.annotation.Retention; 55d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport java.lang.annotation.RetentionPolicy; 5665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport java.util.List; 5765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 5865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko/** 5965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * A RowPresenter for {@link ScheduleRow}. 6065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 61d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko@TargetApi(Build.VERSION_CODES.N) 626ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoclass ScheduleRowPresenter extends RowPresenter { 63d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private static final String TAG = "ScheduleRowPresenter"; 64d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 65d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Retention(RetentionPolicy.SOURCE) 66d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @IntDef({ACTION_START_RECORDING, ACTION_STOP_RECORDING, ACTION_CREATE_SCHEDULE, 67d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko ACTION_REMOVE_SCHEDULE}) 68d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public @interface ScheduleRowAction {} 69d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko /** An action to start recording. */ 70d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public static final int ACTION_START_RECORDING = 1; 71d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko /** An action to stop recording. */ 72d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public static final int ACTION_STOP_RECORDING = 2; 73d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko /** An action to create schedule for the row. */ 74d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public static final int ACTION_CREATE_SCHEDULE = 3; 75d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko /** An action to remove the schedule. */ 76d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public static final int ACTION_REMOVE_SCHEDULE = 4; 77d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 78d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private final Context mContext; 79d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private final DvrManager mDvrManager; 80d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private final DvrScheduleManager mDvrScheduleManager; 8165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 8265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private final String mTunerConflictWillNotBeRecordedInfo; 8365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private final String mTunerConflictWillBePartiallyRecordedInfo; 84d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private final int mAnimationDuration; 85d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 86d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private int mLastFocusedViewId; 8765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 8865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 8965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * A ViewHolder for {@link ScheduleRow} 9065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 9165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public static class ScheduleRowViewHolder extends RowPresenter.ViewHolder { 92d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private ScheduleRowPresenter mPresenter; 93d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @ScheduleRowAction private int[] mActions; 9465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private boolean mLtr; 9565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private LinearLayout mInfoContainer; 96d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // The first action is on the right of the second action. 97d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private RelativeLayout mSecondActionContainer; 98d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private RelativeLayout mFirstActionContainer; 9965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private View mSelectorView; 10065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private TextView mTimeView; 10165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private TextView mProgramTitleView; 10265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private TextView mInfoSeparatorView; 10365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private TextView mChannelNameView; 10465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private TextView mConflictInfoView; 105d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private ImageView mSecondActionView; 106d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private ImageView mFirstActionView; 107d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 108d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private Runnable mPendingAnimationRunnable; 109d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 110d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private final int mSelectorTranslationDelta; 111d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private final int mSelectorWidthDelta; 112d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private final int mInfoContainerTargetWidthWithNoAction; 113d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private final int mInfoContainerTargetWidthWithOneAction; 114d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private final int mInfoContainerTargetWidthWithTwoAction; 115d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private final int mRoundRectRadius; 116d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 117d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private final OnFocusChangeListener mOnFocusChangeListener = 118d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko new View.OnFocusChangeListener() { 119d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 120d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void onFocusChange(View view, boolean focused) { 121d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko view.post(new Runnable() { 122d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 123d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void run() { 124d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (view.isFocused()) { 125d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mPresenter.mLastFocusedViewId = view.getId(); 126d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 127d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko updateSelector(); 128d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 129d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko }); 130d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 131d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko }; 13265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 133d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public ScheduleRowViewHolder(View view, ScheduleRowPresenter presenter) { 13465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko super(view); 135d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mPresenter = presenter; 13665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mLtr = view.getContext().getResources().getConfiguration().getLayoutDirection() 13765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko == View.LAYOUT_DIRECTION_LTR; 13865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mInfoContainer = (LinearLayout) view.findViewById(R.id.info_container); 139d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mSecondActionContainer = (RelativeLayout) view.findViewById( 140d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko R.id.action_second_container); 141d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mSecondActionView = (ImageView) view.findViewById(R.id.action_second); 142d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mFirstActionContainer = (RelativeLayout) view.findViewById( 143d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko R.id.action_first_container); 144d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mFirstActionView = (ImageView) view.findViewById(R.id.action_first); 14565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSelectorView = view.findViewById(R.id.selector); 14665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mTimeView = (TextView) view.findViewById(R.id.time); 14765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mProgramTitleView = (TextView) view.findViewById(R.id.program_title); 14865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mInfoSeparatorView = (TextView) view.findViewById(R.id.info_separator); 14965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mChannelNameView = (TextView) view.findViewById(R.id.channel_name); 15065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mConflictInfoView = (TextView) view.findViewById(R.id.conflict_info); 151d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko Resources res = view.getResources(); 152d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mSelectorTranslationDelta = 153d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko res.getDimensionPixelSize(R.dimen.dvr_schedules_item_section_margin) 154d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko - res.getDimensionPixelSize(R.dimen.dvr_schedules_item_focus_translation_delta); 155d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mSelectorWidthDelta = res.getDimensionPixelSize( 156d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko R.dimen.dvr_schedules_item_focus_width_delta); 157d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mRoundRectRadius = res.getDimensionPixelSize(R.dimen.dvr_schedules_selector_radius); 158d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko int fullWidth = res.getDimensionPixelSize( 159d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko R.dimen.dvr_schedules_item_width) 160d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko - 2 * res.getDimensionPixelSize(R.dimen.dvr_schedules_layout_padding); 161d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mInfoContainerTargetWidthWithNoAction = fullWidth + 2 * mRoundRectRadius; 162d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mInfoContainerTargetWidthWithOneAction = fullWidth 163d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko - res.getDimensionPixelSize(R.dimen.dvr_schedules_item_section_margin) 164d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko - res.getDimensionPixelSize(R.dimen.dvr_schedules_item_delete_width) 165d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko + mRoundRectRadius + mSelectorWidthDelta; 166d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mInfoContainerTargetWidthWithTwoAction = mInfoContainerTargetWidthWithOneAction 167d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko - res.getDimensionPixelSize(R.dimen.dvr_schedules_item_section_margin) 168d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko - res.getDimensionPixelSize(R.dimen.dvr_schedules_item_icon_size); 169d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 170d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mInfoContainer.setOnFocusChangeListener(mOnFocusChangeListener); 171d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mFirstActionContainer.setOnFocusChangeListener(mOnFocusChangeListener); 172d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mSecondActionContainer.setOnFocusChangeListener(mOnFocusChangeListener); 17365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 17465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 17565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 17665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Returns time view. 17765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 17865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public TextView getTimeView() { 17965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return mTimeView; 18065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 18165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 18265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 18365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Returns title view. 18465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 18565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public TextView getProgramTitleView() { 18665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return mProgramTitleView; 18765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 18865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 18965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private void updateSelector() { 19065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko int animationDuration = mSelectorView.getResources().getInteger( 19165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko android.R.integer.config_shortAnimTime); 19265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko DecelerateInterpolator interpolator = new DecelerateInterpolator(); 19365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 194d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mInfoContainer.isFocused() || mSecondActionContainer.isFocused() 195d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko || mFirstActionContainer.isFocused()) { 19665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko final ViewGroup.LayoutParams lp = mSelectorView.getLayoutParams(); 19765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko final int targetWidth; 19865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (mInfoContainer.isFocused()) { 199d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // Use actions to check the visibility of the actions instead of calling 200d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // View.getVisibility() because the view could be on the hiding animation. 201d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mActions == null || mActions.length == 0) { 202d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko targetWidth = mInfoContainerTargetWidthWithNoAction; 203d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else if (mActions.length == 1) { 204d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko targetWidth = mInfoContainerTargetWidthWithOneAction; 20565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 206d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko targetWidth = mInfoContainerTargetWidthWithTwoAction; 20765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 208d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else if (mSecondActionContainer.isFocused()) { 209d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko targetWidth = Math.max(mSecondActionContainer.getWidth(), 2 * mRoundRectRadius); 21065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 211d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko targetWidth = mFirstActionContainer.getWidth() + mRoundRectRadius 212d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko + mSelectorTranslationDelta; 21365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 21465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 21565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko float targetTranslationX; 21665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (mInfoContainer.isFocused()) { 217d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko targetTranslationX = mLtr ? mInfoContainer.getLeft() - mRoundRectRadius 21865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko - mSelectorView.getLeft() : 219d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mInfoContainer.getRight() + mRoundRectRadius - mSelectorView.getRight(); 220d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else if (mSecondActionContainer.isFocused()) { 221d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mSecondActionContainer.getWidth() > 2 * mRoundRectRadius) { 222d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko targetTranslationX = mLtr ? mSecondActionContainer.getLeft() - 22365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSelectorView.getLeft() 224d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko : mSecondActionContainer.getRight() - mSelectorView.getRight(); 22565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 226d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko targetTranslationX = mLtr ? mSecondActionContainer.getLeft() - 227d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko (mRoundRectRadius - mSecondActionContainer.getWidth() / 2) - 22865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSelectorView.getLeft() 229d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko : mSecondActionContainer.getRight() + 230d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko (mRoundRectRadius - mSecondActionContainer.getWidth() / 2) - 23165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSelectorView.getRight(); 23265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 23365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 234d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko targetTranslationX = mLtr ? mFirstActionContainer.getLeft() 235d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko - mSelectorTranslationDelta - mSelectorView.getLeft() 236d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko : mFirstActionContainer.getRight() + mSelectorTranslationDelta 237d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko - mSelectorView.getRight(); 23865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 23965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 24065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (mSelectorView.getAlpha() == 0) { 24165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSelectorView.setTranslationX(targetTranslationX); 24265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko lp.width = targetWidth; 24365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSelectorView.requestLayout(); 24465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 24565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 24665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko // animate the selector in and to the proper width and translation X. 24765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko final float deltaWidth = lp.width - targetWidth; 24865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSelectorView.animate().cancel(); 24965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSelectorView.animate().translationX(targetTranslationX).alpha(1f) 25065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko .setUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 25165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 25265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void onAnimationUpdate(ValueAnimator animation) { 25365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko // Set width to the proper width for this animation step. 25465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko lp.width = targetWidth + Math.round( 25565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko deltaWidth * (1f - animation.getAnimatedFraction())); 25665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSelectorView.requestLayout(); 25765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 25865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko }).setDuration(animationDuration).setInterpolator(interpolator).start(); 259d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mPendingAnimationRunnable != null) { 260d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mPendingAnimationRunnable.run(); 261d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mPendingAnimationRunnable = null; 262d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 26365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 26465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSelectorView.animate().cancel(); 26565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSelectorView.animate().alpha(0f).setDuration(animationDuration) 266d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setInterpolator(interpolator).setUpdateListener(null).start(); 26765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 26865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 26965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 27065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 27165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Grey out the information body. 27265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 27365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void greyOutInfo() { 27465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mTimeView.setTextColor(mInfoContainer.getResources().getColor(R.color 27565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko .dvr_schedules_item_info_grey, null)); 27665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mProgramTitleView.setTextColor(mInfoContainer.getResources().getColor(R.color 27765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko .dvr_schedules_item_info_grey, null)); 27865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mInfoSeparatorView.setTextColor(mInfoContainer.getResources().getColor(R.color 27965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko .dvr_schedules_item_info_grey, null)); 28065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mChannelNameView.setTextColor(mInfoContainer.getResources().getColor(R.color 28165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko .dvr_schedules_item_info_grey, null)); 28265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mConflictInfoView.setTextColor(mInfoContainer.getResources().getColor(R.color 28365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko .dvr_schedules_item_info_grey, null)); 28465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 28565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 28665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 28765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Reverse grey out operation. 28865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 28965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void whiteBackInfo() { 29065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mTimeView.setTextColor(mInfoContainer.getResources().getColor(R.color 29165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko .dvr_schedules_item_info, null)); 29265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mProgramTitleView.setTextColor(mInfoContainer.getResources().getColor(R.color 29365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko .dvr_schedules_item_main, null)); 29465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mInfoSeparatorView.setTextColor(mInfoContainer.getResources().getColor(R.color 29565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko .dvr_schedules_item_info, null)); 29665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mChannelNameView.setTextColor(mInfoContainer.getResources().getColor(R.color 29765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko .dvr_schedules_item_info, null)); 29865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mConflictInfoView.setTextColor(mInfoContainer.getResources().getColor(R.color 29965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko .dvr_schedules_item_info, null)); 30065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 30165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 30265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 30365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public ScheduleRowPresenter(Context context) { 30465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko setHeaderPresenter(null); 30565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko setSelectEffectEnabled(false); 30665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mContext = context; 307d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrManager = TvApplication.getSingletons(context).getDvrManager(); 308d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrScheduleManager = TvApplication.getSingletons(context).getDvrScheduleManager(); 30965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mTunerConflictWillNotBeRecordedInfo = mContext.getString( 31065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko R.string.dvr_schedules_tuner_conflict_will_not_be_recorded_info); 31165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mTunerConflictWillBePartiallyRecordedInfo = mContext.getString( 31265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko R.string.dvr_schedules_tuner_conflict_will_be_partially_recorded); 313d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mAnimationDuration = mContext.getResources().getInteger( 314d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko android.R.integer.config_shortAnimTime); 31565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 31665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 31765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 31865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public ViewHolder createRowViewHolder(ViewGroup parent) { 319d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return onGetScheduleRowViewHolder(LayoutInflater.from(mContext) 320d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .inflate(R.layout.dvr_schedules_item, parent, false)); 32165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 32265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 32365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 32465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Returns context. 32565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 32665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko protected Context getContext() { 32765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return mContext; 32865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 32965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 33065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 331d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Returns DVR manager. 33265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 333d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected DvrManager getDvrManager() { 334d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return mDvrManager; 33565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 33665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 33765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 33865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko protected void onBindRowViewHolder(RowPresenter.ViewHolder vh, Object item) { 33965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko super.onBindRowViewHolder(vh, item); 34065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko ScheduleRowViewHolder viewHolder = (ScheduleRowViewHolder) vh; 341d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko ScheduleRow row = (ScheduleRow) item; 342d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @ScheduleRowAction int[] actions = getAvailableActions(row); 343d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mActions = actions; 34465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko viewHolder.mInfoContainer.setOnClickListener(new View.OnClickListener() { 34565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 34665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void onClick(View view) { 3476ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (isInfoClickable(row)) { 3486ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko onInfoClicked(row); 3496ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 35065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 35165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko }); 35265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 353d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mFirstActionContainer.setOnClickListener(new View.OnClickListener() { 35465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 35565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void onClick(View view) { 356d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko onActionClicked(actions[0], row); 35765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 35865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko }); 35965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 360d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mSecondActionContainer.setOnClickListener(new View.OnClickListener() { 36165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 36265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void onClick(View view) { 363d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko onActionClicked(actions[1], row); 36465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 36565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko }); 36665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 367d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mTimeView.setText(onGetRecordingTimeText(row)); 368d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko String programInfoText = onGetProgramInfoText(row); 36965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (TextUtils.isEmpty(programInfoText)) { 3706ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko int durationMins = Math.max(1, Utils.getRoundOffMinsFromMs(row.getDuration())); 37165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko programInfoText = mContext.getResources().getQuantityString( 37265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko R.plurals.dvr_schedules_recording_duration, durationMins, durationMins); 37365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 374d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko String channelName = getChannelNameText(row); 37565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko viewHolder.mProgramTitleView.setText(programInfoText); 37665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko viewHolder.mInfoSeparatorView.setVisibility((!TextUtils.isEmpty(programInfoText) 37765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko && !TextUtils.isEmpty(channelName)) ? View.VISIBLE : View.GONE); 37865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko viewHolder.mChannelNameView.setText(channelName); 379d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (actions != null) { 380d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko switch (actions.length) { 381d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case 2: 382d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mSecondActionView.setImageResource(getImageForAction(actions[1])); 383d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // pass through 384d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case 1: 385d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mFirstActionView.setImageResource(getImageForAction(actions[0])); 386d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko break; 38765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 388d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 389d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mDvrManager.isConflicting(row.getSchedule())) { 390d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko String conflictInfo; 391d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mDvrScheduleManager.isPartiallyConflicting(row.getSchedule())) { 392d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko conflictInfo = mTunerConflictWillBePartiallyRecordedInfo; 39365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 394d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko conflictInfo = mTunerConflictWillNotBeRecordedInfo; 39565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 396d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mConflictInfoView.setText(conflictInfo); 397d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mConflictInfoView.setVisibility(View.VISIBLE); 398d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 399d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mConflictInfoView.setVisibility(View.GONE); 400d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 401d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (shouldBeGrayedOut(row)) { 402d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.greyOutInfo(); 403d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 404d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.whiteBackInfo(); 405d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 4066ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko viewHolder.mInfoContainer.setFocusable(isInfoClickable(row)); 407d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko updateActionContainer(viewHolder, viewHolder.isSelected()); 408d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 409d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 410d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private int getImageForAction(@ScheduleRowAction int action) { 411d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko switch (action) { 412d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case ACTION_START_RECORDING: 413d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return R.drawable.ic_record_start; 414d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case ACTION_STOP_RECORDING: 415d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return R.drawable.ic_record_stop; 416d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case ACTION_CREATE_SCHEDULE: 417d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return R.drawable.ic_scheduled_recording; 418d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case ACTION_REMOVE_SCHEDULE: 419d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return R.drawable.ic_dvr_cancel; 420d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko default: 421d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return 0; 42265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 42365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 42465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 42565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 42665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Returns view holder for schedule row. 42765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 42865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko protected ScheduleRowViewHolder onGetScheduleRowViewHolder(View view) { 429d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return new ScheduleRowViewHolder(view, this); 43065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 43165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 43265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 43365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Returns time text for time view from scheduled recording. 43465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 435d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected String onGetRecordingTimeText(ScheduleRow row) { 436d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return Utils.getDurationString(mContext, row.getStartTimeMs(), row.getEndTimeMs(), true, 437d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko false, true, 0); 43865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 43965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 44065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 44165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Returns program info text for program title view. 44265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 443d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected String onGetProgramInfoText(ScheduleRow row) { 444d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return row.getProgramTitleWithEpisodeNumber(mContext); 44565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 44665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 447d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private String getChannelNameText(ScheduleRow row) { 448d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko Channel channel = TvApplication.getSingletons(mContext).getChannelDataManager() 449d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .getChannel(row.getChannelId()); 450d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return channel == null ? null : 451d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko TextUtils.isEmpty(channel.getDisplayName()) ? channel.getDisplayNumber() : 452d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko channel.getDisplayName().trim() + " " + channel.getDisplayNumber(); 45365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 45465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 45565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 456d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Called when user click Info in {@link ScheduleRow}. 45765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 4586ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko protected void onInfoClicked(ScheduleRow row) { 4596ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko DvrUiHelper.startDetailsActivity((Activity) mContext, row.getSchedule(), null, true); 4606ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 4616ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko 4626ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko private boolean isInfoClickable(ScheduleRow row) { 4636ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko return row.getSchedule() != null 4646ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko && (row.getSchedule().isNotStarted() || row.getSchedule().isInProgress()); 46565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 46665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 46765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 468d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Called when the button in a row is clicked. 46965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 470d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected void onActionClicked(@ScheduleRowAction final int action, ScheduleRow row) { 471d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko switch (action) { 472d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case ACTION_START_RECORDING: 473d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko onStartRecording(row); 474d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko break; 475d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case ACTION_STOP_RECORDING: 476d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko onStopRecording(row); 477d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko break; 478d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case ACTION_CREATE_SCHEDULE: 479d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko onCreateSchedule(row); 480d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko break; 481d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case ACTION_REMOVE_SCHEDULE: 482d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko onRemoveSchedule(row); 483d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko break; 48465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 48565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 48665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 48765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 488d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Action handler for {@link #ACTION_START_RECORDING}. 48965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 490d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected void onStartRecording(ScheduleRow row) { 491d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko ScheduledRecording schedule = row.getSchedule(); 492d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (schedule == null) { 493d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // This row has been deleted. 49465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 49565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 496d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // Checks if there are current recordings that will be stopped by schedule this program. 497d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // If so, shows confirmation dialog to users. 498d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko List<ScheduledRecording> conflictSchedules = mDvrScheduleManager.getConflictingSchedules( 499d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko schedule.getChannelId(), System.currentTimeMillis(), schedule.getEndTimeMs()); 500d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko for (int i = conflictSchedules.size() - 1; i >= 0; i--) { 501d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko ScheduledRecording conflictSchedule = conflictSchedules.get(i); 502d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (conflictSchedule.isInProgress()) { 503d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko DvrUiHelper.showStopRecordingDialog((Activity) mContext, 504d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko conflictSchedule.getChannelId(), 505d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko DvrStopRecordingFragment.REASON_ON_CONFLICT, 506d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko new HalfSizedDialogFragment.OnActionClickListener() { 507d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 508d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void onActionClick(long actionId) { 509d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (actionId == DvrStopRecordingFragment.ACTION_STOP) { 510d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko onStartRecordingInternal(row); 511d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 512d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 513d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko }); 514d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return; 515d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 51665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 517d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko onStartRecordingInternal(row); 51865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 51965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 520d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private void onStartRecordingInternal(ScheduleRow row) { 521d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (row.isOnAir() && !row.isRecordingInProgress() && !row.isStartRecordingRequested()) { 522d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko row.setStartRecordingRequested(true); 523d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (row.isRecordingNotStarted()) { 524d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrManager.setHighestPriority(row.getSchedule()); 525d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else if (row.isRecordingFinished()) { 526d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrManager.addSchedule(ScheduledRecording.buildFrom(row.getSchedule()) 527d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setId(ScheduledRecording.ID_NOT_SET) 528d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setState(ScheduledRecording.STATE_RECORDING_NOT_STARTED) 529d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setPriority(mDvrManager.suggestHighestPriority(row.getSchedule())) 530d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .build()); 531d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 532d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko SoftPreconditions.checkState(false, TAG, "Invalid row state to start recording: " 533d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko + row); 534d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return; 535d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 536d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko String msg = mContext.getString(R.string.dvr_msg_current_program_scheduled, 537d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko row.getSchedule().getProgramTitle(), 538d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko Utils.toTimeString(row.getEndTimeMs(), false)); 539d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko ToastUtils.show(mContext, msg, Toast.LENGTH_SHORT); 54065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 54165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 54265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 54365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 544d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Action handler for {@link #ACTION_STOP_RECORDING}. 54565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 546d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected void onStopRecording(ScheduleRow row) { 547d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (row.getSchedule() == null) { 548d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // This row has been deleted. 549d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return; 550d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 5516ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (row.isRecordingInProgress() && !row.isStopRecordingRequested()) { 552d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko row.setStopRecordingRequested(true); 553d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrManager.stopRecording(row.getSchedule()); 554d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko CharSequence deletedInfo = onGetProgramInfoText(row); 555d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (TextUtils.isEmpty(deletedInfo)) { 556d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko deletedInfo = getChannelNameText(row); 55765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 558d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko ToastUtils.show(mContext, mContext.getResources() 559d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .getString(R.string.dvr_schedules_deletion_info, deletedInfo), 560d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko Toast.LENGTH_SHORT); 56165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 56265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 56365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 56465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 565d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Action handler for {@link #ACTION_CREATE_SCHEDULE}. 56665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 567d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected void onCreateSchedule(ScheduleRow row) { 568d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (row.getSchedule() == null) { 569d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // This row has been deleted. 570d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return; 571d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 572d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (!row.isOnAir()) { 573d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (row.isScheduleCanceled()) { 574d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrManager.updateScheduledRecording(ScheduledRecording.buildFrom(row.getSchedule()) 575d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setState(ScheduledRecording.STATE_RECORDING_NOT_STARTED) 576d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setPriority(mDvrManager.suggestHighestPriority(row.getSchedule())) 577d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .build()); 578d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko String msg = mContext.getString(R.string.dvr_msg_program_scheduled, 579d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko row.getSchedule().getProgramTitle()); 580d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko ToastUtils.show(mContext, msg, Toast.LENGTH_SHORT); 581d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else if (mDvrManager.isConflicting(row.getSchedule())) { 582d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrManager.setHighestPriority(row.getSchedule()); 583d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 584d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 58565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 58665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 58765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 588d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Action handler for {@link #ACTION_REMOVE_SCHEDULE}. 58965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 590d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected void onRemoveSchedule(ScheduleRow row) { 591d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (row.getSchedule() == null) { 592d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // This row has been deleted. 59365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 59465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 595d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko CharSequence deletedInfo = null; 596d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (row.isOnAir()) { 597d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (row.isRecordingNotStarted()) { 598d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko deletedInfo = getDeletedInfo(row); 599d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrManager.removeScheduledRecording(row.getSchedule()); 600d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 601d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 602d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mDvrManager.isConflicting(row.getSchedule()) 603d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko && !shouldKeepScheduleAfterRemoving()) { 604d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko deletedInfo = getDeletedInfo(row); 605d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrManager.removeScheduledRecording(row.getSchedule()); 606d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else if (row.isRecordingNotStarted()) { 607d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko deletedInfo = getDeletedInfo(row); 608d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrManager.updateScheduledRecording(ScheduledRecording.buildFrom(row.getSchedule()) 609d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setState(ScheduledRecording.STATE_RECORDING_CANCELED) 610d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .build()); 611d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 61265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 613d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (deletedInfo != null) { 614d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko ToastUtils.show(mContext, mContext.getResources() 615d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .getString(R.string.dvr_schedules_deletion_info, deletedInfo), 616d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko Toast.LENGTH_SHORT); 61765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 61865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 61965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 620d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private CharSequence getDeletedInfo(ScheduleRow row) { 621d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko CharSequence deletedInfo = onGetProgramInfoText(row); 622d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (TextUtils.isEmpty(deletedInfo)) { 623d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return getChannelNameText(row); 624d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 625d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return deletedInfo; 62665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 62765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 628d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 629d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected void onRowViewSelected(ViewHolder vh, boolean selected) { 630d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko super.onRowViewSelected(vh, selected); 631d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko updateActionContainer(vh, selected); 63265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 63365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 63465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 635d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Internal method for onRowViewSelected, can be customized by subclass. 63665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 637d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private void updateActionContainer(ViewHolder vh, boolean selected) { 638d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko ScheduleRowViewHolder viewHolder = (ScheduleRowViewHolder) vh; 639d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mSecondActionContainer.animate().setListener(null).cancel(); 640d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mFirstActionContainer.animate().setListener(null).cancel(); 641d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (selected && viewHolder.mActions != null) { 642d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko switch (viewHolder.mActions.length) { 643d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case 2: 644d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko prepareShowActionView(viewHolder.mSecondActionContainer); 645d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko prepareShowActionView(viewHolder.mFirstActionContainer); 646d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mPendingAnimationRunnable = new Runnable() { 647d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 648d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void run() { 649d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko showActionView(viewHolder.mSecondActionContainer); 650d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko showActionView(viewHolder.mFirstActionContainer); 651d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 652d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko }; 653d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko break; 654d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case 1: 655d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko prepareShowActionView(viewHolder.mFirstActionContainer); 656d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mPendingAnimationRunnable = new Runnable() { 657d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 658d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void run() { 659d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko hideActionView(viewHolder.mSecondActionContainer, View.GONE); 660d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko showActionView(viewHolder.mFirstActionContainer); 661d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 662d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko }; 663d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mLastFocusedViewId == R.id.action_second_container) { 664d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mLastFocusedViewId = R.id.info_container; 665d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 666d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko break; 667d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko case 0: 668d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko default: 669d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mPendingAnimationRunnable = new Runnable() { 670d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 671d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void run() { 672d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko hideActionView(viewHolder.mSecondActionContainer, View.GONE); 673d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko hideActionView(viewHolder.mFirstActionContainer, View.GONE); 674d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 675d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko }; 6766ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko mLastFocusedViewId = R.id.info_container; 6776ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko SoftPreconditions.checkState(viewHolder.mInfoContainer.isFocusable(), TAG, 6786ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko "No focusable view in this row: " + viewHolder); 679d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko break; 680d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 681d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko View view = viewHolder.view.findViewById(mLastFocusedViewId); 682d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (view != null && view.getVisibility() == View.VISIBLE) { 683d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // When the row is selected, information container gets the initial focus. 684d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // To give the focus to the same control as the previous row, we need to call 685d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // requestFocus() explicitly. 686d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (view.hasFocus()) { 687d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mPendingAnimationRunnable.run(); 6886ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } else if (view.isFocusable()){ 689721bd0da688cd552737fbb753a00597f95103b95Adrian Roos view.requestFocus(); 6906ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } else { 6916ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko viewHolder.view.requestFocus(); 69265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 69365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 694d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 695d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko viewHolder.mPendingAnimationRunnable = null; 696d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko hideActionView(viewHolder.mFirstActionContainer, View.GONE); 697d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko hideActionView(viewHolder.mSecondActionContainer, View.GONE); 698d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 699d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 700d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 701d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private void prepareShowActionView(View view) { 702d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (view.getVisibility() != View.VISIBLE) { 703d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko view.setAlpha(0.0f); 70465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 705d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko view.setVisibility(View.VISIBLE); 70665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 70765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 70865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 709d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Add animation when view is visible. 71065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 711d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private void showActionView(View view) { 712d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko view.animate().alpha(1.0f).setInterpolator(new DecelerateInterpolator()) 713d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setDuration(mAnimationDuration).start(); 714d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 71565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 716d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko /** 717d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Add animation when view change to invisible. 718d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko */ 719d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko private void hideActionView(View view, int visibility) { 720d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (view.getVisibility() != View.VISIBLE) { 721d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (view.getVisibility() != visibility) { 722d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko view.setVisibility(visibility); 72365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 724d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return; 72565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 726d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko view.animate().alpha(0.0f).setInterpolator(new DecelerateInterpolator()) 727d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setDuration(mAnimationDuration) 728d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko .setListener(new AnimatorListenerAdapter() { 729d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @Override 730d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko public void onAnimationEnd(Animator animation) { 731d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko view.setVisibility(visibility); 732d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko view.animate().setListener(null); 733d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 734d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko }).start(); 73565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 73665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 73765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 738d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Returns the available actions according to the row's state. It should be the reverse order 739d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * with that in the screen. 74065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 741d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko @ScheduleRowAction 742d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected int[] getAvailableActions(ScheduleRow row) { 743d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (row.getSchedule() != null) { 7446ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (row.isRecordingInProgress()) { 7456ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko return new int[]{ACTION_STOP_RECORDING}; 7466ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } else if (row.isOnAir()) { 7476ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (row.isRecordingNotStarted()) { 748d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (canResolveConflict()) { 749d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko // The "START" action can change the conflict states. 750d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return new int[] {ACTION_REMOVE_SCHEDULE, ACTION_START_RECORDING}; 751d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 752d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return new int[] {ACTION_REMOVE_SCHEDULE}; 753d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 754d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else if (row.isRecordingFinished()) { 755d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return new int[] {ACTION_START_RECORDING}; 756d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 757d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko SoftPreconditions.checkState(false, TAG, "Invalid row state in checking the" 758d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko + " available actions(on air): " + row); 759d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 760d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 761d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (row.isScheduleCanceled()) { 762d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return new int[] {ACTION_CREATE_SCHEDULE}; 763d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else if (mDvrManager.isConflicting(row.getSchedule()) && canResolveConflict()) { 764d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return new int[] {ACTION_REMOVE_SCHEDULE, ACTION_CREATE_SCHEDULE}; 765d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else if (row.isRecordingNotStarted()) { 766d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return new int[] {ACTION_REMOVE_SCHEDULE}; 767d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } else { 768d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko SoftPreconditions.checkState(false, TAG, "Invalid row state in checking the" 769d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko + " available actions(future schedule): " + row); 770d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 771d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 772d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 773d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return null; 77465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 77565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 77665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 777d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Check if the conflict can be resolved in this screen. 77865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 779d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected boolean canResolveConflict() { 780d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return true; 78165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 78265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 78365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 784d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Check if the schedule should be kept after removing it. 78565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 786d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected boolean shouldKeepScheduleAfterRemoving() { 787d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return false; 78865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 78965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 79065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 791d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko * Checks if the row should be grayed out. 79265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 793d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko protected boolean shouldBeGrayedOut(ScheduleRow row) { 794d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return row.getSchedule() == null 795d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko || (row.isOnAir() && !row.isRecordingInProgress()) 796d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko || mDvrManager.isConflicting(row.getSchedule()) 797d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko || row.isScheduleCanceled(); 79865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 79965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko} 800