/* Neutrino-GUI - DBoxII-Project Copyright (C) 2001 Steffen Hehn 'McClean' Homepage: http://dbox.cyberphoria.org/ Copyright (C) 2009-2016 Stefan Seyfried License: GPL This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include "eventlist.h" #include "epgplus.h" #include "epgview.h" #include "followscreenings.h" #include "moviebrowser/mb.h" #include "timerlist.h" #include "user_menue.h" #include "widget/icons.h" #include "widget/msgbox.h" #include "widget/mountchooser.h" #include "pictureviewer.h" #include "widget/hintbox.h" #include "widget/buttons.h" #include "bouquetlist.h" #include "widget/stringinput.h" #include "widget/keyboard_input.h" #include #include #include #include #include #include #include #include #include #include #include #include extern CBouquetList * bouquetList; extern CRemoteControl *g_RemoteControl; /* neutrino.cpp */ extern CPictureViewer * g_PicViewer; #if 0 // sort operators bool sortById (const CChannelEvent& a, const CChannelEvent& b) { return a.eventID < b.eventID ; } inline static bool sortbyEventid (const CChannelEvent& a, const CChannelEvent& b) { return (a.channelID == b.channelID && a.eventID == b.eventID && a.startTime == b.startTime); } #endif inline bool sortByDescription (const CChannelEvent& a, const CChannelEvent& b) { if(a.description == b.description) return a.startTime < b.startTime; else return a.description < b.description ; } inline static bool sortByDateTime (const CChannelEvent& a, const CChannelEvent& b) { return a.startTime < b.startTime; } CEventList::CEventList() { frameBuffer = CFrameBuffer::getInstance(); selected = 0; current_event = 0; liststart = 0; sort_mode = 0; m_search_list = SEARCH_LIST_NONE; m_search_epg_item = SEARCH_EPG_TITLE; m_search_channel_id = 1; m_search_bouquet_id= 1; m_search_genre = 1; m_search_fsk = 1; full_width = width = 0; height = 0; x = y = 0; infozone = NULL; infozone_text = ""; item_event_ID = 0; oldIndex = -1; oldEventID = -1; infozone_background = false; header = NULL; pb = NULL; navibar = NULL; footer = NULL; } CEventList::~CEventList() { ResetModules(); } void CEventList::ResetModules() { if (header){ delete header; header = NULL; } if (navibar){ delete navibar; navibar = NULL; } if (pb){ delete pb; pb = NULL; } if (footer){ delete footer; footer = NULL; } } void CEventList::UpdateTimerList(void) { timerlist.clear(); g_Timerd->getTimerList (timerlist); CTimerList *Timerlist = new CTimerList; Timerlist->RemoteBoxTimerList(timerlist); sort(timerlist.begin(), timerlist.end()); delete Timerlist; } // Function: HasTimerConflicts // search for timer conflicts for given time // return: true if found any conflict, you can watch with parameter epg_ID bool CEventList::HasTimerConflicts(time_t starttime, time_t duration, t_event_id *epg_ID) { for(uint i= 0; i < timerlist.size(); i++) { if(timerlist[i].stopTime > starttime-timerPre && timerlist[i].alarmTime < starttime+duration+timerPost) { *epg_ID = timerlist[i].epg_id; return true; } } *epg_ID = 0; return false; } void CEventList::readEvents(const t_channel_id channel_id) { CEitManager::getInstance()->getEventsServiceKey(channel_id , evtlist); time_t azeit=time(NULL); CChannelEventList::iterator e; if ( !evtlist.empty() ) { CEPGData epgData; // todo: what if there are more than one events in the Portal if (CEitManager::getInstance()->getActualEPGServiceKey(channel_id, &epgData )) { // epgData.eventID; // epgData.epg_times.startzeit; CSectionsdClient::LinkageDescriptorList linkedServices; if (CEitManager::getInstance()->getLinkageDescriptorsUniqueKey( epgData.eventID, linkedServices ) ) { if ( linkedServices.size()> 1 ) { CChannelEventList evtlist2; // stores the temporary eventlist of the subchannel channelid t_channel_id channel_id2; #if 0 for (e=evtlist.begin(); e!=evtlist.end(); ++e ) { if ( e->startTime > azeit ) { break; } } // next line is to have a valid e if (evtlist.end() == e) --e; #endif for (unsigned int i=0; igetEventsServiceKey(channel_id2 , evtlist2); for (unsigned int loop=0 ; loop= azeit) /*&& (evtlist2[loop].startTime < e->startTime + (int)e->duration)*/ ) #endif { //FIXME: bad ?evtlist2[loop].sub = true; evtlist.push_back(evtlist2[loop]); } } evtlist2.clear(); } } } } } // Houdini added for Private Premiere EPG, start sorted by start date/time sort(evtlist.begin(),evtlist.end(),sortByDateTime); UpdateTimerList(); } current_event = (unsigned int)-1; for ( e=evtlist.begin(); e!=evtlist.end(); ++e ) { if ( e->startTime > azeit ) { break; } current_event++; } if ( evtlist.empty() ) { CChannelEvent evt; evt.description = g_Locale->getText(LOCALE_EPGLIST_NOEVENTS); evt.eventID = 0; evt.channelID = 0; evt.startTime = 0; evt.duration = 0; evtlist.push_back(evt); } if (current_event == (unsigned int)-1) current_event = 0; selected= current_event; return; } void CEventList::getChannelNames(t_channel_id &channel_id, std::string ¤t_channel_name, std::string &prev_channel_name, std::string &next_channel_name, neutrino_msg_t msg) { if(bouquetList->Bouquets.empty()){ return; } t_bouquet_id current_bouquet_id = bouquetList->getActiveBouquetNumber(); const unsigned int channel_nr = bouquetList->Bouquets[current_bouquet_id]->channelList->getSize(); if(channel_nr < 2){ channel_id = 0; return; } unsigned int tmp_channel = 0; for(unsigned int channel = 0; channel < channel_nr; channel++) { t_channel_id channel_id_tmp = bouquetList->Bouquets[current_bouquet_id]->channelList->getChannelFromIndex(channel)->getChannelID(); if(channel_id_tmp == channel_id){ if ( msg==CRCInput::RC_right || msg==CRCInput::RC_forward ) { channel = (channel+1) %channel_nr; }else if ( msg==CRCInput::RC_left || msg==CRCInput::RC_rewind ){ //RC_rewind channel = (channel == 0) ? channel_nr -1 : channel - 1; } channel_id = bouquetList->Bouquets[current_bouquet_id]->channelList->getChannelFromIndex(channel)->getChannelID(); current_channel_name = CServiceManager::getInstance()->GetServiceName(channel_id); tmp_channel = (channel == 0) ? channel_nr - 1 : channel - 1; channel_id_tmp = bouquetList->Bouquets[current_bouquet_id]->channelList->getChannelFromIndex(tmp_channel)->getChannelID(); prev_channel_name = CServiceManager::getInstance()->GetServiceName(channel_id_tmp); tmp_channel = (channel+1) %channel_nr; channel_id_tmp = bouquetList->Bouquets[current_bouquet_id]->channelList->getChannelFromIndex(tmp_channel)->getChannelID(); next_channel_name = CServiceManager::getInstance()->GetServiceName(channel_id_tmp); break; } } } int CEventList::exec(const t_channel_id channel_id, const std::string& channelname, const std::string& channelname_prev, const std::string& channelname_next,const CChannelEventList &followlist) // UTF-8 { neutrino_msg_t msg; neutrino_msg_data_t data; bool in_search = false; showfollow = false; t_channel_id epg_id = channel_id; CZapitChannel * ch = CServiceManager::getInstance()->FindChannel(channel_id); if (ch) epg_id = ch->getEpgID(); full_width = frameBuffer->getWindowWidth(); x = getScreenStartX(full_width); if (g_settings.eventlist_additional) width = full_width / 3 * 2; else width = full_width; height = frameBuffer->getWindowHeight(); // Calculate header_height header_height = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight(); footer_height = header_height; const int pic_h = 39; header_height = std::max(header_height, pic_h); largefont_height = g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_ITEMLARGE]->getHeight(); { int h1 = g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_ITEMSMALL]->getHeight(); int h2 = g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_DATETIME]->getHeight(); smallfont_height = std::max(h1, h2); } unit_short_minute = g_Locale->getText(LOCALE_UNIT_SHORT_MINUTE); item_height = smallfont_height + OFFSET_INNER_MIN + largefont_height; navibar_height = largefont_height+2*OFFSET_INNER_MIN; listmaxshow = (height - header_height - footer_height - OFFSET_SHADOW - navibar_height)/item_height; height = header_height + footer_height + OFFSET_SHADOW + navibar_height + listmaxshow*item_height; // recalc height y = getScreenStartY(height); // calculate width of right info_zone infozone_width = full_width - width; // init right info_zone if ((g_settings.eventlist_additional) && (infozone == NULL)) infozone = new CComponentsText(x+width+OFFSET_INNER_MID, y + header_height, infozone_width-2*OFFSET_INNER_MID, listmaxshow*item_height); int res = menu_return::RETURN_REPAINT; //printf("CEventList::exec: channel_id %llx\n", channel_id); if(m_search_list == SEARCH_LIST_NONE) // init globals once only { m_search_epg_item = SEARCH_EPG_TITLE; //m_search_keyword = ""; m_search_list = SEARCH_LIST_CHANNEL; //m_search_channel_id = channel_id; m_search_bouquet_id= bouquetList->getActiveBouquetNumber(); //m_search_source_text = ""; } m_search_channel_id = channel_id; m_showChannel = false; // do not show the channel in normal mode, we just need it in search mode sort_mode=0; COSDFader fader(g_settings.theme.menu_Content_alpha); fader.StartFadeIn(); if(!followlist.empty()){ std::insert_iterator >ii(evtlist,evtlist.begin()); copy(followlist.begin(), followlist.end(), ii); showfollow = true; }else{ readEvents(epg_id); } UpdateTimerList(); g_Timerd->getRecordingSafety(timerPre,timerPost); bool dont_hide = false; paintHead(channel_id, channelname, channelname_prev, channelname_next); paint(channel_id); paintFoot(channel_id); int oldselected = selected; int timeout = g_settings.timing[SNeutrinoSettings::TIMING_EPG]; uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(timeout); bool loop = true; while (loop) { g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd); if ( msg <= CRCInput::RC_MaxRC ) timeoutEnd = CRCInput::calcTimeoutEnd(timeout); if((msg == NeutrinoMessages::EVT_TIMER) && (data == fader.GetFadeTimer())) { if(fader.FadeDone()) loop = false; } else if (msg == CRCInput::RC_timeout) { selected = oldselected; if(fader.StartFadeOut()) { timeoutEnd = CRCInput::calcTimeoutEnd(1); msg = 0; } else loop = false; } //manage painting of function bar during scrolling, depends of timerevent types if (msg == CRCInput::RC_up || (int) msg == g_settings.key_pageup || msg == CRCInput::RC_down || (int) msg == g_settings.key_pagedown) { int prev_selected = selected; int new_sel = UpDownKey(evtlist, msg, listmaxshow, selected); if (new_sel >= 0) { selected = new_sel; paintDescription(selected); } paintItem(prev_selected - liststart, channel_id); unsigned int oldliststart = liststart; liststart = (selected/listmaxshow)*listmaxshow; if(oldliststart!=liststart) paint(channel_id); else paintItem(selected - liststart, channel_id); paintFoot(channel_id); } //sort else if (!showfollow && (msg == (neutrino_msg_t)g_settings.key_channelList_sort)) { uint64_t selected_id = evtlist[selected].eventID; if(sort_mode==0) { sort_mode++; sort(evtlist.begin(),evtlist.end(),sortByDescription); } #if 0 else if(sort_mode==1) { sort_mode++; sort(evtlist.begin(),evtlist.end(),sortById); } #endif else { sort_mode=0; sort(evtlist.begin(),evtlist.end(),sortByDateTime); } // find selected for ( selected=0 ; selected < evtlist.size(); selected++ ) { if ( evtlist[selected].eventID == selected_id ) break; } oldselected=selected; if(selected <=listmaxshow) liststart=0; else liststart=(selected/listmaxshow)*listmaxshow; paint(channel_id); } // -- I commented out the following part (code is working) // -- reason: this is a little bit confusing, because e.g. you can enter the function // -- with RED, but pressing RED doesn't leave - it triggers a record timer instead // -- I think it's sufficient, to press RIGHT or HELP to get movie details and then // -- press "auto record" or "auto switch" (rasc 2003-06-28) // --- hm, no need to comment out that part, leave the decision to the user // --- either set addrecord timer key to "no key" and leave eventlist with red (default now), // --- or set addrecord timer key to "red key" (zwen 2003-07-29) else if ((msg == (neutrino_msg_t)g_settings.key_channelList_addrecord) && !g_settings.minimode) { if (g_settings.recording_type != CNeutrinoApp::RECORDING_OFF) { int tID = -1; CTimerd::CTimerEventTypes etype = isScheduled(evtlist[selected].channelID, &evtlist[selected], &tID); if(etype == CTimerd::TIMER_RECORD) //remove timer event { g_Timerd->removeTimerEvent(tID); UpdateTimerList(); paint(evtlist[selected].channelID); paintFoot(evtlist[selected].channelID); continue; } std::string recDir = g_settings.network_nfs_recordingdir; if (g_settings.recording_choose_direct_rec_dir) { int id = -1; CMountChooser recDirs(LOCALE_TIMERLIST_RECORDING_DIR,NEUTRINO_ICON_SETTINGS,&id,NULL,g_settings.network_nfs_recordingdir.c_str()); if (recDirs.hasItem()) { hide(); recDirs.exec(NULL,""); paint(evtlist[selected].channelID); timeoutEnd = CRCInput::calcTimeoutEnd(timeout); } else { printf("[CEventList] no network devices available\n"); } if (id != -1) recDir = g_settings.network_nfs[id].local_dir; else recDir = ""; } bool doRecord = true; if (g_settings.recording_already_found_check) { CHintBox loadBox(LOCALE_RECORDING_ALREADY_FOUND_CHECK, LOCALE_MOVIEBROWSER_SCAN_FOR_MOVIES); loadBox.paint(); CMovieBrowser moviebrowser; const char *rec_title = evtlist[selected].description.c_str(); bool already_found = moviebrowser.gotMovie(rec_title); loadBox.hide(); if (already_found) { printf("already found in moviebrowser: %s\n", rec_title); char message[1024]; snprintf(message, sizeof(message)-1, g_Locale->getText(LOCALE_RECORDING_ALREADY_FOUND), rec_title); doRecord = (ShowMsg(LOCALE_RECORDING_ALREADY_FOUND_CHECK, message, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbNo) == CMsgBox::mbrYes); } } t_channel_id used_id = IS_WEBCHAN(channel_id) ? channel_id : evtlist[selected].channelID; if (!recDir.empty() && doRecord) //add/remove recording timer events and check/warn for conflicts { CFollowScreenings m(used_id, evtlist[selected].startTime, evtlist[selected].startTime + evtlist[selected].duration, evtlist[selected].description, evtlist[selected].eventID, TIMERD_APIDS_CONF, true, "", &evtlist, false); m.exec(NULL, ""); timeoutEnd = CRCInput::calcTimeoutEnd(timeout); } UpdateTimerList(); paint(used_id); paintFoot(used_id); } } else if ( msg == (neutrino_msg_t) g_settings.key_channelList_addremind )//add/remove zapto timer event { int tID = -1; CTimerd::CTimerEventTypes etype = isScheduled(evtlist[selected].channelID, &evtlist[selected], &tID); if(etype == CTimerd::TIMER_ZAPTO) { g_Timerd->removeTimerEvent(tID); UpdateTimerList(); paint(evtlist[selected].channelID); paintFoot(evtlist[selected].channelID); continue; } g_Timerd->addZaptoTimerEvent(IS_WEBCHAN(channel_id) ? channel_id : evtlist[selected].channelID, evtlist[selected].startTime - (g_settings.zapto_pre_time * 60), evtlist[selected].startTime - ANNOUNCETIME - (g_settings.zapto_pre_time * 60), 0, evtlist[selected].eventID, evtlist[selected].startTime, 0); //ShowMsg(LOCALE_TIMER_EVENTTIMED_TITLE, LOCALE_TIMER_EVENTTIMED_MSG, CMsgBox::mbrBack, CMsgBox::mbBack, NEUTRINO_ICON_INFO); UpdateTimerList(); paint(evtlist[selected].channelID ); paintFoot(evtlist[selected].channelID ); timeoutEnd = CRCInput::calcTimeoutEnd(timeout); } else if (msg == (neutrino_msg_t)g_settings.key_channelList_cancel) { if(in_search) { in_search = false; m_showChannel = false; paintHead(channel_id, channelname); readEvents(epg_id); paint(channel_id); paintFoot(channel_id); } else { selected = oldselected; if(fader.StartFadeOut()) { timeoutEnd = CRCInput::calcTimeoutEnd(1); msg = 0; } else loop = false; } } else if ( msg==CRCInput::RC_red ){ loop= false; } else if ( msg==CRCInput::RC_left || msg==CRCInput::RC_right || msg==CRCInput::RC_rewind || msg==CRCInput::RC_forward ) { // maybe remove RC_rewind and RC_forward in the future? std::string next_channel_name, prev_channel_name, current_channel_name; t_channel_id _channel_id = channel_id; getChannelNames(_channel_id, current_channel_name, prev_channel_name, next_channel_name, msg); if(_channel_id){ infozone_background = false; loop = false; dont_hide = true; exec(_channel_id, current_channel_name, prev_channel_name, next_channel_name); } } else if (msg == CRCInput::RC_timer || msg == CRCInput::RC_program || msg == CRCInput::RC_0) { hide(); CTimerList *Timerlist = new CTimerList; Timerlist->exec(NULL, ""); delete Timerlist; UpdateTimerList(); paintHead(channel_id, channelname); oldIndex = -1; oldEventID = -1; infozone_background = false; paint(channel_id); paintFoot(channel_id); timeoutEnd = CRCInput::calcTimeoutEnd(timeout); } else if (msg == CRCInput::RC_epg) { if (g_settings.eventlist_epgplus) { hide(); CEPGplusHandler eplus; eplus.exec(NULL, ""); loop = false; } } else if (msg==CRCInput::RC_help || msg==CRCInput::RC_ok || msg==CRCInput::RC_info) { if ( evtlist[selected].eventID != 0 ) { hide(); //FIXME res = g_EpgData->show(evtlist[selected].sub ? GET_CHANNEL_ID_FROM_EVENT_ID(evtlist[selected].eventID) : channel_id, evtlist[selected].eventID, &evtlist[selected].startTime); res = g_EpgData->show(evtlist[selected].channelID, evtlist[selected].eventID, &evtlist[selected].startTime, true, showfollow ); if ( res == menu_return::RETURN_EXIT_ALL ) { loop = false; } else { //FIXME why getMsg ? g_RCInput->getMsg( &msg, &data, 0 ); if ( ( msg != CRCInput::RC_red ) && ( msg != CRCInput::RC_timeout ) ) { // RC_red schlucken g_RCInput->postMsg( msg, data ); } /* in case timer was added in g_EpgData */ UpdateTimerList(); paintHead(channel_id, in_search ? search_head_name : channelname); oldIndex = -1; oldEventID = -1; infozone_background = false; paint(channel_id); paintFoot(channel_id); timeoutEnd = CRCInput::calcTimeoutEnd(timeout); } } } else if (!showfollow && ( msg==CRCInput::RC_green )) { oldIndex = -1; oldEventID = -1; infozone_background = false; in_search = findEvents(channel_id, channelname); timeoutEnd = CRCInput::calcTimeoutEnd(timeout); } else if (CNeutrinoApp::getInstance()->listModeKey(msg)) { g_RCInput->postMsg (msg, 0); res = menu_return::RETURN_EXIT_ALL; loop = false; } else if (msg == NeutrinoMessages::EVT_SERVICESCHANGED || msg == NeutrinoMessages::EVT_BOUQUETSCHANGED) { g_RCInput->postMsg(msg, data); loop = false; res = menu_return::RETURN_EXIT_ALL; } else { if ( CNeutrinoApp::getInstance()->handleMsg( msg, data ) & messages_return::cancel_all ) { loop = false; res = menu_return::RETURN_EXIT_ALL; } } } if (infozone) delete infozone; infozone = NULL; oldIndex = -1; oldEventID = -1; infozone_background = false; if(!dont_hide){ hide(); fader.StopFade(); } return res; } void CEventList::hide() { ResetModules(); frameBuffer->paintBackgroundBoxRel(x, y, full_width + OFFSET_SHADOW, height + OFFSET_SHADOW); } CTimerd::CTimerEventTypes CEventList::isScheduled(t_channel_id channel_id, CChannelEvent * event, int * tID) { CTimerd::TimerList::iterator timer = timerlist.begin(); for(; timer != timerlist.end(); ++timer) { if(timer->channel_id == channel_id && (timer->eventType == CTimerd::TIMER_ZAPTO || timer->eventType == CTimerd::TIMER_RECORD || timer->eventType == CTimerd::TIMER_REMOTEBOX)) { if(timer->epg_id == event->eventID) { if(timer->epg_starttime == event->startTime) { bool isTimeShiftTimer = false; if( timer->eventType == CTimerd::TIMER_RECORD){ isTimeShiftTimer = CRecordManager::getInstance()->CheckRecordingId_if_Timeshift(timer->eventID); } if(tID) *tID = timer->eventID; if(isTimeShiftTimer)//skip TSHIFT RECORD continue; return timer->eventType; } } } } return (CTimerd::CTimerEventTypes) 0; } void CEventList::paintItem(unsigned int pos, t_channel_id channel_idI) { int ypos = y + header_height + pos*item_height; unsigned int currpos = liststart + pos; bool i_selected = currpos == selected; bool i_marked = currpos == current_event; int i_radius = RADIUS_NONE; fb_pixel_t color; fb_pixel_t bgcolor; getItemColors(color, bgcolor, i_selected, i_marked); if (i_selected || i_marked) i_radius = RADIUS_LARGE; if (i_radius) frameBuffer->paintBoxRel(x, ypos, width - SCROLLBAR_WIDTH, item_height, COL_MENUCONTENT_PLUS_0); frameBuffer->paintBoxRel(x, ypos, width - SCROLLBAR_WIDTH, item_height, bgcolor, i_radius); if(currposgetText(CLocaleManager::getWeekday(tmStartZeit)); datetime_str += strftime(", %H:%M", tmStartZeit); datetime_str += strftime(", %d", tmStartZeit); datetime_str += g_Locale->getText(CLocaleManager::getMonth(tmStartZeit)); if ( m_showChannel ) // show the channel if we made a event search only (which could be made through all channels ). { t_channel_id channel = evtlist[currpos].channelID; datetime_str += " "; datetime_str += CServiceManager::getInstance()->GetServiceName(channel); } snprintf(tmpstr,sizeof(tmpstr), "[%d %s]", evtlist[currpos].duration / 60, unit_short_minute); duration_str = tmpstr; } // 1st line int datetime_width = g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_DATETIME]->getRenderWidth(datetime_str); int duration_width = g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_ITEMSMALL]->getRenderWidth(duration_str); g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_DATETIME]->RenderString(x + OFFSET_INNER_SMALL, ypos + OFFSET_INNER_MIN + smallfont_height, datetime_width, datetime_str, color); int seit = ( evtlist[currpos].startTime - time(NULL) ) / 60; if ( (seit> 0) && (seit<100) && (!duration_str.empty()) ) { char beginnt[100]; snprintf(beginnt, sizeof(beginnt), "%s %d %s", g_Locale->getText(LOCALE_WORD_IN), seit, unit_short_minute); int w = g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_ITEMSMALL]->getRenderWidth(beginnt); g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_ITEMSMALL]->RenderString(x + width - SCROLLBAR_WIDTH - 2*OFFSET_INNER_MID - duration_width - w, ypos + OFFSET_INNER_MIN + smallfont_height, w, beginnt, color); } g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_ITEMSMALL]->RenderString(x + width - SCROLLBAR_WIDTH - OFFSET_INNER_MID - duration_width, ypos + OFFSET_INNER_MIN + smallfont_height, duration_width, duration_str, color); // 2nd line // set status icons t_channel_id channel_tmp = m_showChannel ? evtlist[currpos].channelID : channel_idI; int timerID = -1; CTimerd::CTimerEventTypes etype = isScheduled(channel_tmp, &evtlist[currpos],&timerID); const char *icontype = NULL; if (etype == CTimerd::TIMER_ZAPTO) icontype = NEUTRINO_ICON_MARKER_ZAP; else if (etype == CTimerd::TIMER_RECORD) icontype = NEUTRINO_ICON_MARKER_RECORD; else if (etype == CTimerd::TIMER_REMOTEBOX) icontype = NEUTRINO_ICON_MARKER_RECORD_GRAY; // do we need another icon for remote timers? else { if (timerID > 0 && CRecordManager::getInstance()->CheckRecordingId_if_Timeshift(timerID)) icontype = NEUTRINO_ICON_MARKER_TIMESHIFT; } int iw = 0, ih = 0; if (icontype != NULL) { frameBuffer->getIconSize(icontype, &iw, &ih); frameBuffer->paintIcon(icontype, x + OFFSET_INNER_MID, ypos + OFFSET_INNER_MIN + smallfont_height, largefont_height); iw += OFFSET_INNER_MID; } // detecting timer conflict and set start position of event text depending of possible painted icon bool conflict = HasTimerConflicts(evtlist[currpos].startTime, evtlist[currpos].duration, &item_event_ID); //printf("etype %d , conflicts %d -> %s, conflict event_ID %lld -> current event_ID %lld\n", etype, conflict, evtlist[currpos].description.c_str(), item_event_ID, evtlist[currpos].eventID); int i2w = 0, i2h = 0; if (conflict && item_event_ID != evtlist[currpos].eventID) { //paint_warning = true; frameBuffer->getIconSize(NEUTRINO_ICON_MARKER_WARNING, &i2w, &i2h); frameBuffer->paintIcon(NEUTRINO_ICON_MARKER_WARNING, x + iw + OFFSET_INNER_MID, ypos + OFFSET_INNER_MIN + smallfont_height, largefont_height); iw += i2w + OFFSET_INNER_MID; } // paint 2nd line text g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_ITEMLARGE]->RenderString(x + iw + OFFSET_INNER_MID, ypos + item_height, width - iw - 2*OFFSET_INNER_MID, evtlist[currpos].description, color); showProgressBar(currpos); } } void CEventList::paintDescription(int index) { if (!g_settings.eventlist_additional) return; if (evtlist[index].eventID == oldEventID) { if (oldEventID == 0) { if (index == oldIndex) return; } else return; } oldEventID = evtlist[index].eventID; oldIndex = index; CEPGData epgData; if ( evtlist[index].eventID != 0 ) CEitManager::getInstance()->getEPGid(evtlist[index].eventID, evtlist[index].startTime, &epgData); else CEitManager::getInstance()->getActualEPGServiceKey(evtlist[index].channelID, &epgData ); infozone_text = ""; if (!epgData.info1.empty() && !epgData.info2.empty() && (epgData.info2.find(epgData.info1) != 0)) { infozone_text += epgData.info1; infozone_text += "\n"; infozone_text += epgData.info2; } else if(!epgData.info2.empty()){ infozone_text = epgData.info2; } else if (!epgData.info1.empty()){ infozone_text = epgData.info1; } else infozone_text = g_Locale->getText(LOCALE_EPGLIST_NOEVENTS); if(!infozone_text.empty()) infozone_text = str_replace("\\n", "\n", infozone_text); infozone->setText(infozone_text, CTextBox::TOP, g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_EVENT]); infozone->doPaintBg(false); infozone->doPaintTextBoxBg(true); //FIXME infozone->enableShadow(CC_SHADOW_RIGHT, -1, true); infozone->forceTextPaint(); infozone->paint(CC_SAVE_SCREEN_NO); } void CEventList::paintHead(t_channel_id _channel_id, std::string _channelname, std::string _channelname_prev, std::string _channelname_next) { if (header == NULL){ header = new CComponentsHeader(); header->getTextObject()->enableTboxSaveScreen(g_settings.theme.menu_Head_gradient);//enable screen save for title text if color gradient is in use header->enableClock(); header->enableColBodyGradient(g_settings.theme.menu_Head_gradient, COL_MENUCONTENT_PLUS_0, g_settings.theme.menu_Head_gradient_direction); header->setDimensionsAll(x, y, full_width, header_height); header->enableShadow(CC_SHADOW_RIGHT | CC_SHADOW_CORNER_TOP_RIGHT | CC_SHADOW_CORNER_BOTTOM_RIGHT, -1, true); } //header->getClockObject()->setCorner(RADIUS_LARGE, CORNER_TOP_RIGHT); if (header->isPainted()) header->getChannelLogoObject()->hide(); if (g_settings.channellist_show_channellogo) header->setChannelLogo(_channel_id,_channelname, (CCHeaderTypes::cc_logo_alignment_t)g_settings.channellist_show_channellogo); header->setCaption(_channelname, CCHeaderTypes::CC_TITLE_LEFT); header->paint(CC_SAVE_SCREEN_NO); if(_channelname_prev.empty() && _channelname_next.empty()){ getChannelNames(_channel_id, _channelname, _channelname_prev, _channelname_next, 0); } paintNaviBar(_channelname_prev, _channelname_next); } void CEventList::paintNaviBar(std::string _channelname_prev, std::string _channelname_next) { int navibar_y = y + height - OFFSET_SHADOW - footer_height - navibar_height; if (!navibar) { navibar = new CNaviBar(x, navibar_y, full_width, navibar_height); navibar->setFont(g_Font[SNeutrinoSettings::FONT_TYPE_EVENTLIST_ITEMLARGE]); //FIXME navibar->enableShadow(CC_SHADOW_RIGHT, -1, true); } navibar->enableArrows(!_channelname_prev.empty(), !_channelname_next.empty()); navibar->setText(_channelname_prev, _channelname_next); navibar->paint(false); // shadow frameBuffer->paintBoxRel(x + full_width, navibar_y + OFFSET_SHADOW, OFFSET_SHADOW, navibar_height, COL_SHADOW_PLUS_0); } void CEventList::showProgressBar(int pos) { int epg_done= -1; if ((( time(NULL)- evtlist[pos].startTime )>= 0 ) && (evtlist[pos].duration > 0)) { unsigned nProcentagePassed = ((time(NULL) - evtlist[pos].startTime) * 100 / evtlist[pos].duration); if (nProcentagePassed<= 100) epg_done= nProcentagePassed; } if (!pb) { int pbw = full_width/10; int pbx = x + (full_width - pbw)/2; int pbh = navibar_height - 2*OFFSET_INNER_SMALL; int pby = y + height - OFFSET_SHADOW - footer_height - navibar_height + (navibar_height - pbh)/2; pb = new CProgressBar(pbx, pby, pbw, pbh); pb->setType(CProgressBar::PB_TIMESCALE); pb->doPaintBg(false); } //show progressbar if (epg_done > 0) { pb->setValues(epg_done, 100); pb->paint(true); } else { pb->hide(); } } void CEventList::paint(t_channel_id channel_id) { liststart = (selected/listmaxshow)*listmaxshow; // paint background for right box if (g_settings.eventlist_additional && !infozone_background) { frameBuffer->paintBoxRel(x + width,y + header_height, infozone_width, item_height*listmaxshow, COL_MENUCONTENT_PLUS_0); infozone_background = true; } for(unsigned int count=0; count < listmaxshow; count++) { paintItem(count, channel_id); } // paint content for right box paintDescription(selected); int total_pages; int current_page; getScrollBarData(&total_pages, ¤t_page, evtlist.size(), listmaxshow, selected); paintScrollBar(x + width - SCROLLBAR_WIDTH, y + header_height, SCROLLBAR_WIDTH, item_height*listmaxshow, total_pages, current_page); //FIXME shadow frameBuffer->paintBoxRel(x + full_width, y + header_height + OFFSET_SHADOW, OFFSET_SHADOW, item_height*listmaxshow, COL_SHADOW_PLUS_0); } void CEventList::paintFoot(t_channel_id channel_id) { CColorKeyHelper keyhelper; //user_menue.h neutrino_msg_t dummy = CRCInput::RC_nokey; const char * icon = NULL; struct button_label buttons[7]; //TODO dbt: add directly into footer object with setButtonLabels() int btn_cnt = 0; int tID = -1; //any value, not NULL CTimerd::CTimerEventTypes is_timer = isScheduled(channel_id, &evtlist[selected], &tID); // -- Button: Timer Record & Channelswitch if ((g_settings.recording_type != CNeutrinoApp::RECORDING_OFF) && ((uint) g_settings.key_channelList_addrecord != CRCInput::RC_nokey)) { if (!g_settings.minimode) { // FIXME : display other icons depending on g_settings.key_channelList_addrecord keyhelper.get(&dummy, &icon, g_settings.key_channelList_addrecord); buttons[btn_cnt].button = icon; if (is_timer == CTimerd::TIMER_RECORD) buttons[btn_cnt].locale = LOCALE_TIMERLIST_DELETE; else buttons[btn_cnt].locale = LOCALE_EVENTLISTBAR_RECORDEVENT; btn_cnt++; } } if(!showfollow){ buttons[btn_cnt].button = NEUTRINO_ICON_BUTTON_GREEN; buttons[btn_cnt].locale = LOCALE_EVENTFINDER_SEARCH; // search button btn_cnt++; } // Button: Timer Channelswitch if ((uint) g_settings.key_channelList_addremind != CRCInput::RC_nokey) { if (!g_settings.minimode) { // FIXME : display other icons depending on g_settings.key_channelList_addremind keyhelper.get(&dummy, &icon, g_settings.key_channelList_addremind); buttons[btn_cnt].button = icon; if (is_timer == CTimerd::TIMER_ZAPTO) buttons[btn_cnt].locale = LOCALE_TIMERLIST_DELETE; else buttons[btn_cnt].locale = LOCALE_EVENTLISTBAR_CHANNELSWITCH; btn_cnt++; } } if(!showfollow){ // Button: Event Re-Sort if ((uint) g_settings.key_channelList_sort != CRCInput::RC_nokey) { // FIXME : display other icons depending on g_settings.key_channelList_sort keyhelper.get(&dummy, &icon, g_settings.key_channelList_sort); buttons[btn_cnt].button = icon; buttons[btn_cnt].locale = LOCALE_EVENTLISTBAR_EVENTSORT; btn_cnt++; } } // info button if (evtlist[0].eventID != 0) { buttons[btn_cnt].button = NEUTRINO_ICON_BUTTON_INFO_SMALL; buttons[btn_cnt].locale = LOCALE_EPGMENU_EVENTINFO; btn_cnt++; } // epg button for epg-plus if (g_settings.eventlist_epgplus) { buttons[btn_cnt].button = NEUTRINO_ICON_BUTTON_EPG; buttons[btn_cnt].locale = LOCALE_EPGPLUS_HEAD; btn_cnt++; } // timerlist button buttons[btn_cnt].button = g_info.hw_caps->has_button_timer ? NEUTRINO_ICON_BUTTON_TIMER : NEUTRINO_ICON_BUTTON_0; buttons[btn_cnt].locale = LOCALE_TIMERLIST_NAME; btn_cnt++; // paint footer only on changed content if (!footer) { footer = new CComponentsFooter(); footer->enableShadow(CC_SHADOW_ON, -1, true); } size_t btn_size = 0; if (footer->getButtonChainObject()) { btn_size = footer->getButtonChainObject()->size(); if (btn_cnt == (int)btn_size) { for(size_t i=0; i < btn_size; i++) { CComponentsButton *btn = footer->getButtonLabel(i); if (g_Locale->getString(buttons[i].locale) != btn->getCaptionString()) { btn->setCaption(buttons[i].locale); btn->hide(); btn->paint(); } } } } if (!footer->isPainted() || btn_cnt != (int)btn_size) footer->paintButtons(x, y + height - OFFSET_SHADOW - footer_height, full_width, footer_height, btn_cnt, buttons); } // -- Eventlist Menu Handler Class // -- to be used for calls from Menu int CEventListHandler::exec(CMenuTarget* parent, const std::string &/*actionkey*/) { int res = menu_return::RETURN_EXIT_ALL; if (parent) parent->hide(); CEventList *e = new CEventList; CChannelList *channelList = CNeutrinoApp::getInstance()->channelList; e->exec(CZapit::getInstance()->GetCurrentChannelID(), channelList->getActiveChannelName()); delete e; return res; } bool CEventList::findEvents(t_channel_id channel_id, std::string channelname) { bool res = false; int event = 0; if((m_search_keyword.empty() || m_search_keyword == m_search_autokeyword) && evtlist[selected].eventID != 0) { m_search_keyword = evtlist[selected].description; m_search_autokeyword = m_search_keyword; } CEventFinderMenu menu(&event, &m_search_epg_item, &m_search_keyword, &m_search_list, &m_search_channel_id, &m_search_bouquet_id, &m_search_genre, &m_search_fsk); hide(); menu.exec(NULL,""); search_head_name = g_Locale->getText(LOCALE_EVENTFINDER_SEARCH); if (event == 1) { res = true; m_showChannel = true; // force the event list to paint the channel name if(!evtlist.empty()) evtlist.clear(); if(m_search_list == SEARCH_LIST_CHANNEL) { CEitManager::getInstance()->getEventsServiceKey(m_search_channel_id, evtlist, m_search_epg_item,m_search_keyword,false, m_search_genre,m_search_fsk); } else if(m_search_list == SEARCH_LIST_BOUQUET) { int channel_nr = bouquetList->Bouquets[m_search_bouquet_id]->channelList->getSize(); for(int channel = 0; channel < channel_nr; channel++) { channel_id = bouquetList->Bouquets[m_search_bouquet_id]->channelList->getChannelFromIndex(channel)->getChannelID(); CEitManager::getInstance()->getEventsServiceKey(channel_id, evtlist, m_search_epg_item,m_search_keyword,false, m_search_genre,m_search_fsk); } } else if(m_search_list == SEARCH_LIST_ALL) { CHintBox box(LOCALE_TIMING_EPG,g_Locale->getText(LOCALE_EVENTFINDER_SEARCHING)); box.paint(); std::vector v; int channel_nr = CNeutrinoApp::getInstance ()->channelList->getSize();//unique channelList TV or Radio for(int channel = 0; channel < channel_nr; channel++){ channel_id = CNeutrinoApp::getInstance ()->channelList->getChannelFromIndex(channel)->getChannelID(); v.push_back(channel_id); } std::map ch_id_map; std::vector::iterator it; for (it = v.begin(); it != v.end(); ++it){ ch_id_map[*it & 0xFFFFFFFFFFFFULL] = *it; } CEitManager::getInstance()->getEventsServiceKey(0,evtlist, m_search_epg_item,m_search_keyword, true,m_search_genre,m_search_fsk);//all_chann if(!evtlist.empty()){ std::map::iterator map_it; CChannelEventList::iterator e; for ( e=evtlist.begin(); e!=evtlist.end();++e){ map_it = ch_id_map.find(e->channelID); if (map_it != ch_id_map.end()){ e->channelID = map_it->second;//map channelID48 to channelID } else{ evtlist.erase(e--);// remove event for not found channels in channelList } } } box.hide(); } if(!evtlist.empty()){ sort(evtlist.begin(),evtlist.end(),sortByDateTime); } current_event = (unsigned int)-1; time_t azeit=time(NULL); CChannelEventList::iterator e; for ( e=evtlist.begin(); e!=evtlist.end(); ++e ) { if ( e->startTime > azeit ) { break; } current_event++; } if(evtlist.empty()) { CChannelEvent evt; //evt.description = m_search_keyword + ": " + g_Locale->getText(LOCALE_EPGVIEWER_NOTFOUND); evt.description = g_Locale->getText(LOCALE_EPGVIEWER_NOTFOUND); evt.eventID = 0; evtlist.push_back(evt); } if (current_event == (unsigned int)-1) current_event = 0; selected= current_event; search_head_name += ": '"; search_head_name += m_search_keyword; search_head_name += "'"; if(!m_search_keyword.empty()){ g_settings.epg_search_history.push_front(m_search_keyword); std::list::iterator it = g_settings.epg_search_history.begin(); ++it; while (it != g_settings.epg_search_history.end()) { if (*it == m_search_keyword) it = g_settings.epg_search_history.erase(it); else ++it; } g_settings.epg_search_history_size = g_settings.epg_search_history.size(); if (g_settings.epg_search_history_size > g_settings.epg_search_history_max) g_settings.epg_search_history_size = g_settings.epg_search_history_max; } } if (event) paintHead(0, search_head_name); else paintHead(channel_id, channelname); paint(); paintFoot(channel_id); return(res); } /* class CSearchNotifier : public CChangeObserver { private: CMenuItem* menuItem; public: CSearchNotifier( CMenuItem* i){menuItem=i}; bool changeNotify(const neutrino_locale_t t, void * data) { int selected = *(int*)data; menuItem->setActive(1); menuItem } }; */ /* bool CEventFinderMenuHandler::changeNotify(const neutrino_locale_t OptionName, void *Data) { if(OptionName == ) { } return true; } */ const short GENRE_GROUP_COUNT = 11; const CMenuOptionChooser::keyval GENRE_GROUP[GENRE_GROUP_COUNT] = { { 0xFF, LOCALE_GENRE_ALL }, { 0x18, LOCALE_GENRE_MOVIE }, { 0x24, LOCALE_GENRE_NEWS }, { 0x33, LOCALE_GENRE_SHOW }, { 0x4B, LOCALE_GENRE_SPORTS }, { 0x55, LOCALE_GENRE_CHILDRENS_PROGRAMMES }, { 0x66, LOCALE_GENRE_MUSIC_DANCE }, { 0x7B, LOCALE_GENRE_ARTS }, { 0x83, LOCALE_GENRE_SOCIAL_POLITICAL }, { 0x97, LOCALE_GENRE_DOCUS_MAGAZINES }, { 0xA7, LOCALE_GENRE_TRAVEL_HOBBIES } }; const short FSK_COUNT = 8; const CMenuOptionChooser::keyval FSK[FSK_COUNT] = { { 0, LOCALE_FSK_ALL }, { -7, LOCALE_FSK_TO_7 }, { -12, LOCALE_FSK_TO_12 }, { -16, LOCALE_FSK_TO_16 }, { 7, LOCALE_FSK_FROM_7 }, { 12, LOCALE_FSK_FROM_12 }, { 16, LOCALE_FSK_FROM_16 }, { 18, LOCALE_FSK_FROM_18 } }; #define SEARCH_LIST_OPTION_COUNT 3 const CMenuOptionChooser::keyval SEARCH_LIST_OPTIONS[SEARCH_LIST_OPTION_COUNT] = { // { CEventList::SEARCH_LIST_NONE, LOCALE_PICTUREVIEWER_RESIZE_NONE }, { CEventList::SEARCH_LIST_CHANNEL, LOCALE_TIMERLIST_CHANNEL }, { CEventList::SEARCH_LIST_BOUQUET, LOCALE_BOUQUETLIST_HEAD }, { CEventList::SEARCH_LIST_ALL, LOCALE_CHANNELLIST_HEAD } }; #define SEARCH_EPG_OPTION_COUNT 4 const CMenuOptionChooser::keyval SEARCH_EPG_OPTIONS[SEARCH_EPG_OPTION_COUNT] = { // { CEventList::SEARCH_EPG_NONE, LOCALE_PICTUREVIEWER_RESIZE_NONE }, { CEventList::SEARCH_EPG_TITLE, LOCALE_FONTSIZE_EPG_TITLE }, { CEventList::SEARCH_EPG_INFO1, LOCALE_FONTSIZE_EPG_INFO1 }, { CEventList::SEARCH_EPG_INFO2, LOCALE_FONTSIZE_EPG_INFO2 }, // { CEventList::SEARCH_EPG_GENRE, LOCALE_MOVIEBROWSER_INFO_GENRE_MAJOR }, { CEventList::SEARCH_EPG_ALL, LOCALE_EVENTFINDER_SEARCH_ALL_EPG } }; CEventFinderMenu::CEventFinderMenu(int* event, int* search_epg_item, std::string* search_keyword, int* search_list, t_channel_id* search_channel_id, t_bouquet_id* search_bouquet_id, int* search_genre, int* search_fsk) { m_event = event; m_search_epg_item = search_epg_item; m_search_keyword = search_keyword; m_search_list = search_list; m_search_channel_id = search_channel_id; m_search_bouquet_id = search_bouquet_id; m_search_genre = search_genre; m_search_fsk = search_fsk; width = 40; selected = -1; } int CEventFinderMenu::exec(CMenuTarget* parent, const std::string &actionkey) { int res = menu_return::RETURN_REPAINT; if(actionkey.empty()) { if(parent != NULL) parent->hide(); //printf("0\n"); showMenu(); } else if(actionkey =="#1") { //printf("1\n"); *m_event = true; res = menu_return::RETURN_EXIT_ALL; } else if(actionkey =="#2") { //printf("3\n"); // get channel id / bouquet id if(*m_search_list == CEventList::SEARCH_LIST_CHANNEL) { int nNewBouquet; nNewBouquet = bouquetList->show(); //printf("new_bouquet_id %d\n",nNewBouquet); if (nNewBouquet > -1) { int nNewChannel = bouquetList->Bouquets[nNewBouquet]->channelList->show(); CVFD::getInstance()->setMode(CVFD::MODE_TVRADIO); //printf("nNewChannel %d\n",nNewChannel); if (nNewChannel > -1) { *m_search_bouquet_id = nNewBouquet; *m_search_channel_id = bouquetList->Bouquets[nNewBouquet]->channelList->getActiveChannel_ChannelID(); m_search_channelname = CServiceManager::getInstance()->GetServiceName(*m_search_channel_id); } } } else if(*m_search_list == CEventList::SEARCH_LIST_BOUQUET) { int nNewBouquet; nNewBouquet = bouquetList->show(); //printf("new_bouquet_id %d\n",nNewBouquet); if (nNewBouquet > -1) { *m_search_bouquet_id = nNewBouquet; m_search_channelname = bouquetList->Bouquets[nNewBouquet]->channelList->getName(); } } } else if(actionkey =="#history") { if (parent) parent->hide(); CMenuWidget* m = new CMenuWidget(LOCALE_EVENTFINDER_HISTORY, NEUTRINO_ICON_MOVIEPLAYER, width); m->addKey(CRCInput::RC_spkr, this, "#clear"); m->setSelected(selected); m->addItem(GenericMenuSeparator); m->addItem(GenericMenuBack); m->addItem(GenericMenuSeparatorLine); std::list::iterator it = g_settings.epg_search_history.begin(); for (int i = 0; i < g_settings.epg_search_history_size; i++, ++it) m->addItem(new CMenuForwarder((*it).c_str(), true, NULL, this, (*it).c_str(), CRCInput::convertDigitToKey(i + 1))); m->exec(NULL, ""); m->hide(); delete m; return menu_return::RETURN_REPAINT; } if (actionkey == "#clear") { g_settings.epg_search_history.clear(); g_settings.epg_search_history_size = 0; return menu_return::RETURN_EXIT; } std::list::iterator it = g_settings.epg_search_history.begin(); for (int i = 0; i < g_settings.epg_search_history_size; i++, ++it){ if((*it)== actionkey){ *m_search_keyword = actionkey; g_RCInput->postMsg((neutrino_msg_t) CRCInput::RC_blue, 0); return menu_return::RETURN_EXIT; } } return res; } int CEventFinderMenu::showMenu(void) { int res = menu_return::RETURN_REPAINT; m_search_channelname_mf = NULL; *m_event = false; if(*m_search_list == CEventList::SEARCH_LIST_CHANNEL) { m_search_channelname = CServiceManager::getInstance()->GetServiceName(*m_search_channel_id); } else if(*m_search_list == CEventList::SEARCH_LIST_BOUQUET) { if (*m_search_bouquet_id >= bouquetList->Bouquets.size()){ *m_search_bouquet_id = bouquetList->getActiveBouquetNumber(); } if(!bouquetList->Bouquets.empty()) m_search_channelname = bouquetList->Bouquets[*m_search_bouquet_id]->channelList->getName(); else m_search_channelname =""; } else if(*m_search_list == CEventList::SEARCH_LIST_ALL) { m_search_channelname =""; } int shortcut = 1; CKeyboardInput stringInput(LOCALE_EVENTFINDER_KEYWORD,m_search_keyword); CMenuForwarder* mf0 = new CMenuForwarder(LOCALE_EVENTFINDER_KEYWORD, true, *m_search_keyword, &stringInput, NULL, CRCInput::RC_red); CMenuOptionChooser* mo0 = new CMenuOptionChooser(LOCALE_EVENTFINDER_SEARCH_WITHIN_LIST, m_search_list, SEARCH_LIST_OPTIONS, SEARCH_LIST_OPTION_COUNT, true, this, CRCInput::convertDigitToKey(shortcut++)); m_search_channelname_mf = new CMenuForwarder("", *m_search_list != CEventList::SEARCH_LIST_ALL, m_search_channelname, this, "#2", CRCInput::convertDigitToKey(shortcut++)); CMenuOptionChooser* mo1 = new CMenuOptionChooser(LOCALE_EVENTFINDER_SEARCH_WITHIN_EPG, m_search_epg_item, SEARCH_EPG_OPTIONS, SEARCH_EPG_OPTION_COUNT, true, NULL, CRCInput::convertDigitToKey(shortcut++)); CMenuForwarder* mf1 = new CMenuForwarder(LOCALE_EVENTFINDER_START_SEARCH, true, NULL, this, "#1", CRCInput::RC_green); CMenuOptionChooser* mgenre = new CMenuOptionChooser(LOCALE_EVENTFINDER_GENRE, m_search_genre, GENRE_GROUP, GENRE_GROUP_COUNT, true, NULL, CRCInput::convertDigitToKey(shortcut++)); CMenuOptionChooser* mfsk = new CMenuOptionChooser(LOCALE_EVENTFINDER_FSK, m_search_fsk, FSK, FSK_COUNT, true, NULL, CRCInput::convertDigitToKey(shortcut++)); CMenuWidget searchMenu(LOCALE_EVENTFINDER_HEAD, NEUTRINO_ICON_FEATURES, 40); CMenuForwarder* mf2 = new CMenuForwarder(LOCALE_EVENTFINDER_HISTORY, true, NULL, this, "#history", CRCInput::RC_yellow); CMenuOptionNumberChooser* moc1 = new CMenuOptionNumberChooser(LOCALE_EVENTFINDER_MAX_HISTORY, &g_settings.epg_search_history_max, true, 0, 50, NULL); searchMenu.addItem(GenericMenuSeparator); searchMenu.addItem(GenericMenuBack); searchMenu.addItem(GenericMenuSeparatorLine); searchMenu.addItem(mf0); searchMenu.addItem(mf1); searchMenu.addItem(GenericMenuSeparatorLine); searchMenu.addItem(mo0); searchMenu.addItem(m_search_channelname_mf); searchMenu.addItem(mo1); searchMenu.addItem(GenericMenuSeparatorLine); searchMenu.addItem(mgenre); searchMenu.addItem(mfsk); searchMenu.addItem(GenericMenuSeparatorLine); searchMenu.addItem(mf2); searchMenu.addItem(moc1); res = searchMenu.exec(NULL,""); return(res); } bool CEventFinderMenu::changeNotify(const neutrino_locale_t OptionName, void *) { if (ARE_LOCALES_EQUAL(OptionName, LOCALE_EVENTFINDER_SEARCH_WITHIN_LIST)) { if (*m_search_list == CEventList::SEARCH_LIST_CHANNEL) { m_search_channelname = g_Zapit->getChannelName(*m_search_channel_id); m_search_channelname_mf->setActive(true); } else if (*m_search_list == CEventList::SEARCH_LIST_BOUQUET) { if (*m_search_bouquet_id >= bouquetList->Bouquets.size()){ *m_search_bouquet_id = bouquetList->getActiveBouquetNumber(); } if(!bouquetList->Bouquets.empty()){ m_search_channelname = bouquetList->Bouquets[*m_search_bouquet_id]->channelList->getName(); m_search_channelname_mf->setActive(true); } } else if (*m_search_list == CEventList::SEARCH_LIST_ALL) { m_search_channelname = ""; m_search_channelname_mf->setActive(false); } } return false; }