diff options
| author | Jochen Dolze <vdr@dolze.de> | 2010-08-01 08:42:12 +0200 |
|---|---|---|
| committer | Jochen Dolze <vdr@dolze.de> | 2010-07-31 22:32:15 +0200 |
| commit | 415f957ea35045b32b96831def310465b35035e1 (patch) | |
| tree | 571819cd67f6d0da19e8d290d65db240473da1fb /magazine.cpp | |
| parent | 5785295a438e1ddd874f27b0f89b391d7c976fd7 (diff) | |
| download | vdr-plugin-tvonscreen-415f957ea35045b32b96831def310465b35035e1.tar.gz vdr-plugin-tvonscreen-415f957ea35045b32b96831def310465b35035e1.tar.bz2 | |
Added gettext support
Diffstat (limited to 'magazine.cpp')
| -rw-r--r-- | magazine.cpp | 1415 |
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(¤tFirstTime,&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); +} |
