Exemplo n.º 1
0
        protected void UpdatePrograms()
        {
            UpdateGuiProperties();
            _programsList.Clear();
            IChannel channel = CurrentChannel;

            if (channel != null)
            {
                if (_tvHandler.ProgramInfo.GetPrograms(channel, DateTime.Now.AddHours(-2), DateTime.Now.AddHours(24), out _programs))
                {
                    foreach (IProgram program in _programs)
                    {
                        // Use local variable, otherwise delegate argument is not fixed
                        ProgramProperties programProperties = new ProgramProperties();
                        IProgram          currentProgram    = program;
                        programProperties.SetProgram(currentProgram, channel);

                        ProgramListItem item = new ProgramListItem(programProperties)
                        {
                            Command = new MethodDelegateCommand(() => ShowProgramActions(currentProgram))
                        };
                        item.AdditionalProperties["PROGRAM"] = currentProgram;

                        _programsList.Add(item);
                    }
                }
                ProgramsList.FireChange();
            }
            else
            {
                _programs = null;
            }
        }
        protected async void UpdatePrograms()
        {
            UpdateGuiProperties();
            _programsList.Clear();
            IChannel channel = CurrentChannel;

            if (channel == null)
            {
                _programs = null;
                return;
            }

            var result = await _tvHandler.ProgramInfo.GetProgramsAsync(channel, DateTime.Now.AddHours(-2), DateTime.Now.AddDays(_settings.Settings.SingleChannelGuideDays));

            if (result.Success)
            {
                _programs = result.Result;
                foreach (IProgram program in _programs)
                {
                    // Use local variable, otherwise delegate argument is not fixed
                    ProgramProperties programProperties = new ProgramProperties();
                    IProgram          currentProgram    = program;
                    programProperties.SetProgram(currentProgram, channel);

                    ProgramListItem item = new ProgramListItem(programProperties)
                    {
                        Command = new MethodDelegateCommand(() => ShowProgramActions(currentProgram))
                    };
                    item.AdditionalProperties["PROGRAM"] = currentProgram;

                    _programsList.Add(item);
                }
            }
            ProgramsList.FireChange();
        }
