/* -*- 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 */ #include #include "menu_commands.h" #include #include #include #include "menu_searchresults.h" #include "menu_myedittimer.h" #include "menu_search.h" #include "menu_searchedit.h" #include "epgsearchcfg.h" #include "recdone.h" #include "epgsearchtools.h" #include "switchtimer.h" #include "switchtimer_thread.h" #include "blacklist.h" #include "menu_blacklistedit.h" #include #include "menu_deftimercheckmethod.h" // --- cMenuSearchCommands --------------------------------------------------------- cMenuSearchCommands::cMenuSearchCommands(const char *Title, const cEvent* Event, bool DirectCall, cSearchExt* Search) : cOsdMenu(Title) { SetMenuCategory(mcCommand); directCall = DirectCall; SetHasHotkeys(); LoadCommands(); search = Search; event = Event; Add(new cOsdItem(hk(tr("Repeats")))); Add(new cOsdItem(hk(trVDR("Button$Record")))); Add(new cOsdItem(hk(trVDR("Button$Switch")))); Add(new cOsdItem(hk(tr("Create search")))); Add(new cOsdItem(hk(tr("Search in recordings")))); Add(new cOsdItem(hk(tr("Mark as 'already recorded'?")))); Add(new cOsdItem(hk(tr("Add/Remove to/from switch list?")))); Add(new cOsdItem(hk(tr("Create blacklist")))); for (cCommand *command = commands.First(); command; command = commands.Next(command)) Add(new cOsdItem(hk(command->Title()))); if (event) { cString szTitle = cString::sprintf("%s: %s", tr("EPG Commands"), event->Title()); SetTitle(szTitle); } } cMenuSearchCommands::~cMenuSearchCommands() { } void cMenuSearchCommands::LoadCommands() { const char* szLanguageCode = I18nLanguageCode(I18nCurrentLanguage()); char *pstrSearchToken, *pptr; char *pstrSearch = strdup(szLanguageCode); pstrSearchToken = strtok_r(pstrSearch, ",", &pptr); bool bLoaded = false; while (pstrSearchToken) { // may contain multiple code, e.g. 'ger,deu' cString cmdFile = cString::sprintf("%s-%s.conf", ADDDIR(CONFIGDIR, "epgsearchcmds"), pstrSearchToken); if (access(cmdFile, F_OK) == 0) { commands.Load(cmdFile, true); bLoaded = true; break; } pstrSearchToken = strtok_r(NULL, ",", &pptr); } if (!bLoaded) commands.Load(AddDirectory(CONFIGDIR, "epgsearchcmds.conf"), true); free(pstrSearch); } eOSState cMenuSearchCommands::Switch(void) { LOCK_CHANNELS_READ; const cChannel *channel = Channels->GetByChannelID(event->ChannelID(), true, true); if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true)) return osEnd; else { INFO(trVDR("Can't switch channel!")); return osContinue; } } eOSState cMenuSearchCommands::ExtendedSearch(void) { return AddSubMenu(new cMenuEPGSearchExt()); } eOSState cMenuSearchCommands::Record(void) { if (!event) return osContinue; eTimerMatch timerMatch = tmNone; LOCK_TIMERS_WRITE; Timers->SetExplicitModify(); cTimer* timer = Timers->GetMatch(event, &timerMatch); if (timerMatch == tmFull) { if (EPGSearchConfig.useVDRTimerEditMenu) return AddSubMenu(new cMenuEditTimer(timer)); else return AddSubMenu(new cMenuMyEditTimer(timer, false, event, timer->Channel())); } timer = new cTimer(event); PrepareTimerFile(event, timer); cTimer *t = Timers->GetTimer(timer); if (EPGSearchConfig.onePressTimerCreation == 0 || t || (!t && event->StartTime() - (Setup.MarginStart + 2) * 60 < time(NULL))) { if (t) { delete timer; timer = t; } if (EPGSearchConfig.useVDRTimerEditMenu) return AddSubMenu(new cMenuEditTimer(timer, !t)); else return AddSubMenu(new cMenuMyEditTimer(timer, !t, event)); } else { string fullaux = ""; string aux = ""; if (event) { int bstart = event->StartTime() - timer->StartTime(); int bstop = timer->StopTime() - event->EndTime(); int checkmode = DefTimerCheckModes.GetMode(timer->Channel()); aux = UpdateAuxValue(aux, "channel", NumToString(timer->Channel()->Number()) + " - " + CHANNELNAME(timer->Channel())); 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", timer->FskProtection() ? "yes" : "no"); fullaux = UpdateAuxValue(fullaux, "pin-plugin", aux); #endif SetAux(timer, fullaux); if (Setup.SVDRPPeering && *Setup.SVDRPDefaultHost) timer->SetRemote(Setup.SVDRPDefaultHost); Timers->Add(timer); timer->Matches(); Timers->SetModified(); if (!HandleRemoteTimerModifications(timer)) { ERROR(tr("Epgsearch: RemoteTimerModifications failed")); Timers->Del(timer); } else return osBack; } return osContinue; } eOSState cMenuSearchCommands::MarkAsRecorded(void) { if (!event) return osContinue; if (!Interface->Confirm(tr("Mark as 'already recorded'?"))) return osContinue; cTimer* dummyTimer = new cTimer(event); cMutexLock RecsDoneLock(&RecsDone); RecsDone.Add(new cRecDone(dummyTimer, event, search, "Unused")); RecsDone.Save(); delete dummyTimer; return osBack; } eOSState cMenuSearchCommands::AddToSwitchList(void) { if (!event) return osContinue; time_t now = time(NULL); if (now >= event->StartTime()) { ERROR(tr("Already running!")); return osBack; } cSwitchTimer* switchTimer = SwitchTimers.InSwitchList(event); if (!switchTimer) { if (!Interface->Confirm(tr("Add to switch list?"))) return osContinue; cMutexLock SwitchTimersLock(&SwitchTimers); SwitchTimers.Add(new cSwitchTimer(event)); SwitchTimers.Save(); cSwitchTimerThread::Init(); // asure the thread is running } else { if (!Interface->Confirm(tr("Delete from switch list?"))) return osContinue; cMutexLock SwitchTimersLock(&SwitchTimers); SwitchTimers.Del(switchTimer); SwitchTimers.Save(); if (SwitchTimers.Count() == 0) cSwitchTimerThread::Exit(); } return osBack; } eOSState cMenuSearchCommands::CreateSearchTimer(void) { if (!event) return osContinue; cSearchExt* pNew = new cSearchExt; strcpy(pNew->search, event->Title()); LOCK_CHANNELS_READ; pNew->channelMin = pNew->channelMax = Channels->GetByChannelID(event->ChannelID()); return AddSubMenu(new cMenuEditSearchExt(pNew, true, false, true)); } eOSState cMenuSearchCommands::CreateBlacklist(void) { if (!event) return osContinue; cBlacklist* pNew = new cBlacklist; strcpy(pNew->search, event->Title()); return AddSubMenu(new cMenuBlacklistEdit(pNew, true)); } eOSState cMenuSearchCommands::Execute(void) { int current = Current(); if (current <= 7) { if (current == 0) return AddSubMenu(new cMenuSearchResultsForQuery(event->Title(), true)); if (current == 1) return Record(); if (current == 2) return Switch(); if (current == 3) return CreateSearchTimer(); if (current == 4) return AddSubMenu(new cMenuSearchResultsForRecs(event->Title())); if (current == 5) return MarkAsRecorded(); if (current == 6) return AddToSwitchList(); if (current == 7) return CreateBlacklist(); } cCommand *command = commands.Get(current - 8); if (command) { cString buffer; bool confirmed = true; if (command->Confirm()) { buffer = cString::sprintf("%s?", command->Title()); confirmed = Interface->Confirm(buffer); } if (confirmed) { buffer = cString::sprintf("%s...", command->Title()); Skins.Message(mtStatus, buffer); { LOCK_CHANNELS_READ; buffer = cString::sprintf("'%s' %ld %ld %d '%s' '%s'", EscapeString(event->Title()).c_str(), event->StartTime(), event->EndTime(), ChannelNrFromEvent(event), EscapeString(Channels->GetByChannelID(event->ChannelID(), true, true)->Name()).c_str(), EscapeString(event->ShortText() ? event->ShortText() : "").c_str()); } const char *Result = command->Execute(buffer); Skins.Message(mtStatus, NULL); if (Result) return AddSubMenu(new cMenuText(command->Title(), Result, fontFix)); return osBack; } } return osContinue; } eOSState cMenuSearchCommands::ProcessKey(eKeys Key) { bool hadSubmenu = HasSubMenu(); eOSState state = cOsdMenu::ProcessKey(Key); // jump back to calling menu, if a command was called directly with key '1' .. '9' if (directCall && hadSubmenu && !HasSubMenu()) return osBack; if (state == osUnknown) { switch (Key) { case kGreen: case kYellow: case kBlue: return osContinue; case k1...k9: case kOk: return Execute(); default: break; } } return state; }