From f1e25395ca24f11f52d315a59965a92c4ef9e9f3 Mon Sep 17 00:00:00 2001 From: martii Date: Fri, 1 Jul 2016 15:26:06 +0200 Subject: [PATCH] followscreenings: port code from martiis-neutrino-mp Origin commit data ------------------ Commit: https://github.com/neutrino-images/ni-neutrino/commit/61105699d44de6874fe346e9d8eff52011ebd197 Author: martii Date: 2016-07-01 (Fri, 01 Jul 2016) Origin message was: ------------------ - followscreenings: port code from martiis-neutrino-mp --- data/locale/deutsch.locale | 1 + data/locale/english.locale | 1 + src/gui/Makefile.am | 1 + src/gui/epgplus.cpp | 22 ++-- src/gui/epgview.cpp | 12 +- src/gui/eventlist.cpp | 33 ++---- src/gui/followscreenings.cpp | 187 ++++++++++++++++++++++++++++++ src/gui/followscreenings.h | 80 +++++++++++++ src/gui/timerlist.cpp | 25 ++-- src/gui/timerlist.h | 3 +- src/system/locals.h | 1 + src/system/locals_intern.h | 1 + src/zapit/include/zapit/channel.h | 2 +- 13 files changed, 320 insertions(+), 49 deletions(-) create mode 100644 src/gui/followscreenings.cpp create mode 100644 src/gui/followscreenings.h diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index cae2476ef..a53bbf8c3 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -388,6 +388,7 @@ epgviewer.genre Genre epgviewer.length Spieldauer (Min.) epgviewer.nodetailed Keine ausführlichen Informationen verfügbar epgviewer.notfound Keine Programminformationen (EPG) gefunden +epgviewer.select_screening Terminauswahl eventfinder.fsk Altersfreigabe Filter eventfinder.genre Genre Filter eventfinder.head EPG-Suche diff --git a/data/locale/english.locale b/data/locale/english.locale index c675c25b5..cb28460c2 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -388,6 +388,7 @@ epgviewer.genre Genre epgviewer.length Length (min.) epgviewer.nodetailed No detailed informations available epgviewer.notfound No EPG found +epgviewer.select_screening Select Screening eventfinder.fsk Age rating Filter eventfinder.genre Genre-Filter eventfinder.head Search in EPG diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index d9cb6931e..f1d0c89b9 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -59,6 +59,7 @@ libneutrino_gui_a_SOURCES = \ eventlist.cpp \ favorites.cpp \ filebrowser.cpp \ + followscreenings.cpp \ imageinfo.cpp \ info_menue.cpp \ infoviewer.cpp \ diff --git a/src/gui/epgplus.cpp b/src/gui/epgplus.cpp index c48af512c..d3e4f691e 100644 --- a/src/gui/epgplus.cpp +++ b/src/gui/epgplus.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -1303,6 +1304,11 @@ EpgPlus::MenuTargetAddRecordTimer::MenuTargetAddRecordTimer (EpgPlus * pepgPlus) this->epgPlus = pepgPlus; } +static bool sortByDateTime (const CChannelEvent& a, const CChannelEvent& b) +{ + return a.startTime < b.startTime; +} + int EpgPlus::MenuTargetAddRecordTimer::exec (CMenuTarget * /*parent*/, const std::string & /*actionKey*/) { TCChannelEventEntries::const_iterator It = this->epgPlus->getSelectedEvent(); @@ -1329,14 +1335,14 @@ int EpgPlus::MenuTargetAddRecordTimer::exec (CMenuTarget * /*parent*/, const std } if (g_Timerd->isTimerdAvailable() && doRecord) { - g_Timerd->addRecordTimerEvent (this->epgPlus->selectedChannelEntry->channel->getChannelID(), - (*It)->channelEvent.startTime, - (*It)->channelEvent.startTime + (*It)->channelEvent.duration, - (*It)->channelEvent.eventID, - (*It)->channelEvent.startTime, - (*It)->channelEvent.startTime - (ANNOUNCETIME + 120), - TIMERD_APIDS_CONF, true); - ShowMsg (LOCALE_TIMER_EVENTRECORD_TITLE, g_Locale->getText (LOCALE_TIMER_EVENTRECORD_MSG), CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); + CChannelEventList evtlist; + CEitManager::getInstance()->getEventsServiceKey(this->epgPlus->selectedChannelEntry->channel->channel_id, evtlist); + sort(evtlist.begin(),evtlist.end(),sortByDateTime); + CFollowScreenings m(this->epgPlus->selectedChannelEntry->channel->channel_id, + (*It)->channelEvent.startTime, + (*It)->channelEvent.startTime + (*It)->channelEvent.duration, + (*It)->channelEvent.description, (*It)->channelEvent.eventID, TIMERD_APIDS_CONF, true, "", &evtlist); + m.exec(NULL, ""); } else printf ("timerd not available\n"); } diff --git a/src/gui/epgview.cpp b/src/gui/epgview.cpp index 5d687ed04..7047ea590 100644 --- a/src/gui/epgview.cpp +++ b/src/gui/epgview.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -915,7 +916,16 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start doRecord = (ShowMsg(LOCALE_RECORDING_ALREADY_FOUND_CHECK, message, CMessageBox::mbrYes, CMessageBox::mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes); } } - if (doRecord) + if (doRecord && !call_fromfollowlist) + { + CFollowScreenings m(channel_id, + epgData.epg_times.startzeit, + epgData.epg_times.startzeit + epgData.epg_times.dauer, + epgData.title, epgData.eventID, TIMERD_APIDS_CONF, true, recDir, &evtlist); + m.exec(NULL, ""); + timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_EPG]); + } + else if (doRecord) { if (g_Timerd->addRecordTimerEvent(channel_id, epgData.epg_times.startzeit, diff --git a/src/gui/eventlist.cpp b/src/gui/eventlist.cpp index 90acdf162..9722eb3e7 100644 --- a/src/gui/eventlist.cpp +++ b/src/gui/eventlist.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -487,32 +488,12 @@ int CEventList::exec(const t_channel_id channel_id, const std::string& channelna t_channel_id used_id = IS_WEBTV(channel_id) ? channel_id : evtlist[selected].channelID; if (!recDir.empty() && doRecord) //add/remove recording timer events and check/warn for conflicts { - if (g_Timerd->addRecordTimerEvent(used_id, - evtlist[selected].startTime, - evtlist[selected].startTime + evtlist[selected].duration, - evtlist[selected].eventID, evtlist[selected].startTime, - evtlist[selected].startTime - (ANNOUNCETIME + 120), - TIMERD_APIDS_CONF, true, recDir,false) == -1) - { - if(askUserOnTimerConflict(evtlist[selected].startTime - (ANNOUNCETIME + 120), evtlist[selected].startTime + evtlist[selected].duration)) //check for timer conflict - { - g_Timerd->addRecordTimerEvent(used_id, - evtlist[selected].startTime, - evtlist[selected].startTime + evtlist[selected].duration, - evtlist[selected].eventID, evtlist[selected].startTime, - evtlist[selected].startTime - (ANNOUNCETIME + 120), - TIMERD_APIDS_CONF, true, recDir,true); - - //ask user whether the timer event should be set anyway - ShowMsg(LOCALE_TIMER_EVENTRECORD_TITLE, LOCALE_TIMER_EVENTRECORD_MSG, CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); - timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_EPG]); - } - } - else - { - //ShowMsg(LOCALE_TIMER_EVENTRECORD_TITLE, LOCALE_TIMER_EVENTRECORD_MSG, CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); - timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_EPG]); - } + CFollowScreenings m(channel_id, + evtlist[selected].startTime, + evtlist[selected].startTime + evtlist[selected].duration, + evtlist[selected].description, evtlist[selected].eventID, TIMERD_APIDS_CONF, true, "", &evtlist); + m.exec(NULL, ""); + timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_EPG]); } timerlist.clear(); g_Timerd->getTimerList (timerlist); diff --git a/src/gui/followscreenings.cpp b/src/gui/followscreenings.cpp new file mode 100644 index 000000000..cb1933d6e --- /dev/null +++ b/src/gui/followscreenings.cpp @@ -0,0 +1,187 @@ +/* + Neutrino-GUI - DBoxII-Project + + Copyright (C) 2001 Steffen Hehn 'McClean' + Copyright (C) 2013 martii + Homepage: http://dbox.cyberphoria.org/ + + Kommentar: + + Diese GUI wurde von Grund auf neu programmiert und sollte nun vom + Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert + auf der Client-Server Idee, diese GUI ist also von der direkten DBox- + Steuerung getrennt. Diese wird dann von Daemons uebernommen. + + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +//#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +CFollowScreenings::~CFollowScreenings() +{ + followlist.clear(); +} + +CChannelEventList *CFollowScreenings::getFollowScreenings(void) +{ + if (evtlist && followlist.empty()) { + CChannelEventList::iterator e; + for (e = evtlist->begin(); e != evtlist->end(); ++e) + { + if (e->startTime < starttime) // this includes the current event + continue; + if (! e->eventID) + continue; + if (e->description != title) + continue; + followlist.push_back(*e); + } + } + return &followlist; +} + +int CFollowScreenings::exec(CMenuTarget* /*parent*/, const std::string & actionKey) +{ + unsigned long a; + if (1 == sscanf(actionKey.c_str(), "%lu", &a)) { + int ix = 0; + CChannelEventList::iterator e; + for (e = followlist.begin(); e != followlist.end(); e++, ix++) + if ((time_t)a == e->startTime) { + time_t start = e->startTime - (ANNOUNCETIME + 120); + time_t stop = e->startTime + e->duration; + CTimerd::TimerList overlappingTimers = Timer.getOverlappingTimers(start, stop); + CTimerd::TimerList::iterator i; + for (i = overlappingTimers.begin(); i != overlappingTimers.end(); i++) + if (i->eventType == CTimerd::TIMER_RECORD) { + if (channel_id == i->channel_id && e->startTime == i->epg_starttime) { + Timer.removeTimerEvent(i->eventID); +#if 0 + if (followlist.size() > 1) + forwarders[ix]->iconName_Info_right = ""; + else + ShowMsg(LOCALE_TIMER_EVENTREMOVED_TITLE, LOCALE_TIMER_EVENTREMOVED_MSG, + CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); +#else + forwarders[ix]->iconName_Info_right = ""; +#endif + return menu_return::RETURN_REPAINT; + } + if (!SAME_TRANSPONDER(channel_id, i->channel_id)) { + if (!askUserOnTimerConflict(start, stop, channel_id)) + return menu_return::RETURN_REPAINT; + } + } + + if (g_Timerd->addRecordTimerEvent(channel_id, e->startTime, e->startTime + e->duration, e->eventID, + e->startTime, e->startTime - (ANNOUNCETIME + 120 ), apids, true, recDir, true) == -1) { + //FIXME -- no error handling, but this shouldn't happen ... + } else { +#if 0 + if (followlist.size() > 1) + forwarders[ix]->iconName_Info_right = NEUTRINO_ICON_REC; + else + ShowMsg(LOCALE_TIMER_EVENTRECORD_TITLE, LOCALE_TIMER_EVENTRECORD_MSG, + CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); +#else + forwarders[ix]->iconName_Info_right = NEUTRINO_ICON_REC; +#endif + return menu_return::RETURN_REPAINT; + } + break; // for + } + return menu_return::RETURN_EXIT_ALL; + } + show(); + return menu_return::RETURN_EXIT_ALL; +} + +void CFollowScreenings::updateRightIcon(int ix, time_t start, unsigned int duration) { + time_t stop = start + duration; + start -= (ANNOUNCETIME + 120); + CTimerd::TimerList overlappingTimers = Timer.getOverlappingTimers(start, stop); + start += (ANNOUNCETIME + 120); + CTimerd::TimerList::iterator i; + for (i = overlappingTimers.begin(); i != overlappingTimers.end(); i++) + if (i->eventType == CTimerd::TIMER_RECORD) { + if (channel_id == i->channel_id && start == i->epg_starttime) { + forwarders[ix]->iconName_Info_right = NEUTRINO_ICON_REC; + return; + } + if (!SAME_TRANSPONDER(channel_id, i->channel_id)) { + forwarders[ix]->iconName_Info_right = NEUTRINO_ICON_IMPORTANT; + return; + } + } +} + +void CFollowScreenings::show() +{ + char actionstr[32]; + + getFollowScreenings(); + +#if 0 + if (followlist.size() == 1) { + snprintf(actionstr, sizeof(actionstr), "%lu", followlist.front().startTime); + exec(NULL, actionstr); + } else { +#endif + CMenuWidget m(LOCALE_EPGVIEWER_SELECT_SCREENING, NEUTRINO_ICON_SETTINGS); + const char *icon = NEUTRINO_ICON_BUTTON_RED; + neutrino_msg_t directKey = CRCInput::RC_red; + CChannelEventList::iterator e; + int i = 0; + for (e = followlist.begin(); e != followlist.end(); e++, i++) + { + struct tm *tmStartZeit = localtime(&(e->startTime)); + std::string screening_date = g_Locale->getText(CLocaleManager::getWeekday(tmStartZeit)); + screening_date += '.'; + screening_date += strftime(" %d.", tmStartZeit); + screening_date += g_Locale->getText(CLocaleManager::getMonth(tmStartZeit)); + screening_date += strftime(". %H:%M", tmStartZeit ); + snprintf(actionstr, sizeof(actionstr), "%lu", e->startTime); + forwarders.push_back(new CMenuForwarder(screening_date, true, NULL, this, actionstr, directKey, icon)); + updateRightIcon(i, e->startTime, e->duration); + m.addItem(forwarders[i]); + directKey = CRCInput::convertDigitToKey(1 + i); + icon = NULL; + } + m.enableSaveScreen(true); + m.exec(NULL, ""); +#if 0 + } +#endif +} + diff --git a/src/gui/followscreenings.h b/src/gui/followscreenings.h new file mode 100644 index 000000000..53e362e3e --- /dev/null +++ b/src/gui/followscreenings.h @@ -0,0 +1,80 @@ +/* + Neutrino-GUI - DBoxII-Project + + Copyright (C) 2001 Steffen Hehn 'McClean' + Copyright (C) 2013 martii + Homepage: http://dbox.cyberphoria.org/ + + Kommentar: + + Diese GUI wurde von Grund auf neu programmiert und sollte nun vom + Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert + auf der Client-Server Idee, diese GUI ist also von der direkten DBox- + Steuerung getrennt. Diese wird dann von Daemons uebernommen. + + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#ifndef __followscreening_ +#define __followscreening_ + +#include "widget/menue.h" +#include +#include +#include +#include + +class CFollowScreenings : public CMenuTarget +{ + private: + CEPGData *epgData; + CChannelEventList *evtlist; + CChannelEventList followlist; + CTimerdClient Timer; + t_channel_id channel_id; + time_t starttime; + time_t stoptime; + std::string title; + uint64_t epgID; + unsigned char apids; + bool safety; + std::string recDir; + CTimerd::RecordingInfo eventInfo; + std::vector forwarders; + void updateRightIcon(int i, time_t start, unsigned int duration); + public: + CFollowScreenings(const t_channel_id Channel_id, time_t Starttime, time_t Stoptime, const std::string &Title, uint64_t EpgID=0, + unsigned char Apids=TIMERD_APIDS_STD, bool Safety=false, std::string RecDir="", CChannelEventList *Evtlist=NULL) : CMenuTarget () { + this->channel_id = Channel_id; + this->starttime = Starttime; + this->stoptime = Stoptime; + this->epgID = EpgID; + this->recDir = RecDir; + this->evtlist = Evtlist; + this->title = Title; + this->safety = Safety; + this->apids = Apids; + }; + ~CFollowScreenings(); + CChannelEventList *getFollowScreenings(void); + int exec(CMenuTarget *parent, const std::string & actionKey); + void show(); +}; +#endif + diff --git a/src/gui/timerlist.cpp b/src/gui/timerlist.cpp index fb8927463..ec9cb5085 100644 --- a/src/gui/timerlist.cpp +++ b/src/gui/timerlist.cpp @@ -1261,13 +1261,23 @@ int CTimerList::newTimer() return ret; } -bool askUserOnTimerConflict(time_t announceTime, time_t stopTime) +bool askUserOnTimerConflict(time_t announceTime, time_t stopTime, t_channel_id channel_id) { if (CFEManager::getInstance()->getEnabledCount() == 1) { CTimerdClient Timer; CTimerd::TimerList overlappingTimers = Timer.getOverlappingTimers(announceTime,stopTime); //printf("[CTimerdClient] attention\n%d\t%d\t%d conflicts with:\n",timerNew.announceTime,timerNew.alarmTime,timerNew.stopTime); + // Don't ask if there are overlapping timers on the same transponder. + if (channel_id) { + CTimerd::TimerList::iterator i; + for (i = overlappingTimers.begin(); i != overlappingTimers.end(); i++) + if ((i->eventType != CTimerd::TIMER_RECORD || !SAME_TRANSPONDER(channel_id, i->channel_id))) + break; + if (i == overlappingTimers.end()) + return true; // yes, add timer + } + std::string timerbuf = g_Locale->getText(LOCALE_TIMERLIST_OVERLAPPING_TIMER); timerbuf += "\n"; for (CTimerd::TimerList::iterator it = overlappingTimers.begin(); @@ -1290,20 +1300,13 @@ bool askUserOnTimerConflict(time_t announceTime, time_t stopTime) timerbuf += it->epgTitle; } } - timerbuf += ")"; + timerbuf += "):\n"; - timerbuf += ":\n"; - char at[25] = {0}; struct tm *annTime = localtime(&(it->announceTime)); - strftime(at,20,"%d.%m. %H:%M",annTime); - timerbuf += at; - timerbuf += " - "; + timerbuf += strftime("%d.%m. %H:%M\n",annTime); - char st[25] = {0}; struct tm *sTime = localtime(&(it->stopTime)); - strftime(st,20,"%d.%m. %H:%M",sTime); - timerbuf += st; - timerbuf += "\n"; + timerbuf += strftime("%d.%m. %H:%M\n",sTime); //printf("%d\t%d\t%d\n",it->announceTime,it->alarmTime,it->stopTime); } //printf("message:\n%s\n",timerbuf.c_str()); diff --git a/src/gui/timerlist.h b/src/gui/timerlist.h index 48c299bb8..6ca937ecb 100644 --- a/src/gui/timerlist.h +++ b/src/gui/timerlist.h @@ -97,7 +97,6 @@ class CTimerList : public CMenuTarget, public CListHelpers static std::string convertChannelId2String(const t_channel_id id); // UTF-8 }; -bool askUserOnTimerConflict(time_t announceTime, time_t stopTime); - +bool askUserOnTimerConflict(time_t announceTime, time_t stopTime, t_channel_id channel_id = 0); #endif diff --git a/src/system/locals.h b/src/system/locals.h index 218e1ac98..9aca38703 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -415,6 +415,7 @@ typedef enum LOCALE_EPGVIEWER_LENGTH, LOCALE_EPGVIEWER_NODETAILED, LOCALE_EPGVIEWER_NOTFOUND, + LOCALE_EPGVIEWER_SELECT_SCREENING, LOCALE_EVENTFINDER_FSK, LOCALE_EVENTFINDER_GENRE, LOCALE_EVENTFINDER_HEAD, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index d68ecba46..abfce1c63 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -415,6 +415,7 @@ const char * locale_real_names[] = "epgviewer.length", "epgviewer.nodetailed", "epgviewer.notfound", + "epgviewer.select_screening", "eventfinder.fsk", "eventfinder.genre", "eventfinder.head", diff --git a/src/zapit/include/zapit/channel.h b/src/zapit/include/zapit/channel.h index 834873afa..30f1b5a83 100644 --- a/src/zapit/include/zapit/channel.h +++ b/src/zapit/include/zapit/channel.h @@ -176,7 +176,6 @@ class CZapitChannel void Init(); friend class CChannelList; - t_channel_id channel_id; public: typedef enum channel_flags { @@ -198,6 +197,7 @@ class CZapitChannel int number; CChannelEvent currentEvent,nextEvent; int type; + t_channel_id channel_id; unsigned char scrambled; char * pname; bool has_bouquet;