summaryrefslogtreecommitdiff
path: root/channelepg.c
diff options
context:
space:
mode:
authorkamel5 <vdr.kamel5 (at) gmx (dot) net>2019-07-11 12:07:35 +0200
committerkamel5 <vdr.kamel5 (at) gmx (dot) net>2019-07-11 12:07:35 +0200
commit1df9641621203b9eeb87c269c9e962691398e010 (patch)
treeba92ceb0dab90331c2435f8c5837ff2b2f014d83 /channelepg.c
parent3ed46bd8811b842643b6cfbd274440c16bc33aa7 (diff)
downloadvdr-plugin-tvguide-1df9641621203b9eeb87c269c9e962691398e010.tar.gz
vdr-plugin-tvguide-1df9641621203b9eeb87c269c9e962691398e010.tar.bz2
Rename channelcolumn.* to channelepg.*
Diffstat (limited to 'channelepg.c')
-rw-r--r--channelepg.c399
1 files changed, 399 insertions, 0 deletions
diff --git a/channelepg.c b/channelepg.c
new file mode 100644
index 0000000..2b3e07a
--- /dev/null
+++ b/channelepg.c
@@ -0,0 +1,399 @@
+#include "channelepg.h"
+#include "dummygrid.h"
+
+cChannelEpg::cChannelEpg(int num, const cChannel *channel, cMyTime *myTime) {
+ this->channel = channel;
+ this->num = num;
+ this->myTime = myTime;
+#if VDRVERSNUM < 20301
+ hasTimer = channel->HasTimer();
+#endif
+ hasSwitchTimer = SwitchTimers.ChannelInSwitchList(channel);
+#if VDRVERSNUM < 20301
+ schedulesLock = new cSchedulesLock(false, 100);
+#endif
+ header = NULL;
+}
+
+cChannelEpg::~cChannelEpg(void) {
+ if (header)
+ delete header;
+ grids.Clear();
+#if VDRVERSNUM < 20301
+ delete schedulesLock;
+#endif
+}
+
+void cChannelEpg::clearGrids() {
+ grids.Clear();
+}
+
+void cChannelEpg::createHeader() {
+ header = new cHeaderGrid();
+ header->createBackground(num);
+ header->drawChannel(channel);
+}
+
+void cChannelEpg::drawHeader() {
+ header->setPosition(num);
+}
+
+bool cChannelEpg::readGrids() {
+#if VDRVERSNUM >= 20301
+ const cSchedules* schedules;
+ {
+ LOCK_SCHEDULES_READ;
+ schedules = Schedules;
+ }
+#else
+ schedules = cSchedules::Schedules(*schedulesLock);
+#endif
+ const cSchedule *Schedule = NULL;
+ Schedule = schedules->GetSchedule(channel);
+ if (!Schedule) {
+ addDummyGrid(myTime->GetStart(), myTime->GetEnd(), NULL, false);
+ return true;
+ }
+ bool eventFound = false;
+ bool dummyAtStart = false;
+ const cEvent *startEvent = Schedule->GetEventAround(myTime->GetStart());
+ if (startEvent != NULL) {
+ eventFound = true;
+ } else {
+ for (int i=1; i<6; i++) {
+ startEvent = Schedule->GetEventAround(myTime->GetStart()+i*5*60);
+ if (startEvent) {
+ eventFound = true;
+ dummyAtStart = true;
+ break;
+ }
+ }
+ }
+ if (eventFound) {
+ bool col = true;
+ if (dummyAtStart) {
+ addDummyGrid(myTime->GetStart(), startEvent->StartTime(), NULL, col);
+ col = !col;
+ }
+ bool dummyNeeded = true;
+ bool toFarInFuture = false;
+ time_t endLast = myTime->GetStart();
+ const cEvent *event = startEvent;
+ const cEvent *eventLast = NULL;
+ for (; event; event = Schedule->Events()->Next(event)) {
+ if (endLast < event->StartTime()) {
+ //gap, dummy needed
+ time_t endTime = event->StartTime();
+ if (endTime > myTime->GetEnd()) {
+ endTime = myTime->GetEnd();
+ toFarInFuture = true;
+ }
+ addDummyGrid(endLast, endTime, NULL, col);
+ col = !col;
+ }
+ if (toFarInFuture) {
+ break;
+ }
+ addEpgGrid(event, NULL, col);
+ col = !col;
+ endLast = event->EndTime();
+ if (event->EndTime() > myTime->GetEnd()) {
+ dummyNeeded = false;
+ break;
+ }
+ eventLast = event;
+ }
+ if (dummyNeeded) {
+ addDummyGrid(eventLast->EndTime(), myTime->GetEnd(), NULL, col);
+ }
+ return true;
+ } else {
+ addDummyGrid(myTime->GetStart(), myTime->GetEnd(), NULL, false);
+ return true;
+ }
+ return false;
+}
+
+void cChannelEpg::drawGrids() {
+ for (cGrid *grid = grids.First(); grid; grid = grids.Next(grid)) {
+ grid->SetViewportHeight();
+ grid->PositionPixmap();
+ grid->Draw();
+ }
+}
+
+int cChannelEpg::getX() {
+ return geoManager.timeLineWidth + num*geoManager.colWidth;
+}
+
+int cChannelEpg::getY() {
+ return geoManager.statusHeaderHeight + geoManager.timeLineHeight + num*geoManager.rowHeight;
+}
+
+cGrid * cChannelEpg::getActive() {
+ cMyTime t;
+ t.Now();
+ for (cGrid *grid = grids.First(); grid; grid = grids.Next(grid)) {
+ if (grid->Match(t.Get()))
+ return grid;
+ }
+ return grids.First();
+}
+
+cGrid * cChannelEpg::getNext(cGrid *activeGrid) {
+ if (activeGrid == NULL)
+ return NULL;
+ cGrid *next = grids.Next(activeGrid);
+ if (next)
+ return next;
+ return NULL;
+}
+
+cGrid * cChannelEpg::getPrev(cGrid *activeGrid) {
+ if (activeGrid == NULL)
+ return NULL;
+ cGrid *prev = grids.Prev(activeGrid);
+ if (prev)
+ return prev;
+ return NULL;
+}
+
+cGrid * cChannelEpg::getNeighbor(cGrid *activeGrid) {
+ if (!activeGrid)
+ return NULL;
+ cGrid *neighbor = NULL;
+ int overlap = 0;
+ int overlapNew = 0;
+ cGrid *grid = NULL;
+ grid = grids.First();
+ if (grid) {
+ for (; grid; grid = grids.Next(grid)) {
+ if ( (grid->StartTime() == activeGrid->StartTime()) ) {
+ neighbor = grid;
+ break;
+ }
+ overlapNew = activeGrid->calcOverlap(grid);
+ if (overlapNew > overlap) {
+ neighbor = grid;
+ overlap = overlapNew;
+ }
+ }
+ }
+ if (!neighbor)
+ neighbor = grids.First();
+ return neighbor;
+}
+
+bool cChannelEpg::isFirst(cGrid *grid) {
+ if (grid == grids.First())
+ return true;
+ return false;
+}
+
+void cChannelEpg::AddNewGridsAtStart() {
+ cGrid *firstGrid = NULL;
+ firstGrid = grids.First();
+ if (firstGrid == NULL)
+ return;
+ //if first event is long enough, nothing to do.
+ if (firstGrid->StartTime() <= myTime->GetStart()) {
+ return;
+ }
+ //if not, i have to add new ones to the list
+#if VDRVERSNUM >= 20301
+ const cSchedules* schedules;
+ {
+ LOCK_SCHEDULES_READ;
+ schedules = Schedules;
+ }
+#else
+ schedules = cSchedules::Schedules(*schedulesLock);
+#endif
+ const cSchedule *Schedule = NULL;
+ Schedule = schedules->GetSchedule(channel);
+ if (!Schedule) {
+ if (firstGrid->isDummy()) {
+ firstGrid->SetStartTime(myTime->GetStart());
+ firstGrid->SetEndTime(myTime->GetEnd());
+ }
+ return;
+ }
+ bool col = !(firstGrid->IsColor1());
+ bool dummyNeeded = true;
+ for (const cEvent *event = Schedule->GetEventAround(firstGrid->StartTime()-60); event; event = Schedule->Events()->Prev(event)) {
+ if (!event)
+ break;
+ if (event->EndTime() < myTime->GetStart()) {
+ break;
+ }
+ cGrid *grid = addEpgGrid(event, firstGrid, col);
+ col = !col;
+ firstGrid = grid;
+ if (event->StartTime() <= myTime->GetStart()) {
+ dummyNeeded = false;
+ break;
+ }
+ }
+ if (dummyNeeded) {
+ firstGrid = grids.First();
+ if (firstGrid->isDummy()) {
+ firstGrid->SetStartTime(myTime->GetStart());
+ if (firstGrid->EndTime() >= myTime->GetEnd())
+ firstGrid->SetEndTime(myTime->GetEnd());
+ } else {
+ addDummyGrid(myTime->GetStart(), firstGrid->StartTime(), firstGrid, col);
+ }
+ }
+}
+
+void cChannelEpg::AddNewGridsAtEnd() {
+ cGrid *lastGrid = NULL;
+ lastGrid = grids.Last();
+ if (lastGrid == NULL)
+ return;
+ //if last event is long enough, nothing to do.
+ if (lastGrid->EndTime() >= myTime->GetEnd()) {
+ return;
+ }
+ //if not, i have to add new ones to the list
+#if VDRVERSNUM >= 20301
+ const cSchedules* schedules;
+ {
+ LOCK_SCHEDULES_READ;
+ schedules = Schedules;
+ }
+#else
+ schedules = cSchedules::Schedules(*schedulesLock);
+#endif
+ const cSchedule *Schedule = NULL;
+ Schedule = schedules->GetSchedule(channel);
+ if (!Schedule) {
+ if (lastGrid->isDummy()) {
+ lastGrid->SetStartTime(myTime->GetStart());
+ lastGrid->SetEndTime(myTime->GetEnd());
+ }
+ return;
+ }
+ bool col = !(lastGrid->IsColor1());
+ bool dummyNeeded = true;
+ for (const cEvent *event = Schedule->GetEventAround(lastGrid->EndTime()+60); event; event = Schedule->Events()->Next(event)) {
+ if (!event)
+ break;
+ if (event->StartTime() > myTime->GetEnd()) {
+ break;
+ }
+ addEpgGrid(event, NULL, col);
+ col = !col;
+ if (event->EndTime() > myTime->GetEnd()) {
+ dummyNeeded = false;
+ break;
+ }
+ }
+ if (dummyNeeded) {
+ lastGrid = grids.Last();
+ if (lastGrid->isDummy()) {
+ lastGrid->SetEndTime(myTime->GetEnd());
+ if (lastGrid->StartTime() <= myTime->GetStart())
+ lastGrid->SetStartTime(myTime->GetStart());
+ } else {
+ addDummyGrid(lastGrid->EndTime(), myTime->GetEnd(), NULL, col);
+ }
+ }
+}
+
+void cChannelEpg::ClearOutdatedStart() {
+ cGrid *firstGrid = NULL;
+ while (true) {
+ firstGrid = grids.First();
+ if (!firstGrid)
+ break;
+ if (firstGrid->EndTime() <= myTime->GetStart()) {
+ grids.Del(firstGrid);
+ firstGrid = NULL;
+ } else {
+ if (firstGrid->isDummy()) {
+ firstGrid->SetStartTime(myTime->GetStart());
+ cGrid *next = getNext(firstGrid);
+ if (next) {
+ firstGrid->SetEndTime(next->StartTime());
+ } else {
+ firstGrid->SetEndTime(myTime->GetEnd());
+ }
+ }
+ break;
+ }
+ }
+}
+
+void cChannelEpg::ClearOutdatedEnd() {
+ cGrid *lastGrid = NULL;
+ while (true) {
+ lastGrid = grids.Last();
+ if (!lastGrid)
+ break;
+ if (lastGrid->StartTime() >= myTime->GetEnd()) {
+ grids.Del(lastGrid);
+ lastGrid = NULL;
+ } else {
+ if (lastGrid->isDummy()) {
+ lastGrid->SetEndTime(myTime->GetEnd());
+ cGrid *prev = getPrev(lastGrid);
+ if (prev) {
+ lastGrid->SetStartTime(prev->EndTime());
+ } else {
+ lastGrid->SetStartTime(myTime->GetStart());
+ }
+ }
+ break;
+ }
+ }
+}
+
+cGrid *cChannelEpg::addEpgGrid(const cEvent *event, cGrid *firstGrid, bool color) {
+ cGrid *grid = new cEpgGrid(this, event);
+ grid->setText();
+ grid->SetColor(color);
+ if (!firstGrid)
+ grids.Add(grid);
+ else
+ grids.Ins(grid, firstGrid);
+ return grid;
+}
+
+cGrid *cChannelEpg::addDummyGrid(time_t start, time_t end, cGrid *firstGrid, bool color) {
+ cGrid *dummy = new cDummyGrid(this, start, end);
+ dummy->setText();
+ dummy->SetColor(color);
+ if (!firstGrid)
+ grids.Add(dummy);
+ else
+ grids.Ins(dummy, firstGrid);
+ return dummy;
+}
+
+void cChannelEpg::SetTimers() {
+#if VDRVERSNUM < 20301
+ hasTimer = channel->HasTimer();
+#endif
+ hasSwitchTimer = SwitchTimers.ChannelInSwitchList(channel);
+ for (cGrid *grid = grids.First(); grid; grid = grids.Next(grid)) {
+ bool gridHadTimer = grid->HasTimer();
+ grid->SetTimer();
+ if (gridHadTimer || gridHadTimer != grid->HasTimer())
+ grid->SetDirty();
+ bool gridHadSwitchTimer = grid->HasSwitchTimer();
+ grid->SetSwitchTimer();
+ if (gridHadSwitchTimer != grid->HasSwitchTimer())
+ grid->SetDirty();
+ grid->Draw();
+ }
+}
+
+void cChannelEpg::dumpGrids() {
+ esyslog("tvguide: ------Channel %s %d: %d entires ---------", channel->Name(), num, grids.Count());
+ int i=1;
+ for (cGrid *grid = grids.First(); grid; grid = grids.Next(grid)) {
+ esyslog("tvguide: grid %d: start: %s, stop: %s", i, *cMyTime::printTime(grid->StartTime()), *cMyTime::printTime(grid->EndTime()));
+ i++;
+ }
+}