summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muggle-plugin/Makefile7
-rw-r--r--muggle-plugin/gd_content_interface.c201
-rw-r--r--muggle-plugin/gd_content_interface.h31
-rwxr-xr-xmuggle-plugin/mg_content_interface.h14
-rw-r--r--muggle-plugin/mg_media.c475
-rw-r--r--muggle-plugin/mg_media.h145
-rw-r--r--muggle-plugin/muggle.c8
-rw-r--r--muggle-plugin/sh_muggle.c7
-rw-r--r--muggle-plugin/vdr_menu.c37
9 files changed, 720 insertions, 205 deletions
diff --git a/muggle-plugin/Makefile b/muggle-plugin/Makefile
index fcad314..d913ff7 100644
--- a/muggle-plugin/Makefile
+++ b/muggle-plugin/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for a Video Disk Recorder plugin
#
-# $Id: Makefile,v 1.4 2004/02/03 00:13:24 LarsAC Exp $
+# $Id: Makefile,v 1.5 2004/02/09 19:27:52 MountainMan Exp $
# The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin.
@@ -46,9 +46,10 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
### The object files (add further files here):
-OBJS = $(PLUGIN).o vdr_menu.o mg_database.o mg_content_interface.o sh_dummy_content.o gd_content_interface.o mg_tools.o mg_media.o
+OBJS = $(PLUGIN).o vdr_menu.o mg_database.o mg_content_interface.o gd_content_interface.o mg_tools.o mg_media.o
-BINOBJS = sh_shell_osd_plugin.o sh_shell_osd.o sh_shell_osd_menuitems.o muggle.o vdr_menu.o content_interface.o dummy_content.o gd_content_interface.o muggle_tools.o mgmedia.o
+BINOBJS = mg_database.o mg_content_interface.o gd_content_interface.o mg_tools.o mg_media.o
+#BINOBJS = sh_console_osd.o muggle.o vdr_menu.o content_interface.o gd_content_interface.o muggle_tools.o mgmedia.o
### Implicit rules:
diff --git a/muggle-plugin/gd_content_interface.c b/muggle-plugin/gd_content_interface.c
index 2727f4d..806dff6 100644
--- a/muggle-plugin/gd_content_interface.c
+++ b/muggle-plugin/gd_content_interface.c
@@ -3,10 +3,10 @@
* \brief Data Objects for content (e.g. mp3 files, movies)
* for the vdr muggle plugindatabase
********************************************************************
- * \version $Revision: 1.7 $
- * \date $Date: 2004/02/03 00:13:24 $
+ * \version $Revision: 1.8 $
+ * \date $Date: 2004/02/09 19:27:52 $
* \author Ralf Klueber, Lars von Wedel, Andreas Kellner
- * \author file owner: $Author: LarsAC $
+ * \author file owner: $Author: MountainMan $
*
* DUMMY
* Implements main classes of for content items and interfaces to SQL databases
@@ -62,82 +62,122 @@ vector<string> *GdGetStoredPlaylists(MYSQL db)
return list;
}
-/*******************************************************************/
-/* class class gdTrackFilters */
-/********************************************************************/
-gdTrackFilters::gdTrackFilters()
-{
- clear();
-}
-gdTrackFilters::~gdTrackFilters()
-{
-}
-void gdTrackFilters::clear()
+//------------------------------------------------------------------
+//------------------------------------------------------------------
+//
+// class gdTrackFilters
+//
+//------------------------------------------------------------------
+//------------------------------------------------------------------
+
+/*!
+ *******************************************************************
+ * \brief constructor, constracts a number >=1 of filter sets
+ *
+ * the first set (index 0 ) is active by default
+ ********************************************************************/
+gdFilterSets::gdFilterSets()
{
- mgFilter* filter ;
- // remove old filters
- for(vector<mgFilter*>::iterator iter = m_filters.begin();
- iter != m_filters.end(); iter++)
- {
- delete (*iter);
- }
- m_filters.clear();
+ mgFilter* filter;
+ m_titles.push_back("Trackfilter");
+
// create an initial set of filters with empty values
- // title
+ vector<mgFilter*>* set = new vector<mgFilter*>();
+
+ // title
filter = new mgFilterString("title", "");
- m_filters.push_back(filter);
+ set->push_back(filter);
// artist
filter = new mgFilterString("artist", "");
- m_filters.push_back(filter);
+ set->push_back(filter);
// genre
filter = new mgFilterString("genre", "");
- m_filters.push_back(filter);
- // year
- filter = new mgFilterInt("year", -1);
- m_filters.push_back(filter);
+ set->push_back(filter);
+ // year-from
+ filter = new mgFilterInt("year (from)", 0);
+ set->push_back(filter);
+ // year-to
+ filter = new mgFilterInt("year (to)", 9999);
+ set->push_back(filter);
// rating
- filter = new mgFilterInt("rating", -1);
- m_filters.push_back(filter);
+ filter = new mgFilterInt("rating", 0);
+ set->push_back(filter);
+
+ m_sets.push_back(set);
+ m_activeSetId = 0;
+ m_activeSet = set;
+}
+
+/*!
+ *******************************************************************
+ * \briefdestructor
+ ********************************************************************/
+gdFilterSets::~gdFilterSets()
+{
+ // everything is done in the destructor of the base class
}
-string gdTrackFilters::CreateSQL()
+/*!
+ *******************************************************************
+ * \brief computes the restrictions specified by the active filter set
+ * \param viewPrt index of the appropriate defualt view
+ * \return sql string representing the restrictions
+ ********************************************************************/
+string gdFilterSets::computeRestriction(int *viewPrt)
{
string sql_str = "1";
- for(vector<mgFilter*>::iterator iter = m_filters.begin();
- iter != m_filters.end(); iter++)
+ for(vector<mgFilter*>::iterator iter = m_activeSet->begin();
+ iter != m_activeSet->end(); iter++)
{
- if(strcmp((*iter)->getName(), "title") == 0 )
+ if((*iter)->isSet())
+ {
+ if(strcmp((*iter)->getName(), "title") == 0 )
{
- sql_str = "AND tracks.title like '"
- + (*iter)->getStrVal() + "%'";
+ sql_str = sql_str + " AND tracks.title like ' "
+ + (*iter)->getStrVal() + "'";
}
- else if(strcmp((*iter)->getName(), "artist") == 0 )
- {
- sql_str = "AND tracks.artist like '"
- + (*iter)->getStrVal() + "%'";
+ else if(strcmp((*iter)->getName(), "artist") == 0 )
+ {
+ sql_str = sql_str + " AND tracks.artist like ''"
+ + (*iter)->getStrVal() + "'";
}
- else if(strcmp((*iter)->getName(), "genre") == 0 )
- {
- sql_str = "AND genre.name like '"
- + (*iter)->getStrVal() + "%'";
+ else if(strcmp((*iter)->getName(), "genre") == 0 )
+ {
+ sql_str = sql_str + " AND genre.name like ''"
+ + (*iter)->getStrVal() + "'";
}
- else if(strcmp((*iter)->getName(), "year") == 0 )
- {
- sql_str = "AND tracks.year = " + (*iter)->getStrVal();
+ else if(strcmp((*iter)->getName(), "year (from)") == 0 )
+ {
+ sql_str = sql_str + " AND tracks.year >= " + (*iter)->getStrVal();
}
- else if(strcmp((*iter)->getName(), "rating") == 0 )
- {
- sql_str = "AND tracks.rating >= " + (*iter)->getStrVal();
+ else if(strcmp((*iter)->getName(), "year (to)") == 0 )
+ {
+ sql_str = sql_str + " AND tracks.year <= " + (*iter)->getStrVal();
+ }
+ else if(strcmp((*iter)->getName(), "rating") == 0 )
+ {
+ sql_str = sql_str + " AND tracks.rating >= " + (*iter)->getStrVal();
}
+ else
+ {
+ mgWarning("Ignoring unknown filter %s", (*iter)->getName());
+ }
+ }
}
+ *viewPrt = 1; // artist -> album -> title
+ mgDebug(1, "Applying sql string %s (view=%d)",sql_str.c_str(), *viewPrt);
return sql_str;
}
-/*******************************************************************/
-/* class mgTack */
-/********************************************************************/
+//------------------------------------------------------------------
+//------------------------------------------------------------------
+//
+// class mgTack
+//
+//------------------------------------------------------------------
+//------------------------------------------------------------------
mgGdTrack mgGdTrack::UNDEFINED = mgGdTrack();
/*!
@@ -328,14 +368,13 @@ string mgGdTrack::getLabel(int col)
}
}
-string mgGdTrack::getDescription()
+vector<mgFilter*> *mgGdTrack::getTrackInfo()
{
- if(!m_retrieved)
- {
- readData();
- }
- return m_artist + " - " + m_title;
-
+ return new vector<mgFilter*>();
+}
+bool mgGdTrack::setTrackInfo(vector<mgFilter*> *info)
+{
+ return false;
}
/*!
@@ -505,6 +544,13 @@ bool mgGdTrack::writeData()
return true;
}
+//------------------------------------------------------------------
+//------------------------------------------------------------------
+//
+// class GdTracklist
+//
+//------------------------------------------------------------------
+//------------------------------------------------------------------
GdTracklist::GdTracklist(MYSQL db_handle, string restrictions)
{
MYSQL_RES *result;
@@ -531,9 +577,13 @@ GdTracklist::GdTracklist(MYSQL db_handle, string restrictions)
}
-/*******************************************************************/
-/* class GdPlaylist */
-/********************************************************************/
+//------------------------------------------------------------------
+//------------------------------------------------------------------
+//
+// class GdPlaylist
+//
+//------------------------------------------------------------------
+//------------------------------------------------------------------
/*!
*****************************************************************************
@@ -734,9 +784,13 @@ int GdPlaylist::getPlayTimeRemaining()
return 0; // dummy
}
-/*******************************************************************/
-/* class GdTreeNode */
-/*******************************************************************/
+//------------------------------------------------------------------
+//------------------------------------------------------------------
+//
+// class GdTreeNode
+//
+//------------------------------------------------------------------
+//------------------------------------------------------------------
/*!
*****************************************************************************
@@ -1078,27 +1132,27 @@ bool GdTreeNode::expand()
new_child = new GdTreeNode(this, // parent
"1" , // id
"Artist -> Album -> Title", // label,
- "1");
+ m_restriction);
m_children.push_back(new_child);
new_child = new GdTreeNode(this, // parent
"2" , // id
"Genre -> Artist -> Album -> Track" , // label,
- "1");
+ m_restriction);
m_children.push_back(new_child);
new_child = new GdTreeNode(this, // parent
"3" , // id
"Artist -> Track" , // label,
- "1");
+ m_restriction);
m_children.push_back(new_child);
new_child = new GdTreeNode(this, // parent
"4" , // id
"Genre -> Year -> Track" , // label,
- "1");
+ m_restriction);
m_children.push_back(new_child);
new_child = new GdTreeNode(this, // parent
"5" , // id
"Album -> Track" , // label,
- "1");
+ m_restriction);
m_children.push_back(new_child);
} else {
new_child = new GdTreeNode(this, // parent
@@ -1199,6 +1253,9 @@ mgContentItem* GdTreeNode::getSingleTrack()
/* -------------------- begin CVS log ---------------------------------
* $Log: gd_content_interface.c,v $
+ * Revision 1.8 2004/02/09 19:27:52 MountainMan
+ * filter set implemented
+ *
* Revision 1.7 2004/02/03 00:13:24 LarsAC
* Improved OSD handling of collapse/back
*
diff --git a/muggle-plugin/gd_content_interface.h b/muggle-plugin/gd_content_interface.h
index 476dc5d..fecca7c 100644
--- a/muggle-plugin/gd_content_interface.h
+++ b/muggle-plugin/gd_content_interface.h
@@ -3,8 +3,8 @@
* \brief Data Objects for content (e.g. mp3 files, movies)
* for the vdr muggle plugindatabase
********************************************************************
- * \version $Revision: 1.3 $
- * \date $Date: 2004/02/02 22:48:04 $
+ * \version $Revision: 1.4 $
+ * \date $Date: 2004/02/09 19:27:52 $
* \author Ralf Klueber, Lars von Wedel, Andreas Kellner
* \author file owner: $Author: MountainMan $
*
@@ -35,17 +35,24 @@ int GdInitDatabase(MYSQL *db);
std::vector<std::string> *GdGetStoredPlaylists(MYSQL db);
-class gdTrackFilters: public mgTrackFilters
+class gdFilterSets : public mgFilterSets
{
+
public:
- gdTrackFilters();
- ~gdTrackFilters();
+ gdFilterSets();
+ // constructor, constracts a number >=1 of filter sets
+ // the first set (index 0 ) is active by default
+
+ virtual ~gdFilterSets();
+ // destructor
+
+ virtual std::string computeRestriction(int *viewPrt);
+ // computes the (e.g. sql-) restrictions specified by the active filter set
+ // and returns the index of the appropriate defualt view in viewPrt
- virtual std::string CreateSQL();
- virtual void clear();
-
};
+
/*!
*******************************************************************
* \class mgGdTrack
@@ -99,7 +106,10 @@ private:
virtual std::string getSourceFile();
virtual std::string getTitle();
virtual std::string getLabel(int col);
- virtual std::string getDescription();
+
+ virtual std::vector<mgFilter*> *getTrackInfo();
+ virtual bool setTrackInfo(std::vector<mgFilter*>*);
+
virtual std::string getGenre();
virtual int getRating();
@@ -209,6 +219,9 @@ public:
/* -------------------- begin CVS log ---------------------------------
* $Log: gd_content_interface.h,v $
+ * Revision 1.4 2004/02/09 19:27:52 MountainMan
+ * filter set implemented
+ *
* Revision 1.3 2004/02/02 22:48:04 MountainMan
* added CVS $Log
*
diff --git a/muggle-plugin/mg_content_interface.h b/muggle-plugin/mg_content_interface.h
index 1c210d1..b7bc7a3 100755
--- a/muggle-plugin/mg_content_interface.h
+++ b/muggle-plugin/mg_content_interface.h
@@ -3,8 +3,8 @@
* \brief Data Objects for content (e.g. mp3 files, movies)
* for the vdr muggle plugindatabase
********************************************************************
- * \version $Revision: 1.2 $
- * \date $Date: 2004/02/02 22:48:04 $
+ * \version $Revision: 1.3 $
+ * \date $Date: 2004/02/09 19:27:52 $
* \author Ralf Klueber, Lars von Wedel, Andreas Kellner
* \author file owner: $Author: MountainMan $
*
@@ -28,6 +28,7 @@
#include <mysql/mysql.h>
#define ILLEGAL_ID -1
+class mgFilter;
/*!
*******************************************************************
@@ -90,6 +91,9 @@ class mgContentItem
virtual std::string getDescription()// return a short textual description
{return "";}
+ virtual std::vector<mgFilter*> *getTrackInfo(){return NULL;}
+ virtual bool updateTrackInfo(std::vector<mgFilter*>*){return false;}
+
virtual std::string getGenre(){return "";}
virtual int getRating()
{
@@ -212,6 +216,7 @@ public:
virtual ~mgSelectionTreeNode();
// compute children on the fly
+ virtual bool isLeafNode()=0;
virtual bool expand()=0;
virtual void collapse(); // removes all children (recursively)
@@ -237,11 +242,14 @@ public:
// Note: This function allocates memory for the vector and for all elements of the vector
// The calling function is in charge of releasing this memory
virtual std::vector<mgContentItem*>* getTracks()=0;
-
+ virtual mgContentItem* getSingleTrack()=0;
};
/* -------------------- begin CVS log ---------------------------------
* $Log: mg_content_interface.h,v $
+ * Revision 1.3 2004/02/09 19:27:52 MountainMan
+ * filter set implemented
+ *
* Revision 1.2 2004/02/02 22:48:04 MountainMan
* added CVS $Log
*
diff --git a/muggle-plugin/mg_media.c b/muggle-plugin/mg_media.c
index 088ba65..54fd32c 100644
--- a/muggle-plugin/mg_media.c
+++ b/muggle-plugin/mg_media.c
@@ -3,8 +3,8 @@
* \brief Top level access to media in vdr plugin muggle
* for the vdr muggle plugindatabase
********************************************************************
- * \version $Revision: 1.8 $
- * \date $Date: 2004/02/02 23:33:41 $
+ * \version $Revision: 1.9 $
+ * \date $Date: 2004/02/09 19:27:52 $
* \author Ralf Klueber, Lars von Wedel, Andreas Kellner
* \author file owner: $Author: MountainMan $
*
@@ -18,7 +18,6 @@
#include "mg_content_interface.h"
#include "gd_content_interface.h"
-#include "sh_dummy_content.h"
using namespace std;
@@ -52,8 +51,10 @@ mgFilterInt::mgFilterInt(const char *name, int value, int min, int max)
{
m_type = INT;
m_intval = value;
- m_min = min;
+ m_default_val = value;
+ m_stored_val = value;
m_max = max;
+ m_min = min;
}
mgFilterInt::~mgFilterInt()
{
@@ -66,15 +67,50 @@ string mgFilterInt::getStrVal()
return (string)buffer;
}
+
+int mgFilterInt::getIntVal()
+{
+ return (int) m_intval;
+}
+
+int mgFilterInt::getVal()
+{
+ return m_intval;
+}
+
int mgFilterInt::getMin()
{
return m_min;
}
+
int mgFilterInt::getMax()
{
return m_max;
}
+void mgFilterInt::store()
+{
+ m_stored_val = m_intval;
+}
+void mgFilterInt::restore()
+{
+ m_intval = m_stored_val;
+}
+void mgFilterInt::clear()
+{
+ m_stored_val = m_default_val;
+ m_intval = m_default_val;
+}
+
+bool mgFilterInt::isSet()
+{
+ if(m_stored_val == m_default_val)
+ {
+ return false;
+ }
+ return true;
+}
+
//-------------------------------------------------------------------
// mgFilterString
//-------------------------------------------------------------------
@@ -84,6 +120,8 @@ mgFilterString::mgFilterString(const char *name, const char* value,
{
m_type = STRING;
m_strval = strdup(value);
+ m_default_val = strdup(value);
+ m_stored_val = strdup(value);
m_allowedchar = allowedchar;
m_maxlen = maxlen;
}
@@ -109,7 +147,33 @@ string mgFilterString::getStrVal()
return (string) m_strval;
}
+void mgFilterString::store()
+{
+ if(m_stored_val) free(m_stored_val);
+ m_stored_val = strdup(m_strval);
+}
+void mgFilterString::restore()
+{
+ if(m_strval) free(m_strval);
+ m_strval = strdup(m_stored_val);
+}
+void mgFilterString::clear()
+{
+ if(m_stored_val) free(m_stored_val);
+ if(m_strval) free(m_strval);
+
+ m_stored_val = strdup(m_default_val);
+ m_strval = strdup(m_default_val);
+}
+bool mgFilterString::isSet()
+{
+ if(strlen(m_stored_val) == 0)
+ {
+ return false;
+ }
+ return true;
+}
//-------------------------------------------------------------------
// mgFilterBool
//-------------------------------------------------------------------
@@ -118,11 +182,14 @@ mgFilterBool::mgFilterBool(const char *name, bool value,
: mgFilter(name)
{
m_type = BOOL;
- m_bval = (bool) value;
+ m_bval = (int) value;
+ m_default_val = value;
+ m_stored_val = value;
m_truestr = truestr;
m_falsestr = falsestr;
}
+
mgFilterBool::~mgFilterBool()
{
}
@@ -134,27 +201,60 @@ string mgFilterBool::getStrVal()
else
return "false";
}
+
+int mgFilterBool::getIntVal()
+{
+ return (int) m_bval;
+}
+
string mgFilterBool::getTrueString()
{
return m_truestr;
}
+
string mgFilterBool::getFalseString()
{
return m_falsestr;
}
+
bool mgFilterBool::getVal()
{
return (bool) m_bval;
}
+void mgFilterBool::store()
+{
+ m_stored_val = (bool) m_bval;
+}
+
+void mgFilterBool::restore()
+{
+ m_bval = (int) m_stored_val;
+}
+
+void mgFilterBool::clear()
+{
+ m_stored_val = (int) m_default_val;
+ m_bval = (int) m_default_val;
+}
+
+bool mgFilterBool::isSet()
+{
+ if(m_stored_val == m_default_val )
+ {
+ return false;
+ }
+ return true;
+}
//-------------------------------------------------------------------
// mgFilterChoice
//-------------------------------------------------------------------
-mgFilterChoice::mgFilterChoice(const char *name, int val, vector<string> *choices)
+mgFilterChoice::mgFilterChoice(const char *name, int value, vector<string> *choices)
: mgFilter(name)
{
m_choices = *choices;
- m_selval = val;
+ m_selval = value;
+ m_default_val = value;
if( m_selval < 0 || m_selval >= (int) m_choices.size() )
{
mgError("mgFilterChoice::mgFilterChoice(..): Illegal index %d", m_selval);
@@ -177,27 +277,171 @@ vector<string> &mgFilterChoice::getChoices()
{
return m_choices;
}
+void mgFilterChoice::store()
+{
+ m_stored_val = m_selval;
+
+}
+void mgFilterChoice::restore()
+{
+ m_selval = m_stored_val;
+}
+void mgFilterChoice::clear()
+{
+ m_stored_val = m_default_val;
+ m_selval = m_default_val;
+}
+
+bool mgFilterChoice::isSet()
+{
+ if(m_stored_val == m_default_val)
+ {
+ return false;
+ }
+ return true;
+}
+
//-------------------------------------------------------------------
-// mgTrackFilters
+// mgFilterSets
//-------------------------------------------------------------------
-mgTrackFilters::mgTrackFilters()
+/*!
+ *******************************************************************
+ * \brief constructor
+ *
+ * constructor of the base class
+ ********************************************************************/
+mgFilterSets::mgFilterSets()
{
+ // nothing to be done in the base class
}
-mgTrackFilters::~mgTrackFilters()
+ /*!
+ *******************************************************************
+ * \brief destructor
+ ********************************************************************/
+mgFilterSets::~mgFilterSets()
{
- for(vector<mgFilter*>::iterator iter = m_filters.begin();
- iter != m_filters.end(); iter++)
+ vector<mgFilter*> *set;
+ for(vector<vector<mgFilter*>*>::iterator iter1 = m_sets.begin();
+ iter1 != m_sets.end(); iter1++)
+ {
+ set = *iter1;
+ for(vector<mgFilter*>::iterator iter2 = set->begin();
+ iter2 != set->end(); iter2++)
{
- delete (*iter);
+ delete (*iter2);
}
- m_filters.clear();
+ set->clear();
+ delete set;
+ }
+ m_sets.clear();
+}
+ /*!
+ *******************************************************************
+ * \brief returns the number of available sets
+ ********************************************************************/
+int mgFilterSets::numSets()
+{
+ return m_sets.size();
+}
+
+ /*!
+ *******************************************************************
+ * \brief proceeds to the next one in a circular fashion
+ ********************************************************************/
+void mgFilterSets::nextSet()
+{
+ m_activeSetId++;
+ if(m_activeSetId >= (int) m_sets.size())
+ {
+ m_activeSetId = 0;
+ }
+ m_activeSet = m_sets[m_activeSetId];
+}
+ //
+
+/*!
+ *******************************************************************
+ * \brief activates a specific set by index
+ *
+ * \par n : index of the set to be activated
+ *
+ * If n is not a valid filter set, the first set (index 0 ) is activated
+ ********************************************************************/
+void mgFilterSets::select(int n)
+{
+ m_activeSetId = n ;
+ if(m_activeSetId >= (int) m_sets.size())
+ {
+ m_activeSetId = 0;
+ }
+ m_activeSet = m_sets[m_activeSetId];
+
+}
+
+ /*!
+ *******************************************************************
+ * \brief restores the default values for all filter values in the active set
+ ********************************************************************/
+ void mgFilterSets::clear()
+{
+ for(vector<mgFilter*>::iterator iter = m_activeSet->begin();
+ iter != m_activeSet->end(); iter++)
+ {
+ (*iter)->clear();
+ }
+}
+ /*!
+ *******************************************************************
+ * \brief stores the current filter values
+ ********************************************************************/
+ void mgFilterSets::accept()
+{
+ for(vector<mgFilter*>::iterator iter = m_activeSet->begin();
+ iter != m_activeSet->end(); iter++)
+ {
+ (*iter)->store();
+ }
+}
+
+/*!
+ *******************************************************************
+ * \brief returns the active filter set to the application
+ *
+ * the application may temporarily modify the filter values
+ * accept() needs to be called to memorize the changed values
+ ********************************************************************/
+ vector<mgFilter*> *mgFilterSets::getFilters()
+{
+ for(vector<mgFilter*>::iterator iter = m_activeSet->begin();
+ iter != m_activeSet->end(); iter++)
+ {
+ (*iter)->restore();
+ }
+ return m_activeSet;
}
-vector<mgFilter*> *mgTrackFilters::getFilters()
+
+/*!
+ *******************************************************************
+ * \brief return title of the active filter set
+ ********************************************************************/
+string mgFilterSets::getTitle()
{
- return &m_filters;
+ if(m_activeSetId < (int) m_titles.size())
+ {
+ return m_titles[m_activeSetId];
+ }
+ else
+ {
+ mgWarning("Implementation error: No title string for filter set %d",
+ m_activeSetId);
+ return "NO-TITLE";
+ }
}
+//-------------------------------------------------------------------
+// mgFilterSets
+//-------------------------------------------------------------------
/*!
*******************************************************************
* \class mgMedia
@@ -207,20 +451,15 @@ vector<mgFilter*> *mgTrackFilters::getFilters()
mgMedia::mgMedia(contentType mediatype)
{
int errval = 0;
- m_trackfilter = NULL;
+ m_filters = NULL;
m_mediatype = mediatype;
- m_sql_trackfilter = "1";
+ m_sql_filter = "1";
m_defaultView = 1;
// now initialize the database
mgDebug(1, "Media Type %sselected", getMediaTypeName().c_str());
switch(m_mediatype)
{
- case DUMMY:
- {
- errval = DummyInitDatabase(&m_db);
- break;
- }
case GD_MP3:
{
errval = GdInitDatabase(&m_db);
@@ -235,11 +474,6 @@ mgMedia::mgMedia(contentType mediatype)
mgDebug(3, "Initializing track filters");
switch(m_mediatype)
{
- case DUMMY:
- {
- errval = DummyInitDatabase(&m_db);
- break;
- }
case GD_MP3:
{
errval = GdInitDatabase(&m_db);
@@ -248,20 +482,26 @@ mgMedia::mgMedia(contentType mediatype)
}
}
+/*!
+ *******************************************************************
+ * \brief
+ ********************************************************************/
mgMedia::~mgMedia()
{
- if( m_trackfilter )
+ if( m_filters )
{
- delete m_trackfilter;
+ delete m_filters;
}
}
+/*!
+ *******************************************************************
+ * \brief
+ ********************************************************************/
string mgMedia::getMediaTypeName()
{
switch(m_mediatype)
{
- case DUMMY:
- return "DUMMY";
case GD_MP3:
return "GiantDisc-mp3";
}
@@ -270,57 +510,41 @@ string mgMedia::getMediaTypeName()
}
+/*!
+ *******************************************************************
+ * \brief
+ ********************************************************************/
mgSelectionTreeNode* mgMedia::getSelectionRoot()
{
switch(m_mediatype)
{
- case DUMMY:
- return new DummyTreeNode(m_db, m_defaultView);
case GD_MP3:
- return new GdTreeNode(m_db, m_defaultView, m_sql_trackfilter);
+ return new GdTreeNode(m_db, m_defaultView, m_sql_filter);
}
mgError("implementation Error"); // we should never get here
return NULL;
}
-vector<mgFilter*> *mgMedia::getTrackFilters()
-{
- switch(m_mediatype)
- {
- case DUMMY:
- // return mgFilters();
- case GD_MP3:
- if( m_trackfilter == NULL )
- {
- m_trackfilter = new gdTrackFilters();
- }
- return m_trackfilter->getFilters();
- default:
- break;
- }
- mgError("implementation Error"); // we should never get here
- return NULL;
-}
-
-void mgMedia::applyTrackFilters(vector<mgFilter*> *filters)
-{
-}
+/*!
+ *******************************************************************
+ * \brief
+ ********************************************************************/
mgPlaylist* mgMedia::createTemporaryPlaylist()
{
string tmpname = "current";
return loadPlaylist(tmpname);
}
+/*!
+ *******************************************************************
+ * \brief
+ ********************************************************************/
mgPlaylist* mgMedia::loadPlaylist(string name)
{
mgPlaylist *list;
switch(m_mediatype)
{
- case DUMMY:
- list = new DummyPlaylist(name, m_db);
- list->setDisplayColumns(getDefaultCols());
- return list;
case GD_MP3:
list = new GdPlaylist(name, m_db);
list->setDisplayColumns(getDefaultCols());
@@ -330,12 +554,14 @@ mgPlaylist* mgMedia::loadPlaylist(string name)
return NULL;
}
+/*!
+ *******************************************************************
+ * \brief
+ ********************************************************************/
vector<string> *mgMedia::getStoredPlaylists()
{
switch(m_mediatype)
{
- case DUMMY:
- return DummyGetStoredPlaylists(m_db);
case GD_MP3:
return GdGetStoredPlaylists(m_db);
}
@@ -343,15 +569,15 @@ vector<string> *mgMedia::getStoredPlaylists()
return new vector<string>();
}
+/*!
+ *******************************************************************
+ * \brief
+ ********************************************************************/
vector<int> mgMedia::getDefaultCols()
{
vector<int> cols;
switch(m_mediatype)
{
- case DUMMY:
- cols.push_back(1); // artist
- cols.push_back(0); // track
- return cols;
case GD_MP3:
cols.push_back(1); // artist
cols.push_back(0); // track
@@ -362,18 +588,17 @@ vector<int> mgMedia::getDefaultCols()
return cols;
}
+/*!
+ *******************************************************************
+ * \brief
+ ********************************************************************/
mgTracklist* mgMedia::getTracks()
{
mgTracklist *tracks;
switch(m_mediatype)
{
- case DUMMY:
-
- tracks = new DummyTracklist(m_db, m_sql_trackfilter);
- tracks->setDisplayColumns(getDefaultCols());
- return tracks;
case GD_MP3:
- tracks = new GdTracklist(m_db, m_sql_trackfilter);
+ tracks = new GdTracklist(m_db, m_sql_filter);
tracks->setDisplayColumns(getDefaultCols());
return tracks;
}
@@ -381,8 +606,112 @@ mgTracklist* mgMedia::getTracks()
return NULL;
}
+
+/*!
+ *******************************************************************
+ * \brief creates FiliterSetObject for the selected media type
+ * and activates set n (if available)
+ ********************************************************************/
+void mgMedia::initFilterSet(int num)
+{
+ switch(m_mediatype)
+ {
+ case GD_MP3:
+ m_filters = new gdFilterSets();
+ m_filters->select(num);
+ break;
+ }
+}
+
+/*!
+ *******************************************************************
+ * \brief returns pointer to the activen filter set to be modified by the osd
+ *
+ * Note: Modifications become only effective by calling applyActiveFilter()
+ ********************************************************************/
+vector<mgFilter*> *mgMedia::getActiveFilters()
+{
+ if(!m_filters)
+ {
+ mgError("ImplementationError: getActiveFilters m_filters == NULL");
+ }
+ return m_filters->getFilters();
+}
+
+/*!
+ *******************************************************************
+ * \brief returns title of the active filter set
+ ********************************************************************/
+string mgMedia::getActiveFilterTitle()
+{
+
+ switch(m_mediatype)
+ {
+ case GD_MP3:
+ if(!m_filters)
+ {
+ mgError("ImplementationError:getActiveFilterTitle m_filters == NULL");
+ }
+ return m_filters->getTitle();
+ }
+ return "";
+}
+
+/*!
+ *******************************************************************
+ * \brief proceeds to the next filter set in a cirlucar fashion
+ ********************************************************************/
+void mgMedia::nextFilterSet()
+{
+ if(!m_filters)
+ {
+ mgError("ImplementationError: nextFilterSet m_filters == NULL");
+ }
+ m_filters->nextSet();
+}
+
+/*!
+ *******************************************************************
+ * \brief clears the current filter values and restores defaults
+ ********************************************************************/
+void mgMedia::clearActiveFilter()
+{
+ if(!m_filters)
+ {
+ mgError("ImplementationError: clearActiveFilter m_filters == NULL");
+ }
+ m_filters->clear();
+}
+
+/*!
+ *******************************************************************
+ * \brief Applies the active filter set and returns a root node for the
+ * selection in the default view for this filter set
+ ********************************************************************/
+mgSelectionTreeNode *mgMedia::applyActiveFilter()
+{
+ int view;
+
+ switch(m_mediatype)
+ {
+ case GD_MP3:
+ if(!m_filters)
+ {
+ mgError("ImplementationError: applyActiveFilter() m_filters == NULL");
+ }
+ m_filters->accept();
+ m_sql_filter = m_filters->computeRestriction(&view);
+ return new GdTreeNode(m_db, view, m_sql_filter);
+ }
+ return NULL;
+}
+
+
/* -------------------- begin CVS log ---------------------------------
* $Log: mg_media.c,v $
+ * Revision 1.9 2004/02/09 19:27:52 MountainMan
+ * filter set implemented
+ *
* Revision 1.8 2004/02/02 23:33:41 MountainMan
* impementation of gdTrackFilters
*
diff --git a/muggle-plugin/mg_media.h b/muggle-plugin/mg_media.h
index d39ce93..619c2e7 100644
--- a/muggle-plugin/mg_media.h
+++ b/muggle-plugin/mg_media.h
@@ -3,8 +3,8 @@
* \brief Top level access to media in vdr plugin muggle
* for the vdr muggle plugindatabase
********************************************************************
- * \version $Revision: 1.7 $
- * \date $Date: 2004/02/02 23:33:41 $
+ * \version $Revision: 1.8 $
+ * \date $Date: 2004/02/09 19:27:52 $
* \author Ralf Klueber, Lars von Wedel, Andreas Kellner
* \author file owner: $Author: MountainMan $
*
@@ -28,7 +28,7 @@ class mgSelectionTreeNode;
*******************************************************************
* \class mgFilter
*
- * represents a filter value with boundaries or choices
+ * Abstract base class for representation of filter values with boundaries
********************************************************************/
class mgFilter
{
@@ -44,6 +44,11 @@ class mgFilter
filterType getType();
const char* getName();
virtual std::string getStrVal()=0;
+ virtual int getIntVal(){return 0;}
+ virtual void store()=0;
+ virtual void restore()=0;
+ virtual void clear()=0;
+ virtual bool isSet()=0;
};
/*!
@@ -55,17 +60,24 @@ class mgFilterInt : public mgFilter
private:
int m_min;
int m_max;
+ int m_stored_val;
+ int m_default_val;
public:
int m_intval;
- mgFilterInt(const char *name, int value, int min = 0, int max = INT_MAX);
+ mgFilterInt(const char *name, int value, int min = 0, int max = 9999);
virtual ~mgFilterInt();
int getVal();
int getMin();
int getMax();
virtual std::string getStrVal();
+ virtual int getIntVal();
+ virtual void store();
+ virtual void restore();
+ virtual void clear();
+ virtual bool isSet();
};
/*!
@@ -77,6 +89,9 @@ class mgFilterString : public mgFilter
private:
std::string m_allowedchar;
int m_maxlen;
+ char* m_stored_val;
+ char* m_default_val;
+
public:
char* m_strval;
@@ -88,6 +103,10 @@ class mgFilterString : public mgFilter
int getMaxLength();
std::string getAllowedChars();
virtual std::string getStrVal();
+ virtual void store();
+ virtual void restore();
+ virtual void clear();
+ virtual bool isSet();
};
/*!
@@ -99,6 +118,8 @@ class mgFilterBool : public mgFilter
private:
std::string m_truestr;
std::string m_falsestr;
+ bool m_stored_val;
+ bool m_default_val;
public:
int m_bval;
@@ -108,9 +129,14 @@ class mgFilterBool : public mgFilter
virtual ~mgFilterBool();
virtual std::string getStrVal();
+ virtual int getIntVal();
std::string getTrueString();
std::string getFalseString();
bool getVal();
+ virtual void store();
+ virtual void restore();
+ virtual void clear();
+ virtual bool isSet();
};
/*!
@@ -121,7 +147,9 @@ class mgFilterChoice : public mgFilter
{
private:
std::vector<std::string> m_choices;
-
+ int m_stored_val;
+ int m_default_val;
+
public:
int m_selval; // index of the currently selected item
@@ -130,30 +158,68 @@ class mgFilterChoice : public mgFilter
virtual std::string getStrVal();
virtual std::vector<std::string> &getChoices();
-
+ virtual void store();
+ virtual void restore();
+ virtual void clear();
+ virtual bool isSet();
};
+
/*!
*******************************************************************
- * \class mgrackFilters
+ * \class mgFilterSets
*
- * Represents a set of filters to set and memorize the search
- * constraint for a specific track
+ * Represents one or several sets of filters to set and memorize
+ * search constraint
********************************************************************/
-class mgTrackFilters
-{
+class mgFilterSets {
protected:
- std::vector<mgFilter*> m_filters;
+ int m_activeSetId;
+ std::vector<mgFilter*> *m_activeSet; // pointer to the active filter set
+
+ std::vector< std::vector<mgFilter*>*> m_sets;
+ // stores name-value pairs, even if a different set is active
+
+ std::vector<std::string> m_titles;
+ // stores the titles for all filters
+
public:
- mgTrackFilters();
- virtual ~mgTrackFilters();
+ mgFilterSets();
+ // constructor, constracts a number >=1 of filter sets
+ // the first set (index 0 ) is active by default
- std::vector<mgFilter*> *getFilters();
-
- virtual std::string CreateSQL()=0;
- virtual void clear()=0;
-
+ virtual ~mgFilterSets();
+ // destructor
+
+ int numSets();
+ // returns the number of available sets
+
+ void nextSet();
+ // proceeds to the next one in a circular fashion
+
+ void select(int n);
+ // activates a specific set by index
+
+ virtual void clear();
+ // restores the default values for all filter values in the active set
+ // normally, the default values represent 'no restrictions'
+
+ void accept();
+ // stores the current filter values
+
+ std::vector<mgFilter*> *getFilters();
+ // returns the active set to the application
+ // the application may temporarily modify the filter values
+ // accept() needs to be called to memorize the changed values
+
+ virtual std::string computeRestriction(int *viewPrt)=0;
+ // computes the (e.g. sql-) restrictions specified by the active filter set
+ // and returns the index of the appropriate defualt view in viewPrt
+
+ std::string getTitle();
+ // returns title of active filter set
};
+
/*!
*******************************************************************
* \class mgMedia
@@ -170,16 +236,15 @@ class mgMedia
public:
typedef enum contentType{
- DUMMY =0,
- GD_MP3
+ GD_MP3
} contentType;
private:
MYSQL m_db;
contentType m_mediatype;
- std::string m_sql_trackfilter;
+ std::string m_sql_filter;
int m_defaultView;
- mgTrackFilters *m_trackfilter;
+ mgFilterSets *m_filters;
public:
mgMedia(contentType mediatype);
@@ -189,10 +254,6 @@ class mgMedia
mgSelectionTreeNode* getSelectionRoot();
- // filter management
- std::vector<mgFilter*> *getTrackFilters();
- void applyTrackFilters(std::vector<mgFilter*> *filters);
-
// playlist management
mgPlaylist* createTemporaryPlaylist();
mgPlaylist* loadPlaylist( std::string name );
@@ -200,10 +261,38 @@ class mgMedia
std::vector<int> getDefaultCols();
mgTracklist* getTracks();
+
+ // filter management
+
+ void initFilterSet(int num=0);
+ // creates FiliterSetObject for the selected media type
+ // and activates set n (if available)
+
+
+ std::vector<mgFilter*> *getActiveFilters();
+ // returns pointer to the activen filter set to be modified by the osd
+ // Note: Modifications become only active by calling applyActiveFilter()
+
+ std::string getActiveFilterTitle();
+
+ void nextFilterSet();
+ // proceeds to the next filter set in a cirlucar fashion
+
+ void clearActiveFilter();
+ // clears the current filter values and restores defaults
+
+
+ mgSelectionTreeNode *applyActiveFilter();
+ // Applies the active filter set and returns a root node for the
+ // selection in the default view for this filter set
+
};
/* -------------------- begin CVS log ---------------------------------
* $Log: mg_media.h,v $
+ * Revision 1.8 2004/02/09 19:27:52 MountainMan
+ * filter set implemented
+ *
* Revision 1.7 2004/02/02 23:33:41 MountainMan
* impementation of gdTrackFilters
*
@@ -213,5 +302,5 @@ class mgMedia
*
* --------------------- end CVS log ----------------------------------
*/
-#endif /* END _CONTENT_INTERFACE_H */
+#endif /* END _MG_MEDIA_H */
diff --git a/muggle-plugin/muggle.c b/muggle-plugin/muggle.c
index 845eab3..e03e56d 100644
--- a/muggle-plugin/muggle.c
+++ b/muggle-plugin/muggle.c
@@ -2,10 +2,10 @@
/*! \file muggle.c
* \brief Implements a plugin for browsing media libraries within VDR
********************************************************************
- * \version $Revision: 1.2 $
- * \date $Date: 2004/02/03 19:28:46 $
+ * \version $Revision: 1.3 $
+ * \date $Date: 2004/02/09 19:27:52 $
* \author Ralf Klueber, Lars von Wedel, Andreas Kellner
- * \author file owner: $Author: LarsAC $
+ * \author file owner: $Author: MountainMan $
*/
/*******************************************************************/
@@ -75,7 +75,7 @@ bool mgMuggle::Start(void)
m_media = new mgMedia( mgMedia::GD_MP3 );
m_root = m_media->getSelectionRoot();
m_playlist = m_media->createTemporaryPlaylist();
-
+ m_media->initFilterSet();
return true;
}
diff --git a/muggle-plugin/sh_muggle.c b/muggle-plugin/sh_muggle.c
index ef26f57..485905e 100644
--- a/muggle-plugin/sh_muggle.c
+++ b/muggle-plugin/sh_muggle.c
@@ -2,9 +2,9 @@
#include <stdlib.h>
#include "mysql/mysql.h"
-#include "content_interface.h"
-#include "mgmedia.h"
-#include "muggle_tools.h"
+#include "mg_content_interface.h"
+#include "mg_media.h"
+#include "mg_tools.h"
#include <unistd.h>
#define DISPLAY_SIZE 20
@@ -17,6 +17,7 @@
#define PLAYLIST_VIEW 3
#define FILTER_VIEW 4
+using namespace std;
const char playlist_command_str[] =
" s : shuffle\n"
diff --git a/muggle-plugin/vdr_menu.c b/muggle-plugin/vdr_menu.c
index 317a647..30d254a 100644
--- a/muggle-plugin/vdr_menu.c
+++ b/muggle-plugin/vdr_menu.c
@@ -2,12 +2,12 @@
/*! \file vdr_menu.c
* \brief Implements menu handling for broswing media libraries within VDR
********************************************************************
- * \version $Revision: 1.12 $
- * \date $Date: 2004/02/08 10:48:44 $
+ * \version $Revision: 1.13 $
+ * \date $Date: 2004/02/09 19:27:52 $
* \author Ralf Klueber, Lars von Wedel, Andreas Kellner
- * \author file owner: $Author: LarsAC $
+ * \author file owner: $Author: MountainMan $
*
- * $Id: vdr_menu.c,v 1.12 2004/02/08 10:48:44 LarsAC Exp $
+ * $Id: vdr_menu.c,v 1.13 2004/02/09 19:27:52 MountainMan Exp $
*/
/*******************************************************************/
@@ -344,17 +344,22 @@ eOSState mgMainMenu::ProcessKey(eKeys key)
// OK: Create filter and selection tree and display
mgDebug( 1, "mgMainMenu: create and apply filter" );
// m_media->applyFilters();
+ state = osContinue;
} break;
- case kRed: // ???
+ case kRed: //
{
- state = osContinue;
mgDebug( 1, "mgMainMenu: query and display results" );
+ if(m_root) delete m_root;
+ m_root = m_media->applyActiveFilter();
+ DisplayTree( m_root );
+ state = osContinue;
} break;
case kGreen:
{
// cycle FILTER -> TREE
- mgDebug( 1, "mgMainMenu: clear filters (todo)" );
- DisplayFilterSelector();
+ mgDebug( 1, "mgMainMenu: next filters " );
+ m_media->nextFilterSet();
+ DisplayFilter();
state = osContinue;
} break;
case kYellow:
@@ -536,19 +541,27 @@ void mgMainMenu::DisplayFilter()
mgDebug( 1, "Creating Muggle filter view" );
SetButtons();
- SetTitle( "Muggle Filter View" );
+ SetTitle( m_media->getActiveFilterTitle().c_str() );
+ mgDebug( 1, "filter view2" );
- vector<mgFilter*> *filter_list = m_media->getTrackFilters();
+ vector<mgFilter*> *filter_list = m_media->getActiveFilters();
+ mgDebug( 1, "filter view3" );
+ int i=0;
for( 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() ) );
@@ -573,6 +586,7 @@ void mgMainMenu::DisplayFilter()
{
} break;
}
+ i++;
}
Display();
@@ -586,6 +600,9 @@ void mgMainMenu::DisplayFilterSelector()
/************************************************************
*
* $Log: vdr_menu.c,v $
+ * Revision 1.13 2004/02/09 19:27:52 MountainMan
+ * filter set implemented
+ *
* Revision 1.12 2004/02/08 10:48:44 LarsAC
* Made major revisions in OSD behavior
*