/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #ifndef __USERVARS_INC__ #define __USERVARS_INC__ #include #include #include #include #include #include #include #include "varparser.h" #include "epgsearchtools.h" #include "epgsearchcats.h" using std::string; using std::set; using std::map; using std::ostringstream; class cUserVar : public cListObject { const cEvent* oldEvent; // cache bool oldescapeStrings; string oldResult; string EvaluateCondExpr(const cEvent* e, bool escapeStrings = false); string EvaluateCompExpr(const cEvent* e, bool escapeStrings = false); string EvaluateShellCmd(const cEvent* e); string EvaluateConnectCmd(const cEvent* e); string EvaluateLengthCmd(const cEvent* e); public: cUserVar(); cVarParser varparser; set usedVars; virtual string Evaluate(const cEvent* e, bool escapeStrings = false); string EvaluateInternalVars(const string& Expr, const cEvent* e, bool escapeStrings = false); string EvaluateInternalTimerVars(const string& Expr, const cTimer* t); string EvaluateInternalSearchVars(const string& Expr, const cSearchExt* s); string EvaluateExtEPGVars(const string& Expr, const cEvent* e, bool escapeStrings = false); string EvaluateUserVars(const string& Expr, const cEvent* e, bool escapeStrings = false); virtual string Name(bool = false) { return varparser.varName; } virtual bool IsCondExpr() { return varparser.IsCondExpr(); } virtual bool IsShellCmd() { return varparser.IsShellCmd(); } virtual bool IsConnectCmd() { return varparser.IsConnectCmd(); } virtual bool IsLengthCmd() { return varparser.IsLengthCmd(); } bool DependsOnVar(const string& varName); bool DependsOnVar(cUserVar* var); bool AddDepVar(cUserVar* var); void ResetCache(); }; class cExtEPGVar : public cUserVar { const string name; static string nameSpace; public: cExtEPGVar(const string& Name) : name(Name) {} string Name(bool withNamespace = false) { return "%" + (withNamespace?nameSpace + ".":"") + name + "%"; } bool IsCondExpr() { return false; } bool IsShellCmd() { return false; } string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; cSearchExtCat* SearchExtCat = SearchExtCats.First(); while (SearchExtCat) { string varName = string("%") + SearchExtCat->name + string("%"); int varPos = FindIgnoreCase(varName, Name()); if (varPos == 0) { char* value = GetExtEPGValue(e, SearchExtCat); string res = value?value:""; if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } SearchExtCat = SearchExtCats.Next(SearchExtCat); } return ""; } }; class cInternalVar : public cUserVar { const string name; public: cInternalVar(const string& Name) : name(Name) {} string Name(bool = false) { return "%" + name + "%"; } bool IsCondExpr() { return false; } bool IsShellCmd() { return false; } }; class cTitleVar : public cInternalVar { public: cTitleVar() : cInternalVar("title") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { string res = (e && !isempty(e->Title()))? e->Title() : ""; if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } }; class cSubtitleVar : public cInternalVar { public: cSubtitleVar() : cInternalVar("subtitle") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { string res = (e && !isempty(e->ShortText()))? e->ShortText() : ""; if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } }; class cSummaryVar : public cInternalVar { public: cSummaryVar() : cInternalVar("summary") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { string res = (e && !isempty(e->Description()))? e->Description() : ""; if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } }; class cHTMLSummaryVar : public cInternalVar { public: cHTMLSummaryVar() : cInternalVar("htmlsummary") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (e && !isempty(e->Description())) { string res = ReplaceAll(e->Description(), "\n", "
"); if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } else return ""; } }; class cEventIDVar : public cInternalVar { public: cEventIDVar() : cInternalVar("eventid") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (e) { ostringstream os; os << e->EventID(); return os.str(); } else return ""; } }; class cLiveEventIDVar : public cInternalVar { public: cLiveEventIDVar() : cInternalVar("liveeventid") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; LOCK_CHANNELS_READ; const cChannel *channel = Channels->GetByChannelID(e->ChannelID(), true); if (!channel) return ""; string res(channel->GetChannelID().ToString()); res = "event_" + res; res = ReplaceAll(res, ".", "p"); res = ReplaceAll(res, "-", "m"); res += "_" + NumToString(e->EventID()); if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } }; class cTimeVar : public cInternalVar { public: cTimeVar() : cInternalVar("time") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { string res = (e? *(e->GetTimeString()) : ""); if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } }; class cTimeEndVar : public cInternalVar { public: cTimeEndVar() : cInternalVar("timeend") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { string res = (e? *(e->GetEndTimeString()) : ""); if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } }; class cTime_wVar : public cInternalVar { public: cTime_wVar() : cInternalVar("time_w") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { string res = (e? WEEKDAYNAME(e->StartTime()) : ""); if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } }; class cTime_dVar : public cInternalVar { public: cTime_dVar() : cInternalVar("time_d") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; char day[3] = ""; struct tm tm_r; const time_t t = e->StartTime(); tm *tm = localtime_r(&t, &tm_r); strftime(day, sizeof(day), "%d", tm); if (escapeStrings) return "'" + EscapeString(day) + "'"; else return day; } }; class cTime_lngVar : public cInternalVar { public: cTime_lngVar() : cInternalVar("time_lng") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; ostringstream os; os << e->StartTime(); if (escapeStrings) return "'" + EscapeString(os.str()) + "'"; else return os.str(); } }; class cTimeSpanVar : public cInternalVar { public: cTimeSpanVar() : cInternalVar("timespan") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; time_t diff = e->StartTime() - time(NULL); string res; if (labs(diff) >= SECSINDAY) { cString buffer; if (diff > 0) buffer = cString::sprintf(tr("in %02ldd"), long(diff / SECSINDAY)); else buffer = cString::sprintf("%02ldd", long(-diff / SECSINDAY)); res = buffer; } else if (labs(diff) >= (60 * 60)) { cString buffer; if (diff > 0) buffer = cString::sprintf(tr("in %02ldh"), long(diff / (60*60))); else buffer = cString::sprintf("%02ldh", long(-diff / (60*60))); res = buffer; } else { cString buffer; if (diff > 0) buffer = cString::sprintf(tr("in %02ldm"), long(diff / 60)); else buffer = cString::sprintf("%02ldm", long(-diff / 60)); res = buffer; } if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } }; class cLength_Var : public cInternalVar { public: cLength_Var() : cInternalVar("length") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { return (e? NumToString(e->Duration()) : ""); } }; class cDateVar : public cInternalVar { public: cDateVar() : cInternalVar("date") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; char date[9] = ""; struct tm tm_r; const time_t t = e->StartTime(); tm *tm = localtime_r(&t, &tm_r); strftime(date, sizeof(date), "%d.%m.%y", tm); if (escapeStrings) return "'" + EscapeString(date) + "'"; else return date; } }; class cDateShortVar : public cInternalVar { public: cDateShortVar() : cInternalVar("datesh") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; char dateshort[7] = ""; struct tm tm_r; const time_t t = e->StartTime(); tm *tm = localtime_r(&t, &tm_r); strftime(dateshort, sizeof(dateshort), "%d.%m.", tm); if (escapeStrings) return "'" + EscapeString(dateshort) + "'"; else return dateshort; } }; class cDateISOVar : public cInternalVar { public: cDateISOVar() : cInternalVar("date_iso") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; char dateISO[11] = ""; struct tm tm_r; const time_t t = e->StartTime(); tm *tm = localtime_r(&t, &tm_r); strftime(dateISO, sizeof(dateISO), "%Y-%m-%d", tm); if (escapeStrings) return "'" + EscapeString(dateISO) + "'"; else return dateISO; } }; class cYearVar : public cInternalVar { public: cYearVar() : cInternalVar("year") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; char year[5] = ""; struct tm tm_r; const time_t t = e->StartTime(); tm *tm = localtime_r(&t, &tm_r); strftime(year, sizeof(year), "%Y", tm); if (escapeStrings) return "'" + EscapeString(year) + "'"; else return year; } }; class cMonthVar : public cInternalVar { public: cMonthVar() : cInternalVar("month") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; char month[3] = ""; struct tm tm_r; const time_t t = e->StartTime(); tm *tm = localtime_r(&t, &tm_r); strftime(month, sizeof(month), "%m", tm); if (escapeStrings) return "'" + EscapeString(month) + "'"; else return month; } }; class cDayVar : public cInternalVar { public: cDayVar() : cInternalVar("day") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; char day[3] = ""; struct tm tm_r; const time_t t = e->StartTime(); tm *tm = localtime_r(&t, &tm_r); strftime(day, sizeof(day), "%d", tm); if (escapeStrings) return "'" + EscapeString(day) + "'"; else return day; } }; class cWeekVar : public cInternalVar { public: cWeekVar() : cInternalVar("week") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; char day[3] = ""; struct tm tm_r; const time_t t = e->StartTime(); tm *tm = localtime_r(&t, &tm_r); strftime(day, sizeof(day), "%V", tm); if (escapeStrings) return "'" + EscapeString(day) + "'"; else return day; } }; class cChannelNrVar : public cInternalVar { public: cChannelNrVar() : cInternalVar("chnr") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { int chnr = ChannelNrFromEvent(e); if (chnr < 0) return ""; return NumToString(chnr); } }; class cChannelShortVar : public cInternalVar { public: cChannelShortVar() : cInternalVar("chsh") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; LOCK_CHANNELS_READ; const cChannel *channel = Channels->GetByChannelID(e->ChannelID(), true); string res = channel?channel->ShortName(true):""; if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } }; class cChannelLongVar : public cInternalVar { public: cChannelLongVar() : cInternalVar("chlng") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; LOCK_CHANNELS_READ; const cChannel *channel = Channels->GetByChannelID(e->ChannelID(), true); string res = channel?channel->Name():""; if (escapeStrings) return "'" + EscapeString(res) + "'"; else return res; } }; class cChannelDataVar : public cInternalVar { public: cChannelDataVar() : cInternalVar("chdata") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; LOCK_CHANNELS_READ; const cChannel *channel = Channels->GetByChannelID(e->ChannelID(), true); return channel?CHANNELSTRING(channel):""; } }; class cChannelGroupVar : public cInternalVar { public: cChannelGroupVar() : cInternalVar("chgrp") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; ostringstream os; LOCK_CHANNELS_READ; const cChannel *channel = Channels->GetByChannelID(e->ChannelID(), true); while(channel && !channel->GroupSep()) channel = Channels->Prev(channel); if (!channel || !channel->Name()) return ""; string grpName = channel->Name(); if (escapeStrings) return "'" + EscapeString(grpName) + "'"; else return grpName; } }; class cNEWTCmdVar : public cInternalVar { public: cNEWTCmdVar() : cInternalVar("newtcmd") {} string Evaluate(const cEvent* e, bool escapeStrings = false) { if (!e) return ""; cTimer* timer = new cTimer(e); string newtCmd = *(timer->ToText()); if (escapeStrings) return "'" + EscapeString(newtCmd) + "'"; else return newtCmd; } }; // independet variables class cColonVar : public cInternalVar { public: cColonVar() : cInternalVar("colon") {} string Evaluate(const cEvent*, bool escapeStrings = false) { return ":"; } }; class cDateNowVar : public cInternalVar { public: cDateNowVar() : cInternalVar("datenow") {} string Evaluate(const cEvent*, bool escapeStrings = false) { char date[9] = ""; struct tm tm_r; const time_t t = time(NULL); tm *tm = localtime_r(&t, &tm_r); strftime(date, sizeof(date), "%d.%m.%y", tm); if (escapeStrings) return "'" + EscapeString(date) + "'"; else return date; } }; class cDateShortNowVar : public cInternalVar { public: cDateShortNowVar() : cInternalVar("dateshnow") {} string Evaluate(const cEvent*, bool escapeStrings = false) { char dateshort[7] = ""; struct tm tm_r; const time_t t = time(NULL); tm *tm = localtime_r(&t, &tm_r); strftime(dateshort, sizeof(dateshort), "%d.%m.", tm); if (escapeStrings) return "'" + EscapeString(dateshort) + "'"; else return dateshort; } }; class cDateISONowVar : public cInternalVar { public: cDateISONowVar() : cInternalVar("date_iso_now") {} string Evaluate(const cEvent*, bool escapeStrings = false) { char dateISO[11] = ""; struct tm tm_r; const time_t t = time(NULL); tm *tm = localtime_r(&t, &tm_r); strftime(dateISO, sizeof(dateISO), "%Y-%m-%d", tm); if (escapeStrings) return "'" + EscapeString(dateISO) + "'"; else return dateISO; } }; class cTimeNowVar : public cInternalVar { public: cTimeNowVar() : cInternalVar("timenow") {} string Evaluate(const cEvent*, bool escapeStrings = false) { return TIMESTRING(time(NULL)); } }; class cVideodirVar : public cInternalVar { public: cVideodirVar() : cInternalVar("videodir") {} string Evaluate(const cEvent*, bool escapeStrings = false) { return cVideoDirectory::Name(); } }; class cPlugconfdirVar : public cInternalVar { public: static string dir; cPlugconfdirVar() : cInternalVar("plugconfdir") {} string Evaluate(const cEvent*, bool escapeStrings = false) { return dir; } }; class cEpgsearchconfdirVar : public cInternalVar { public: static string dir; cEpgsearchconfdirVar() : cInternalVar("epgsearchdir") {} string Evaluate(const cEvent*, bool escapeStrings = false) { return CONFIGDIR; } }; // timer variables class cTimerVar { static string nameSpace; const string name; public: cTimerVar(const string& Name) : name(Name) {} virtual ~cTimerVar() {} string Name() { return "%" + nameSpace + "." + name + "%"; } virtual string Evaluate(const cTimer* t) = 0; }; class cTimerDateVar : public cTimerVar { public: cTimerDateVar() : cTimerVar("date") {} string Evaluate(const cTimer* t) { if (!t) return ""; return DATESTRING(t->StartTime()); } }; class cTimerStartVar : public cTimerVar { public: cTimerStartVar() : cTimerVar("start") {} string Evaluate(const cTimer* t) { if (!t) return ""; return TIMESTRING(t->StartTime()); } }; class cTimerStopVar : public cTimerVar { public: cTimerStopVar() : cTimerVar("stop") {} string Evaluate(const cTimer* t) { if (!t) return ""; return TIMESTRING(t->StopTime()); } }; class cTimerFileVar : public cTimerVar { public: cTimerFileVar() : cTimerVar("file") {} string Evaluate(const cTimer* t) { if (!t) return ""; return t->File(); } }; class cTimerChnrVar : public cTimerVar { public: cTimerChnrVar() : cTimerVar("chnr") {} string Evaluate(const cTimer* t) { if (!t || !t->Channel()) return ""; return NumToString(t->Channel()->Number()); } }; class cTimerChannelShortVar : public cTimerVar { public: cTimerChannelShortVar() : cTimerVar("chsh") {} string Evaluate(const cTimer* t) { if (!t || !t->Channel()) return ""; return t->Channel()->ShortName(true); } }; class cTimerChannelLongVar : public cTimerVar { public: cTimerChannelLongVar() : cTimerVar("chlng") {} string Evaluate(const cTimer* t) { if (!t || !t->Channel()) return ""; return t->Channel()->Name(); } }; class cTimerSearchVar : public cTimerVar { public: cTimerSearchVar() : cTimerVar("search") {} string Evaluate(const cTimer* t) { if (!t) return ""; cSearchExt* s = TriggeredFromSearchTimer(t); if (!s) return ""; return s->search; } }; class cTimerSearchIDVar : public cTimerVar { public: cTimerSearchIDVar() : cTimerVar("searchid") {} string Evaluate(const cTimer* t) { if (!t) return ""; int ID = TriggeredFromSearchTimerID(t); if (ID < 0) return ""; return NumToString(ID); } }; class cTimerLiveIDVar : public cTimerVar { public: cTimerLiveIDVar() : cTimerVar("liveid") {} string Evaluate(const cTimer* t) { if (!t || !t->Channel()) return ""; ostringstream builder; builder << *(t->Channel()->GetChannelID().ToString()) << ":" << t->WeekDays() << ":" << t->Day() << ":" << t->Start() << ":" << t->Stop(); string res = builder.str(); res = "timer_" + res; res = ReplaceAll(res, ".", "p"); res = ReplaceAll(res, "-", "m"); res = ReplaceAll(res, ":", "c"); return res; } }; // search variables class cSearchVar { const string name; static string nameSpace; public: cSearchVar(const string& Name) : name(Name) {} virtual ~cSearchVar() {} string Name() { return "%" + nameSpace + "." + name + "%"; } virtual string Evaluate(const cSearchExt* s) = 0; }; class cSearchQueryVar : public cSearchVar { public: cSearchQueryVar() : cSearchVar("query") {} string Evaluate(const cSearchExt* s) { if (!s) return ""; return s->search; } }; class cSearchSeriesVar : public cSearchVar { public: cSearchSeriesVar() : cSearchVar("series") {} string Evaluate(const cSearchExt* s) { if (!s) return ""; return NumToString(s->useEpisode); } }; class cUserVars : public cList { public: cTitleVar titleVar; cSubtitleVar subtitleVar; cSummaryVar summaryVar; cHTMLSummaryVar htmlsummaryVar; cEventIDVar eventIDVar; cLiveEventIDVar liveeventIDVar; cTimeVar timeVar; cTimeEndVar timeEndVar; cTime_wVar time_wVar; cTime_dVar time_dVar; cTime_lngVar time_lngVar; cTimeSpanVar time_spanVar; cLength_Var length_Var; cDateVar dateVar; cDateShortVar dateShortVar; cDateISOVar dateISOVar; cYearVar yearVar; cMonthVar monthVar; cDayVar dayVar; cWeekVar weekVar; cChannelNrVar chnrVar; cChannelShortVar chShortVar; cChannelLongVar chLongVar; cChannelDataVar chDataVar; cChannelGroupVar chGroupVar; cNEWTCmdVar newtCmdVar; cSearchQueryVar searchQueryVar; cSearchSeriesVar searchSeriesVar; cColonVar colonVar; cDateNowVar dateNowVar; cDateShortNowVar dateShortNowVar; cDateISONowVar dateISONowVar; cTimeNowVar timeNowVar; cVideodirVar videodirVar; cPlugconfdirVar plugconfdirVar; cEpgsearchconfdirVar epgsearchconfdirVar; cTimerDateVar timerDateVar; cTimerStartVar timerStartVar; cTimerStopVar timerStopVar; cTimerFileVar timerFileVar; cTimerChnrVar timerChnrVar; cTimerChannelShortVar timerChShortVar; cTimerChannelLongVar timerChLongVar; cTimerSearchVar timerSearchVar; cTimerSearchIDVar timerSearchIDVar; cTimerLiveIDVar timerLiveIDVar; map extEPGVars; set userVars; map internalVars; map internalTimerVars; map internalSearchVars; void InitInternalVars() { internalVars[titleVar.Name()] = &titleVar; internalVars[subtitleVar.Name()] = &subtitleVar; internalVars[summaryVar.Name()] = &summaryVar; internalVars[htmlsummaryVar.Name()] = &htmlsummaryVar; internalVars[eventIDVar.Name()] = &eventIDVar; internalVars[liveeventIDVar.Name()] = &liveeventIDVar; internalVars[timeVar.Name()] = &timeVar; internalVars[timeEndVar.Name()] = &timeEndVar; internalVars[time_wVar.Name()] = &time_wVar; internalVars[time_dVar.Name()] = &time_dVar; internalVars[time_lngVar.Name()] = &time_lngVar; internalVars[time_spanVar.Name()] = &time_spanVar; internalVars[length_Var.Name()] = &length_Var; internalVars[dateVar.Name()] = &dateVar; internalVars[dateShortVar.Name()] = &dateShortVar; internalVars[dateISOVar.Name()] = &dateISOVar; internalVars[yearVar.Name()] = &yearVar; internalVars[monthVar.Name()] = &monthVar; internalVars[dayVar.Name()] = &dayVar; internalVars[weekVar.Name()] = &weekVar; internalVars[chnrVar.Name()] = &chnrVar; internalVars[chShortVar.Name()] = &chShortVar; internalVars[chLongVar.Name()] = &chLongVar; internalVars[chDataVar.Name()] = &chDataVar; internalVars[chGroupVar.Name()] = &chGroupVar; internalVars[newtCmdVar.Name()] = &newtCmdVar; internalVars[colonVar.Name()] = &colonVar; internalVars[dateNowVar.Name()] = &dateNowVar; internalVars[dateShortNowVar.Name()] = &dateShortNowVar; internalVars[dateISONowVar.Name()] = &dateISONowVar; internalVars[timeNowVar.Name()] = &timeNowVar; internalVars[videodirVar.Name()] = &videodirVar; internalVars[plugconfdirVar.Name()] = &plugconfdirVar; internalVars[epgsearchconfdirVar.Name()] = &epgsearchconfdirVar; internalTimerVars[timerDateVar.Name()] = &timerDateVar; internalTimerVars[timerStartVar.Name()] = &timerStartVar; internalTimerVars[timerStopVar.Name()] = &timerStopVar; internalTimerVars[timerFileVar.Name()] = &timerFileVar; internalTimerVars[timerChnrVar.Name()] = &timerChnrVar; internalTimerVars[timerChShortVar.Name()] = &timerChShortVar; internalTimerVars[timerChLongVar.Name()] = &timerChLongVar; internalTimerVars[timerSearchVar.Name()] = &timerSearchVar; internalTimerVars[timerSearchIDVar.Name()] = &timerSearchIDVar; internalTimerVars[timerLiveIDVar.Name()] = &timerLiveIDVar; internalSearchVars[searchQueryVar.Name()] = &searchQueryVar; internalSearchVars[searchSeriesVar.Name()] = &searchSeriesVar; } void InitExtEPGVars() { cSearchExtCat* SearchExtCat = SearchExtCats.First(); while (SearchExtCat) { string varName = SearchExtCat->name; std::transform(varName.begin(), varName.end(), varName.begin(), tolower); cExtEPGVar* extEPGVar = new cExtEPGVar(varName); extEPGVars[extEPGVar->Name()] = extEPGVar; SearchExtCat = SearchExtCats.Next(SearchExtCat); } } void ResetCache() { cUserVar* var = First(); while (var) { var->ResetCache(); var = Next(var); } } ~cUserVars() { std::map::iterator evar; for (evar = extEPGVars.begin(); evar != extEPGVars.end(); ++evar) delete evar->second; extEPGVars.clear(); std::set::iterator uvar; for (uvar = userVars.begin(); uvar != userVars.end(); ++uvar) delete (*uvar); userVars.clear(); } cUserVar* GetFromName(const string& varName, bool log = true); }; extern cUserVars UserVars; class cUserVarLine : public cListObject { public: static bool Parse(char *s); }; class cUserVarFile : public cConfig { public: cUserVarFile() { UserVars.Clear(); }; }; class cVarExpr { string expr; public: set usedVars; cVarExpr(const string& Expr) : expr(Expr) {} string Evaluate(const cEvent* e = NULL); string Evaluate(const cTimer* t); string Evaluate(const cSearchExt* s); bool DependsOnVar(const string& varName, const cEvent* e); }; #endif