From 350ebad826ece189072d19b2dc9224ffc8e4aced Mon Sep 17 00:00:00 2001 From: Martin Wache Date: Sat, 20 Nov 2010 13:07:12 +0100 Subject: - some fixes and improvements to multischedule --- css/styles.css | 70 ++++++++++++++ pages/menu.ecpp | 1 + pages/multischedule.ecpp | 231 +++++++++++++++++++++++++++++++++++------------ tools.cpp | 1 + 4 files changed, 243 insertions(+), 60 deletions(-) diff --git a/css/styles.css b/css/styles.css index 4fd23b1..35b2119 100644 --- a/css/styles.css +++ b/css/styles.css @@ -867,6 +867,76 @@ table.listing a { font-weight: bold; } +/* ################################## + # table schedule + # (this is used for the MultiSchedule) + ################################## +*/ + +table.mschedule { + padding: 0px; + margin: 0px; +} + +table.mschedule tr { + height: 12px; +} + +table.mschedule tr td.event { + background: transparent url(img/bg_line.png) bottom repeat-x; + border-bottom: 1px solid #C0C1DA; +} + +table.mschedule tr.odd td.time { + background-color: #D0D0ff; +} + +table.mschedule tr.even td.time { + background-color: #ffffff; +} + +table.mschedule tr.current_row td.time { + background-color: #ffB0B0; +} + +table.mschedule tr td.leftcol { + padding-left: 7px; + padding-right: 5px; +} + +table.mschedule div.content1 { + min-width: 20em; + max-width: 30em; +} + +table.mschedule div.tools1 { + float: right; +} + +table.mschedule div.start { + float: left; +} + +table.mschedule tr td div.title { + padding: 3px; + clear: both; +} + +table.mschedule tr td div.short { + clear: both; + overflow: hidden; +} + +table.mschedule tr td div.description { + overflow: hidden; + clear: both; +} + +table.mschedule a { + color: black; + font-weight: bold; +} + /* ############################## # Blue Background Thingy diff --git a/pages/menu.ecpp b/pages/menu.ecpp index dbcb862..5721e42 100644 --- a/pages/menu.ecpp +++ b/pages/menu.ecpp @@ -86,6 +86,7 @@ if (!component.empty()) {
<& menu.component current=("whats_on") &> <& menu.component current=("schedule") &> + <& menu.component current=("multischedule") &> <& menu.component current=("timers") &> <%cpp> if (LiveFeatures< features::epgsearch >().Recent()) { diff --git a/pages/multischedule.ecpp b/pages/multischedule.ecpp index ab97d9b..3d207ec 100644 --- a/pages/multischedule.ecpp +++ b/pages/multischedule.ecpp @@ -18,17 +18,19 @@ struct SchedEntry { string title; string short_description; string description; + string description_trunc; string start; string end; string day; string epgid; + bool truncated; int start_row; int row_count; }; <%args> - int channel = -1; + int channel = 1; <%session scope="global"> bool logged_in(false); @@ -39,33 +41,10 @@ bool logged_in(false); <%include>page_init.eh <%cpp> if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); - -<%cpp> - pageTitle = trVDR("Schedule"); - - cSchedulesLock schedulesLock; - cSchedules const* schedules = cSchedules::Schedules( schedulesLock ); - - ReadLock channelsLock( Channels ); - if ( !channelsLock ) - throw HtmlError( tr("Couldn't aquire access to channels, please try again later.") ); - - // cChannel* Channel; (see %request above) - if ( channel > 0 ) { - Channel = Channels.GetByNumber( channel ); - } - else { - if (cDevice::CurrentChannel()) { - Channel = Channels.GetByNumber(cDevice::CurrentChannel()); - } - else { - Channel = Channels.Get( Channels.GetNextNormal( -1 ) ); - } - } - if ( Channel == 0 ) - throw HtmlError( tr("Couldn't find channel or no channels available. Maybe you mistyped your request?") ); - - cSchedule const* Schedule = schedules->GetSchedule( Channel ); +pageTitle = trVDR("Schedule"); + Channel = Channels.GetByNumber( channel ); + if (!Channel) + throw HtmlError( tr("Error didn't find the channel") ); <& pageelems.doc_type &> @@ -76,32 +55,64 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); <& pageelems.logo &> - <& menu active=("multischedule") component=("schedule.channel_selection") &> + <& menu active=("multischedule") component=("multischedule.channel_selection") &>
<%cpp> - if ( Schedule == 0 ) { - - <$ tr("No schedules available for this channel") $>. -<%cpp> - } - else { + + cSchedulesLock schedulesLock; + cSchedules const* schedules = cSchedules::Schedules( schedulesLock ); + + ReadLock channelsLock( Channels ); + if ( !channelsLock ) + throw HtmlError( tr("Couldn't aquire access to channels, please try again later.") ); +{ time_t now = time(NULL) - ::Setup.EPGLinger * 60; time_t sched_start = 3600 * (now / 3600); // start at a full hour // tChannelID channel_id(Channel->GetChannelID()); // int evntNr = 0; -#define MAX_CHANNELS 5 +#define MAX_CHANNELS 3 #define MAX_EVENTS 200 -#define MINUTES_PER_ROW 6 +#define MINUTES_PER_ROW 5 +#define CHARACTERS_PER_ROW 30 SchedEntry table[MAX_CHANNELS][MAX_EVENTS]; + int chan = 0; + int count[ MAX_CHANNELS ]; + string channel_names[ MAX_CHANNELS]; + for ( chan = 0; chanEvents()->First(); Event && count < MAX_EVENTS; + count[ chan ] = 0; + + Channel = Channels.GetByNumber( channel+chan ); + if ( ! Channel ) + continue; + if ( Channel->GroupSep() || Channel->Name() == '\0' ) + continue; + channel_names[ chan ] = Channel->Name(); + + cSchedule const* Schedule = schedules->GetSchedule( Channel ); + if ( ! Schedule ) + continue; + for (const cEvent *Event = Schedule->Events()->First(); Event && count[chan] < MAX_EVENTS; Event = Schedule->Events()->Next(Event)) { if (Event->EndTime() <= sched_start ) continue; EpgInfoPtr epgEvent = EpgEvents::CreateEpgInfo(Channel, Event); - SchedEntry &en=table[0][count]; + if ( prev_row < 0 && Event->StartTime() > sched_start + MINUTES_PER_ROW ) + { + // insert dummy event at start + SchedEntry &en=table[chan][count[chan]]; + int event_start_row = (Event->StartTime() - sched_start) / 60 / MINUTES_PER_ROW; + en.start_row = 0; + en.row_count = event_start_row; + // no title and no start time = dummy event + en.title = ""; + en.start = ""; + prev_row = en.start_row + en.row_count; + count[chan]++; + } + SchedEntry &en=table[chan][count[chan]]; en.title = epgEvent->Title(); en.short_description = epgEvent->ShortDescr(); @@ -113,31 +124,71 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); // string strEventID = lexical_cast(Event->EventID(); en.start_row = prev_row > 0 ? prev_row : 0; - prev_row = en.start_row; int end_time = Schedule->Events()->Next(Event) ? Schedule->Events()->Next(Event)->StartTime() : Event->EndTime(); int next_event_start_row = (end_time - sched_start) / 60 / MINUTES_PER_ROW; en.row_count = next_event_start_row - en.start_row; - if ( en.row_count < 2 ) - en.row_count = 2; + if ( en.row_count < 1 ) + en.row_count = 1; prev_row = en.start_row + en.row_count; - count++; - }; + + // truncate description if too long + en.truncated=false; + en.description_trunc=StringWordTruncate( en.description, + CHARACTERS_PER_ROW*(en.row_count-2), + en.truncated ); + + + + count[chan]++; + }; + } - +
<%cpp> time_t sched_end = sched_start + 60 * 60 * 12; // 12 hr int sched_end_row = ( sched_end - sched_start ) / 60 / MINUTES_PER_ROW; - int cur_event = 0; - for (int row = 0 ; row < sched_end_row; row++ ) + int cur_event[ MAX_CHANNELS ]; + for (int i=0;i + + + +<%cpp> + for ( int channel = 0; channel< MAX_CHANNELS ; channel++) + { + + + +<%cpp> + } + + +<%cpp> + bool odd=true; + for (int row = 0 ; row < sched_end_row; row++ ) { + int minutes= ( (sched_start + row * 60 * MINUTES_PER_ROW ) % 3600 ) / 60; + string row_class; + if ( minutes == 0 ) + { + // full hour, swap odd/even + odd = !odd; + }; + if ( (sched_start + row * 60 * MINUTES_PER_ROW ) <= now && + (sched_start + (row+1) * 60 * MINUTES_PER_ROW ) > now ) + { + row_class +=" current_row "; + } + row_class += odd ? " odd " : " even "; - - + <%cpp> - if ( table[0][cur_event].start_row == row ) - { - SchedEntry &en=table[0][cur_event]; - bool truncated = false; + for ( int channel = 0; channel< MAX_CHANNELS ; channel++) + { + // output spacer column - + <%cpp> - cur_event++; - } + if ( table[channel][cur_event[channel]].start_row != row ) + // no new event in this channel, skip it + continue; + + SchedEntry &en=table[channel][cur_event[channel]]; + if (en.title.empty() && en.start.empty() ) + { + // empty dummy event + + +<%cpp> + cur_event[channel]++; + continue; + + } + // output an event cell + + +<%cpp> + // move to next event for this channel + cur_event[channel]++; + } <%cpp> diff --git a/tools.cpp b/tools.cpp index bda91f0..e8589d7 100644 --- a/tools.cpp +++ b/tools.cpp @@ -114,6 +114,7 @@ namespace vdrlive { { if (input.length() <= maxLen) { + truncated = false; return input; } truncated = true; -- cgit v1.2.3
<$ tr("Time") $>
 
<$ channel_names[channel] $>
 
+
<%cpp> - if ( (sched_start + row * 60 * MINUTES_PER_ROW ) % 3600 == 0 ) + if ( minutes == 0 ) { <$ FormatDateTime( tr("%I:%M %p"), sched_start + row * 60 * MINUTES_PER_ROW ) $> @@ -148,20 +199,80 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html");   <%cpp> - } + } -   + +
+
+ <& pageelems.event_timer epgid=(en.epgid) &> +<%cpp> + if (LiveFeatures().Recent() ) { + + " alt="" <& tooltip.hint text=(tr("Search for repeats.")) &>> +<%cpp> + } else { + <%cpp> + } + + <& pageelems.imdb_info_href title=(en.title) &> +
<$ en.start $>
+ +<%cpp> + if ( en.row_count>2 && !en.short_description.empty() ) + { + +
<$ en.short_description.empty() ? " " : en.short_description $>
+<%cpp> + } + if ( en.row_count>3 && ! en.description_trunc.empty() ) + { + +
<$en.description_trunc$>... +<%cpp> + if ( en.truncated ) + { + + <& tooltip.display domId=en.epgid &>> <$ tr("more") $> +<%cpp> + } + +
+<%cpp> + + } + + +