trunk 20080912
[gitenigma.git] / src / epgwindow.cpp
blob279a9d874eaee68bf62d796f7bda476acdbfa655
1 #include <epgwindow.h>
2 #include <enigma_event.h>
4 #include <algorithm>
6 #include <timer.h>
7 #include <enigma_main.h>
8 #include <enigma_lcd.h>
9 #include <lib/gui/eskin.h>
10 #include <lib/dvb/edvb.h>
11 #include <lib/dvb/dvbservice.h>
12 #include <lib/gdi/font.h>
13 #include <lib/system/init_num.h>
14 #include "epgactions.h"
16 gFont eListBoxEntryEPG::TimeFont;
17 gFont eListBoxEntryEPG::DescrFont;
18 gPixmap *eListBoxEntryEPG::inTimer=0;
19 gPixmap *eListBoxEntryEPG::inTimerRec=0;
20 int eListBoxEntryEPG::timeXSize=0;
21 int eListBoxEntryEPG::dateXSize=0;
23 eString LocalEventData::country;
24 eString LocalEventData::primary_language;
25 eString LocalEventData::secondary_language;
27 eAutoInitP0<epgSelectorActions> i_epgSelectorActions(eAutoInitNumbers::actions, "epg selector actions");
29 eListBoxEntryEPG::~eListBoxEntryEPG()
31 if (paraTime)
32 paraTime->destroy();
34 if (paraDate)
35 paraDate->destroy();
37 if (paraDescr)
38 paraDescr->destroy();
41 int eListBoxEntryEPG::getEntryHeight()
43 if (!DescrFont.pointSize && !TimeFont.pointSize)
45 DescrFont = eSkin::getActive()->queryFont("eEPGSelector.Entry.Description");
46 TimeFont = eSkin::getActive()->queryFont("eEPGSelector.Entry.DateTime");
47 inTimer = eSkin::getActive()->queryImage("timer_symbol");
48 inTimerRec = eSkin::getActive()->queryImage("timer_rec_symbol");
49 eTextPara* tmp = new eTextPara( eRect(0, 0, 200, 30) );
50 tmp->setFont( TimeFont );
51 tmp->renderString( "00:00" );
52 timeXSize = tmp->getBoundBox().width();
53 tmp->destroy();
54 tmp = new eTextPara( eRect(0, 0, 200, 30) );
55 tmp->setFont( TimeFont );
56 tmp->renderString( "Tue 09.09," );
57 dateXSize = tmp->getBoundBox().width();
58 tmp->destroy();
60 return calcFontHeight(DescrFont)+4;
63 void eListBoxEntryEPG::build()
65 start_time = *localtime(&event.start_time);
67 LocalEventData led;
68 led.getLocalData(&event, &descr);
70 if (descr)
71 return;
72 for (ePtrList<Descriptor>::iterator d(event.descriptor); d != event.descriptor.end(); ++d)
74 Descriptor *descriptor=*d;
75 if (descriptor->Tag()==DESCR_TIME_SHIFTED_EVENT)
77 // build parent Service Reference
78 eServiceReferenceDVB nvodService(
79 ((eServiceReferenceDVB&)service).getDVBNamespace(),
80 service.data[2], service.data[3],
81 ((TimeShiftedEventDescriptor*)descriptor)->reference_service_id, service.data[0] );
82 // get EITEvent from Parent...
83 EITEvent* evt = eEPGCache::getInstance()->lookupEvent(nvodService, ((TimeShiftedEventDescriptor*)descriptor)->reference_event_id );
84 if (evt)
86 led.getLocalData(evt, &descr);
87 delete evt;
88 return;
92 descr = "no event data available";
95 eListBoxEntryEPG::eListBoxEntryEPG(const eit_event_struct* evt, eListBox<eListBoxEntryEPG> *listbox, eServiceReference &ref)
96 :eListBoxEntry((eListBox<eListBoxEntry>*)listbox), paraDate(0), paraTime(0), paraDescr(0), event(evt,(((eServiceReferenceDVB&)ref).getTransportStreamID().get()<<16)|((eServiceReferenceDVB&)ref).getOriginalNetworkID().get()), service(ref)
98 build();
101 eListBoxEntryEPG::eListBoxEntryEPG(EITEvent& evt, eListBox<eListBoxEntryEPG> *listbox, eServiceReference &ref)
102 :eListBoxEntry((eListBox<eListBoxEntry>*)listbox), paraDate(0), paraTime(0), paraDescr(0), event(evt), service(ref)
104 build();
107 /* extern const char *dayStrShort[]; bug fix - at localization,
108 macro the type _ ("xxxxx") for a constant does not work,
109 if it is declared outside of the function */
111 const eString &eListBoxEntryEPG::redraw(gPainter *rc, const eRect& rect, gColor coActiveB, gColor coActiveF, gColor coNormalB, gColor coNormalF, int hilited)
113 const char *dayStrShort[7] = { _("Sun"), _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat") };
115 drawEntryRect(rc, rect, coActiveB, coActiveF, coNormalB, coNormalF, hilited);
117 int xpos=rect.left()+10;
118 if (!paraDate)
120 paraDate = new eTextPara( eRect( 0, 0, dateXSize, rect.height()) );
121 paraDate->setFont( TimeFont );
122 hlp.sprintf("%02d.%02d,", start_time.tm_mday, start_time.tm_mon+1);
123 paraDate->renderString( eString(dayStrShort[start_time.tm_wday])+' '+hlp );
124 paraDate->realign( eTextPara::dirRight );
125 TimeYOffs = ((rect.height() - paraDate->getBoundBox().height()) / 2 ) - paraDate->getBoundBox().top();
127 rc->renderPara(*paraDate, ePoint( xpos, rect.top() + TimeYOffs ) );
128 xpos+=dateXSize+paraDate->getBoundBox().height();
130 if (!paraTime)
132 paraTime = new eTextPara( eRect( 0, 0, timeXSize, rect.height()) );
133 paraTime->setFont( TimeFont );
134 eString tmp;
135 tmp.sprintf("%02d:%02d", start_time.tm_hour, start_time.tm_min);
136 paraTime->renderString( tmp );
137 paraTime->realign( eTextPara::dirRight );
138 hlp+=tmp;
140 rc->renderPara(*paraTime, ePoint( xpos, rect.top() + TimeYOffs ) );
141 xpos+=timeXSize+paraTime->getBoundBox().height();
143 ePlaylistEntry* p=0;
144 if ( (p = eTimerManager::getInstance()->findEvent( &service, &event )) )
145 if ( p->type & ePlaylistEntry::SwitchTimerEntry )
147 int ypos = (rect.height() - inTimer->y) / 2;
148 rc->blit( *inTimer, ePoint( xpos, rect.top()+ypos ), eRect(), gPixmap::blitAlphaTest);
149 xpos+=paraTime->getBoundBox().height()+inTimer->x;
151 else if ( p->type & ePlaylistEntry::RecTimerEntry )
153 int ypos = (rect.height() - inTimerRec->y) / 2;
154 rc->blit( *inTimerRec, ePoint( xpos, rect.top()+ypos ), eRect(), gPixmap::blitAlphaTest);
155 xpos+=paraTime->getBoundBox().height()+inTimerRec->x;
158 if (!paraDescr)
160 paraDescr = new eTextPara( eRect( 0 ,0, rect.width(), rect.height()) );
161 paraDescr->setFont( DescrFont );
162 paraDescr->renderString(descr);
163 DescrYOffs = 0; // ((rect.height() - paraDescr->getBoundBox().height()) / 2 ) - paraDescr->getBoundBox().top();
164 hlp=hlp+' '+descr;
166 rc->renderPara(*paraDescr, ePoint( xpos, rect.top() + DescrYOffs ) );
168 return hlp;
171 void eEPGSelector::fillEPGList()
173 eService *service=eDVB::getInstance()->settings->getTransponders()->searchService(current);
174 if (service)
175 setText(eString(_("EPG - "))+service->service_name);
176 eDebug("get EventMap for onid: %02x, sid: %02x", current.getOriginalNetworkID().get(), current.getServiceID().get());
178 eEPGCache::getInstance()->Lock();
179 const timeMap* evt = eEPGCache::getInstance()->getTimeMap(current);
180 timeMap::const_iterator It;
181 if (evt)
182 It = evt->begin();
184 int tsidonid = (current.getTransportStreamID().get()<<16)|current.getOriginalNetworkID().get();
185 if (current.data[0] == 5 ) // NVOD REF ENTRY
187 for (; It != evt->end(); It++)
189 EITEvent evt(*It->second,tsidonid); // NVOD Service Event
190 for (ePtrList<Descriptor>::iterator d(evt.descriptor); d != evt.descriptor.end(); ++d)
192 Descriptor *descr=*d;
193 // dereference only TimeShiftedEventDescriptor specific data when the Tag is okay...
194 if (descr->Tag()==DESCR_TIME_SHIFTED_EVENT)
196 TimeShiftedEventDescriptor *descriptor = (TimeShiftedEventDescriptor*) descr;
197 // eServiceReferenceDVB ref( current.getTransportStreamID().get(), current.getOriginalNetworkID().get(), descriptor->reference_event_id, 4 );
198 const timeMap *parent = eEPGCache::getInstance()->getTimeMap(eZapMain::getInstance()->refservice);
199 timeMap::const_iterator pIt;
200 if ( parent )
202 pIt = parent->find( descriptor->reference_event_id );
203 if ( pIt != parent->end() ) // event found..
205 // build EITEvent with short and ext description )
206 EITEvent e(*pIt->second,tsidonid);
207 // do not delete ePtrListEntrys..
208 e.descriptor.setAutoDelete(false);
209 e.start_time = evt.start_time;
210 e.duration = evt.duration;
211 e.event_id = evt.event_id;
212 e.free_CA_mode = evt.free_CA_mode;
213 e.running_status = evt.running_status;
214 new eListBoxEntryEPG(e, events, current );
215 break;
222 #if 0
223 else if (current.data[0] == 4 ) //NVOD
225 for (; It != evt->end(); It++)
227 EITEvent evt(*It->second); // NVOD Service Event
229 const std::list<NVODReferenceEntry> *RefList = eEPGCache::getInstance()->getNVODRefList( (eServiceReferenceDVB&)current );
230 if (RefList)
232 for (std::list<NVODReferenceEntry>::const_iterator it( RefList->begin() ); it != RefList->end(); it++ )
234 eServiceReferenceDVB ref( ((eServiceReferenceDVB&)current).getDVBNamespace(), it->transport_stream_id, it->original_network_id, it->service_id, 5 );
235 const timeMap *eMap = eEPGCache::getInstance()->getTimeMap( ref );
236 if (eMap)
238 for ( timeMap::const_iterator refIt( eMap->begin() ); refIt != eMap->end(); refIt++)
240 EITEvent refEvt(*refIt->second);
241 for (ePtrList<Descriptor>::iterator d(refEvt.descriptor); d != refEvt.descriptor.end(); ++d)
243 Descriptor *descriptor=*d;
244 if (descriptor->Tag()==DESCR_TIME_SHIFTED_EVENT)
246 if ( ((TimeShiftedEventDescriptor*)descriptor)->reference_event_id == evt.event_id)
248 // make copy of ref Event ( then we habe begintime and duration )
249 EITEvent e(*It->second);
250 // do not delete ePtrListEntrys..
251 e.descriptor.setAutoDelete(false);
252 e.start_time = refEvt.start_time;
253 e.duration = refEvt.duration;
254 e.event_id = refEvt.event_id;
255 e.free_CA_mode = refEvt.free_CA_mode;
256 e.running_status = refEvt.running_status;
257 new eListBoxEntryEPG(e, events, ref);
258 break;
268 #endif
269 else for (It = evt->begin(); It != evt->end(); It++)
270 new eListBoxEntryEPG(*It->second, events, current);
271 eEPGCache::getInstance()->Unlock();
274 void eEPGSelector::entrySelected(eListBoxEntryEPG *entry)
276 eDVBServiceController *sapi=eDVB::getInstance()->getServiceAPI();
278 if (!entry || !sapi)
279 close(0);
280 else
282 int ret;
283 hide();
284 eService *service=eDVB::getInstance()->settings->getTransponders()->searchService(current);
285 eEventDisplay ei(service ? service->service_name.c_str() : "", current, 0, &entry->event);
286 #ifndef DISABLE_LCD
287 ei.setLCD(LCDTitle, LCDElement);
288 #endif
289 ei.show();
290 while((ret = ei.exec()))
292 eListBoxEntryEPG* tmp;
294 if (ret == 1)
295 tmp=events->goPrev();
296 else if (ret == 2)
297 tmp=events->goNext();
298 else
299 break; // close EventDisplay
301 if (tmp)
302 ei.setEvent(&tmp->event);
304 ei.hide();
305 show();
309 eEPGSelector::eEPGSelector(const eServiceReferenceDVB &service)
310 :eWindow(0), current(service)
312 events = new eListBox<eListBoxEntryEPG>(this);
313 events->setName("events");
314 events->setActiveColor(eSkin::getActive()->queryScheme("eServiceSelector.highlight.background"), eSkin::getActive()->queryScheme("eServiceSelector.highlight.foreground"));
316 if (eSkin::getActive()->build(this, "eEPGSelector"))
317 eWarning("EPG selector widget build failed!");
319 CONNECT(events->selected, eEPGSelector::entrySelected);
320 fillEPGList();
321 addActionMap( &i_epgSelectorActions->map );
322 #ifndef DISABLE_FILE
323 addActionToHelpList( &i_epgSelectorActions->addDVRTimerEvent );
324 #endif
325 #ifndef DISABLE_NETWORK
326 addActionToHelpList( &i_epgSelectorActions->addNGRABTimerEvent );
327 #endif
328 addActionToHelpList( &i_epgSelectorActions->addSwitchTimerEvent );
329 addActionToHelpList( &i_epgSelectorActions->removeTimerEvent );
330 setHelpID(12);
333 int eEPGSelector::eventHandler(const eWidgetEvent &event)
335 int addtype=-1;
336 switch (event.type)
338 case eWidgetEvent::evtAction:
339 if ( (addtype = i_epgSelectorActions->checkTimerActions( event.action )) != -1 )
341 else if (event.action == &i_epgSelectorActions->removeTimerEvent)
343 if ( eTimerManager::getInstance()->removeEventFromTimerList( this, &current, &events->getCurrent()->event ) )
344 events->invalidateCurrent();
346 else if (event.action == &i_epgSelectorActions->showExtendedInfo)
347 entrySelected(events->getCurrent());
348 else
349 break;
350 if (addtype != -1)
352 if ( !eTimerManager::getInstance()->eventAlreadyInList( this, events->getCurrent()->event, events->getCurrent()->service) )
354 hide();
355 eTimerEditView v( events->getCurrent()->event, addtype, events->getCurrent()->service);
356 v.show();
357 v.exec();
358 v.hide();
359 invalidate();
360 show();
363 return 1;
364 default:
365 break;
367 return eWindow::eventHandler(event);
370 /* search for the presence of language from given EIT event descriptors*/
371 bool LocalEventData::language_exists(EITEvent *event, eString lang)
373 ShortEventName=ExtendedEventText=ShortEventText="";
374 bool retval=0;
375 for (ePtrList<Descriptor>::iterator descriptor(event->descriptor); descriptor != event->descriptor.end(); ++descriptor)
377 if (descriptor->Tag() == DESCR_SHORT_EVENT)
379 ShortEventDescriptor *ss = (ShortEventDescriptor*)*descriptor;
380 if (!lang || !strncmp(lang.c_str(), ss->language_code, 3) )
382 ShortEventName=ss->event_name;
383 ShortEventText=ss->text;
384 retval=1;
387 else if (descriptor->Tag() == DESCR_EXTENDED_EVENT)
389 ExtendedEventDescriptor *ss = (ExtendedEventDescriptor*)*descriptor;
390 if (!lang || !strncmp(lang.c_str(), ss->language_code, 3) )
392 ExtendedEventText += ss->text;
393 retval=1;
397 return retval;
400 const char MAX_LANG = 37;
401 /* OSD language (see /share/locales/locales) to iso639 conversion table */
402 eString ISOtbl[MAX_LANG][2] =
404 {"ar_AE","ara"},
405 {"C","eng"},
406 {"cs_CZ","ces"}, /* or 'cze' */
407 {"cs_CZ","cze"},
408 {"da_DK","dan"},
409 {"de_DE","deu"}, /* also 'ger' is valid iso639 code!! */
410 {"de_DE","ger"},
411 {"el_GR","gre"}, /* also 'ell' is valid */
412 {"el_GR","ell"},
413 {"es_ES","esl"}, /* also 'spa' is ok */
414 {"es_ES","spa"},
415 {"et_EE","est"},
416 {"fi_FI","fin"},
417 {"fr_FR","fra"},
418 {"hr_HR","hrv"}, /* or 'scr' */
419 {"hr_HR","scr"},
420 {"hu_HU","hun"},
421 {"is_IS","isl"}, /* or 'ice' */
422 {"is_IS","ice"},
423 {"it_IT","ita"},
424 {"lt_LT","lit"},
425 {"nl_NL","nld"}, /* or 'dut' */
426 {"nl_NL","dut"},
427 {"no_NO","nor"},
428 {"pl_PL","pol"},
429 {"pt_PT","por"},
430 {"ro_RO","ron"}, /* or 'rum' */
431 {"ro_RO","rum"},
432 {"ru_RU","rus"},
433 {"sk_SK","slk"}, /* or 'slo' */
434 {"sk_SK","slo"},
435 {"sl_SI","slv"},
436 {"sr_YU","srp"}, /* or 'scc' */
437 {"sr_YU","scc"},
438 {"sv_SE","swe"},
439 {"tr_TR","tur"},
440 {"ur_IN","urd"}
443 LocalEventData::LocalEventData()
445 if ( !country )
447 char *str=0;
448 eConfig::getInstance()->getKey("/elitedvb/language", str); // fetch selected OSD country
449 if (!str)
450 eDebug("No OSD-language found!");
451 else
453 country=str;
454 free(str);
455 for (int i=0; i < MAX_LANG; i++)
456 if (country==ISOtbl[i][0])
457 if (!primary_language)
458 primary_language=ISOtbl[i][1];
459 else
460 secondary_language=ISOtbl[i][1];
462 #if 0
463 if ( country )
464 eDebug("Country = %s",country.c_str());
465 if ( primary_language )
466 eDebug("Primary Language = %s",primary_language.c_str());
467 if ( secondary_language )
468 eDebug("Secondary Language = %s",secondary_language.c_str());
469 #endif
473 /* short event name, short event text and extended event text */
474 void LocalEventData::getLocalData(EITEvent *event, eString *name, eString *desc, eString *text)
476 if (!language_exists(event,primary_language))
477 if (!language_exists(event,secondary_language))
478 if (!language_exists(event,"eng"))
479 language_exists(event,0);
480 if ( name )
481 *name=ShortEventName;
482 if ( desc )
483 *desc=ShortEventText;
484 if ( text )
485 *text=ExtendedEventText;