/**************************************************************************** * DESCRIPTION: * Configuration Menus * * $Id: menus.cpp,v 1.15 2006/03/05 09:47:25 ralf Exp $ * * Contact: ranga@vdrtools.de * * Copyright (C) 2004 by Ralf Dotzert ****************************************************************************/ #include #include #include #include #include #include #include #include #include "menus.h" #include "config.h" #include "sysconfig.h" #include "debug.h" #define VALUETEXTMAXLEN 100 #define VALUEIPMAXLEN 16 // ################################################################################### // MenuNode // ################################################################################### /** * Constructor of Object * */ MenuNode::MenuNode( ) { _menu = NULL; _menuEntry = NULL; _objType = MenuNode::UNDEFINED; } /** * Destructor of Object * */ MenuNode::~ MenuNode( ) { destroy(); } /** * Destroy Object */ void MenuNode::destroy( ) { delete _menu; delete _menuEntry; _objType = MenuNode::UNDEFINED; _menu = NULL; _menuEntry = NULL; } /** * * @param menu */ void MenuNode::SetNode( Menu * menu ) { _menu = menu; if( menu->GetSystem() != NULL ) _objType = MENUSYSTEM; else _objType = MENU; } /** * * @param menuEntry */ void MenuNode::SetNode( MenuEntry * menuEntry ) { _menuEntry = menuEntry; _objType = ENTRY; } /** * * @return */ MenuNode::Type MenuNode::GetType( ) { return(_objType); } /** * * @return */ Menu * MenuNode::GetMenu( ) { if( _objType == MENU || _objType == MENUSYSTEM) return(_menu); else return(NULL); } /** * * @return */ MenuEntry * MenuNode::GetMenuEntry( ) { if( _objType == ENTRY) return(_menuEntry); else return(NULL); } int MenuNode::GetNr( ) { if( _objType == MENU) return(_menu->GetNr()); else return(_menuEntry->GetNr()); } MenuNode * MenuNode::GetNode( int index ) { if( _objType == MENU) return(_menu->GetNode(index)); else return(_menuEntry->GetNode(index)); } /** * * @return */ const char * MenuNode::GetName( ) { const char* result = NULL; if( _menu != NULL) result= _menu->GetName(); else if( _menuEntry != NULL) result= _menuEntry->GetName(); return(result); } /** * */ void MenuNode::Print( int offset) { if( _objType == MenuNode::MENU) { _menu->Print(offset); } else if( _objType == MenuNode::ENTRY) { _menuEntry->Print(offset); } } /** * */ void MenuNode::Print() { Print(0); } void MenuNode::SetSysConfig( Sysconfig *sysconf ) { if( _objType == ENTRY) { _menuEntry->SetSysConfig(sysconf); } else _menu->SetSysConfig(sysconf); } // ################################################################################### // Menu // ################################################################################### /** * * @return */ Menu::Menu() { _name = NULL; _command = NULL; _help = NULL; _help2 = NULL; _system = NULL; } /** * * @param name * @return */ Menu::Menu(const char * name ) { _name = NULL; _command = NULL; _help = NULL; _help2 = NULL; _system = NULL; SetName(name); } /** * * @return */ Menu::~ Menu( ) { destroy(); } /** * Destroy Object */ void Menu::destroy( ) { delete [] _name; delete [] _command; delete [] _help; delete [] _help2; delete [] _system; _name = NULL; _command = NULL; _system = NULL; _help = NULL; _help2 = NULL; } /** * set name of menu * @param nam specifies the name of the menu */ void Menu::SetName( const char * nam ) { delete [] _name; _name=Util::Strdupnew(nam); } /** * return Menu Name * @return name of menu */ const char * Menu::GetName( ) { return(_name); } /** * return Menu Comand * @return command of menu */ const char * Menu::GetCommand( ) { return(_command); } /** * set command of menu * @param command specifies the command of the menu */ void Menu::SetCommand( const char * command ) { delete [] _command; _command=Util::Strdupnew(command); } /** * return Menu System * @return system command of menu */ const char * Menu::GetSystem( ) { return(_system); } /** * set system command of menu * @param system specifies the system command of the menu */ void Menu::SetSystem( const char * system ) { delete [] _system; _system=Util::Strdupnew(system); } /** * Add the given node to the Node List * @param menu pointer to allocate Menu Object */ void Menu::AddNode( Menu * menu ) { MenuNode *n = new MenuNode; n->SetNode(menu); _subMenus.Add(n); } /** * Add the given node to the Node List * @param menuEntry pointer to allocate MenuEntry Object */ void Menu::AddNode( MenuEntry * menuEntry ) { MenuNode *n = new MenuNode; n->SetNode(menuEntry); _subMenus.Add(n); } /** * Load XMl subtrre * @param xmlNode current XMl Node to Parse * @return true on success */ bool Menu::LoadXml( TiXmlNode * xmlNode ) { bool ok = true; TiXmlElement *elem = NULL; if(xmlNode != NULL && xmlNode->Type() == TiXmlNode::ELEMENT) { do { if(xmlNode->Type() == TiXmlNode::ELEMENT) { elem = xmlNode->ToElement (); if( strcmp(xmlNode->Value(), "menu")== 0) { const char* name = elem->Attribute("name"); const char* command = elem->Attribute("command"); const char* system = elem->Attribute("system"); const char* help1 = elem->Attribute("help1"); const char* help2 = elem->Attribute("help2"); if( name != NULL ) { Menu * m = new Menu(name); if( m!= NULL && (ok=m->LoadXml(xmlNode->FirstChild()))== true ) { m->SetCommand(command); m->SetHelp1(help1); m->SetHelp2(help2); m->SetSystem(system); AddNode(m); } else delete m; } else ok = false; } else if( strcmp(xmlNode->Value(), "entry")== 0) { const char* command = elem->Attribute("command"); const char* help1 = elem->Attribute("help1"); const char* help2 = elem->Attribute("help2"); MenuEntry * e = new MenuEntry(); if( e != NULL && (ok=e->AddEntry(xmlNode))== true ) { e->SetCommand(command); e->SetHelp1(help1); e->SetHelp2(help2); AddNode(e); } else delete e; } } }while( (xmlNode=xmlNode->NextSibling())!=NULL && ok == true); } return(ok); } /** * Save Menu to XML Structure * @param xml xml structure * @return true on success */ TiXmlNode *Menu::SaveXml() { bool ok = true; TiXmlElement *m = new TiXmlElement("menu"); TiXmlNode *tmp = NULL; m->SetAttribute("name", GetName()); if( GetCommand()!= NULL) m->SetAttribute("command", GetCommand()); if( GetHelp1() != NULL) m->SetAttribute("help1", GetHelp1()); if( GetHelp2() != NULL) m->SetAttribute("help2", GetHelp2()); if( GetSystem()!= NULL) m->SetAttribute("system", GetSystem()); for (MenuNode *subMenu = _subMenus.First(); subMenu; subMenu = _subMenus.Next(subMenu)) { if(subMenu->GetType() == MenuNode::MENU || subMenu->GetType() == MenuNode::MENUSYSTEM) { tmp=subMenu->GetMenu()->SaveXml(); } else if(subMenu->GetType() == MenuNode::ENTRY) { tmp=subMenu->GetMenuEntry()->SaveXml(); } if( tmp != NULL) m->LinkEndChild(tmp); else ok=false; } if( ok=false) { delete m; m = NULL; } return(m); } /** * return Help for Menu/Entry * @return help of menu/entry */ const char * Menu::GetHelp1( ) { return(_help); } /** * set help for menu/entry * @param command specifies the help for the menu/entry */ void Menu::SetHelp1( const char * help ) { delete [] _help; _help=Util::Strdupnew(help); } /** * return Detailed Help for Menu/Entry * @return help of menu/entry */ const char * Menu::GetHelp2( ) { return(_help2); } /** * set detailed help for menu/entry * @param command specifies the help for the menu/entry */ void Menu::SetHelp2( const char * help ) { delete [] _help2; _help2=Util::Strdupnew(help); } int Menu::GetNr( ) { return(_subMenus.Count()); } /** * * @param index * @return */ MenuNode * Menu::GetNode( int index ) { return(_subMenus.Get(index)); } void Menu::SetSysConfig( Sysconfig *sysconf ) { for (MenuNode *subMenu = _subMenus.First(); subMenu; subMenu = _subMenus.Next(subMenu)) { subMenu->SetSysConfig(sysconf ); } } /** * */ void Menu::Print( int offset) { for(int i=0; iPrint(offset+4); } } /** * */ void Menu::Print() { Print(0); } // ################################################################################### // MenuEntry // ################################################################################### /** * * @return */ MenuEntry::MenuEntry( ) { _sysconfigName = NULL; _valueText = NULL; _valueIp = NULL; _valueTextMaxLen = 0; _valueIpMaxLen = 0; _valueNumber = 0; _valueBool = 0; _setupCommand = NULL; _type = Util::UNDEFINED; _command = NULL; _help = NULL; _help2 = NULL; _system = NULL; } /** * * @return */ MenuEntry::~ MenuEntry( ) { destroy(); } /** * Destroy Object */ void MenuEntry::destroy( ) { delete [] _sysconfigName; delete [] _valueText; delete [] _valueIp; delete [] _setupCommand; delete [] _help; delete [] _help2; _sysconfigName = NULL; _valueText = NULL; _valueIp = NULL; _setupCommand = NULL; _help = NULL; _help2 = NULL; } /** * set the corrspondig name in the sysconfig file * @param nam the name used in the sysconfig file */ void MenuEntry::SetSysconfigName( const char * name ) { _sysconfigName = Util::Strdupnew(name); } /** * * @return the name used in the sysconfig file */ const char * MenuEntry::GetSysconfigName( ) { return(_sysconfigName); } /** * * @param typ Set Type */ void MenuEntry::SetType( Util::Type typ ) { _type = typ; } /** * * @return */ Util::Type MenuEntry::GetType( ) { return(_type); } /** * Set the Value * @param val */ void MenuEntry::SetValue(Util::Type type,const char * val ) { _type = type; switch(_type) { case Util::BOOL: Util::isBool(val, _valueBool); break; case Util::TEXT: _valueText = Util::Strdupnew(val, VALUETEXTMAXLEN); _valueTextMaxLen = VALUETEXTMAXLEN; break; case Util::IP: _valueIp = Util::Strdupnew(val, VALUEIPMAXLEN); _valueIpMaxLen = VALUEIPMAXLEN; break; case Util::NUMBER_TEXT: _valueText = Util::Strdupnew(val, VALUETEXTMAXLEN); _valueTextMaxLen = VALUETEXTMAXLEN; break; case Util::HEX: _valueText = Util::Strdupnew(val, VALUETEXTMAXLEN); _valueTextMaxLen = VALUETEXTMAXLEN; break; case Util::NUMBER: Util::isNumber(val, _valueNumber); break; case Util::SELECTION: _valueText = Util::Strdupnew(val, VALUETEXTMAXLEN); _valueTextMaxLen = VALUETEXTMAXLEN; break; case Util::UNDEFINED: break; } } const char * MenuEntry::GetSelectedValue( ) { return(_selectionValues.GetSelectedValue()); } const char * MenuEntry::GetSelectionValue( int index ) { return(_selectionValues.GetValue(index)); } int MenuEntry::GetNrOfSelectionValues( ) { return(_selectionValues.GetNr()); } const char ** MenuEntry::GetSelectionValues( ) { return(_selectionValues.GetValues()); } void MenuEntry::SetSelection( const char * val) { _selectionValues.SetSelection(val); } void MenuEntry::SetSetupCommand( const char * command ) { _setupCommand = Util::Strdupnew(command); } const char * MenuEntry::GetSetupCommand( ) { return(_setupCommand); } /** * Return the Value * @return */ const char * MenuEntry::GetValue( ) { return(_valueText); } int MenuEntry::GetValueTextMaxLen( ) { return(_valueTextMaxLen); } /** * * @return */ const char * MenuEntry::GetValueAsString( ) { const char * result=NULL; static char numberStr[20]; switch(_type) { case Util::BOOL: result = Util::boolToStr(_valueBool); break; case Util::NUMBER_TEXT: case Util::HEX: case Util::TEXT: result =_valueText; break; case Util::IP: result = _valueIp; break; case Util::NUMBER: sprintf(numberStr,"%d", _valueNumber); result = (const char*) numberStr; break; case Util::SELECTION: result=_selectionValues.GetSelectedValue(); break; default: result=Util::typeToStr(_type); break; } return(result); } /** * * @return */ int * MenuEntry::GetValueBoolRef( ) { return(&_valueBool); } /** * * @return */ int * MenuEntry::GetValueNumberRef( ) { return(&_valueNumber); } /** * * @param node * @param selection * @return */ bool MenuEntry::AddSelectionValues( TiXmlNode * node, const char*selection ) { bool ok = true; if( _setupCommand != NULL && strcmp(_setupCommand, "childlock")!=0 ) { ok = ExecSetupCommand(); _selectionValues.SetSelection(selection); } else if( node != NULL && node->Type() == TiXmlNode::ELEMENT) { do { _selectionValues.Add(node->FirstChild()->Value()); }while( (node=node->NextSibling("value"))!= NULL && ok==true); _selectionValues.SetSelection(selection); } return(ok); } /** * * @return */ bool MenuEntry::ExecSetupCommand() { bool ok = true; char *command; const char * line; char fname[] = "/tmp/setup.values"; int err; asprintf (&command, "%s >%s", _setupCommand, fname); if (err=system(command)) { DEBUG4("%s: Could not execute: %s, errno=%d\n", DBG_PREFIX, _setupCommand, err); ok = false; } else { FILE * fp = fopen(fname, "r"); if( fp != NULL) { while( (line = readLine(fp)) != NULL) { _selectionValues.Add(line); delete [] line; } fclose(fp); } else { DEBUG4("%s: Could not read file: %s, errno=%d\n", DBG_PREFIX, fname, errno); ok = false; } } return(ok); } int * MenuEntry::GetReferenceSelection( ) { return(_selectionValues.GetReferenceSelection()); } /** * Add SubEntry to * @param node XML poiter to subtree * @return ok on success */ bool MenuEntry::AddEntry( TiXmlNode *node ) { bool ok = true; TiXmlElement *elem = NULL; if(node != NULL && node->Type() == TiXmlNode::ELEMENT) { elem = node->ToElement (); const char* nam = elem->Attribute("name"); const char* sysconf = elem->Attribute("sysconfig"); const char* typStr = elem->Attribute("type"); const char* val = elem->Attribute("value"); const char* setup = elem->Attribute("setup"); Util::Type typ = Util::UNDEFINED; if( nam != NULL && sysconf!= NULL && typStr != NULL && val != NULL && Util::isType(typStr, typ)) { if( Sysconfig::GetVariable(sysconf) != NULL) val=Sysconfig::GetVariable(sysconf); SetName(nam); SetSysconfigName(sysconf); SetValue(typ, val); SetSetupCommand(setup); //CHILDLOCK if( setup != NULL && strcmp(setup, "childlock")== 0) Config::SetChildLock(GetValue()); ok = AddSelectionValues(node->FirstChild("value"), val); if(ok == true && _type == Util::SELECTION) // Set Selection { SetSelection (val); } } else { DEBUG4("%s Error in XML File, Column=%d Row%d\n", DBG_PREFIX, node->Column (), node->Row()); ok = false; } } return(ok); } /** * Convert ENtry in XML Structure * @return xml E�lement or NULL if error */ TiXmlNode *MenuEntry::SaveXml( ) { TiXmlElement *e = new TiXmlElement("entry"); if( e != NULL ) { e->SetAttribute("name", GetName()); e->SetAttribute("sysconfig", GetSysconfigName()); e->SetAttribute("type", Util::typeToStr(_type)); if( _setupCommand != NULL ) e->SetAttribute("setup", _setupCommand); if( _type == Util::SELECTION) { if( _setupCommand != NULL ) { if(strcmp(_setupCommand, "channellist")==0) Util::SwitchChannelList(GetSelectedValue()); } else { for(int i=0; i< GetNrOfSelectionValues(); i++) { TiXmlElement *e1 = new TiXmlElement("value"); e1->LinkEndChild( new TiXmlText (GetSelectionValue(i))); e->LinkEndChild(e1); } } e->SetAttribute("value", GetSelectedValue()); } else e->SetAttribute("value", GetValueAsString()); if( GetCommand()!= NULL) e->SetAttribute("command", GetCommand()); if( GetHelp1()!= NULL) e->SetAttribute("help1", GetHelp1()); if( GetHelp2()!= NULL) e->SetAttribute("help2", GetHelp2()); } for (MenuNode *subMenu = _subMenus.First(); subMenu; subMenu = _subMenus.Next(subMenu)) { e->LinkEndChild(subMenu->GetMenuEntry()->SaveXml()); } return(e); } void MenuEntry::SetSysConfig( Sysconfig *sysconf ) { sysconf->SetVariable(GetSysconfigName(), GetValueAsString()); for (MenuNode *subMenu = _subMenus.First(); subMenu; subMenu = _subMenus.Next(subMenu)) { subMenu->SetSysConfig(sysconf ); } } /** * */ void MenuEntry::Print( int offset) { for(int i=0; iPrint(offset+4); } } /** * */ void MenuEntry::Print() { Print(0); } /** * read one line from opened file * @param fp opened filepointer * @return null if EOF or allocated character String holding one line */ const char * MenuEntry::readLine( FILE * fp ) { char myChar; char buf[1024]; int i=0; int maxLen = (int) sizeof(buf)-1; char *line=NULL; while((myChar=fgetc(fp)) != EOF ) { if(myChar=='\n' || i==maxLen) { line = new char[i+1]; strncpy(line, buf, i); line[i]='\0'; return(line); } else buf[i++]=myChar; } return((const char*)line); } // ################################################################################### // Menus // ################################################################################### /** * Constructor of Object * */ Menus::Menus() { } /** * Destructor of Object * */ Menus::~Menus() { } /** * return the numer of menus * @return */ int Menus::GetNr( ) { return(Count()); } /** * Load XML representation * @param node current node in XML Tree * @return true on success */ bool Menus::LoadXml( TiXmlNode * node ) { bool ok = true; TiXmlElement *elem = NULL; if(node != NULL && node->Type() == TiXmlNode::ELEMENT && (node=node->FirstChild())!=NULL) { do { if(node->Type() == TiXmlNode::ELEMENT && strcmp(node->Value(), "menu")== 0) { elem = node->ToElement (); const char* name = elem->Attribute("name"); const char* command = elem->Attribute("command"); const char* system = elem->Attribute("system"); const char* help1 = elem->Attribute("help1"); const char* help2 = elem->Attribute("help2"); if( name != NULL ) { Menu * m = new Menu(name); m->SetCommand(command); m->SetSystem(system); m->SetHelp1(help1); m->SetHelp2(help2); if( m!= NULL && (ok=m->LoadXml(node->FirstChild()))== true ) ok=AddNode(m); else delete m; } else { ok = false; } } }while( (node=node->NextSibling())!=NULL && ok == true); } else ok = false; return(ok); } /** * Save Menues to XML Structure * @param xml XML structure * @return true on success */ bool Menus::SaveXml(TiXmlNode * root) { bool ok = true; TiXmlNode *tmp = NULL; TiXmlElement *m = new TiXmlElement("menus"); // Root element of menus for(int i=0; iGetMenu()->SaveXml()) != NULL) { m->LinkEndChild(tmp); } else ok=false; } root->LinkEndChild(m); return(ok); } /** * Add a Menu Node * @param name name of Menu * @param xmlNode current XML Node * @return true on success */ bool Menus::AddNode( Menu *menu ) { bool ok = true; MenuNode *n = new MenuNode; Add(n); n->SetNode(menu); return(ok); } /** * Return refernce to specified Menu * @param index of menu * @return pointer to menu */ MenuNode *Menus::GetMenuNode(int index) { return(Get(index)); } /** * Print Nodes */ void Menus::Print( ) { for( int i=0; iPrint(); } // ################################################################################### // MenuEntryValueList // ################################################################################### MenuEntryValueList::MenuEntryValueList( ) { _values = NULL; _nr = 0; _selection =0; } MenuEntryValueList::~ MenuEntryValueList( ) { destroy(); } void MenuEntryValueList::copy( MenuEntryValueList const & other ) { for(int i=0; i0) { for(int i=0; i<_nr; i++) { for(int j=0; j 0 && index <_nr && index >=0) { result=_values[index]; } return(result); } const char ** MenuEntryValueList::GetValues( ) { return(_values); } int * MenuEntryValueList::GetReferenceSelection( ) { return(&_selection); } void MenuEntryValueList::SetSelection( const char * value ) { bool found =false; _selection = 0; for(int i=0; i<_nr && found==false; i++) { if( strcmp(_values[i], value)== 0) { _selection =i; found=true; } } } const char * MenuEntryValueList::GetSelectedValue( ) { if(_nr == 0) return(NULL); else { return(_values[_selection]); } }