summaryrefslogtreecommitdiff
path: root/menu_myedittimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'menu_myedittimer.c')
-rw-r--r--menu_myedittimer.c490
1 files changed, 490 insertions, 0 deletions
diff --git a/menu_myedittimer.c b/menu_myedittimer.c
new file mode 100644
index 0000000..fbd3a3b
--- /dev/null
+++ b/menu_myedittimer.c
@@ -0,0 +1,490 @@
+/*
+Copyright (C) 2004-2007 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
+*/
+
+#include <vector>
+#include "menu_myedittimer.h"
+#include "epgsearchcfg.h"
+#include "epgsearchcats.h"
+#include "timer_thread.h"
+#include "menu_dirselect.h"
+#include "menu_searchedit.h"
+#include "epgsearchtools.h"
+#include "recstatus.h"
+#include "uservars.h"
+#include "menu_deftimercheckmethod.h"
+#include <math.h>
+
+const char *cMenuMyEditTimer::CheckModes[3];
+
+cMenuMyEditTimer::cMenuMyEditTimer(cTimer *Timer, bool New, const cEvent* Event, const cChannel* forcechannel)
+:cOsdMenu(tr("Edit timer"), 14)
+{
+ CheckModes[0] = tr("no check");
+ CheckModes[UPD_CHDUR] = tr("by channel and time");
+ CheckModes[UPD_EVENTID] = tr("by event ID");
+
+ strcpy(file, "");
+ strcpy(directory, "");
+ UserDefDaysOfWeek = 0;
+ checkmode = 0;
+ if (Timer)
+ {
+ timer = Timer;
+ event = Event;
+ flags = Timer->Flags();
+ day = Timer->Day();
+ weekdays = Timer->WeekDays();
+
+ start = Timer->Start();
+ stop = Timer->Stop();
+ priority = Timer->Priority();
+ lifetime = Timer->Lifetime();
+ strcpy(file, Timer->File());
+ channel = Timer->Channel()->Number();
+#ifdef USE_PINPLUGIN
+ fskProtection = Timer->FskProtection();
+#endif
+ if (forcechannel)
+ channel = forcechannel->Number();
+ SplitFile();
+
+ addIfConfirmed = New;
+ Set();
+ SetHelp(addIfConfirmed?NULL:trVDR("Button$Delete"), NULL, NULL, NULL);
+ }
+}
+
+void cMenuMyEditTimer::SplitFile()
+{
+ char* tmp = strrchr(file, '~');
+ if (tmp) // split file in real file and directory
+ {
+ if (event && !isempty(event->ShortText()))
+ {
+ char* eventFile = NULL;
+ asprintf(&eventFile, "%s~%s", event->Title(), event->ShortText());
+ char* tmp2 = strstr(file, eventFile);
+ free(eventFile);
+ if (tmp2) // file contains title and subtitle
+ {
+ if (tmp2 > file)
+ {
+ *(tmp2-1) = 0;
+ strcpy(directory, file);
+ strcpy(file, tmp2);
+ }
+ else
+ *directory = 0;
+ }
+ else
+ {
+ *tmp = 0;
+ strcpy(directory, file);
+ strcpy(file, tmp+1);
+ }
+ }
+ else
+ {
+ *tmp = 0;
+ strcpy(directory, file);
+ strcpy(file, tmp+1);
+ }
+ }
+ else
+ *directory = 0;
+}
+
+void cMenuMyEditTimer::Set()
+{
+ int current = Current();
+ Clear();
+
+ cSearchExt* search = TriggeredFromSearchTimer(timer);
+
+ Add(new cMenuEditBitItem( trVDR("Active"), &flags, tfActive));
+#ifdef USE_PINPLUGIN
+ if (cOsd::pinValid) Add(new cMenuEditChanItem(tr("Channel"), &channel));
+ else {
+ char* buf = 0;
+ asprintf(&buf, "%s\t%s", tr("Channel"), Channels.GetByNumber(channel)->Name());
+ Add(new cOsdItem(buf));
+ free(buf);
+ }
+#else
+ Add(new cMenuEditChanItem(trVDR("Channel"), &channel));
+#endif
+ Add(new cMenuEditDateItem(trVDR("Day"), &day, &weekdays));
+
+ if (!IsSingleEvent())
+ Add(new cMenuEditDateItem(trVDR("First day"), &day));
+
+ Add(new cMenuEditTimeItem(trVDR("Start"), &start));
+ Add(new cMenuEditTimeItem(trVDR("Stop"), &stop));
+ Add(new cMenuEditBitItem( trVDR("VPS"), &flags, tfVps));
+ Add(new cMenuEditIntItem( trVDR("Priority"), &priority, 0, MAXPRIORITY));
+ Add(new cMenuEditIntItem( trVDR("Lifetime"), &lifetime, 0, MAXLIFETIME));
+#ifdef USE_PINPLUGIN
+ if (cOsd::pinValid || !fskProtection) Add(new cMenuEditBoolItem(tr("Childlock"),&fskProtection));
+ else {
+ char* buf = 0;
+ asprintf(&buf, "%s\t%s", tr("Childlock"), fskProtection ? trVDR("yes") : trVDR("no"));
+ Add(new cOsdItem(buf));
+ free(buf);
+ }
+#endif
+ Add(new cMenuEditStrItem( trVDR("File"), file, MaxFileName, trVDR(FileNameChars)));
+ Add(new cMenuEditStrItem( tr("Directory"), directory, MaxFileName, tr(AllowedChars)));
+
+ if (search)
+ {
+ cMenuEditStrItem* searchtimerItem = new cMenuEditStrItem( tr("Search timer"), search->search, MaxFileName, tr(AllowedChars));
+ searchtimerItem->SetSelectable(false);
+ Add(searchtimerItem);
+ }
+ else if (IsSingleEvent() && event)
+ {
+ checkmode = DefTimerCheckModes.GetMode(Channels.GetByNumber(channel));
+ char* checkmodeAux = GetAuxValue(timer, "update");
+ if (checkmodeAux)
+ {
+ checkmode = atoi(checkmodeAux);
+ free(checkmodeAux);
+ }
+ Add(new cMenuEditStraItem(tr("Timer check"), &checkmode, 3, CheckModes));
+ }
+
+ int deviceNr = gl_recStatusMonitor->TimerRecDevice(timer);
+ if (deviceNr > 0)
+ {
+ cOsdItem* pInfoItem = new cOsdItem("");
+ pInfoItem->SetSelectable(false);
+ Add(pInfoItem);
+ char* info = NULL;
+ asprintf(&info, "%s: %d/%d", tr("recording with device"), deviceNr, cDevice::NumDevices());
+ pInfoItem = new cOsdItem(info);
+ free(info);
+ pInfoItem->SetSelectable(false);
+ Add(pInfoItem);
+ }
+
+ if (current > -1)
+ {
+ SetCurrent(Get(current));
+ RefreshCurrent();
+ }
+ Display();
+}
+
+cMenuMyEditTimer::~cMenuMyEditTimer()
+{
+ if (timer && addIfConfirmed)
+ delete timer; // apparently it wasn't confirmed
+}
+
+void cMenuMyEditTimer::HandleSubtitle()
+{
+ const char* ItemText = Get(Current())->Text();
+ if (strstr(ItemText, tr("File")) != ItemText)
+ return;
+ if (InEditMode(ItemText, tr("File"), file))
+ return;
+
+ if (!event || (event && !event->ShortText()))
+ return;
+ char* tmp = strchr(file, '~');
+ if (tmp)
+ {
+ *tmp = 0;
+ SetHelp(addIfConfirmed?NULL:trVDR("Button$Delete"), NULL, trVDR("Button$Reset"), tr("Button$With subtitle"));
+ }
+ else
+ {
+ strcat(file, "~");
+ strcat(file, event->ShortText());
+ SetHelp(addIfConfirmed?NULL:trVDR("Button$Delete"), NULL, trVDR("Button$Reset"), tr("Button$Without subtitle"));
+ }
+ RefreshCurrent();
+ Display();
+}
+
+bool cMenuMyEditTimer::IsSingleEvent(void) const
+{
+ return !weekdays;
+}
+
+eOSState cMenuMyEditTimer::DeleteTimer()
+{
+ // Check if this timer is active:
+ if (timer) {
+ if (Interface->Confirm(tr("Delete timer?"))) {
+ if (timer->Recording()) {
+ if (Interface->Confirm(tr("Timer still recording - really delete?"))) {
+ timer->Skip();
+ cRecordControls::Process(time(NULL));
+ }
+ else
+ return osContinue;
+ }
+ LogFile.iSysLog("deleting timer %s", *timer->ToDescr());
+ Timers.Del(timer);
+ cOsdMenu::Del(Current());
+ Timers.SetModified();
+ Display();
+ return osBack;
+ }
+ }
+ return osContinue;
+}
+
+eOSState cMenuMyEditTimer::ProcessKey(eKeys Key)
+{
+ bool bWasSingleEvent = IsSingleEvent();
+
+ eOSState state = cOsdMenu::ProcessKey(Key);
+
+ if (bWasSingleEvent != IsSingleEvent())
+ {
+ Set();
+ Display();
+ }
+
+ int iOnDirectoryItem = 0;
+ int iOnFileItem = 0;
+ int iOnDayItem = 0;
+ const char* ItemText = Get(Current())->Text();
+ if (!HasSubMenu() && ItemText && strlen(ItemText)>0)
+ {
+ if (strstr(ItemText, tr("Day")) == ItemText)
+ {
+ if (!IsSingleEvent())
+ {
+ SetHelp(trVDR("Button$Edit"));
+ iOnDayItem = 1;
+ }
+ else
+ SetHelp(addIfConfirmed?NULL:trVDR("Button$Delete"), NULL, NULL, NULL);
+ }
+ else if (strstr(ItemText, tr("Directory")) == ItemText)
+ {
+ if (!InEditMode(ItemText, tr("Directory"), directory))
+ SetHelp(addIfConfirmed?NULL:trVDR("Button$Delete"), NULL, trVDR("Button$Reset"), tr("Button$Select"));
+ iOnDirectoryItem = 1;
+ }
+ else if (strstr(ItemText, tr("File")) == ItemText)
+ {
+ if (!InEditMode(ItemText, tr("File"), file))
+ {
+ if (event && event->ShortText())
+ {
+ if (strchr(file, '~'))
+ SetHelp(addIfConfirmed?NULL:trVDR("Button$Delete"), NULL, trVDR("Button$Reset"), tr("Button$Without subtitle"));
+ else
+ SetHelp(addIfConfirmed?NULL:trVDR("Button$Delete"), NULL, trVDR("Button$Reset"), tr("Button$With subtitle"));
+ }
+ else
+ SetHelp(addIfConfirmed?NULL:trVDR("Button$Delete"), NULL, trVDR("Button$Reset"), NULL);
+ }
+ iOnFileItem = 1;
+ }
+ else
+ SetHelp(addIfConfirmed?NULL:trVDR("Button$Delete"), NULL, NULL, NULL);
+ }
+
+ if ((Key == kYellow) && (iOnDirectoryItem && !InEditMode(ItemText, tr("Directory"), directory) ||
+ iOnFileItem && !InEditMode(ItemText, tr("File"), file)))
+ {
+ if (iOnDirectoryItem)
+ strcpy(directory, "");
+ if (iOnFileItem && event)
+ strn0cpy(file, event->Title(),sizeof(file));
+ RefreshCurrent();
+ Display();
+ }
+
+ if (state == osUnknown)
+ {
+ switch (Key)
+ {
+ case kOk:
+ {
+ cChannel *ch = Channels.GetByNumber(channel);
+ if (!ch)
+ {
+ Skins.Message(mtError, tr("*** Invalid Channel ***"));
+ break;
+ }
+
+ string fullaux = "";
+ string aux = "";
+ if (timer && timer->Aux())
+ fullaux = timer->Aux();
+
+ int bstart = 0, bstop = 0; // calculate margins
+ if (event && IsSingleEvent())
+ {
+ time_t startTime = 0, stopTime = 0;;
+ int begin = cTimer::TimeToInt(start); // seconds from midnight
+ int length = cTimer::TimeToInt(stop) - begin;
+ if (length < 0)
+ length += SECSINDAY;
+ startTime = cTimer::SetTime(day, begin);
+ stopTime = startTime + length;
+ bstart = event->StartTime() - startTime;
+ bstop = stopTime - event->EndTime();
+
+ char* epgsearchaux = GetAuxValue(timer, "epgsearch");
+ if (epgsearchaux)
+ {
+ aux = epgsearchaux;
+ free(epgsearchaux);
+ }
+ aux = UpdateAuxValue(aux, "channel", NumToString(ch->Number()) + " - " + CHANNELNAME(ch));
+ aux = UpdateAuxValue(aux, "update", checkmode);
+ aux = UpdateAuxValue(aux, "eventid", event->EventID());
+ aux = UpdateAuxValue(aux, "bstart", bstart);
+ aux = UpdateAuxValue(aux, "bstop", bstop);
+ fullaux = UpdateAuxValue(fullaux, "epgsearch", aux);
+ }
+
+#ifdef USE_PINPLUGIN
+ aux = "";
+ aux = UpdateAuxValue(aux, "protected", fskProtection ? "yes" : "no");
+ fullaux = UpdateAuxValue(fullaux, "pin-plugin", aux);
+#endif
+
+ char* tmpFile = strdup(file);
+ tmpFile = strreplace(tmpFile, ':', '|');
+ char* tmpDir = strdup(directory);
+ tmpDir = strreplace(tmpDir, ':', '|');
+ if (strlen(tmpFile) == 0)
+ tmpFile = strdup(CHANNELNAME(ch));
+
+ if (timer)
+ {
+ char* cmdbuf = NULL;
+ if (addIfConfirmed)
+ asprintf(&cmdbuf, "NEWT %d:%d:%s:%04d:%04d:%d:%d:%s%s%s:%s",
+ flags,
+ ch->Number(),
+#if VDRVERSNUM < 10503
+ PRINTDAY(day, weekdays),
+#else
+ PRINTDAY(day, weekdays, true),
+#endif
+ start,
+ stop,
+ priority,
+ lifetime,
+ strlen(tmpDir)>0?tmpDir:"",
+ (strlen(tmpDir)>0 && strlen(tmpFile)>0)?"~":"",
+ tmpFile,
+ fullaux.c_str());
+ else
+ asprintf(&cmdbuf, "MODT %d %d:%d:%s:%04d:%04d:%d:%d:%s%s%s:%s",
+ timer->Index()+1,
+ flags,
+ ch->Number(),
+#if VDRVERSNUM < 10503
+ PRINTDAY(day, weekdays),
+#else
+ PRINTDAY(day, weekdays, true),
+#endif
+ start,
+ stop,
+ priority,
+ lifetime,
+ strlen(tmpDir)>0?tmpDir:"",
+ (strlen(tmpDir)>0 && strlen(tmpFile)>0)?"~":"",
+ tmpFile,
+ fullaux.c_str());
+
+ cTimerThread timerThread;
+ timerThread.Init(cmdbuf);
+
+ free(cmdbuf);
+ free(tmpFile);
+ free(tmpDir);
+
+ addIfConfirmed = false;
+ }
+ }
+ return osBack;
+ case kRed:
+ if (HasSubMenu())
+ return osContinue;
+ else
+ if (iOnDayItem)
+ return AddSubMenu(new cMenuEditDaysOfWeek(&weekdays,1,false));
+ else
+ return DeleteTimer();
+ break;
+ case kGreen:
+ case kYellow:
+ return osContinue;
+ case kBlue:
+ if (HasSubMenu())
+ return osContinue;
+ if (iOnDirectoryItem && !InEditMode(ItemText, tr("Directory"), directory))
+ state = AddSubMenu(new cMenuDirSelect(directory));
+ if (iOnFileItem)
+ {
+ HandleSubtitle();
+ return osContinue;
+ }
+ break;
+ default: break;
+ }
+ }
+
+ if (Key != kNone && !HasSubMenu())
+ {
+ if (iOnDirectoryItem && !InEditMode(ItemText, tr("Directory"), directory))
+ ReplaceDirVars();
+ }
+ return state;
+}
+
+void cMenuMyEditTimer::ReplaceDirVars()
+{
+ if (!strchr(directory,'%') || !event)
+ return;
+
+ cVarExpr varExpr(directory);
+ strcpy(directory, varExpr.Evaluate(event).c_str());
+ if (strchr(directory, '%') != NULL) // only set directory to new value if all categories could have been replaced
+ *directory = 0;
+ if (varExpr.DependsOnVar("%title%", event) || varExpr.DependsOnVar("%subtitle%", event))
+ {
+ strcpy(file, directory);
+ *directory = 0;
+ SplitFile();
+ }
+
+ RefreshCurrent();
+ // update title too
+ if (Current() > 0)
+ Get(Current()-1)->Set();
+ Display();
+ return;
+}
+