#! /bin/sh /usr/share/dpatch/dpatch-run ## 03_cmdsubmenu.dpatch by Albu at vdrportal.de ## http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.7-1.5.15.diff ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Adds submenus within the commands and recording commands menu. ## DP: To create a submenu entry, prefix the name by one ore more "-". @DPATCH@ diff -urNad vdr-1.5.15~/README.cmdsubmenu vdr-1.5.15/README.cmdsubmenu --- vdr-1.5.15~/README.cmdsubmenu 1970-01-01 01:00:00.000000000 +0100 +++ vdr-1.5.15/README.cmdsubmenu 2008-02-17 21:01:18.000000000 +0100 @@ -0,0 +1,58 @@ +CmdSubmenu patch for VDR +------------------------ + +With this patch the commands and recording commands menus can be organised +hierarchically. To create a submenu entry, prefix the name by one ore more "-". + + +Standard: + +description_1 : cmd_1 +description_2 : cmd_2 + + +A submenu with two entries: + +Submenu title ... : echo "submenu" +-description_1 : cmd_1 +-description_2 : cmd_2 + +The dummy command in the title row is necessary. + + +* History + + 2003-10-08: Version 0.1 - Albu at vdrportal.de + http://vdrportal.de/board/thread.php?threadid=6319 + + 2003-10-09: Version 0.2 - Tobias Grimm + - Added Define CMD_SUBMENUS in Makefile + + 2004-05-28: Version 0.3 - Thomas Günther + - Fixed compilation with gcc-3.3.3 + - Added new virtual method AddConfig in cConfig + - Redefining of method Add in cListBase to virtual no longer necessary + - Improved code in menu.c + http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.3.diff + + 2004-12-20: Version 0.4 - Thomas Günther + - Solved conflict with jumpplay patch 0.6 + http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.4.diff + + 2006-04-22: Version 0.5 - Thomas Günther + - Added version define CMDSUBMENUVERSNUM + - Reformated to VDR style indentions + - Added description in README.cmdsubmenu + http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.5-1.3.47.diff + + 2006-04-23: Version 0.6 - Thomas Günther + - Fixed menus with more than one level + http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.6-1.3.47.diff + + 2006-05-15: Version 0.7 - Thomas Günther + - Fixed build with G++ 4.1 (extra qualification) + http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.7-1.4.0.diff + + 2007-02-17: - Tobias Grimm + - Adapted to vdr-1.5.15 + http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.7-1.5.15.diff diff -urNad vdr-1.5.15~/config.c vdr-1.5.15/config.c --- vdr-1.5.15~/config.c 2008-02-17 14:39:00.000000000 +0100 +++ vdr-1.5.15/config.c 2008-02-17 21:03:48.000000000 +0100 @@ -28,18 +28,26 @@ { title = command = NULL; confirm = false; + nIndent = 0; + childs = NULL; } cCommand::~cCommand() { free(title); free(command); + delete childs; } bool cCommand::Parse(const char *s) { const char *p = strchr(s, ':'); if (p) { + nIndent = 0; + while (*s == '-') { + nIndent++; + s++; + } int l = p - s; if (l > 0) { title = MALLOC(char, l + 1); @@ -85,6 +93,18 @@ return result; } +int cCommand::getChildCount(void) +{ + return childs ? childs->Count() : 0; +} + +void cCommand::addChild(cCommand *newChild) +{ + if (!childs) + childs = new cCommands(); + childs->AddConfig(newChild); +} + // --- cSVDRPhost ------------------------------------------------------------ cSVDRPhost::cSVDRPhost(void) @@ -126,6 +146,21 @@ cCommands Commands; cCommands RecordingCommands; +void cCommands::AddConfig(cCommand *Object) +{ + if (!Object) + return; + //isyslog ("Indent %d %s\n", Object->getIndent(), Object->Title()); + for (int index = Count() - 1; index >= 0; index--) { + cCommand *parent = Get(index); + if (parent->getIndent() < Object->getIndent()) { + parent->addChild(Object); + return; + } + } + cConfig::Add(Object); +} + // --- cSVDRPhosts ----------------------------------------------------------- cSVDRPhosts SVDRPhosts; diff -urNad vdr-1.5.15~/config.h vdr-1.5.15/config.h --- vdr-1.5.15~/config.h 2008-02-05 16:35:11.000000000 +0100 +++ vdr-1.5.15/config.h 2008-02-17 21:01:18.000000000 +0100 @@ -36,6 +36,8 @@ // plugins to work with newer versions of the core VDR as long as no // VDR header files have changed. +#define CMDSUBMENUVERSNUM 7 + #define MAXPRIORITY 99 #define MAXLIFETIME 99 @@ -48,11 +50,15 @@ #define MaxSkinName 16 #define MaxThemeName 16 +class cCommands; + class cCommand : public cListObject { private: char *title; char *command; bool confirm; + int nIndent; + cCommands *childs; static char *result; public: cCommand(void); @@ -61,6 +67,12 @@ const char *Title(void) { return title; } bool Confirm(void) { return confirm; } const char *Execute(const char *Parameters = NULL); + int getIndent(void) { return nIndent; } + void setIndent(int nNewIndent) { nIndent = nNewIndent; } + cCommands *getChilds(void) { return childs; } + int getChildCount(void); + bool hasChilds(void) { return getChildCount() > 0; } + void addChild(cCommand *newChild); }; typedef uint32_t in_addr_t; //XXX from /usr/include/netinet/in.h (apparently this is not defined on systems with glibc < 2.2) @@ -88,6 +100,7 @@ public: cConfig(void) { fileName = NULL; } virtual ~cConfig() { free(fileName); } + virtual void AddConfig(T *Object) { cList::Add(Object); } const char *FileName(void) { return fileName; } bool Load(const char *FileName = NULL, bool AllowComments = false, bool MustExist = false) { @@ -117,7 +130,7 @@ if (!isempty(s)) { T *l = new T; if (l->Parse(s)) - Add(l); + AddConfig(l); else { esyslog("ERROR: error in %s, line %d", fileName, line); delete l; @@ -159,7 +172,10 @@ } }; -class cCommands : public cConfig {}; +class cCommands : public cConfig { +public: + virtual void AddConfig(cCommand *Object); + }; class cSVDRPhosts : public cConfig { public: diff -urNad vdr-1.5.15~/menu.c vdr-1.5.15/menu.c --- vdr-1.5.15~/menu.c 2008-02-16 14:53:26.000000000 +0100 +++ vdr-1.5.15/menu.c 2008-02-17 21:04:33.000000000 +0100 @@ -1579,6 +1579,10 @@ cCommand *command = commands->Get(Current()); if (command) { bool confirmed = true; + if (command->hasChilds()) { + AddSubMenu(new cMenuCommands(command->Title(), command->getChilds(), parameters)); + return osContinue; + } if (command->Confirm()) confirmed = Interface->Confirm(cString::sprintf("%s?", command->Title())); if (confirmed) {