summaryrefslogtreecommitdiff
path: root/vdr_menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'vdr_menu.c')
-rw-r--r--vdr_menu.c1390
1 files changed, 543 insertions, 847 deletions
diff --git a/vdr_menu.c b/vdr_menu.c
index fbc7794..e64688f 100644
--- a/vdr_menu.c
+++ b/vdr_menu.c
@@ -1,10 +1,9 @@
-/*!
+/*!
* \file vdr_menu.c
* \brief Implements menu handling for browsing media libraries within VDR
*
- * \version $Revision: 1.27 $
- * \date $Date$
- * \author Ralf Klueber, Lars von Wedel, Andreas Kellner
+ * \version $Revision: 1.27 $ * \date $Date$
+ * \author Ralf Klueber, Lars von Wedel, Andreas Kellner, Wolfgang Rohdewald
* \author Responsible author: $Author$
*
* $Id$
@@ -14,10 +13,6 @@
#include <string>
#include <vector>
-// #include <cstring>
-
-#include <mysql/mysql.h>
-
#include <menuitems.h>
#include <tools.h>
#include <config.h>
@@ -28,965 +23,666 @@
#include <vdr/skins.h>
#endif
-#include "muggle.h"
+#include "vdr_setup.h"
#include "vdr_menu.h"
#include "vdr_player.h"
#include "i18n.h"
-#include "mg_content_interface.h"
-#include "mg_playlist.h"
#define DEBUG
#include "mg_tools.h"
-#include "mg_media.h"
-#include "mg_filters.h"
-#include "gd_content_interface.h"
-
-// ----------------------- mgMenuTreeItem ------------------
+#include <config.h>
+#if VDRVERSNUM >= 10307
+#include <vdr/interface.h>
+#include <vdr/skins.h>
+#endif
-mgMenuTreeItem::mgMenuTreeItem( mgSelectionTreeNode *node )
- : m_node( node )
+void
+mgStatus::OsdCurrentItem(const char* Text)
{
- Set();
+ cOsdItem* i = main->Get(main->Current());
+ if (!i) return;
+ if (i == IgnoreNextEventOn)
+ {
+ IgnoreNextEventOn = NULL;
+ return;
+ }
+ mgAction * a = dynamic_cast<mgAction *>(i);
+ if (!a)
+ mgError("mgStatus::OsdCurrentItem expected an mgAction*");
+ a->Notify();
+}
+
+void Play(mgSelection *sel,const bool select) {
+ mgSelection *s = new mgSelection(sel);
+ if (select) s->select();
+ if (s->empty())
+ {
+ delete s;
+ return;
+ }
+ mgPlayerControl *c = PlayerControl ();
+ if (c)
+ c->NewPlaylist (s);
+ else
+ cControl::Launch (new mgPlayerControl (s));
}
-mgSelectionTreeNode* mgMenuTreeItem::Node()
+
+//! \brief queue the selection for playing, abort ongoing instant play
+void
+mgMainMenu::PlayQueue()
{
- return m_node;
+ queue_playing=true;
+ instant_playing=false;
+ Play(playselection());
}
-void mgMenuTreeItem::Set()
+//! \brief queue the selection for playing, abort ongoing queue playing
+void
+mgMainMenu::PlayInstant(const bool select)
{
- char *buffer = 0;
- asprintf( &buffer, m_node->getLabel().c_str() );
- SetText( buffer, false );
+ instant_playing=true;
+ Play(selection(),select);
}
-// ----------------------- mgMainMenu ----------------------
-mgMainMenu::mgMainMenu(mgMedia *media, mgSelectionTreeNode *root,
- mgPlaylist *playlist, cCommands *playlist_commands)
- : cOsdMenu( "" ), m_media(media), m_root(root),
- m_current_playlist(playlist), m_playlist_commands(playlist_commands)
+bool
+mgMainMenu::ShowingCollections()
{
- mgDebug( 1, "Creating Muggle Main Menu" );
-
- SetTitle( tr("Muggle Media Database") );
- SetButtons();
+ return (UsingCollection && selection ()->level () == 0);
+}
- DisplayTree( m_root );
- strncpy( m_listname, playlist->getListname().c_str(), 31 );
- m_listname[31] = '\0';
- m_editing_listname = false;
+bool
+mgMainMenu::DefaultCollectionSelected()
+{
+ string this_sel = trim(selection ()->getCurrentValue());
+ return (ShowingCollections () && this_sel == default_collection);
}
-mgSelectionTreeNode *mgMainMenu::CurrentNode()
+
+bool
+mgMainMenu::DefaultCollectionEntered()
{
- mgMenuTreeItem *item = (mgMenuTreeItem *)Get( Current() );
- return item? item->Node(): 0;
+ if (!UsingCollection) return false;
+ if (selection()->level()==0) return false;
+ string collection = trim(selection ()->getKeyValue(0));
+ return (collection == default_collection);
}
-mgMenuTreeItem *mgMainMenu::CurrentItem()
-{
- mgMenuTreeItem *item = (mgMenuTreeItem *)Get( Current() );
- return item;
+mgMenu *
+mgMainMenu::Parent ()
+{
+ if (Menus.size () < 2)
+ return NULL;
+ return Menus[Menus.size () - 2];
}
-void mgMainMenu::SetButtons( )
+
+mgOsdItem*
+mgMenu::GenerateAction(const mgActions action)
{
- SetHasHotkeys();
+ mgOsdItem *result = actGenerate(action);
+ if (result)
+ {
+ result->SetMenu(this);
+ if (!result->Enabled())
+ {
+ delete result;
+ result=NULL;
+ }
+ }
+ return result;
+}
- if( m_state == TREE )
- {
- SetHelp( tr("Add"), tr("Cycle tree"), tr("Playlist"), tr("Submenu") );
- }
- else if( m_state == TREE_SUBMENU )
- {
- SetHelp( tr("Instant Play"), tr("2"), tr("3"), tr("Mainmenu") );
- }
- else if( m_state == PLAYLIST )
- {
- SetHelp( tr("Play"), tr("Move"), tr("Filter"), tr("Submenu") );
- }
- else if( m_state == PLAYLIST_SUBMENU )
- {
- SetHelp( tr("Load"), tr("Save"), tr("Delete"), tr("Mainmenu") );
- }
- else if( m_state == FILTER )
+void
+mgMenu::ExecuteAction(const mgActions action)
+{
+ mgAction *a = GenerateAction (action);
+ if (a)
{
- SetHelp( tr("Query"), tr("Other Search"), tr("Browser"), tr("Submenu") );
+ a->Execute ();
+ delete a;
}
- else
- {
- SetHelp( "t", "o", "d", "o" );
- }
}
-void mgMainMenu::Move( int from, int to )
-{
- m_current_playlist->move( from, to );
- cOsdMenu::Move( from, to );
- Display();
+mgPlayerControl *
+PlayerControl ()
+{
+ mgPlayerControl *result = NULL;
+ cControl *control = cControl::Control ();
+ if (control && typeid (*control) == typeid (mgPlayerControl))
+// is there a running MP3 player?
+ result = static_cast < mgPlayerControl * >(control);
+ return result;
}
-eOSState mgMainMenu::ProcessKey(eKeys key)
-{
- MGLOG( "mgMainMenu::ProcessKey" );
- eOSState state = cOsdMenu::ProcessKey(key);
- if( m_state == TREE )
- {
- mgDebug( 1, "mgMainMenu: in state TREE" );
- // Navigate with up/dn, left/right (pgup, pgdn)
- // Expand with OK, Collapse with Back
- if( state == osUnknown )
- {
- switch( key )
- {
- case kOk:
- {
- m_history.push_back( Current() );
- mgSelectionTreeNode *child = CurrentNode();
- DisplayTree( child );
-
- state = osContinue;
- } break;
- case kRed:
- {
- mgSelectionTreeNode *current = CurrentNode();
- if( current )
- {
- mgDebug( 1, "mgMainMenu: add selection %s to playlist", current->getLabel().c_str() );
- // Add selection to Play
- std::vector<mgContentItem*> *tracks = current->getTracks();
-
- if( tracks )
- {
-
- char *buffer = 0;
- asprintf( &buffer, tr("%d tracks sent to current playlist"), (int) tracks->size() );
- m_current_playlist->appendList(tracks);
-#if VDRVERSNUM >= 10307
- Skins.Message(mtInfo,buffer);
- Skins.Flush();
-#else
- Interface->Status( buffer );
- Interface->Flush();
-#endif
- free( buffer );
- }
- else
- {
- mgDebug(1, "No tracks for current selection" );
- }
- }
- else
- {
- mgDebug(1, "Cannot find currently selected node!" );
- }
- state = osContinue;
- } break;
- case kGreen:
- {
- mgDebug( 1, "mgMainMenu: cycle treeviews (todo)" );
-
- state = osContinue;
- } break;
- case kYellow:
- {
- mgDebug( 1, "mgMainMenu: cycle to playlist view" );
-
- DisplayPlaylist();
- } break;
- case kBlue:
- {
- m_last_osd_index = Current();
- m_menu_item = CurrentItem()->Node();
- DisplayTreeSubmenu();
-
- state = osContinue;
- } break;
- default:
- {
- state = osContinue;
- } break;
- }
- }
- else if( state == osBack )
- {
- mgSelectionTreeNode *parent = m_node->getParent();
-
- if( parent )
- {
- mgDebug( 1, "mgMainMenu: collapse current node" );
-
- m_node->collapse();
+mgMenu::mgMenu ()
+{
+ m_osd = NULL;
+ TreeRedAction = mgActions(0);
+ TreeGreenAction = mgActions(0);
+ TreeYellowAction = mgActions(0);
+ CollRedAction = mgActions(0);
+ CollGreenAction = mgActions(0);
+ CollYellowAction = mgActions(0);
+}
- // restore last selected entry
- int last = m_history.back();
- m_history.pop_back();
- DisplayTree( parent, last );
-
- state = osContinue;
- }
- else
- {
- // Back pressed on root level... Go back to Main VDR menu
- state = osBack;
+// ----------------------- mgMainMenu ----------------------
- // state = osContinue;
- }
- }
- }
- else if( m_state == TREE_SUBMENU )
- {
- if( state == osUnknown )
- {
- switch( key )
- {
- case k0 ... k9:
- {
- int n = key - k0;
- TreeSubmenuAction( n );
-
- state = osContinue;
- } break;
- case kRed:
- {
- state = TreeSubmenuAction( 0 );
- } break;
- case kBlue:
- {
- m_state = TREE;
-
- // restore last selected entry
- int last = m_history.back();
- DisplayTree( m_node, last );
-
- state = osContinue;
- } break;
- case kOk:
- {
- state = TreeSubmenuAction( Current() );
- } break;
- default:
- {
- state = osContinue;
- } break;
- }
- }
- else if( state == osBack )
- {
- m_state = TREE;
- // restore last selected entry
- int last = m_history.back();
- DisplayTree( m_node, last );
-
- state = osContinue;
- }
- }
- else if( m_state == PLAYLIST )
- {
- if( state == osUnknown )
- {
- switch( key )
- {
- case kOk:
- {
- // start replay at selected index
- unsigned idx = Current();
- Play( m_current_playlist, idx );
- state = osContinue;
- } break;
- case kRed:
- {
- // TODO: what happens if the user presses play and the player is already active?
- // TODO: resume?
- unsigned resume = mgMuggle::getResumeIndex();
- Play( m_current_playlist, resume );
- state = osEnd;
- } break;
- case kGreen:
- {
- Mark();
-
- state = osContinue;
- } break;
- case kYellow:
- {
- DisplayFilter();
- state = osContinue;
- } break;
- case kBlue:
- {
- // Submenu
- m_last_osd_index = Current();
- DisplayPlaylistSubmenu();
-
- state = osContinue;
- } break;
- default:
- {
- state = osContinue;
- };
- }
- }
- }
- else if( m_state == LOAD_PLAYLIST )
- {
- if( state == osUnknown )
- {
- switch( key )
- {
- case kOk:
- {
- // load the selected playlist
-
- m_current_playlist -> clear();
- delete m_current_playlist;
-
- std::string selected = (*m_plists)[ Current() ];
- m_current_playlist = m_media->loadPlaylist( selected.c_str() );
-
- // clean the list of playlist
- m_plists->clear();
- m_last_osd_index =0;
- DisplayPlaylist(0);
- state = osContinue;
- } break;
- default:
- {
- state = osContinue;
- };
- }
- }
- }
- else if( m_state == PLAYLIST_SUBMENU )
- {
- if( state == osUnknown )
- {
- switch( key )
- {
- case k0 ... k9:
- {
- int n = key - k0;
- PlaylistSubmenuAction( n );
-
- state = osContinue;
- } break;
- case kYellow:
- {
- PlaylistSubmenuAction( 3 );
- } break;
- case kBlue:
- {
- m_state = PLAYLIST;
- DisplayPlaylist( m_last_osd_index );
-
- state = osContinue;
- } break;
- case kOk:
- {
- if( Current() != 0 )
- { // not editing playlist name
- state = PlaylistSubmenuAction( Current() );
- }
- else
- { // editing playlist name
- m_editing_listname = !m_editing_listname;
- if( m_editing_listname = false )
- { // we just changed from true to false so editing was terminated
- RenamePlaylist( std::string( m_listname ) );
-
- }
- }
- } break;
- default:
- {
- state = osContinue;
- } break;
- }
- }
- else if( state == osBack )
- {
- m_state = PLAYLIST;
- DisplayPlaylist( m_last_osd_index );
-
- state = osContinue;
- }
- }
- else if( m_state == PLAYLIST_COMMANDS )
- {
- if( state == osUnknown )
- {
- switch( key )
- {
- case kOk:
- {
- state = ExecutePlaylistCommand( Current() );
- } break;
- default:
- {
- }
- }
- }
- else if( state == osBack )
- {
- m_state = PLAYLIST_SUBMENU;
- DisplayPlaylistSubmenu();
-
- state = osContinue;
- }
- }
- else if( m_state == FILTER )
- {
- if( state == osUnknown )
- {
- switch( key )
- {
- case kRed: //
- {
- mgDebug( 1, "mgMainMenu: query and display results" );
-
- if( m_root )
- {
- delete m_root;
- }
-
- m_root = m_media->applyActiveFilter();
- // collapse all?
- DisplayTree( m_root );
-
- state = osContinue;
- } break;
- case kGreen:
- {
- // cycle FILTER -> TREE
- mgDebug( 1, "mgMainMenu: next filters " );
-
- m_media->nextFilterSet();
- DisplayFilter();
-
- state = osContinue;
- } break;
- case kYellow:
- {
- // Green: treeview
- mgDebug( 1, "mgMainMenu: switch to treeview" );
-
- DisplayTreeViewSelector();
-
- state = osContinue;
- } break;
- case kBlue:
- {
- mgDebug( 1, "mgMainMenu: submenu" );
- state = osContinue;
- } break;
- default:
- {
- state = osContinue;
- }
- }
- }
- else if( state == osBack )
- {
- // m_media->resetFilters();?
- }
- // RaK: Verhindert, dass die Help Buttons verschwinden,
- // ist aber keine schöne Lösung
- //SetHelp( tr("Query"), tr("Other Search"), tr("Browser"), tr("Submenu") );
- }
- else
- {
- mgDebug(1, "Process key: else");
- mgDebug(1, "Process key: %d", (int) state);
- }
-
- return state;
+void mgMainMenu::SaveState()
+{
+ char *b;
+ asprintf(&b,"%s/muggle.state",cPlugin::ConfigDirectory ("muggle"));
+ FILE *f = fopen(b,"w");
+ free(b);
+ if (!f) return;
+ mgValmap nmain("MainMenu");
+ nmain.put("DefaultCollection",default_collection);
+ nmain.put("UsingCollection",UsingCollection);
+ nmain.put("TreeRedAction",int(Menus.front()->TreeRedAction));
+ nmain.put("TreeGreenAction",int(Menus.front()->TreeGreenAction));
+ nmain.put("TreeYellowAction",int(Menus.front()->TreeYellowAction));
+ nmain.put("CollRedAction",int(Menus.front()->CollRedAction));
+ nmain.put("CollGreenAction",int(Menus.front()->CollGreenAction));
+ nmain.put("CollYellowAction",int(Menus.front()->CollYellowAction));
+ mgValmap nsel("tree");
+ m_treesel.DumpState(nsel);
+ mgValmap ncol("collection");
+ m_collectionsel.DumpState(ncol);
+ nmain.Write(f);
+ nsel.Write(f);
+ ncol.Write(f);
+ fclose(f);
}
-void mgMainMenu::DisplayTree( mgSelectionTreeNode* node, int select )
+mgMainMenu::mgMainMenu ():cOsdMenu ("")
{
- m_state = TREE;
+ m_Status = new mgStatus(this);
+ m_message = NULL;
+ queue_playing=false;
+ instant_playing=false;
+ play_collection = tr("play");
+ mgValmap nsel("tree");
+ mgValmap ncol("collection");
+ mgValmap nmain("MainMenu");
+
+ // define defaults for values missing in state file:
+ ncol.put("Keys.0.Choice","Collection");
+ ncol.put("Keys.1.Choice","Collection item");
+ nmain.put("DefaultCollection",play_collection);
+ nmain.put("UsingCollection","false");
+ nmain.put("TreeRedAction",int(actAddThisToCollection));
+ nmain.put("TreeGreenAction",int(actInstantPlay));
+ nmain.put("TreeYellowAction",int(actToggleSelection));
+ nmain.put("CollRedAction",int(actAddThisToCollection));
+ nmain.put("CollGreenAction",int(actInstantPlay));
+ nmain.put("CollYellowAction",int(actToggleSelection));
+
+ // load values from state file
+ char *b;
+ asprintf(&b,"%s/muggle.state",cPlugin::ConfigDirectory ("muggle"));
+ FILE *f = fopen(b,"r");
+ free(b);
+ if (f) {
+ nsel.Read(f);
+ ncol.Read(f);
+ nmain.Read(f);
+ fclose(f);
+ }
- if( node->expand( ) )
+ // get values from mgValmaps
+ default_collection = nmain.getstr("DefaultCollection");
+ UsingCollection = nmain.getbool("UsingCollection");
+ InitMapFromSetup(nsel);
+ m_treesel.InitFrom (nsel);
+ InitMapFromSetup(ncol);
+ m_collectionsel.InitFrom (ncol);
+ m_playsel.InitFrom(ncol);
+
+ // initialize
+ m_collectionsel.CreateCollection(default_collection);
+ m_collectionsel.CreateCollection(play_collection);
+ m_playsel.setKey(0,"Collection");
+ m_playsel.setKey(1,"Collection item");
+ m_playsel.enter(play_collection);
+ UseNormalSelection ();
+ unsigned int posi = selection()->gotoPosition();
+ mgMenu *root = new mgTree;
+ root->TreeRedAction = mgActions(nmain.getuint("TreeRedAction"));
+ root->TreeGreenAction = mgActions(nmain.getuint("TreeGreenAction"));
+ root->TreeYellowAction = mgActions(nmain.getuint("TreeYellowAction"));
+ root->CollRedAction = mgActions(nmain.getuint("CollRedAction"));
+ root->CollGreenAction = mgActions(nmain.getuint("CollGreenAction"));
+ root->CollYellowAction = mgActions(nmain.getuint("CollYellowAction"));
+ AddMenu (root);
+
+ SetCurrent (Get (posi));
+
+// Read commands for collections in etc. /video/muggle/playlist_commands.conf
+ external_commands = new cCommands ();
+
+ char *
+ cmd_file = (char *) AddDirectory (cPlugin::ConfigDirectory ("muggle"),
+ "playlist_commands.conf");
+ mgDebug (1, "mgMuggle::Start: Looking for file %s", cmd_file);
+ bool have_cmd_file = external_commands->Load ((const char *) cmd_file);
+
+ if (!have_cmd_file)
{
- Clear();
-
- char buffer[256];
- sprintf( buffer, "Muggle - %s", node->getLabel().c_str() );
-
- SetTitle( buffer );
- SetButtons();
-
- m_node = node;
- std::vector<mgSelectionTreeNode*> children = node->getChildren();
-
- for( std::vector<mgSelectionTreeNode*>::iterator iter = children.begin();
- iter != children.end();
- iter ++ )
- {
- Add( new mgMenuTreeItem( *iter ) );
- }
-
- cOsdItem *item = Get( select );
- SetCurrent( item );
-
- RefreshCurrent();
- DisplayCurrent(true);
+ delete external_commands;
+ external_commands = NULL;
}
- Display();
+ forcerefresh = false;
}
-void mgMainMenu::DisplayTreeViewSelector()
+mgMainMenu::~mgMainMenu()
{
- m_history.clear();
- // collapse all!
- DisplayTree( m_root );
+ delete m_Status;
}
-void mgMainMenu::DisplayTreeSubmenu()
+void
+mgMainMenu::InitMapFromSetup (mgValmap& nv)
{
- m_state = TREE_SUBMENU;
-
- Clear();
- SetButtons();
+ // values from setup override saved values
+ nv["Host"] = the_setup.DbHost;
+ nv["User"] = the_setup.DbUser;
+ nv["Password"] = the_setup.DbPass;
+ nv["Directory"] = cPlugin::ConfigDirectory ("muggle");
+ nv["ToplevelDir"] = the_setup.ToplevelDir;
+}
- char *buffer;
- asprintf( &buffer, "Muggle - %s", tr("Tree View Commands") );
- SetTitle( buffer );
- free( buffer );
+void
+mgMenu::AddAction (const mgActions action, const bool hotkey)
+{
+ mgOsdItem *a = GenerateAction(action);
+ if (!a) return;
+ const char *mn = a->MenuName();
+ if (strlen(mn)==0)
+ mgError("AddAction(%d):MenuName is empty",int(action));
+ if (hotkey)
+ a->SetText(osd()->hk(mn));
+ else
+ a->SetText(mn);
+ free(const_cast<char*>(mn));
+ osd()->Add(a);
+}
- // Add items
- Add( new cOsdItem( "Instant play" ) );
- Display();
+void
+mgMenu::AddExternalAction(const mgActions action, const char *title)
+{
+ mgOsdItem *a = GenerateAction(action);
+ if (!a) return;
+ a->SetText(osd()->hk(title));
+ osd()->Add(a);
}
-eOSState mgMainMenu::TreeSubmenuAction( int n )
+void
+mgMenu::AddSelectionItems ()
{
- eOSState state = osContinue;
-
- switch( n )
+ for (unsigned int i = 0; i < selection()->values.size (); i++)
+ {
+ mgOsdItem *a = GenerateAction(actEntry);
+ if (!a) continue;
+ a->SetText(a->MenuName(i+1,selection()->values[i]),false);
+ osd()->Add(a);
+ }
+ if (osd()->ShowingCollections ())
{
- case 0:
- {
- // action 0: instant play of current node, might need a security question
-
- mgSelectionTreeNode *current = CurrentNode();
- if( current )
- {
- // append current node
- std::vector<mgContentItem*> *tracks = m_menu_item->getTracks();
-
- if( tracks )
- {
- // clear playlist
- m_current_playlist->clear();
- m_current_playlist->appendList( tracks );
-
- // play
- mgMuggle::setResumeIndex( 0 );
- Play( m_current_playlist, 0 );
-
- state = osEnd;
- }
- }
- } break;
- case 1:
- {
- // action 0
- } break;
- default:
- {
- // undefined action
- } break;
+ mgCreateCollection *a = new mgCreateCollection;
+ if (!a) return;
+ a->SetMenu(this);
+ if (!a->Enabled())
+ {
+ delete a;
+ a=NULL;
+ }
+ if (!a) return;
+ a->SetText(a->MenuName(),false);
+ osd()->Add(a);
}
-
- return state;
}
-void mgMainMenu::DisplayPlaylist( int index_current )
-{
- m_state = PLAYLIST;
-
- // make sure we have a current playlist
- Clear();
- SetButtons();
- std::vector<mgContentItem*>* list = m_current_playlist-> getAll();
- static char titlestr[80];
- sprintf( titlestr, "Muggle - %s (%d %s)",tr("Playlist"),
- list->size() ,
- tr("items") );
- SetTitle( titlestr );
+const char *
+mgMenu::BlueName ()
+{
+ if (typeid (*this) == typeid (mgTree))
+ return tr("Commands");
+ else
+ return tr ("List");
+}
- for( unsigned int i = 0; i < m_current_playlist->getNumItems(); i++)
+void
+mgMenu::SetHelpKeys()
+{
+ const char *Red = NULL;
+ const char *Green = NULL;
+ const char *Yellow = NULL;
+ mgOsdItem *a;
+ if (osd()->UsingCollection)
{
- std::string label = m_current_playlist->getLabel( i, " " );
- Add( new cOsdItem( label.c_str() ) );
+ if ((a = GenerateAction (CollRedAction)))
+ Red = a->ButtonName ();
+ if ((a = GenerateAction (CollGreenAction)))
+ Green = a->ButtonName ();
+ if ((a = GenerateAction (CollYellowAction)))
+ Yellow = a->ButtonName ();
}
-
- if( index_current >= 0 )
+ else
{
- cOsdItem *item = Get( m_last_osd_index );
- SetCurrent( item );
- RefreshCurrent();
- DisplayCurrent( true );
- }
-
- Display();
-}
-
-void mgMainMenu::LoadPlaylist()
-{
- m_state = LOAD_PLAYLIST;
- static char titlestr[80];
-
- // make sure we have a current playlist
- Clear();
- SetButtons();
- sprintf( titlestr, "Muggle - %s %s ",tr("load"), tr("Playlist"));
- SetTitle( titlestr );
-
- // retrieve list of available playlists
- m_plists = m_media->getStoredPlaylists();
-
- for(std::vector<std::string>::iterator iter = m_plists->begin();
- iter != m_plists->end() ; iter++)
- {
- Add( new cOsdItem( iter->c_str() ) );
+ if ((a = GenerateAction (TreeRedAction)))
+ Red = a->ButtonName ();
+ if ((a = GenerateAction (TreeGreenAction)))
+ Green = a->ButtonName ();
+ if ((a = GenerateAction (TreeYellowAction)))
+ Yellow = a->ButtonName ();
}
-
- Display();
+ osd()->SetHelpKeys(Red,Green,Yellow,BlueName());
}
-void mgMainMenu::SavePlaylist()
-{
- if(m_current_playlist->getListname() == "")
- {
- // create dummy listname with current date and time
- time_t currentTime = time(NULL);
- m_current_playlist->setListname(ctime(&currentTime));
- }
- m_current_playlist->storePlaylist();
-}
-void mgMainMenu::RenamePlaylist( std::string name )
+void
+mgMenu::InitOsd (const char *title,const bool hashotkeys)
{
- // dummy function. USes current date as name
- m_current_playlist->setListname( name );
-
- // confirmation
-#if VDRVERSNUM >= 10307
- Skins.Message(mtInfo, "Playlist renamed" );
- Skins.Flush();
-#else
- Interface->Status( "Playlist renamed" );
- Interface->Flush();
-#endif
+ osd ()->InitOsd (title,hashotkeys);
}
-void mgMainMenu::DisplayPlaylistSubmenu()
+
+void
+mgMainMenu::InitOsd (const char *title,const bool hashotkeys)
{
- static const char allowed[] = { "abcdefghijklmnopqrstuvwxyz0123456789-_" };
+ Clear ();
+ SetTitle (title);
+ if (hashotkeys) SetHasHotkeys ();
+}
- m_state = PLAYLIST_SUBMENU;
- Clear();
- SetButtons();
- SetTitle( "Muggle - Playlist View Commands" );
+void
+mgSubmenu::BuildOsd ()
+{
+ static char b[100];
+ snprintf(b,99,tr("Commands:%s"),trim(osd()->selection()->getCurrentValue()).c_str());
+ InitOsd (b);
+ mgMenu *p = osd ()->Parent ();
+ if (!p)
+ return;
+ AddAction(actInstantPlay);
+ AddAction(actAddThisToCollection);
+ AddAction(actRemoveThisFromCollection);
+ AddAction(actToggleSelection);
+ AddAction(actSetDefault);
+ AddAction(actDeleteCollection);
+ AddAction(actChooseSearch);
+ AddAction(actExportTracklist);
+ cCommand *command;
+ if (osd()->external_commands)
+ {
+ int idx=0;
+ while ((command = osd ()->external_commands->Get (idx)) != NULL)
+ {
+ if (idx>actExternalHigh-actExternal0)
+ {
+ mgWarning("Too many external commands");
+ break;
+ }
+ AddExternalAction (mgActions(idx+int(actExternal0)),command->Title());
+ idx++;
+ }
+ }
+ TreeRedAction = actSetButton;
+ TreeGreenAction = actSetButton;
+ TreeYellowAction = actSetButton;
+ CollRedAction = actSetButton;
+ CollGreenAction = actSetButton;
+ CollYellowAction = actSetButton;
+}
- // Add items
- Add( new cMenuEditStrItem( tr("Playlist name"), m_listname, 31, allowed ) );
- Add( new cOsdItem( tr("Load playlist" ) ) );
- Add( new cOsdItem( tr("Save playlist" ) ) );
- Add( new cOsdItem( tr("Clear playlist" ) ) );
- Add( new cOsdItem( tr("Remove entry from list" ) ) );
- Add( new cOsdItem( tr("Export playlist" ) ) );
- if( m_playlist_commands )
+eOSState
+mgTree::Process (eKeys key)
+{
+ eOSState result = osUnknown;
+ switch (key)
{
- Add( new cOsdItem( tr("External playlist commands" ) ) );
+ case kRed:
+ if (osd()->UsingCollection)
+ ExecuteAction (CollRedAction);
+ else
+ ExecuteAction (TreeRedAction);
+ return osContinue;
+ case kGreen:
+ if (osd()->UsingCollection)
+ ExecuteAction (CollGreenAction);
+ else
+ ExecuteAction (TreeGreenAction);
+ return osContinue;
+ case kYellow:
+ if (osd()->UsingCollection)
+ ExecuteAction (CollYellowAction);
+ else
+ ExecuteAction (TreeYellowAction);
+ return osContinue;
+ default:
+ result = osUnknown;
+ break;
}
+ return result;
+}
- Display();
+void
+mgTree::BuildOsd ()
+{
+ InitOsd (selection ()->getListname ().c_str (), false);
+ AddSelectionItems ();
}
-void mgMainMenu::DisplayPlaylistCommands()
+void
+mgMainMenu::Message1(const char *msg, const char *arg1)
{
- m_state = PLAYLIST_COMMANDS;
+ if (strlen(msg)==0) return;
+ asprintf (&m_message, tr (msg), arg1);
+}
- cCommand *command;
- int i = 0;
- Clear();
- SetTitle( "Muggle - External Playlist Commands" );
+eOSState mgMainMenu::ProcessKey (eKeys key)
+{
+ eOSState result = osContinue;
+ if (key!=kNone)
+ mgDebug (3, "MainMenu::ProcessKey(%d)", (int) key);
- while( ( command = m_playlist_commands->Get(i) ) != NULL )
+ if (Menus.size()<1)
+ mgError("mgMainMenu::ProcessKey: Menus is empty");
+
+ mgPlayerControl * c = PlayerControl ();
+ if (c)
{
- Add( new cOsdItem( hk( command->Title() ) ) );
- i++;
+ if (!c->Active ())
+ {
+ c->Shutdown ();
+ if (instant_playing && queue_playing) {
+ PlayQueue();
+ }
+ else
+ {
+ instant_playing = false;
+ queue_playing = false;
+ }
+ }
+ else
+ {
+ switch (key)
+ {
+ case kPause:
+ c->Pause ();
+ break;
+ case kStop:
+ if (instant_playing && queue_playing) {
+ PlayQueue();
+ }
+ else
+ {
+ queue_playing = false;
+ c->Stop ();
+ }
+ break;
+ case kChanUp:
+ c->Forward ();
+ break;
+ case kChanDn:
+ c->Backward ();
+ break;
+ default:
+ goto otherkeys;
+ }
+ goto pr_exit;
+ }
}
+ else
+ if (key==kPlay) {
+ PlayQueue();
+ goto pr_exit;
+ }
+otherkeys:
+ newmenu = Menus.back(); // Default: Stay in current menu
+ newposition = -1;
- Display();
-}
-
-eOSState mgMainMenu::ExecutePlaylistCommand( int current )
-{
- cCommand *command = m_playlist_commands->Get( current );
- if( command )
{
- char *buffer = NULL;
- bool confirmed = true;
- if( command->Confirm() )
- {
- asprintf( &buffer, "%s?", command->Title() );
-//#if VDRVERSNUM < 10307
- confirmed = Interface->Confirm( buffer );
-//#else
-//#endif
- free( buffer );
- }
- if( confirmed )
- {
- asprintf( &buffer, "%s...", command->Title() );
-#if VDRVERSNUM >= 10307
- Skins.Message(mtInfo,buffer);
- Skins.Flush();
-#else
- Interface->Status( buffer );
- Interface->Flush();
-#endif
- free( buffer );
+ mgMenu * oldmenu = newmenu;
- std::string tmp_m3u_file = (char *) AddDirectory( cPlugin::ConfigDirectory("muggle"), "current.m3u" );
- m_current_playlist->exportM3U( tmp_m3u_file );
+// item specific key logic:
+ result = cOsdMenu::ProcessKey (key);
- char *result = (char *)command->Execute( tmp_m3u_file.c_str() );
+// mgMenu specific key logic:
+ if (result == osUnknown)
+ result = oldmenu->Process (key);
+ }
+// catch osBack for empty OSD lists
+// (because if the list was empty, no mgOsdItem::ProcessKey was ever called)
+ if (result == osBack)
+ {
+ // do as if there was an entry
+ mgOsdItem *a = Menus.back()->GenerateAction(actEntry);
+ if (a)
+ {
+ result = a->Back();
+ delete a;
+ }
+ }
- /* What to do? Recode cMenuText (not much)?
- if( result )
- {
- return AddSubMenu( new cMenuText( command->Title(), result ) );
- }
- */
-
- free( result );
+// do nothing for unknown keys:
+ if (result == osUnknown)
+ goto pr_exit;
- return osEnd;
- }
+// change OSD menu as requested:
+ if (newmenu == NULL)
+ {
+ if (Menus.size () > 1)
+ {
+ Menus.pop_back ();
+ forcerefresh = true;
+ }
+ else
+ {
+ result = osBack; // game over
+ goto pr_exit;
+ }
}
- return osContinue;
-}
-
-eOSState mgMainMenu::PlaylistSubmenuAction( int n )
-{
- std::cout << "mgMainMenu::PlaylistSubmenuAction: " << n << std::endl << std::flush;
- eOSState state = osContinue;
-
- switch( n )
+ else if (newmenu != Menus.back ())
{
- case 0:
- { // rename playlist - should never get here!
- state = osContinue;
- } break;
-
- case 1:
- {
- LoadPlaylist();
-#if VDRVERSNUM < 10307
- Interface->Flush();
-#else
- Skins.Flush();
-#endif
- // jump to playlist view from here?
- } break;
- case 2:
- {
- SavePlaylist();
-#if VDRVERSNUM >= 10307
- Skins.Message(mtInfo,"Playlist saved");
- Skins.Flush();
-#else
- Interface->Status( "Playlist saved");
- Interface->Flush();
-#endif
- } break;
- case 3:
- { // clear playlist
+ AddMenu (newmenu);
+ }
- cControl *control = cControl::Control();
- std::string buffer;
+ if (UsingCollection)
+ forcerefresh |= m_collectionsel.cacheIsEmpty();
+ else
+ forcerefresh |= m_treesel.cacheIsEmpty();
- if( control && typeid(*control) == typeid(mgPlayerControl) )
- {
- buffer = "Cannot clear playlist while playing.";
- }
- else
- {
- m_current_playlist->clear();
+ forcerefresh |= (newposition>=0);
- buffer = "Playlist cleared";
- }
-
- // confirmation
-#if VDRVERSNUM >= 10307
- Skins.Message( mtInfo, buffer.c_str() );
- Skins.Flush();
-#else
- Interface->Status( buffer.c_str() );
- Interface->Flush();
-#endif
-
- state = osContinue;
- } break;
- case 4:
- { // remove selected title
- bool res = m_current_playlist->remove( m_last_osd_index );
-
- if( m_last_osd_index > 0 )
- {
- m_last_osd_index --;
- }
- DisplayPlaylist( m_last_osd_index );
-
- // confirmation
- std::string confirm = res? "Entry deleted": "Cannot delete entry";
+ if (forcerefresh)
+ {
+ mgDebug(2,"forced refresh");
+ forcerefresh = false;
+ if (newposition<0)
+ newposition = selection()->gotoPosition();
+ Menus.back ()->Display (newposition);
+ }
+pr_exit:
+ showMessage();
+ return result;
+}
+void
+mgMainMenu::showMessage()
+{
+ if (m_message)
+ {
#if VDRVERSNUM >= 10307
- Skins.Message( mtInfo, confirm.c_str() );
- Skins.Flush();
+ Skins.Message (mtInfo, m_message);
+ Skins.Flush ();
#else
- Interface->Status( confirm.c_str() );
- Interface->Flush();
+ Interface->Status (m_message);
+ Interface->Flush ();
#endif
- } break;
- case 5:
- {
- std::string m3u_file = AddDirectory( cPlugin::ConfigDirectory("muggle"),
- m_current_playlist->getListname().c_str() );
- m_current_playlist->exportM3U( m3u_file );
- } break;
- case 6:
- {
- DisplayPlaylistCommands();
- } break;
- default:
- {
- // undefined action
- } break;
+ free(m_message);
+ m_message = NULL;
}
-
- return state;
}
-void mgMainMenu::DisplayFilter()
-{
- m_state = FILTER;
- Clear();
- SetButtons();
+void
+mgMainMenu::AddMenu (mgMenu * m)
+{
+ Menus.push_back (m);
+ m->setosd (this);
+ m->Display (0);
+}
- SetTitle( m_media->getActiveFilterTitle().c_str() );
- std::vector<mgFilter*> *filter_list = m_media->getActiveFilters();
-
- int i=0;
- for( std::vector<mgFilter*>::iterator iter = filter_list->begin();
- iter != filter_list->end();
- iter ++ )
- {
- mgDebug( 1, "Filter %d/%dint filter %s='%s'",
- i, filter_list->size(),
- (*iter)->getName(),
- (*iter)->getStrVal().c_str());
- switch( (*iter)->getType() )
- {
- case mgFilter::INT:
- {
- mgFilterInt *fi = (mgFilterInt *) (*iter);
-
- Add( new cMenuEditIntItem( fi->getName(),
- &(fi->m_intval),
- fi->getMin(), fi->getMax() ) );
- } break;
- case mgFilter::STRING:
- {
- mgFilterString *fs = (mgFilterString *) (*iter);
-
- // BUG: This might be buggy as fs->getAllowedChars() may become
- // invalid while VDR is still trying to access it
- Add( new cMenuEditStrItem( fs->getName(), fs->m_strval,
- fs->getMaxLength(),
- fs->getAllowedChars().c_str() ) );
-
- } break;
- case mgFilter::BOOL:
- {
- mgFilterBool *fb = (mgFilterBool *) (*iter);
- Add( new cMenuEditBoolItem( fb->getName(), &( fb->m_bval),
- fb->getTrueString().c_str(),
- fb->getFalseString().c_str() ) );
- } break;
- case mgFilter::CHOICE:
- {
- mgFilterChoice *fc = (mgFilterChoice *) (*iter);
- std::vector<std::string> choices = fc->getChoices();
-
- char **choices_str = new (char *)[ choices.size() ];
-
- int j = 0;
- for( std::vector<std::string>::iterator iter = choices.begin();
- iter != choices.end();
- iter ++, j ++ )
- {
- // BUG: Is this a big memory leak!? When to delete and who?
- // RaK: zweiter Iterator war "i" richtig: "j"
- // choices_str[j] = strndup( choices[i].c_str(), 128 );
- choices_str[j] = strndup( choices[j].c_str(), 128 );
- }
-
- Add( new cMenuEditStraItem( fc->getName(), &( fc->m_selval ),
- choices.size(), choices_str ) );
-
- // delete all choices_str elements!
- // delete[] choices_str; // ???
-
- } break;
- default:
- case mgFilter::UNDEF:
- {
- } break;
- }
- i++;
- }
-
- Display();
+eOSState
+mgSubmenu::Process (eKeys key)
+{
+ return osUnknown;
}
-void mgMainMenu::DisplayFilterSelector()
+
+void
+mgTreeViewSelector::BuildOsd ()
{
- // show available filters, load on OK?
+ InitOsd (tr ("Tree View Selection"));
+ AddAction(actSearchCollItem);
+ AddAction(actSearchArtistAlbumTitle);
+ AddAction(actSearchArtistTitle);
+ AddAction(actSearchAlbumTitle);
+ AddAction(actSearchGenreYearTitle);
+ AddAction(actSearchGenreArtistAlbumTitle);
}
-void mgMainMenu::Play( mgPlaylist *plist, unsigned first )
+void
+mgMainMenu::DisplayGoto (unsigned int select)
{
- MGLOG( "mgMainMenu::Play" );
- cControl *control = cControl::Control();
-
- if( control && typeid(*control) == typeid(mgPlayerControl) )
- { // is there a running MP3 player?
- static_cast<mgPlayerControl*>(control)->NewPlaylist(plist, first); // signal the running player to load the new playlist
- }
- else
+ if (select >= 0)
{
- cControl::Launch( new mgPlayerControl(plist, first) );
+ SetCurrent (Get (select));
+ RefreshCurrent ();
}
+ Display ();
+ DisplayMenu()->SetTabs(25);
+}
+
+
+void
+mgMenu::Display (const unsigned int position)
+{
+ BuildOsd ();
+ osd ()->DisplayGoto (position);
}
+