diff options
author | MountainMan <MountainMan@e10066b5-e1e2-0310-b819-94efdf66514b> | 2004-02-09 19:27:52 +0000 |
---|---|---|
committer | MountainMan <MountainMan@e10066b5-e1e2-0310-b819-94efdf66514b> | 2004-02-09 19:27:52 +0000 |
commit | d62ff70e806d5992436b1abc04fd479e5623a1fa (patch) | |
tree | 2c2788a6a6012005042c96e98a5bb83fb9c80478 | |
parent | a6cd0e97d915a7e5fcb3db6fd25eaac624b03d57 (diff) | |
download | vdr-plugin-muggle-d62ff70e806d5992436b1abc04fd479e5623a1fa.tar.gz vdr-plugin-muggle-d62ff70e806d5992436b1abc04fd479e5623a1fa.tar.bz2 |
filter set implemented
git-svn-id: https://vdr-muggle.svn.sourceforge.net/svnroot/vdr-muggle/trunk@31 e10066b5-e1e2-0310-b819-94efdf66514b
-rw-r--r-- | muggle-plugin/Makefile | 7 | ||||
-rw-r--r-- | muggle-plugin/gd_content_interface.c | 201 | ||||
-rw-r--r-- | muggle-plugin/gd_content_interface.h | 31 | ||||
-rwxr-xr-x | muggle-plugin/mg_content_interface.h | 14 | ||||
-rw-r--r-- | muggle-plugin/mg_media.c | 475 | ||||
-rw-r--r-- | muggle-plugin/mg_media.h | 145 | ||||
-rw-r--r-- | muggle-plugin/muggle.c | 8 | ||||
-rw-r--r-- | muggle-plugin/sh_muggle.c | 7 | ||||
-rw-r--r-- | muggle-plugin/vdr_menu.c | 37 |
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 * |