/* -*- 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_blacklistedit.h" #include "changrp.h" #include "epgsearchcats.h" #include "epgsearchtools.h" #include "menu_dirselect.h" #include "menu_searchedit.h" #include "menu_searchtemplate.h" #include "epgsearchcfg.h" #include extern cChannelGroups ChannelGroups; extern cSearchExtCats SearchExtCats; extern const char AllowedChars[]; // --- cMenuBlacklistEdit -------------------------------------------------------- cMenuBlacklistEdit::cMenuBlacklistEdit(cBlacklist *Blacklist, bool New) : cOsdMenu(tr("Edit blacklist"), 32) { SetMenuCategory(mcSetupPlugins); SearchModes[0] = strdup(tr("phrase")); SearchModes[1] = strdup(tr("all words")); SearchModes[2] = strdup(tr("at least one word")); SearchModes[3] = strdup(tr("match exactly")); SearchModes[4] = strdup(tr("regular expression")); SearchModes[5] = strdup(tr("fuzzy")); DaysOfWeek[0] = strdup(WeekDayName(0)); DaysOfWeek[1] = strdup(WeekDayName(1)); DaysOfWeek[2] = strdup(WeekDayName(2)); DaysOfWeek[3] = strdup(WeekDayName(3)); DaysOfWeek[4] = strdup(WeekDayName(4)); DaysOfWeek[5] = strdup(WeekDayName(5)); DaysOfWeek[6] = strdup(WeekDayName(6)); DaysOfWeek[7] = strdup(tr("user-defined")); UseChannelSel[0] = strdup(trVDR("no")); UseChannelSel[1] = strdup(tr("interval")); UseChannelSel[2] = strdup(tr("channel group")); UseChannelSel[3] = strdup(tr("only FTA")); if (New) { cSearchExt* SearchTempl = NULL; // copy the default settings, if we have a default template cMutexLock SearchTemplatesLock(&SearchTemplates); cSearchExt *SearchExtTempl = SearchTemplates.First(); while (SearchExtTempl) { if (SearchExtTempl->ID == EPGSearchConfig.DefSearchTemplateID) SearchTempl = SearchExtTempl; SearchExtTempl = SearchTemplates.Next(SearchExtTempl); } if (SearchTempl) Blacklist->CopyFromTemplate(SearchTempl); } blacklist = Blacklist; addIfConfirmed = New; if (blacklist) { data = *blacklist; UserDefDayOfWeek = 0; if (blacklist->DayOfWeek < 0) { UserDefDayOfWeek = blacklist->DayOfWeek; data.DayOfWeek = 7; } menuitemsChGr = NULL; channelGroupName = NULL; channelMin = channelMax = cDevice::CurrentChannel(); channelGroupNr = 0; if (data.useChannel == 1) { channelMin = data.channelMin->Number(); channelMax = data.channelMax->Number(); } if (data.useChannel == 2) { channelGroupNr = ChannelGroups.GetIndex(data.channelGroup); if (channelGroupNr == -1) { free(data.channelGroup); data.channelGroup = NULL; channelGroupNr = 0; // no selection } else { channelGroupName = strdup(data.channelGroup); channelGroupNr++; } } catvaluesNumeric = NULL; if (SearchExtCats.Count() > 0) { catvaluesNumeric = (int*) malloc(SearchExtCats.Count() * sizeof(int)); cSearchExtCat *SearchExtCat = SearchExtCats.First(); int index = 0; while (SearchExtCat) { catvaluesNumeric[index] = atol(blacklist->catvalues[index]); SearchExtCat = SearchExtCats.Next(SearchExtCat); index++; } } Set(); } } void cMenuBlacklistEdit::Set() { int current = Current(); Clear(); Add(new cMenuEditStrItem(tr("Search term"), data.search, sizeof(data.search), tr(AllowedChars))); Add(new cMenuEditStraItem(tr("Search mode"), &data.mode, 6, SearchModes)); if (data.mode == 5) // fuzzy Add(new cMenuEditIntItem(IndentMenuItem(tr("Tolerance")), &data.fuzzyTolerance, 1, 9)); Add(new cMenuEditBoolItem(tr("Match case"), &data.useCase, trVDR("no"), trVDR("yes"))); Add(new cMenuEditBoolItem(tr("Use title"), &data.useTitle, trVDR("no"), trVDR("yes"))); Add(new cMenuEditBoolItem(tr("Use subtitle"), &data.useSubtitle, trVDR("no"), trVDR("yes"))); Add(new cMenuEditBoolItem(tr("Use description"), &data.useDescription, trVDR("no"), trVDR("yes"))); // show Categories only if we have them if (SearchExtCats.Count() > 0) { Add(new cMenuEditBoolItem(tr("Use extended EPG info"), &data.useExtEPGInfo, trVDR("no"), trVDR("yes"))); if (data.useExtEPGInfo) { cSearchExtCat *SearchExtCat = SearchExtCats.First(); int index = 0; while (SearchExtCat) { if (SearchExtCat->searchmode >= 10) Add(new cMenuEditIntItem(IndentMenuItem(SearchExtCat->menuname), &catvaluesNumeric[index], 0, 999999, "")); else Add(new cMenuEditStrItem(IndentMenuItem(SearchExtCat->menuname), data.catvalues[index], MaxFileName, tr(AllowedChars))); SearchExtCat = SearchExtCats.Next(SearchExtCat); index++; } Add(new cMenuEditBoolItem(IndentMenuItem(tr("Ignore missing categories")), &data.ignoreMissingEPGCats, trVDR("no"), trVDR("yes"))); } } Add(new cMenuEditStraItem(tr("Use channel"), &data.useChannel, 4, UseChannelSel)); if (data.useChannel == 1) { Add(new cMenuEditChanItem(tr(" from channel"), &channelMin)); Add(new cMenuEditChanItem(tr(" to channel"), &channelMax)); } if (data.useChannel == 2) { // create the char array for the menu display if (menuitemsChGr) delete [] menuitemsChGr; menuitemsChGr = ChannelGroups.CreateMenuitemsList(); int oldchannelGroupNr = channelGroupNr; channelGroupNr = ChannelGroups.GetIndex(channelGroupName); if (channelGroupNr == -1) { if (oldchannelGroupNr > 0 && oldchannelGroupNr <= ChannelGroups.Count()) // perhaps its name was changed channelGroupNr = oldchannelGroupNr; else channelGroupNr = 0; // no selection } else channelGroupNr++; Add(new cMenuEditStraItem(IndentMenuItem(tr("Channel group")), &channelGroupNr, ChannelGroups.Count() + 1, menuitemsChGr)); } Add(new cMenuEditBoolItem(tr("Use time"), &data.useTime, trVDR("no"), trVDR("yes"))); if (data.useTime == true) { Add(new cMenuEditTimeItem(tr(" Start after"), &data.startTime)); Add(new cMenuEditTimeItem(tr(" Start before"), &data.stopTime)); } Add(new cMenuEditBoolItem(tr("Use duration"), &data.useDuration, trVDR("no"), trVDR("yes"))); if (data.useDuration == true) { Add(new cMenuEditTimeItem(tr(" Min. duration"), &data.minDuration)); Add(new cMenuEditTimeItem(tr(" Max. duration"), &data.maxDuration)); } Add(new cMenuEditBoolItem(tr("Use day of week"), &data.useDayOfWeek, trVDR("no"), trVDR("yes"))); if (data.useDayOfWeek) { if (data.DayOfWeek < 0) { UserDefDayOfWeek = data.DayOfWeek; data.DayOfWeek = 7; } Add(new cMenuEditStraItem(IndentMenuItem(tr("Day of week")), &data.DayOfWeek, 8, DaysOfWeek)); } Add(new cMenuEditBoolItem(tr("Use global"), &data.isGlobal, trVDR("no"), trVDR("yes"))); SetCurrent(Get(current)); } cMenuBlacklistEdit::~cMenuBlacklistEdit() { if (blacklist && addIfConfirmed) delete blacklist; // apparently it wasn't confirmed if (menuitemsChGr) free(menuitemsChGr); if (channelGroupName) free(channelGroupName); if (catvaluesNumeric) free(catvaluesNumeric); int i; for (i = 0; i <= 4; i++) free(SearchModes[i]); for (i = 0; i <= 7; i++) free(DaysOfWeek[i]); for (i = 0; i <= 2; i++) free(UseChannelSel[i]); } eOSState cMenuBlacklistEdit::ProcessKey(eKeys Key) { bool bHadSubMenu = HasSubMenu(); int iTemp_mode = data.mode; int iTemp_useTime = data.useTime; int iTemp_useChannel = data.useChannel; int iTemp_useDuration = data.useDuration; int iTemp_useDayOfWeek = data.useDayOfWeek; int iTemp_useExtEPGInfo = data.useExtEPGInfo; eOSState state = cOsdMenu::ProcessKey(Key); if (iTemp_mode != data.mode || iTemp_useTime != data.useTime || iTemp_useChannel != data.useChannel || iTemp_useDuration != data.useDuration || iTemp_useDayOfWeek != data.useDayOfWeek || iTemp_useExtEPGInfo != data.useExtEPGInfo) { Set(); Display(); } const char* ItemText = Get(Current())->Text(); if (!HasSubMenu()) { if (strlen(ItemText) > 0 && strstr(ItemText, tr(" from channel")) == ItemText && ((Key >= k0 && Key <= k9) || Key == kLeft || Key == kRight)) { channelMax = channelMin; Set(); Display(); } } int iOnUserDefDayItem = 0; int iOnUseChannelGroups = 0; int iOnChannelGroup = 0; int iOnTerm = 0; int iOnExtCatItemBrowsable = 0; int iCatIndex = -1; char* catname = NULL; if (!HasSubMenu() && strlen(ItemText) > 0) { // check, if on an item of ext. EPG info int iOnExtCatItem = 0; cSearchExtCat *SearchExtCat = SearchExtCats.First(); int index = 0; while (SearchExtCat) { if (strstr(ItemText, IndentMenuItem(SearchExtCat->menuname)) == ItemText) { iOnExtCatItem = 1; if (SearchExtCat->nvalues > 0) iOnExtCatItemBrowsable = 1; iCatIndex = index; catname = SearchExtCat->menuname; break; } index++; SearchExtCat = SearchExtCats.Next(SearchExtCat); } if (strstr(ItemText, tr("Search term")) == ItemText) { if (!InEditMode(ItemText, tr("Search term"), data.search)) { // show template for a new search SetHelp(NULL, NULL, NULL, tr("Button$Templates")); iOnTerm = 1; } } if (strstr(ItemText, IndentMenuItem(tr("Day of week"))) == ItemText) { if (data.DayOfWeek == 7) { SetHelp(trVDR("Button$Edit")); iOnUserDefDayItem = 1; } else SetHelp(NULL); } else if (strstr(ItemText, tr("Use channel")) == ItemText && data.useChannel == 2) { SetHelp(NULL, NULL, NULL, tr("Button$Setup")); iOnUseChannelGroups = 1; } else if (strstr(ItemText, IndentMenuItem(tr("Channel group"))) == ItemText) { SetHelp(NULL, NULL, NULL, tr("Button$Setup")); iOnChannelGroup = 1; } else if (iOnExtCatItem) { if (!InEditMode(ItemText, IndentMenuItem(catname), data.catvalues[iCatIndex]) || SearchExtCats.Get(iCatIndex)->searchmode >= 10) SetHelp(NULL, NULL, NULL, iOnExtCatItemBrowsable ? tr("Button$Select") : NULL); } else if (strstr(ItemText, tr("Search term")) != ItemText) SetHelp(NULL, NULL, NULL, NULL); } if (state == osUnknown) { if (HasSubMenu()) return osContinue; switch (Key) { case kOk: if (data.useChannel == 1) { LOCK_CHANNELS_READ; const cChannel *ch = Channels->GetByNumber(channelMin); if (ch) data.channelMin = ch; else { ERROR(tr("*** Invalid Channel ***")); break; } ch = Channels->GetByNumber(channelMax); if (ch) data.channelMax = ch; else { ERROR(tr("*** Invalid Channel ***")); break; } if (channelMin > channelMax) { ERROR(tr("Please check channel criteria!")); return osContinue; } } if (data.useChannel == 2) data.channelGroup = strdup(menuitemsChGr[channelGroupNr]); if (blacklist) { *blacklist = data; if (data.DayOfWeek == 7) blacklist->DayOfWeek = UserDefDayOfWeek; // transfer numeric cat values back to search cSearchExtCat *SearchExtCat = SearchExtCats.First(); int index = 0; while (SearchExtCat) { if (SearchExtCat->searchmode >= 10) { if (blacklist->catvalues[index]) free(blacklist->catvalues[index]); msprintf(&blacklist->catvalues[index], "%d", catvaluesNumeric[index]); } SearchExtCat = SearchExtCats.Next(SearchExtCat); index++; } if (addIfConfirmed) { cMutexLock BlacklistLock(&Blacklists); blacklist->ID = Blacklists.GetNewID(); Blacklists.Add(blacklist); } Blacklists.Save(); addIfConfirmed = false; } return osBack; case kRed: if (iOnUserDefDayItem) state = AddSubMenu(new cMenuEditDaysOfWeek(&UserDefDayOfWeek)); break; case kBlue: if (iOnUseChannelGroups || iOnChannelGroup) { if (channelGroupName) free(channelGroupName); channelGroupName = strdup(menuitemsChGr[channelGroupNr]); state = AddSubMenu(new cMenuChannelGroups(&channelGroupName)); } if (iOnTerm) state = AddSubMenu(new cMenuEPGSearchTemplate(NULL, &data, addIfConfirmed)); if (iOnExtCatItemBrowsable) state = AddSubMenu(new cMenuCatValuesSelect(data.catvalues[iCatIndex], iCatIndex, SearchExtCats.Get(iCatIndex)->searchmode)); break; case kGreen: case kYellow: state = osContinue; default: break; } } if ((iOnUseChannelGroups || iOnChannelGroup || iOnTerm || iOnExtCatItemBrowsable) && bHadSubMenu && !HasSubMenu()) { // return form submenu if (iOnTerm) { if (data.DayOfWeek < 0) { UserDefDayOfWeek = data.DayOfWeek; data.DayOfWeek = 7; } if (data.useChannel == 2) { channelGroupNr = ChannelGroups.GetIndex(data.channelGroup); channelGroupName = strdup(data.channelGroup); } } if (iOnExtCatItemBrowsable && SearchExtCats.Count() > 0) { cSearchExtCat *SearchExtCat = SearchExtCats.First(); int index = 0; while (SearchExtCat) { if (SearchExtCat->searchmode >= 10) catvaluesNumeric[index] = atoi(data.catvalues[index]); SearchExtCat = SearchExtCats.Next(SearchExtCat); index++; } } Set(); Display(); } return state; }