diff --git a/epg_events.cpp b/epg_events.cpp index 6d42bd66..dae82c74 100644 --- a/epg_events.cpp +++ b/epg_events.cpp @@ -37,6 +37,11 @@ namespace vdrlive { } + const std::string EpgInfo::ChannelName() const + { const cChannel* channel = Channel(); + return channel ? channel->Name() : ""; + } + const std::string EpgInfo::CurrentTime(const char* format) const { return FormatDateTime(format, time(0)); @@ -175,6 +180,12 @@ namespace vdrlive return (info && info->Description()) ? info->Description() : ""; } + const std::string EpgRecording::ChannelName() const + { + const cRecordingInfo* info = m_recording ? m_recording->Info() : 0; + return info && info->ChannelName() ? info->ChannelName(): ""; + } + const std::string EpgRecording::Archived() const { if (!m_checkedArchived && m_recording) { @@ -215,19 +226,24 @@ namespace vdrlive int EpgRecording::Elapsed() const { + if (!m_recording) + return -1; + int current, total; + // try currently playing recording if any cControl* pControl = cControl::Control(); if (pControl) { - int current, total; - if (pControl->GetIndex(current,total)) - { - if (total) - { - return (100 * current) / total; - } - } + const cRecording* playing = pControl->GetRecording(); + if (playing && playing->Id() == m_recording->Id() + && pControl->GetIndex(current,total) && total) + return (100 * current) / total; } - return 0; + // Check for resume position next + current = m_recording->GetResume(); + total= m_recording->NumFrames(); + if (current > 0 && total > 0) + return (100 * current) / total; + return -1; } const std::string EpgRecording::Name() const @@ -549,7 +565,7 @@ bool appendEpgItem(cLargeString &epg_item, RecordingsItemPtr &recItem, const cEv epg_item.append(" - "); AppendDateTime(epg_item, tr("%I:%M %p"), Event->EndTime() ); epg_item.append(" "); - AppendDuration(epg_item, tr("(%d:%02d)"), Event->Duration() /60/60, Event->Duration()/60 % 60); + AppendDuration(epg_item, tr("(%d:%02d)"), Event->Duration()); epg_item.append("\"]"); return recItemFound; } diff --git a/epg_events.h b/epg_events.h index af5aa7d8..eab09a38 100644 --- a/epg_events.h +++ b/epg_events.h @@ -107,6 +107,8 @@ namespace vdrlive virtual cChannel const * Channel() const { return 0; } + virtual std::string const ChannelName() const; + virtual std::string const Archived() const { return ""; } virtual std::string const FileName() const { return ""; } @@ -257,6 +259,8 @@ namespace vdrlive virtual std::string const LongDescr() const; + virtual std::string const ChannelName() const; + virtual std::string const Archived() const; virtual std::string const FileName() const; diff --git a/live/css/styles.css b/live/css/styles.css index 01c42b86..13a44934 100644 --- a/live/css/styles.css +++ b/live/css/styles.css @@ -490,7 +490,7 @@ div#pagemenu form a { } div#pagemenu form a img { - vertical-align: middle; + vertical-align: middle; margin-top: -5px; } @@ -711,6 +711,10 @@ div.event div.station { width: 255px; } +div.event div.title a { + color: black; +} + div.station div { margin: 0; padding: 0; @@ -769,7 +773,6 @@ div.content div.tools { margin: 0; padding: 0; padding-top: 3px; - text-align: center; vertical-align: top; } @@ -778,15 +781,6 @@ div.content div.tools img { margin: 2px 5px; } -div.content div { - padding-left: 0px; - margin-left: 35px; -} - -div.content div div { - margin-left: 0px; -} - div.description { margin: 5px 5px 0px 5px; overflow: hidden; @@ -801,13 +795,17 @@ div.short { } div.info { - padding: 5px 5px 5px 0px; + margin: 5px 5px 0px 0px; overflow: hidden; } -div.info div.time { +div.info div.duration { float: right; - padding: 0px; + margin: 0px 5px 0px 5px; +} + +div.info div.time { + margin: 0px 5px 0px 5px; } div.info div.date { @@ -817,12 +815,12 @@ div.info div.date { div.progress { overflow: hidden; - padding-right: 4px; + padding: 2px 0px; margin: 0px; } div.progress div { - float: right; + float: right; padding: 0px; } @@ -929,7 +927,13 @@ table.mschedule tr { height: 12px; } +table.mschedule td.time { + vertical-align: top; + padding: 5px; +} + table.mschedule tr td.event { + vertical-align: top; background: transparent url(../img/bg_line.png) bottom repeat-x; border-bottom: 1px solid #C0C1DA; } @@ -951,8 +955,8 @@ table.mschedule tr td.current_row { } table.mschedule tr td.leftcol { - padding-left: 7px; - padding-right: 5px; + padding-left: 7px; + padding-right: 5px; } table.mschedule div.content1 { @@ -960,6 +964,10 @@ table.mschedule div.content1 { max-width: 30em; } +table.mschedule div.content1>div { + margin: 5px 5px 5px 7px; +} + table.mschedule div.tools1 { float: right; } @@ -969,7 +977,6 @@ table.mschedule div.start { } table.mschedule tr td div.title { - padding: 3px; clear: both; } @@ -988,6 +995,10 @@ table.mschedule a { font-weight: bold; } +table.mschedule a>img { + vertical-align: text-bottom; +} + /* ############################## # Blue Background Thingy @@ -1000,12 +1011,12 @@ div.boxheader { background: url(../img/bg_box_l.png) top left no-repeat; } -div.boxheader div { +div.boxheader > div { margin: 0px; background: url(../img/bg_box_r.png) top right no-repeat; } -div.boxheader div div { +div.boxheader > div > div { background: url(../img/bg_box_h.png) repeat-x; vertical-align: middle; text-align: left; @@ -1016,7 +1027,8 @@ div.boxheader div div { color: white; font-weight: bold; height: 21px; - line-height: 20px; + line-height: 20px; + white-space: nowrap; } /* @@ -1061,7 +1073,7 @@ tr.recording_item:last-child { float: left; } -.recording_item div.recording_imgs{ +.recording_item div.recording_imgs { margin: 2px; } @@ -1099,7 +1111,9 @@ tr.recording_item:last-child { } .recording_item div.recording_actions { - padding-left: 5px; + float: right; + padding-left: 0.5em; + padding-right: 0.5em; } /* @@ -1306,25 +1320,16 @@ div.epg_content { overflow: hidden; } -div.epg_content div { - margin-left: 35px; -} - div.epg_content div.epg_tools { float: left; width: 26px; - margin: 0; + margin: 0 9px 0 0; padding: 0; padding-top: 3px; - text-align: center; vertical-align: top; } -div.epg_content div div { - margin-left: 0px; -} - div.epg_content div.epg_tools img { margin: 2px 5px; } @@ -1358,7 +1363,7 @@ div.epg_content div.about_right { } div.epg_content div.about_line { - padding-left: 0px; + padding-left: 30px; } div.epg_content div.about_head { diff --git a/live/js/live/infowin.js b/live/js/live/infowin.js index c01d704e..a3669668 100644 --- a/live/js/live/infowin.js +++ b/live/js/live/infowin.js @@ -167,7 +167,7 @@ var InfoWin = new Class({ this.fireEvent('onDomExtend', [id, bodyElems]); this.winBody.adopt(bodyElems); var firstScript = bodyElems.getElement('script.injectIcons'); - if (firstScript) { + if (firstScript && firstScript.length && firstScript[0]) { var js_m = new Element('div').adopt(firstScript).firstChild.textContent; eval(js_m); } diff --git a/pages/epginfo.ecpp b/pages/epginfo.ecpp index 1937fd87..85104594 100644 --- a/pages/epginfo.ecpp +++ b/pages/epginfo.ecpp @@ -152,7 +152,7 @@ using namespace vdrlive; if (epgEvent->EventDuration() < 0) { // epg event, no recording start += std::string(" - ") + epgEvent->EndTime(tr("%I:%M %p")); start += " "; - AppendDuration(start, tr("(%d:%02d)"), epgEvent->Duration()/60/60, epgEvent->Duration()/60 % 60); + AppendDuration(start, tr("(%d:%02d)"), epgEvent->Duration()); } std::string tools_component; @@ -167,7 +167,7 @@ using namespace vdrlive; tools_component = "epginfo.epgTools"; - <& pageelems.epg_tt_box boxId=(epgEvent->Id()) caption=(epgEvent->Caption()) tools_comp=(tools_component) time=(start) title=(epgEvent->Title()) short_descr=(epgEvent->ShortDescr()) long_descr=(epgEvent->LongDescr()) archived=(epgEvent->Archived()) elapsed=(epgEvent->Elapsed()) filename=(epgEvent->FileName()) epgImage=(epgImage) irecording=(irecording) ievent=(i_event) iepgEvent=(i_epgEvent) &> + <& pageelems.epg_tt_box boxId=(epgEvent->Id()) caption=(epgEvent->Caption()) tools_comp=(tools_component) time=(start) title=(epgEvent->Title()) short_descr=(epgEvent->ShortDescr()) long_descr=(epgEvent->LongDescr()) archived=(epgEvent->Archived()) elapsed=(epgEvent->Elapsed()) channel=(epgEvent->ChannelName()) filename=(epgEvent->FileName()) epgImage=(epgImage) irecording=(irecording) ievent=(i_event) iepgEvent=(i_epgEvent) &> <%cpp> } if (aboutBox) { diff --git a/pages/multischedule.ecpp b/pages/multischedule.ecpp index 234f94b0..86421b8a 100644 --- a/pages/multischedule.ecpp +++ b/pages/multischedule.ecpp @@ -21,6 +21,16 @@ struct SchedEntry { bool has_timer; int start_row; int row_count; + + static SchedEntry DummyEntry(int start_row, int row_count) { + SchedEntry en; + en.start_row = start_row; + en.row_count = row_count; + // no title and no start time = dummy event + en.title = ""; + en.start = ""; + return en; + } }; std::string channel_groups_setting; @@ -39,6 +49,8 @@ std::vector times_start; <%request scope="global"> unsigned int channel_group=0; unsigned int time_selected=0; + cString prev; + cString next; <%include>page_init.eh <%cpp> @@ -184,6 +196,7 @@ std::vector times_start; if ( channel >= (int)channel_groups_numbers.size() ) channel = 0; channel_group = channel; + { // build time list times_names.clear(); @@ -259,17 +272,44 @@ std::vector times_start; time_para = times_names.size()-1; time_selected=time_para; } + + if (channel_group > 0) + prev = cString::sprintf("href=\"multischedule.html?time_para=%i&channel=%i\"", time_selected, channel_group - 1); + if (channel_group < channel_groups_numbers.size() - 1) + next = cString::sprintf("href=\"multischedule.html?time_para=%i&channel=%i\"", time_selected, channel_group + 1); <& pageelems.doc_type &> - + VDR Live - <$ pageTitle $> <& pageelems.stylesheets &> <& pageelems.ajax_js &> - <& pageelems.create_html_js &> + <& pageelems.create_html_js &> + - + <& pageelems.logo &> <& menu active=("multischedule") component=("multischedule.channel_selection") &>
@@ -334,7 +374,12 @@ std::vector times_start; Schedule = schedules->GetSchedule( Channel ); #endif if ( ! Schedule ) + { + // insert dummy event for the entire channel if no EPG data + table[ j ].push_back( SchedEntry::DummyEntry(0 , sched_end_row)); + prev_row = sched_end_row; continue; + } for (const cEvent *Event = Schedule->Events()->First(); Event; Event = Schedule->Events()->Next(Event) ) { @@ -505,7 +550,7 @@ std::vector times_start; continue; } - // output an event cell + // output an event cell " rowspan="<$ en.row_count $>">
@@ -605,7 +650,7 @@ std::vector times_start; | -« Prev +"?>« Prev" ?> | -Next » +"?>Next »" ?> diff --git a/pages/pageelems.ecpp b/pages/pageelems.ecpp index 5b0bb2a7..84d96f29 100644 --- a/pages/pageelems.ecpp +++ b/pages/pageelems.ecpp @@ -67,7 +67,7 @@ else lf = " "; +<%cpp> if (sdhd) { + <%cpp> + } } } } @@ -588,10 +596,12 @@ injectHdSdIcon(\"icons-<$epgid$>\", \"<$sdhd$>\", \"<$(channel&&channel->Name()) <%cpp> if (cDevice::PrimaryDevice() && cDevice::PrimaryDevice()->HasDecoder() ) { - "><& pageelems.ajax_action_href action="switch_channel" tip=(tr("Switch to this channel.")) param=(channelId) image="zap.png" alt="" &> - <%cpp> } if (LiveFeatures().Recent() && eventId != 0) { - ">" alt="" <& tooltip.hint text=(tr("Search for repeats.")) &>> - <%cpp> } + "><& pageelems.ajax_action_href action="switch_channel" tip=(tr("Switch to this channel.")) param=(channelId) image="zap.png" alt="" &> + <%cpp> } if (LiveFeatures().Recent()) { + "> + <%cpp> if (eventId) { + " alt="" <& tooltip.hint text=(tr("Search for repeats.")) &>> + <%cpp> } } "><%cpp>if ((duration == 0) || (elapsed > 0)) { <& pageelems.hls_channel channelId=(channelId) &><%cpp> } <%cpp> if (LiveSetup().GetShowPlayMediaplayer() ) { "><%cpp>if ((duration == 0) || (elapsed > 0)) { <& pageelems.m3u_playlist_channel channelId=(channelId) &><%cpp> } @@ -618,6 +628,7 @@ injectHdSdIcon(\"icons-<$epgid$>\", \"<$sdhd$>\", \"<$(channel&&channel->Name()) std::string caption; std::string tools_comp; std::string time; + std::string channel; std::string title; std::string short_descr; std::string long_descr; @@ -742,23 +753,37 @@ if (scraperMovieOrTv.found) { <& (tools_comp) id=(boxId) archived=(archived) detail=(2) title=(title) s_IMDB_ID=(scraperMovieOrTv.IMDB_ID) &>
-
<%cpp> if (!archived.empty()) { <$ (archived + " ") $><%cpp> } - +
+
+<%cpp> if (epgEvent && epgEvent->EventDuration() >= 0) { // recording -<$ (time) $> ("><$ FormatDuration(tr("%d:%02d"), epgEvent->Duration()/60/60, epgEvent->Duration()/60 % 60)$>/"><$FormatDuration(tr("%d:%02d"), epgEvent->EventDuration()/60/60, epgEvent->EventDuration()/60 % 60)$>) -
-<%cpp> } else { -<$ (time) $>
- -<%cpp> } if (elapsed >= 0) { -
<& pageelems.progressbar progress=(elapsed) &>
+ "><$ FormatDuration(tr("%d:%02d"), epgEvent->Duration())$> / "><$FormatDuration(tr("%d:%02d"), epgEvent->EventDuration())$> <%cpp> - } +} +if (elapsed >= 0) { + +
<& pageelems.progressbar progress=(elapsed) &>
+<%cpp> +} + +
+
+<%cpp> +if (!archived.empty()) { + + <$ (archived + " ") $> +<%cpp> +} + + <$ (time) $> +<%cpp> +if (!filename.empty() && !channel.empty()) {
<$ (channel) $>
<%cpp> } -
<$ (title) $>
-
<$ (short_descr) $>
-
_description> +
+
<$ (title) $>
+
<$ (short_descr) $>
+
_description> <%cpp> std::list images = EpgEvents::EpgImages(boxId); @@ -1142,7 +1167,7 @@ for (const cTvMedia &media: *media_v) { (<$ tr("Homepage") $>)
<$ tr("Information providers") $>
-
Movie information provided by TMDB
+
Movie information provided by TMDB. This product uses the TMDB API but is not endorsed or certified by TMDB
Information provided by TheTVDB.com. Please consider supporting them
<$ tr("Bugs and suggestions") $>
<$ tr("If you encounter any bugs or would like to suggest new features, please use our bugtracker") $>:
diff --git a/pages/recordings.ecpp b/pages/recordings.ecpp index 235a6bf7..85708c13 100644 --- a/pages/recordings.ecpp +++ b/pages/recordings.ecpp @@ -159,16 +159,18 @@ function RecordingActionS(s, id, A, Img, Title) { // [7] : runtime (scraper) // [8] : relase date (scraper) // end scraper data -// [9] : Day, time & duration +// [9] : Day, time // [10] : Number of recording errors -// [11] : SD/HD/UHD s/h/u -// [12] : SD/HD/UHD title +// [11] : audio/SD/HD/UHD r/s/h/u +// [12] : channel name // [13] : _new // [14] : Name // [15] : Shorttext // [16] : Description // [17] : Recording Length deviation in seconds // [18] : Folder (if displayFolder == true. Otherwise, this does not exist / out of range) +// [19] : duration +// [20] : size #> function RecordingsSt(s, level, displayFolder, data) { s.a += '
  • ' @@ -194,8 +196,12 @@ function RecordingsSt(s, level, displayFolder, data) { addScraperImageTitle(s, obj[3], obj[4], obj[5], obj[6], obj[7], obj[8], '<$$lf$>'); s.a += '' <%cpp> } - s.a += '
    ' + s.a += '