summaryrefslogtreecommitdiff
path: root/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'menu.c')
-rw-r--r--menu.c301
1 files changed, 297 insertions, 4 deletions
diff --git a/menu.c b/menu.c
index b0077a0d..f37ee25e 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 2.10 2009/12/06 11:29:05 kls Exp $
+ * $Id: menu.c 2.11 2010/01/17 12:08:03 kls Exp $
*/
#include "menu.h"
@@ -623,11 +623,276 @@ eOSState cMenuText::ProcessKey(eKeys Key)
return state;
}
+// --- cMenuFolderItem -------------------------------------------------------
+
+class cMenuFolderItem : public cOsdItem {
+private:
+ cNestedItem *folder;
+public:
+ cMenuFolderItem(cNestedItem *Folder);
+ cNestedItem *Folder(void) { return folder; }
+ };
+
+cMenuFolderItem::cMenuFolderItem(cNestedItem *Folder)
+:cOsdItem(Folder->Text())
+{
+ folder = Folder;
+ if (folder->SubItems())
+ SetText(cString::sprintf("%s...", folder->Text()));
+}
+
+// --- cMenuEditFolder -------------------------------------------------------
+
+class cMenuEditFolder : public cOsdMenu {
+private:
+ cList<cNestedItem> *list;
+ cNestedItem *folder;
+ char name[PATH_MAX];
+ int subFolder;
+ eOSState Confirm(void);
+public:
+ cMenuEditFolder(const char *Dir, cList<cNestedItem> *List, cNestedItem *Folder = NULL);
+ cString GetFolder(void);
+ virtual eOSState ProcessKey(eKeys Key);
+ };
+
+cMenuEditFolder::cMenuEditFolder(const char *Dir, cList<cNestedItem> *List, cNestedItem *Folder)
+:cOsdMenu(Folder ? tr("Edit folder") : tr("New folder"), 12)
+{
+ list = List;
+ folder = Folder;
+ if (folder) {
+ strn0cpy(name, folder->Text(), sizeof(name));
+ subFolder = folder->SubItems() != NULL;
+ }
+ else {
+ *name = 0;
+ subFolder = 0;
+ cRemote::Put(kRight, true); // go right into string editing mode
+ }
+ if (!isempty(Dir)) {
+ cOsdItem *DirItem = new cOsdItem(Dir);
+ DirItem->SetSelectable(false);
+ Add(DirItem);
+ }
+ Add(new cMenuEditStrItem( tr("Name"), name, sizeof(name)));
+ Add(new cMenuEditBoolItem(tr("Sub folder"), &subFolder));
+}
+
+cString cMenuEditFolder::GetFolder(void)
+{
+ return folder ? folder->Text() : "";
+}
+
+eOSState cMenuEditFolder::Confirm(void)
+{
+ if (!folder || strcmp(folder->Text(), name) != 0) {
+ // each name may occur only once in a folder list
+ for (cNestedItem *Folder = list->First(); Folder; Folder = list->Next(Folder)) {
+ if (strcmp(Folder->Text(), name) == 0) {
+ Skins.Message(mtError, tr("Folder name already exists!"));
+ return osContinue;
+ }
+ }
+ char *p = strpbrk(name, "\\{}#~"); // FOLDERDELIMCHAR
+ if (p) {
+ Skins.Message(mtError, cString::sprintf(tr("Folder name must not contain '%c'!"), *p));
+ return osContinue;
+ }
+ }
+ if (folder) {
+ folder->SetText(name);
+ folder->SetSubItems(subFolder);
+ }
+ else
+ list->Add(folder = new cNestedItem(name, subFolder));
+ return osEnd;
+}
+
+eOSState cMenuEditFolder::ProcessKey(eKeys Key)
+{
+ eOSState state = cOsdMenu::ProcessKey(Key);
+
+ if (state == osUnknown) {
+ switch (Key) {
+ case kOk: return Confirm();
+ case kRed:
+ case kGreen:
+ case kYellow:
+ case kBlue: return osContinue;
+ default: break;
+ }
+ }
+ return state;
+}
+
+// --- cMenuFolder -----------------------------------------------------------
+
+cMenuFolder::cMenuFolder(const char *Title, cNestedItemList *NestedItemList, const char *Path)
+:cOsdMenu(Title)
+{
+ list = nestedItemList = NestedItemList;
+ firstFolder = NULL;
+ editing = false;
+ Set();
+ SetHelpKeys();
+ DescendPath(Path);
+}
+
+cMenuFolder::cMenuFolder(const char *Title, cList<cNestedItem> *List, cNestedItemList *NestedItemList, const char *Dir, const char *Path)
+:cOsdMenu(Title)
+{
+ list = List;
+ nestedItemList = NestedItemList;
+ dir = Dir;
+ firstFolder = NULL;
+ editing = false;
+ Set();
+ SetHelpKeys();
+ DescendPath(Path);
+}
+
+void cMenuFolder::SetHelpKeys(void)
+{
+ SetHelp(firstFolder ? tr("Button$Select") : NULL, tr("Button$New"), firstFolder ? tr("Button$Delete") : NULL, firstFolder ? tr("Button$Edit") : NULL);
+}
+
+void cMenuFolder::Set(const char *CurrentFolder)
+{
+ firstFolder = NULL;
+ Clear();
+ if (!isempty(dir)) {
+ cOsdItem *DirItem = new cOsdItem(dir);
+ DirItem->SetSelectable(false);
+ Add(DirItem);
+ }
+ list->Sort();
+ for (cNestedItem *Folder = list->First(); Folder; Folder = list->Next(Folder)) {
+ cOsdItem *FolderItem = new cMenuFolderItem(Folder);
+ Add(FolderItem, CurrentFolder ? strcmp(Folder->Text(), CurrentFolder) == 0 : false);
+ if (!firstFolder)
+ firstFolder = FolderItem;
+ }
+}
+
+void cMenuFolder::DescendPath(const char *Path)
+{
+ if (Path) {
+ const char *p = strchr(Path, FOLDERDELIMCHAR);
+ if (p) {
+ for (cMenuFolderItem *Folder = (cMenuFolderItem *)firstFolder; Folder; Folder = (cMenuFolderItem *)Next(Folder)) {
+ if (strncmp(Folder->Folder()->Text(), Path, p - Path) == 0) {
+ SetCurrent(Folder);
+ if (Folder->Folder()->SubItems())
+ AddSubMenu(new cMenuFolder(Title(), Folder->Folder()->SubItems(), nestedItemList, !isempty(dir) ? *cString::sprintf("%s%c%s", *dir, FOLDERDELIMCHAR, Folder->Folder()->Text()) : Folder->Folder()->Text(), p + 1));
+ break;
+ }
+ }
+ }
+ }
+}
+
+eOSState cMenuFolder::Select(void)
+{
+ if (firstFolder) {
+ cMenuFolderItem *Folder = (cMenuFolderItem *)Get(Current());
+ if (Folder) {
+ if (Folder->Folder()->SubItems())
+ return AddSubMenu(new cMenuFolder(Title(), Folder->Folder()->SubItems(), nestedItemList, !isempty(dir) ? *cString::sprintf("%s%c%s", *dir, FOLDERDELIMCHAR, Folder->Folder()->Text()) : Folder->Folder()->Text()));
+ else
+ return osEnd;
+ }
+ }
+ return osContinue;
+}
+
+eOSState cMenuFolder::New(void)
+{
+ editing = true;
+ return AddSubMenu(new cMenuEditFolder(dir, list));
+}
+
+eOSState cMenuFolder::Delete(void)
+{
+ if (!HasSubMenu() && firstFolder) {
+ cMenuFolderItem *Folder = (cMenuFolderItem *)Get(Current());
+ if (Folder && Interface->Confirm(Folder->Folder()->SubItems() ? tr("Delete folder and all sub folders?") : tr("Delete folder?"))) {
+ list->Del(Folder->Folder());
+ Del(Folder->Index());
+ firstFolder = Get(isempty(dir) ? 0 : 1);
+ Display();
+ SetHelpKeys();
+ nestedItemList->Save();
+ }
+ }
+ return osContinue;
+}
+
+eOSState cMenuFolder::Edit(void)
+{
+ if (!HasSubMenu() && firstFolder) {
+ cMenuFolderItem *Folder = (cMenuFolderItem *)Get(Current());
+ if (Folder) {
+ editing = true;
+ return AddSubMenu(new cMenuEditFolder(dir, list, Folder->Folder()));
+ }
+ }
+ return osContinue;
+}
+
+eOSState cMenuFolder::SetFolder(void)
+{
+ cMenuEditFolder *mef = (cMenuEditFolder *)SubMenu();
+ if (mef) {
+ Set(mef->GetFolder());
+ SetHelpKeys();
+ Display();
+ nestedItemList->Save();
+ }
+ return CloseSubMenu();
+}
+
+cString cMenuFolder::GetFolder(void)
+{
+ if (firstFolder) {
+ cMenuFolderItem *Folder = (cMenuFolderItem *)Get(Current());
+ if (Folder) {
+ cMenuFolder *mf = (cMenuFolder *)SubMenu();
+ if (mf)
+ return cString::sprintf("%s%c%s", Folder->Folder()->Text(), FOLDERDELIMCHAR, *mf->GetFolder());
+ return Folder->Folder()->Text();
+ }
+ }
+ return "";
+}
+
+eOSState cMenuFolder::ProcessKey(eKeys Key)
+{
+ if (!HasSubMenu())
+ editing = false;
+ eOSState state = cOsdMenu::ProcessKey(Key);
+
+ if (state == osUnknown) {
+ switch (Key) {
+ case kOk:
+ case kRed: return Select();
+ case kGreen: return New();
+ case kYellow: return Delete();
+ case kBlue: return Edit();
+ default: state = osContinue;
+ }
+ }
+ else if (state == osEnd && HasSubMenu() && editing)
+ state = SetFolder();
+ return state;
+}
+
// --- cMenuEditTimer --------------------------------------------------------
cMenuEditTimer::cMenuEditTimer(cTimer *Timer, bool New)
:cOsdMenu(tr("Edit timer"), 12)
{
+ file = NULL;
firstday = NULL;
timer = Timer;
addIfConfirmed = New;
@@ -644,9 +909,10 @@ cMenuEditTimer::cMenuEditTimer(cTimer *Timer, bool New)
Add(new cMenuEditBitItem( tr("VPS"), &data.flags, tfVps));
Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, MAXPRIORITY));
Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, MAXLIFETIME));
- Add(new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file)));
+ Add(file = new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file)));
SetFirstDayItem();
}
+ SetHelpKeys();
Timers.IncBeingEdited();
}
@@ -657,6 +923,11 @@ cMenuEditTimer::~cMenuEditTimer()
Timers.DecBeingEdited();
}
+void cMenuEditTimer::SetHelpKeys(void)
+{
+ SetHelp(tr("Button$Folder"));
+}
+
void cMenuEditTimer::SetFirstDayItem(void)
{
if (!firstday && !data.IsSingleEvent()) {
@@ -670,6 +941,26 @@ void cMenuEditTimer::SetFirstDayItem(void)
}
}
+eOSState cMenuEditTimer::SetFolder(void)
+{
+ cMenuFolder *mf = (cMenuFolder *)SubMenu();
+ if (mf) {
+ cString Folder = mf->GetFolder();
+ char *p = strrchr(data.file, FOLDERDELIMCHAR);
+ if (p)
+ p++;
+ else
+ p = data.file;
+ if (!isempty(*Folder))
+ strn0cpy(data.file, cString::sprintf("%s%c%s", *Folder, FOLDERDELIMCHAR, p), sizeof(data.file));
+ else if (p != data.file)
+ memmove(data.file, p, strlen(p) + 1);
+ SetCurrent(file);
+ Display();
+ }
+ return CloseSubMenu();
+}
+
eOSState cMenuEditTimer::ProcessKey(eKeys Key)
{
eOSState state = cOsdMenu::ProcessKey(Key);
@@ -699,13 +990,15 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key)
}
}
return osBack;
- case kRed:
+ case kRed: return AddSubMenu(new cMenuFolder(tr("Select folder"), &Folders, data.file));
case kGreen:
case kYellow:
case kBlue: return osContinue;
default: break;
}
}
+ else if (state == osEnd && HasSubMenu())
+ state = SetFolder();
if (Key != kNone)
SetFirstDayItem();
return state;
@@ -1921,7 +2214,7 @@ void cMenuRecordings::Set(bool Refresh)
Clear();
Recordings.Sort();
for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
- if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == '~')) {
+ if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == FOLDERDELIMCHAR)) {
cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level);
if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) {
Add(Item);