summaryrefslogtreecommitdiff
path: root/magazine.cpp
diff options
context:
space:
mode:
authorJochen Dolze <vdr@dolze.de>2010-08-01 08:42:12 +0200
committerJochen Dolze <vdr@dolze.de>2010-07-31 22:32:15 +0200
commit415f957ea35045b32b96831def310465b35035e1 (patch)
tree571819cd67f6d0da19e8d290d65db240473da1fb /magazine.cpp
parent5785295a438e1ddd874f27b0f89b391d7c976fd7 (diff)
downloadvdr-plugin-tvonscreen-415f957ea35045b32b96831def310465b35035e1.tar.gz
vdr-plugin-tvonscreen-415f957ea35045b32b96831def310465b35035e1.tar.bz2
Added gettext support
Diffstat (limited to 'magazine.cpp')
-rw-r--r--magazine.cpp1415
1 files changed, 1415 insertions, 0 deletions
diff --git a/magazine.cpp b/magazine.cpp
new file mode 100644
index 0000000..8dcf801
--- /dev/null
+++ b/magazine.cpp
@@ -0,0 +1,1415 @@
+/*
+ * magazine.c
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: magazine.c,v 1.34 2006/06/18 13:59:36 schmitzj Exp $
+ *
+ */
+
+#include "magazine.h"
+#include "TVonscreen.h"
+
+#define clrGrey 0xFF5F5F5F
+#define clrBackground clrGray50 // this should be tied somehow into current theme
+
+static tArea Areas[NUMBER_OF_AREAS] =
+{
+#ifndef MULTINAMES
+ { 8+45, 0, 8+45 + 188*2+184 - 1, 0 + 48/*20*/ - 1, 8 }, // NAMES_AREA
+#else
+ { 8+45, 0, 8+45 + 184 - 1, 0 + 48/*20*/ - 1, 4 }, // NAME1_AREA
+ { 8+45+188, 0, 8+45+188 + 184 - 1, 0 + 48/*20*/ - 1, 4 }, // NAME2_AREA
+ { 8+45+188*2, 0, 8+45+188*2 + 184 - 1, 0 + 48/*20*/ - 1, 4 }, // NAME3_AREA
+#endif
+ { 0, 0, 0 + 8+40 - 1, TL_YSTART + 384 - 1, 2 }, // TIMELINE_AREA
+ { 8+45, TL_YSTART, 8+45 + 184 - 1, TL_YSTART + 384 - 1, 2 }, // SCHED1_AREA
+ { 8+45+188, TL_YSTART, 8+45+188 + 184 - 1, TL_YSTART + 384 - 1, 2 }, // SCHED2_AREA
+ { 8+45+188*2, TL_YSTART, 8+45+188*2 + 184 - 1, TL_YSTART + 384 - 1, 2 }, // SCHED3_AREA
+ { 50, 384+TL_YSTART+8, 50 + 8+45+188*2+184-101 - 1, 384+TL_YSTART+8 + 20 - 1, 2 }, // CONTROL_AREA
+};
+
+static int CompareSchedules(const void *p1, const void *p2) {
+
+ int c1nr = 9999; // there should be no one with more than 9999 channels
+ int c2nr = 9999;
+
+ cChannel* c1 = Channels.GetByChannelID((*(const cSchedule**)p1)->ChannelID(), true);
+ if (c1)
+ c1nr = c1->Number();
+
+ cChannel* c2 = Channels.GetByChannelID((*(const cSchedule**)p2)->ChannelID(), true);
+ if (c2)
+ c2nr = c2->Number();
+
+ return c1nr - c2nr;
+}
+
+
+magazine::magazine(class cPlugin *p)
+{
+ parent=p;
+ const cSchedules* Schedules = cSchedules::Schedules(_schedulesLock);
+
+ curmode=SHOW;
+ EDIT_curEvent=0;
+
+ f1=NULL;
+ f2=NULL;
+ f3=NULL;
+ f4=NULL;
+ me=NULL;
+ met=NULL;
+ mes=NULL;
+
+ timeline_tested=false;
+ timeline_found_conflict=false;
+
+ // Create and sort entries for menu items
+ // --------------------------------------
+
+ const cSchedule* Schedule = Schedules->First();
+
+ int num = 0;
+ schedArray = NULL;
+ while (Schedule)
+ {
+ schedArray = (const cSchedule **)realloc(schedArray, (num + 1) * sizeof(cSchedule*));
+
+ if (Schedule->GetPresentEvent())
+ { // if there exist an event -> add to array
+ // check if we can get a channel NAME ( XXX )
+ // I thougt that this must always work , but doesn't
+ cChannel *c = Channels.GetByChannelID(Schedule->ChannelID(), true);
+ if (c)
+ {
+ schedArray[num] = Schedule;
+ ++num;
+ }
+ }
+ Schedule = (const cSchedule*)Schedules->Next(Schedule);
+ }
+ schedArrayNum=num;
+ qsort(schedArray, num, sizeof(cSchedule*), CompareSchedules);
+ currentFirst=0;
+
+ int currentChannel = Channels.GetByNumber(cDevice::CurrentChannel())->Number();
+ for(int i=0;i<schedArrayNum;i++)
+ {
+ cChannel *channel = Channels.GetByChannelID(schedArray[i]->ChannelID(), true);
+ if (channel->Number()==currentChannel)
+ {
+ currentFirst=i-1;
+ if (currentFirst<0)
+ currentFirst=0;
+ break;
+ }
+ }
+
+ ev1=NULL;
+ ev2=NULL;
+ ev3=NULL;
+ fullHours=NULL;
+ fullHours_tmp1=NULL;
+ fullHours_tmp2=NULL;
+ fullHours_tmp3=NULL;
+
+ currentFirstTime=time(NULL);
+}
+magazine::~magazine(void)
+{
+ if (me)
+ {
+ delete me;
+ me=NULL;
+ }
+ if (met)
+ {
+ delete met;
+ met=NULL;
+ }
+ if (mes)
+ {
+ delete mes;
+ mes=NULL;
+ }
+
+ delete [] fullHours_tmp3;
+ delete [] fullHours_tmp2;
+ delete [] fullHours_tmp1;
+ delete [] fullHours;
+ delete [] ev1;
+ delete [] ev2;
+ delete [] ev3;
+
+ delete f1;
+ delete f2;
+ delete f3;
+ delete f4;
+
+ free(schedArray);
+ delete osd;
+}
+void magazine::printLogo(const cSchedule *s,int p)
+{
+ cChannel* channel;
+ const char *txt;
+ int x=184*p+p*4;
+ int currentChannel;
+
+#ifdef MULTINAMES
+ int a=0;
+ switch (p)
+ {
+ case 0:
+ default:
+ a=NAME1_AREA;
+ break;
+ case 1:
+ a=NAME2_AREA;
+ break;
+ case 2:
+ a=NAME3_AREA;
+ break;
+ }
+ x=0;
+#else
+ int a=NAMES_AREA;
+#endif
+ if (s!=NULL)
+ {
+ currentChannel = Channels.GetByNumber(cDevice::CurrentChannel())->Number();
+ channel = Channels.GetByChannelID(s->ChannelID(), true);
+ txt=channel->ShortName(true);
+ // logo: 64x48px
+
+ const char *ConfigDirectory=cPlugin::ConfigDirectory("logos");
+ if (tvonscreenCfg.logos)
+ ConfigDirectory=tvonscreenCfg.logos;
+ char *fname=new char[strlen(ConfigDirectory) + 1 + strlen(txt) + strlen(".xpm") + 1];
+ sprintf(fname,"%s/%s.xpm",ConfigDirectory,txt);
+ DrawXpm(fname,osd,x+Areas[a].x1,Areas[a].y1,0,tvonscreenCfg.bwlogos);
+ }
+}
+void magazine::printHead(const cSchedule *s,int p)
+{
+ cChannel* channel;
+ const char *txt;
+ int x=184*p+p*4;
+ int currentChannel;
+ int wmin=0,yoff=0;
+
+ if (tvonscreenCfg.showLogos)
+ wmin=64;
+
+#ifdef MULTINAMES
+ int a;
+ switch (p)
+ {
+ case 0:
+ default:
+ a=NAME1_AREA;
+ break;
+ case 1:
+ a=NAME2_AREA;
+ break;
+ case 2:
+ a=NAME3_AREA;
+ break;
+ }
+ x=0;
+#else
+ int a=NAMES_AREA;
+#endif
+#if TL_YSTART == 48
+ yoff=28;
+ osd->DrawRectangle(x+Areas[a].x1,0+Areas[a].y1+0,x+Areas[a].x1+188,Areas[a].y1+48,clrTransparent);
+ osd->DrawEllipse(x+Areas[a].x1+182-28,0+Areas[a].y1,x+Areas[a].x1+182,Areas[a].y1+28,clrGrey,1);
+ osd->DrawEllipse(x+Areas[a].x1+182-28-2,0+Areas[a].y1+2,x+Areas[a].x1+182-2,Areas[a].y1+28+2,clrTransparent,1);
+
+ osd->DrawEllipse(x+Areas[a].x1,Areas[a].y1,x+Areas[a].x1+28,Areas[a].y1+28,clrGrey,2);
+ osd->DrawEllipse(x+Areas[a].x1+2,Areas[a].y1+2,x+Areas[a].x1+28+2,Areas[a].y1+28+2,clrTransparent,2);
+
+ osd->DrawRectangle(x+Areas[a].x1+28,0+Areas[a].y1,x+Areas[a].x1+182-28,Areas[a].y1+2,clrGrey);
+ osd->DrawRectangle(x+Areas[a].x1+182-2,0+Areas[a].y1+28,x+Areas[a].x1+182,Areas[a].y1+28+20,clrGrey);
+ osd->DrawRectangle(x+Areas[a].x1,0+Areas[a].y1+28,x+Areas[a].x1+2,Areas[a].y1+28+20,clrGrey); // nie zu sehen, außer wenn kein Logo gefunden wird
+
+ if (p==2) DrawXpm(TVonscreen,osd,x+Areas[a].x1+182-110,0+Areas[a].y1);
+
+ if (tvonscreenCfg.showChannels || !tvonscreenCfg.showLogos)
+#endif
+ osd->DrawRectangle(x+Areas[a].x1,yoff+Areas[a].y1,x+Areas[a].x1+182,Areas[a].y1+20+yoff,clrBlue);
+
+ if (tvonscreenCfg.showChannels || !tvonscreenCfg.showLogos)
+ {
+ if (s!=NULL)
+ {
+ tColor col=clrWhite;
+
+ currentChannel = Channels.GetByNumber(cDevice::CurrentChannel())->Number();
+ channel = Channels.GetByChannelID(s->ChannelID(), true);
+ if (currentChannel==channel->Number())
+ {
+ col=clrCyan;
+ }
+ txt=channel->ShortName(true);
+
+ if (!tvonscreenCfg.XLfonts || f3->LargeWidth(txt)>=184-wmin)
+ f3->Text(wmin+x+Areas[a].x1+(184-wmin-f3->Width(txt))/2,Areas[a].y1+yoff-1,txt,col,clrBlue);
+ else
+ f3->LargeText(wmin+x+Areas[a].x1+(184-wmin-f3->LargeWidth(txt))/2,Areas[a].y1+yoff-1,txt,col,clrBlue);
+ }
+ }
+}
+void magazine::showHeads(bool onlyBG)
+{
+ const cSchedule *s1=NULL,*s2=NULL,*s3=NULL;
+
+ if (!onlyBG)
+ {
+ s1=schedArrayNum>currentFirst?schedArray[currentFirst]:NULL;
+ s2=schedArrayNum>currentFirst+1?schedArray[currentFirst+1]:NULL;
+ s3=schedArrayNum>currentFirst+2?schedArray[currentFirst+2]:NULL;
+ }
+
+ printHead(s1,0);
+ printHead(s2,1);
+ printHead(s3,2);
+
+ if (tvonscreenCfg.showLogos)
+ {
+ printLogo(s1,0);
+ printLogo(s2,1);
+ printLogo(s3,2);
+ }
+}
+void magazine::showKeys(void)
+{
+ char txt[100];
+ osd->DrawRectangle(Areas[CONTROL_AREA].x1, Areas[CONTROL_AREA].y1, Areas[CONTROL_AREA].x2+1, Areas[CONTROL_AREA].y2+1, clrTransparent);
+ if (tvonscreenCfg.noInfoLine)
+ return;
+
+ txt[0]=0;
+ if (curmode==SHOW)
+ {
+ sprintf(txt,"%s",tr("Press 1 for help"));
+ }
+ f4->Text(Areas[CONTROL_AREA].x1+(8+45+188*2+184-101-f4->Width(txt))/2,Areas[CONTROL_AREA].y1,txt,clrWhite,clrBackground);
+}
+void magazine::showTimeline(void)
+{
+ int lh=-1;
+ int lhc=0;
+ tColor hgr[]={clrBlue,clrBlack};
+ char dtxt[50];
+ time_t t1;
+ struct tm tm_r1;
+
+ t1=currentFirstTime;
+ localtime_r(&t1,&tm_r1);
+
+ osd->DrawRectangle(0+Areas[TIMELINE_AREA].x1,0+Areas[TIMELINE_AREA].y1,48,400+TL_YSTART,clrBlack);
+ for(int i=0;i<evnum;i++)
+ {
+ int y=i*f1->Height()+TL_YSTART;
+ if (lh!=fullHours[i] && fullHours[i]>=0)
+ {
+ lh=fullHours[i];
+ lhc=lh&1;
+ }
+ osd->DrawRectangle(0+Areas[TIMELINE_AREA].x1,y+Areas[TIMELINE_AREA].y1,48,y+f1->Height(),hgr[lhc]);
+ }
+
+#if TL_YSTART == 24
+ strftime(dtxt,sizeof(dtxt),tr("%d-%m"),&tm_r1);
+ f3->Text((48-f3->Width(dtxt))/2+Areas[TIMELINE_AREA].x1,0+Areas[TIMELINE_AREA].y1,dtxt,clrWhite,clrBlack);
+#else
+ strcpy(dtxt,WeekDayName(tm_r1.tm_wday));
+ osd->DrawRectangle(0+Areas[TIMELINE_AREA].x1,0+Areas[TIMELINE_AREA].y1,Areas[TIMELINE_AREA].x1+48,Areas[TIMELINE_AREA].y1+f3->Height()*2,clrWhite);
+ osd->DrawRectangle(2+Areas[TIMELINE_AREA].x1,2+Areas[TIMELINE_AREA].y1,Areas[TIMELINE_AREA].x1+48-2,Areas[TIMELINE_AREA].y1+f3->Height(),clrBlack);
+ f3->Text((48-f3->Width(dtxt))/2+Areas[TIMELINE_AREA].x1,0+Areas[TIMELINE_AREA].y1,dtxt,clrWhite,clrBlack);
+ strftime(dtxt,sizeof(dtxt),tr("%d-%m"),&tm_r1);
+ f3->Text((48-f3->Width(dtxt))/2+Areas[TIMELINE_AREA].x1,0+Areas[TIMELINE_AREA].y1+f3->Height(),dtxt,clrBlack,clrWhite);
+#endif
+ for(int i=0;i<evnum;i++)
+ {
+ int y=i*f1->Height()+TL_YSTART;
+ if (fullHours[i]>=0 && lh!=fullHours[i])
+ {
+ char txt[50];
+ sprintf(txt,"%02d",fullHours[i]);
+ lh=fullHours[i];
+ f1->Text((48-f1->Width(txt))/2+Areas[TIMELINE_AREA].x1,y+Areas[TIMELINE_AREA].y1,txt,clrWhite,clrBlack);
+ if (i+1<evnum && (fullHours[i+1]==lh || fullHours[i+1]==-1))
+ {
+ strcpy(txt,tr("o'clock"));
+ f2->Text((48-f2->Width(txt))/2+Areas[TIMELINE_AREA].x1,y+f1->Height()+Areas[TIMELINE_AREA].y1,txt,clrWhite,clrBlack);
+ }
+ }
+ }
+}
+void magazine::showSched(const cSchedule *s,cEvent **ev,tMagazineArea area)
+{
+ cEvent *oldev=NULL,*cev=NULL;
+
+ int j=0;
+ const char *txt;
+ cString timetxt;
+ int lh=-1;
+ int lhc=0;
+
+ tColor hgr[]={clrGrey,clrBackground};
+ tColor col=clrWhite;
+
+ osd->DrawRectangle(Areas[area].x1, Areas[area].y1, Areas[area].x2+1, Areas[area].y2+1, clrGray50);
+
+ for(int i=0;i<evnum;i++)
+ {
+ int y=i*f1->Height(); //+24;
+ if (lh!=fullHours[i] && fullHours[i]>=0)
+ {
+ lh=fullHours[i];
+ lhc=lh&1;
+ }
+ osd->DrawRectangle(Areas[area].x1,Areas[area].y1+y,Areas[area].x1+184,Areas[area].y1+y+f1->Height(),hgr[lhc]);
+ }
+ for(int i=0;i<evnum;i++)
+ {
+ int y=i*f1->Height(); //+24;
+ cev=ev[i];
+ if (cev!=NULL)
+ {
+ if (oldev!=cev)
+ {
+ if (oldev)
+ {
+ txt=oldev->ShortText();
+ int cc=f2->TextHeight(184-f1->Width("00:0"),txt);
+ if (cc<=i-j)
+ {
+ f2->Text(f1->Width("00:0")+Areas[area].x1,(j)*f1->Height()+Areas[area].y1,184-f1->Width("00:0"),i-j,txt,col,clrBackground);
+ }
+ }
+ col=clrWhite;
+ if (EDIT_curEvent==cev->EventID())
+ {
+ col=clrYellow;
+ EDIT_curEVI=i;
+ }
+ timetxt=cev->GetTimeString();
+ txt=cev->Title();
+ if (i+f1->TextHeight(f1->Width("00:00 ")+Areas[area].x1,txt)>=evnum)
+ break;
+ f1->Text(Areas[area].x1,y+Areas[area].y1,timetxt,col,clrBackground);
+ j=i+f1->Text(f1->Width("00:00 ")+Areas[area].x1,y+Areas[area].y1,184-f1->Width("00:00 "),20,txt,col,clrBackground);
+ oldev=cev;
+ }
+ }
+ }
+ if (oldev)
+ {
+ txt=oldev->ShortText();
+ if (j+f2->TextHeight(f1->Width("00:00")+Areas[area].x1,txt)>=evnum)
+ f2->Text(f1->Width("00:0")+Areas[area].x1,j*f1->Height()+Areas[area].y1,184-f1->Width("00:0"),evnum-j,txt,col,clrBackground);
+ }
+ if (!EDIT_curEvent)
+ {
+ if (!timeline_tested)
+ {
+ timeline_tested=true;
+ cPlugin *p = cPluginManager::GetPlugin("timeline");
+ if (p)
+ {
+ char *args[]={"timeline_command_interface","conflicts"};
+ timeline_found_conflict=p->ProcessArgs(1,args);
+ }
+ }
+ if (timeline_found_conflict)
+ {
+ osd->DrawRectangle(Areas[area].x1,Areas[area].y2-f2->Height()-6,Areas[area].x1+184,Areas[area].y2+1,clrWhite);
+ osd->DrawRectangle(Areas[area].x1,Areas[area].y2-f2->Height()-4,Areas[area].x1+184,Areas[area].y2+1,clrYellow);
+ const char *txt=tr("Timer conflict!");
+ int x=(184-f2->Width(txt))/2;
+ f2->Text(x+Areas[area].x1,Areas[area].y2-f2->Height()-4,txt,clrBackground,clrYellow);
+ }
+ }
+}
+void magazine::showScheds()
+{
+ const cSchedule *s1=schedArrayNum>currentFirst?schedArray[currentFirst]:NULL;
+ const cSchedule *s2=schedArrayNum>currentFirst+1?schedArray[currentFirst+1]:NULL;
+ const cSchedule *s3=schedArrayNum>currentFirst+2?schedArray[currentFirst+2]:NULL;
+
+ if (s1!=NULL)
+ {
+ showSched(s1,ev1,SCHED1_AREA);
+ }
+
+ if (s2!=NULL)
+ {
+ showSched(s2,ev2,SCHED2_AREA);
+ }
+
+ if (s3!=NULL)
+ {
+ showSched(s3,ev3,SCHED3_AREA);
+ }
+}
+const cEvent *magazine::getNext(const cSchedule *s,const cEvent *e)
+{
+ if (e == NULL)
+ return NULL;
+
+ const cEvent *pe = NULL;
+ time_t ref = e->StartTime();
+
+ time_t delta = INT_MAX;
+
+ for (int i=0;i< (s->Events())->Count();i++)
+ {
+ const cEvent *p = (s->Events())->Get(i);
+ if (p!=e)
+ {
+ time_t dt = p->StartTime() - ref;
+ if (dt > 0 && dt < delta)
+ {
+ delta = dt;
+ pe = p;
+ }
+ }
+ }
+ return pe;
+}
+const cEvent *magazine::getPrev(const cSchedule *s,const cEvent *e)
+{
+ if (e == NULL)
+ return NULL;
+
+ const cEvent *pe = NULL;
+ time_t ref = e->StartTime();
+ time_t delta = INT_MAX;
+
+
+ for (int i=0;i< (s->Events())->Count();i++)
+ {
+ const cEvent *p = (s->Events())->Get(i);
+
+ if (p!=e)
+ {
+ time_t dt = ref - p->StartTime();
+ if (dt > 0 && dt < delta)
+ {
+ delta = dt;
+ pe = p;
+ }
+ }
+ }
+ return pe;
+}
+void magazine::calcSched(const cSchedule *s,cEvent **ev)
+{
+ const cEvent *cev=NULL;
+ const cEvent *cev2=NULL;
+ int cc=0;
+
+ for(int i=0;i<evnum;i++)
+ {
+ ev[i]=NULL;
+ if (cev==NULL)
+ {
+ cev=s->GetEventAround(currentFirstTime);
+ cev2=NULL;
+ if (cev)
+ {
+ cc=f1->TextHeight(184-f1->Width("00:00 "),cev->Title());
+ time_t t=cev->StartTime();
+ struct tm tm_r;
+ localtime_r(&t,&tm_r);
+ fullHours[i]=tm_r.tm_hour; //mzlog(0," fH[%d]=%d '%s'",i,tm_r.tm_hour,cev->Title());
+ }
+ }
+ else
+ {
+ if (!cev2)
+ cev2=getNext(s,cev);
+ if (cev2 && cc--<=1)
+ {
+ int z=(cev2->StartTime()-currentFirstTime)*6/60/60;
+ if (z<i)
+ {
+ cev=cev2;
+ cev2=NULL;
+
+ cc=f1->TextHeight(184-f1->Width("00:00 "),cev->Title());
+ time_t t=cev->StartTime();
+
+ struct tm tm_r;
+ localtime_r(&t,&tm_r);
+ fullHours[i]=tm_r.tm_hour; //mzlog(0," fH[%d]=%d '%s'",i,tm_r.tm_hour,cev->Title());
+ }
+ }
+ }
+ ev[i]=(cEvent *)cev;
+ }
+}
+void magazine::calcScheds()
+{
+ const cSchedule *s1=schedArrayNum>currentFirst?schedArray[currentFirst]:NULL;
+ const cSchedule *s2=schedArrayNum>currentFirst+1?schedArray[currentFirst+1]:NULL;
+ const cSchedule *s3=schedArrayNum>currentFirst+2?schedArray[currentFirst+2]:NULL;
+
+ for(int i=0;i<evnum;i++)
+ {
+ fullHours[i]=-1;
+ fullHours_tmp1[i]=-1;
+ fullHours_tmp2[i]=-1;
+ fullHours_tmp3[i]=-1;
+ }
+
+ if (s1!=NULL)
+ {
+ calcSched(s1,ev1);
+ for(int i=0;i<evnum;i++)
+ {
+ fullHours_tmp1[i]=fullHours[i];
+ fullHours[i]=-1;
+ }
+ }
+
+ if (s2!=NULL)
+ {
+ calcSched(s2,ev2);
+ for(int i=0;i<evnum;i++)
+ {
+ fullHours_tmp2[i]=fullHours[i];
+ fullHours[i]=-1;
+ }
+ }
+
+ if (s3!=NULL)
+ {
+ calcSched(s3,ev3);
+ for(int i=0;i<evnum;i++)
+ {
+ fullHours_tmp3[i]=fullHours[i];
+ fullHours[i]=-1;
+ }
+ }
+ int lfh1,lfh2,lfh3;
+ lfh1=lfh2=lfh3=-1;
+ for(int i=0;i<evnum;i++)
+ {
+ if (fullHours_tmp1[i]>=0)
+ lfh1=fullHours_tmp1[i];
+ fullHours_tmp1[i]=lfh1;
+ if (fullHours_tmp2[i]>=0)
+ lfh2=fullHours_tmp2[i];
+ fullHours_tmp2[i]=lfh2;
+ if (fullHours_tmp3[i]>=0)
+ lfh3=fullHours_tmp3[i];
+ fullHours_tmp3[i]=lfh3;
+ if (fullHours_tmp1[i]>fullHours[i])
+ fullHours[i]=fullHours_tmp1[i];
+ if (fullHours_tmp2[i]>fullHours[i])
+ fullHours[i]=fullHours_tmp2[i];
+ if (fullHours_tmp3[i]>fullHours[i])
+ fullHours[i]=fullHours_tmp3[i];
+ }
+}
+void magazine::output(void)
+{
+/* for (int i=0; i < (int)(sizeof(Areas)/sizeof(tArea)); i++)
+ {
+ cBitmap *b=osd->GetBitmap(i);
+ if (b)
+ b->Reset();
+ } */
+ cBitmap *b=osd->GetBitmap(NAMES_AREA);
+ if (b)
+ {
+ b->Reset();
+ if (tvonscreenCfg.colorworkaround)
+ {
+ // This is an ugly work around for color problems with DVB driver or hardware or vdr handling, who knows
+ b->SetColor(0,clrTransparent);
+ b->SetColor(1,clrBlue);
+ b->SetColor(2,clrWhite);
+ b->SetColor(3,clrGrey);
+ b->SetColor(4,0xffff0000);
+ b->SetColor(5,clrCyan);
+ for(int i=6;i<128;i++)
+ {
+ b->SetColor(i,0x01000000|i);
+ }
+ // End work around
+ }
+ }
+/* for(int i=0; i < (int)(sizeof(Areas)/sizeof(tArea)); i++)
+ {
+ cBitmap *b=osd->GetBitmap(i);
+ int col;
+ b->Colors(col);
+ mzlog(5," 1. NumColors(%d):%d",i,col);
+ } */
+
+ showHeads();
+ showKeys();
+ calcScheds();
+ showScheds();
+ showTimeline();
+
+/* for (int i=0; i < (int)(sizeof(Areas)/sizeof(tArea)); i++)
+ {
+ cBitmap *b=osd->GetBitmap(i);
+ int col;
+ const tColor *tc=b->Colors(col);
+ mzlog(5," 2. NumColors(%d):%d",i,col);
+ if (i==NAMES_AREA)
+ {
+ for(int j=0;j<col;j++)
+ {
+ mzlog(5," Col(%d): %x",j,tc[j]);
+ }
+ }
+ } */
+
+ osd->Flush();
+}
+void magazine::outputLR(void)
+{
+/* for (int i=0; i < (int)(sizeof(Areas)/sizeof(tArea)); i++)
+ {
+ cBitmap *b=osd->GetBitmap(i);
+ if (b)
+ b->Reset();
+ } */
+ cBitmap *b=osd->GetBitmap(NAMES_AREA);
+ if (b)
+ {
+ b->Reset();
+ if (tvonscreenCfg.colorworkaround)
+ {
+ // This is an ugly work around for color problems with DVB driver or hardware or vdr handling, who knows
+ b->SetColor(0,clrTransparent);
+ b->SetColor(1,clrBlue);
+ b->SetColor(2,clrWhite);
+ b->SetColor(3,clrGrey);
+ b->SetColor(4,0xffff0000);
+ b->SetColor(5,clrCyan);
+ for(int i=6;i<128;i++)
+ {
+ b->SetColor(i,0x01000000|i);
+ }
+ // End work around
+ }
+ }
+
+ showHeads();
+ calcScheds();
+ searchcEvt();
+ showScheds();
+ showTimeline();
+
+ osd->Flush();
+}
+void magazine::gotoUsertime(int u)
+{
+ struct tm tm_r;
+ localtime_r(&currentFirstTime,&tm_r);
+ tm_r.tm_hour=u/100;
+ tm_r.tm_min=u%100;
+ tm_r.tm_sec=0;
+ currentFirstTime=mktime(&tm_r);
+ if (currentFirstTime<time(NULL))
+ {
+ if (tvonscreenCfg.thenshownextday)
+ currentFirstTime+=(60*60*24);
+ else
+ currentFirstTime=time(NULL);
+ }
+ output();
+}
+void magazine::showHelp()
+{
+ anyFont *usef=f2;
+ int j=0;
+ const char *txt;
+ int lines=384/usef->Height();
+ int width=184;
+
+ char *helptext[]={
+ "NORMAL MODE:",
+ "arrows\n\tmove view",
+ "back\n\tclose TV OnScreen",
+ "red/blue\n\t-/+ one day",
+ "green/yellow\n\tone page left/right",
+ "7/9\n\tone page left/right",
+ "8\n\tgoto current channel",
+ "0\n\tgoto now",
+ "4/5/6\n\tgoto configured time",
+ "ok\n\tswitch to edit mode\n",
+ "EDIT MODE:",
+ "back\n\tback to normal mode",
+ "arrows\n\tmove selected schedule",
+ "record\n\tcreate timer",
+ "ok\n\tshow details",
+ "|\n(c) 2004 Jürgen Schmitz\n\thttp://www.js-home.org/vdr",
+ NULL
+ };
+
+ int area=SCHED1_AREA;
+
+ osd->DrawRectangle(Areas[SCHED1_AREA].x1, Areas[SCHED1_AREA].y1+1, Areas[SCHED1_AREA].x2+1, Areas[SCHED1_AREA].y2+1, clrGrey);
+ osd->DrawRectangle(Areas[SCHED2_AREA].x1, Areas[SCHED2_AREA].y1+1, Areas[SCHED2_AREA].x2+1, Areas[SCHED2_AREA].y2+1, clrGrey);
+ osd->DrawRectangle(Areas[SCHED3_AREA].x1, Areas[SCHED3_AREA].y1+1, Areas[SCHED3_AREA].x2+1, Areas[SCHED3_AREA].y2+1, clrGrey);
+
+ osd->DrawRectangle(Areas[SCHED1_AREA].x1+2, Areas[SCHED1_AREA].y1, Areas[SCHED1_AREA].x2+1-3, Areas[SCHED1_AREA].y2+1-3, clrGray50);
+ osd->DrawRectangle(Areas[SCHED2_AREA].x1+2, Areas[SCHED2_AREA].y1, Areas[SCHED2_AREA].x2+1-3, Areas[SCHED2_AREA].y2+1-3, clrGray50);
+ osd->DrawRectangle(Areas[SCHED3_AREA].x1+2, Areas[SCHED3_AREA].y1, Areas[SCHED3_AREA].x2+1-3, Areas[SCHED3_AREA].y2+1-3, clrGray50);
+
+ osd->DrawRectangle(0+Areas[TIMELINE_AREA].x1,0+Areas[TIMELINE_AREA].y1+TL_YSTART,Areas[TIMELINE_AREA].x1+48,Areas[TIMELINE_AREA].y1+400+TL_YSTART,clrBlack);
+ showHeads(true);
+// osd->Flush();
+
+ do
+ {
+ for(int i=0;i<lines;)
+ {
+ int y=i*usef->Height();
+ if (helptext[j]==NULL)
+ break;
+ if (helptext[j][0]=='|')
+ txt=helptext[j]+1;
+ else
+ txt=tr(helptext[j]);
+
+ if (i+usef->TextHeight(width,txt)>=lines)
+ break;
+
+ i+=usef->Text(Areas[area].x1+4,y+Areas[area].y1,width-8,lines-i,txt,clrWhite,clrBackground);
+ j++;
+ }
+ if (area==SCHED1_AREA)
+ area=SCHED2_AREA;
+ else if (area==SCHED2_AREA)
+ area=SCHED3_AREA;
+ else if (area==SCHED3_AREA)
+ break;
+ }
+ while (helptext[j]);
+ osd->Flush();
+}
+
+void magazine::autoTimer(const class cEvent *cev)
+{
+ FILE *f;
+ if ((f=fopen(tvonscreenCfg.vdradminfile,"a")))
+ {
+ const char *title;
+ int chan;
+
+ title=cev->Title();
+ cChannel *cc=Channels.GetByChannelID(cev->ChannelID());
+ chan=cc->Number();
+
+ fprintf(f,"1:%s:1:::1:40:7:%d:\n",title,chan);
+ fclose(f);
+ }
+}
+
+#if VDRVERSNUM < 10503
+#include "fontosd/fontosd-arial18.c"
+#include "fontosd/fontosd-verdana16.c"
+#include "fontosd/fontosd-tahoma16.c"
+#include "fontosd/fontosd-timesNewRoman16.c"
+#endif
+
+void magazine::Show(void)
+{
+ mzlog(10," magazine::Show()");
+
+ if (me)
+ {
+ delete me;
+ me=NULL;
+ }
+ if (met)
+ {
+ delete met;
+ met=NULL;
+ }
+ if (mes)
+ {
+ delete mes;
+ mes=NULL;
+ }
+
+ osd = cOsdProvider::NewOsd(((Setup.OSDWidth - 612) / 2) + Setup.OSDLeft, ((Setup.OSDHeight - 436) / 2) + Setup.OSDTop);
+ if (osd && !osd->SetAreas(Areas, sizeof(Areas)/sizeof(tArea)))
+ {
+ delete [] fullHours;
+ delete [] ev1;
+ delete [] ev2;
+ delete [] ev3;
+
+ delete f1;
+ delete f2;
+ delete f3;
+ delete f4;
+
+#if VDRVERSNUM >= 10503
+ f1=new anyFont(osd,18,1); // Sendung
+ f2=new anyFont(osd,16,1); // Extra-Info
+ f3=new anyFont(osd,20,1); // Sender
+ f4=new anyFont(osd,16); // Tasten
+#else
+ f1=new anyFont(osd,(cFont::tPixelData *)fontosd_arial18,FONTOSD_ARIAL18,1); // Sendung
+ f2=new anyFont(osd,(cFont::tPixelData *)fontosd_verdana16,FONTOSD_VERDANA16,1); // Extra-Info
+ f3=new anyFont(osd,(cFont::tPixelData *)fontosd_tahoma16,FONTOSD_TAHOMA16,1); // Sender
+ f4=new anyFont(osd,(cFont::tPixelData *)fontosd_newroman16,FONTOSD_NEWROMAN16); // Tasten
+#endif
+ for (int i=0; i < (int)(sizeof(Areas)/sizeof(tArea)); i++)
+ {
+// cBitmap *b=osd->GetBitmap(i);
+// if (b)
+// b->Reset();
+ osd->DrawRectangle(Areas[i].x1, Areas[i].y1, Areas[i].x2+1, Areas[i].y2+1, clrGray50);
+ }
+ evnum=(Areas[SCHED1_AREA].y2-Areas[SCHED1_AREA].y1)/f1->Height();
+
+ ev1=new cEvent*[evnum];
+ ev2=new cEvent*[evnum];
+ ev3=new cEvent*[evnum];
+
+ fullHours=new int[evnum];
+ fullHours_tmp1=new int[evnum];
+ fullHours_tmp2=new int[evnum];
+ fullHours_tmp3=new int[evnum];
+
+ output();
+ }
+}
+cEvent **magazine::ev4ch(int p)
+{
+ cEvent **ev=NULL;
+ if (p==currentFirst)
+ ev=ev1;
+ else if (p==currentFirst+1)
+ ev=ev2;
+ if (p==currentFirst+2)
+ ev=ev3;
+ return ev;
+}
+void magazine::searchcEvt(void)
+{
+ cEvent **ev=ev4ch(EDIT_curChannel);
+ for(int i=EDIT_curEVI;i>=0;i--)
+ {
+ if (ev[i])
+ {
+ EDIT_curEvent=ev[i]->EventID();
+ break;
+ }
+ }
+}
+eOSState magazine::ProcessKey(eKeys Key)
+{
+ //mzlog(10," ProcessKey(%d)",Key);
+ eOSState state;
+ if (me)
+ {
+ state=me->ProcessKey(Key);
+ if (state==osBack)
+ {
+ state=osContinue;
+ delete me;
+ me=NULL;
+ if (!osd)
+ Show();
+ }
+ else if (state == osUnknown || state == osContinue)
+ {
+ switch (Key & ~k_Repeat)
+ {
+ case kOk:
+ case kBack:
+ delete me;
+ me=NULL;
+ if (!osd)
+ Show();
+ break;
+ case kBlue: // Umschalten - obsolete!
+ {
+ cEvent **ev=ev4ch(EDIT_curChannel);
+ cChannel *channel = Channels.GetByChannelID(ev[EDIT_curEVI]->ChannelID(), true);
+ if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true))
+ {
+ delete me;
+ me=NULL;
+ return osEnd;
+ }
+ }
+ break;
+ case kGreen: // Suchen
+ {
+// mzlog(10," Search");
+ delete me;
+ me=NULL;
+ cEvent **ev=ev4ch(EDIT_curChannel);
+ mes=new cSearchMenu(ev[EDIT_curEVI]);
+ state=osContinue;
+ }
+ break;
+ case kYellow: // add AutoTimer
+ {
+// mzlog(10," AutoTimer");
+ if (tvonscreenCfg.vdradminfile)
+ {
+ me->helpLine(false);
+ state=osContinue;
+
+ cEvent **ev=ev4ch(EDIT_curChannel);
+ autoTimer(ev[EDIT_curEVI]);
+ me->printMsg(tr("Added AutoTimer to vdradmin."));
+ }
+ else
+ {
+ me->printMsg(tr("Startoption 'vdradminfile' not set!"));
+ me->helpLine(false);
+ state=osContinue;
+ }
+ }
+ break;
+ case kRed:
+ case kRecord: // new
+ {
+ delete me;
+ me=NULL;
+ cEvent **ev=ev4ch(EDIT_curChannel);
+ cTimer *timer = new cTimer(ev[EDIT_curEVI]);
+ cTimer *t = Timers.GetTimer(timer);
+ if (t)
+ {
+ delete timer;
+ timer = t;
+ }
+ met=new cMenuEditTimer(timer, !t);
+ met->Display();
+ state=osContinue;
+ }
+ break;
+ }
+ }
+ }
+ else if (met)
+ {
+ state=met->ProcessKey(Key);
+ if (state==osBack)
+ {
+ state=osContinue;
+ delete met;
+ met=NULL;
+ if (!osd)
+ Show();
+ }
+ else if (state == osUnknown)
+ {
+ switch (Key & ~k_Repeat)
+ {
+ case kOk:
+ case kBack:
+ delete met;
+ met=NULL;
+ if (!osd)
+ Show();
+ break;
+ }
+ }
+ }
+ else if (mes)
+ {
+ state=mes->ProcessKey(Key);
+ if (state==osBack)
+ {
+ state=osContinue;
+ delete mes;
+ mes=NULL;
+ if (!osd)
+ Show();
+ }
+ else if (state == osUnknown)
+ {
+ switch (Key & ~k_Repeat)
+ {
+ case kOk:
+ case kGreen:
+ {
+ const cEvent *ev=mes->currentSelected();
+ if (ev)
+ {
+ delete mes;
+ mes=NULL;
+ me=new tvOcMenuEvent(ev);
+ me->Display();
+ }
+ }
+ state=osContinue;
+ break;
+ case kYellow:
+ mes->searchIn(schedArray,schedArrayNum);
+ state=osContinue;
+ break;
+ case kBack:
+ case kBlue:
+ delete mes;
+ mes=NULL;
+ if (!osd)
+ Show();
+ break;
+ case kRed:
+ const cEvent *ev=mes->currentSelected();
+ if (ev)
+ {
+ delete mes;
+ mes=NULL;
+ cTimer *timer = new cTimer(ev);
+ cTimer *t = Timers.GetTimer(timer);
+ if (t)
+ {
+ delete timer;
+ timer = t;
+ }
+ met=new cMenuEditTimer(timer, !t);
+ met->Display();
+ }
+ state=osContinue;
+ break;
+ }
+ }
+ }
+ else
+ {
+ state = cOsdObject::ProcessKey(Key);
+
+ if (state == osUnknown && schedArrayNum>currentFirst)
+ {
+ if (curmode==SHOW)
+ {
+ switch (Key & ~k_Repeat)
+ {
+ case kOk:
+ if (schedArrayNum>currentFirst)
+ {
+ curmode=EDIT;
+ EDIT_curChannel=currentFirst;
+ for(int i=0;i<evnum;i++)
+ {
+ if (ev1[i])
+ {
+ EDIT_curEvent=ev1[i]->EventID();
+ break;
+ }
+ }
+ output();
+ }
+ break;
+ case kBack:
+ return osBack;
+ case kLeft:
+ currentFirst--;
+ if (currentFirst<0)
+ currentFirst=0;
+ output();
+ break;
+ case kRight:
+ currentFirst++;
+ if (currentFirst>schedArrayNum-3)
+ currentFirst=schedArrayNum-3;
+ if (currentFirst<0)
+ currentFirst=0;
+ output();
+ break;
+ case kUp:
+ currentFirstTime-=60*30;
+ if (currentFirstTime<time(NULL))
+ currentFirstTime=time(NULL);
+ output();
+ break;
+ case kDown:
+ currentFirstTime+=60*30;
+ output();
+ break;
+ case kRed: // -1 Tag
+ currentFirstTime-=24*60*60;
+ if (currentFirstTime<time(NULL))
+ currentFirstTime=time(NULL);
+ output();
+ break;
+ case kBlue: // +1 Tag
+ currentFirstTime+=24*60*60;
+ output();
+ break;
+ case k7: // -1 Seite (3 Sender)
+ case kGreen:
+ currentFirst-=3;
+ if (currentFirst<0)
+ currentFirst=0;
+ output();
+ break;
+ case k9: // +1 Seite (3 Sender)
+ case kYellow:
+ currentFirst+=3;
+ if (currentFirst>schedArrayNum-3)
+ currentFirst=schedArrayNum-3;
+ if (currentFirst<0)
+ currentFirst=0;
+ output();
+ break;
+ case k8: // zum aktuellen Sender
+ {
+ int currentChannel = Channels.GetByNumber(cDevice::CurrentChannel())->Number();
+ for(int i=0;i<schedArrayNum;i++)
+ {
+ cChannel *channel = Channels.GetByChannelID(schedArray[i]->ChannelID(), true);
+ if (channel->Number()==currentChannel)
+ {
+ currentFirst=i-1;
+ if (currentFirst<0)
+ currentFirst=0;
+ output();
+ break;
+ }
+ }
+ }
+ break;
+ case k0: // jetzt
+ currentFirstTime=time(NULL);
+ output();
+ break;
+ case k1:
+ showHelp();
+ break;
+ case k4: // usertime1
+ gotoUsertime(tvonscreenCfg.usertime1);
+ break;
+ case k5: // usertime2
+ gotoUsertime(tvonscreenCfg.usertime2);
+ break;
+ case k6: // usertime3
+ gotoUsertime(tvonscreenCfg.usertime3);
+ break;
+ /* case k0:
+ break;
+ case k1:
+ break;
+ case k2:
+ break;
+ case k3:
+ break;
+ case k4:
+ break;
+ case k5:
+ break;
+ case k6:
+ break;
+ case k8:
+ break; */
+ default:
+ return state;
+ }
+ }
+ else
+ {
+ switch (Key & ~k_Repeat)
+ {
+ case kOk:
+ {
+ cEvent **ev=ev4ch(EDIT_curChannel);
+ if (ev[EDIT_curEVI] != NULL)
+ {
+ delete osd;
+ osd=NULL;
+ me=new tvOcMenuEvent(ev[EDIT_curEVI]);
+ me->Display();
+ curmode=SHOW;
+ EDIT_curEvent=0;
+ return osContinue;
+ }
+ }
+ break;
+ case kBack:
+ curmode=SHOW;
+ EDIT_curEvent=0;
+ output();
+ break;
+ case kLeft:
+ EDIT_curChannel--;
+ if (EDIT_curChannel<0)
+ EDIT_curChannel=0;
+ if (EDIT_curChannel<currentFirst)
+ {
+ currentFirst--;
+ if (currentFirst<0)
+ currentFirst=0;
+ EDIT_curChannel=currentFirst;
+ }
+ outputLR();
+ break;
+ case kRight:
+ EDIT_curChannel++;
+ if (EDIT_curChannel>schedArrayNum-1)
+ EDIT_curChannel=schedArrayNum-1;
+ if (EDIT_curChannel<0)
+ EDIT_curChannel=0;
+ if (EDIT_curChannel>currentFirst+2)
+ {
+ currentFirst++;
+ if (currentFirst>schedArrayNum-3)
+ currentFirst=schedArrayNum-3;
+ if (currentFirst<0)
+ currentFirst=0;
+ EDIT_curChannel=currentFirst+2;
+ }
+ outputLR();
+ break;
+ case kUp:
+ {
+ cEvent **ev=ev4ch(EDIT_curChannel);
+ const cEvent *e=getPrev(schedArray[EDIT_curChannel],ev[EDIT_curEVI]);
+
+ if (e)
+ {
+ int found;
+ do
+ {
+ found=0;
+ for(int i=0;i<evnum;i++)
+ {
+ if (ev[i] && ev[i]->EventID()==e->EventID())
+ {
+ found=1;
+ EDIT_curEvent=e->EventID();
+ }
+ }
+ if (!found)
+ {
+ currentFirstTime-=60*30;
+ if (currentFirstTime<time(NULL))
+ {
+ currentFirstTime=time(NULL);
+ found=1;
+ }
+ calcScheds();
+ }
+ }
+ while (!found);
+ }
+ output();
+ }
+ break;
+ case kDown:
+ {
+ cEvent **ev=ev4ch(EDIT_curChannel);
+ const cEvent *e=getNext(schedArray[EDIT_curChannel],ev[EDIT_curEVI]);
+
+ if (e)
+ {
+ EDIT_curEvent=e->EventID();
+ int found,cc=0;
+ do
+ {
+ found=0;
+ cc++;
+ for(int i=0;i<evnum;i++)
+ {
+ if (ev[i] && ev[i]->EventID()==EDIT_curEvent)
+ {
+ found=1;
+ }
+ }
+ if (!found)
+ {
+ currentFirstTime+=60*30;
+ calcScheds();
+ }
+ }
+ while (!found && cc<48);
+ }
+ output();
+ }
+ break;
+/* case kRed:
+ break;
+ case kBlue:
+ break;
+ case kGreen:
+ break;
+ case kYellow:
+ break; */
+ /* case k0:
+ break;
+ case k1:
+ break;
+ case k2:
+ break;
+ case k3:
+ break;
+ case k4:
+ break;
+ case k5:
+ break;
+ case k6:
+ break;
+ case k7:
+ break;
+ case k8:
+ break;
+ case k9:
+ break; */
+ case kRecord:
+ {
+ cEvent **ev=ev4ch(EDIT_curChannel);
+ if (ev[EDIT_curEVI] != NULL)
+ {
+ delete osd;
+ osd=NULL;
+ cTimer *timer = new cTimer(ev[EDIT_curEVI]);
+ cTimer *t = Timers.GetTimer(timer);
+ if (t)
+ {
+ delete timer;
+ timer = t;
+ }
+ met=new cMenuEditTimer(timer, !t);
+ }
+ }
+ break;
+ default:
+ return state;
+ }
+ }
+ state = osContinue;
+ }
+ }
+ return state;
+}
+
+#include <stdarg.h>
+
+void mzlog(int level, const char *fmt, ...)
+{
+ auto char t[BUFSIZ];
+ auto va_list ap;
+ int minlevel=0;
+
+ va_start(ap, fmt);
+
+ if (level>=minlevel)
+ {
+ vsnprintf(t + 10, sizeof t - 10, fmt, ap);
+ memcpy(t, "tvonscreen: ", 10);
+ syslog(LOG_DEBUG, "%s", t);
+ }
+ va_end(ap);
+}