diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | css/styles.css | 9 | ||||
-rw-r--r-- | epg_events.cpp | 47 | ||||
-rw-r--r-- | epg_events.h | 62 | ||||
-rw-r--r-- | pages/pageelems.ecpp | 41 | ||||
-rw-r--r-- | pages/recordings.ecpp | 2 | ||||
-rw-r--r-- | pages/whats_on.ecpp | 51 | ||||
-rw-r--r-- | tools.cpp | 5 | ||||
-rw-r--r-- | tools.h | 1 |
9 files changed, 170 insertions, 52 deletions
@@ -1,7 +1,7 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile,v 1.29 2007/01/18 18:29:30 lordjaxom Exp $ +# $Id: Makefile,v 1.30 2007/01/19 22:03:03 tadi Exp $ # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. @@ -59,7 +59,7 @@ SUBDIRS = httpd pages css images javascript ### The object files (add further files here): PLUGINOBJS = $(PLUGIN).o thread.o tntconfig.o setup.o i18n.o timers.o \ - tools.o recordings.o tasks.o status.o + tools.o recordings.o tasks.o status.o epg_events.o WEBLIBS = pages/libpages.a css/libcss.a images/libimages.a \ javascript/libjavascript.a diff --git a/css/styles.css b/css/styles.css index d4f04a1..e303e35 100644 --- a/css/styles.css +++ b/css/styles.css @@ -41,6 +41,7 @@ div.domTThint { font-size: 11px; border: 1px solid #EBC94C; background-color: #F4FFC3; + max-width: 35em; } div.domTThint .caption { @@ -201,7 +202,7 @@ table td.buttonpanel { */ div.event { width: 255px; - height: 255px; + height: 155px; padding: 0; margin-right: 5px; float: left; @@ -238,7 +239,7 @@ div.station div div div { div.content { width: 253px; - height: 220px; + height: 120px; padding: 0; margin: 0; @@ -251,7 +252,7 @@ div.content { div.content div.tools { float: left; width: 26px; - height: 220px; + height: 120px; margin: 0; padding: 0; @@ -270,6 +271,8 @@ div.content div { div.description { margin: 5px; + font-weight: bold; + cursor: pointer; } div.info { diff --git a/epg_events.cpp b/epg_events.cpp new file mode 100644 index 0000000..f2f7fc2 --- /dev/null +++ b/epg_events.cpp @@ -0,0 +1,47 @@ +#include "tools.h" + +#include "epg_events.h" + +namespace vdrlive +{ + EpgEvent::EpgEvent(const std::string& id, const cEvent* event, const char* channelName) : + eventId(id), + title(event->Title() ? event->Title() : ""), + channel_name(channelName), + short_descr(event->ShortText() ? event->ShortText() : ""), + long_descr(event->Description() ? event->Description() : ""), + start_time(event->StartTime()), + end_time(event->EndTime()) + { + } + + EpgEvent::~EpgEvent() + { + } + + const std::string EpgEvent::StartTime(const char* format) const + { + return FormatDateTime(format, start_time); + } + + const std::string EpgEvent::EndTime(const char* format) const + { + return FormatDateTime(format, end_time); + } + + EpgEvents::EpgEvents() : + std::vector<EpgEventPtr>() + { + } + + EpgEvents::~EpgEvents() + { + } +#ifdef never + EpgEventsPtr EpgEvents::dim(size_t count) + { + EpgEventsPtr ePtr(new EpgEvents(count)); + return ePtr; + } +#endif +}; // namespace vdrlive diff --git a/epg_events.h b/epg_events.h new file mode 100644 index 0000000..61ba3ff --- /dev/null +++ b/epg_events.h @@ -0,0 +1,62 @@ +#ifndef VDR_LIVE_WHATS_ON_H +#define VDR_LIVE_WHATS_ON_H + +#include <ctime> +#include <vector> +#include <boost/shared_ptr.hpp> + +#include <vdr/plugin.h> +#include <vdr/channels.h> +#include <vdr/epg.h> +#include <vdr/config.h> +#include <vdr/i18n.h> + +#include "live.h" + +namespace vdrlive +{ + + class EpgEvent + { + public: + EpgEvent(const std::string& id, const cEvent* event, const char* channelName = ""); + + virtual ~EpgEvent(); + + const std::string& Id() const { return eventId; } + + const std::string& Title() const { return title; } + + const std::string& ChannelName() const { return channel_name; } + + const std::string& ShortDescr() const { return short_descr; } + + const std::string& LongDescr() const { return long_descr; } + + const std::string StartTime(const char* format) const; + + const std::string EndTime(const char* format) const; + + private: + std::string eventId; + std::string title; + std::string channel_name; + std::string short_descr; + std::string long_descr; + time_t start_time; + time_t end_time; + }; + + typedef boost::shared_ptr<EpgEvent> EpgEventPtr; + + class EpgEvents : public std::vector<EpgEventPtr> { + public: + EpgEvents(); + virtual ~EpgEvents(); + + private: + }; +}; // namespace vdrlive + +#endif // VDR_LIVE_WHATS_ON_H + diff --git a/pages/pageelems.ecpp b/pages/pageelems.ecpp index 932184b..61089b1 100644 --- a/pages/pageelems.ecpp +++ b/pages/pageelems.ecpp @@ -4,41 +4,23 @@ #include "tools.h" using namespace std; +using namespace vdrlive; </%pre> +<# ---------------------------------------------------------------------- #> + <%def doc_type> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> </%def> +<# ---------------------------------------------------------------------- #> + <%def logo> <img src="logo.png" alt="VDR Live!" class="logo"/> </%def> -<# -<%def header_box> -<%args> -content[]; -component; -</%args> -<{ -}> - <div class="head_box_l"> - <div class="head_box_m"> - <div class="head_box_r"> - <table class="head_box_text"><tr><td> -% for(content_type::const_iterator it = content.begin(); it != content.end(); ++it) { - <$ *it $> -% } -% if (!component.empty()) { - <& (component) &> -% } - </td></tr></table> - </div> - </div> - </div> -</%def> -#> +<# ---------------------------------------------------------------------- #> <%def event_timer> <%args> @@ -48,20 +30,27 @@ component; <a href="edit_timer.html?channelid=<$ channelid $>&eventid=<$ eventid $>"><img src="record.png" alt="" <& tooltip.hint text=(tr("Record this")) &> /></a> </%def> +<# ---------------------------------------------------------------------- #> + <%def ajax_js> <script type="text/javascript" language="javascript" src="ajax.js"></script> </%def> +<# ---------------------------------------------------------------------- #> + <%def ajax_action_href> <%args> string action; + string tip; string param; string image; string alt = ""; </%args> - <a href="javascript:LiveSimpleAjaxRequest('<$ action $>.xml', 'param', '<$ param $>');"><img src="<$ image $>" border="0" alt="<$ alt $>" /></a> + <a href="javascript:LiveSimpleAjaxRequest('<$ action $>.xml', 'param', '<$ param $>');" <%cpp>if (!tip.empty()) { </%cpp><& tooltip.hint text=(tip) &> <%cpp> } </%cpp>><img src="<$ image $>" alt="<$ alt $>" /></a> </%def> +<# ---------------------------------------------------------------------- #> + <%def epg_tt_box> <%args> string boxId; @@ -85,7 +74,7 @@ component; <div class="title"><$ (title) $></div> <div class="short"><$ (short_descr) $></div> <div class="description"> - <$ (long_descr) $> + <{ reply.out() << StringEscapeAndBreak(long_descr); }> </div> </div> </div> diff --git a/pages/recordings.ecpp b/pages/recordings.ecpp index 59d255c..a97dd17 100644 --- a/pages/recordings.ecpp +++ b/pages/recordings.ecpp @@ -37,7 +37,7 @@ RecordingsTree::RecordingsItemPtr currRecItem; <div class="recordings"> <& recordings.recordings_item &> </div> - <div class="recordings_data" style="display: none;"> + <div class="epg_data" style="display: none;"> <& recordings.recordings_data &> </div> % } diff --git a/pages/whats_on.ecpp b/pages/whats_on.ecpp index b9062e0..d0e0595 100644 --- a/pages/whats_on.ecpp +++ b/pages/whats_on.ecpp @@ -6,6 +6,7 @@ #include <vdr/i18n.h> #include "setup.h" #include "tools.h" +#include "epg_events.h" using namespace std; using namespace vdrlive; @@ -34,7 +35,7 @@ if (type == "now") { <head> <title>VDR-Live - <$ head $></title> <link rel="stylesheet" type="text/css" href="styles.css" /> - <& tooltip.javascript &> + <& tooltip.javascript var=("domTT_oneOnly") value=("true") var=("domTT_styleClass") value=("domTTepg") &> <& pageelems.ajax_js &> </head> <body> @@ -42,50 +43,47 @@ if (type == "now") { <& menu active=(type) &> <div class="inhalt"> <{ + EpgEvents epgEvents; + ReadLock channelsLock( Channels ); if (channelsLock) { + int evntNr = 0; for (cChannel *Channel = Channels.First(); Channel && Channel->Number() <= LiveSetup().GetLastChannel(); Channel = Channels.Next(Channel)) { if (!Channel->GroupSep()) { const cSchedule *Schedule = Schedules->GetSchedule(Channel); if (Schedule) { const cEvent *Event = (type == "now" ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent()); if (Event) { - string title(Event->Title() ? Event->Title() : ""); - string channel_name(Channel->Name()); - string short_description(Event->ShortText() ? Event->ShortText() : ""); - string description(Event->Description() ? Event->Description() : ""); - string start(Event->StartTime() ? FormatDateTime(tr("%I:%M %p"), Event->StartTime()) : ""); - string end(Event->EndTime() ? FormatDateTime(tr("%I:%M %p"), Event->EndTime()) : ""); + std::string evntId("eventId_"); + evntId += lexical_cast<std::string, int>(++evntNr); + EpgEventPtr epgEvent(new EpgEvent(evntId, Event, Channel->Name())); + epgEvents.push_back(epgEvent); tChannelID channel_id(Channel->GetChannelID()); tEventID event = Event->EventID(); bool truncated = false; - description = StringWordTruncate(description, 250, truncated); - if (truncated) { - description += string(" ") + tr("more") + string(" ..."); - } + string description(StringWordTruncate(epgEvent->LongDescr(), 250, truncated)); }> <div class="event"> <div class="station"> - <div><div><div><$ channel_name $></div></div></div> + <div><div><div><$ (epgEvent->ChannelName()) $></div></div></div> </div> <div class="content"> <div class="tools"> <& pageelems.event_timer channelid=(channel_id) eventid=(event) &> - <& pageelems.ajax_action_href action="switch_channel" param=(channel_id) image="zap.png" alt="" &> +% if (type == "now") { + <& pageelems.ajax_action_href action="switch_channel" tip=(tr("Switch to this channel.")) param=(channel_id) image="zap.png" alt="" &> +% } </div> <div> - <div class="info"><$ start $> - <$ end $></div> - <div class="title"><$ title $></div> - <div class="short"><$ short_description $></div> - <div class="description"> - <{ reply.out() << StringEscapeAndBreak( description ); }> - </div> + <div class="info"><$ (epgEvent->StartTime(tr("%I:%M %p"))) $> - <$ (epgEvent->EndTime(tr("%I:%M %p"))) $></div> + <div class="title"><$ (epgEvent->Title()) $></div> + <div class="short"><$ (epgEvent->ShortDescr()) $></div> + <div class="description"<& tooltip.hint text=(StringEscapeAndBreak(description) + string("<br />") + string(tr("Click to view details."))) &><& tooltip.display domId=(epgEvent->Id()) &>><$ (string(tr("more")) + string(" ...")) $></div> </div> </div> </div> - <{ } } @@ -94,6 +92,19 @@ if (type == "now") { } }> </div> + + <div class="epg_data" style="display: none;"> +<{ + // create hidden div for the tooltip hints. + for (vector<EpgEventPtr>::iterator i = epgEvents.begin(); i != epgEvents.end(); ++i) { + EpgEventPtr epg = *i; +}> + <& pageelems.epg_tt_box boxId=(epg->Id()) caption=(epg->ChannelName()) time=(epg->StartTime(tr("%I:%M %p")) + string(" - ") + epg->EndTime(tr("%I:%M %p"))) title=(epg->Title()) short_descr=(epg->ShortDescr()) long_descr=(epg->LongDescr()) &> +<{ + } +}> + </div> + </body> </html> <%include>page_exit.eh</%include> @@ -95,6 +95,11 @@ string StringWordTruncate(const string& input, size_t maxLen, bool& truncated) return result.substr(0, pos); } +string StringFormatBreak(string const& input) +{ + return StringReplace( input, "\n", "<br/>" ); +} + string StringEscapeAndBreak( string const& input ) { stringstream plainBuilder; @@ -28,6 +28,7 @@ int StringToInt( std::string const& string, int base = 10 ); std::string StringRepeat(int times, const std::string& input); std::string StringWordTruncate(const std::string& input, size_t maxLen, bool& truncated); std::string StringEscapeAndBreak( std::string const& input ); +std::string StringFormatBreak(std::string const& input); struct bad_lexical_cast: std::runtime_error { |