summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--css/styles.css10
-rw-r--r--epg_events.cpp22
-rw-r--r--epg_events.h13
-rw-r--r--i18n.cpp310
-rw-r--r--images/Makefile2
-rw-r--r--images/on_dvd.pngbin0 -> 821 bytes
-rw-r--r--javascript/vdr_status.js2
-rw-r--r--pages/pageelems.ecpp47
-rw-r--r--pages/recordings.ecpp184
-rw-r--r--pages/tooltip.ecpp8
-rw-r--r--recordings.cpp68
-rw-r--r--recordings.h12
12 files changed, 434 insertions, 244 deletions
diff --git a/css/styles.css b/css/styles.css
index 2cfce95..734788b 100644
--- a/css/styles.css
+++ b/css/styles.css
@@ -34,6 +34,15 @@ img {
}
/* ######################
+ # global style properties
+ ######################
+*/
+
+.bold {
+ font-weight: bold;
+}
+
+/* ######################
# Tooltip style for hints
######################
*/
@@ -591,6 +600,7 @@ div.boxheader div div {
*/
div.recordings {
+ border: 1px solid black;
}
.recordings ul {
diff --git a/epg_events.cpp b/epg_events.cpp
index ec95fde..2d5237c 100644
--- a/epg_events.cpp
+++ b/epg_events.cpp
@@ -1,6 +1,7 @@
#include <time.h>
#include "tools.h"
+#include "recordings.h"
#include "epg_events.h"
@@ -18,6 +19,7 @@ namespace vdrlive
m_title(title),
m_short_descr(short_descr),
m_long_descr(long_descr),
+ m_archived(),
m_start_time(start_time),
m_end_time(end_time)
{
@@ -29,11 +31,31 @@ namespace vdrlive
m_title(event->Title() ? event->Title() : ""),
m_short_descr(event->ShortText() ? event->ShortText() : ""),
m_long_descr(event->Description() ? event->Description() : ""),
+ m_archived(),
m_start_time(event->StartTime()),
m_end_time(event->EndTime())
{
}
+ EpgEvent::EpgEvent(const std::string& id,
+ const std::string& caption,
+ const std::string& title,
+ const std::string& short_descr,
+ const std::string& long_descr,
+ const std::string& archived,
+ time_t start_time,
+ time_t end_time) :
+ m_eventId(id),
+ m_caption(caption),
+ m_title(title),
+ m_short_descr(short_descr),
+ m_long_descr(long_descr),
+ m_archived(archived),
+ m_start_time(start_time),
+ m_end_time(end_time)
+ {
+ }
+
EpgEvent::~EpgEvent()
{
}
diff --git a/epg_events.h b/epg_events.h
index 330f7ba..03c7947 100644
--- a/epg_events.h
+++ b/epg_events.h
@@ -15,7 +15,6 @@
namespace vdrlive
{
-
class EpgEvent
{
public:
@@ -31,6 +30,15 @@ namespace vdrlive
const cEvent* event,
const char* channelName = "");
+ EpgEvent(const std::string& id,
+ const std::string& caption,
+ const std::string& title,
+ const std::string& short_descr,
+ const std::string& long_descr,
+ const std::string& archived,
+ time_t start_time,
+ time_t end_time);
+
virtual ~EpgEvent();
const std::string& Id() const { return m_eventId; }
@@ -43,6 +51,8 @@ namespace vdrlive
const std::string& LongDescr() const { return m_long_descr; }
+ const std::string& Archived() const { return m_archived; }
+
const std::string StartTime(const char* format) const;
const std::string EndTime(const char* format) const;
@@ -59,6 +69,7 @@ namespace vdrlive
std::string m_title;
std::string m_short_descr;
std::string m_long_descr;
+ std::string m_archived;
time_t m_start_time;
time_t m_end_time;
};
diff --git a/i18n.cpp b/i18n.cpp
index 07bf47b..dfa0259 100644
--- a/i18n.cpp
+++ b/i18n.cpp
@@ -201,6 +201,50 @@ const tI18nPhrase Phrases[] = {
"", // Dansk
"", // Czech
},
+ { "List of recordings", // English
+ "Liste der Aufnahmen", // Deutsch
+ "", // Slovenski
+ "", // Italiano
+ "", // Nederlands
+ "", // Português
+ "", // Français
+ "", // Norsk
+ "", // Finnish
+ "", // Polski
+ "", // Español
+ "", // Greek
+ "", // Svenska
+ "", // Românã
+ "", // Magyar
+ "", // Català
+ "", // Russian
+ "", // Hrvatski
+ "", // Eesti
+ "", // Dansk
+ "", // Czech
+ },
+ { "No recordings found", // English
+ "Keine Aufnahmen vorhanden", // Deutsch
+ "", // Slovenski
+ "", // Italiano
+ "", // Nederlands
+ "", // Português
+ "", // Français
+ "", // Norsk
+ "", // Finnish
+ "", // Polski
+ "", // Español
+ "", // Greek
+ "", // Svenska
+ "", // Românã
+ "", // Magyar
+ "", // Català
+ "", // Russian
+ "", // Hrvatski
+ "", // Eesti
+ "", // Dansk
+ "", // Czech
+ },
{ "Remote Control", // English
"Fernbedienung", // Deutsch
"", // Slovenski
@@ -2669,26 +2713,26 @@ const tI18nPhrase Phrases[] = {
"",
},
{ "Delete this search timer?", // English
- "Diesen Suchtimer löschen?", // Deutsch
- "", // Slovenski
- "", // Italiano
- "", // Nederlands
- "", // Português
- "", // Français
- "", // Norsk
- "", // Finnish
- "", // Polski
- "", // Español
- "", // Greek
- "", // Svenska
- "", // Românã
- "", // Magyar
- "", // Català
- "", // Russian
- "", // Hrvatski
- "", // Eesti
- "", // Dansk
- "", // Czech
+ "Diesen Suchtimer löschen?", // Deutsch
+ "", // Slovenski
+ "", // Italiano
+ "", // Nederlands
+ "", // Português
+ "", // Français
+ "", // Norsk
+ "", // Finnish
+ "", // Polski
+ "", // Español
+ "", // Greek
+ "", // Svenska
+ "", // Românã
+ "", // Magyar
+ "", // Català
+ "", // Russian
+ "", // Hrvatski
+ "", // Eesti
+ "", // Dansk
+ "", // Czech
},
{ "Cancel",
"Abbrechen",
@@ -2735,7 +2779,7 @@ const tI18nPhrase Phrases[] = {
"",
"",
},
- { "Test", // English
+ { "Test", // English
"Testen", // Deutsch
"", // Slovenski
"", // Italiano
@@ -2756,8 +2800,8 @@ const tI18nPhrase Phrases[] = {
"", // Eesti
"", // Dansk
"", // Czech
- },
- { "The time the show may start at the latest", // English
+ },
+ { "The time the show may start at the latest", // English
"Die Zeit, zu der die Sendung spätestens angefangen haben muss", // Deutsch
"", // Slovenski
"", // Italiano
@@ -2778,8 +2822,8 @@ const tI18nPhrase Phrases[] = {
"", // Eesti
"", // Dansk
"", // Czech
- },
- { "The time the show may start at the earliest", // English
+ },
+ { "The time the show may start at the earliest", // English
"Die Zeit, zu der die Sendung frühestens anfangen darf", // Deutsch
"", // Slovenski
"", // Italiano
@@ -2800,31 +2844,31 @@ const tI18nPhrase Phrases[] = {
"", // Eesti
"", // Dansk
"", // Czech
- },
+ },
{ "Search text too short - use anyway?",
- "Suchtext zu kurz - trotzdem verwenden?",
- "",// TODO
- "Il testo da cercare è troppo corto. Continuare lo stesso?",// Italiano
- "Zoek tekst tekort - toch gebruiken?",
- "",// TODO
- "Texte de recherche est trop court - l'utiliser comme même?",
- "",// TODO
- "Liian suppea hakuehto - etsitäänkö silti?",
- "",// TODO
- "",// TODO
- "",// TODO
- "",// TODO
- "",// TODO
- "",// TODO
- "",// TODO
- "",// TODO
- "",// TODO
- "",// TODO Eesti
- "",// TODO Dansk
- "",// TODO Èesky (Czech)
+ "Suchtext zu kurz - trotzdem verwenden?",
+ "",// TODO
+ "Il testo da cercare è troppo corto. Continuare lo stesso?",// Italiano
+ "Zoek tekst tekort - toch gebruiken?",
+ "",// TODO
+ "Texte de recherche est trop court - l'utiliser comme même?",
+ "",// TODO
+ "Liian suppea hakuehto - etsitäänkö silti?",
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO Eesti
+ "",// TODO Dansk
+ "",// TODO Èesky (Czech)
},
- { "User", // English
+ { "User", // English
"Benutzer", // Deutsch
"", // Slovenski
"", // Italiano
@@ -2845,8 +2889,8 @@ const tI18nPhrase Phrases[] = {
"", // Eesti
"", // Dansk
"", // Czech
- },
- { "Password", // English
+ },
+ { "Password", // English
"Passwort", // Deutsch
"", // Slovenski
"", // Italiano
@@ -2867,8 +2911,8 @@ const tI18nPhrase Phrases[] = {
"", // Eesti
"", // Dansk
"", // Czech
- },
- { "Last channel to display", // English
+ },
+ { "Last channel to display", // English
"Letzer angezeigter Kanal", // Deutsch
"", // Slovenski
"", // Italiano
@@ -2889,8 +2933,8 @@ const tI18nPhrase Phrases[] = {
"", // Eesti
"", // Dansk
"", // Czech
- },
- { "Use authentication", // English
+ },
+ { "Use authentication", // English
"Authentifizierung nutzen", // Deutsch
"", // Slovenski
"", // Italiano
@@ -2911,8 +2955,8 @@ const tI18nPhrase Phrases[] = {
"", // Eesti
"", // Dansk
"", // Czech
- },
- { "No Limit", // English
+ },
+ { "No Limit", // English
"Alle zeigen", // Deutsch
"", // Slovenski
"", // Italiano
@@ -2933,8 +2977,8 @@ const tI18nPhrase Phrases[] = {
"", // Eesti
"", // Dansk
"", // Czech
- },
- { "Admin login", // English
+ },
+ { "Admin login", // English
"Admin Login", // Deutsch
"", // Slovenski
"", // Italiano
@@ -2955,8 +2999,8 @@ const tI18nPhrase Phrases[] = {
"", // Eesti
"", // Dansk
"", // Czech
- },
- { "Admin password", // English
+ },
+ { "Admin password", // English
"Admin Passwort", // Deutsch
"", // Slovenski
"", // Italiano
@@ -2977,8 +3021,8 @@ const tI18nPhrase Phrases[] = {
"", // Eesti
"", // Dansk
"", // Czech
- },
- { "VDR Live Login", // English
+ },
+ { "VDR Live Login", // English
"VDR Live Login", // Deutsch
"", // Slovenski
"", // Italiano
@@ -2999,7 +3043,7 @@ const tI18nPhrase Phrases[] = {
"", // Eesti
"", // Dansk
"", // Czech
- },
+ },
{ "Logout", // English
"Abmelden", // Deutsch
"", // Slovenski
@@ -3045,70 +3089,92 @@ const tI18nPhrase Phrases[] = {
"", // Czech
},
{ "Search", // English
- "Suchen", // Deutsch
- "", // Slovenski
- "", // Italiano
- "", // Nederlands
- "", // Português
- "", // Français
- "", // Norsk
- "", // Finnish
- "", // Polski
- "", // Español
- "", // Greek
- "", // Svenska
- "", // Românã
- "", // Magyar
- "", // Català
- "", // Russian
- "", // Hrvatski
- "", // Eesti
- "", // Dansk
- "", // Czech
+ "Suchen", // Deutsch
+ "", // Slovenski
+ "", // Italiano
+ "", // Nederlands
+ "", // Português
+ "", // Français
+ "", // Norsk
+ "", // Finnish
+ "", // Polski
+ "", // Español
+ "", // Greek
+ "", // Svenska
+ "", // Românã
+ "", // Magyar
+ "", // Català
+ "", // Russian
+ "", // Hrvatski
+ "", // Eesti
+ "", // Dansk
+ "", // Czech
},
{ "Extended search", // English
- "Erweiterte Suche", // Deutsch
- "", // Slovenski
- "", // Italiano
- "", // Nederlands
- "", // Português
- "", // Français
- "", // Norsk
- "", // Finnish
- "", // Polski
- "", // Español
- "", // Greek
- "", // Svenska
- "", // Românã
- "", // Magyar
- "", // Català
- "", // Russian
- "", // Hrvatski
- "", // Eesti
- "", // Dansk
- "", // Czech
+ "Erweiterte Suche", // Deutsch
+ "", // Slovenski
+ "", // Italiano
+ "", // Nederlands
+ "", // Português
+ "", // Français
+ "", // Norsk
+ "", // Finnish
+ "", // Polski
+ "", // Español
+ "", // Greek
+ "", // Svenska
+ "", // Românã
+ "", // Magyar
+ "", // Català
+ "", // Russian
+ "", // Hrvatski
+ "", // Eesti
+ "", // Dansk
+ "", // Czech
},
{ "Search settings", // English
- "Einstellungen zur Suche", // Deutsch
- "", // Slovenski
- "", // Italiano
- "", // Nederlands
- "", // Português
- "", // Français
- "", // Norsk
- "", // Finnish
- "", // Polski
- "", // Español
- "", // Greek
- "", // Svenska
- "", // Românã
- "", // Magyar
- "", // Català
- "", // Russian
- "", // Hrvatski
- "", // Eesti
- "", // Dansk
- "", // Czech
+ "Einstellungen zur Suche", // Deutsch
+ "", // Slovenski
+ "", // Italiano
+ "", // Nederlands
+ "", // Português
+ "", // Français
+ "", // Norsk
+ "", // Finnish
+ "", // Polski
+ "", // Español
+ "", // Greek
+ "", // Svenska
+ "", // Românã
+ "", // Magyar
+ "", // Català
+ "", // Russian
+ "", // Hrvatski
+ "", // Eesti
+ "", // Dansk
+ "", // Czech
+ },
+ { "On archive DVD No.", // English
+ "Auf Archiv-DVD Nr.", // Deutsch
+ "", // Slovenski
+ "", // Italiano
+ "", // Nederlands
+ "", // Português
+ "", // Français
+ "", // Norsk
+ "", // Finnish
+ "", // Polski
+ "", // Español
+ "", // Greek
+ "", // Svenska
+ "", // Românã
+ "", // Magyar
+ "", // Català
+ "", // Russian
+ "", // Hrvatski
+ "", // Eesti
+ "", // Dansk
+ "", // Czech
},
/*
{ "", // English
diff --git a/images/Makefile b/images/Makefile
index abfd360..098a701 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -23,7 +23,7 @@ OBJS = logo.o record.o active.o inactive.o button_blue.o \
reload.o stop.o one_uparrow.o one_downarrow.o tv.o \
remotecontrol.o search.o record_timer.o button_red.o \
button_green.o button_new.o help.o logo_login.o \
- button_yellow.o arrow.o
+ button_yellow.o arrow.o on_dvd.o
### Default rules:
diff --git a/images/on_dvd.png b/images/on_dvd.png
new file mode 100644
index 0000000..13c1168
--- /dev/null
+++ b/images/on_dvd.png
Binary files differ
diff --git a/javascript/vdr_status.js b/javascript/vdr_status.js
index 829b19c..073d568 100644
--- a/javascript/vdr_status.js
+++ b/javascript/vdr_status.js
@@ -31,7 +31,7 @@ function LiveStatusRequest(url, containerid)
}
status.onerror = function(message)
{
- vst_reload = false;
+ LiveStatusToggleUpdate();
LiveStatusReportError(message, containerid);
}
status.request("update", vst_reload ? "1" : "0");
diff --git a/pages/pageelems.ecpp b/pages/pageelems.ecpp
index 7acf72a..a7fcf33 100644
--- a/pages/pageelems.ecpp
+++ b/pages/pageelems.ecpp
@@ -79,7 +79,7 @@ using namespace vdrlive;
string progress = "0";
string id;
</%args>
-<div class="__progress"><div class="__elapsed" <? !id.empty() ? "id=" + id ?> style="width: <$ progress $>px"></div></div>
+<div class="__progress"><div class="__elapsed" <%cpp> if (!id.empty()) { </%cpp>id="<$ id $>"<%cpp> } </%cpp> style="width: <$ progress $>px"></div></div>
</%def>
<# ---------------------------------------------------------------------- #>
@@ -90,7 +90,7 @@ using namespace vdrlive;
tEventID eventid;
</%args>
<%cpp> const cTimer* timer = LiveTimerManager().GetTimer(eventid, channelid);
- if (timer) {
+ if (timer) {
</%cpp>
<a href="edit_timer.html?timerid=<$ LiveTimerManager().GetTimers().GetTimerId(*timer) $>">
<img src="record_timer.png" alt="" <& tooltip.hint text=(tr("Edit this")) &> />
@@ -104,8 +104,8 @@ using namespace vdrlive;
<# ---------------------------------------------------------------------- #>
<%def ajax_js>
- <script type="text/javascript" language="javascript" src="ajax.js"></script>
- <script type="text/javascript" language="javascript" src="vdr_status.js"></script>
+ <script type="text/javascript" src="ajax.js"></script>
+ <script type="text/javascript" src="vdr_status.js"></script>
</%def>
<# ---------------------------------------------------------------------- #>
@@ -119,7 +119,7 @@ using namespace vdrlive;
string alt;
string id;
</%args>
-<%cpp> { </%cpp> <a <? !id.empty() ? "id=" + id ?> <& hide_element hide=(!id.empty()) &> href="javascript:LiveSimpleAjaxRequest('<$ action $>.xml', 'param', '<$ param $>');" <%cpp>if (!tip.empty()) { </%cpp><& tooltip.hint text=(tip) &> <%cpp> } </%cpp>><img src="<$ image $>" alt="<$ alt $>"></img></a> <%cpp> } </%cpp>
+<%cpp> { </%cpp> <a <%cpp> if (!id.empty()) { </%cpp> id="<$ id $>" <%cpp> } </%cpp><& hide_element hide=(!id.empty()) &> href="javascript:LiveSimpleAjaxRequest('<$ action $>.xml', 'param', '<$ param $>');" <%cpp>if (!tip.empty()) { </%cpp><& tooltip.hint text=(tip) &> <%cpp> } </%cpp>><img src="<$ image $>" alt="<$ alt $>"></img></a> <%cpp> } </%cpp>
</%def>
<# ---------------------------------------------------------------------- #>
@@ -133,6 +133,7 @@ using namespace vdrlive;
string title;
string short_descr;
string long_descr;
+ string archived;
int elapsed = -1;
</%args>
<div class="epg_description" id="<$ (boxId) $>">
@@ -141,50 +142,20 @@ using namespace vdrlive;
</div>
<div class="epg_content">
<div class="epg_tools">
- <& (tools_comp) id=(boxId) &>
+ <& (tools_comp) id=(boxId) archived=(archived) &>
</div>
<div>
- <div class="info"><$ (time) $></div>
+ <div class="info"><%cpp> if (!archived.empty()) { </%cpp><span class="bold"><$ (archived + " ") $></span><%cpp> } </%cpp><$ (time) $></div>
% if (elapsed >= 0) {
<div class="progress"><div><& pageelems.progressbar progress=(elapsed) &></div></div>
% }
<div class="title"><$ (title) $></div>
<div class="short"><$ (short_descr) $></div>
<div class="description">
- <{ reply.out() << StringEscapeAndBreak(long_descr); }>
+ <%cpp> reply.out() << StringEscapeAndBreak(long_descr); </%cpp>
</div>
</div>
</div>
</div>
</%def>
-<# ---------------------------------------------------------------------- #>
-
-<%def status_box>
-<%args>
- string type;
- string currentTime;
- string caption;
- string title;
- string duration;
- int elapsed;
- string prev_chan;
- string next_chan;
-</%args>
- <div class="statuscontent">
- <div class="st_header">
- <div class="caption"><$ caption $></div>
- <div class="now">&nbsp;<$ currentTime $></div>
- </div>
- <div class="st_content">
- <div class="name"><$ title $></div>
- <div class="duration">&nbsp;<$ duration $></div>
- </div>
- <div class="st_controls">
- <div class="st_btns"><a href="javascript:LiveStatusToggleUpdate()" <& tooltip.hint text=(tr("Stop updates")) &>><img id="statusReloadBtn" src="stop.png" alt=""></img></a><%cpp>if (!prev_chan.empty()) { </%cpp><& ajax_action_href action=("switch_channel") param=(prev_chan) image=("one_downarrow.png") tip=(tr("previous channel")) &><%cpp> } if (!next_chan.empty()) { </%cpp><& ajax_action_href action=("switch_channel") param=(next_chan) image=("one_uparrow.png") tip=(tr("next channel")) &><%cpp> } </%cpp></div>
-% if (elapsed >= 0) {
- <div class="st_pbar"><& pageelems.progressbar progress=(elapsed) &></div>
-% }
- </div>
- </div>
-</%def>
diff --git a/pages/recordings.ecpp b/pages/recordings.ecpp
index 87c534e..c9f9432 100644
--- a/pages/recordings.ecpp
+++ b/pages/recordings.ecpp
@@ -16,7 +16,7 @@ using namespace std;
<%args>
</%args>
<%session scope="global">
-bool logged_in(false);
+ bool logged_in(false);
</%session>
<%request scope="page">
RecordingsTree recordingsTree(LiveRecordingsManager());
@@ -36,17 +36,20 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html");
<link rel="stylesheet" type="text/css" href="styles.css" />
<& tooltip.javascript var=("domTT_styleClass") value=("domTTepg") &>
<& pageelems.ajax_js &>
- <script type="text/javascript" language="javascript" src="treeview.js"></script>
+ <script type="text/javascript" src="treeview.js"></script>
</head>
<body onload="<& pageelems.infobox_start_update &>">
<& pageelems.logo &>
<& menu active=("recordings") &>
<div class="inhalt">
+ <div class="boxheader"><div><div><$ tr("List of recordings") $></div></div></div>
% if (Recordings.Count() == 0) {
- Keine Aufnahmen vorhanden
+ <$ tr("No recordings found") $>
% } else {
<div class="recordings">
+ <ul class="recordingslist" style="display: block;">
<& recordings.recordings_item &>
+ </ul>
</div>
<div class="epg_data" style="display: none;">
<& recordings.recordings_data &>
@@ -57,123 +60,152 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html");
</html>
<%include>page_exit.eh</%include>
+<# ---------------------------------------------------------------------- #>
+
<%def recordings_item>
<%args>
-path[];
-int level = 0;
+ path[];
+ int level = 0;
</%args>
-<{
-if (level > 0) {
-}>
- <ul class="recordingslist" style="display: none;">
-<{
-}
-else {
-}>
- <ul class="recordingslist" style="display: block;">
-<{
-} // if (level > 0)
+<%cpp>
RecordingsTree::Map::iterator iter;
RecordingsTree::Map::iterator end = recordingsTree.end(path);
-}>
- <li class="recording">
-<{
+
for (iter = recordingsTree.begin(path); iter != end; ++iter) {
RecordingsTree::RecordingsItemPtr recItem = iter->second;
string folderimg("folder_closed.png");
string collapseimg("plus.png");
if (recItem->IsDir()) {
- reply.out() << string("\t\t\t")
- + string("<div class=\"recording_item\" onclick=\"Toggle(this)\">\n")
- + string("\t\t\t<div class=\"recording_imgs\">")
- + StringRepeat(level, "<img src=\"transparent.png\" alt=\"\" width=\"16px\" height=\"16px\" />")
- + string("<img class=\"recording_expander\" src=\"") + collapseimg + string("\" alt=\"\" />")
- + string("<img class=\"recording_folder\" src=\"") + folderimg + string("\" alt=\"\" />")
- + string("</div>");
-}>
- <div class="recording_spec">
- <div class="recording_name"><$ recItem->Name() $></div>
- </div>
- <div class="recording_actions">&nbsp;</div>
- </div>
-<{
+</%cpp>
+ <li class="recording">
+ <& rec_item_dir name=(recItem->Name()) level=(level) &>
+<%cpp>
cxxtools::QueryParams recItemParams(qparam, false);
for (path_type::const_iterator i = path.begin(); i != path.end(); ++i) {
recItemParams.add("path", *i);
}
recItemParams.add("path", recItem->Name());
recItemParams.add("level", lexical_cast<string, int>(level + 1));
- callComp("recordings.recordings_item", request, reply, recItemParams);
- }
-}
+</%cpp>
+ <ul class="recordingslist" style="display: none;">
+% callComp("recordings.recordings_item", request, reply, recItemParams);
+ </ul>
+ </li>
+% }
+%}
+<%cpp>
for (iter = recordingsTree.begin(path); iter != end; ++iter) {
RecordingsTree::RecordingsItemPtr recItem = iter->second;
- string folderimg("folder_closed.png");
- string collapseimg("plus.png");
if (!recItem->IsDir()) {
- const cRecordingInfo* info = recItem->RecInfo();
- if (info) {
- EpgEventPtr epgEvent(new EpgEvent(recItem->Id(),
- recItem->Name(),
- info->Title() ? info->Title() : recItem->Name(),
- info->ShortText() ? info->ShortText() : "",
- info->Description() ? info->Description() : "",
- recItem->StartTime(),
- recItem->StartTime()));
+ EpgEventPtr epgEvent(RecordingsTree::CreateEpgEvent(recItem));
+ if (epgEvent) {
epgEvents.push_back(epgEvent);
}
string day(FormatDateTime("%a,", recItem->StartTime()));
string dayLen(lexical_cast<string, int>(day.length() - 1) + ".25em;");
- reply.out() << string("\t\t\t")
- + string("<div class=\"recording_item\">\n")
- + string("\t\t\t<div class=\"recording_imgs\">")
- + StringRepeat(level, "<img src=\"transparent.png\" alt=\"\" width=\"16px\" height=\"16px\" />")
- + string("<img src=\"transparent.png\" alt=\"\" width=\"16px\" height=\"16px\" />")
- + string("<img src=\"movie.png\" alt=\"movie\" />")
- + string("</div>");
-
- string shortDescr(tr("Click to view details.")); if (info && info->ShortText()) shortDescr = (string("") + info->ShortText() + string("<br />") + shortDescr);
-}>
- <div class="recording_spec">
- <div class="recording_day" style="width: <$ dayLen $>"><$ day $></div>
- <div class="recording_date"><$ FormatDateTime(tr("%b %d %y"), recItem->StartTime()) $></div>
- <div class="recording_time"><$ FormatDateTime(tr("%I:%M %p"), recItem->StartTime()) $></div>
- <div class="recording_name" <& tooltip.hint text=(shortDescr) &><& tooltip.display domId=(recItem->Id()) &>><$ recItem->Name() $></div>
- </div>
- <div class="recording_actions">
- <& pageelems.ajax_action_href action="play_recording" param=(recItem->Id()) tip=(tr("play this recording.")) image="play.png" alt="" &>
- <img src="edit.png" alt="" />
- <img src="del.png" alt="" />
- </div>
- </div>
-% }
- </li>
-<{
+ string shortDescr(tr("Click to view details.")); if (epgEvent && !epgEvent->ShortDescr().empty()) shortDescr = (epgEvent->ShortDescr() + string("<br />") + shortDescr);
+</%cpp>
+ <li class="recording">
+ <& rec_item_file name=(recItem->Name()) level=(level) id=(recItem->Id()) day=(day) dayLen=(dayLen) startTime=(recItem->StartTime()) shortDescr=(shortDescr) archived=(epgEvent ? epgEvent->Archived() : "") archiveId=(recItem->ArchiveId()) &>
+ </li>
+<%cpp>
+ }
}
-}>
- </ul>
+</%cpp>
</%def>
+<# ---------------------------------------------------------------------- #>
<%def recordings_data>
<{
-
// create hidden div for the tooltip hints.
for (vector<EpgEventPtr>::iterator i = epgEvents.begin(); i != epgEvents.end(); ++i) {
EpgEventPtr epg = *i;
string start(epg->StartTime("%a,") + string(" ")
+ epg->StartTime(tr("%b %d %y")) + string(" ")
+ epg->StartTime(tr("%I:%M %p")));
+ string tools_component = epg->Archived().empty() ? "recordings.rec_tools" : "recordings.archived_disc" ;
}>
- <& pageelems.epg_tt_box boxId=(epg->Id()) caption=(epg->Caption()) tools_comp=("recordings.rec_tools") time=(start) title=(epg->Title()) short_descr=(epg->ShortDescr()) long_descr=(epg->LongDescr()) elapsed=(epg->Elapsed()) &>
+ <& pageelems.epg_tt_box boxId=(epg->Id()) caption=(epg->Caption()) tools_comp=(tools_component) time=(start) title=(epg->Title()) short_descr=(epg->ShortDescr()) long_descr=(epg->LongDescr()) archived=(epg->Archived()) elapsed=(epg->Elapsed()) &>
<{
}
}>
</%def>
+<# ---------------------------------------------------------------------- #>
+
<%def rec_tools>
<%args>
string id;
</%args>
<& pageelems.ajax_action_href action="play_recording" param=(id) tip=(tr("play this recording.")) image="play.png" alt="" &>
</%def>
+
+<# ---------------------------------------------------------------------- #>
+
+<%def archived_disc>
+<%args>
+ string archived;
+</%args>
+<img src="on_dvd.png" alt="on_dvd" <& tooltip.hint text=(archived) &> />
+</%def>
+
+<# ---------------------------------------------------------------------- #>
+
+<%def rec_item_dir>
+<%args>
+ string name;
+ int level;
+ string collapseimg = "plus.png";
+ string folderimg = "folder_closed.png";
+</%args>
+ <div class="recording_item" onclick="Toggle(this)">
+ <div class="recording_imgs"><%cpp> reply.out() << StringRepeat(level, "<img src=\"transparent.png\" alt=\"\" width=\"16px\" height=\"16px\" />"); </%cpp><img class="recording_expander" src="<$ collapseimg $>" alt="" /><img class="recording_folder" src="<$ folderimg $>" alt="" /></div>
+ <div class="recording_spec">
+ <div class="recording_name"><$ name $></div>
+ </div>
+ <div class="recording_actions">&nbsp;</div>
+ </div>
+</%def>
+
+<# ---------------------------------------------------------------------- #>
+
+<%def rec_item_file>
+<%args>
+ string name;
+ int level;
+ string id;
+ string day;
+ string dayLen;
+ time_t startTime;
+ string shortDescr;
+ string archived;
+ string archiveId;
+</%args>
+ <div class="recording_item">
+ <div class="recording_imgs"><%cpp> reply.out() << StringRepeat(level + 1, "<img src=\"transparent.png\" alt=\"\" width=\"16px\" height=\"16px\" />"); </%cpp><%cpp> if (!archived.empty()) { </%cpp><& archived_disc archived=(archived) &><%cpp> } else { </%cpp><img src="movie.png" alt="movie" /><%cpp> } </%cpp></div>
+ <div class="recording_spec">
+ <div class="recording_day" style="width: <$ dayLen $>"><$ day $></div>
+ <div class="recording_date"><$ FormatDateTime(tr("%b %d %y"), startTime) $></div>
+ <div class="recording_time"><$ FormatDateTime(tr("%I:%M %p"), startTime) $></div>
+ <div class="recording_name" <& tooltip.hint text=(shortDescr) &><& tooltip.display domId=(id) &>><$ name $></div>
+ <%cpp> if (! archived.empty()) { </%cpp><div><$ archived $></div><%cpp> } </%cpp>
+ </div>
+ <div class="recording_actions">
+<%cpp>
+ if (archived.empty()) {
+</%cpp>
+ <& pageelems.ajax_action_href action="play_recording" param=(id) tip=(tr("play this recording.")) image="play.png" alt="" &>
+<%cpp>
+ }
+ else {
+</%cpp>
+ <img src="transparent.png" alt="" width="16px" height="16px" />
+<%cpp>
+ }
+</%cpp>
+ <img src="edit.png" alt="" />
+ <img src="del.png" alt="" />
+ </div>
+ </div>
+</%def>
diff --git a/pages/tooltip.ecpp b/pages/tooltip.ecpp
index a52eb7b..47af850 100644
--- a/pages/tooltip.ecpp
+++ b/pages/tooltip.ecpp
@@ -4,10 +4,10 @@ styleClass="domTThint";
var[];
value[];
</%args>
- <script type="text/javascript" language="javascript" src="domLib.js"></script>
- <script type="text/javascript" language="javascript" src="domTT.js"></script>
- <script type="text/javascript" language="javascript" src="domTT_drag.js"></script>
- <script type="text/javascript" language="javascript">
+ <script type="text/javascript" src="domLib.js"></script>
+ <script type="text/javascript" src="domTT.js"></script>
+ <script type="text/javascript" src="domTT_drag.js"></script>
+ <script type="text/javascript">
var domTT_styleClass = "<$ styleClass $>";
% int idx = 0;
% for (var_type::const_iterator it = var.begin(); it != var.end(); ++it, idx++) {
diff --git a/recordings.cpp b/recordings.cpp
index 4c8aba8..72178c1 100644
--- a/recordings.cpp
+++ b/recordings.cpp
@@ -1,10 +1,13 @@
+#include <unistd.h>
#include <cstring>
#include <openssl/md5.h>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <string>
#include <sstream>
+#include <fstream>
#include "tools.h"
+#include "epg_events.h"
#include "recordings.h"
@@ -25,7 +28,7 @@ namespace vdrlive {
MD5(reinterpret_cast<const unsigned char*>(fileName), strlen(fileName), md5);
ostringstream hashStr;
- hashStr << hex;
+ hashStr << "MD5" << hex;
for (size_t i = 0; i < MD5_DIGEST_LENGTH; i++)
hashStr << (0 + md5[i]);
return hashStr.str();
@@ -190,6 +193,69 @@ namespace vdrlive {
return m_recording->start;
}
+ bool RecordingsTree::RecordingsItemRec::IsArchived() const
+ {
+ string filename = m_recording->FileName();
+
+ string vdrFile = filename + "/001.vdr";
+ if (0 == access(vdrFile.c_str(), R_OK))
+ return false;
+
+ filename += "/dvd.vdr";
+ return (0 == access(filename.c_str(), R_OK));
+ }
+
+ const std::string RecordingsTree::RecordingsItemRec::ArchiveId() const
+ {
+ string filename = m_recording->FileName();
+
+ filename += "/dvd.vdr";
+ ifstream dvd(filename.c_str());
+
+ if (dvd) {
+ string archiveDisc;
+ string videoDisc;
+ dvd >> archiveDisc;
+ if ("0000" == archiveDisc) {
+ dvd >> videoDisc;
+ return videoDisc;
+ }
+ return archiveDisc;
+ }
+ return "";
+ }
+
+ EpgEventPtr RecordingsTree::CreateEpgEvent(const RecordingsItemPtr recItem)
+ {
+ const cRecordingInfo* info = recItem->RecInfo();
+ if (info) {
+ std::string archived;
+ if (recItem->IsArchived()) {
+ archived += " [";
+ archived += tr("On archive DVD No.");
+ archived += ": ";
+ archived += recItem->ArchiveId();
+ archived += "]";
+ }
+ EpgEventPtr epgEvent(
+ new EpgEvent(
+ recItem->Id(),
+ recItem->Name(),
+ info->Title() ? info->Title() : recItem->Name(),
+ info->ShortText() ? info->ShortText() : "",
+ info->Description() ? info->Description() : "",
+ archived,
+ recItem->StartTime(),
+ recItem->StartTime()
+ )
+ );
+ return epgEvent;
+ }
+ else {
+ return EpgEventPtr();
+ }
+ }
+
RecordingsManagerPtr LiveRecordingsManager()
{
static weak_ptr<RecordingsManager> livingRecMan;
diff --git a/recordings.h b/recordings.h
index 5bea835..1e4b57b 100644
--- a/recordings.h
+++ b/recordings.h
@@ -9,6 +9,10 @@
namespace vdrlive {
+ // Forward declations from epg_events.h
+ class EpgEvent;
+ typedef boost::shared_ptr<EpgEvent> EpgEventPtr;
+
class RecordingsManager;
typedef boost::shared_ptr<RecordingsManager> RecordingsManagerPtr;
@@ -54,8 +58,10 @@ namespace vdrlive {
virtual time_t StartTime() const = 0;
virtual bool IsDir() const = 0;
+ virtual bool IsArchived() const = 0;
virtual const std::string& Name() const { return m_name; }
virtual const std::string Id() const = 0;
+ virtual const std::string ArchiveId() const = 0;
virtual const cRecording* Recording() const { return 0; }
virtual const cRecordingInfo* RecInfo() const { return 0; }
@@ -78,7 +84,9 @@ namespace vdrlive {
virtual time_t StartTime() const { return 0; }
virtual bool IsDir() const { return true; }
+ virtual bool IsArchived() const { return false; }
virtual const std::string Id() const { std::string e; return e; }
+ virtual const std::string ArchiveId() const { std::string e; return e; }
private:
int m_level;
@@ -93,7 +101,9 @@ namespace vdrlive {
virtual time_t StartTime() const;
virtual bool IsDir() const { return false; }
+ virtual bool IsArchived() const ;
virtual const std::string Id() const { return m_id; }
+ virtual const std::string ArchiveId() const;
virtual const cRecording* Recording() const { return m_recording; }
virtual const cRecordingInfo* RecInfo() const { return m_recording->Info(); }
@@ -112,6 +122,8 @@ namespace vdrlive {
int MaxLevel() const { return m_maxLevel; }
+ static EpgEventPtr CreateEpgEvent(const RecordingsItemPtr recItem);
+
private:
int m_maxLevel;
RecordingsItemPtr m_root;