summaryrefslogtreecommitdiff
path: root/menu_dirselect.c
diff options
context:
space:
mode:
authorChristian Wieninger <winni@debian.(none)>2007-11-11 15:40:28 +0100
committerChristian Wieninger <winni@debian.(none)>2007-11-11 15:40:28 +0100
commit8d4f8607dc1558ce73eb4c376bdbf78ddb65da83 (patch)
treed0c5dde81a36ab2e8a2edc7c1e6922556518b312 /menu_dirselect.c
downloadvdr-plugin-epgsearch-8d4f8607dc1558ce73eb4c376bdbf78ddb65da83.tar.gz
vdr-plugin-epgsearch-8d4f8607dc1558ce73eb4c376bdbf78ddb65da83.tar.bz2
Initial commit
Diffstat (limited to 'menu_dirselect.c')
-rw-r--r--menu_dirselect.c254
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;
+}
+