diff options
author | Christian Wieninger <winni@debian.(none)> | 2007-11-11 15:40:28 +0100 |
---|---|---|
committer | Christian Wieninger <winni@debian.(none)> | 2007-11-11 15:40:28 +0100 |
commit | 8d4f8607dc1558ce73eb4c376bdbf78ddb65da83 (patch) | |
tree | d0c5dde81a36ab2e8a2edc7c1e6922556518b312 /menu_dirselect.c | |
download | vdr-plugin-epgsearch-8d4f8607dc1558ce73eb4c376bdbf78ddb65da83.tar.gz vdr-plugin-epgsearch-8d4f8607dc1558ce73eb4c376bdbf78ddb65da83.tar.bz2 |
Initial commit
Diffstat (limited to 'menu_dirselect.c')
-rw-r--r-- | menu_dirselect.c | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/menu_dirselect.c b/menu_dirselect.c new file mode 100644 index 0000000..b92b8cf --- /dev/null +++ b/menu_dirselect.c @@ -0,0 +1,254 @@ +/* +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 "menu_dirselect.h" +#include "epgsearchext.h" +#include "epgsearchcats.h" +#include "epgsearchtools.h" + +set<string> cMenuDirSelect::directorySet; + +cDirExts DirExts; + +// --- cMenuDirItem --------------------------------------------------------- +class cMenuDirItem : public cOsdItem +{ + private: + char* directory; + public: + cMenuDirItem(const char* text) : cOsdItem(text) { directory = strdup(text);} + ~cMenuDirItem(){ if (directory) free(directory);} + virtual int Compare(const cListObject &ListObject) const; +}; + +int cMenuDirItem::Compare(const cListObject &ListObject) const +{ + const cMenuDirItem *p = (cMenuDirItem *)&ListObject; + int hasVars1 = (strchr(directory,'%') != NULL?1:0); + int hasVars2 = (strchr(p->directory,'%') != NULL?1:0); + if (hasVars1 || hasVars2) + { + if (hasVars1 != hasVars2) + return hasVars2-hasVars1; + else + return strcasecmp(directory, p->directory); + } + else + return strcasecmp(directory, p->directory); +} + + +// --- cMenuDirSelect --------------------------------------------------------- + +cMenuDirSelect::cMenuDirSelect(char* szDirectory) + :cOsdMenu(tr("Select directory")) +{ + Directory = szDirectory; + yellow=NULL; + MaxLevel = 1; + CurLevel = 1; + Load(); +} + +cMenuDirSelect::~cMenuDirSelect() +{ + if (yellow) free(yellow); +} + +int cMenuDirSelect::Level(const char* szDir) +{ + int iLevel = 1; + if (strchr(szDir, '%')) // dirs with vars always have level 1 + return 1; + do + { + char* pos = strchr(szDir, '~'); + if (pos) + { + iLevel++; + szDir = pos+1; + } + else + return iLevel; + } + while(true); + return 1; +} + +void cMenuDirSelect::AddDistinct(const char* szText) +{ + int iLevel = Level(szText); + MaxLevel = max(MaxLevel, iLevel); + + if (iLevel > CurLevel) // only show Items of the specified level, except those with vars + return; + + for(int i=0; i<Count(); i++) + { + const char* ItemText = Get(i)->Text(); + char* itemtext = strdup(ItemText); + char* sztext = strdup(szText); + ToLower(itemtext); + ToLower(sztext); + if (itemtext && strlen(itemtext) > 0 && strcmp(sztext, itemtext) == 0) + { + free(itemtext); + free(sztext); + return; + } + free(itemtext); + free(sztext); + } + Add(new cMenuDirItem(hk(szText))); +} + +void cMenuDirSelect::CreateDirSet() +{ + directorySet.clear(); + + // add distinct directories from current recordings + if (Recordings.Count() == 0) + Recordings.Load(); + for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) + { + if (recording->HierarchyLevels() > 0) + { + char* dir = strdup(recording->Name()); + // strip the trailing rec dir + char* pos = strrchr(dir, '~'); + if (pos) + { + *pos=0; + for(int iLevel = 0; iLevel < recording->HierarchyLevels(); iLevel++) + { + directorySet.insert(dir); + char* pos = strrchr(dir, '~'); + if (pos) + *pos=0; + } + } + free(dir); + } + } + // add distinct directories from current timers + for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) + { + char* dir = strdup(timer->File()); + // strip the trailing name dir + char* pos = strrchr(dir, '~'); + if (pos) + { + *pos=0; + do + { + directorySet.insert(dir); + char* pos = strrchr(dir, '~'); + if (pos) + *pos=0; + else break; + } + while(true); + } + free(dir); + } + cMutexLock SearchExtsLock(&SearchExts); + cSearchExt *searchExt = SearchExts.First(); + // add distinct directories from existing search timers + while (searchExt) + { + if (strlen(searchExt->directory) > 0) + directorySet.insert(searchExt->directory); + searchExt = SearchExts.Next(searchExt); + } + // add distinct directories from epgsearchdirs.conf + DirExts.Load(AddDirectory(CONFIGDIR, "epgsearchdirs.conf"), true); + cDirExt* DirExt = DirExts.First(); + while (DirExt) + { + directorySet.insert(DirExt->Name()); + DirExt = DirExts.Next(DirExt); + } +} + + +void cMenuDirSelect::Load() +{ + int current = Current(); + char* oldSelection = NULL; // save old selection for reselection + if (current>-1) + oldSelection = strdup(Get(current)->Text()); + Clear(); + + CreateDirSet(); + std::set<string>::iterator it; + for (it = directorySet.begin(); it != directorySet.end(); it++) + AddDistinct((*it).c_str()); + + Sort(); + for(int i=0; i<Count(); i++) + { + const char* text = Get(i)->Text(); + if (oldSelection && strchr(text, '%') == NULL && strstr(text, oldSelection) == text) // skip entries with variables + { + SetCurrent(Get(i)); + break; + } + } + if (oldSelection) free(oldSelection); + + if (yellow) + { + free(yellow); + yellow = NULL; + } + asprintf(&yellow, "%s %d", tr("Button$Level"), (CurLevel==MaxLevel?1:CurLevel+1)); + SetHelp(NULL, NULL, MaxLevel==1?NULL:yellow, tr("Button$Select")); + Display(); +} + +eOSState cMenuDirSelect::ProcessKey(eKeys Key) +{ + eOSState state = cOsdMenu::ProcessKey(Key); + + if (state == osUnknown) { + switch (Key) { + case kBlue|k_Repeat: + case kYellow: + if (++CurLevel>MaxLevel) + CurLevel=1; + Load(); + return osContinue; + case kGreen: + case kRed: + return osContinue; + case kBlue: + case kOk: + if (Count() > 0) + strn0cpy(Directory,Get(Current())->Text(), MaxFileName); + return osBack; + default: break; + } + } + return state; +} + |