Exemplo n.º 3
0
        /// <summary>
        /// Save current focus row (in _lastFocussedRow) and either set _focusOnChannelHeader or save time (in _focusTime)
        /// </summary>
        /// <param name="program">Set to the currently focussed program, if there is one</param>
        /// <returns>True if the focus was on a channel header or program
        /// False if control didn't have focus, or focus was on group header</returns>
        private bool SaveFocusPosition(out ProgramListItem program)
        {
            FrameworkElement header;
            int row;

            _focusOnChannelheader = false;
            if (GetFocusedRowAndStartTime(out program, out header, out row))
            {
                if (header != null)
                {
                    // Focus on channel header
                    _focusOnChannelheader = true;
                    _lastFocusedRow       = row;
                    _focusTime            = DateTime.MinValue;
                    return(true);
                }
                else if (program != null)
                {
                    _lastFocusedRow = row;
                    // Focus on program. If existing _focusTime is covered by program, leave it unchanged, otherwise set to program start time
                    if (program.Program.StartTime > _focusTime || program.Program.EndTime <= _focusTime)
                    {
                        _focusTime = program.Program.StartTime;
                    }
                    return(true);
                }
            }
            _focusTime = DateTime.MinValue;
            return(false);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Tries to update a program item, i.e. if recording status was changed.
        /// </summary>
        /// <param name="program">Program</param>
        private void UpdateProgramStatus(IProgram program)
        {
            if (program == null)
            {
                return;
            }
            FrameworkElement control = GetProgramItems().FirstOrDefault(el =>
            {
                ProgramListItem programListItem = (ProgramListItem)el.Context;
                if (programListItem == null)
                {
                    return(false);
                }
                ProgramProperties programProperties = programListItem.Program;
                return(programProperties != null && programProperties.ProgramId == program.ProgramId);
            });

            if (control == null)
            {
                return;
            }

            // Update properties
            IProgramRecordingStatus recordingStatus = program as IProgramRecordingStatus;

            if (recordingStatus != null)
            {
                ((ProgramListItem)control.Context).Program.UpdateState(recordingStatus.RecordingStatus);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Gets the currently focused program or header control and its Grid.Row.
        /// </summary>
        /// <param name="program">Focused program</param>
        /// <param name="headerControl">Focused header</param>
        /// <param name="row">The focused row</param>
        /// <returns><c>true</c> if matching program could be found</returns>
        private bool GetFocusedRowAndStartTime(out ProgramListItem program, out FrameworkElement headerControl, out int row)
        {
            program       = null;
            headerControl = null;
            row           = 0;
            FrameworkElement currentElement = GetFocusedElementOrChild();

            while (currentElement != null)
            {
                if (currentElement.DataContext != null)
                {
                    // Check for program
                    var item = currentElement.DataContext.Source as ProgramListItem;
                    if (item != null)
                    {
                        program = item;
                        row     = GetRow(currentElement);
                        return(true);
                    }
                    // Check for channel header
                    var channel = currentElement.DataContext.Source as ChannelProgramListItem;
                    if (channel != null)
                    {
                        headerControl = currentElement;
                        row           = GetRow(currentElement);
                        return(true);
                    }
                }
                currentElement = currentElement.LogicalParent as Control;
            }
            return(false);
        }
Exemplo n.º 6
0
        private ListItem CreateProgramItem(IProgram program, ISchedule schedule)
        {
            ProgramProperties programProperties = new ProgramProperties();
            IProgram          currentProgram    = program;
            IChannel          channel;

            if (!_tvHandler.ChannelAndGroupInfo.GetChannel(currentProgram.ChannelId, out channel))
            {
                channel = null;
            }
            programProperties.SetProgram(currentProgram, channel);

            ListItem item = new ProgramListItem(programProperties)
            {
                Command = new MethodDelegateCommand(() => ShowActions(schedule, program))
            };

            if (channel != null)
            {
                item.SetLabel("ChannelName", channel.Name);
            }
            item.SetLabel("ScheduleType", string.Format("[SlimTvClient.ScheduleRecordingType_{0}]", schedule.RecordingType));
            item.AdditionalProperties["PROGRAM"]  = currentProgram;
            item.AdditionalProperties["SCHEDULE"] = schedule;
            return(item);
        }
        private async Task <ListItem> CreateScheduleItem(ISchedule schedule, IChannel channel)
        {
            ListItem item = null;

            if (channel != null)
            {
                var programResult = await _tvHandler.ProgramInfo.GetProgramsAsync(channel, schedule.StartTime, schedule.EndTime);

                if (programResult.Success)
                {
                    ProgramProperties programProperties = new ProgramProperties();
                    programProperties.SetProgram(programResult.Result.First(), channel);
                    item = new ProgramListItem(programProperties)
                    {
                        Command = new MethodDelegateCommand(() => ShowSchedules()),
                    };
                    item.SetLabel("Name", schedule.Name);
                }
            }
            if (item == null)
            {
                item = new ListItem("Name", schedule.Name)
                {
                    Command = new MethodDelegateCommand(() => ShowSchedules()),
                };
            }
            item.SetLabel("ChannelName", channel?.Name ?? "");
            item.SetLabel("StartTime", schedule.StartTime.FormatProgramStartTime());
            item.SetLabel("EndTime", schedule.EndTime.FormatProgramEndTime());
            item.SetLabel("ScheduleType", string.Format("[SlimTvClient.ScheduleRecordingType_{0}]", schedule.RecordingType));
            item.AdditionalProperties["SCHEDULE"] = schedule;
            return(item);
        }
        private ListItem CreateScheduleItem(ISchedule schedule, ProgramProperties program)
        {
            ListItem item  = null;
            DateTime start = schedule.StartTime;
            DateTime end   = schedule.EndTime;

            if (program != null)
            {
                item = new ProgramListItem(program)
                {
                    Command = new MethodDelegateCommand(() => ShowSchedules()),
                };
                item.SetLabel("Name", schedule.Name);
                start = program.StartTime;
                end   = program.EndTime;
            }
            if (item == null)
            {
                item = new ListItem("Name", schedule.Name)
                {
                    Command = new MethodDelegateCommand(() => ShowSchedules()),
                };
            }
            item.SetLabel("ChannelName", program?.ChannelName ?? "");
            item.SetLabel("StartTime", start.FormatProgramStartTime());
            item.SetLabel("EndTime", end.FormatProgramEndTime());
            item.SetLabel("ScheduleType", string.Format("[SlimTvClient.ScheduleRecordingType_{0}]", schedule.RecordingType));
            item.AdditionalProperties["SCHEDULE"] = schedule;
            return(item);
        }
        private void FillProgramsList()
        {
            _programsList.Clear();

            foreach (IProgram program in _programs)
            {
                // Use local variable, otherwise delegate argument is not fixed
                ProgramProperties programProperties = new ProgramProperties();
                IProgram          currentProgram    = program;
                programProperties.SetProgram(currentProgram);

                ProgramListItem item = new ProgramListItem(programProperties)
                {
                    Command = new MethodDelegateCommand(() =>
                    {
                        var isSingle = programProperties.IsScheduled;
                        var isSeries = programProperties.IsSeriesScheduled;
                        if (isSingle || isSeries)
                        {
                            CancelSchedule(currentProgram);
                        }
                        else
                        {
                            RecordSeries(currentProgram);
                        }
                    })
                };
                item.AdditionalProperties["PROGRAM"] = currentProgram;
                item.Selected = _lastProgramId == program.ProgramId; // Restore focus

                _programsList.Add(item);
            }

            _programsList.FireChange();
        }
Exemplo n.º 10
0
        protected ItemsList GetProgramsList(IChannel channel, DateTime referenceStart, DateTime referenceEnd)
        {
            ItemsList channelPrograms = new ItemsList();

            if (_tvHandler.ProgramInfo.GetPrograms(channel, referenceStart, referenceEnd, out _programs))
            {
                foreach (IProgram program in _programs)
                {
                    // Use local variable, otherwise delegate argument is not fixed
                    ProgramProperties programProperties = new ProgramProperties(GuideStartTime, GuideEndTime);
                    IProgram          currentProgram    = program;
                    programProperties.SetProgram(currentProgram);

                    ProgramListItem item = new ProgramListItem(programProperties)
                    {
                        Command = new MethodDelegateCommand(() => ShowProgramActions(currentProgram))
                    };
                    item.AdditionalProperties["PROGRAM"] = currentProgram;

                    channelPrograms.Add(item);
                }
            }
            else
            {
                channelPrograms.Add(NoProgramPlaceholder());
            }
            return(channelPrograms);
        }
        public void RecordMenu()
        {
            ProgramListItem item = SlimTvExtScheduleModel.CurrentItem as ProgramListItem;

            if (item != null)
            {
                ShowProgramActions(item.AdditionalProperties["PROGRAM"] as IProgram);
            }
        }
Exemplo n.º 12
0
 private static void RemoveZeroDurations(ItemsList programs)
 {
     for (int i = programs.Count - 1; i >= 0; i--)
     {
         ProgramListItem currentItem = (ProgramListItem)programs[i];
         if (currentItem.Program.RemainingDuration == 0)
         {
             programs.Remove(currentItem);
         }
     }
 }
Exemplo n.º 13
0
        private static void CreateProgramListItem(IProgram program, ListItem itemToUpdate, IProgram previousProgram = null)
        {
            ProgramListItem item = itemToUpdate as ProgramListItem;

            if (item == null)
            {
                return;
            }
            item.Program.SetProgram(program ?? GetNoProgram(previousProgram));
            item.AdditionalProperties["PROGRAM"] = program;
        }
        private void FillProgramsList()
        {
            _programsList.Clear();

            bool isSingle = false;
            bool isSeries = false;

            foreach (IProgram program in _programs)
            {
                IChannel channel;
                if (!_tvHandler.ChannelAndGroupInfo.GetChannel(program.ChannelId, out channel))
                {
                    channel = null;
                }
                // Use local variable, otherwise delegate argument is not fixed
                ProgramProperties programProperties = new ProgramProperties();
                IProgram          currentProgram    = program;
                programProperties.SetProgram(currentProgram, channel);

                if (ProgramComparer.Instance.Equals(_selectedProgram, program))
                {
                    isSingle = programProperties.IsScheduled;
                    isSeries = programProperties.IsSeriesScheduled;
                }

                ProgramListItem item = new ProgramListItem(programProperties)
                {
                    Command = new MethodDelegateCommand(() => CreateOrDeleteSchedule(currentProgram))
                };
                item.AdditionalProperties["PROGRAM"] = currentProgram;
                item.Selected = _lastProgramId == program.ProgramId; // Restore focus
                if (channel != null)
                {
                    item.SetLabel("ChannelName", channel.Name);
                    item.SetLabel("ChannelLogoType", channel.GetFanArtMediaType());
                }

                _programsList.Add(item);
            }

            // "Record" buttons are related to properties, for schedules we need to keep them to "Cancel record" state.
            if (_isScheduleMode)
            {
                isSingle = isSeries = _selectedSchedule != null;
            }

            IsSingleRecordingScheduled = isSingle;
            IsSeriesRecordingScheduled = isSeries;

            _programsList.FireChange();
        }
Exemplo n.º 15
0
        /// <summary>
        /// Tries to find an existing control for given <paramref name="program"/> in the Grid row with index <paramref name="rowIndex"/>.
        /// If no control was found, this method creates a new control and adds it to the Grid.
        /// </summary>
        /// <param name="program">Program.</param>
        /// <param name="rowIndex">RowIndex.</param>
        /// <returns>Control.</returns>
        private Control GetOrCreateControl(ProgramListItem program, int rowIndex)
        {
            Control control = GetRowItems(rowIndex).FirstOrDefault(el => ((ProgramListItem)el.Context).Program.ProgramId == program.Program.ProgramId);

            if (control != null)
            {
                return(control);
            }

            control = CreateControl(program);
            // Deep copy the styles to each program button.
            control.Template = MpfCopyManager.DeepCopyCutLVPs(ProgramTemplate);
            Children.Add(control);
            return(control);
        }
        private ListItem CreateProgramItem(IProgram program, IChannel channel)
        {
            ProgramProperties programProperties = new ProgramProperties();

            programProperties.SetProgram(program, channel);

            ProgramListItem item = new ProgramListItem(programProperties)
            {
                Command = new AsyncMethodDelegateCommand(() => SlimTvModelBase.TuneChannel(channel)),
            };

            item.SetLabel("ChannelName", channel.Name);
            item.AdditionalProperties["PROGRAM"] = program;
            return(item);
        }
        private ProgramListItem BuildProgramListItem(IProgram program, IChannel channel)
        {
            ProgramProperties programProperties = new ProgramProperties();
            IProgram          currentProgram    = program;

            programProperties.SetProgram(currentProgram, channel);

            ProgramListItem item = new ProgramListItem(programProperties)
            {
                Command = new MethodDelegateCommand(() => ShowProgramActions(currentProgram))
            };

            item.AdditionalProperties["PROGRAM"] = currentProgram;
            return(item);
        }
Exemplo n.º 18
0
 private void TrimEnd(ItemsList programs)
 {
     for (int i = programs.Count - 1; i >= 0; i--)
     {
         ProgramListItem firstItem = (ProgramListItem)programs[i];
         if (firstItem.Program.StartTime > GuideEndTime)
         {
             programs.RemoveAt(i);
         }
         else
         {
             break;
         }
     }
 }
Exemplo n.º 19
0
 private void TrimStart(ItemsList programs)
 {
     for (int i = 0; i < programs.Count; i++)
     {
         ProgramListItem firstItem = (ProgramListItem)programs[0];
         if (firstItem.Program.EndTime <= GuideStartTime)
         {
             programs.RemoveAt(0);
         }
         else
         {
             break;
         }
     }
 }
Exemplo n.º 20
0
        private static void CreateProgramListItem(IProgram program, ItemsList channelPrograms)
        {
            ProgramListItem item;

            if (program == null)
            {
                item = GetNoProgramPlaceholder();
            }
            else
            {
                ProgramProperties programProperties = new ProgramProperties();
                programProperties.SetProgram(program);
                item = new ProgramListItem(programProperties);
            }
            item.AdditionalProperties["PROGRAM"] = program;
            channelPrograms.Add(item);
        }
Exemplo n.º 21
0
    public void ScrollRight()
    {
        for (int i = 1; i < programAnchors.Length; i++)
        {
            displayedPrograms[i].transform.position = programAnchors[i - 1].transform.position;
        }
        ProgramListItem temp = displayedPrograms[0];

        displayedPrograms.Remove(temp);
        Destroy(temp.gameObject);
        scrollIndex++;
        ProgramListItem newListItem = Instantiate(listItem, programAnchors[programAnchors.Length - 1].transform).GetComponent <ProgramListItem>();

        newListItem.SetProgram(PersistentState.instance.GetOwnedPrograms()[scrollIndex + programAnchors.Length - 1]);
        displayedPrograms.Add(newListItem);
        UpdateScrollEnabled();
    }
Exemplo n.º 22
0
    private void RefreshProgramList()
    {
        foreach (ProgramListItem listItem in displayedPrograms)
        {
            Destroy(listItem.gameObject);
        }
        displayedPrograms.Clear();
        int i = scrollIndex;

        while (i < scrollIndex + programAnchors.Length && i < PersistentState.instance.GetOwnedPrograms().Count)
        {
            ProgramListItem newListItem = Instantiate(listItem, programAnchors[i - scrollIndex].transform).GetComponent <ProgramListItem>();
            newListItem.SetProgram(PersistentState.instance.GetOwnedPrograms()[i]);
            displayedPrograms.Add(newListItem);
            i++;
        }
        UpdateScrollEnabled();
    }
Exemplo n.º 23
0
        public void SetProgram(int program_number, byte[] program_bytes)
        {
            ProgramListItem p;

            if (this.programs.ContainsKey(program_number))
            {
                // updating a program
                p = this.programs[program_number];
                p.updateProgram (program_bytes);
                this.programList.Items.RemoveAt(program_number);
                this.programList.Items.Insert(program_number, p);
            }
            else
            {
                // adding a new program
                p = new ProgramListItem(program_number, program_bytes);
                this.programList.Items.Add(p);
                this.programs.Add(program_number, p);
            }
        }
        private void FillProgramsList()
        {
            _programsList.Clear();

            bool isSingle = false;
            bool isSeries = false;

            foreach (IProgram program in _programs)
            {
                // Use local variable, otherwise delegate argument is not fixed
                ProgramProperties programProperties = new ProgramProperties();
                IProgram          currentProgram    = program;
                programProperties.SetProgram(currentProgram);

                if (ProgramComparer.Instance.Equals(_selectedProgram, program))
                {
                    isSingle = programProperties.IsScheduled;
                    isSeries = programProperties.IsSeriesScheduled;
                }

                ProgramListItem item = new ProgramListItem(programProperties)
                {
                    Command = new MethodDelegateCommand(() => CreateOrDeleteSchedule(currentProgram))
                };
                item.AdditionalProperties["PROGRAM"] = currentProgram;
                item.Selected = _lastProgramId == program.ProgramId; // Restore focus

                _programsList.Add(item);
            }

            // "Record" buttons are related to properties, for schedules we need to keep them to "Cancel record" state.
            if (_isScheduleMode)
            {
                isSingle = isSeries = _selectedSchedule != null;
            }

            IsSingleRecordingScheduled = isSingle;
            IsSeriesRecordingScheduled = isSeries;

            _programsList.FireChange();
        }
Exemplo n.º 25
0
        protected override bool UpdateRecordingStatus(IProgram program, RecordingStatus newStatus)
        {
            bool changed = base.UpdateRecordingStatus(program, newStatus);

            if (changed)
            {
                ChannelProgramListItem programChannel = _channelList.OfType <ChannelProgramListItem>().FirstOrDefault(c => c.Channel.ChannelId == program.ChannelId);
                if (programChannel == null)
                {
                    return(false);
                }

                ProgramListItem listProgram = programChannel.Programs.OfType <ProgramListItem>().FirstOrDefault(p => p.Program.ProgramId == program.ProgramId);
                if (listProgram == null)
                {
                    return(false);
                }
                listProgram.Program.IsScheduled = newStatus != RecordingStatus.None;
            }
            return(changed);
        }
        private void FillNoPrograms(ChannelProgramListItem channel, DateTime viewPortStart, DateTime viewPortEnd)
        {
            var programs = channel.Programs;

            if (programs.Count == 0)
            {
                programs.Add(NoProgramPlaceholder(channel.Channel, null, null));
                return;
            }
            ProgramListItem firstItem = programs.Cast <ProgramListItem>().First();
            ProgramListItem lastItem  = programs.Cast <ProgramListItem>().Last();

            if (firstItem.Program.StartTime > viewPortStart)
            {
                programs.Insert(0, NoProgramPlaceholder(channel.Channel, null, firstItem.Program.StartTime));
            }

            if (lastItem.Program.EndTime < viewPortEnd)
            {
                programs.Add(NoProgramPlaceholder(channel.Channel, lastItem.Program.EndTime, null));
            }
        }
Exemplo n.º 27
0
        /// <summary>
        /// Calculates to position (Column) and size (ColumnSpan) for the given <paramref name="program"/> by considering the avaiable viewport (<paramref name="viewportStart"/>, <paramref name="viewportEnd"/>).
        /// </summary>
        /// <param name="program">Program.</param>
        /// <param name="viewportStart">Viewport from.</param>
        /// <param name="viewportEnd">Viewport to.</param>
        /// <param name="colIndex">Returns Column.</param>
        /// <param name="colSpan">Returns ColumnSpan.</param>
        /// <param name="lastEndTime">Last program's end time.</param>
        private void CalculateProgamPosition(ProgramListItem program, DateTime viewportStart, DateTime viewportEnd, ref int colIndex, ref int colSpan, ref DateTime?lastEndTime)
        {
            if (program.Program.EndTime < viewportStart || program.Program.StartTime > viewportEnd)
            {
                return;
            }

            DateTime programViewStart = program.Program.StartTime < viewportStart ? viewportStart : program.Program.StartTime;

            double minutesSinceStart = (programViewStart - viewportStart).TotalMinutes;
            int    headersOffset     = GroupButtonEnabled ? 2 : 1;

            if (lastEndTime != null)
            {
                int newColIndex = (int)Math.Round(minutesSinceStart / _perCellTime) + headersOffset; // Header offset
                if (lastEndTime != program.Program.StartTime)
                {
                    colIndex = Math.Max(colIndex, newColIndex); // colIndex is already set to new position. Calculation is only done to support gaps in programs.
                }
                lastEndTime = program.Program.EndTime;
            }

            colSpan = (int)Math.Round((program.Program.EndTime - programViewStart).TotalMinutes / _perCellTime);

            if (colIndex + colSpan > _numberOfColumns + headersOffset)
            {
                colSpan = _numberOfColumns - colIndex + headersOffset;
            }

            if (colSpan == 0)
            {
                colSpan = 1;
            }

#if DEBUG_LAYOUT
            // Debug layouting:
            ServiceRegistration.Get <ILogger>().Debug("EPG: {0,2}-{1,2}: {3}-{4}: {2}", colIndex, colSpan, program.Program.Title, program.Program.StartTime.ToShortTimeString(), program.Program.EndTime.ToShortTimeString());
#endif
        }
Exemplo n.º 28
0
        private void UpdateChannelPrograms(ChannelProgramListItem channel)
        {
            int programCount = channel.Programs.Count;

            if (programCount > 0)
            {
                ProgramListItem firstItem = (ProgramListItem)channel.Programs[0];
                ProgramListItem lastItem  = (ProgramListItem)channel.Programs[programCount - 1];
                DateTime        timeFrom  = firstItem.Program.StartTime;
                DateTime        timeTo    = lastItem.Program.EndTime;
                if (timeFrom > GuideStartTime)
                {
                    ReloadStart(channel, timeFrom);
                }
                else
                {
                    TrimStart(channel.Programs);
                }

                if (timeTo < GuideEndTime)
                {
                    ReloadEnd(channel, timeTo);
                }
                else
                {
                    TrimEnd(channel.Programs);
                }

                foreach (ProgramListItem program in channel.Programs)
                {
                    program.Program.UpdateDuration(GuideStartTime, GuideEndTime);
                }

                RemoveZeroDurations(channel.Programs);
            }
            channel.Programs.FireChange();
        }
Exemplo n.º 29
0
        private bool CreateOrUpdateRow(bool updateOnly, ref int channelIndex, int rowIndex)
        {
            if (channelIndex >= ChannelsPrograms.Count)
            {
                return(false);
            }
            ChannelProgramListItem channel = ChannelsPrograms[channelIndex] as ChannelProgramListItem;

            if (channel == null)
            {
                return(false);
            }

            // Default: take viewport from model
            var model = SlimTvMultiChannelGuideModel;

            if (model == null)
            {
                return(false);
            }
            DateTime viewportStart = model.GuideStartTime;
            DateTime viewportEnd   = model.GuideEndTime;

            int colIndex = GroupButtonEnabled ? 1 : 0;

            if (!updateOnly)
            {
                Control btnHeader = CreateControl(channel);
                SetGrid(btnHeader, colIndex, rowIndex, 1);

                // Deep copy the styles to each program button.
                btnHeader.Template = MpfCopyManager.DeepCopyCutLVPs(HeaderTemplate);
                Children.Add(btnHeader);
            }

            int      colSpan       = 0;
            DateTime?lastStartTime = null;
            DateTime?lastEndTime   = viewportStart;

#if DEBUG_LAYOUT
            // Debug layouting:
            if (rowIndex == 0)
            {
                ServiceRegistration.Get <ILogger>().Debug("EPG: Viewport: {0}-{1} PerCell: {2} min", viewportStart.ToShortTimeString(), viewportEnd.ToShortTimeString(), _perCellTime);
            }
#endif
            if (updateOnly)
            {
                // Remove all programs outside of viewport.
                DateTime start      = viewportStart;
                DateTime end        = viewportEnd;
                var      removeList = GetRowItems(rowIndex).Where(el =>
                {
                    ProgramListItem p = (ProgramListItem)el.Context;
                    return(p.Program.EndTime <= start || p.Program.StartTime >= end || channel.Channel.ChannelId != ((IProgram)p.AdditionalProperties["PROGRAM"]).ChannelId ||
                           p is PlaceholderListItem);
                }).ToList();
                removeList.ForEach(Children.Remove);
            }

            colIndex++; // After header (and optional GroupButton)
            int programIndex = 0;
            while (programIndex < channel.Programs.Count && colIndex <= _numberOfColumns)
            {
                ProgramListItem program = channel.Programs[programIndex] as ProgramListItem;
                if (program == null || program.Program.StartTime > viewportEnd)
                {
                    break;
                }

                // Ignore programs outside viewport and programs that start at same time (duplicates)
                if (program.Program.EndTime <= viewportStart || (lastStartTime.HasValue && lastStartTime.Value == program.Program.StartTime))
                {
                    programIndex++;
                    continue;
                }

                lastStartTime = program.Program.StartTime;

                CalculateProgamPosition(program, viewportStart, viewportEnd, ref colIndex, ref colSpan, ref lastEndTime);

                Control btnEpg = GetOrCreateControl(program, rowIndex);
                SetGrid(btnEpg, colIndex, rowIndex, colSpan);
                programIndex++;
                colIndex += colSpan; // Skip spanned columns.
            }
            channelIndex++;
            return(true);
        }